Bug 482921 part 1 - Implement HTML syntax highlighting using the new parser. r=Olli.Pettay.

This commit is contained in:
Henri Sivonen 2010-07-30 13:15:38 +03:00
Родитель 3e5a97a7af
Коммит aa8cafb38c
37 изменённых файлов: 4254 добавлений и 107 удалений

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

@ -576,7 +576,8 @@ nsHTMLDocument::StartAutodetection(nsIDocShell *aDocShell, nsACString& aCharset,
if (mIsRegularHTML && if (mIsRegularHTML &&
nsHtml5Module::sEnabled && nsHtml5Module::sEnabled &&
aCommand && aCommand &&
!nsCRT::strcmp(aCommand, "view")) { (!nsCRT::strcmp(aCommand, "view") ||
!nsCRT::strcmp(aCommand, "view-source"))) {
return; // the HTML5 parser uses chardet directly return; // the HTML5 parser uses chardet directly
} }
nsCOMPtr <nsIParserFilter> cdetflt; nsCOMPtr <nsIParserFilter> cdetflt;
@ -675,7 +676,8 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
if (loadAsHtml5 && if (loadAsHtml5 &&
!(contentType.EqualsLiteral("text/html") && !(contentType.EqualsLiteral("text/html") &&
aCommand && aCommand &&
!nsCRT::strcmp(aCommand, "view"))) { (!nsCRT::strcmp(aCommand, "view") ||
!nsCRT::strcmp(aCommand, "view-source")))) {
loadAsHtml5 = false; loadAsHtml5 = false;
} }
@ -728,7 +730,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
if (needsParser) { if (needsParser) {
if (loadAsHtml5) { if (loadAsHtml5) {
mParser = nsHtml5Module::NewHtml5Parser(); mParser = nsHtml5Module::NewHtml5Parser();
mParser->MarkAsNotScriptCreated(); 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);

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

@ -107,6 +107,7 @@ CPPSRCS = \
nsHtml5Speculation.cpp \ nsHtml5Speculation.cpp \
nsHtml5SpeculativeLoad.cpp \ nsHtml5SpeculativeLoad.cpp \
nsHtml5SVGLoadDispatcher.cpp \ nsHtml5SVGLoadDispatcher.cpp \
nsHtml5Highlighter.cpp \
$(NULL) $(NULL)
FORCE_STATIC_LIB = 1 FORCE_STATIC_LIB = 1

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

@ -1220,6 +1220,9 @@ public class Tokenizer implements Locator {
if (attributeName != null) { if (attributeName != null) {
String val = longStrBufToString(); // Ownership transferred to String val = longStrBufToString(); // Ownership transferred to
// HtmlAttributes // HtmlAttributes
// CPPONLY: if (mViewSource) {
// CPPONLY: mViewSource.MaybeLinkifyAttributeValue(attributeName, val);
// CPPONLY: }
// [NOCPP[ // [NOCPP[
if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata
&& attributeName.isCaseFolded()) { && attributeName.isCaseFolded()) {
@ -1316,8 +1319,17 @@ public class Tokenizer implements Locator {
* meaning. (The rest of the array is garbage and should not be * meaning. (The rest of the array is garbage and should not be
* examined.) * examined.)
*/ */
// CPPONLY: if (mViewSource) {
// CPPONLY: mViewSource.SetBuffer(buffer);
// CPPONLY: pos = stateLoopReportTransitions(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
// CPPONLY: mViewSource.DropBuffer((pos == buffer.getEnd()) ? pos : pos + 1);
// CPPONLY: } else {
// CPPONLY: pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, buffer.getEnd());
// CPPONLY: }
// [NOCPP[
pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState, pos = stateLoop(state, c, pos, buffer.getBuffer(), false, returnState,
buffer.getEnd()); buffer.getEnd());
// ]NOCPP]
if (pos == buffer.getEnd()) { if (pos == buffer.getEnd()) {
// exiting due to end of buffer // exiting due to end of buffer
buffer.setStart(pos); buffer.setStart(pos);
@ -3149,6 +3161,7 @@ public class Tokenizer implements Locator {
* second column of the named character references * second column of the named character references
* table). * table).
*/ */
// CPPONLY: mViewSource.CompletedNamedCharacterReference();
@Const @NoLength char[] val = NamedCharacters.VALUES[candidate]; @Const @NoLength char[] val = NamedCharacters.VALUES[candidate];
if ( if (
// [NOCPP[ // [NOCPP[

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

@ -33,17 +33,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -33,17 +33,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -0,0 +1,676 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML5 View Source code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsHtml5Highlighter.h"
#include "nsDebug.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5AttributeName.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
PRUnichar nsHtml5Highlighter::sComment[] =
{ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
PRUnichar nsHtml5Highlighter::sCdata[] =
{ 'c', 'd', 'a', 't', 'a', 0 };
PRUnichar nsHtml5Highlighter::sEntity[] =
{ 'e', 'n', 't', 'i', 't', 'y', 0 };
PRUnichar nsHtml5Highlighter::sEndTag[] =
{ 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
PRUnichar nsHtml5Highlighter::sStartTag[] =
{ 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
PRUnichar nsHtml5Highlighter::sAttributeName[] =
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
PRUnichar nsHtml5Highlighter::sAttributeValue[] =
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
'v', 'a', 'l', 'u', 'e', 0 };
PRUnichar nsHtml5Highlighter::sDoctype[] =
{ 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
: mState(NS_HTML5TOKENIZER_DATA)
, mCStart(PR_INT32_MAX)
, mPos(0)
, mInlinesOpen(0)
, mBuffer(nsnull)
, mSyntaxHighlight(Preferences::GetBool("view_source.syntax_highlight",
true))
, mWrapLongLines(Preferences::GetBool("view_source.wrap_long_lines", true))
, mTabSize(Preferences::GetInt("view_source.tab_size", 4))
, mOpSink(aOpSink)
, mHandles(new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH])
, mHandlesUsed(0)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
nsHtml5Highlighter::~nsHtml5Highlighter()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
void
nsHtml5Highlighter::Start()
{
// Doctype
mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
nsIContent** root = CreateElement(nsHtml5Atoms::html, nsnull);
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
mStack.AppendElement(root);
Push(nsGkAtoms::head, nsnull);
Push(nsGkAtoms::title, nsnull);
// XUL will add the "Source of: " prefix.
AppendCharacters(mURL.get(), 0, mURL.Length());
Pop(); // title
nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
nsString* rel = new nsString(NS_LITERAL_STRING("stylesheet"));
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel);
nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type);
nsString* href = new nsString(
NS_LITERAL_STRING("resource://gre-resources/viewsource.css"));
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href);
Push(nsGkAtoms::link, linkAttrs);
mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
Pop(); // link
Pop(); // head
nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
nsString* id = new nsString(NS_LITERAL_STRING("viewsource"));
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id);
if (mWrapLongLines) {
nsString* klass = new nsString(NS_LITERAL_STRING("wrap"));
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass);
}
if (mTabSize > 0) {
nsString* style = new nsString(NS_LITERAL_STRING("-moz-tab-size: "));
style->AppendInt(mTabSize);
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, style);
}
Push(nsGkAtoms::body, bodyAttrs);
nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
nsString* preId = new nsString(NS_LITERAL_STRING("line1"));
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId);
Push(nsGkAtoms::pre, preAttrs);
mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
}
PRInt32
nsHtml5Highlighter::Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos)
{
mPos = aPos;
switch (mState) {
case NS_HTML5TOKENIZER_SCRIPT_DATA:
case NS_HTML5TOKENIZER_RAWTEXT:
case NS_HTML5TOKENIZER_RCDATA:
case NS_HTML5TOKENIZER_DATA:
// We can transition on < and on &. Either way, we don't yet know the
// role of the token, so open a span without class.
StartSpan();
break;
case NS_HTML5TOKENIZER_TAG_OPEN:
switch (aState) {
case NS_HTML5TOKENIZER_TAG_NAME:
StartSpan(sStartTag);
break;
case NS_HTML5TOKENIZER_DATA:
EndInline(); // DATA
break;
}
break;
case NS_HTML5TOKENIZER_TAG_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
EndInline(); // NS_HTML5TOKENIZER_TAG_NAME
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
EndInline(); // NS_HTML5TOKENIZER_TAG_NAME
StartSpan(); // for highlighting the slash
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
StartSpan(sAttributeName);
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
EndInline(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
EndInline(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
StartSpan(); // for highlighting the slash
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
switch (aState) {
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
FlushCurrent();
StartA();
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
StartA();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
EndInline();
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
StartSpan();
break;
default:
NS_NOTREACHED("Impossible transition.");
break;
}
break;
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
FlushCurrent();
EndInline();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
EndInline();
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
StartSpan();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
break;
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
StartSpan(sAttributeName);
break;
default:
FinishTag();
break;
}
break;
// most comment states are omitted, because they don't matter to
// highlighting
case NS_HTML5TOKENIZER_COMMENT_END:
case NS_HTML5TOKENIZER_COMMENT_END_BANG:
case NS_HTML5TOKENIZER_COMMENT_START_DASH:
case NS_HTML5TOKENIZER_BOGUS_COMMENT:
case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
if (aState == NS_HTML5TOKENIZER_DATA) {
AddClass(sComment);
FinishTag();
}
break;
// most cdata states are omitted, because they don't matter to
// highlighting
case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
if (aState == NS_HTML5TOKENIZER_DATA) {
AddClass(sCdata);
FinishTag();
}
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
switch (aState) {
case NS_HTML5TOKENIZER_CONSUME_NCR:
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
break;
default:
// not actually a character reference
EndInline();
break;
}
break;
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
if (aState == NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL) {
break;
}
// not actually a character reference
EndInline();
break;
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
// XXX need tokenizer cooperation to set class!
if (!aReconsume) {
FlushCurrent();
}
EndInline();
break;
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
switch (aState) {
case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE:
AddClass(sEntity);
FlushCurrent();
break;
case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME:
AddClass(sEntity);
break;
}
EndInline();
break;
case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN:
switch (aState) {
case NS_HTML5TOKENIZER_DATA:
FinishTag();
break;
case NS_HTML5TOKENIZER_TAG_NAME:
StartSpan(sEndTag);
break;
}
break;
case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN:
if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
FlushCurrent();
StartSpan(); // don't know if it is "end-tag" yet :-(
break;
}
EndInline();
break;
case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
AddClass(sEndTag);
EndInline();
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
AddClass(sEndTag);
EndInline();
StartSpan(); // for highlighting the slash
break;
case NS_HTML5TOKENIZER_DATA: // yes, as a result of emitting the token
AddClass(sEndTag);
FinishTag();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
break;
}
FinishTag();
break;
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH:
if (aState == NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
StartSpan();
}
break;
// Lots of double escape states omitted, because they don't highlight.
// Likewise, only doctype states that can emit the doctype are of
// interest. Otherwise, the transition out of bogus comment deals.
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
if (aState == NS_HTML5TOKENIZER_DATA) {
AddClass(sDoctype);
FinishTag();
}
break;
default:
break;
}
mState = aState;
return aState;
}
void
nsHtml5Highlighter::End()
{
switch (mState) {
case NS_HTML5TOKENIZER_COMMENT_END:
case NS_HTML5TOKENIZER_COMMENT_END_BANG:
case NS_HTML5TOKENIZER_COMMENT_START_DASH:
case NS_HTML5TOKENIZER_BOGUS_COMMENT:
case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
AddClass(sComment);
break;
case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
AddClass(sCdata);
break;
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
// XXX need tokenizer help here
break;
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
AddClass(sDoctype);
break;
default:
break;
}
FlushOps();
}
void
nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer)
{
NS_PRECONDITION(!mBuffer, "Old buffer still here!");
mBuffer = aBuffer;
mCStart = aBuffer->getStart();
}
void
nsHtml5Highlighter::DropBuffer(PRInt32 aPos)
{
NS_PRECONDITION(mBuffer, "No buffer to drop!");
mPos = aPos;
FlushChars();
mBuffer = nsnull;
}
void
nsHtml5Highlighter::StartSpan()
{
FlushChars();
Push(nsGkAtoms::span, nsnull);
++mInlinesOpen;
}
void
nsHtml5Highlighter::StartSpan(const PRUnichar* aClass)
{
StartSpan();
AddClass(aClass);
}
void
nsHtml5Highlighter::EndInline()
{
FlushChars();
Pop();
--mInlinesOpen;
}
void
nsHtml5Highlighter::StartA()
{
FlushChars();
Push(nsGkAtoms::a, nsnull);
AddClass(sAttributeValue);
++mInlinesOpen;
}
void
nsHtml5Highlighter::FinishTag()
{
while (mInlinesOpen > 1) {
EndInline();
}
FlushCurrent(); // >
EndInline(); // DATA
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
}
void
nsHtml5Highlighter::FlushChars()
{
if (mPos > mCStart) {
AppendCharacters(mBuffer->getBuffer(), mCStart, mPos - mCStart);
mCStart = mPos;
}
}
void
nsHtml5Highlighter::FlushCurrent()
{
mPos++;
FlushChars();
}
bool
nsHtml5Highlighter::FlushOps()
{
bool hasOps = !mOpQueue.IsEmpty();
if (hasOps) {
mOpSink->MoveOpsFrom(mOpQueue);
}
return hasOps;
}
void
nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue)
{
if (!(nsHtml5AttributeName::ATTR_HREF == aName
|| nsHtml5AttributeName::ATTR_SRC == aName
|| nsHtml5AttributeName::ATTR_ACTION == aName
|| nsHtml5AttributeName::ATTR_CITE == aName
|| nsHtml5AttributeName::ATTR_BACKGROUND == aName
|| nsHtml5AttributeName::ATTR_LONGDESC == aName
|| nsHtml5AttributeName::ATTR_XLINK_HREF == aName
|| nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
return;
}
AddViewSourceHref(*aValue);
}
void
nsHtml5Highlighter::CompletedNamedCharacterReference()
{
AddClass(sEntity);
}
nsIContent**
nsHtml5Highlighter::AllocateContentHandle()
{
if (mHandlesUsed == NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH) {
mOldHandles.AppendElement(mHandles.forget());
mHandles = new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH];
mHandlesUsed = 0;
}
#ifdef DEBUG
mHandles[mHandlesUsed] = (nsIContent*)0xC0DEDBAD;
#endif
return &mHandles[mHandlesUsed++];
}
nsIContent**
nsHtml5Highlighter::CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
{
NS_PRECONDITION(aName, "Got null name.");
nsIContent** content = AllocateContentHandle();
mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
aName,
aAttributes,
content,
true);
return content;
}
nsIContent**
nsHtml5Highlighter::CurrentNode()
{
NS_PRECONDITION(mStack.Length() >= 1, "Must have something on stack.");
return mStack[mStack.Length() - 1];
}
void
nsHtml5Highlighter::Push(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
{
NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
nsIContent** elt = CreateElement(aName, aAttributes); // Don't inline below!
mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
mStack.AppendElement(elt);
}
void
nsHtml5Highlighter::Pop()
{
NS_PRECONDITION(mStack.Length() >= 2, "Popping when stack too short.");
mStack.RemoveElementAt(mStack.Length() - 1);
}
void
nsHtml5Highlighter::AppendCharacters(const PRUnichar* aBuffer,
PRInt32 aStart,
PRInt32 aLength)
{
NS_PRECONDITION(aBuffer, "Null buffer");
PRUnichar* bufferCopy = new PRUnichar[aLength];
memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(PRUnichar));
mOpQueue.AppendElement()->Init(eTreeOpAppendText,
bufferCopy,
aLength,
CurrentNode());
}
void
nsHtml5Highlighter::AddClass(const PRUnichar* aClass)
{
mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
}
void
nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
{
PRUnichar* bufferCopy = new PRUnichar[aValue.Length() + 1];
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(PRUnichar));
bufferCopy[aValue.Length()] = 0;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
bufferCopy,
aValue.Length(),
CurrentNode());
}

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

