Bug 1433345 - part 3: Make HTMLEditor store ResizerSelectionListener directly r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 26 Jan 2018 15:14:04 +0900
changeset 748211 421d672ccb1d3b0ae09cb583795b6750d2213b96
parent 748210 56edc2197f05783ae7bffdfd00ef057de2731c31
child 748212 437ebf52fe2ee796a1664fbb2d693bf304ae9246
push id97089
push usermasayuki@d-toybox.com
push dateMon, 29 Jan 2018 07:02:13 +0000
reviewersm_kato
bugs1433345
milestone60.0a1
Bug 1433345 - part 3: Make HTMLEditor store ResizerSelectionListener directly r?m_kato This patch makes HTMLEditor store ResizerSelectionListener directly and make it cycle collectable. However, in the following patch, this class will be removed completely because it doesn't necessary if HTMLEditor becomes a selection listener. MozReview-Commit-ID: 2iXlTcZdzvj
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLEditorObjectResizer.cpp
editor/libeditor/HTMLEditorObjectResizerUtils.h
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -141,29 +141,26 @@ HTMLEditor::~HTMLEditor()
     mRules->AsHTMLEditRules()->EndListeningToEditActions();
   }
 
   //the autopointers will clear themselves up.
   //but we need to also remove the listeners or we have a leak
   RefPtr<Selection> selection = GetSelection();
   // if we don't get the selection, just skip this
   if (selection) {
-    nsCOMPtr<nsISelectionListener>listener;
-    listener = do_QueryInterface(mTypeInState);
-    if (listener) {
-      selection->RemoveSelectionListener(listener);
+    if (mTypeInState) {
+      selection->RemoveSelectionListener(mTypeInState);
     }
-    listener = do_QueryInterface(mSelectionListenerP);
-    if (listener) {
-      selection->RemoveSelectionListener(listener);
+    if (mResizerSelectionListener) {
+      selection->RemoveSelectionListener(mResizerSelectionListener);
     }
   }
 
   mTypeInState = nullptr;
-  mSelectionListenerP = nullptr;
+  mResizerSelectionListener = nullptr;
 
   if (mLinkHandler && IsInitialized()) {
     nsCOMPtr<nsIPresShell> ps = GetPresShell();
 
     if (ps && ps->GetPresContext()) {
       ps->GetPresContext()->SetLinkHandler(mLinkHandler);
     }
   }
@@ -197,32 +194,32 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   tmp->HideAnonymousEditingUIs();
 
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLinkHandler)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLEditor, TextEditor)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTypeInState)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mComposerCommandsUpdater)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizerSelectionListener)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopLeftHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTopRightHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLeftHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRightHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBottomLeftHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBottomHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBottomRightHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActivatedHandle)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizingShadow)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizingInfo)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizedObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMouseMotionListenerP)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionListenerP)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizeEventListenerP)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAbsolutelyPositionedObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGrabber)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPositioningShadow)
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInlineEditedCell)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAddColumnBeforeButton)
@@ -298,33 +295,30 @@ HTMLEditor::Init(nsIDOMDocument* aDoc,
       mLinkHandler = context->GetLinkHandler();
       context->SetLinkHandler(nullptr);
     }
 
     // init the type-in state
     mTypeInState = new TypeInState();
 
     // init the selection listener for image resizing
