Bug 1644903 - Make nsINode::InsertBefore() callers call ErrorResult::WouldReportJSException() when inserting node may be in another document r=m_kato

`nsINode::InsertBefore()` removes inserting node from a document if it's in
a document including different document.  In this case, `UpdateReflectorGlobal`
in BindingUtils.cpp calls `ErrorResult::MightThrowJSException()`, but editor
never throws exception with `ErrorResult`.  Therefore, editor needs to call
`ErrorResult::WouldReportJSException()` explicitly if the inserting node may
be in another document.

As far as I checked, it can happen only when undoing or redoing a transaction.
Therefore, this patch touches only transaction classes.

Depends on D81683

Differential Revision: https://phabricator.services.mozilla.com/D81684
This commit is contained in:
Masayuki Nakano 2020-07-01 13:13:13 +00:00
parent 66545f5913
commit 2c83c27c9c
7 changed files with 30 additions and 0 deletions

View File

@ -145,6 +145,9 @@ void CreateElementTransaction::InsertNewNode(ErrorResult& aError) {
container->InsertBefore(newElement, child, aError);
NS_WARNING_ASSERTION(!aError.Failed(),
"nsINode::InsertBefore() failed, but ignored");
// InsertBefore() may call MightThrowJSException() even if there is no
// error. We don't need the flag here.
aError.WouldReportJSException();
return;
}

View File

@ -93,6 +93,9 @@ DeleteNodeTransaction::UndoTransaction() {
// XXX Perhaps, we should check `refContent` is a child of `parentNode`,
// and if it's not, we should stop undoing or something.
parentNode->InsertBefore(contentToDelete, refContent, error);
// InsertBefore() may call MightThrowJSException() even if there is no error.
// We don't need the flag here.
error.WouldReportJSException();
if (error.Failed()) {
NS_WARNING("nsINode::InsertBefore() failed");
return error.StealNSResult();

View File

@ -106,6 +106,9 @@ NS_IMETHODIMP InsertNodeTransaction::DoTransaction() {
ErrorResult error;
container->InsertBefore(contentToInsert, refChild, error);
// InsertBefore() may call MightThrowJSException() even if there is no
// error. We don't need the flag here.
error.WouldReportJSException();
if (error.Failed()) {
NS_WARNING("nsINode::InsertBefore() failed");
return error.StealNSResult();

View File

@ -132,6 +132,9 @@ NS_IMETHODIMP JoinNodeTransaction::UndoTransaction() {
// Second, re-insert the left node into the tree
parentNode->InsertBefore(leftContent, rightContent, error);
// InsertBefore() may call MightThrowJSException() even if there is no
// error. We don't need the flag here.
error.WouldReportJSException();
NS_WARNING_ASSERTION(!error.Failed(), "nsINode::InsertBefore() failed");
return error.StealNSResult();
}

View File

@ -188,6 +188,9 @@ NS_IMETHODIMP SplitNodeTransaction::RedoTransaction() {
// Second, re-insert the left node into the tree
containerParentNode->InsertBefore(newLeftContent,
startOfRightContent.GetContainer(), error);
// InsertBefore() may call MightThrowJSException() even if there is no
// error. We don't need the flag here.
error.WouldReportJSException();
NS_WARNING_ASSERTION(!error.Failed(), "nsINode::InsertBefore() failed");
return error.StealNSResult();
}

View File

@ -0,0 +1,14 @@
<script>
window.onload = () => {
document.execCommand("undo", false)
}
function go() {
var a = document.getElementById("a")
document.execCommand("delete", false)
b.contentDocument.adoptNode(a)
}
</script>
<p contenteditable="true">
<link id="a" item="">
<details open="" ontoggle="go()">
<iframe id="b"></iframe>

View File

@ -123,6 +123,7 @@ load 1618906.html
load 1623913.html
load 1624007.html
load 1624011.html
load 1644903.html
load 1645983-1.html
load 1645983-2.html
load 1648564.html