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
Родитель 2443167dbb
Коммит 509e2178fb
9 изменённых файлов: 63 добавлений и 11 удалений

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

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

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

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

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

@ -87,7 +87,8 @@ nsresult
NS_NewContentViewer(nsIContentViewer** aResult); NS_NewContentViewer(nsIContentViewer** aResult);
// XXXbz if you change the MIME types here, be sure to update // 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[] = { static const char* const gHTMLTypes[] = {
TEXT_HTML, TEXT_HTML,
TEXT_PLAIN, TEXT_PLAIN,

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

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

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

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

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

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

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

@ -37,6 +37,12 @@
nsAutoPtr<nsHtml5Highlighter> mViewSource; 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); void EnableViewSource(nsHtml5Highlighter* aHighlighter);
bool FlushViewSource(); bool FlushViewSource();

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

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

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

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