commit 45119548c9489da1bffbcfff635a849d079b699f
parent 4852c962c4a137755524851aad30c772acd025bd
Author: Masayuki Nakano <masayuki@d-toybox.com>
Date: Wed, 3 Dec 2025 22:41:36 +0000
Bug 2003699 - Make `nsIFrame::GetSelectionController()` return raw pointer r=emilio,layout-reviewers
It returns `nsresult` and has out-param for returning
`nsISelectionController*`. However, no caller of it handles differently
when this returns error vs. `nullptr` for `nsISelectionController*`.
Therefore, this should return `nsISelectionController*` simply.
Then, we don't need the same name method in the derived class,
`nsTextControlFrame`.
Differential Revision: https://phabricator.services.mozilla.com/D274880
Diffstat:
8 files changed, 71 insertions(+), 80 deletions(-)
diff --git a/accessible/base/nsCoreUtils.cpp b/accessible/base/nsCoreUtils.cpp
@@ -234,14 +234,15 @@ nsresult nsCoreUtils::ScrollSubstringTo(nsIFrame* aFrame, nsRange* aRange,
return NS_ERROR_FAILURE;
}
- nsPresContext* presContext = aFrame->PresContext();
-
- nsCOMPtr<nsISelectionController> selCon;
- aFrame->GetSelectionController(presContext, getter_AddRefs(selCon));
- NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
-
- RefPtr<dom::Selection> selection =
- selCon->GetSelection(nsISelectionController::SELECTION_ACCESSIBILITY);
+ const RefPtr<dom::Selection> selection = [&]() -> dom::Selection* {
+ nsISelectionController* const selCon = aFrame->GetSelectionController();
+ NS_ENSURE_TRUE(selCon, nullptr);
+ return selCon->GetSelection(
+ nsISelectionController::SELECTION_ACCESSIBILITY);
+ }();
+ if (MOZ_UNLIKELY(!selection)) {
+ return NS_ERROR_FAILURE;
+ }
selection->RemoveAllRanges(IgnoreErrors());
selection->AddRangeAndSelectFramesAndNotifyListeners(*aRange, IgnoreErrors());
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
@@ -9949,12 +9949,9 @@ bool PresShell::EventHandler::PrepareToUseCaretPosition(
// the correct menu at a weird place than the wrong menu.
// After ScrollSelectionIntoView(), the pending notifications might be
// flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
- nsCOMPtr<nsISelectionController> selCon;
- if (frame) {
- frame->GetSelectionController(GetPresContext(), getter_AddRefs(selCon));
- } else {
- selCon = static_cast<nsISelectionController*>(mPresShell);
- }
+ const nsCOMPtr<nsISelectionController> selCon =
+ frame ? frame->GetSelectionController()
+ : static_cast<nsISelectionController*>(mPresShell);
if (selCon) {
rv = selCon->ScrollSelectionIntoView(
SelectionType::eNormal, nsISelectionController::SELECTION_FOCUS_REGION,
diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h
@@ -119,9 +119,6 @@ class nsTextControlFrame : public nsContainerFrame,
nsFrameSelection* GetOwnedFrameSelection() {
return ControlElement()->GetIndependentFrameSelection();
}
- nsISelectionController* GetSelectionController() {
- return ControlElement()->GetSelectionController();
- }
void PlaceholderChanged(const nsAttrValue* aOld, const nsAttrValue* aNew);
diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp
@@ -2300,14 +2300,7 @@ static nsIFrame* GetActiveSelectionFrame(nsPresContext* aPresContext,
}
bool nsIFrame::ShouldHandleSelectionMovementEvents() {
- nsCOMPtr<nsISelectionController> selCon;
- GetSelectionController(PresContext(), getter_AddRefs(selCon));
- if (!selCon) {
- return false;
- }
- int16_t selType = nsISelectionController::SELECTION_OFF;
- selCon->GetDisplaySelection(&selType);
- if (selType == nsISelectionController::SELECTION_OFF) {
+ if (GetDisplaySelection() == nsISelectionController::SELECTION_OFF) {
return false;
}
if (!IsSelectable()) {
@@ -4912,13 +4905,7 @@ bool nsIFrame::ShouldPaintNormalSelection() const {
}
// If we're not selectable by user, we should paint selection only while the
// normal selection is styled as "attention" by "Find in Page" or something.
- nsCOMPtr<nsISelectionController> selCon;
- GetSelectionController(PresContext(), getter_AddRefs(selCon));
- int16_t displaySelection = nsISelectionController::SELECTION_OFF;
- if (selCon) {
- selCon->GetDisplaySelection(&displaySelection);
- }
- return displaySelection == nsISelectionController::SELECTION_ATTENTION;
+ return GetDisplaySelection() == nsISelectionController::SELECTION_ATTENTION;
}
bool nsIFrame::ShouldHaveLineIfEmpty() const {
@@ -9193,16 +9180,21 @@ bool nsIFrame::IsSelfEmpty() {
return IsHiddenByContentVisibilityOfInFlowParentForLayout();
}
-nsresult nsIFrame::GetSelectionController(
- nsPresContext* aPresContext, nsISelectionController** aSelCon) const {
- if (!aPresContext || !aSelCon) {
- return NS_ERROR_INVALID_ARG;
+nsISelectionController* nsIFrame::GetSelectionController() const {
+ if (nsTextControlFrame* const tcf = GetContainingTextControlFrame()) {
+ return tcf->ControlElement()->GetSelectionController();
}
- if (nsTextControlFrame* tcf = GetContainingTextControlFrame()) {
- return tcf->GetOwnedSelectionController(aSelCon);
+ return static_cast<nsISelectionController*>(PresShell());
+}
+
+int16_t nsIFrame::GetDisplaySelection() const {
+ nsISelectionController* const selCon = GetSelectionController();
+ if (MOZ_UNLIKELY(!selCon)) {
+ return nsISelectionController::SELECTION_OFF;
}
- *aSelCon = do_AddRef(aPresContext->PresShell()).take();
- return NS_OK;
+ int16_t display = nsISelectionController::SELECTION_OFF;
+ selCon->GetDisplaySelection(&display);
+ return display;
}
already_AddRefed<nsFrameSelection> nsIFrame::GetFrameSelection() {
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
@@ -4062,12 +4062,14 @@ class nsIFrame : public nsQueryFrame {
/**
* Called to retrieve the SelectionController associated with the frame.
- *
- * @param aSelCon will contain the selection controller associated with
- * the frame.
*/
- nsresult GetSelectionController(nsPresContext* aPresContext,
- nsISelectionController** aSelCon) const;
+ nsISelectionController* GetSelectionController() const;
+
+ /**
+ * Return the display value of selections which is default to SELECTION_OFF if
+ * there is no selection controller.
+ */
+ int16_t GetDisplaySelection() const;
/**
* Call to get nsFrameSelection for this frame.
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
@@ -8061,19 +8061,15 @@ nsRect nsTextFrame::WebRenderBounds() {
}
int16_t nsTextFrame::GetSelectionStatus(int16_t* aSelectionFlags) {
- // get the selection controller
- nsCOMPtr<nsISelectionController> selectionController;
- nsresult rv = GetSelectionController(PresContext(),
- getter_AddRefs(selectionController));
- if (NS_FAILED(rv) || !selectionController) {
+ nsISelectionController* const selCon = GetSelectionController();
+ if (MOZ_UNLIKELY(!selCon)) {
return nsISelectionController::SELECTION_OFF;
}
- selectionController->GetSelectionFlags(aSelectionFlags);
-
- int16_t selectionValue;
- selectionController->GetDisplaySelection(&selectionValue);
+ selCon->GetSelectionFlags(aSelectionFlags);
+ int16_t selectionValue = nsISelectionController::SELECTION_OFF;
+ selCon->GetDisplaySelection(&selectionValue);
return selectionValue;
}
diff --git a/toolkit/components/find/nsWebBrowserFind.cpp b/toolkit/components/find/nsWebBrowserFind.cpp
@@ -312,15 +312,12 @@ void nsWebBrowserFind::SetSelectionAndScroll(nsPIDOMWindowOuter* aWindow,
return;
}
- nsCOMPtr<nsINode> node = aRange->GetStartContainer();
- nsCOMPtr<nsIContent> content(do_QueryInterface(node));
- nsIFrame* frame = content->GetPrimaryFrame();
- if (!frame) {
+ nsCOMPtr<nsIContent> content =
+ nsIContent::FromNodeOrNull(aRange->GetStartContainer());
+ nsIFrame* const frameForStartContainer = content->GetPrimaryFrame();
+ if (!frameForStartContainer) {
return;
}
- nsCOMPtr<nsISelectionController> selCon;
- frame->GetSelectionController(presShell->GetPresContext(),
- getter_AddRefs(selCon));
// since the match could be an anonymous textnode inside a
// <textarea> or text <input>, we need to get the outer frame
@@ -338,6 +335,8 @@ void nsWebBrowserFind::SetSelectionAndScroll(nsPIDOMWindowOuter* aWindow,
}
}
+ const nsCOMPtr<nsISelectionController> selCon =
+ frameForStartContainer->GetSelectionController();
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
RefPtr<Selection> selection =
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
@@ -675,27 +674,27 @@ already_AddRefed<Selection> nsWebBrowserFind::GetFrameSelection(
// text input controls have their independent selection controllers that we
// must use when they have focus.
- nsPresContext* presContext = presShell->GetPresContext();
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
nsCOMPtr<nsIContent> focusedContent = nsFocusManager::GetFocusedDescendant(
aWindow, nsFocusManager::eOnlyCurrentWindow,
getter_AddRefs(focusedWindow));
- nsIFrame* frame =
+ nsIFrame* const frame =
focusedContent ? focusedContent->GetPrimaryFrame() : nullptr;
nsCOMPtr<nsISelectionController> selCon;
- RefPtr<Selection> sel;
if (frame) {
- frame->GetSelectionController(presContext, getter_AddRefs(selCon));
- sel = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
+ nsISelectionController* const selCon = frame->GetSelectionController();
+ Selection* const sel =
+ selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
if (sel && sel->RangeCount() > 0) {
- return sel.forget();
+ return do_AddRef(sel);
}
}
- sel = presShell->GetSelection(nsISelectionController::SELECTION_NORMAL);
+ RefPtr<Selection> sel =
+ presShell->GetSelection(nsISelectionController::SELECTION_NORMAL);
return sel.forget();
}
diff --git a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
@@ -954,23 +954,30 @@ nsresult nsTypeAheadFind::FindInternal(uint32_t aMode,
void nsTypeAheadFind::GetSelection(PresShell* aPresShell,
nsISelectionController** aSelCon,
Selection** aDOMSel) {
- if (!aPresShell) return;
-
- // if aCurrentNode is nullptr, get selection for document
+ *aSelCon = nullptr;
*aDOMSel = nullptr;
- nsPresContext* presContext = aPresShell->GetPresContext();
+ if (MOZ_UNLIKELY(!aPresShell)) {
+ return;
+ }
- nsIFrame* frame = aPresShell->GetRootFrame();
+ nsPresContext* const presContext = aPresShell->GetPresContext();
+ if (MOZ_UNLIKELY(!presContext)) {
+ return;
+ }
- if (presContext && frame) {
- frame->GetSelectionController(presContext, aSelCon);
- if (*aSelCon) {
- RefPtr<Selection> sel =
- (*aSelCon)->GetSelection(nsISelectionController::SELECTION_NORMAL);
- sel.forget(aDOMSel);
- }
+ nsIFrame* const frame = aPresShell->GetRootFrame();
+ if (MOZ_UNLIKELY(!frame)) {
+ return;
+ }
+
+ nsCOMPtr<nsISelectionController> selCon = frame->GetSelectionController();
+ RefPtr<Selection> sel;
+ if (selCon) {
+ sel = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL);
}
+ selCon.forget(aSelCon);
+ sel.forget(aDOMSel);
}
NS_IMETHODIMP