Bug 1448317 - Don't include absolutely-positioned and float children in element outline. r=dholbert
authorXidorn Quan <me@upsuper.org>
Tue, 23 Oct 2018 06:37:16 +0000
changeset 490871 88c9e1c85918410a8d6bd10c25b4e1b17b5b58fc
parent 490849 dfa1eb1d036fc0b11a449627c0a69702b3f6309f
child 490872 924b484fa4dff96148d00cfaf16bea9f065ed054
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersdholbert
bugs1448317
milestone65.0a1
Bug 1448317 - Don't include absolutely-positioned and float children in element outline. r=dholbert Differential Revision: https://phabricator.services.mozilla.com/D9349
layout/generic/nsFrame.cpp
layout/reftests/outline/outline-overflow-block-abspos.html
layout/reftests/outline/outline-overflow-block-float.html
layout/reftests/outline/outline-overflow-block-ref.html
layout/reftests/outline/outline-overflow-inlineblock-abspos.html
layout/reftests/outline/outline-overflow-inlineblock-float.html
layout/reftests/outline/outline-overflow-inlineblock-ref.html
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -9239,28 +9239,36 @@ UnionBorderBoxes(nsIFrame* aFrame, bool 
       fType == LayoutFrameType::SVGOuterSVG) {
     return u;
   }
 
   const nsStyleEffects* effects = aFrame->StyleEffects();
   Maybe<nsRect> clipPropClipRect =
     aFrame->GetClipPropClipRect(disp, effects, bounds.Size());
 
-  // Iterate over all children except pop-ups.
+  // Iterate over all children except pop-up, absolutely-positioned, and
+  // float ones.
   const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList |
