Bug 1465936 - Ignore contain:paint for elements without a principal box, internal table elements except table-cell, internal ruby elements, and non-atomic inlines. r=dholbert
☠☠ backed out by fc4a67d2aea5 ☠ ☠
authorYusuf Sermet <ysermet@mozilla.com>
Tue, 05 Jun 2018 15:32:40 -0700
changeset 422329 a2e4bbd59dc7
parent 422328 ffdeb96ca6d0
child 422330 0c800e84c991
push id65109
push userbtara@mozilla.com
push dateTue, 12 Jun 2018 04:18:12 +0000
treeherderautoland@a2e4bbd59dc7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1465936
milestone62.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 1465936 - Ignore contain:paint for elements without a principal box, internal table elements except table-cell, internal ruby elements, and non-atomic inlines. r=dholbert MozReview-Commit-ID: 3Y4clUkIe9O
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-internal-table-001-ref.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-internal-table-001a.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-internal-table-001b.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-no-principal-box-001-ref.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-no-principal-box-001.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-containing-block-001-ref.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-containing-block-001.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-stacking-and-clipping-001-ref.html
layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-stacking-and-clipping-001.html
layout/reftests/w3c-css/submitted/contain/reftest.list
layout/style/nsStyleStruct.h
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-internal-table-001-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS Reftest Reference</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <style>
+      tr {
+        z-index: 10;
+      }
+      th {
+        background-color: blue;
+        padding-left: 50px;
+      }
+      caption {
+        position: fixed;
+        background-color: yellow;
+        z-index: 2;
+      }
+    </style>
+  </head>
+  <body>
+    <table>
+      <caption>PASS</caption>
+      <tr>
+        <th>&emsp;</th>
+      </tr>
+    </table>
+  </body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-internal-table-001a.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS-contain test: paint containment on internal table elements except table-cell.</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-paint">
+    <link rel="match" href="contain-paint-ignored-cases-internal-table-001-ref.html">
+    <meta name="assert" content="Paint containment should not apply to internal table elements except table-cell. This test testes only the tr element, and confirms contain:paint does not create a stacking context.">
+    <style>
+      tr {
+        contain: paint;
+        z-index: 10;
+      }
+      th {
+        background-color: blue;
+        padding-left: 50px;
+      }
+      caption {
+        position: fixed;
+        background-color: yellow;
+        z-index: 2;
+      }
+    </style>
+  </head>
+  <body>
+    <table>
+      <caption>PASS</caption>
+      <tr>
+        <th>&emsp;</th>
+      </tr>
+    </table>
+  </body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-internal-table-001b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS-contain test: paint containment on internal table elements except table-cell.</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-paint">
+    <link rel="match" href="contain-paint-ignored-cases-internal-table-001-ref.html">
+    <meta name="assert" content="Paint containment should not apply to internal table elements except table-cell. This test testes only the tbody element, and confirms contain:paint does not create a stacking context.">
+    <style>
+      tbody {
+        contain: paint;
+        z-index: 10;
+      }
+      th {
+        background-color: blue;
+        padding-left: 50px;
+      }
+      caption {
+        position: fixed;
+        background-color: yellow;
+        z-index: 2;
+      }
+    </style>
+  </head>
+  <body>
+    <table>
+      <caption>PASS</caption>
+      <tbody>
+        <tr>
+          <th>&emsp;</th>
+        </tr>
+      </tbody>
+    </table>
+  </body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-no-principal-box-001-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Reftest Reference</title>
+  <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+  <style>
+    div {
+      position: relative;
+      width: 100px;
+    }
+    #div1,
+    #div3 {
+      background-color: #cfc;
+      height: 100px;
+    }
+    #div1 {
+      z-index: 5;
+    }
+    #div2 {
+      display: contents;
+      background-color: #fdd;
+      height: 100px;
+      top: -20px;
+    }
+    #div2_1 {
+      background-color: #ffc;
+      z-index: 6;
+      top: -10px;
+      height: 100px;
+    }
+    #div2_2 {
+      z-index: 3;
+      position: absolute;
+      top: -15px;
+      width: 40px;
+      height: 300px;
+      background-color: #ddf;
+    }
+    #div3 {
+      z-index: 2;
+      top: -50px;
+    }
+  </style>
+</head>
+<body>
+  <div id="div1"></div>
+
+  <div id="div2">
+    <div id="div2_1"></div>
+
+    <div id="div2_2"></div>
+  </div>
+
+  <div id="div3"></div>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-no-principal-box-001.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>CSS Test: 'contain: paint' with 'display: contents'.</title>
+  <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+  <link rel="help" href="https://drafts.csswg.org/css-contain/#containment-paint">
+  <link rel="match" href="contain-paint-ignored-cases-no-principal-box-001-ref.html">
+  <meta name="assert" content="Contain:paint should have no effect when no principle box is generated.">
+  <style>
+    div {
+      position: relative;
+      width: 100px;
+    }
+    #div1,
+    #div3 {
+      background-color: #cfc;
+      height: 100px;
+    }
+    #div1 {
+      z-index: 5;
+    }
+    #div2 {
+      display: contents;
+      contain: paint;
+      background-color: #fdd;
+      height: 100px;
+      top: -20px;
+    }
+    #div2_1 {
+      background-color: #ffc;
+      z-index: 6;
+      top: -10px;
+      height: 100px;
+    }
+    #div2_2 {
+      z-index: 3;
+      position: absolute;
+      top: -15px;
+      width: 40px;
+      height: 300px;
+      background-color: #ddf;
+    }
+    #div3 {
+      z-index: 2;
+      top: -50px;
+    }
+  </style>
+</head>
+<body>
+  <div id="div1"></div>
+
+  <div id="div2">
+    <div id="div2_1"></div>
+
+    <div id="div2_2"></div>
+  </div>
+
+  <div id="div3"></div>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-containing-block-001-ref.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html lang=en>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS Reftest Reference</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <style>
+      rb,
+      rbc,
+      rt,
+      rtc {
+        background-color: yellow;
+        font-size: 2em;
+      }
+      rbc {
+        display: ruby-base-container;
+      }
+      .contained {
+        width: 50px;
+        height: 10px;
+        background-color: blue;
+        top: 0;
+        left: 0;
+        position: fixed;
+      }
+      .wrapper {
+        display: inline-block;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="wrapper"><ruby><rt>&emsp;<div class="contained"></div></rt></ruby></div>
+    <div class="wrapper"><ruby><rtc>&emsp;<div class="contained"></div></rtc></ruby></div>
+    <div class="wrapper"><ruby><rb>&emsp;<div class="contained"></div></rb></ruby></div>
+    <div class="wrapper"><ruby><rbc>&emsp;<div class="contained"></div></rbc></ruby></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-containing-block-001.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang=en>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS-contain test: paint containment on internal ruby elements.</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-paint">
+    <link rel="match" href="contain-paint-ignored-cases-ruby-containing-block-001-ref.html">
+    <meta name="assert" content="Paint containment should not apply to ruby base, ruby base container, ruby text, and ruby text container. This test confirms contain:paint does not act as a containing block for fixed positioned descendants.">
+    <style>
+      rb,
+      rbc,
+      rt,
+      rtc {
+        contain: paint;
+        background-color: yellow;
+        font-size: 2em;
+      }
+      rbc {
+        display: ruby-base-container;
+      }
+      .contained {
+        width: 50px;
+        height: 10px;
+        background-color: blue;
+        top: 0;
+        left: 0;
+        position: fixed;
+      }
+      .wrapper {
+        display: inline-block;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="wrapper"><ruby><rt>&emsp;<div class="contained"></div></rt></ruby></div>
+    <div class="wrapper"><ruby><rtc>&emsp;<div class="contained"></div></rtc></ruby></div>
+    <div class="wrapper"><ruby><rb>&emsp;<div class="contained"></div></rb></ruby></div>
+    <div class="wrapper"><ruby><rbc>&emsp;<div class="contained"></div></rbc></ruby></div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-stacking-and-clipping-001-ref.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html lang=en>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS Reftest Reference</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <style>
+      div {
+        position: relative;
+      }
+      rbc {
+        display: ruby-base-container;
+      }
+      .contained {
+        z-index: 5;
+        width: 70px;
+        height: 10px;
+        background-color: blue;
+        margin-left: -25px;
+      }
+      .background {
+        display: inline-block;
+        background-color: yellow;
+        height: 50px;
+        width: 50px;
+        position: fixed;
+        z-index: 2;
+      }
+      .group {
+        display: inline-block;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rb>&emsp;<div class="contained"></div></rb></ruby>
+    </div>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rbc>&emsp;<div class="contained"></div></rbc></ruby>
+    </div>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rt>&emsp;<div class="contained"></div></rt></ruby>
+    </div>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rtc>&emsp;<div class="contained"></div></rtc></ruby>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/contain/contain-paint-ignored-cases-ruby-stacking-and-clipping-001.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<html lang=en>
+  <head>
+    <meta charset=utf-8>
+    <title>CSS-contain test: paint containment on internal ruby elements.</title>
+    <link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
+    <link rel="help" href="http://www.w3.org/TR/css-containment-1/#containment-paint">
+    <link rel="match" href="contain-paint-ignored-cases-ruby-stacking-and-clipping-001-ref.html">
+    <meta name="assert" content="Paint containment should not apply to ruby base, ruby base container, ruby text, and ruby text container. This test confirms that contain:paint does not create a stacking context and does not apply overflow clipping.">
+    <style>
+      div {
+        position: relative;
+      }
+      rb,
+      rbc,
+      rt,
+      rtc {
+        contain: paint;
+      }
+      rbc {
+        display: ruby-base-container;
+      }
+      .contained {
+        z-index: 5;
+        width: 70px;
+        height: 10px;
+        background-color: blue;
+        margin-left: -25px;
+      }
+      .background {
+        background-color: yellow;
+        height: 50px;
+        width: 50px;
+        position: fixed;
+        z-index: 2;
+      }
+      .group {
+        display: inline-block;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rb>&emsp;<div class="contained"></div></rb></ruby>
+    </div>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rbc>&emsp;<div class="contained"></div></rbc></ruby>
+    </div>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rt>&emsp;<div class="contained"></div></rt></ruby>
+    </div>
+    <div class="group">
+      <div class="background"></div>
+      <ruby><rtc>&emsp;<div class="contained"></div></rtc></ruby>
+    </div>
+  </body>
+</html>
--- a/layout/reftests/w3c-css/submitted/contain/reftest.list
+++ b/layout/reftests/w3c-css/submitted/contain/reftest.list
@@ -5,10 +5,15 @@ default-preferences pref(layout.css.cont
 == contain-paint-clip-003.html contain-paint-clip-003-ref.html
 == contain-paint-clip-004.html contain-paint-clip-004-ref.html
 == contain-paint-clip-005.html contain-paint-clip-003-ref.html
 pref(layout.css.overflow-clip-box.enabled,true) == contain-paint-clip-006.html contain-paint-clip-006-ref.html
 == contain-paint-containing-block-absolute-001.html contain-paint-containing-block-absolute-001-ref.html
 == contain-paint-containing-block-fixed-001.html contain-paint-containing-block-fixed-001-ref.html
 == contain-paint-formatting-context-float-001.html contain-paint-formatting-context-float-001-ref.html
 == contain-paint-formatting-context-margin-001.html contain-paint-formatting-context-margin-001-ref.html
+== contain-paint-ignored-cases-internal-table-001a.html contain-paint-ignored-cases-internal-table-001-ref.html
+== contain-paint-ignored-cases-internal-table-001b.html contain-paint-ignored-cases-internal-table-001-ref.html
+== contain-paint-ignored-cases-no-principal-box-001.html contain-paint-ignored-cases-no-principal-box-001-ref.html
+== contain-paint-ignored-cases-ruby-containing-block-001.html contain-paint-ignored-cases-ruby-containing-block-001-ref.html
+== contain-paint-ignored-cases-ruby-stacking-and-clipping-001.html contain-paint-ignored-cases-ruby-stacking-and-clipping-001-ref.html
 == contain-paint-stacking-context-001a.html contain-paint-stacking-context-001-ref.html
 == contain-paint-stacking-context-001b.html contain-paint-stacking-context-001-ref.html
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2371,17 +2371,21 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
 
   bool IsOriginalDisplayInlineOutsideStyle() const {
     return IsDisplayTypeInlineOutside(mOriginalDisplay);
   }
 
   bool IsInnerTableStyle() const {
     return mozilla::StyleDisplay::TableCaption == mDisplay ||
            mozilla::StyleDisplay::TableCell == mDisplay ||
-           mozilla::StyleDisplay::TableRow == mDisplay ||
+           IsInternalTableStyleExceptCell();
+  }
+
+  bool IsInternalTableStyleExceptCell() const {
+    return mozilla::StyleDisplay::TableRow == mDisplay ||
            mozilla::StyleDisplay::TableRowGroup == mDisplay ||
            mozilla::StyleDisplay::TableHeaderGroup == mDisplay ||
            mozilla::StyleDisplay::TableFooterGroup == mDisplay ||
            mozilla::StyleDisplay::TableColumn == mDisplay ||
            mozilla::StyleDisplay::TableColumnGroup == mDisplay;
   }
 
   bool IsFloatingStyle() const {
@@ -2399,39 +2403,49 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   }
   bool IsPositionForcingStackingContext() const {
     return NS_STYLE_POSITION_STICKY == mPosition ||
            NS_STYLE_POSITION_FIXED == mPosition;
   }
 
   static bool IsRubyDisplayType(mozilla::StyleDisplay aDisplay) {
     return mozilla::StyleDisplay::Ruby == aDisplay ||
-           mozilla::StyleDisplay::RubyBase == aDisplay ||
+           IsInternalRubyDisplayType(aDisplay);
+  }
+
+  static bool IsInternalRubyDisplayType(mozilla::StyleDisplay aDisplay) {
+    return mozilla::StyleDisplay::RubyBase == aDisplay ||
            mozilla::StyleDisplay::RubyBaseContainer == aDisplay ||
            mozilla::StyleDisplay::RubyText == aDisplay ||
            mozilla::StyleDisplay::RubyTextContainer == aDisplay;
   }
 
   bool IsRubyDisplayType() const {
     return IsRubyDisplayType(mDisplay);
   }
 
+  bool IsInternalRubyDisplayType() const {
+    return IsInternalRubyDisplayType(mDisplay);
+  }
+
   bool IsOutOfFlowStyle() const {
     return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
   }
 
   bool IsScrollableOverflow() const {
     // mOverflowX and mOverflowY always match when one of them is
     // NS_STYLE_OVERFLOW_VISIBLE or NS_STYLE_OVERFLOW_CLIP.
     return mOverflowX != NS_STYLE_OVERFLOW_VISIBLE &&
            mOverflowX != NS_STYLE_OVERFLOW_CLIP;
   }
 
   bool IsContainPaint() const {
-    return NS_STYLE_CONTAIN_PAINT & mContain;
+    return (NS_STYLE_CONTAIN_PAINT & mContain) &&
+           !IsInternalRubyDisplayType() &&
+           !IsInternalTableStyleExceptCell();
   }
 
   /* Returns whether the element has the -moz-transform property
    * or a related property. */
   bool HasTransformStyle() const {
     return mSpecifiedTransform || mSpecifiedRotate || mSpecifiedTranslate ||
            mSpecifiedScale ||
            mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||