Introduce a new non-heap-allocated type for holding nsStringBuffer* in the HTML parser.

master
Fedor 2019-09-05 20:03:31 +03:00
parent 9c0a72c8e7
commit da7905c861
34 changed files with 719 additions and 358 deletions

View File

@ -39,6 +39,7 @@ EXPORTS += [
'nsHtml5SpeculativeLoad.h', 'nsHtml5SpeculativeLoad.h',
'nsHtml5StreamListener.h', 'nsHtml5StreamListener.h',
'nsHtml5StreamParser.h', 'nsHtml5StreamParser.h',
'nsHtml5String.h',
'nsHtml5StringParser.h', 'nsHtml5StringParser.h',
'nsHtml5SVGLoadDispatcher.h', 'nsHtml5SVGLoadDispatcher.h',
'nsHtml5TreeOperation.h', 'nsHtml5TreeOperation.h',
@ -78,6 +79,7 @@ UNIFIED_SOURCES += [
'nsHtml5StateSnapshot.cpp', 'nsHtml5StateSnapshot.cpp',
'nsHtml5StreamListener.cpp', 'nsHtml5StreamListener.cpp',
'nsHtml5StreamParser.cpp', 'nsHtml5StreamParser.cpp',
'nsHtml5String.cpp',
'nsHtml5StringParser.cpp', 'nsHtml5StringParser.cpp',
'nsHtml5SVGLoadDispatcher.cpp', 'nsHtml5SVGLoadDispatcher.cpp',
'nsHtml5Tokenizer.cpp', 'nsHtml5Tokenizer.cpp',

View File

@ -51,10 +51,11 @@ class nsHtml5ArrayCopy {
memcpy(target, source, size_t(length) * sizeof(int32_t)); memcpy(target, source, size_t(length) * sizeof(int32_t));
} }
static inline void static inline void arraycopy(nsHtml5String* source,
arraycopy(nsString** source, nsString** target, int32_t length) nsHtml5String* target,
int32_t length)
{ {
memcpy(target, source, size_t(length) * sizeof(nsString*)); memcpy(target, source, size_t(length) * sizeof(nsHtml5String));
} }
static inline void static inline void

View File

@ -29,7 +29,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -29,7 +29,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -91,7 +91,7 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
if (length > INT32_MAX) { if (length > INT32_MAX) {
length = INT32_MAX; length = INT32_MAX;
} }
AppendCharacters(aTitle.get(), 0, (int32_t)length); AppendCharacters(aTitle.BeginReading(), 0, (int32_t)length);
Pop(); // title Pop(); // title
Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes()); Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
@ -105,7 +105,7 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes()); Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0); nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
nsString* preId = new nsString(NS_LITERAL_STRING("line1")); nsHtml5String preId = nsHtml5Portability::newStringFromLiteral("line1");
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId, -1); preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId, -1);
Push(nsGkAtoms::pre, preAttrs); Push(nsGkAtoms::pre, preAttrs);
@ -618,7 +618,7 @@ nsHtml5Highlighter::FlushOps()
void void
nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName, nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue) nsHtml5String aValue)
{ {
if (!(nsHtml5AttributeName::ATTR_HREF == aName || if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
nsHtml5AttributeName::ATTR_SRC == aName || nsHtml5AttributeName::ATTR_SRC == aName ||
@ -630,7 +630,7 @@ nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) { nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
return; return;
} }
AddViewSourceHref(*aValue); AddViewSourceHref(aValue);
} }
void void
@ -717,10 +717,10 @@ nsHtml5Highlighter::AddClass(const char16_t* aClass)
} }
void void
nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue) nsHtml5Highlighter::AddViewSourceHref(nsHtml5String aValue)
{ {
char16_t* bufferCopy = new char16_t[aValue.Length() + 1]; char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t)); aValue.CopyToBuffer(bufferCopy);
bufferCopy[aValue.Length()] = 0; bufferCopy[aValue.Length()] = 0;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref, mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
@ -730,14 +730,14 @@ nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
} }
void void
nsHtml5Highlighter::AddBase(const nsString& aValue) nsHtml5Highlighter::AddBase(nsHtml5String aValue)
{ {
if(mSeenBase) { if(mSeenBase) {
return; return;
} }
mSeenBase = true; mSeenBase = true;
char16_t* bufferCopy = new char16_t[aValue.Length() + 1]; char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t)); aValue.CopyToBuffer(bufferCopy);
bufferCopy[aValue.Length()] = 0; bufferCopy[aValue.Length()] = 0;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase, mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase,

View File

