In order to support `StaticRange`s, which are not `MutationObserver`s, RangeBoundaries need to have an alternative way of ensuring that `mRef` points to the correct node.
This is now done by validating `mRef` every time `Ref()` is called using the parent and offset.
For performance reasons, this is disabled by default and should only be used for `StaticRange`s.
Differential Revision: https://phabricator.services.mozilla.com/D177892
I was going to write an automated test but turns out that some of this
became much harder to test after bug 582459 :-(
Let me know if you want me to take a look at writing a browser test
(since I think otherwise we can't test this, we need to move focus
outside of the active tab).
Differential Revision: https://phabricator.services.mozilla.com/D178825
The EditorEventListener for HTMLEditor is registered on document,
which is problematic because it can't receive events when the focus is
switched between elements in the same shadow tree due to shadow dom
encapsulation.
We fix this by moving the EditorEventListener to nsWindowRoot so the
events can always be received.
Differential Revision: https://phabricator.services.mozilla.com/D178215
The EditorEventListener for HTMLEditor is registered on document,
which is problematic because it can't receive events when the focus is
switched between elements in the same shadow tree due to shadow dom
encapsulation.
We fix this by moving the EditorEventListener to nsWindowRoot so the
events can always be received.
Differential Revision: https://phabricator.services.mozilla.com/D178215
When `WSRunScanner::ScanNextVisibleNodeOrBlockBoundary` reaches a block
boundary, it may return `WSScanResult` without valid position value from
this path:
https://searchfox.org/mozilla-central/rev/11a4d97a7b5cdfa133f4bda4525649f651703018/editor/libeditor/WSRunObject.cpp#1777-1782
That happens if the reason is `WSType::CurrentBlockBoundary` or
`WSType::OtherBlockBoundary` even in usual cases.
If it's `WSType::CurrentBlockBoundary`, `TextFragmentDataAtStartRef().EndRef()`
may point in a text node in the block, but its `GetEndReasonContent()` returns
the block. I'm not sure whether this is intentional result. (I guess t's a
bug.)
If it's `WSType::OtherBlockBoundary`, `TextFragmentDataAtStartRef().EndRef()`
may point in the list item, but `GetEndReasonContent()` returns a child block.
Those scan result change needs to understand `TextFragmentData` behavior again,
but it's difficult as you know. Therefore, this fixes the caller side not to
use `WSScanResult::Point()` if it meets a block boundary since start of the
block boundary is a good place to put caret.
Differential Revision: https://phabricator.services.mozilla.com/D178281
With the preceding patch, comment nodes are also moved at deleting a block/line
boundary. However, this causes some WPT failures. Therefore, this adds an
option to the related methods.
Note that Chrome removes all comment nodes in moving nodes. However, I don't
have the motivation to do that because it requires additional cost and I have
no idea to improve the compatibility in usual web apps. So I believe that
doing it wastes the runtime performance unless we'd get a bug reports by the
difference.
Therefore, this patch does not update WPTs too.
Differential Revision: https://phabricator.services.mozilla.com/D176767
`HTMLEditUtils::CanNodeContain` does not handle comment nodes and cdata section
nodes (the latter one is available only in XHTML documents, it's treated as a
comment node in HTML documents).
When copying HTML from Word on Windows, that contains 2 comment nodes at
start of pasting body (which does not appear in clipboard viewer, so, Gecko
creates them somewhere) and that causes `HTMLEditUtils::CanNodeContain` returns
`false` for any parents. Therefore,
`HTMLEditor::InsertNodeIntoProperAncestorWithTransaction` returns error
and the pasting fails with odd state and unexpectedly split the list item in
`HTMLWithContextInserter::InsertContents`. Finally, undoing fails to do some
of them and causes destroying the editable nodes.
This patch makes `HTMLEditUtils::CanNodeContain` work with comment nodes
and cdata section nodes (the latter is treated as a comment node since there
is no "cdata" tag definition of `nsHTMLTag`) and
`HTMLEditor::InsertNodeIntoProperAncestorWithTransaction` just return
"not handled" result for some other types of nodes which cannot be inserted
in any elements.
Note that the result of pasting from Word is different from Chrome's result.
Chrome does not paste such comment nodes (but inserts comment nodes with
`insertHTML` command). For now, I don't want to work on fixing this
compatibility issue since comment nodes does not cause any known troubles.
Therefore, this patch does not contain WPT updates.
Differential Revision: https://phabricator.services.mozilla.com/D176766
Some handlers, e.g., `HTMLWithContextInserter` may want to skip post processing
after inserting new node instead of immediately stop handling the action.
Currently, `HTMLWithContextInserter` correctly ignores the cases only when
`NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE` is required. Therefore, making
`InsertNodeWithTransaction` return the error makes `HTMLWithContextInserter`
work correctly in tricky cases.
Differential Revision: https://phabricator.services.mozilla.com/D177446
If a `paste` event listener moves focus, Chrome makes new editor keep handling
the pasting. For the compatibility, we should follow it unless the new focused
element is in different document because user should allow to paste it
explicitly.
On the other hand, this just stops handling "cut" in same situation because
handling it requires to update clipboard without user's activation. Therefore,
the clipboard content and/or the new editor content may be lost from the users
point of view.
Note that `nsContentUtils::GetActiveEditor` may return `HTMLEditor` instance
when focused element does not have `TextEditor` even when non-editable element
has focus. Therefore, if it returns an `HTMLEditor`, we need to check whether
it's active in the DOM window with a call of `HTMEditor::IsActiveInDOMWindow`.
Differential Revision: https://phabricator.services.mozilla.com/D176741
This patch makes `EditorBase` implement them as non-virtual methods and
implement their first part. Then, they call new virtual methods to handle
paste and paste-as-quotation.
With this change, `TextEditor` starts to dispatch `paste` event when
paste-as-quotation. The new test checks it.
Differential Revision: https://phabricator.services.mozilla.com/D176739
It does not handle critical cases properly, and it uses an out-param.
We can rewrite it with `Result`. However, unfortunately,
`nsCopySupport::FireClipboardEvent` does not return error. Therefore,
the root callers still need to treat the error cases as "canceled".
Differential Revision: https://phabricator.services.mozilla.com/D176737
If a `paste` event listener moves focus, Chrome makes new editor keep handling
the pasting. For the compatibility, we should follow it unless the new focused
element is in different document because user should allow to paste it
explicitly.
On the other hand, this just stops handling "cut" in same situation because
handling it requires to update clipboard without user's activation. Therefore,
the clipboard content and/or the new editor content may be lost from the users
point of view.
Note that `nsContentUtils::GetActiveEditor` may return `HTMLEditor` instance
when focused element does not have `TextEditor` even when non-editable element
has focus. Therefore, if it returns an `HTMLEditor`, we need to check whether
it's active in the DOM window with a call of `HTMEditor::IsActiveInDOMWindow`.
Differential Revision: https://phabricator.services.mozilla.com/D176741
This patch makes `EditorBase` implement them as non-virtual methods and
implement their first part. Then, they call new virtual methods to handle
paste and paste-as-quotation.
With this change, `TextEditor` starts to dispatch `paste` event when
paste-as-quotation. The new test checks it.
Differential Revision: https://phabricator.services.mozilla.com/D176739
It does not handle critical cases properly, and it uses an out-param.
We can rewrite it with `Result`. However, unfortunately,
`nsCopySupport::FireClipboardEvent` does not return error. Therefore,
the root callers still need to treat the error cases as "canceled".
Differential Revision: https://phabricator.services.mozilla.com/D176737
`IMEStateManager` basically runs at focus change. However, when `designMode`
is set to `"off"` or focused editing host becomes non-editable (removing
`contenteditable` attribute or `contenteditable` attribute is set to `false`),
IME may be disabled without a focus change. Therefore, `Document` needs to
notify `IMEStateManager` of the timing.
Additionally, `nsFocusManager` does not change focus when focused element
becomes not focusable (bug 1807597). Therefore, `Document` needs to kick
`focus` or `blur` event handler of `HTMLEditor` when active editing host
becomes not editable.
However, if an ancestor of focused element becomes editable, I think that
`HTMLEditor` does not work well without focus move because it computes
editing host with current editing state in a lot of places, but `Selection`
and `nsFocusManager::GetFocusedElement` keeps working with previous focused
element which is now a editable child of editing host. Therefore, this patch
marks them as `todo` in the new tests.
Differential Revision: https://phabricator.services.mozilla.com/D171196
Make all UA widgets also NAC.
Keep the UA widget flag but break at anonymous subtree boundaries, so
that only nodes inside the UA widget directly (and not NAC from those)
get the flag.
This is important because two callers depend on this difference:
* The style system, since we still want to match content rules from
stylesheets in the UA widget. We also match user rules, which is a
bit sketchy, but that was the previous behavior, will file a
follow-up for that.
* The reflector code, since we want the scope for UA widgets to not
include the NAC nodes inside that UA widget. nsINode::IsInUAWidget
got it wrong.
After this patch, ChromeOnlyAccess is equivalent to
IsInNativeAnonymousSubtree, so we should probably unify the naming.
That's left for a follow-up patch because I don't have a strong
preference.
Differential Revision: https://phabricator.services.mozilla.com/D174310
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