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:
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
10
editor/libeditor/crashtests/1701348.html
Normal file
10
editor/libeditor/crashtests/1701348.html
Normal 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">
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user