Bug 1848409 - Tweak the UpdateDefaultPreventedOnContent call to only special case the HTMLEditorEventListener case r=masayuki,dom-core

Calling `UpdateDefaultPreventedOnContent` separately from
`PreventDefault()` is error-prone. This patch should make it
safer.

Differential Revision: https://phabricator.services.mozilla.com/D186052
This commit is contained in:
Sean Feng
2023-08-15 13:46:42 +00:00
parent 37f42b0c3e
commit 036a480b6a
7 changed files with 43 additions and 40 deletions

View File

@@ -924,10 +924,6 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent) {
handler->CanDropLink(dragEvent, false, &canDropLink); handler->CanDropLink(dragEvent, false, &canDropLink);
if (canDropLink) { if (canDropLink) {
aEvent->PreventDefault(); aEvent->PreventDefault();
WidgetDragEvent* asWidgetDropEvent =
dragEvent->WidgetEventPtr()->AsDragEvent();
asWidgetDropEvent->UpdateDefaultPreventedOnContent(
asWidgetDropEvent->mCurrentTarget);
} }
} else if (eventType.EqualsLiteral("drop")) { } else if (eventType.EqualsLiteral("drop")) {
nsCOMPtr<nsIWebNavigation> webnav = nsCOMPtr<nsIWebNavigation> webnav =
@@ -979,10 +975,6 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent) {
} else { } else {
aEvent->StopPropagation(); aEvent->StopPropagation();
aEvent->PreventDefault(); aEvent->PreventDefault();
WidgetDragEvent* asWidgetDropEvent =
dragEvent->WidgetEventPtr()->AsDragEvent();
asWidgetDropEvent->UpdateDefaultPreventedOnContent(
asWidgetDropEvent->mCurrentTarget);
} }
} }

View File

