Bug 1091425 - Use the correct document when creating nodes in the HTML5 parser. r=hsivonen
This commit is contained in:
@@ -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]
|
||||
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user