Bug 713427. Don't assume things about lazy frame construction bits that just aren't true when doing IsVisible() testing. r=tnikkel
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 18 Jan 2012 16:10:06 -0500
changeset 84818 efb5775264896624c063620eaca52f4108b3bdc7
parent 84817 1d3e470a47095f5bcc91f3f9674896e5fc415c3a
child 84819 f8f3d849c74acc24db4e82141e3902c166ce56f0
push id21879
push usermak77@bonardo.net
push dateThu, 19 Jan 2012 10:34:58 +0000
treeherdermozilla-central@f76b576a9e28 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs713427
milestone12.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 713427. Don't assume things about lazy frame construction bits that just aren't true when doing IsVisible() testing. r=tnikkel
editor/libeditor/base/crashtests/713427-1.html
editor/libeditor/base/crashtests/713427-2.xhtml
editor/libeditor/base/crashtests/crashtests.list
editor/libeditor/base/nsEditor.cpp
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/base/crashtests/713427-1.html
@@ -0,0 +1,9 @@
+<span>
+<script contenteditable="true"></script>
+<blockquote>
+<input>
+<code style="display: table-row;">
+<html contenteditable="true">
+</blockquote>
+
+
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/base/crashtests/713427-2.xhtml
@@ -0,0 +1,28 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<script>
+<![CDATA[
+
+function boom()
+{
+  while (document.documentElement.firstChild) {
+    document.documentElement.removeChild(document.documentElement.firstChild);
+  }
+
+  var td = document.createElementNS("http://www.w3.org/1999/xhtml", "td");
+  td.setAttributeNS(null, "contenteditable", "true");
+  (document.documentElement).appendChild(td);
+  var head = document.createElementNS("http://www.w3.org/1999/xhtml", "head");
+  (document.documentElement).appendChild(head);
+
+  head.appendChild(td);
+}
+
+window.addEventListener("load", boom, false);
+
+]]>
+</script>
+</head>
+
+<body></body>
+</html>
--- a/editor/libeditor/base/crashtests/crashtests.list
+++ b/editor/libeditor/base/crashtests/crashtests.list
@@ -3,8 +3,10 @@ load 382527-1.html
 load 402172-1.html
 load 407079-1.html
 load 407256-1.html
 load 430624-1.html
 load 459613.html
 load 475132-1.xhtml
 asserts-if(!Android,1) load 633709.xhtml # Bug 695364
 asserts-if(!Android,6) load 636074-1.html # Bug 439258, charged to the wrong test due to bug 635550
+load 713427-1.html
+load 713427-2.xhtml
--- a/editor/libeditor/base/nsEditor.cpp
+++ b/editor/libeditor/base/nsEditor.cpp
@@ -3600,42 +3600,47 @@ IsElementVisible(dom::Element* aElement)
 {
   if (aElement->GetPrimaryFrame()) {
     // It's visible, for our purposes
     return true;
   }
 
   nsIContent *cur = aElement;
   for (; ;) {
+    // Walk up the tree looking for the nearest ancestor with a frame.
+    // The state of the child right below it will determine whether
+    // we might possibly have a frame or not.
+    bool haveLazyBitOnChild = cur->HasFlag(NODE_NEEDS_FRAME);
     cur = cur->GetFlattenedTreeParent();
     if (!cur) {
-      // None of our ancestors have lazy bits set, so we shouldn't have a frame
-      return false;
+      if (!haveLazyBitOnChild) {
+        // None of our ancestors have lazy bits set, so we shouldn't
+        // have a frame
+        return false;
+      }
+
+      // The root has a lazy frame construction bit.  We need to check
+      // our style.
+      break;
     }
 
     if (cur->GetPrimaryFrame()) {
-      // None of our ancestors up to the nearest ancestor with a frame have
-      // lazy bits; that means we won't get a frame
-      return false;
-    }
-
-    if (cur->HasFlag(NODE_NEEDS_FRAME)) {
-      // Double-check that the parent doesn't have a leaf frame
-      nsIContent *parent = cur->GetFlattenedTreeParent();
-      if (parent) {
-        NS_ASSERTION(parent->GetPrimaryFrame(),
-                     "Why does our parent not have a frame?");
-        if (parent->GetPrimaryFrame()->IsLeaf()) {
-          // No frame for us
-          return false;
-        }
+      if (!haveLazyBitOnChild) {
+        // Our ancestor directly under |cur| doesn't have lazy bits;
+        // that means we won't get a frame
+        return false;
       }
 
-      // |cur| will get a frame sometime.  What does that mean for us?
-      // |We have to figure that out!
+      if (cur->GetPrimaryFrame()->IsLeaf()) {
+        // Nothing under here will ever get frames
+        return false;
+      }
+
+      // Otherwise, we might end up with a frame when that lazy bit is
+      // processed.  Figure out our actual style.
       break;
     }
   }
 
   // Now it might be that we have no frame because we're in a
   // display:none subtree, or it might be that we're just dealing with
   // lazy frame construction and it hasn't happened yet.  Check which
   // one it is.