Bug 1518002 - Update selection cache when initializing editor. r=masayuki
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 18 Jan 2019 10:00:23 +0000
changeset 511521 16ad98f608feb829110b74171b1c4cd70867c0cf
parent 511520 3b442a1b227d70bb7c3d28b763588a8962e52ea8
child 511522 92c56dcf69b8dadf31af02054dcbfda5802000d1
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1518002, 1465702
milestone66.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 1518002 - Update selection cache when initializing editor. r=masayuki GitLab's comment calls scrollTop on input event handler. The scollTop may cause reflow. When causing reflow, editor is destroyed and initialized again. Then nsTextEditorState will set current value to editor. But this is failure. By bug 1465702, selection is cached in edit action. When initializing editor, selection controller is updated, so selection into cache becomes invalid. It means that all selection methods will return error since document is different. So we should update selection cache when initializing editor. Also, I cannot create test case for this situation since we have to cause reflow in input and/or composition event. Do you have any idea? Differential Revision: https://phabricator.services.mozilla.com/D16944
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -258,16 +258,29 @@ nsresult EditorBase::Init(Document& aDoc
     selectionController = aSelectionController;
   } else {
     nsCOMPtr<nsIPresShell> presShell = GetPresShell();
     selectionController = do_QueryInterface(presShell);
   }
   MOZ_ASSERT(selectionController,
              "Selection controller should be available at this point");
 
+  if (mEditActionData) {
+    // During edit action, selection is cached. But this selection is invalid
+    // now since selection controller is updated, so we have to update this
+    // cache.
+    Selection* selection = selectionController->GetSelection(
+        nsISelectionController::SELECTION_NORMAL);
+    NS_WARNING_ASSERTION(selection,
+                         "We cannot update selection cache in the edit action");
+    if (selection) {
+      mEditActionData->UpdateSelectionCache(*selection);
+    }
+  }
+
   // set up root element if we are passed one.
   if (aRoot) {
     mRootElement = aRoot;
   }
 
   mUpdateCount = 0;
 
   // If this is an editor for <input> or <textarea>, the text node which
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -727,16 +727,26 @@ class EditorBase : public nsIEditor,
 
     RangeUpdater& RangeUpdaterRef() {
       return mParentData ? mParentData->RangeUpdaterRef() : mRangeUpdater;
     }
     const RangeUpdater& RangeUpdaterRef() const {
       return mParentData ? mParentData->RangeUpdaterRef() : mRangeUpdater;
     }
 
+    void UpdateSelectionCache(Selection& aSelection) {
+      AutoEditActionDataSetter* actionData = this;
+      while (actionData) {
+        if (actionData->mSelection) {
+          actionData->mSelection = &aSelection;
+        }
+        actionData = actionData->mParentData;
+      }
+    }
+
    private:
     EditorBase& mEditorBase;
     RefPtr<Selection> mSelection;
     // EditAction may be nested, for example, a command may be executed
     // from mutation event listener which is run while editor changes
     // the DOM tree.  In such case, we need to handle edit action separately.
     AutoEditActionDataSetter* mParentData;