Bug 1504072 - non-display outer SVG also doesn't maintain overflow r=longsonr
authorviolet <violet.bugreport@gmail.com>
Sun, 17 Mar 2019 11:00:48 +0000
changeset 464704 5f22cf5bfe6f0281522103ecf8d23c88dc37b5e6
parent 464703 cb58de9731cbdfc59aa208aa6118dbcd0ea4f5bf
child 464705 46e6675abc338804c81392b90bf0aac5e5c09cdc
push id35718
push usernerli@mozilla.com
push dateSun, 17 Mar 2019 21:37:26 +0000
treeherdermozilla-central@46e6675abc33 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslongsonr
bugs1504072
milestone67.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 1504072 - non-display outer SVG also doesn't maintain overflow r=longsonr There is some inconsistency between nsIFrame::FrameMaintainsOverflow() and nsSVGContainerFrame::ComputeCustomOverflow(). If an element is a nondisplay outer SVG, the latter gives false while the former returns true. We make them consistent since nondisplay element doesn't need to maintain overflow. Differential Revision: https://phabricator.services.mozilla.com/D23809
layout/generic/nsIFrame.h
layout/svg/crashtests/1504072.html
layout/svg/crashtests/crashtests.list
layout/svg/nsSVGOuterSVGFrame.cpp
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -4007,17 +4007,22 @@ class nsIFrame : public nsQueryFrame {
   }
 
   /**
    * Return whether this frame keeps track of overflow areas. (Frames for
    * non-display SVG elements -- e.g. <clipPath> -- do not maintain overflow
    * areas, because they're never painted.)
    */
   bool FrameMaintainsOverflow() const {
-    return !HasAllStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
+    // The IsSVGElement() check below is necessary, because the
+    // NS_STATE_IS_OUTER_SVG bit has conflict in other frames due to lack
+    // of bits.
+    return !HasAllStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY) &&
+           !(HasAllStateBits(NS_STATE_IS_OUTER_SVG | NS_FRAME_IS_NONDISPLAY) &&
+             GetContent()->IsSVGElement(nsGkAtoms::svg));
   }
 
   /*
    * @param aStyleDisplay:  If the caller has this->StyleDisplay(), providing
    *   it here will improve performance.
    */
   bool BackfaceIsHidden(const nsStyleDisplay* aStyleDisplay) const {
     MOZ_ASSERT(aStyleDisplay == StyleDisplay());
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/1504072.html
@@ -0,0 +1,4 @@
+<style>
+svg { perspective: 0px }
+</style>
+<svg overflow="scroll" systemLanguage="">
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -216,9 +216,10 @@ load blob-merging-and-retained-display-l
 load empty-blob-merging.html
 load grouping-empty-bounds.html
 load 1480275.html
 load 1480224.html
 load 1502936.html
 load 1504918.svg
 load perspective-invalidation.html
 load invalid_url.html
+load 1504072.html
 load 1072758.html
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -480,22 +480,27 @@ void nsSVGOuterSVGFrame::Reflow(nsPresCo
   // descendants added to its own. (Note that the default user-agent style
   // sheet makes 'hidden' the default value for :not(root(svg)), so usually
   // FinishAndStoreOverflow will still clip this back to the frame's rect.)
   //
   // WARNING!! Keep UpdateBounds below in sync with whatever we do for our
   // overflow rects here! (Again, see bug 875175.)
   //
   aDesiredSize.SetOverflowAreasToDesiredBounds();
-  if (!mIsRootContent) {
-    aDesiredSize.mOverflowAreas.VisualOverflow().UnionRect(
-        aDesiredSize.mOverflowAreas.VisualOverflow(),
-        anonKid->GetVisualOverflowRect() + anonKid->GetPosition());
+
+  // An outer SVG will be here as a nondisplay if it fails the conditional
+  // processing test. In that case, we don't maintain its overflow.
+  if (!HasAnyStateBits(NS_FRAME_IS_NONDISPLAY)) {
+    if (!mIsRootContent) {
+      aDesiredSize.mOverflowAreas.VisualOverflow().UnionRect(
+          aDesiredSize.mOverflowAreas.VisualOverflow(),
+          anonKid->GetVisualOverflowRect() + anonKid->GetPosition());
+    }
+    FinishAndStoreOverflow(&aDesiredSize);
   }
-  FinishAndStoreOverflow(&aDesiredSize);
 
   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
                  ("exit nsSVGOuterSVGFrame::Reflow: size=%d,%d",
                   aDesiredSize.Width(), aDesiredSize.Height()));
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
 }
 
 void nsSVGOuterSVGFrame::DidReflow(nsPresContext* aPresContext,