In the most cases, the scanner users should ignore empty inline
containers so that the behavior should be the default behavior.
Then, the options becomes clearer what the callers can expect.
Differential Revision: https://phabricator.services.mozilla.com/D284963
Perhaps, we should stop using "visible" from the API names because
some API users use the methods while modifying the DOM. Therefore, the
new APIs explain the position of a line break or whether it's
significant or unnecessary from the layout point of view.
This patch adds API to check a line break position which may return
following/preceding block boundary's element and to scan following
block boundary with ignoring unnecessary line break which is done in
some places with calling
`WSRunScanner::ScanInclusiveNextVisibleNodeOrBlockBoundary()` twice.
Additionally, making the extant internal API mainly `HTMLEditUtils`
use the new API to do the correct handling.
Note that this makes `HTMLEditUtils::GetLeafNodeType` return `Ignore`
if the caller does not want invisible things and the node is in
`display:none` element. This change is required to keep passing some
tests whose editing host is `display:inline` and it's followed by
invisible text like `<script>`.
Differential Revision: https://phabricator.services.mozilla.com/D284962
`WalkTreeOptions` is similar to `LeafNodeOptions` and it's hard to
maintain both of them. Additionally, `LeafNodeOptions` can specify
which type of leaf nodes should be ignored at scanning. Therefore,
`LeafNodeOptions` can be used for them.
Differential Revision: https://phabricator.services.mozilla.com/D277523
This adds some options which ignore some types of inline elements.
For example, `IgnoreAnyEmptyInlineContainers` is useful to scan previous
or next editable point because Chrome ignores empty inline elements when
deleting from next to an inline element.
`IgnoreInvisibleInlineVoidElements` is useful to scan invisible line
break from end of a block or checking a line break is invisible because
visible inline element makes a line after the last line break. E.g.,
```html
<div>ABC<br><span></span></div>
```
This shows only one line. However,
```html
<div>ABC<br><span style="border:1px solid"></span></div>
```
This shows 2 lines in the `<div>`.
Additionally, renaming the existing `LeafNodeType` values for making
them easier to understand.
Differential Revision: https://phabricator.services.mozilla.com/D277520
An empty inline container element such as `<span></span>` has 2
meanings, if it's visible with specified style, e.g., has non-zero
padding, it should be treated like a replaced element like `<img>`.
However, if it's invisible, it should be treated as `Comment` or
empty `Text`. Therefore, the scanner users need a special handling for
them in some cases. So, it should be identified with the new `WSType`.
Unfortunately, neither
`HTMLEditUtils::IsInclusiveAncestorCSSDisplayNone` nor
`HTMLEditUtils::IsVisibleElementEvenIfLeafNode` is testable within
GTest because it does not have layout information.
Differential Revision: https://phabricator.services.mozilla.com/D277519
This reverts commit 5ccf392dce.
Revert "Bug 1998077 - part 6: Reimplement `HTMLEditUtils::Get(First|Last)Child()` and `HTMLEditUtils::Get(Next|Previous)Sibling()` with `LeafNodeOptions` r=m_kato"
This reverts commit 12eb928cb5.
Revert "Bug 1998077 - part 5: Replace the remaining `HTMLEditUtils::Get(Next|Previous)Content()` with new ones based on `Get(Next|Previous)LeafNodeOr(Next|Previous)BlockElement()` r=m_kato"
This reverts commit 58b4243d10.
Revert "Bug 1998077 - part 4: Replace some callers of `HTMLEditUtils::Get(Next|Previous)Content()` with `HTMLEditUtils::Get(Next|Previous)LeafContentOr(Next|Previous)BlockElement()` r=m_kato"
This reverts commit dd46967eb4.
Revert "Bug 1998077 - part 3: Add new options to ignore empty/invisible leaf nodes r=m_kato"
This reverts commit ca50a4a628.
Revert "Bug 1998077 - part 2: Add `WSType::EmptyInlineContainerElement` r=m_kato"
This reverts commit 4a5d93d631.
Revert "Bug 1998077 - part 1: Make `HTMLEditUtils::IsVisibleElementEvenIfLeafNode` work better if primary frame is available r=m_kato"
This reverts commit b42dc9d35f.
`WalkTreeOptions` is similar to `LeafNodeOptions` and it's hard to
maintain both of them. Additionally, `LeafNodeOptions` can specify
which type of leaf nodes should be ignored at scanning. Therefore,
`LeafNodeOptions` can be used for them.
Differential Revision: https://phabricator.services.mozilla.com/D277523
This adds some options which ignore some types of inline elements.
For example, `IgnoreAnyEmptyInlineContainers` is useful to scan previous
or next editable point because Chrome ignores empty inline elements when
deleting from next to an inline element.
`IgnoreInvisibleInlineVoidElements` is useful to scan invisible line
break from end of a block or checking a line break is invisible because
visible inline element makes a line after the last line break. E.g.,
```html
<div>ABC<br><span></span></div>
```
This shows only one line. However,
```html
<div>ABC<br><span style="border:1px solid"></span></div>
```
This shows 2 lines in the `<div>`.
Additionally, renaming the existing `LeafNodeType` values for making
them easier to understand.
Differential Revision: https://phabricator.services.mozilla.com/D277520
An empty inline container element such as `<span></span>` has 2
meanings, if it's visible with specified style, e.g., has non-zero
padding, it should be treated like a replaced element like `<img>`.
However, if it's invisible, it should be treated as `Comment` or
empty `Text`. Therefore, the scanner users need a special handling for
them in some cases. So, it should be identified with the new `WSType`.
Unfortunately, neither
`HTMLEditUtils::IsInclusiveAncestorCSSDisplayNone` nor
`HTMLEditUtils::IsVisibleElementEvenIfLeafNode` is testable within
GTest because it does not have layout information.
Differential Revision: https://phabricator.services.mozilla.com/D277519
They should stop at a `Comment` node or treat `Command` as "visible"
node only when:
- The caller wants to handle only with current or adjacent `Text` node
- The caller wants to list all invisible nodes until the first visible thing
In other words, most users must want to ignore `Comment` nodes.
Therefore, their default behavior should be so but they should treat
`Comment` nodes in an optional mode.
Differential Revision: https://phabricator.services.mozilla.com/D270461
In theory, the low level APIs of `HTMLEditUtils` should not choose
`BlockInlineCheck` value. However, the callers may want if the
direction is changed in the API, e.g., when scanning siblings but then
climbing up. For preserving the low level API behavior, this patch
adds new `BlockInlineCheck` value, `Auto`. Then, the `HTMLEditUtils`
APIs choose proper value for the direction automatically only when
`Auto` is specified.
Differential Revision: https://phabricator.services.mozilla.com/D270118
It's not required explicitly to specify
`BlockInlineCheck::UseComputedDisplayStyle` and
`BlockInlineCheck::UseComputedDisplayOutsideStyle` to `WSRunScanner`
too. And it should take an `EnumSet` for making it easier to maintain
the class in the future.
Differential Revision: https://phabricator.services.mozilla.com/D270117
In theory, scanning from outside to inside, i.e., checking a sibling
or a child, `display-outside` should be used to check whether the
element is a block or an inline. Similarly, scanning from inside to
outside, i.e., checking a parent, `display-inside` should be used to
check whether the element is a block or an inline.
`HTMLEditUtils`'s related methods are low API, but `WSRunScanner` is
higher API. Therefore, I think `WSRunScanner` should work with the
theory.
This patch makes the internal scanner of `WSRunScanner`,
`TextFragmentData`, take only whether refer HTML default style or CSS
style and consider itself whether use
`BlockInlineCheck::UseComputedDisplayOutsideStyle` or
`BlockInlineCheck::UseComputedDisplayStyle`.
So, this patch should fix some edge case bugs of
`display: inline-block`. However, unfortunately, there is not enough
tests for that.
Differential Revision: https://phabricator.services.mozilla.com/D270116
These utility methods behave odd in some edge cases and they are not
tested. Therefore, they should be tested with new unit tests and we
should fix the odd behaviors.
Differential Revision: https://phabricator.services.mozilla.com/D265186
This patch updates all occurrences of the type `nsTextFragment` into its new name, `mozilla::dom::CharacterDataBuffer`.
It also updates the includes, including sorting.
Differential Revision: https://phabricator.services.mozilla.com/D259867
There is a case that "\n" is not a preformatted line break, but it's
rendered as a non-collapsible white-space. Therefore, for checking
whether a "\n" is a collapsible white-space,
`EditorUtils::IsWhiteSpacePreformatted` should be used instead of
`EditorUtils::IsNewLinePreformatted`.
Differential Revision: https://phabricator.services.mozilla.com/D257458
They are internal APIs to return next/previous visible thing or
a padding `<br>` element. However, when they reach a `Comment`, they
don't skip it and return it as a special content. `Comment` is always
invisible so that they should skip such invisible nodes.
Differential Revision: https://phabricator.services.mozilla.com/D257125
When `HTMLEditor::InsertElementAtSelectionAsAction` inserts given element,
it tries to normalize the white-spaces around the insertion point [1].
Then, `WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt` tries to
delete invisible white-spaces around the insertion point first [2].
If the insertion point is not in leading white-spaces nor trailing white-spaces
around a block boundary, it tries to scan preceding and following white-spaces
to delete the surrounding invisible white-spaces [3].
At this time, it uses `TextFragmentData::GetInclusiveNextCharPoint()` and
`TextFragmentData::GetPreviousCharPoint()` which was initialized at the
insertion point.
However, they may return a point behind a block boundary with both digging into
a sibling block or skipping a sibling block. Therefore, the result may
be too far from the insertion point and the following code in
`WhiteSpaceVisibilityKeeper::EnsureNoInvisibleWhiteSpaces()` may extend the
range to contain children because `GetFirstASCIIWhiteSpacePointCollapsedTo()`
and `GetEndOfCollapsibleASCIIWhiteSpaces()` uses `GetInclusiveNextCharPoint`
and `GetPreviousCharPoint()` too.
Therefore, when Thunderbird inserts a `<p>` with a call of
`HTMLEditor::InsertElementAtSelectionAsAction()` after `<blockquote>`,
it may delete the preceding text in the `<blockquote>` accidentally.
So, the scan methods of `WSRunScanner` shouldn't cross the block boundaries
because they handle only text fragment in the same line.
1. https://searchfox.org/mozilla-central/rev/27bb03eebacd679df419dac52a3b99c142cdb5db/editor/libeditor/HTMLEditor.cpp#2264-2269
2. https://searchfox.org/mozilla-central/rev/27bb03eebacd679df419dac52a3b99c142cdb5db/editor/libeditor/WhiteSpaceVisibilityKeeper.cpp#1501-1503
3. https://searchfox.org/mozilla-central/rev/27bb03eebacd679df419dac52a3b99c142cdb5db/editor/libeditor/WhiteSpaceVisibilityKeeper.cpp#2447-2469
Differential Revision: https://phabricator.services.mozilla.com/D244876
A preformatted linefeed works exactly same as `<br>` as far as I know.
Actually, white-spaces before a preformatted linefeed is visible as a space.
Therefore, the method should not keep scanning invisible white-spaces if the
sequence ends with a preformatted linefeed.
The check was introduced in D124560 which is for initial support of
`white-space: pre-*`. So, this is a traditional hidden bug, but this appeared
by that we started deleting unnecessary linebreaks.
Differential Revision: https://phabricator.services.mozilla.com/D235918
Chromium considers whether an element is block or inline with `display-outside`.
Therefore, they treat `inline-block` is an inline element. For following the
behavior, we use `BlockInlineCheck::UseComputedDisplayOutsideStyle` in many
places. However, if `WSRunScanner` works for considering a collapsible
white-space visibility, it needs to treat `inline-block` as a block only when
it's an ancestor.
In the reported case, the editing host is `inline-block`. So, `WSRunScanner`
reached the ancestor limiter if scanning only editable nodes. To fix this bug,
this changes the behavior only when the scanner reached the ancestor limiter.
In the future, we need to change the scanner methods of `HTMLEditUtils`
use the new inline methods.
Differential Revision: https://phabricator.services.mozilla.com/D235530
It stores the editing host. However, its role is scan the DOM from a point in
a block containing the point. Therefore, it can know which node is editing
host when it scans without computing the editing host. So, it does not need
to be specified the editing host.
Then, it can scan non-editable DOM too. Therefore, this extends some utility
methods of `HTMLEditUtils` which are used by `TextFragmentData` and
`BoundaryData`.
Differential Revision: https://phabricator.services.mozilla.com/D232937
Its role is scanning the DOM. Therefore, it can know which node is an editing
host during a scan. Therefore, it does not require the editing host parameter.
To fix that, some utility methods of `HTMLEditUtils` needs to work with
non-editable nodes. Therefore, this patch also updates `HTMLEditUtils`.
Finally, this gets rid of the `NS_ASSERTION`s in the constructor of
`TextFragmentData` because it'll be available with non-editable nodes too.
Although current all callers assume that it works as in an editing host.
Differential Revision: https://phabricator.services.mozilla.com/D232934
It stores the editing host. However, its role is scan the DOM from a point in
a block containing the point. Therefore, it can know which node is editing
host when it scans without computing the editing host. So, it does not need
to be specified the editing host.
Then, it can scan non-editable DOM too. Therefore, this extends some utility
methods of `HTMLEditUtils` which are used by `TextFragmentData` and
`BoundaryData`.
Differential Revision: https://phabricator.services.mozilla.com/D232937
Its role is scanning the DOM. Therefore, it can know which node is an editing
host during a scan. Therefore, it does not require the editing host parameter.
To fix that, some utility methods of `HTMLEditUtils` needs to work with
non-editable nodes. Therefore, this patch also updates `HTMLEditUtils`.
Finally, this gets rid of the `NS_ASSERTION`s in the constructor of
`TextFragmentData` because it'll be available with non-editable nodes too.
Although current all callers assume that it works as in an editing host.
Differential Revision: https://phabricator.services.mozilla.com/D232934