@ -78,7 +78,7 @@ class nsHtml5Highlighter
* @param aValue the value of the attribute * @param aValue the value of the attribute
*/ */
void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName, void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue); nsHtml5String aValue);
/** /**
* Inform the highlighter that the tokenizer successfully completed a * Inform the highlighter that the tokenizer successfully completed a
@ -147,7 +147,7 @@ class nsHtml5Highlighter
* *
* @param aValue the base URL to add * @param aValue the base URL to add
*/ */
void AddBase(const nsString& aValue); void AddBase(nsHtml5String aValue);
private: private:
@ -272,7 +272,7 @@ class nsHtml5Highlighter
* *
* @param aValue the (potentially relative) URL to link to * @param aValue the (potentially relative) URL to link to
*/ */
void AddViewSourceHref(const nsString& aValue); void AddViewSourceHref(nsHtml5String aValue);
/** /**
* The state we are transitioning away from. * The state we are transitioning away from.

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -58,11 +58,11 @@
nsHtml5HtmlAttributes* nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES = nullptr; nsHtml5HtmlAttributes* nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES = nullptr;
nsHtml5HtmlAttributes::nsHtml5HtmlAttributes(int32_t mode) nsHtml5HtmlAttributes::nsHtml5HtmlAttributes(int32_t mode)
: mode(mode), : mode(mode)
length(0), , length(0)
names(jArray<nsHtml5AttributeName*,int32_t>::newJArray(8)), , names(jArray<nsHtml5AttributeName*, int32_t>::newJArray(8))
values(jArray<nsString*,int32_t>::newJArray(8)), , values(jArray<nsHtml5String, int32_t>::newJArray(8))
lines(jArray<int32_t,int32_t>::newJArray(8)) , lines(jArray<int32_t, int32_t>::newJArray(8))
{ {
MOZ_COUNT_CTOR(nsHtml5HtmlAttributes); MOZ_COUNT_CTOR(nsHtml5HtmlAttributes);
} }
@ -85,7 +85,7 @@ nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name)
return -1; return -1;
} }
nsString* nsHtml5String
nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name) nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name)
{ {
int32_t index = getIndex(name); int32_t index = getIndex(name);
@ -123,7 +123,7 @@ nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index)
return names[index]->getPrefix(mode); return names[index]->getPrefix(mode);
} }
nsString* nsHtml5String
nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index) nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index)
{ {
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds"); MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
@ -145,14 +145,17 @@ nsHtml5HtmlAttributes::getLineNoBoundsCheck(int32_t index)
} }
void void
nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsString* value, int32_t line) nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name,
nsHtml5String value,
int32_t line)
{ {
if (names.length == length) { if (names.length == length) {
int32_t newLen = length << 1; int32_t newLen = length << 1;
jArray<nsHtml5AttributeName*,int32_t> newNames = jArray<nsHtml5AttributeName*,int32_t>::newJArray(newLen); jArray<nsHtml5AttributeName*,int32_t> newNames = jArray<nsHtml5AttributeName*,int32_t>::newJArray(newLen);
nsHtml5ArrayCopy::arraycopy(names, newNames, names.length); nsHtml5ArrayCopy::arraycopy(names, newNames, names.length);
names = newNames; names = newNames;
jArray<nsString*,int32_t> newValues = jArray<nsString*,int32_t>::newJArray(newLen); jArray<nsHtml5String, int32_t> newValues =
jArray<nsHtml5String, int32_t>::newJArray(newLen);
nsHtml5ArrayCopy::arraycopy(values, newValues, values.length); nsHtml5ArrayCopy::arraycopy(values, newValues, values.length);
values = newValues; values = newValues;
jArray<int32_t,int32_t> newLines = jArray<int32_t,int32_t>::newJArray(newLen); jArray<int32_t,int32_t> newLines = jArray<int32_t,int32_t>::newJArray(newLen);
@ -171,7 +174,7 @@ nsHtml5HtmlAttributes::clear(int32_t m)
for (int32_t i = 0; i < length; i++) { for (int32_t i = 0; i < length; i++) {
names[i]->release(); names[i]->release();
names[i] = nullptr; names[i] = nullptr;
nsHtml5Portability::releaseString(values[i]); values[i].Release();
values[i] = nullptr; values[i] = nullptr;
} }
length = 0; length = 0;
@ -181,7 +184,7 @@ nsHtml5HtmlAttributes::clear(int32_t m)
void void
nsHtml5HtmlAttributes::releaseValue(int32_t i) nsHtml5HtmlAttributes::releaseValue(int32_t i)
{ {
nsHtml5Portability::releaseString(values[i]); values[i].Release();
} }
void void

View File

@ -31,7 +31,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -64,21 +64,23 @@ class nsHtml5HtmlAttributes
int32_t mode; int32_t mode;
int32_t length; int32_t length;
autoJArray<nsHtml5AttributeName*,int32_t> names; autoJArray<nsHtml5AttributeName*,int32_t> names;
autoJArray<nsString*,int32_t> values; autoJArray<nsHtml5String, int32_t> values;
autoJArray<int32_t,int32_t> lines; autoJArray<int32_t,int32_t> lines;
public: public:
explicit nsHtml5HtmlAttributes(int32_t mode); explicit nsHtml5HtmlAttributes(int32_t mode);
~nsHtml5HtmlAttributes(); ~nsHtml5HtmlAttributes();
int32_t getIndex(nsHtml5AttributeName* name); int32_t getIndex(nsHtml5AttributeName* name);
nsString* getValue(nsHtml5AttributeName* name); nsHtml5String getValue(nsHtml5AttributeName* name);
int32_t getLength(); int32_t getLength();
nsIAtom* getLocalNameNoBoundsCheck(int32_t index); nsIAtom* getLocalNameNoBoundsCheck(int32_t index);
int32_t getURINoBoundsCheck(int32_t index); int32_t getURINoBoundsCheck(int32_t index);
nsIAtom* getPrefixNoBoundsCheck(int32_t index); nsIAtom* getPrefixNoBoundsCheck(int32_t index);
nsString* getValueNoBoundsCheck(int32_t index); nsHtml5String getValueNoBoundsCheck(int32_t index);
nsHtml5AttributeName* getAttributeNameNoBoundsCheck(int32_t index); nsHtml5AttributeName* getAttributeNameNoBoundsCheck(int32_t index);
int32_t getLineNoBoundsCheck(int32_t index); int32_t getLineNoBoundsCheck(int32_t index);
void addAttribute(nsHtml5AttributeName* name, nsString* value, int32_t line); void addAttribute(nsHtml5AttributeName* name,
nsHtml5String value,
int32_t line);
void clear(int32_t m); void clear(int32_t m);
void releaseValue(int32_t i); void releaseValue(int32_t i);
void clearWithoutReleasingContents(); void clearWithoutReleasingContents();

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -86,8 +86,8 @@ nsHtml5MetaScanner::nsHtml5MetaScanner(nsHtml5TreeBuilder* tb)
nsHtml5MetaScanner::~nsHtml5MetaScanner() nsHtml5MetaScanner::~nsHtml5MetaScanner()
{ {
MOZ_COUNT_DTOR(nsHtml5MetaScanner); MOZ_COUNT_DTOR(nsHtml5MetaScanner);
nsHtml5Portability::releaseString(content); content.Release();
nsHtml5Portability::releaseString(charset); charset.Release();
} }
void void
@ -771,9 +771,9 @@ bool
nsHtml5MetaScanner::handleTag() nsHtml5MetaScanner::handleTag()
{ {
bool stop = handleTagInner(); bool stop = handleTagInner();
nsHtml5Portability::releaseString(content); content.Release();
content = nullptr; content = nullptr;
nsHtml5Portability::releaseString(charset); charset.Release();
charset = nullptr; charset = nullptr;
httpEquivState = NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN; httpEquivState = NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN;
return stop; return stop;
@ -786,12 +786,13 @@ nsHtml5MetaScanner::handleTagInner()
return true; return true;
} }
if (!!content && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE) { if (!!content && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE) {
nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, treeBuilder); nsHtml5String extract =
nsHtml5TreeBuilder::extractCharsetFromContent(content, treeBuilder);
if (!extract) { if (!extract) {
return false; return false;
} }
bool success = tryCharset(extract); bool success = tryCharset(extract);
nsHtml5Portability::releaseString(extract); extract.Release();
return success; return success;
} }
return false; return false;

View File

@ -31,7 +31,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -76,8 +76,8 @@ class nsHtml5MetaScanner
private: private:
int32_t strBufLen; int32_t strBufLen;
autoJArray<char16_t,int32_t> strBuf; autoJArray<char16_t,int32_t> strBuf;
nsString* content; nsHtml5String content;
nsString* charset; nsHtml5String charset;
int32_t httpEquivState; int32_t httpEquivState;
nsHtml5TreeBuilder* treeBuilder; nsHtml5TreeBuilder* treeBuilder;
public: public:
@ -100,7 +100,7 @@ class nsHtml5MetaScanner
bool handleTag(); bool handleTag();
bool handleTagInner(); bool handleTagInner();
protected: protected:
bool tryCharset(nsString* encoding); bool tryCharset(nsHtml5String encoding);
public: public:
static void initializeStatics(); static void initializeStatics();
static void releaseStatics(); static void releaseStatics();

View File

@ -19,13 +19,15 @@ nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsACString& charset)
} }
bool bool
nsHtml5MetaScanner::tryCharset(nsString* charset) nsHtml5MetaScanner::tryCharset(nsHtml5String charset)
{ {
// This code needs to stay in sync with // This code needs to stay in sync with
// nsHtml5StreamParser::internalEncodingDeclaration. Unfortunately, the // nsHtml5StreamParser::internalEncodingDeclaration. Unfortunately, the
// trickery with member fields here leads to some copy-paste reuse. :-( // trickery with member fields here leads to some copy-paste reuse. :-(
nsAutoCString label; nsAutoCString label;
CopyUTF16toUTF8(*charset, label); nsString charset16; // Not Auto, because using it to hold nsStringBuffer*
charset.ToString(charset16);
CopyUTF16toUTF8(charset16, label);
nsAutoCString encoding; nsAutoCString encoding;
if (!EncodingUtils::FindEncodingForLabel(label, encoding)) { if (!EncodingUtils::FindEncodingForLabel(label, encoding)) {
return false; return false;

View File

@ -5,21 +5,24 @@
#include "nsHtml5PlainTextUtils.h" #include "nsHtml5PlainTextUtils.h"
#include "nsHtml5AttributeName.h" #include "nsHtml5AttributeName.h"
#include "nsHtml5Portability.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "nsHtml5String.h"
// static // static
nsHtml5HtmlAttributes* nsHtml5HtmlAttributes*
nsHtml5PlainTextUtils::NewLinkAttributes() nsHtml5PlainTextUtils::NewLinkAttributes()
{ {
nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0); nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
nsString* rel = new nsString(NS_LITERAL_STRING("alternate stylesheet")); nsHtml5String rel =
nsHtml5Portability::newStringFromLiteral("alternate stylesheet");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1); linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1);
nsString* type = new nsString(NS_LITERAL_STRING("text/css")); nsHtml5String type = nsHtml5Portability::newStringFromLiteral("text/css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1); linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
nsString* href = new nsString( nsHtml5String href = nsHtml5Portability::newStringFromLiteral(
NS_LITERAL_STRING("resource://gre-resources/plaintext.css")); "resource://gre-resources/plaintext.css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1); linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
nsresult rv; nsresult rv;
@ -34,7 +37,7 @@ nsHtml5PlainTextUtils::NewLinkAttributes()
bundle->GetStringFromName(u"plainText.wordWrap", getter_Copies(title)); bundle->GetStringFromName(u"plainText.wordWrap", getter_Copies(title));
} }
nsString* titleCopy = new nsString(title); linkAttrs->addAttribute(
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TITLE, titleCopy, -1); nsHtml5AttributeName::ATTR_TITLE, nsHtml5String::FromString(title), -1);
return linkAttrs; return linkAttrs;
} }

View File

@ -16,37 +16,31 @@ nsHtml5Portability::newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_
return interner->GetAtom(nsDependentSubstring(buf, buf + length)); return interner->GetAtom(nsDependentSubstring(buf, buf + length));
} }
nsString* nsHtml5String
nsHtml5Portability::newStringFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5TreeBuilder* treeBuilder) nsHtml5Portability::newStringFromBuffer(char16_t* buf,
int32_t offset,
int32_t length,
nsHtml5TreeBuilder* treeBuilder)
{ {
nsString* str = new nsString(); return nsHtml5String::FromBuffer(buf + offset, length, treeBuilder);
bool succeeded = str->Append(buf + offset, length, mozilla::fallible);
if (!succeeded) {
str->Assign(char16_t(0xFFFD));
treeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
return str;
} }
nsString* nsHtml5String
nsHtml5Portability::newEmptyString() nsHtml5Portability::newEmptyString()
{ {
return new nsString(); return nsHtml5String::EmptyString();
} }
nsString* nsHtml5String
nsHtml5Portability::newStringFromLiteral(const char* literal) nsHtml5Portability::newStringFromLiteral(const char* literal)
{ {
nsString* str = new nsString(); return nsHtml5String::FromLiteral(literal);
str->AssignASCII(literal);
return str;
} }
nsString* nsHtml5String
nsHtml5Portability::newStringFromString(nsString* string) { nsHtml5Portability::newStringFromString(nsHtml5String string)
nsString* newStr = new nsString(); {
newStr->Assign(*string); return string.Clone();
return newStr;
} }
jArray<char16_t,int32_t> jArray<char16_t,int32_t>
@ -60,12 +54,14 @@ nsHtml5Portability::newCharArrayFromLocal(nsIAtom* local)
return arr; return arr;
} }
jArray<char16_t,int32_t> jArray<char16_t, int32_t>
nsHtml5Portability::newCharArrayFromString(nsString* string) nsHtml5Portability::newCharArrayFromString(nsHtml5String string)
{ {
int32_t len = string->Length(); MOZ_RELEASE_ASSERT(string);
uint32_t len = string.Length();
MOZ_RELEASE_ASSERT(len < INT32_MAX);
jArray<char16_t,int32_t> arr = jArray<char16_t,int32_t>::newJArray(len); jArray<char16_t,int32_t> arr = jArray<char16_t,int32_t>::newJArray(len);
memcpy(arr, string->BeginReading(), len * sizeof(char16_t)); string.CopyToBuffer(arr);
return arr; return arr;
} }
@ -82,12 +78,6 @@ nsHtml5Portability::newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner
return local; return local;
} }
void
nsHtml5Portability::releaseString(nsString* str)
{
delete str;
}
bool bool
nsHtml5Portability::localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length) nsHtml5Portability::localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length)
{ {
@ -95,55 +85,32 @@ nsHtml5Portability::localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t off
} }
bool bool
nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string) nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
const char* lowerCaseLiteral,
nsHtml5String string)
{ {
if (!string) { return string.LowerCaseStartsWithASCII(lowerCaseLiteral);
return false;
}
const char* litPtr = lowerCaseLiteral;
const char16_t* strPtr = string->BeginReading();
const char16_t* end = string->EndReading();
char16_t litChar;
while ((litChar = *litPtr)) {
NS_ASSERTION(!(litChar >= 'A' && litChar <= 'Z'), "Literal isn't in lower case.");
if (strPtr == end) {
return false;
}
char16_t strChar = *strPtr;
if (strChar >= 'A' && strChar <= 'Z') {
strChar += 0x20;
}
if (litChar != strChar) {
return false;
}
++litPtr;
++strPtr;
}
return true;
} }
bool bool
nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string) nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
const char* lowerCaseLiteral,
nsHtml5String string)
{ {
if (!string) { return string.LowerCaseEqualsASCII(lowerCaseLiteral);
return false;
}
return string->LowerCaseEqualsASCII(lowerCaseLiteral);
} }
bool bool
nsHtml5Portability::literalEqualsString(const char* literal, nsString* string) nsHtml5Portability::literalEqualsString(const char* literal,
nsHtml5String string)
{ {
if (!string) { return string.EqualsASCII(literal);
return false;
}
return string->EqualsASCII(literal);
} }
bool bool
nsHtml5Portability::stringEqualsString(nsString* one, nsString* other) nsHtml5Portability::stringEqualsString(nsHtml5String one, nsHtml5String other)
{ {
return one->Equals(*other); return one.Equals(other);
} }
void void

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -59,19 +59,26 @@ class nsHtml5Portability
{ {
public: public:
static nsIAtom* newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner); static nsIAtom* newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
static nsString* newStringFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5TreeBuilder* treeBuilder); static nsHtml5String newStringFromBuffer(char16_t* buf,
static nsString* newEmptyString(); int32_t offset,
static nsString* newStringFromLiteral(const char* literal); int32_t length,
static nsString* newStringFromString(nsString* string); nsHtml5TreeBuilder* treeBuilder);
static nsHtml5String newEmptyString();
static nsHtml5String newStringFromLiteral(const char* literal);
static nsHtml5String newStringFromString(nsHtml5String string);
static jArray<char16_t,int32_t> newCharArrayFromLocal(nsIAtom* local); static jArray<char16_t,int32_t> newCharArrayFromLocal(nsIAtom* local);
static jArray<char16_t,int32_t> newCharArrayFromString(nsString* string); static jArray<char16_t, int32_t> newCharArrayFromString(
nsHtml5String string);
static nsIAtom* newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner); static nsIAtom* newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner);
static void releaseString(nsString* str);
static bool localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length); static bool localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length);
static bool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string); static bool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
static bool lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string); const char* lowerCaseLiteral,
static bool literalEqualsString(const char* literal, nsString* string); nsHtml5String string);
static bool stringEqualsString(nsString* one, nsString* other); static bool lowerCaseLiteralEqualsIgnoreAsciiCaseString(
const char* lowerCaseLiteral,
nsHtml5String string);
static bool literalEqualsString(const char* literal, nsHtml5String string);
static bool stringEqualsString(nsHtml5String one, nsHtml5String other);
static void initializeStatics(); static void initializeStatics();
static void releaseStatics(); static void releaseStatics();
}; };

View File

@ -35,45 +35,57 @@ class nsHtml5SpeculativeLoad {
nsHtml5SpeculativeLoad(); nsHtml5SpeculativeLoad();
~nsHtml5SpeculativeLoad(); ~nsHtml5SpeculativeLoad();
inline void InitBase(const nsAString& aUrl) inline void InitBase(nsHtml5String aUrl)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadBase; mOpCode = eSpeculativeLoadBase;
mUrl.Assign(aUrl); aUrl.ToString(mUrl);
} }
inline void InitMetaCSP(const nsAString& aCSP) { inline void InitMetaCSP(nsHtml5String aCSP)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadCSP; mOpCode = eSpeculativeLoadCSP;
nsString csp; // Not Auto, because using it to hold nsStringBuffer*
aCSP.ToString(csp);
mMetaCSP.Assign( mMetaCSP.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aCSP)); nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(csp));
} }
inline void InitMetaReferrerPolicy(const nsAString& aReferrerPolicy) { inline void InitMetaReferrerPolicy(nsHtml5String aReferrerPolicy)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadMetaReferrer; mOpCode = eSpeculativeLoadMetaReferrer;
nsString
referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
aReferrerPolicy.ToString(referrerPolicy);
mReferrerPolicy.Assign( mReferrerPolicy.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy)); nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
referrerPolicy));
} }
inline void InitImage(const nsAString& aUrl, inline void InitImage(nsHtml5String aUrl,
const nsAString& aCrossOrigin, nsHtml5String aCrossOrigin,
const nsAString& aReferrerPolicy, nsHtml5String aReferrerPolicy,
const nsAString& aSrcset, nsHtml5String aSrcset,
const nsAString& aSizes) nsHtml5String aSizes)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadImage; mOpCode = eSpeculativeLoadImage;
mUrl.Assign(aUrl); aUrl.ToString(mUrl);
mCrossOrigin.Assign(aCrossOrigin); aCrossOrigin.ToString(mCrossOrigin);
nsString
referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
aReferrerPolicy.ToString(referrerPolicy);
mReferrerPolicy.Assign( mReferrerPolicy.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy)); nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
mSrcset.Assign(aSrcset); referrerPolicy));
mSizes.Assign(aSizes); aSrcset.ToString(mSrcset);
aSizes.ToString(mSizes);
} }
// <picture> elements have multiple <source> nodes followed by an <img>, // <picture> elements have multiple <source> nodes followed by an <img>,
@ -97,49 +109,50 @@ class nsHtml5SpeculativeLoad {
mOpCode = eSpeculativeLoadEndPicture; mOpCode = eSpeculativeLoadEndPicture;
} }
inline void InitPictureSource(const nsAString& aSrcset, inline void InitPictureSource(nsHtml5String aSrcset,
const nsAString& aSizes, nsHtml5String aSizes,
const nsAString& aType, nsHtml5String aType,
const nsAString& aMedia) nsHtml5String aMedia)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadPictureSource; mOpCode = eSpeculativeLoadPictureSource;
mSrcset.Assign(aSrcset); aSrcset.ToString(mSrcset);
mSizes.Assign(aSizes); aSizes.ToString(mSizes);
mTypeOrCharsetSourceOrDocumentMode.Assign(aType); aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
mMedia.Assign(aMedia); aMedia.ToString(mMedia);
} }
inline void InitScript(const nsAString& aUrl, inline void InitScript(nsHtml5String aUrl,
const nsAString& aCharset, nsHtml5String aCharset,
const nsAString& aType, nsHtml5String aType,
const nsAString& aCrossOrigin, nsHtml5String aCrossOrigin,
const nsAString& aIntegrity, nsHtml5String aIntegrity,
bool aParserInHead) bool aParserInHead)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = aParserInHead ? mOpCode = aParserInHead ?
eSpeculativeLoadScriptFromHead : eSpeculativeLoadScript; eSpeculativeLoadScriptFromHead : eSpeculativeLoadScript;
mUrl.Assign(aUrl); aUrl.ToString(mUrl);
mCharset.Assign(aCharset); aCharset.ToString(mCharset);
mTypeOrCharsetSourceOrDocumentMode.Assign(aType); aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
mCrossOrigin.Assign(aCrossOrigin); aCrossOrigin.ToString(mCrossOrigin);
mIntegrity.Assign(aIntegrity); aIntegrity.ToString(mIntegrity);
} }
inline void InitStyle(const nsAString& aUrl, const nsAString& aCharset, inline void InitStyle(nsHtml5String aUrl,
const nsAString& aCrossOrigin, nsHtml5String aCharset,
const nsAString& aIntegrity) nsHtml5String aCrossOrigin,
nsHtml5String aIntegrity)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadStyle; mOpCode = eSpeculativeLoadStyle;
mUrl.Assign(aUrl); aUrl.ToString(mUrl);
mCharset.Assign(aCharset); aCharset.ToString(mCharset);
mCrossOrigin.Assign(aCrossOrigin); aCrossOrigin.ToString(mCrossOrigin);
mIntegrity.Assign(aIntegrity); aIntegrity.ToString(mIntegrity);
} }
/** /**
@ -153,12 +166,12 @@ class nsHtml5SpeculativeLoad {
* manifests seen by the parser thread have to maintain the queue order * manifests seen by the parser thread have to maintain the queue order
* relative to true speculative loads. See bug 541079. * relative to true speculative loads. See bug 541079.
*/ */
inline void InitManifest(const nsAString& aUrl) inline void InitManifest(nsHtml5String aUrl)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadManifest; mOpCode = eSpeculativeLoadManifest;
mUrl.Assign(aUrl); aUrl.ToString(mUrl);
} }
/** /**
@ -195,14 +208,13 @@ class nsHtml5SpeculativeLoad {
mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aMode); mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aMode);
} }
inline void InitPreconnect(const nsAString& aUrl, inline void InitPreconnect(nsHtml5String aUrl, nsHtml5String aCrossOrigin)
const nsAString& aCrossOrigin)
{ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized, NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!"); "Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadPreconnect; mOpCode = eSpeculativeLoadPreconnect;
mUrl.Assign(aUrl); aUrl.ToString(mUrl);
mCrossOrigin.Assign(aCrossOrigin); aCrossOrigin.ToString(mCrossOrigin);
} }
void Perform(nsHtml5TreeOpExecutor* aExecutor); void Perform(nsHtml5TreeOpExecutor* aExecutor);

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -31,7 +31,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -29,7 +29,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -1261,7 +1261,7 @@ nsHtml5StreamParser::PreferredForInternalEncodingDecl(nsACString& aEncoding)
} }
bool bool
nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding) nsHtml5StreamParser::internalEncodingDeclaration(nsHtml5String aEncoding)
{ {
// This code needs to stay in sync with // This code needs to stay in sync with
// nsHtml5MetaScanner::tryCharset. Unfortunately, the // nsHtml5MetaScanner::tryCharset. Unfortunately, the
@ -1270,9 +1270,10 @@ nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
if (mCharsetSource >= kCharsetFromMetaTag) { // this threshold corresponds to "confident" in the HTML5 spec if (mCharsetSource >= kCharsetFromMetaTag) { // this threshold corresponds to "confident" in the HTML5 spec
return false; return false;
} }
nsString newEncoding16; // Not Auto, because using it to hold nsStringBuffer*
aEncoding.ToString(newEncoding16);
nsAutoCString newEncoding; nsAutoCString newEncoding;
CopyUTF16toUTF8(*aEncoding, newEncoding); CopyUTF16toUTF8(newEncoding16, newEncoding);
if (!PreferredForInternalEncodingDecl(newEncoding)) { if (!PreferredForInternalEncodingDecl(newEncoding)) {
return false; return false;

View File

@ -145,7 +145,7 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver {
/** /**
* Tree builder uses this to report a late <meta charset> * Tree builder uses this to report a late <meta charset>
*/ */
bool internalEncodingDeclaration(nsString* aEncoding); bool internalEncodingDeclaration(nsHtml5String aEncoding);
// Not from an external interface // Not from an external interface

