Bug 1946001 - Rename methods which return an independent nsFrameSelection to GetIndependentFrameSelection() r=emilio

The methods are now, `GetConstFrameSelection()` etc, but does not return
`const nsFrameSelection*`.  I believe that `GetIndependentFrameSelection()` is
clearer than the old names.

And also this patch adds `IsIndependentSelection()` and
`GetIndependentSelectionRootParentElement()` to make some callers of
`GetLimiter()` easier to read.

For the consistency, `GetLimiter()` should be renamed too, but I already have
a patch doing it in bug 1954020 and it's bigger.  Therefore, I leave it as-is
for now.

Differential Revision: https://phabricator.services.mozilla.com/D241774
This commit is contained in:
Masayuki Nakano
2025-03-17 12:49:57 +00:00
parent 9a826750c4
commit 80089dd884
12 changed files with 59 additions and 36 deletions

View File

@@ -126,26 +126,28 @@ void SelectionChangeEventDispatcher::OnSelectionChange(Document* aDoc,
// Be aware, don't call GetTextControlFromSelectionLimiter once you might
// run script because selection limit may have already been changed by it.
nsCOMPtr<nsIContent> textControl;
if ((maybeHasFormSelectEventListeners &&
(aReason & nsISelectionListener::JS_REASON)) ||
maybeHasSelectionChangeEventListeners) {
if (const nsFrameSelection* fs = aSel->GetFrameSelection()) {
if (nsCOMPtr<nsIContent> root = fs->GetLimiter()) {
textControl = root->GetClosestNativeAnonymousSubtreeRootParentOrHost();
MOZ_ASSERT_IF(textControl,
textControl->IsTextControlElement() &&
!textControl->IsInNativeAnonymousSubtree());
const RefPtr<Element> textControlElement = [&]() -> Element* {
if (!(maybeHasFormSelectEventListeners &&
(aReason & nsISelectionListener::JS_REASON)) &&
!maybeHasSelectionChangeEventListeners) {
return nullptr;
}
const nsFrameSelection* fs = aSel->GetFrameSelection();
if (!fs || !fs->IsIndependentSelection()) {
return nullptr;
}
};
Element* textControl = fs->GetIndependentSelectionRootParentElement();
MOZ_ASSERT_IF(textControl, textControl->IsTextControlElement());
MOZ_ASSERT_IF(textControl, !textControl->IsInNativeAnonymousSubtree());
return textControl;
}();
// Selection changes with non-JS reason only cares about whether the new
// selection is collapsed or not. See TextInputListener::OnSelectionChange.
if (textControl && maybeHasFormSelectEventListeners &&
if (textControlElement && maybeHasFormSelectEventListeners &&
(aReason & nsISelectionListener::JS_REASON)) {
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(textControl, eFormSelect, CanBubble::eYes);
RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
textControlElement, eFormSelect, CanBubble::eYes);
asyncDispatcher->PostDOMEvent();
}
@@ -157,13 +159,14 @@ void SelectionChangeEventDispatcher::OnSelectionChange(Document* aDoc,
// controls, so for now we only support doing that under a pref, disabled by
// default.
// See https://github.com/w3c/selection-api/issues/53.
if (textControl &&
if (textControlElement &&
!StaticPrefs::dom_select_events_textcontrols_selectionchange_enabled()) {
return;
}
nsINode* target =
textControl ? static_cast<nsINode*>(textControl.get()) : aDoc;
nsINode* target = textControlElement
? static_cast<nsINode*>(textControlElement.get())
: aDoc;
if (!target) {
return;
}
@@ -174,7 +177,7 @@ void SelectionChangeEventDispatcher::OnSelectionChange(Document* aDoc,
target->SetHasScheduledSelectionChangeEvent();
CanBubble canBubble = textControl ? CanBubble::eYes : CanBubble::eNo;
CanBubble canBubble = textControlElement ? CanBubble::eYes : CanBubble::eNo;
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncSelectionChangeEventDispatcher(target, eSelectionChange,
canBubble);

View File

@@ -2423,10 +2423,10 @@ nsISelectionController* HTMLInputElement::GetSelectionController() {
return nullptr;
}
nsFrameSelection* HTMLInputElement::GetConstFrameSelection() {
nsFrameSelection* HTMLInputElement::GetIndependentFrameSelection() const {
TextControlState* state = GetEditorState();
if (state) {
return state->GetConstFrameSelection();
return state->GetIndependentFrameSelection();
}
return nullptr;
}
@@ -3105,7 +3105,7 @@ void HTMLInputElement::Select() {
MOZ_ASSERT(state, "Single line text controls are expected to have a state");
if (FocusState() != FocusTristate::eUnfocusable) {
RefPtr<nsFrameSelection> fs = state->GetConstFrameSelection();
RefPtr<nsFrameSelection> fs = state->GetIndependentFrameSelection();
if (fs && fs->MouseDownRecorded()) {
// This means that we're being called while the frame selection has a
// mouse down event recorded to adjust the caret during the mouse up

View File

@@ -241,7 +241,7 @@ class HTMLInputElement final : public TextControlElement,
MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditor() override;
TextEditor* GetExtantTextEditor() const override;
nsISelectionController* GetSelectionController() override;
nsFrameSelection* GetConstFrameSelection() override;
nsFrameSelection* GetIndependentFrameSelection() const override;
TextControlState* GetTextControlState() const override {
return GetEditorState();
}

View File

@@ -179,9 +179,9 @@ nsISelectionController* HTMLTextAreaElement::GetSelectionController() {
return mState->GetSelectionController();
}
nsFrameSelection* HTMLTextAreaElement::GetConstFrameSelection() {
nsFrameSelection* HTMLTextAreaElement::GetIndependentFrameSelection() const {
MOZ_ASSERT(mState);
return mState->GetConstFrameSelection();
return mState->GetIndependentFrameSelection();
}
nsresult HTMLTextAreaElement::BindToFrame(nsTextControlFrame* aFrame) {

View File

@@ -88,7 +88,7 @@ class HTMLTextAreaElement final : public TextControlElement,
MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditor() override;
TextEditor* GetExtantTextEditor() const override;
nsISelectionController* GetSelectionController() override;
nsFrameSelection* GetConstFrameSelection() override;
nsFrameSelection* GetIndependentFrameSelection() const override;
TextControlState* GetTextControlState() const override { return mState; }
nsresult BindToFrame(nsTextControlFrame* aFrame) override;
MOZ_CAN_RUN_SCRIPT void UnbindFromFrame(nsTextControlFrame* aFrame) override;

View File

@@ -131,7 +131,7 @@ class TextControlElement : public nsGenericHTMLFormControlElementWithState {
*/
virtual nsISelectionController* GetSelectionController() = 0;
virtual nsFrameSelection* GetConstFrameSelection() = 0;
virtual nsFrameSelection* GetIndependentFrameSelection() const = 0;
virtual TextControlState* GetTextControlState() const = 0;

View File

@@ -343,7 +343,9 @@ class TextInputSelectionController final : public nsSupportsWeakReference,
Element& aEditorRootAnonymousDiv);
void SetScrollContainerFrame(ScrollContainerFrame* aScrollContainerFrame);
nsFrameSelection* GetConstFrameSelection() { return mFrameSelection; }
nsFrameSelection* GetIndependentFrameSelection() const {
return mFrameSelection;
}
// Will return null if !mFrameSelection.
Selection* GetSelection(SelectionType aSelectionType);
@@ -1526,8 +1528,8 @@ void TextControlState::Traverse(nsCycleCollectionTraversalCallback& cb) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextEditor)
}
nsFrameSelection* TextControlState::GetConstFrameSelection() {
return mSelCon ? mSelCon->GetConstFrameSelection() : nullptr;
nsFrameSelection* TextControlState::GetIndependentFrameSelection() const {
return mSelCon ? mSelCon->GetIndependentFrameSelection() : nullptr;
}
TextEditor* TextControlState::GetTextEditor() {
@@ -1691,7 +1693,7 @@ nsresult TextControlState::PrepareEditor(const nsAString* aValue) {
return NS_OK;
}
AutoHideSelectionChanges hideSelectionChanges(GetConstFrameSelection());
AutoHideSelectionChanges hideSelectionChanges(GetIndependentFrameSelection());
if (mHandlingState) {
// Don't attempt to initialize recursively!

View File

@@ -222,7 +222,7 @@ class TextControlState final : public SupportsWeakPtr {
MOZ_CAN_RUN_SCRIPT TextEditor* GetTextEditor();
TextEditor* GetExtantTextEditor() const;
nsISelectionController* GetSelectionController() const;
nsFrameSelection* GetConstFrameSelection();
nsFrameSelection* GetIndependentFrameSelection() const;
nsresult BindToFrame(nsTextControlFrame* aFrame);
MOZ_CAN_RUN_SCRIPT void UnbindFromFrame(nsTextControlFrame* aFrame);
MOZ_CAN_RUN_SCRIPT nsresult PrepareEditor(const nsAString* aValue = nullptr);

View File

@@ -2871,8 +2871,8 @@ nsresult nsDocViewerFocusListener::HandleEvent(Event* aEvent) {
if (selection != presShell->ConstFrameSelection()) {
RefPtr<Document> doc = presShell->GetDocument();
const bool selectionMatchesFocus =
selection->GetLimiter() &&
selection->GetLimiter()->GetChromeOnlyAccessSubtreeRootParent() ==
selection->IsIndependentSelection() &&
selection->GetIndependentSelectionRootParentElement() ==
doc->GetUnretargetedFocusedContent();
if (NS_WARN_IF(!selectionMatchesFocus)) {
presShell->FrameSelectionWillLoseFocus(*selection);

View File

@@ -288,7 +288,7 @@ nsresult nsTextControlFrame::EnsureEditorInitialized() {
// Hide selection changes during the initialization, as webpages should not
// be aware of these initializations
AutoHideSelectionChanges hideSelectionChanges(
textControlElement->GetConstFrameSelection());
textControlElement->GetIndependentFrameSelection());
nsAutoScriptBlocker scriptBlocker;

View File

@@ -117,7 +117,7 @@ class nsTextControlFrame : public nsContainerFrame,
mozilla::SelectionDirection);
NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon);
nsFrameSelection* GetOwnedFrameSelection() {
return ControlElement()->GetConstFrameSelection();
return ControlElement()->GetIndependentFrameSelection();
}
nsISelectionController* GetSelectionController() {
return ControlElement()->GetSelectionController();

View File

@@ -291,6 +291,13 @@ class nsFrameSelection final {
mClickSelectionType = aClickSelectionType;
}
/**
* Return true if this is an instance for an independent selection.
* Currently, independent selection is created only in the text controls
* to manage selections in their native anonymous subtree.
*/
[[nodiscard]] bool IsIndependentSelection() const { return !!GetLimiter(); }
/**
* Returns true if the selection was created by doubleclick or
* long tap over a word.
@@ -822,9 +829,20 @@ class nsFrameSelection final {
* non-nullptr only when this instance is for an independent selection of a
* text control. Then, this returns the editor root anonymous <div> in the
* text control element.
* TODO: Rename this to GetIndependentSelectionRootElement() in bug 1954020
*/
Element* GetLimiter() const { return mLimiters.mLimiter; }
/**
* Get the independent selection root parent which is usually a text control
* element which hosts the anonymous subtree managed by this frame selection.
*/
Element* GetIndependentSelectionRootParentElement() const {
MOZ_DIAGNOSTIC_ASSERT(IsIndependentSelection());
return Element::FromNodeOrNull(
mLimiters.mLimiter->GetClosestNativeAnonymousSubtreeRootParentOrHost());
}
/**
* GetAncestorLimiter() returns the root of current selection ranges. This is
* typically the focused editing host unless it's the root element of the