Bug 471319 - Don't make incorrect assumptions about the bogus node after undo/redo. r=ehsan
authorGraeme McCutcheon <graememcc_firefox@graeme-online.co.uk>
Wed, 04 Jan 2012 15:15:09 +0000
changeset 86334 0ac1cbff2a676dd6312e9ee2dcd813e14645fcc8
parent 86333 4f11bea71a4a50465fc6b05e02def70a163dca04
child 86335 fcc32e70c95fdbb491100259f35742d1b45c0cd9
child 86340 78d17e22a223f7ea26c2dc5379f0f53bebb0b96a
push idunknown
push userunknown
push dateunknown
reviewersehsan
bugs471319
milestone12.0a1
Bug 471319 - Don't make incorrect assumptions about the bogus node after undo/redo. r=ehsan
editor/libeditor/text/nsTextEditRules.cpp
editor/libeditor/text/tests/Makefile.in
editor/libeditor/text/tests/test_bug471319.html
--- a/editor/libeditor/text/nsTextEditRules.cpp
+++ b/editor/libeditor/text/nsTextEditRules.cpp
@@ -939,27 +939,23 @@ nsTextEditRules::WillUndo(nsISelection *
  */
 nsresult
 nsTextEditRules::DidUndo(nsISelection *aSelection, nsresult aResult)
 {
   nsresult res = aResult;  // if aResult is an error, we return it.
   if (!aSelection) { return NS_ERROR_NULL_POINTER; }
   if (NS_SUCCEEDED(res)) 
   {
-    if (mBogusNode) {
-      mBogusNode = nsnull;
-    }
+    nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
+    NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
+    nsCOMPtr<nsIDOMNode> node = mEditor->GetLeftmostChild(theRoot);
+    if (node && mEditor->IsMozEditorBogusNode(node))
+      mBogusNode = node;
     else
-    {
-      nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
-      NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
-      nsCOMPtr<nsIDOMNode> node = mEditor->GetLeftmostChild(theRoot);
-      if (node && mEditor->IsMozEditorBogusNode(node))
-        mBogusNode = node;
-    }
+      mBogusNode = nsnull;
   }
   return res;
 }
 
 nsresult
 nsTextEditRules::WillRedo(nsISelection *aSelection, bool *aCancel, bool *aHandled)
 {
   if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
@@ -972,40 +968,41 @@ nsTextEditRules::WillRedo(nsISelection *
 
 nsresult
 nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
 {
   nsresult res = aResult;  // if aResult is an error, we return it.
   if (!aSelection) { return NS_ERROR_NULL_POINTER; }
   if (NS_SUCCEEDED(res)) 
   {
-    if (mBogusNode) {
-      mBogusNode = nsnull;
-    }
-    else
+    nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
+    NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
+    
+    nsCOMPtr<nsIDOMNodeList> nodeList;
+    res = theRoot->GetElementsByTagName(NS_LITERAL_STRING("br"),
+                                        getter_AddRefs(nodeList));
+    NS_ENSURE_SUCCESS(res, res);
+    if (nodeList)
     {
-      nsCOMPtr<nsIDOMElement> theRoot = do_QueryInterface(mEditor->GetRoot());
-      NS_ENSURE_TRUE(theRoot, NS_ERROR_FAILURE);
+      PRUint32 len;
+      nodeList->GetLength(&len);
       
-      nsCOMPtr<nsIDOMNodeList> nodeList;
-      res = theRoot->GetElementsByTagName(NS_LITERAL_STRING("br"),
-                                          getter_AddRefs(nodeList));
-      NS_ENSURE_SUCCESS(res, res);
-      if (nodeList)
-      {
-        PRUint32 len;
-        nodeList->GetLength(&len);
-        
-        if (len != 1) return NS_OK;  // only in the case of one br could there be the bogus node
-        nsCOMPtr<nsIDOMNode> node;
-        nodeList->Item(0, getter_AddRefs(node));
-        NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
-        if (mEditor->IsMozEditorBogusNode(node))
-          mBogusNode = node;
+      if (len != 1) {
+        // only in the case of one br could there be the bogus node
+        mBogusNode = nsnull;
+        return NS_OK;  
       }
+
+      nsCOMPtr<nsIDOMNode> node;
+      nodeList->Item(0, getter_AddRefs(node));
+      NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
+      if (mEditor->IsMozEditorBogusNode(node))
+        mBogusNode = node;
+      else
+        mBogusNode = nsnull;
     }
   }
   return res;
 }
 
 nsresult
 nsTextEditRules::WillOutputText(nsISelection *aSelection, 
                                 const nsAString  *aOutputFormat,
--- a/editor/libeditor/text/tests/Makefile.in
+++ b/editor/libeditor/text/tests/Makefile.in
@@ -71,16 +71,17 @@ include $(topsrcdir)/config/rules.mk
 # on our editor, and the combinations depend on the system.
 ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 _TEST_FILES += \
 		test_texteditor_keyevent_handling.html \
 		$(NULL)
 endif
 
 _CHROME_TEST_FILES = \
+		test_bug471319.html \
 		test_bug483651.html \
 		test_bug636465.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs:: $(_CHROME_TEST_FILES)
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/text/tests/test_bug471319.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML>
+<!-- ***** BEGIN LICENSE BLOCK *****
+   - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+   -
+   - The contents of this file are subject to the Mozilla Public License Version
+   - 1.1 (the "License"); you may not use this file except in compliance with
+   - the License. You may obtain a copy of the License at
+   - http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS IS" basis,
+   - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+   - for the specific language governing rights and limitations under the
+   - License.
+   -
+   - The Original Code is Plaintext Editor Test code
+   -
+   - The Initial Developer of the Original Code is
+   - Graeme McCutcheon <graememcc_firefox@graeme-online.co.uk>.
+   - Portions created by the Initial Developer are Copyright (C) 2011
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the GPL or the LGPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=471319
+-->
+
+<head>
+  <title>Test for Bug 471319</title>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
+</head>
+
+<body onload="doTest();">
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=471319">Mozilla Bug 471319</a>
+  <p id="display"></p>
+  <div id="content" style="display: none">
+  </div>
+
+  <pre id="test">
+    <script type="application/javascript;version=1.7">
+
+      /** Test for Bug 471319 **/
+    
+      SimpleTest.waitForExplicitFinish();
+
+      function doTest() {
+        let t1 = $("t1");
+        let editor = null;
+
+        // Test 1: Undo on an empty editor - the editor should not forget about
+        // the bogus node
+        t1.QueryInterface(Components.interfaces.nsIDOMNSEditableElement);
+        t1Editor = t1.editor;
+
+        // Did the editor recognize the new bogus node?
+        t1Editor.undo(1);
+        ok(!t1.value, "<br> still recognized as bogus node on undo");
+
+
+        // Test 2: Redo on an empty editor - the editor should not forget about
+        // the bogus node
+        let t2 = $("t2");
+        t2.QueryInterface(Components.interfaces.nsIDOMNSEditableElement);
+        t2Editor = t2.editor;
+
+        // Did the editor recognize the new bogus node?
+        t2Editor.redo(1);
+        ok(!t2.value, "<br> still recognized as bogus node on redo");
+
+
+        // Test 3: Undoing a batched transaction where both end points of the
+        // transaction are the bogus node - the bogus node should still be
+        // recognized as bogus
+        t1Editor.transactionManager.beginBatch();
+        t1.value = "mozilla";
+        t1.value = "";
+        t1Editor.transactionManager.endBatch();
+        t1Editor.undo(1);
+        ok(!t1.value,
+           "recreated <br> from undo transaction recognized as bogus");
+
+
+        // Test 4: Redoing a batched transaction where both end points of the
+        // transaction are the bogus node - the bogus node should still be
+        // recognized as bogus
+        t1Editor.redo(1);
+        ok(!t1.value,
+           "recreated <br> from redo transaction recognized as bogus");
+        SimpleTest.finish();
+     }
+   </script>
+  </pre>
+
+  <input type="text" id="t1" />
+  <input type="text" id="t2" />
+</body>
+</html>