View File

@ -0,0 +1,226 @@
/* 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 "nsHtml5String.h"
#include "nsCharTraits.h"
#include "nsUTF8Utils.h"
#include "nsHtml5TreeBuilder.h"
nsHtml5String::nsHtml5String(already_AddRefed<nsStringBuffer> aBuffer,
uint32_t aLength)
: mBuffer(aBuffer.take())
, mLength(aLength)
{
if (mBuffer) {
MOZ_ASSERT(aLength);
} else {
MOZ_ASSERT(!aLength || aLength == UINT32_MAX);
}
}
void
nsHtml5String::ToString(nsAString& aString)
{
if (mBuffer) {
mBuffer->ToString(mLength, aString);
} else {
aString.Truncate();
if (mLength) {
aString.SetIsVoid(true);
}
}
}
void
nsHtml5String::CopyToBuffer(char16_t* aBuffer)
{
if (mBuffer) {
memcpy(aBuffer, mBuffer->Data(), mLength * sizeof(char16_t));
}
}
bool
nsHtml5String::LowerCaseEqualsASCII(const char* aLowerCaseLiteral)
{
if (!mBuffer) {
if (mLength) {
// This string is null
return false;
}
// this string is empty
return !(*aLowerCaseLiteral);
}
return !nsCharTraits<char16_t>::compareLowerCaseToASCIINullTerminated(
reinterpret_cast<char16_t*>(mBuffer->Data()), Length(), aLowerCaseLiteral);
}
bool
nsHtml5String::EqualsASCII(const char* aLiteral)
{
if (!mBuffer) {
if (mLength) {
// This string is null
return false;
}
// this string is empty
return !(*aLiteral);
}
return !nsCharTraits<char16_t>::compareASCIINullTerminated(
reinterpret_cast<char16_t*>(mBuffer->Data()), Length(), aLiteral);
}
bool
nsHtml5String::LowerCaseStartsWithASCII(const char* aLowerCaseLiteral)
{
if (!mBuffer) {
if (mLength) {
// This string is null
return false;
}
// this string is empty
return !(*aLowerCaseLiteral);
}
const char* litPtr = aLowerCaseLiteral;
const char16_t* strPtr = reinterpret_cast<char16_t*>(mBuffer->Data());
const char16_t* end = strPtr + Length();
char16_t litChar;
while ((litChar = *litPtr) && (strPtr != end)) {
MOZ_ASSERT(!(litChar >= 'A' && litChar <= 'Z'),
"Literal isn't in lower case.");
char16_t strChar = *strPtr;
if (strChar >= 'A' && strChar <= 'Z') {
strChar += 0x20;
}
if (litChar != strChar) {
return false;
}
++litPtr;
++strPtr;
}
return true;
}
bool
nsHtml5String::Equals(nsHtml5String aOther)
{
MOZ_ASSERT(operator bool());
MOZ_ASSERT(aOther);
if (mLength != aOther.mLength) {
return false;
}
if (!mBuffer) {
return true;
}
MOZ_ASSERT(aOther.mBuffer);
return !memcmp(
mBuffer->Data(), aOther.mBuffer->Data(), Length() * sizeof(char16_t));
}
nsHtml5String
nsHtml5String::Clone()
{
MOZ_ASSERT(operator bool());
RefPtr<nsStringBuffer> ref(mBuffer);
return nsHtml5String(ref.forget(), mLength);
}
void
nsHtml5String::Release()
{
if (mBuffer) {
mBuffer->Release();
mBuffer = nullptr;
}
mLength = UINT32_MAX;
}
// static
nsHtml5String
nsHtml5String::FromBuffer(char16_t* aBuffer,
int32_t aLength,
nsHtml5TreeBuilder* aTreeBuilder)
{
if (!aLength) {
return nsHtml5String(nullptr, 0U);
}
// Work with nsStringBuffer directly to make sure that storage is actually
// nsStringBuffer and to make sure the allocation strategy matches
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
// copy.
RefPtr<nsStringBuffer> buffer(
nsStringBuffer::Alloc((aLength + 1) * sizeof(char16_t)));
if (!buffer) {
if (!aTreeBuilder) {
MOZ_CRASH("Out of memory.");
}
aTreeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
buffer = nsStringBuffer::Alloc(2 * sizeof(char16_t));
if (!buffer) {
MOZ_CRASH(
"Out of memory so badly that couldn't even allocate placeholder.");
}
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
data[0] = 0xFFFD;
data[1] = 0;
return nsHtml5String(buffer.forget(), 1);
}
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
memcpy(data, aBuffer, aLength * sizeof(char16_t));
data[aLength] = 0;
return nsHtml5String(buffer.forget(), aLength);
}
// static
nsHtml5String
nsHtml5String::FromLiteral(const char* aLiteral)
{
size_t length = std::strlen(aLiteral);
if (!length) {
return nsHtml5String(nullptr, 0U);
}
// Work with nsStringBuffer directly to make sure that storage is actually
// nsStringBuffer and to make sure the allocation strategy matches
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
// copy.
RefPtr<nsStringBuffer> buffer(
nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)));
if (!buffer) {
MOZ_CRASH("Out of memory.");
}
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
LossyConvertEncoding8to16 converter(data);
converter.write(aLiteral, length);
data[length] = 0;
return nsHtml5String(buffer.forget(), length);
}
// static
nsHtml5String
nsHtml5String::FromString(const nsAString& aString)
{
auto length = aString.Length();
if (!length) {
return nsHtml5String(nullptr, 0U);
}
RefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aString);
if (buffer) {
return nsHtml5String(buffer.forget(), length);
}
buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t));
if (!buffer) {
MOZ_CRASH("Out of memory.");
}
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
memcpy(data, aString.BeginReading(), length * sizeof(char16_t));
data[length] = 0;
return nsHtml5String(buffer.forget(), length);
}
// static
nsHtml5String
nsHtml5String::EmptyString()
{
return nsHtml5String(nullptr, 0U);
}

View File

@ -0,0 +1,95 @@
/* 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/. */
#ifndef nsHtml5String_h
#define nsHtml5String_h
#include "nsString.h"
class nsHtml5TreeBuilder;
/**
* A pass-by-value type that combines an unsafe `nsStringBuffer*` with its
* logical length (`uint32_t`). (`nsStringBuffer` knows its capacity but not
* its logical length, i.e. how much of the capacity is in use.)
*
* Holding or passing this type is as unsafe as holding or passing
* `nsStringBuffer*`.
*
* Empty strings and null strings are distinct. Since an empty nsString does
* not have a an `nsStringBuffer`, both empty and null `nsHtml5String` have
* `nullptr` as `mBuffer`. If `mBuffer` is `nullptr`, the empty case is marked
* with `mLength` being zero and the null case with `mLength` being non-zero.
*/
class nsHtml5String final
{
public:
/**
* Default constructor.
*/
inline nsHtml5String()
: nsHtml5String(nullptr)
{
}
/**
* Constructor from nullptr.
*/
inline MOZ_IMPLICIT nsHtml5String(decltype(nullptr))
: mBuffer(nullptr)
, mLength(UINT32_MAX)
{
}
inline uint32_t Length() const { return mBuffer ? mLength : 0; }
/**
* False iff the string is logically null
*/
inline MOZ_IMPLICIT operator bool() const { return !(!mBuffer && mLength); }
void ToString(nsAString& aString);
void CopyToBuffer(char16_t* aBuffer);
bool LowerCaseEqualsASCII(const char* aLowerCaseLiteral);
bool EqualsASCII(const char* aLiteral);
bool LowerCaseStartsWithASCII(const char* aLowerCaseLiteral);
bool Equals(nsHtml5String aOther);
nsHtml5String Clone();
void Release();
static nsHtml5String FromBuffer(char16_t* aBuffer,
int32_t aLength,
nsHtml5TreeBuilder* aTreeBuilder);
static nsHtml5String FromLiteral(const char* aLiteral);
static nsHtml5String FromString(const nsAString& aString);
static nsHtml5String EmptyString();
private:
/**
* Constructor from raw parts.
*/
nsHtml5String(already_AddRefed<nsStringBuffer> aBuffer, uint32_t aLength);
/**
* nullptr if the string is logically null or logically empty
*/
nsStringBuffer* mBuffer;
/**
* The length of the string. non-zero if the string is logically null.
*/
uint32_t mLength;
};
#endif // nsHtml5String_h

