Bug 1177346 Part 1 - Add setSuppressedEventListener interface, r=smaug.

--HG--
extra : rebase_source : a01b747e49f06fe6ef7724e38648ea28601b2793
This commit is contained in:
Brian Hackett 2019-01-03 06:39:12 -10:00
parent e0ab49f760
commit c73140a5cf
4 changed files with 51 additions and 0 deletions

View File

@ -1746,6 +1746,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(Document)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnonymousContents)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCommandDispatcher)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFeaturePolicy)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSuppressedEventListener)
// Traverse all our nsCOMArrays.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
@ -1837,6 +1838,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Document)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCommandDispatcher)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentL10n);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFeaturePolicy)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSuppressedEventListener)
tmp->mParentDocument = nullptr;
@ -8492,6 +8494,17 @@ void Document::AddSuspendedChannelEventQueue(net::ChannelEventQueue* aQueue) {
mSuspendedQueues.AppendElement(aQueue);
}
static bool SetSuppressedEventListenerInSubDocument(Document* aDocument,
void* aData) {
aDocument->SetSuppressedEventListener(static_cast<EventListener*>(aData));
return true;
}
void Document::SetSuppressedEventListener(EventListener* aListener) {
mSuppressedEventListener = aListener;
EnumerateSubDocuments(SetSuppressedEventListenerInSubDocument, aListener);
}
nsISupports* Document::GetCurrentContentSink() {
return mParser ? mParser->GetContentSink() : nullptr;
}

View File

@ -2446,6 +2446,12 @@ class Document : public nsINode,
*/
bool IsVisibleConsideringAncestors() const;
void SetSuppressedEventListener(EventListener* aListener);
EventListener* GetSuppressedEventListener() {
return mSuppressedEventListener;
}
/**
* Return true when this document is active, i.e., an active document
* in a content viewer. Note that this will return true for bfcached
@ -4137,6 +4143,8 @@ class Document : public nsINode,
// events were suppressed.
nsTArray<RefPtr<mozilla::net::ChannelEventQueue>> mSuspendedQueues;
RefPtr<EventListener> mSuppressedEventListener;
/**
* https://html.spec.whatwg.org/#ignore-destructive-writes-counter
*/

View File

@ -505,6 +505,14 @@ partial interface Document {
void notifyUserGestureActivation();
};
// Extension to give chrome JS the ability to set an event handler which is
// called with certain events that happened while events were suppressed in the
// document or one of its subdocuments.
partial interface Document {
[ChromeOnly]
void setSuppressedEventListener(EventListener? aListener);
};
// Extension to give chrome and XBL JS the ability to determine whether
// the document is sandboxed without permission to run scripts
// and whether inline scripts are blocked by the document's CSP.

View File

@ -6785,6 +6785,28 @@ nsresult PresShell::HandleEvent(nsIFrame* aFrame, WidgetGUIEvent* aEvent,
auto event = MakeUnique<DelayedMouseEvent>(aEvent->AsMouseEvent());
mDelayedEvents.AppendElement(std::move(event));
}
// If there is a suppressed event listener associated with the document,
// notify it about the suppressed mouse event. This allows devtools
// features to continue receiving mouse events even when the devtools
// debugger has paused execution in a page.
RefPtr<EventListener> suppressedListener =
frame->PresContext()->Document()->GetSuppressedEventListener();
if (suppressedListener &&
aEvent->AsMouseEvent()->mReason != WidgetMouseEvent::eSynthesized) {
nsCOMPtr<nsIContent> targetContent;
frame->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
if (targetContent) {
aEvent->mTarget = targetContent;
}
nsCOMPtr<EventTarget> et = aEvent->mTarget;
RefPtr<Event> event = EventDispatcher::CreateEvent(
et, frame->PresContext(), aEvent, EmptyString());
suppressedListener->HandleEvent(*event);
}
return NS_OK;
}