зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1680611 - part 1: Mark all `nsFocusManager` methods whose names explain that they may dispatch events as `MOZ_CAN_RUN_SCRIPT` r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D147060
This commit is contained in:
Родитель
ce08aec555
Коммит
498eae6328
|
@ -12261,24 +12261,28 @@ void Document::NotifyAbortedLoad() {
|
|||
}
|
||||
}
|
||||
|
||||
static void FireOrClearDelayedEvents(nsTArray<nsCOMPtr<Document>>& aDocuments,
|
||||
bool aFireEvents) {
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (!fm) return;
|
||||
MOZ_CAN_RUN_SCRIPT static void FireOrClearDelayedEvents(
|
||||
nsTArray<nsCOMPtr<Document>>&& aDocuments, bool aFireEvents) {
|
||||
RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager();
|
||||
if (MOZ_UNLIKELY(!fm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aDocuments.Length(); ++i) {
|
||||
nsTArray<nsCOMPtr<Document>> documents = std::move(aDocuments);
|
||||
for (uint32_t i = 0; i < documents.Length(); ++i) {
|
||||
nsCOMPtr<Document> document = std::move(documents[i]);
|
||||
// NB: Don't bother trying to fire delayed events on documents that were
|
||||
// closed before this event ran.
|
||||
if (!aDocuments[i]->EventHandlingSuppressed()) {
|
||||
fm->FireDelayedEvents(aDocuments[i]);
|
||||
RefPtr<PresShell> presShell = aDocuments[i]->GetPresShell();
|
||||
if (!document->EventHandlingSuppressed()) {
|
||||
fm->FireDelayedEvents(document);
|
||||
RefPtr<PresShell> presShell = document->GetPresShell();
|
||||
if (presShell) {
|
||||
// Only fire events for active documents.
|
||||
bool fire = aFireEvents && aDocuments[i]->GetInnerWindow() &&
|
||||
aDocuments[i]->GetInnerWindow()->IsCurrentInnerWindow();
|
||||
bool fire = aFireEvents && document->GetInnerWindow() &&
|
||||
document->GetInnerWindow()->IsCurrentInnerWindow();
|
||||
presShell->FireOrClearDelayedEvents(fire);
|
||||
}
|
||||
aDocuments[i]->FireOrClearPostMessageEvents(aFireEvents);
|
||||
document->FireOrClearPostMessageEvents(aFireEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12612,8 +12616,10 @@ class nsDelayedEventDispatcher : public Runnable {
|
|||
mDocuments(std::move(aDocuments)) {}
|
||||
virtual ~nsDelayedEventDispatcher() = default;
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
FireOrClearDelayedEvents(mDocuments, true);
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
|
||||
FireOrClearDelayedEvents(std::move(mDocuments), true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -12674,7 +12680,7 @@ void Document::UnsuppressEventHandlingAndFireEvents(bool aFireEvents) {
|
|||
new nsDelayedEventDispatcher(std::move(documents));
|
||||
Dispatch(TaskCategory::Other, ded.forget());
|
||||
} else {
|
||||
FireOrClearDelayedEvents(documents, false);
|
||||
FireOrClearDelayedEvents(std::move(documents), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2772,7 +2772,8 @@ class Document : public nsINode,
|
|||
* @param aFireEvents If true, delayed events (focus/blur) will be fired
|
||||
* asynchronously.
|
||||
*/
|
||||
void UnsuppressEventHandlingAndFireEvents(bool aFireEvents);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void UnsuppressEventHandlingAndFireEvents(
|
||||
bool aFireEvents);
|
||||
|
||||
uint32_t EventHandlingSuppressed() const { return mEventsSuppressed; }
|
||||
|
||||
|
|
|
@ -1038,23 +1038,23 @@ void nsFocusManager::WindowHidden(mozIDOMWindowProxy* aWindow,
|
|||
// window, or an ancestor of the focused window. Either way, the focus is no
|
||||
// longer valid, so it needs to be updated.
|
||||
|
||||
RefPtr<Element> oldFocusedElement = std::move(mFocusedElement);
|
||||
const RefPtr<Element> oldFocusedElement = std::move(mFocusedElement);
|
||||
|
||||
nsCOMPtr<nsIDocShell> focusedDocShell = mFocusedWindow->GetDocShell();
|
||||
if (!focusedDocShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<PresShell> presShell = focusedDocShell->GetPresShell();
|
||||
const RefPtr<PresShell> presShell = focusedDocShell->GetPresShell();
|
||||
|
||||
if (oldFocusedElement && oldFocusedElement->IsInComposedDoc()) {
|
||||
NotifyFocusStateChange(oldFocusedElement, nullptr, 0, false, false);
|
||||
window->UpdateCommands(u"focus"_ns, nullptr, 0);
|
||||
|
||||
if (presShell) {
|
||||
SendFocusOrBlurEvent(eBlur, presShell,
|
||||
oldFocusedElement->GetComposedDoc(),
|
||||
oldFocusedElement, false);
|
||||
RefPtr<Document> composedDoc = oldFocusedElement->GetComposedDoc();
|
||||
SendFocusOrBlurEvent(eBlur, presShell, composedDoc, oldFocusedElement,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2434,13 +2434,15 @@ bool nsFocusManager::BlurImpl(BrowsingContext* aBrowsingContextToClear,
|
|||
SetFocusedWindowInternal(nullptr, aActionId);
|
||||
mFocusedElement = nullptr;
|
||||
|
||||
Document* doc = window->GetExtantDoc();
|
||||
RefPtr<Document> doc = window->GetExtantDoc();
|
||||
if (doc) {
|
||||
SendFocusOrBlurEvent(eBlur, presShell, doc, ToSupports(doc), false);
|
||||
SendFocusOrBlurEvent(eBlur, presShell, doc,
|
||||
MOZ_KnownLive(ToSupports(doc)), false);
|
||||
}
|
||||
if (!GetFocusedBrowsingContext()) {
|
||||
SendFocusOrBlurEvent(eBlur, presShell, doc,
|
||||
window->GetCurrentInnerWindow(), false);
|
||||
nsCOMPtr<nsPIDOMWindowInner> innerWindow =
|
||||
window->GetCurrentInnerWindow();
|
||||
SendFocusOrBlurEvent(eBlur, presShell, doc, innerWindow, false);
|
||||
}
|
||||
|
||||
// check if a different window was focused
|
||||
|
@ -2496,7 +2498,7 @@ void nsFocusManager::Focus(
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<PresShell> presShell = docShell->GetPresShell();
|
||||
const RefPtr<PresShell> presShell = docShell->GetPresShell();
|
||||
if (!presShell) {
|
||||
return;
|
||||
}
|
||||
|
@ -2594,7 +2596,7 @@ void nsFocusManager::Focus(
|
|||
// if switching to a new document, first fire the focus event on the
|
||||
// document and then the window.
|
||||
if (aIsNewDocument) {
|
||||
Document* doc = aWindow->GetExtantDoc();
|
||||
RefPtr<Document> doc = aWindow->GetExtantDoc();
|
||||
// The focus change should be notified to IMEStateManager from here if:
|
||||
// * the focused element is in design mode or
|
||||
// * nobody gets focus and the document is in design mode
|
||||
|
@ -2606,13 +2608,14 @@ void nsFocusManager::Focus(
|
|||
GetFocusMoveActionCause(aFlags));
|
||||
}
|
||||
if (doc && !focusInOtherContentProcess) {
|
||||
SendFocusOrBlurEvent(eFocus, presShell, doc, ToSupports(doc),
|
||||
aWindowRaised);
|
||||
SendFocusOrBlurEvent(eFocus, presShell, doc,
|
||||
MOZ_KnownLive(ToSupports(doc)), aWindowRaised);
|
||||
}
|
||||
if (GetFocusedBrowsingContext() == aWindow->GetBrowsingContext() &&
|
||||
!mFocusedElement && !focusInOtherContentProcess) {
|
||||
SendFocusOrBlurEvent(eFocus, presShell, doc,
|
||||
aWindow->GetCurrentInnerWindow(), aWindowRaised);
|
||||
nsCOMPtr<nsPIDOMWindowInner> innerWindow =
|
||||
aWindow->GetCurrentInnerWindow();
|
||||
SendFocusOrBlurEvent(eFocus, presShell, doc, innerWindow, aWindowRaised);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2659,11 +2662,11 @@ void nsFocusManager::Focus(
|
|||
}
|
||||
|
||||
if (!focusInOtherContentProcess) {
|
||||
SendFocusOrBlurEvent(eFocus, presShell, aElement->GetComposedDoc(),
|
||||
aElement, aWindowRaised, isRefocus,
|
||||
aBlurredElementInfo
|
||||
? aBlurredElementInfo->mElement.get()
|
||||
: nullptr);
|
||||
RefPtr<Document> composedDocument = aElement->GetComposedDoc();
|
||||
RefPtr<Element> relatedTargetElement =
|
||||
aBlurredElementInfo ? aBlurredElementInfo->mElement.get() : nullptr;
|
||||
SendFocusOrBlurEvent(eFocus, presShell, composedDocument, aElement,
|
||||
aWindowRaised, isRefocus, relatedTargetElement);
|
||||
}
|
||||
} else {
|
||||
IMEStateManager::OnChangeFocus(presContext, nullptr,
|
||||
|
|
|
@ -251,12 +251,13 @@ class nsFocusManager final : public nsIFocusManager,
|
|||
* Called when a document in a window has been hidden or otherwise can no
|
||||
* longer accept focus.
|
||||
*/
|
||||
void WindowHidden(mozIDOMWindowProxy* aWindow, uint64_t aActionId);
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY void WindowHidden(mozIDOMWindowProxy* aWindow,
|
||||
uint64_t aActionId);
|
||||
|
||||
/**
|
||||
* Fire any events that have been delayed due to synchronized actions.
|
||||
*/
|
||||
void FireDelayedEvents(Document* aDocument);
|
||||
MOZ_CAN_RUN_SCRIPT void FireDelayedEvents(Document* aDocument);
|
||||
|
||||
void WasNuked(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
|
@ -480,7 +481,7 @@ class nsFocusManager final : public nsIFocusManager,
|
|||
*
|
||||
* aWindowRaised should only be true if called from WindowRaised.
|
||||
*/
|
||||
void SendFocusOrBlurEvent(
|
||||
MOZ_CAN_RUN_SCRIPT void SendFocusOrBlurEvent(
|
||||
mozilla::EventMessage aEventMessage, mozilla::PresShell* aPresShell,
|
||||
Document* aDocument, nsISupports* aTarget, bool aWindowRaised,
|
||||
bool aIsRefocus = false,
|
||||
|
@ -493,7 +494,7 @@ class nsFocusManager final : public nsIFocusManager,
|
|||
*
|
||||
* aWindowRaised should only be true if called from WindowRaised.
|
||||
*/
|
||||
void FireFocusOrBlurEvent(
|
||||
MOZ_CAN_RUN_SCRIPT void FireFocusOrBlurEvent(
|
||||
mozilla::EventMessage aEventMessage, mozilla::PresShell* aPresShell,
|
||||
nsISupports* aTarget, bool aWindowRaised, bool aIsRefocus = false,
|
||||
mozilla::dom::EventTarget* aRelatedTarget = nullptr);
|
||||
|
@ -515,7 +516,7 @@ class nsFocusManager final : public nsIFocusManager,
|
|||
* aRelatedTarget is the content related to the event (the object
|
||||
* losing focus for focusin, the object getting focus for focusout).
|
||||
*/
|
||||
void FireFocusInOrOutEvent(
|
||||
MOZ_CAN_RUN_SCRIPT void FireFocusInOrOutEvent(
|
||||
mozilla::EventMessage aEventMessage, mozilla::PresShell* aPresShell,
|
||||
nsISupports* aTarget, nsPIDOMWindowOuter* aCurrentFocusedWindow,
|
||||
nsIContent* aCurrentFocusedContent,
|
||||
|
|
Загрузка…
Ссылка в новой задаче