Bug 772321 - Implement CSS parsing of writing-mode r=dbaron
authorRick Eyre <rick.eyre@hotmail.com>
Tue, 28 May 2013 12:00:49 -0400
changeset 133986 3e2d3f3235b4
parent 133985 04a12e995be8
child 133987 9c001ba8508a
push id24780
push useremorley@mozilla.com
push date2013-06-05 10:40 +0000
treeherdermozilla-central@b925d7cdd09a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs772321
milestone24.0a1
Bug 772321 - Implement CSS parsing of writing-mode r=dbaron
layout/base/nsStyleConsts.h
layout/style/nsCSSKeywordList.h
layout/style/nsCSSPropList.h
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/style/test/property_database.js
modules/libpref/src/init/all.js
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -359,16 +359,21 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_CURSOR_EW_RESIZE               35
 #define NS_STYLE_CURSOR_NONE                    36
 
 // See nsStyleVisibility
 #define NS_STYLE_DIRECTION_LTR                  0
 #define NS_STYLE_DIRECTION_RTL                  1
 #define NS_STYLE_DIRECTION_INHERIT              2
 
+// See nsStyleVisibility
+#define NS_STYLE_WRITING_MODE_HORIZONTAL_TB     0
+#define NS_STYLE_WRITING_MODE_VERTICAL_LR       1
+#define NS_STYLE_WRITING_MODE_VERTICAL_RL       2
+
 // See nsStyleDisplay
 #define NS_STYLE_DISPLAY_NONE                   0
 #define NS_STYLE_DISPLAY_BLOCK                  1
 #define NS_STYLE_DISPLAY_INLINE                 2
 #define NS_STYLE_DISPLAY_INLINE_BLOCK           3
 #define NS_STYLE_DISPLAY_LIST_ITEM              4
 #define NS_STYLE_DISPLAY_TABLE                  8
 #define NS_STYLE_DISPLAY_INLINE_TABLE           9
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -279,16 +279,17 @@ CSS_KEY(hidden, hidden)
 CSS_KEY(hide, hide)
 CSS_KEY(highlight, highlight)
 CSS_KEY(highlighttext, highlighttext)
 CSS_KEY(hiragana, hiragana)
 CSS_KEY(hiragana-iroha, hiragana_iroha)
 CSS_KEY(historical-forms, historical_forms)
 CSS_KEY(historical-ligatures, historical_ligatures)
 CSS_KEY(horizontal, horizontal)
+CSS_KEY(horizontal-tb, horizontal_tb)
 CSS_KEY(hz, hz)
 CSS_KEY(icon, icon)
 CSS_KEY(ignore, ignore)
 CSS_KEY(in, in)
 CSS_KEY(interlace, interlace)
 CSS_KEY(inactive, inactive)
 CSS_KEY(inactiveborder, inactiveborder)
 CSS_KEY(inactivecaption, inactivecaption)
@@ -501,16 +502,18 @@ CSS_KEY(ultra-condensed, ultra_condensed
 CSS_KEY(ultra-expanded, ultra_expanded)
 CSS_KEY(underline, underline)
 CSS_KEY(unicase, unicase)
 CSS_KEY(upper-alpha, upper_alpha)
 CSS_KEY(upper-latin, upper_latin)
 CSS_KEY(upper-roman, upper_roman)
 CSS_KEY(uppercase, uppercase)
 CSS_KEY(vertical, vertical)
+CSS_KEY(vertical-lr, vertical_lr)
+CSS_KEY(vertical-rl, vertical_rl)
 CSS_KEY(vertical-text, vertical_text)
 CSS_KEY(visible, visible)
 CSS_KEY(visiblefill, visiblefill)
 CSS_KEY(visiblepainted, visiblepainted)
 CSS_KEY(visiblestroke, visiblestroke)
 CSS_KEY(w-resize, w_resize)
 CSS_KEY(wait, wait)
 CSS_KEY(wavy, wavy)
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -2616,16 +2616,26 @@ CSS_PROP_VISIBILITY(
     PointerEvents,
     CSS_PROPERTY_PARSE_VALUE |
         CSS_PROPERTY_APPLIES_TO_PLACEHOLDER,
     "",
     VARIANT_HK,
     kPointerEventsKTable,
     offsetof(nsStyleVisibility, mPointerEvents),
     eStyleAnimType_EnumU8)
+CSS_PROP_VISIBILITY(
+    writing-mode,
+    writing_mode,
+    WritingMode,
+    CSS_PROPERTY_PARSE_VALUE,
+    "layout.css.vertical-text.enabled",
+    VARIANT_HK,
+    kWritingModeKTable,
+    offsetof(nsStyleVisibility, mWritingMode),
+    eStyleAnimType_EnumU8)
 CSS_PROP_DISPLAY(
     position,
     position,
     Position,
     CSS_PROPERTY_PARSE_VALUE,
     "",
     VARIANT_HK,
     kPositionKTable,
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1565,16 +1565,23 @@ const int32_t nsCSSProps::kWordBreakKTab
 };
 
 const int32_t nsCSSProps::kWordWrapKTable[] = {
   eCSSKeyword_normal, NS_STYLE_WORDWRAP_NORMAL,
   eCSSKeyword_break_word, NS_STYLE_WORDWRAP_BREAK_WORD,
   eCSSKeyword_UNKNOWN,-1
 };
 
+const int32_t nsCSSProps::kWritingModeKTable[] = {
+  eCSSKeyword_horizontal_tb, NS_STYLE_WRITING_MODE_HORIZONTAL_TB,
+  eCSSKeyword_vertical_lr, NS_STYLE_WRITING_MODE_VERTICAL_LR,
+  eCSSKeyword_vertical_rl, NS_STYLE_WRITING_MODE_VERTICAL_RL,
+  eCSSKeyword_UNKNOWN, -1
+};
+
 const int32_t nsCSSProps::kHyphensKTable[] = {
   eCSSKeyword_none, NS_STYLE_HYPHENS_NONE,
   eCSSKeyword_manual, NS_STYLE_HYPHENS_MANUAL,
   eCSSKeyword_auto, NS_STYLE_HYPHENS_AUTO,
   eCSSKeyword_UNKNOWN,-1
 };
 
 // Specific keyword tables for XUL.properties
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -460,12 +460,13 @@ public:
   static const int32_t kVerticalAlignKTable[];
   static const int32_t kVisibilityKTable[];
   static const int32_t kVolumeKTable[];
   static const int32_t kWhitespaceKTable[];
   static const int32_t kWidthKTable[]; // also min-width, max-width
   static const int32_t kWindowShadowKTable[];
   static const int32_t kWordBreakKTable[];
   static const int32_t kWordWrapKTable[];
+  static const int32_t kWritingModeKTable[];
   static const int32_t kHyphensKTable[];
 };
 
 #endif /* nsCSSProps_h___ */
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2934,16 +2934,26 @@ nsComputedDOMStyle::DoGetVisibility()
 {
   nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mVisible,
                                                nsCSSProps::kVisibilityKTable));
   return val;
 }
 
 CSSValue*
