Bug 1677253 - Part 1: Fire select event from SelectionChangeEventDispatcher r=masayuki

Differential Revision: https://phabricator.services.mozilla.com/D101245
This commit is contained in:
Kagami Sascha Rosylight 2021-01-12 08:59:34 +00:00
Родитель e740ed7de3
Коммит 8bbd008864
3 изменённых файлов: 25 добавлений и 51 удалений

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

@ -120,53 +120,35 @@ void SelectionChangeEventDispatcher::OnSelectionChange(Document* aDoc,
return;
}
nsCOMPtr<nsINode> textControl;
if (const nsFrameSelection* fs = aSel->GetFrameSelection()) {
if (nsCOMPtr<nsIContent> root = fs->GetLimiter()) {
textControl = root->GetClosestNativeAnonymousSubtreeRoot();
}
}
if (textControl && !(aReason & (nsISelectionListener::MOUSEUP_REASON |
nsISelectionListener::KEYPRESS_REASON |
nsISelectionListener::DRAG_REASON))) {
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(textControl, eFormSelect, CanBubble::eYes);
asyncDispatcher->PostDOMEvent();
}
// The spec currently doesn't say that we should dispatch this event on text
// 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 (StaticPrefs::dom_select_events_textcontrols_enabled()) {
nsCOMPtr<nsINode> target;
if (textControl && !StaticPrefs::dom_select_events_textcontrols_enabled()) {
return;
}
// Check if we should be firing this event to a different node than the
// document. The limiter of the nsFrameSelection will be within the native
// anonymous subtree of the node we want to fire the event on. We need to
// climb up the parent chain to escape the native anonymous subtree, and
// then fire the event.
if (const nsFrameSelection* fs = aSel->GetFrameSelection()) {
if (nsCOMPtr<nsIContent> root = fs->GetLimiter()) {
while (root && root->IsInNativeAnonymousSubtree()) {
root = root->GetParent();
}
nsCOMPtr<nsINode> target = textControl ? textControl : aDoc;
target = std::move(root);
}
}
// If we didn't get a target before, we can instead fire the event at the
// document.
if (!target) {
target = aDoc;
}
if (target) {
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(target, eSelectionChange, CanBubble::eNo);
asyncDispatcher->PostDOMEvent();
}
} else {
if (const nsFrameSelection* fs = aSel->GetFrameSelection()) {
if (nsCOMPtr<nsIContent> root = fs->GetLimiter()) {
if (root->IsInNativeAnonymousSubtree()) {
return;
}
}
}
if (aDoc) {
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(aDoc, eSelectionChange, CanBubble::eNo);
asyncDispatcher->PostDOMEvent();
}
if (target) {
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(target, eSelectionChange, CanBubble::eNo);
asyncDispatcher->PostDOMEvent();
}
}

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

@ -374,7 +374,8 @@ void EventListenerManager::AddEventListenerInternal(
if (!aFlags.mInSystemGroup) {
mMayHaveInputOrCompositionEventListener = true;
}
} else if (aEventMessage == eSelectionChange) {
} else if (aEventMessage == eSelectionChange ||
aEventMessage == eFormSelect) {
mMayHaveSelectionChangeEventListener = true;
if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
window->SetHasSelectionChangeEventListeners();

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

@ -2101,15 +2101,6 @@ void TextControlState::SetSelectionRange(
// example.
mBoundFrame->ScrollSelectionIntoViewAsync();
}
// Press on to firing the event even if that failed, like our old code did.
// But is that really what we want? Firing the event _and_ throwing from
// here is weird. Maybe we should just ignore ScrollSelectionIntoView
// failures?
// XXXbz This is preserving our current behavior of firing a "select" event
// on all mutations when we have an editor, but we should really consider
// fixing that...
changed = true;
}
if (changed) {