This also changes the function to return a sequence (JS Array) instead of
an nsFontFaceList object, and converts nsFontFace/nsIDOMFontFace into a
Web IDL implemented object too.
MozReview-Commit-ID: 1iAW3DYe5kO
nsRange::SetStart(), nsRange::SetEnd(), nsRange::IsPointInRange() and
nsRange::ComparePoint() take a set of container node and offset in it to
specifying a DOM point. However, the caller may not have computed the offset
but may know the child node at the point. In such case, they can avoid
computing the offset with nsINode::IndexOf() if they have overloads which
take RawRangeBoundary.
Therefore, this patch implements the overloads and changes the callers in
editor.
MozReview-Commit-ID: E4DLbAgTTCI
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
Inserting/removing things into a doubly-linked list is much faster than doing
the same with a hashtable. Selection ranges register themselves on their common
ancestor, but all we do with that in non-debug code is iterate all the ranges
registered. A doubly-linked list works fine for that.
This adds three words to every range for the LinkedListItem members, but that
should be OK.
Inserting/removing things into a doubly-linked list is much faster than doing
the same with a hashtable. Selection ranges register themselves on their common
ancestor, but all we do with that in non-debug code is iterate all the ranges
registered. A doubly-linked list works fine for that.
This adds three words to every range for the LinkedListItem members, but that
should be OK.
This costs an extra word per range, but ranges aren't that small anyway. The
benefit is that we don't have to recompute it dynamically when we need it, which
lets us simplify how selection ranges get registered with their common ancestors.
nsIContentIterator::Init() takes nsRange but it's too expensive for some users.
So, there should be another Init() which can be specified a range in DOM tree
with 2 pairs of nsINode* and uint32_t.
MozReview-Commit-ID: 6JXic0KOM2d
Allocating and initializing nsRange is too expensive especially for temporary
use. However, ContentEventHandler uses nsRange only for representing two DOM
points. So, it should use simpler helper class, RawRange, for reducing some
unnecessary runtime cost.
Note that this still uses nsRange for initializing nsIContentIterator. This
will be fixed by the following patch.
MozReview-Commit-ID: 5TUy6yJf7HA
DOM Standard defines that offset of Range is unsigned long. However, nsRange uses int32_t to them.
This patch makes nsRange use uint32_t instead. However, this patch does NOT allow to set over INT32_MAX as offset values since a lot of users of nsRange cannot treat the values as over INT32_MAX because a lot of internal APIs take int32_t as offsets.
For easier to search such points, this patch adds static_cast<int32_t> to uint32_t variables when they are used for int32_t arguments.
And note that nsContentUtils::ComparePoints() behaves odd. It accepts negative offset and compares such value with valid offset simply. This patch still uses int32_t offset variables in nsRange::CompareNodeToRange() even though it may be negative value if nsINode::IndexOf() returns -1 because the caller of it depends on this behavior.
MozReview-Commit-ID: 8RbOgA86JuT
Selection::Collapse() removes all ranges first, then, adds a collapsed range which is a new instance of nsRange.
However, new nsRange's initialize cost isn't cheap. It needs to add itself to mutation observer and computes common ancestor. However, Selection::Collapse() doesn't move the range to different document. If old range is reusable, we can avoid to remove old range from mutation observer and add new range to mutation observer, and also we can avoid to recompute common ancestor if the node is not changed, e.g., only offset is changed in selected node.
MozReview-Commit-ID: BoCBod7WVr5
nsRange::DoSetRange() adds/remove its root to/from mutation observer, initializes common ancestor, registers itself to the common ancestor, unregisters itself from old common ancestor, and notifies selection listeners of selection change.
However, those runtime cost is expensive but on the other hand, a lot of callers set both start and end of the range and that causes calling DoSetRange() twice.
This patch renames Set() to SetStartAndEnd() for easier to understand the meaning and make it call DoSetRange() only once.
MozReview-Commit-ID: FRV55tuBAgg