Bug 1098275 - Inlinize block-level boxes inside ruby. r=heycam
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 11 Dec 2014 09:26:18 +1100
changeset 219872 f291ce1eacd0b14ecccd22219be950276e1ca5ec
parent 219871 da727b086b56522e59ad2e54ef1852e1d287a313
child 219873 1472cc0c85b2694fa1d035996ec555c92ba1a0dc
push id10419
push usercbook@mozilla.com
push dateTue, 16 Dec 2014 12:45:27 +0000
treeherderfx-team@ec87657146eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1098275
milestone37.0a1
Bug 1098275 - Inlinize block-level boxes inside ruby. r=heycam
layout/base/RestyleManager.cpp
layout/style/nsStyleContext.cpp
layout/style/nsStyleContext.h
layout/style/nsStyleStruct.h
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -2899,16 +2899,23 @@ ElementRestyler::ComputeRestyleResultFro
 
   if (oldContext->HasPseudoElementData() !=
         aNewContext->HasPseudoElementData()) {
     LOG_RESTYLE_CONTINUE("NS_STYLE_HAS_PSEUDO_ELEMENT_DATA differs between old"
                          " and new style contexts");
     return eRestyleResult_Continue;
   }
 
+  if (oldContext->IsDirectlyInsideRuby() !=
+        aNewContext->IsDirectlyInsideRuby()) {
+    LOG_RESTYLE_CONTINUE("NS_STYLE_IS_DIRECTLY_INSIDE_RUBY differes between old"
+                         " and new style contexts");
+    return eRestyleResult_Continue;
+  }
+
   return eRestyleResult_Stop;
 }
 
 ElementRestyler::RestyleResult
 ElementRestyler::RestyleSelf(nsIFrame* aSelf,
                              nsRestyleHint aRestyleHint,
                              uint32_t* aSwappedStructs)
 {
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -502,18 +502,18 @@ nsStyleContext::ApplyStyleFixups(bool aS
     }
   }
 
   // Adjust the "display" values of flex and grid items (but not for raw text,
   // placeholders, or table-parts). CSS3 Flexbox section 4 says:
   //   # The computed 'display' of a flex item is determined
   //   # by applying the table in CSS 2.1 Chapter 9.7.
   // ...which converts inline-level elements to their block-level equivalents.
-  // Any direct children of elements with Ruby display values which are
-  // block-level are converted to their inline-level equivalents.
+  // Any block-level element directly contained by elements with ruby display
+  // values are converted to their inline-level equivalents.
   if (!aSkipParentDisplayBasedStyleFixup && mParent) {
     // Skip display:contents ancestors to reach the potential container.
     // (If there are only display:contents ancestors between this node and
     // a flex/grid container ancestor, then this node is a flex/grid item, since
     // its parent *in the frame tree* will be the flex/grid container. So we treat
     // it like a flex/grid item here.)
     nsStyleContext* containerContext = mParent;
     const nsStyleDisplay* containerDisp = containerContext->StyleDisplay();
@@ -553,22 +553,27 @@ nsStyleContext::ApplyStyleFixups(bool aS
                        "We shouldn't be changing the display value of "
                        "positioned content (and we should have already "
                        "converted its display value to be block-level...)");
           nsStyleDisplay *mutable_display =
             static_cast<nsStyleDisplay*>(GetUniqueStyleData(eStyleStruct_Display));
           mutable_display->mDisplay = displayVal;
         }
       }
-    } else if (containerDisp->IsRubyDisplayType()) {
+    }
+
+    // The display change should only occur for "in-flow" children
+    if (!disp->IsOutOfFlowStyle() &&
+        ((containerDisp->mDisplay == NS_STYLE_DISPLAY_INLINE &&
+          containerContext->IsDirectlyInsideRuby()) ||
+         containerDisp->IsRubyDisplayType())) {
+      mBits |= NS_STYLE_IS_DIRECTLY_INSIDE_RUBY;
       uint8_t displayVal = disp->mDisplay;
       nsRuleNode::EnsureInlineDisplay(displayVal);
-      // The display change should only occur for "in-flow" children
-      if (displayVal != disp->mDisplay && 
-          !disp->IsOutOfFlowStyle()) {
+      if (displayVal != disp->mDisplay) {
         nsStyleDisplay *mutable_display =
           static_cast<nsStyleDisplay*>(GetUniqueStyleData(eStyleStruct_Display));
         mutable_display->mDisplay = displayVal;
       }
     }
   }
 
   // Compute User Interface style, to trigger loads of cursors
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -125,16 +125,22 @@ public:
                      nsRuleNode* aRulesIfVisited,
                      bool aRelevantLinkVisited);
 
   // Does this style context or any of its ancestors have text
   // decoration lines?
   bool HasTextDecorationLines() const
     { return !!(mBits & NS_STYLE_HAS_TEXT_DECORATION_LINES); }
 
+  // Whether this style context or any of its inline-level ancestors
+  // is directly contained by a ruby box? It is used to inlinize
+  // block-level descendants and suppress line breaks inside ruby.
+  bool IsDirectlyInsideRuby() const
+    { return !!(mBits & NS_STYLE_IS_DIRECTLY_INSIDE_RUBY); }
+
   // Does this style context represent the style for a pseudo-element or
   // inherit data from such a style context?  Whether this returns true
   // is equivalent to whether it or any of its ancestors returns
   // non-null for GetPseudo.
   bool HasPseudoElementData() const
     { return !!(mBits & NS_STYLE_HAS_PSEUDO_ELEMENT_DATA); }
 
   // Is the only link whose visitedness is allowed to influence the
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -51,19 +51,20 @@ class imgIContainer;
 #define NS_STYLE_IS_STYLE_IF_VISITED       0x008000000
 // See nsStyleContext::UsesGrandancestorStyle
 #define NS_STYLE_USES_GRANDANCESTOR_STYLE  0x010000000
 // See nsStyleContext::IsShared
 #define NS_STYLE_IS_SHARED                 0x020000000
 // See nsStyleContext::AssertStructsNotUsedElsewhere
 // (This bit is currently only used in #ifdef DEBUG code.)
 #define NS_STYLE_IS_GOING_AWAY             0x040000000
+// See nsStyleContext::IsDirectlyInsideRuby
+#define NS_STYLE_IS_DIRECTLY_INSIDE_RUBY   0x080000000
 // See nsStyleContext::GetPseudoEnum
-#define NS_STYLE_CONTEXT_TYPE_MASK         0xf80000000
-#define NS_STYLE_CONTEXT_TYPE_SHIFT        31
+#define NS_STYLE_CONTEXT_TYPE_SHIFT        32
 
 // Additional bits for nsRuleNode's mDependentBits:
 #define NS_RULE_NODE_GC_MARK                0x02000000
 #define NS_RULE_NODE_USED_DIRECTLY          0x04000000
 #define NS_RULE_NODE_IS_IMPORTANT           0x08000000
 #define NS_RULE_NODE_LEVEL_MASK             0xf0000000
 #define NS_RULE_NODE_LEVEL_SHIFT            28