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

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

@ -30,6 +30,7 @@
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsINameSpaceManager.h"
#include "nsIContent.h"
@ -74,7 +75,7 @@ class nsHtml5AttributeName
static nsIAtom** COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix);
public:
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:
static PRInt32 bufToHash(PRUnichar* buf, PRInt32 len);
PRInt32* uri;

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -59,6 +59,7 @@
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5Parser.h"
#include "nsHtml5AtomTable.h"
//-------------- 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_NSCOMPTR_AMBIGUOUS(mExecutor, nsIContentSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mStreamParser, nsIStreamListener)
tmp->mTreeBuilder->DoTraverse(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExecutor)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mStreamParser)
tmp->mTreeBuilder->DoUnlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsHtml5Parser::nsHtml5Parser()
@ -111,8 +110,11 @@ nsHtml5Parser::nsHtml5Parser()
, mExecutor(new nsHtml5TreeOpExecutor())
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
, mAtomTable(new nsHtml5AtomTable())
{
mExecutor->SetTreeBuilder(mTreeBuilder);
mAtomTable->Init(); // we aren't checking for OOM anyway...
mTokenizer->setInterner(mAtomTable);
// There's a zeroing operator new for everything else
}
@ -455,7 +457,10 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
nsIURI* uri = doc->GetDocumentURI();
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
mExecutor->SetBaseUriFromDocument();
@ -463,7 +468,8 @@ nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
mExecutor->SetParser(this);
mExecutor->SetNodeInfoManager(target->GetOwnerDoc()->NodeInfoManager());
mTreeBuilder->setFragmentContext(aContextLocalName, aContextNamespace, target, aQuirks);
nsIContent* weakTarget = target;
mTreeBuilder->setFragmentContext(aContextLocalName, aContextNamespace, &weakTarget, aQuirks);
mFragmentMode = PR_TRUE;
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();
mTokenizer->end();
mExecutor->DropParserAndPerfHint();
mAtomTable->Clear();
return NS_OK;
}
@ -518,6 +525,7 @@ nsHtml5Parser::Reset()
mStreamParser = nsnull;
mRootContextKey = nsnull;
mContinueEvent = nsnull; // weak ref
mAtomTable->Clear(); // should be already cleared in the fragment case anyway
// Portable parser objects
while (mFirstBuffer->next) {
nsHtml5UTF16Buffer* oldBuf = mFirstBuffer;

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

@ -60,6 +60,7 @@
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5StreamParser.h"
#include "nsHtml5AtomTable.h"
class nsHtml5Parser : public nsIParser {
public:
@ -338,7 +339,7 @@ class nsHtml5Parser : public nsIParser {
/**
* The tree operation executor
*/
nsRefPtr<nsHtml5TreeOpExecutor> mExecutor;
nsRefPtr<nsHtml5TreeOpExecutor> mExecutor;
/**
* The HTML5 tree builder
@ -353,7 +354,12 @@ class nsHtml5Parser : public nsIParser {
/**
* The stream parser.
*/
nsRefPtr<nsHtml5StreamParser> mStreamParser;
nsRefPtr<nsHtml5StreamParser> mStreamParser;
/**
* The scoped atom service
*/
const nsAutoPtr<nsHtml5AtomTable> mAtomTable;
};
#endif

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

@ -42,10 +42,11 @@
#include "nsHtml5Portability.h"
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.");
return NS_NewAtom(nsDependentSubstring(buf, buf + length));
NS_ASSERTION(interner, "Didn't get an atom service.");
return interner->GetAtom(nsDependentSubstring(buf, buf + length));
}
nsString*
@ -101,28 +102,28 @@ nsHtml5Portability::releaseString(nsString* str)
delete str;
}
// XXX useless code
void
nsHtml5Portability::retainLocal(nsIAtom* local)
{
NS_IF_ADDREF(local);
}
// XXX useless code
void
nsHtml5Portability::releaseLocal(nsIAtom* local)
{
NS_IF_RELEASE(local);
}
// XXX Useless code
void
nsHtml5Portability::retainElement(nsIContent* element)
nsHtml5Portability::retainElement(nsIContent** element)
{
NS_IF_ADDREF(element);
}
// XXX Useless code
void
nsHtml5Portability::releaseElement(nsIContent* element)
nsHtml5Portability::releaseElement(nsIContent** element)
{
NS_IF_RELEASE(element);
}
PRBool

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

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

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