View File

@ -32,7 +32,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
@ -113,7 +113,8 @@ nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner)
} }
void void
nsHtml5Tokenizer::initLocation(nsString* newPublicId, nsString* newSystemId) nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
nsHtml5String newSystemId)
{ {
this->systemId = newSystemId; this->systemId = newSystemId;
this->publicId = newPublicId; this->publicId = newPublicId;
@ -222,10 +223,11 @@ nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState)
} }
} }
nsString* nsHtml5String
nsHtml5Tokenizer::strBufToString() nsHtml5Tokenizer::strBufToString()
{ {
nsString* str = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, tokenHandler); nsHtml5String str =
nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, tokenHandler);
clearStrBufAfterUse(); clearStrBufAfterUse();
return str; return str;
} }
@ -350,7 +352,7 @@ void
nsHtml5Tokenizer::addAttributeWithValue() nsHtml5Tokenizer::addAttributeWithValue()
{ {
if (attributeName) { if (attributeName) {
nsString* val = strBufToString(); nsHtml5String val = strBufToString();
if (mViewSource) { if (mViewSource) {
mViewSource->MaybeLinkifyAttributeValue(attributeName, val); mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
} }
@ -3496,11 +3498,11 @@ nsHtml5Tokenizer::initDoctypeFields()
clearStrBufAfterUse(); clearStrBufAfterUse();
doctypeName = nsHtml5Atoms::emptystring; doctypeName = nsHtml5Atoms::emptystring;
if (systemIdentifier) { if (systemIdentifier) {
nsHtml5Portability::releaseString(systemIdentifier); systemIdentifier.Release();
systemIdentifier = nullptr; systemIdentifier = nullptr;
} }
if (publicIdentifier) { if (publicIdentifier) {
nsHtml5Portability::releaseString(publicIdentifier); publicIdentifier.Release();
publicIdentifier = nullptr; publicIdentifier = nullptr;
} }
forceQuirks = false; forceQuirks = false;
@ -3662,11 +3664,11 @@ nsHtml5Tokenizer::eof()
errEofInDoctype(); errEofInDoctype();
doctypeName = nsHtml5Atoms::emptystring; doctypeName = nsHtml5Atoms::emptystring;
if (systemIdentifier) { if (systemIdentifier) {
nsHtml5Portability::releaseString(systemIdentifier); systemIdentifier.Release();
systemIdentifier = nullptr; systemIdentifier = nullptr;
} }
if (publicIdentifier) { if (publicIdentifier) {
nsHtml5Portability::releaseString(publicIdentifier); publicIdentifier.Release();
publicIdentifier = nullptr; publicIdentifier = nullptr;
} }
forceQuirks = true; forceQuirks = true;
@ -3896,14 +3898,14 @@ nsHtml5Tokenizer::emitDoctypeToken(int32_t pos)
cstart = pos + 1; cstart = pos + 1;
tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier, forceQuirks); tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier, forceQuirks);
doctypeName = nullptr; doctypeName = nullptr;
nsHtml5Portability::releaseString(publicIdentifier); publicIdentifier.Release();
publicIdentifier = nullptr; publicIdentifier = nullptr;
nsHtml5Portability::releaseString(systemIdentifier); systemIdentifier.Release();
systemIdentifier = nullptr; systemIdentifier = nullptr;
} }
bool bool
nsHtml5Tokenizer::internalEncodingDeclaration(nsString* internalCharset) nsHtml5Tokenizer::internalEncodingDeclaration(nsHtml5String internalCharset)
{ {
if (encodingDeclarationHandler) { if (encodingDeclarationHandler) {
return encodingDeclarationHandler->internalEncodingDeclaration(internalCharset); return encodingDeclarationHandler->internalEncodingDeclaration(internalCharset);
@ -3938,11 +3940,11 @@ nsHtml5Tokenizer::end()
strBuf = nullptr; strBuf = nullptr;
doctypeName = nullptr; doctypeName = nullptr;
if (systemIdentifier) { if (systemIdentifier) {
nsHtml5Portability::releaseString(systemIdentifier); systemIdentifier.Release();
systemIdentifier = nullptr; systemIdentifier = nullptr;
} }
if (publicIdentifier) { if (publicIdentifier) {
nsHtml5Portability::releaseString(publicIdentifier); publicIdentifier.Release();
publicIdentifier = nullptr; publicIdentifier = nullptr;
} }
if (tagName) { if (tagName) {
@ -4041,13 +4043,13 @@ nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
} else { } else {
doctypeName = nsHtml5Portability::newLocalFromLocal(other->doctypeName, interner); doctypeName = nsHtml5Portability::newLocalFromLocal(other->doctypeName, interner);
} }
nsHtml5Portability::releaseString(systemIdentifier); systemIdentifier.Release();
if (!other->systemIdentifier) { if (!other->systemIdentifier) {
systemIdentifier = nullptr; systemIdentifier = nullptr;
} else { } else {
systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier); systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier);
} }
nsHtml5Portability::releaseString(publicIdentifier); publicIdentifier.Release();
if (!other->publicIdentifier) { if (!other->publicIdentifier) {
publicIdentifier = nullptr; publicIdentifier = nullptr;
} else { } else {

View File

@ -33,7 +33,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
#include "jArray.h" #include "jArray.h"
@ -106,8 +106,8 @@ class nsHtml5Tokenizer
protected: protected:
int32_t cstart; int32_t cstart;
private: private:
nsString* publicId; nsHtml5String publicId;
nsString* systemId; nsHtml5String systemId;
autoJArray<char16_t,int32_t> strBuf; autoJArray<char16_t,int32_t> strBuf;
int32_t strBufLen; int32_t strBufLen;
autoJArray<char16_t,int32_t> charRefBuf; autoJArray<char16_t,int32_t> charRefBuf;
@ -126,8 +126,8 @@ class nsHtml5Tokenizer
nsHtml5AttributeName* attributeName; nsHtml5AttributeName* attributeName;
private: private:
nsIAtom* doctypeName; nsIAtom* doctypeName;
nsString* publicIdentifier; nsHtml5String publicIdentifier;
nsString* systemIdentifier; nsHtml5String systemIdentifier;
nsHtml5HtmlAttributes* attributes; nsHtml5HtmlAttributes* attributes;
bool newAttributesEachTime; bool newAttributesEachTime;
bool shouldSuspend; bool shouldSuspend;
@ -141,7 +141,7 @@ class nsHtml5Tokenizer
public: public:
nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource); nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
void setInterner(nsHtml5AtomTable* interner); void setInterner(nsHtml5AtomTable* interner);
void initLocation(nsString* newPublicId, nsString* newSystemId); void initLocation(nsHtml5String newPublicId, nsHtml5String newSystemId);
bool isViewingXmlSource(); bool isViewingXmlSource();
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation); void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation);
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation); void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation);
@ -193,7 +193,7 @@ class nsHtml5Tokenizer
} }
protected: protected:
nsString* strBufToString(); nsHtml5String strBufToString();
private: private:
void strBufToDoctypeName(); void strBufToDoctypeName();
void emitStrBuf(); void emitStrBuf();
@ -285,7 +285,7 @@ class nsHtml5Tokenizer
} }
public: public:
bool internalEncodingDeclaration(nsString* internalCharset); bool internalEncodingDeclaration(nsHtml5String internalCharset);
private: private:
void emitOrAppendTwo(const char16_t* val, int32_t returnState); void emitOrAppendTwo(const char16_t* val, int32_t returnState);
void emitOrAppendOne(const char16_t* val, int32_t returnState); void emitOrAppendOne(const char16_t* val, int32_t returnState);

