Move the caret invalidation from CharacterDataChanged to CharacterDataWillChange so that the text doesn't change under the caret before invalidation. Bug 887631, r=ehsan, a=abillings
authorSimon Montagu <smontagu@smontagu.org>
Sun, 21 Jul 2013 10:15:06 +0300
changeset 143114 2492f2386f35
parent 143113 9a44b2d7257c
child 143117 0d0a4155b914
push id2657
push usersmontagu@mozilla.com
push dateSun, 21 Jul 2013 07:15:43 +0000
treeherdermozilla-beta@2492f2386f35 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan, abillings
bugs887631
milestone23.0
Move the caret invalidation from CharacterDataChanged to CharacterDataWillChange so that the text doesn't change under the caret before invalidation. Bug 887631, r=ehsan, a=abillings
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -3907,35 +3907,48 @@ PresShell::FlushPendingNotifications(moz
       if (!mIsDestroying) {
         mViewManager->UpdateWidgetGeometry();
       }
     }
   }
 }
 
 void
+PresShell::CharacterDataWillChange(nsIDocument *aDocument,
+                                   nsIContent*  aContent,
+                                   CharacterDataChangeInfo* aInfo)
+{
+  NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged");
+  NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
+
+  if (mCaret) {
+    // Invalidate the caret's current location before we call into the frame
+    // constructor. It is important to do this now, and not wait until the
+    // resulting reflow, because this call causes continuation frames of the
+    // text frame the caret is in to forget what part of the content they
+    // refer to, making it hard for them to return the correct continuation
+    // frame to the caret.
+    //
+    // It's also important to do this before the content actually changes, since
+    // in bidi text the caret needs to look at the content to determine its
+    // position and shape.
+    mCaret->InvalidateOutsideCaret();
+  }
+}
+
+void
 PresShell::CharacterDataChanged(nsIDocument *aDocument,
                                 nsIContent*  aContent,
                                 CharacterDataChangeInfo* aInfo)
 {
   NS_PRECONDITION(!mIsDocumentGone, "Unexpected CharacterDataChanged");
   NS_PRECONDITION(aDocument == mDocument, "Unexpected aDocument");
 
   nsAutoCauseReflowNotifier crNotifier(this);
 
-  if (mCaret) {
-    // Invalidate the caret's current location before we call into the frame
-    // constructor. It is important to do this now, and not wait until the
-    // resulting reflow, because this call causes continuation frames of the
-    // text frame the caret is in to forget what part of the content they
-    // refer to, making it hard for them to return the correct continuation
-    // frame to the caret.
-    mCaret->InvalidateOutsideCaret();
-  }
-
   // Call this here so it only happens for real content mutations and
   // not cases when the frame constructor calls its own methods to force
   // frame reconstruction.
   nsIContent *container = aContent->GetParent();
   uint32_t selectorFlags =
     container ? (container->GetFlags() & NODE_ALL_SELECTOR_FLAGS) : 0;
   if (selectorFlags != 0 && !aContent->IsRootOfAnonymousSubtree()) {
     Element* element = container->AsElement();
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -245,16 +245,17 @@ public:
   NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETADDED
   NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETREMOVED
   NS_DECL_NSIDOCUMENTOBSERVER_STYLESHEETAPPLICABLESTATECHANGED
   NS_DECL_NSIDOCUMENTOBSERVER_STYLERULECHANGED
   NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEADDED
   NS_DECL_NSIDOCUMENTOBSERVER_STYLERULEREMOVED
 
   // nsIMutationObserver
+  NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATAWILLCHANGE
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   NS_DECL_NSIOBSERVER