Bug 1053048 nsTextEditorState::UnbindFromFrame() should ensure to call nsTextInputListener::EditAction() for updating the content r=ehsan
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 19 Aug 2014 20:54:08 +0900
changeset 200252 99f640f313595fc5ce635439fbeb9571b7f36629
parent 200251 e8101d5f9defc1c3810c6074d6a3cf292447346d
child 200253 77bf46f52906ecd6c09a13539642be83471661a1
push id47856
push usermasayuki@d-toybox.com
push dateTue, 19 Aug 2014 11:54:21 +0000
treeherdermozilla-inbound@77bf46f52906 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1053048
milestone34.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 1053048 nsTextEditorState::UnbindFromFrame() should ensure to call nsTextInputListener::EditAction() for updating the content r=ehsan
content/html/content/src/nsTextEditorState.cpp
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -659,16 +659,18 @@ public:
   /** SetEditor gives an address to the editor that will be accessed
    *  @param aEditor the editor this listener calls for editing operations
    */
   void SetFrame(nsTextControlFrame *aFrame){mFrame = aFrame;}
 
   void SettingValue(bool aValue) { mSettingValue = aValue; }
   void SetValueChanged(bool aSetValueChanged) { mSetValueChanged = aSetValueChanged; }
 
+  bool IsInEditAction() const { return mInEditAction; }
+
   NS_DECL_ISUPPORTS
 
   NS_DECL_NSISELECTIONLISTENER
 
   NS_DECL_NSIDOMEVENTLISTENER
 
   NS_DECL_NSIEDITOROBSERVER
 
@@ -703,31 +705,36 @@ protected:
    * refrain from calling OnValueChanged.
    */
   bool mSettingValue;
   /**
    * Whether we are in the process of a SetValue call that doesn't want
    * |SetValueChanged| to be called.
    */
   bool mSetValueChanged;
+  /**
+   * mInEditAction is true while editor handling an edit action.
+   */
+  bool mInEditAction;
 };
 
 
 /*
  * nsTextInputListener implementation
  */
 
 nsTextInputListener::nsTextInputListener(nsITextControlElement* aTxtCtrlElement)
 : mFrame(nullptr)
 , mTxtCtrlElement(aTxtCtrlElement)
 , mSelectionWasCollapsed(true)
 , mHadUndoItems(false)
 , mHadRedoItems(false)
 , mSettingValue(false)
 , mSetValueChanged(true)
+, mInEditAction(false)
 {
 }
 
 nsTextInputListener::~nsTextInputListener() 
 {
 }
 
 NS_IMPL_ISUPPORTS(nsTextInputListener,
@@ -884,16 +891,18 @@ nsTextInputListener::HandleEvent(nsIDOME
   return NS_OK;
 }
 
 // BEGIN nsIEditorObserver
 
 NS_IMETHODIMP
 nsTextInputListener::EditAction()
 {
+  mInEditAction = false;
+
   nsWeakFrame weakFrame = mFrame;
 
   nsITextControlFrame* frameBase = do_QueryFrame(mFrame);
   nsTextControlFrame* frame = static_cast<nsTextControlFrame*> (frameBase);
   NS_ASSERTION(frame, "Where is our frame?");
   //
   // Update the undo / redo menus
   //
@@ -929,22 +938,24 @@ nsTextInputListener::EditAction()
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputListener::BeforeEditAction()
 {
+  mInEditAction = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsTextInputListener::CancelEditAction()
 {
+  mInEditAction = false;
   return NS_OK;
 }
 
 // END nsIEditorObserver
 
 
 nsresult
 nsTextInputListener::UpdateTextInputCommands(const nsAString& commandsToUpdate,
@@ -1513,16 +1524,23 @@ void
 nsTextEditorState::UnbindFromFrame(nsTextControlFrame* aFrame)
 {
   NS_ENSURE_TRUE_VOID(mBoundFrame);
 
   // If it was, however, it should be unbounded from the same frame.
   NS_ASSERTION(!aFrame || aFrame == mBoundFrame, "Unbinding from the wrong frame");
   NS_ENSURE_TRUE_VOID(!aFrame || aFrame == mBoundFrame);
 
+  // If the editor is modified, we need to notify it here because editor may be
+  // destroyed before EditAction() is called if selection listener causes
+  // flushing layout.
+  if (mTextListener && mTextListener->IsInEditAction()) {
+    mTextListener->EditAction();
+  }
+
   // We need to start storing the value outside of the editor if we're not
   // going to use it anymore, so retrieve it for now.
   nsAutoString value;
   GetValue(value, true);
 
   if (mRestoringSelection) {
     mRestoringSelection->Revoke();
     mRestoringSelection = nullptr;