@ -0,0 +1,349 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML5 View Source code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsHtml5Highlighter_h_
#define nsHtml5Highlighter_h_
#include "prtypes.h"
#include "nsCOMPtr.h"
#include "nsHtml5TreeOperation.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5TreeOperation.h"
#include "nsAHtml5TreeOpSink.h"
#define NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH 512
/**
* A state machine for generating HTML for display in View Source based on
* the transitions the tokenizer makes on the source being viewed.
*/
class nsHtml5Highlighter
{
public:
/**
* The constructor.
*
* @param aOpSink the sink for the tree ops generated by this highlighter
*/
nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink);
/**
* The destructor.
*/
~nsHtml5Highlighter();
/**
* Starts the generated document.
*/
void Start();
/**
* Report a tokenizer state transition.
*
* @param aState the state being transitioned to
* @param aReconsume whether this is a reconsuming transition
* @param aPos the tokenizer's current position into the buffer
*/
PRInt32 Transition(PRInt32 aState, bool aReconsume, PRInt32 aPos);
/**
* Report end of file.
*/
void End();
/**
* Set the current buffer being tokenized
*/
void SetBuffer(nsHtml5UTF16Buffer* aBuffer);
/**
* Let go of the buffer being tokenized but first, flush text from it.
*
* @param aPos the first UTF-16 code unit not to flush
*/
void DropBuffer(PRInt32 aPos);
/**
* Flush the tree ops into the sink.
*
* @return true if there were ops to flush
*/
bool FlushOps();
/**
* Linkify the current attribute value if the attribute name is one of
* known URL attributes. (When executing tree ops, javascript: URLs will
* not be linkified, though.)
*
* @param aName the name of the attribute
* @param aValue the value of the attribute
*/
void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue);
/**
* Inform the highlighter that the tokenizer successfully completed a
* named character reference.
*/
void CompletedNamedCharacterReference();
private:
/**
* Starts a span with no class.
*/
void StartSpan();
/**
* Starts a <span> and sets the class attribute on it.
*
* @param aClass the class to set (MUST be a static string that does not
* need to be released!)
*/
void StartSpan(const PRUnichar* aClass);
/**
* End the current <span> or <a>.
*/
void EndInline();
/**
* Starts an <a>.
*/
void StartA();
/**
* Flushes characters up to but not including the current one.
*/
void FlushChars();
/**
* Flushes characters up to and including the current one.
*/
void FlushCurrent();
/**
* Finishes a source tag being highlighted by closing the open <span> and
* <a> elements.
*/
void FinishTag();
/**
* Adds a class attribute to the current node.
*
* @param aClass the class to set (MUST be a static string that does not
* need to be released!)
*/
void AddClass(const PRUnichar* aClass);
/**
* Allocates a handle for an element.
*
* @return the handle
*/
nsIContent** AllocateContentHandle();
/**
* Enqueues an element creation tree operation.
*
* @param aName the name of the element
* @param aAttributes the attribute holder (ownership will be taken) or
* nsnull for no attributes
* @return the handle for the element that will be created
*/
nsIContent** CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes);
/**
* Gets the handle for the current node. May be called only after the
* root element has been set.
*
* @return the handle for the current node
*/
nsIContent** CurrentNode();
/**
* Create an element and push it (its handle) on the stack.
*
* @param aName the name of the element
* @param aAttributes the attribute holder (ownership will be taken) or
* nsnull for no attributes
*/
void Push(nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes);
/**
* Pops the current node off the stack.
*/
void Pop();
/**
* Appends text content to the current node.
*
* @param aBuffer the buffer to copy from
* @param aStart the index of the first code unit to copy
* @param aLength the number of code units to copy
*/
void AppendCharacters(const PRUnichar* aBuffer,
PRInt32 aStart,
PRInt32 aLength);
/**
* Enqueues a tree op for adding an href attribute with the view-source:
* URL scheme to the current node.
*
* @param aValue the (potentially relative) URL to link to
*/
void AddViewSourceHref(const nsString& aValue);
/**
* The state we are transitioning away from.
*/
PRInt32 mState;
/**
* The index of the first UTF-16 code unit in mBuffer that hasn't been
* flushed yet.
*/
PRInt32 mCStart;
/**
* The position of the code unit in mBuffer that caused the current
* transition.
*/
PRInt32 mPos;
/**
* The number of inline elements open inside the <pre>.
*/
PRInt32 mInlinesOpen;
/**
* The current buffer being tokenized.
*/
nsHtml5UTF16Buffer* mBuffer;
/**
* The URL of the document to be shown in the page title.
*/
nsString mURL;
/**
* Whether to highlight syntax visibly initially.
*/
bool mSyntaxHighlight;
/**
* Whether to wrap long lines.
*/
bool mWrapLongLines;
/**
* The tab size pref.
*/
PRInt32 mTabSize;
/**
* The outgoing tree op queue.
*/
nsTArray<nsHtml5TreeOperation> mOpQueue;
/**
* The tree op stage for the tree op executor.
*/
nsAHtml5TreeOpSink* mOpSink;
/**
* Memory for element handles.
*/
nsAutoArrayPtr<nsIContent*> mHandles;
/**
* Number of handles used in mHandles
*/
PRInt32 mHandlesUsed;
/**
* A holder for old contents of mHandles
*/
nsTArray<nsAutoArrayPtr<nsIContent*> > mOldHandles;
/**
* The element stack.
*/
nsTArray<nsIContent**> mStack;
/**
* The string "comment"
*/
static PRUnichar sComment[];
/**
* The string "cdata"
*/
static PRUnichar sCdata[];
/**
* The string "start-tag"
*/
static PRUnichar sStartTag[];
/**
* The string "attribute-name"
*/
static PRUnichar sAttributeName[];
/**
* The string "attribute-value"
*/
static PRUnichar sAttributeValue[];
/**
* The string "end-tag"
*/
static PRUnichar sEndTag[];
/**
* The string "doctype"
*/
static PRUnichar sDoctype[];
/**
* The string "entity"
*/
static PRUnichar sEntity[];
};
#endif // nsHtml5Highlighter_h_

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -35,17 +35,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -35,17 +35,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -128,7 +128,8 @@ nsHtml5Parser::GetCommand(nsCString& aCommand)
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
nsHtml5Parser::SetCommand(const char* aCommand) nsHtml5Parser::SetCommand(const char* aCommand)
{ {
NS_ASSERTION(!strcmp(aCommand, "view"), "Parser command was not view"); NS_ASSERTION(!strcmp(aCommand, "view") || !strcmp(aCommand, "view-source"),
"Parser command was not view");
} }
NS_IMETHODIMP_(void) NS_IMETHODIMP_(void)
@ -698,10 +699,21 @@ nsHtml5Parser::EndEvaluatingParserInsertedScript()
} }
void void
nsHtml5Parser::MarkAsNotScriptCreated() nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
{ {
NS_PRECONDITION(!mStreamParser, "Must not call this twice."); NS_PRECONDITION(!mStreamParser, "Must not call this twice.");
mStreamParser = new nsHtml5StreamParser(mExecutor, this); eParserMode mode = NORMAL;
if (!nsCRT::strcmp(aCommand, "view-source")) {
mode = VIEW_SOURCE_HTML;
// XXX XML view source not implemented yet
}
#ifdef DEBUG
else {
NS_ASSERTION(!nsCRT::strcmp(aCommand, "view"),
"Unsupported parser command!");
}
#endif
mStreamParser = new nsHtml5StreamParser(mExecutor, this, mode);
} }
bool bool

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

