Bug 803677 - Fix offsetTop/offsetParent for element with display:table-cell that have anonymous table parents. r=bzbarsky
authorBenedict Singer <singerb.dev@gmail.com>
Tue, 11 Dec 2012 08:48:04 -0500
changeset 115715 939a0ad6e8d6453f0ebc86ea7b136a6bd01ede9c
parent 115714 99a78630d2c237ae5fb6a712eed340c990e43b3f
child 115716 5ed9e56c7a5d415f4445c00b89a01fba8cb1a6bd
push id24020
push useremorley@mozilla.com
push dateWed, 12 Dec 2012 10:01:41 +0000
treeherdermozilla-central@634180132e68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs803677
milestone20.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 803677 - Fix offsetTop/offsetParent for element with display:table-cell that have anonymous table parents. r=bzbarsky
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/test/Makefile.in
content/html/content/test/test_bug803677.html
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -374,18 +374,28 @@ static bool IS_TABLE_CELL(nsIAtom* frame
   return nsGkAtoms::tableCellFrame == frameType ||
     nsGkAtoms::bcTableCellFrame == frameType;
 }
 
 static bool
 IsOffsetParent(nsIFrame* aFrame)
 {
   nsIAtom* frameType = aFrame->GetType();
-  return (IS_TABLE_CELL(frameType) ||
-          frameType == nsGkAtoms::tableFrame);
+  
+  if (IS_TABLE_CELL(frameType) || frameType == nsGkAtoms::tableFrame) {
+    // Per the IDL for Element, only td, th, and table are acceptable offsetParents
+    // apart from body or positioned elements; we need to check the content type as
+    // well as the frame type so we ignore anonymous tables created by an element
+    // with display: table-cell with no actual table
+    nsIContent* content = aFrame->GetContent();
+
+    return content->IsHTML(nsGkAtoms::table) || content->IsHTML(nsGkAtoms::td)
+      || content->IsHTML(nsGkAtoms::th);
+  }
+  return false;
 }
 
 Element*
 nsGenericHTMLElement::GetOffsetRect(nsRect& aRect)
 {
   aRect = nsRect();
 
   nsIFrame* frame = GetStyledFrame();
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -265,16 +265,17 @@ MOCHITEST_FILES = \
 		test_bug742549.html \
 		test_bug745685.html \
 		test_input_file_picker.html \
 		test_bug763626.html \
 		test_bug780993.html \
 		test_bug786564.html \
 		test_bug797113.html \
 		test_bug787134.html \
+		test_bug803677.html \
 		test_iframe_sandbox_inheritance.html \
 		file_iframe_sandbox_a_if1.html \
 		file_iframe_sandbox_a_if2.html \
 		file_iframe_sandbox_a_if3.html \
 		file_iframe_sandbox_a_if4.html \
 		file_iframe_sandbox_a_if5.html \
 		file_iframe_sandbox_a_if6.html \
 		file_iframe_sandbox_a_if7.html \
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug803677.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=803677
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 803677</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script src="reflect.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+<style>
+	.base { border:1px solid gray; }
+	.bad-table { display:table-cell; border:1px solid red; }
+</style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=803677">Mozilla Bug 803677</a>
+<p id="display"></p>
+<div id="content">
+	<p class="base">1</p>
+	<p class="base">2</p>
+	<p class="base">3</p>
+	<p class="base bad-table">4</p>
+	<p class="base">7</p>
+	<p class="base">8</p>
+	<p class="base">9</p>
+</div>
+<pre id="test">
+<script type="application/javascript">
+    var p = document.querySelectorAll(".base");
+    var parent = document.querySelector("body");
+    var prevOffset = 0;
+    for (var i = 0; i < p.length; i++) {
+        var t = 0, e = p[i];
+        is(e.offsetParent, parent, "Offset parent of all paragraphs should be the body.");
+        while (e) {
+            t += e.offsetTop;
+            e = e.offsetParent;
+        }
+        p[i].innerHTML = t;
+
+        ok(t > prevOffset, "Offset should increase down the page");
+        prevOffset = t;
+    }
+</script>
+</pre>
+</body>
+</html>