Bug 1941520 - Make HTMLEditor::OnModifyDocument set top level edit sub-action before maintaining the white-space visibility r=m_kato

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 commit is contained in:
Masayuki Nakano
2025-01-15 08:24:34 +00:00
parent a24b23bc19
commit 6f4cdf57e0
6 changed files with 169 additions and 72 deletions

View File

@@ -379,6 +379,14 @@ nsresult HTMLEditor::OnEndHandlingTopLevelEditSubAction() {
nsresult HTMLEditor::OnEndHandlingTopLevelEditSubActionInternal() {
MOZ_ASSERT(IsTopLevelEditSubActionDataAvailable());
// If we just maintained the DOM tree for consistent behavior even after
// web apps modified the DOM, we should not touch the DOM in this
// post-processor.
if (GetTopLevelEditSubAction() ==
EditSubAction::eMaintainWhiteSpaceVisibility) {
return NS_OK;
}
nsresult rv = EnsureSelectionInBodyOrDocumentElement();
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
return NS_ERROR_EDITOR_DESTROYED;