@ -246,8 +246,11 @@ class nsHtml5Parser : public nsIParser,
/** /**
* Marks the HTML5 parser as not a script-created parser: Prepares the * Marks the HTML5 parser as not a script-created parser: Prepares the
* parser to be able to read a stream. * parser to be able to read a stream.
*
* @param aCommand the parser command (Yeah, this is bad API design. Let's
* make this better when retiring nsIParser)
*/ */
virtual void MarkAsNotScriptCreated(); virtual void MarkAsNotScriptCreated(const char* aCommand);
/** /**
* True if this is a script-created HTML5 parser. * True if this is a script-created HTML5 parser.

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -35,17 +35,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -33,17 +33,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -53,6 +53,7 @@
#include "nsHtml5RefPtr.h" #include "nsHtml5RefPtr.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "nsHtml5Highlighter.h"
using namespace mozilla; using namespace mozilla;
@ -174,12 +175,16 @@ class nsHtml5LoadFlusher : public nsRunnable
}; };
nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor, nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
nsHtml5Parser* aOwner) nsHtml5Parser* aOwner,
eParserMode aMode)
: mFirstBuffer(nsnull) // Will be filled when starting : mFirstBuffer(nsnull) // Will be filled when starting
, mLastBuffer(nsnull) // Will be filled when starting , mLastBuffer(nsnull) // Will be filled when starting
, mExecutor(aExecutor) , mExecutor(aExecutor)
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor->GetStage(), , mTreeBuilder(new nsHtml5TreeBuilder((aMode == VIEW_SOURCE_HTML ||
mExecutor->GetStage())) aMode == VIEW_SOURCE_XML) ?
nsnull : mExecutor->GetStage(),
aMode == NORMAL ?
mExecutor->GetStage() : nsnull))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder)) , mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
, mTokenizerMutex("nsHtml5StreamParser mTokenizerMutex") , mTokenizerMutex("nsHtml5StreamParser mTokenizerMutex")
, mOwner(aOwner) , mOwner(aOwner)
@ -189,6 +194,7 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
, mExecutorFlusher(new nsHtml5ExecutorFlusher(aExecutor)) , mExecutorFlusher(new nsHtml5ExecutorFlusher(aExecutor))
, mLoadFlusher(new nsHtml5LoadFlusher(aExecutor)) , mLoadFlusher(new nsHtml5LoadFlusher(aExecutor))
, mFlushTimer(do_CreateInstance("@mozilla.org/timer;1")) , mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
, mMode(aMode)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mFlushTimer->SetTarget(mThread); mFlushTimer->SetTarget(mThread);
@ -199,6 +205,10 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
mTokenizer->setInterner(&mAtomTable); mTokenizer->setInterner(&mAtomTable);
mTokenizer->setEncodingDeclarationHandler(this); mTokenizer->setEncodingDeclarationHandler(this);
if (aMode == VIEW_SOURCE_HTML || aMode == VIEW_SOURCE_XML) {
mTokenizer->EnableViewSource(new nsHtml5Highlighter(mExecutor->GetStage()));
}
// Chardet instantiation adapted from nsDOMFile. // Chardet instantiation adapted from nsDOMFile.
// Chardet is initialized here even if it turns out to be useless // Chardet is initialized here even if it turns out to be useless
// to make the chardet refcount its observer (nsHtml5StreamParser) // to make the chardet refcount its observer (nsHtml5StreamParser)
@ -685,6 +695,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
mStreamState = STREAM_BEING_READ; mStreamState = STREAM_BEING_READ;
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
mTokenizer->StartViewSource();
}
// For View Source, the parser should run with scripts "enabled" if a normal
// load would have scripts enabled.
bool scriptingEnabled = mExecutor->IsScriptEnabled(); bool scriptingEnabled = mExecutor->IsScriptEnabled();
mOwner->StartTokenizer(scriptingEnabled); mOwner->StartTokenizer(scriptingEnabled);
mTreeBuilder->setScriptingEnabled(scriptingEnabled); mTreeBuilder->setScriptingEnabled(scriptingEnabled);
@ -713,7 +728,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
nsresult rv = NS_OK; nsresult rv = NS_OK;
mReparseForbidden = false; // 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);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mRequest, &rv)); nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mRequest, &rv));
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
nsCAutoString method; nsCAutoString method;
@ -1007,6 +1026,9 @@ nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer()
mFlushTimer->Cancel(); mFlushTimer->Cancel();
mFlushTimerArmed = false; mFlushTimerArmed = false;
} }
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
mTokenizer->FlushViewSource();
}
mTreeBuilder->Flush(); mTreeBuilder->Flush();
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) { if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
NS_WARNING("failed to dispatch executor flush event"); NS_WARNING("failed to dispatch executor flush event");
@ -1049,6 +1071,9 @@ nsHtml5StreamParser::ParseAvailableData()
mAtEOF = true; mAtEOF = true;
mTokenizer->eof(); mTokenizer->eof();
mTreeBuilder->StreamEnded(); mTreeBuilder->StreamEnded();
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
mTokenizer->EndViewSource();
}
FlushTreeOpsAndDisarmTimer(); FlushTreeOpsAndDisarmTimer();
return; // no more data and not expecting more return; // no more data and not expecting more
default: default:
@ -1069,7 +1094,7 @@ nsHtml5StreamParser::ParseAvailableData()
// Terminate, but that never happens together with script. // Terminate, but that never happens together with script.
// Can't assert that here, though, because it's possible that the main // Can't assert that here, though, because it's possible that the main
// thread has called Terminate() while this thread was parsing. // thread has called Terminate() while this thread was parsing.
if (mTreeBuilder->HasScript()) { if (mMode == NORMAL && mTreeBuilder->HasScript()) {
mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex); mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
nsHtml5Speculation* speculation = nsHtml5Speculation* speculation =
new nsHtml5Speculation(mFirstBuffer, new nsHtml5Speculation(mFirstBuffer,
@ -1114,6 +1139,8 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
bool aLastWasCR) bool aLastWasCR)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!(mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML),
"ContinueAfterScripts called in view source mode!");
if (mExecutor->IsBroken()) { if (mExecutor->IsBroken()) {
return; return;
} }
@ -1329,11 +1356,20 @@ nsHtml5StreamParser::TimerFlush()
return; return;
} }
// we aren't speculating and we don't know when new data is if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
// going to arrive. Send data to the main thread. mTreeBuilder->Flush(); // delete useless ops
if (mTreeBuilder->Flush(true)) { if (mTokenizer->FlushViewSource()) {
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) { if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
NS_WARNING("failed to dispatch executor flush event"); NS_WARNING("failed to dispatch executor flush event");
}
}
} else {
// we aren't speculating and we don't know when new data is
// going to arrive. Send data to the main thread.
if (mTreeBuilder->Flush(true)) {
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
NS_WARNING("failed to dispatch executor flush event");
}
} }
} }
} }

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

@ -60,6 +60,28 @@ class nsHtml5Parser;
#define NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE 1024 #define NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE 1024
#define NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE 1024 #define NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE 1024
enum eParserMode {
/**
* Parse a document normally as HTML.
*/
NORMAL,
/**
* View document as HTML source.
*/
VIEW_SOURCE_HTML,
/**
* View document as XML source
*/
VIEW_SOURCE_XML,
/**
* View document as plain text
*/
PLAIN_TEXT
};
enum eBomState { enum eBomState {
/** /**
* BOM sniffing hasn't started. * BOM sniffing hasn't started.
@ -118,7 +140,8 @@ class nsHtml5StreamParser : public nsIStreamListener,
static void InitializeStatics(); static void InitializeStatics();
nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor, nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
nsHtml5Parser* aOwner); nsHtml5Parser* aOwner,
eParserMode aMode);
virtual ~nsHtml5StreamParser(); virtual ~nsHtml5StreamParser();
@ -495,6 +518,11 @@ class nsHtml5StreamParser : public nsIStreamListener,
*/ */
bool mFlushTimerEverFired; bool mFlushTimerEverFired;
/**
* Whether the parser is doing a normal parse, view source or plain text.
*/
eParserMode mMode;
/** /**
* The pref html5.flushtimer.initialdelay: Time in milliseconds between * The pref html5.flushtimer.initialdelay: Time in milliseconds between
* the time a network buffer is seen and the timer firing when the * the time a network buffer is seen and the timer firing when the

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -35,9 +35,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h" #include "nsHtml5DocumentMode.h"
@ -45,10 +43,9 @@
#include "nsHtml5NamedCharacters.h" #include "nsHtml5NamedCharacters.h"
#include "nsHtml5NamedCharactersAccel.h" #include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Highlighter.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;
@ -219,6 +216,7 @@ class nsHtml5Tokenizer
bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer); bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);
private: private:
PRInt32 stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* buf, bool reconsume, PRInt32 returnState, PRInt32 endPos); PRInt32 stateLoop(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* buf, bool reconsume, PRInt32 returnState, PRInt32 endPos);
PRInt32 stateLoopReportTransitions(PRInt32 state, PRUnichar c, PRInt32 pos, PRUnichar* buf, bool reconsume, PRInt32 returnState, PRInt32 endPos);
void initDoctypeFields(); void initDoctypeFields();
inline void adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn() inline void adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn()
{ {
@ -291,6 +289,8 @@ class nsHtml5Tokenizer
~nsHtml5Tokenizer(); ~nsHtml5Tokenizer();
static void initializeStatics(); static void initializeStatics();
static void releaseStatics(); static void releaseStatics();
#include "nsHtml5TokenizerHSupplement.h"
}; };
#define NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK ~1 #define NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK ~1

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

@ -0,0 +1,60 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML5 View Source code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
void
nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter)
{
mViewSource = aHighlighter;
}
bool
nsHtml5Tokenizer::FlushViewSource()
{
return mViewSource->FlushOps();
}
void
nsHtml5Tokenizer::StartViewSource()
{
mViewSource->Start();
}
void
nsHtml5Tokenizer::EndViewSource()
{
mViewSource->End();
}

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

@ -0,0 +1,46 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is HTML5 View Source code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Henri Sivonen <hsivonen@iki.fi>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
nsAutoPtr<nsHtml5Highlighter> mViewSource;
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
bool FlushViewSource();
void StartViewSource();
void EndViewSource();

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

@ -44,7 +44,6 @@
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5Parser.h" #include "nsHtml5Parser.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsHtml5TreeOperation.h" #include "nsHtml5TreeOperation.h"
#include "nsHtml5PendingNotification.h" #include "nsHtml5PendingNotification.h"
#include "nsHtml5StateSnapshot.h" #include "nsHtml5StateSnapshot.h"

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

@ -45,7 +45,6 @@
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5Parser.h" #include "nsHtml5Parser.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsHtml5TreeOperation.h" #include "nsHtml5TreeOperation.h"
#include "nsHtml5PendingNotification.h" #include "nsHtml5PendingNotification.h"
#include "nsHtml5StateSnapshot.h" #include "nsHtml5StateSnapshot.h"

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

@ -893,6 +893,24 @@ nsHtml5TreeOpExecutor::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* a
GetParser()->InitializeDocWriteParserState(aState, aLine); GetParser()->InitializeDocWriteParserState(aState, aLine);
} }
nsIURI*
nsHtml5TreeOpExecutor::GetViewSourceBaseURI()
{
if (!mViewSourceBaseURI) {
nsCOMPtr<nsIURI> orig = mDocument->GetOriginalURI();
bool isViewSource;
orig->SchemeIs("view-source", &isViewSource);
if (isViewSource) {
nsCOMPtr<nsINestedURI> nested = do_QueryInterface(orig);
NS_ASSERTION(nested, "URI with scheme view-source didn't QI to nested!");
nested->GetInnerURI(getter_AddRefs(mViewSourceBaseURI));
} else {
mViewSourceBaseURI = orig;
}
}
return mViewSourceBaseURI;
}
// Speculative loading // Speculative loading
already_AddRefed<nsIURI> already_AddRefed<nsIURI>

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

@ -112,6 +112,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
nsCOMPtr<nsIURI> mSpeculationBaseURI; nsCOMPtr<nsIURI> mSpeculationBaseURI;
nsCOMPtr<nsIURI> mViewSourceBaseURI;
/** /**
* Whether the parser has started * Whether the parser has started
*/ */
@ -416,6 +418,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
} }
#endif #endif
nsIURI* GetViewSourceBaseURI();
void PreloadScript(const nsAString& aURL, void PreloadScript(const nsAString& aURL,
const nsAString& aCharset, const nsAString& aCharset,
const nsAString& aType); const nsAString& aType);

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

