Everyone calls them with the shell of the current composed document, and this
allows the multi-presShell stuff to just be in UpdateCurrentStyleSources /
DoGetStyleContextNoFlush.
The only reason we need to use OwnerDoc()->GetShell() instead of the composed
doc in GetStyleContext / GetStyleContextNoFlush is Element::GetBindingURL, which
does expect to get the binding URL for stuff outside of the composed doc (and
changing that gave me a useless browser).
That's technically a behavior change on the cases that used to pass nullptr, but
I think all callers are fine with that. I could also just add a special function
for that particular case, it may be worth it.
MozReview-Commit-ID: 2XlnkgdgDCK
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
--HG--
rename : layout/inspector/nsFontFace.cpp => layout/inspector/InspectorFontFace.cpp
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
--HG--
extra : rebase_source : 8d1632a030f1e0a0dd2b81c3996c19d427e8b0bd
EditorDOMPoint was a subclass of RangeBoundary. Therefore, for heavy
use of it in editor, we've implemented a lot of complicated feature
into RangeBoundary. However, EditorDOMPoint stopped inheriting
RangeBoundary. So, we can get simple RangeBoundary implementation
back now.
This patch makes RangeBoundary.h almost same as 3f7cbec2446b except
keeps implementing GetPreviousSiblingOfChildAtOffset() and
GetNextSiblingOfChildAtOffset() because the former is used by
Selection and both of them are simple. And also keeps making it
a friend of EditorDOMPoint because EditorDOMPoint still needs to
copy to/from RangeBoundary.
MozReview-Commit-ID: Hr5SA52ScK0
--HG--
extra : rebase_source : a00a46ff931a5c4fcabf910510fa448b513f50c5
RangeBoundaryBase shouldn't compute mRef when it's initialized with offset.
E.g., some users of the template class may initialize it with a container and
offset in it but it may not refer mRef or may refer after modifying offset.
On the other hand, RangeBoundaryBase::InvalidateOffset() is a special method.
It assumes that mRef is always initialized when it's called but can be
invalidate mOffset until retrieved actually. This is necessary for
nsRange::mStart and nsRange::mEnd since the offset may be changed when
some nodes are inserted before the referring node.
So, now, InvalidateOffset() should be a protected method and make nsRange a
friend class of RangeBoundaryBase. Then, when nsRange sets mStart and/or mEnd,
nsRange itself should guarantee that their mRefs are initialized.
MozReview-Commit-ID: Alr4YkDXIND
--HG--
extra : rebase_source : 7e6828374db7989ae91b9e485571ec553f7435af
This should really always test true, but apparently sometimes doesn't...
that's quite strange. Hopefully the diagnostic asserts will help pin down how
it can happen.
MozReview-Commit-ID: 4bxdalIaUnQ
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
--HG--
extra : rebase_source : 28ff355a2aa0dcb5d65495806ef8c67f1da642ea
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
--HG--
extra : rebase_source : c4eb58e8f37c408c75479e6961ba9225f8bcee77
Per spec, Range.prototype.extractNodes() should copy the nodes in tree
order:
https://dom.spec.whatwg.org/#dom-range-extractcontents
Gecko instead copies them in reverse order. This causes us to fail a
wpt MutationObserver test.
MozReview-Commit-ID: 8MYXGhDsJCd
--HG--
extra : rebase_source : 94fb2e96370e575906ba9927d904561744a1d7bb
If a range endpoint is in the middle of a text node, and you call
deleteContents() or extractContents(), the spec says to delete the data
from the node. In the case of extractContents(), the new text node
that's inserted into the DocumentFragment is a clone with its data set
to the bit that was deleted.
<https://dom.spec.whatwg.org/#dom-range-deletecontents>
<https://dom.spec.whatwg.org/#dom-range-extractcontents>
We don't do this. Instead, we split the text node. Then the bit to
delete is deleted naturally at a later stage together with all the other
nodes.
The result is the same, but on the way there we do a bunch more node
mutations. This causes extra mutation records, which cause us to fail a
WPT test. Chrome passes. Changing to match the spec actually reduces
our lines of code anyway.
MozReview-Commit-ID: FTTV5yNSj71
--HG--
extra : rebase_source : 8d5f36c68c71db0700f0b86d1a73462759f922e8
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
--HG--
extra : rebase_source : 46d526c6d50dfa2f104439b19b8691477b17a4af
`nsRange` registers mutation observers to adjust the range when content
changes. However, there are some cases where we adjust the start and/or
end offsets but don't notify selection listeners (i.e. we don't call
`nsRange::DoSetRange` to set the new range points, contrary to what the
comment above `nsRange::DoSetRange` says). This patch makes us call
`nsRange::DoSetRange` in those cases. The patch adds a testcase in
test_selectevents.html, and changes a few unexpected-pass cases in
test_composition_text_querycontent.xul that this patch fixed.
MozReview-Commit-ID: 73D8RYMS3MS
--HG--
extra : rebase_source : da0cc3073e4b8ad23c6f6eab42da5aa8b269cae9
This does NOT change variable names like |endNode| because it's not odd and somebody use it for nsINode and endContent for nsIContent. So, changing them needs more work.
MozReview-Commit-ID: 22imUltlu5R
--HG--
extra : rebase_source : 6c93069d0586b37c5084eaa71861085c01da7a7d
This does NOT change variable names like |startNode| because it's not odd and somebody use it for nsINode and startContent for nsIContent. So, changing them needs more work.
MozReview-Commit-ID: H19pTDprRuT
--HG--
extra : rebase_source : 7a7454ac14da48a597ff19a50c863d04dcaddd6e
Web standards use "Container" instead of "Parent". So, nsRange shouldn't use "Parent" for its members and methods.
MozReview-Commit-ID: Ho6N0diuWtE
--HG--
extra : rebase_source : ee4eb7068a68b118c7fe98e9e9e7fa9c9e7f13e2
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
--HG--
extra : rebase_source : 67adf929cf119e2425f7d3741651217522094590
This avoids conflicts with mozilla::dom::FrameType.
MozReview-Commit-ID: 7aEMbHRaTFk
--HG--
extra : rebase_source : 2d01321f5ce0ec8c0e3f70984674f82678034b3c
In the next patch we want to add a method called
GetUnanimatedStyleContextForElementNoFlush but that's much too long. Instead it
seems better to just drop 'ForElement' from all these methods since it should be
fairly obvious we are getting the style context for an element given that the
first argument is an element.
MozReview-Commit-ID: JQKaEuCKV2F
--HG--
extra : rebase_source : 3ba51f3b00d1ec7bc91102629d9c0abb88992fef
When nsRange::*JS() is called, mCalledByJS is set to true. In such case, Selection::NotifySelectionListeners() may move focus or anyway, it calls selection listeners. Then, they may cause calling non-*JS() methods of the nsRange instance. In this case, nsRange treats the call as called by JS since mCalledByJS is still true.
For preventing this issue, before calling Selection::NotifySelectionListeners(), nsRange should set mCalledByJS to false.
This patch renames AutoCalledByJSSetter to AutoCalledByJSRestore and make it stop setting mCalledByJS automatically. So, AutoCalledByJSRestore works same as AutoRestore now.
MozReview-Commit-ID: IYsbQTGp3VA
--HG--
extra : rebase_source : 582eb2288c035861f16149dde42c22aba555bb5a
Selection may be changed by methods of Selection or methods of Range retrieved by Selection.getRangeAt(). Selection::NotifySelectionListeners() is called after every selection change of each of them, so, this method must be a good point to move focus.
If new common ancestor of all ranges is editable and in an editing host, we should move focus to it. Otherwise, if an editing host has focus but new common ancestor is not editable, we should move focus from the editing host.
For consistency with the other browsers, this patch doesn't move focus to other focusable element.
MozReview-Commit-ID: 6sNsuzwqECX
--HG--
extra : rebase_source : 9ba52ab0bd1249abded81019847c85182ca1926e
Selection needs to be able to distinguish if every selection change is caused by JS (i.e., via Selection API) or the others.
This patch maps some methods of Range and Selection to *JS(). Each of them marks its instance as "used by JS" and calls corresponding method.
With this change, Selection::NotifySelectionListeners() can move focus only when it's caused by Selection API.
MozReview-Commit-ID: 1GoLHiIJ10Y
--HG--
extra : rebase_source : 02d497f9e55b3325a2e01c3041cadb90881dccb8
The main renaming was generated with the following python script:
```
import sys
import re
CAMEL_CASE_REGEX = re.compile(r"(^|_|-)([A-Z])([A-Z]+)")
DISPLAY_REGEX = re.compile(r"\bNS_STYLE_DISPLAY_([^M][A-Z_]+)\b")
def to_camel_case(ident):
return re.sub(CAMEL_CASE_REGEX,
lambda m: m.group(2) + m.group(3).lower(), ident)
def constant_to_enum(constant):
return "StyleDisplay::" + to_camel_case(constant) + ("_" if constant == "NONE" else "")
def process_line(line):
return re.sub(DISPLAY_REGEX,
lambda m: constant_to_enum(m.group(1)), line)
lines = []
with open(sys.argv[1], "r") as f:
for line in f:
lines.append(process_line(line))
with open(sys.argv[1], "w") as f:
for line in lines:
f.write(line)
```
And the following shell commands:
```
find . -name '*.cpp' -exec python display.py {} \;
find . -name '*.h' -exec python display.py {} \;
```
MozReview-Commit-ID: 91xYCbLC2Vf
CLOSED TREE
Backed out changeset dbadb8fe5803 (bug 1216001)
Backed out changeset a30593ebd58e (bug 1216001)
Backed out changeset c1646ffa71b4 (bug 1216001)