зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1343037 part 11. Implement a SetSelectionRange function on nsTextEditorState. r=ehsan
MozReview-Commit-ID: 5xUkcnkptwQ
This commit is contained in:
Родитель
083facd7b2
Коммит
fd2deff856
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче