Bug 907396 - Style system support for display:contents. r=dbaron
authorMats Palmgren <matspal@gmail.com>
Thu, 20 Nov 2014 18:24:08 +0000
changeset 232900 ff8c07f86822e54335838081fb728ffb32e12192
parent 232899 f39fc9dc4c0d8a3565116a1b4e6852f80f9a397c
child 232901 39bd6adc47edf1014ab5d066f3293fe4e7640375
push id7326
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:58:42 +0000
treeherdermozilla-aurora@d3a3b2a0f2f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs907396
milestone36.0a1
Bug 907396 - Style system support for display:contents. r=dbaron
layout/style/nsCSSKeywordList.h
layout/style/nsCSSProps.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleConsts.h
layout/style/nsStyleStruct.h
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -190,16 +190,17 @@ CSS_KEY(color, color)
 CSS_KEY(color-burn, color_burn)
 CSS_KEY(color-dodge, color_dodge)
 CSS_KEY(common-ligatures, common_ligatures)
 CSS_KEY(column, column)
 CSS_KEY(column-reverse, column_reverse)
 CSS_KEY(condensed, condensed)
 CSS_KEY(contain, contain)
 CSS_KEY(content-box, content_box)
+CSS_KEY(contents, contents)
 CSS_KEY(context-fill, context_fill)
 CSS_KEY(context-fill-opacity, context_fill_opacity)
 CSS_KEY(context-menu, context_menu)
 CSS_KEY(context-stroke, context_stroke)
 CSS_KEY(context-stroke-opacity, context_stroke_opacity)
 CSS_KEY(context-value, context_value)
 CSS_KEY(continuous, continuous)
 CSS_KEY(contrast, contrast)
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1115,16 +1115,19 @@ KTableValue nsCSSProps::kDisplayKTable[]
   eCSSKeyword_grid,                NS_STYLE_DISPLAY_GRID,
   eCSSKeyword_inline_grid,         NS_STYLE_DISPLAY_INLINE_GRID,
   // The next five entries are controlled by the layout.css.ruby.enabled pref.
   eCSSKeyword_ruby,                NS_STYLE_DISPLAY_RUBY,
   eCSSKeyword_ruby_base,           NS_STYLE_DISPLAY_RUBY_BASE,
   eCSSKeyword_ruby_base_container, NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER,
   eCSSKeyword_ruby_text,           NS_STYLE_DISPLAY_RUBY_TEXT,
   eCSSKeyword_ruby_text_container, NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER,
