Bug 746993 - Fix editor caret behaviour when pressing RETURN after a BR node. r=ehsan, a=tracking-firefox
authorMike Conley <mconley@mozilla.com>
Fri, 20 Apr 2012 12:57:17 -0400
changeset 95354 7dc2085a8cc6f913f3c76a2b5388c23a11223724
parent 95353 27a52fed91a5216c7970b1ac78d6234e7727b53a
child 95355 38110d3443632522753427617ca3db566b1d75a5
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, tracking-firefox
bugs746993
milestone14.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 746993 - Fix editor caret behaviour when pressing RETURN after a BR node. r=ehsan, a=tracking-firefox
editor/libeditor/html/nsHTMLEditRules.cpp
layout/base/tests/Makefile.in
layout/base/tests/bug746993-1-ref.html
layout/base/tests/bug746993-1.html
layout/base/tests/test_reftests_with_caret.html
--- a/editor/libeditor/html/nsHTMLEditRules.cpp
+++ b/editor/libeditor/html/nsHTMLEditRules.cpp
@@ -7678,37 +7678,39 @@ nsHTMLEditRules::CheckInterlinePosition(
     return NS_OK;
   }
 
   // get the (collapsed) selection location
   nsCOMPtr<nsIDOMNode> selNode, node;
   PRInt32 selOffset;
   res = mHTMLEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
   NS_ENSURE_SUCCESS(res, res);
-  
+
+  // First, let's check to see if we are after a <br>.  We take care of this
+  // special-case first so that we don't accidentally fall through into one
+  // of the other conditionals.
+  mHTMLEditor->GetPriorHTMLNode(selNode, selOffset, address_of(node), true);
+  if (node && nsTextEditUtils::IsBreak(node))
+  {
+    selPriv->SetInterlinePosition(true);
+    return NS_OK;
+  }
+
   // are we after a block?  If so try set caret to following content
   mHTMLEditor->GetPriorHTMLSibling(selNode, selOffset, address_of(node));
   if (node && IsBlockNode(node))
   {
     selPriv->SetInterlinePosition(true);
     return NS_OK;
   }
 
   // are we before a block?  If so try set caret to prior content
   mHTMLEditor->GetNextHTMLSibling(selNode, selOffset, address_of(node));
   if (node && IsBlockNode(node))
-  {
     selPriv->SetInterlinePosition(false);
-    return NS_OK;
-  }
-  
-  // are we after a <br>?  If so we want to stick to whatever is after <br>.
-  mHTMLEditor->GetPriorHTMLNode(selNode, selOffset, address_of(node), true);
-  if (node && nsTextEditUtils::IsBreak(node))
-      selPriv->SetInterlinePosition(true);
   return NS_OK;
 }
 
 nsresult 
 nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection aAction)
 {
   NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
   nsCOMPtr<nsISelection> selection(aSelection);
--- a/layout/base/tests/Makefile.in
+++ b/layout/base/tests/Makefile.in
@@ -153,16 +153,18 @@ DEFINES += -D_IMPL_NS_LAYOUT
 		     bug646382-2.html \
 		     bug646382-2-ref.html \
 		     bug664087-1.html \
 		     bug664087-1-ref.html \
 		     bug664087-2.html \
 		     bug664087-2-ref.html \
 		     bug682712-1.html \
 		     bug682712-1-ref.html \
+		     bug746993-1.html \
+		     bug746993-1-ref.html \
 		test_bug514127.html \
 		test_bug518777.html \
 		test_bug548545.xhtml \
 		test_bug558663.html \
 		test_bug559499.html \
 		test_bug569520.html \
 		test_bug582181-1.html \
 		test_bug582181-2.html \
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/bug746993-1-ref.html
@@ -0,0 +1,20 @@
+<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>
+  </head>
+  <body onload="start()">
+    <iframe src="data:text/html,<body contenteditable>Here's some text.<br /><br /><div></div></body>"></iframe>
+    <script>
+      function start() {
+        var iframe = document.querySelector("iframe");
+        var win = iframe.contentWindow;
+        var doc = iframe.contentDocument;
+        iframe.focus();
+        doc.body.focus();
+        win.getSelection().collapse(doc.body, 3);
+        document.documentElement.removeAttribute("class");
+      }
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/base/tests/bug746993-1.html
@@ -0,0 +1,33 @@
+<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>
+  </head>
+  <body onload="start()">
+    <iframe src="data:text/html,<body contenteditable><br /><div></div></body>"></iframe>
+    <script>
+      function start() {
+        var iframe = document.querySelector("iframe");
+        var win = iframe.contentWindow;
+        var doc = iframe.contentDocument;
+        iframe.focus();
+        doc.body.focus();
+        win.getSelection().collapse(doc.body, 0);
+        synthesizeText(
+          { "composition":
+            {
+              "string": "Here's some text.",
+              "clauses":
+              [
+                { "length": 17, "attr": COMPOSITION_ATTR_RAWINPUT }
+              ]
+            },
+            "caret": { "start": 2, "length": 0 }
+          }
+         )
+        synthesizeKey("VK_RETURN", {});
+        document.documentElement.removeAttribute("class");
+      }
+    </script>
+  </body>
+</html>
--- a/layout/base/tests/test_reftests_with_caret.html
+++ b/layout/base/tests/test_reftests_with_caret.html
@@ -126,16 +126,17 @@ if (!isWindows) {
   tests.push([ 'bug612271-1.html' , 'bug612271-ref.html' ]);   // bug 681032
   tests.push([ 'bug612271-2.html' , 'bug612271-ref.html' ]);   // bug 680581
   tests.push([ 'bug612271-3.html' , 'bug612271-ref.html' ]);   // bug 681035
   tests.push([ 'bug613433-1.html' , 'bug613433-ref.html' ]);   // bug 681332
   tests.push([ 'bug613433-2.html' , 'bug613433-ref.html' ]);   // bug 681332
   tests.push([ 'bug613433-3.html' , 'bug613433-ref.html' ]);   // bug 681332
   tests.push([ 'bug613807-1.html' , 'bug613807-1-ref.html' ]); // bug 680574
   tests.push([ 'bug634406-1.html' , 'bug634406-1-ref.html' ]); // bug 681146
+  tests.push([ 'bug746993-1.html' , 'bug746993-1-ref.html' ]); // bug 746993
 }
 
 tests.push(function() {SpecialPowers.setBoolPref("bidi.browser.ui", true);});
 
 if (!isWindows) {
   tests.push([ 'bug646382-1.html' , 'bug646382-1-ref.html' ]);  // bug 681076
   tests.push([ 'bug646382-2.html' , 'bug646382-2-ref.html' ]);  // bug 680577
   tests.push([ 'bug664087-1.html' , 'bug664087-1-ref.html' ]);  // bug 681038