+nsComputedDOMStyle::DoGetWritingMode()
+{
+  nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
+  val->SetIdent(
+    nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mWritingMode,
+                                   nsCSSProps::kWritingModeKTable));
+  return val;
+}
+
+CSSValue*
 nsComputedDOMStyle::DoGetDirection()
 {
   nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue;
   val->SetIdent(
     nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mDirection,
                                    nsCSSProps::kDirectionKTable));
   return val;
 }
@@ -4995,16 +5005,17 @@ nsComputedDOMStyle::GetQueryableProperty
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(vertical_align,         VerticalAlign),
     COMPUTED_STYLE_MAP_ENTRY(visibility,                    Visibility),
     COMPUTED_STYLE_MAP_ENTRY(white_space,                   WhiteSpace),
     // COMPUTED_STYLE_MAP_ENTRY(widows,                     Widows),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(width,                  Width),
     COMPUTED_STYLE_MAP_ENTRY(word_break,                    WordBreak),
     COMPUTED_STYLE_MAP_ENTRY(word_spacing,                  WordSpacing),
     COMPUTED_STYLE_MAP_ENTRY(word_wrap,                     WordWrap),
+    COMPUTED_STYLE_MAP_ENTRY(writing_mode,                  WritingMode),
     COMPUTED_STYLE_MAP_ENTRY(z_index,                       ZIndex),
 
     /* ******************************* *\
      * Implementations of -moz- styles *
     \* ******************************* */
 
     COMPUTED_STYLE_MAP_ENTRY(appearance,                    Appearance),
     COMPUTED_STYLE_MAP_ENTRY(_moz_background_inline_policy, BackgroundInlinePolicy),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -322,16 +322,17 @@ private:
   mozilla::dom::CSSValue* DoGetHyphens();
   mozilla::dom::CSSValue* DoGetTabSize();
   mozilla::dom::CSSValue* DoGetTextSizeAdjust();
 
   /* Visibility properties */
   mozilla::dom::CSSValue* DoGetOpacity();
   mozilla::dom::CSSValue* DoGetPointerEvents();
   mozilla::dom::CSSValue* DoGetVisibility();
+  mozilla::dom::CSSValue* DoGetWritingMode();
 
   /* Direction properties */
   mozilla::dom::CSSValue* DoGetDirection();
   mozilla::dom::CSSValue* DoGetUnicodeBidi();
 
   /* Display properties */
   mozilla::dom::CSSValue* DoGetBinding();
   mozilla::dom::CSSValue* DoGetClear();
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -5238,16 +5238,22 @@ nsRuleNode::ComputeVisibilityData(void* 
               NS_STYLE_VISIBILITY_VISIBLE, 0, 0, 0, 0);
 
   // pointer-events: enum, inherit, initial
   SetDiscrete(*aRuleData->ValueForPointerEvents(), visibility->mPointerEvents,
               canStoreInRuleTree,
               SETDSC_ENUMERATED, parentVisibility->mPointerEvents,
               NS_STYLE_POINTER_EVENTS_AUTO, 0, 0, 0, 0);
 
