diff --git a/editor/libeditor/HTMLAbsPositionEditor.cpp b/editor/libeditor/HTMLAbsPositionEditor.cpp
index 30a27801cf66..c8e092dbfea9 100644
--- a/editor/libeditor/HTMLAbsPositionEditor.cpp
+++ b/editor/libeditor/HTMLAbsPositionEditor.cpp
@@ -6,6 +6,7 @@
#include
+#include "HTMLEditorEventListener.h"
#include "HTMLEditorObjectResizerUtils.h"
#include "HTMLEditRules.h"
#include "HTMLEditUtils.h"
@@ -436,20 +437,14 @@ HTMLEditor::SnapToGrid(int32_t& newX, int32_t& newY)
nsresult
HTMLEditor::GrabberClicked()
{
- // add a mouse move listener to the editor
- nsresult rv = NS_OK;
- if (!mMouseMotionListenerP) {
- EventTarget* eventTarget = GetDOMEventTarget();
- if (NS_WARN_IF(!eventTarget)) {
- return NS_ERROR_FAILURE;
- }
- mMouseMotionListenerP = new ResizerMouseMotionListener(*this);
- EventListenerManager* eventListenerManager =
- eventTarget->GetOrCreateListenerManager();
- eventListenerManager->AddEventListenerByType(
- mMouseMotionListenerP,
- NS_LITERAL_STRING("mousemove"),
- TrustedEventsAtSystemGroupBubble());
+ if (NS_WARN_IF(!mEventListener)) {
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+ nsresult rv =
+ static_cast(mEventListener.get())->
+ ListenToMouseMoveEventForGrabber(true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return NS_OK;
}
mGrabberClicked = true;
return rv;
@@ -467,16 +462,13 @@ HTMLEditor::EndMoving()
mPositioningShadow = nullptr;
}
- EventTarget* eventTarget = GetDOMEventTarget();
- if (eventTarget && mMouseMotionListenerP) {
- EventListenerManager* eventListenerManager =
- eventTarget->GetOrCreateListenerManager();
- eventListenerManager->RemoveEventListenerByType(
- mMouseMotionListenerP,
- NS_LITERAL_STRING("mousemove"),
- TrustedEventsAtSystemGroupBubble());
+ if (mEventListener) {
+ DebugOnly rvIgnored =
+ static_cast(mEventListener.get())->
+ ListenToMouseMoveEventForGrabber(false);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
+ "Failed to remove mousemove event listener");
}
- mMouseMotionListenerP = nullptr;
mGrabberClicked = false;
mIsMoving = false;
diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp
index ba2902a922ea..fb8f98cd5262 100644
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -286,7 +286,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLEditor, TextEditor)
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(mAbsolutelyPositionedObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGrabber)
@@ -543,27 +542,6 @@ HTMLEditor::RemoveEventListeners()
return;
}
- RefPtr target = GetDOMEventTarget();
-
- if (target) {
- // mMouseMotionListenerP can be registerd with other targets than the DOM
- // event receiver that we can reach from here. But nonetheless, unregister
- // the event listener with the DOM event receiver (if it's registerd with
- // other targets, it'll get unregisterd once the target goes
- // away).
-
- if (mMouseMotionListenerP) {
- // mMouseMotionListenerP might be registerd either as bubbling or
- // capturing, unregister by both.
- target->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
- mMouseMotionListenerP, false);
- target->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
- mMouseMotionListenerP, true);
- }
- }
-
- mMouseMotionListenerP = nullptr;
-
TextEditor::RemoveEventListeners();
}
diff --git a/editor/libeditor/HTMLEditor.h b/editor/libeditor/HTMLEditor.h
index bf6a5ea2eb16..16383d04eeea 100644
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -227,7 +227,7 @@ public:
* event callback when the mouse pointer is moved
* @param aMouseEvent [IN] the event
*/
- nsresult OnMouseMove(dom::MouseEvent* aMouseEvent);
+ MOZ_CAN_RUN_SCRIPT nsresult OnMouseMove(dom::MouseEvent* aMouseEvent);
/**
* IsCSSEnabled() returns true if this editor treats styles with style
@@ -2559,8 +2559,6 @@ protected:
RefPtr mResizedObject;
- nsCOMPtr mMouseMotionListenerP;
-
int32_t mOriginalX;
int32_t mOriginalY;
diff --git a/editor/libeditor/HTMLEditorEventListener.cpp b/editor/libeditor/HTMLEditorEventListener.cpp
index 0bfec7eaac1e..5203d54e6130 100644
--- a/editor/libeditor/HTMLEditorEventListener.cpp
+++ b/editor/libeditor/HTMLEditorEventListener.cpp
@@ -45,6 +45,16 @@ HTMLEditorEventListener::Disconnect()
EditorEventListener::Disconnect();
}
+ if (mListeningToMouseMoveEventForResizers) {
+ DebugOnly rvIgnored = ListenToMouseMoveEventForResizers(false);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
+ "Failed to remove resize event listener of resizers");
+ }
+ if (mListeningToMouseMoveEventForGrabber) {
+ DebugOnly rvIgnored = ListenToMouseMoveEventForGrabber(false);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
+ "Failed to remove resize event listener of grabber");
+ }
if (mListeningToResizeEvent) {
DebugOnly rvIgnored = ListenToWindowResizeEvent(false);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
@@ -59,6 +69,23 @@ HTMLEditorEventListener::HandleEvent(Event* aEvent)
{
WidgetEvent* internalEvent = aEvent->WidgetEventPtr();
switch (internalEvent->mMessage) {
+ case eMouseMove: {
+ if (DetachedFromEditor()) {
+ return NS_OK;
+ }
+
+ RefPtr mouseEvent = aEvent->AsMouseEvent();
+ if (NS_WARN_IF(!mouseEvent)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr htmlEditor = mEditorBase->AsHTMLEditor();
+ MOZ_ASSERT(htmlEditor);
+ DebugOnly rvIgnored = htmlEditor->OnMouseMove(mouseEvent);
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
+ "Resizers failed to handle mousemove events");
+ return NS_OK;
+ }
case eResize: {
if (DetachedFromEditor()) {
return NS_OK;
@@ -80,6 +107,82 @@ HTMLEditorEventListener::HandleEvent(Event* aEvent)
return NS_OK;
}
}
+
+nsresult
+HTMLEditorEventListener::ListenToMouseMoveEventForResizersOrGrabber(
+ bool aListen,
+ bool aForGrabber)
+{
+ MOZ_ASSERT(aForGrabber ?
+ mListeningToMouseMoveEventForGrabber != aListen :
+ mListeningToMouseMoveEventForResizers != aListen);
+
+ if (NS_WARN_IF(DetachedFromEditor())) {
+ return aListen ? NS_ERROR_FAILURE : NS_OK;
+ }
+
+ if (aListen) {
+ if (aForGrabber && mListeningToMouseMoveEventForResizers) {
+ // We've already added mousemove event listener for resizers.
+ mListeningToMouseMoveEventForGrabber = true;
+ return NS_OK;
+ }
+ if (!aForGrabber && mListeningToMouseMoveEventForGrabber) {
+ // We've already added mousemove event listener for grabber.
+ mListeningToMouseMoveEventForResizers = true;
+ return NS_OK;
+ }
+ } else {
+ if (aForGrabber && mListeningToMouseMoveEventForResizers) {
+ // We need to keep listening to mousemove event listener for resizers.
+ mListeningToMouseMoveEventForGrabber = false;
+ return NS_OK;
+ }
+ if (!aForGrabber && mListeningToMouseMoveEventForGrabber) {
+ // We need to keep listening to mousemove event listener for grabber.
+ mListeningToMouseMoveEventForResizers = false;
+ return NS_OK;
+ }
+ }
+
+ EventTarget* target = mEditorBase->AsHTMLEditor()->GetDOMEventTarget();
+ if (NS_WARN_IF(!target)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Listen to mousemove events in the system group since web apps may stop
+ // propagation before we receive the events.
+ EventListenerManager* eventListenerManager =
+ target->GetOrCreateListenerManager();
+ if (NS_WARN_IF(!eventListenerManager)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (aListen) {
+ eventListenerManager->AddEventListenerByType(
+ this,
+ NS_LITERAL_STRING("mousemove"),
+ TrustedEventsAtSystemGroupBubble());
+ if (aForGrabber) {
+ mListeningToMouseMoveEventForGrabber = true;
+ } else {
+ mListeningToMouseMoveEventForResizers = true;
+ }
+ return NS_OK;
+ }
+
+ eventListenerManager->RemoveEventListenerByType(
+ this,
+ NS_LITERAL_STRING("mousemove"),
+ TrustedEventsAtSystemGroupBubble());
+ if (aForGrabber) {
+ mListeningToMouseMoveEventForGrabber = false;
+ } else {
+ mListeningToMouseMoveEventForResizers = false;
+ }
+ return NS_OK;
+}
+
nsresult
HTMLEditorEventListener::ListenToWindowResizeEvent(bool aListen)
{
diff --git a/editor/libeditor/HTMLEditorEventListener.h b/editor/libeditor/HTMLEditorEventListener.h
index 5f5e7171d2c8..d6081f3fe150 100644
--- a/editor/libeditor/HTMLEditorEventListener.h
+++ b/editor/libeditor/HTMLEditorEventListener.h
@@ -18,6 +18,8 @@ class HTMLEditorEventListener final : public EditorEventListener
public:
HTMLEditorEventListener()
: EditorEventListener()
+ , mListeningToMouseMoveEventForResizers(false)
+ , mListeningToMouseMoveEventForGrabber(false)
, mListeningToResizeEvent(false)
{
}
@@ -37,6 +39,41 @@ public:
virtual void Disconnect() override;
+ /**
+ * ListenToMouseMoveEventForResizers() starts to listen to or stop
+ * listening to "mousemove" events for resizers.
+ */
+ nsresult ListenToMouseMoveEventForResizers(bool aListen)
+ {
+ if (aListen == mListeningToMouseMoveEventForResizers) {
+ return NS_OK;
+ }
+ nsresult rv =
+ ListenToMouseMoveEventForResizersOrGrabber(aListen, false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
+ /**
+ * ListenToMouseMoveEventForResizers() starts to listen to or stop
+ * listening to "mousemove" events for grabber to move absolutely
+ * positioned element.
+ */
+ nsresult ListenToMouseMoveEventForGrabber(bool aListen)
+ {
+ if (aListen == mListeningToMouseMoveEventForGrabber) {
+ return NS_OK;
+ }
+ nsresult rv =
+ ListenToMouseMoveEventForResizersOrGrabber(aListen, true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
+ }
+
/**
* ListenToWindowResizeEvent() starts to listen to or stop listening to
* "resize" events of the document.
@@ -50,6 +87,11 @@ protected:
MOZ_CAN_RUN_SCRIPT
virtual nsresult MouseClick(WidgetMouseEvent* aMouseClickEvent) override;
+ nsresult
+ ListenToMouseMoveEventForResizersOrGrabber(bool aListen, bool aForGrabber);
+
+ bool mListeningToMouseMoveEventForResizers;
+ bool mListeningToMouseMoveEventForGrabber;
bool mListeningToResizeEvent;
};
diff --git a/editor/libeditor/HTMLEditorObjectResizer.cpp b/editor/libeditor/HTMLEditorObjectResizer.cpp
index 167cca8e52d2..58758fb6b7c6 100644
--- a/editor/libeditor/HTMLEditorObjectResizer.cpp
+++ b/editor/libeditor/HTMLEditorObjectResizer.cpp
@@ -39,36 +39,6 @@ namespace mozilla {
using namespace dom;
-/******************************************************************************
- * mozilla::ResizerMouseMotionListener
- ******************************************************************************/
-
-NS_IMPL_ISUPPORTS(ResizerMouseMotionListener, nsIDOMEventListener)
-
-ResizerMouseMotionListener::ResizerMouseMotionListener(HTMLEditor& aHTMLEditor)
- : mHTMLEditorWeak(&aHTMLEditor)
-{
-}
-
-NS_IMETHODIMP
-ResizerMouseMotionListener::HandleEvent(Event* aMouseEvent)
-{
- MouseEvent* mouseEvent = aMouseEvent->AsMouseEvent();
- if (!mouseEvent) {
- //non-ui event passed in. bad things.
- return NS_OK;
- }
-
- // Don't do anything special if not an HTML object resizer editor
- RefPtr htmlEditor = mHTMLEditorWeak.get();
- if (htmlEditor) {
- // check if we have to redisplay a resizing shadow
- htmlEditor->OnMouseMove(mouseEvent);
- }
-
- return NS_OK;
-}
-
/******************************************************************************
* mozilla::HTMLEditor
******************************************************************************/
@@ -529,8 +499,6 @@ HTMLEditor::HideResizersInternal()
ManualNACPtr resizingShadow(std::move(mResizingShadow));
ManualNACPtr resizingInfo(std::move(mResizingInfo));
RefPtr activatedHandle(std::move(mActivatedHandle));
- nsCOMPtr mouseMotionListener(
- std::move(mMouseMotionListenerP));
RefPtr resizedObject(std::move(mResizedObject));
// Remvoe all handles.
@@ -573,13 +541,15 @@ HTMLEditor::HideResizersInternal()
// Remove resizing state of the target element.
resizedObject->UnsetAttr(kNameSpaceID_None, nsGkAtoms::_moz_resizing, true);
- // Remove mousemove event listener from the event target.
- nsCOMPtr target = GetDOMEventTarget();
- NS_WARNING_ASSERTION(target, "GetDOMEventTarget() returned nullptr");
+ if (!mEventListener) {
+ return NS_OK;
+ }
- if (target && mouseMotionListener) {
- target->RemoveEventListener(NS_LITERAL_STRING("mousemove"),
- mouseMotionListener, true);
+ nsresult rv =
+ static_cast(mEventListener.get())->
+ ListenToMouseMoveEventForResizers(false);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
}
// Remove resize event listener from the window.
@@ -587,9 +557,8 @@ HTMLEditor::HideResizersInternal()
return NS_OK;
}
- nsresult rv =
- static_cast(mEventListener.get())->
- ListenToWindowResizeEvent(false);
+ rv = static_cast(mEventListener.get())->
+ ListenToWindowResizeEvent(false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@@ -654,22 +623,16 @@ HTMLEditor::StartResizing(Element* aHandle)
mResizedObjectHeight);
// add a mouse move listener to the editor
- nsresult result = NS_OK;
- if (!mMouseMotionListenerP) {
- mMouseMotionListenerP = new ResizerMouseMotionListener(*this);
- if (!mMouseMotionListenerP) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- EventTarget* target = GetDOMEventTarget();
- NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
-
- result = target->AddEventListener(NS_LITERAL_STRING("mousemove"),
- mMouseMotionListenerP, true);
- NS_ASSERTION(NS_SUCCEEDED(result),
- "failed to register mouse motion listener");
+ if (NS_WARN_IF(!mEventListener)) {
+ return NS_ERROR_NOT_INITIALIZED;
}
- return result;
+ nsresult rv =
+ static_cast(mEventListener.get())->
+ ListenToMouseMoveEventForResizers(true);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ return NS_OK;
}
nsresult
diff --git a/editor/libeditor/HTMLEditorObjectResizerUtils.h b/editor/libeditor/HTMLEditorObjectResizerUtils.h
index b08094399a56..223e42fc5196 100644
--- a/editor/libeditor/HTMLEditorObjectResizerUtils.h
+++ b/editor/libeditor/HTMLEditorObjectResizerUtils.h
@@ -26,23 +26,6 @@ namespace mozilla {
#define kBottom NS_LITERAL_STRING("s")
#define kBottomRight NS_LITERAL_STRING("se")
-/******************************************************************************
- * mozilla::ResizerMouseMotionListener
- ******************************************************************************/
-
-class ResizerMouseMotionListener final : public nsIDOMEventListener
-{
-public:
- explicit ResizerMouseMotionListener(HTMLEditor& aHTMLEditor);
-
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDOMEVENTLISTENER
-
-protected:
- virtual ~ResizerMouseMotionListener() {}
- CachedWeakPtr mHTMLEditorWeak;
-};
-
} // namespace mozilla
#endif // #ifndef HTMLEditorObjectResizerUtils_h