Bug 1613521 - Make NeedsToDispatchBeforeInputEvent() return false if the edit action requires a clipboard event and it's not dispatched yet r=m_kato

The reason of hitting the assertion is, a clipboard event listener nests
another edit action, initializing the editor, runs, and tries to create an
anonymous `<br>` element with transaction, but it checks whether `beforeinput`
event has already been dispatched or not with the parent edit action data.

For fixing it, this patch adds a flag to edit action data to indicate whether
a clipboard event has already been dispatched or not.  If it's already been
dispatched, it's **okay** to modify the DOM tree.  Ideally, we should put off
modifying the DOM tree after dispatching `beforeinput` event, but this case
does not notify web apps anything so that this patch should be fine.

Although this patch adds a crash test which is attached by the reporter,
it's not reproducible with current editor code because we stopped modifying
native anonymous nodes with transaction, but it depends on the behavior.
Still this assertion hits in `test_clipboard_noeditor.html` intermittently,
but I don't have idea how to reproduce this permanently.  Therefore, this
patch does not contain a test to check to regression actually.

Differential Revision: https://phabricator.services.mozilla.com/D95115
This commit is contained in:
Masayuki Nakano
2020-10-30 07:21:40 +00:00
parent 728c559525
commit 0eba024e2d
7 changed files with 102 additions and 21 deletions

View File

@@ -576,8 +576,13 @@ nsresult TextEditor::PasteAsAction(int32_t aClipboardType,
return NS_ERROR_NOT_INITIALIZED;
}
if (aDispatchPasteEvent && !FireClipboardEvent(ePaste, aClipboardType)) {
return EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_ACTION_CANCELED);
if (aDispatchPasteEvent) {
if (!FireClipboardEvent(ePaste, aClipboardType)) {
return EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_ACTION_CANCELED);
}
} else {
// The caller must already have dispatched a "paste" event.
editActionData.NotifyOfDispatchingClipboardEvent();
}
if (AsHTMLEditor()) {