Bug 1140198 - display:contents on the root element (but not else-where) should compute to 'block'. r=roc
authorMats Palmgren <mats@mozilla.com>
Sat, 07 Mar 2015 14:35:02 +0000
changeset 232389 aa19896bead798fbad8a772e347f3c237d8f062c
parent 232388 27ac269bb796b25a45d35708af40ef8eaa0c5618
child 232390 a3053a836a09a719bceac3d8ffe3f9e866e2c436
push id56535
push usermpalmgren@mozilla.com
push dateSat, 07 Mar 2015 14:35:24 +0000
treeherdermozilla-inbound@aa19896bead7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1140198
milestone39.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 1140198 - display:contents on the root element (but not else-where) should compute to 'block'. r=roc
layout/base/crashtests/1140198.html
layout/base/crashtests/crashtests.list
layout/base/nsCSSFrameConstructor.cpp
layout/style/nsStyleContext.cpp
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/1140198.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+  document.documentElement.style.display = "contents";
+  document.designMode = 'on';
+  document.documentElement.insertAdjacentHTML("beforeEnd", "<span><optgroup>");
+}
+
+</script>
+</head>
+<body onload="boom();"></body>
+</html>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -453,8 +453,9 @@ load 935765-1.html
 load 942690.html
 load 973390-1.html
 load 1001237.html
 load 1043163-1.html
 load 1061028.html
 load 1116104.html
 load 1107508-1.html
 load 1127198-1.html
+load 1140198.html
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2593,18 +2593,17 @@ nsCSSFrameConstructor::ConstructDocEleme
     // if the document is a table then just populate it.
     contentFrame = static_cast<nsContainerFrame*>(
       ConstructTable(state, item, mDocElementContainingBlock,
                      styleContext->StyleDisplay(),
                      frameItems));
     newFrame = frameItems.FirstChild();
     NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
   } else {
-    MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK ||
-               display->mDisplay == NS_STYLE_DISPLAY_CONTENTS,
+    MOZ_ASSERT(display->mDisplay == NS_STYLE_DISPLAY_BLOCK,
                "Unhandled display type for root element");
     contentFrame = NS_NewBlockFormattingContext(mPresShell, styleContext);
     nsFrameItems frameItems;
     // Use a null PendingBinding, since our binding is not in fact pending.
     ConstructBlock(state, display, aDocElement,
                    state.GetGeometricParent(display,
                                             mDocElementContainingBlock),
                    mDocElementContainingBlock, styleContext,
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -557,17 +557,24 @@ nsStyleContext::ApplyStyleFixups(bool aS
   // the root element.  We can't implement them in nsRuleNode because we
   // don't want to store all display structs that aren't 'block',
   // 'inline', or 'table' in the style context tree on the off chance
   // that the root element has its style reresolved later.  So do them
   // here if needed, by changing the style data, so that other code
   // doesn't get confused by looking at the style data.
   if (!mParent) {
     uint8_t displayVal = disp->mDisplay;
-    nsRuleNode::EnsureBlockDisplay(displayVal, true);
+    if (displayVal != NS_STYLE_DISPLAY_CONTENTS) {
+      nsRuleNode::EnsureBlockDisplay(displayVal, true);
+    } else {
+      // http://dev.w3.org/csswg/css-display/#transformations
+      // "... a display-outside of 'contents' computes to block-level
+      //  on the root element."
+      displayVal = NS_STYLE_DISPLAY_BLOCK;
+    }
     if (displayVal != disp->mDisplay) {
       nsStyleDisplay *mutable_display =
         static_cast<nsStyleDisplay*>(GetUniqueStyleData(eStyleStruct_Display));
 
       // If we're in this code, then mOriginalDisplay doesn't matter
       // for purposes of the cascade (because this nsStyleDisplay
       // isn't living in the ruletree anyway), and for determining
       // hypothetical boxes it's better to have mOriginalDisplay