Bug 516406 - Make document.write() parser and stream parser have distinct tokenizers in the HTML5 parser. r=bnewman.

This commit is contained in:
Henri Sivonen
2009-09-21 16:18:20 +03:00
parent 4384f2fdf0
commit 2cf48a3ad5
39 changed files with 1546 additions and 614 deletions

View File

@@ -45,6 +45,7 @@
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5MetaScanner.h"
@@ -74,9 +75,12 @@ nsHtml5Tokenizer::nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler)
encodingDeclarationHandler(nsnull),
bmpChar(jArray<PRUnichar,PRInt32>(1)),
astralChar(jArray<PRUnichar,PRInt32>(2)),
attributes(nsnull),
tagName(nsnull),
attributeName(nsnull)
attributeName(nsnull),
doctypeName(nsnull),
publicIdentifier(nsnull),
systemIdentifier(nsnull),
attributes(nsnull)
{
MOZ_COUNT_CTOR(nsHtml5Tokenizer);
}
@@ -400,6 +404,7 @@ nsHtml5Tokenizer::addAttributeWithoutValue()
if (!!attributeName) {
attributes->addAttribute(attributeName, nsHtml5Portability::newEmptyString());
attributeName = nsnull;
}
}
@@ -409,6 +414,7 @@ nsHtml5Tokenizer::addAttributeWithValue()
if (!!attributeName) {
nsString* value = longStrBufToString();
attributes->addAttribute(attributeName, value);
attributeName = nsnull;
}
}
@@ -420,39 +426,8 @@ nsHtml5Tokenizer::startErrorReporting()
void
nsHtml5Tokenizer::start()
{
confident = PR_FALSE;
strBuf = jArray<PRUnichar,PRInt32>(64);
strBufLen = 0;
longStrBuf = jArray<PRUnichar,PRInt32>(1024);
longStrBufLen = 0;
stateSave = NS_HTML5TOKENIZER_DATA;
line = 1;
lastCR = PR_FALSE;
initializeWithoutStarting();
tokenHandler->startTokenization(this);
index = 0;
forceQuirks = PR_FALSE;
additional = '\0';
entCol = -1;
lo = 0;
hi = (nsHtml5NamedCharacters::NAMES.length - 1);
candidate = -1;
strBufMark = 0;
prevValue = -1;
value = 0;
seenDigits = PR_FALSE;
shouldSuspend = PR_FALSE;
if (!!tagName) {
tagName->release();
tagName = nsnull;
}
if (!!attributeName) {
attributeName->release();
attributeName = nsnull;
}
if (!!attributes) {
delete attributes;
attributes = nsnull;
}
}
PRBool
@@ -948,7 +923,7 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
}
case '&': {
clearStrBufAndAppendCurrentC(c);
rememberAmpersandLocation('\0');
rememberAmpersandLocation('>');
returnState = state;
state = NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE;
goto stateloop;
@@ -2894,6 +2869,22 @@ nsHtml5Tokenizer::stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar*
return pos;
}
void
nsHtml5Tokenizer::initDoctypeFields()
{
nsHtml5Portability::releaseLocal(doctypeName);
doctypeName = nsHtml5Atoms::emptystring;
if (!!systemIdentifier) {
nsHtml5Portability::releaseString(systemIdentifier);
systemIdentifier = nsnull;
}
if (!!publicIdentifier) {
nsHtml5Portability::releaseString(publicIdentifier);
publicIdentifier = nsnull;
}
forceQuirks = PR_FALSE;
}
void
nsHtml5Tokenizer::emitCarriageReturn(PRUnichar* buf, PRInt32 pos)
{
@@ -3057,9 +3048,16 @@ nsHtml5Tokenizer::eof()
emitComment(0, 0);
} else {
nsHtml5Portability::releaseLocal(doctypeName);
doctypeName = nsHtml5Atoms::emptystring;
publicIdentifier = nsnull;
systemIdentifier = nsnull;
if (!!systemIdentifier) {
nsHtml5Portability::releaseString(systemIdentifier);
systemIdentifier = nsnull;
}
if (!!publicIdentifier) {
nsHtml5Portability::releaseString(publicIdentifier);
publicIdentifier = nsnull;
}
forceQuirks = PR_TRUE;
emitDoctypeToken(0);
goto eofloop_end;
@@ -3268,8 +3266,11 @@ nsHtml5Tokenizer::emitDoctypeToken(PRInt32 pos)
cstart = pos + 1;
tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier, forceQuirks);
nsHtml5Portability::releaseLocal(doctypeName);
doctypeName = nsnull;
nsHtml5Portability::releaseString(publicIdentifier);
publicIdentifier = nsnull;
nsHtml5Portability::releaseString(systemIdentifier);
systemIdentifier = nsnull;
}
void
@@ -3303,11 +3304,20 @@ nsHtml5Tokenizer::emitOrAppendOne(PRUnichar* val, PRInt32 returnState)
void
nsHtml5Tokenizer::end()
{
strBuf.release();
strBuf = nsnull;
longStrBuf.release();
longStrBuf = nsnull;
systemIdentifier = nsnull;
publicIdentifier = nsnull;
nsHtml5Portability::releaseLocal(doctypeName);
doctypeName = nsnull;
if (!!systemIdentifier) {
nsHtml5Portability::releaseString(systemIdentifier);
systemIdentifier = nsnull;
}
if (!!publicIdentifier) {
nsHtml5Portability::releaseString(publicIdentifier);
publicIdentifier = nsnull;
}
if (!!tagName) {
tagName->release();
tagName = nsnull;
@@ -3366,6 +3376,122 @@ nsHtml5Tokenizer::isInDataState()
return (stateSave == NS_HTML5TOKENIZER_DATA);
}
void
nsHtml5Tokenizer::resetToDataState()
{
strBufLen = 0;
longStrBufLen = 0;
stateSave = NS_HTML5TOKENIZER_DATA;
lastCR = PR_FALSE;
index = 0;
forceQuirks = PR_FALSE;
additional = '\0';
entCol = -1;
lo = 0;
hi = (nsHtml5NamedCharacters::NAMES.length - 1);
candidate = -1;
strBufMark = 0;
prevValue = -1;
value = 0;
seenDigits = PR_FALSE;
shouldSuspend = PR_FALSE;
initDoctypeFields();
if (!!tagName) {
tagName->release();
tagName = nsnull;
}
if (!!attributeName) {
attributeName->release();
attributeName = nsnull;
}
if (!!attributes) {
delete attributes;
attributes = nsnull;
}
}
void
nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
{
strBufLen = other->strBufLen;
if (strBufLen > strBuf.length) {
strBuf.release();
strBuf = jArray<PRUnichar,PRInt32>(strBufLen);
}
nsHtml5ArrayCopy::arraycopy(other->strBuf, strBuf, strBufLen);
longStrBufLen = other->longStrBufLen;
if (longStrBufLen > longStrBuf.length) {
longStrBuf.release();
longStrBuf = jArray<PRUnichar,PRInt32>(longStrBufLen);
}
nsHtml5ArrayCopy::arraycopy(other->longStrBuf, longStrBuf, longStrBufLen);
stateSave = other->stateSave;
lastCR = other->lastCR;
index = other->index;
forceQuirks = other->forceQuirks;
additional = other->additional;
entCol = other->entCol;
lo = other->lo;
hi = other->hi;
candidate = other->candidate;
strBufMark = other->strBufMark;
prevValue = other->prevValue;
value = other->value;
seenDigits = other->seenDigits;
shouldSuspend = PR_FALSE;
nsHtml5Portability::releaseLocal(doctypeName);
if (!other->doctypeName) {
doctypeName = nsnull;
} else {
doctypeName = nsHtml5Portability::newLocalFromLocal(other->doctypeName, interner);
}
nsHtml5Portability::releaseString(systemIdentifier);
if (!other->systemIdentifier) {
systemIdentifier = nsnull;
} else {
systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier);
}
nsHtml5Portability::releaseString(publicIdentifier);
if (!other->publicIdentifier) {
publicIdentifier = nsnull;
} else {
publicIdentifier = nsHtml5Portability::newStringFromString(other->publicIdentifier);
}
if (!!tagName) {
tagName->release();
}
if (!other->tagName) {
tagName = nsnull;
} else {
tagName = other->tagName->cloneElementName(interner);
}
if (!!attributeName) {
attributeName->release();
}
if (!other->attributeName) {
attributeName = nsnull;
} else {
attributeName = other->attributeName->cloneAttributeName(interner);
}
if (!!attributes) {
delete attributes;
}
if (!other->attributes) {
attributes = nsnull;
} else {
attributes = other->attributes->cloneAttributes(interner);
}
}
void
nsHtml5Tokenizer::initializeWithoutStarting()
{
confident = PR_FALSE;
strBuf = jArray<PRUnichar,PRInt32>(64);
longStrBuf = jArray<PRUnichar,PRInt32>(1024);
resetToDataState();
}
void
nsHtml5Tokenizer::setEncodingDeclarationHandler(nsHtml5StreamParser* encodingDeclarationHandler)
{