Bug 1091425 - Use the correct document when creating nodes in the HTML5 parser. r=hsivonen

This commit is contained in:
William Chen
2014-11-09 22:50:18 -08:00
parent 2be147d4eb
commit fdf3148d35
10 changed files with 344 additions and 122 deletions

View File

@@ -22,6 +22,7 @@ support-files =
[test_event_stopping.html]
[test_template.html]
[test_template_xhtml.html]
[test_template_custom_elements.html]
[test_shadowroot.html]
[test_shadowroot_inert_element.html]
[test_shadowroot_host.html]

View File

@@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1091425
-->
<head>
<title>Test for custom elements in template</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<template>
<x-foo></x-foo>
</template>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1091425">Bug 1091425</a>
<script>
var p = {};
p.createdCallback = function() {
ok(false, "Created callback should not be called for custom elements in templates.");
};
document.registerElement("x-foo", { prototype: p });
ok(true, "Created callback should not be called for custom elements in templates.");
</script>
<template>
<x-foo></x-foo>
</template>
</body>
</html>

View File

@@ -719,7 +719,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: if (tokenizer.isViewingXmlSource()) {
// CPPONLY: T elt = createElement("http://www.w3.org/2000/svg",
// CPPONLY: "svg",
// CPPONLY: tokenizer.emptyAttributes());
// CPPONLY: tokenizer.emptyAttributes(), null);
// CPPONLY: StackNode<T> node = new StackNode<T>(ElementName.SVG,
// CPPONLY: "svg",
// CPPONLY: elt);
@@ -4806,7 +4806,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
assert node == listOfActiveFormattingElements[nodeListPos];
assert node == stack[nodePos];
T clone = createElement("http://www.w3.org/1999/xhtml",
node.name, node.attributes.cloneAttributes(null));
node.name, node.attributes.cloneAttributes(null), commonAncestor.node);
StackNode<T> newNode = new StackNode<T>(node.getFlags(), node.ns,
node.name, clone, node.popName, node.attributes
// [NOCPP[
@@ -4835,7 +4835,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
T clone = createElement("http://www.w3.org/1999/xhtml",
formattingElt.name,
formattingElt.attributes.cloneAttributes(null));
formattingElt.attributes.cloneAttributes(null), furthestBlock.node);
StackNode<T> formattingClone = new StackNode<T>(
formattingElt.getFlags(), formattingElt.ns,
formattingElt.name, clone, formattingElt.popName,
@@ -5014,8 +5014,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
while (entryPos < listPtr) {
entryPos++;
StackNode<T> entry = listOfActiveFormattingElements[entryPos];
T clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
StackNode<T> currentNode = stack[currentPtr];
T clone;
if (currentNode.isFosterParenting()) {
clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes(null));
} else {
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes(null), currentNode.node);
appendElement(clone, currentNode.node);
}
StackNode<T> entryClone = new StackNode<T>(entry.getFlags(),
entry.ns, entry.name, clone, entry.popName,
entry.attributes
@@ -5023,13 +5033,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
, entry.getLocator()
// ]NOCPP]
);
entry.dropAttributes(); // transfer ownership to entryClone
StackNode<T> currentNode = stack[currentPtr];
if (currentNode.isFosterParenting()) {
insertIntoFosterParent(clone);
} else {
appendElement(clone, currentNode.node);
}
push(entryClone);
// stack takes ownership of the local variable
listOfActiveFormattingElements[entryPos] = entryClone;
@@ -5052,6 +5058,26 @@ public abstract class TreeBuilder<T> implements TokenHandler,
insertFosterParentedChild(child, node.node, stack[tablePos - 1].node);
}
private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes) throws SAXException {
return createAndInsertFosterParentedElement(ns, name, attributes, null);
}
private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T form) throws SAXException {
int tablePos = findLastOrRoot(TreeBuilder.TABLE);
int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
if (templatePos >= tablePos) {
T child = createElement(ns, name, attributes, form, stack[templatePos].node);
appendElement(child, stack[templatePos].node);
return child;
}
StackNode<T> node = stack[tablePos];
return createAndInsertFosterParentedElement(ns, name, attributes, form, node.node, stack[tablePos - 1].node);
}
private boolean isInStack(StackNode<T> node) {
for (int i = currentPtr; i >= 0; i--) {
if (stack[i] == node) {
@@ -5206,9 +5232,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
T elt = createElement("http://www.w3.org/1999/xhtml", "head",
attributes);
appendElement(elt, stack[currentPtr].node);
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode);
appendElement(elt, currentNode);
headPointer = elt;
StackNode<T> node = new StackNode<T>(ElementName.HEAD,
elt
@@ -5234,20 +5260,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
T elt = createElement("http://www.w3.org/1999/xhtml", "form",
attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", "form", attributes);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node);
appendElement(elt, current.node);
}
if (!isTemplateContents()) {
formPointer = elt;
}
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
} else {
appendElement(elt, current.node);
}
StackNode<T> node = new StackNode<T>(ElementName.FORM,
elt
// [NOCPP[
@@ -5267,12 +5294,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
HtmlAttributes clone = attributes.cloneAttributes(null);
// Attributes must not be read after calling createElement, because
// createElement may delete attributes in C++.
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.name, attributes);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes, current.node);
appendElement(elt, current.node);
}
StackNode<T> node = new StackNode<T>(elementName, elt, clone
@@ -5292,8 +5320,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// This method can't be called for custom elements
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes);
appendElement(elt, stack[currentPtr].node);
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes, currentNode);
appendElement(elt, currentNode);
if (ElementName.TEMPLATE == elementName) {
elt = getDocumentFragmentForTemplate(elt);
}
@@ -5315,12 +5344,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
popName = checkPopName(popName);
}
// ]NOCPP]
T elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node);
appendElement(elt, current.node);
}
StackNode<T> node = new StackNode<T>(elementName, elt, popName
@@ -5348,13 +5378,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
// Attributes must not be read after calling createElement(), since
// createElement may delete the object in C++.
T elt = createElement("http://www.w3.org/1998/Math/MathML", popName,
attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
} else {
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node);
appendElement(elt, current.node);
}
StackNode<T> node = new StackNode<T>(elementName, elt, popName,
@@ -5397,12 +5427,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
popName = checkPopName(popName);
}
// ]NOCPP]
T elt = createElement("http://www.w3.org/2000/svg", popName, attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes);
} else {
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node);
appendElement(elt, current.node);
}
StackNode<T> node = new StackNode<T>(elementName, popName, elt
@@ -5420,13 +5451,16 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// Can't be called for custom elements
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.name, attributes,
form == null || fragment || isTemplateContents() ? null : form);
T elt;
T formOwner = form == null || fragment || isTemplateContents() ? null : form;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.name,
attributes, formOwner);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", elementName.name,
attributes, formOwner, current.node);
appendElement(elt, current.node);
}
StackNode<T> node = new StackNode<T>(elementName, elt
@@ -5443,13 +5477,16 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// Can't be called for custom elements
T elt = createElement("http://www.w3.org/1999/xhtml", name, attributes,
form == null || fragment || isTemplateContents() ? null : form);
T elt;
T formOwner = form == null || fragment || isTemplateContents() ? null : form;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", name,
attributes, formOwner);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", name,
attributes, formOwner, current.node);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
@@ -5466,12 +5503,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
popName = checkPopName(popName);
}
// ]NOCPP]
T elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
@@ -5488,12 +5526,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
popName = checkPopName(popName);
}
// ]NOCPP]
T elt = createElement("http://www.w3.org/2000/svg", popName, attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes);
} else {
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/2000/svg", popName, elt);
@@ -5510,12 +5549,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
popName = checkPopName(popName);
}
// ]NOCPP]
T elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
T elt;
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
} else {
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
@@ -5528,10 +5568,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// Can't be called for custom elements
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", name, attributes,
form == null || fragment || isTemplateContents() ? null : form);
StackNode<T> current = stack[currentPtr];
appendElement(elt, current.node);
form == null || fragment || isTemplateContents() ? null : form, currentNode);
appendElement(elt, currentNode);
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
elementPopped("http://www.w3.org/1999/xhtml", name, elt);
}
@@ -5540,12 +5580,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", "form",
attributes);
attributes, currentNode);
formPointer = elt;
// ownership transferred to form pointer
StackNode<T> current = stack[currentPtr];
appendElement(elt, current.node);
appendElement(elt, currentNode);
elementPushed("http://www.w3.org/1999/xhtml", "form", elt);
elementPopped("http://www.w3.org/1999/xhtml", "form", elt);
}
@@ -5578,11 +5618,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
protected abstract T createElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes) throws SAXException;
HtmlAttributes attributes, T intendedParent) throws SAXException;
protected T createElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T form) throws SAXException {
return createElement("http://www.w3.org/1999/xhtml", name, attributes);
HtmlAttributes attributes, T form, T intendedParent) throws SAXException {
return createElement("http://www.w3.org/1999/xhtml", name, attributes, intendedParent);
}
protected abstract T createHtmlElementSetAsRoot(HtmlAttributes attributes)
@@ -5601,6 +5641,20 @@ public abstract class TreeBuilder<T> implements TokenHandler,
protected abstract void insertFosterParentedChild(T child, T table,
T stackParent) throws SAXException;
// We don't generate CPP code for this method because it is not used in generated CPP
// code. Instead, the form owner version of this method is called with a null form owner.
// [NOCPP[
protected abstract T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T table, T stackParent) throws SAXException;
// ]NOCPP]
protected T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T form, T table, T stackParent) throws SAXException {
return createAndInsertFosterParentedElement(ns, name, attributes, table, stackParent);
};
protected abstract void insertFosterParentedCharacters(
@NoLength char[] buf, int start, int length, T table, T stackParent)
throws SAXException;

