This new cache implementation keeps the last N node/index combos in a stack-allocated array, which will be queried before calling nsINode::ComputeIndexOf().
Differential Revision: https://phabricator.services.mozilla.com/D203900
This new cache implementation keeps the last N node/index combos in a stack-allocated array, which will be queried before calling nsINode::ComputeIndexOf().
Differential Revision: https://phabricator.services.mozilla.com/D203900
This new cache implementation keeps the last N node/index combos in a stack-allocated array, which will be queried before calling nsINode::ComputeIndexOf().
Differential Revision: https://phabricator.services.mozilla.com/D203900
This new cache implementation keeps the last N node/index combos in a stack-allocated array, which will be queried before calling nsINode::ComputeIndexOf().
Differential Revision: https://phabricator.services.mozilla.com/D203900
These loops may run script.
In `HyperTextAccessible`, it calls
`RemoveRangeAndUnselectFramesAndNotifyListeners`. So, chrome script which is not
directly related to this module may run in each call. I think that using
`RemoveAllRanges` is better for here. Before bug 1735446, this loop tried
to keep first range, but accidentally, I changed this loop delete all ranges.
However, `SetSelectionBoundsAt` will add a range if it's required and there is
no bug reports. Therefore, I think keep the new behavior is better.
In `nsRange::DeleteFromDocument`, the loop may run mutation events too.
Therefore, it needs to store all ranges first. Then, the preceding patch
changes the behavior here if a selection range is moved to different root.
Previously, it was deleted, but now, they are not touched.
Depends on D200606
Differential Revision: https://phabricator.services.mozilla.com/D200607
Ranges stored in Selection::StyledRanges are expected to be sorted by their start point.
In Bug 1872535 a range reordering was introduced which makes sure that static ranges are at the right spot after a DOM mutation has happened.
Reordering is necessary in two conditions:
- The document generation has changed (=There are changes to the DOM tree)
- A selection has changed (which would call NotfySelectionListeners())
However, when a range is added, it is not necessary to reorder, since the AddRange...() method inserts the new range at the correct spot (and reorders beforehand if necessary).
Differential Revision: https://phabricator.services.mozilla.com/D200592
Ranges inside of a `Selection` are expected to be sorted by their start point by the painting algorithms. Also, `StaticRange`s, which previously were not part of `Selection`, need to be considered for painting based on their `IsValid()` status.
This is now added by introducing a second array for invalid static ranges and an additional re-ordering method which needs to be called before paint that moves ranges in between.
A potential change in range endpoints can be determined by observing the `Document`s generation and by adding a flag that's set to true in `Selection::NotifySelectionObservers()`.
Differential Revision: https://phabricator.services.mozilla.com/D198943
The methods are in `nsCaret`, `nsFrameSelection` and `dom::Selection`. That
makes harder to read, and they are called each other, so, they are reused for
different purpose. Therefore, it must be better to move them into a new class.
Then, the name differences may become more unclear. If you think so, feel free
to request renaming some methods of them.
Differential Revision: https://phabricator.services.mozilla.com/D197288
A caller of it should be independent from `nsFrameSelection` instance.
Therefore, I'd like to separate it to static method part and instance method
part.
Differential Revision: https://phabricator.services.mozilla.com/D197287
Its name sounds a getter, but it updates the caret association hint of
`nsFrameSelection`, but at least, one of its callers,
`nsFrameSelection::PeekOffsetForCaretMove` shouldn't update it because it
just scans the previous or next position for caret.
Then, `Selection::GetPrimaryFrameForFocusNode` can be implemented with a
new static method which is useful for `PeekOffsetForCaretMove` when it becomes
a static method.
Differential Revision: https://phabricator.services.mozilla.com/D197286
Oddly, it updates `nsFrameSelection` instance and some root callers may depend
on that. Therefore, this patch keep updating `nsFrameSelection` in the callers.
Differential Revision: https://phabricator.services.mozilla.com/D197284
When pressing `ArrowLeft` key at:
```
<p>abc</p><p><span contenteditable=false>def</span>{}<br></p>
```
, caret is moved into the non-editable text because
`nsCaret::GetCaretFrameForNodeOffset` looks for a preceding text node from
the `BRFrame`. This is required if the preceding text node ends with a
collapsible white-space but followed by a `<br>` because the text frame
should not contain the white-space rect and `BRFrame` frame should be next
to it, i.e., the white-space looks like a overflown content.
So, for rendering a caret, the method needs to return non-editable text frame
even in the case, but for considering new caret position in the DOM tree, it
should not return non-editable text frame.
Therefore, this patch adds a param to `nsCaret::GetCaretFrameForNodeOffset()`
which forcibly return editable content frame or not and makes
`Selection::GetPrimaryOrCaretFrameForNodeOffset` call it with the new option
because its callers are the handler of caret navigation.
Differential Revision: https://phabricator.services.mozilla.com/D196259
Sorry this is not a particularly easy patch to review. But it should be
mostly straight-forward.
I kept Document::Dispatch mostly for convenience, but could be
cleaned-up too / changed by SchedulerGroup::Dispatch. Similarly maybe
that can just be NS_DispatchToMainThread if we add an NS_IsMainThread
check there or something (to preserve shutdown semantics).
Differential Revision: https://phabricator.services.mozilla.com/D190450
This function had some code that we hadn't yet updated to support vertical
writing modes. This patch makes it more generic so that it can properly handle
vertical-writing-mode text nodes (so that we can e.g. properly keep the caret
scrolled into view, in a vertical-writing-mode textfield).
I'm just focusing on vertical vs. horizontal generification for now. I'm not
entirely sure if it makes sense to make it even-more-generic-still to support
reversed-inline-direction writing modes as well. I wasn't able to trigger any
issues with those in some brief testing, so I think this patch is sufficient
as-is, but I left a TODO(dholbert) code-comment to call out that ambiguity
that's still present in the code.
Differential Revision: https://phabricator.services.mozilla.com/D187160
This patch doesn't change behavior. It's just laying the groundwork for the
next patch which adds vertical-writing-mode support.
(This patch adds some documentation in terms of logical axes, though, which
will become accurate as of the next patch in this series.)
Differential Revision: https://phabricator.services.mozilla.com/D187161
This function had some code that we hadn't yet updated to support vertical
writing modes. This patch makes it more generic so that it can properly handle
vertical-writing-mode text nodes (so that we can e.g. properly keep the caret
scrolled into view, in a vertical-writing-mode textfield).
I'm just focusing on vertical vs. horizontal generification for now. I'm not
entirely sure if it makes sense to make it even-more-generic-still to support
reversed-inline-direction writing modes as well. I wasn't able to trigger any
issues with those in some brief testing, so I think this patch is sufficient
as-is, but I left a TODO(dholbert) code-comment to call out that ambiguity
that's still present in the code.
Differential Revision: https://phabricator.services.mozilla.com/D187160
This patch doesn't change behavior. It's just laying the groundwork for the
next patch which adds vertical-writing-mode support.
(This patch adds some documentation in terms of logical axes, though, which
will become accurate as of the next patch in this series.)
Differential Revision: https://phabricator.services.mozilla.com/D187161
It always set to "start of next line" when new range was added. However,
after bug 1815802, it does nothing when adding range is one of its ranges.
Therefore, if interline position is set to "end of line" by our internal
code, like editor, `getSelection().addRange(getSelection().getRangeAt(0))`
keeps the last interline position.
Differential Revision: https://phabricator.services.mozilla.com/D182300
The idea of this struct is to allow live data of a highlight selection to be passed into layout.
Layout needs highlight properties such as priority or type to resolve combinations of highlights correctly.
Differential Revision: https://phabricator.services.mozilla.com/D181142
With this change, Selections are also registered into StaticRanges,
ultimately making them visible to `nsINode::IsSelected()`,
which is necessary to paint them.
Differential Revision: https://phabricator.services.mozilla.com/D175784
With this change, Selections are also registered into StaticRanges,
ultimately making them visible to `nsINode::IsSelected()`,
which is necessary to paint them.
Differential Revision: https://phabricator.services.mozilla.com/D175784
It's hard to check Selection API calls from both JS and internals when we debug
web apps which has complicated `contenteditable` editor. Therefore, I'd like to
add an ability to log Selection API calls.
This patch needs to stop some methods inlined. Therefore, this could affect to
the performance in release builds, though. If so, I need to work on some
optimization later.
For minimizing the impact for performance, this patch also makes them to check
the logging level before calling logging methods. It's currently redundant
for `LogLevel::Info` case. However, this avoids any performance impact from
changes of `MOZ_LOG` implementation and in the blocks.
Differential Revision: https://phabricator.services.mozilla.com/D170585
This change is necessary to support the [CSS Highlight API](https://drafts.csswg.org/css-highlight-api-1/),
which uses `Selection` internally.
To replace `nsRange` with `AbstractRange`, some sections needed to be
adapted since `nsRange`-specific features were used.
Therefore, some methods (such as `GetRangeAt()`) may only be called if
the `Selection` is *not* of type `SelectionType::eHighlight`,
as it (per spec) returns an `nsRange`.
These methods will now `MOZ_ASSERT` if called for a highlight selection.
Additional methods are implemented which return `AbstractRange`
instead and are safe to be called for every selection type.
This commit also improves support of highlight features:
- Invalidation of highlight ranges: adding/removing Ranges in-place instead of
removing and re-adding the Selection object associated with the highlight.
- Ranges are only associated with the Selection that shares the same Document
- Fixed minor IDL issue
Differential Revision: https://phabricator.services.mozilla.com/D170582
The Custom Highlight API allows a use case where a `Range` of a `Highlight`
is also used as `Selection`. Due to the decision to use the `Selection` mechanism
to display `Highlight`s, a `Range` can be part of several `Selection`s.
Since the `Range` has a pointer to its associated `Selection`
to notify about changes, this must be adapted to allow several `Selections`.
As a tradeoff of performance and memory usage, the `Selection`s are stored
as `mozilla::LinkedList`. A helper class `mozilla::SelectionListWrapper`
was implemented to allow `Selection`s to be in multiple of these lists
and without having to be derived from `LinkedListElement<T>`.
To simplify usage of the list, the use case "does this range belong to Selection x?"
is wrapped into the convenience method`IsInSelection(Selection&)`;
The method previously named like this was renamed to `IsInAnySelection()`
to be named more precisely.
Registering and unregistering of the closest common inclusive ancestor
of the `Range` is done when the first `Selection` is registered and
the last `Selection` is unregistered.
Differential Revision: https://phabricator.services.mozilla.com/D169597
`Selection` stores given ranges directly if and only if it's possible.
Therefore, adding a range which is already in the array of `Selection` ranges
needs to do nothing.
Differential Revision: https://phabricator.services.mozilla.com/D169301
In bug 1486370, bug 1487591 and bug 1487659, we made `Selection` handle some
selection listeners with pointers to concrete classes for the performance (for
saving virtual call cost, allocation cost of the selection listener array and
copy cost of the array before notifying). However, at that time, I forgot to
change the condition of early return. Therefore, current `Selection` does not
notify concrete class listeners of selection changes if there is no active
`nsISelectionListener` instances for the `Selection` instance.
Differential Revision: https://phabricator.services.mozilla.com/D169191
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203
Added WebIDL interfaces as per spec, added some necessary changes to support maplike and setlike structures to be accessed from C++.
Added `::highlight(foo)` pseudo element to CSS engine.
Implemented Highlight as new kind of `Selection` using `HighlightType::eHighlight`. This implies Selections being added/removed during runtime (one `Selection` object per highlight identifier), therefore a dynamic container for highlight `Selection` objects was added to `nsFrameSelection`. Also, the painting code queries the highlight style for highlight Selections.
Implementation is currently hidden behind a pref `dom.customHighlightAPI.enabled`.
Differential Revision: https://phabricator.services.mozilla.com/D164203