Bug 515142 - Make HTML5 parser never clone nodes. WHATWG spec SVN rev 2947. rs=sicking.

This commit is contained in:
Henri Sivonen 2009-09-21 10:00:10 +03:00
Родитель 30a5c8e6ab
Коммит d2e28c3cf5
14 изменённых файлов: 92 добавлений и 23 удалений

Просмотреть файл

@ -158,6 +158,12 @@ nsHtml5AttributeName::~nsHtml5AttributeName()
delete[] local;
}
nsHtml5AttributeName*
nsHtml5AttributeName::cloneAttributeName()
{
return this;
}
PRInt32
nsHtml5AttributeName::getUri(PRInt32 mode)
{

Просмотреть файл

@ -57,20 +57,23 @@ class nsHtml5Portability;
class nsHtml5AttributeName
{
private:
public:
static PRInt32* ALL_NO_NS;
private:
static PRInt32* XMLNS_NS;
static PRInt32* XML_NS;
static PRInt32* XLINK_NS;
public:
static nsIAtom** ALL_NO_PREFIX;
private:
static nsIAtom** XMLNS_PREFIX;
static nsIAtom** XLINK_PREFIX;
static nsIAtom** XML_PREFIX;
static nsIAtom** SVG_DIFFERENT(nsIAtom* name, nsIAtom* camel);
static nsIAtom** MATH_DIFFERENT(nsIAtom* name, nsIAtom* camel);
static nsIAtom** COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix);
static nsIAtom** SAME_LOCAL(nsIAtom* name);
public:
static nsIAtom** SAME_LOCAL(nsIAtom* name);
static nsHtml5AttributeName* nameByBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length);
private:
static PRInt32 bufToHash(PRUnichar* buf, PRInt32 len);
@ -84,6 +87,7 @@ class nsHtml5AttributeName
public:
virtual void release();
~nsHtml5AttributeName();
virtual nsHtml5AttributeName* cloneAttributeName();
PRInt32 getUri(PRInt32 mode);
nsIAtom* getLocal(PRInt32 mode);
nsIAtom* getPrefix(PRInt32 mode);

Просмотреть файл

@ -223,6 +223,17 @@ nsHtml5HtmlAttributes::adjustForSvg()
mode = NS_HTML5ATTRIBUTE_NAME_SVG;
}
nsHtml5HtmlAttributes*
nsHtml5HtmlAttributes::cloneAttributes()
{
nsHtml5HtmlAttributes* clone = new nsHtml5HtmlAttributes(0);
for (PRInt32 i = 0; i < length; i++) {
clone->addAttribute(names[i]->cloneAttributeName(), nsHtml5Portability::newStringFromString(values[i]));
}
return clone;
}
void
nsHtml5HtmlAttributes::initializeStatics()
{

Просмотреть файл

@ -83,6 +83,7 @@ class nsHtml5HtmlAttributes
PRBool contains(nsHtml5AttributeName* name);
void adjustForMath();
void adjustForSvg();
nsHtml5HtmlAttributes* cloneAttributes();
static void initializeStatics();
static void releaseStatics();
};

Просмотреть файл

@ -68,6 +68,13 @@ nsHtml5Portability::newStringFromLiteral(const char* literal)
return str;
}
nsString*
nsHtml5Portability::newStringFromString(nsString* string) {
nsString* newStr = new nsString();
newStr->Assign(*string);
return newStr;
}
jArray<PRUnichar,PRInt32>
nsHtml5Portability::newCharArrayFromLocal(nsIAtom* local)
{

Просмотреть файл

@ -62,6 +62,7 @@ class nsHtml5Portability
static nsString* newStringFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length);
static nsString* newEmptyString();
static nsString* newStringFromLiteral(const char* literal);
static nsString* newStringFromString(nsString* string);
static jArray<PRUnichar,PRInt32> newCharArrayFromLocal(nsIAtom* local);
static jArray<PRUnichar,PRInt32> newCharArrayFromString(nsString* string);
static void releaseString(nsString* str);

Просмотреть файл

