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-06-21 00:58:35 +00:00
parent e6ad82a33f
commit 7fe1ff4e91
4 changed files with 65 additions and 86 deletions

View File

@@ -2041,20 +2041,7 @@ void TextControlState::SetSelectionRange(
aStart = aEnd;
}
bool changed = false;
nsresult rv = NS_OK; // For the ScrollSelectionIntoView() return value.
if (IsSelectionCached()) {
SelectionProperties& props = GetSelectionProperties();
if (!props.HasMaxLength()) {
// A clone without a dirty value flag may not have a max length yet
nsAutoString value;
GetValue(value, false);
props.SetMaxLength(value.Length());
}
changed |= props.SetStart(aStart);
changed |= props.SetEnd(aEnd);
changed |= props.SetDirection(aDirection);
} else {
if (!IsSelectionCached()) {
MOZ_ASSERT(mBoundFrame, "Our frame should still be valid");
aRv = mBoundFrame->SetSelectionRange(aStart, aEnd, aDirection);
if (aRv.Failed() ||
@@ -2066,36 +2053,38 @@ 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;
return;
}
if (changed) {
// It sure would be nice if we had an existing Element* or so to work with.
RefPtr<AsyncEventDispatcher> asyncDispatcher = new AsyncEventDispatcher(
mTextCtrlElement, eFormSelect, CanBubble::eYes);
SelectionProperties& props = GetSelectionProperties();
if (!props.HasMaxLength()) {
// A clone without a dirty value flag may not have a max length yet
nsAutoString value;
GetValue(value, false);
props.SetMaxLength(value.Length());
}
bool changed = props.SetStart(aStart);
changed |= props.SetEnd(aEnd);
changed |= props.SetDirection(aDirection);
if (!changed) {
return;
}
// It sure would be nice if we had an existing Element* or so to work with.
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(mTextCtrlElement, eFormSelect, CanBubble::eYes);
asyncDispatcher->PostDOMEvent();
// SelectionChangeEventDispatcher covers this when !IsSelectionCached().
// XXX(krosylight): Shouldn't it fire before select event?
// Currently Gecko and Blink both fire selectionchange after select.
if (IsSelectionCached() &&
StaticPrefs::dom_select_events_textcontrols_enabled()) {
asyncDispatcher = new AsyncEventDispatcher(
mTextCtrlElement, eSelectionChange, CanBubble::eNo);
asyncDispatcher->PostDOMEvent();
// SelectionChangeEventDispatcher covers this when !IsSelectionCached().
// XXX(krosylight): Shouldn't it fire before select event?
// Currently Gecko and Blink both fire selectionchange after select.
if (IsSelectionCached() &&
StaticPrefs::dom_select_events_textcontrols_enabled()) {
asyncDispatcher = new AsyncEventDispatcher(
mTextCtrlElement, eSelectionChange, CanBubble::eNo);
asyncDispatcher->PostDOMEvent();
}
}
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
}
@@ -2277,7 +2266,8 @@ void TextControlState::SetRangeText(const nsAString& aReplacement,
// Batch selectionchanges from SetValueFromSetRangeText and SetSelectionRange
Selection* selection =
mSelCon ? mSelCon->GetSelection(SelectionType::eNormal) : nullptr;
SelectionBatcher selectionBatcher(selection); // no-op if nullptr
SelectionBatcher selectionBatcher(
selection, nsISelectionListener::JS_REASON); // no-op if nullptr
MOZ_ASSERT(aStart <= aEnd);
value.Replace(aStart, aEnd - aStart, aReplacement);