Bug 989012 - Part 2: Don't get stuck when seeing an image without a src or alt attribute; r=roc
☠☠ backed out by 007fbd5bc4bd ☠ ☠
authorEhsan Akhgari <ehsan@mozilla.com>
Thu, 15 Jan 2015 11:59:13 -0500
changeset 226064 9698f6f3f72e98d8ddced3cee5cde812595ef33a
parent 226063 22fb05349a10681c74da313485dac594dc1d7a82
child 226065 d28a04536e7e3908b4b89f8e17a786f0470db2ab
push id54755
push usereakhgari@mozilla.com
push dateTue, 27 Jan 2015 20:36:05 +0000
treeherdermozilla-inbound@9698f6f3f72e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs989012
milestone38.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 989012 - Part 2: Don't get stuck when seeing an image without a src or alt attribute; r=roc We do not want to traverse inside native anonymous elements, but we should still be able to skip over generated content, to avoid getting stuck on such images.
layout/base/tests/bug989012-3-ref.html
layout/base/tests/bug989012-3.html
layout/base/tests/mochitest.ini
layout/base/tests/test_reftests_with_caret.html
layout/generic/nsFrame.cpp
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/bug989012-3-ref.html
@@ -0,0 +1,28 @@
+<html class="reftest-wait">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+    <style>
+      img {
+        border: solid 1px red;
+        mid-width: 1em;
+        display: inline-block;
+      }
+    </style>
+  </head>
+  <body onload="start()">
+    <div onfocus="done()" contenteditable>foo<img>bar</div>
+    <script>
+      var div = document.querySelector("div");
+      function start() {
+        div.focus();
+      }
+      function done() {
+        var sel = getSelection();
+        // Set the caret right before "bar"
+        sel.collapse(div.lastChild, 0);
+        document.documentElement.removeAttribute("class");
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/bug989012-3.html
@@ -0,0 +1,31 @@
+<html class="reftest-wait">
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+    <style>
+      img {
+        border: solid 1px red;
+        mid-width: 1em;
+        display: inline-block;
+      }
+    </style>
+  </head>
+  <body onload="start()">
+    <div onfocus="done()" contenteditable>foo<img>bar</div>
+    <script>
+      var div = document.querySelector("div");
+      function start() {
+        div.focus();
+      }
+      function done() {
+        var sel = getSelection();
+        sel.collapse(div, 0);
+        // Press Right four times to set the caret right before "bar"
+        for (var i = 0; i < 4; ++i) {
+          synthesizeKey("VK_RIGHT", {});
+        }
+        document.documentElement.removeAttribute("class");
+      }
+    </script>
+  </body>
+</html>
--- a/layout/base/tests/mochitest.ini
+++ b/layout/base/tests/mochitest.ini
@@ -52,16 +52,18 @@ support-files =
   bug570378-persian-4-ref.html
   bug570378-persian-5.html
   bug570378-persian-5-ref.html
   bug644768.html
   bug989012-1.html
   bug989012-1-ref.html
   bug989012-2.html
   bug989012-2-ref.html
+  bug989012-3.html
+  bug989012-3-ref.html
   bug1061468.html
   bug1061468-ref.html
   bug1109968-1-ref.html
   bug1109968-1.html
   bug1109968-2-ref.html
   bug1109968-2.html
 
 [test_preserve3d_sorting_hit_testing.html]
--- a/layout/base/tests/test_reftests_with_caret.html
+++ b/layout/base/tests/test_reftests_with_caret.html
@@ -104,16 +104,17 @@ function endTest() {
 
 var tests = [
     [ 'bug106855-1.html' , 'bug106855-1-ref.html' ] ,
     [ 'bug106855-2.html' , 'bug106855-1-ref.html' ] ,
     [ 'bug389321-2.html' , 'bug389321-2-ref.html' ] ,
     [ 'bug613807-1.html' , 'bug613807-1-ref.html' ] ,
     [ 'bug989012-1.html' , 'bug989012-1-ref.html' ] ,
     [ 'bug989012-2.html' , 'bug989012-2-ref.html' ] ,
+    [ 'bug989012-3.html' , 'bug989012-3-ref.html' ] ,
     [ 'bug1082486-1.html', 'bug1082486-1-ref.html'] ,
     [ 'bug1082486-2.html', 'bug1082486-2-ref.html'] ,
     // The following test cases are all involving with one sending
     // synthesizeKey(), the other without. They ought to be failed
     // when touch caret preference on. Test them with preference off.
     function() {SpecialPowers.setBoolPref("touchcaret.enabled", false);} ,
     [ 'bug240933-1.html' , 'bug240933-1-ref.html' ] ,
     [ 'bug240933-2.html' , 'bug240933-1-ref.html' ] ,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -7041,20 +7041,22 @@ nsIFrame::GetFrameFromDirection(nsDirect
 
     if (aDirection == eDirNext)
       frameTraversal->Next();
     else
       frameTraversal->Prev();
 
     traversedFrame = frameTraversal->CurrentItem();
 
-    // Skip anonymous elements
+    // Skip anonymous elements, but watch out for generated content
     if (!traversedFrame ||
-        traversedFrame->GetContent()->IsRootOfNativeAnonymousSubtree())
+        (!traversedFrame->IsGeneratedContentFrame() &&
+         traversedFrame->GetContent()->IsRootOfNativeAnonymousSubtree())) {
       return NS_ERROR_FAILURE;
+    }
 
     traversedFrame->IsSelectable(&selectable, nullptr);
     if (!selectable) {
       *aOutMovedOverNonSelectableText = true;
     }
   } // while (!selectable)
 
   *aOutOffset = (aDirection == eDirNext) ? 0 : -1;