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
authorRobert O'Callahan <robert@ocallahan.org>
Fri, 17 Jan 2014 23:39:04 +1300
changeset 164132 6ce27f9e743f961f892b9e4998ae5ef70559f6c4
parent 164131 0cb7841990d8de527acc92dafacfca106c68b74d
child 164133 3d2f331a57a470535cc355fa071e14ecb774f90e
push id26026
push userphilringnalda@gmail.com
push dateSat, 18 Jan 2014 23:17:27 +0000
treeherdermozilla-central@61fd0f987cf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs960277
milestone29.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 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
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
 
@@ -5645,31 +5646,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
@@ -48,8 +48,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;