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 draft
authorYusuf Sermet <ysermet@mozilla.com>
Tue, 05 Jun 2018 15:32:40 -0700
changeset 805559 6772555b5342
parent 805456 3c73973bd637
child 806785 89621cbb333a
push id112694
push userbmo:ysermet@mozilla.com
push dateThu, 07 Jun 2018 23:32:15 +0000
reviewersdholbert
bugs1465936
milestone62.0a1
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
@@ -2382,17 +2382,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 {
@@ -2410,39 +2414,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 ||