mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
be4fef94e8
- Bug 711670: Setup the Mac Application Delegate earlier to respond to URLs clicked in external applications when updates are pending. r=mstange (2471469680) - Bug 1252889: On Windows use a 10 second pause instead of trying to invoke the JIT debugger with MOZ_DEBUG_CHILD_PROCESS. r=jimm (228cd75e4d) - Bug 1253850: On Windows change MOZ_DEBUG_CHILD_PROCESS back to JIT and add MOZ_DEBUG_CHILD_PAUSE for a 10 second pause. r=mchang (83cdaec0a7) - Bug 1259809 - Make CrashReporter::InitChildProcessTmpDir conditional on MOZ_CRASHREPORTER. r=aklotz (19672176dd) - Bug 1176703 - attempt to fix define issues with some compilers/envs, rs=me, CLOSED TREE, bustage (8e6f3a6b94) - Bug 1266292 - Remove unnecessary compiler checks for MSVS 2010 in gfx/2d/. r=bas (9c3acd9f5d) - Bug 1195788 - Set arithmetic composite clamp to true for D2D filter node. r=bas (5ba4191512) - Bug 1248223 - verify that stroke widths are finite for Skia. r=jmuizelaar (1f676f5c24) - Bug 1241918 - remove workarounds for zero-length dash intervals in HelpersSkia.h, r=jrmuizel (ce0665ab77) - crashreporter includes (c64d834706) - Add a driver crash guard to D3D11 DXVA. (bug 1253666, r=mattwoodrow) (8589eef61b) - Bug 1189918 - Theme overrides should work in safe mode for comm-central applications too. r=bsmedberg (535486b4c0) - Disable the WebGL crash guard on Android. (bug 1256371, r=snorp) a=merge (855cc66aef) - Bug 1265273 - Add two missing get_PBrowserParent() null checks. r=jimm. (b5f9ac0967) - Bug 1261599 - null check SendPBrowserConstructor return in ContentParent to avoid crashes on content process shutdown. r=smaug (28e2ad71b5) - Fix D3D11VideoCrashGuard missing a switch case in ContentParent. (bug 1263725, r=mattwoodrow) (07a5b63633) - Bug 1216371 - Load default theme from XPI in safe mode. r=bsmedberg (596bc54a13) - Bug 1216371 - Load default theme from XPI in safe mode. r=bsmedberg (596bc54a13) - Bug 1162965 - Use /dev/shm instead of /tmp for sandbox chroot if possible. r=kang (4fa3c77756) - Bug 1264226: Don't use '_COARSE' Posix clocks if not defined, r=jld (a173b195eb) - Bug 1259273 - Add sys_unlink to seccomp-bpf whitelist. r=jld (72ca2626f6) - Bug 1259283 - Add sys_fchown to seccomp whitelist. r=jld (628f3cd627) - Bug 1253194: Suppress -Wimplicit-fallthrough clang warning for intentional fallthrough in icu_utf.cc (which is imported code). r=bobowen (a503963ff2) - Bug 1257031 - Return more informative error code when encountering invalid integers rather than SEC_ERROR_BAD_DER. r=keeler (7f4955614a) - Bug 1153446 - Replace instances of double spacing with single spacing in nsserrors.properties. r=dkeeler (166f0bd1c4) - Bug 1256530 - Fix compiler warnings about casting to larger size. r=hsivonen (53020d1543) - Bug 1251235 - changed from naked pointers to UniquePtr to prevent resource leak. r=froydnj (953040a377) - Bug 1264887: |nsWifiScannerDBus|: Hold DBusConnection reference in |RefPtr|, r=josh (3d8b9b3f52) - Bug 1212056 - Add virtual dtor to WindowsWifiScannerInterface. r=jdm (ce00cf01e9) - code style (d7fea73856) - Bug 1222170 - fix initialization order in ScopedWLANObject; r=jimm (b515ea0273) - Bug 1204919 - Build osx_corewlan.mm with -Wno-error=objc-method-access to avoid bustage on some machines in warnings-on-errors builds. r=glandium. (f88b02868d) - Bug 1204277 - Disallow warnings in six more directories. r=glandium. (7e249cf4ab) - Bug 1248761 - Destroy VRHMDInfo objects on the compositor thread r=daoshengmu (ccf6af1fec) - Bug 1260530 - Add support for Oculus 1.3 runtime r=daoshengmu (f7ed5abb4f) - Bug 1242005 - Disable C4359 to allow compilation on VS2015; r=kip (71db7148f4) - Bug 1176158 - "Remove unused lang atoms (ko-xxx and x-symbol)" r=vladimir (25e46d1150) - Bug 1176158 - Part 2. Remove unused ko_xxx and x_symbols from gfxGDIFontList. r=jdaggett (9b213333e0) - Bug 1262304 - Add a pref to dump display lists for the content process. r=BenWa (c0a4e56542) - Bug 1180942 - Use cairo's image backend for drawing on linux. r=jrmuizel (83deed801b) - Bug 1254400 - Handle device reset for d3d9. r=dvander (170aaeb272) - Bug 1254400 - Make access to d3d9 device manager thread-safe. r=dvander (a6112d8b84) - Bug 1256547: When the DWM is disabled don't force presentation. r=milan (0fe31bfc50) - Bug 1229988 - verify that reference draw target is created after device reset and log failure in gfxWindowsPlatform::UpdateRenderMode. r=milan (32084a6688) - Bug 1250669. Don't init dwrite fonts if content device creation fails. r=dvander (4a55599c8b) - Include vendor and device ids in content process DXGI adapter matching. (bug 1228905, r=jrmuizel) (c9403d3798) - Bug 1233576. Ensure vsync timestamps are monotonic on Windows 10. r=kats (d075fb7230) - Bug 1249036 Check that DWMFlush executes correctly. r=kats (f460b09853) - Bug 1259248. Follow up to fix static analysis bustage (ab462300ff) - Bug 1259248. Add a comment about mfbt/Range.h (a78f7c2110) - Bug 1262681 - Draw target also has to be valid for us to demand a snapshot. r=bas (c4c0bfcaca) - Bug 1258313 - Allow snapping of 'pseudo' 3d transforms. r=jrmuizel (fc85ac9147) - Bug 1241060 - Skip non-2d sibling layers when calculating plugin window clipping under e10s. r=mstange (fc6836ab11) - Bug 1257288 - Have APZ hit testing respect scroll clips. r=kats (5f8db91909) - Bug 1255961 - Avoid zeroing out shmems (r=dvander) (cc0e856f83) - Bug 1251523 - Remove TextureFlags::DEALLOCATE_CLIENT from AndroidSurfaceTextureData r=nical (406a27e229) - Regenerate SyncObjects on device resets. (bug 1255711, r=bas) (8a83c23cdf) - Bug 1240659 - Add GonkNativeHandle::CreateDupNhObj() r=nical (3da777655e) - Bug 1238602 - Update ParamTraits<GonkNativeHandle>::Read() r=nical (969f8177fd) - Bug 1248923 - Store result in Update ParamTraits<GonkNativeHandle>::Read() r=nical (0052a996a0)
803 lines
23 KiB
C++
803 lines
23 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsHtml5Highlighter.h"
|
|
#include "nsDebug.h"
|
|
#include "nsHtml5Tokenizer.h"
|
|
#include "nsHtml5AttributeName.h"
|
|
#include "nsString.h"
|
|
#include "nsThreadUtils.h"
|
|
#include "nsHtml5ViewSourceUtils.h"
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/Preferences.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
// The old code had a limit of 16 tokens. 1300 is a number picked my measuring
|
|
// the size of 16 tokens on cnn.com.
|
|
#define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
|
|
|
|
char16_t nsHtml5Highlighter::sComment[] =
|
|
{ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sCdata[] =
|
|
{ 'c', 'd', 'a', 't', 'a', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sEntity[] =
|
|
{ 'e', 'n', 't', 'i', 't', 'y', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sEndTag[] =
|
|
{ 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sStartTag[] =
|
|
{ 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sAttributeName[] =
|
|
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sAttributeValue[] =
|
|
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
|
|
'v', 'a', 'l', 'u', 'e', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sDoctype[] =
|
|
{ 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
|
|
|
|
char16_t nsHtml5Highlighter::sPi[] =
|
|
{ 'p', 'i', 0 };
|
|
|
|
nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
|
|
: mState(NS_HTML5TOKENIZER_DATA)
|
|
, mCStart(INT32_MAX)
|
|
, mPos(0)
|
|
, mLineNumber(1)
|
|
, mInlinesOpen(0)
|
|
, mInCharacters(false)
|
|
, mBuffer(nullptr)
|
|
, mOpSink(aOpSink)
|
|
, mCurrentRun(nullptr)
|
|
, mAmpersand(nullptr)
|
|
, mSlash(nullptr)
|
|
, mHandles(MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH))
|
|
, mHandlesUsed(0)
|
|
, mSeenBase(false)
|
|
{
|
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
}
|
|
|
|
nsHtml5Highlighter::~nsHtml5Highlighter()
|
|
{
|
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::Start(const nsAutoString& aTitle)
|
|
{
|
|
// Doctype
|
|
mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
|
|
|
|
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
|
|
|
|
nsIContent** root = CreateElement(nsHtml5Atoms::html, nullptr, nullptr);
|
|
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
|
|
mStack.AppendElement(root);
|
|
|
|
Push(nsGkAtoms::head, nullptr);
|
|
|
|
Push(nsGkAtoms::title, nullptr);
|
|
// XUL will add the "Source of: " prefix.
|
|
uint32_t length = aTitle.Length();
|
|
if (length > INT32_MAX) {
|
|
length = INT32_MAX;
|
|
}
|
|
AppendCharacters(aTitle.get(), 0, (int32_t)length);
|
|
Pop(); // title
|
|
|
|
Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
|
|
|
|
mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
|
|
|
|
Pop(); // link
|
|
|
|
Pop(); // head
|
|
|
|
Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
|
|
|
|
nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
|
|
nsString* preId = new nsString(NS_LITERAL_STRING("line1"));
|
|
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId);
|
|
Push(nsGkAtoms::pre, preAttrs);
|
|
|
|
StartCharacters();
|
|
|
|
mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
|
|
}
|
|
|
|
int32_t
|
|
nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume, int32_t 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.
|
|
if (aState == NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE) {
|
|
StartSpan();
|
|
// Start another span for highlighting the ampersand
|
|
StartSpan();
|
|
mAmpersand = CurrentNode();
|
|
} else {
|
|
EndCharactersAndStartMarkupRun();
|
|
}
|
|
break;
|
|
case NS_HTML5TOKENIZER_TAG_OPEN:
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_TAG_NAME:
|
|
StartSpan(sStartTag);
|
|
break;
|
|
case NS_HTML5TOKENIZER_DATA:
|
|
FinishTag(); // DATA
|
|
break;
|
|
case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION:
|
|
AddClass(sPi);
|
|
break;
|
|
}
|
|
break;
|
|
case NS_HTML5TOKENIZER_TAG_NAME:
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
|
EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
|
|
break;
|
|
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
|
EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
|
|
StartSpan(); // for highlighting the slash
|
|
mSlash = CurrentNode();
|
|
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
|
|
mSlash = CurrentNode();
|
|
break;
|
|
default:
|
|
FinishTag();
|
|
break;
|
|
}
|
|
break;
|
|
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
|
|
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
|
|
EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
|
|
break;
|
|
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
|
EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
|
|
StartSpan(); // for highlighting the slash
|
|
mSlash = CurrentNode();
|
|
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:
|
|
EndSpanOrA();
|
|
break;
|
|
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
|
|
StartSpan();
|
|
StartSpan(); // for ampersand itself
|
|
mAmpersand = CurrentNode();
|
|
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
|
|
mSlash = CurrentNode();
|
|
break;
|
|
default:
|
|
FinishTag();
|
|
break;
|
|
}
|
|
break;
|
|
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
|
EndSpanOrA(); // end the slash highlight
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
|
break;
|
|
default:
|
|
FinishTag();
|
|
break;
|
|
}
|
|
break;
|
|
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
|
EndSpanOrA();
|
|
break;
|
|
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
|
|
StartSpan();
|
|
StartSpan(); // for ampersand itself
|
|
mAmpersand = CurrentNode();
|
|
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
|
|
mSlash = CurrentNode();
|
|
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_START:
|
|
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:
|
|
EndSpanOrA(); // the span for the ampersand
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_CONSUME_NCR:
|
|
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
|
|
break;
|
|
default:
|
|
// not actually a character reference
|
|
EndSpanOrA();
|
|
break;
|
|
}
|
|
break;
|
|
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
|
|
if (aState == NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL) {
|
|
break;
|
|
}
|
|
// not actually a character reference
|
|
EndSpanOrA();
|
|
break;
|
|
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
|
|
if (!aReconsume) {
|
|
FlushCurrent();
|
|
}
|
|
EndSpanOrA();
|
|
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;
|
|
}
|
|
EndSpanOrA();
|
|
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;
|
|
}
|
|
EndSpanOrA();
|
|
StartCharacters();
|
|
break;
|
|
case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
|
|
switch (aState) {
|
|
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
|
|
AddClass(sEndTag);
|
|
EndSpanOrA();
|
|
break;
|
|
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
|
|
AddClass(sEndTag);
|
|
EndSpanOrA();
|
|
StartSpan(); // for highlighting the slash
|
|
mSlash = CurrentNode();
|
|
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) {
|
|
FlushCurrent();
|
|
StartSpan(); // don't know if it is "end-tag" yet :-(
|
|
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) {
|
|
EndCharactersAndStartMarkupRun();
|
|
}
|
|
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;
|
|
case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK:
|
|
if (aState == NS_HTML5TOKENIZER_DATA) {
|
|
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;
|
|
}
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(eTreeOpStreamEnded);
|
|
FlushOps();
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer)
|
|
{
|
|
NS_PRECONDITION(!mBuffer, "Old buffer still here!");
|
|
mBuffer = aBuffer;
|
|
mCStart = aBuffer->getStart();
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::DropBuffer(int32_t aPos)
|
|
{
|
|
NS_PRECONDITION(mBuffer, "No buffer to drop!");
|
|
mPos = aPos;
|
|
FlushChars();
|
|
mBuffer = nullptr;
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::StartSpan()
|
|
{
|
|
FlushChars();
|
|
Push(nsGkAtoms::span, nullptr);
|
|
++mInlinesOpen;
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::StartSpan(const char16_t* aClass)
|
|
{
|
|
StartSpan();
|
|
AddClass(aClass);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::EndSpanOrA()
|
|
{
|
|
FlushChars();
|
|
Pop();
|
|
--mInlinesOpen;
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::StartCharacters()
|
|
{
|
|
NS_PRECONDITION(!mInCharacters, "Already in characters!");
|
|
FlushChars();
|
|
Push(nsGkAtoms::span, nullptr);
|
|
mCurrentRun = CurrentNode();
|
|
mInCharacters = true;
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::EndCharactersAndStartMarkupRun()
|
|
{
|
|
NS_PRECONDITION(mInCharacters, "Not in characters!");
|
|
FlushChars();
|
|
Pop();
|
|
mInCharacters = false;
|
|
// Now start markup run
|
|
StartSpan();
|
|
mCurrentRun = CurrentNode();
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::StartA()
|
|
{
|
|
FlushChars();
|
|
Push(nsGkAtoms::a, nullptr);
|
|
AddClass(sAttributeValue);
|
|
++mInlinesOpen;
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::FinishTag()
|
|
{
|
|
while (mInlinesOpen > 1) {
|
|
EndSpanOrA();
|
|
}
|
|
FlushCurrent(); // >
|
|
EndSpanOrA(); // DATA
|
|
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
|
|
StartCharacters();
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::FlushChars()
|
|
{
|
|
if (mCStart < mPos) {
|
|
char16_t* buf = mBuffer->getBuffer();
|
|
int32_t i = mCStart;
|
|
while (i < mPos) {
|
|
char16_t c = buf[i];
|
|
switch (c) {
|
|
case '\r':
|
|
// The input this code sees has been normalized so that there are
|
|
// CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
|
|
// to show consistent LF line breaks to layout. It is OK to mutate
|
|
// the input data, because there are no reparses in the View Source
|
|
// case, so we won't need the original data in the buffer anymore.
|
|
buf[i] = '\n';
|
|
MOZ_FALLTHROUGH;
|
|
case '\n': {
|
|
++i;
|
|
if (mCStart < i) {
|
|
int32_t len = i - mCStart;
|
|
AppendCharacters(buf, mCStart, len);
|
|
mCStart = i;
|
|
}
|
|
++mLineNumber;
|
|
Push(nsGkAtoms::span, nullptr);
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
|
|
Pop();
|
|
break;
|
|
}
|
|
default:
|
|
++i;
|
|
break;
|
|
}
|
|
}
|
|
if (mCStart < mPos) {
|
|
int32_t len = mPos - mCStart;
|
|
AppendCharacters(buf, mCStart, len);
|
|
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(Move(mHandles));
|
|
mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH);
|
|
mHandlesUsed = 0;
|
|
}
|
|
#ifdef DEBUG
|
|
mHandles[mHandlesUsed] = reinterpret_cast<nsIContent*>(uintptr_t(0xC0DEDBAD));
|
|
#endif
|
|
return &mHandles[mHandlesUsed++];
|
|
}
|
|
|
|
nsIContent**
|
|
nsHtml5Highlighter::CreateElement(nsIAtom* aName,
|
|
nsHtml5HtmlAttributes* aAttributes,
|
|
nsIContent** aIntendedParent)
|
|
{
|
|
NS_PRECONDITION(aName, "Got null name.");
|
|
nsIContent** content = AllocateContentHandle();
|
|
mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
|
|
aName,
|
|
aAttributes,
|
|
content,
|
|
aIntendedParent,
|
|
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, CurrentNode()); // 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 char16_t* aBuffer,
|
|
int32_t aStart,
|
|
int32_t aLength)
|
|
{
|
|
NS_PRECONDITION(aBuffer, "Null buffer");
|
|
|
|
char16_t* bufferCopy = new char16_t[aLength];
|
|
memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(char16_t));
|
|
|
|
mOpQueue.AppendElement()->Init(eTreeOpAppendText,
|
|
bufferCopy,
|
|
aLength,
|
|
CurrentNode());
|
|
}
|
|
|
|
|
|
void
|
|
nsHtml5Highlighter::AddClass(const char16_t* aClass)
|
|
{
|
|
mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
|
|
{
|
|
char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
|
|
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t));
|
|
bufferCopy[aValue.Length()] = 0;
|
|
|
|
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
|
|
bufferCopy,
|
|
aValue.Length(),
|
|
CurrentNode());
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddBase(const nsString& aValue)
|
|
{
|
|
if(mSeenBase) {
|
|
return;
|
|
}
|
|
mSeenBase = true;
|
|
char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
|
|
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t));
|
|
bufferCopy[aValue.Length()] = 0;
|
|
|
|
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase,
|
|
bufferCopy,
|
|
aValue.Length());
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId)
|
|
{
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(CurrentNode(), aMsgId);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId)
|
|
{
|
|
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(mCurrentRun, aMsgId);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
|
|
nsIAtom* aName)
|
|
{
|
|
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(mCurrentRun, aMsgId, aName);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
|
|
nsIAtom* aName,
|
|
nsIAtom* aOther)
|
|
{
|
|
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(mCurrentRun, aMsgId, aName, aOther);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId)
|
|
{
|
|
NS_PRECONDITION(mAmpersand, "Adding error to ampersand without one!");
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(mAmpersand, aMsgId);
|
|
}
|
|
|
|
void
|
|
nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId)
|
|
{
|
|
NS_PRECONDITION(mSlash, "Adding error to slash without one!");
|
|
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
|
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
|
treeOp->Init(mSlash, aMsgId);
|
|
}
|