Bug 802895 - Parser changes to support srcdoc attributes for iframes, r=hsivonen

This commit is contained in:
James Kitchener 2013-06-28 23:13:23 -04:00
Родитель a33e8b9ec5
Коммит a1621fa975
13 изменённых файлов: 527 добавлений и 425 удалений

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

@ -882,6 +882,7 @@ public final class AttributeName
public static final AttributeName POSTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("poster"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); public static final AttributeName POSTER = new AttributeName(ALL_NO_NS, SAME_LOCAL("poster"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName POINTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("points"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); public static final AttributeName POINTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("points"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName PROMPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("prompt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); public static final AttributeName PROMPT = new AttributeName(ALL_NO_NS, SAME_LOCAL("prompt"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SRCDOC = new AttributeName(ALL_NO_NS, SAME_LOCAL("srcdoc"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SCOPED = new AttributeName(ALL_NO_NS, SAME_LOCAL("scoped"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); public static final AttributeName SCOPED = new AttributeName(ALL_NO_NS, SAME_LOCAL("scoped"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName STRING = new AttributeName(ALL_NO_NS, SAME_LOCAL("string"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); public static final AttributeName STRING = new AttributeName(ALL_NO_NS, SAME_LOCAL("string"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SCHEME = new AttributeName(ALL_NO_NS, SAME_LOCAL("scheme"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG); public static final AttributeName SCHEME = new AttributeName(ALL_NO_NS, SAME_LOCAL("scheme"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
@ -1463,6 +1464,7 @@ public final class AttributeName
POSTER, POSTER,
POINTS, POINTS,
PROMPT, PROMPT,
SRCDOC,
SCOPED, SCOPED,
STRING, STRING,
SCHEME, SCHEME,
@ -2045,6 +2047,7 @@ public final class AttributeName
223089542, 223089542,
223138630, 223138630,
223311265, 223311265,
224431494,
224547358, 224547358,
224587256, 224587256,
224589550, 224589550,

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

@ -448,6 +448,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private boolean quirks = false; private boolean quirks = false;
private boolean isSrcdocDocument = false;
// [NOCPP[ // [NOCPP[
private boolean reportingDoctype = true; private boolean reportingDoctype = true;
@ -4158,6 +4160,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private void documentModeInternal(DocumentMode m, String publicIdentifier, private void documentModeInternal(DocumentMode m, String publicIdentifier,
String systemIdentifier, boolean html4SpecificAdditionalErrorChecks) String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
throws SAXException { throws SAXException {
if (isSrcdocDocument) {
// Srcdoc documents are always rendered in standards mode.
quirks = false;
if (documentModeHandler != null) {
documentModeHandler.documentMode(
DocumentMode.STANDARDS_MODE
// [NOCPP[
, null, null, false
// ]NOCPP]
);
}
return;
}
quirks = (m == DocumentMode.QUIRKS_MODE); quirks = (m == DocumentMode.QUIRKS_MODE);
if (documentModeHandler != null) { if (documentModeHandler != null) {
documentModeHandler.documentMode( documentModeHandler.documentMode(
@ -5531,6 +5548,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
this.scriptingEnabled = scriptingEnabled; this.scriptingEnabled = scriptingEnabled;
} }
public void setIsSrcdocDocument(boolean isSrcdocDocument) {
this.isSrcdocDocument = isSrcdocDocument;
}
// [NOCPP[ // [NOCPP[
/** /**
@ -5951,11 +5972,15 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
private void errAlmostStandardsDoctype() throws SAXException { private void errAlmostStandardsDoctype() throws SAXException {
err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D."); if (!isSrcdocDocument) {
err("Almost standards mode doctype. Expected \u201C<!DOCTYPE html>\u201D.");
}
} }
private void errQuirkyDoctype() throws SAXException { private void errQuirkyDoctype() throws SAXException {
err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D."); if (!isSrcdocDocument) {
err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.");
}
} }
private void errNonSpaceInTrailer() throws SAXException { private void errNonSpaceInTrailer() throws SAXException {
@ -5990,7 +6015,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
private void errStartTagWithoutDoctype() throws SAXException { private void errStartTagWithoutDoctype() throws SAXException {
err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); if (!isSrcdocDocument) {
err("Start tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
}
} }
private void errNoSelectInTableScope() throws SAXException { private void errNoSelectInTableScope() throws SAXException {
@ -6069,7 +6096,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
} }
private void errEndTagSeenWithoutDoctype() throws SAXException { private void errEndTagSeenWithoutDoctype() throws SAXException {
err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D."); if (!isSrcdocDocument) {
err("End tag seen without seeing a doctype first. Expected \u201C<!DOCTYPE html>\u201D.");
}
} }
private void errEndTagAfterBody() throws SAXException { private void errEndTagAfterBody() throws SAXException {

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

@ -226,6 +226,7 @@ HTML5_ATOM(vspace, "vspace")
HTML5_ATOM(poster, "poster") HTML5_ATOM(poster, "poster")
HTML5_ATOM(points, "points") HTML5_ATOM(points, "points")
HTML5_ATOM(prompt, "prompt") HTML5_ATOM(prompt, "prompt")
HTML5_ATOM(srcdoc, "srcdoc")
HTML5_ATOM(scoped, "scoped") HTML5_ATOM(scoped, "scoped")
HTML5_ATOM(string, "string") HTML5_ATOM(string, "string")
HTML5_ATOM(scheme, "scheme") HTML5_ATOM(scheme, "scheme")

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -256,6 +256,7 @@ class nsHtml5AttributeName
static nsHtml5AttributeName* ATTR_POSTER; static nsHtml5AttributeName* ATTR_POSTER;
static nsHtml5AttributeName* ATTR_POINTS; static nsHtml5AttributeName* ATTR_POINTS;
static nsHtml5AttributeName* ATTR_PROMPT; static nsHtml5AttributeName* ATTR_PROMPT;
static nsHtml5AttributeName* ATTR_SRCDOC;
static nsHtml5AttributeName* ATTR_SCOPED; static nsHtml5AttributeName* ATTR_SCOPED;
static nsHtml5AttributeName* ATTR_STRING; static nsHtml5AttributeName* ATTR_STRING;
static nsHtml5AttributeName* ATTR_SCHEME; static nsHtml5AttributeName* ATTR_SCHEME;

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

@ -10,6 +10,7 @@
#include "nsHtml5Parser.h" #include "nsHtml5Parser.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsHtml5DependentUTF16Buffer.h" #include "nsHtml5DependentUTF16Buffer.h"
#include "nsIInputStreamChannel.h"
NS_INTERFACE_TABLE_HEAD(nsHtml5Parser) NS_INTERFACE_TABLE_HEAD(nsHtml5Parser)
NS_INTERFACE_TABLE2(nsHtml5Parser, nsIParser, nsISupportsWeakReference) NS_INTERFACE_TABLE2(nsHtml5Parser, nsIParser, nsISupportsWeakReference)
@ -213,6 +214,9 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
// This is the first document.write() on a document.open()ed document // This is the first document.write() on a document.open()ed document
mExecutor->SetParser(this); mExecutor->SetParser(this);
mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled()); mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled());
mTreeBuilder->setIsSrcdocDocument(IsSrcdocDocument());
mTokenizer->start(); mTokenizer->start();
mExecutor->Start(); mExecutor->Start();
if (!aContentType.EqualsLiteral("text/html")) { if (!aContentType.EqualsLiteral("text/html")) {
@ -674,6 +678,9 @@ nsHtml5Parser::Initialize(nsIDocument* aDoc,
void void
nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) { nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) {
mTreeBuilder->setIsSrcdocDocument(IsSrcdocDocument());
mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled); mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled);
mTreeBuilder->setScriptingEnabled(aScriptingEnabled); mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
mTokenizer->start(); mTokenizer->start();
@ -697,3 +704,21 @@ nsHtml5Parser::ContinueAfterFailedCharsetSwitch()
"Tried to continue after failed charset switch without a stream parser"); "Tried to continue after failed charset switch without a stream parser");
mStreamParser->ContinueAfterFailedCharsetSwitch(); mStreamParser->ContinueAfterFailedCharsetSwitch();
} }
bool
nsHtml5Parser::IsSrcdocDocument()
{
nsresult rv;
bool isSrcdoc = false;
nsCOMPtr<nsIChannel> channel;
rv = GetChannel(getter_AddRefs(channel));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIInputStreamChannel> isr = do_QueryInterface(channel);
if (isr) {
isr->GetIsSrcdocChannel(&isSrcdoc);
}
}
return isSrcdoc;
}

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

@ -258,6 +258,8 @@ class nsHtml5Parser : public nsIParser,
*/ */
void ParseUntilBlocked(); void ParseUntilBlocked();
bool IsSrcdocDocument();
private: private:
// State variables // State variables

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

@ -26,6 +26,7 @@
#include "nsINestedURI.h" #include "nsINestedURI.h"
#include "nsCharsetSource.h" #include "nsCharsetSource.h"
#include "nsIWyciwygChannel.h" #include "nsIWyciwygChannel.h"
#include "nsIInputStreamChannel.h"
#include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/EncodingUtils.h"
@ -872,6 +873,7 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
bool scriptingEnabled = mMode == LOAD_AS_DATA ? bool scriptingEnabled = mMode == LOAD_AS_DATA ?
false : mExecutor->IsScriptEnabled(); false : mExecutor->IsScriptEnabled();
mOwner->StartTokenizer(scriptingEnabled); mOwner->StartTokenizer(scriptingEnabled);
mTreeBuilder->setIsSrcdocDocument(IsSrcdocDocument());
mTreeBuilder->setScriptingEnabled(scriptingEnabled); mTreeBuilder->setScriptingEnabled(scriptingEnabled);
mTreeBuilder->SetPreventScriptExecution(!((mMode == NORMAL) && mTreeBuilder->SetPreventScriptExecution(!((mMode == NORMAL) &&
scriptingEnabled)); scriptingEnabled));
@ -1609,3 +1611,20 @@ nsHtml5StreamParser::MarkAsBroken()
NS_WARNING("failed to dispatch executor flush event"); NS_WARNING("failed to dispatch executor flush event");
} }
} }
bool
nsHtml5StreamParser::IsSrcdocDocument()
{
nsresult rv;
bool isSrcdoc = false;
nsCOMPtr<nsIChannel> channel;
rv = GetChannel(getter_AddRefs(channel));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIInputStreamChannel> isr = do_QueryInterface(channel);
if (isr) {
isr->GetIsSrcdocChannel(&isSrcdoc);
}
}
return isSrcdoc;
}

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

@ -198,6 +198,8 @@ class nsHtml5StreamParser : public nsIStreamListener,
*/ */
void SetViewSourceTitle(nsIURI* aURL); void SetViewSourceTitle(nsIURI* aURL);
bool IsSrcdocDocument();
private: private:
#ifdef DEBUG #ifdef DEBUG

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

@ -102,6 +102,7 @@ nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
NS_PRECONDITION(!mExecutor->HasStarted(), NS_PRECONDITION(!mExecutor->HasStarted(),
"Tried to start parse without initializing the parser."); "Tried to start parse without initializing the parser.");
mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing); mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
mTreeBuilder->setIsSrcdocDocument(aDocument->IsSrcdocDocument());
mTokenizer->start(); mTokenizer->start();
mExecutor->Start(); // Don't call WillBuildModel in fragment case mExecutor->Start(); // Don't call WillBuildModel in fragment case
if (!aSourceBuffer.IsEmpty()) { if (!aSourceBuffer.IsEmpty()) {

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

@ -3119,6 +3119,13 @@ nsHtml5TreeBuilder::isSecondOnStackBody()
void void
nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks) nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks)
{ {
if (isSrcdocDocument) {
quirks = false;
if (this) {
this->documentMode(STANDARDS_MODE);
}
return;
}
quirks = (m == QUIRKS_MODE); quirks = (m == QUIRKS_MODE);
if (this) { if (this) {
this->documentMode(m); this->documentMode(m);
@ -4064,6 +4071,12 @@ nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled)
this->scriptingEnabled = scriptingEnabled; this->scriptingEnabled = scriptingEnabled;
} }
void
nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument)
{
this->isSrcdocDocument = isSrcdocDocument;
}
void void
nsHtml5TreeBuilder::flushCharacters() nsHtml5TreeBuilder::flushCharacters()
{ {

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

@ -98,6 +98,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
int32_t charBufferLen; int32_t charBufferLen;
private: private:
bool quirks; bool quirks;
bool isSrcdocDocument;
public: public:
void startTokenization(nsHtml5Tokenizer* self); void startTokenization(nsHtml5Tokenizer* self);
void doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks); void doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks);
@ -235,6 +236,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
public: public:
bool isScriptingEnabled(); bool isScriptingEnabled();
void setScriptingEnabled(bool scriptingEnabled); void setScriptingEnabled(bool scriptingEnabled);
void setIsSrcdocDocument(bool isSrcdocDocument);
void flushCharacters(); void flushCharacters();
private: private:
bool charBufferContainsNonWhitespace(); bool charBufferContainsNonWhitespace();

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

@ -823,7 +823,7 @@ nsHtml5TreeBuilder::errStrayDoctype()
void void
nsHtml5TreeBuilder::errAlmostStandardsDoctype() nsHtml5TreeBuilder::errAlmostStandardsDoctype()
{ {
if (MOZ_UNLIKELY(mViewSource)) { if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype"); mViewSource->AddErrorToCurrentRun("errAlmostStandardsDoctype");
} }
} }
@ -831,7 +831,7 @@ nsHtml5TreeBuilder::errAlmostStandardsDoctype()
void void
nsHtml5TreeBuilder::errQuirkyDoctype() nsHtml5TreeBuilder::errQuirkyDoctype()
{ {
if (MOZ_UNLIKELY(mViewSource)) { if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
mViewSource->AddErrorToCurrentRun("errQuirkyDoctype"); mViewSource->AddErrorToCurrentRun("errQuirkyDoctype");
} }
} }
@ -895,7 +895,7 @@ nsHtml5TreeBuilder::errFooBetweenHeadAndBody(nsIAtom* aName)
void void
nsHtml5TreeBuilder::errStartTagWithoutDoctype() nsHtml5TreeBuilder::errStartTagWithoutDoctype()
{ {
if (MOZ_UNLIKELY(mViewSource)) { if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype"); mViewSource->AddErrorToCurrentRun("errStartTagWithoutDoctype");
} }
} }
@ -1016,7 +1016,7 @@ nsHtml5TreeBuilder::errStartTagInTableBody(nsIAtom* aName)
void void
nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype() nsHtml5TreeBuilder::errEndTagSeenWithoutDoctype()
{ {
if (MOZ_UNLIKELY(mViewSource)) { if (MOZ_UNLIKELY(mViewSource) && !isSrcdocDocument) {
mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype"); mViewSource->AddErrorToCurrentRun("errEndTagSeenWithoutDoctype");
} }
} }