This API is temporarily available and useful for web app developers who want to
stop supporting Gecko specific join/split direction handling as soon as possible
and who do not want Mozilla block their release schedule by rescheduling of
shipping the new behavior. Additionally, adding this command allows web apps
detects whether Gecko supports the new behavior and whether it's enabled.
On the other hand, We don't want to ship opt-out API because it's hard to keep
maintaining the legacy behavior specific paths. Therefore, the command does
nothing if web app calls
`Document.execCommand("enableCompatibleJoinSplitDirection", false "false")` if
the new behavior is enabled by default.
Differential Revision: https://phabricator.services.mozilla.com/D172351
The source node is typically a text node, and it may be editable by
`contenteditable` or `designMode`. In that case, the source node may be removed
during the DnD session even without tricky JS code. In this case, Blink and
WebKit updates the source node to dispatch `dragend` to the editing host.
This behavior does not conform to the standardized DnD behavior, however,
this is reasonable for editor apps which want to listen to events in editing
host or window/document for footprint and/or performance reason. Therefore,
we should follow their behavior.
Differential Revision: https://phabricator.services.mozilla.com/D172091
If one of them are removed from the DOM tree, it's hard to keep handling it
since we have both split direction paths. Therefore, let's just return error
but not throw new exception in the case.
Differential Revision: https://phabricator.services.mozilla.com/D172205
The root cause of this bug is, we tried to compute new offset with offset at
the new node. However, as explained in the inline comments, it should compute
the offset with the right node offset in the new mode. Therefore, it needs
to handle it by itself instead of just calling `SelAdjInsertNode`.
Differential Revision: https://phabricator.services.mozilla.com/D171965
In the legacy mode, right node is not removed from the DOM tree, therefore,
this bug was hidden. However, after enabling the new mode, the point will
be out of the document. Therefore, the check will cause
`NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE` error and the joining code stops handling
the deletion.
Differential Revision: https://phabricator.services.mozilla.com/D171822
Computed color values will not be in the correct format, closer to the
one specified by the author. This also means that colors accross the
code are stored now as AbsoluteColor or StyleAbsoluteColor. This allows
color space/gamut information to be available for use.
Some animation related test failures had to be changed, because colors
now has greater precision. Animated a color now causes a lot more
animation updates, which was not initially expected. See the bug for
discussion.
Differential Revision: https://phabricator.services.mozilla.com/D171021
There are some paths which do not set `mAnchorFocusRange` correctly.
Therefore, even if its `RangeCount()` returns 1 or larger,
`GetAnchorFocusRange()` may return `nullptr`.
Differential Revision: https://phabricator.services.mozilla.com/D171045
However, we still need to climbing up the tree when
`nsIFrame::GetPrimaryFrame()` returns `nullptr`.
`<span inert style="display:none">` cases fail in Chrome. It must be caused by
their editor's `Selection` normalization result, but I think that it's wrong
behavior because `Selection` is a DOM API and the range is `inert`ed element.
Therefore, it's odd to change the behavior from the style.
Differential Revision: https://phabricator.services.mozilla.com/D170164
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
And also this changes `HTMLEditor::ReplaceTextWithTransaction` which is the only
user of `ReplaceTextTransaction`.
Depends on D169745
Differential Revision: https://phabricator.services.mozilla.com/D169746
And also this patch makes its only user,
`EditorBase::InsertTextIntoTextNodeWithTransaction`, and its only caller,
`EditorBase::InsertTextWithTransaction`, return `InsertTextResult` for
returning both end of inserted text and caret point suggestion. Note that
if it's for IME composition, `CompositionTransaction` needs to update
`Selection` directly. Therefore, caret point may be unset under composition
to updating `Selection` to wrong point (it seems that
`TextEditor::HandleInsertText` can be simplified later because of this change).
Depends on D169044
Differential Revision: https://phabricator.services.mozilla.com/D169744
This is not very optimimal, but tracking spellchecking state in DOM tree is tricky because of multiple contentEditables and possibility to set spellcheck true/false anywhere etc.
At least this helps with the testcase quite a bit.
Differential Revision: https://phabricator.services.mozilla.com/D169870
`AutoDeleteRangesHandler::Run` shrink the range not to delete list item if
the list is not empty. However, due to the bug of
`HTMLEditUtils::GetRangeSelectingAllContentInAllListItems`, it may get empty
range (in the testcase, first the only `<li>` element is the list has empty
text node as first child, and the range is collapsed into it). Therefore,
`AutoDeleteRangesHandler::Run` gives up to delete the list items, but does not
update the `Selection`. Therefore, from the caller point of view, `Selection`
is unexpectedly not collapsed even after deleting `Selection`.
Therefore, this patch also makes `AutoDeleteRangeHandler::Run` collapse
`Selection` if it gives up to delete something.
Differential Revision: https://phabricator.services.mozilla.com/D169044
Due to the loose error checks, this patch changes the behavior in edge cases.
E.g., if there is a case that `Selection` is extended by some unexpected JS
listeners/observers, the result may be different. However, it must be not a
problem because normal web apps should handle it later.
Differential Revision: https://phabricator.services.mozilla.com/D169040
First, `EditorBase::CreateTransactionForDeleteSelection` returns an instance of
`EditAggregateTransaction`. It's a base class of `PlaceholderTransaction` and
`DeleteRangeTransaction` but it's also a concrete class. However, it's too
generic. Therefore, this patch creates `DeleteMultipleRangesTransaction` which
is a simple sub-class of it, and makes `EditAggregateTransaction` be an abstract
class. Then, add `AddChild` methods to each concrete class to restrict the
type of child transactions.
Next, `DeleteRangeTransaction` contains only `DeleteNodeTransaction` and
`DeleteTextTransaction`. Therefore, once they have a common base class,
we can check the type easier. Therefore, this patch also adds
`DeleteContentTransactionBase` and
`EditorBase::CreateTransactionForCollapsedRange` becomes clearer what it
returns.
With these changes, `DeleteRangeTransaction` obviously contains only
`DeleteContentTransactionBase`, `DeleteMultipleRangesTransaction` contains only
`DeleteRangeTransaction`, `DeleteNodeTransaction` and `DeleteTextTransaction`.
And they are guaranteed at build time (at least from outside the classes).
***
fix
Differential Revision: https://phabricator.services.mozilla.com/D169038
According to the WPTs and their result in the other browsers, we should:
* do not work with a range anchored from a node in an element which has `inert`.
* collapse the range first when it ends at a node in an element which has `inert`.
See new WPT for the detail.
Note that `inert` with `contenteditable` must not be so major cases. Therefore,
this patch does not fix the edge cases like the `nsFrameSelection` use cases
and replacing `Selection` cases of the other edit commands/operations.
Depends on D169037
Differential Revision: https://phabricator.services.mozilla.com/D169743
It currently check range boundaries are start/end of a list element. However,
there are a lot of cases. E.g., selection can starts and/or ends inner
position due to invisible white-spaces and sub-lists.
The expectations of the new tests are based on Chrome's result. However,
unfortunately, the joining result of sub-lists is different from Chrome.
Therefore, they fail. (Gecko makes each list element has one list item.)
Differential Revision: https://phabricator.services.mozilla.com/D169037
`AutoListElementCreator::HandleChildParagraphElement` assumes that `<p>` never
has block children, but it's wrong because web apps can put any element under
any element with DOM API. Therefore, we should handle `<p>` in
`HandleChildDivElement` too.
Then, it causes new failures at:
* Handling first `<p>` met before creating first list element
* Handling empty `<p>` element
These failures have not been detected with `<div>` yet because there are only
tests for `<p>`. Therefore, these failures also existing bugs of the `<div>`
handler. For solving these issues, we need to create a list element with an
empty list item or only an empty list item element before unwrapping `<div>`
(and `<p>`). Then, unwrapped inline elements correctly moved to new list item
elements. Additionally, it needs not to reuse previous list item element which
accepted inline contents outside `<div>` (and `<p>`) for keeping the line break
caused by the `<div>`.
For adding duplication the lambda method code of new calls of
`HTMLEditor::CreateAndInsertElement`, this patch creates shared static methods.
Differential Revision: https://phabricator.services.mozilla.com/D168869
This patch moves each chunk of the `for` loop code to a new method and moves
all over the `for` loop code into `HandleChildContent` for making it possible
to call it recursively in `HandleChildDivElement` to avoid touching the array.
For sharing the state of `for` loop, this patch creates `AutoHandlingState`
in `AutListElementCreator` and make the new handlers take it and update them
if necessary. This approach makes it clearer that which method is a handler
in the `for` loop, and makes it safer to break the loop outside with updating
members.
Differential Revision: https://phabricator.services.mozilla.com/D168868