Bug 907396 - Style system support for display:contents. r=dbaron
authorMats Palmgren <matspal@gmail.com>
Thu, 20 Nov 2014 18:24:08 +0000
changeset 216686 ff8c07f86822e54335838081fb728ffb32e12192
parent 216685 f39fc9dc4c0d8a3565116a1b4e6852f80f9a397c
child 216687 39bd6adc47edf1014ab5d066f3293fe4e7640375
push id52125
push usermpalmgren@mozilla.com
push dateThu, 20 Nov 2014 18:24:21 +0000
treeherdermozilla-inbound@1a4bb406f950 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs907396
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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);