@ -36,12 +36,23 @@
* ***** END LICENSE BLOCK ***** */
#include "nsHtml5ReleasableAttributeName.h"
#include "nsHtml5Portability.h"
nsHtml5ReleasableAttributeName::nsHtml5ReleasableAttributeName(PRInt32* uri, nsIAtom** local, nsIAtom** prefix)
: nsHtml5AttributeName(uri, local, prefix)
{
}
nsHtml5AttributeName*
nsHtml5ReleasableAttributeName::cloneAttributeName()
{
nsIAtom* l = getLocal(0);
nsHtml5Portability::retainLocal(l);
return new nsHtml5ReleasableAttributeName(nsHtml5AttributeName::ALL_NO_NS,
nsHtml5AttributeName::SAME_LOCAL(l),
nsHtml5AttributeName::ALL_NO_PREFIX);
}
void
nsHtml5ReleasableAttributeName::release()
{

Просмотреть файл

@ -44,6 +44,7 @@ class nsHtml5ReleasableAttributeName : public nsHtml5AttributeName
{
public:
nsHtml5ReleasableAttributeName(PRInt32* uri, nsIAtom** local, nsIAtom** prefix);
virtual nsHtml5AttributeName* cloneAttributeName();
virtual void release();
};

Просмотреть файл

@ -56,7 +56,7 @@
#include "nsHtml5StackNode.h"
nsHtml5StackNode::nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent* node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName)
nsHtml5StackNode::nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent* node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName, nsHtml5HtmlAttributes* attributes)
: group(group),
name(name),
popName(popName),
@ -65,6 +65,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsI
scoping(scoping),
special(special),
fosterParenting(fosterParenting),
attributes(attributes),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
@ -83,6 +84,26 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName,
scoping(elementName->scoping),
special(elementName->special),
fosterParenting(elementName->fosterParenting),
attributes(nsnull),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
nsHtml5Portability::retainLocal(name);
nsHtml5Portability::retainLocal(popName);
nsHtml5Portability::retainElement(node);
}
nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsHtml5HtmlAttributes* attributes)
: group(elementName->group),
name(elementName->name),
popName(elementName->name),
ns(ns),
node(node),
scoping(elementName->scoping),
special(elementName->special),
fosterParenting(elementName->fosterParenting),
attributes(attributes),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
@ -101,6 +122,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName,
scoping(elementName->scoping),
special(elementName->special),
fosterParenting(elementName->fosterParenting),
attributes(nsnull),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
@ -119,6 +141,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName,
scoping(scoping),
special(PR_FALSE),
fosterParenting(PR_FALSE),
attributes(nsnull),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
@ -134,6 +157,13 @@ nsHtml5StackNode::~nsHtml5StackNode()
nsHtml5Portability::releaseLocal(name);
nsHtml5Portability::releaseLocal(popName);
nsHtml5Portability::releaseElement(node);
delete attributes;
}
void
nsHtml5StackNode::dropAttributes()
{
attributes = nsnull;
}
void

Просмотреть файл

@ -68,14 +68,17 @@ class nsHtml5StackNode
PRBool scoping;
PRBool special;
PRBool fosterParenting;
nsHtml5HtmlAttributes* attributes;
private:
PRInt32 refcount;
public:
nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent* node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName);
nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent* node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName, nsHtml5HtmlAttributes* attributes);
nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node);
nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsHtml5HtmlAttributes* attributes);
nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsIAtom* popName);
nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsIAtom* popName, PRBool scoping);
~nsHtml5StackNode();
void dropAttributes();
void retain();
void release();
static void initializeStatics();

Просмотреть файл

@ -382,6 +382,7 @@ nsHtml5Tokenizer::attributeNameComplete()
void
nsHtml5Tokenizer::addAttributeWithoutValue()
{
if (!!attributeName) {
attributes->addAttribute(attributeName, nsHtml5Portability::newEmptyString());
}
@ -754,6 +755,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
case '&': {
clearLongStrBuf();
state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED;
reconsume = PR_TRUE;
goto stateloop;
}
@ -779,6 +781,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
default: {
clearLongStrBufAndAppendCurrentC(c);
state = NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED;
goto stateloop;
}
}

