Bug 1489437 - Part 1: Make HTML parser distinguish network, document.write and fragments in append operation; r=smaug,hsivonen

For custom element reaction invocation in the parser, we need a way to distinguish the tree appending operation is from fragments or not,
since we don't want to execute reactions until innerHTML finishes running.
(See spec changes https://github.com/whatwg/html/issues/4025)

We don't need to do anything for opAppendText and opAppendCommand since the text and command won't have any chance to
be a custom element.

Differential Revision: https://phabricator.services.mozilla.com/D10226
This commit is contained in:
Edgar Chen 2021-01-06 09:29:41 +00:00
parent 76ab9e2294
commit 3a7902f2c4
4 changed files with 23 additions and 5 deletions

View File

@ -651,7 +651,7 @@ void nsHtml5Highlighter::Push(
MOZ_ASSERT(mStack.Length() >= 1, "Pushing without root.");
nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode(),
aCreator); // Don't inline below!
opAppend operation(elt, CurrentNode());
opAppend operation(elt, CurrentNode(), mozilla::dom::FROM_PARSER_NETWORK);
mOpQueue.AppendElement()->Init(mozilla::AsVariant(operation));
mStack.AppendElement(elt);
}

View File

@ -608,7 +608,7 @@ void nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild,
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::Append(
static_cast<nsIContent*>(aChild), static_cast<nsIContent*>(aParent),
mBuilder);
mozilla::dom::FROM_PARSER_FRAGMENT, mBuilder);
if (NS_FAILED(rv)) {
MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
@ -620,7 +620,11 @@ void nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild,
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
return;
}
opAppend operation(aChild, aParent);
opAppend operation(aChild, aParent,
(!!mSpeculativeLoadStage)
? mozilla::dom::FROM_PARSER_NETWORK
: mozilla::dom::FROM_PARSER_DOCUMENT_WRITE);
treeOp->Init(mozilla::AsVariant(operation));
}

View File

@ -256,6 +256,12 @@ nsresult nsHtml5TreeOperation::Append(nsIContent* aNode, nsIContent* aParent,
return rv;
}
nsresult nsHtml5TreeOperation::Append(nsIContent* aNode, nsIContent* aParent,
mozilla::dom::FromParser aFromParser,
nsHtml5DocumentBuilder* aBuilder) {
return Append(aNode, aParent, aBuilder);
}
nsresult nsHtml5TreeOperation::AppendToDocument(
nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder) {
MOZ_ASSERT(aBuilder);
@ -762,7 +768,8 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
bool* mStreamEnded;
nsresult operator()(const opAppend& aOperation) {
return Append(*(aOperation.mChild), *(aOperation.mParent), mBuilder);
return Append(*(aOperation.mChild), *(aOperation.mParent),
aOperation.mFromNetwork, mBuilder);
}
nsresult operator()(const opDetach& aOperation) {

View File

@ -36,8 +36,11 @@ struct opDetach {
struct opAppend {
nsIContent** mChild;
nsIContent** mParent;
mozilla::dom::FromParser mFromNetwork;
explicit opAppend(nsIContentHandle* aChild, nsIContentHandle* aParent) {
explicit opAppend(nsIContentHandle* aChild, nsIContentHandle* aParent,
mozilla::dom::FromParser aFromNetwork)
: mFromNetwork(aFromNetwork) {
mChild = static_cast<nsIContent**>(aChild);
mParent = static_cast<nsIContent**>(aParent);
};
@ -517,6 +520,10 @@ class nsHtml5TreeOperation final {
static nsresult Append(nsIContent* aNode, nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder);
static nsresult Append(nsIContent* aNode, nsIContent* aParent,
mozilla::dom::FromParser aFromParser,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendToDocument(nsIContent* aNode,
nsHtml5DocumentBuilder* aBuilder);