Bug 515338 - Make HTML5 parser internals not hold nsIContent or regular dynamic atoms. r=bnewman.

--HG--
extra : rebase_source : 955eb137d96a4ea1461417ada9809404a1218dd1
This commit is contained in:
Henri Sivonen 2009-09-21 14:43:43 +03:00
Родитель c50c97c5bf
Коммит a1cc303397
31 изменённых файлов: 713 добавлений и 447 удалений

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

@ -29,6 +29,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -96,17 +97,17 @@ nsHtml5AttributeName::SAME_LOCAL(nsIAtom* name)
} }
nsHtml5AttributeName* nsHtml5AttributeName*
nsHtml5AttributeName::nameByBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length) nsHtml5AttributeName::nameByBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner)
{ {
PRInt32 hash = nsHtml5AttributeName::bufToHash(buf, length); PRInt32 hash = nsHtml5AttributeName::bufToHash(buf, length);
PRInt32 index = nsHtml5AttributeName::ATTRIBUTE_HASHES.binarySearch(hash); PRInt32 index = nsHtml5AttributeName::ATTRIBUTE_HASHES.binarySearch(hash);
if (index < 0) { if (index < 0) {
return nsHtml5AttributeName::createAttributeName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length)); return nsHtml5AttributeName::createAttributeName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
} else { } else {
nsHtml5AttributeName* attributeName = nsHtml5AttributeName::ATTRIBUTE_NAMES[index]; nsHtml5AttributeName* attributeName = nsHtml5AttributeName::ATTRIBUTE_NAMES[index];
nsIAtom* name = attributeName->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML); nsIAtom* name = attributeName->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML);
if (!nsHtml5Portability::localEqualsBuffer(name, buf, offset, length)) { if (!nsHtml5Portability::localEqualsBuffer(name, buf, offset, length)) {
return nsHtml5AttributeName::createAttributeName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length)); return nsHtml5AttributeName::createAttributeName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
} }
return attributeName; return attributeName;
} }

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -74,7 +75,7 @@ class nsHtml5AttributeName
static nsIAtom** COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix); static nsIAtom** COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix);
public: public:
static nsIAtom** SAME_LOCAL(nsIAtom* name); static nsIAtom** SAME_LOCAL(nsIAtom* name);
static nsHtml5AttributeName* nameByBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length); static nsHtml5AttributeName* nameByBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner);
private: private:
static PRInt32 bufToHash(PRUnichar* buf, PRInt32 len); static PRInt32 bufToHash(PRUnichar* buf, PRInt32 len);
PRInt32* uri; PRInt32* uri;

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

@ -29,6 +29,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -56,17 +57,17 @@
#include "nsHtml5ReleasableElementName.h" #include "nsHtml5ReleasableElementName.h"
nsHtml5ElementName* nsHtml5ElementName*
nsHtml5ElementName::elementNameByBuffer(jArray<PRUnichar,PRInt32> buf, PRInt32 offset, PRInt32 length) nsHtml5ElementName::elementNameByBuffer(jArray<PRUnichar,PRInt32> buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner)
{ {
PRInt32 hash = nsHtml5ElementName::bufToHash(buf, length); PRInt32 hash = nsHtml5ElementName::bufToHash(buf, length);
PRInt32 index = nsHtml5ElementName::ELEMENT_HASHES.binarySearch(hash); PRInt32 index = nsHtml5ElementName::ELEMENT_HASHES.binarySearch(hash);
if (index < 0) { if (index < 0) {
return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length)); return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
} else { } else {
nsHtml5ElementName* elementName = nsHtml5ElementName::ELEMENT_NAMES[index]; nsHtml5ElementName* elementName = nsHtml5ElementName::ELEMENT_NAMES[index];
nsIAtom* name = elementName->name; nsIAtom* name = elementName->name;
if (!nsHtml5Portability::localEqualsBuffer(name, buf, offset, length)) { if (!nsHtml5Portability::localEqualsBuffer(name, buf, offset, length)) {
return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length)); return new nsHtml5ReleasableElementName(nsHtml5Portability::newLocalNameFromBuffer(buf, offset, length, interner));
} }
return elementName; return elementName;
} }

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -65,7 +66,7 @@ class nsHtml5ElementName
PRBool special; PRBool special;
PRBool scoping; PRBool scoping;
PRBool fosterParenting; PRBool fosterParenting;
static nsHtml5ElementName* elementNameByBuffer(jArray<PRUnichar,PRInt32> buf, PRInt32 offset, PRInt32 length); static nsHtml5ElementName* elementNameByBuffer(jArray<PRUnichar,PRInt32> buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner);
private: private:
static PRInt32 bufToHash(jArray<PRUnichar,PRInt32> buf, PRInt32 len); static PRInt32 bufToHash(jArray<PRUnichar,PRInt32> buf, PRInt32 len);
nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, PRInt32 group, PRBool special, PRBool scoping, PRBool fosterParenting); nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, PRInt32 group, PRBool special, PRBool scoping, PRBool fosterParenting);

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"

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

@ -31,6 +31,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"

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

@ -31,6 +31,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"

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

@ -59,6 +59,7 @@
#include "nsHtml5UTF16Buffer.h" #include "nsHtml5UTF16Buffer.h"
#include "nsHtml5TreeBuilder.h" #include "nsHtml5TreeBuilder.h"
#include "nsHtml5Parser.h" #include "nsHtml5Parser.h"
#include "nsHtml5AtomTable.h"
//-------------- Begin ParseContinue Event Definition ------------------------ //-------------- Begin ParseContinue Event Definition ------------------------
/* /*
@ -96,13 +97,11 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5Parser) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mExecutor, nsIContentSink) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mExecutor, nsIContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mStreamParser, nsIStreamListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mStreamParser, nsIStreamListener)
tmp->mTreeBuilder->DoTraverse(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5Parser) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExecutor) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExecutor)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mStreamParser) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mStreamParser)
tmp->mTreeBuilder->DoUnlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsHtml5Parser::nsHtml5Parser() nsHtml5Parser::nsHtml5Parser()
@ -111,8 +110,11 @@ nsHtml5Parser::nsHtml5Parser()
, mExecutor(new nsHtml5TreeOpExecutor()) , mExecutor(new nsHtml5TreeOpExecutor())
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor)) , mTreeBuilder(new nsHtml5TreeBuilder(mExecutor))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder)) , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
, mAtomTable(new nsHtml5AtomTable())
{ {
mExecutor->SetTreeBuilder(mTreeBuilder); mExecutor->SetTreeBuilder(mTreeBuilder);
mAtomTable->Init(); // we aren't checking for OOM anyway...
mTokenizer->setInterner(mAtomTable);
// There's a zeroing operator new for everything else // There's a zeroing operator new for everything else
} }
@ -455,7 +457,10 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
nsIURI* uri = doc->GetDocumentURI(); nsIURI* uri = doc->GetDocumentURI();
NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
Initialize(doc, uri, nsnull, nsnull); nsCOMPtr<nsISupports> container = doc->GetContainer();
NS_ENSURE_TRUE(container, NS_ERROR_NOT_AVAILABLE);
Initialize(doc, uri, container, nsnull);
// Initialize() doesn't deal with base URI // Initialize() doesn't deal with base URI
mExecutor->SetBaseUriFromDocument(); mExecutor->SetBaseUriFromDocument();
@ -463,7 +468,8 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
mExecutor->SetParser(this); mExecutor->SetParser(this);
mExecutor->SetNodeInfoManager(target->GetOwnerDoc()->NodeInfoManager()); mExecutor->SetNodeInfoManager(target->GetOwnerDoc()->NodeInfoManager());
mTreeBuilder->setFragmentContext(aContextLocalName, aContextNamespace, target, aQuirks); nsIContent* weakTarget = target;
mTreeBuilder->setFragmentContext(aContextLocalName, aContextNamespace, &weakTarget, aQuirks);
mFragmentMode = PR_TRUE; mFragmentMode = PR_TRUE;
NS_PRECONDITION(mExecutor->GetLifeCycle() == NOT_STARTED, "Tried to start parse without initializing the parser properly."); NS_PRECONDITION(mExecutor->GetLifeCycle() == NOT_STARTED, "Tried to start parse without initializing the parser properly.");
@ -489,6 +495,7 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
mExecutor->Flush(); mExecutor->Flush();
mTokenizer->end(); mTokenizer->end();
mExecutor->DropParserAndPerfHint(); mExecutor->DropParserAndPerfHint();
mAtomTable->Clear();
return NS_OK; return NS_OK;
} }
@ -518,6 +525,7 @@ nsHtml5Parser::Reset()
mStreamParser = nsnull; mStreamParser = nsnull;
mRootContextKey = nsnull; mRootContextKey = nsnull;
mContinueEvent = nsnull; // weak ref mContinueEvent = nsnull; // weak ref
mAtomTable->Clear(); // should be already cleared in the fragment case anyway
// Portable parser objects // Portable parser objects
while (mFirstBuffer->next) { while (mFirstBuffer->next) {
nsHtml5UTF16Buffer* oldBuf = mFirstBuffer; nsHtml5UTF16Buffer* oldBuf = mFirstBuffer;

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

@ -60,6 +60,7 @@
#include "nsHtml5UTF16Buffer.h" #include "nsHtml5UTF16Buffer.h"
#include "nsHtml5TreeOpExecutor.h" #include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5StreamParser.h" #include "nsHtml5StreamParser.h"
#include "nsHtml5AtomTable.h"
class nsHtml5Parser : public nsIParser { class nsHtml5Parser : public nsIParser {
public: public:
@ -355,5 +356,10 @@ class nsHtml5Parser : public nsIParser {
*/ */
nsRefPtr<nsHtml5StreamParser> mStreamParser; nsRefPtr<nsHtml5StreamParser> mStreamParser;
/**
* The scoped atom service
*/
const nsAutoPtr<nsHtml5AtomTable> mAtomTable;
}; };
#endif #endif

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

