зеркало из https://github.com/mozilla/pjs.git
Bug 482921 part 1 - Implement HTML syntax highlighting using the new parser. r=Olli.Pettay.
This commit is contained in:
Родитель
3e5a97a7af
Коммит
aa8cafb38c
|
@ -576,7 +576,8 @@ nsHTMLDocument::StartAutodetection(nsIDocShell *aDocShell, nsACString& aCharset,
|
|||
if (mIsRegularHTML &&
|
||||
nsHtml5Module::sEnabled &&
|
||||
aCommand &&
|
||||
!nsCRT::strcmp(aCommand, "view")) {
|
||||
(!nsCRT::strcmp(aCommand, "view") ||
|
||||
!nsCRT::strcmp(aCommand, "view-source"))) {
|
||||
return; // the HTML5 parser uses chardet directly
|
||||
}
|
||||
nsCOMPtr <nsIParserFilter> cdetflt;
|
||||
|
@ -675,7 +676,8 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
if (loadAsHtml5 &&
|
||||
!(contentType.EqualsLiteral("text/html") &&
|
||||
aCommand &&
|
||||
!nsCRT::strcmp(aCommand, "view"))) {
|
||||
(!nsCRT::strcmp(aCommand, "view") ||
|
||||
!nsCRT::strcmp(aCommand, "view-source")))) {
|
||||
loadAsHtml5 = false;
|
||||
}
|
||||
|
||||
|
@ -728,7 +730,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
|||
if (needsParser) {
|
||||
if (loadAsHtml5) {
|
||||
mParser = nsHtml5Module::NewHtml5Parser();
|
||||
mParser->MarkAsNotScriptCreated();
|
||||
mParser->MarkAsNotScriptCreated(aCommand);
|
||||
} else {
|
||||
mParser = do_CreateInstance(kCParserCID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -107,6 +107,7 @@ CPPSRCS = \
|
|||
nsHtml5Speculation.cpp \
|
||||
nsHtml5SpeculativeLoad.cpp \
|
||||
nsHtml5SVGLoadDispatcher.cpp \
|
||||
nsHtml5Highlighter.cpp \
|
||||
$(NULL)
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
|
|
@ -1220,6 +1220,9 @@ public class Tokenizer implements Locator {
|
|||
if (attributeName != null) {
|
||||
String val = longStrBufToString(); // Ownership transferred to
|
||||
// HtmlAttributes
|
||||
// CPPONLY: if (mViewSource) {
|
||||
// CPPONLY: mViewSource.MaybeLinkifyAttributeValue(attributeName, val);
|
||||
// CPPONLY: }
|
||||
// [NOCPP[
|
||||
if (!endTag && html4 && html4ModeCompatibleWithXhtml1Schemata
|
||||
&& attributeName.isCaseFolded()) {
|
||||
|
@ -1316,8 +1319,17 @@ public class Tokenizer implements Locator {
|
|||
* meaning. (The rest of the array is garbage and should not be
|
||||
* 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,
|
||||
buffer.getEnd());
|
||||
// ]NOCPP]
|
||||
if (pos == buffer.getEnd()) {
|
||||
// exiting due to end of buffer
|
||||
buffer.setStart(pos);
|
||||
|
@ -3149,6 +3161,7 @@ public class Tokenizer implements Locator {
|
|||
* second column of the named character references
|
||||
* table).
|
||||
*/
|
||||
// CPPONLY: mViewSource.CompletedNamedCharacterReference();
|
||||
@Const @NoLength char[] val = NamedCharacters.VALUES[candidate];
|
||||
if (
|
||||
// [NOCPP[
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
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 "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -128,7 +128,8 @@ nsHtml5Parser::GetCommand(nsCString& aCommand)
|
|||
NS_IMETHODIMP_(void)
|
||||
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)
|
||||
|
@ -698,10 +699,21 @@ nsHtml5Parser::EndEvaluatingParserInsertedScript()
|
|||
}
|
||||
|
||||
void
|
||||
nsHtml5Parser::MarkAsNotScriptCreated()
|
||||
nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -246,8 +246,11 @@ class nsHtml5Parser : public nsIParser,
|
|||
/**
|
||||
* Marks the HTML5 parser as not a script-created parser: Prepares the
|
||||
* 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.
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsHtml5RefPtr.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsHtml5Highlighter.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -174,12 +175,16 @@ class nsHtml5LoadFlusher : public nsRunnable
|
|||
};
|
||||
|
||||
nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
||||
nsHtml5Parser* aOwner)
|
||||
nsHtml5Parser* aOwner,
|
||||
eParserMode aMode)
|
||||
: mFirstBuffer(nsnull) // Will be filled when starting
|
||||
, mLastBuffer(nsnull) // Will be filled when starting
|
||||
, mExecutor(aExecutor)
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor->GetStage(),
|
||||
mExecutor->GetStage()))
|
||||
, mTreeBuilder(new nsHtml5TreeBuilder((aMode == VIEW_SOURCE_HTML ||
|
||||
aMode == VIEW_SOURCE_XML) ?
|
||||
nsnull : mExecutor->GetStage(),
|
||||
aMode == NORMAL ?
|
||||
mExecutor->GetStage() : nsnull))
|
||||
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder))
|
||||
, mTokenizerMutex("nsHtml5StreamParser mTokenizerMutex")
|
||||
, mOwner(aOwner)
|
||||
|
@ -189,6 +194,7 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
|||
, mExecutorFlusher(new nsHtml5ExecutorFlusher(aExecutor))
|
||||
, mLoadFlusher(new nsHtml5LoadFlusher(aExecutor))
|
||||
, mFlushTimer(do_CreateInstance("@mozilla.org/timer;1"))
|
||||
, mMode(aMode)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
mFlushTimer->SetTarget(mThread);
|
||||
|
@ -199,6 +205,10 @@ nsHtml5StreamParser::nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
|||
mTokenizer->setInterner(&mAtomTable);
|
||||
mTokenizer->setEncodingDeclarationHandler(this);
|
||||
|
||||
if (aMode == VIEW_SOURCE_HTML || aMode == VIEW_SOURCE_XML) {
|
||||
mTokenizer->EnableViewSource(new nsHtml5Highlighter(mExecutor->GetStage()));
|
||||
}
|
||||
|
||||
// Chardet instantiation adapted from nsDOMFile.
|
||||
// Chardet is initialized here even if it turns out to be useless
|
||||
// to make the chardet refcount its observer (nsHtml5StreamParser)
|
||||
|
@ -685,6 +695,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
|
||||
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();
|
||||
mOwner->StartTokenizer(scriptingEnabled);
|
||||
mTreeBuilder->setScriptingEnabled(scriptingEnabled);
|
||||
|
@ -713,7 +728,11 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|||
|
||||
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));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCAutoString method;
|
||||
|
@ -1007,6 +1026,9 @@ nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer()
|
|||
mFlushTimer->Cancel();
|
||||
mFlushTimerArmed = false;
|
||||
}
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
|
@ -1049,6 +1071,9 @@ nsHtml5StreamParser::ParseAvailableData()
|
|||
mAtEOF = true;
|
||||
mTokenizer->eof();
|
||||
mTreeBuilder->StreamEnded();
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTokenizer->EndViewSource();
|
||||
}
|
||||
FlushTreeOpsAndDisarmTimer();
|
||||
return; // no more data and not expecting more
|
||||
default:
|
||||
|
@ -1069,7 +1094,7 @@ nsHtml5StreamParser::ParseAvailableData()
|
|||
// Terminate, but that never happens together with script.
|
||||
// Can't assert that here, though, because it's possible that the main
|
||||
// thread has called Terminate() while this thread was parsing.
|
||||
if (mTreeBuilder->HasScript()) {
|
||||
if (mMode == NORMAL && mTreeBuilder->HasScript()) {
|
||||
mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
|
||||
nsHtml5Speculation* speculation =
|
||||
new nsHtml5Speculation(mFirstBuffer,
|
||||
|
@ -1114,6 +1139,8 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
|
|||
bool aLastWasCR)
|
||||
{
|
||||
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()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1329,6 +1356,14 @@ nsHtml5StreamParser::TimerFlush()
|
|||
return;
|
||||
}
|
||||
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
mTreeBuilder->Flush(); // delete useless ops
|
||||
if (mTokenizer->FlushViewSource()) {
|
||||
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
||||
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)) {
|
||||
|
@ -1336,6 +1371,7 @@ nsHtml5StreamParser::TimerFlush()
|
|||
NS_WARNING("failed to dispatch executor flush event");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -60,6 +60,28 @@ class nsHtml5Parser;
|
|||
#define NS_HTML5_STREAM_PARSER_READ_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 {
|
||||
/**
|
||||
* BOM sniffing hasn't started.
|
||||
|
@ -118,7 +140,8 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
static void InitializeStatics();
|
||||
|
||||
nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
|
||||
nsHtml5Parser* aOwner);
|
||||
nsHtml5Parser* aOwner,
|
||||
eParserMode aMode);
|
||||
|
||||
virtual ~nsHtml5StreamParser();
|
||||
|
||||
|
@ -495,6 +518,11 @@ class nsHtml5StreamParser : public nsIStreamListener,
|
|||
*/
|
||||
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 time a network buffer is seen and the timer firing when the
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -35,9 +35,7 @@
|
|||
#include "nsIAtom.h"
|
||||
#include "nsHtml5AtomTable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
|
@ -45,10 +43,9 @@
|
|||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
#include "nsHtml5Highlighter.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
||||
|
@ -219,6 +216,7 @@ class nsHtml5Tokenizer
|
|||
bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);
|
||||
private:
|
||||
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();
|
||||
inline void adjustDoubleHyphenAndAppendToLongStrBufCarriageReturn()
|
||||
{
|
||||
|
@ -291,6 +289,8 @@ class nsHtml5Tokenizer
|
|||
~nsHtml5Tokenizer();
|
||||
static void initializeStatics();
|
||||
static void releaseStatics();
|
||||
|
||||
#include "nsHtml5TokenizerHSupplement.h"
|
||||
};
|
||||
|
||||
#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 "nsHtml5Parser.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5Parser.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
|
|
|
@ -893,6 +893,24 @@ nsHtml5TreeOpExecutor::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* a
|
|||
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
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
|
|
|
@ -112,6 +112,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
|||
|
||||
nsCOMPtr<nsIURI> mSpeculationBaseURI;
|
||||
|
||||
nsCOMPtr<nsIURI> mViewSourceBaseURI;
|
||||
|
||||
/**
|
||||
* Whether the parser has started
|
||||
*/
|
||||
|
@ -416,6 +418,8 @@ class nsHtml5TreeOpExecutor : public nsContentSink,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsIURI* GetViewSourceBaseURI();
|
||||
|
||||
void PreloadScript(const nsAString& aURL,
|
||||
const nsAString& aCharset,
|
||||
const nsAString& aType);
|
||||
|
|
|
@ -65,6 +65,9 @@
|
|||
#include "nsEscape.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsHtml5SVGLoadDispatcher.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
namespace dom = mozilla::dom;
|
||||
|
||||
|
@ -125,6 +128,7 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation()
|
|||
case eTreeOpAppendText:
|
||||
case eTreeOpAppendComment:
|
||||
case eTreeOpAppendCommentToDocument:
|
||||
case eTreeOpAddViewSourceHref:
|
||||
delete[] mTwo.unicharPtr;
|
||||
break;
|
||||
case eTreeOpSetDocumentCharset:
|
||||
|
@ -707,6 +711,69 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||
}
|
||||
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: {
|
||||
NS_NOTREACHED("Bogus tree op");
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ enum eHtml5TreeOperation {
|
|||
eTreeOpSetStyleLineNumber,
|
||||
eTreeOpSetScriptLineNumberAndFreeze,
|
||||
eTreeOpSvgLoad,
|
||||
eTreeOpAddClass,
|
||||
eTreeOpAddViewSourceHref,
|
||||
eTreeOpStartLayout
|
||||
};
|
||||
|
||||
|
@ -293,6 +295,17 @@ class nsHtml5TreeOperation {
|
|||
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() {
|
||||
return mOpCode == eTreeOpRunScript;
|
||||
}
|
||||
|
|
|
@ -33,17 +33,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
#include "nsHtml5Tokenizer.h"
|
||||
|
|
|
@ -34,17 +34,13 @@
|
|||
#include "nsString.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "jArray.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsHtml5ArrayCopy.h"
|
||||
#include "nsHtml5NamedCharacters.h"
|
||||
#include "nsHtml5NamedCharactersAccel.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5ByteReadable.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsAHtml5TreeBuilderState.h"
|
||||
#include "nsHtml5Macros.h"
|
||||
|
||||
class nsHtml5StreamParser;
|
||||
|
|
|
@ -301,7 +301,7 @@ class nsIParser : public nsISupports {
|
|||
/**
|
||||
* 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.
|
||||
|
|
|
@ -1824,7 +1824,7 @@ nsParser::EndEvaluatingParserInsertedScript()
|
|||
}
|
||||
|
||||
void
|
||||
nsParser::MarkAsNotScriptCreated()
|
||||
nsParser::MarkAsNotScriptCreated(const char* aCommand)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -343,7 +343,7 @@ class nsParser : public nsIParser,
|
|||
/**
|
||||
* No-op.
|
||||
*/
|
||||
virtual void MarkAsNotScriptCreated();
|
||||
virtual void MarkAsNotScriptCreated(const char* aCommand);
|
||||
|
||||
/**
|
||||
* Always false.
|
||||
|
|
Загрузка…
Ссылка в новой задаче