@ -65,6 +65,9 @@
#include "nsEscape.h" #include "nsEscape.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "nsHtml5SVGLoadDispatcher.h" #include "nsHtml5SVGLoadDispatcher.h"
#include "nsIURI.h"
#include "nsIProtocolHandler.h"
#include "nsNetUtil.h"
namespace dom = mozilla::dom; namespace dom = mozilla::dom;
@ -125,6 +128,7 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation()
case eTreeOpAppendText: case eTreeOpAppendText:
case eTreeOpAppendComment: case eTreeOpAppendComment:
case eTreeOpAppendCommentToDocument: case eTreeOpAppendCommentToDocument:
case eTreeOpAddViewSourceHref:
delete[] mTwo.unicharPtr; delete[] mTwo.unicharPtr;
break; break;
case eTreeOpSetDocumentCharset: case eTreeOpSetDocumentCharset:
@ -707,6 +711,69 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
} }
return rv; return rv;
} }
case eTreeOpAddClass: {
nsIContent* node = *(mOne.node);
PRUnichar* str = mTwo.unicharPtr;
nsDependentString depStr(str);
node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, depStr, true);
return rv;
}
case eTreeOpAddViewSourceHref: {
nsIContent* node = *mOne.node;
PRUnichar* buffer = mTwo.unicharPtr;
PRInt32 length = mInt;
nsDependentString relative(buffer, length);
nsIDocument* doc = aBuilder->GetDocument();
const nsCString& charset = doc->GetDocumentCharacterSet();
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri),
relative,
charset.get(),
aBuilder->GetViewSourceBaseURI());
NS_ENSURE_SUCCESS(rv, rv);
// Reuse the fix for bug 467852
// URLs that execute script (e.g. "javascript:" URLs) should just be
// ignored. There's nothing reasonable we can do with them, and allowing
// them to execute in the context of the view-source window presents a
// security risk. Just return the empty string in this case.
bool openingExecutesScript = false;
rv = NS_URIChainHasFlags(uri,
nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT,
&openingExecutesScript);
NS_ENSURE_SUCCESS(rv, NS_OK);
if (openingExecutesScript) {
return NS_OK;
}
nsCAutoString viewSourceUrl;
// URLs that return data (e.g. "http:" URLs) should be prefixed with
// "view-source:". URLs that don't return data should just be returned
// undecorated.
bool doesNotReturnData = false;
rv = NS_URIChainHasFlags(uri,
nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
&doesNotReturnData);
NS_ENSURE_SUCCESS(rv, NS_OK);
if (!doesNotReturnData) {
viewSourceUrl.AssignLiteral("view-source:");
}
nsCAutoString spec;
uri->GetSpec(spec);
viewSourceUrl.Append(spec);
nsAutoString utf16;
CopyUTF8toUTF16(viewSourceUrl, utf16);
node->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
return rv;
}
default: { default: {
NS_NOTREACHED("Bogus tree op"); NS_NOTREACHED("Bogus tree op");
} }

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