@ -42,10 +42,11 @@
#include "nsHtml5Portability.h" #include "nsHtml5Portability.h"
nsIAtom* nsIAtom*
nsHtml5Portability::newLocalNameFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length) nsHtml5Portability::newLocalNameFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner)
{ {
NS_ASSERTION(!offset, "The offset should always be zero here."); NS_ASSERTION(!offset, "The offset should always be zero here.");
return NS_NewAtom(nsDependentSubstring(buf, buf + length)); NS_ASSERTION(interner, "Didn't get an atom service.");
return interner->GetAtom(nsDependentSubstring(buf, buf + length));
} }
nsString* nsString*
@ -101,28 +102,28 @@ nsHtml5Portability::releaseString(nsString* str)
delete str; delete str;
} }
// XXX useless code
void void
nsHtml5Portability::retainLocal(nsIAtom* local) nsHtml5Portability::retainLocal(nsIAtom* local)
{ {
NS_IF_ADDREF(local);
} }
// XXX useless code
void void
nsHtml5Portability::releaseLocal(nsIAtom* local) nsHtml5Portability::releaseLocal(nsIAtom* local)
{ {
NS_IF_RELEASE(local);
} }
// XXX Useless code
void void
nsHtml5Portability::retainElement(nsIContent* element) nsHtml5Portability::retainElement(nsIContent** element)
{ {
NS_IF_ADDREF(element);
} }
// XXX Useless code
void void
nsHtml5Portability::releaseElement(nsIContent* element) nsHtml5Portability::releaseElement(nsIContent** element)
{ {
NS_IF_RELEASE(element);
} }
PRBool PRBool

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -58,7 +59,7 @@ class nsHtml5StateSnapshot;
class nsHtml5Portability class nsHtml5Portability
{ {
public: public:
static nsIAtom* newLocalNameFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length); static nsIAtom* newLocalNameFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length, nsHtml5AtomTable* interner);
static nsString* newStringFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length); static nsString* newStringFromBuffer(PRUnichar* buf, PRInt32 offset, PRInt32 length);
static nsString* newEmptyString(); static nsString* newEmptyString();
static nsString* newStringFromLiteral(const char* literal); static nsString* newStringFromLiteral(const char* literal);
@ -68,8 +69,8 @@ class nsHtml5Portability
static void releaseString(nsString* str); static void releaseString(nsString* str);
static void retainLocal(nsIAtom* local); static void retainLocal(nsIAtom* local);
static void releaseLocal(nsIAtom* local); static void releaseLocal(nsIAtom* local);
static void retainElement(nsIContent* elt); static void retainElement(nsIContent** elt);
static void releaseElement(nsIContent* elt); static void releaseElement(nsIContent** elt);
static PRBool localEqualsBuffer(nsIAtom* local, PRUnichar* buf, PRInt32 offset, PRInt32 length); static PRBool localEqualsBuffer(nsIAtom* local, PRUnichar* buf, PRInt32 offset, PRInt32 length);
static PRBool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string); static PRBool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
static PRBool lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string); static PRBool lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -56,7 +57,7 @@
#include "nsHtml5StackNode.h" #include "nsHtml5StackNode.h"
nsHtml5StackNode::nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent* node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName, nsHtml5HtmlAttributes* attributes) nsHtml5StackNode::nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent** node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName, nsHtml5HtmlAttributes* attributes)
: group(group), : group(group),
name(name), name(name),
popName(popName), popName(popName),
@ -75,7 +76,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsI
} }
nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node) nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent** node)
: group(elementName->group), : group(elementName->group),
name(elementName->name), name(elementName->name),
popName(elementName->name), popName(elementName->name),
@ -94,7 +95,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName,
} }
nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsHtml5HtmlAttributes* attributes) nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent** node, nsHtml5HtmlAttributes* attributes)
: group(elementName->group), : group(elementName->group),
name(elementName->name), name(elementName->name),
popName(elementName->name), popName(elementName->name),
@ -113,7 +114,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName,
} }
nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsIAtom* popName) nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName)
: group(elementName->group), : group(elementName->group),
name(elementName->name), name(elementName->name),
popName(popName), popName(popName),
@ -132,7 +133,7 @@ nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName,
} }
nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsIAtom* popName, PRBool scoping) nsHtml5StackNode::nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName, PRBool scoping)
: group(elementName->group), : group(elementName->group),
name(elementName->name), name(elementName->name),
popName(popName), popName(popName),
@ -192,5 +193,3 @@ nsHtml5StackNode::releaseStatics()
} }
#include "nsHtml5StackNodeCppSupplement.h"

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

@ -31,6 +31,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -64,7 +65,7 @@ class nsHtml5StackNode
nsIAtom* name; nsIAtom* name;
nsIAtom* popName; nsIAtom* popName;
PRInt32 ns; PRInt32 ns;
nsIContent* node; nsIContent** node;
PRBool scoping; PRBool scoping;
PRBool special; PRBool special;
PRBool fosterParenting; PRBool fosterParenting;
@ -72,19 +73,17 @@ class nsHtml5StackNode
private: private:
PRInt32 refcount; PRInt32 refcount;
public: public:
nsHtml5StackNode(PRInt32 group, PRInt32 ns, nsIAtom* name, nsIContent* node, PRBool scoping, PRBool special, PRBool fosterParenting, nsIAtom* popName, nsHtml5HtmlAttributes* attributes); 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);
nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsHtml5HtmlAttributes* attributes); 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);
nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent* node, nsIAtom* popName, PRBool scoping); nsHtml5StackNode(PRInt32 ns, nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName, PRBool scoping);
~nsHtml5StackNode(); ~nsHtml5StackNode();
void dropAttributes(); void dropAttributes();
void retain(); void retain();
void release(); void release();
static void initializeStatics(); static void initializeStatics();
static void releaseStatics(); static void releaseStatics();
#include "nsHtml5StackNodeHSupplement.h"
}; };
#ifdef nsHtml5StackNode_cpp__ #ifdef nsHtml5StackNode_cpp__

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

@ -1,56 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML Parser C++ Translator code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5StackNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsHtml5StackNode)
NS_IF_RELEASE(tmp->node);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMETHODIMP
nsHtml5StackNode::NS_CYCLE_COLLECTION_INNERCLASS::Traverse
(void *p, nsCycleCollectionTraversalCallback &cb)
{
nsHtml5StackNode *tmp = static_cast<nsHtml5StackNode*>(p);
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsHtml5StackNode, tmp->refcount)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(node);
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsHtml5StackNode, retain)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsHtml5StackNode, release)

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

@ -1,38 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML Parser C++ Translator code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsHtml5StackNode)

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

@ -29,6 +29,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -55,7 +56,7 @@
#include "nsHtml5StateSnapshot.h" #include "nsHtml5StateSnapshot.h"
nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent* formPointer) nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent** formPointer)
: stack(stack), : stack(stack),
listOfActiveFormattingElements(listOfActiveFormattingElements), listOfActiveFormattingElements(listOfActiveFormattingElements),
formPointer(formPointer) formPointer(formPointer)

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -58,10 +59,10 @@ class nsHtml5Portability;
class nsHtml5StateSnapshot class nsHtml5StateSnapshot
{ {
public: public:
nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent* formPointer); nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,PRInt32> stack, jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements, nsIContent** formPointer);
jArray<nsHtml5StackNode*,PRInt32> stack; jArray<nsHtml5StackNode*,PRInt32> stack;
jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements; jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements;
nsIContent* formPointer; nsIContent** formPointer;
~nsHtml5StateSnapshot(); ~nsHtml5StateSnapshot();
static void initializeStatics(); static void initializeStatics();
static void releaseStatics(); static void releaseStatics();

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

@ -581,7 +581,10 @@ nsHtml5StreamParser::ParseUntilSuspend()
return; // no more data for now but expecting more return; // no more data for now but expecting more
case STREAM_ENDING: case STREAM_ENDING:
mDone = PR_TRUE; mDone = PR_TRUE;
{
nsRefPtr<nsHtml5StreamParser> kungFuDeathGrip(this);
mExecutor->DidBuildModel(PR_FALSE); mExecutor->DidBuildModel(PR_FALSE);
}
return; // no more data and not expecting more return; // no more data and not expecting more
default: default:
NS_NOTREACHED("It should be impossible to reach this."); NS_NOTREACHED("It should be impossible to reach this.");

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