View File

@ -34,7 +34,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsITimer.h" #include "nsITimer.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -154,13 +154,16 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
} }
void void
nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks) nsHtml5TreeBuilder::doctype(nsIAtom* name,
nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier,
bool forceQuirks)
{ {
needToDropLF = false; needToDropLF = false;
if (!isInForeign() && mode == NS_HTML5TREE_BUILDER_INITIAL) { if (!isInForeign() && mode == NS_HTML5TREE_BUILDER_INITIAL) {
nsString* emptyString = nsHtml5Portability::newEmptyString(); nsHtml5String emptyString = nsHtml5Portability::newEmptyString();
appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier); appendDoctypeToDocument(!name ? nsHtml5Atoms::emptystring : name, !publicIdentifier ? emptyString : publicIdentifier, !systemIdentifier ? emptyString : systemIdentifier);
nsHtml5Portability::releaseString(emptyString); emptyString.Release();
if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) { if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) {
errQuirkyDoctype(); errQuirkyDoctype();
documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false); documentModeInternal(QUIRKS_MODE, publicIdentifier, systemIdentifier, false);
@ -1990,8 +1993,9 @@ nsHtml5TreeBuilder::isSpecialParentInForeign(nsHtml5StackNode* stackNode)
return (kNameSpaceID_XHTML == ns) || (stackNode->isHtmlIntegrationPoint()) || ((kNameSpaceID_MathML == ns) && (stackNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT)); return (kNameSpaceID_XHTML == ns) || (stackNode->isHtmlIntegrationPoint()) || ((kNameSpaceID_MathML == ns) && (stackNode->getGroup() == NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT));
} }
nsString* nsHtml5String
nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb) nsHtml5TreeBuilder::extractCharsetFromContent(nsHtml5String attributeValue,
nsHtml5TreeBuilder* tb)
{ {
int32_t charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL; int32_t charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
int32_t start = -1; int32_t start = -1;
@ -2175,12 +2179,13 @@ nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5T
} }
} }
charsetloop_end: ; charsetloop_end: ;
nsString* charset = nullptr; nsHtml5String charset = nullptr;
if (start != -1) { if (start != -1) {
if (end == -1) { if (end == -1) {
end = buffer.length; end = buffer.length;
} }
charset = nsHtml5Portability::newStringFromBuffer(buffer, start, end - start, tb); charset =
nsHtml5Portability::newStringFromBuffer(buffer, start, end - start, tb);
} }
return charset; return charset;
} }
@ -2188,7 +2193,8 @@ nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5T
void void
nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes)
{ {
nsString* charset = attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET); nsHtml5String charset =
attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
if (charset) { if (charset) {
if (tokenizer->internalEncodingDeclaration(charset)) { if (tokenizer->internalEncodingDeclaration(charset)) {
requestSuspension(); requestSuspension();
@ -2199,15 +2205,17 @@ nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes)
if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("content-type", attributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) { if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("content-type", attributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
return; return;
} }
nsString* content = attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT); nsHtml5String content =
attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (content) { if (content) {
nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, this); nsHtml5String extract =
nsHtml5TreeBuilder::extractCharsetFromContent(content, this);
if (extract) { if (extract) {
if (tokenizer->internalEncodingDeclaration(extract)) { if (tokenizer->internalEncodingDeclaration(extract)) {
requestSuspension(); requestSuspension();
} }
} }
nsHtml5Portability::releaseString(extract); extract.Release();
} }
} }
@ -3208,7 +3216,11 @@ nsHtml5TreeBuilder::isSecondOnStackBody()
} }
void void
nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks) nsHtml5TreeBuilder::documentModeInternal(
nsHtml5DocumentMode m,
nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier,
bool html4SpecificAdditionalErrorChecks)
{ {
if (isSrcdocDocument) { if (isSrcdocDocument) {
quirks = false; quirks = false;
@ -3220,7 +3232,8 @@ nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* public
} }
bool bool
nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier) nsHtml5TreeBuilder::isAlmostStandards(nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier)
{ {
if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) { if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) {
return true; return true;
@ -3240,7 +3253,10 @@ nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* syst
} }
bool bool
nsHtml5TreeBuilder::isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks) nsHtml5TreeBuilder::isQuirky(nsIAtom* name,
nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier,
bool forceQuirks)
{ {
if (forceQuirks) { if (forceQuirks) {
return true; return true;
@ -4051,7 +4067,8 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5Elem
bool bool
nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes) nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes)
{ {
nsString* encoding = attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING); nsHtml5String encoding =
attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING);
if (!encoding) { if (!encoding) {
return false; return false;
} }

View File

@ -35,7 +35,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsITimer.h" #include "nsITimer.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"
@ -103,7 +103,10 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
bool isSrcdocDocument; bool isSrcdocDocument;
public: public:
void startTokenization(nsHtml5Tokenizer* self); void startTokenization(nsHtml5Tokenizer* self);
void doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks); void doctype(nsIAtom* name,
nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier,
bool forceQuirks);
void comment(char16_t* buf, int32_t start, int32_t length); void comment(char16_t* buf, int32_t start, int32_t length);
void characters(const char16_t* buf, int32_t start, int32_t length); void characters(const char16_t* buf, int32_t start, int32_t length);
void zeroOriginatingReplacementCharacter(); void zeroOriginatingReplacementCharacter();
@ -119,7 +122,8 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
bool isTemplateModeStackEmpty(); bool isTemplateModeStackEmpty();
bool isSpecialParentInForeign(nsHtml5StackNode* stackNode); bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
public: public:
static nsString* extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb); static nsHtml5String extractCharsetFromContent(nsHtml5String attributeValue,
nsHtml5TreeBuilder* tb);
private: private:
void checkMetaCharset(nsHtml5HtmlAttributes* attributes); void checkMetaCharset(nsHtml5HtmlAttributes* attributes);
public: public:
@ -136,9 +140,16 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void generateImpliedEndTagsExceptFor(nsIAtom* name); void generateImpliedEndTagsExceptFor(nsIAtom* name);
void generateImpliedEndTags(); void generateImpliedEndTags();
bool isSecondOnStackBody(); bool isSecondOnStackBody();
void documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks); void documentModeInternal(nsHtml5DocumentMode m,
bool isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier); nsHtml5String publicIdentifier,
bool isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks); nsHtml5String systemIdentifier,
bool html4SpecificAdditionalErrorChecks);
bool isAlmostStandards(nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier);
bool isQuirky(nsIAtom* name,
nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier,
bool forceQuirks);
void closeTheCell(int32_t eltPos); void closeTheCell(int32_t eltPos);
int32_t findLastInTableScopeTdTh(); int32_t findLastInTableScopeTdTh();
void clearStackBackTo(int32_t eltPos); void clearStackBackTo(int32_t eltPos);
@ -224,7 +235,9 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void markMalformedIfScript(nsIContentHandle* elt); void markMalformedIfScript(nsIContentHandle* elt);
void start(bool fragmentMode); void start(bool fragmentMode);
void end(); void end();
void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier); void appendDoctypeToDocument(nsIAtom* name,
nsHtml5String publicIdentifier,
nsHtml5String systemIdentifier);
void elementPushed(int32_t ns, nsIAtom* name, nsIContentHandle* node); void elementPushed(int32_t ns, nsIAtom* name, nsIContentHandle* node);
void elementPopped(int32_t ns, nsIAtom* name, nsIContentHandle* node); void elementPopped(int32_t ns, nsIAtom* name, nsIContentHandle* node);
public: public:

