зеркало из https://github.com/mozilla/gecko-dev.git
Bug 515142 - Make HTML5 parser never clone nodes. WHATWG spec SVN rev 2947. rs=sicking.
This commit is contained in:
Родитель
30a5c8e6ab
Коммит
d2e28c3cf5
|
@ -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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче