From cdfbc99cdf18ddc9e4f5f9722ac21d13979cdd7e Mon Sep 17 00:00:00 2001 From: Masayuki Nakano <masayuki@d-toybox.com> Date: Thu, 26 May 2022 04:37:19 +0000 Subject: [PATCH] Bug 1680611 - part 6: Mark `nsFocusManager::MoveCaretToFocus()` and its callers in `nsFocusManager` as `MOZ_CAN_RUN_SCRIPT` r=smaug Differential Revision: https://phabricator.services.mozilla.com/D147065 --- dom/base/nsFocusManager.cpp | 20 +++++++++++-------- dom/base/nsFocusManager.h | 16 ++++++++------- dom/interfaces/base/nsIFocusManager.idl | 1 + editor/libeditor/EditorBase.cpp | 4 +++- editor/libeditor/EditorBase.h | 2 +- .../typeaheadfind/nsTypeAheadFind.cpp | 5 ++--- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index cb12fe5ad1ebc..3ee9fc3b7437d 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -216,7 +216,9 @@ void nsFocusManager::Shutdown() { sInstance = nullptr; } // static void nsFocusManager::PrefChanged(const char* aPref, void* aSelf) { - static_cast<nsFocusManager*>(aSelf)->PrefChanged(aPref); + if (RefPtr<nsFocusManager> fm = static_cast<nsFocusManager*>(aSelf)) { + fm->PrefChanged(aPref); + } } void nsFocusManager::PrefChanged(const char* aPref) { @@ -643,9 +645,8 @@ nsFocusManager::MoveCaretToFocus(mozIDOMWindowProxy* aWindow) { NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow); - nsCOMPtr<nsIContent> content = window->GetFocusedElement(); - if (content) { - MoveCaretToFocus(presShell, content); + if (RefPtr<Element> focusedElement = window->GetFocusedElement()) { + MoveCaretToFocus(presShell, focusedElement); } } } @@ -2693,9 +2694,11 @@ void nsFocusManager::Focus( // needed. If this is a different document than was focused before, also // update the caret's visibility. If this is the same document, the caret // visibility should be the same as before so there is no need to update it. - if (mFocusedElement == aElement) + if (mFocusedElement == aElement) { + RefPtr<Element> focusedElement = mFocusedElement; UpdateCaret(aFocusChanged && !(aFlags & FLAG_BYMOUSE), aIsNewDocument, - mFocusedElement); + focusedElement); + } } class FocusBlurEvent : public Runnable { @@ -2995,7 +2998,8 @@ void nsFocusManager::RaiseWindow(nsPIDOMWindowOuter* aWindow, } void nsFocusManager::UpdateCaretForCaretBrowsingMode() { - UpdateCaret(false, true, mFocusedElement); + RefPtr<Element> focusedElement = mFocusedElement; + UpdateCaret(false, true, focusedElement); } void nsFocusManager::UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility, @@ -3019,7 +3023,7 @@ void nsFocusManager::UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility, bool browseWithCaret = Preferences::GetBool("accessibility.browsewithcaret"); - RefPtr<PresShell> presShell = focusedDocShell->GetPresShell(); + const RefPtr<PresShell> presShell = focusedDocShell->GetPresShell(); if (!presShell) { return; } diff --git a/dom/base/nsFocusManager.h b/dom/base/nsFocusManager.h index aca51b4950e9a..556fad90a5881 100644 --- a/dom/base/nsFocusManager.h +++ b/dom/base/nsFocusManager.h @@ -64,8 +64,9 @@ class nsFocusManager final : public nsIFocusManager, MOZ_CAN_RUN_SCRIPT static void FocusWindow( nsPIDOMWindowOuter* aWindow, mozilla::dom::CallerType aCallerType); - static void PrefChanged(const char* aPref, void* aSelf); - void PrefChanged(const char* aPref); + MOZ_CAN_RUN_SCRIPT_BOUNDARY static void PrefChanged(const char* aPref, + void* aSelf); + MOZ_CAN_RUN_SCRIPT void PrefChanged(const char* aPref); /** * Retrieve the single focus manager. @@ -161,7 +162,7 @@ class nsFocusManager final : public nsIFocusManager, /** * Update the caret with current mode (whether in caret browsing mode or not). */ - void UpdateCaretForCaretBrowsingMode(); + MOZ_CAN_RUN_SCRIPT void UpdateCaretForCaretBrowsingMode(); /** @see nsIFocusManager.getLastFocusMethod() */ uint32_t GetLastFocusMethod(nsPIDOMWindowOuter*) const; @@ -531,14 +532,15 @@ class nsFocusManager final : public nsIFocusManager, * aUpdateVisibility should be true to update whether the caret is * visible or not. */ - void UpdateCaret(bool aMoveCaretToFocus, bool aUpdateVisibility, - nsIContent* aContent); + MOZ_CAN_RUN_SCRIPT void UpdateCaret(bool aMoveCaretToFocus, + bool aUpdateVisibility, + nsIContent* aContent); /** * Helper method to move the caret to the focused element aContent. */ - MOZ_CAN_RUN_SCRIPT_BOUNDARY void MoveCaretToFocus( - mozilla::PresShell* aPresShell, nsIContent* aContent); + MOZ_CAN_RUN_SCRIPT void MoveCaretToFocus(mozilla::PresShell* aPresShell, + nsIContent* aContent); /** * Makes the caret visible or not, depending on aVisible. diff --git a/dom/interfaces/base/nsIFocusManager.idl b/dom/interfaces/base/nsIFocusManager.idl index 6c05185d66d3b..056da78770499 100644 --- a/dom/interfaces/base/nsIFocusManager.idl +++ b/dom/interfaces/base/nsIFocusManager.idl @@ -159,6 +159,7 @@ interface nsIFocusManager : nsISupports /** * Moves the selection caret within aWindow to the current focus. */ + [can_run_script] void moveCaretToFocus(in mozIDOMWindowProxy aWindow); /*** diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 0029c6acfe52d..01010689f189d 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -5332,10 +5332,12 @@ nsresult EditorBase::FinalizeSelection() { "nsISelectionController::SetCaretEnabled(false) failed, but ignored"); } - nsFocusManager* focusManager = nsFocusManager::GetFocusManager(); + RefPtr<nsFocusManager> focusManager = nsFocusManager::GetFocusManager(); if (NS_WARN_IF(!focusManager)) { return NS_ERROR_NOT_INITIALIZED; } + // TODO: Running script from here makes harder to handle blur events. We + // should do this asynchronously. focusManager->UpdateCaretForCaretBrowsingMode(); if (nsCOMPtr<nsINode> node = do_QueryInterface(GetDOMEventTarget())) { if (node->OwnerDoc()->GetUnretargetedFocusedContent() != node) { diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 9c2662481170d..c06713cb52ff8 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -292,7 +292,7 @@ class EditorBase : public nsIEditor, /** * Finalizes selection and caret for the editor. */ - nsresult FinalizeSelection(); + MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult FinalizeSelection(); /** * Returns true if selection is in an editable element and both the range diff --git a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp index 8d4b00d5e1fd4..316091cfe4c52 100644 --- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp +++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp @@ -983,9 +983,8 @@ nsresult nsTypeAheadFind::FindInternal(uint32_t aMode, nsCOMPtr<Document> document = presShell->GetDocument(); if (!document) return NS_ERROR_UNEXPECTED; - nsFocusManager* fm = nsFocusManager::GetFocusManager(); - if (fm) { - nsPIDOMWindowOuter* window = document->GetWindow(); + if (RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager()) { + nsCOMPtr<nsPIDOMWindowOuter> window = document->GetWindow(); RefPtr<Element> focusedElement; nsCOMPtr<mozIDOMWindowProxy> focusedWindow; fm->GetFocusedElementForWindow(window, false, -- GitLab