Bug 1701348 - Make TextEditor::Init() and HTMLEditor::Init() stop using EditAction::eNotEditing r=m_kato

Currently, they set `EditAction::eNotEditing` even though they may create a
paddning `<br>` element.  If there is already handling edit action, setting
`eNotEditing` makes inherit the parent edit action.
https://searchfox.org/mozilla-central/rev/be413c29deeb86be6cdac22445e0d0b035cb9e04/editor/libeditor/EditorBase.cpp#5150-5159

However, in the reported case, `FlushPendingNotificationsIfToHandleDeletionWithFrameSelection()`
is called for computing target ranges at `forwarddelete` command handling.
In this case, `EditAction::eDeleteSelection` or something is set as parent
edit action.
https://searchfox.org/mozilla-central/rev/be413c29deeb86be6cdac22445e0d0b035cb9e04/editor/libeditor/EditorBase.cpp#3638-3660
But at this moment, `beforeinput` event hasn't been dispatched.  Then,
initializing code inherits this state and trying to insert a padding `<br>`
element without `beforeinput` event.  Then, we hit the assertion.

For solving this issue, `Init` methods should set edit action to "initializing"
and it should be marked as not requiring `beforeinput` event.

Differential Revision: https://phabricator.services.mozilla.com/D111191
This commit is contained in:
Masayuki Nakano
2021-04-08 08:51:41 +00:00
parent 6b92a97915
commit a629f3f5ac
6 changed files with 23 additions and 9 deletions

View File

@@ -19,11 +19,14 @@ enum class EditAction {
// eNone indicates no edit action is being handled.
eNone,
// eNotEditing indicates that something is retrieved or initializing
// something at creating, destroying or focus move etc, i.e., not edit
// action is being handled but editor is doing something.
// eNotEditing indicates that something is retrieved, doing something at
// destroying or focus move etc, i.e., not edit action is being handled but
// editor is doing something.
eNotEditing,
// eInitializing indicates that the editor instance is being initialized.
eInitializing,
// eInsertText indicates to insert some characters.
eInsertText,
@@ -632,6 +635,7 @@ inline bool MayEditActionDeleteSelection(const EditAction aEditAction) {
switch (aEditAction) {
case EditAction::eNone:
case EditAction::eNotEditing:
case EditAction::eInitializing:
return false;
// EditActions modifying around selection.

View File

@@ -1140,6 +1140,9 @@ class EditorBase : public nsIEditor,
// If we're not handling edit action, we don't need to handle
// "beforeinput" event.
case EditAction::eNotEditing:
// If we're being initialized, we may need to create a padding <br>
// element, but it shouldn't cause `beforeinput` event.
case EditAction::eInitializing:
// If raw level transaction API is used, the API user needs to handle
// both "beforeinput" event and "input" event if it's necessary.
case EditAction::eUnknown:

View File

@@ -292,9 +292,7 @@ nsresult HTMLEditor::Init(Document& aDoc, Element* aRoot,
NS_ENSURE_SUCCESS(rv, rv);
}
// XXX `eNotEditing` is a lie since InitEditorContentAndSelection() may
// insert padding `<br>`.
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
AutoEditActionDataSetter editActionData(*this, EditAction::eInitializing);
if (NS_WARN_IF(!editActionData.CanHandle())) {
return NS_ERROR_FAILURE;
}

View File

@@ -130,9 +130,7 @@ nsresult TextEditor::Init(Document& aDoc, Element* aRoot,
return rv;
}
// XXX `eNotEditing` is a lie since InitEditorContentAndSelection() may
// insert padding `<br>`.
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
AutoEditActionDataSetter editActionData(*this, EditAction::eInitializing);
if (NS_WARN_IF(!editActionData.CanHandle())) {
return NS_ERROR_FAILURE;
}

View File

@@ -0,0 +1,10 @@
<style>
.c { resize: both }
</style>
<script>
window.onload = () => {
a.className = "a"
document.execCommand("delete", false)
}
</script>
<input id="a" autofocus="autofocus" class="c">

View File

@@ -143,3 +143,4 @@ load 1655508.html
load 1655988.html
pref(dom.document.exec_command.nested_calls_allowed,true) load 1666556.html
asserts(1) load 1677566.html # assertion in constructor of TextFragmentData (initialized for non-editable content)
load 1701348.html