None of the C++ callers of RemoveSelectionListener care about whether the
listener was already-added, and the only JS caller is in a test and knows the
listener was added. So the behavior change to no-op instead of throwing when
trying to remove a nonexistent listener is OK. Furthermore, the removal is
null-safe, so there's no point to explicitly failing if null is passed (which
it never is).
Since content can't directly add selection listeners, we can just use an
infallible append instead of returning errors callers don't check for anyway.
Also, no one passes null to AddSelectionListener, so we don't have to worry
about that part.
This way we don't have to deal with QI to get a Selection out of a weakref.
mfbt weakrefs don't have a SizeOfOnlyThis. In any case, the memory used by the
weakref itself is pretty minor...
Some methods of editor retrieves anchor and focus of selection. However, there
are no methods which directly access RangeBoundary of anchor and focus.
This patch adds it for making editor code simpler and avoiding unnecessary
child offset computation.
MozReview-Commit-ID: EvepQpFMi8S
This private method DoAutoScroll() modifies aPoint inside of it, and none of
other callers (StartAutoScrollTimer() and nsAutoScrollTimer::Notify()) read
aPoint afterwards, so we make aPoint pass by value rather than pass by
non-const-reference. This is necessary for later parts.
MozReview-Commit-ID: 9PtxFXIka7X
Selection should have Collapse() methods which take RawRangeBoundary instead of
a set of container and offset in it. Then, if caller know only child node but
doesn't know offset in the container, neither callers, Selections nor nsRange
needs to compute offset. This makes them avoid calling expensive method,
nsINode::IndexOf().
MozReview-Commit-ID: 79IRajLe1FE
nsISelectionPrivate is accessible to script, while nsISelection is
not, so making the former inherit from the latter means script doesn't
have a complete view of the inheritance chain so the XPIDL compiler
produces an error.
It turns out that nothing in script relies on this inheritance, which
makes sense because I'm not sure how it would even work, so just
remove it.
MozReview-Commit-ID: 3Py2T7cprlD
There is no reason to keep StartBatchChanges and EndBatchChanges in nsISelectionPrivate since this is noscript method. And if moving it to Selection, we can remove virtual keyword.
MozReview-Commit-ID: Go6njiW3r2x
Similar to Selection::Collapse(), if mCachedRange is available,
Selection::SetBaseAndExtent() should use it rather than creating new nsRange
instance.
Then, it can reduce the allocation cost and may reduce some other cost, e.g.,
adding it to mutation observer.
MozReview-Commit-ID: InQQusw2KMc
When setting value of <input type="text">, nsTextEditorState removes all
ranges of normal selection first. Then, TextEditor sets the value. Finally,
TextEditor collapses the selection at the end of the text.
In bug 1386471, we got that there are some problems to remove the call of
Selection::RemoveAllRanges() in nsTextEditorState. Therefore, we need another
approach to improve Selection::Collapse().
The approach of this patch is, when removing all ranges from normal selection,
Selection can cache an nsRange instance if there is an instance which is not
referenced from other than the Selection (i.e., it'll be removed when
Selection::Clear() is called). Then, Selection::Collapse() can reuse it. With
this fix, Selection::Collapse() can reduce allocation cost and may reduce some
other cost like adding it to mutation observer.
However, keeping nsRange instance may cause increasing mutation observer's cost
since nsRange will be adjusted its start node/offset and end node/offset with
mutation observer to guarantee that the range is always valid. So, we can
cache such range only when the caller (or its callee) will set selection range
later. Therefore, this patch adds Selection::RemoveAllRangesTemporarily()
and make only nsTextEditorState::SetValue() and
ContentEventHandler::OnSelectionEvent() use it.
MozReview-Commit-ID: FjWrbz4S1ld
nsISelectionController::SELECTION_* are declared as bit-mask. However, no
methods of nsISelectionController treat them as bit-mask and these
values need a switch statement in nsFrameSelection to convert SelectionType to
array index of nsFrameSelection::mDOMSelections because it's too big to create
an array to do it. Additionally, this conversion appears profile of
attachment 8848015.
So, now, we should declare these values as sequential integer values.
However, only nsTextFrame uses these values as bit-mask. Therefore, this patch
adds new type, SelectionTypeMask and creates new inline method,
ToSelectionTypeMask(SelectionType), to retrieve mask value for a SelectionType.
MozReview-Commit-ID: 5Za8mA6iu4
There is no reason that SetTextRangeStyle is defined at nsISelectionPrivate. Also, SetTextRangeStyle isn't scriptable, and is called from CompositionTransaction::SetIMESelection only. So we should move this to Selection.
MozReview-Commit-ID: FCOA6wVhvYZ
When enabling lazy frame construction, whitespace only node might not have frame. So editor/libeditor/tests/test_bug1315065.html is failure because nsFrameSelection::MoveCaret returns error since focus node is whitespace only node that has no frame.
So if focus node is whitespace only, we should promote to parent to get primary frame then try again.
MozReview-Commit-ID: K83T2LP3Pc5
nsContentUtils::GetHTMLEditor() currently returns nsIEditor* since editor of doc shell may be any type of editors such as TextEditor or editor object which is implemented by JS. However, nsIEditor is now a builtin class. So, it can return HTMLEditor.
MozReview-Commit-ID: 3YoFOplZa7W
This matches the spec and Chrome, and seems to bring us closer to Edge
and WebKit as well. It also matches our own behavior for addRange(),
which was changed in bug 1341137.
For collapse and selectAllChildren, we match the tests and browsers, but
the spec is incorrect at the time of this writing:
https://github.com/w3c/selection-api/pull/86
The removeAllRanges test hadn't been updated for the spec change.
MozReview-Commit-ID: DTK8283k5IP
Most selections on the Web end up with one Range inside them.
By reserving the space for this one range inline, we can avoid the
allocator pressure in a lot of hot code when manipulating the
Selection object.