mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 1461708 - part 4: Move implementation of UIEvent::GetRangeParent() and UIEvent::RangeOffset() to nsLayoutUtils r=smaug
We need to move EditorEventListener::HandleMiddleClickPaste() into EventStateManager to handle middle click paste after all click events are dispatched. This is preparation of the change. HandleMiddleClickPaste() uses UIEvent::GetRangeParent() and UIEvent::RangeOffset() to collapse Selection at clicked point. However, EventStateManager cannot access them since EventStateManager can handle it with WidgetMouseEvent. Fortunately, only WidgetMouseEvent is necessary for implementing them. Therefore, we can move the implementation into nsLayoutUtils and merge them. Differential Revision: https://phabricator.services.mozilla.com/D7851 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
4bc3e93065
commit
d472d6f312
@ -184,54 +184,34 @@ UIEvent::PageY() const
|
||||
already_AddRefed<nsINode>
|
||||
UIEvent::GetRangeParent()
|
||||
{
|
||||
nsIFrame* targetFrame = nullptr;
|
||||
|
||||
if (mPresContext) {
|
||||
nsCOMPtr<nsIPresShell> shell = mPresContext->GetPresShell();
|
||||
if (shell) {
|
||||
shell->FlushPendingNotifications(FlushType::Layout);
|
||||
targetFrame = mPresContext->EventStateManager()->GetEventTarget();
|
||||
}
|
||||
if (NS_WARN_IF(!mPresContext)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (targetFrame) {
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
|
||||
targetFrame);
|
||||
nsCOMPtr<nsIContent> parent = targetFrame->GetContentOffsetsFromPoint(pt).content;
|
||||
if (parent) {
|
||||
if (parent->ChromeOnlyAccess() &&
|
||||
!nsContentUtils::CanAccessNativeAnon()) {
|
||||
return nullptr;
|
||||
}
|
||||
return parent.forget();
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||
if (NS_WARN_IF(!presShell)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
nsCOMPtr<nsIContent> container;
|
||||
nsLayoutUtils::GetContainerAndOffsetAtEvent(presShell, mEvent,
|
||||
getter_AddRefs(container),
|
||||
nullptr);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
int32_t
|
||||
UIEvent::RangeOffset() const
|
||||
{
|
||||
if (!mPresContext) {
|
||||
if (NS_WARN_IF(!mPresContext)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = mPresContext->GetPresShell();
|
||||
if (!shell) {
|
||||
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||
if (NS_WARN_IF(!presShell)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
shell->FlushPendingNotifications(FlushType::Layout);
|
||||
|
||||
nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
|
||||
if (!targetFrame) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent,
|
||||
targetFrame);
|
||||
return targetFrame->GetContentOffsetsFromPoint(pt).offset;
|
||||
int32_t offset = 0;
|
||||
nsLayoutUtils::GetContainerAndOffsetAtEvent(presShell, mEvent,
|
||||
nullptr, &offset);
|
||||
return offset;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
|
@ -88,8 +88,10 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
already_AddRefed<nsINode> GetRangeParent();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
int32_t RangeOffset() const;
|
||||
|
||||
protected:
|
||||
|
@ -380,19 +380,26 @@ EditorEventListener::HandleEvent(Event* aEvent)
|
||||
switch (internalEvent->mMessage) {
|
||||
// dragenter
|
||||
case eDragEnter: {
|
||||
return DragEnter(aEvent->AsDragEvent());
|
||||
// aEvent should be grabbed by the caller since this is
|
||||
// nsIDOMEventListener method. However, our clang plugin cannot check it
|
||||
// if we use Event::As*Event(). So, we need to grab it by ourselves.
|
||||
RefPtr<DragEvent> dragEvent = aEvent->AsDragEvent();
|
||||
return DragEnter(dragEvent);
|
||||
}
|
||||
// dragover
|
||||
case eDragOver: {
|
||||
return DragOver(aEvent->AsDragEvent());
|
||||
RefPtr<DragEvent> dragEvent = aEvent->AsDragEvent();
|
||||
return DragOver(dragEvent);
|
||||
}
|
||||
// dragexit
|
||||
case eDragExit: {
|
||||
return DragExit(aEvent->AsDragEvent());
|
||||
RefPtr<DragEvent> dragEvent = aEvent->AsDragEvent();
|
||||
return DragExit(dragEvent);
|
||||
}
|
||||
// drop
|
||||
case eDrop: {
|
||||
return Drop(aEvent->AsDragEvent());
|
||||
RefPtr<DragEvent> dragEvent = aEvent->AsDragEvent();
|
||||
return Drop(dragEvent);
|
||||
}
|
||||
#ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
|
||||
// keydown
|
||||
@ -420,7 +427,7 @@ EditorEventListener::HandleEvent(Event* aEvent)
|
||||
if (mMouseDownOrUpConsumedByIME) {
|
||||
return NS_OK;
|
||||
}
|
||||
MouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
RefPtr<MouseEvent> mouseEvent = aEvent->AsMouseEvent();
|
||||
return NS_WARN_IF(!mouseEvent) ? NS_OK : MouseDown(mouseEvent);
|
||||
}
|
||||
// mouseup
|
||||
@ -441,13 +448,15 @@ EditorEventListener::HandleEvent(Event* aEvent)
|
||||
if (mMouseDownOrUpConsumedByIME) {
|
||||
return NS_OK;
|
||||
}
|
||||
MouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
RefPtr<MouseEvent> mouseEvent = aEvent->AsMouseEvent();
|
||||
return NS_WARN_IF(!mouseEvent) ? NS_OK : MouseUp(mouseEvent);
|
||||
}
|
||||
// click
|
||||
case eMouseClick: {
|
||||
MouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
NS_ENSURE_TRUE(mouseEvent, NS_OK);
|
||||
RefPtr<MouseEvent> mouseEvent = aEvent->AsMouseEvent();
|
||||
if (NS_WARN_IF(!mouseEvent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
// If the preceding mousedown event or mouseup event was consumed,
|
||||
// editor shouldn't handle this click event.
|
||||
if (mMouseDownOrUpConsumedByIME) {
|
||||
|
@ -48,7 +48,10 @@ public:
|
||||
void Disconnect();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
// nsIDOMEventListener
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHOD HandleEvent(dom::Event *aEvent) override;
|
||||
|
||||
void SpellCheckIfNeeded();
|
||||
|
||||
@ -66,17 +69,19 @@ protected:
|
||||
nsresult HandleChangeComposition(WidgetCompositionEvent* aCompositionEvent);
|
||||
nsresult HandleStartComposition(WidgetCompositionEvent* aCompositionEvent);
|
||||
void HandleEndComposition(WidgetCompositionEvent* aCompositionEvent);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult MouseDown(dom::MouseEvent* aMouseEvent);
|
||||
virtual nsresult MouseUp(dom::MouseEvent* aMouseEvent) { return NS_OK; }
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult MouseClick(dom::MouseEvent* aMouseEvent);
|
||||
nsresult Focus(InternalFocusEvent* aFocusEvent);
|
||||
nsresult Blur(InternalFocusEvent* aBlurEvent);
|
||||
nsresult DragEnter(dom::DragEvent* aDragEvent);
|
||||
nsresult DragOver(dom::DragEvent* aDragEvent);
|
||||
MOZ_CAN_RUN_SCRIPT nsresult DragEnter(dom::DragEvent* aDragEvent);
|
||||
MOZ_CAN_RUN_SCRIPT nsresult DragOver(dom::DragEvent* aDragEvent);
|
||||
nsresult DragExit(dom::DragEvent* aDragEvent);
|
||||
nsresult Drop(dom::DragEvent* aDragEvent);
|
||||
MOZ_CAN_RUN_SCRIPT nsresult Drop(dom::DragEvent* aDragEvent);
|
||||
|
||||
bool CanDrop(dom::DragEvent* aEvent);
|
||||
MOZ_CAN_RUN_SCRIPT bool CanDrop(dom::DragEvent* aEvent);
|
||||
void CleanupDragDropCaret();
|
||||
nsIPresShell* GetPresShell() const;
|
||||
nsPresContext* GetPresContext() const;
|
||||
@ -86,6 +91,7 @@ protected:
|
||||
bool EditorHasFocus();
|
||||
bool IsFileControlTextBox();
|
||||
bool ShouldHandleNativeKeyBindings(WidgetKeyboardEvent* aKeyboardEvent);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult HandleMiddleClickPaste(dom::MouseEvent* aMouseEvent);
|
||||
|
||||
/**
|
||||
|
@ -30,8 +30,10 @@ public:
|
||||
virtual nsresult Connect(EditorBase* aEditorBase) override;
|
||||
|
||||
protected:
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult MouseDown(dom::MouseEvent* aMouseEvent) override;
|
||||
virtual nsresult MouseUp(dom::MouseEvent* aMouseEvent) override;
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult MouseClick(dom::MouseEvent* aMouseEvent) override;
|
||||
};
|
||||
|
||||
|
@ -213,6 +213,7 @@ public:
|
||||
* OnDrop() is called from EditorEventListener::Drop that is handler of drop
|
||||
* event.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult OnDrop(dom::DragEvent* aDropEvent);
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/FloatingPoint.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/gfx/PathHelpers.h"
|
||||
@ -2230,6 +2231,59 @@ nsLayoutUtils::GetPopupFrameForEventCoordinates(nsPresContext* aPresContext,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutUtils::GetContainerAndOffsetAtEvent(nsIPresShell* aPresShell,
|
||||
const WidgetEvent* aEvent,
|
||||
nsIContent** aContainer,
|
||||
int32_t* aOffset)
|
||||
{
|
||||
MOZ_ASSERT(aContainer || aOffset);
|
||||
|
||||
if (aContainer) {
|
||||
*aContainer = nullptr;
|
||||
}
|
||||
if (aOffset) {
|
||||
*aOffset = 0;
|
||||
}
|
||||
|
||||
if (!aPresShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
aPresShell->FlushPendingNotifications(FlushType::Layout);
|
||||
|
||||
RefPtr<nsPresContext> presContext = aPresShell->GetPresContext();
|
||||
if (!presContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIFrame* targetFrame = presContext->EventStateManager()->GetEventTarget();
|
||||
if (!targetFrame) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPoint point =
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, targetFrame);
|
||||
|
||||
if (aContainer) {
|
||||
// TODO: This result may be useful to change to Selection. However, this
|
||||
// may return improper node (e.g., native anonymous node) for the
|
||||
// Selection. Perhaps, this should take Selection optionally and
|
||||
// if it's specified, needs to check if it's proper for the
|
||||
// Selection.
|
||||
nsCOMPtr<nsIContent> container =
|
||||
targetFrame->GetContentOffsetsFromPoint(point).content;
|
||||
if (container &&
|
||||
(!container->ChromeOnlyAccess() ||
|
||||
nsContentUtils::CanAccessNativeAnon())) {
|
||||
container.forget(aContainer);
|
||||
}
|
||||
}
|
||||
if (aOffset) {
|
||||
*aOffset = targetFrame->GetContentOffsetsFromPoint(point).offset;
|
||||
}
|
||||
}
|
||||
|
||||
static void ConstrainToCoordValues(float& aStart, float& aSize)
|
||||
{
|
||||
MOZ_ASSERT(aSize >= 0);
|
||||
|
@ -776,6 +776,22 @@ public:
|
||||
nsPresContext* aPresContext,
|
||||
const mozilla::WidgetEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Get container and offset if aEvent collapses Selection.
|
||||
* @param aPresShell The PresShell handling aEvent.
|
||||
* @param aEvent The event having coordinates where you want to
|
||||
* collapse Selection.
|
||||
* @param aContainer Returns the container node at the point.
|
||||
* Set nullptr if you don't need this.
|
||||
* @param aOffset Returns offset in the container node at the point.
|
||||
* Set nullptr if you don't need this.
|
||||
*/
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void GetContainerAndOffsetAtEvent(nsIPresShell* aPresShell,
|
||||
const mozilla::WidgetEvent* aEvent,
|
||||
nsIContent** aContainer,
|
||||
int32_t* aOffset);
|
||||
|
||||
/**
|
||||
* Translate from widget coordinates to the view's coordinates
|
||||
* @param aPresContext the PresContext for the view
|
||||
|
@ -632,7 +632,7 @@ nsXULPopupManager::InitTriggerEvent(Event* aEvent, nsIContent* aPopup,
|
||||
|
||||
mCachedModifiers = 0;
|
||||
|
||||
UIEvent* uiEvent = aEvent ? aEvent->AsUIEvent() : nullptr;
|
||||
RefPtr<UIEvent> uiEvent = aEvent ? aEvent->AsUIEvent() : nullptr;
|
||||
if (uiEvent) {
|
||||
mRangeParent = uiEvent->GetRangeParent();
|
||||
mRangeOffset = uiEvent->RangeOffset();
|
||||
|
@ -714,6 +714,7 @@ protected:
|
||||
|
||||
// set the event that was used to trigger the popup, or null to clear the
|
||||
// event details. aTriggerContent will be set to the target of the event.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
void InitTriggerEvent(mozilla::dom::Event* aEvent, nsIContent* aPopup, nsIContent** aTriggerContent);
|
||||
|
||||
// callbacks for ShowPopup and HidePopup as events may be done asynchronously
|
||||
|
Loading…
Reference in New Issue
Block a user