Bug 1479859 patch 4 - Test becoming a containing block for contain:paint only for those frames that support it. r=dholbert
authorL. David Baron <dbaron@dbaron.org>
Tue, 07 Aug 2018 15:02:08 -0700
changeset 430494 6897f3935cc77f531ce4b1ac5f5b6febdb010c58
parent 430493 8e24328ba71484dd144b9d0d2fdd287a9327c1b4
child 430495 c629114f55f0c9120f58e4fb2747d4ac96464bef
push id34406
push userncsoregi@mozilla.com
push dateWed, 08 Aug 2018 09:58:58 +0000
treeherdermozilla-central@17116905bc07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1479859
milestone63.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 1479859 patch 4 - Test becoming a containing block for contain:paint only for those frames that support it. r=dholbert This fixes the regression of three web-platform-test reftests: testing/web-platform/tests/css/css-contain/contain-paint-002.html testing/web-platform/tests/css/css-contain/contain-paint-011.html testing/web-platform/tests/css/css-contain/contain-paint-012.html that was caused by patch 1, but it's written on top of the code in patches 2 and 3 so it's easier to fix afterwards. Differential Revision: https://phabricator.services.mozilla.com/D2812
layout/style/ComputedStyle.cpp
layout/style/nsStyleStruct.h
layout/style/nsStyleStructInlines.h
--- a/layout/style/ComputedStyle.cpp
+++ b/layout/style/ComputedStyle.cpp
@@ -247,17 +247,30 @@ ComputedStyle::CalcStyleDifference(Compu
         (isFixedCB =
            oldDisp->IsFixedPosContainingBlockForNonSVGTextFrames(*this)) ==
         newDisp->IsFixedPosContainingBlockForNonSVGTextFrames(*aNewContext) &&
         // transform-supporting frames are a subcategory of non-SVG-text
         // frames, so no need to test this if isFixedCB is true (both
         // before and after the change)
         (isFixedCB ||
          oldDisp->IsFixedPosContainingBlockForTransformSupportingFrames() ==
-         newDisp->IsFixedPosContainingBlockForTransformSupportingFrames())) {
+         newDisp->IsFixedPosContainingBlockForTransformSupportingFrames()) &&
+        // contain-layout-and-paint-supporting frames are a subset of
+        // non-SVG-text frames, so no need to test this if isFixedCB is true
+        // (both before and after the change).
+        //
+        // Note, however, that neither of these last two sets is a
+        // subset of the other, because table frames support contain:
+        // layout/paint but not transforms (which are instead inherited
+        // to the table wrapper), and quite a few frame types support
+        // transforms but not contain: layout/paint (e.g., table rows
+        // and row groups, many SVG frames).
+        (isFixedCB ||
+         oldDisp->IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() ==
+         newDisp->IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames())) {
       // While some styles that cause the frame to be a containing block
       // has changed, the overall result cannot have changed (no matter
       // what the frame type is).
       hint &= ~nsChangeHint_UpdateContainingBlock;
     }
   }
 
   MOZ_ASSERT(NS_IsHintSubset(hint, nsChangeHint_AllHints),
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2435,23 +2435,27 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
    * aContextFrame is the frame for which this is the nsStyleDisplay.
    */
   inline bool IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const;
 
   /**
    * Tests for only the sub-parts of IsFixedPosContainingBlock that apply
    * to:
    *  - nearly all frames, except those that are SVG text frames.
+   *  - frames that support CSS contain:layout and contain:paint and are not
+   *    SVG text frames.
    *  - frames that support CSS transforms and are not SVG text frames.
    *
    * This should be used only when the caller has the style but not the
    * frame (i.e., when calculating style changes).
    */
   inline bool IsFixedPosContainingBlockForNonSVGTextFrames(
     mozilla::ComputedStyle&) const;
+  inline bool
+    IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const;
   inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const;
 
   /**
    * Returns the final combined transform.
    **/
   already_AddRefed<nsCSSValueSharedList> GetCombinedTransform() const {
     if (mCombinedTransform) {
       return do_AddRef(mCombinedTransform);
--- a/layout/style/nsStyleStructInlines.h
+++ b/layout/style/nsStyleStructInlines.h
@@ -156,44 +156,50 @@ nsStyleDisplay::HasPerspective(const nsI
 bool
 nsStyleDisplay::IsFixedPosContainingBlockForNonSVGTextFrames(
   mozilla::ComputedStyle& aStyle) const
 {
   // NOTE: Any CSS properties that influence the output of this function
   // should have the FIXPOS_CB flag set on them.
   NS_ASSERTION(aStyle.ThreadsafeStyleDisplay() == this, "unexpected aStyle");
 
-  if (IsContainPaint()) {
-    return true;
-  }
-
   if (mWillChangeBitField & NS_STYLE_WILL_CHANGE_FIXPOS_CB) {
     return true;
   }
 
   return aStyle.ThreadsafeStyleEffects()->HasFilters();
 }
 
 bool
+nsStyleDisplay::IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const
+{
+  // FIXME (bug 1472919): 'contain: layout' should also establish a
+  // containing block for fixed and absolute positioned elements.
+  return IsContainPaint();
+}
+
+bool
 nsStyleDisplay::IsFixedPosContainingBlockForTransformSupportingFrames() const
 {
   // NOTE: Any CSS properties that influence the output of this function
   // should have the FIXPOS_CB flag set on them.
   return HasTransformStyle() || HasPerspectiveStyle();
 }
 
 bool
 nsStyleDisplay::IsFixedPosContainingBlock(const nsIFrame* aContextFrame) const
 {
   mozilla::ComputedStyle* style = aContextFrame->Style();
   NS_ASSERTION(style->ThreadsafeStyleDisplay() == this,
                "unexpected aContextFrame");
   // NOTE: Any CSS properties that influence the output of this function
   // should have the FIXPOS_CB flag set on them.
   if (!IsFixedPosContainingBlockForNonSVGTextFrames(*style) &&
+      (!IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() ||
+       !aContextFrame->IsFrameOfType(nsIFrame::eSupportsContainLayoutAndPaint)) &&
       (!IsFixedPosContainingBlockForTransformSupportingFrames() ||
        !aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms))) {
     return false;
   }
   return !nsSVGUtils::IsInSVGTextSubtree(aContextFrame);
 }
 
 bool
@@ -211,16 +217,18 @@ nsStyleDisplay::IsAbsPosContainingBlock(
 {
   mozilla::ComputedStyle *style = aContextFrame->Style();
   NS_ASSERTION(style->ThreadsafeStyleDisplay() == this,
                "unexpected aContextFrame");
   // NOTE: Any CSS properties that influence the output of this function
   // should have the ABSPOS_CB set on them.
   if (!IsAbsPosContainingBlockForNonSVGTextFrames() &&
       !IsFixedPosContainingBlockForNonSVGTextFrames(*style) &&
+      (!IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() ||
+       !aContextFrame->IsFrameOfType(nsIFrame::eSupportsContainLayoutAndPaint)) &&
       (!IsFixedPosContainingBlockForTransformSupportingFrames() ||
        !aContextFrame->IsFrameOfType(nsIFrame::eSupportsCSSTransforms))) {
     return false;
   }
   return !nsSVGUtils::IsInSVGTextSubtree(aContextFrame);
 }
 
 bool