@@ -437,13 +437,39 @@ void Event::PreventDefaultInternal(bool aCalledByDefaultHandler,
return; return;
} }
// If this is called by default handlers, the caller will call if (mEvent->mClass == eDragEventClass) {
// UpdateDefaultPreventedOnContent when necessary. UpdateDefaultPreventedOnContentForDragEvent();
if (!aCalledByDefaultHandler) { }
if (WidgetDragEvent* dragEvent = mEvent->AsDragEvent()) { }
dragEvent->UpdateDefaultPreventedOnContent(dragEvent->mCurrentTarget);
void Event::UpdateDefaultPreventedOnContentForDragEvent() {
WidgetDragEvent* dragEvent = mEvent->AsDragEvent();
if (!dragEvent) {
return;
}
nsIPrincipal* principal = nullptr;
// Since we now have HTMLEditorEventListener registered on nsWindowRoot,
// mCurrentTarget could be nsWindowRoot, so we need to use
// mTarget if that's the case.
MOZ_ASSERT_IF(dragEvent->mInHTMLEditorEventListener,
mEvent->mCurrentTarget->IsRootWindow());
EventTarget* target = dragEvent->mInHTMLEditorEventListener
? mEvent->mTarget
: mEvent->mCurrentTarget;
nsINode* node = nsINode::FromEventTargetOrNull(target);
if (node) {
principal = node->NodePrincipal();
} else {
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(target);
if (sop) {
principal = sop->GetPrincipal();
} }
} }
if (principal && !principal->IsSystemPrincipal()) {
dragEvent->mDefaultPreventedOnContent = true;
}
} }
void Event::SetEventType(const nsAString& aEventTypeArg) { void Event::SetEventType(const nsAString& aEventTypeArg) {

View File

@@ -84,6 +84,8 @@ class Event : public nsISupports, public nsWrapperCache {
void ConstructorInit(EventTarget* aOwner, nsPresContext* aPresContext, void ConstructorInit(EventTarget* aOwner, nsPresContext* aPresContext,
WidgetEvent* aEvent); WidgetEvent* aEvent);
void UpdateDefaultPreventedOnContentForDragEvent();
public: public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Event) NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(Event)

View File

@@ -311,25 +311,6 @@ uint16_t MouseEvent::InputSource() const {
} // namespace mozilla::dom } // namespace mozilla::dom
using namespace mozilla; using namespace mozilla;
void WidgetDragEvent::UpdateDefaultPreventedOnContent(
dom::EventTarget* aTarget) {
MOZ_ASSERT(DefaultPrevented());
nsIPrincipal* principal = nullptr;
nsINode* node = nsINode::FromEventTargetOrNull(aTarget);
if (node) {
principal = node->NodePrincipal();
} else {
nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aTarget);
if (sop) {
principal = sop->GetPrincipal();
}
}
if (principal && !principal->IsSystemPrincipal()) {
mDefaultPreventedOnContent = true;
}
}
using namespace mozilla::dom; using namespace mozilla::dom;
already_AddRefed<MouseEvent> NS_NewDOMMouseEvent(EventTarget* aOwner, already_AddRefed<MouseEvent> NS_NewDOMMouseEvent(EventTarget* aOwner,

View File

@@ -875,10 +875,13 @@ nsresult EditorEventListener::DragOverOrDrop(DragEvent* aDragEvent) {
return NS_OK; return NS_OK;
} }
aDragEvent->PreventDefault();
WidgetDragEvent* asWidgetEvent = aDragEvent->WidgetEventPtr()->AsDragEvent(); WidgetDragEvent* asWidgetEvent = aDragEvent->WidgetEventPtr()->AsDragEvent();
asWidgetEvent->UpdateDefaultPreventedOnContent(asWidgetEvent->mTarget); AutoRestore<bool> inHTMLEditorEventListener(
asWidgetEvent->mInHTMLEditorEventListener);
if (mEditorBase->IsHTMLEditor()) {
asWidgetEvent->mInHTMLEditorEventListener = true;
}
aDragEvent->PreventDefault();
aDragEvent->StopImmediatePropagation(); aDragEvent->StopImmediatePropagation();

View File

@@ -226,8 +226,6 @@ nsFileControlFrame::DnDListener::HandleEvent(Event* aEvent) {
if (eventType.EqualsLiteral("dragover")) { if (eventType.EqualsLiteral("dragover")) {
// Prevent default if we can accept this drag data // Prevent default if we can accept this drag data
aEvent->PreventDefault(); aEvent->PreventDefault();
WidgetDragEvent* asWidgetEvent = dragEvent->WidgetEventPtr()->AsDragEvent();
asWidgetEvent->UpdateDefaultPreventedOnContent(asWidgetEvent->mTarget);
return NS_OK; return NS_OK;
} }

View File

@@ -347,7 +347,8 @@ class WidgetDragEvent : public WidgetMouseEvent {
: WidgetMouseEvent(aIsTrusted, aMessage, aWidget, eDragEventClass, eReal, : WidgetMouseEvent(aIsTrusted, aMessage, aWidget, eDragEventClass, eReal,
aTime), aTime),
mUserCancelled(false), mUserCancelled(false),
mDefaultPreventedOnContent(false) {} mDefaultPreventedOnContent(false),
mInHTMLEditorEventListener(false) {}
virtual WidgetEvent* Duplicate() const override { virtual WidgetEvent* Duplicate() const override {
MOZ_ASSERT(mClass == eDragEventClass, MOZ_ASSERT(mClass == eDragEventClass,
@@ -367,6 +368,8 @@ class WidgetDragEvent : public WidgetMouseEvent {
bool mUserCancelled; bool mUserCancelled;
// If this is true, the drag event's preventDefault() is called on content. // If this is true, the drag event's preventDefault() is called on content.
bool mDefaultPreventedOnContent; bool mDefaultPreventedOnContent;
// If this event is currently being handled by HTMLEditorEventListener.
bool mInHTMLEditorEventListener;
// XXX Not tested by test_assign_event_data.html // XXX Not tested by test_assign_event_data.html
void AssignDragEventData(const WidgetDragEvent& aEvent, bool aCopyTargets) { void AssignDragEventData(const WidgetDragEvent& aEvent, bool aCopyTargets) {
@@ -378,8 +381,6 @@ class WidgetDragEvent : public WidgetMouseEvent {
mDefaultPreventedOnContent = aEvent.mDefaultPreventedOnContent; mDefaultPreventedOnContent = aEvent.mDefaultPreventedOnContent;
} }
void UpdateDefaultPreventedOnContent(dom::EventTarget* aTarget);
/** /**
* Should be called before dispatching the DOM tree if this event is * Should be called before dispatching the DOM tree if this event is
* synthesized for tests because drop effect is initialized before * synthesized for tests because drop effect is initialized before