-    mSelectionListenerP = new ResizerSelectionListener(*this);
+    mResizerSelectionListener = new ResizerSelectionListener(*this);
 
     if (!IsInteractionAllowed()) {
       // ignore any errors from this in case the file is missing
       AddOverrideStyleSheet(NS_LITERAL_STRING("resource://gre/res/EditorOverride.css"));
     }
 
     RefPtr<Selection> selection = GetSelection();
     if (selection) {
-      nsCOMPtr<nsISelectionListener>listener;
-      listener = do_QueryInterface(mTypeInState);
-      if (listener) {
-        selection->AddSelectionListener(listener);
+      if (mTypeInState) {
+        selection->AddSelectionListener(mTypeInState);
       }
-      listener = do_QueryInterface(mSelectionListenerP);
-      if (listener) {
-        selection->AddSelectionListener(listener);
+      if (mResizerSelectionListener) {
+        selection->AddSelectionListener(mResizerSelectionListener);
       }
     }
   }
   NS_ENSURE_SUCCESS(rulesRv, rulesRv);
 
   return NS_OK;
 }
 
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -44,16 +44,17 @@ class nsILinkHandler;
 class nsTableWrapperFrame;
 class nsIDOMRange;
 class nsRange;
 
 namespace mozilla {
 class AutoSelectionSetterAfterTableEdit;
 class HTMLEditorEventListener;
 class HTMLEditRules;
+class ResizerSelectionListener;
 class TypeInState;
 class WSRunObject;
 enum class EditAction : int32_t;
 struct PropItem;
 template<class T> class OwningNonNull;
 namespace dom {
 class DocumentFragment;
 } // namespace dom
@@ -984,16 +985,17 @@ protected:
    */
   void SetSelectionAfterTableEdit(nsIDOMElement* aTable,
                                   int32_t aRow, int32_t aCol,
                                   int32_t aDirection, bool aSelected);
 
 protected:
   RefPtr<TypeInState> mTypeInState;
   RefPtr<ComposerCommandsUpdater> mComposerCommandsUpdater;
+  RefPtr<ResizerSelectionListener> mResizerSelectionListener;
 
   bool mCRInParagraphCreatesParagraph;
 
   bool mCSSAware;
   UniquePtr<CSSEditUtils> mCSSEditUtils;
 
   // Used by GetFirstSelectedCell and GetNextSelectedCell
   int32_t  mSelectedCellIndex;
@@ -1067,17 +1069,16 @@ protected:
   nsCOMPtr<Element> mActivatedHandle;
 
   ManualNACPtr mResizingShadow;
   ManualNACPtr mResizingInfo;
 
   nsCOMPtr<Element> mResizedObject;
 
   nsCOMPtr<nsIDOMEventListener>  mMouseMotionListenerP;
-  nsCOMPtr<nsISelectionListener> mSelectionListenerP;
   nsCOMPtr<nsIDOMEventListener>  mResizeEventListenerP;
 
   int32_t mOriginalX;
   int32_t mOriginalY;
 
   int32_t mResizedObjectX;
   int32_t mResizedObjectY;
   int32_t mResizedObjectWidth;
--- a/editor/libeditor/HTMLEditorObjectResizer.cpp
+++ b/editor/libeditor/HTMLEditorObjectResizer.cpp
@@ -66,34 +66,47 @@ DocumentResizeEventListener::HandleEvent
   }
   return NS_OK;
 }
 
 /******************************************************************************
  * mozilla::ResizerSelectionListener
  ******************************************************************************/
 
-NS_IMPL_ISUPPORTS(ResizerSelectionListener, nsISelectionListener)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizerSelectionListener)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizerSelectionListener)
+
+NS_INTERFACE_MAP_BEGIN(ResizerSelectionListener)
+  NS_INTERFACE_MAP_ENTRY(nsISelectionListener)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISelectionListener)
+  NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(ResizerSelectionListener)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION(ResizerSelectionListener,
+                         mHTMLEditor)
 
 ResizerSelectionListener::ResizerSelectionListener(HTMLEditor& aHTMLEditor)
-  : mHTMLEditorWeak(&aHTMLEditor)
+  : mHTMLEditor(&aHTMLEditor)
 {
 }
 
 NS_IMETHODIMP
 ResizerSelectionListener::NotifySelectionChanged(nsIDOMDocument* aDOMDocument,
                                                  nsISelection* aSelection,
                                                  int16_t aReason)
 {
+  if (!mHTMLEditor) {
+    return NS_OK;
+  }
   if ((aReason & (nsISelectionListener::MOUSEDOWN_REASON |
                   nsISelectionListener::KEYPRESS_REASON |
                   nsISelectionListener::SELECTALL_REASON)) && aSelection) {
     // the selection changed and we need to check if we have to
     // hide and/or redisplay resizing handles
-    RefPtr<HTMLEditor> htmlEditor = mHTMLEditorWeak.get();
+    RefPtr<HTMLEditor> htmlEditor = mHTMLEditor;
     if (htmlEditor) {
       htmlEditor->CheckSelectionStateForAnonymousButtons(aSelection);
     }
   }
 
   return NS_OK;
 }
 
--- a/editor/libeditor/HTMLEditorObjectResizerUtils.h
+++ b/editor/libeditor/HTMLEditorObjectResizerUtils.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef HTMLEditorObjectResizerUtils_h
 #define HTMLEditorObjectResizerUtils_h
 
 #include "mozilla/HTMLEditor.h"
+#include "nsCycleCollectionParticipant.h"
 #include "nsIDOMEventListener.h"
 #include "nsISelectionListener.h"
 #include "nsISupportsImpl.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsLiteralString.h"
 
 class nsIHTMLEditor;
 
@@ -31,22 +32,25 @@ namespace mozilla {
  ******************************************************************************/
 
 class ResizerSelectionListener final : public nsISelectionListener
 {
 public:
   explicit ResizerSelectionListener(HTMLEditor& aHTMLEditor);
   void Reset();
 
-  NS_DECL_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ResizerSelectionListener,
+                                           nsISelectionListener)
+
   NS_DECL_NSISELECTIONLISTENER
 
 protected:
-  virtual ~ResizerSelectionListener() {}
-  CachedWeakPtr<HTMLEditor, nsIHTMLEditor> mHTMLEditorWeak;
+  virtual ~ResizerSelectionListener() = default;
+  RefPtr<HTMLEditor> mHTMLEditor;
 };
 
 /******************************************************************************
  * mozilla::ResizerMouseMotionListener
  ******************************************************************************/
 
 class ResizerMouseMotionListener final : public nsIDOMEventListener
 {