Просмотреть файл

@ -3058,8 +3058,9 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
}
nsIContent* clone = shallowClone(node->node);
nsHtml5StackNode* newNode = new nsHtml5StackNode(node->group, node->ns, node->name, clone, node->scoping, node->special, node->fosterParenting, node->popName);
nsIContent* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes());
nsHtml5StackNode* newNode = new nsHtml5StackNode(node->group, node->ns, node->name, clone, node->scoping, node->special, node->fosterParenting, node->popName, node->attributes);
node->dropAttributes();
stack[nodePos] = newNode;
newNode->retain();
listOfActiveFormattingElements[nodeListPos] = newNode;
@ -3079,8 +3080,9 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
detachFromParent(lastNode->node);
appendElement(lastNode->node, commonAncestor->node);
}
nsIContent* clone = shallowClone(formattingElt->node);
nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->group, formattingElt->ns, formattingElt->name, clone, formattingElt->scoping, formattingElt->special, formattingElt->fosterParenting, formattingElt->popName);
nsIContent* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes());
nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->group, formattingElt->ns, formattingElt->name, clone, formattingElt->scoping, formattingElt->special, formattingElt->fosterParenting, formattingElt->popName, formattingElt->attributes);
formattingElt->dropAttributes();
appendChildrenToNewParent(furthestBlock->node, clone);
appendElement(clone, furthestBlock->node);
removeFromListOfActiveFormattingElements(formattingEltListPos);
@ -3225,8 +3227,9 @@ nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
while (entryPos < listPtr) {
entryPos++;
nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
nsIContent* clone = shallowClone(entry->node);
nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->group, entry->ns, entry->name, clone, entry->scoping, entry->special, entry->fosterParenting, entry->popName);
nsIContent* clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes());
nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->group, entry->ns, entry->name, clone, entry->scoping, entry->special, entry->fosterParenting, entry->popName, entry->attributes);
entry->dropAttributes();
nsHtml5StackNode* currentNode = stack[currentPtr];
if (currentNode->fosterParenting) {
insertIntoFosterParent(clone);
@ -3358,7 +3361,7 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(PRInt32
} else {
appendElement(elt, current->node);
}
nsHtml5StackNode* node = new nsHtml5StackNode(ns, elementName, elt);
nsHtml5StackNode* node = new nsHtml5StackNode(ns, elementName, elt, attributes->cloneAttributes());
push(node);
append(node);
node->retain();

Просмотреть файл

@ -76,7 +76,6 @@ class nsHtml5TreeBuilder
protected:
nsHtml5Tokenizer* tokenizer;
private:
nsHtml5TreeBuilder* documentModeHandler;
PRBool scriptingEnabled;
PRBool needToDropLF;
PRBool fragment;
@ -184,7 +183,6 @@ class nsHtml5TreeBuilder
nsIContent* createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
void detachFromParent(nsIContent* element);
PRBool hasChildren(nsIContent* element);
nsIContent* shallowClone(nsIContent* element);
void appendElement(nsIContent* child, nsIContent* newParent);
void appendChildrenToNewParent(nsIContent* oldParent, nsIContent* newParent);
void insertFosterParentedChild(nsIContent* child, nsIContent* table, nsIContent* stackParent);

Просмотреть файл

@ -141,16 +141,6 @@ nsHtml5TreeBuilder::detachFromParent(nsIContent* aElement)
treeOp->Init(eTreeOpDetach, aElement);
}
nsIContent*
nsHtml5TreeBuilder::shallowClone(nsIContent* aElement)
{
nsINode* clone;
aElement->Clone(aElement->NodeInfo(), &clone);
// XXX nsresult
NS_ASSERTION(clone->IsNodeOfType(nsINode::eCONTENT), "Cloning an element didn't yield a content node.");
return static_cast<nsIContent*>(clone);
}
void
nsHtml5TreeBuilder::appendElement(nsIContent* aChild, nsIContent* aParent)
{