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:
Masayuki Nakano 2022-05-26 04:37:17 +00:00
Родитель ce08aec555
Коммит 498eae6328
4 изменённых файлов: 51 добавлений и 40 удалений

Просмотреть файл

@ -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,