Bug 256180 parser part - Insert elements as siblings instead of children at the Blink-defined magic depth for compatibility. r=smaug
MozReview-Commit-ID: K8fgv3rgklt
This commit is contained in:
@@ -444,11 +444,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
|
||||
private T headPointer;
|
||||
|
||||
/**
|
||||
* Used to work around Gecko limitations. Not used in Java.
|
||||
*/
|
||||
private T deepTreeSurrogateParent;
|
||||
|
||||
protected @Auto char[] charBuffer;
|
||||
|
||||
protected int charBufferLen = 0;
|
||||
@@ -615,7 +610,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
listPtr = -1;
|
||||
formPointer = null;
|
||||
headPointer = null;
|
||||
deepTreeSurrogateParent = null;
|
||||
// [NOCPP[
|
||||
html4 = false;
|
||||
idLocations.clear();
|
||||
@@ -1642,7 +1636,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
public final void endTokenization() throws SAXException {
|
||||
formPointer = null;
|
||||
headPointer = null;
|
||||
deepTreeSurrogateParent = null;
|
||||
templateModeStack = null;
|
||||
if (stack != null) {
|
||||
while (currentPtr > -1) {
|
||||
@@ -4718,7 +4711,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
removeFromListOfActiveFormattingElements(formattingEltListPos);
|
||||
return true;
|
||||
}
|
||||
// commonAncestor is used for running the algorithm and
|
||||
// insertionCommonAncestor is used for the actual insertions to
|
||||
// keep them depth-limited.
|
||||
StackNode<T> commonAncestor = stack[formattingEltStackPos - 1]; // weak ref
|
||||
T insertionCommonAncestor = nodeFromStackWithBlinkCompat(formattingEltStackPos - 1); // weak ref
|
||||
StackNode<T> furthestBlock = stack[furthestBlockPos]; // weak ref
|
||||
// detachFromParent(furthestBlock.node); XXX AAA CHANGE
|
||||
int bookmark = formattingEltListPos;
|
||||
@@ -4766,7 +4763,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), commonAncestor.node
|
||||
node.name, node.attributes.cloneAttributes(null), insertionCommonAncestor
|
||||
// CPPONLY: , htmlCreator(node.getHtmlCreator())
|
||||
);
|
||||
StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
|
||||
@@ -4785,16 +4782,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
node = newNode;
|
||||
// } XXX AAA CHANGE
|
||||
detachFromParent(lastNode.node);
|
||||
appendElement(lastNode.node, node.node);
|
||||
appendElement(lastNode.node, nodeFromStackWithBlinkCompat(nodePos));
|
||||
lastNode = node;
|
||||
}
|
||||
// If we insert into a foster parent, for simplicity, we insert
|
||||
// accoding to the spec without Blink's depth limit.
|
||||
if (commonAncestor.isFosterParenting()) {
|
||||
fatal();
|
||||
detachFromParent(lastNode.node);
|
||||
insertIntoFosterParent(lastNode.node);
|
||||
} else {
|
||||
detachFromParent(lastNode.node);
|
||||
appendElement(lastNode.node, commonAncestor.node);
|
||||
appendElement(lastNode.node, insertionCommonAncestor);
|
||||
}
|
||||
T clone = createElement("http://www.w3.org/1999/xhtml",
|
||||
formattingElt.name,
|
||||
@@ -4980,20 +4979,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
while (entryPos < listPtr) {
|
||||
entryPos++;
|
||||
StackNode<T> entry = listOfActiveFormattingElements[entryPos];
|
||||
StackNode<T> currentNode = stack[currentPtr];
|
||||
StackNode<T> current = stack[currentPtr];
|
||||
|
||||
T clone;
|
||||
if (currentNode.isFosterParenting()) {
|
||||
if (current.isFosterParenting()) {
|
||||
clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
|
||||
entry.attributes.cloneAttributes(null)
|
||||
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
|
||||
entry.attributes.cloneAttributes(null), currentNode.node
|
||||
entry.attributes.cloneAttributes(null), currentNode
|
||||
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
|
||||
);
|
||||
appendElement(clone, currentNode.node);
|
||||
appendElement(clone, currentNode);
|
||||
}
|
||||
|
||||
StackNode<T> entryClone = createStackNode(entry.getFlags(),
|
||||
@@ -5336,7 +5336,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// [NOCPP[
|
||||
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
|
||||
// ]NOCPP]
|
||||
T currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode
|
||||
/*
|
||||
* head uses NS_NewHTMLSharedElement creator
|
||||
@@ -5378,10 +5378,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
|
||||
if (!isTemplateContents()) {
|
||||
@@ -5415,10 +5416,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt, clone
|
||||
// [NOCPP[
|
||||
@@ -5437,7 +5439,7 @@ 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 currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
@@ -5471,10 +5473,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt, popName
|
||||
// [NOCPP[
|
||||
@@ -5509,10 +5512,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt, popName,
|
||||
markAsHtmlIntegrationPoint
|
||||
@@ -5562,10 +5566,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, popName, elt
|
||||
// [NOCPP[
|
||||
@@ -5592,11 +5597,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(),
|
||||
attributes, formOwner, current.node
|
||||
attributes, formOwner, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt
|
||||
// [NOCPP[
|
||||
@@ -5623,11 +5629,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", name,
|
||||
attributes, formOwner, current.node
|
||||
attributes, formOwner, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
|
||||
elementPopped("http://www.w3.org/1999/xhtml", name, elt);
|
||||
@@ -5651,10 +5658,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
|
||||
elementPopped("http://www.w3.org/1999/xhtml", popName, elt);
|
||||
@@ -5678,10 +5686,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/2000/svg", popName, elt);
|
||||
elementPopped("http://www.w3.org/2000/svg", popName, elt);
|
||||
@@ -5705,10 +5714,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
|
||||
elementPopped("http://www.w3.org/1998/Math/MathML", popName, elt);
|
||||
@@ -5719,7 +5729,7 @@ 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 currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", "input", attributes,
|
||||
form == null || fragment || isTemplateContents() ? null : form, currentNode
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLInputElement)
|
||||
@@ -5733,7 +5743,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// [NOCPP[
|
||||
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
|
||||
// ]NOCPP]
|
||||
T currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", "form",
|
||||
attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
@@ -6145,7 +6155,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
System.arraycopy(templateModeStack, 0, templateModeStackCopy, 0,
|
||||
templateModeStackCopy.length);
|
||||
return new StateSnapshot<T>(stackCopy, listCopy, templateModeStackCopy, formPointer,
|
||||
headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk,
|
||||
headPointer, mode, originalMode, framesetOk,
|
||||
needToDropLF, quirks);
|
||||
}
|
||||
|
||||
@@ -6162,7 +6172,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
|| templateModeStackLen != templateModePtr + 1
|
||||
|| formPointer != snapshot.getFormPointer()
|
||||
|| headPointer != snapshot.getHeadPointer()
|
||||
|| deepTreeSurrogateParent != snapshot.getDeepTreeSurrogateParent()
|
||||
|| mode != snapshot.getMode()
|
||||
|| originalMode != snapshot.getOriginalMode()
|
||||
|| framesetOk != snapshot.isFramesetOk()
|
||||
@@ -6268,7 +6277,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
System.arraycopy(templateModeStackCopy, 0, templateModeStack, 0, templateModeStackLen);
|
||||
formPointer = snapshot.getFormPointer();
|
||||
headPointer = snapshot.getHeadPointer();
|
||||
deepTreeSurrogateParent = snapshot.getDeepTreeSurrogateParent();
|
||||
mode = snapshot.getMode();
|
||||
originalMode = snapshot.getOriginalMode();
|
||||
framesetOk = snapshot.isFramesetOk();
|
||||
@@ -6285,6 +6293,33 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>stack[stackPos].node</code> if <code>stackPos</code> is
|
||||
* smaller than Blink's magic limit or the node at Blink's magic limit
|
||||
* otherwise.
|
||||
*
|
||||
* In order to get Blink-compatible handling of excessive deeply-nested
|
||||
* markup, this method must be used to obtain the node that is used as the
|
||||
* parent node of an insertion.
|
||||
*
|
||||
* Blink's magic number is 512, but our counting is off by one compared to
|
||||
* Blink's way of counting, so in order to get the same
|
||||
* externally-observable outcome, we use 511 as our magic number.
|
||||
*
|
||||
* @param stackPos the stack position to attempt to read
|
||||
* @return node at the position capped to Blink's magic number
|
||||
* @throws SAXException
|
||||
*/
|
||||
private T nodeFromStackWithBlinkCompat(int stackPos) throws SAXException {
|
||||
// Magic number if off by one relative to Blink's magic number, but the
|
||||
// outcome is the same, because the counting is different by one.
|
||||
if (stackPos > 511) {
|
||||
errDeepTree();
|
||||
return stack[511].node;
|
||||
}
|
||||
return stack[stackPos].node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
|
||||
*/
|
||||
@@ -6301,15 +6336,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
return headPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the deepTreeSurrogateParent.
|
||||
*
|
||||
* @return the deepTreeSurrogateParent
|
||||
*/
|
||||
public T getDeepTreeSurrogateParent() {
|
||||
return deepTreeSurrogateParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
|
||||
*/
|
||||
@@ -6397,6 +6423,16 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
return templateModePtr + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complains about an over-deep tree. Theoretically this should just be
|
||||
* a warning, but in practice authors should take this as an error.
|
||||
*
|
||||
* @throws SAXException
|
||||
*/
|
||||
private void errDeepTree() throws SAXException {
|
||||
err("The document tree is more than 513 elements deep, which causes Firefox and Chrome flatten the tree.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a stray start tag.
|
||||
* @param name the name of the stray tag
|
||||
|
||||
Reference in New Issue
Block a user