The serializer needs to make each mailcite starts from head of a line.
However, mailcite may be a blocked `<span>`. So, its preceding `<br>`
is not required from the HTML point of view, but we need to preserve
it for the serializer.
If we need this hack in some other places, we should make
`HTMLEditUtils::GetFollowingUnnecessaryLineBreak()` aware of this
special handling in a follow up bug.
Differential Revision: https://phabricator.services.mozilla.com/D270784
In bug 1925635, I moved the post processing after deleting ranges in
`EditorBase::DeleteRangesWithTransaction` into the `HTMLEditor`'s override.
At this time, I makes it uses `HTMLEditUtils::IsEmptyNode` to check whether
the `Text` and its containers become empty. Therefore, if `Ctrl`+`Backspace`
deletes the only word in the `Text` which starts with a collapsible white-space
causes deleting the `Text` after deleting all visible characters in the `Text`.
Therefore, this makes check it with `Text::TextDataLength` too before searching
the most distant ancestor inline element which becomes empty.
However, it may cause leading invisible white-spaces of the only word visible
because `nsFrameSelection` computes the word range strictly in the `Text`.
Therefore, this patch also makes `HTMLEditor::DeleteRangesWithTransaction` and
`AutoDeleteRangesHandler::ComputeRangesToDeleteRangesWithTransaction` extend
each range to delete to include surrounding invisible white-spaces too.
Therefore, this patch adds the new method to `AutoClonedRangeArray`.
Then, I hit 4 existing bugs with new test failures.
One is `HTMLEditUtils::LineRequiresPaddingLineBreakToBeVisible`. It checks
whether the candidate point to insert a `<br>` is followed by a block boundary
first. Then, it checks whether the candidate point follows a collapsible
white-space or a block boundary. However, it uses
`WSRunScanner::ScanPreviousVisibleNodeOrBlockBoundary()` which ignores invisible
white-spaces. Therefore, it will ignore the new invisible white-space and
reaches preceding `Text`. Thus, it fails to put a `<br>` and makes the new
invisible white-space "fixed" as invisible.
Therefore, this patch rewrites the check with using
`HTMLEditUtils::GetPreviousLeafContentOrPreviousBlockElement()`.
Next one is, `HTMLEditor::DeleteEmptyInclusiveAncestorInlineElements()`
returns end of deleted node if it's followed by a non-editable node, i.e.,
an element has `contenteditable="false"`. Therefore, its caller inserts a
`<br>` to the end of the container when deleting preceding editable node of a
non-editable node.
Therefore, this patch removes the editable state check.
Next, `AutoBlockElementsJoiner::HandleDeleteNonCollapsedRange` may put a padding
`<br>` after the moved line, but it does not assume that the moved line does not
ends with a block boundary. This causes failing #46 and #48 tests in
`text_bug772796.html`. E.g., when pressing `Delete` in
`<div>foo[]<div><span style="white-space:pre"><div>bar</div>baz</span>`, we move
the second `<div>` as a child of the parent `<span>` to end of the first `<div>`
like `<div>foo<span style="white-space:pre"><div>bar</div></span></div>...`.
Without the change, it starts to put unnecessary `<br>` after ` the `<span>`
because of the bug fix in `HTMLEditUtils::LineRequiresPaddingLineBreakToBeVisible`
above. This result is completely odd from the users point of view (looks like
just move caret), but we should avoid to put the unnecessary `<br>`.
Finally, we'll fail an assertion when putting caret at the last of
`AutoBlockElementsJoiner::DeleteContentInRange` because it forgets to flush
the tracking range before using it. This appeared by the changes above.
Therefore, this patch fixes this bug too.
Differential Revision: https://phabricator.services.mozilla.com/D240703
It's an alias of `nsINode::GetClosestNativeAnonymousSubtreeRootParentOrHost()`
and oddly it returns `const nsIContent*` rather than `nsIContent*`. Therefore,
some callers need to use `const_cast`.
Differential Revision: https://phabricator.services.mozilla.com/D241776
This patch fixes multiple points which may cross independent selection
boundaries which is element boundary of the native anonymous `<div>` for
editable content in text controls. The reason why I don't split this patch is,
fixing one of them leads another assertion failure. So, I couldn't pass all
tests with separated patches.
1. `nsFrameTraversal` should take `Element` instead of `nsIFrame` for the
limiter because e.g., inline editing host like `<span contenteditable>` may
have multiple frames if it's wrapped. Therefore, we should make it take
an element as the ancestor limiter, and check it when getting parent frame
or after getting previous or next frame.
2. `nsIFrame::PeekBackwardAndForward` may cross the boundary because it does not
take the anonymous `<div>` element as ancestor limiter of the selection. It's
currently used only for extending selection. Therefore, I rename it to make
it clearer.
3. `SelectionMovementUtils::GetPrevNextBidiLevel` to take the ancestor limiter
for calling `nsIFrame::GetFrameFromDirection()`.
4. `nsINode` should have a method to return the `nsFrameSelection` instance
which manages the selection in the node. This makes the check simpler, and
this is not expensive. Then, for making it clearer, I rename
`TextControlElement::GetConstFrameSelection()` to
`GetIndependentFrameSelection()`.
5. `nsINode::GetSelectionRootContent()` should have an option to return
independent selection root when the node is its host for
`nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree()`
6. `nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree()` should not
retrieve independent selection root when the given frame is a text control
frame.
7. `RangeUtils` should get parent with checking the independent selection
boundaries.
8. `Selection::Extend` should assert if the destination is managed by its
frame selection to detect a bug.
Differential Revision: https://phabricator.services.mozilla.com/D241587
The style editing commands should be disabled in
`contenteditable="plaintext-only"`. Currently, we return `false` from
`execCommand`, but we still claim that the commands are enabled for
`queryCommandEnabled`.
Differential Revision: https://phabricator.services.mozilla.com/D239985
Enabling the new normalizer causes this assertion failure:
```
###!!! ASSERTION: Want to fire DOMNodeRemoved event, but it's not safe: 'Error', file /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:5586
#01: NS_DebugBreak [xpcom/base/nsDebugImpl.cpp:508]
#02: nsContentUtils::MaybeFireNodeRemoved(nsINode*, nsINode*) [dom/base/nsContentUtils.cpp:5587]
#03: nsINode::RemoveChild(nsINode&, mozilla::ErrorResult&) [dom/base/nsINode.cpp:0]
#04: mozilla::DeleteNodeTransaction::DoTransaction() [editor/libeditor/DeleteNodeTransaction.cpp:112]
#05: mozilla::EditorBase::DoTransactionInternal(nsITransaction*) [editor/libeditor/EditorBase.cpp:929]
#06: mozilla::EditorBase::DeleteNodeWithTransaction(nsIContent&) [editor/libeditor/EditorBase.cpp:2685]
#07: mozilla::WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitTextNodeAt(mozilla::HTMLEditor&, mozilla::EditorDOMPointBase<RefPtr<mozilla::dom::Text>, nsIContent*> const&, mozilla::EnumSet<mozilla::WhiteSpaceVisibilityKeeper::NormalizeOption, unsigned int>) [editor/libeditor/WhiteSpaceVisibilityKeeper.cpp:1384]
#08: mozilla::WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt(mozilla::HTMLEditor&, mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&, mozilla::EnumSet<mozilla::WhiteSpaceVisibilityKeeper::NormalizeOption, unsigned int>) [editor/libeditor/WhiteSpaceVisibilityKeeper.cpp:1599]
#09: mozilla::HTMLEditor::PrepareToInsertLineBreak(mozilla::HTMLEditor::LineBreakType, mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&) [editor/libeditor/HTMLEditor.cpp:4418]
#10: mozilla::EditorBase::InsertPaddingBRElementForEmptyLastLineWithTransaction(mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&) [editor/libeditor/EditorBase.cpp:2511]
#11: mozilla::HTMLEditor::InsertBRElementToEmptyListItemsAndTableCellsInRange(mozilla::RangeBoundaryBase<nsINode*, nsIContent*> const&, mozilla::RangeBoundaryBase<nsINode*, nsIContent*> const&) [editor/libeditor/HTMLEditSubActionHandler.cpp:0]
#12: mozilla::HTMLEditor::InitEditorContentAndSelection() [editor/libeditor/HTMLEditSubActionHandler.cpp:187]
#13: mozilla::HTMLEditor::Init(mozilla::dom::Document&, mozilla::ComposerCommandsUpdater&, unsigned int) [editor/libeditor/HTMLEditor.cpp:412]
#14: nsEditingSession::SetupEditorOnWindow(nsPIDOMWindowOuter&) [editor/composer/nsEditingSession.cpp:405]
```
The initialization is required only for empty table cells and empty list items
and they are typically not used at initial document. So, I think that it's fine
to stop normalizing white-spaces before succeeded to initialize `HTMLEditor`.
If this change causes a web-compat issue in the wild, let's make it run
asynchronously.
Differential Revision: https://phabricator.services.mozilla.com/D239473
Unfortunately, this patch becomes big because this includes multiple utility
methods to normalize white-spaces and touching a lot of places.
In some edge cases, this starts failing when the new white-space normalizer is
enabled.
```
FAIL execCommand("forwarddelete", false, ""): "a [] | b" - assert_equals: Modified text is wrong expected "a " but got "a "
FAIL execCommand("forwarddelete", false, ""): "a [] | b" - assert_equals: Modified text is wrong expected "a " but got "a "
FAIL execCommand("forwarddelete", false, ""): "a []b| c" - assert_equals: Modified text is wrong expected "a " but got "a "
FAIL execCommand("forwarddelete", false, ""): "a [] <span style=white-space:pre;> </span>" - assert_equals: expected "a <span style=\"white-space:pre;\"> </span>" but got "a <span style=\"white-space:pre;\"> </span>"
```
In these failures, we normalize the trailing white-spaces of the preceding
`Text` too, but Chrome does not do that. However, in some cases, they do
in similar cases. Therefore, it's hard to align all cases due to the handling
order difference. Additionally, these failure results are not odd. So, these
new failures are acceptable.
```
FAIL execCommand("forwarddelete", false, ""): "<span>abc[] <span> def</span></span>" - assert_equals: expected "<span>abc<span> def</span></span>" but got "<span>abc<span> def</span></span>"
FAIL execCommand("forwarddelete", false, ""): "<span><span>abc[] </span> def</span>" - assert_equals: expected "<span><span>abc</span> def</span>" but got "<span><span>abc</span> def</span>"
FAIL execCommand("forwarddelete", false, ""): "<span>abc[] </span><span> def</span>" - assert_equals: expected "<span>abc</span><span> def</span>" but got "<span>abc</span><span> def</span>"
FAIL execCommand("forwarddelete", false, ""): "<span>abc[] </span><span> def</span>" - assert_equals: expected "<span>abc </span><span> def</span>" but got "<span>abc </span><span> def</span>"
```
In these failures, we don't normalize the leading white-spaces of the following
`Text`. However, Chrome does so in some other cases. So, it's hard to align
the behavior in these cases too. The new normalizer ensures that the preceding
`Text` ends with a visible char. Therefore, the following `Text` won't starts
with new invisible white-spaces. Therefore, these failures are also acceptable.
```
FAIL execCommand("forwarddelete", false, ""): "<span style=white-space:pre;> [] </span> a" - assert_equals: expected "<span style=\"white-space:pre;\"> </span> a" but got "<span style=\"white-space:pre;\"> </span> a"
```
In this failure, we don't normalize the following `Text` but Chrome does it.
However, I don't think we should do it because this updates the `Text` which
is preformatted. Therefore, this is also acceptable.
So, I think that we can accept all new failures.
Differential Revision: https://phabricator.services.mozilla.com/D239468
Surprisingly, it has not normalize white-spaces around it. So, in some edge
cases, it might cause changing visibility of surrounding white-spaces.
Differential Revision: https://phabricator.services.mozilla.com/D239467
Unfortunately, this change does not make
`white-spaces-after-execCommand-insertparagraph.tentative.html` pass because
the insert paragraph handler inserts a temporary `<br>` element and that causes
normalizing the following white-spaces at the split point. However, Chrome
does not normalize the following white-spaces if it begins with an NBSP.
Differential Revision: https://phabricator.services.mozilla.com/D239465
When inserting a `<br>` element or a preformatted line break at middle of a
`Text`, we need to split it first. At this time, we should normalize the
surrounding white-spaces before split. Then, we can use only one
`ReplaceTextTransaction` instance for the normalization in the most cases.
Differential Revision: https://phabricator.services.mozilla.com/D239464
First, it makes it deletes invisible white-spaces at the insertion point.
This makes the further processing simpler.
Second, it extends the range to update in `Text` which will contain the
insertion string when it's not used for inserting nor updating composition
string, as containing all surrounding white-spaces at the insertion point.
Next, it normalizes the inserting string with the surrounding white-spaces with
the same rules as the other browsers especially as Chrome.
1. a collapsible white-space at start or end of a `Text` is always an NBSP.
2. a collapsible white-space immediately before or after a preformatted line
break is always an NBSP.
3. a collapsible white-space surrounded by non-collapsible chars is always an
ASCII white-space.
4. collapsible white-spaces are pairs of an NBSP and an ASCII white-space.
Then, we can make `HTMLEditor::OnEndHandlingTopLevelEditSubActionInternal()`
stop normalizing white-spaces when inserting text.
Differential Revision: https://phabricator.services.mozilla.com/D239463
Enabling the new normalizer causes this assertion failure:
```
###!!! ASSERTION: Want to fire DOMNodeRemoved event, but it's not safe: 'Error', file /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:5586
#01: NS_DebugBreak [xpcom/base/nsDebugImpl.cpp:508]
#02: nsContentUtils::MaybeFireNodeRemoved(nsINode*, nsINode*) [dom/base/nsContentUtils.cpp:5587]
#03: nsINode::RemoveChild(nsINode&, mozilla::ErrorResult&) [dom/base/nsINode.cpp:0]
#04: mozilla::DeleteNodeTransaction::DoTransaction() [editor/libeditor/DeleteNodeTransaction.cpp:112]
#05: mozilla::EditorBase::DoTransactionInternal(nsITransaction*) [editor/libeditor/EditorBase.cpp:929]
#06: mozilla::EditorBase::DeleteNodeWithTransaction(nsIContent&) [editor/libeditor/EditorBase.cpp:2685]
#07: mozilla::WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitTextNodeAt(mozilla::HTMLEditor&, mozilla::EditorDOMPointBase<RefPtr<mozilla::dom::Text>, nsIContent*> const&, mozilla::EnumSet<mozilla::WhiteSpaceVisibilityKeeper::NormalizeOption, unsigned int>) [editor/libeditor/WhiteSpaceVisibilityKeeper.cpp:1384]
#08: mozilla::WhiteSpaceVisibilityKeeper::NormalizeWhiteSpacesToSplitAt(mozilla::HTMLEditor&, mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&, mozilla::EnumSet<mozilla::WhiteSpaceVisibilityKeeper::NormalizeOption, unsigned int>) [editor/libeditor/WhiteSpaceVisibilityKeeper.cpp:1599]
#09: mozilla::HTMLEditor::PrepareToInsertLineBreak(mozilla::HTMLEditor::LineBreakType, mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&) [editor/libeditor/HTMLEditor.cpp:4418]
#10: mozilla::EditorBase::InsertPaddingBRElementForEmptyLastLineWithTransaction(mozilla::EditorDOMPointBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&) [editor/libeditor/EditorBase.cpp:2511]
#11: mozilla::HTMLEditor::InsertBRElementToEmptyListItemsAndTableCellsInRange(mozilla::RangeBoundaryBase<nsINode*, nsIContent*> const&, mozilla::RangeBoundaryBase<nsINode*, nsIContent*> const&) [editor/libeditor/HTMLEditSubActionHandler.cpp:0]
#12: mozilla::HTMLEditor::InitEditorContentAndSelection() [editor/libeditor/HTMLEditSubActionHandler.cpp:187]
#13: mozilla::HTMLEditor::Init(mozilla::dom::Document&, mozilla::ComposerCommandsUpdater&, unsigned int) [editor/libeditor/HTMLEditor.cpp:412]
#14: nsEditingSession::SetupEditorOnWindow(nsPIDOMWindowOuter&) [editor/composer/nsEditingSession.cpp:405]
```
The initialization is required only for empty table cells and empty list items
and they are typically not used at initial document. So, I think that it's fine
to stop normalizing white-spaces before succeeded to initialize `HTMLEditor`.
If this change causes a web-compat issue in the wild, let's make it run
asynchronously.
Differential Revision: https://phabricator.services.mozilla.com/D239473
Unfortunately, this patch becomes big because this includes multiple utility
methods to normalize white-spaces and touching a lot of places.
In some edge cases, this starts failing when the new white-space normalizer is
enabled.
```
FAIL execCommand("forwarddelete", false, ""): "a [] | b" - assert_equals: Modified text is wrong expected "a " but got "a "
FAIL execCommand("forwarddelete", false, ""): "a [] | b" - assert_equals: Modified text is wrong expected "a " but got "a "
FAIL execCommand("forwarddelete", false, ""): "a []b| c" - assert_equals: Modified text is wrong expected "a " but got "a "
FAIL execCommand("forwarddelete", false, ""): "a [] <span style=white-space:pre;> </span>" - assert_equals: expected "a <span style=\"white-space:pre;\"> </span>" but got "a <span style=\"white-space:pre;\"> </span>"
```
In these failures, we normalize the trailing white-spaces of the preceding
`Text` too, but Chrome does not do that. However, in some cases, they do
in similar cases. Therefore, it's hard to align all cases due to the handling
order difference. Additionally, these failure results are not odd. So, these
new failures are acceptable.
```
FAIL execCommand("forwarddelete", false, ""): "<span>abc[] <span> def</span></span>" - assert_equals: expected "<span>abc<span> def</span></span>" but got "<span>abc<span> def</span></span>"
FAIL execCommand("forwarddelete", false, ""): "<span><span>abc[] </span> def</span>" - assert_equals: expected "<span><span>abc</span> def</span>" but got "<span><span>abc</span> def</span>"
FAIL execCommand("forwarddelete", false, ""): "<span>abc[] </span><span> def</span>" - assert_equals: expected "<span>abc</span><span> def</span>" but got "<span>abc</span><span> def</span>"
FAIL execCommand("forwarddelete", false, ""): "<span>abc[] </span><span> def</span>" - assert_equals: expected "<span>abc </span><span> def</span>" but got "<span>abc </span><span> def</span>"
```
In these failures, we don't normalize the leading white-spaces of the following
`Text`. However, Chrome does so in some other cases. So, it's hard to align
the behavior in these cases too. The new normalizer ensures that the preceding
`Text` ends with a visible char. Therefore, the following `Text` won't starts
with new invisible white-spaces. Therefore, these failures are also acceptable.
```
FAIL execCommand("forwarddelete", false, ""): "<span style=white-space:pre;> [] </span> a" - assert_equals: expected "<span style=\"white-space:pre;\"> </span> a" but got "<span style=\"white-space:pre;\"> </span> a"
```
In this failure, we don't normalize the following `Text` but Chrome does it.
However, I don't think we should do it because this updates the `Text` which
is preformatted. Therefore, this is also acceptable.
So, I think that we can accept all new failures.
Differential Revision: https://phabricator.services.mozilla.com/D239468
Surprisingly, it has not normalize white-spaces around it. So, in some edge
cases, it might cause changing visibility of surrounding white-spaces.
Differential Revision: https://phabricator.services.mozilla.com/D239467
Unfortunately, this change does not make
`white-spaces-after-execCommand-insertparagraph.tentative.html` pass because
the insert paragraph handler inserts a temporary `<br>` element and that causes
normalizing the following white-spaces at the split point. However, Chrome
does not normalize the following white-spaces if it begins with an NBSP.
Differential Revision: https://phabricator.services.mozilla.com/D239465
When inserting a `<br>` element or a preformatted line break at middle of a
`Text`, we need to split it first. At this time, we should normalize the
surrounding white-spaces before split. Then, we can use only one
`ReplaceTextTransaction` instance for the normalization in the most cases.
Differential Revision: https://phabricator.services.mozilla.com/D239464
First, it makes it deletes invisible white-spaces at the insertion point.
This makes the further processing simpler.
Second, it extends the range to update in `Text` which will contain the
insertion string when it's not used for inserting nor updating composition
string, as containing all surrounding white-spaces at the insertion point.
Next, it normalizes the inserting string with the surrounding white-spaces with
the same rules as the other browsers especially as Chrome.
1. a collapsible white-space at start or end of a `Text` is always an NBSP.
2. a collapsible white-space immediately before or after a preformatted line
break is always an NBSP.
3. a collapsible white-space surrounded by non-collapsible chars is always an
ASCII white-space.
4. collapsible white-spaces are pairs of an NBSP and an ASCII white-space.
Then, we can make `HTMLEditor::OnEndHandlingTopLevelEditSubActionInternal()`
stop normalizing white-spaces when inserting text.
Differential Revision: https://phabricator.services.mozilla.com/D239463
The hacks are only for specific web apps. Therefore, unless they require to
know the selection changes, we don't need to expose that.
Differential Revision: https://phabricator.services.mozilla.com/D239835
If I run `./mach wpt testing/web-platform/tests/editing` with just enabling the
new normalizer, I see some assertion failures which are caused by scanning or
updating non-editable regions.
According to the debug result, it's caused by sometimes caret point is suggested
in non-editable node and further handling will use various utilities which
asserts whether the target is editable.
Ideally, we should add assertion into `CaretPoint`, but it's hard and I don't
have enough time to fix every regression which will be found by fuzzing tests
even though most of them are not so important in the real web apps. Therefore,
this fixes only the causes which I found in the WPTs.
Differential Revision: https://phabricator.services.mozilla.com/D238408
The hacks are required only for the other legacy behavior which uses ASCII
white-space even before a block boundary but with a padding `<br>` element.
Therefore, once we use the Blink compare behavior, it'll put an NBSP without
a padding `<br>`, we don't need them anymore.
Differential Revision: https://phabricator.services.mozilla.com/D237523
Usually, we name methods as `GetFoo()` if they may return `nullptr`, on the
other hand, we name methods as `Foo()` if they won't return `nullptr`.
`RangeBoundaryBase::Container()` may return `nullptr`. So, this name may cause
misleading of some developers. Let's rename it as `GetContainer()`.
This does not change anything for avoiding merge conflict with the other
landings.
Differential Revision: https://phabricator.services.mozilla.com/D236796
They grabs `Selection`, but that appears in the profile. Fortunately, we
don't require the instance in the methods including the callees. Therefore,
we don't need to create it at every mutation.
Differential Revision: https://phabricator.services.mozilla.com/D236095
Move the relevant bits to html.css or other UA sheets, and use faster
things than attribute selectors (read: classes) for resizers and such
things.
The hidden class can just be a hidden attribute since we don't otherwise
style these.
The cursor can just be set at the resizer / grabber creation time.
One known behavior change other than this is not styling using the
_moz_abspos attribute. The reasoning for this is that these are content
nodes, and in general having these kinds of rules for content nodes
isn't great. E.g. these two pages behave differently:
* data:text/html,<div _moz_abspos=black>boo</div>
* data:text/html,<div _moz_abspos=black>boo</div><div contenteditable></div>
We could use the style attribute for this, I suppose, just like we set
the position or what not, but then we need to save / restore as needed
or something. I'd rather not change the stacking order or backgrounds or
what not, too.
If you feel very strongly about that piece of functionality of the
abspos editor I could try to restore it somehow. But I honestly rather
not.
The rest of the stuff should just work.
Differential Revision: https://phabricator.services.mozilla.com/D235319
Note that this removes a lot of `aEditingHost` params. This may cause odd
behavior if editing host is changed by a legacy mutation event listener.
However, it'll be completely deleted soon and even if we meet some regressions,
we can just restore the param to set `aAncestorLimiter`.
Differential Revision: https://phabricator.services.mozilla.com/D233794
If it scans starting from a editable point, it does not require the editing
host as an ancestor limiter. Therefore, some users can be free from editing
host.
Differential Revision: https://phabricator.services.mozilla.com/D233791
`nsFrameSelection::GetLimiter()` is not `nullptr` only when it's an instance for
an independent selection of a text control. In the case, it's set to the editor
root anonymous `<div>` of the text control. Despite the name, this is already
optimized only for this purpose in `nsFrameSelection::NodeIsInLimiters()`.
Thus, we don't have any problems to make this clearer for the other developers
with renaming some parameter names.
`nsFrameSelection::GetAncestorLimiter()` is also always an `Element`. So,
we can change this to `Element` too.
Differential Revision: https://phabricator.services.mozilla.com/D235254
Note that this removes a lot of `aEditingHost` params. This may cause odd
behavior if editing host is changed by a legacy mutation event listener.
However, it'll be completely deleted soon and even if we meet some regressions,
we can just restore the param to set `aAncestorLimiter`.
Differential Revision: https://phabricator.services.mozilla.com/D233794
If it scans starting from a editable point, it does not require the editing
host as an ancestor limiter. Therefore, some users can be free from editing
host.
Differential Revision: https://phabricator.services.mozilla.com/D233791
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
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
The logic before getting editing host in them are correct, but both
`nsIContent::GetEditingHost()` and `HTMLEditor::ComputeEditingHostInternal()`
return `Document::GetBody()` result if it's in the design mode.
For now, we should just add nullptr checks into the methods since they are
required only for some specific web apps.
Differential Revision: https://phabricator.services.mozilla.com/D234442
`HTMLEditor::DoSplitNode` does:
1. Insert a new right node
2. Move content in left node into the right node
`HTMLEditor::DoJoinNodes` does:
1. Move content of the right node to the left node
2. Delete the left node
So, all things are done when connected. Therefore `IMEContentObserver` uses its
cache and it's harder to debug. Additionally, temporarily the touching range
becomes wider then the result at joining nodes. That could cause IME gets
received longer text change range. Therefore, they should do:
`HTMLEditor::DoSplitNode`:
1. Move content in left node to the orphan new right node (then, only removing
content is handled by `IMEContentObserver`)
2. Insert the right node (then, `IMEContentObserver` can compute the offset and
length only once)
`HTMLEditor::DoJoinNodes`:
1. Delete the right node (then, all moving content is treated as removed by
`IMEContentObserver`, i.e., it needs to compute offset/length once)
2. Move the non-connected right node children into the left node (then,
`IMEContentObserver` can cache all moving nodes and compute offset/length once)
Differential Revision: https://phabricator.services.mozilla.com/D232882
When pasting text, a `paste` event is fired before a `beforeinput` event.
Therefore, the editor still does not have top level edit sub-action. Therefore,
the DOM mutation caused by the web app will be handled by
`HTMLEditor::OnModifyDocument` immediately after removing the script blocker.
At this time, we may do:
* insert a padding `<br>` if something immediately after last input is removed
* replace a collapsible white-space if padding `<br>` is removed
Then, each handler sets the top level edit sub-action and the post-processor
will run immediately. Then, especially in the latter case,
`WhiteSpaceVisibilityKeeper::NormalizeVisibleWhiteSpacesAt` will insert a
padding `<br>` again and restores the replaced NBSP to a collapsible
white-space unexpectedly.
Therefore, if web apps trying to normalize the pasted content with removing
the pasted nodes temporarily, it may cause entering an infinite loop.
This patch makes `HTMLEditor::OnModifyDocument` set edit sub-action for the
hacks to avoid running the post-processor.
Additionally, this touches `EditorBase::DoTransactionInternal` to avoid the
assertion failure of the new test. The assertion failure indicates a logical
bug of our basic strategy. However, we should not touch the big design change
for now. (Anyway, the hack should be removed as soon as possible.)
Differential Revision: https://phabricator.services.mozilla.com/D234278
This is a hack until bug 503838 is fixed.
The other browsers puts an NBSP for the last ASCII white-space immediately
before a block boundary to make it visible. However, we currently need to
keep using an ASCII white-space as-is with putting a padding `<br>` element.
However, web apps may delete the `<br>` for some reasons without maintaining
the preceding collapsible white-space visibility since it's not required in
the other browsers.
Therefore, this patch replaces the white-spaces only when we meet such
situation. Of course, this breaks the undo stack, but touching the DOM anyway
causes breaking the undo stack. Thus, we can trust the web app as that it
manages their on undo stack.
Differential Revision: https://phabricator.services.mozilla.com/D233472