Bug 960277 - Part 3: nsFieldSetFrame's anonymous child should not inherit CSS 'position', but should still be an abs-pos containing block if the fieldset is. r=mats, a=lsblakk
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 17 Jan 2014 23:39:04 +1300
changeset 176068 7832d9a8974ec14068ef11fe8a6d951881dbbf30
parent 176067 f51c653bd79a42eb388a759b9c1e5d332e1aeb99
child 176069 a3f8a8d0dc9104936c7d08bc98074278cb7ef469
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats, lsblakk
bugs960277
milestone28.0a2
Bug 960277 - Part 3: nsFieldSetFrame's anonymous child should not inherit CSS 'position', but should still be an abs-pos containing block if the fieldset is. r=mats, a=lsblakk
layout/base/nsCSSFrameConstructor.cpp
layout/forms/crashtests/960277-2.html
layout/forms/crashtests/crashtests.list
layout/forms/test/mochitest.ini
layout/forms/test/test_bug960277.html
layout/style/forms.css
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -63,16 +63,17 @@
 #include "nsTArray.h"
 #include "nsGenericDOMDataNode.h"
 #include "mozilla/dom/Element.h"
 #include "nsAutoLayoutPhase.h"
 #include "nsStyleStructInlines.h"
 #include "nsPageContentFrame.h"
 #include "RestyleManager.h"
 #include "StickyScrollContainer.h"
+#include "nsFieldSetFrame.h"
 
 #ifdef MOZ_XUL
 #include "nsIRootBox.h"
 #endif
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
@@ -5658,31 +5659,42 @@ nsCSSFrameConstructor::GetAbsoluteContai
     // scrolledframe might be.  So, we need to check this special case to return
     // the correct containing block (the scrolledframe) in that case.
     // If we're looking for a fixed-pos containing block and the frame is
     // not transformed, skip it.
     if (!frame->IsPositioned() ||
         (aType == FIXED_POS && !frame->StyleDisplay()->HasTransform(frame))) {
       continue;
     }
-    nsIFrame* absPosCBCandidate = nullptr;
-    if (frame->GetType() == nsGkAtoms::scrollFrame) {
-      nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
+    nsIFrame* absPosCBCandidate = frame;
+    nsIAtom* type = absPosCBCandidate->GetType();
+    if (type == nsGkAtoms::fieldSetFrame) {
+      absPosCBCandidate = static_cast<nsFieldSetFrame*>(absPosCBCandidate)->GetInner();
+      if (!absPosCBCandidate) {
+        continue;
+      }
+      type = absPosCBCandidate->GetType();
+    }
+    if (type == nsGkAtoms::scrollFrame) {
+      nsIScrollableFrame* scrollFrame = do_QueryFrame(absPosCBCandidate);
       absPosCBCandidate = scrollFrame->GetScrolledFrame();
-    } else {
-      // Only first continuations can be containing blocks.
-      absPosCBCandidate = frame->FirstContinuation();
-    }
+      if (!absPosCBCandidate) {
+        continue;
+      }
+      type = absPosCBCandidate->GetType();
+    }
+    // Only first continuations can be containing blocks.
+    absPosCBCandidate = absPosCBCandidate->FirstContinuation();
     // Is the frame really an absolute container?
-    if (!absPosCBCandidate || !absPosCBCandidate->IsAbsoluteContainer()) {
+    if (!absPosCBCandidate->IsAbsoluteContainer()) {
       continue;
     }
 
     // For tables, skip the inner frame and consider the outer table frame.
-    if (absPosCBCandidate->GetType() == nsGkAtoms::tableFrame) {
+    if (type == nsGkAtoms::tableFrame) {
       continue;
     }
     // For outer table frames, we can just return absPosCBCandidate.
     return absPosCBCandidate;
   }
 
   // It is possible for the search for the containing block to fail, because
   // no absolute container can be found in the parent chain.  In those cases,
new file mode 100644
--- /dev/null
+++ b/layout/forms/crashtests/960277-2.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<style>
+#d { overflow:scroll; width:200px; height:200px; background:yellow; }
+#d2 { right:0; width:100px; height:100px; background:purple; }
+</style>
+<fieldset id="d">
+  <div id="d2"></div>
+</fieldset>
+<script>
+d.getBoundingClientRect();
+d.style.transform = "translateX(100px)";
+d.getBoundingClientRect();
+d2.style.position = "absolute";
+</script>
--- a/layout/forms/crashtests/crashtests.list
+++ b/layout/forms/crashtests/crashtests.list
@@ -46,8 +46,9 @@ skip-if(B2G) load 498698-1.html # bug 83
 asserts(1) load 578604-1.html # bug 584564
 asserts(4-7) load 590302-1.xhtml # bug 584564
 load 626014.xhtml
 load 639733.xhtml
 asserts(0-1) load 669767.html
 load 682684.xhtml
 load 865602.html
 load 944198.html
+load 960277-2.html
--- a/layout/forms/test/mochitest.ini
+++ b/layout/forms/test/mochitest.ini
@@ -31,11 +31,12 @@ support-files =
 [test_bug620936.html]
 [test_bug644542.html]
 [test_bug672810.html]
 [test_bug704049.html]
 [test_bug717878_input_scroll.html]
 [test_bug869314.html]
 [test_bug903715.html]
 [test_bug957562.html]
+[test_bug960277.html]
 [test_listcontrol_search.html]
 [test_select_prevent_default.html]
 [test_textarea_resize.html]
new file mode 100644
--- /dev/null
+++ b/layout/forms/test/test_bug960277.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=960277
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 903715</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=960277">Mozilla Bug 960277</a>
+<p id="display"></p>
+<fieldset style="position:relative; height:100px; margin:50px; background:blue;">
+<legend style="background:purple">
+  <div id="d" style="position:absolute; background:yellow; top:0; left:0; width:50px; height:50px;"></div>
+</legend>
+</fieldset>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+var rect = d.getBoundingClientRect();
+is(document.elementFromPoint(rect.left + 10, rect.top + 10), d,
+   "Hit testing yellow div");
+</script>
+</body>
+</html>
--- a/layout/style/forms.css
+++ b/layout/style/forms.css
@@ -11,17 +11,16 @@
 @namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
 
 *|*::-moz-fieldset-content {
   display: block;
   unicode-bidi: inherit;
   text-overflow: inherit;
   overflow: inherit;
   padding: inherit;
-  position: inherit;
   height: 100%;   /* Need this so percentage heights of kids work right */
 }
 
 /* miscellaneous form elements */
 
 fieldset > legend {
   padding-left: 2px;
   padding-right: 2px;