+  // The next entry is controlled by the layout.css.display-contents.enabled
+  // pref.
+  eCSSKeyword_contents,            NS_STYLE_DISPLAY_CONTENTS,
   eCSSKeyword_UNKNOWN,-1
 };
 
 const KTableValue nsCSSProps::kEmptyCellsKTable[] = {
   eCSSKeyword_show,                 NS_STYLE_TABLE_EMPTY_CELLS_SHOW,
   eCSSKeyword_hide,                 NS_STYLE_TABLE_EMPTY_CELLS_HIDE,
   eCSSKeyword__moz_show_background, NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND,
   eCSSKeyword_UNKNOWN,-1
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -121,16 +121,17 @@ nsRuleNode::ChildrenHashOps = {
   PL_DHashMoveEntryStub,
   PL_DHashClearEntryStub,
   PL_DHashFinalizeStub,
   nullptr
 };
 
 
 // EnsureBlockDisplay:
+// Never change display:none or display:contents *ever*, otherwise:
 //  - if the display value (argument) is not a block-type
 //    then we set it to a valid block display value
 //  - For enforcing the floated/positioned element CSS2 rules
 //  - We allow the behavior of "list-item" to be customized.
 //    CSS21 says that position/float do not convert 'list-item' to 'block',
 //    but it explicitly does not define whether 'list-item' should be
 //    converted to block *on the root node*. To allow for flexibility
 //    (so that we don't have to support a list-item root node), this method
@@ -144,17 +145,18 @@ nsRuleNode::EnsureBlockDisplay(uint8_t& 
   // see if the display value is already a block
   switch (display) {
   case NS_STYLE_DISPLAY_LIST_ITEM :
     if (aConvertListItem) {
       display = NS_STYLE_DISPLAY_BLOCK;
       break;
     } // else, fall through to share the 'break' for non-changing display vals
   case NS_STYLE_DISPLAY_NONE :
-    // never change display:none *ever*
+  case NS_STYLE_DISPLAY_CONTENTS :
+    // never change display:none or display:contents *ever*
   case NS_STYLE_DISPLAY_TABLE :
   case NS_STYLE_DISPLAY_BLOCK :
   case NS_STYLE_DISPLAY_FLEX :
   case NS_STYLE_DISPLAY_GRID :
     // do not muck with these at all - already blocks
     // This is equivalent to nsStyleDisplay::IsBlockOutside.  (XXX Maybe we
     // should just call that?)
     // This needs to match the check done in
@@ -5554,17 +5556,32 @@ nsRuleNode::ComputeDisplayData(void* aSt
     NS_ABORT_IF_FALSE(false, "unrecognized clip unit");
   }
 
   if (display->mDisplay != NS_STYLE_DISPLAY_NONE) {
     // CSS2 9.7 specifies display type corrections dealing with 'float'
     // and 'position'.  Since generated content can't be floated or
     // positioned, we can deal with it here.
 
-    if (nsCSSPseudoElements::firstLetter == aContext->GetPseudo()) {
+    nsIAtom* pseudo = aContext->GetPseudo();
+    if (pseudo && display->mDisplay == NS_STYLE_DISPLAY_CONTENTS) {
+      // We don't want to create frames for anonymous content using a parent
+      // frame that is for content above the root of the anon tree.
+      // (XXX what we really should check here is not GetPseudo() but if there's
+      //  a 'content' property value that implies anon content but we can't
+      //  check that here since that's a different struct(?))
+      // We might get display:contents to work for CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS
+      // pseudos (:first-letter etc) in the future, but those have a lot of
+      // special handling in frame construction so they are also unsupported
+      // for now.
+      display->mOriginalDisplay = display->mDisplay = NS_STYLE_DISPLAY_INLINE;
+      canStoreInRuleTree = false;
+    }
+
+    if (nsCSSPseudoElements::firstLetter == pseudo) {
       // a non-floating first-letter must be inline
       // XXX this fix can go away once bug 103189 is fixed correctly
       // Note that we reset mOriginalDisplay to enforce the invariant that it equals mDisplay if we're not positioned or floating.
       display->mOriginalDisplay = display->mDisplay = NS_STYLE_DISPLAY_INLINE;
 
       // We can't cache the data in the rule tree since if a more specific
       // rule has 'float: left' we'll end up with the wrong 'display'
       // property.
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -438,16 +438,17 @@ static inline mozilla::css::Side operato
 #define NS_STYLE_DISPLAY_INLINE_FLEX            30
 #define NS_STYLE_DISPLAY_GRID                   31
 #define NS_STYLE_DISPLAY_INLINE_GRID            32
 #define NS_STYLE_DISPLAY_RUBY                   33
 #define NS_STYLE_DISPLAY_RUBY_BASE              34
 #define NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER    35
 #define NS_STYLE_DISPLAY_RUBY_TEXT              36
 #define NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER    37
+#define NS_STYLE_DISPLAY_CONTENTS               38
 
 // See nsStylePosition
 #define NS_STYLE_ALIGN_CONTENT_FLEX_START       0
 #define NS_STYLE_ALIGN_CONTENT_FLEX_END         1
 #define NS_STYLE_ALIGN_CONTENT_CENTER           2
 #define NS_STYLE_ALIGN_CONTENT_SPACE_BETWEEN    3
 #define NS_STYLE_ALIGN_CONTENT_SPACE_AROUND     4
 #define NS_STYLE_ALIGN_CONTENT_STRETCH          5
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2096,17 +2096,18 @@ struct nsStyleDisplay {
            NS_STYLE_DISPLAY_INLINE_FLEX == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_GRID == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_XUL_GRID == aDisplay ||
            NS_STYLE_DISPLAY_INLINE_STACK == aDisplay ||
            NS_STYLE_DISPLAY_RUBY == aDisplay ||
            NS_STYLE_DISPLAY_RUBY_BASE == aDisplay ||
            NS_STYLE_DISPLAY_RUBY_BASE_CONTAINER == aDisplay ||
            NS_STYLE_DISPLAY_RUBY_TEXT == aDisplay ||
-           NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER == aDisplay;
+           NS_STYLE_DISPLAY_RUBY_TEXT_CONTAINER == aDisplay ||
+           NS_STYLE_DISPLAY_CONTENTS == aDisplay;
   }
 
   bool IsInlineOutsideStyle() const {
     return IsDisplayTypeInlineOutside(mDisplay);
   }
 
   bool IsOriginalDisplayInlineOutsideStyle() const {
     return IsDisplayTypeInlineOutside(mOriginalDisplay);