It returns the non-editable `<body>` causes the deletion handlers fail to
adjust range in the editing host and that caused hitting the assertion.
This patch also includes the wrong testcase with which the bug was reported.
Differential Revision: https://phabricator.services.mozilla.com/D164533
If the start boundary is immediately before the next node or if the end boundary
is immediately after the previous node, it should be shrunken for consistency
with setting style behavior and the other browsers.
Depends on D164526
Differential Revision: https://phabricator.services.mozilla.com/D164527
The remaining issue is, `RemoveInlinePropertiesAsSubAction` uses
`AutoInlineStyleSetter` for removing bold style coming from parent block or
its ancestors with new `<span style="font-weight: normal">`. However,
in the normal removing code users `Selection` range restorer. Therefore,
we cannot adjust the range simply without splitting the part of the normal
part and the special part for bold style.
This patch moves the part from an existing `for` loop which calls
`RemoveStyleInside` to a new `for` loop.
Depends on D164524
Differential Revision: https://phabricator.services.mozilla.com/D164525
They ignore non-editable nodes at scanning the DOM tree. According to the
other browsers' behavior, at least `PromoteInlineRange` should not do it.
(Removing `<a name>` is not a feature of `execCommand` and the `unlink` behavior
is anyway incompatible.)
Additionally, we don't need to stop scanning the DOM tree when we meet `<body>`.
Scanning its parents also fine because typically it's wont be extended since
there should be `<head>` element before `<body>`.
Therefore, we can make them simpler.
Depends on D164523
Differential Revision: https://phabricator.services.mozilla.com/D164524
Chrome and Safari selects content nodes which are applied the new style.
E.g., when `abc[def]ghi` gets embolden, it should become `abc<b>[def]</b>ghi`,
but Gecko does `abc[<b>def]</b>ghi` because `RangeUpdater::SelAdjSplitNode`
does not update the split point (i.e., end of the new text node, "abc" in the
example) [1].
Therefore, this patch makes `AutoInlineStyleSetter` record first and last points
trying to apply the style, then, `HTMLEditor::SetInlinePropertiesAsSubAction`
can set `Selection` to the applied range.
1. https://searchfox.org/mozilla-central/rev/dd216c1307a2bf1b0d2465b9749fa86dac44303a/editor/libeditor/SelectionState.cpp#329-334
Depends on D164522
Differential Revision: https://phabricator.services.mozilla.com/D164523
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
As of the prior patch, these are no longer needed. I removed
these with a script, then ran clang-format on the files, then
manually reverted a few unrelated changed from the formatter.
Differential Revision: https://phabricator.services.mozilla.com/D164829
Chrome preserves inline styles of first character in the deleting/replacing
if first visible thing is text. Safari preserves inline style of the first
content of the range (i.e., styles of `<img>` etc is also respected).
For now, due to the market share and Safari's behavior is not obviously better
than Chrome, let's try to emulate the Chrome's behavior. However, the rules are
complicated and probably depend on how it implements the deletion. Therefore,
this patch makes Gecko only scan following text node if selection range starts
from end of a text node.
Depends on D164520
Differential Revision: https://phabricator.services.mozilla.com/D164521
Currently, `HTMLEditor` preserves styled elements with the reversed order in
the loop.
https://searchfox.org/mozilla-central/rev/d7d5c89ee7bc70dec0fd846689ca030f94931393/editor/libeditor/HTMLEditSubActionHandler.cpp#8638-8658
I.e., if `<b><i></i></b>` is restored in the HTML styling mode, it will be
restored as `<i><b>...</b></i>`. This blocks writing tests for bug 1789574.
Therefore, this should be fixed first.
(As I commented in the method, ideally we should store all inline elements and
restore all of them, but currently we don't need to do it. It requires redesign
of the style cache, but it seems that we don't know web apps which is broken by
current behavior. Therefore, I think that we should do it when we meet a
trouble with the behavior.)
Depends on D164519
Differential Revision: https://phabricator.services.mozilla.com/D164520
This patch removes some traditional behavior check in the mochitest and
port it into expected results which match with the behavior of Chrome.
Almost all the new tests pass in Chrome, but some fails due to odd result in
Chrome. E.g., Chrome sometimes append `style` attribute with empty value.
Therefore, the expectations in this patch must be what Chrome developers
expected at implementing it.
Depends on D164004
Differential Revision: https://phabricator.services.mozilla.com/D164519
The other browsers use any inline elements to set CSS property for applying
an inline style. However, Gecko limits it to a `<span>` which does not have
any attributes. The other browsers' design is better for saving number of
elements and runtime cost of inserting new element (moving all children to the
new element and inserting it to the original position). Therefore, it's nicer
to follow the other browses. Then, we can avoid new WPT failures at aligning
other behaviors to the other browsers.
With doing that, removing style code requires complicated changes because
`RemoveStyleInside` assumes that one element has one style, but after taking
the compatible behavior, one element can have multiple styles including the
style represented by the element itself.
Note that the new expected failures are caused by bug 1183844. Gecko returns
closest ancestor element's background color for
`queryCommandValue("backColor")`. Therefore, it returns "transparent" of the
inner `<span>` element.
Differential Revision: https://phabricator.services.mozilla.com/D164004
Now, we can make there simpler because the part does one of them:
* Replaces element with new `<span>`
* Removes element
* Removes attribute
* Does nothing
However, there are duplicated code. We should consider what there does with
lambdas.
Depends on D164002
Differential Revision: https://phabricator.services.mozilla.com/D164003
This change makes the following changes smaller. Once we remove CSS style
first, then, it becomes easier to consider whether we should delete the element
since `style` attribute may be deleted by `ChangeStyleTransaction` if the
removing style is the last rule in it.
Depends on D164000
Differential Revision: https://phabricator.services.mozilla.com/D164001
In the test case, `deleteFromDocument` call makes the point unset. We should
make it check whether a legacy mutation event listener creates unexpected result
after calling `RemoveAlignFromDescendants`.
Differential Revision: https://phabricator.services.mozilla.com/D163767
Gecko wraps selection (and parent elements if entirely selected in them) in
new `<span>` element and set `text-decoration`. However, the other browsers
tries to reuse selected or parent element which already has `text-decoration`
style. The other browsers' behavior is more reasonable from point of view of:
* smaller footprint
* minimizing to update the DOM tree
And aligning the behavior makes it easier to check the compatibility between
browsers and us avoid from new test failures aligning other behaviors to the
other browsers.
If there is an element specifying `text-decoration`, its `text-decoration`
declaration should be updated first.
If found element is `<i>`, `<s>` or `<strike>`, it should be replaced with new
`<span>` because these elements just represents the visual style and we should
not use such elements in the CSS mode (bug 1802736). At this time, unless
the element has `text-decoration` rules in its `style` attribute value, we
the new `text-decoration` style should have the value represented by the
removing element (i.e., `underline` for `<i>`, `line-through` for the others).
However, if found element is `<ins>` or `<del>`, we should set its
`text-decoration` and unless it already has `text-decoration` rules, we need
to append corresponding style (`underline` for `<ins>` and `line-through` for
`<del>`) too.
When setting the values or removing a value from `text-decoration` declaration,
the value should be normalized to represent only `text-decoration-line` for
compatibility with the other browsers and keeping the implementation simpler.
And also the value should be built as the following order:
1. underline
2. overline
3. line-though
rather than updating current value with complicated code. Then, the tests can
compare with one expectation.
Depends on D163188
Differential Revision: https://phabricator.services.mozilla.com/D163429
The other browsers do not move styling nodes to existing element if the element
is never created in the mode. For example, `execCommand("bold")` in the CSS mode
for `[abc]<b>def</b>`, the other browsers make it
`<span style="font-weight: bold">abc</span><b>def</b>`, but Gecko does
`<b>abcdef</b>`. Similarly, `execCommand("bold")` in the HTML mode for
`[abc]<span style="font-weight: bold">def</span>`, the other browsers make it
`<b>abc</b><span style="font-weight: bold">def</span>`, but Gecko does it
`<span style="font-weight: bold">abcdef</span>`.
This patch makes Gecko align the behavior to the other browsers.
Differential Revision: https://phabricator.services.mozilla.com/D163188
`execCommand("superscript")` and `execCommand("subscript")` are handled
specially.
`<sup>` and `<sub>` are exclusive. Therefore, existing element is removed first.
However, they are not mapped to CSS due to bug 394304 comment 2 even though the
behavior is different from the other browsers. Therefore, Gecko does not remove
`vertical-align` styles from selected ranges. On the other hand, the other
browsers do it. This makes sense and matches with the handling in HTML mode.
Therefore, we should remove `vertical-align` style around the selection ranges.
Note that this updates existing WPTs.
The first block of each command checks how the command work with similar
`<span>` having `vertical-align` style. The new expectation matches with the
other browsers (i.e., currently they fail in the other browsers).
The second block of each command checks how the command work with similar
situation but there is a sibling which has the applying style (i.e., `<sup>`
or `<sub>`). These tests keep failing in the other browsers since they want
to update `vertical-align` style at the selected range in the `<span>` having
`vertical-align` style.
Anyway, this fix is for avoiding new WPT failures of fixing bug 1792386, and
these commands must not be used so widely especially in the CSS mode.
Therefore, I believe that this change is not so risky.
Depends on D163183
Differential Revision: https://phabricator.services.mozilla.com/D163184
* `SetInlinePropertyOnTextNode`
* `SetInlinePropertyOnNode`
* `SetInlinePropertyOnNodeImpl`
* `ElementIsGoodContainerForTheStyle`
These `HTMLEditor` methods run only when `SetInlinePropertyOnTextNode` or
`SetInlinePropertyOnNode` is called, they take common style information as 3
arguments and they run in a short period. Therefore, they can be in a stack
only class.
Differential Revision: https://phabricator.services.mozilla.com/D163183
When keyboard events are fired by auto repeat feature of OS, each event is fired
in each event loop. However, `repeat` feature of the `synthesizeKey` and
typing multiple characters with `sendString` dispatch keyboard events in an
event loop. Therefore, asynchronous scrolling is handled differently from
users' scenario. So we should emulate the users' scenario better with
synthesizing each event with waiting a tick.
Depends on D162527
Differential Revision: https://phabricator.services.mozilla.com/D162528
It uses legacy `hitEventLoop` hack with `setTimeout`. Now, we have better
utility methods and can avoid using callbacks with using async/await.
However, waiting only for `waitToClearOutAnyPotentialScrolls` does not fix
the intermittent failure. Therefore, this patch checks whether the scroll
result in its wrapper to make sure that there is no pending scroll.
Differential Revision: https://phabricator.services.mozilla.com/D162527
And also making it and `BuildCSSDeclarations` return pairs of CSS property and
value with an array makes their callers simpler.
Depends on D162517
Differential Revision: https://phabricator.services.mozilla.com/D162518
This patch creates a base class of `EditorInlineStyle`, the name is
`EditorElementStyle`. It requires only attribute of HTML. However, it's
obviously different from `EditorInlineStyle`'s rule which is `mHTMLProperty`
cannot be `nullptr`. Therefore, the methods which can treat only
`EditorInlineStyle` do not want the data only whose attribute is not `nullptr`.
For solving this issue at build time, this approach is better than renaming
`EditorInlineStyle` and make it have the new mode.
Depends on D162513
Differential Revision: https://phabricator.services.mozilla.com/D162514