Bug 479959 - Reimplement text/plain loading using the HTML5 parser. r=Olli.Pettay.

This commit is contained in:
Henri Sivonen 2011-11-01 17:27:36 +02:00
parent 111a0573d5
commit dc6ff15cba
9 changed files with 63 additions and 11 deletions

View File

@ -36,7 +36,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=430050
document.getElementById('b').loadURI('data:text/plain,succeeded',
null,
'UTF-8');
setTimeout(endTest, 0);
document.getElementById('b').addEventListener("load", endTest);
}
}, true);
document.documentElement.setAttribute("foo", "bar");

View File

@ -141,6 +141,7 @@
#include "prprf.h"
#include "mozilla/dom/Element.h"
#include "mozilla/Preferences.h"
#include "nsMimeTypes.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -162,6 +163,7 @@ const PRInt32 kBackward = 1;
//#define DEBUG_charset
#define NS_USE_NEW_VIEW_SOURCE 1
#define NS_USE_NEW_PLAIN_TEXT 1
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
@ -652,17 +654,30 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
bool aReset,
nsIContentSink* aSink)
{
nsCAutoString contentType;
aChannel->GetContentType(contentType);
bool viewSource = aCommand && !nsCRT::strcmp(aCommand, "view-source") &&
NS_USE_NEW_VIEW_SOURCE;
bool loadAsHtml5 = nsHtml5Module::sEnabled || viewSource;
bool plainText = (contentType.EqualsLiteral(TEXT_PLAIN) ||
contentType.EqualsLiteral(TEXT_CSS) ||
contentType.EqualsLiteral(APPLICATION_JAVASCRIPT) ||
contentType.EqualsLiteral(APPLICATION_XJAVASCRIPT) ||
contentType.EqualsLiteral(TEXT_ECMASCRIPT) ||
contentType.EqualsLiteral(APPLICATION_ECMASCRIPT) ||
contentType.EqualsLiteral(TEXT_JAVASCRIPT));
bool loadAsHtml5 = nsHtml5Module::sEnabled || viewSource || plainText;
if (!NS_USE_NEW_PLAIN_TEXT && !viewSource) {
plainText = false;
}
NS_ASSERTION(!(plainText && aSink),
"Someone tries to load plain text into a custom sink.");
if (aSink) {
loadAsHtml5 = false;
}
nsCAutoString contentType;
aChannel->GetContentType(contentType);
if (contentType.Equals("application/xhtml+xml") && !viewSource) {
// We're parsing XHTML as XML, remember that.
@ -677,7 +692,8 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
}
#endif
if (loadAsHtml5 && !viewSource && !(contentType.EqualsLiteral("text/html") &&
if (loadAsHtml5 && !viewSource &&
(!(contentType.EqualsLiteral("text/html") || plainText) &&
aCommand && !nsCRT::strcmp(aCommand, "view"))) {
loadAsHtml5 = false;
}
@ -731,9 +747,13 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
if (needsParser) {
if (loadAsHtml5) {
mParser = nsHtml5Module::NewHtml5Parser();
mParser->MarkAsNotScriptCreated((viewSource &&
!contentType.EqualsLiteral("text/html")) ?
"view-source-xml": aCommand);
if (plainText) {
mParser->MarkAsNotScriptCreated("plain-text");
} else if (viewSource && !contentType.EqualsLiteral("text/html")) {
mParser->MarkAsNotScriptCreated("view-source-xml");
} else {
mParser->MarkAsNotScriptCreated(aCommand);
}
} else {
mParser = do_CreateInstance(kCParserCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -87,7 +87,8 @@ nsresult
NS_NewContentViewer(nsIContentViewer** aResult);
// XXXbz if you change the MIME types here, be sure to update
// nsIParser.h and DetermineParseMode in nsParser.cpp accordingly.
// nsIParser.h and DetermineParseMode in nsParser.cpp and
// nsHTMLDocument::StartDocumentLoad accordingly.
static const char* const gHTMLTypes[] = {
TEXT_HTML,
TEXT_PLAIN,

View File

@ -707,6 +707,8 @@ nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
mode = VIEW_SOURCE_HTML;
} else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
mode = VIEW_SOURCE_XML;
} else if (!nsCRT::strcmp(aCommand, "plain-text")) {
mode = PLAIN_TEXT;
}
#ifdef DEBUG
else {

View File

@ -866,6 +866,12 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
mTokenizer->start();
mExecutor->Start();
mExecutor->StartReadingFromStage();
if (mMode == PLAIN_TEXT) {
mTreeBuilder->StartPlainText();
mTokenizer->StartPlainText();
}
/*
* If you move the following line, be very careful not to cause
* WillBuildModel to be called before the document has had its
@ -891,7 +897,7 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
// The line below means that the encoding can end up being wrong if
// a view-source URL is loaded without having the encoding hint from a
// previous normal load in the history.
mReparseForbidden = !(mMode == NORMAL);
mReparseForbidden = !(mMode == NORMAL || mMode == PLAIN_TEXT);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mRequest, &rv));
if (NS_SUCCEEDED(rv)) {

View File

@ -35,6 +35,12 @@
*
* ***** END LICENSE BLOCK ***** */
void
nsHtml5Tokenizer::StartPlainText()
{
stateSave = NS_HTML5TOKENIZER_PLAINTEXT;
}
void
nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter)
{

View File

@ -37,6 +37,12 @@
nsAutoPtr<nsHtml5Highlighter> mViewSource;
/**
* Starts handling text/plain. This is a one-way initialization. There is
* no corresponding EndPlainText() call.
*/
void StartPlainText();
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
bool FlushViewSource();

View File

@ -700,6 +700,15 @@ nsHtml5TreeBuilder::MarkAsBroken()
mOpQueue.AppendElement()->Init(eTreeOpMarkAsBroken);
}
void
nsHtml5TreeBuilder::StartPlainText()
{
startTag(nsHtml5ElementName::ELT_PRE,
nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES,
false);
needToDropLF = false;
}
// DocumentModeHandler
void
nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)

View File

@ -95,6 +95,8 @@
~nsHtml5TreeBuilder();
void StartPlainText();
bool HasScript();
void SetOpSink(nsAHtml5TreeOpSink* aOpSink) {