View File

@@ -79,7 +79,7 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
nsIContent** root = CreateElement(nsHtml5Atoms::html, nullptr);
nsIContent** root = CreateElement(nsHtml5Atoms::html, nullptr, nullptr);
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
mStack.AppendElement(root);
@@ -655,7 +655,8 @@ nsHtml5Highlighter::AllocateContentHandle()
nsIContent**
nsHtml5Highlighter::CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent)
{
NS_PRECONDITION(aName, "Got null name.");
nsIContent** content = AllocateContentHandle();
@@ -663,6 +664,7 @@ nsHtml5Highlighter::CreateElement(nsIAtom* aName,
aName,
aAttributes,
content,
aIntendedParent,
true);
return content;
}
@@ -679,7 +681,7 @@ nsHtml5Highlighter::Push(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
{
NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
nsIContent** elt = CreateElement(aName, aAttributes); // Don't inline below!
nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode()); // Don't inline below!
mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
mStack.AppendElement(elt);
}

View File

@@ -226,10 +226,12 @@ class nsHtml5Highlighter
* @param aName the name of the element
* @param aAttributes the attribute holder (ownership will be taken) or
* nullptr for no attributes
* @param aIntendedParent the intended parent node for the created element
* @return the handle for the element that will be created
*/
nsIContent** CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes);
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent);
/**
* Gets the handle for the current node. May be called only after the

View File

@@ -145,7 +145,7 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
} else {
mode = NS_HTML5TREE_BUILDER_INITIAL;
if (tokenizer->isViewingXmlSource()) {
nsIContentHandle* elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes());
nsIContentHandle* elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes(), nullptr);
nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_SVG, nsHtml5Atoms::svg, elt);
currentPtr++;
stack[currentPtr] = node;
@@ -3646,7 +3646,7 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
}
MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]);
MOZ_ASSERT(node == stack[nodePos]);
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr));
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr), commonAncestor->node);
nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, clone, node->popName, node->attributes);
node->dropAttributes();
stack[nodePos] = newNode;
@@ -3667,7 +3667,7 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
detachFromParent(lastNode->node);
appendElement(lastNode->node, commonAncestor->node);
}
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr));
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr), furthestBlock->node);
nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->getFlags(), formattingElt->ns, formattingElt->name, clone, formattingElt->popName, formattingElt->attributes);
formattingElt->dropAttributes();
appendChildrenToNewParent(furthestBlock->node, clone);
@@ -3828,15 +3828,16 @@ nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
while (entryPos < listPtr) {
entryPos++;
nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->getFlags(), entry->ns, entry->name, clone, entry->popName, entry->attributes);
entry->dropAttributes();
nsHtml5StackNode* currentNode = stack[currentPtr];
nsIContentHandle* clone;
if (currentNode->isFosterParenting()) {
insertIntoFosterParent(clone);
clone = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
} else {
clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr), currentNode->node);
appendElement(clone, currentNode->node);
}
nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->getFlags(), entry->ns, entry->name, clone, entry->popName, entry->attributes);
entry->dropAttributes();
push(entryClone);
listOfActiveFormattingElements[entryPos] = entryClone;
entry->release();
@@ -3857,6 +3858,26 @@ nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle* child)
insertFosterParentedChild(child, node->node, stack[tablePos - 1]->node);
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes)
{
return createAndInsertFosterParentedElement(ns, name, attributes, nullptr);
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
{
int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
if (templatePos >= tablePos) {
nsIContentHandle* child = createElement(ns, name, attributes, form, stack[templatePos]->node);
appendElement(child, stack[templatePos]->node);
return child;
}
nsHtml5StackNode* node = stack[tablePos];
return createAndInsertFosterParentedElement(ns, name, attributes, form, node->node, stack[tablePos - 1]->node);
}
bool
nsHtml5TreeBuilder::isInStack(nsHtml5StackNode* node)
{
@@ -3921,8 +3942,9 @@ nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush()
void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes);
appendElement(elt, stack[currentPtr]->node);
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes, currentNode);
appendElement(elt, currentNode);
headPointer = elt;
nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, elt);
push(node);
@@ -3943,17 +3965,18 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement()
void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
if (!isTemplateContents()) {
formPointer = elt;
}
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
} else {
elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes, current->node);
appendElement(elt, current->node);
}
if (!isTemplateContents()) {
formPointer = elt;
}
nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_FORM, elt);
push(node);
}
@@ -3962,12 +3985,13 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsHtml5HtmlAttributes* clone = attributes->cloneAttributes(nullptr);
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, elementName->name, attributes);
} else {
elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, current->node);
appendElement(elt, current->node);
}
nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, clone);
@@ -3979,8 +4003,9 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5
void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
appendElement(elt, stack[currentPtr]->node);
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, currentNode);
appendElement(elt, currentNode);
if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
elt = getDocumentFragmentForTemplate(elt);
}
@@ -3992,12 +4017,13 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIAtom* popName = elementName->name;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, popName, attributes);
} else {
elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node);
appendElement(elt, current->node);
}
nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName);
@@ -4012,12 +4038,13 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5Elem
if (nsHtml5ElementName::ELT_ANNOTATION_XML == elementName && annotationXmlEncodingPermitsHtml(attributes)) {
markAsHtmlIntegrationPoint = true;
}
nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_MathML, popName, attributes);
} else {
elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node);
appendElement(elt, current->node);
}
nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName, markAsHtmlIntegrationPoint);
@@ -4038,12 +4065,13 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIAtom* popName = elementName->camelCaseName;
nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_SVG, popName, attributes);
} else {
elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node);
appendElement(elt, current->node);
}
nsHtml5StackNode* node = new nsHtml5StackNode(elementName, popName, elt);
@@ -4053,12 +4081,14 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5Element
void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
nsIContentHandle* elt;
nsIContentHandle* formOwner = !form || fragment || isTemplateContents() ? nullptr : form;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, elementName->name, attributes, formOwner);
} else {
elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, formOwner, current->node);
appendElement(elt, current->node);
}
nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
@@ -4068,12 +4098,14 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementNam
void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
nsIContentHandle* elt;
nsIContentHandle* formOwner = !form || fragment || isTemplateContents() ? nullptr : form;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, name, attributes, formOwner);
} else {
elt = createElement(kNameSpaceID_XHTML, name, attributes, formOwner, current->node);
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_XHTML, name, elt);
@@ -4084,12 +4116,13 @@ void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIAtom* popName = elementName->name;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, popName, attributes);
} else {
elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node);
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_XHTML, popName, elt);
@@ -4100,12 +4133,13 @@ void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIAtom* popName = elementName->camelCaseName;
nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_SVG, popName, attributes);
} else {
elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node);
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_SVG, popName, elt);
@@ -4116,12 +4150,13 @@ void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIAtom* popName = elementName->name;
nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes);
nsIContentHandle* elt;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
insertIntoFosterParent(elt);
elt = createAndInsertFosterParentedElement(kNameSpaceID_MathML, popName, attributes);
} else {
elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node);
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_MathML, popName, elt);
@@ -4131,9 +4166,9 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName
void
nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
nsHtml5StackNode* current = stack[currentPtr];
appendElement(elt, current->node);
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form, currentNode);
appendElement(elt, currentNode);
elementPushed(kNameSpaceID_XHTML, name, elt);
elementPopped(kNameSpaceID_XHTML, name, elt);
}
@@ -4141,10 +4176,10 @@ nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttribu
void
nsHtml5TreeBuilder::appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes, currentNode);
formPointer = elt;
nsHtml5StackNode* current = stack[currentPtr];
appendElement(elt, current->node);
appendElement(elt, currentNode);
elementPushed(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
elementPopped(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
}
@@ -4155,7 +4190,7 @@ nsHtml5TreeBuilder::requestSuspension()
tokenizer->requestSuspension();
}
bool
;bool
nsHtml5TreeBuilder::isInForeign()
{
return currentPtr >= 0 && stack[currentPtr]->ns != kNameSpaceID_XHTML;

View File

@@ -177,6 +177,8 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void pushHeadPointerOntoStack();
void reconstructTheActiveFormattingElements();
void insertIntoFosterParent(nsIContentHandle* child);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
bool isInStack(nsHtml5StackNode* node);
void popTemplateMode();
void pop();
@@ -204,15 +206,16 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
protected:
void accumulateCharacters(const char16_t* buf, int32_t start, int32_t length);
void requestSuspension();
nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* intendedParent);
nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form, nsIContentHandle* intendedParent);
nsIContentHandle* createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
void detachFromParent(nsIContentHandle* element);
bool hasChildren(nsIContentHandle* element);
void appendElement(nsIContentHandle* child, nsIContentHandle* newParent);
void appendChildrenToNewParent(nsIContentHandle* oldParent, nsIContentHandle* newParent);
void insertFosterParentedChild(nsIContentHandle* child, nsIContentHandle* table, nsIContentHandle* stackParent);
void insertFosterParentedCharacters(char16_t* buf, int32_t start, int32_t length, nsIContentHandle* table, nsIContentHandle* stackParent);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form, nsIContentHandle* table, nsIContentHandle* stackParent);
;void insertFosterParentedCharacters(char16_t* buf, int32_t start, int32_t length, nsIContentHandle* table, nsIContentHandle* stackParent);
void appendCharacters(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
void appendIsindexPrompt(nsIContentHandle* parent);
void appendComment(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);

View File

@@ -67,7 +67,9 @@ nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
}
nsIContentHandle*
nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes)
nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aIntendedParent)
{
NS_PRECONDITION(aAttributes, "Got null attributes.");
NS_PRECONDITION(aName, "Got null name.");
@@ -78,11 +80,22 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5Htm
if (mBuilder) {
nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
nsIContent* intendedParent = aIntendedParent ?
static_cast<nsIContent*>(aIntendedParent) : nullptr;
// intendedParent == nullptr is a special case where the
// intended parent is the document.
nsNodeInfoManager* nodeInfoManager = intendedParent ?
intendedParent->OwnerDoc()->NodeInfoManager() :
mBuilder->GetNodeInfoManager();
nsIContent* elem =
nsHtml5TreeOperation::CreateElement(aNamespace,
name,
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
nodeInfoManager,
mBuilder);
if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
@@ -98,6 +111,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5Htm
aName,
aAttributes,
content,
aIntendedParent,
!!mSpeculativeLoadStage);
// mSpeculativeLoadStage is non-null only in the off-the-main-thread
// tree builder, which handles the network stream
@@ -257,9 +271,13 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5Htm
}
nsIContentHandle*
nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContentHandle* aFormElement)
nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aFormElement,
nsIContentHandle* aIntendedParent)
{
nsIContentHandle* content = createElement(aNamespace, aName, aAttributes);
nsIContentHandle* content = createElement(aNamespace, aName, aAttributes,
aIntendedParent);
if (aFormElement) {
if (mBuilder) {
nsHtml5TreeOperation::SetFormElement(static_cast<nsIContent*>(content),
@@ -276,7 +294,10 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5Htm
nsIContentHandle*
nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
{
nsIContentHandle* content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes);
nsIContentHandle* content = createElement(kNameSpaceID_XHTML,
nsHtml5Atoms::html,
aAttributes,
nullptr);
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendToDocument(static_cast<nsIContent*>(content),
mBuilder);
@@ -291,6 +312,49 @@ nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttribute
return content;
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t aNamespace, nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aFormElement,
nsIContentHandle* aTable,
nsIContentHandle* aStackParent)
{
NS_PRECONDITION(aTable, "Null table");
NS_PRECONDITION(aStackParent, "Null stack parent");
if (mBuilder) {
// Get the foster parent to use as the intended parent when creating
// the child element.
nsIContent* fosterParent = nsHtml5TreeOperation::GetFosterParent(
static_cast<nsIContent*>(aTable),
static_cast<nsIContent*>(aStackParent));
nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
aFormElement, fosterParent);
insertFosterParentedChild(child, aTable, aStackParent);
return child;
}
// Tree op to get the foster parent that we use as the intended parent
// when creating the child element.
nsHtml5TreeOperation* fosterParentTreeOp = mOpQueue.AppendElement();
NS_ASSERTION(fosterParentTreeOp, "Tree op allocation failed.");
nsIContentHandle* fosterParentHandle = AllocateContentHandle();
fosterParentTreeOp->Init(eTreeOpGetFosterParent, aTable,
aStackParent, fosterParentHandle);
// Create the element with the correct intended parent.
nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
aFormElement, fosterParentHandle);
// Insert the child into the foster parent.
insertFosterParentedChild(child, aTable, aStackParent);
return child;
}
void
nsHtml5TreeBuilder::detachFromParent(nsIContentHandle* aElement)
{

View File

@@ -158,7 +158,8 @@ nsHtml5TreeOperation::AppendText(const char16_t* aBuffer,
aBuilder);
}
nsRefPtr<nsTextNode> text = new nsTextNode(aBuilder->GetNodeInfoManager());
nsNodeInfoManager* nodeInfoManager = aParent->OwnerDoc()->NodeInfoManager();
nsRefPtr<nsTextNode> text = new nsTextNode(nodeInfoManager);
NS_ASSERTION(text, "Infallible malloc failed?");
rv = text->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
@@ -335,6 +336,7 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder)
{
bool isKeygen = (aName == nsHtml5Atoms::keygen && aNs == kNameSpaceID_XHTML);
@@ -343,7 +345,7 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
}
nsCOMPtr<dom::Element> newElement;
nsRefPtr<dom::NodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->
nsRefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->
GetNodeInfo(aName, nullptr, aNs, nsIDOMNode::ELEMENT_NODE);
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
NS_NewElement(getter_AddRefs(newElement),
@@ -383,7 +385,7 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
false);
nsRefPtr<dom::NodeInfo> optionNodeInfo =
aBuilder->GetNodeInfoManager()->GetNodeInfo(nsHtml5Atoms::option,
aNodeInfoManager->GetNodeInfo(nsHtml5Atoms::option,
nullptr,
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
@@ -394,8 +396,7 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
NS_NewElement(getter_AddRefs(optionElt),
ni.forget(),
aFromParser);
nsRefPtr<nsTextNode> optionText =
new nsTextNode(aBuilder->GetNodeInfoManager());
nsRefPtr<nsTextNode> optionText = new nsTextNode(aNodeInfoManager);
(void) optionText->SetText(theContent[i], false);
optionElt->AppendChildTo(optionText, false);
newContent->AppendChildTo(optionElt, false);
@@ -517,8 +518,8 @@ nsHtml5TreeOperation::FosterParentText(nsIContent* aStackParent,
aBuilder);
}
nsRefPtr<nsTextNode> text =
new nsTextNode(aBuilder->GetNodeInfoManager());
nsNodeInfoManager* nodeInfoManager = aStackParent->OwnerDoc()->NodeInfoManager();
nsRefPtr<nsTextNode> text = new nsTextNode(nodeInfoManager);
NS_ASSERTION(text, "Infallible malloc failed?");
rv = text->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
@@ -538,8 +539,8 @@ nsHtml5TreeOperation::AppendComment(nsIContent* aParent,
int32_t aLength,
nsHtml5DocumentBuilder* aBuilder)
{
nsRefPtr<dom::Comment> comment =
new dom::Comment(aBuilder->GetNodeInfoManager());
nsNodeInfoManager* nodeInfoManager = aParent->OwnerDoc()->NodeInfoManager();
nsRefPtr<dom::Comment> comment = new dom::Comment(nodeInfoManager);
NS_ASSERTION(comment, "Infallible malloc failed?");
nsresult rv = comment->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
@@ -592,6 +593,13 @@ nsHtml5TreeOperation::GetDocumentFragmentForTemplate(nsIContent* aNode)
return frag;
}
nsIContent*
nsHtml5TreeOperation::GetFosterParent(nsIContent* aTable, nsIContent* aStackParent)
{
nsIContent* tableParent = aTable->GetParent();
return IsElementOrTemplateContent(tableParent) ? tableParent : aStackParent;
}
void
nsHtml5TreeOperation::PreventScriptExecution(nsIContent* aNode)
{
@@ -672,6 +680,13 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
int32_t ns = mFour.integer;
nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
nsHtml5HtmlAttributes* attributes = mThree.attributes;
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
// intendedParent == nullptr is a special case where the
// intended parent is the document.
nsNodeInfoManager* nodeInfoManager = intendedParent ?
intendedParent->OwnerDoc()->NodeInfoManager() :
aBuilder->GetNodeInfoManager();
*target = CreateElement(ns,
name,
@@ -679,6 +694,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
mOpCode == eTreeOpCreateElementNetwork ?
dom::FROM_PARSER_NETWORK :
dom::FROM_PARSER_DOCUMENT_WRITE,
nodeInfoManager,
aBuilder);
return NS_OK;
}
@@ -729,6 +745,13 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
*mTwo.node = GetDocumentFragmentForTemplate(node);
return NS_OK;
}
case eTreeOpGetFosterParent: {
nsIContent* table = *(mOne.node);
nsIContent* stackParent = *(mTwo.node);
nsIContent* fosterParent = GetFosterParent(table, stackParent);
*mThree.node = fosterParent;
return NS_OK;
}
case eTreeOpMarkAsBroken: {
return mOne.result;
}

View File

@@ -35,6 +35,7 @@ enum eHtml5TreeOperation {
eTreeOpAppendCommentToDocument,
eTreeOpAppendDoctypeToDocument,
eTreeOpGetDocumentFragmentForTemplate,
eTreeOpGetFosterParent,
// Gecko-specific on-pop ops
eTreeOpMarkAsBroken,
eTreeOpRunScript,
@@ -149,6 +150,7 @@ class nsHtml5TreeOperation {
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder);
static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
@@ -178,6 +180,8 @@ class nsHtml5TreeOperation {
static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
static nsIContent* GetFosterParent(nsIContent* aTable, nsIContent* aStackParent);
static void PreventScriptExecution(nsIContent* aNode);
static void DoneAddingChildren(nsIContent* aNode);
@@ -288,6 +292,7 @@ class nsHtml5TreeOperation {
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aTarget,
nsIContentHandle* aIntendedParent,
bool aFromNetwork)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
@@ -298,6 +303,7 @@ class nsHtml5TreeOperation {
eTreeOpCreateElementNetwork :
eTreeOpCreateElementNotNetwork;
mFour.integer = aNamespace;
mFive.node = static_cast<nsIContent**>(aIntendedParent);
mOne.node = static_cast<nsIContent**>(aTarget);
mTwo.atom = aName;
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
@@ -499,7 +505,7 @@ class nsHtml5TreeOperation {
nsAHtml5TreeBuilderState* state;
int32_t integer;
nsresult result;
} mOne, mTwo, mThree, mFour;
} mOne, mTwo, mThree, mFour, mFive;
};
#endif // nsHtml5TreeOperation_h