Bug 1518002 - Update selection cache when initializing editor. r=masayuki, a=RyanVM
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Fri, 18 Jan 2019 10:00:23 +0000
changeset 509554 ff8f2153265d685e8486211e391a2fdc09185453
parent 509553 32f1e101f51434bb7419d30e94b4a31193cf11f8
child 509555 a95de98740380133be0ae2e6368170cf413c021c
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, RyanVM
bugs1518002, 1465702
milestone65.0
Bug 1518002 - Update selection cache when initializing editor. r=masayuki, a=RyanVM 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(nsIDocument& a
     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
@@ -726,16 +726,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;