@ -30,6 +30,7 @@
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsINameSpaceManager.h"
#include "nsIContent.h"
@ -56,7 +57,7 @@
#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),
name(name),
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),
name(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),
name(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),
name(elementName->name),
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),
name(elementName->name),
popName(popName),
@ -192,5 +193,3 @@ nsHtml5StackNode::releaseStatics()
}
#include "nsHtml5StackNodeCppSupplement.h"

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

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

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

@ -30,6 +30,7 @@
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsINameSpaceManager.h"
#include "nsIContent.h"
@ -58,10 +59,10 @@ class nsHtml5Portability;
class nsHtml5StateSnapshot
{
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> listOfActiveFormattingElements;
nsIContent* formPointer;
nsIContent** formPointer;
~nsHtml5StateSnapshot();
static void initializeStatics();
static void releaseStatics();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -74,19 +74,22 @@ NS_IMPL_ADDREF_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
NS_IMPL_RELEASE_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_NSCOMARRAY(mOwnedElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mOwnedNonElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
if (tmp->mFlushTimer) {
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_NSCOMARRAY(mOwnedElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mOwnedNonElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
: mSuppressEOF(PR_FALSE)
, mHasProcessedBase(PR_FALSE)
@ -504,12 +507,14 @@ nsHtml5TreeOpExecutor::MaybeSuspend() {
void
nsHtml5TreeOpExecutor::MaybeExecuteScript() {
if (mScriptElement) {
// mUninterruptibleDocWrite = PR_FALSE;
ExecuteScript();
if (mStreamParser) {
mStreamParser->Suspend();
}
if (!mTreeBuilder->HasScript()) {
return;
}
Flush(); // Let the doc update end before we start executing the script
NS_ASSERTION(mScriptElement, "No script to run");
ExecuteScript();
if (mStreamParser) {
mStreamParser->Suspend();
}
}

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

@ -53,6 +53,7 @@
#include "nsITimer.h"
#include "nsIScriptElement.h"
#include "nsIParser.h"
#include "nsCOMArray.h"
class nsHtml5TreeBuilder;
class nsHtml5Tokenizer;
@ -112,6 +113,12 @@ class nsHtml5TreeOpExecutor : public nsIContentSink,
nsTArray<nsIContentPtr> mElementsSeenInThisAppendBatch;
nsTArray<nsHtml5PendingNotification> mPendingNotifications;
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
@ -244,6 +251,10 @@ class nsHtml5TreeOpExecutor : public nsIContentSink,
*/
nsresult MaybePerformCharsetSwitch();
inline void SetScriptElement(nsIContent* aScript) {
mScriptElement = aScript;
}
/**
* Runs mScriptElement
*/
@ -376,19 +387,20 @@ class nsHtml5TreeOpExecutor : public nsIContentSink,
mScriptElement = nsnull;
}
}
/**
* Request execution of the script element when the tokenizer returns
*/
void SetScriptElement(nsIContent* aScript) {
mScriptElement = aScript;
}
void SetTreeBuilder(nsHtml5TreeBuilder* aBuilder) {
mTreeBuilder = aBuilder;
}
void Reset();
inline void HoldElement(nsIContent* aContent) {
mOwnedElements.AppendObject(aContent);
}
inline void HoldNonElement(nsIContent* aContent) {
mOwnedNonElements.AppendObject(aContent);
}
private:

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

@ -48,6 +48,15 @@
#include "nsBindingManager.h"
#include "nsXBLBinding.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()
: mOpCode(eTreeOpAppend)
@ -58,6 +67,23 @@ nsHtml5TreeOperation::nsHtml5TreeOperation()
nsHtml5TreeOperation::~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
@ -66,15 +92,18 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder)
nsresult rv = NS_OK;
switch(mOpCode) {
case eTreeOpAppend: {
aBuilder->PostPendingAppendNotification(mParent, mNode);
rv = mParent->AppendChildTo(mNode, PR_FALSE);
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
aBuilder->PostPendingAppendNotification(parent, node);
rv = parent->AppendChildTo(node, PR_FALSE);
return rv;
}
case eTreeOpDetach: {
nsIContent* node = *(mOne.node);
aBuilder->FlushPendingAppendNotifications();
nsIContent* parent = mNode->GetParent();
nsIContent* parent = node->GetParent();
if (parent) {
PRUint32 pos = parent->IndexOf(mNode);
PRUint32 pos = parent->IndexOf(node);
NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
rv = parent->RemoveChildAt(pos, PR_TRUE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
@ -82,115 +111,248 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder)
return rv;
}
case eTreeOpAppendChildrenToNewParent: {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
aBuilder->FlushPendingAppendNotifications();
PRUint32 childCount = mParent->GetChildCount();
PRUint32 childCount = parent->GetChildCount();
PRBool didAppend = PR_FALSE;
while (mNode->GetChildCount()) {
nsCOMPtr<nsIContent> child = mNode->GetChildAt(0);
rv = mNode->RemoveChildAt(0, PR_TRUE, PR_FALSE);
while (node->GetChildCount()) {
nsCOMPtr<nsIContent> child = node->GetChildAt(0);
rv = node->RemoveChildAt(0, PR_TRUE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = mParent->AppendChildTo(child, PR_FALSE);
rv = parent->AppendChildTo(child, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
didAppend = PR_TRUE;
}
if (didAppend) {
nsNodeUtils::ContentAppended(mParent, childCount);
nsNodeUtils::ContentAppended(parent, childCount);
}
return rv;
}
case eTreeOpFosterParent: {
nsIContent* parent = mTable->GetParent();
if (parent && parent->IsNodeOfType(nsINode::eELEMENT)) {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
nsIContent* table = *(mThree.node);
nsIContent* foster = table->GetParent();
if (foster && foster->IsNodeOfType(nsINode::eELEMENT)) {
aBuilder->FlushPendingAppendNotifications();
PRUint32 pos = parent->IndexOf(mTable);
rv = parent->InsertChildAt(mNode, pos, PR_FALSE);
PRUint32 pos = foster->IndexOf(table);
rv = foster->InsertChildAt(node, pos, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::ContentInserted(parent, mNode, pos);
nsNodeUtils::ContentInserted(foster, node, pos);
} else {
aBuilder->PostPendingAppendNotification(mParent, mNode);
rv = mParent->AppendChildTo(mNode, PR_FALSE);
aBuilder->PostPendingAppendNotification(parent, node);
rv = parent->AppendChildTo(node, PR_FALSE);
}
return rv;
}
case eTreeOpAppendToDocument: {
nsIContent* node = *(mOne.node);
aBuilder->FlushPendingAppendNotifications();
nsIDocument* doc = aBuilder->GetDocument();
PRUint32 childCount = doc->GetChildCount();
rv = doc->AppendChildTo(mNode, PR_FALSE);
rv = doc->AppendChildTo(node, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::ContentInserted(doc, mNode, childCount);
nsNodeUtils::ContentInserted(doc, node, childCount);
return rv;
}
case eTreeOpAddAttributes: {
// mNode holds the new attributes and mParent is the target
nsIDocument* document = mParent->GetCurrentDoc();
PRUint32 len = mNode->GetAttrCount();
for (PRUint32 i = 0; i < len; ++i) {
const nsAttrName* attrName = mNode->GetAttrNameAt(i);
nsIAtom* localName = attrName->LocalName();
PRInt32 nsuri = attrName->NamespaceID();
if (!mParent->HasAttr(nsuri, localName)) {
nsAutoString value;
mNode->GetAttr(nsuri, localName, value);
nsIContent* node = *(mOne.node);
nsHtml5HtmlAttributes* attributes = mTwo.attributes;
nsIDocument* document = node->GetCurrentDoc();
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));
PRInt32 nsuri = attributes->getURI(i);
if (!node->HasAttr(nsuri, localName)) {
// the manual notification code is based on nsGenericElement
PRUint32 stateMask = PRUint32(mParent->IntrinsicState());
nsNodeUtils::AttributeWillChange(mParent,
PRUint32 stateMask = PRUint32(node->IntrinsicState());
nsNodeUtils::AttributeWillChange(node,
nsuri,
localName,
static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION));
// 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?
mParent->SetAttr(nsuri, localName, attrName->GetPrefix(), value, PR_FALSE);
if (document || mParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
nsIDocument* ownerDoc = mParent->GetOwnerDoc();
if (document || node->HasFlag(NODE_FORCE_XBL_BINDINGS)) {
nsIDocument* ownerDoc = node->GetOwnerDoc();
if (ownerDoc) {
nsRefPtr<nsXBLBinding> binding =
ownerDoc->BindingManager()->GetBinding(mParent);
ownerDoc->BindingManager()->GetBinding(node);
if (binding) {
binding->AttributeChanged(localName, nsuri, PR_FALSE, PR_FALSE);
}
}
}
stateMask = stateMask ^ PRUint32(mParent->IntrinsicState());
stateMask ^= PRUint32(node->IntrinsicState());
if (stateMask && document) {
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,
localName,
static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION),
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;
}
case eTreeOpDoneAddingChildren: {
mNode->DoneAddingChildren(aBuilder->HaveNotified(mNode));
nsIContent* node = *(mOne.node);
node->DoneAddingChildren(aBuilder->HaveNotified(node));
return rv;
}
case eTreeOpDoneCreatingElement: {
mNode->DoneCreatingElement();
nsIContent* node = *(mOne.node);
node->DoneCreatingElement();
return rv;
}
case eTreeOpUpdateStyleSheet: {
aBuilder->UpdateStyleSheet(mNode);
nsIContent* node = *(mOne.node);
aBuilder->UpdateStyleSheet(node);
return rv;
}
case eTreeOpProcessBase: {
rv = aBuilder->ProcessBASETag(mNode);
nsIContent* node = *(mOne.node);
rv = aBuilder->ProcessBASETag(node);
return rv;
}
case eTreeOpProcessMeta: {
rv = aBuilder->ProcessMETATag(mNode);
nsIContent* node = *(mOne.node);
rv = aBuilder->ProcessMETATag(node);
return rv;
}
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;
}
case eTreeOpStartLayout: {
@ -198,7 +360,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder)
return rv;
}
case eTreeOpDocumentMode: {
aBuilder->DocumentMode(mMode);
aBuilder->DocumentMode(mOne.mode);
return rv;
}
default: {

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

@ -40,6 +40,7 @@
#include "nsIContent.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5HtmlAttributes.h"
class nsHtml5TreeOpExecutor;
@ -52,16 +53,45 @@ enum eHtml5TreeOperation {
eTreeOpAppendToDocument,
eTreeOpAddAttributes,
eTreeOpDocumentMode,
eTreeOpCreateElement,
eTreeOpSetFormElement,
eTreeOpCreateTextNode,
eTreeOpCreateComment,
eTreeOpCreateDoctype,
// Gecko-specific on-pop ops
eTreeOpRunScript,
eTreeOpDoneAddingChildren,
eTreeOpDoneCreatingElement,
eTreeOpUpdateStyleSheet,
eTreeOpProcessBase,
eTreeOpProcessMeta,
eTreeOpProcessOfflineManifest,
eTreeOpMarkMalformedIfScript,
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 {
public:
@ -69,54 +99,113 @@ class nsHtml5TreeOperation {
~nsHtml5TreeOperation();
inline void Init(nsIContent* aNode, nsIContent* aParent) {
mNode = aNode;
mParent = aParent;
inline void Init(nsIContent** aNode, nsIContent** aParent) {
mOne.node = aNode;
mTwo.node = aParent;
}
inline void Init(eHtml5TreeOperation aOpCode, nsIContent* aNode) {
inline void Init(eHtml5TreeOperation aOpCode, nsIContent** aNode) {
mOpCode = aOpCode;
mNode = aNode;
mOne.node = aNode;
}
inline void Init(eHtml5TreeOperation aOpCode,
nsIContent* aNode,
nsIContent* aParent) {
nsIContent** aNode,
nsIContent** aParent) {
mOpCode = aOpCode;
mNode = aNode;
mParent = aParent;
mOne.node = aNode;
mTwo.node = aParent;
}
inline void Init(eHtml5TreeOperation aOpCode,
nsIContent* aNode,
nsIContent* aParent,
nsIContent* aTable) {
nsIContent** aNode,
nsIContent** aParent,
nsIContent** aTable) {
mOpCode = aOpCode;
mNode = aNode;
mParent = aParent;
mTable = aTable;
mOne.node = aNode;
mTwo.node = aParent;
mThree.node = aTable;
}
inline void Init(nsHtml5DocumentMode aMode) {
mOpCode = eTreeOpDocumentMode;
mMode = aMode;
mOne.mode = aMode;
}
inline void Init(PRInt32 aNamespace,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aTarget) {
mOpCode = eTreeOpCreateElement;
mInt = aNamespace;
mOne.node = aTarget;
mTwo.atom = aName;
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
mThree.attributes = nsnull;
} else {
mThree.attributes = aAttributes;
}
}
inline void DoTraverse(nsCycleCollectionTraversalCallback &cb) {
nsHtml5TreeOperation* tmp = this;
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNode);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTable);
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);
inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom) {
if (!aAtom || aAtom->IsStaticAtom()) {
return aAtom;
}
nsAutoString str;
aAtom->ToString(str);
return do_GetAtom(str);
}
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;
nsCOMPtr<nsIContent> mNode;
nsCOMPtr<nsIContent> mParent;
nsCOMPtr<nsIContent> mTable;
nsHtml5DocumentMode mMode; // space-wasting temporary solution
union {
nsIContent** node;
nsIAtom* atom;
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__

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

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

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

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