Bug 1343037 part 11. Implement a SetSelectionRange function on nsTextEditorState. r=ehsan

MozReview-Commit-ID: 5xUkcnkptwQ
This commit is contained in:
Boris Zbarsky 2017-03-09 14:44:05 -05:00
Родитель 083facd7b2
Коммит fd2deff856
2 изменённых файлов: 79 добавлений и 0 удалений

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

@ -1645,6 +1645,69 @@ nsTextEditorState::GetSelectionDirection(ErrorResult& aRv)
return nsITextControlFrame::eBackward;
}
void
nsTextEditorState::SetSelectionRange(int32_t aStart, int32_t aEnd,
nsITextControlFrame::SelectionDirection aDirection,
ErrorResult& aRv)
{
MOZ_ASSERT(IsSelectionCached() || mBoundFrame,
"How can we have a non-cached selection but no frame?");
if (aStart > aEnd) {
aStart = aEnd;
}
bool changed = false;
nsresult rv = NS_OK; // For the ScrollSelectionIntoView() return value.
if (IsSelectionCached()) {
nsAutoString value;
// XXXbz is "false" the right thing to pass here? Hard to tell, given the
// various mismatches between our impl and the spec.
GetValue(value, false);
uint32_t length = value.Length();
if (uint32_t(aStart) > length) {
aStart = length;
}
if (uint32_t(aEnd) > length) {
aEnd = length;
}
SelectionProperties& props = GetSelectionProperties();
changed = props.GetStart() != aStart ||
props.GetEnd() != aEnd ||
props.GetDirection() != aDirection;
props.SetStart(aStart);
props.SetEnd(aEnd);
props.SetDirection(aDirection);
} else {
aRv = mBoundFrame->SetSelectionRange(aStart, aEnd, aDirection);
if (aRv.Failed()) {
return;
}
rv = mBoundFrame->ScrollSelectionIntoView();
// 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) {
// It sure would be nice if we had an existing Element* or so to work with.
nsCOMPtr<nsINode> node = do_QueryInterface(mTextCtrlElement);
RefPtr<AsyncEventDispatcher> asyncDispatcher =
new AsyncEventDispatcher(node, NS_LITERAL_STRING("select"), true, false);
asyncDispatcher->PostDOMEvent();
}
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
}
HTMLInputElement*
nsTextEditorState::GetParentNumberControl(nsFrame* aFrame) const
{

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

@ -281,6 +281,22 @@ public:
nsITextControlFrame::SelectionDirection
GetSelectionDirection(mozilla::ErrorResult& aRv);
// Set the selection range (start, end, direction). aEnd is allowed to be
// smaller than aStart; in that case aStart will be reset to the same value as
// aEnd. This basically implements
// https://html.spec.whatwg.org/multipage/forms.html#set-the-selection-range
// but with the start/end already coerced to zero if null (and without the
// special infinity value), and the direction already converted to a
// SelectionDirection.
//
// If we have a frame, this method will scroll the selection into view.
//
// XXXbz This should really take uint32_t, but none of our guts (either the
// frame or our cached selection state) work with uint32_t at the moment...
void SetSelectionRange(int32_t aStart, int32_t aEnd,
nsITextControlFrame::SelectionDirection aDirection,
mozilla::ErrorResult& aRv);
void UpdateEditableState(bool aNotify) {
if (mRootNode) {
mRootNode->UpdateEditableState(aNotify);