View File

@ -123,181 +123,178 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
switch (aNamespace) { switch (aNamespace) {
case kNameSpaceID_XHTML: case kNameSpaceID_XHTML:
if (nsHtml5Atoms::img == aName) { if (nsHtml5Atoms::img == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC); nsHtml5String url =
nsString* srcset = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
nsHtml5String srcset =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET); aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
nsString* crossOrigin = nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsString* referrerPolicy = nsHtml5String referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY); aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
nsString* sizes = nsHtml5String sizes =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES); aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitImage(
InitImage(url ? *url : NullString(), url, crossOrigin, referrerPolicy, srcset, sizes);
crossOrigin ? *crossOrigin : NullString(),
referrerPolicy ? *referrerPolicy : NullString(),
srcset ? *srcset : NullString(),
sizes ? *sizes : NullString());
} else if (nsHtml5Atoms::source == aName) { } else if (nsHtml5Atoms::source == aName) {
nsString* srcset = nsHtml5String srcset =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET); aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
// Sources without srcset cannot be selected. The source could also be // Sources without srcset cannot be selected. The source could also be
// for a media element, but in that context doesn't use srcset. See // for a media element, but in that context doesn't use srcset. See
// comments in nsHtml5SpeculativeLoad.h about <picture> preloading // comments in nsHtml5SpeculativeLoad.h about <picture> preloading
if (srcset) { if (srcset) {
nsString* sizes = nsHtml5String sizes =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES); aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
nsString* type = nsHtml5String type =
aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE); aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
nsString* media = nsHtml5String media =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA); aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitPictureSource(
InitPictureSource(*srcset, srcset, sizes, type, media);
sizes ? *sizes : NullString(),
type ? *type : NullString(),
media ? *media : NullString());
} }
} else if (nsHtml5Atoms::script == aName) { } else if (nsHtml5Atoms::script == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed."); NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber()); treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
if (url) { if (url) {
nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET); nsHtml5String charset =
nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE); aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
nsString* crossOrigin = nsHtml5String type =
aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsString* integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitScript(
InitScript(*url, url,
(charset) ? *charset : EmptyString(), charset,
(type) ? *type : EmptyString(), type,
(crossOrigin) ? *crossOrigin : NullString(), crossOrigin,
(integrity) ? *integrity : NullString(), integrity,
mode == NS_HTML5TREE_BUILDER_IN_HEAD); mode == NS_HTML5TREE_BUILDER_IN_HEAD);
mCurrentHtmlScriptIsAsyncOrDefer = mCurrentHtmlScriptIsAsyncOrDefer =
aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) || aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER); aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
} }
} else if (nsHtml5Atoms::link == aName) { } else if (nsHtml5Atoms::link == aName) {
nsString* rel = aAttributes->getValue(nsHtml5AttributeName::ATTR_REL); nsHtml5String rel =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REL);
// Not splitting on space here is bogus but the old parser didn't even // Not splitting on space here is bogus but the old parser didn't even
// do a case-insensitive check. // do a case-insensitive check.
if (rel) { if (rel) {
if (rel->LowerCaseEqualsASCII("stylesheet")) { if (rel.LowerCaseEqualsASCII("stylesheet")) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) { if (url) {
nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET); nsHtml5String charset =
nsString* crossOrigin = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsString* integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitStyle(
InitStyle(*url, url, charset, crossOrigin, integrity);
(charset) ? *charset : EmptyString(),
(crossOrigin) ? *crossOrigin : NullString(),
(integrity) ? *integrity : NullString());
} }
} else if (rel->LowerCaseEqualsASCII("preconnect")) { } else if (rel.LowerCaseEqualsASCII("preconnect")) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) { if (url) {
nsString* crossOrigin = nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitPreconnect(
InitPreconnect(*url, (crossOrigin) ? *crossOrigin : NullString()); url, crossOrigin);
} }
} }
} }
} else if (nsHtml5Atoms::video == aName) { } else if (nsHtml5Atoms::video == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
if (url) { if (url) {
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(), mSpeculativeLoadQueue.AppendElement()->InitImage(
NullString(), url, nullptr, nullptr, nullptr, nullptr);
NullString(),
NullString());
} }
} else if (nsHtml5Atoms::style == aName) { } else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed."); NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber()); treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
} else if (nsHtml5Atoms::html == aName) { } else if (nsHtml5Atoms::html == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST); nsHtml5String url =
if (url) { aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
mSpeculativeLoadQueue.AppendElement()->InitManifest(*url); mSpeculativeLoadQueue.AppendElement()->InitManifest(url);
} else {
mSpeculativeLoadQueue.AppendElement()->InitManifest(EmptyString());
}
} else if (nsHtml5Atoms::base == aName) { } else if (nsHtml5Atoms::base == aName) {
nsString* url = nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF); aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) { if (url) {
mSpeculativeLoadQueue.AppendElement()->InitBase(*url); mSpeculativeLoadQueue.AppendElement()->InitBase(url);
} }
} else if (nsHtml5Atoms::meta == aName) { } else if (nsHtml5Atoms::meta == aName) {
if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString( if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
"content-security-policy", "content-security-policy",
aAttributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) { aAttributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
nsString* csp = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT); nsHtml5String csp =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (csp) { if (csp) {
mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(*csp); mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(csp);
} }
} }
else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString( else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
"referrer", "referrer",
aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) { aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) {
nsString* referrerPolicy = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT); nsHtml5String referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (referrerPolicy) { if (referrerPolicy) {
mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(*referrerPolicy); mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(
referrerPolicy);
} }
} }
} }
break; break;
case kNameSpaceID_SVG: case kNameSpaceID_SVG:
if (nsHtml5Atoms::image == aName) { if (nsHtml5Atoms::image == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) { if (url) {
mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(), mSpeculativeLoadQueue.AppendElement()->InitImage(
NullString(), url, nullptr, nullptr, nullptr, nullptr);
NullString(),
NullString());
} }
} else if (nsHtml5Atoms::script == aName) { } else if (nsHtml5Atoms::script == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed."); NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber()); treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) { if (url) {
nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE); nsHtml5String type =
nsString* crossOrigin = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsString* integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitScript(
InitScript(*url, url,
EmptyString(), nullptr,
(type) ? *type : EmptyString(), type,
(crossOrigin) ? *crossOrigin : NullString(), crossOrigin,
(integrity) ? *integrity : NullString(), integrity,
mode == NS_HTML5TREE_BUILDER_IN_HEAD); mode == NS_HTML5TREE_BUILDER_IN_HEAD);
} }
} else if (nsHtml5Atoms::style == aName) { } else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed."); NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber()); treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) { if (url) {
nsString* crossOrigin = nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN); aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsString* integrity = nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY); aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
mSpeculativeLoadQueue.AppendElement()-> mSpeculativeLoadQueue.AppendElement()->InitStyle(
InitStyle(*url, EmptyString(), url, nullptr, crossOrigin, integrity);
(crossOrigin) ? *crossOrigin : NullString(),
(integrity) ? *integrity : NullString());
} }
} }
break; break;
@ -320,18 +317,23 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
} }
} else if (aNamespace == kNameSpaceID_XHTML) { } else if (aNamespace == kNameSpaceID_XHTML) {
if (nsHtml5Atoms::html == aName) { if (nsHtml5Atoms::html == aName) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed."); NS_ASSERTION(treeOp, "Tree op allocation failed.");
if (url) { if (url) {
treeOp->Init(eTreeOpProcessOfflineManifest, *url); nsString
urlString; // Not Auto, because using it to hold nsStringBuffer*
url.ToString(urlString);
treeOp->Init(eTreeOpProcessOfflineManifest, urlString);
} else { } else {
treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString()); treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
} }
} else if (nsHtml5Atoms::base == aName && mViewSource) { } else if (nsHtml5Atoms::base == aName && mViewSource) {
nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF); nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) { if (url) {
mViewSource->AddBase(*url); mViewSource->AddBase(url);
} }
} }
} }
@ -743,17 +745,19 @@ nsHtml5TreeBuilder::end()
} }
void void
nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId) nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName,
nsHtml5String aPublicId,
nsHtml5String aSystemId)
{ {
NS_PRECONDITION(aName, "Null name"); NS_PRECONDITION(aName, "Null name");
nsString publicId; // Not Auto, because using it to hold nsStringBuffer*
nsString systemId; // Not Auto, because using it to hold nsStringBuffer*
aPublicId.ToString(publicId);
aSystemId.ToString(systemId);
if (mBuilder) { if (mBuilder) {
nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName); nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
nsresult rv = nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
nsHtml5TreeOperation::AppendDoctypeToDocument(name, name, publicId, systemId, mBuilder);
*aPublicId,
*aSystemId,
mBuilder);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
MarkAsBrokenAndRequestSuspension(rv); MarkAsBrokenAndRequestSuspension(rv);
} }
@ -762,7 +766,7 @@ nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId,
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(); nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed."); NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(aName, *aPublicId, *aSystemId); treeOp->Init(aName, publicId, systemId);
// nsXMLContentSink can flush here, but what's the point? // nsXMLContentSink can flush here, but what's the point?
// It can also interrupt here, but we can't. // It can also interrupt here, but we can't.
} }