-                                    nsIFrame::kSelectPopupList);
+                                    nsIFrame::kSelectPopupList |
+                                    nsIFrame::kAbsoluteList |
+                                    nsIFrame::kFixedList |
+                                    nsIFrame::kFloatList);
   for (nsIFrame::ChildListIterator childLists(aFrame);
        !childLists.IsDone(); childLists.Next()) {
     if (skip.Contains(childLists.CurrentID())) {
       continue;
     }
 
     nsFrameList children = childLists.CurrentList();
     for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
       nsIFrame* child = e.get();
+      if (child->IsPlaceholderFrame()) {
+        continue;
+      }
+
       // Note that passing |true| for aApplyTransform when
       // child->Combines3DTransformWithAncestors() is incorrect if our
       // aApplyTransform is false... but the opposite would be as
       // well.  This is because elements within a preserve-3d scene
       // are always transformed up to the top of the scene.  This
       // means we don't have a mechanism for getting a transform up to
       // an intermediate point within the scene.  We choose to
       // over-transform rather than under-transform because this is
--- a/layout/reftests/outline/outline-overflow-block-abspos.html
+++ b/layout/reftests/outline/outline-overflow-block-abspos.html
@@ -1,14 +1,25 @@
 <!DOCTYPE HTML>
-<title>outline goes around overflow, floats</title>
+<title>outline doesn't go around overflowing abspos descendants</title>
 <style>
 
 html, body { margin: 0; padding: 0; border: none }
 html { overflow:hidden /* avoid second reflow for scrollbars */ }
 
-body > div { margin: 100px; outline: 2px solid blue; position: relative }
+body > div {
+  margin: 100px;
+  width: 50px; height: 50px;
+  outline: 2px solid blue;
+  position: relative;
+}
 
-body > div > div { position: absolute; top: 0; left: 0; width: 100px; height: 100px }
+body > div > div {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100px;
+  height: 100px;
+}
 
 </style>
 <body>
 <div><div></div></div>
--- a/layout/reftests/outline/outline-overflow-block-float.html
+++ b/layout/reftests/outline/outline-overflow-block-float.html
@@ -1,14 +1,23 @@
 <!DOCTYPE HTML>
-<title>outline goes around overflow, floats</title>
+<title>outline doesn't go around overflowing floats</title>
 <style>
 
 html, body { margin: 0; padding: 0; border: none }
 html { overflow:hidden /* avoid second reflow for scrollbars */ }
 
-body > div { margin: 100px; outline: 2px solid blue }
+body > div {
+  margin: 100px;
+  width: 50px; height: 50px;
+  outline: 2px solid blue;
+  position: relative;
+}
 
-body > div > div { float: left; width: 100px; height: 100px }
+body > div > div {
+  float: left;
+  width: 100px;
+  height: 100px;
+}
 
 </style>
 <body>
 <div><div></div></div>
--- a/layout/reftests/outline/outline-overflow-block-ref.html
+++ b/layout/reftests/outline/outline-overflow-block-ref.html
@@ -1,12 +1,17 @@
 <!DOCTYPE HTML>
-<title>outline goes around overflow, floats</title>
+<title>reference</title>
 <style>
 
 html, body { margin: 0; padding: 0; border: none }
 html { overflow:hidden /* avoid second reflow for scrollbars */ }
 
-body > div { margin: 98px; border: 2px solid blue; height: 100px }
+body > div {
+  margin: 98px;
+  border: 2px solid blue;
+  width: 50px;
+  height: 50px;
+}
 
 </style>
 <body>
 <div></div>
--- a/layout/reftests/outline/outline-overflow-inlineblock-abspos.html
+++ b/layout/reftests/outline/outline-overflow-inlineblock-abspos.html
@@ -1,14 +1,27 @@
 <!DOCTYPE HTML>
-<title>outline goes around overflow, floats</title>
+<title>outline doesn't go around overflowing abspos descendants</title>
 <style>
 
 html, body { margin: 0; padding: 0; border: none }
 html { overflow:hidden /* avoid second reflow for scrollbars */ }
 
-body > div { margin: 100px; outline: 2px solid blue; display: inline-block; height: 0; width: 0; position: relative }
+body > div {
+  margin: 100px;
+  outline: 2px solid blue;
+  display: inline-block;
+  height: 50px;
+  width: 50px;
+  position: relative;
+}
 
-body > div > div { position: absolute; top: 0; left: 0; width: 100px; height: 100px }
+body > div > div {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100px;
+  height: 100px;
+}
 
 </style>
 <body>
 <div><div></div></div>
--- a/layout/reftests/outline/outline-overflow-inlineblock-float.html
+++ b/layout/reftests/outline/outline-overflow-inlineblock-float.html
@@ -1,14 +1,24 @@
 <!DOCTYPE HTML>
-<title>outline goes around overflow, floats</title>
+<title>outline doesn't go around overflowing floats</title>
 <style>
 
 html, body { margin: 0; padding: 0; border: none }
 html { overflow:hidden /* avoid second reflow for scrollbars */ }
 
-body > div { margin: 100px; outline: 2px solid blue; display: inline-block; height: 0; width: 0 }
+body > div {
+  margin: 100px;
+  outline: 2px solid blue;
+  display: inline-block;
+  height: 50px;
+  width: 50px;
+}
 
-body > div > div { float: left; width: 100px; height: 100px }
+body > div > div {
+  float: left;
+  width: 100px;
+  height: 100px;
+}
 
 </style>
 <body>
 <div><div></div></div>
--- a/layout/reftests/outline/outline-overflow-inlineblock-ref.html
+++ b/layout/reftests/outline/outline-overflow-inlineblock-ref.html
@@ -1,12 +1,17 @@
 <!DOCTYPE HTML>
-<title>outline goes around overflow, floats</title>
+<title>reference</title>
 <style>
 
 html, body { margin: 0; padding: 0; border: none }
 html { overflow:hidden /* avoid second reflow for scrollbars */ }
 
-body > div { margin: 98px; border: 2px solid blue; height: 100px; width: 100px }
+body > div {
+  margin: 98px;
+  border: 2px solid blue;
+  width: 50px;
+  height: 50px;
+}
 
 </style>
 <body>
 <div></div>