@ -84,6 +84,8 @@ enum eHtml5TreeOperation {
eTreeOpSetStyleLineNumber, eTreeOpSetStyleLineNumber,
eTreeOpSetScriptLineNumberAndFreeze, eTreeOpSetScriptLineNumberAndFreeze,
eTreeOpSvgLoad, eTreeOpSvgLoad,
eTreeOpAddClass,
eTreeOpAddViewSourceHref,
eTreeOpStartLayout eTreeOpStartLayout
}; };
@ -293,6 +295,17 @@ class nsHtml5TreeOperation {
mInt = aInt; mInt = aInt;
} }
inline void InitAddClass(nsIContent** aNode, const PRUnichar* aClass) {
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
NS_PRECONDITION(aClass, "Initialized tree op with null string.");
// aClass must be a literal string that does not need freeing
mOpCode = eTreeOpAddClass;
mOne.node = aNode;
mTwo.unicharPtr = (PRUnichar*)aClass;
}
inline bool IsRunScript() { inline bool IsRunScript() {
return mOpCode == eTreeOpRunScript; return mOpCode == eTreeOpRunScript;
} }

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

@ -33,17 +33,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
#include "nsHtml5Tokenizer.h" #include "nsHtml5Tokenizer.h"

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

@ -34,17 +34,13 @@
#include "nsString.h" #include "nsString.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIDocument.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h" #include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h" #include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h" #include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h" #include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h" #include "nsIUnicodeDecoder.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h" #include "nsHtml5Macros.h"
class nsHtml5StreamParser; class nsHtml5StreamParser;

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

@ -301,7 +301,7 @@ class nsIParser : public nsISupports {
/** /**
* Marks the HTML5 parser as not a script-created parser. * Marks the HTML5 parser as not a script-created parser.
*/ */
virtual void MarkAsNotScriptCreated() = 0; virtual void MarkAsNotScriptCreated(const char* aCommand) = 0;
/** /**
* True if this is a script-created HTML5 parser. * True if this is a script-created HTML5 parser.

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

@ -1824,7 +1824,7 @@ nsParser::EndEvaluatingParserInsertedScript()
} }
void void
nsParser::MarkAsNotScriptCreated() nsParser::MarkAsNotScriptCreated(const char* aCommand)
{ {
} }

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

@ -343,7 +343,7 @@ class nsParser : public nsIParser,
/** /**
* No-op. * No-op.
*/ */
virtual void MarkAsNotScriptCreated(); virtual void MarkAsNotScriptCreated(const char* aCommand);
/** /**
* Always false. * Always false.