View File

@ -319,11 +319,10 @@ nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
if (!node->HasAttr(nsuri, localName)) { if (!node->HasAttr(nsuri, localName)) {
// prefix doesn't need regetting. it is always null or a static atom // prefix doesn't need regetting. it is always null or a static atom
// local name is never null // local name is never null
node->SetAttr(nsuri, nsString value; // Not Auto, because using it to hold nsStringBuffer*
localName, aAttributes->getValueNoBoundsCheck(i).ToString(value);
aAttributes->getPrefixNoBoundsCheck(i), node->SetAttr(
*(aAttributes->getValueNoBoundsCheck(i)), nsuri, localName, aAttributes->getPrefixNoBoundsCheck(i), value, true);
true);
// XXX what to do with nsresult? // XXX what to do with nsresult?
} }
} }
@ -418,12 +417,14 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i); nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i); int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
aAttributes->getValueNoBoundsCheck(i).ToString(value);
if (aNs == kNameSpaceID_XHTML && if (aNs == kNameSpaceID_XHTML &&
nsHtml5Atoms::a == aName && nsHtml5Atoms::a == aName &&
nsHtml5Atoms::name == localName) { nsHtml5Atoms::name == localName) {
// This is an HTML5-incompliant Geckoism. // This is an HTML5-incompliant Geckoism.
// Remove when fixing bug 582361 // Remove when fixing bug 582361
NS_ConvertUTF16toUTF8 cname(*(aAttributes->getValueNoBoundsCheck(i))); NS_ConvertUTF16toUTF8 cname(value);
NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting())); NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
newContent->SetAttr(nsuri, newContent->SetAttr(nsuri,
localName, localName,
@ -431,7 +432,6 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
uv, uv,
false); false);
} else { } else {
nsString& value = *(aAttributes->getValueNoBoundsCheck(i));
newContent->SetAttr(nsuri, newContent->SetAttr(nsuri,
localName, localName,
prefix, prefix,

View File

@ -29,7 +29,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -30,7 +30,7 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsHtml5AtomTable.h" #include "nsHtml5AtomTable.h"
#include "nsString.h" #include "nsHtml5String.h"
#include "nsNameSpaceManager.h" #include "nsNameSpaceManager.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsTraceRefcnt.h" #include "nsTraceRefcnt.h"

View File

@ -6,32 +6,35 @@
#include "nsHtml5ViewSourceUtils.h" #include "nsHtml5ViewSourceUtils.h"
#include "nsHtml5AttributeName.h" #include "nsHtml5AttributeName.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/UniquePtr.h" #include "nsHtml5String.h"
// static // static
nsHtml5HtmlAttributes* nsHtml5HtmlAttributes*
nsHtml5ViewSourceUtils::NewBodyAttributes() nsHtml5ViewSourceUtils::NewBodyAttributes()
{ {
nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0); nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
auto id = MakeUnique<nsString>(NS_LITERAL_STRING("viewsource")); nsHtml5String id = nsHtml5Portability::newStringFromLiteral("viewsource");
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id.release(), -1); bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id, -1);
auto klass = MakeUnique<nsString>(); nsString klass;
if (mozilla::Preferences::GetBool("view_source.wrap_long_lines", true)) { if (mozilla::Preferences::GetBool("view_source.wrap_long_lines", true)) {
klass->Append(NS_LITERAL_STRING("wrap ")); klass.Append(NS_LITERAL_STRING("wrap "));
} }
if (mozilla::Preferences::GetBool("view_source.syntax_highlight", true)) { if (mozilla::Preferences::GetBool("view_source.syntax_highlight", true)) {
klass->Append(NS_LITERAL_STRING("highlight")); klass.Append(NS_LITERAL_STRING("highlight"));
} }
if (!klass->IsEmpty()) { if (!klass.IsEmpty()) {
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass.release(), -1); bodyAttrs->addAttribute(
nsHtml5AttributeName::ATTR_CLASS, nsHtml5String::FromString(klass), -1);
} }
int32_t tabSize = mozilla::Preferences::GetInt("view_source.tab_size", 4); int32_t tabSize = mozilla::Preferences::GetInt("view_source.tab_size", 4);
if (tabSize > 0) { if (tabSize > 0) {
auto style = MakeUnique<nsString>(NS_LITERAL_STRING("-moz-tab-size: ")); nsString style;
style->AppendInt(tabSize); style.AssignASCII("-moz-tab-size: ");
bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_STYLE, style.release(), -1); style.AppendInt(tabSize);
bodyAttrs->addAttribute(
nsHtml5AttributeName::ATTR_STYLE, nsHtml5String::FromString(style), -1);
} }
return bodyAttrs; return bodyAttrs;
@ -42,12 +45,12 @@ nsHtml5HtmlAttributes*
nsHtml5ViewSourceUtils::NewLinkAttributes() nsHtml5ViewSourceUtils::NewLinkAttributes()
{ {
nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0); nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
nsString* rel = new nsString(NS_LITERAL_STRING("stylesheet")); nsHtml5String rel = nsHtml5Portability::newStringFromLiteral("stylesheet");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1); linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1);
nsString* type = new nsString(NS_LITERAL_STRING("text/css")); nsHtml5String type = nsHtml5Portability::newStringFromLiteral("text/css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1); linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
nsString* href = new nsString( nsHtml5String href = nsHtml5Portability::newStringFromLiteral(
NS_LITERAL_STRING("resource://gre-resources/viewsource.css")); "resource://gre-resources/viewsource.css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1); linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
return linkAttrs; return linkAttrs;
} }