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
parent 9e4002f51b
commit 881001dff5
13 changed files with 527 additions and 425 deletions

View File

@ -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 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 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 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);
@ -1463,6 +1464,7 @@ public final class AttributeName
POSTER,
POINTS,
PROMPT,
SRCDOC,
SCOPED,
STRING,
SCHEME,
@ -2045,6 +2047,7 @@ public final class AttributeName
223089542,
223138630,
223311265,
224431494,
224547358,
224587256,
224589550,

View File

@ -448,6 +448,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private boolean quirks = false;
private boolean isSrcdocDocument = false;
// [NOCPP[
private boolean reportingDoctype = true;
@ -4158,6 +4160,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private void documentModeInternal(DocumentMode m, String publicIdentifier,
String systemIdentifier, boolean html4SpecificAdditionalErrorChecks)
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);
if (documentModeHandler != null) {
documentModeHandler.documentMode(
@ -5531,6 +5548,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
this.scriptingEnabled = scriptingEnabled;
}
public void setIsSrcdocDocument(boolean isSrcdocDocument) {
this.isSrcdocDocument = isSrcdocDocument;
}
// [NOCPP[
/**
@ -5951,11 +5972,15 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
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 {
err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.");
if (!isSrcdocDocument) {
err("Quirky doctype. Expected \u201C<!DOCTYPE html>\u201D.");
}
}
private void errNonSpaceInTrailer() throws SAXException {
@ -5990,7 +6015,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
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 {
@ -6069,7 +6096,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
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 {

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

@ -10,6 +10,7 @@
#include "nsHtml5Parser.h"
#include "nsHtml5AtomTable.h"
#include "nsHtml5DependentUTF16Buffer.h"
#include "nsIInputStreamChannel.h"
NS_INTERFACE_TABLE_HEAD(nsHtml5Parser)
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
mExecutor->SetParser(this);
mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled());
mTreeBuilder->setIsSrcdocDocument(IsSrcdocDocument());
mTokenizer->start();
mExecutor->Start();
if (!aContentType.EqualsLiteral("text/html")) {
@ -674,6 +678,9 @@ nsHtml5Parser::Initialize(nsIDocument* aDoc,
void
nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) {
mTreeBuilder->setIsSrcdocDocument(IsSrcdocDocument());
mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled);
mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
mTokenizer->start();
@ -697,3 +704,21 @@ nsHtml5Parser::ContinueAfterFailedCharsetSwitch()
"Tried to continue after failed charset switch without a stream parser");
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;
}

View File

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

View File

@ -26,6 +26,7 @@
#include "nsINestedURI.h"
#include "nsCharsetSource.h"
#include "nsIWyciwygChannel.h"
#include "nsIInputStreamChannel.h"
#include "mozilla/dom/EncodingUtils.h"
@ -872,6 +873,7 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
bool scriptingEnabled = mMode == LOAD_AS_DATA ?
false : mExecutor->IsScriptEnabled();
mOwner->StartTokenizer(scriptingEnabled);
mTreeBuilder->setIsSrcdocDocument(IsSrcdocDocument());
mTreeBuilder->setScriptingEnabled(scriptingEnabled);
mTreeBuilder->SetPreventScriptExecution(!((mMode == NORMAL) &&
scriptingEnabled));
@ -1609,3 +1611,20 @@ nsHtml5StreamParser::MarkAsBroken()
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;
}

View File

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

View File

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

View File

@ -3119,6 +3119,13 @@ nsHtml5TreeBuilder::isSecondOnStackBody()
void
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);
if (this) {
this->documentMode(m);
@ -4064,6 +4071,12 @@ nsHtml5TreeBuilder::setScriptingEnabled(bool scriptingEnabled)
this->scriptingEnabled = scriptingEnabled;
}
void
nsHtml5TreeBuilder::setIsSrcdocDocument(bool isSrcdocDocument)
{
this->isSrcdocDocument = isSrcdocDocument;
}
void
nsHtml5TreeBuilder::flushCharacters()
{

View File

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

View File

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