+  // writing-mode: enum, inherit, initial
+  SetDiscrete(*aRuleData->ValueForWritingMode(), visibility->mWritingMode,
+              canStoreInRuleTree, SETDSC_ENUMERATED,
+              parentVisibility->mWritingMode,
+              NS_STYLE_WRITING_MODE_HORIZONTAL_TB, 0, 0, 0, 0);
+
   COMPUTE_END_INHERITED(Visibility, visibility)
 }
 
 const void*
 nsRuleNode::ComputeColorData(void* aStartStruct,
                              const nsRuleData* aRuleData,
                              nsStyleContext* aContext,
                              nsRuleNode* aHighestNode,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2300,31 +2300,33 @@ nsStyleVisibility::nsStyleVisibility(nsP
   uint32_t bidiOptions = aPresContext->GetBidi();
   if (GET_BIDI_OPTION_DIRECTION(bidiOptions) == IBMBIDI_TEXTDIRECTION_RTL)
     mDirection = NS_STYLE_DIRECTION_RTL;
   else
     mDirection = NS_STYLE_DIRECTION_LTR;
 
   mVisible = NS_STYLE_VISIBILITY_VISIBLE;
   mPointerEvents = NS_STYLE_POINTER_EVENTS_AUTO;
+  mWritingMode = NS_STYLE_WRITING_MODE_HORIZONTAL_TB;
 }
 
 nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
 {
   MOZ_COUNT_CTOR(nsStyleVisibility);
   mDirection = aSource.mDirection;
   mVisible = aSource.mVisible;
   mPointerEvents = aSource.mPointerEvents;
+  mWritingMode = aSource.mWritingMode;
 } 
 
 nsChangeHint nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
 {
   nsChangeHint hint = nsChangeHint(0);
 
-  if (mDirection != aOther.mDirection) {
+  if (mDirection != aOther.mDirection || mWritingMode != aOther.mWritingMode) {
     NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
   } else {
     if (mVisible != aOther.mVisible) {
       if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
           (NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible)) {
         NS_UpdateHint(hint, NS_STYLE_HINT_REFLOW);
       } else {
         NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1365,16 +1365,17 @@ struct nsStyleVisibility {
   nsChangeHint CalcDifference(const nsStyleVisibility& aOther) const;
   static nsChangeHint MaxDifference() {
     return NS_STYLE_HINT_FRAMECHANGE;
   }
 
   uint8_t mDirection;                  // [inherited] see nsStyleConsts.h NS_STYLE_DIRECTION_*
   uint8_t mVisible;                    // [inherited]
   uint8_t mPointerEvents;              // [inherited] see nsStyleConsts.h
+  uint8_t mWritingMode;                // [inherited] see nsStyleConsts.h
 
   bool IsVisible() const {
     return (mVisible == NS_STYLE_VISIBILITY_VISIBLE);
   }
 
   bool IsVisibleOrCollapsed() const {
     return ((mVisible == NS_STYLE_VISIBILITY_VISIBLE) ||
             (mVisible == NS_STYLE_VISIBILITY_COLLAPSE));
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -4252,16 +4252,32 @@ if (SpecialPowers.getBoolPref("layout.cs
 	};
 	for (var prop in flexProperties) {
 		gCSSProperties[prop] = flexProperties[prop];
 	}
 	gCSSProperties["display"].other_values.push("flex");
 	gCSSProperties["display"].other_values.push("inline-flex");
 }
 
+if (SpecialPowers.getBoolPref("layout.css.vertical-text.enabled")) {
+	var verticalTextProperties = {
+		"writing-mode": {
+			domProp: "writingMode",
+			inherited: true,
+			type: CSS_TYPE_LONGHAND,
+			initial_values: [ "horizontal-tb" ],
+			other_values: [ "vertical-lr", "vertical-rl" ],
+			invalid_values: [ "10px", "30%", "justify", "auto", "1em" ]
+		}
+	};
+	for (var prop in verticalTextProperties) {
+		gCSSProperties[prop] = verticalTextProperties[prop];
+	}
+}
+
 if (SpecialPowers.getBoolPref("layout.css.font-features.enabled")) {
 	var fontFeatureProperties = {
 		"font-kerning": {
 			domProp: "fontKerning",
 			inherited: true,
 			type: CSS_TYPE_LONGHAND,
 			initial_values: [ "auto" ],
 			other_values: [ "normal", "none" ],
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1767,16 +1767,19 @@ pref("layout.css.prefixes.animations", t
 
 // Is support for the :scope selector enabled?
 #ifdef RELEASE_BUILD
 pref("layout.css.scope-pseudo.enabled", false);
 #else
 pref("layout.css.scope-pseudo.enabled", true);
 #endif
 
+// Is support for CSS vertical text enabled?
+pref("layout.css.vertical-text.enabled", false);
+
 // pref for which side vertical scrollbars should be on
 // 0 = end-side in UI direction
 // 1 = end-side in document/content direction
 // 2 = right
 // 3 = left
 pref("layout.scrollbar.side", 0);
 
 // pref to control browser frame rate, in Hz. A value <= 0 means choose