Note that although this builds, it would (by itself) result in some test breakage;
this is resolved in the following patches that build on this.
Differential Revision: https://phabricator.services.mozilla.com/D198790
Note that although this builds, it would (by itself) result in some test breakage;
this is resolved in the following patches that build on this.
Differential Revision: https://phabricator.services.mozilla.com/D198790
Note that although this builds, it would (by itself) result in some test breakage;
this is resolved in the following patches that build on this.
Differential Revision: https://phabricator.services.mozilla.com/D198790
This is a simple mistake of the previous patch. The code path is originally for
a left click handling. Therefore, there is no check whether the click point is
in a selection range because in that case, left click should collapse selection.
However, the selection should not be collapse when it's a right click in a
selection range because the context menu target is the selection range.
The `ui.mouse.right_click.collapse_selection.stop_if_non_collapsed_selection`
pref is set to `true` by default. Therefore, the existence of a non-collapsed
selection has hidden this bug. However, if it's set to `false`, this always
happens. Additionally, editor does not set ancestor limiter of selection if the
root element is editable [1]. I think that we can now remove this special path,
but it's risky. Therefore, this patch just adds the new check into the method.
1. https://searchfox.org/mozilla-central/rev/ce4599d3d4e20e34cb6db68f255c3dff1aec246b/editor/libeditor/EditorBase.cpp#5448,5450-5451
Differential Revision: https://phabricator.services.mozilla.com/D193529
Most usage is a straight replacement but gtk needs extra changes as it transfers plain text in UTF8 natively and needs to be converted into UTF16, and Windows uses single-byte characters for RTF and CF_HTML formats so we preserve this.
Differential Revision: https://phabricator.services.mozilla.com/D158587
Blink's behavior is better than Gecko. That is, when selected range crosses
an inline element boundary, Blink shrinks selected range to select only
children, but Gecko extends selected range to cover all inline parents around
the range. E.g., when setting `abc[<i>def]</i>ghi` to `<b>`, Chrome changes it
to `abc<i><b>def</b></i>ghi`, but Gecko changes it to `abc<b><i>def</i></b>ghi`.
The Gecko's behavior is odd especially when `abc<i>[def]</i>ghi` since user
does not select the `<i>`, but Gecko wraps it in new `<b>`.
However, if the range contains an inline element entirely, e.g.,
`abc[<i>def</i>]ghi`, Chrome changes it to `abc<b><i>def</i></b>ghi` without
shrinking the range. This is reasonable too.
On the other hand, there is a case that browsers need to extend the range.
That is an parent inline element has the style of what we're setting a range to.
E.g., `abc<span style="background-color: red"><b>[def]</b></span>ghi`, user
wants to update the style attribute of the `<span>` element rather than wrapping
the selected text node with new `<span>` element in the `<b>`. Therefore,
if shrunken range starts from very beginning of a node or ends at very end of
a node and the inline parents have same style, we need extend the range to wrap
it. (Note that Gecko deletes same styles in range with
`HTMLEditor::RemoveStyleInside`. Therefore, wrapping most distant inline
element makes Gecko works as expected.)
Finally, if the containers of range boundaries are not same one, we should
extend the range to save the number of creating element. E.g.,
`<span>[abc</span> <span>def]</span>` should become
`<b><span>abc</span> <span>def</span>` rather than
`<span><b>abc</b></span><b> </b><span><b>def</b></span>`.
Note that the new expected failures are caused by the difference of selection
range after applying the style. That should be fixed by the following patch.
Depends on D164521
Differential Revision: https://phabricator.services.mozilla.com/D164522
It's the only method which is used outside of the editor module. Therefore,
we can stop exposing `EditorUtils.h` later.
Depends on D158634
Differential Revision: https://phabricator.services.mozilla.com/D158635
Any callers do not refer "ignored", "handled" and "cancel" state without
checking whether the method returns error or not. Therefore, error state
can be (and should be) managed by `mozilla::Result`'s error state.
Perhaps, it should store a caret position later because deletion handlers
of `HTMLEditor` use it, but update `Selection` immediately.
Differential Revision: https://phabricator.services.mozilla.com/D158080
Unfortunately, it's hard to split this (and similar) patch because we need to
touch `MoveNodeResult` itself for making it available as the ok type of
`Result`. However, I guess that it's not so hard to investigate regression
point if something would be found later because `MoveNodeResult` is mainly
used by deletion which is the most complicated part of `HTMLEditor`, but
`MoveNodeResult` is used only in a few cases.
Differential Revision: https://phabricator.services.mozilla.com/D157574
Gecko just joins 2 blocks when editable block parents are same element, e.g.,
both are `<div>`. However, Chrome and Safari moves only first line of the
right block into the left block, and Gecko does it when both blocks are
different elements.
Ideally, we should take same behavior as Chrome and Safari because it's
reasonable for both compatibility with the other browsers and consistency
when both blocks are different but has same style, then we don't need to
maintain different behavior paths.
However, doing it for all elements are too risky because right block will be
merged into left block if right block has no line break. On the other hand,
without doing it, preserving `white-space` is really hard because we need to
maintain the both paths.
Therefore, I'd like to change the behavior only when both blocks have different
`white-space` styles. Usually, web apps do not change `white-space` for each
block, so I think that this is safer than doing this in all elements,
additionally, we can revert the behavior easy since this patch is really small.
Differential Revision: https://phabricator.services.mozilla.com/D157412
With taking an `AutoRangeArray` which is initialized with `Selection`, it can
restore selection and check if it's collapsed and if collapsed in the expected
list element. Then, its caller can apply the returned range to `Selection`
because it's an edit sub-action handler.
Differential Revision: https://phabricator.services.mozilla.com/D152969
It oddly retrieve an ancestor list element which contains one range in the
selection ranges. So, working it with `AutoRangeArray` which is initialized
with `Selection` makes `HTMLEditor` smaller...
Differential Revision: https://phabricator.services.mozilla.com/D152966
This patch makes it take `AutoRangeArray` and it can save a snapshot of the
ranges and restore it like `AutoSelectionRestorer`.
For accessing `HTMLEditor::RangeUpdaterRef` for clearing the saved ranges,
`AutoRangeArray` needs to store `HTMLEditor`. Therefore, its constructors
and the destructor cannot be inlined in the header due to the include-hell.
Differential Revision: https://phabricator.services.mozilla.com/D149089
Although they update the DOM tree with transactions, but for making `HTMLEditor`
smaller, and the following patches makes the related code simpler, we need to
move them into `AutoRangeArray`.
Differential Revision: https://phabricator.services.mozilla.com/D149084
It's always work with `Selection` ranges. Then, it should be treated within
`AutoRangeArray` which can be initialized with `Selection` ranges automatically.
Then, we can making `HTMLEditor` simpler.
Note tha this tries to make it get editing host when the corresponding
public method is called (after dispatched `beforeinput` event if handling a
users' operation). However, as commented in
`HTMLEditor::SetParagraphFormatAsAction`, it breaks a tricky crash test.
Therefore, only the format block path computes it after the preparation.
Differential Revision: https://phabricator.services.mozilla.com/D149079
For making extending the range to wrap the lines containing start and end
boundaries of each range of `AutoRangeArray::mRanges`, we need a method which
updates existing `nsRange` instances rather than creating new one.
Differential Revision: https://phabricator.services.mozilla.com/D149078
Similar to the previous patch, you must feel odd to move the methods. They
will be static methods in the `EditorUtils.cpp` file later.
Differential Revision: https://phabricator.services.mozilla.com/D149075
This must make you feel odd. However, this is a separate patch for making easier
to review the following patches. This will be a private member of
`AutoRangeArray`.
Differential Revision: https://phabricator.services.mozilla.com/D149074
In the testcase, editing host is removed when first node removing, but
`HTMLEditor::Destroyed()` still returns `false`. So, ideally, we should add
a check of editing host validity in `Destroyed()`, but for now, we should make
the method check whether the handling range is still editable after running
each transaction.
Depends on D147723
Differential Revision: https://phabricator.services.mozilla.com/D147724
It's currently computes the corresponding editing host from the focus node of
`Selection` with climbing up the DOM tree. So, it does not just return a stored
element. Therefore, some callers use it multiple times. For avoiding it, we
should rename it to explain that it computes the editing host.
Note that I think that we should make it takes a node to compute editing host
without `Selection` for solving the case of no selection ranges. Therefore,
I don't like to include more information into the name.
Differential Revision: https://phabricator.services.mozilla.com/D147504
None of the consumer need to mutate styles, and this saves some ugly
const_casting on the next patch.
Doesn't change behavior.
Differential Revision: https://phabricator.services.mozilla.com/D147555
The strategy of this patch and most following patches is, returning candidate
caret position with `CreateNodeResultBase`, and make each caller choose whether
it updates `Selection` immediately, put it off until exiting from a loop, or
just ignore.
This patch makes `HTMLEditor::HandleInsertBRElement` return
`CreateElementResult` and makes its callers handle selection as same as the
method does.
And note that I've not realized that `NS_FAILED` and `NS_SUCCEEDED` include
`MOZ_(UN)LIKELY`. Therefore, they don't need to be wrapped with them. And
also `NS_WARN_IF` has it too (but it's not in opt build, see bug 1765909).
On the other hand, neither `Result::isErr` nor `Result::isOk` has them
(bug 1765916). Therefore, except in the case of `Result`, this and following
patches will remove unnecessary `MOZ_(UN)LIKELY` from editor.
Differential Revision: https://phabricator.services.mozilla.com/D144644
To avoid the unnecessary conversion between `EditorDOMPoint` and
`EditorRawDOMPoint`, it should be a template method which can take/return either
`EditorDOMPoint` or `EditorRawDOMPoint`.
Differential Revision: https://phabricator.services.mozilla.com/D143880
The implicit copy constructors and `operator=` makes it harder to realize
that implicit conversion wastes the runtime cost. Therefore, this patch
replaces them with a template method to convert the `EditorDOMPointBase` type.
Differential Revision: https://phabricator.services.mozilla.com/D143878
It's an internal API corresponding to `Selection.getRangeAt` DOM API.
I think that it should use `uint32_t` rather than `size_t` because of the
consistency with the DOM API and `Selection::RangeCount()`.
This patch fixes all callers of `GetRangeAt()`, and rewrites it with ranged-
loops unless original ones do not refer `RangeCount()` every time and may run
script in the loop.
Differential Revision: https://phabricator.services.mozilla.com/D128848
Our internal code can touch internal `Selection` object of `<input>` and
`<textarea>`, thus, selection ranges in them may be not in the text node.
Therefore, we should make `TextEditor` instance try to shrink the deleting
ranges into the text node first.
In a followup bug (perhaps, bug 1734846), we should split the deletion code into
`TextEditor` and `HTMLEditor` for making the code simpler and never regressed.
Differential Revision: https://phabricator.services.mozilla.com/D133181
I'd like to split utilities for all editors and only for `HTMLEditor`.
This moves some trivial classes into new `HTMLEditHelpers.h`. Perhaps, it's
better if we can move them into `HTMLEditUtils.h`, but it has too many inline
method definitions so that adding new classes into it makes it much bigger.
Depends on D130349
Differential Revision: https://phabricator.services.mozilla.com/D130425
If `white-space` is `pre-line`, only linefeed characters are preformatted, but
white-spaces are collapsible. And if collapsible white-spaces follow or
are followed by a preformatted linefeed, they are removed. Therefore,
these methods need to scan following or preceding white-spaces of first
linefeed if the caller wants to delete. Unless doing it, the removed
white-spaces would become visible due to no linefeed character containing
sequence.
Differential Revision: https://phabricator.services.mozilla.com/D124557
This patch adds `EditorUtils::IsNewLinePreformatted()` to check whether a
linefeed character is collapsible or not.
Then, a lot of users of `EditorDOMPointBase::Is*CharASCIISpace()` and
`EditorDOMPointBase::Is*CharASCIISpaceOrNBSP()` should check whether the
white-space at the point is collapsible or not. Therefore, this patch adds
`Is*CharCollapsibleASCIISpace()` and `Is*CharCollapsibleASCIISpaceOrNBSP()`
too.
Then, makes such callers use the new API instead.
Differential Revision: https://phabricator.services.mozilla.com/D123871
The method returns false even if linefeed characters are preformatted.
So, it should be renamed to explain what it does clearer.
And this renames `TextFragmentData::mIsPreformatted` and its accessors too.
Differential Revision: https://phabricator.services.mozilla.com/D123870
This will make implementing the new behavior behind a pref
really straight-forward, and is generally nicer.
Depends on D121858
Differential Revision: https://phabricator.services.mozilla.com/D121705
It should be treated as `uint32_t` since DOM API does so. However, there are
some exceptions:
* Result of `nsINode::ComputeIndexOf()`
* Result of `nsAString` methods
They return `-1` as not found, and anyway, they cannot treat large integer
than `INT32_MAX`. Therefore, this patch does not touch around them.
Differential Revision: https://phabricator.services.mozilla.com/D118933
It just creates an `nsITransferable` instance and add 2 flavors for storing
plain text. Therefore, it can be in `EditorUtils` instead.
Depends on D116566
Differential Revision: https://phabricator.services.mozilla.com/D116567
Like the other browsers, we shouldn't allow to user modify content in
`<select>` element. Note that this case won't occur with moving caret
with input devices. This occurs only with Selection API.
FYI: Chrome deletes `<select>` element if children of it are selected,
but it's odd behavior since user don't see where is selected visually
and may cause unexpected data loss (i.e., deleting `<select>` element).
Perhaps, we should investigate the behavior in other replaced elements
like `<textarea>` etc in follow up bugs.
Depends on D112513
Differential Revision: https://phabricator.services.mozilla.com/D112517
The lifetime of it is guaranteed by `AutoEditActionDataSetter` which grabs
`Selection` until it's destroyed, and it's a stack only class and created
at first step of all public method calls. Therefore, we can mark it as
`MOZ_KNOWN_LIVE` and we can change it returning reference of `Selection`
instead of reference of `RefPtr<Selection>`.
Differential Revision: https://phabricator.services.mozilla.com/D110896
For making delete handlers simpler, and set better target ranges to the
corresponding `beforeinput` event, we should ignore non-editable ranges
before handling deletion.
This patch makes editor stop handling deleteion when a range crosses editing
host boundaries. In this case, Gecko has done nothing, but fired
`beforeinput` event. Note that Blink deletes editable contents in the range
**until** it meets first non-editable content, but I don't think this is
a good behavior because it makes things complicated. Therefore, I filed
a spec issue: https://github.com/w3c/editing/issues/283
On the other hand, this behavior change causes different behavior in
https://searchfox.org/mozilla-central/source/editor/libeditor/crashtests/1345015.html
It tries to insert paragraph into `<html>` element, but our editor currently
does not support it. Therefore, it hits `MOZ_ASSERT`. Therefore, this patch
added a new check into `HTMLEditor::InsertParagraphSeparatorAsSubAction()`.
Differential Revision: https://phabricator.services.mozilla.com/D107588
Among other things, there were some misuses of std::forward, and
GenericErrorResult was (presumably accidentally) instatiated with
references as the template argument type, e.g. const nsresult&,
which circumvented the check for not calling it with NS_OK in
ResultExtensions.h
Differential Revision: https://phabricator.services.mozilla.com/D90561