summaryrefslogtreecommitdiffstats
path: root/parser
diff options
context:
space:
mode:
authorwin7-7 <win7-7@users.noreply.github.com>2019-07-05 21:58:21 +0300
committerwin7-7 <win7-7@users.noreply.github.com>2019-07-05 21:58:21 +0300
commit7c5a0db237c7a43136ee3cdc6cfb0663778d9e2c (patch)
tree9cd5a806763b73bed3fef3d599f32b525f4c0d7a /parser
parent0e54a032624b4ce23a959454047bfd504a734cc0 (diff)
downloadUXP-7c5a0db237c7a43136ee3cdc6cfb0663778d9e2c.tar
UXP-7c5a0db237c7a43136ee3cdc6cfb0663778d9e2c.tar.gz
UXP-7c5a0db237c7a43136ee3cdc6cfb0663778d9e2c.tar.lz
UXP-7c5a0db237c7a43136ee3cdc6cfb0663778d9e2c.tar.xz
UXP-7c5a0db237c7a43136ee3cdc6cfb0663778d9e2c.zip
Introduce a new non-heap-allocated type for holding nsStringBuffer* in the HTML parser.
An innerHTML setter profile shows about 10% of the time being spent under nsHtml5HtmlAttributes::clear, mostly deleting nsStrings.
Diffstat (limited to 'parser')
-rw-r--r--parser/html/moz.build2
-rw-r--r--parser/html/nsHtml5ArrayCopy.h7
-rw-r--r--parser/html/nsHtml5AttributeName.cpp2
-rw-r--r--parser/html/nsHtml5AttributeName.h2
-rw-r--r--parser/html/nsHtml5ElementName.cpp2
-rw-r--r--parser/html/nsHtml5ElementName.h2
-rw-r--r--parser/html/nsHtml5Highlighter.cpp16
-rw-r--r--parser/html/nsHtml5Highlighter.h6
-rw-r--r--parser/html/nsHtml5HtmlAttributes.cpp27
-rw-r--r--parser/html/nsHtml5HtmlAttributes.h12
-rw-r--r--parser/html/nsHtml5MetaScanner.cpp15
-rw-r--r--parser/html/nsHtml5MetaScanner.h8
-rw-r--r--parser/html/nsHtml5MetaScannerCppSupplement.h6
-rw-r--r--parser/html/nsHtml5PlainTextUtils.cpp15
-rw-r--r--parser/html/nsHtml5Portability.cpp99
-rw-r--r--parser/html/nsHtml5Portability.h29
-rw-r--r--parser/html/nsHtml5SpeculativeLoad.h106
-rw-r--r--parser/html/nsHtml5StackNode.cpp2
-rw-r--r--parser/html/nsHtml5StackNode.h2
-rw-r--r--parser/html/nsHtml5StateSnapshot.cpp2
-rw-r--r--parser/html/nsHtml5StateSnapshot.h2
-rw-r--r--parser/html/nsHtml5StreamParser.cpp7
-rw-r--r--parser/html/nsHtml5StreamParser.h2
-rw-r--r--parser/html/nsHtml5String.cpp226
-rw-r--r--parser/html/nsHtml5String.h95
-rw-r--r--parser/html/nsHtml5Tokenizer.cpp34
-rw-r--r--parser/html/nsHtml5Tokenizer.h16
-rw-r--r--parser/html/nsHtml5TreeBuilder.cpp49
-rw-r--r--parser/html/nsHtml5TreeBuilder.h27
-rw-r--r--parser/html/nsHtml5TreeBuilderCppSupplement.h206
-rw-r--r--parser/html/nsHtml5TreeOperation.cpp14
-rw-r--r--parser/html/nsHtml5UTF16Buffer.cpp2
-rw-r--r--parser/html/nsHtml5UTF16Buffer.h2
-rw-r--r--parser/html/nsHtml5ViewSourceUtils.cpp33
34 files changed, 719 insertions, 358 deletions
diff --git a/parser/html/moz.build b/parser/html/moz.build
index 4a2da8a79..cd6031abe 100644
--- a/parser/html/moz.build
+++ b/parser/html/moz.build
@@ -39,6 +39,7 @@ EXPORTS += [
'nsHtml5SpeculativeLoad.h',
'nsHtml5StreamListener.h',
'nsHtml5StreamParser.h',
+ 'nsHtml5String.h',
'nsHtml5StringParser.h',
'nsHtml5SVGLoadDispatcher.h',
'nsHtml5TreeOperation.h',
@@ -78,6 +79,7 @@ UNIFIED_SOURCES += [
'nsHtml5StateSnapshot.cpp',
'nsHtml5StreamListener.cpp',
'nsHtml5StreamParser.cpp',
+ 'nsHtml5String.cpp',
'nsHtml5StringParser.cpp',
'nsHtml5SVGLoadDispatcher.cpp',
'nsHtml5Tokenizer.cpp',
diff --git a/parser/html/nsHtml5ArrayCopy.h b/parser/html/nsHtml5ArrayCopy.h
index 78ed65568..594a801ab 100644
--- a/parser/html/nsHtml5ArrayCopy.h
+++ b/parser/html/nsHtml5ArrayCopy.h
@@ -51,10 +51,11 @@ class nsHtml5ArrayCopy {
memcpy(target, source, size_t(length) * sizeof(int32_t));
}
- static inline void
- arraycopy(nsString** source, nsString** target, int32_t length)
+ static inline void arraycopy(nsHtml5String* source,
+ nsHtml5String* target,
+ int32_t length)
{
- memcpy(target, source, size_t(length) * sizeof(nsString*));
+ memcpy(target, source, size_t(length) * sizeof(nsHtml5String));
}
static inline void
diff --git a/parser/html/nsHtml5AttributeName.cpp b/parser/html/nsHtml5AttributeName.cpp
index fc7745adc..dc546c111 100644
--- a/parser/html/nsHtml5AttributeName.cpp
+++ b/parser/html/nsHtml5AttributeName.cpp
@@ -29,7 +29,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5AttributeName.h b/parser/html/nsHtml5AttributeName.h
index 748dcf3c9..d0b93341b 100644
--- a/parser/html/nsHtml5AttributeName.h
+++ b/parser/html/nsHtml5AttributeName.h
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5ElementName.cpp b/parser/html/nsHtml5ElementName.cpp
index 1aa6f11ce..fb523e7ef 100644
--- a/parser/html/nsHtml5ElementName.cpp
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -29,7 +29,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5ElementName.h b/parser/html/nsHtml5ElementName.h
index b4df323a6..b5f0e4b9b 100644
--- a/parser/html/nsHtml5ElementName.h
+++ b/parser/html/nsHtml5ElementName.h
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5Highlighter.cpp b/parser/html/nsHtml5Highlighter.cpp
index 259803ee1..23cdf7d84 100644
--- a/parser/html/nsHtml5Highlighter.cpp
+++ b/parser/html/nsHtml5Highlighter.cpp
@@ -91,7 +91,7 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
if (length > INT32_MAX) {
length = INT32_MAX;
}
- AppendCharacters(aTitle.get(), 0, (int32_t)length);
+ AppendCharacters(aTitle.BeginReading(), 0, (int32_t)length);
Pop(); // title
Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
@@ -105,7 +105,7 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
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);
Push(nsGkAtoms::pre, preAttrs);
@@ -618,7 +618,7 @@ nsHtml5Highlighter::FlushOps()
void
nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
- nsString* aValue)
+ nsHtml5String aValue)
{
if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
nsHtml5AttributeName::ATTR_SRC == aName ||
@@ -630,7 +630,7 @@ nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
return;
}
- AddViewSourceHref(*aValue);
+ AddViewSourceHref(aValue);
}
void
@@ -717,10 +717,10 @@ nsHtml5Highlighter::AddClass(const char16_t* aClass)
}
void
-nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
+nsHtml5Highlighter::AddViewSourceHref(nsHtml5String aValue)
{
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;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
@@ -730,14 +730,14 @@ nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
}
void
-nsHtml5Highlighter::AddBase(const nsString& aValue)
+nsHtml5Highlighter::AddBase(nsHtml5String aValue)
{
if(mSeenBase) {
return;
}
mSeenBase = true;
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;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase,
diff --git a/parser/html/nsHtml5Highlighter.h b/parser/html/nsHtml5Highlighter.h
index e9474869e..366f11582 100644
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -78,7 +78,7 @@ class nsHtml5Highlighter
* @param aValue the value of the attribute
*/
void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
- nsString* aValue);
+ nsHtml5String aValue);
/**
* Inform the highlighter that the tokenizer successfully completed a
@@ -147,7 +147,7 @@ class nsHtml5Highlighter
*
* @param aValue the base URL to add
*/
- void AddBase(const nsString& aValue);
+ void AddBase(nsHtml5String aValue);
private:
@@ -272,7 +272,7 @@ class nsHtml5Highlighter
*
* @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.
diff --git a/parser/html/nsHtml5HtmlAttributes.cpp b/parser/html/nsHtml5HtmlAttributes.cpp
index d515f381d..62b9ae2b2 100644
--- a/parser/html/nsHtml5HtmlAttributes.cpp
+++ b/parser/html/nsHtml5HtmlAttributes.cpp
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -58,11 +58,11 @@
nsHtml5HtmlAttributes* nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES = nullptr;
nsHtml5HtmlAttributes::nsHtml5HtmlAttributes(int32_t mode)
- : mode(mode),
- length(0),
- names(jArray<nsHtml5AttributeName*,int32_t>::newJArray(8)),
- values(jArray<nsString*,int32_t>::newJArray(8)),
- lines(jArray<int32_t,int32_t>::newJArray(8))
+ : mode(mode)
+ , length(0)
+ , names(jArray<nsHtml5AttributeName*, int32_t>::newJArray(8))
+ , values(jArray<nsHtml5String, int32_t>::newJArray(8))
+ , lines(jArray<int32_t, int32_t>::newJArray(8))
{
MOZ_COUNT_CTOR(nsHtml5HtmlAttributes);
}
@@ -85,7 +85,7 @@ nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name)
return -1;
}
-nsString*
+nsHtml5String
nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name)
{
int32_t index = getIndex(name);
@@ -123,7 +123,7 @@ nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index)
return names[index]->getPrefix(mode);
}
-nsString*
+nsHtml5String
nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
@@ -145,14 +145,17 @@ nsHtml5HtmlAttributes::getLineNoBoundsCheck(int32_t index)
}
void
-nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsString* value, int32_t line)
+nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name,
+ nsHtml5String value,
+ int32_t line)
{
if (names.length == length) {
int32_t newLen = length << 1;
jArray<nsHtml5AttributeName*,int32_t> newNames = jArray<nsHtml5AttributeName*,int32_t>::newJArray(newLen);
nsHtml5ArrayCopy::arraycopy(names, newNames, names.length);
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);
values = newValues;
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++) {
names[i]->release();
names[i] = nullptr;
- nsHtml5Portability::releaseString(values[i]);
+ values[i].Release();
values[i] = nullptr;
}
length = 0;
@@ -181,7 +184,7 @@ nsHtml5HtmlAttributes::clear(int32_t m)
void
nsHtml5HtmlAttributes::releaseValue(int32_t i)
{
- nsHtml5Portability::releaseString(values[i]);
+ values[i].Release();
}
void
diff --git a/parser/html/nsHtml5HtmlAttributes.h b/parser/html/nsHtml5HtmlAttributes.h
index c02d0a08c..12149a0b5 100644
--- a/parser/html/nsHtml5HtmlAttributes.h
+++ b/parser/html/nsHtml5HtmlAttributes.h
@@ -31,7 +31,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -64,21 +64,23 @@ class nsHtml5HtmlAttributes
int32_t mode;
int32_t length;
autoJArray<nsHtml5AttributeName*,int32_t> names;
- autoJArray<nsString*,int32_t> values;
+ autoJArray<nsHtml5String, int32_t> values;
autoJArray<int32_t,int32_t> lines;
public:
explicit nsHtml5HtmlAttributes(int32_t mode);
~nsHtml5HtmlAttributes();
int32_t getIndex(nsHtml5AttributeName* name);
- nsString* getValue(nsHtml5AttributeName* name);
+ nsHtml5String getValue(nsHtml5AttributeName* name);
int32_t getLength();
nsIAtom* getLocalNameNoBoundsCheck(int32_t index);
int32_t getURINoBoundsCheck(int32_t index);
nsIAtom* getPrefixNoBoundsCheck(int32_t index);
- nsString* getValueNoBoundsCheck(int32_t index);
+ nsHtml5String getValueNoBoundsCheck(int32_t index);
nsHtml5AttributeName* getAttributeNameNoBoundsCheck(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 releaseValue(int32_t i);
void clearWithoutReleasingContents();
diff --git a/parser/html/nsHtml5MetaScanner.cpp b/parser/html/nsHtml5MetaScanner.cpp
index d39eacd9b..24f17b02b 100644
--- a/parser/html/nsHtml5MetaScanner.cpp
+++ b/parser/html/nsHtml5MetaScanner.cpp
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -86,8 +86,8 @@ nsHtml5MetaScanner::nsHtml5MetaScanner(nsHtml5TreeBuilder* tb)
nsHtml5MetaScanner::~nsHtml5MetaScanner()
{
MOZ_COUNT_DTOR(nsHtml5MetaScanner);
- nsHtml5Portability::releaseString(content);
- nsHtml5Portability::releaseString(charset);
+ content.Release();
+ charset.Release();
}
void
@@ -771,9 +771,9 @@ bool
nsHtml5MetaScanner::handleTag()
{
bool stop = handleTagInner();
- nsHtml5Portability::releaseString(content);
+ content.Release();
content = nullptr;
- nsHtml5Portability::releaseString(charset);
+ charset.Release();
charset = nullptr;
httpEquivState = NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN;
return stop;
@@ -786,12 +786,13 @@ nsHtml5MetaScanner::handleTagInner()
return true;
}
if (!!content && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE) {
- nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, treeBuilder);
+ nsHtml5String extract =
+ nsHtml5TreeBuilder::extractCharsetFromContent(content, treeBuilder);
if (!extract) {
return false;
}
bool success = tryCharset(extract);
- nsHtml5Portability::releaseString(extract);
+ extract.Release();
return success;
}
return false;
diff --git a/parser/html/nsHtml5MetaScanner.h b/parser/html/nsHtml5MetaScanner.h
index 4e0ad7647..a4d308147 100644
--- a/parser/html/nsHtml5MetaScanner.h
+++ b/parser/html/nsHtml5MetaScanner.h
@@ -31,7 +31,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -76,8 +76,8 @@ class nsHtml5MetaScanner
private:
int32_t strBufLen;
autoJArray<char16_t,int32_t> strBuf;
- nsString* content;
- nsString* charset;
+ nsHtml5String content;
+ nsHtml5String charset;
int32_t httpEquivState;
nsHtml5TreeBuilder* treeBuilder;
public:
@@ -100,7 +100,7 @@ class nsHtml5MetaScanner
bool handleTag();
bool handleTagInner();
protected:
- bool tryCharset(nsString* encoding);
+ bool tryCharset(nsHtml5String encoding);
public:
static void initializeStatics();
static void releaseStatics();
diff --git a/parser/html/nsHtml5MetaScannerCppSupplement.h b/parser/html/nsHtml5MetaScannerCppSupplement.h
index 5e7033777..9d2496361 100644
--- a/parser/html/nsHtml5MetaScannerCppSupplement.h
+++ b/parser/html/nsHtml5MetaScannerCppSupplement.h
@@ -19,13 +19,15 @@ nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsACString& charset)
}
bool
-nsHtml5MetaScanner::tryCharset(nsString* charset)
+nsHtml5MetaScanner::tryCharset(nsHtml5String charset)
{
// This code needs to stay in sync with
// nsHtml5StreamParser::internalEncodingDeclaration. Unfortunately, the
// trickery with member fields here leads to some copy-paste reuse. :-(
nsAutoCString label;
- CopyUTF16toUTF8(*charset, label);
+ nsString charset16; // Not Auto, because using it to hold nsStringBuffer*
+ charset.ToString(charset16);
+ CopyUTF16toUTF8(charset16, label);
nsAutoCString encoding;
if (!EncodingUtils::FindEncodingForLabel(label, encoding)) {
return false;
diff --git a/parser/html/nsHtml5PlainTextUtils.cpp b/parser/html/nsHtml5PlainTextUtils.cpp
index 4f0eab81b..0d2933150 100644
--- a/parser/html/nsHtml5PlainTextUtils.cpp
+++ b/parser/html/nsHtml5PlainTextUtils.cpp
@@ -5,21 +5,24 @@
#include "nsHtml5PlainTextUtils.h"
#include "nsHtml5AttributeName.h"
+#include "nsHtml5Portability.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "mozilla/Preferences.h"
+#include "nsHtml5String.h"
// static
nsHtml5HtmlAttributes*
nsHtml5PlainTextUtils::NewLinkAttributes()
{
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);
- nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
+ nsHtml5String type = nsHtml5Portability::newStringFromLiteral("text/css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
- nsString* href = new nsString(
- NS_LITERAL_STRING("resource://gre-resources/plaintext.css"));
+ nsHtml5String href = nsHtml5Portability::newStringFromLiteral(
+ "resource://gre-resources/plaintext.css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
nsresult rv;
@@ -34,7 +37,7 @@ nsHtml5PlainTextUtils::NewLinkAttributes()
bundle->GetStringFromName(u"plainText.wordWrap", getter_Copies(title));
}
- nsString* titleCopy = new nsString(title);
- linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TITLE, titleCopy, -1);
+ linkAttrs->addAttribute(
+ nsHtml5AttributeName::ATTR_TITLE, nsHtml5String::FromString(title), -1);
return linkAttrs;
}
diff --git a/parser/html/nsHtml5Portability.cpp b/parser/html/nsHtml5Portability.cpp
index 0a7c6f845..5a76b3c56 100644
--- a/parser/html/nsHtml5Portability.cpp
+++ b/parser/html/nsHtml5Portability.cpp
@@ -16,37 +16,31 @@ nsHtml5Portability::newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_
return interner->GetAtom(nsDependentSubstring(buf, buf + length));
}
-nsString*
-nsHtml5Portability::newStringFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5TreeBuilder* treeBuilder)
+nsHtml5String
+nsHtml5Portability::newStringFromBuffer(char16_t* buf,
+ int32_t offset,
+ int32_t length,
+ nsHtml5TreeBuilder* treeBuilder)
{
- nsString* str = new nsString();
- 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;
+ return nsHtml5String::FromBuffer(buf + offset, length, treeBuilder);
}
-nsString*
+nsHtml5String
nsHtml5Portability::newEmptyString()
{
- return new nsString();
+ return nsHtml5String::EmptyString();
}
-nsString*
+nsHtml5String
nsHtml5Portability::newStringFromLiteral(const char* literal)
{
- nsString* str = new nsString();
- str->AssignASCII(literal);
- return str;
+ return nsHtml5String::FromLiteral(literal);
}
-nsString*
-nsHtml5Portability::newStringFromString(nsString* string) {
- nsString* newStr = new nsString();
- newStr->Assign(*string);
- return newStr;
+nsHtml5String
+nsHtml5Portability::newStringFromString(nsHtml5String string)
+{
+ return string.Clone();
}
jArray<char16_t,int32_t>
@@ -60,12 +54,14 @@ nsHtml5Portability::newCharArrayFromLocal(nsIAtom* local)
return arr;
}
-jArray<char16_t,int32_t>
-nsHtml5Portability::newCharArrayFromString(nsString* string)
+jArray<char16_t, int32_t>
+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);
- memcpy(arr, string->BeginReading(), len * sizeof(char16_t));
+ string.CopyToBuffer(arr);
return arr;
}
@@ -82,12 +78,6 @@ nsHtml5Portability::newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner
return local;
}
-void
-nsHtml5Portability::releaseString(nsString* str)
-{
- delete str;
-}
-
bool
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
-nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string)
+nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+ const char* lowerCaseLiteral,
+ nsHtml5String string)
{
- if (!string) {
- 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;
+ return string.LowerCaseStartsWithASCII(lowerCaseLiteral);
}
bool
-nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string)
+nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
+ const char* lowerCaseLiteral,
+ nsHtml5String string)
{
- if (!string) {
- return false;
- }
- return string->LowerCaseEqualsASCII(lowerCaseLiteral);
+ return string.LowerCaseEqualsASCII(lowerCaseLiteral);
}
bool
-nsHtml5Portability::literalEqualsString(const char* literal, nsString* string)
+nsHtml5Portability::literalEqualsString(const char* literal,
+ nsHtml5String string)
{
- if (!string) {
- return false;
- }
- return string->EqualsASCII(literal);
+ return string.EqualsASCII(literal);
}
bool
-nsHtml5Portability::stringEqualsString(nsString* one, nsString* other)
+nsHtml5Portability::stringEqualsString(nsHtml5String one, nsHtml5String other)
{
- return one->Equals(*other);
+ return one.Equals(other);
}
void
diff --git a/parser/html/nsHtml5Portability.h b/parser/html/nsHtml5Portability.h
index bd85ccbdb..a3214dd2f 100644
--- a/parser/html/nsHtml5Portability.h
+++ b/parser/html/nsHtml5Portability.h
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -59,19 +59,26 @@ class nsHtml5Portability
{
public:
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 nsString* newEmptyString();
- static nsString* newStringFromLiteral(const char* literal);
- static nsString* newStringFromString(nsString* string);
+ static nsHtml5String newStringFromBuffer(char16_t* buf,
+ int32_t offset,
+ int32_t length,
+ 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> newCharArrayFromString(nsString* string);
+ static jArray<char16_t, int32_t> newCharArrayFromString(
+ nsHtml5String string);
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 lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
- static bool lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string);
- static bool literalEqualsString(const char* literal, nsString* string);
- static bool stringEqualsString(nsString* one, nsString* other);
+ static bool lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(
+ const char* lowerCaseLiteral,
+ nsHtml5String string);
+ 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 releaseStatics();
};
diff --git a/parser/html/nsHtml5SpeculativeLoad.h b/parser/html/nsHtml5SpeculativeLoad.h
index 575f6186d..6f1365bcf 100644
--- a/parser/html/nsHtml5SpeculativeLoad.h
+++ b/parser/html/nsHtml5SpeculativeLoad.h
@@ -35,45 +35,57 @@ class nsHtml5SpeculativeLoad {
nsHtml5SpeculativeLoad();
~nsHtml5SpeculativeLoad();
- inline void InitBase(const nsAString& aUrl)
+ inline void InitBase(nsHtml5String aUrl)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadBase;
- mUrl.Assign(aUrl);
+ aUrl.ToString(mUrl);
}
- inline void InitMetaCSP(const nsAString& aCSP) {
+ inline void InitMetaCSP(nsHtml5String aCSP)
+ {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadCSP;
+ nsString csp; // Not Auto, because using it to hold nsStringBuffer*
+ aCSP.ToString(csp);
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,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadMetaReferrer;
+ nsString
+ referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
+ aReferrerPolicy.ToString(referrerPolicy);
mReferrerPolicy.Assign(
- nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
+ nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
+ referrerPolicy));
}
- inline void InitImage(const nsAString& aUrl,
- const nsAString& aCrossOrigin,
- const nsAString& aReferrerPolicy,
- const nsAString& aSrcset,
- const nsAString& aSizes)
+ inline void InitImage(nsHtml5String aUrl,
+ nsHtml5String aCrossOrigin,
+ nsHtml5String aReferrerPolicy,
+ nsHtml5String aSrcset,
+ nsHtml5String aSizes)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadImage;
- mUrl.Assign(aUrl);
- mCrossOrigin.Assign(aCrossOrigin);
+ aUrl.ToString(mUrl);
+ aCrossOrigin.ToString(mCrossOrigin);
+ nsString
+ referrerPolicy; // Not Auto, because using it to hold nsStringBuffer*
+ aReferrerPolicy.ToString(referrerPolicy);
mReferrerPolicy.Assign(
- nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
- mSrcset.Assign(aSrcset);
- mSizes.Assign(aSizes);
+ nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
+ referrerPolicy));
+ aSrcset.ToString(mSrcset);
+ aSizes.ToString(mSizes);
}
// <picture> elements have multiple <source> nodes followed by an <img>,
@@ -97,49 +109,50 @@ class nsHtml5SpeculativeLoad {
mOpCode = eSpeculativeLoadEndPicture;
}
- inline void InitPictureSource(const nsAString& aSrcset,
- const nsAString& aSizes,
- const nsAString& aType,
- const nsAString& aMedia)
+ inline void InitPictureSource(nsHtml5String aSrcset,
+ nsHtml5String aSizes,
+ nsHtml5String aType,
+ nsHtml5String aMedia)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadPictureSource;
- mSrcset.Assign(aSrcset);
- mSizes.Assign(aSizes);
- mTypeOrCharsetSourceOrDocumentMode.Assign(aType);
- mMedia.Assign(aMedia);
+ aSrcset.ToString(mSrcset);
+ aSizes.ToString(mSizes);
+ aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
+ aMedia.ToString(mMedia);
}
- inline void InitScript(const nsAString& aUrl,
- const nsAString& aCharset,
- const nsAString& aType,
- const nsAString& aCrossOrigin,
- const nsAString& aIntegrity,
+ inline void InitScript(nsHtml5String aUrl,
+ nsHtml5String aCharset,
+ nsHtml5String aType,
+ nsHtml5String aCrossOrigin,
+ nsHtml5String aIntegrity,
bool aParserInHead)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = aParserInHead ?
eSpeculativeLoadScriptFromHead : eSpeculativeLoadScript;
- mUrl.Assign(aUrl);
- mCharset.Assign(aCharset);
- mTypeOrCharsetSourceOrDocumentMode.Assign(aType);
- mCrossOrigin.Assign(aCrossOrigin);
- mIntegrity.Assign(aIntegrity);
+ aUrl.ToString(mUrl);
+ aCharset.ToString(mCharset);
+ aType.ToString(mTypeOrCharsetSourceOrDocumentMode);
+ aCrossOrigin.ToString(mCrossOrigin);
+ aIntegrity.ToString(mIntegrity);
}
- inline void InitStyle(const nsAString& aUrl, const nsAString& aCharset,
- const nsAString& aCrossOrigin,
- const nsAString& aIntegrity)
+ inline void InitStyle(nsHtml5String aUrl,
+ nsHtml5String aCharset,
+ nsHtml5String aCrossOrigin,
+ nsHtml5String aIntegrity)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadStyle;
- mUrl.Assign(aUrl);
- mCharset.Assign(aCharset);
- mCrossOrigin.Assign(aCrossOrigin);
- mIntegrity.Assign(aIntegrity);
+ aUrl.ToString(mUrl);
+ aCharset.ToString(mCharset);
+ aCrossOrigin.ToString(mCrossOrigin);
+ aIntegrity.ToString(mIntegrity);
}
/**
@@ -153,12 +166,12 @@ class nsHtml5SpeculativeLoad {
* manifests seen by the parser thread have to maintain the queue order
* relative to true speculative loads. See bug 541079.
*/
- inline void InitManifest(const nsAString& aUrl)
+ inline void InitManifest(nsHtml5String aUrl)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadManifest;
- mUrl.Assign(aUrl);
+ aUrl.ToString(mUrl);
}
/**
@@ -195,14 +208,13 @@ class nsHtml5SpeculativeLoad {
mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aMode);
}
- inline void InitPreconnect(const nsAString& aUrl,
- const nsAString& aCrossOrigin)
+ inline void InitPreconnect(nsHtml5String aUrl, nsHtml5String aCrossOrigin)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadPreconnect;
- mUrl.Assign(aUrl);
- mCrossOrigin.Assign(aCrossOrigin);
+ aUrl.ToString(mUrl);
+ aCrossOrigin.ToString(mCrossOrigin);
}
void Perform(nsHtml5TreeOpExecutor* aExecutor);
diff --git a/parser/html/nsHtml5StackNode.cpp b/parser/html/nsHtml5StackNode.cpp
index ac5f0b2a3..41163ae40 100644
--- a/parser/html/nsHtml5StackNode.cpp
+++ b/parser/html/nsHtml5StackNode.cpp
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5StackNode.h b/parser/html/nsHtml5StackNode.h
index 57909ca9c..1677ec571 100644
--- a/parser/html/nsHtml5StackNode.h
+++ b/parser/html/nsHtml5StackNode.h
@@ -31,7 +31,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5StateSnapshot.cpp b/parser/html/nsHtml5StateSnapshot.cpp
index e8e3debf0..90780738b 100644
--- a/parser/html/nsHtml5StateSnapshot.cpp
+++ b/parser/html/nsHtml5StateSnapshot.cpp
@@ -29,7 +29,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5StateSnapshot.h b/parser/html/nsHtml5StateSnapshot.h
index 141b34340..119570499 100644
--- a/parser/html/nsHtml5StateSnapshot.h
+++ b/parser/html/nsHtml5StateSnapshot.h
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp
index 83bf4d8b6..ab4548125 100644
--- a/parser/html/nsHtml5StreamParser.cpp
+++ b/parser/html/nsHtml5StreamParser.cpp
@@ -1261,7 +1261,7 @@ nsHtml5StreamParser::PreferredForInternalEncodingDecl(nsACString& aEncoding)
}
bool
-nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
+nsHtml5StreamParser::internalEncodingDeclaration(nsHtml5String aEncoding)
{
// This code needs to stay in sync with
// nsHtml5MetaScanner::tryCharset. Unfortunately, the
@@ -1270,9 +1270,10 @@ nsHtml5StreamParser::internalEncodingDeclaration(nsString* aEncoding)
if (mCharsetSource >= kCharsetFromMetaTag) { // this threshold corresponds to "confident" in the HTML5 spec
return false;
}
-
+ nsString newEncoding16; // Not Auto, because using it to hold nsStringBuffer*
+ aEncoding.ToString(newEncoding16);
nsAutoCString newEncoding;
- CopyUTF16toUTF8(*aEncoding, newEncoding);
+ CopyUTF16toUTF8(newEncoding16, newEncoding);
if (!PreferredForInternalEncodingDecl(newEncoding)) {
return false;
diff --git a/parser/html/nsHtml5StreamParser.h b/parser/html/nsHtml5StreamParser.h
index 9a38ba067..2560f84ab 100644
--- a/parser/html/nsHtml5StreamParser.h
+++ b/parser/html/nsHtml5StreamParser.h
@@ -145,7 +145,7 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver {
/**
* Tree builder uses this to report a late <meta charset>
*/
- bool internalEncodingDeclaration(nsString* aEncoding);
+ bool internalEncodingDeclaration(nsHtml5String aEncoding);
// Not from an external interface
diff --git a/parser/html/nsHtml5String.cpp b/parser/html/nsHtml5String.cpp
new file mode 100644
index 000000000..d26eeaede
--- /dev/null
+++ b/parser/html/nsHtml5String.cpp
@@ -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);
+
+} \ No newline at end of file
diff --git a/parser/html/nsHtml5String.h b/parser/html/nsHtml5String.h
new file mode 100644
index 000000000..191bf6be8
--- /dev/null
+++ b/parser/html/nsHtml5String.h
@@ -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 \ No newline at end of file
diff --git a/parser/html/nsHtml5Tokenizer.cpp b/parser/html/nsHtml5Tokenizer.cpp
index 2838d74aa..a9db8d0c1 100644
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -32,7 +32,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
@@ -113,7 +113,8 @@ nsHtml5Tokenizer::setInterner(nsHtml5AtomTable* interner)
}
void
-nsHtml5Tokenizer::initLocation(nsString* newPublicId, nsString* newSystemId)
+nsHtml5Tokenizer::initLocation(nsHtml5String newPublicId,
+ nsHtml5String newSystemId)
{
this->systemId = newSystemId;
this->publicId = newPublicId;
@@ -222,10 +223,11 @@ nsHtml5Tokenizer::emitOrAppendCharRefBuf(int32_t returnState)
}
}
-nsString*
+nsHtml5String
nsHtml5Tokenizer::strBufToString()
{
- nsString* str = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, tokenHandler);
+ nsHtml5String str =
+ nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, tokenHandler);
clearStrBufAfterUse();
return str;
}
@@ -350,7 +352,7 @@ void
nsHtml5Tokenizer::addAttributeWithValue()
{
if (attributeName) {
- nsString* val = strBufToString();
+ nsHtml5String val = strBufToString();
if (mViewSource) {
mViewSource->MaybeLinkifyAttributeValue(attributeName, val);
}
@@ -3496,11 +3498,11 @@ nsHtml5Tokenizer::initDoctypeFields()
clearStrBufAfterUse();
doctypeName = nsHtml5Atoms::emptystring;
if (systemIdentifier) {
- nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier.Release();
systemIdentifier = nullptr;
}
if (publicIdentifier) {
- nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier.Release();
publicIdentifier = nullptr;
}
forceQuirks = false;
@@ -3662,11 +3664,11 @@ nsHtml5Tokenizer::eof()
errEofInDoctype();
doctypeName = nsHtml5Atoms::emptystring;
if (systemIdentifier) {
- nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier.Release();
systemIdentifier = nullptr;
}
if (publicIdentifier) {
- nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier.Release();
publicIdentifier = nullptr;
}
forceQuirks = true;
@@ -3896,14 +3898,14 @@ nsHtml5Tokenizer::emitDoctypeToken(int32_t pos)
cstart = pos + 1;
tokenHandler->doctype(doctypeName, publicIdentifier, systemIdentifier, forceQuirks);
doctypeName = nullptr;
- nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier.Release();
publicIdentifier = nullptr;
- nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier.Release();
systemIdentifier = nullptr;
}
bool
-nsHtml5Tokenizer::internalEncodingDeclaration(nsString* internalCharset)
+nsHtml5Tokenizer::internalEncodingDeclaration(nsHtml5String internalCharset)
{
if (encodingDeclarationHandler) {
return encodingDeclarationHandler->internalEncodingDeclaration(internalCharset);
@@ -3938,11 +3940,11 @@ nsHtml5Tokenizer::end()
strBuf = nullptr;
doctypeName = nullptr;
if (systemIdentifier) {
- nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier.Release();
systemIdentifier = nullptr;
}
if (publicIdentifier) {
- nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier.Release();
publicIdentifier = nullptr;
}
if (tagName) {
@@ -4041,13 +4043,13 @@ nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
} else {
doctypeName = nsHtml5Portability::newLocalFromLocal(other->doctypeName, interner);
}
- nsHtml5Portability::releaseString(systemIdentifier);
+ systemIdentifier.Release();
if (!other->systemIdentifier) {
systemIdentifier = nullptr;
} else {
systemIdentifier = nsHtml5Portability::newStringFromString(other->systemIdentifier);
}
- nsHtml5Portability::releaseString(publicIdentifier);
+ publicIdentifier.Release();
if (!other->publicIdentifier) {
publicIdentifier = nullptr;
} else {
diff --git a/parser/html/nsHtml5Tokenizer.h b/parser/html/nsHtml5Tokenizer.h
index da509b69b..00cca9a9c 100644
--- a/parser/html/nsHtml5Tokenizer.h
+++ b/parser/html/nsHtml5Tokenizer.h
@@ -33,7 +33,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
@@ -106,8 +106,8 @@ class nsHtml5Tokenizer
protected:
int32_t cstart;
private:
- nsString* publicId;
- nsString* systemId;
+ nsHtml5String publicId;
+ nsHtml5String systemId;
autoJArray<char16_t,int32_t> strBuf;
int32_t strBufLen;
autoJArray<char16_t,int32_t> charRefBuf;
@@ -126,8 +126,8 @@ class nsHtml5Tokenizer
nsHtml5AttributeName* attributeName;
private:
nsIAtom* doctypeName;
- nsString* publicIdentifier;
- nsString* systemIdentifier;
+ nsHtml5String publicIdentifier;
+ nsHtml5String systemIdentifier;
nsHtml5HtmlAttributes* attributes;
bool newAttributesEachTime;
bool shouldSuspend;
@@ -141,7 +141,7 @@ class nsHtml5Tokenizer
public:
nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
void setInterner(nsHtml5AtomTable* interner);
- void initLocation(nsString* newPublicId, nsString* newSystemId);
+ void initLocation(nsHtml5String newPublicId, nsHtml5String newSystemId);
bool isViewingXmlSource();
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation);
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation);
@@ -193,7 +193,7 @@ class nsHtml5Tokenizer
}
protected:
- nsString* strBufToString();
+ nsHtml5String strBufToString();
private:
void strBufToDoctypeName();
void emitStrBuf();
@@ -285,7 +285,7 @@ class nsHtml5Tokenizer
}
public:
- bool internalEncodingDeclaration(nsString* internalCharset);
+ bool internalEncodingDeclaration(nsHtml5String internalCharset);
private:
void emitOrAppendTwo(const char16_t* val, int32_t returnState);
void emitOrAppendOne(const char16_t* val, int32_t returnState);
diff --git a/parser/html/nsHtml5TreeBuilder.cpp b/parser/html/nsHtml5TreeBuilder.cpp
index f694116ba..457c7deb1 100644
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -34,7 +34,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsITimer.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -154,13 +154,16 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
}
void
-nsHtml5TreeBuilder::doctype(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks)
+nsHtml5TreeBuilder::doctype(nsIAtom* name,
+ nsHtml5String publicIdentifier,
+ nsHtml5String systemIdentifier,
+ bool forceQuirks)
{
needToDropLF = false;
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);
- nsHtml5Portability::releaseString(emptyString);
+ emptyString.Release();
if (isQuirky(name, publicIdentifier, systemIdentifier, forceQuirks)) {
errQuirkyDoctype();
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));
}
-nsString*
-nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb)
+nsHtml5String
+nsHtml5TreeBuilder::extractCharsetFromContent(nsHtml5String attributeValue,
+ nsHtml5TreeBuilder* tb)
{
int32_t charsetState = NS_HTML5TREE_BUILDER_CHARSET_INITIAL;
int32_t start = -1;
@@ -2175,12 +2179,13 @@ nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5T
}
}
charsetloop_end: ;
- nsString* charset = nullptr;
+ nsHtml5String charset = nullptr;
if (start != -1) {
if (end == -1) {
end = buffer.length;
}
- charset = nsHtml5Portability::newStringFromBuffer(buffer, start, end - start, tb);
+ charset =
+ nsHtml5Portability::newStringFromBuffer(buffer, start, end - start, tb);
}
return charset;
}
@@ -2188,7 +2193,8 @@ nsHtml5TreeBuilder::extractCharsetFromContent(nsString* attributeValue, nsHtml5T
void
nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes)
{
- nsString* charset = attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
+ nsHtml5String charset =
+ attributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
if (charset) {
if (tokenizer->internalEncodingDeclaration(charset)) {
requestSuspension();
@@ -2199,15 +2205,17 @@ nsHtml5TreeBuilder::checkMetaCharset(nsHtml5HtmlAttributes* attributes)
if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("content-type", attributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
return;
}
- nsString* content = attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
+ nsHtml5String content =
+ attributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (content) {
- nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, this);
+ nsHtml5String extract =
+ nsHtml5TreeBuilder::extractCharsetFromContent(content, this);
if (extract) {
if (tokenizer->internalEncodingDeclaration(extract)) {
requestSuspension();
}
}
- nsHtml5Portability::releaseString(extract);
+ extract.Release();
}
}
@@ -3208,7 +3216,11 @@ nsHtml5TreeBuilder::isSecondOnStackBody()
}
void
-nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks)
+nsHtml5TreeBuilder::documentModeInternal(
+ nsHtml5DocumentMode m,
+ nsHtml5String publicIdentifier,
+ nsHtml5String systemIdentifier,
+ bool html4SpecificAdditionalErrorChecks)
{
if (isSrcdocDocument) {
quirks = false;
@@ -3220,7 +3232,8 @@ nsHtml5TreeBuilder::documentModeInternal(nsHtml5DocumentMode m, nsString* public
}
bool
-nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier)
+nsHtml5TreeBuilder::isAlmostStandards(nsHtml5String publicIdentifier,
+ nsHtml5String systemIdentifier)
{
if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("-//w3c//dtd xhtml 1.0 transitional//en", publicIdentifier)) {
return true;
@@ -3240,7 +3253,10 @@ nsHtml5TreeBuilder::isAlmostStandards(nsString* publicIdentifier, nsString* syst
}
bool
-nsHtml5TreeBuilder::isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks)
+nsHtml5TreeBuilder::isQuirky(nsIAtom* name,
+ nsHtml5String publicIdentifier,
+ nsHtml5String systemIdentifier,
+ bool forceQuirks)
{
if (forceQuirks) {
return true;
@@ -4051,7 +4067,8 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5Elem
bool
nsHtml5TreeBuilder::annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes)
{
- nsString* encoding = attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING);
+ nsHtml5String encoding =
+ attributes->getValue(nsHtml5AttributeName::ATTR_ENCODING);
if (!encoding) {
return false;
}
diff --git a/parser/html/nsHtml5TreeBuilder.h b/parser/html/nsHtml5TreeBuilder.h
index a66b168be..67f5010c5 100644
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -35,7 +35,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsITimer.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
@@ -103,7 +103,10 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
bool isSrcdocDocument;
public:
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 characters(const char16_t* buf, int32_t start, int32_t length);
void zeroOriginatingReplacementCharacter();
@@ -119,7 +122,8 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
bool isTemplateModeStackEmpty();
bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
public:
- static nsString* extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb);
+ static nsHtml5String extractCharsetFromContent(nsHtml5String attributeValue,
+ nsHtml5TreeBuilder* tb);
private:
void checkMetaCharset(nsHtml5HtmlAttributes* attributes);
public:
@@ -136,9 +140,16 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void generateImpliedEndTagsExceptFor(nsIAtom* name);
void generateImpliedEndTags();
bool isSecondOnStackBody();
- void documentModeInternal(nsHtml5DocumentMode m, nsString* publicIdentifier, nsString* systemIdentifier, bool html4SpecificAdditionalErrorChecks);
- bool isAlmostStandards(nsString* publicIdentifier, nsString* systemIdentifier);
- bool isQuirky(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier, bool forceQuirks);
+ void documentModeInternal(nsHtml5DocumentMode m,
+ nsHtml5String publicIdentifier,
+ 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);
int32_t findLastInTableScopeTdTh();
void clearStackBackTo(int32_t eltPos);
@@ -224,7 +235,9 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void markMalformedIfScript(nsIContentHandle* elt);
void start(bool fragmentMode);
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 elementPopped(int32_t ns, nsIAtom* name, nsIContentHandle* node);
public:
diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h
index ff17c326e..aacc5a3e0 100644
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -123,181 +123,178 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
switch (aNamespace) {
case kNameSpaceID_XHTML:
if (nsHtml5Atoms::img == aName) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
- nsString* srcset =
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
+ nsHtml5String srcset =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
- nsString* crossOrigin =
+ nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
- nsString* referrerPolicy =
+ nsHtml5String referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
- nsString* sizes =
+ nsHtml5String sizes =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
- mSpeculativeLoadQueue.AppendElement()->
- InitImage(url ? *url : NullString(),
- crossOrigin ? *crossOrigin : NullString(),
- referrerPolicy ? *referrerPolicy : NullString(),
- srcset ? *srcset : NullString(),
- sizes ? *sizes : NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitImage(
+ url, crossOrigin, referrerPolicy, srcset, sizes);
} else if (nsHtml5Atoms::source == aName) {
- nsString* srcset =
+ nsHtml5String srcset =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRCSET);
// Sources without srcset cannot be selected. The source could also be
// for a media element, but in that context doesn't use srcset. See
// comments in nsHtml5SpeculativeLoad.h about <picture> preloading
if (srcset) {
- nsString* sizes =
+ nsHtml5String sizes =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
- nsString* type =
+ nsHtml5String type =
aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
- nsString* media =
+ nsHtml5String media =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA);
- mSpeculativeLoadQueue.AppendElement()->
- InitPictureSource(*srcset,
- sizes ? *sizes : NullString(),
- type ? *type : NullString(),
- media ? *media : NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitPictureSource(
+ srcset, sizes, type, media);
}
} else if (nsHtml5Atoms::script == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
if (url) {
- nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
- nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
- nsString* crossOrigin =
+ nsHtml5String charset =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
+ nsHtml5String type =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
+ nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
- nsString* integrity =
+ nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
- mSpeculativeLoadQueue.AppendElement()->
- InitScript(*url,
- (charset) ? *charset : EmptyString(),
- (type) ? *type : EmptyString(),
- (crossOrigin) ? *crossOrigin : NullString(),
- (integrity) ? *integrity : NullString(),
- mode == NS_HTML5TREE_BUILDER_IN_HEAD);
+ mSpeculativeLoadQueue.AppendElement()->InitScript(
+ url,
+ charset,
+ type,
+ crossOrigin,
+ integrity,
+ mode == NS_HTML5TREE_BUILDER_IN_HEAD);
mCurrentHtmlScriptIsAsyncOrDefer =
aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER);
}
} 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
// do a case-insensitive check.
if (rel) {
- if (rel->LowerCaseEqualsASCII("stylesheet")) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ if (rel.LowerCaseEqualsASCII("stylesheet")) {
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) {
- nsString* charset = aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
- nsString* crossOrigin =
+ nsHtml5String charset =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
+ nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
- nsString* integrity =
+ nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
- mSpeculativeLoadQueue.AppendElement()->
- InitStyle(*url,
- (charset) ? *charset : EmptyString(),
- (crossOrigin) ? *crossOrigin : NullString(),
- (integrity) ? *integrity : NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitStyle(
+ url, charset, crossOrigin, integrity);
}
- } else if (rel->LowerCaseEqualsASCII("preconnect")) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ } else if (rel.LowerCaseEqualsASCII("preconnect")) {
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) {
- nsString* crossOrigin =
+ nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
- mSpeculativeLoadQueue.AppendElement()->
- InitPreconnect(*url, (crossOrigin) ? *crossOrigin : NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitPreconnect(
+ url, crossOrigin);
}
}
}
} else if (nsHtml5Atoms::video == aName) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
if (url) {
- mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(),
- NullString(),
- NullString(),
- NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitImage(
+ url, nullptr, nullptr, nullptr, nullptr);
}
} else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
} else if (nsHtml5Atoms::html == aName) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
- if (url) {
- mSpeculativeLoadQueue.AppendElement()->InitManifest(*url);
- } else {
- mSpeculativeLoadQueue.AppendElement()->InitManifest(EmptyString());
- }
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
+ mSpeculativeLoadQueue.AppendElement()->InitManifest(url);
} else if (nsHtml5Atoms::base == aName) {
- nsString* url =
- aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) {
- mSpeculativeLoadQueue.AppendElement()->InitBase(*url);
+ mSpeculativeLoadQueue.AppendElement()->InitBase(url);
}
} else if (nsHtml5Atoms::meta == aName) {
if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
"content-security-policy",
aAttributes->getValue(nsHtml5AttributeName::ATTR_HTTP_EQUIV))) {
- nsString* csp = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
+ nsHtml5String csp =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (csp) {
- mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(*csp);
+ mSpeculativeLoadQueue.AppendElement()->InitMetaCSP(csp);
}
}
else if (nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(
"referrer",
aAttributes->getValue(nsHtml5AttributeName::ATTR_NAME))) {
- nsString* referrerPolicy = aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
+ nsHtml5String referrerPolicy =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_CONTENT);
if (referrerPolicy) {
- mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(*referrerPolicy);
+ mSpeculativeLoadQueue.AppendElement()->InitMetaReferrerPolicy(
+ referrerPolicy);
}
}
}
break;
case kNameSpaceID_SVG:
if (nsHtml5Atoms::image == aName) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
- mSpeculativeLoadQueue.AppendElement()->InitImage(*url, NullString(),
- NullString(),
- NullString(),
- NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitImage(
+ url, nullptr, nullptr, nullptr, nullptr);
}
} else if (nsHtml5Atoms::script == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
- nsString* type = aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
- nsString* crossOrigin =
+ nsHtml5String type =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
+ nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
- nsString* integrity =
+ nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
- mSpeculativeLoadQueue.AppendElement()->
- InitScript(*url,
- EmptyString(),
- (type) ? *type : EmptyString(),
- (crossOrigin) ? *crossOrigin : NullString(),
- (integrity) ? *integrity : NullString(),
- mode == NS_HTML5TREE_BUILDER_IN_HEAD);
+ mSpeculativeLoadQueue.AppendElement()->InitScript(
+ url,
+ nullptr,
+ type,
+ crossOrigin,
+ integrity,
+ mode == NS_HTML5TREE_BUILDER_IN_HEAD);
}
} else if (nsHtml5Atoms::style == aName) {
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
- nsString* crossOrigin =
+ nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
- nsString* integrity =
+ nsHtml5String integrity =
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
- mSpeculativeLoadQueue.AppendElement()->
- InitStyle(*url, EmptyString(),
- (crossOrigin) ? *crossOrigin : NullString(),
- (integrity) ? *integrity : NullString());
+ mSpeculativeLoadQueue.AppendElement()->InitStyle(
+ url, nullptr, crossOrigin, integrity);
}
}
break;
@@ -320,18 +317,23 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
}
} else if (aNamespace == kNameSpaceID_XHTML) {
if (nsHtml5Atoms::html == aName) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
if (url) {
- treeOp->Init(eTreeOpProcessOfflineManifest, *url);
+ nsString
+ urlString; // Not Auto, because using it to hold nsStringBuffer*
+ url.ToString(urlString);
+ treeOp->Init(eTreeOpProcessOfflineManifest, urlString);
} else {
treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
}
} else if (nsHtml5Atoms::base == aName && mViewSource) {
- nsString* url = aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
+ nsHtml5String url =
+ aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (url) {
- mViewSource->AddBase(*url);
+ mViewSource->AddBase(url);
}
}
}
@@ -743,17 +745,19 @@ nsHtml5TreeBuilder::end()
}
void
-nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId, nsString* aSystemId)
+nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName,
+ nsHtml5String aPublicId,
+ nsHtml5String aSystemId)
{
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) {
nsCOMPtr<nsIAtom> name = nsHtml5TreeOperation::Reget(aName);
- nsresult rv =
- nsHtml5TreeOperation::AppendDoctypeToDocument(name,
- *aPublicId,
- *aSystemId,
- mBuilder);
+ nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
+ name, publicId, systemId, mBuilder);
if (NS_FAILED(rv)) {
MarkAsBrokenAndRequestSuspension(rv);
}
@@ -762,7 +766,7 @@ nsHtml5TreeBuilder::appendDoctypeToDocument(nsIAtom* aName, nsString* aPublicId,
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
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?
// It can also interrupt here, but we can't.
}
diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp
index af246a253..3877e01b8 100644
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -319,11 +319,10 @@ nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
if (!node->HasAttr(nsuri, localName)) {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
- node->SetAttr(nsuri,
- localName,
- aAttributes->getPrefixNoBoundsCheck(i),
- *(aAttributes->getValueNoBoundsCheck(i)),
- true);
+ nsString value; // Not Auto, because using it to hold nsStringBuffer*
+ aAttributes->getValueNoBoundsCheck(i).ToString(value);
+ node->SetAttr(
+ nsuri, localName, aAttributes->getPrefixNoBoundsCheck(i), value, true);
// XXX what to do with nsresult?
}
}
@@ -418,12 +417,14 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(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 &&
nsHtml5Atoms::a == aName &&
nsHtml5Atoms::name == localName) {
// This is an HTML5-incompliant Geckoism.
// Remove when fixing bug 582361
- NS_ConvertUTF16toUTF8 cname(*(aAttributes->getValueNoBoundsCheck(i)));
+ NS_ConvertUTF16toUTF8 cname(value);
NS_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
newContent->SetAttr(nsuri,
localName,
@@ -431,7 +432,6 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
uv,
false);
} else {
- nsString& value = *(aAttributes->getValueNoBoundsCheck(i));
newContent->SetAttr(nsuri,
localName,
prefix,
diff --git a/parser/html/nsHtml5UTF16Buffer.cpp b/parser/html/nsHtml5UTF16Buffer.cpp
index f70365ce4..0d6870bc4 100644
--- a/parser/html/nsHtml5UTF16Buffer.cpp
+++ b/parser/html/nsHtml5UTF16Buffer.cpp
@@ -29,7 +29,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5UTF16Buffer.h b/parser/html/nsHtml5UTF16Buffer.h
index cf810e124..c94245f74 100644
--- a/parser/html/nsHtml5UTF16Buffer.h
+++ b/parser/html/nsHtml5UTF16Buffer.h
@@ -30,7 +30,7 @@
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
-#include "nsString.h"
+#include "nsHtml5String.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
diff --git a/parser/html/nsHtml5ViewSourceUtils.cpp b/parser/html/nsHtml5ViewSourceUtils.cpp
index 4dd33fc05..b2f635bff 100644
--- a/parser/html/nsHtml5ViewSourceUtils.cpp
+++ b/parser/html/nsHtml5ViewSourceUtils.cpp
@@ -6,32 +6,35 @@
#include "nsHtml5ViewSourceUtils.h"
#include "nsHtml5AttributeName.h"
#include "mozilla/Preferences.h"
-#include "mozilla/UniquePtr.h"
+#include "nsHtml5String.h"
// static
nsHtml5HtmlAttributes*
nsHtml5ViewSourceUtils::NewBodyAttributes()
{
nsHtml5HtmlAttributes* bodyAttrs = new nsHtml5HtmlAttributes(0);
- auto id = MakeUnique<nsString>(NS_LITERAL_STRING("viewsource"));
- bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id.release(), -1);
+ nsHtml5String id = nsHtml5Portability::newStringFromLiteral("viewsource");
+ bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, id, -1);
- auto klass = MakeUnique<nsString>();
+ nsString klass;
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)) {
- klass->Append(NS_LITERAL_STRING("highlight"));
+ klass.Append(NS_LITERAL_STRING("highlight"));
}
- if (!klass->IsEmpty()) {
- bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_CLASS, klass.release(), -1);
+ if (!klass.IsEmpty()) {
+ bodyAttrs->addAttribute(
+ nsHtml5AttributeName::ATTR_CLASS, nsHtml5String::FromString(klass), -1);
}
int32_t tabSize = mozilla::Preferences::GetInt("view_source.tab_size", 4);
if (tabSize > 0) {
- auto style = MakeUnique<nsString>(NS_LITERAL_STRING("-moz-tab-size: "));
- style->AppendInt(tabSize);
- bodyAttrs->addAttribute(nsHtml5AttributeName::ATTR_STYLE, style.release(), -1);
+ nsString style;
+ style.AssignASCII("-moz-tab-size: ");
+ style.AppendInt(tabSize);
+ bodyAttrs->addAttribute(
+ nsHtml5AttributeName::ATTR_STYLE, nsHtml5String::FromString(style), -1);
}
return bodyAttrs;
@@ -42,12 +45,12 @@ nsHtml5HtmlAttributes*
nsHtml5ViewSourceUtils::NewLinkAttributes()
{
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);
- nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
+ nsHtml5String type = nsHtml5Portability::newStringFromLiteral("text/css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
- nsString* href = new nsString(
- NS_LITERAL_STRING("resource://gre-resources/viewsource.css"));
+ nsHtml5String href = nsHtml5Portability::newStringFromLiteral(
+ "resource://gre-resources/viewsource.css");
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
return linkAttrs;
}