@ -32,6 +32,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -72,11 +73,20 @@ nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler)
: tokenHandler(tokenHandler), : tokenHandler(tokenHandler),
encodingDeclarationHandler(nsnull), encodingDeclarationHandler(nsnull),
bmpChar(jArray<PRUnichar,PRInt32>(1)), bmpChar(jArray<PRUnichar,PRInt32>(1)),
astralChar(jArray<PRUnichar,PRInt32>(2)) astralChar(jArray<PRUnichar,PRInt32>(2)),
attributes(nsnull),
tagName(nsnull),
attributeName(nsnull)
{ {
MOZ_COUNT_CTOR(nsHtml5Tokenizer); MOZ_COUNT_CTOR(nsHtml5Tokenizer);
} }
void
nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner)
{
this->interner = interner;
}
void void
nsHtml5Tokenizer::initLocation(nsString* newPublicId, nsString* newSystemId) nsHtml5Tokenizer::initLocation(nsString* newPublicId, nsString* newSystemId)
{ {
@ -100,7 +110,7 @@ nsHtml5Tokenizer::setContentModelFlag(PRInt32 contentModelFlag, nsIAtom* content
return; return;
} }
jArray<PRUnichar,PRInt32> asArray = nsHtml5Portability::newCharArrayFromLocal(contentModelElement); jArray<PRUnichar,PRInt32> asArray = nsHtml5Portability::newCharArrayFromLocal(contentModelElement);
this->contentModelElement = nsHtml5ElementName::elementNameByBuffer(asArray, 0, asArray.length); this->contentModelElement = nsHtml5ElementName::elementNameByBuffer(asArray, 0, asArray.length, interner);
asArray.release(); asArray.release();
contentModelElementToArray(); contentModelElementToArray();
} }
@ -229,7 +239,7 @@ nsHtml5Tokenizer::strBufToString()
void void
nsHtml5Tokenizer::strBufToDoctypeName() nsHtml5Tokenizer::strBufToDoctypeName()
{ {
doctypeName = nsHtml5Portability::newLocalNameFromBuffer(strBuf, 0, strBufLen); doctypeName = nsHtml5Portability::newLocalNameFromBuffer(strBuf, 0, strBufLen, interner);
} }
void void
@ -342,13 +352,13 @@ nsHtml5Tokenizer::flushChars(PRUnichar* buf, PRInt32 pos)
void void
nsHtml5Tokenizer::resetAttributes() nsHtml5Tokenizer::resetAttributes()
{ {
attributes->clear(0); attributes = nsnull;
} }
void void
nsHtml5Tokenizer::strBufToElementNameString() nsHtml5Tokenizer::strBufToElementNameString()
{ {
tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, 0, strBufLen); tagName = nsHtml5ElementName::elementNameByBuffer(strBuf, 0, strBufLen, interner);
} }
PRInt32 PRInt32
@ -364,6 +374,8 @@ nsHtml5Tokenizer::emitCurrentTagToken(PRBool selfClosing, PRInt32 pos)
} else { } else {
tokenHandler->startTag(tagName, attrs, selfClosing); tokenHandler->startTag(tagName, attrs, selfClosing);
} }
tagName->release();
tagName = nsnull;
resetAttributes(); resetAttributes();
return stateSave; return stateSave;
} }
@ -371,7 +383,10 @@ nsHtml5Tokenizer::emitCurrentTagToken(PRBool selfClosing, PRInt32 pos)
void void
nsHtml5Tokenizer::attributeNameComplete() nsHtml5Tokenizer::attributeNameComplete()
{ {
attributeName = nsHtml5AttributeName::nameByBuffer(strBuf, 0, strBufLen); attributeName = nsHtml5AttributeName::nameByBuffer(strBuf, 0, strBufLen, interner);
if (!attributes) {
attributes = new nsHtml5HtmlAttributes(0);
}
if (attributes->contains(attributeName)) { if (attributes->contains(attributeName)) {
attributeName->release(); attributeName->release();
@ -426,7 +441,18 @@ nsHtml5Tokenizer::start()
value = 0; value = 0;
seenDigits = PR_FALSE; seenDigits = PR_FALSE;
shouldSuspend = PR_FALSE; shouldSuspend = PR_FALSE;
attributes = new nsHtml5HtmlAttributes(0); if (!!tagName) {
tagName->release();
tagName = nsnull;
}
if (!!attributeName) {
attributeName->release();
attributeName = nsnull;
}
if (!!attributes) {
delete attributes;
attributes = nsnull;
}
} }
PRBool PRBool
@ -3282,8 +3308,14 @@ nsHtml5Tokenizer::end()
systemIdentifier = nsnull; systemIdentifier = nsnull;
publicIdentifier = nsnull; publicIdentifier = nsnull;
doctypeName = nsnull; doctypeName = nsnull;
if (!!tagName) {
tagName->release();
tagName = nsnull; tagName = nsnull;
}
if (!!attributeName) {
attributeName->release();
attributeName = nsnull; attributeName = nsnull;
}
tokenHandler->endTokenization(); tokenHandler->endTokenization();
if (!!attributes) { if (!!attributes) {
attributes->clear(0); attributes->clear(0);

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

@ -33,6 +33,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
@ -134,8 +135,10 @@ class nsHtml5Tokenizer
PRBool confident; PRBool confident;
private: private:
PRInt32 line; PRInt32 line;
nsHtml5AtomTable* interner;
public: public:
nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler); nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler);
void setInterner(nsHtml5AtomTable* interner);
void initLocation(nsString* newPublicId, nsString* newSystemId); void initLocation(nsString* newPublicId, nsString* newSystemId);
~nsHtml5Tokenizer(); ~nsHtml5Tokenizer();
void setContentModelFlag(PRInt32 contentModelFlag, nsIAtom* contentModelElement); void setContentModelFlag(PRInt32 contentModelFlag, nsIAtom* contentModelElement);

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

@ -82,7 +82,7 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
charBufferLen = 0; charBufferLen = 0;
charBuffer = jArray<PRUnichar,PRInt32>(1024); charBuffer = jArray<PRUnichar,PRInt32>(1024);
if (fragment) { if (fragment) {
nsIContent* elt; nsIContent** elt;
if (!!contextNode) { if (!!contextNode) {
elt = contextNode; elt = contextNode;
nsHtml5Portability::retainElement(elt); nsHtml5Portability::retainElement(elt);
@ -618,6 +618,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} else { } else {
appendToCurrentNodeAndPushElementMayFosterCamelCase(currNs, elementName, attributes); appendToCurrentNodeAndPushElementMayFosterCamelCase(currNs, elementName, attributes);
} }
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} else { } else {
attributes->adjustForMath(); attributes->adjustForMath();
@ -627,6 +628,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} else { } else {
appendToCurrentNodeAndPushElementMayFosterNoScoping(currNs, elementName, attributes); appendToCurrentNodeAndPushElementMayFosterNoScoping(currNs, elementName, attributes);
} }
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
} }
@ -641,6 +643,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot()); clearStackBackTo(findLastInTableScopeOrRootTbodyTheadTfoot());
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_ROW; mode = NS_HTML5TREE_BUILDER_IN_ROW;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_TD_OR_TH: { case NS_HTML5TREE_BUILDER_TD_OR_TH: {
@ -676,6 +679,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_CELL; mode = NS_HTML5TREE_BUILDER_IN_CELL;
insertMarker(); insertMarker();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_CAPTION: case NS_HTML5TREE_BUILDER_CAPTION:
@ -706,12 +710,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
insertMarker(); insertMarker();
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_CAPTION; mode = NS_HTML5TREE_BUILDER_IN_CAPTION;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_COLGROUP: { case NS_HTML5TREE_BUILDER_COLGROUP: {
clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP; mode = NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_COL: { case NS_HTML5TREE_BUILDER_COL: {
@ -724,6 +730,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE)); clearStackBackTo(findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE));
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY; mode = NS_HTML5TREE_BUILDER_IN_TABLE_BODY;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_TR: case NS_HTML5TREE_BUILDER_TR:
@ -756,6 +763,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_INPUT: { case NS_HTML5TREE_BUILDER_INPUT: {
@ -764,6 +772,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
appendVoidElementToCurrent(kNameSpaceID_XHTML, name, attributes, formPointer); appendVoidElementToCurrent(kNameSpaceID_XHTML, name, attributes, formPointer);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -839,6 +848,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
} else { } else {
@ -877,6 +887,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_BASE: case NS_HTML5TREE_BUILDER_BASE:
@ -891,6 +902,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_BODY: { case NS_HTML5TREE_BUILDER_BODY: {
addAttributesToBody(attributes); addAttributesToBody(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_P: case NS_HTML5TREE_BUILDER_P:
@ -899,6 +911,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION: { case NS_HTML5TREE_BUILDER_ADDRESS_OR_DIR_OR_ARTICLE_OR_ASIDE_OR_DATAGRID_OR_DETAILS_OR_DIALOG_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_NAV_OR_SECTION: {
implicitlyCloseP(); implicitlyCloseP();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: { case NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6: {
@ -908,17 +921,20 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
pop(); pop();
} }
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_FIELDSET: { case NS_HTML5TREE_BUILDER_FIELDSET: {
implicitlyCloseP(); implicitlyCloseP();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: { case NS_HTML5TREE_BUILDER_PRE_OR_LISTING: {
implicitlyCloseP(); implicitlyCloseP();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
needToDropLF = PR_TRUE; needToDropLF = PR_TRUE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_FORM: { case NS_HTML5TREE_BUILDER_FORM: {
@ -928,6 +944,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} else { } else {
implicitlyCloseP(); implicitlyCloseP();
appendToCurrentNodeAndPushFormElementMayFoster(attributes); appendToCurrentNodeAndPushFormElementMayFoster(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
} }
@ -952,12 +969,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
implicitlyCloseP(); implicitlyCloseP();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_PLAINTEXT: { case NS_HTML5TREE_BUILDER_PLAINTEXT: {
implicitlyCloseP(); implicitlyCloseP();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_PLAINTEXT, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_PLAINTEXT, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_A: { case NS_HTML5TREE_BUILDER_A: {
@ -976,12 +995,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushFormattingElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushFormattingElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U: case NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
case NS_HTML5TREE_BUILDER_FONT: { case NS_HTML5TREE_BUILDER_FONT: {
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushFormattingElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushFormattingElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_NOBR: { case NS_HTML5TREE_BUILDER_NOBR: {
@ -991,6 +1012,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
adoptionAgencyEndTag(nsHtml5Atoms::nobr); adoptionAgencyEndTag(nsHtml5Atoms::nobr);
} }
appendToCurrentNodeAndPushFormattingElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushFormattingElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_BUTTON: { case NS_HTML5TREE_BUILDER_BUTTON: {
@ -1010,6 +1032,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer);
insertMarker(); insertMarker();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
} }
@ -1017,12 +1040,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer);
insertMarker(); insertMarker();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: { case NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET: {
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
insertMarker(); insertMarker();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_XMP: { case NS_HTML5TREE_BUILDER_XMP: {
@ -1031,6 +1056,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_TABLE: { case NS_HTML5TREE_BUILDER_TABLE: {
@ -1039,6 +1065,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_TABLE; mode = NS_HTML5TREE_BUILDER_IN_TABLE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_BR: case NS_HTML5TREE_BUILDER_BR:
@ -1049,12 +1076,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE: { case NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE: {
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_HR: { case NS_HTML5TREE_BUILDER_HR: {
implicitlyCloseP(); implicitlyCloseP();
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_IMAGE: { case NS_HTML5TREE_BUILDER_IMAGE: {
@ -1067,6 +1096,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, name, attributes, formPointer); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, name, attributes, formPointer);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_ISINDEX: { case NS_HTML5TREE_BUILDER_ISINDEX: {
@ -1111,6 +1141,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
delete formAttrs; delete formAttrs;
delete inputAttributes; delete inputAttributes;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_TEXTAREA: { case NS_HTML5TREE_BUILDER_TEXTAREA: {
@ -1119,12 +1150,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
needToDropLF = PR_TRUE; needToDropLF = PR_TRUE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_NOSCRIPT: { case NS_HTML5TREE_BUILDER_NOSCRIPT: {
if (!scriptingEnabled) { if (!scriptingEnabled) {
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} else { } else {
} }
@ -1136,6 +1169,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_SELECT: { case NS_HTML5TREE_BUILDER_SELECT: {
@ -1156,6 +1190,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
break; break;
} }
} }
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_OPTGROUP: case NS_HTML5TREE_BUILDER_OPTGROUP:
@ -1185,6 +1220,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_RT_OR_RP: { case NS_HTML5TREE_BUILDER_RT_OR_RP: {
@ -1199,6 +1235,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
} }
} }
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_MATH: { case NS_HTML5TREE_BUILDER_MATH: {
@ -1211,6 +1248,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_MathML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_MathML, elementName, attributes);
foreignFlag = NS_HTML5TREE_BUILDER_IN_FOREIGN; foreignFlag = NS_HTML5TREE_BUILDER_IN_FOREIGN;
} }
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_SVG: { case NS_HTML5TREE_BUILDER_SVG: {
@ -1223,6 +1261,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_SVG, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_SVG, elementName, attributes);
foreignFlag = NS_HTML5TREE_BUILDER_IN_FOREIGN; foreignFlag = NS_HTML5TREE_BUILDER_IN_FOREIGN;
} }
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_CAPTION: case NS_HTML5TREE_BUILDER_CAPTION:
@ -1240,11 +1279,13 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL: { case NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL: {
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes, formPointer);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
reconstructTheActiveFormattingElements(); reconstructTheActiveFormattingElements();
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
} }
@ -1257,12 +1298,14 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_BASE: case NS_HTML5TREE_BUILDER_BASE:
case NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE: { case NS_HTML5TREE_BUILDER_COMMAND_OR_EVENT_SOURCE: {
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_META: case NS_HTML5TREE_BUILDER_META:
@ -1274,6 +1317,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_NOSCRIPT: { case NS_HTML5TREE_BUILDER_NOSCRIPT: {
@ -1286,6 +1330,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElementMayFoster(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT; mode = NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT;
} }
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_SCRIPT: case NS_HTML5TREE_BUILDER_SCRIPT:
@ -1295,6 +1340,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_HEAD: { case NS_HTML5TREE_BUILDER_HEAD: {
@ -1315,17 +1361,20 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_LINK: { case NS_HTML5TREE_BUILDER_LINK: {
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_META: { case NS_HTML5TREE_BUILDER_META: {
checkMetaCharset(attributes); checkMetaCharset(attributes);
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_STYLE: case NS_HTML5TREE_BUILDER_STYLE:
@ -1334,6 +1383,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_HEAD: { case NS_HTML5TREE_BUILDER_HEAD: {
@ -1357,11 +1407,13 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_COL: { case NS_HTML5TREE_BUILDER_COL: {
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1396,6 +1448,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_OPTION: { case NS_HTML5TREE_BUILDER_OPTION: {
@ -1403,6 +1456,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
pop(); pop();
} }
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_OPTGROUP: { case NS_HTML5TREE_BUILDER_OPTGROUP: {
@ -1413,6 +1467,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
pop(); pop();
} }
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_SELECT: { case NS_HTML5TREE_BUILDER_SELECT: {
@ -1441,6 +1496,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1454,6 +1510,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1467,11 +1524,13 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
switch(group) { switch(group) {
case NS_HTML5TREE_BUILDER_FRAMESET: { case NS_HTML5TREE_BUILDER_FRAMESET: {
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_FRAME: { case NS_HTML5TREE_BUILDER_FRAME: {
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: default:
@ -1483,6 +1542,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_NOFRAMES: { case NS_HTML5TREE_BUILDER_NOFRAMES: {
@ -1490,6 +1550,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1512,6 +1573,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendHtmlElementToDocumentAndPush(attributes); appendHtmlElementToDocumentAndPush(attributes);
} }
mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD; mode = NS_HTML5TREE_BUILDER_BEFORE_HEAD;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1526,11 +1588,13 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_HEAD: { case NS_HTML5TREE_BUILDER_HEAD: {
appendToCurrentNodeAndPushHeadElement(attributes); appendToCurrentNodeAndPushHeadElement(attributes);
mode = NS_HTML5TREE_BUILDER_IN_HEAD; mode = NS_HTML5TREE_BUILDER_IN_HEAD;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1545,6 +1609,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_BODY: { case NS_HTML5TREE_BUILDER_BODY: {
@ -1554,11 +1619,13 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendToCurrentNodeAndPushBodyElement(attributes); appendToCurrentNodeAndPushBodyElement(attributes);
} }
mode = NS_HTML5TREE_BUILDER_FRAMESET_OK; mode = NS_HTML5TREE_BUILDER_FRAMESET_OK;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_FRAMESET: { case NS_HTML5TREE_BUILDER_FRAMESET: {
appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes); appendToCurrentNodeAndPushElement(kNameSpaceID_XHTML, elementName, attributes);
mode = NS_HTML5TREE_BUILDER_IN_FRAMESET; mode = NS_HTML5TREE_BUILDER_IN_FRAMESET;
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_BASE: { case NS_HTML5TREE_BUILDER_BASE: {
@ -1567,6 +1634,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
pop(); pop();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_LINK: { case NS_HTML5TREE_BUILDER_LINK: {
@ -1575,6 +1643,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
pop(); pop();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_META: { case NS_HTML5TREE_BUILDER_META: {
@ -1584,6 +1653,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes); appendVoidElementToCurrentMayFoster(kNameSpaceID_XHTML, elementName, attributes);
selfClosing = PR_FALSE; selfClosing = PR_FALSE;
pop(); pop();
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_SCRIPT: { case NS_HTML5TREE_BUILDER_SCRIPT: {
@ -1593,6 +1663,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_STYLE: case NS_HTML5TREE_BUILDER_STYLE:
@ -1603,6 +1674,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_TITLE: { case NS_HTML5TREE_BUILDER_TITLE: {
@ -1612,6 +1684,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_RCDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
case NS_HTML5TREE_BUILDER_HEAD: { case NS_HTML5TREE_BUILDER_HEAD: {
@ -1630,6 +1703,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case NS_HTML5TREE_BUILDER_HTML: { case NS_HTML5TREE_BUILDER_HTML: {
addAttributesToHtml(attributes); addAttributesToHtml(attributes);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1647,6 +1721,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
originalMode = mode; originalMode = mode;
mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA; mode = NS_HTML5TREE_BUILDER_IN_CDATA_RCDATA;
tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName); tokenizer->setContentModelFlag(NS_HTML5TOKENIZER_CDATA, elementName);
attributes = nsnull;
goto starttagloop_end; goto starttagloop_end;
} }
default: { default: {
@ -1666,6 +1741,9 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
if (selfClosing) { if (selfClosing) {
} }
if (attributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
delete attributes;
}
} }
nsString* nsString*
@ -3058,7 +3136,7 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
} }
nsIContent* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes()); 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); nsHtml5StackNode* newNode = new nsHtml5StackNode(node->group, node->ns, node->name, clone, node->scoping, node->special, node->fosterParenting, node->popName, node->attributes);
node->dropAttributes(); node->dropAttributes();
stack[nodePos] = newNode; stack[nodePos] = newNode;
@ -3080,7 +3158,7 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
detachFromParent(lastNode->node); detachFromParent(lastNode->node);
appendElement(lastNode->node, commonAncestor->node); appendElement(lastNode->node, commonAncestor->node);
} }
nsIContent* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes()); 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); nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->group, formattingElt->ns, formattingElt->name, clone, formattingElt->scoping, formattingElt->special, formattingElt->fosterParenting, formattingElt->popName, formattingElt->attributes);
formattingElt->dropAttributes(); formattingElt->dropAttributes();
appendChildrenToNewParent(furthestBlock->node, clone); appendChildrenToNewParent(furthestBlock->node, clone);
@ -3227,7 +3305,7 @@ nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
while (entryPos < listPtr) { while (entryPos < listPtr) {
entryPos++; entryPos++;
nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos]; nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
nsIContent* clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes()); 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); nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->group, entry->ns, entry->name, clone, entry->scoping, entry->special, entry->fosterParenting, entry->popName, entry->attributes);
entry->dropAttributes(); entry->dropAttributes();
nsHtml5StackNode* currentNode = stack[currentPtr]; nsHtml5StackNode* currentNode = stack[currentPtr];
@ -3244,11 +3322,11 @@ nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
} }
void void
nsHtml5TreeBuilder::insertIntoFosterParent(nsIContent* child) nsHtml5TreeBuilder::insertIntoFosterParent(nsIContent** child)
{ {
PRInt32 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE); PRInt32 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
nsHtml5StackNode* node = stack[eltPos]; nsHtml5StackNode* node = stack[eltPos];
nsIContent* elt = node->node; nsIContent** elt = node->node;
if (!eltPos) { if (!eltPos) {
appendElement(child, elt); appendElement(child, elt);
return; return;
@ -3293,7 +3371,7 @@ nsHtml5TreeBuilder::popOnEof()
void void
nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes)
{ {
nsIContent* elt = createHtmlElementSetAsRoot(attributes); nsIContent** elt = createHtmlElementSetAsRoot(attributes);
nsHtml5StackNode* node = new nsHtml5StackNode(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HTML, elt); nsHtml5StackNode* node = new nsHtml5StackNode(kNameSpaceID_XHTML, nsHtml5ElementName::ELT_HTML, elt);
push(node); push(node);
nsHtml5Portability::releaseElement(elt); nsHtml5Portability::releaseElement(elt);
@ -3309,7 +3387,7 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes); nsIContent** elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes);
appendElement(elt, stack[currentPtr]->node); appendElement(elt, stack[currentPtr]->node);
headPointer = elt; headPointer = elt;
nsHtml5Portability::retainElement(headPointer); nsHtml5Portability::retainElement(headPointer);
@ -3334,7 +3412,7 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes); nsIContent** elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
formPointer = elt; formPointer = elt;
nsHtml5Portability::retainElement(formPointer); nsHtml5Portability::retainElement(formPointer);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
@ -3353,7 +3431,7 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(ns, elementName->name, attributes); nsIContent** elt = createElement(ns, elementName->name, attributes);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3372,7 +3450,7 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(ns, elementName->name, attributes); nsIContent** elt = createElement(ns, elementName->name, attributes);
appendElement(elt, stack[currentPtr]->node); appendElement(elt, stack[currentPtr]->node);
nsHtml5StackNode* node = new nsHtml5StackNode(ns, elementName, elt); nsHtml5StackNode* node = new nsHtml5StackNode(ns, elementName, elt);
push(node); push(node);
@ -3384,7 +3462,7 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtm
{ {
flushCharacters(); flushCharacters();
nsIAtom* popName = elementName->name; nsIAtom* popName = elementName->name;
nsIContent* elt = createElement(ns, popName, attributes); nsIContent** elt = createElement(ns, popName, attributes);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3402,7 +3480,7 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterNoScoping(PRInt32
{ {
flushCharacters(); flushCharacters();
nsIAtom* popName = elementName->name; nsIAtom* popName = elementName->name;
nsIContent* elt = createElement(ns, popName, attributes); nsIContent** elt = createElement(ns, popName, attributes);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3420,7 +3498,7 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterCamelCase(PRInt32
{ {
flushCharacters(); flushCharacters();
nsIAtom* popName = elementName->camelCaseName; nsIAtom* popName = elementName->camelCaseName;
nsIContent* elt = createElement(ns, popName, attributes); nsIContent** elt = createElement(ns, popName, attributes);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3434,10 +3512,10 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterCamelCase(PRInt32
} }
void void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContent* form) nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContent** form)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(ns, elementName->name, attributes, form); nsIContent** elt = createElement(ns, elementName->name, attributes, form);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3451,10 +3529,10 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtm
} }
void void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent* form) nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(ns, name, attributes, form); nsIContent** elt = createElement(ns, name, attributes, form);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3472,7 +3550,7 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(PRInt32 ns, nsHtml5Eleme
{ {
flushCharacters(); flushCharacters();
nsIAtom* popName = elementName->name; nsIAtom* popName = elementName->name;
nsIContent* elt = createElement(ns, popName, attributes); nsIContent** elt = createElement(ns, popName, attributes);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3490,7 +3568,7 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterCamelCase(PRInt32 ns, nsH
{ {
flushCharacters(); flushCharacters();
nsIAtom* popName = elementName->camelCaseName; nsIAtom* popName = elementName->camelCaseName;
nsIContent* elt = createElement(ns, popName, attributes); nsIContent** elt = createElement(ns, popName, attributes);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
if (current->fosterParenting) { if (current->fosterParenting) {
@ -3504,10 +3582,10 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterCamelCase(PRInt32 ns, nsH
} }
void void
nsHtml5TreeBuilder::appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent* form) nsHtml5TreeBuilder::appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form)
{ {
flushCharacters(); flushCharacters();
nsIContent* elt = createElement(ns, name, attributes, form); nsIContent** elt = createElement(ns, name, attributes, form);
nsHtml5StackNode* current = stack[currentPtr]; nsHtml5StackNode* current = stack[currentPtr];
appendElement(elt, current->node); appendElement(elt, current->node);
elementPushed(ns, name, elt); elementPushed(ns, name, elt);
@ -3536,7 +3614,7 @@ nsHtml5TreeBuilder::requestSuspension()
} }
void void
nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, PRInt32 ns, nsIContent* node, PRBool quirks) nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, PRInt32 ns, nsIContent** node, PRBool quirks)
{ {
this->contextName = context; this->contextName = context;
nsHtml5Portability::retainLocal(context); nsHtml5Portability::retainLocal(context);
@ -3547,7 +3625,7 @@ nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, PRInt32 ns, nsIContent*
this->quirks = quirks; this->quirks = quirks;
} }
nsIContent* nsIContent**
nsHtml5TreeBuilder::currentNode() nsHtml5TreeBuilder::currentNode()
{ {
return stack[currentPtr]->node; return stack[currentPtr]->node;
@ -3580,7 +3658,7 @@ nsHtml5TreeBuilder::flushCharacters()
PRInt32 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE); PRInt32 eltPos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
nsHtml5StackNode* node = stack[eltPos]; nsHtml5StackNode* node = stack[eltPos];
nsIContent* elt = node->node; nsIContent** elt = node->node;
if (!eltPos) { if (!eltPos) {
appendCharacters(elt, charBuffer, 0, charBufferLen); appendCharacters(elt, charBuffer, 0, charBufferLen);
charBufferLen = 0; charBufferLen = 0;

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

@ -81,13 +81,13 @@ class nsHtml5TreeBuilder
PRBool fragment; PRBool fragment;
nsIAtom* contextName; nsIAtom* contextName;
PRInt32 contextNamespace; PRInt32 contextNamespace;
nsIContent* contextNode; nsIContent** contextNode;
jArray<nsHtml5StackNode*,PRInt32> stack; jArray<nsHtml5StackNode*,PRInt32> stack;
PRInt32 currentPtr; PRInt32 currentPtr;
jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements; jArray<nsHtml5StackNode*,PRInt32> listOfActiveFormattingElements;
PRInt32 listPtr; PRInt32 listPtr;
nsIContent* formPointer; nsIContent** formPointer;
nsIContent* headPointer; nsIContent** headPointer;
protected: protected:
jArray<PRUnichar,PRInt32> charBuffer; jArray<PRUnichar,PRInt32> charBuffer;
PRInt32 charBufferLen; PRInt32 charBufferLen;
@ -154,7 +154,7 @@ class nsHtml5TreeBuilder
void addAttributesToHtml(nsHtml5HtmlAttributes* attributes); void addAttributesToHtml(nsHtml5HtmlAttributes* attributes);
void pushHeadPointerOntoStack(); void pushHeadPointerOntoStack();
void reconstructTheActiveFormattingElements(); void reconstructTheActiveFormattingElements();
void insertIntoFosterParent(nsIContent* child); void insertIntoFosterParent(nsIContent** child);
PRBool isInStack(nsHtml5StackNode* node); PRBool isInStack(nsHtml5StackNode* node);
void pop(); void pop();
void popOnEof(); void popOnEof();
@ -169,38 +169,38 @@ class nsHtml5TreeBuilder
void appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFosterNoScoping(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendToCurrentNodeAndPushElementMayFosterNoScoping(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFosterCamelCase(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendToCurrentNodeAndPushElementMayFosterCamelCase(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContent* form); void appendToCurrentNodeAndPushElementMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContent** form);
void appendVoidElementToCurrentMayFoster(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent* form); void appendVoidElementToCurrentMayFoster(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form);
void appendVoidElementToCurrentMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendVoidElementToCurrentMayFoster(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendVoidElementToCurrentMayFosterCamelCase(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes); void appendVoidElementToCurrentMayFosterCamelCase(PRInt32 ns, nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent* form); void appendVoidElementToCurrent(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form);
protected: protected:
void accumulateCharacters(PRUnichar* buf, PRInt32 start, PRInt32 length); void accumulateCharacters(PRUnichar* buf, PRInt32 start, PRInt32 length);
void accumulateCharacter(PRUnichar c); void accumulateCharacter(PRUnichar c);
void requestSuspension(); void requestSuspension();
nsIContent* createElement(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes); nsIContent** createElement(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
nsIContent* createElement(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent* form); nsIContent** createElement(PRInt32 ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form);
nsIContent* createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes); nsIContent** createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
void detachFromParent(nsIContent* element); void detachFromParent(nsIContent** element);
PRBool hasChildren(nsIContent* element); PRBool hasChildren(nsIContent** element);
void appendElement(nsIContent* child, nsIContent* newParent); void appendElement(nsIContent** child, nsIContent** newParent);
void appendChildrenToNewParent(nsIContent* oldParent, nsIContent* newParent); void appendChildrenToNewParent(nsIContent** oldParent, nsIContent** newParent);
void insertFosterParentedChild(nsIContent* child, nsIContent* table, nsIContent* stackParent); void insertFosterParentedChild(nsIContent** child, nsIContent** table, nsIContent** stackParent);
void insertFosterParentedCharacters(PRUnichar* buf, PRInt32 start, PRInt32 length, nsIContent* table, nsIContent* stackParent); void insertFosterParentedCharacters(PRUnichar* buf, PRInt32 start, PRInt32 length, nsIContent** table, nsIContent** stackParent);
void appendCharacters(nsIContent* parent, PRUnichar* buf, PRInt32 start, PRInt32 length); void appendCharacters(nsIContent** parent, PRUnichar* buf, PRInt32 start, PRInt32 length);
void appendComment(nsIContent* parent, PRUnichar* buf, PRInt32 start, PRInt32 length); void appendComment(nsIContent** parent, PRUnichar* buf, PRInt32 start, PRInt32 length);
void appendCommentToDocument(PRUnichar* buf, PRInt32 start, PRInt32 length); void appendCommentToDocument(PRUnichar* buf, PRInt32 start, PRInt32 length);
void addAttributesToElement(nsIContent* element, nsHtml5HtmlAttributes* attributes); void addAttributesToElement(nsIContent** element, nsHtml5HtmlAttributes* attributes);
void markMalformedIfScript(nsIContent* elt); void markMalformedIfScript(nsIContent** elt);
void start(PRBool fragment); void start(PRBool fragment);
void end(); void end();
void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier); void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier);
void elementPushed(PRInt32 ns, nsIAtom* name, nsIContent* node); void elementPushed(PRInt32 ns, nsIAtom* name, nsIContent** node);
void elementPopped(PRInt32 ns, nsIAtom* name, nsIContent* node); void elementPopped(PRInt32 ns, nsIAtom* name, nsIContent** node);
public: public:
void setFragmentContext(nsIAtom* context, PRInt32 ns, nsIContent* node, PRBool quirks); void setFragmentContext(nsIAtom* context, PRInt32 ns, nsIContent** node, PRBool quirks);
protected: protected:
nsIContent* currentNode(); nsIContent** currentNode();
public: public:
PRBool isScriptingEnabled(); PRBool isScriptingEnabled();
void setScriptingEnabled(PRBool scriptingEnabled); void setScriptingEnabled(PRBool scriptingEnabled);

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

@ -39,22 +39,13 @@
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "nsContentErrors.h" #include "nsContentErrors.h"
#include "nsContentCreatorFunctions.h"
#include "nsIDOMDocumentType.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsPresContext.h" #include "nsPresContext.h"
#include "nsEvent.h" #include "nsEvent.h"
#include "nsGUIEvent.h" #include "nsGUIEvent.h"
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsNodeUtils.h" #include "nsNodeUtils.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsTraceRefcnt.h"
#include "mozAutoDocUpdate.h"
#include "nsIScriptElement.h"
#include "nsIDTD.h"
// this really should be autogenerated... // this really should be autogenerated...
jArray<PRUnichar,PRInt32> nsHtml5TreeBuilder::ISINDEX_PROMPT = jArray<PRUnichar,PRInt32>(); jArray<PRUnichar,PRInt32> nsHtml5TreeBuilder::ISINDEX_PROMPT = jArray<PRUnichar,PRInt32>();
@ -65,6 +56,8 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5TreeOpExecutor* aExec)
, formPointer(nsnull) , formPointer(nsnull)
, headPointer(nsnull) , headPointer(nsnull)
, mExecutor(aExec) , mExecutor(aExec)
, mHandles(new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH])
, mHandlesUsed(0)
#ifdef DEBUG #ifdef DEBUG
, mActive(PR_FALSE) , mActive(PR_FALSE)
#endif #endif
@ -79,54 +72,32 @@ nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
mOpQueue.Clear(); mOpQueue.Clear();
} }
nsIContent* nsIContent**
nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes) nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes)
{ {
nsIContent* newContent; nsIContent** content = AllocateContentHandle();
nsCOMPtr<nsINodeInfo> nodeInfo = mExecutor->GetNodeInfoManager()->GetNodeInfo(aName, nsnull, aNamespace); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(nodeInfo, "Got null nodeinfo."); // XXX if null, OOM!
NS_NewElement(&newContent, nodeInfo->NamespaceID(), nodeInfo, PR_TRUE); treeOp->Init(aNamespace, aName, aAttributes, content);
NS_ASSERTION(newContent, "Element creation created null pointer."); return content;
PRInt32 len = aAttributes->getLength();
for (PRInt32 i = 0; i < len; ++i) {
newContent->SetAttr(aAttributes->getURI(i), aAttributes->getLocalName(i), aAttributes->getPrefix(i), *(aAttributes->getValue(i)), PR_FALSE);
// XXX what to do with nsresult?
}
if (aNamespace != kNameSpaceID_MathML && (aName == nsHtml5Atoms::style || (aNamespace == kNameSpaceID_XHTML && aName == nsHtml5Atoms::link))) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
#if 0
if (!aNodeInfo->Equals(nsGkAtoms::link, kNameSpaceID_XHTML)) {
ssle->SetLineNumber(aLineNumber);
}
#endif
}
}
return newContent;
} }
nsIContent* nsIContent**
nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContent* aFormElement) nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContent** aFormElement)
{ {
nsIContent* content = createElement(aNamespace, aName, aAttributes); nsIContent** content = createElement(aNamespace, aName, aAttributes);
if (aFormElement) { if (aFormElement) {
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(content)); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(formControl, "Form-associated element did not implement nsIFormControl."); // XXX if null, OOM!
nsCOMPtr<nsIDOMHTMLFormElement> formElement(do_QueryInterface(aFormElement)); treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
NS_ASSERTION(formElement, "The form element doesn't implement nsIDOMHTMLFormElement.");
if (formControl) { // avoid crashing on <output>
formControl->SetForm(formElement);
}
} }
return content; return content;
} }
nsIContent* nsIContent**
nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes) nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
{ {
nsIContent* content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes); nsIContent** content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes);
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(eTreeOpAppendToDocument, content); treeOp->Init(eTreeOpAppendToDocument, content);
@ -134,7 +105,7 @@ nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttribute
} }
void void
nsHtml5TreeBuilder::detachFromParent(nsIContent* aElement) nsHtml5TreeBuilder::detachFromParent(nsIContent** aElement)
{ {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
@ -142,7 +113,7 @@ nsHtml5TreeBuilder::detachFromParent(nsIContent* aElement)
} }
void void
nsHtml5TreeBuilder::appendElement(nsIContent* aChild, nsIContent* aParent) nsHtml5TreeBuilder::appendElement(nsIContent** aChild, nsIContent** aParent)
{ {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
@ -150,7 +121,7 @@ nsHtml5TreeBuilder::appendElement(nsIContent* aChild, nsIContent* aParent)
} }
void void
nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContent* aOldParent, nsIContent* aNewParent) nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContent** aOldParent, nsIContent** aNewParent)
{ {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
@ -158,20 +129,24 @@ nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContent* aOldParent, nsIContent
} }
void void
nsHtml5TreeBuilder::insertFosterParentedCharacters(PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength, nsIContent* aTable, nsIContent* aStackParent) nsHtml5TreeBuilder::insertFosterParentedCharacters(PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength, nsIContent** aTable, nsIContent** aStackParent)
{ {
nsCOMPtr<nsIContent> text; PRUnichar* bufferCopy = new PRUnichar[aLength];
NS_NewTextNode(getter_AddRefs(text), mExecutor->GetNodeInfoManager()); memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
// XXX nsresult and comment null check?
text->SetText(aBuffer + aStart, aLength, PR_FALSE); nsIContent** text = AllocateContentHandle();
// XXX nsresult
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(eTreeOpCreateTextNode, bufferCopy, aLength, text);
treeOp = mOpQueue.AppendElement();
// XXX if null, OOM!
treeOp->Init(eTreeOpFosterParent, text, aStackParent, aTable); treeOp->Init(eTreeOpFosterParent, text, aStackParent, aTable);
} }
void void
nsHtml5TreeBuilder::insertFosterParentedChild(nsIContent* aChild, nsIContent* aTable, nsIContent* aStackParent) nsHtml5TreeBuilder::insertFosterParentedChild(nsIContent** aChild, nsIContent** aTable, nsIContent** aStackParent)
{ {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
@ -179,61 +154,73 @@ nsHtml5TreeBuilder::insertFosterParentedChild(nsIContent* aChild, nsIContent* aT
} }
void void
nsHtml5TreeBuilder::appendCharacters(nsIContent* aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength) nsHtml5TreeBuilder::appendCharacters(nsIContent** aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
{ {
nsCOMPtr<nsIContent> text; PRUnichar* bufferCopy = new PRUnichar[aLength];
NS_NewTextNode(getter_AddRefs(text), mExecutor->GetNodeInfoManager()); memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
// XXX nsresult and comment null check?
text->SetText(aBuffer + aStart, aLength, PR_FALSE); nsIContent** text = AllocateContentHandle();
// XXX nsresult
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(eTreeOpCreateTextNode, bufferCopy, aLength, text);
treeOp = mOpQueue.AppendElement();
// XXX if null, OOM!
treeOp->Init(text, aParent); treeOp->Init(text, aParent);
} }
void void
nsHtml5TreeBuilder::appendComment(nsIContent* aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength) nsHtml5TreeBuilder::appendComment(nsIContent** aParent, PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
{ {
nsCOMPtr<nsIContent> comment; PRUnichar* bufferCopy = new PRUnichar[aLength];
NS_NewCommentNode(getter_AddRefs(comment), mExecutor->GetNodeInfoManager()); memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
// XXX nsresult and comment null check?
comment->SetText(aBuffer + aStart, aLength, PR_FALSE); nsIContent** comment = AllocateContentHandle();
// XXX nsresult
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(eTreeOpCreateComment, bufferCopy, aLength, comment);
treeOp = mOpQueue.AppendElement();
// XXX if null, OOM!
treeOp->Init(comment, aParent); treeOp->Init(comment, aParent);
} }
void void
nsHtml5TreeBuilder::appendCommentToDocument(PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength) nsHtml5TreeBuilder::appendCommentToDocument(PRUnichar* aBuffer, PRInt32 aStart, PRInt32 aLength)
{ {
nsCOMPtr<nsIContent> comment; PRUnichar* bufferCopy = new PRUnichar[aLength];
NS_NewCommentNode(getter_AddRefs(comment), mExecutor->GetNodeInfoManager()); memcpy(bufferCopy, aBuffer, aLength * sizeof(PRUnichar));
// XXX nsresult and comment null check?
comment->SetText(aBuffer + aStart, aLength, PR_FALSE); nsIContent** comment = AllocateContentHandle();
// XXX nsresult
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(eTreeOpCreateComment, bufferCopy, aLength, comment);
treeOp = mOpQueue.AppendElement();
// XXX if null, OOM!
treeOp->Init(eTreeOpAppendToDocument, comment); treeOp->Init(eTreeOpAppendToDocument, comment);
} }
void void
nsHtml5TreeBuilder::addAttributesToElement(nsIContent* aElement, nsHtml5HtmlAttributes* aAttributes) nsHtml5TreeBuilder::addAttributesToElement(nsIContent** aElement, nsHtml5HtmlAttributes* aAttributes)
{ {
nsIContent* holder = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::div, aAttributes); if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
return;
}
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(eTreeOpAddAttributes, holder, aElement); treeOp->Init(aElement, aAttributes);
} }
void void
nsHtml5TreeBuilder::markMalformedIfScript(nsIContent* elt) nsHtml5TreeBuilder::markMalformedIfScript(nsIContent** elt)
{ {
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(elt); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
if (sele) { // XXX if null, OOM!
// Make sure to serialize this script correctly, for nice round tripping. treeOp->Init(eTreeOpMarkMalformedIfScript, elt);
sele->SetIsMalformed();
}
} }
void void
@ -267,32 +254,21 @@ nsHtml5TreeBuilder::end()
void void
nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId) nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId)
{ {
// Adapted from nsXMLContentSink nsIContent** content = AllocateContentHandle();
// Create a new doctype node
nsCOMPtr<nsIDOMDocumentType> docType;
nsAutoString voidString;
voidString.SetIsVoid(PR_TRUE);
NS_NewDOMDocumentType(getter_AddRefs(docType),
mExecutor->GetNodeInfoManager(),
nsnull,
aName,
nsnull,
nsnull,
*aPublicId,
*aSystemId,
voidString);
NS_ASSERTION(docType, "Doctype creation failed.");
nsCOMPtr<nsIContent> content = do_QueryInterface(docType);
NS_ASSERTION(content, "doctype isn't content?");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM! // XXX if null, OOM!
treeOp->Init(aName, *aPublicId, *aSystemId, content);
treeOp = mOpQueue.AppendElement();
// XXX if null, OOM!
treeOp->Init(eTreeOpAppendToDocument, content); treeOp->Init(eTreeOpAppendToDocument, content);
// nsXMLContentSink can flush here, but what's the point? // nsXMLContentSink can flush here, but what's the point?
// It can also interrupt here, but we can't. // It can also interrupt here, but we can't.
} }
void void
nsHtml5TreeBuilder::elementPushed(PRInt32 aNamespace, nsIAtom* aName, nsIContent* aElement) nsHtml5TreeBuilder::elementPushed(PRInt32 aNamespace, nsIAtom* aName, nsIContent** aElement)
{ {
NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!"); NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
NS_ASSERTION(aName, "Element doesn't have local name!"); NS_ASSERTION(aName, "Element doesn't have local name!");
@ -314,7 +290,7 @@ nsHtml5TreeBuilder::elementPushed(PRInt32 aNamespace, nsIAtom* aName, nsIContent
} }
void void
nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent* aElement) nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent** aElement)
{ {
NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!"); NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
NS_ASSERTION(aName, "Element doesn't have local name!"); NS_ASSERTION(aName, "Element doesn't have local name!");
@ -326,7 +302,9 @@ nsHtml5TreeBuilder::elementPopped(PRInt32 aNamespace, nsIAtom* aName, nsIContent
// we now have only SVG and HTML // we now have only SVG and HTML
if (aName == nsHtml5Atoms::script) { if (aName == nsHtml5Atoms::script) {
requestSuspension(); requestSuspension();
mExecutor->SetScriptElement(aElement); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
// XXX if null, OOM!
treeOp->Init(eTreeOpRunScript, aElement);
return; return;
} }
if (aName == nsHtml5Atoms::title) { if (aName == nsHtml5Atoms::title) {
@ -415,59 +393,25 @@ nsHtml5TreeBuilder::accumulateCharacters(PRUnichar* aBuf, PRInt32 aStart, PRInt3
charBufferLen = newFillLen; charBufferLen = newFillLen;
} }
void nsIContent**
nsHtml5TreeBuilder::DoUnlink() nsHtml5TreeBuilder::AllocateContentHandle()
{ {
nsHtml5TreeBuilder* tmp = this; if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
NS_IF_RELEASE(contextNode); mOldHandles.AppendElement(mHandles.forget());
NS_IF_RELEASE(formPointer); mHandles = new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH];
NS_IF_RELEASE(headPointer); mHandlesUsed = 0;
while (currentPtr > -1) {
stack[currentPtr]->release();
currentPtr--;
} }
while (listPtr > -1) { return &mHandles[mHandlesUsed++];
if (listOfActiveFormattingElements[listPtr]) {
listOfActiveFormattingElements[listPtr]->release();
}
listPtr--;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mOpQueue);
} }
void PRBool
nsHtml5TreeBuilder::DoTraverse(nsCycleCollectionTraversalCallback &cb) nsHtml5TreeBuilder::HasScript()
{ {
nsHtml5TreeBuilder* tmp = this; PRUint32 len = mOpQueue.Length();
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(contextNode); if (!len) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(formPointer); return PR_FALSE;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(headPointer);
if (stack) {
for (PRInt32 i = 0; i <= currentPtr; i++) {
#ifdef DEBUG_CC
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "stack[i]");
#endif
cb.NoteNativeChild(stack[i], &NS_CYCLE_COLLECTION_NAME(nsHtml5StackNode));
}
}
if (listOfActiveFormattingElements) {
for (PRInt32 i = 0; i <= listPtr; i++) {
if (listOfActiveFormattingElements[i]) {
#ifdef DEBUG_CC
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "listOfActiveFormattingElements[i]");
#endif
cb.NoteNativeChild(listOfActiveFormattingElements[i], &NS_CYCLE_COLLECTION_NAME(nsHtml5StackNode));
}
}
}
const nsHtml5TreeOperation* start = mOpQueue.Elements();
const nsHtml5TreeOperation* end = start + mOpQueue.Length();
for (nsHtml5TreeOperation* iter = (nsHtml5TreeOperation*)start; iter < end; ++iter) {
#ifdef DEBUG_CC
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mOpQueue[i]");
#endif
iter->DoTraverse(cb);
} }
return mOpQueue.ElementAt(len - 1).IsRunScript();
} }
// DocumentModeHandler // DocumentModeHandler

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

@ -35,30 +35,33 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
private: private:
nsTArray<nsHtml5TreeOperation> mOpQueue; nsTArray<nsHtml5TreeOperation> mOpQueue;
nsHtml5TreeOpExecutor* mExecutor; nsHtml5TreeOpExecutor* mExecutor;
nsAutoArrayPtr<nsIContent*> mHandles;
PRInt32 mHandlesUsed;
nsTArray<nsAutoArrayPtr<nsIContent*> > mOldHandles;
#ifdef DEBUG #ifdef DEBUG
PRBool mActive; PRBool mActive;
#endif #endif
public:
nsHtml5TreeBuilder(nsHtml5TreeOpExecutor* aExec);
~nsHtml5TreeBuilder();
void DoUnlink();
void DoTraverse(nsCycleCollectionTraversalCallback &cb);
// DocumentModeHandler // DocumentModeHandler
/** /**
* Tree builder uses this to report quirkiness of the document * Tree builder uses this to report quirkiness of the document
*/ */
void documentMode(nsHtml5DocumentMode m); void documentMode(nsHtml5DocumentMode m);
nsIContent** AllocateContentHandle();
public:
nsHtml5TreeBuilder(nsHtml5TreeOpExecutor* aExec);
~nsHtml5TreeBuilder();
inline PRUint32 GetOpQueueLength() { inline PRUint32 GetOpQueueLength() {
return mOpQueue.Length(); return mOpQueue.Length();
} }
@ -70,3 +73,6 @@
inline void ReqSuspension() { inline void ReqSuspension() {
requestSuspension(); requestSuspension();
} }
PRBool HasScript();

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

@ -74,19 +74,22 @@ NS_IMPL_ADDREF_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
NS_IMPL_RELEASE_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) NS_IMPL_RELEASE_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFlushTimer); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFlushTimer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mOwnedElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mOwnedNonElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
if (tmp->mFlushTimer) { if (tmp->mFlushTimer) {
tmp->mFlushTimer->Cancel(); tmp->mFlushTimer->Cancel();
} }
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFlushTimer); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFlushTimer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mOwnedElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mOwnedNonElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor() nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
: mSuppressEOF(PR_FALSE) : mSuppressEOF(PR_FALSE)
, mHasProcessedBase(PR_FALSE) , mHasProcessedBase(PR_FALSE)
@ -504,13 +507,15 @@ nsHtml5TreeOpExecutor::MaybeSuspend() {
void void
nsHtml5TreeOpExecutor::MaybeExecuteScript() { nsHtml5TreeOpExecutor::MaybeExecuteScript() {
if (mScriptElement) { if (!mTreeBuilder->HasScript()) {
// mUninterruptibleDocWrite = PR_FALSE; return;
}
Flush(); // Let the doc update end before we start executing the script
NS_ASSERTION(mScriptElement, "No script to run");
ExecuteScript(); ExecuteScript();
if (mStreamParser) { if (mStreamParser) {
mStreamParser->Suspend(); mStreamParser->Suspend();
} }
}
} }
void void

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

@ -53,6 +53,7 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "nsIScriptElement.h" #include "nsIScriptElement.h"
#include "nsIParser.h" #include "nsIParser.h"
#include "nsCOMArray.h"
class nsHtml5TreeBuilder; class nsHtml5TreeBuilder;
class nsHtml5Tokenizer; class nsHtml5Tokenizer;
@ -112,6 +113,12 @@ class nsHtml5TreeOpExecutor : public nsIContentSink,
nsTArray<nsIContentPtr> mElementsSeenInThisAppendBatch; nsTArray<nsIContentPtr> mElementsSeenInThisAppendBatch;
nsTArray<nsHtml5PendingNotification> mPendingNotifications; nsTArray<nsHtml5PendingNotification> mPendingNotifications;
nsHtml5StreamParser* mStreamParser; nsHtml5StreamParser* mStreamParser;
nsCOMArray<nsIContent> mOwnedElements;
// This could be optimized away by introducing more tree ops so that
// non-elements wouldn't use the handle setup but the text node / comment
// / doctype operand would be remembered by the tree op executor.
nsCOMArray<nsIContent> mOwnedNonElements;
/** /**
* The character encoding to which to switch in a late <meta> renavigation * The character encoding to which to switch in a late <meta> renavigation
@ -244,6 +251,10 @@ class nsHtml5TreeOpExecutor : public nsIContentSink,
*/ */
nsresult MaybePerformCharsetSwitch(); nsresult MaybePerformCharsetSwitch();
inline void SetScriptElement(nsIContent* aScript) {
mScriptElement = aScript;
}
/** /**
* Runs mScriptElement * Runs mScriptElement
*/ */
@ -377,19 +388,20 @@ class nsHtml5TreeOpExecutor : public nsIContentSink,
} }
} }
/**
* Request execution of the script element when the tokenizer returns
*/
void SetScriptElement(nsIContent* aScript) {
mScriptElement = aScript;
}
void SetTreeBuilder(nsHtml5TreeBuilder* aBuilder) { void SetTreeBuilder(nsHtml5TreeBuilder* aBuilder) {
mTreeBuilder = aBuilder; mTreeBuilder = aBuilder;
} }
void Reset(); void Reset();
inline void HoldElement(nsIContent* aContent) {
mOwnedElements.AppendObject(aContent);
}
inline void HoldNonElement(nsIContent* aContent) {
mOwnedNonElements.AppendObject(aContent);
}
private: private:
nsHtml5Tokenizer* GetTokenizer(); nsHtml5Tokenizer* GetTokenizer();

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

@ -48,6 +48,15 @@
#include "nsBindingManager.h" #include "nsBindingManager.h"
#include "nsXBLBinding.h" #include "nsXBLBinding.h"
#include "nsHtml5DocumentMode.h" #include "nsHtml5DocumentMode.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsContentCreatorFunctions.h"
#include "nsIScriptElement.h"
#include "nsIDTD.h"
#include "nsTraceRefcnt.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsIDOMDocumentType.h"
nsHtml5TreeOperation::nsHtml5TreeOperation() nsHtml5TreeOperation::nsHtml5TreeOperation()
: mOpCode(eTreeOpAppend) : mOpCode(eTreeOpAppend)
@ -58,6 +67,23 @@ nsHtml5TreeOperation::nsHtml5TreeOperation()
nsHtml5TreeOperation::~nsHtml5TreeOperation() nsHtml5TreeOperation::~nsHtml5TreeOperation()
{ {
MOZ_COUNT_DTOR(nsHtml5TreeOperation); MOZ_COUNT_DTOR(nsHtml5TreeOperation);
switch(mOpCode) {
case eTreeOpAddAttributes:
delete mTwo.attributes;
break;
case eTreeOpCreateElement:
delete mThree.attributes;
break;
case eTreeOpCreateDoctype:
delete mTwo.stringPair;
break;
case eTreeOpCreateTextNode:
case eTreeOpCreateComment:
delete[] mTwo.unicharPtr;
break;
default: // keep the compiler happy
break;
}
} }
nsresult nsresult
@ -66,15 +92,18 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder)
nsresult rv = NS_OK; nsresult rv = NS_OK;
switch(mOpCode) { switch(mOpCode) {
case eTreeOpAppend: { case eTreeOpAppend: {
aBuilder->PostPendingAppendNotification(mParent, mNode); nsIContent* node = *(mOne.node);
rv = mParent->AppendChildTo(mNode, PR_FALSE); nsIContent* parent = *(mTwo.node);
aBuilder->PostPendingAppendNotification(parent, node);
rv = parent->AppendChildTo(node, PR_FALSE);
return rv; return rv;
} }
case eTreeOpDetach: { case eTreeOpDetach: {
nsIContent* node = *(mOne.node);
aBuilder->FlushPendingAppendNotifications(); aBuilder->FlushPendingAppendNotifications();
nsIContent* parent = mNode->GetParent(); nsIContent* parent = node->GetParent();
if (parent) { if (parent) {
PRUint32 pos = parent->IndexOf(mNode); PRUint32 pos = parent->IndexOf(node);
NS_ASSERTION((pos >= 0), "Element not found as child of its parent"); NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
rv = parent->RemoveChildAt(pos, PR_TRUE, PR_FALSE); rv = parent->RemoveChildAt(pos, PR_TRUE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -82,115 +111,248 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder)
return rv; return rv;
} }
case eTreeOpAppendChildrenToNewParent: { case eTreeOpAppendChildrenToNewParent: {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
aBuilder->FlushPendingAppendNotifications(); aBuilder->FlushPendingAppendNotifications();
PRUint32 childCount = mParent->GetChildCount(); PRUint32 childCount = parent->GetChildCount();
PRBool didAppend = PR_FALSE; PRBool didAppend = PR_FALSE;
while (mNode->GetChildCount()) { while (node->GetChildCount()) {
nsCOMPtr<nsIContent> child = mNode->GetChildAt(0); nsCOMPtr<nsIContent> child = node->GetChildAt(0);
rv = mNode->RemoveChildAt(0, PR_TRUE, PR_FALSE); rv = node->RemoveChildAt(0, PR_TRUE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = mParent->AppendChildTo(child, PR_FALSE); rv = parent->AppendChildTo(child, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
didAppend = PR_TRUE; didAppend = PR_TRUE;
} }
if (didAppend) { if (didAppend) {
nsNodeUtils::ContentAppended(mParent, childCount); nsNodeUtils::ContentAppended(parent, childCount);
} }
return rv; return rv;
} }
case eTreeOpFosterParent: { case eTreeOpFosterParent: {
nsIContent* parent = mTable->GetParent(); nsIContent* node = *(mOne.node);
if (parent && parent->IsNodeOfType(nsINode::eELEMENT)) { nsIContent* parent = *(mTwo.node);
nsIContent* table = *(mThree.node);
nsIContent* foster = table->GetParent();
if (foster && foster->IsNodeOfType(nsINode::eELEMENT)) {
aBuilder->FlushPendingAppendNotifications(); aBuilder->FlushPendingAppendNotifications();
PRUint32 pos = parent->IndexOf(mTable); PRUint32 pos = foster->IndexOf(table);
rv = parent->InsertChildAt(mNode, pos, PR_FALSE); rv = foster->InsertChildAt(node, pos, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::ContentInserted(parent, mNode, pos); nsNodeUtils::ContentInserted(foster, node, pos);
} else { } else {
aBuilder->PostPendingAppendNotification(mParent, mNode); aBuilder->PostPendingAppendNotification(parent, node);
rv = mParent->AppendChildTo(mNode, PR_FALSE); rv = parent->AppendChildTo(node, PR_FALSE);
} }
return rv; return rv;
} }
case eTreeOpAppendToDocument: { case eTreeOpAppendToDocument: {
nsIContent* node = *(mOne.node);
aBuilder->FlushPendingAppendNotifications(); aBuilder->FlushPendingAppendNotifications();
nsIDocument* doc = aBuilder->GetDocument(); nsIDocument* doc = aBuilder->GetDocument();
PRUint32 childCount = doc->GetChildCount(); PRUint32 childCount = doc->GetChildCount();
rv = doc->AppendChildTo(mNode, PR_FALSE); rv = doc->AppendChildTo(node, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::ContentInserted(doc, mNode, childCount); nsNodeUtils::ContentInserted(doc, node, childCount);
return rv; return rv;
} }
case eTreeOpAddAttributes: { case eTreeOpAddAttributes: {
// mNode holds the new attributes and mParent is the target nsIContent* node = *(mOne.node);
nsIDocument* document = mParent->GetCurrentDoc(); nsHtml5HtmlAttributes* attributes = mTwo.attributes;
PRUint32 len = mNode->GetAttrCount(); nsIDocument* document = node->GetCurrentDoc();
for (PRUint32 i = 0; i < len; ++i) {
const nsAttrName* attrName = mNode->GetAttrNameAt(i); PRInt32 len = attributes->getLength();
nsIAtom* localName = attrName->LocalName(); for (PRInt32 i = 0; i < len; ++i) {
PRInt32 nsuri = attrName->NamespaceID(); // prefix doesn't need regetting. it is always null or a static atom
if (!mParent->HasAttr(nsuri, localName)) { // local name is never null
nsAutoString value; nsCOMPtr<nsIAtom> localName = Reget(attributes->getLocalName(i));
mNode->GetAttr(nsuri, localName, value); PRInt32 nsuri = attributes->getURI(i);
if (!node->HasAttr(nsuri, localName)) {
// the manual notification code is based on nsGenericElement // the manual notification code is based on nsGenericElement
PRUint32 stateMask = PRUint32(mParent->IntrinsicState()); PRUint32 stateMask = PRUint32(node->IntrinsicState());
nsNodeUtils::AttributeWillChange(mParent, nsNodeUtils::AttributeWillChange(node,
nsuri, nsuri,
localName, localName,
static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION)); static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION));
mParent->SetAttr(nsuri, localName, attrName->GetPrefix(), value, PR_FALSE); // prefix doesn't need regetting. it is always null or a static atom
// local name is never null
node->SetAttr(nsuri, localName, attributes->getPrefix(i), *(attributes->getValue(i)), PR_FALSE);
// XXX what to do with nsresult?
if (document || mParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) { if (document || node->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
nsIDocument* ownerDoc = mParent->GetOwnerDoc(); nsIDocument* ownerDoc = node->GetOwnerDoc();
if (ownerDoc) { if (ownerDoc) {
nsRefPtr<nsXBLBinding> binding = nsRefPtr<nsXBLBinding> binding =
ownerDoc->BindingManager()->GetBinding(mParent); ownerDoc->BindingManager()->GetBinding(node);
if (binding) { if (binding) {
binding->AttributeChanged(localName, nsuri, PR_FALSE, PR_FALSE); binding->AttributeChanged(localName, nsuri, PR_FALSE, PR_FALSE);
} }
} }
} }
stateMask = stateMask ^ PRUint32(mParent->IntrinsicState()); stateMask ^= PRUint32(node->IntrinsicState());
if (stateMask && document) { if (stateMask && document) {
MOZ_AUTO_DOC_UPDATE(document, UPDATE_CONTENT_STATE, PR_TRUE); MOZ_AUTO_DOC_UPDATE(document, UPDATE_CONTENT_STATE, PR_TRUE);
document->ContentStatesChanged(mParent, nsnull, stateMask); document->ContentStatesChanged(node, nsnull, stateMask);
} }
nsNodeUtils::AttributeChanged(mParent, nsNodeUtils::AttributeChanged(node,
nsuri, nsuri,
localName, localName,
static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION), static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION),
stateMask); stateMask);
} }
} }
return rv;
}
case eTreeOpCreateElement: {
nsIContent** target = mOne.node;
PRInt32 ns = mInt;
nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
nsHtml5HtmlAttributes* attributes = mThree.attributes;
nsCOMPtr<nsIContent> newContent;
nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->GetNodeInfo(name, nsnull, ns);
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
NS_NewElement(getter_AddRefs(newContent), nodeInfo->NamespaceID(), nodeInfo, PR_TRUE);
NS_ASSERTION(newContent, "Element creation created null pointer.");
aBuilder->HoldElement(*target = newContent);
if (!attributes) {
return rv;
}
PRInt32 len = attributes->getLength();
for (PRInt32 i = 0; i < len; ++i) {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
nsCOMPtr<nsIAtom> localName = Reget(attributes->getLocalName(i));
newContent->SetAttr(attributes->getURI(i), localName, attributes->getPrefix(i), *(attributes->getValue(i)), PR_FALSE);
// XXX what to do with nsresult?
}
if (ns != kNameSpaceID_MathML && (name == nsHtml5Atoms::style || (ns == kNameSpaceID_XHTML && name == nsHtml5Atoms::link))) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
}
return rv;
}
case eTreeOpSetFormElement: {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node));
NS_ASSERTION(formControl, "Form-associated element did not implement nsIFormControl.");
nsCOMPtr<nsIDOMHTMLFormElement> formElement(do_QueryInterface(parent));
NS_ASSERTION(formElement, "The form element doesn't implement nsIDOMHTMLFormElement.");
if (formControl) { // avoid crashing on <output>
formControl->SetForm(formElement);
}
return rv;
}
case eTreeOpCreateTextNode: {
nsIContent** target = mOne.node;
PRUnichar* buffer = mTwo.unicharPtr;
PRInt32 length = mInt;
nsCOMPtr<nsIContent> text;
NS_NewTextNode(getter_AddRefs(text), aBuilder->GetNodeInfoManager());
// XXX nsresult and comment null check?
text->SetText(buffer, length, PR_FALSE);
// XXX nsresult
aBuilder->HoldNonElement(*target = text);
return rv;
}
case eTreeOpCreateComment: {
nsIContent** target = mOne.node;
PRUnichar* buffer = mTwo.unicharPtr;
PRInt32 length = mInt;
nsCOMPtr<nsIContent> comment;
NS_NewCommentNode(getter_AddRefs(comment), aBuilder->GetNodeInfoManager());
// XXX nsresult and comment null check?
comment->SetText(buffer, length, PR_FALSE);
// XXX nsresult
aBuilder->HoldNonElement(*target = comment);
return rv;
}
case eTreeOpCreateDoctype: {
nsCOMPtr<nsIAtom> name = Reget(mOne.atom);
nsHtml5TreeOperationStringPair* pair = mTwo.stringPair;
nsString publicId;
nsString systemId;
pair->Get(publicId, systemId);
nsIContent** target = mThree.node;
// Adapted from nsXMLContentSink
// Create a new doctype node
nsCOMPtr<nsIDOMDocumentType> docType;
nsAutoString voidString;
voidString.SetIsVoid(PR_TRUE);
NS_NewDOMDocumentType(getter_AddRefs(docType),
aBuilder->GetNodeInfoManager(),
nsnull,
name,
nsnull,
nsnull,
publicId,
systemId,
voidString);
NS_ASSERTION(docType, "Doctype creation failed.");
nsCOMPtr<nsIContent> asContent = do_QueryInterface(docType);
aBuilder->HoldNonElement(*target = asContent);
return rv;
}
case eTreeOpRunScript: {
nsIContent* node = *(mOne.node);
aBuilder->SetScriptElement(node);
return rv; return rv;
} }
case eTreeOpDoneAddingChildren: { case eTreeOpDoneAddingChildren: {
mNode->DoneAddingChildren(aBuilder->HaveNotified(mNode)); nsIContent* node = *(mOne.node);
node->DoneAddingChildren(aBuilder->HaveNotified(node));
return rv; return rv;
} }
case eTreeOpDoneCreatingElement: { case eTreeOpDoneCreatingElement: {
mNode->DoneCreatingElement(); nsIContent* node = *(mOne.node);
node->DoneCreatingElement();
return rv; return rv;
} }
case eTreeOpUpdateStyleSheet: { case eTreeOpUpdateStyleSheet: {
aBuilder->UpdateStyleSheet(mNode); nsIContent* node = *(mOne.node);
aBuilder->UpdateStyleSheet(node);
return rv; return rv;
} }
case eTreeOpProcessBase: { case eTreeOpProcessBase: {
rv = aBuilder->ProcessBASETag(mNode); nsIContent* node = *(mOne.node);
rv = aBuilder->ProcessBASETag(node);
return rv; return rv;
} }
case eTreeOpProcessMeta: { case eTreeOpProcessMeta: {
rv = aBuilder->ProcessMETATag(mNode); nsIContent* node = *(mOne.node);
rv = aBuilder->ProcessMETATag(node);
return rv; return rv;
} }
case eTreeOpProcessOfflineManifest: { case eTreeOpProcessOfflineManifest: {
aBuilder->ProcessOfflineManifest(mNode); nsIContent* node = *(mOne.node);
aBuilder->ProcessOfflineManifest(node);
return rv;
}
case eTreeOpMarkMalformedIfScript: {
nsIContent* node = *(mOne.node);
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(node);
if (sele) {
// Make sure to serialize this script correctly, for nice round tripping.
sele->SetIsMalformed();
}
return rv; return rv;
} }
case eTreeOpStartLayout: { case eTreeOpStartLayout: {
@ -198,7 +360,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder)
return rv; return rv;
} }
case eTreeOpDocumentMode: { case eTreeOpDocumentMode: {
aBuilder->DocumentMode(mMode); aBuilder->DocumentMode(mOne.mode);
return rv; return rv;
} }
default: { default: {

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

@ -40,6 +40,7 @@
#include "nsIContent.h" #include "nsIContent.h"
#include "nsHtml5DocumentMode.h" #include "nsHtml5DocumentMode.h"
#include "nsHtml5HtmlAttributes.h"
class nsHtml5TreeOpExecutor; class nsHtml5TreeOpExecutor;
@ -52,16 +53,45 @@ enum eHtml5TreeOperation {
eTreeOpAppendToDocument, eTreeOpAppendToDocument,
eTreeOpAddAttributes, eTreeOpAddAttributes,
eTreeOpDocumentMode, eTreeOpDocumentMode,
eTreeOpCreateElement,
eTreeOpSetFormElement,
eTreeOpCreateTextNode,
eTreeOpCreateComment,
eTreeOpCreateDoctype,
// Gecko-specific on-pop ops // Gecko-specific on-pop ops
eTreeOpRunScript,
eTreeOpDoneAddingChildren, eTreeOpDoneAddingChildren,
eTreeOpDoneCreatingElement, eTreeOpDoneCreatingElement,
eTreeOpUpdateStyleSheet, eTreeOpUpdateStyleSheet,
eTreeOpProcessBase, eTreeOpProcessBase,
eTreeOpProcessMeta, eTreeOpProcessMeta,
eTreeOpProcessOfflineManifest, eTreeOpProcessOfflineManifest,
eTreeOpMarkMalformedIfScript,
eTreeOpStartLayout eTreeOpStartLayout
}; };
class nsHtml5TreeOperationStringPair {
private:
nsString mPublicId;
nsString mSystemId;
public:
nsHtml5TreeOperationStringPair(const nsAString& aPublicId,
const nsAString& aSystemId)
: mPublicId(aPublicId)
, mSystemId(aSystemId) {
MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair);
}
~nsHtml5TreeOperationStringPair() {
MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair);
}
inline void Get(nsAString& aPublicId, nsAString& aSystemId) {
aPublicId.Assign(mPublicId);
aSystemId.Assign(mSystemId);
}
};
class nsHtml5TreeOperation { class nsHtml5TreeOperation {
public: public:
@ -69,54 +99,113 @@ class nsHtml5TreeOperation {
~nsHtml5TreeOperation(); ~nsHtml5TreeOperation();
inline void Init(nsIContent* aNode, nsIContent* aParent) { inline void Init(nsIContent** aNode, nsIContent** aParent) {
mNode = aNode; mOne.node = aNode;
mParent = aParent; mTwo.node = aParent;
} }
inline void Init(eHtml5TreeOperation aOpCode, nsIContent* aNode) { inline void Init(eHtml5TreeOperation aOpCode, nsIContent** aNode) {
mOpCode = aOpCode; mOpCode = aOpCode;
mNode = aNode; mOne.node = aNode;
} }
inline void Init(eHtml5TreeOperation aOpCode, inline void Init(eHtml5TreeOperation aOpCode,
nsIContent* aNode, nsIContent** aNode,
nsIContent* aParent) { nsIContent** aParent) {
mOpCode = aOpCode; mOpCode = aOpCode;
mNode = aNode; mOne.node = aNode;
mParent = aParent; mTwo.node = aParent;
} }
inline void Init(eHtml5TreeOperation aOpCode, inline void Init(eHtml5TreeOperation aOpCode,
nsIContent* aNode, nsIContent** aNode,
nsIContent* aParent, nsIContent** aParent,
nsIContent* aTable) { nsIContent** aTable) {
mOpCode = aOpCode; mOpCode = aOpCode;
mNode = aNode; mOne.node = aNode;
mParent = aParent; mTwo.node = aParent;
mTable = aTable; mThree.node = aTable;
} }
inline void Init(nsHtml5DocumentMode aMode) { inline void Init(nsHtml5DocumentMode aMode) {
mOpCode = eTreeOpDocumentMode; mOpCode = eTreeOpDocumentMode;
mMode = aMode; mOne.mode = aMode;
} }
inline void DoTraverse(nsCycleCollectionTraversalCallback &cb) { inline void Init(PRInt32 aNamespace,
nsHtml5TreeOperation* tmp = this; nsIAtom* aName,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNode); nsHtml5HtmlAttributes* aAttributes,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent); nsIContent** aTarget) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTable); mOpCode = eTreeOpCreateElement;
mInt = aNamespace;
mOne.node = aTarget;
mTwo.atom = aName;
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
mThree.attributes = nsnull;
} else {
mThree.attributes = aAttributes;
}
}
inline void Init(eHtml5TreeOperation aOpCode,
PRUnichar* aBuffer,
PRInt32 aLength,
nsIContent** aTarget) {
mOpCode = aOpCode;
mOne.node = aTarget;
mTwo.unicharPtr = aBuffer;
mInt = aLength;
}
inline void Init(nsIContent** aElement,
nsHtml5HtmlAttributes* aAttributes) {
mOpCode = eTreeOpAddAttributes;
mOne.node = aElement;
mTwo.attributes = aAttributes;
}
inline void Init(nsIAtom* aName,
const nsAString& aPublicId,
const nsAString& aSystemId, nsIContent** aTarget) {
mOpCode = eTreeOpCreateDoctype;
mOne.atom = aName;
mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
mThree.node = aTarget;
}
inline PRBool IsRunScript() {
return mOpCode == eTreeOpRunScript;
} }
nsresult Perform(nsHtml5TreeOpExecutor* aBuilder); nsresult Perform(nsHtml5TreeOpExecutor* aBuilder);
inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom) {
if (!aAtom || aAtom->IsStaticAtom()) {
return aAtom;
}
nsAutoString str;
aAtom->ToString(str);
return do_GetAtom(str);
}
private: private:
// possible optimization:
// Make the queue take items the size of pointer and make the op code
// decide how many operands it dequeues after it.
eHtml5TreeOperation mOpCode; eHtml5TreeOperation mOpCode;
nsCOMPtr<nsIContent> mNode; union {
nsCOMPtr<nsIContent> mParent; nsIContent** node;
nsCOMPtr<nsIContent> mTable; nsIAtom* atom;
nsHtml5DocumentMode mMode; // space-wasting temporary solution nsHtml5HtmlAttributes* attributes;
nsHtml5DocumentMode mode;
PRUnichar* unicharPtr;
nsHtml5TreeOperationStringPair* stringPair;
} mOne, mTwo, mThree;
PRInt32 mInt; // optimize this away later by using an end
// pointer instead of string length and distinct
// element creation opcodes for HTML, MathML and
// SVG.
}; };
#endif // nsHtml5TreeOperation_h__ #endif // nsHtml5TreeOperation_h__

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

@ -29,6 +29,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"

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

@ -30,6 +30,7 @@
#include "prtypes.h" #include "prtypes.h"
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"