import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

120
parser/html/jArray.h Normal file
View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2008-2015 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef jArray_h
#define jArray_h
#include "mozilla/Attributes.h"
#include "mozilla/BinarySearch.h"
#include "nsDebug.h"
template<class T, class L>
struct staticJArray {
const T* arr;
const L length;
operator T*() { return arr; }
T& operator[] (L const index) {
MOZ_ASSERT(index >= 0, "Array access with negative index.");
MOZ_ASSERT(index < length, "Array index out of bounds.");
return ((T*)arr)[index];
}
L binarySearch(T const elem) {
size_t idx;
bool found = mozilla::BinarySearch(arr, 0, length, elem, &idx);
return found ? idx : -1;
}
};
template<class T, class L>
struct jArray {
T* arr;
L length;
static jArray<T,L> newJArray(L const len) {
MOZ_ASSERT(len >= 0, "Negative length.");
jArray<T,L> newArray = { new T[size_t(len)], len };
return newArray;
}
static jArray<T,L> newFallibleJArray(L const len) {
MOZ_ASSERT(len >= 0, "Negative length.");
T* a = new (mozilla::fallible) T[size_t(len)];
jArray<T,L> newArray = { a, a ? len : 0 };
return newArray;
}
operator T*() { return arr; }
T& operator[] (L const index) {
MOZ_ASSERT(index >= 0, "Array access with negative index.");
MOZ_ASSERT(index < length, "Array index out of bounds.");
return arr[index];
}
void operator=(staticJArray<T,L>& other) {
arr = (T*)other.arr;
length = other.length;
}
};
template<class T, class L>
class autoJArray {
private:
T* arr;
public:
L length;
autoJArray()
: arr(0)
, length(0)
{
}
MOZ_IMPLICIT autoJArray(const jArray<T,L>& other)
: arr(other.arr)
, length(other.length)
{
}
~autoJArray()
{
delete[] arr;
}
operator T*() { return arr; }
T& operator[] (L const index) {
MOZ_ASSERT(index >= 0, "Array access with negative index.");
MOZ_ASSERT(index < length, "Array index out of bounds.");
return arr[index];
}
operator jArray<T,L>() {
// WARNING! This makes it possible to goof with buffer ownership!
// This is needed for the getStack and getListOfActiveFormattingElements
// methods to work sensibly.
jArray<T,L> newArray = { arr, length };
return newArray;
}
void operator=(const jArray<T,L>& other) {
delete[] arr;
arr = other.arr;
length = other.length;
}
void operator=(decltype(nullptr)) {
// Make assigning null to an array in Java delete the buffer in C++
delete[] arr;
arr = nullptr;
length = 0;
}
};
#endif // jArray_h

59
parser/html/java/Makefile Normal file
View file

@ -0,0 +1,59 @@
# 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/.
libs:: translator
translator:: javaparser \
; mkdir -p htmlparser/bin && \
find htmlparser/translator-src/nu/validator/htmlparser -name "*.java" | \
xargs javac -cp javaparser.jar -g -d htmlparser/bin && \
jar cfm translator.jar manifest.txt -C htmlparser/bin .
javaparser:: \
; mkdir -p javaparser/bin && \
find javaparser/src -name "*.java" | \
xargs javac -encoding ISO-8859-1 -g -d javaparser/bin && \
jar cf javaparser.jar -C javaparser/bin .
sync_javaparser:: \
; if [ ! -d javaparser/.git ] ; \
then rm -rf javaparser ; \
git clone https://github.com/javaparser/javaparser.git ; \
fi ; \
cd javaparser ; git checkout javaparser-1.0.6 ; cd ..
sync_htmlparser:: \
; if [ -d htmlparser/.hg ] ; \
then cd htmlparser ; hg pull --rebase ; cd .. ; \
else \
rm -rf htmlparser ; \
hg clone https://hg.mozilla.org/projects/htmlparser ; \
fi
sync:: sync_javaparser sync_htmlparser
translate:: translator \
; mkdir -p ../javasrc ; \
java -jar translator.jar \
htmlparser/src/nu/validator/htmlparser/impl \
.. ../nsHtml5AtomList.h
translate_from_snapshot:: translator \
; mkdir -p ../javasrc ; \
java -jar translator.jar \
../javasrc \
.. ../nsHtml5AtomList.h
named_characters:: translator \
; java -cp translator.jar \
nu.validator.htmlparser.generator.GenerateNamedCharactersCpp \
named-character-references.html ../
clean_javaparser:: \
; rm -rf javaparser/bin javaparser.jar
clean_htmlparser:: \
; rm -rf htmlparser/bin translator.jar
clean:: clean_javaparser clean_htmlparser

View file

@ -0,0 +1,46 @@
If this is your first time building the HTML5 parser, you need to execute the
following commands (from this directory) to bootstrap the translation:
make sync # fetch remote source files and licenses
make translate # perform the Java-to-C++ translation from the remote
# sources
make named_characters # Generate tables for named character tokenization
If you make changes to the translator or the javaparser, you can rebuild by
retyping 'make' in this directory. If you make changes to the HTML5 Java
implementation, you can retranslate the Java sources from the htmlparser
repository by retyping 'make translate' in this directory.
The makefile supports the following targets:
sync_htmlparser:
Retrieves the HTML parser and Java to C++ translator sources from Mozilla's
htmlparser repository.
sync_javaparser:
Retrieves the javaparser sources from GitHub.
sync:
Runs both sync_javaparser and sync_htmlparser.
javaparser:
Builds the javaparser library retrieved earlier by sync_javaparser.
translator:
Runs the javaparser target and then builds the Java to C++ translator from
sources retrieved earlier by sync_htmlparser.
libs:
The default target. Alias for translator
translate:
Runs the translator target and then translates the HTML parser sources
retrieved by sync_htmlparser copying the Java sources to ../javasrc.
translate_from_snapshot:
Runs the translator target and then translates the HTML parser sources
stored in ../javasrc.
named_characters:
Generates data tables for named character tokenization.
clean_javaparser:
Removes the build products of the javaparser target.
clean_htmlparser:
Removes the build products of the translator target.
clean:
Runs both clean_javaparser and clean_htmlparser.
Ben Newman (23 September 2009)
Henri Sivonen (11 August 2016)

View file

@ -0,0 +1,2 @@
Main-Class: nu.validator.htmlparser.cpptranslate.Main
Class-Path: javaparser.jar

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,618 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import nu.validator.htmlparser.annotation.Auto;
import nu.validator.htmlparser.annotation.IdType;
import nu.validator.htmlparser.annotation.Local;
import nu.validator.htmlparser.annotation.NsUri;
import nu.validator.htmlparser.annotation.Prefix;
import nu.validator.htmlparser.annotation.QName;
import nu.validator.htmlparser.common.Interner;
import nu.validator.htmlparser.common.XmlViolationPolicy;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* Be careful with this class. QName is the name in from HTML tokenization.
* Otherwise, please refer to the interface doc.
*
* @version $Id: AttributesImpl.java 206 2008-03-20 14:09:29Z hsivonen $
* @author hsivonen
*/
public final class HtmlAttributes implements Attributes {
// [NOCPP[
private static final AttributeName[] EMPTY_ATTRIBUTENAMES = new AttributeName[0];
private static final String[] EMPTY_STRINGS = new String[0];
// ]NOCPP]
public static final HtmlAttributes EMPTY_ATTRIBUTES = new HtmlAttributes(
AttributeName.HTML);
private int mode;
private int length;
private @Auto AttributeName[] names;
private @Auto String[] values; // XXX perhaps make this @NoLength?
// CPPONLY: private @Auto int[] lines; // XXX perhaps make this @NoLength?
// [NOCPP[
private String idValue;
private int xmlnsLength;
private AttributeName[] xmlnsNames;
private String[] xmlnsValues;
// ]NOCPP]
public HtmlAttributes(int mode) {
this.mode = mode;
this.length = 0;
/*
* The length of 5 covers covers 98.3% of elements
* according to Hixie, but lets round to the next power of two for
* jemalloc.
*/
this.names = new AttributeName[8];
this.values = new String[8];
// CPPONLY: this.lines = new int[8];
// [NOCPP[
this.idValue = null;
this.xmlnsLength = 0;
this.xmlnsNames = HtmlAttributes.EMPTY_ATTRIBUTENAMES;
this.xmlnsValues = HtmlAttributes.EMPTY_STRINGS;
// ]NOCPP]
}
/*
public HtmlAttributes(HtmlAttributes other) {
this.mode = other.mode;
this.length = other.length;
this.names = new AttributeName[other.length];
this.values = new String[other.length];
// [NOCPP[
this.idValue = other.idValue;
this.xmlnsLength = other.xmlnsLength;
this.xmlnsNames = new AttributeName[other.xmlnsLength];
this.xmlnsValues = new String[other.xmlnsLength];
// ]NOCPP]
}
*/
void destructor() {
clear(0);
}
/**
* Only use with a static argument
*
* @param name
* @return
*/
public int getIndex(AttributeName name) {
for (int i = 0; i < length; i++) {
if (names[i] == name) {
return i;
}
}
return -1;
}
/**
* Only use with static argument.
*
* @see org.xml.sax.Attributes#getValue(java.lang.String)
*/
public String getValue(AttributeName name) {
int index = getIndex(name);
if (index == -1) {
return null;
} else {
return getValueNoBoundsCheck(index);
}
}
public int getLength() {
return length;
}
/**
* Variant of <code>getLocalName(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the local name at index
*/
public @Local String getLocalNameNoBoundsCheck(int index) {
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
return names[index].getLocal(mode);
}
/**
* Variant of <code>getURI(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the namespace URI at index
*/
public @NsUri String getURINoBoundsCheck(int index) {
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
return names[index].getUri(mode);
}
/**
* Variant of <code>getPrefix(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the namespace prefix at index
*/
public @Prefix String getPrefixNoBoundsCheck(int index) {
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
return names[index].getPrefix(mode);
}
/**
* Variant of <code>getValue(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the attribute value at index
*/
public String getValueNoBoundsCheck(int index) {
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
return values[index];
}
/**
* Variant of <code>getAttributeName(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the attribute name at index
*/
public AttributeName getAttributeNameNoBoundsCheck(int index) {
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
return names[index];
}
// CPPONLY: /**
// CPPONLY: * Obtains a line number without bounds check.
// CPPONLY: * @param index a valid attribute index
// CPPONLY: * @return the line number at index or -1 if unknown
// CPPONLY: */
// CPPONLY: public int getLineNoBoundsCheck(int index) {
// CPPONLY: assert index < length && index >= 0: "Index out of bounds";
// CPPONLY: return lines[index];
// CPPONLY: }
// [NOCPP[
/**
* Variant of <code>getQName(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the QName at index
*/
public @QName String getQNameNoBoundsCheck(int index) {
return names[index].getQName(mode);
}
/**
* Variant of <code>getType(int index)</code> without bounds check.
* @param index a valid attribute index
* @return the attribute type at index
*/
public @IdType String getTypeNoBoundsCheck(int index) {
return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
}
public int getIndex(String qName) {
for (int i = 0; i < length; i++) {
if (names[i].getQName(mode).equals(qName)) {
return i;
}
}
return -1;
}
public int getIndex(String uri, String localName) {
for (int i = 0; i < length; i++) {
if (names[i].getLocal(mode).equals(localName)
&& names[i].getUri(mode).equals(uri)) {
return i;
}
}
return -1;
}
public @IdType String getType(String qName) {
int index = getIndex(qName);
if (index == -1) {
return null;
} else {
return getType(index);
}
}
public @IdType String getType(String uri, String localName) {
int index = getIndex(uri, localName);
if (index == -1) {
return null;
} else {
return getType(index);
}
}
public String getValue(String qName) {
int index = getIndex(qName);
if (index == -1) {
return null;
} else {
return getValue(index);
}
}
public String getValue(String uri, String localName) {
int index = getIndex(uri, localName);
if (index == -1) {
return null;
} else {
return getValue(index);
}
}
public @Local String getLocalName(int index) {
if (index < length && index >= 0) {
return names[index].getLocal(mode);
} else {
return null;
}
}
public @QName String getQName(int index) {
if (index < length && index >= 0) {
return names[index].getQName(mode);
} else {
return null;
}
}
public @IdType String getType(int index) {
if (index < length && index >= 0) {
return (names[index] == AttributeName.ID) ? "ID" : "CDATA";
} else {
return null;
}
}
public AttributeName getAttributeName(int index) {
if (index < length && index >= 0) {
return names[index];
} else {
return null;
}
}
public @NsUri String getURI(int index) {
if (index < length && index >= 0) {
return names[index].getUri(mode);
} else {
return null;
}
}
public @Prefix String getPrefix(int index) {
if (index < length && index >= 0) {
return names[index].getPrefix(mode);
} else {
return null;
}
}
public String getValue(int index) {
if (index < length && index >= 0) {
return values[index];
} else {
return null;
}
}
public String getId() {
return idValue;
}
public int getXmlnsLength() {
return xmlnsLength;
}
public @Local String getXmlnsLocalName(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsNames[index].getLocal(mode);
} else {
return null;
}
}
public @NsUri String getXmlnsURI(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsNames[index].getUri(mode);
} else {
return null;
}
}
public String getXmlnsValue(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsValues[index];
} else {
return null;
}
}
public int getXmlnsIndex(AttributeName name) {
for (int i = 0; i < xmlnsLength; i++) {
if (xmlnsNames[i] == name) {
return i;
}
}
return -1;
}
public String getXmlnsValue(AttributeName name) {
int index = getXmlnsIndex(name);
if (index == -1) {
return null;
} else {
return getXmlnsValue(index);
}
}
public AttributeName getXmlnsAttributeName(int index) {
if (index < xmlnsLength && index >= 0) {
return xmlnsNames[index];
} else {
return null;
}
}
// ]NOCPP]
void addAttribute(AttributeName name, String value
// [NOCPP[
, XmlViolationPolicy xmlnsPolicy
// ]NOCPP]
// CPPONLY: , int line
) throws SAXException {
// [NOCPP[
if (name == AttributeName.ID) {
idValue = value;
}
if (name.isXmlns()) {
if (xmlnsNames.length == xmlnsLength) {
int newLen = xmlnsLength == 0 ? 2 : xmlnsLength << 1;
AttributeName[] newNames = new AttributeName[newLen];
System.arraycopy(xmlnsNames, 0, newNames, 0, xmlnsNames.length);
xmlnsNames = newNames;
String[] newValues = new String[newLen];
System.arraycopy(xmlnsValues, 0, newValues, 0, xmlnsValues.length);
xmlnsValues = newValues;
}
xmlnsNames[xmlnsLength] = name;
xmlnsValues[xmlnsLength] = value;
xmlnsLength++;
switch (xmlnsPolicy) {
case FATAL:
// this is ugly
throw new SAXException("Saw an xmlns attribute.");
case ALTER_INFOSET:
return;
case ALLOW:
// fall through
}
}
// ]NOCPP]
if (names.length == length) {
int newLen = length << 1; // The first growth covers virtually
// 100% of elements according to
// Hixie
AttributeName[] newNames = new AttributeName[newLen];
System.arraycopy(names, 0, newNames, 0, names.length);
names = newNames;
String[] newValues = new String[newLen];
System.arraycopy(values, 0, newValues, 0, values.length);
values = newValues;
// CPPONLY: int[] newLines = new int[newLen];
// CPPONLY: System.arraycopy(lines, 0, newLines, 0, lines.length);
// CPPONLY: lines = newLines;
}
names[length] = name;
values[length] = value;
// CPPONLY: lines[length] = line;
length++;
}
void clear(int m) {
for (int i = 0; i < length; i++) {
names[i].release();
names[i] = null;
Portability.releaseString(values[i]);
values[i] = null;
}
length = 0;
mode = m;
// [NOCPP[
idValue = null;
for (int i = 0; i < xmlnsLength; i++) {
xmlnsNames[i] = null;
xmlnsValues[i] = null;
}
xmlnsLength = 0;
// ]NOCPP]
}
/**
* This is used in C++ to release special <code>isindex</code>
* attribute values whose ownership is not transferred.
*/
void releaseValue(int i) {
Portability.releaseString(values[i]);
}
/**
* This is only used for <code>AttributeName</code> ownership transfer
* in the isindex case to avoid freeing custom names twice in C++.
*/
void clearWithoutReleasingContents() {
for (int i = 0; i < length; i++) {
names[i] = null;
values[i] = null;
}
length = 0;
}
boolean contains(AttributeName name) {
for (int i = 0; i < length; i++) {
if (name.equalsAnother(names[i])) {
return true;
}
}
// [NOCPP[
for (int i = 0; i < xmlnsLength; i++) {
if (name.equalsAnother(xmlnsNames[i])) {
return true;
}
}
// ]NOCPP]
return false;
}
public void adjustForMath() {
mode = AttributeName.MATHML;
}
public void adjustForSvg() {
mode = AttributeName.SVG;
}
public HtmlAttributes cloneAttributes(Interner interner)
throws SAXException {
assert (length == 0
// [NOCPP[
&& xmlnsLength == 0
// ]NOCPP]
)
|| mode == 0 || mode == 3;
HtmlAttributes clone = new HtmlAttributes(0);
for (int i = 0; i < length; i++) {
clone.addAttribute(names[i].cloneAttributeName(interner),
Portability.newStringFromString(values[i])
// [NOCPP[
, XmlViolationPolicy.ALLOW
// ]NOCPP]
// CPPONLY: , lines[i]
);
}
// [NOCPP[
for (int i = 0; i < xmlnsLength; i++) {
clone.addAttribute(xmlnsNames[i], xmlnsValues[i],
XmlViolationPolicy.ALLOW);
}
// ]NOCPP]
return clone; // XXX!!!
}
public boolean equalsAnother(HtmlAttributes other) {
assert mode == 0 || mode == 3 : "Trying to compare attributes in foreign content.";
int otherLength = other.getLength();
if (length != otherLength) {
return false;
}
for (int i = 0; i < length; i++) {
// Work around the limitations of C++
boolean found = false;
// The comparing just the local names is OK, since these attribute
// holders are both supposed to belong to HTML formatting elements
@Local String ownLocal = names[i].getLocal(AttributeName.HTML);
for (int j = 0; j < otherLength; j++) {
if (ownLocal == other.names[j].getLocal(AttributeName.HTML)) {
found = true;
if (!Portability.stringEqualsString(values[i], other.values[j])) {
return false;
}
}
}
if (!found) {
return false;
}
}
return true;
}
// [NOCPP[
void processNonNcNames(TreeBuilder<?> treeBuilder, XmlViolationPolicy namePolicy) throws SAXException {
for (int i = 0; i < length; i++) {
AttributeName attName = names[i];
if (!attName.isNcName(mode)) {
String name = attName.getLocal(mode);
switch (namePolicy) {
case ALTER_INFOSET:
names[i] = AttributeName.create(NCName.escapeName(name));
// fall through
case ALLOW:
if (attName != AttributeName.XML_LANG) {
treeBuilder.warn("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
}
break;
case FATAL:
treeBuilder.fatal("Attribute \u201C" + name + "\u201D is not serializable as XML 1.0.");
break;
}
}
}
}
public void merge(HtmlAttributes attributes) throws SAXException {
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
AttributeName name = attributes.getAttributeNameNoBoundsCheck(i);
if (!contains(name)) {
addAttribute(name, attributes.getValueNoBoundsCheck(i), XmlViolationPolicy.ALLOW);
}
}
}
// ]NOCPP]
}

View file

@ -0,0 +1,854 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2015 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import java.io.IOException;
import nu.validator.htmlparser.annotation.Auto;
import nu.validator.htmlparser.annotation.Inline;
import nu.validator.htmlparser.common.ByteReadable;
import org.xml.sax.SAXException;
public abstract class MetaScanner {
/**
* Constant for "charset".
*/
private static final char[] CHARSET = { 'h', 'a', 'r', 's', 'e', 't' };
/**
* Constant for "content".
*/
private static final char[] CONTENT = { 'o', 'n', 't', 'e', 'n', 't' };
/**
* Constant for "http-equiv".
*/
private static final char[] HTTP_EQUIV = { 't', 't', 'p', '-', 'e', 'q',
'u', 'i', 'v' };
/**
* Constant for "content-type".
*/
private static final char[] CONTENT_TYPE = { 'c', 'o', 'n', 't', 'e', 'n',
't', '-', 't', 'y', 'p', 'e' };
private static final int NO = 0;
private static final int M = 1;
private static final int E = 2;
private static final int T = 3;
private static final int A = 4;
private static final int DATA = 0;
private static final int TAG_OPEN = 1;
private static final int SCAN_UNTIL_GT = 2;
private static final int TAG_NAME = 3;
private static final int BEFORE_ATTRIBUTE_NAME = 4;
private static final int ATTRIBUTE_NAME = 5;
private static final int AFTER_ATTRIBUTE_NAME = 6;
private static final int BEFORE_ATTRIBUTE_VALUE = 7;
private static final int ATTRIBUTE_VALUE_DOUBLE_QUOTED = 8;
private static final int ATTRIBUTE_VALUE_SINGLE_QUOTED = 9;
private static final int ATTRIBUTE_VALUE_UNQUOTED = 10;
private static final int AFTER_ATTRIBUTE_VALUE_QUOTED = 11;
private static final int MARKUP_DECLARATION_OPEN = 13;
private static final int MARKUP_DECLARATION_HYPHEN = 14;
private static final int COMMENT_START = 15;
private static final int COMMENT_START_DASH = 16;
private static final int COMMENT = 17;
private static final int COMMENT_END_DASH = 18;
private static final int COMMENT_END = 19;
private static final int SELF_CLOSING_START_TAG = 20;
private static final int HTTP_EQUIV_NOT_SEEN = 0;
private static final int HTTP_EQUIV_CONTENT_TYPE = 1;
private static final int HTTP_EQUIV_OTHER = 2;
/**
* The data source.
*/
protected ByteReadable readable;
/**
* The state of the state machine that recognizes the tag name "meta".
*/
private int metaState = NO;
/**
* The current position in recognizing the attribute name "content".
*/
private int contentIndex = Integer.MAX_VALUE;
/**
* The current position in recognizing the attribute name "charset".
*/
private int charsetIndex = Integer.MAX_VALUE;
/**
* The current position in recognizing the attribute name "http-equive".
*/
private int httpEquivIndex = Integer.MAX_VALUE;
/**
* The current position in recognizing the attribute value "content-type".
*/
private int contentTypeIndex = Integer.MAX_VALUE;
/**
* The tokenizer state.
*/
protected int stateSave = DATA;
/**
* The currently filled length of strBuf.
*/
private int strBufLen;
/**
* Accumulation buffer for attribute values.
*/
private @Auto char[] strBuf;
private String content;
private String charset;
private int httpEquivState;
// CPPONLY: private TreeBuilder treeBuilder;
public MetaScanner(
// CPPONLY: TreeBuilder tb
) {
this.readable = null;
this.metaState = NO;
this.contentIndex = Integer.MAX_VALUE;
this.charsetIndex = Integer.MAX_VALUE;
this.httpEquivIndex = Integer.MAX_VALUE;
this.contentTypeIndex = Integer.MAX_VALUE;
this.stateSave = DATA;
this.strBufLen = 0;
this.strBuf = new char[36];
this.content = null;
this.charset = null;
this.httpEquivState = HTTP_EQUIV_NOT_SEEN;
// CPPONLY: this.treeBuilder = tb;
}
@SuppressWarnings("unused") private void destructor() {
Portability.releaseString(content);
Portability.releaseString(charset);
}
// [NOCPP[
/**
* Reads a byte from the data source.
*
* -1 means end.
* @return
* @throws IOException
*/
protected int read() throws IOException {
return readable.readByte();
}
// ]NOCPP]
// WARNING When editing this, makes sure the bytecode length shown by javap
// stays under 8000 bytes!
/**
* The runs the meta scanning algorithm.
*/
protected final void stateLoop(int state)
throws SAXException, IOException {
int c = -1;
boolean reconsume = false;
stateloop: for (;;) {
switch (state) {
case DATA:
dataloop: for (;;) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch (c) {
case -1:
break stateloop;
case '<':
state = MetaScanner.TAG_OPEN;
break dataloop; // FALL THROUGH continue
// stateloop;
default:
continue;
}
}
// WARNING FALLTHRU CASE TRANSITION: DON'T REORDER
case TAG_OPEN:
tagopenloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case 'm':
case 'M':
metaState = M;
state = MetaScanner.TAG_NAME;
break tagopenloop;
// continue stateloop;
case '!':
state = MetaScanner.MARKUP_DECLARATION_OPEN;
continue stateloop;
case '?':
case '/':
state = MetaScanner.SCAN_UNTIL_GT;
continue stateloop;
case '>':
state = MetaScanner.DATA;
continue stateloop;
default:
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
metaState = NO;
state = MetaScanner.TAG_NAME;
break tagopenloop;
// continue stateloop;
}
state = MetaScanner.DATA;
reconsume = true;
continue stateloop;
}
}
// FALL THROUGH DON'T REORDER
case TAG_NAME:
tagnameloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
break tagnameloop;
// continue stateloop;
case '/':
state = MetaScanner.SELF_CLOSING_START_TAG;
continue stateloop;
case '>':
state = MetaScanner.DATA;
continue stateloop;
case 'e':
case 'E':
if (metaState == M) {
metaState = E;
} else {
metaState = NO;
}
continue;
case 't':
case 'T':
if (metaState == E) {
metaState = T;
} else {
metaState = NO;
}
continue;
case 'a':
case 'A':
if (metaState == T) {
metaState = A;
} else {
metaState = NO;
}
continue;
default:
metaState = NO;
continue;
}
}
// FALLTHRU DON'T REORDER
case BEFORE_ATTRIBUTE_NAME:
beforeattributenameloop: for (;;) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
/*
* Consume the next input character:
*/
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
continue;
case '/':
state = MetaScanner.SELF_CLOSING_START_TAG;
continue stateloop;
case '>':
if (handleTag()) {
break stateloop;
}
state = DATA;
continue stateloop;
case 'c':
case 'C':
contentIndex = 0;
charsetIndex = 0;
httpEquivIndex = Integer.MAX_VALUE;
contentTypeIndex = Integer.MAX_VALUE;
state = MetaScanner.ATTRIBUTE_NAME;
break beforeattributenameloop;
case 'h':
case 'H':
contentIndex = Integer.MAX_VALUE;
charsetIndex = Integer.MAX_VALUE;
httpEquivIndex = 0;
contentTypeIndex = Integer.MAX_VALUE;
state = MetaScanner.ATTRIBUTE_NAME;
break beforeattributenameloop;
default:
contentIndex = Integer.MAX_VALUE;
charsetIndex = Integer.MAX_VALUE;
httpEquivIndex = Integer.MAX_VALUE;
contentTypeIndex = Integer.MAX_VALUE;
state = MetaScanner.ATTRIBUTE_NAME;
break beforeattributenameloop;
// continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case ATTRIBUTE_NAME:
attributenameloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
state = MetaScanner.AFTER_ATTRIBUTE_NAME;
continue stateloop;
case '/':
state = MetaScanner.SELF_CLOSING_START_TAG;
continue stateloop;
case '=':
strBufLen = 0;
contentTypeIndex = 0;
state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
break attributenameloop;
// continue stateloop;
case '>':
if (handleTag()) {
break stateloop;
}
state = MetaScanner.DATA;
continue stateloop;
default:
if (metaState == A) {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
if (contentIndex < CONTENT.length && c == CONTENT[contentIndex]) {
++contentIndex;
} else {
contentIndex = Integer.MAX_VALUE;
}
if (charsetIndex < CHARSET.length && c == CHARSET[charsetIndex]) {
++charsetIndex;
} else {
charsetIndex = Integer.MAX_VALUE;
}
if (httpEquivIndex < HTTP_EQUIV.length && c == HTTP_EQUIV[httpEquivIndex]) {
++httpEquivIndex;
} else {
httpEquivIndex = Integer.MAX_VALUE;
}
}
continue;
}
}
// FALLTHRU DON'T REORDER
case BEFORE_ATTRIBUTE_VALUE:
beforeattributevalueloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
continue;
case '"':
state = MetaScanner.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
break beforeattributevalueloop;
// continue stateloop;
case '\'':
state = MetaScanner.ATTRIBUTE_VALUE_SINGLE_QUOTED;
continue stateloop;
case '>':
if (handleTag()) {
break stateloop;
}
state = MetaScanner.DATA;
continue stateloop;
default:
handleCharInAttributeValue(c);
state = MetaScanner.ATTRIBUTE_VALUE_UNQUOTED;
continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case ATTRIBUTE_VALUE_DOUBLE_QUOTED:
attributevaluedoublequotedloop: for (;;) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch (c) {
case -1:
break stateloop;
case '"':
handleAttributeValue();
state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
break attributevaluedoublequotedloop;
// continue stateloop;
default:
handleCharInAttributeValue(c);
continue;
}
}
// FALLTHRU DON'T REORDER
case AFTER_ATTRIBUTE_VALUE_QUOTED:
afterattributevaluequotedloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
continue stateloop;
case '/':
state = MetaScanner.SELF_CLOSING_START_TAG;
break afterattributevaluequotedloop;
// continue stateloop;
case '>':
if (handleTag()) {
break stateloop;
}
state = MetaScanner.DATA;
continue stateloop;
default:
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
reconsume = true;
continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case SELF_CLOSING_START_TAG:
c = read();
switch (c) {
case -1:
break stateloop;
case '>':
if (handleTag()) {
break stateloop;
}
state = MetaScanner.DATA;
continue stateloop;
default:
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
reconsume = true;
continue stateloop;
}
// XXX reorder point
case ATTRIBUTE_VALUE_UNQUOTED:
for (;;) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
handleAttributeValue();
state = MetaScanner.BEFORE_ATTRIBUTE_NAME;
continue stateloop;
case '>':
handleAttributeValue();
if (handleTag()) {
break stateloop;
}
state = MetaScanner.DATA;
continue stateloop;
default:
handleCharInAttributeValue(c);
continue;
}
}
// XXX reorder point
case AFTER_ATTRIBUTE_NAME:
for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case ' ':
case '\t':
case '\n':
case '\u000C':
continue;
case '/':
handleAttributeValue();
state = MetaScanner.SELF_CLOSING_START_TAG;
continue stateloop;
case '=':
strBufLen = 0;
contentTypeIndex = 0;
state = MetaScanner.BEFORE_ATTRIBUTE_VALUE;
continue stateloop;
case '>':
handleAttributeValue();
if (handleTag()) {
break stateloop;
}
state = MetaScanner.DATA;
continue stateloop;
case 'c':
case 'C':
contentIndex = 0;
charsetIndex = 0;
state = MetaScanner.ATTRIBUTE_NAME;
continue stateloop;
default:
contentIndex = Integer.MAX_VALUE;
charsetIndex = Integer.MAX_VALUE;
state = MetaScanner.ATTRIBUTE_NAME;
continue stateloop;
}
}
// XXX reorder point
case MARKUP_DECLARATION_OPEN:
markupdeclarationopenloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case '-':
state = MetaScanner.MARKUP_DECLARATION_HYPHEN;
break markupdeclarationopenloop;
// continue stateloop;
default:
state = MetaScanner.SCAN_UNTIL_GT;
reconsume = true;
continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case MARKUP_DECLARATION_HYPHEN:
markupdeclarationhyphenloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case '-':
state = MetaScanner.COMMENT_START;
break markupdeclarationhyphenloop;
// continue stateloop;
default:
state = MetaScanner.SCAN_UNTIL_GT;
reconsume = true;
continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case COMMENT_START:
commentstartloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case '-':
state = MetaScanner.COMMENT_START_DASH;
continue stateloop;
case '>':
state = MetaScanner.DATA;
continue stateloop;
default:
state = MetaScanner.COMMENT;
break commentstartloop;
// continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case COMMENT:
commentloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case '-':
state = MetaScanner.COMMENT_END_DASH;
break commentloop;
// continue stateloop;
default:
continue;
}
}
// FALLTHRU DON'T REORDER
case COMMENT_END_DASH:
commentenddashloop: for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case '-':
state = MetaScanner.COMMENT_END;
break commentenddashloop;
// continue stateloop;
default:
state = MetaScanner.COMMENT;
continue stateloop;
}
}
// FALLTHRU DON'T REORDER
case COMMENT_END:
for (;;) {
c = read();
switch (c) {
case -1:
break stateloop;
case '>':
state = MetaScanner.DATA;
continue stateloop;
case '-':
continue;
default:
state = MetaScanner.COMMENT;
continue stateloop;
}
}
// XXX reorder point
case COMMENT_START_DASH:
c = read();
switch (c) {
case -1:
break stateloop;
case '-':
state = MetaScanner.COMMENT_END;
continue stateloop;
case '>':
state = MetaScanner.DATA;
continue stateloop;
default:
state = MetaScanner.COMMENT;
continue stateloop;
}
// XXX reorder point
case ATTRIBUTE_VALUE_SINGLE_QUOTED:
for (;;) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch (c) {
case -1:
break stateloop;
case '\'':
handleAttributeValue();
state = MetaScanner.AFTER_ATTRIBUTE_VALUE_QUOTED;
continue stateloop;
default:
handleCharInAttributeValue(c);
continue;
}
}
// XXX reorder point
case SCAN_UNTIL_GT:
for (;;) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch (c) {
case -1:
break stateloop;
case '>':
state = MetaScanner.DATA;
continue stateloop;
default:
continue;
}
}
}
}
stateSave = state;
}
private void handleCharInAttributeValue(int c) {
if (metaState == A) {
if (contentIndex == CONTENT.length || charsetIndex == CHARSET.length) {
addToBuffer(c);
} else if (httpEquivIndex == HTTP_EQUIV.length) {
if (contentTypeIndex < CONTENT_TYPE.length && toAsciiLowerCase(c) == CONTENT_TYPE[contentTypeIndex]) {
++contentTypeIndex;
} else {
contentTypeIndex = Integer.MAX_VALUE;
}
}
}
}
@Inline private int toAsciiLowerCase(int c) {
if (c >= 'A' && c <= 'Z') {
return c + 0x20;
}
return c;
}
/**
* Adds a character to the accumulation buffer.
* @param c the character to add
*/
private void addToBuffer(int c) {
if (strBufLen == strBuf.length) {
char[] newBuf = new char[strBuf.length + (strBuf.length << 1)];
System.arraycopy(strBuf, 0, newBuf, 0, strBuf.length);
strBuf = newBuf;
}
strBuf[strBufLen++] = (char)c;
}
/**
* Attempts to extract a charset name from the accumulation buffer.
* @return <code>true</code> if successful
* @throws SAXException
*/
private void handleAttributeValue() throws SAXException {
if (metaState != A) {
return;
}
if (contentIndex == CONTENT.length && content == null) {
content = Portability.newStringFromBuffer(strBuf, 0, strBufLen
// CPPONLY: , treeBuilder
);
return;
}
if (charsetIndex == CHARSET.length && charset == null) {
charset = Portability.newStringFromBuffer(strBuf, 0, strBufLen
// CPPONLY: , treeBuilder
);
return;
}
if (httpEquivIndex == HTTP_EQUIV.length
&& httpEquivState == HTTP_EQUIV_NOT_SEEN) {
httpEquivState = (contentTypeIndex == CONTENT_TYPE.length) ? HTTP_EQUIV_CONTENT_TYPE
: HTTP_EQUIV_OTHER;
return;
}
}
private boolean handleTag() throws SAXException {
boolean stop = handleTagInner();
Portability.releaseString(content);
content = null;
Portability.releaseString(charset);
charset = null;
httpEquivState = HTTP_EQUIV_NOT_SEEN;
return stop;
}
private boolean handleTagInner() throws SAXException {
if (charset != null && tryCharset(charset)) {
return true;
}
if (content != null && httpEquivState == HTTP_EQUIV_CONTENT_TYPE) {
String extract = TreeBuilder.extractCharsetFromContent(content
// CPPONLY: , treeBuilder
);
if (extract == null) {
return false;
}
boolean success = tryCharset(extract);
Portability.releaseString(extract);
return success;
}
return false;
}
/**
* Tries to switch to an encoding.
*
* @param encoding
* @return <code>true</code> if successful
* @throws SAXException
*/
protected abstract boolean tryCharset(String encoding) throws SAXException;
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2008-2015 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import nu.validator.htmlparser.annotation.Literal;
import nu.validator.htmlparser.annotation.Local;
import nu.validator.htmlparser.annotation.NoLength;
import nu.validator.htmlparser.common.Interner;
public final class Portability {
// Allocating methods
/**
* Allocates a new local name object. In C++, the refcount must be set up in such a way that
* calling <code>releaseLocal</code> on the return value balances the refcount set by this method.
*/
public static @Local String newLocalNameFromBuffer(@NoLength char[] buf, int offset, int length, Interner interner) {
return new String(buf, offset, length).intern();
}
public static String newStringFromBuffer(@NoLength char[] buf, int offset, int length
// CPPONLY: , TreeBuilder treeBuilder
) {
return new String(buf, offset, length);
}
public static String newEmptyString() {
return "";
}
public static String newStringFromLiteral(@Literal String literal) {
return literal;
}
public static String newStringFromString(String string) {
return string;
}
// XXX get rid of this
public static char[] newCharArrayFromLocal(@Local String local) {
return local.toCharArray();
}
public static char[] newCharArrayFromString(String string) {
return string.toCharArray();
}
public static @Local String newLocalFromLocal(@Local String local, Interner interner) {
return local;
}
// Deallocation methods
public static void releaseString(String str) {
// No-op in Java
}
// Comparison methods
public static boolean localEqualsBuffer(@Local String local, @NoLength char[] buf, int offset, int length) {
if (local.length() != length) {
return false;
}
for (int i = 0; i < length; i++) {
if (local.charAt(i) != buf[offset + i]) {
return false;
}
}
return true;
}
public static boolean lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
String string) {
if (string == null) {
return false;
}
if (lowerCaseLiteral.length() > string.length()) {
return false;
}
for (int i = 0; i < lowerCaseLiteral.length(); i++) {
char c0 = lowerCaseLiteral.charAt(i);
char c1 = string.charAt(i);
if (c1 >= 'A' && c1 <= 'Z') {
c1 += 0x20;
}
if (c0 != c1) {
return false;
}
}
return true;
}
public static boolean lowerCaseLiteralEqualsIgnoreAsciiCaseString(@Literal String lowerCaseLiteral,
String string) {
if (string == null) {
return false;
}
if (lowerCaseLiteral.length() != string.length()) {
return false;
}
for (int i = 0; i < lowerCaseLiteral.length(); i++) {
char c0 = lowerCaseLiteral.charAt(i);
char c1 = string.charAt(i);
if (c1 >= 'A' && c1 <= 'Z') {
c1 += 0x20;
}
if (c0 != c1) {
return false;
}
}
return true;
}
public static boolean literalEqualsString(@Literal String literal, String string) {
return literal.equals(string);
}
public static boolean stringEqualsString(String one, String other) {
return one.equals(other);
}
public static void delete(Object o) {
}
public static void deleteArray(Object o) {
}
}

View file

@ -0,0 +1,6 @@
The .java files in this directory were placed here by the Java-to-C++
translator that lives in parser/html/java/translator. Together they represent
a snapshot of the Java code that was translated to produce the corresponding
.h and .cpp files in the parent directory. Changing these .java files is not
worthwhile, as they will just be overwritten by the next translation. See
parser/html/java/README.txt for information about performing the translation.

View file

@ -0,0 +1,295 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2007-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import nu.validator.htmlparser.annotation.Inline;
import nu.validator.htmlparser.annotation.Local;
import nu.validator.htmlparser.annotation.NsUri;
final class StackNode<T> {
final int flags;
final @Local String name;
final @Local String popName;
final @NsUri String ns;
final T node;
// Only used on the list of formatting elements
HtmlAttributes attributes;
private int refcount = 1;
// [NOCPP[
private final TaintableLocatorImpl locator;
public TaintableLocatorImpl getLocator() {
return locator;
}
// ]NOCPP]
@Inline public int getFlags() {
return flags;
}
public int getGroup() {
return flags & ElementName.GROUP_MASK;
}
public boolean isScoping() {
return (flags & ElementName.SCOPING) != 0;
}
public boolean isSpecial() {
return (flags & ElementName.SPECIAL) != 0;
}
public boolean isFosterParenting() {
return (flags & ElementName.FOSTER_PARENTING) != 0;
}
public boolean isHtmlIntegrationPoint() {
return (flags & ElementName.HTML_INTEGRATION_POINT) != 0;
}
// [NOCPP[
public boolean isOptionalEndTag() {
return (flags & ElementName.OPTIONAL_END_TAG) != 0;
}
// ]NOCPP]
/**
* Constructor for copying. This doesn't take another <code>StackNode</code>
* because in C++ the caller is reponsible for reobtaining the local names
* from another interner.
*
* @param flags
* @param ns
* @param name
* @param node
* @param popName
* @param attributes
*/
StackNode(int flags, @NsUri String ns, @Local String name, T node,
@Local String popName, HtmlAttributes attributes
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
this.flags = flags;
this.name = name;
this.popName = popName;
this.ns = ns;
this.node = node;
this.attributes = attributes;
this.refcount = 1;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
}
/**
* Short hand for well-known HTML elements.
*
* @param elementName
* @param node
*/
StackNode(ElementName elementName, T node
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
this.flags = elementName.getFlags();
this.name = elementName.name;
this.popName = elementName.name;
this.ns = "http://www.w3.org/1999/xhtml";
this.node = node;
this.attributes = null;
this.refcount = 1;
assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
// [NOCPP[
this.locator = locator;
// ]NOCPP]
}
/**
* Constructor for HTML formatting elements.
*
* @param elementName
* @param node
* @param attributes
*/
StackNode(ElementName elementName, T node, HtmlAttributes attributes
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
this.flags = elementName.getFlags();
this.name = elementName.name;
this.popName = elementName.name;
this.ns = "http://www.w3.org/1999/xhtml";
this.node = node;
this.attributes = attributes;
this.refcount = 1;
assert !elementName.isCustom() : "Don't use this constructor for custom elements.";
// [NOCPP[
this.locator = locator;
// ]NOCPP]
}
/**
* The common-case HTML constructor.
*
* @param elementName
* @param node
* @param popName
*/
StackNode(ElementName elementName, T node, @Local String popName
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
this.flags = elementName.getFlags();
this.name = elementName.name;
this.popName = popName;
this.ns = "http://www.w3.org/1999/xhtml";
this.node = node;
this.attributes = null;
this.refcount = 1;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
}
/**
* Constructor for SVG elements. Note that the order of the arguments is
* what distinguishes this from the HTML constructor. This is ugly, but
* AFAICT the least disruptive way to make this work with Java's generics
* and without unnecessary branches. :-(
*
* @param elementName
* @param popName
* @param node
*/
StackNode(ElementName elementName, @Local String popName, T node
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
this.flags = prepareSvgFlags(elementName.getFlags());
this.name = elementName.name;
this.popName = popName;
this.ns = "http://www.w3.org/2000/svg";
this.node = node;
this.attributes = null;
this.refcount = 1;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
}
/**
* Constructor for MathML.
*
* @param elementName
* @param node
* @param popName
* @param markAsIntegrationPoint
*/
StackNode(ElementName elementName, T node, @Local String popName,
boolean markAsIntegrationPoint
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
this.flags = prepareMathFlags(elementName.getFlags(),
markAsIntegrationPoint);
this.name = elementName.name;
this.popName = popName;
this.ns = "http://www.w3.org/1998/Math/MathML";
this.node = node;
this.attributes = null;
this.refcount = 1;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
}
private static int prepareSvgFlags(int flags) {
flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
| ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
if ((flags & ElementName.SCOPING_AS_SVG) != 0) {
flags |= (ElementName.SCOPING | ElementName.SPECIAL | ElementName.HTML_INTEGRATION_POINT);
}
return flags;
}
private static int prepareMathFlags(int flags,
boolean markAsIntegrationPoint) {
flags &= ~(ElementName.FOSTER_PARENTING | ElementName.SCOPING
| ElementName.SPECIAL | ElementName.OPTIONAL_END_TAG);
if ((flags & ElementName.SCOPING_AS_MATHML) != 0) {
flags |= (ElementName.SCOPING | ElementName.SPECIAL);
}
if (markAsIntegrationPoint) {
flags |= ElementName.HTML_INTEGRATION_POINT;
}
return flags;
}
@SuppressWarnings("unused") private void destructor() {
Portability.delete(attributes);
}
public void dropAttributes() {
attributes = null;
}
// [NOCPP[
/**
* @see java.lang.Object#toString()
*/
@Override public @Local String toString() {
return name;
}
// ]NOCPP]
public void retain() {
refcount++;
}
public void release() {
refcount--;
if (refcount == 0) {
Portability.delete(this);
}
}
}

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2009-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import nu.validator.htmlparser.annotation.Auto;
public class StateSnapshot<T> implements TreeBuilderState<T> {
private final @Auto StackNode<T>[] stack;
private final @Auto StackNode<T>[] listOfActiveFormattingElements;
private final @Auto int[] templateModeStack;
private final T formPointer;
private final T headPointer;
private final T deepTreeSurrogateParent;
private final int mode;
private final int originalMode;
private final boolean framesetOk;
private final boolean needToDropLF;
private final boolean quirks;
/**
* @param stack
* @param listOfActiveFormattingElements
* @param templateModeStack
* @param formPointer
* @param headPointer
* @param deepTreeSurrogateParent
* @param mode
* @param originalMode
* @param framesetOk
* @param needToDropLF
* @param quirks
*/
StateSnapshot(StackNode<T>[] stack,
StackNode<T>[] listOfActiveFormattingElements, int[] templateModeStack, T formPointer,
T headPointer, T deepTreeSurrogateParent, int mode, int originalMode,
boolean framesetOk, boolean needToDropLF, boolean quirks) {
this.stack = stack;
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
this.templateModeStack = templateModeStack;
this.formPointer = formPointer;
this.headPointer = headPointer;
this.deepTreeSurrogateParent = deepTreeSurrogateParent;
this.mode = mode;
this.originalMode = originalMode;
this.framesetOk = framesetOk;
this.needToDropLF = needToDropLF;
this.quirks = quirks;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
*/
public StackNode<T>[] getStack() {
return stack;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStack()
*/
public int[] getTemplateModeStack() {
return templateModeStack;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
*/
public StackNode<T>[] getListOfActiveFormattingElements() {
return listOfActiveFormattingElements;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
*/
public T getFormPointer() {
return formPointer;
}
/**
* Returns the headPointer.
*
* @return the headPointer
*/
public T getHeadPointer() {
return headPointer;
}
/**
* Returns the deepTreeSurrogateParent.
*
* @return the deepTreeSurrogateParent
*/
public T getDeepTreeSurrogateParent() {
return deepTreeSurrogateParent;
}
/**
* Returns the mode.
*
* @return the mode
*/
public int getMode() {
return mode;
}
/**
* Returns the originalMode.
*
* @return the originalMode
*/
public int getOriginalMode() {
return originalMode;
}
/**
* Returns the framesetOk.
*
* @return the framesetOk
*/
public boolean isFramesetOk() {
return framesetOk;
}
/**
* Returns the needToDropLF.
*
* @return the needToDropLF
*/
public boolean isNeedToDropLF() {
return needToDropLF;
}
/**
* Returns the quirks.
*
* @return the quirks
*/
public boolean isQuirks() {
return quirks;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElementsLength()
*/
public int getListOfActiveFormattingElementsLength() {
return listOfActiveFormattingElements.length;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getStackLength()
*/
public int getStackLength() {
return stack.length;
}
/**
* @see nu.validator.htmlparser.impl.TreeBuilderState#getTemplateModeStackLength()
*/
public int getTemplateModeStackLength() {
return templateModeStack.length;
}
@SuppressWarnings("unused") private void destructor() {
for (int i = 0; i < stack.length; i++) {
stack[i].release();
}
for (int i = 0; i < listOfActiveFormattingElements.length; i++) {
if (listOfActiveFormattingElements[i] != null) {
listOfActiveFormattingElements[i].release();
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,151 @@
/*
* Copyright (c) 2008-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package nu.validator.htmlparser.impl;
import nu.validator.htmlparser.annotation.NoLength;
/**
* An UTF-16 buffer that knows the start and end indeces of its unconsumed
* content.
*
* @version $Id$
* @author hsivonen
*/
public final class UTF16Buffer {
/**
* The backing store of the buffer. May be larger than the logical content
* of this <code>UTF16Buffer</code>.
*/
private final @NoLength char[] buffer;
/**
* The index of the first unconsumed character in the backing buffer.
*/
private int start;
/**
* The index of the slot immediately after the last character in the backing
* buffer that is part of the logical content of this
* <code>UTF16Buffer</code>.
*/
private int end;
//[NOCPP[
/**
* Constructor for wrapping an existing UTF-16 code unit array.
*
* @param buffer
* the backing buffer
* @param start
* the index of the first character to consume
* @param end
* the index immediately after the last character to consume
*/
public UTF16Buffer(@NoLength char[] buffer, int start, int end) {
this.buffer = buffer;
this.start = start;
this.end = end;
}
// ]NOCPP]
/**
* Returns the start index.
*
* @return the start index
*/
public int getStart() {
return start;
}
/**
* Sets the start index.
*
* @param start
* the start index
*/
public void setStart(int start) {
this.start = start;
}
/**
* Returns the backing buffer.
*
* @return the backing buffer
*/
public @NoLength char[] getBuffer() {
return buffer;
}
/**
* Returns the end index.
*
* @return the end index
*/
public int getEnd() {
return end;
}
/**
* Checks if the buffer has data left.
*
* @return <code>true</code> if there's data left
*/
public boolean hasMore() {
return start < end;
}
/**
* Returns <code>end - start</code>.
*
* @return <code>end - start</code>
*/
public int getLength() {
return end - start;
}
/**
* Adjusts the start index to skip over the first character if it is a line
* feed and the previous character was a carriage return.
*
* @param lastWasCR
* whether the previous character was a carriage return
*/
public void adjust(boolean lastWasCR) {
if (lastWasCR && buffer[start] == '\n') {
start++;
}
}
/**
* Sets the end index.
*
* @param end
* the end index
*/
public void setEnd(int end) {
this.end = end;
}
}

104
parser/html/moz.build Normal file
View file

@ -0,0 +1,104 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPIDL_SOURCES += [
'nsIParserUtils.idl',
'nsIScriptableUnescapeHTML.idl',
]
XPIDL_MODULE = 'html5'
EXPORTS += [
'jArray.h',
'nsAHtml5TreeBuilderState.h',
'nsAHtml5TreeOpSink.h',
'nsHtml5ArrayCopy.h',
'nsHtml5AtomList.h',
'nsHtml5Atoms.h',
'nsHtml5AtomTable.h',
'nsHtml5ByteReadable.h',
'nsHtml5DependentUTF16Buffer.h',
'nsHtml5DocumentBuilder.h',
'nsHtml5DocumentMode.h',
'nsHtml5HtmlAttributes.h',
'nsHtml5Macros.h',
'nsHtml5MetaScanner.h',
'nsHtml5MetaScannerHSupplement.h',
'nsHtml5Module.h',
'nsHtml5NamedCharacters.h',
'nsHtml5NamedCharactersAccel.h',
'nsHtml5OplessBuilder.h',
'nsHtml5OwningUTF16Buffer.h',
'nsHtml5Parser.h',
'nsHtml5PlainTextUtils.h',
'nsHtml5RefPtr.h',
'nsHtml5Speculation.h',
'nsHtml5SpeculativeLoad.h',
'nsHtml5StreamListener.h',
'nsHtml5StreamParser.h',
'nsHtml5StringParser.h',
'nsHtml5SVGLoadDispatcher.h',
'nsHtml5TreeOperation.h',
'nsHtml5TreeOpExecutor.h',
'nsHtml5TreeOpStage.h',
'nsHtml5UTF16Buffer.h',
'nsHtml5UTF16BufferHSupplement.h',
'nsHtml5ViewSourceUtils.h',
'nsIContentHandle.h',
'nsParserUtils.h',
]
UNIFIED_SOURCES += [
'nsHtml5Atom.cpp',
'nsHtml5Atoms.cpp',
'nsHtml5AtomTable.cpp',
'nsHtml5AttributeName.cpp',
'nsHtml5DependentUTF16Buffer.cpp',
'nsHtml5DocumentBuilder.cpp',
'nsHtml5ElementName.cpp',
'nsHtml5Highlighter.cpp',
'nsHtml5HtmlAttributes.cpp',
'nsHtml5MetaScanner.cpp',
'nsHtml5Module.cpp',
'nsHtml5NamedCharacters.cpp',
'nsHtml5NamedCharactersAccel.cpp',
'nsHtml5OplessBuilder.cpp',
'nsHtml5OwningUTF16Buffer.cpp',
'nsHtml5Parser.cpp',
'nsHtml5PlainTextUtils.cpp',
'nsHtml5Portability.cpp',
'nsHtml5ReleasableAttributeName.cpp',
'nsHtml5ReleasableElementName.cpp',
'nsHtml5Speculation.cpp',
'nsHtml5SpeculativeLoad.cpp',
'nsHtml5StackNode.cpp',
'nsHtml5StateSnapshot.cpp',
'nsHtml5StreamListener.cpp',
'nsHtml5StreamParser.cpp',
'nsHtml5StringParser.cpp',
'nsHtml5SVGLoadDispatcher.cpp',
'nsHtml5Tokenizer.cpp',
'nsHtml5TreeBuilder.cpp',
'nsHtml5TreeOperation.cpp',
'nsHtml5TreeOpExecutor.cpp',
'nsHtml5TreeOpStage.cpp',
'nsHtml5UTF16Buffer.cpp',
'nsHtml5ViewSourceUtils.cpp',
'nsParserUtils.cpp',
]
FINAL_LIBRARY = 'xul'
# DEFINES['ENABLE_VOID_MENUITEM'] = True
LOCAL_INCLUDES += [
'/dom/base',
]
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']
if CONFIG['CLANG_CXX']:
CXXFLAGS += ['-Wno-implicit-fallthrough']

View file

@ -0,0 +1,50 @@
/* 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 nsAHtml5TreeBuilderState_h
#define nsAHtml5TreeBuilderState_h
#include "nsIContentHandle.h"
/**
* Interface for exposing the internal state of the HTML5 tree builder.
* For more documentation, please see
* http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/impl/StateSnapshot.java
*/
class nsAHtml5TreeBuilderState {
public:
virtual jArray<nsHtml5StackNode*,int32_t> getStack() = 0;
virtual jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements() = 0;
virtual jArray<int32_t,int32_t> getTemplateModeStack() = 0;
virtual int32_t getStackLength() = 0;
virtual int32_t getListOfActiveFormattingElementsLength() = 0;
virtual int32_t getTemplateModeStackLength() = 0;
virtual nsIContentHandle* getFormPointer() = 0;
virtual nsIContentHandle* getHeadPointer() = 0;
virtual nsIContentHandle* getDeepTreeSurrogateParent() = 0;
virtual int32_t getMode() = 0;
virtual int32_t getOriginalMode() = 0;
virtual bool isFramesetOk() = 0;
virtual bool isNeedToDropLF() = 0;
virtual bool isQuirks() = 0;
virtual ~nsAHtml5TreeBuilderState() {
}
};
#endif /* nsAHtml5TreeBuilderState_h */

View file

@ -0,0 +1,24 @@
/* 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 nsAHtml5TreeOpSink_h
#define nsAHtml5TreeOpSink_h
/**
* The purpose of this interface is to connect a tree op executor
* (main-thread case), a tree op stage (non-speculative off-the-main-thread
* case) or a speculation (speculative case).
*/
class nsAHtml5TreeOpSink {
public:
/**
* Flush the operations from the tree operations from the argument
* queue into this sink unconditionally.
*/
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) = 0;
};
#endif /* nsAHtml5TreeOpSink_h */

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2008 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef nsHtml5ArrayCopy_h
#define nsHtml5ArrayCopy_h
class nsString;
class nsHtml5StackNode;
class nsHtml5AttributeName;
// Unfortunately, these don't work as template functions because the arguments
// would need coercion from a template class, which complicates things.
class nsHtml5ArrayCopy {
public:
static inline void
arraycopy(char16_t* source, int32_t sourceOffset, char16_t* target, int32_t targetOffset, int32_t length)
{
memcpy(&(target[targetOffset]), &(source[sourceOffset]), size_t(length) * sizeof(char16_t));
}
static inline void
arraycopy(char16_t* source, char16_t* target, int32_t length)
{
memcpy(target, source, size_t(length) * sizeof(char16_t));
}
static inline void
arraycopy(int32_t* source, int32_t* target, int32_t length)
{
memcpy(target, source, size_t(length) * sizeof(int32_t));
}
static inline void
arraycopy(nsString** source, nsString** target, int32_t length)
{
memcpy(target, source, size_t(length) * sizeof(nsString*));
}
static inline void
arraycopy(nsHtml5AttributeName** source, nsHtml5AttributeName** target, int32_t length)
{
memcpy(target, source, size_t(length) * sizeof(nsHtml5AttributeName*));
}
static inline void
arraycopy(nsHtml5StackNode** source, nsHtml5StackNode** target, int32_t length)
{
memcpy(target, source, size_t(length) * sizeof(nsHtml5StackNode*));
}
static inline void
arraycopy(nsHtml5StackNode** arr, int32_t sourceOffset, int32_t targetOffset, int32_t length)
{
memmove(&(arr[targetOffset]), &(arr[sourceOffset]), size_t(length) * sizeof(nsHtml5StackNode*));
}
};
#endif // nsHtml5ArrayCopy_h

View file

@ -0,0 +1,91 @@
/* 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 "nsHtml5Atom.h"
#include "nsAutoPtr.h"
#include "mozilla/Unused.h"
nsHtml5Atom::nsHtml5Atom(const nsAString& aString)
{
mLength = aString.Length();
mIsStatic = false;
RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
if (buf) {
mString = static_cast<char16_t*>(buf->Data());
} else {
const size_t size = (mLength + 1) * sizeof(char16_t);
buf = nsStringBuffer::Alloc(size);
if (MOZ_UNLIKELY(!buf)) {
// We OOM because atom allocations should be small and it's hard to
// handle them more gracefully in a constructor.
NS_ABORT_OOM(size);
}
mString = static_cast<char16_t*>(buf->Data());
CopyUnicodeTo(aString, 0, mString, mLength);
mString[mLength] = char16_t(0);
}
NS_ASSERTION(mString[mLength] == char16_t(0), "null terminated");
NS_ASSERTION(buf && buf->StorageSize() >= (mLength+1) * sizeof(char16_t),
"enough storage");
NS_ASSERTION(Equals(aString), "correct data");
// Take ownership of buffer
mozilla::Unused << buf.forget();
}
nsHtml5Atom::~nsHtml5Atom()
{
nsStringBuffer::FromData(mString)->Release();
}
NS_IMETHODIMP_(MozExternalRefCountType)
nsHtml5Atom::AddRef()
{
NS_NOTREACHED("Attempt to AddRef an nsHtml5Atom.");
return 2;
}
NS_IMETHODIMP_(MozExternalRefCountType)
nsHtml5Atom::Release()
{
NS_NOTREACHED("Attempt to Release an nsHtml5Atom.");
return 1;
}
NS_IMETHODIMP
nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_NOTREACHED("Attempt to call QueryInterface an nsHtml5Atom.");
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsHtml5Atom::ScriptableToString(nsAString& aBuf)
{
NS_NOTREACHED("Should not call ScriptableToString.");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHtml5Atom::ToUTF8String(nsACString& aReturn)
{
NS_NOTREACHED("Should not attempt to convert to an UTF-8 string.");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHtml5Atom::ScriptableEquals(const nsAString& aString, bool* aResult)
{
NS_NOTREACHED("Should not call ScriptableEquals.");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP_(size_t)
nsHtml5Atom::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
{
NS_NOTREACHED("Should not call SizeOfIncludingThis.");
return 0;
}

28
parser/html/nsHtml5Atom.h Normal file
View file

@ -0,0 +1,28 @@
/* 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 nsHtml5Atom_h
#define nsHtml5Atom_h
#include "nsIAtom.h"
#include "mozilla/Attributes.h"
/**
* A dynamic atom implementation meant for use within the nsHtml5Tokenizer and
* nsHtml5TreeBuilder owned by one nsHtml5Parser or nsHtml5StreamParser
* instance.
*
* Usage is documented in nsHtml5AtomTable and nsIAtom.
*/
class nsHtml5Atom final : public nsIAtom
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIATOM
explicit nsHtml5Atom(const nsAString& aString);
~nsHtml5Atom();
};
#endif // nsHtml5Atom_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,56 @@
/* 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 "nsHtml5AtomTable.h"
#include "nsHtml5Atom.h"
#include "nsThreadUtils.h"
nsHtml5AtomEntry::nsHtml5AtomEntry(KeyTypePointer aStr)
: nsStringHashKey(aStr)
, mAtom(new nsHtml5Atom(*aStr))
{
}
nsHtml5AtomEntry::nsHtml5AtomEntry(const nsHtml5AtomEntry& aOther)
: nsStringHashKey(aOther)
, mAtom(nullptr)
{
NS_NOTREACHED("nsHtml5AtomTable is broken and tried to copy an entry");
}
nsHtml5AtomEntry::~nsHtml5AtomEntry()
{
}
nsHtml5AtomTable::nsHtml5AtomTable()
{
#ifdef DEBUG
NS_GetMainThread(getter_AddRefs(mPermittedLookupThread));
#endif
}
nsHtml5AtomTable::~nsHtml5AtomTable()
{
}
nsIAtom*
nsHtml5AtomTable::GetAtom(const nsAString& aKey)
{
#ifdef DEBUG
{
nsCOMPtr<nsIThread> currentThread;
NS_GetCurrentThread(getter_AddRefs(currentThread));
NS_ASSERTION(mPermittedLookupThread == currentThread, "Wrong thread!");
}
#endif
nsIAtom* atom = NS_GetStaticAtom(aKey);
if (atom) {
return atom;
}
nsHtml5AtomEntry* entry = mTable.PutEntry(aKey);
if (!entry) {
return nullptr;
}
return entry->GetAtom();
}

View file

@ -0,0 +1,107 @@
/* 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 nsHtml5AtomTable_h
#define nsHtml5AtomTable_h
#include "nsHashKeys.h"
#include "nsTHashtable.h"
#include "nsAutoPtr.h"
#include "nsIAtom.h"
#include "nsIThread.h"
class nsHtml5Atom;
class nsHtml5AtomEntry : public nsStringHashKey
{
public:
explicit nsHtml5AtomEntry(KeyTypePointer aStr);
nsHtml5AtomEntry(const nsHtml5AtomEntry& aOther);
~nsHtml5AtomEntry();
inline nsHtml5Atom* GetAtom()
{
return mAtom;
}
private:
nsAutoPtr<nsHtml5Atom> mAtom;
};
/**
* nsHtml5AtomTable provides non-locking lookup and creation of atoms for
* nsHtml5Parser or nsHtml5StreamParser.
*
* The hashtable holds dynamically allocated atoms that are private to an
* instance of nsHtml5Parser or nsHtml5StreamParser. (Static atoms are used on
* interned nsHtml5ElementNames and interned nsHtml5AttributeNames. Also, when
* the doctype name is 'html', that identifier needs to be represented as a
* static atom.)
*
* Each instance of nsHtml5Parser has a single instance of nsHtml5AtomTable,
* and each instance of nsHtml5StreamParser has a single instance of
* nsHtml5AtomTable. Dynamic atoms obtained from an nsHtml5AtomTable are valid
* for == comparison with each other or with atoms declared in nsHtml5Atoms
* within the nsHtml5Tokenizer and the nsHtml5TreeBuilder instances owned by
* the same nsHtml5Parser/nsHtml5StreamParser instance that owns the
* nsHtml5AtomTable instance.
*
* Dynamic atoms (atoms whose IsStaticAtom() returns false) obtained from
* nsHtml5AtomTable must be re-obtained from another atom table when there's a
* need to migrate atoms from an nsHtml5Parser to its nsHtml5StreamParser
* (re-obtain from the other nsHtml5AtomTable), from an nsHtml5Parser to its
* owner nsHtml5Parser (re-obtain from the other nsHtml5AtomTable) or from the
* parser to the DOM (re-obtain from the application-wide atom table). To
* re-obtain an atom from another atom table, obtain a string from the atom
* using ToString(nsAString&) and look up an atom in the other table using that
* string.
*
* An instance of nsHtml5AtomTable that belongs to an nsHtml5Parser is only
* accessed from the main thread. An instance of nsHtml5AtomTable that belongs
* to an nsHtml5StreamParser is accessed both from the main thread and from the
* thread that executes the runnables of the nsHtml5StreamParser instance.
* However, the threads never access the nsHtml5AtomTable instance concurrently
* in the nsHtml5StreamParser case.
*
* Methods on the atoms obtained from nsHtml5AtomTable may be called on any
* thread, although they only need to be called on the main thread or on the
* thread working for the nsHtml5StreamParser when nsHtml5AtomTable belongs to
* an nsHtml5StreamParser.
*
* Dynamic atoms obtained from nsHtml5AtomTable are deleted when the
* nsHtml5AtomTable itself is destructed, which happens when the owner
* nsHtml5Parser or nsHtml5StreamParser is destructed.
*/
class nsHtml5AtomTable
{
public:
nsHtml5AtomTable();
~nsHtml5AtomTable();
/**
* Obtains the atom for the given string in the scope of this atom table.
*/
nsIAtom* GetAtom(const nsAString& aKey);
/**
* Empties the table.
*/
void Clear()
{
mTable.Clear();
}
#ifdef DEBUG
void SetPermittedLookupThread(nsIThread* aThread)
{
mPermittedLookupThread = aThread;
}
#endif
private:
nsTHashtable<nsHtml5AtomEntry> mTable;
#ifdef DEBUG
nsCOMPtr<nsIThread> mPermittedLookupThread;
#endif
};
#endif // nsHtml5AtomTable_h

View file

@ -0,0 +1,36 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
/*
* This class wraps up the creation (and destruction) of the standard
* set of atoms used by the HTML5 parser; the atoms are created when
* nsHtml5Module is loaded and they are destroyed when nsHtml5Module is
* unloaded.
*/
#include "nsHtml5Atoms.h"
#include "nsStaticAtom.h"
using namespace mozilla;
// define storage for all atoms
#define HTML5_ATOM(_name, _value) nsIAtom* nsHtml5Atoms::_name;
#include "nsHtml5AtomList.h"
#undef HTML5_ATOM
#define HTML5_ATOM(name_, value_) NS_STATIC_ATOM_BUFFER(name_##_buffer, value_)
#include "nsHtml5AtomList.h"
#undef HTML5_ATOM
static const nsStaticAtom Html5Atoms_info[] = {
#define HTML5_ATOM(name_, value_) NS_STATIC_ATOM(name_##_buffer, &nsHtml5Atoms::name_),
#include "nsHtml5AtomList.h"
#undef HTML5_ATOM
};
void nsHtml5Atoms::AddRefAtoms()
{
NS_RegisterStaticAtoms(Html5Atoms_info);
}

View file

@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
/*
* This class wraps up the creation (and destruction) of the standard
* set of atoms used by gklayout; the atoms are created when gklayout
* is loaded and they are destroyed when gklayout is unloaded.
*/
#ifndef nsHtml5Atoms_h
#define nsHtml5Atoms_h
#include "nsIAtom.h"
class nsHtml5Atoms {
public:
static void AddRefAtoms();
/* Declare all atoms
The atom names and values are stored in nsGkAtomList.h and
are brought to you by the magic of C preprocessing
Add new atoms to nsGkAtomList and all support logic will be auto-generated
*/
#define HTML5_ATOM(_name, _value) static nsIAtom* _name;
#include "nsHtml5AtomList.h"
#undef HTML5_ATOM
};
#endif /* nsHtml5Atoms_h */

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,692 @@
/*
* Copyright (c) 2008-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit AttributeName.java instead and regenerate.
*/
#ifndef nsHtml5AttributeName_h
#define nsHtml5AttributeName_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5AttributeName
{
public:
static int32_t* ALL_NO_NS;
private:
static int32_t* XMLNS_NS;
static int32_t* XML_NS;
static int32_t* XLINK_NS;
public:
static nsIAtom** ALL_NO_PREFIX;
private:
static nsIAtom** XMLNS_PREFIX;
static nsIAtom** XLINK_PREFIX;
static nsIAtom** XML_PREFIX;
static nsIAtom** SVG_DIFFERENT(nsIAtom* name, nsIAtom* camel);
static nsIAtom** MATH_DIFFERENT(nsIAtom* name, nsIAtom* camel);
static nsIAtom** COLONIFIED_LOCAL(nsIAtom* name, nsIAtom* suffix);
public:
static nsIAtom** SAME_LOCAL(nsIAtom* name);
static nsHtml5AttributeName* nameByBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
private:
static int32_t bufToHash(char16_t* buf, int32_t len);
int32_t* uri;
nsIAtom** local;
nsIAtom** prefix;
protected:
nsHtml5AttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix);
private:
static nsHtml5AttributeName* createAttributeName(nsIAtom* name);
public:
virtual void release();
virtual ~nsHtml5AttributeName();
virtual nsHtml5AttributeName* cloneAttributeName(nsHtml5AtomTable* interner);
int32_t getUri(int32_t mode);
nsIAtom* getLocal(int32_t mode);
nsIAtom* getPrefix(int32_t mode);
bool equalsAnother(nsHtml5AttributeName* another);
static nsHtml5AttributeName* ATTR_D;
static nsHtml5AttributeName* ATTR_K;
static nsHtml5AttributeName* ATTR_R;
static nsHtml5AttributeName* ATTR_X;
static nsHtml5AttributeName* ATTR_Y;
static nsHtml5AttributeName* ATTR_Z;
static nsHtml5AttributeName* ATTR_BY;
static nsHtml5AttributeName* ATTR_CX;
static nsHtml5AttributeName* ATTR_CY;
static nsHtml5AttributeName* ATTR_DX;
static nsHtml5AttributeName* ATTR_DY;
static nsHtml5AttributeName* ATTR_G2;
static nsHtml5AttributeName* ATTR_G1;
static nsHtml5AttributeName* ATTR_FX;
static nsHtml5AttributeName* ATTR_FY;
static nsHtml5AttributeName* ATTR_K4;
static nsHtml5AttributeName* ATTR_K2;
static nsHtml5AttributeName* ATTR_K3;
static nsHtml5AttributeName* ATTR_K1;
static nsHtml5AttributeName* ATTR_ID;
static nsHtml5AttributeName* ATTR_IN;
static nsHtml5AttributeName* ATTR_U2;
static nsHtml5AttributeName* ATTR_U1;
static nsHtml5AttributeName* ATTR_RT;
static nsHtml5AttributeName* ATTR_RX;
static nsHtml5AttributeName* ATTR_RY;
static nsHtml5AttributeName* ATTR_TO;
static nsHtml5AttributeName* ATTR_Y2;
static nsHtml5AttributeName* ATTR_Y1;
static nsHtml5AttributeName* ATTR_X1;
static nsHtml5AttributeName* ATTR_X2;
static nsHtml5AttributeName* ATTR_ALT;
static nsHtml5AttributeName* ATTR_DIR;
static nsHtml5AttributeName* ATTR_DUR;
static nsHtml5AttributeName* ATTR_END;
static nsHtml5AttributeName* ATTR_FOR;
static nsHtml5AttributeName* ATTR_IN2;
static nsHtml5AttributeName* ATTR_MAX;
static nsHtml5AttributeName* ATTR_MIN;
static nsHtml5AttributeName* ATTR_LOW;
static nsHtml5AttributeName* ATTR_REL;
static nsHtml5AttributeName* ATTR_REV;
static nsHtml5AttributeName* ATTR_SRC;
static nsHtml5AttributeName* ATTR_AXIS;
static nsHtml5AttributeName* ATTR_ABBR;
static nsHtml5AttributeName* ATTR_BBOX;
static nsHtml5AttributeName* ATTR_CITE;
static nsHtml5AttributeName* ATTR_CODE;
static nsHtml5AttributeName* ATTR_BIAS;
static nsHtml5AttributeName* ATTR_COLS;
static nsHtml5AttributeName* ATTR_CLIP;
static nsHtml5AttributeName* ATTR_CHAR;
static nsHtml5AttributeName* ATTR_BASE;
static nsHtml5AttributeName* ATTR_EDGE;
static nsHtml5AttributeName* ATTR_DATA;
static nsHtml5AttributeName* ATTR_FILL;
static nsHtml5AttributeName* ATTR_FROM;
static nsHtml5AttributeName* ATTR_FORM;
static nsHtml5AttributeName* ATTR_FACE;
static nsHtml5AttributeName* ATTR_HIGH;
static nsHtml5AttributeName* ATTR_HREF;
static nsHtml5AttributeName* ATTR_OPEN;
static nsHtml5AttributeName* ATTR_ICON;
static nsHtml5AttributeName* ATTR_NAME;
static nsHtml5AttributeName* ATTR_MODE;
static nsHtml5AttributeName* ATTR_MASK;
static nsHtml5AttributeName* ATTR_LINK;
static nsHtml5AttributeName* ATTR_LANG;
static nsHtml5AttributeName* ATTR_LOOP;
static nsHtml5AttributeName* ATTR_LIST;
static nsHtml5AttributeName* ATTR_TYPE;
static nsHtml5AttributeName* ATTR_WHEN;
static nsHtml5AttributeName* ATTR_WRAP;
static nsHtml5AttributeName* ATTR_TEXT;
static nsHtml5AttributeName* ATTR_PATH;
static nsHtml5AttributeName* ATTR_PING;
static nsHtml5AttributeName* ATTR_REFX;
static nsHtml5AttributeName* ATTR_REFY;
static nsHtml5AttributeName* ATTR_SIZE;
static nsHtml5AttributeName* ATTR_SEED;
static nsHtml5AttributeName* ATTR_ROWS;
static nsHtml5AttributeName* ATTR_SPAN;
static nsHtml5AttributeName* ATTR_STEP;
static nsHtml5AttributeName* ATTR_ROLE;
static nsHtml5AttributeName* ATTR_XREF;
static nsHtml5AttributeName* ATTR_ASYNC;
static nsHtml5AttributeName* ATTR_ALINK;
static nsHtml5AttributeName* ATTR_ALIGN;
static nsHtml5AttributeName* ATTR_CLOSE;
static nsHtml5AttributeName* ATTR_COLOR;
static nsHtml5AttributeName* ATTR_CLASS;
static nsHtml5AttributeName* ATTR_CLEAR;
static nsHtml5AttributeName* ATTR_BEGIN;
static nsHtml5AttributeName* ATTR_DEPTH;
static nsHtml5AttributeName* ATTR_DEFER;
static nsHtml5AttributeName* ATTR_FENCE;
static nsHtml5AttributeName* ATTR_FRAME;
static nsHtml5AttributeName* ATTR_ISMAP;
static nsHtml5AttributeName* ATTR_ONEND;
static nsHtml5AttributeName* ATTR_INDEX;
static nsHtml5AttributeName* ATTR_ORDER;
static nsHtml5AttributeName* ATTR_OTHER;
static nsHtml5AttributeName* ATTR_ONCUT;
static nsHtml5AttributeName* ATTR_NARGS;
static nsHtml5AttributeName* ATTR_MEDIA;
static nsHtml5AttributeName* ATTR_LABEL;
static nsHtml5AttributeName* ATTR_LOCAL;
static nsHtml5AttributeName* ATTR_WIDTH;
static nsHtml5AttributeName* ATTR_TITLE;
static nsHtml5AttributeName* ATTR_VLINK;
static nsHtml5AttributeName* ATTR_VALUE;
static nsHtml5AttributeName* ATTR_SLOPE;
static nsHtml5AttributeName* ATTR_SHAPE;
static nsHtml5AttributeName* ATTR_SCOPE;
static nsHtml5AttributeName* ATTR_SCALE;
static nsHtml5AttributeName* ATTR_SPEED;
static nsHtml5AttributeName* ATTR_STYLE;
static nsHtml5AttributeName* ATTR_RULES;
static nsHtml5AttributeName* ATTR_STEMH;
static nsHtml5AttributeName* ATTR_SIZES;
static nsHtml5AttributeName* ATTR_STEMV;
static nsHtml5AttributeName* ATTR_START;
static nsHtml5AttributeName* ATTR_XMLNS;
static nsHtml5AttributeName* ATTR_ACCEPT;
static nsHtml5AttributeName* ATTR_ACCENT;
static nsHtml5AttributeName* ATTR_ASCENT;
static nsHtml5AttributeName* ATTR_ACTIVE;
static nsHtml5AttributeName* ATTR_ALTIMG;
static nsHtml5AttributeName* ATTR_ACTION;
static nsHtml5AttributeName* ATTR_BORDER;
static nsHtml5AttributeName* ATTR_CURSOR;
static nsHtml5AttributeName* ATTR_COORDS;
static nsHtml5AttributeName* ATTR_FILTER;
static nsHtml5AttributeName* ATTR_FORMAT;
static nsHtml5AttributeName* ATTR_HIDDEN;
static nsHtml5AttributeName* ATTR_HSPACE;
static nsHtml5AttributeName* ATTR_HEIGHT;
static nsHtml5AttributeName* ATTR_ONMOVE;
static nsHtml5AttributeName* ATTR_ONLOAD;
static nsHtml5AttributeName* ATTR_ONDRAG;
static nsHtml5AttributeName* ATTR_ORIGIN;
static nsHtml5AttributeName* ATTR_ONZOOM;
static nsHtml5AttributeName* ATTR_ONHELP;
static nsHtml5AttributeName* ATTR_ONSTOP;
static nsHtml5AttributeName* ATTR_ONDROP;
static nsHtml5AttributeName* ATTR_ONBLUR;
static nsHtml5AttributeName* ATTR_OBJECT;
static nsHtml5AttributeName* ATTR_OFFSET;
static nsHtml5AttributeName* ATTR_ORIENT;
static nsHtml5AttributeName* ATTR_ONCOPY;
static nsHtml5AttributeName* ATTR_NOWRAP;
static nsHtml5AttributeName* ATTR_NOHREF;
static nsHtml5AttributeName* ATTR_MACROS;
static nsHtml5AttributeName* ATTR_METHOD;
static nsHtml5AttributeName* ATTR_LOWSRC;
static nsHtml5AttributeName* ATTR_LSPACE;
static nsHtml5AttributeName* ATTR_LQUOTE;
static nsHtml5AttributeName* ATTR_USEMAP;
static nsHtml5AttributeName* ATTR_WIDTHS;
static nsHtml5AttributeName* ATTR_TARGET;
static nsHtml5AttributeName* ATTR_VALUES;
static nsHtml5AttributeName* ATTR_VALIGN;
static nsHtml5AttributeName* ATTR_VSPACE;
static nsHtml5AttributeName* ATTR_POSTER;
static nsHtml5AttributeName* ATTR_POINTS;
static nsHtml5AttributeName* ATTR_PROMPT;
static nsHtml5AttributeName* ATTR_SRCDOC;
static nsHtml5AttributeName* ATTR_SCOPED;
static nsHtml5AttributeName* ATTR_STRING;
static nsHtml5AttributeName* ATTR_SCHEME;
static nsHtml5AttributeName* ATTR_STROKE;
static nsHtml5AttributeName* ATTR_RADIUS;
static nsHtml5AttributeName* ATTR_RESULT;
static nsHtml5AttributeName* ATTR_REPEAT;
static nsHtml5AttributeName* ATTR_SRCSET;
static nsHtml5AttributeName* ATTR_RSPACE;
static nsHtml5AttributeName* ATTR_ROTATE;
static nsHtml5AttributeName* ATTR_RQUOTE;
static nsHtml5AttributeName* ATTR_ALTTEXT;
static nsHtml5AttributeName* ATTR_ARCHIVE;
static nsHtml5AttributeName* ATTR_AZIMUTH;
static nsHtml5AttributeName* ATTR_CLOSURE;
static nsHtml5AttributeName* ATTR_CHECKED;
static nsHtml5AttributeName* ATTR_CLASSID;
static nsHtml5AttributeName* ATTR_CHAROFF;
static nsHtml5AttributeName* ATTR_BGCOLOR;
static nsHtml5AttributeName* ATTR_COLSPAN;
static nsHtml5AttributeName* ATTR_CHARSET;
static nsHtml5AttributeName* ATTR_COMPACT;
static nsHtml5AttributeName* ATTR_CONTENT;
static nsHtml5AttributeName* ATTR_ENCTYPE;
static nsHtml5AttributeName* ATTR_DATASRC;
static nsHtml5AttributeName* ATTR_DATAFLD;
static nsHtml5AttributeName* ATTR_DECLARE;
static nsHtml5AttributeName* ATTR_DISPLAY;
static nsHtml5AttributeName* ATTR_DIVISOR;
static nsHtml5AttributeName* ATTR_DEFAULT;
static nsHtml5AttributeName* ATTR_DESCENT;
static nsHtml5AttributeName* ATTR_KERNING;
static nsHtml5AttributeName* ATTR_HANGING;
static nsHtml5AttributeName* ATTR_HEADERS;
static nsHtml5AttributeName* ATTR_ONPASTE;
static nsHtml5AttributeName* ATTR_ONCLICK;
static nsHtml5AttributeName* ATTR_OPTIMUM;
static nsHtml5AttributeName* ATTR_ONBEGIN;
static nsHtml5AttributeName* ATTR_ONKEYUP;
static nsHtml5AttributeName* ATTR_ONFOCUS;
static nsHtml5AttributeName* ATTR_ONERROR;
static nsHtml5AttributeName* ATTR_ONINPUT;
static nsHtml5AttributeName* ATTR_ONABORT;
static nsHtml5AttributeName* ATTR_ONSTART;
static nsHtml5AttributeName* ATTR_ONRESET;
static nsHtml5AttributeName* ATTR_OPACITY;
static nsHtml5AttributeName* ATTR_NOSHADE;
static nsHtml5AttributeName* ATTR_MINSIZE;
static nsHtml5AttributeName* ATTR_MAXSIZE;
static nsHtml5AttributeName* ATTR_LARGEOP;
static nsHtml5AttributeName* ATTR_UNICODE;
static nsHtml5AttributeName* ATTR_TARGETX;
static nsHtml5AttributeName* ATTR_TARGETY;
static nsHtml5AttributeName* ATTR_VIEWBOX;
static nsHtml5AttributeName* ATTR_VERSION;
static nsHtml5AttributeName* ATTR_PATTERN;
static nsHtml5AttributeName* ATTR_PROFILE;
static nsHtml5AttributeName* ATTR_SPACING;
static nsHtml5AttributeName* ATTR_RESTART;
static nsHtml5AttributeName* ATTR_ROWSPAN;
static nsHtml5AttributeName* ATTR_SANDBOX;
static nsHtml5AttributeName* ATTR_SUMMARY;
static nsHtml5AttributeName* ATTR_STANDBY;
static nsHtml5AttributeName* ATTR_REPLACE;
static nsHtml5AttributeName* ATTR_AUTOPLAY;
static nsHtml5AttributeName* ATTR_ADDITIVE;
static nsHtml5AttributeName* ATTR_CALCMODE;
static nsHtml5AttributeName* ATTR_CODETYPE;
static nsHtml5AttributeName* ATTR_CODEBASE;
static nsHtml5AttributeName* ATTR_CONTROLS;
static nsHtml5AttributeName* ATTR_BEVELLED;
static nsHtml5AttributeName* ATTR_BASELINE;
static nsHtml5AttributeName* ATTR_EXPONENT;
static nsHtml5AttributeName* ATTR_EDGEMODE;
static nsHtml5AttributeName* ATTR_ENCODING;
static nsHtml5AttributeName* ATTR_GLYPHREF;
static nsHtml5AttributeName* ATTR_DATETIME;
static nsHtml5AttributeName* ATTR_DISABLED;
static nsHtml5AttributeName* ATTR_FONTSIZE;
static nsHtml5AttributeName* ATTR_KEYTIMES;
static nsHtml5AttributeName* ATTR_PANOSE_1;
static nsHtml5AttributeName* ATTR_HREFLANG;
static nsHtml5AttributeName* ATTR_ONRESIZE;
static nsHtml5AttributeName* ATTR_ONCHANGE;
static nsHtml5AttributeName* ATTR_ONBOUNCE;
static nsHtml5AttributeName* ATTR_ONUNLOAD;
static nsHtml5AttributeName* ATTR_ONFINISH;
static nsHtml5AttributeName* ATTR_ONSCROLL;
static nsHtml5AttributeName* ATTR_OPERATOR;
static nsHtml5AttributeName* ATTR_OVERFLOW;
static nsHtml5AttributeName* ATTR_ONSUBMIT;
static nsHtml5AttributeName* ATTR_ONREPEAT;
static nsHtml5AttributeName* ATTR_ONSELECT;
static nsHtml5AttributeName* ATTR_NOTATION;
static nsHtml5AttributeName* ATTR_NORESIZE;
static nsHtml5AttributeName* ATTR_MANIFEST;
static nsHtml5AttributeName* ATTR_MATHSIZE;
static nsHtml5AttributeName* ATTR_MULTIPLE;
static nsHtml5AttributeName* ATTR_LONGDESC;
static nsHtml5AttributeName* ATTR_LANGUAGE;
static nsHtml5AttributeName* ATTR_TEMPLATE;
static nsHtml5AttributeName* ATTR_TABINDEX;
static nsHtml5AttributeName* ATTR_PROPERTY;
static nsHtml5AttributeName* ATTR_READONLY;
static nsHtml5AttributeName* ATTR_SELECTED;
static nsHtml5AttributeName* ATTR_ROWLINES;
static nsHtml5AttributeName* ATTR_SEAMLESS;
static nsHtml5AttributeName* ATTR_ROWALIGN;
static nsHtml5AttributeName* ATTR_STRETCHY;
static nsHtml5AttributeName* ATTR_REQUIRED;
static nsHtml5AttributeName* ATTR_XML_BASE;
static nsHtml5AttributeName* ATTR_XML_LANG;
static nsHtml5AttributeName* ATTR_X_HEIGHT;
static nsHtml5AttributeName* ATTR_ARIA_OWNS;
static nsHtml5AttributeName* ATTR_AUTOFOCUS;
static nsHtml5AttributeName* ATTR_ARIA_SORT;
static nsHtml5AttributeName* ATTR_ACCESSKEY;
static nsHtml5AttributeName* ATTR_ARIA_BUSY;
static nsHtml5AttributeName* ATTR_ARIA_GRAB;
static nsHtml5AttributeName* ATTR_AMPLITUDE;
static nsHtml5AttributeName* ATTR_ARIA_LIVE;
static nsHtml5AttributeName* ATTR_CLIP_RULE;
static nsHtml5AttributeName* ATTR_CLIP_PATH;
static nsHtml5AttributeName* ATTR_EQUALROWS;
static nsHtml5AttributeName* ATTR_ELEVATION;
static nsHtml5AttributeName* ATTR_DIRECTION;
static nsHtml5AttributeName* ATTR_DRAGGABLE;
static nsHtml5AttributeName* ATTR_FILL_RULE;
static nsHtml5AttributeName* ATTR_FONTSTYLE;
static nsHtml5AttributeName* ATTR_FONT_SIZE;
static nsHtml5AttributeName* ATTR_KEYSYSTEM;
static nsHtml5AttributeName* ATTR_KEYPOINTS;
static nsHtml5AttributeName* ATTR_HIDEFOCUS;
static nsHtml5AttributeName* ATTR_ONMESSAGE;
static nsHtml5AttributeName* ATTR_INTERCEPT;
static nsHtml5AttributeName* ATTR_ONDRAGEND;
static nsHtml5AttributeName* ATTR_ONMOVEEND;
static nsHtml5AttributeName* ATTR_ONINVALID;
static nsHtml5AttributeName* ATTR_INTEGRITY;
static nsHtml5AttributeName* ATTR_ONKEYDOWN;
static nsHtml5AttributeName* ATTR_ONFOCUSIN;
static nsHtml5AttributeName* ATTR_ONMOUSEUP;
static nsHtml5AttributeName* ATTR_INPUTMODE;
static nsHtml5AttributeName* ATTR_ONROWEXIT;
static nsHtml5AttributeName* ATTR_MATHCOLOR;
static nsHtml5AttributeName* ATTR_MASKUNITS;
static nsHtml5AttributeName* ATTR_MAXLENGTH;
static nsHtml5AttributeName* ATTR_LINEBREAK;
static nsHtml5AttributeName* ATTR_TRANSFORM;
static nsHtml5AttributeName* ATTR_V_HANGING;
static nsHtml5AttributeName* ATTR_VALUETYPE;
static nsHtml5AttributeName* ATTR_POINTSATZ;
static nsHtml5AttributeName* ATTR_POINTSATX;
static nsHtml5AttributeName* ATTR_POINTSATY;
static nsHtml5AttributeName* ATTR_SYMMETRIC;
static nsHtml5AttributeName* ATTR_SCROLLING;
static nsHtml5AttributeName* ATTR_REPEATDUR;
static nsHtml5AttributeName* ATTR_SELECTION;
static nsHtml5AttributeName* ATTR_SEPARATOR;
static nsHtml5AttributeName* ATTR_XML_SPACE;
static nsHtml5AttributeName* ATTR_AUTOSUBMIT;
static nsHtml5AttributeName* ATTR_ALPHABETIC;
static nsHtml5AttributeName* ATTR_ACTIONTYPE;
static nsHtml5AttributeName* ATTR_ACCUMULATE;
static nsHtml5AttributeName* ATTR_ARIA_LEVEL;
static nsHtml5AttributeName* ATTR_COLUMNSPAN;
static nsHtml5AttributeName* ATTR_CAP_HEIGHT;
static nsHtml5AttributeName* ATTR_BACKGROUND;
static nsHtml5AttributeName* ATTR_GLYPH_NAME;
static nsHtml5AttributeName* ATTR_GROUPALIGN;
static nsHtml5AttributeName* ATTR_FONTFAMILY;
static nsHtml5AttributeName* ATTR_FONTWEIGHT;
static nsHtml5AttributeName* ATTR_FONT_STYLE;
static nsHtml5AttributeName* ATTR_KEYSPLINES;
static nsHtml5AttributeName* ATTR_HTTP_EQUIV;
static nsHtml5AttributeName* ATTR_ONACTIVATE;
static nsHtml5AttributeName* ATTR_OCCURRENCE;
static nsHtml5AttributeName* ATTR_IRRELEVANT;
static nsHtml5AttributeName* ATTR_ONDBLCLICK;
static nsHtml5AttributeName* ATTR_ONDRAGDROP;
static nsHtml5AttributeName* ATTR_ONKEYPRESS;
static nsHtml5AttributeName* ATTR_ONROWENTER;
static nsHtml5AttributeName* ATTR_ONDRAGOVER;
static nsHtml5AttributeName* ATTR_ONFOCUSOUT;
static nsHtml5AttributeName* ATTR_ONMOUSEOUT;
static nsHtml5AttributeName* ATTR_NUMOCTAVES;
static nsHtml5AttributeName* ATTR_MARKER_MID;
static nsHtml5AttributeName* ATTR_MARKER_END;
static nsHtml5AttributeName* ATTR_TEXTLENGTH;
static nsHtml5AttributeName* ATTR_VISIBILITY;
static nsHtml5AttributeName* ATTR_VIEWTARGET;
static nsHtml5AttributeName* ATTR_VERT_ADV_Y;
static nsHtml5AttributeName* ATTR_PATHLENGTH;
static nsHtml5AttributeName* ATTR_REPEAT_MAX;
static nsHtml5AttributeName* ATTR_RADIOGROUP;
static nsHtml5AttributeName* ATTR_STOP_COLOR;
static nsHtml5AttributeName* ATTR_SEPARATORS;
static nsHtml5AttributeName* ATTR_REPEAT_MIN;
static nsHtml5AttributeName* ATTR_ROWSPACING;
static nsHtml5AttributeName* ATTR_ZOOMANDPAN;
static nsHtml5AttributeName* ATTR_XLINK_TYPE;
static nsHtml5AttributeName* ATTR_XLINK_ROLE;
static nsHtml5AttributeName* ATTR_XLINK_HREF;
static nsHtml5AttributeName* ATTR_XLINK_SHOW;
static nsHtml5AttributeName* ATTR_ACCENTUNDER;
static nsHtml5AttributeName* ATTR_ARIA_SECRET;
static nsHtml5AttributeName* ATTR_ARIA_ATOMIC;
static nsHtml5AttributeName* ATTR_ARIA_HIDDEN;
static nsHtml5AttributeName* ATTR_ARIA_FLOWTO;
static nsHtml5AttributeName* ATTR_ARABIC_FORM;
static nsHtml5AttributeName* ATTR_CELLPADDING;
static nsHtml5AttributeName* ATTR_CELLSPACING;
static nsHtml5AttributeName* ATTR_COLUMNWIDTH;
static nsHtml5AttributeName* ATTR_CROSSORIGIN;
static nsHtml5AttributeName* ATTR_COLUMNALIGN;
static nsHtml5AttributeName* ATTR_COLUMNLINES;
static nsHtml5AttributeName* ATTR_CONTEXTMENU;
static nsHtml5AttributeName* ATTR_BASEPROFILE;
static nsHtml5AttributeName* ATTR_FONT_FAMILY;
static nsHtml5AttributeName* ATTR_FRAMEBORDER;
static nsHtml5AttributeName* ATTR_FILTERUNITS;
static nsHtml5AttributeName* ATTR_FLOOD_COLOR;
static nsHtml5AttributeName* ATTR_FONT_WEIGHT;
static nsHtml5AttributeName* ATTR_HORIZ_ADV_X;
static nsHtml5AttributeName* ATTR_ONDRAGLEAVE;
static nsHtml5AttributeName* ATTR_ONMOUSEMOVE;
static nsHtml5AttributeName* ATTR_ORIENTATION;
static nsHtml5AttributeName* ATTR_ONMOUSEDOWN;
static nsHtml5AttributeName* ATTR_ONMOUSEOVER;
static nsHtml5AttributeName* ATTR_ONDRAGENTER;
static nsHtml5AttributeName* ATTR_IDEOGRAPHIC;
static nsHtml5AttributeName* ATTR_ONBEFORECUT;
static nsHtml5AttributeName* ATTR_ONFORMINPUT;
static nsHtml5AttributeName* ATTR_ONDRAGSTART;
static nsHtml5AttributeName* ATTR_ONMOVESTART;
static nsHtml5AttributeName* ATTR_MARKERUNITS;
static nsHtml5AttributeName* ATTR_MATHVARIANT;
static nsHtml5AttributeName* ATTR_MARGINWIDTH;
static nsHtml5AttributeName* ATTR_MARKERWIDTH;
static nsHtml5AttributeName* ATTR_TEXT_ANCHOR;
static nsHtml5AttributeName* ATTR_TABLEVALUES;
static nsHtml5AttributeName* ATTR_SCRIPTLEVEL;
static nsHtml5AttributeName* ATTR_REPEATCOUNT;
static nsHtml5AttributeName* ATTR_STITCHTILES;
static nsHtml5AttributeName* ATTR_STARTOFFSET;
static nsHtml5AttributeName* ATTR_SCROLLDELAY;
static nsHtml5AttributeName* ATTR_XMLNS_XLINK;
static nsHtml5AttributeName* ATTR_XLINK_TITLE;
static nsHtml5AttributeName* ATTR_ARIA_INVALID;
static nsHtml5AttributeName* ATTR_ARIA_PRESSED;
static nsHtml5AttributeName* ATTR_ARIA_CHECKED;
static nsHtml5AttributeName* ATTR_AUTOCOMPLETE;
static nsHtml5AttributeName* ATTR_ARIA_SETSIZE;
static nsHtml5AttributeName* ATTR_ARIA_CHANNEL;
static nsHtml5AttributeName* ATTR_EQUALCOLUMNS;
static nsHtml5AttributeName* ATTR_DISPLAYSTYLE;
static nsHtml5AttributeName* ATTR_DATAFORMATAS;
static nsHtml5AttributeName* ATTR_FILL_OPACITY;
static nsHtml5AttributeName* ATTR_FONT_VARIANT;
static nsHtml5AttributeName* ATTR_FONT_STRETCH;
static nsHtml5AttributeName* ATTR_FRAMESPACING;
static nsHtml5AttributeName* ATTR_KERNELMATRIX;
static nsHtml5AttributeName* ATTR_ONDEACTIVATE;
static nsHtml5AttributeName* ATTR_ONROWSDELETE;
static nsHtml5AttributeName* ATTR_ONMOUSELEAVE;
static nsHtml5AttributeName* ATTR_ONFORMCHANGE;
static nsHtml5AttributeName* ATTR_ONCELLCHANGE;
static nsHtml5AttributeName* ATTR_ONMOUSEWHEEL;
static nsHtml5AttributeName* ATTR_ONMOUSEENTER;
static nsHtml5AttributeName* ATTR_ONAFTERPRINT;
static nsHtml5AttributeName* ATTR_ONBEFORECOPY;
static nsHtml5AttributeName* ATTR_MARGINHEIGHT;
static nsHtml5AttributeName* ATTR_MARKERHEIGHT;
static nsHtml5AttributeName* ATTR_MARKER_START;
static nsHtml5AttributeName* ATTR_MATHEMATICAL;
static nsHtml5AttributeName* ATTR_LENGTHADJUST;
static nsHtml5AttributeName* ATTR_UNSELECTABLE;
static nsHtml5AttributeName* ATTR_UNICODE_BIDI;
static nsHtml5AttributeName* ATTR_UNITS_PER_EM;
static nsHtml5AttributeName* ATTR_WORD_SPACING;
static nsHtml5AttributeName* ATTR_WRITING_MODE;
static nsHtml5AttributeName* ATTR_V_ALPHABETIC;
static nsHtml5AttributeName* ATTR_PATTERNUNITS;
static nsHtml5AttributeName* ATTR_SPREADMETHOD;
static nsHtml5AttributeName* ATTR_SURFACESCALE;
static nsHtml5AttributeName* ATTR_STROKE_WIDTH;
static nsHtml5AttributeName* ATTR_REPEAT_START;
static nsHtml5AttributeName* ATTR_STDDEVIATION;
static nsHtml5AttributeName* ATTR_STOP_OPACITY;
static nsHtml5AttributeName* ATTR_ARIA_CONTROLS;
static nsHtml5AttributeName* ATTR_ARIA_HASPOPUP;
static nsHtml5AttributeName* ATTR_ACCENT_HEIGHT;
static nsHtml5AttributeName* ATTR_ARIA_VALUENOW;
static nsHtml5AttributeName* ATTR_ARIA_RELEVANT;
static nsHtml5AttributeName* ATTR_ARIA_POSINSET;
static nsHtml5AttributeName* ATTR_ARIA_VALUEMAX;
static nsHtml5AttributeName* ATTR_ARIA_READONLY;
static nsHtml5AttributeName* ATTR_ARIA_SELECTED;
static nsHtml5AttributeName* ATTR_ARIA_REQUIRED;
static nsHtml5AttributeName* ATTR_ARIA_EXPANDED;
static nsHtml5AttributeName* ATTR_ARIA_DISABLED;
static nsHtml5AttributeName* ATTR_ATTRIBUTETYPE;
static nsHtml5AttributeName* ATTR_ATTRIBUTENAME;
static nsHtml5AttributeName* ATTR_ARIA_DATATYPE;
static nsHtml5AttributeName* ATTR_ARIA_VALUEMIN;
static nsHtml5AttributeName* ATTR_BASEFREQUENCY;
static nsHtml5AttributeName* ATTR_COLUMNSPACING;
static nsHtml5AttributeName* ATTR_COLOR_PROFILE;
static nsHtml5AttributeName* ATTR_CLIPPATHUNITS;
static nsHtml5AttributeName* ATTR_DEFINITIONURL;
static nsHtml5AttributeName* ATTR_GRADIENTUNITS;
static nsHtml5AttributeName* ATTR_FLOOD_OPACITY;
static nsHtml5AttributeName* ATTR_ONAFTERUPDATE;
static nsHtml5AttributeName* ATTR_ONERRORUPDATE;
static nsHtml5AttributeName* ATTR_ONBEFOREPASTE;
static nsHtml5AttributeName* ATTR_ONLOSECAPTURE;
static nsHtml5AttributeName* ATTR_ONCONTEXTMENU;
static nsHtml5AttributeName* ATTR_ONSELECTSTART;
static nsHtml5AttributeName* ATTR_ONBEFOREPRINT;
static nsHtml5AttributeName* ATTR_MOVABLELIMITS;
static nsHtml5AttributeName* ATTR_LINETHICKNESS;
static nsHtml5AttributeName* ATTR_UNICODE_RANGE;
static nsHtml5AttributeName* ATTR_THINMATHSPACE;
static nsHtml5AttributeName* ATTR_VERT_ORIGIN_X;
static nsHtml5AttributeName* ATTR_VERT_ORIGIN_Y;
static nsHtml5AttributeName* ATTR_V_IDEOGRAPHIC;
static nsHtml5AttributeName* ATTR_PRESERVEALPHA;
static nsHtml5AttributeName* ATTR_SCRIPTMINSIZE;
static nsHtml5AttributeName* ATTR_SPECIFICATION;
static nsHtml5AttributeName* ATTR_XLINK_ACTUATE;
static nsHtml5AttributeName* ATTR_XLINK_ARCROLE;
static nsHtml5AttributeName* ATTR_ACCEPT_CHARSET;
static nsHtml5AttributeName* ATTR_ALIGNMENTSCOPE;
static nsHtml5AttributeName* ATTR_ARIA_MULTILINE;
static nsHtml5AttributeName* ATTR_BASELINE_SHIFT;
static nsHtml5AttributeName* ATTR_HORIZ_ORIGIN_X;
static nsHtml5AttributeName* ATTR_HORIZ_ORIGIN_Y;
static nsHtml5AttributeName* ATTR_ONBEFOREUPDATE;
static nsHtml5AttributeName* ATTR_ONFILTERCHANGE;
static nsHtml5AttributeName* ATTR_ONROWSINSERTED;
static nsHtml5AttributeName* ATTR_ONBEFOREUNLOAD;
static nsHtml5AttributeName* ATTR_MATHBACKGROUND;
static nsHtml5AttributeName* ATTR_LETTER_SPACING;
static nsHtml5AttributeName* ATTR_LIGHTING_COLOR;
static nsHtml5AttributeName* ATTR_THICKMATHSPACE;
static nsHtml5AttributeName* ATTR_TEXT_RENDERING;
static nsHtml5AttributeName* ATTR_V_MATHEMATICAL;
static nsHtml5AttributeName* ATTR_POINTER_EVENTS;
static nsHtml5AttributeName* ATTR_PRIMITIVEUNITS;
static nsHtml5AttributeName* ATTR_REFERRERPOLICY;
static nsHtml5AttributeName* ATTR_SYSTEMLANGUAGE;
static nsHtml5AttributeName* ATTR_STROKE_LINECAP;
static nsHtml5AttributeName* ATTR_SUBSCRIPTSHIFT;
static nsHtml5AttributeName* ATTR_STROKE_OPACITY;
static nsHtml5AttributeName* ATTR_ARIA_DROPEFFECT;
static nsHtml5AttributeName* ATTR_ARIA_LABELLEDBY;
static nsHtml5AttributeName* ATTR_ARIA_TEMPLATEID;
static nsHtml5AttributeName* ATTR_COLOR_RENDERING;
static nsHtml5AttributeName* ATTR_CONTENTEDITABLE;
static nsHtml5AttributeName* ATTR_DIFFUSECONSTANT;
static nsHtml5AttributeName* ATTR_ONDATAAVAILABLE;
static nsHtml5AttributeName* ATTR_ONCONTROLSELECT;
static nsHtml5AttributeName* ATTR_IMAGE_RENDERING;
static nsHtml5AttributeName* ATTR_MEDIUMMATHSPACE;
static nsHtml5AttributeName* ATTR_TEXT_DECORATION;
static nsHtml5AttributeName* ATTR_SHAPE_RENDERING;
static nsHtml5AttributeName* ATTR_STROKE_LINEJOIN;
static nsHtml5AttributeName* ATTR_REPEAT_TEMPLATE;
static nsHtml5AttributeName* ATTR_ARIA_DESCRIBEDBY;
static nsHtml5AttributeName* ATTR_FONT_SIZE_ADJUST;
static nsHtml5AttributeName* ATTR_KERNELUNITLENGTH;
static nsHtml5AttributeName* ATTR_ONBEFOREACTIVATE;
static nsHtml5AttributeName* ATTR_ONPROPERTYCHANGE;
static nsHtml5AttributeName* ATTR_ONDATASETCHANGED;
static nsHtml5AttributeName* ATTR_MASKCONTENTUNITS;
static nsHtml5AttributeName* ATTR_PATTERNTRANSFORM;
static nsHtml5AttributeName* ATTR_REQUIREDFEATURES;
static nsHtml5AttributeName* ATTR_RENDERING_INTENT;
static nsHtml5AttributeName* ATTR_SPECULAREXPONENT;
static nsHtml5AttributeName* ATTR_SPECULARCONSTANT;
static nsHtml5AttributeName* ATTR_SUPERSCRIPTSHIFT;
static nsHtml5AttributeName* ATTR_STROKE_DASHARRAY;
static nsHtml5AttributeName* ATTR_XCHANNELSELECTOR;
static nsHtml5AttributeName* ATTR_YCHANNELSELECTOR;
static nsHtml5AttributeName* ATTR_ARIA_AUTOCOMPLETE;
static nsHtml5AttributeName* ATTR_ENABLE_BACKGROUND;
static nsHtml5AttributeName* ATTR_DOMINANT_BASELINE;
static nsHtml5AttributeName* ATTR_GRADIENTTRANSFORM;
static nsHtml5AttributeName* ATTR_ONBEFORDEACTIVATE;
static nsHtml5AttributeName* ATTR_ONDATASETCOMPLETE;
static nsHtml5AttributeName* ATTR_OVERLINE_POSITION;
static nsHtml5AttributeName* ATTR_ONBEFOREEDITFOCUS;
static nsHtml5AttributeName* ATTR_LIMITINGCONEANGLE;
static nsHtml5AttributeName* ATTR_VERYTHINMATHSPACE;
static nsHtml5AttributeName* ATTR_STROKE_DASHOFFSET;
static nsHtml5AttributeName* ATTR_STROKE_MITERLIMIT;
static nsHtml5AttributeName* ATTR_ALIGNMENT_BASELINE;
static nsHtml5AttributeName* ATTR_ONREADYSTATECHANGE;
static nsHtml5AttributeName* ATTR_OVERLINE_THICKNESS;
static nsHtml5AttributeName* ATTR_UNDERLINE_POSITION;
static nsHtml5AttributeName* ATTR_VERYTHICKMATHSPACE;
static nsHtml5AttributeName* ATTR_REQUIREDEXTENSIONS;
static nsHtml5AttributeName* ATTR_COLOR_INTERPOLATION;
static nsHtml5AttributeName* ATTR_UNDERLINE_THICKNESS;
static nsHtml5AttributeName* ATTR_PRESERVEASPECTRATIO;
static nsHtml5AttributeName* ATTR_PATTERNCONTENTUNITS;
static nsHtml5AttributeName* ATTR_ARIA_MULTISELECTABLE;
static nsHtml5AttributeName* ATTR_SCRIPTSIZEMULTIPLIER;
static nsHtml5AttributeName* ATTR_ARIA_ACTIVEDESCENDANT;
static nsHtml5AttributeName* ATTR_VERYVERYTHINMATHSPACE;
static nsHtml5AttributeName* ATTR_VERYVERYTHICKMATHSPACE;
static nsHtml5AttributeName* ATTR_STRIKETHROUGH_POSITION;
static nsHtml5AttributeName* ATTR_STRIKETHROUGH_THICKNESS;
static nsHtml5AttributeName* ATTR_GLYPH_ORIENTATION_VERTICAL;
static nsHtml5AttributeName* ATTR_COLOR_INTERPOLATION_FILTERS;
static nsHtml5AttributeName* ATTR_GLYPH_ORIENTATION_HORIZONTAL;
private:
static nsHtml5AttributeName** ATTRIBUTE_NAMES;
static staticJArray<int32_t,int32_t> ATTRIBUTE_HASHES;
public:
static void initializeStatics();
static void releaseStatics();
};
#define NS_HTML5ATTRIBUTE_NAME_HTML 0
#define NS_HTML5ATTRIBUTE_NAME_MATHML 1
#define NS_HTML5ATTRIBUTE_NAME_SVG 2
#endif

View file

@ -0,0 +1,33 @@
/* 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 nsHtml5ByteReadable_h
#define nsHtml5ByteReadable_h
/**
* A weak reference wrapper around a byte array.
*/
class nsHtml5ByteReadable
{
public:
nsHtml5ByteReadable(const uint8_t* aCurrent, const uint8_t* aEnd)
: current(aCurrent),
end(aEnd)
{
}
inline int32_t read() {
if (current < end) {
return *(current++);
} else {
return -1;
}
}
private:
const uint8_t* current;
const uint8_t* end;
};
#endif

View file

@ -0,0 +1,33 @@
/* 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 "nsHtml5DependentUTF16Buffer.h"
nsHtml5DependentUTF16Buffer::nsHtml5DependentUTF16Buffer(const nsAString& aToWrap)
: nsHtml5UTF16Buffer(const_cast<char16_t*> (aToWrap.BeginReading()),
aToWrap.Length())
{
MOZ_COUNT_CTOR(nsHtml5DependentUTF16Buffer);
}
nsHtml5DependentUTF16Buffer::~nsHtml5DependentUTF16Buffer()
{
MOZ_COUNT_DTOR(nsHtml5DependentUTF16Buffer);
}
already_AddRefed<nsHtml5OwningUTF16Buffer>
nsHtml5DependentUTF16Buffer::FalliblyCopyAsOwningBuffer()
{
int32_t newLength = getEnd() - getStart();
RefPtr<nsHtml5OwningUTF16Buffer> newObj =
nsHtml5OwningUTF16Buffer::FalliblyCreate(newLength);
if (!newObj) {
return nullptr;
}
newObj->setEnd(newLength);
memcpy(newObj->getBuffer(),
getBuffer() + getStart(),
newLength * sizeof(char16_t));
return newObj.forget();
}

View file

@ -0,0 +1,31 @@
/* 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 nsHtml5DependentUTF16Buffer_h
#define nsHtml5DependentUTF16Buffer_h
#include "nscore.h"
#include "nsHtml5OwningUTF16Buffer.h"
class MOZ_STACK_CLASS nsHtml5DependentUTF16Buffer : public nsHtml5UTF16Buffer
{
public:
/**
* Wraps a string without taking ownership of the buffer. aToWrap MUST NOT
* go away or be shortened while nsHtml5DependentUTF16Buffer is in use.
*/
explicit nsHtml5DependentUTF16Buffer(const nsAString& aToWrap);
~nsHtml5DependentUTF16Buffer();
/**
* Copies the currently unconsumed part of this buffer into a new
* heap-allocated nsHtml5OwningUTF16Buffer. The new object is allocated
* with a fallible allocator. If the allocation fails, nullptr is returned.
* @return heap-allocated copy or nullptr if memory allocation failed
*/
already_AddRefed<nsHtml5OwningUTF16Buffer> FalliblyCopyAsOwningBuffer();
};
#endif // nsHtml5DependentUTF16Buffer_h

View file

@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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 "nsHtml5DocumentBuilder.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsStyleLinkElement.h"
#include "nsScriptLoader.h"
#include "nsIHTMLDocument.h"
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder, nsContentSink,
mOwnedElements)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder)
NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
nsHtml5DocumentBuilder::nsHtml5DocumentBuilder(bool aRunsToCompletion)
{
mRunsToCompletion = aRunsToCompletion;
}
nsresult
nsHtml5DocumentBuilder::Init(nsIDocument* aDoc,
nsIURI* aURI,
nsISupports* aContainer,
nsIChannel* aChannel)
{
return nsContentSink::Init(aDoc, aURI, aContainer, aChannel);
}
nsHtml5DocumentBuilder::~nsHtml5DocumentBuilder()
{
}
nsresult
nsHtml5DocumentBuilder::MarkAsBroken(nsresult aReason)
{
mBroken = aReason;
return aReason;
}
void
nsHtml5DocumentBuilder::SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource)
{
if (mDocument) {
mDocument->SetDocumentCharacterSetSource(aCharsetSource);
mDocument->SetDocumentCharacterSet(aCharset);
}
}
void
nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
{
// Break out of the doc update created by Flush() to zap a runnable
// waiting to call UpdateStyleSheet without the right observer
EndDocUpdate();
if (MOZ_UNLIKELY(!mParser)) {
// EndDocUpdate ran stuff that called nsIParser::Terminate()
return;
}
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aElement));
NS_ASSERTION(ssle, "Node didn't QI to style.");
ssle->SetEnableUpdates(true);
bool willNotify;
bool isAlternate;
nsresult rv = ssle->UpdateStyleSheet(mRunsToCompletion ? nullptr : this,
&willNotify,
&isAlternate);
if (NS_SUCCEEDED(rv) && willNotify && !isAlternate && !mRunsToCompletion) {
++mPendingSheetCount;
mScriptLoader->AddParserBlockingScriptExecutionBlocker();
}
// Re-open update
BeginDocUpdate();
}
void
nsHtml5DocumentBuilder::SetDocumentMode(nsHtml5DocumentMode m)
{
nsCompatibility mode = eCompatibility_NavQuirks;
switch (m) {
case STANDARDS_MODE:
mode = eCompatibility_FullStandards;
break;
case ALMOST_STANDARDS_MODE:
mode = eCompatibility_AlmostStandards;
break;
case QUIRKS_MODE:
mode = eCompatibility_NavQuirks;
break;
}
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(mDocument);
NS_ASSERTION(htmlDocument, "Document didn't QI into HTML document.");
htmlDocument->SetCompatibilityMode(mode);
}
// nsContentSink overrides
void
nsHtml5DocumentBuilder::UpdateChildCounts()
{
// No-op
}
nsresult
nsHtml5DocumentBuilder::FlushTags()
{
return NS_OK;
}

View file

@ -0,0 +1,130 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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 nsHtml5DocumentBuilder_h
#define nsHtml5DocumentBuilder_h
#include "nsContentSink.h"
#include "nsHtml5DocumentMode.h"
#include "nsIDocument.h"
#include "nsIContent.h"
typedef nsIContent* nsIContentPtr;
enum eHtml5FlushState {
eNotFlushing = 0, // not flushing
eInFlush = 1, // the Flush() method is on the call stack
eInDocUpdate = 2, // inside an update batch on the document
eNotifying = 3 // flushing pending append notifications
};
class nsHtml5DocumentBuilder : public nsContentSink
{
public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5DocumentBuilder,
nsContentSink)
NS_DECL_ISUPPORTS_INHERITED
inline void HoldElement(already_AddRefed<nsIContent> aContent)
{
*(mOwnedElements.AppendElement()) = aContent;
}
nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
nsISupports* aContainer, nsIChannel* aChannel);
// Getters and setters for fields from nsContentSink
nsIDocument* GetDocument()
{
return mDocument;
}
nsNodeInfoManager* GetNodeInfoManager()
{
return mNodeInfoManager;
}
/**
* Marks this parser as broken and tells the stream parser (if any) to
* terminate.
*
* @return aReason for convenience
*/
virtual nsresult MarkAsBroken(nsresult aReason);
/**
* Checks if this parser is broken. Returns a non-NS_OK (i.e. non-0)
* value if broken.
*/
inline nsresult IsBroken()
{
return mBroken;
}
inline void BeginDocUpdate()
{
NS_PRECONDITION(mFlushState == eInFlush, "Tried to double-open update.");
NS_PRECONDITION(mParser, "Started update without parser.");
mFlushState = eInDocUpdate;
mDocument->BeginUpdate(UPDATE_CONTENT_MODEL);
}
inline void EndDocUpdate()
{
NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync");
if (mFlushState == eInDocUpdate) {
mFlushState = eInFlush;
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
}
}
bool IsInDocUpdate()
{
return mFlushState == eInDocUpdate;
}
void SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource);
/**
* Sets up style sheet load / parse
*/
void UpdateStyleSheet(nsIContent* aElement);
void SetDocumentMode(nsHtml5DocumentMode m);
void SetNodeInfoManager(nsNodeInfoManager* aManager)
{
mNodeInfoManager = aManager;
}
// nsContentSink methods
virtual void UpdateChildCounts() override;
virtual nsresult FlushTags() override;
protected:
explicit nsHtml5DocumentBuilder(bool aRunsToCompletion);
virtual ~nsHtml5DocumentBuilder();
protected:
AutoTArray<nsCOMPtr<nsIContent>, 32> mOwnedElements;
/**
* Non-NS_OK if this parser should refuse to process any more input.
* For example, the parser needs to be marked as broken if it drops some
* input due to a memory allocation failure. In such a case, the whole
* parser needs to be marked as broken, because some input has been lost
* and parsing more input could lead to a DOM where pieces of HTML source
* that weren't supposed to become scripts become scripts.
*
* Since NS_OK is actually 0, zeroing operator new takes care of
* initializing this.
*/
nsresult mBroken;
eHtml5FlushState mFlushState;
};
#endif // nsHtml5DocumentBuilder_h

View file

@ -0,0 +1,14 @@
/* 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 nsHtml5DocumentMode_h
#define nsHtml5DocumentMode_h
enum nsHtml5DocumentMode {
STANDARDS_MODE,
ALMOST_STANDARDS_MODE,
QUIRKS_MODE
};
#endif // nsHtml5DocumentMode_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,499 @@
/*
* Copyright (c) 2008-2014 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit ElementName.java instead and regenerate.
*/
#ifndef nsHtml5ElementName_h
#define nsHtml5ElementName_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5ElementName
{
public:
static nsHtml5ElementName* ELT_NULL_ELEMENT_NAME;
nsIAtom* name;
nsIAtom* camelCaseName;
int32_t flags;
inline int32_t getFlags()
{
return flags;
}
int32_t getGroup();
bool isCustom();
static nsHtml5ElementName* elementNameByBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner);
private:
static int32_t bufToHash(char16_t* buf, int32_t len);
nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, int32_t flags);
protected:
explicit nsHtml5ElementName(nsIAtom* name);
public:
virtual void release();
virtual ~nsHtml5ElementName();
virtual nsHtml5ElementName* cloneElementName(nsHtml5AtomTable* interner);
static nsHtml5ElementName* ELT_A;
static nsHtml5ElementName* ELT_B;
static nsHtml5ElementName* ELT_G;
static nsHtml5ElementName* ELT_I;
static nsHtml5ElementName* ELT_P;
static nsHtml5ElementName* ELT_Q;
static nsHtml5ElementName* ELT_S;
static nsHtml5ElementName* ELT_U;
static nsHtml5ElementName* ELT_BR;
static nsHtml5ElementName* ELT_CI;
static nsHtml5ElementName* ELT_CN;
static nsHtml5ElementName* ELT_DD;
static nsHtml5ElementName* ELT_DL;
static nsHtml5ElementName* ELT_DT;
static nsHtml5ElementName* ELT_EM;
static nsHtml5ElementName* ELT_EQ;
static nsHtml5ElementName* ELT_FN;
static nsHtml5ElementName* ELT_H1;
static nsHtml5ElementName* ELT_H2;
static nsHtml5ElementName* ELT_H3;
static nsHtml5ElementName* ELT_H4;
static nsHtml5ElementName* ELT_H5;
static nsHtml5ElementName* ELT_H6;
static nsHtml5ElementName* ELT_GT;
static nsHtml5ElementName* ELT_HR;
static nsHtml5ElementName* ELT_IN;
static nsHtml5ElementName* ELT_LI;
static nsHtml5ElementName* ELT_LN;
static nsHtml5ElementName* ELT_LT;
static nsHtml5ElementName* ELT_MI;
static nsHtml5ElementName* ELT_MN;
static nsHtml5ElementName* ELT_MO;
static nsHtml5ElementName* ELT_MS;
static nsHtml5ElementName* ELT_OL;
static nsHtml5ElementName* ELT_OR;
static nsHtml5ElementName* ELT_PI;
static nsHtml5ElementName* ELT_RB;
static nsHtml5ElementName* ELT_RP;
static nsHtml5ElementName* ELT_RT;
static nsHtml5ElementName* ELT_TD;
static nsHtml5ElementName* ELT_TH;
static nsHtml5ElementName* ELT_TR;
static nsHtml5ElementName* ELT_TT;
static nsHtml5ElementName* ELT_UL;
static nsHtml5ElementName* ELT_AND;
static nsHtml5ElementName* ELT_ARG;
static nsHtml5ElementName* ELT_ABS;
static nsHtml5ElementName* ELT_BIG;
static nsHtml5ElementName* ELT_BDO;
static nsHtml5ElementName* ELT_CSC;
static nsHtml5ElementName* ELT_COL;
static nsHtml5ElementName* ELT_COS;
static nsHtml5ElementName* ELT_COT;
static nsHtml5ElementName* ELT_DEL;
static nsHtml5ElementName* ELT_DFN;
static nsHtml5ElementName* ELT_DIR;
static nsHtml5ElementName* ELT_DIV;
static nsHtml5ElementName* ELT_EXP;
static nsHtml5ElementName* ELT_GCD;
static nsHtml5ElementName* ELT_GEQ;
static nsHtml5ElementName* ELT_IMG;
static nsHtml5ElementName* ELT_INS;
static nsHtml5ElementName* ELT_INT;
static nsHtml5ElementName* ELT_KBD;
static nsHtml5ElementName* ELT_LOG;
static nsHtml5ElementName* ELT_LCM;
static nsHtml5ElementName* ELT_LEQ;
static nsHtml5ElementName* ELT_MTD;
static nsHtml5ElementName* ELT_MIN;
static nsHtml5ElementName* ELT_MAP;
static nsHtml5ElementName* ELT_MTR;
static nsHtml5ElementName* ELT_MAX;
static nsHtml5ElementName* ELT_NEQ;
static nsHtml5ElementName* ELT_NOT;
static nsHtml5ElementName* ELT_NAV;
static nsHtml5ElementName* ELT_PRE;
static nsHtml5ElementName* ELT_RTC;
static nsHtml5ElementName* ELT_REM;
static nsHtml5ElementName* ELT_SUB;
static nsHtml5ElementName* ELT_SEC;
static nsHtml5ElementName* ELT_SVG;
static nsHtml5ElementName* ELT_SUM;
static nsHtml5ElementName* ELT_SIN;
static nsHtml5ElementName* ELT_SEP;
static nsHtml5ElementName* ELT_SUP;
static nsHtml5ElementName* ELT_SET;
static nsHtml5ElementName* ELT_TAN;
static nsHtml5ElementName* ELT_USE;
static nsHtml5ElementName* ELT_VAR;
static nsHtml5ElementName* ELT_WBR;
static nsHtml5ElementName* ELT_XMP;
static nsHtml5ElementName* ELT_XOR;
static nsHtml5ElementName* ELT_AREA;
static nsHtml5ElementName* ELT_ABBR;
static nsHtml5ElementName* ELT_BASE;
static nsHtml5ElementName* ELT_BVAR;
static nsHtml5ElementName* ELT_BODY;
static nsHtml5ElementName* ELT_CARD;
static nsHtml5ElementName* ELT_CODE;
static nsHtml5ElementName* ELT_CITE;
static nsHtml5ElementName* ELT_CSCH;
static nsHtml5ElementName* ELT_COSH;
static nsHtml5ElementName* ELT_COTH;
static nsHtml5ElementName* ELT_CURL;
static nsHtml5ElementName* ELT_DESC;
static nsHtml5ElementName* ELT_DIFF;
static nsHtml5ElementName* ELT_DEFS;
static nsHtml5ElementName* ELT_FORM;
static nsHtml5ElementName* ELT_FONT;
static nsHtml5ElementName* ELT_GRAD;
static nsHtml5ElementName* ELT_HEAD;
static nsHtml5ElementName* ELT_HTML;
static nsHtml5ElementName* ELT_LINE;
static nsHtml5ElementName* ELT_LINK;
static nsHtml5ElementName* ELT_LIST;
static nsHtml5ElementName* ELT_META;
static nsHtml5ElementName* ELT_MSUB;
static nsHtml5ElementName* ELT_MODE;
static nsHtml5ElementName* ELT_MATH;
static nsHtml5ElementName* ELT_MARK;
static nsHtml5ElementName* ELT_MASK;
static nsHtml5ElementName* ELT_MEAN;
static nsHtml5ElementName* ELT_MAIN;
static nsHtml5ElementName* ELT_MSUP;
static nsHtml5ElementName* ELT_MENU;
static nsHtml5ElementName* ELT_MROW;
static nsHtml5ElementName* ELT_NONE;
static nsHtml5ElementName* ELT_NOBR;
static nsHtml5ElementName* ELT_NEST;
static nsHtml5ElementName* ELT_PATH;
static nsHtml5ElementName* ELT_PLUS;
static nsHtml5ElementName* ELT_RULE;
static nsHtml5ElementName* ELT_REAL;
static nsHtml5ElementName* ELT_RELN;
static nsHtml5ElementName* ELT_RECT;
static nsHtml5ElementName* ELT_ROOT;
static nsHtml5ElementName* ELT_RUBY;
static nsHtml5ElementName* ELT_SECH;
static nsHtml5ElementName* ELT_SINH;
static nsHtml5ElementName* ELT_SPAN;
static nsHtml5ElementName* ELT_SAMP;
static nsHtml5ElementName* ELT_STOP;
static nsHtml5ElementName* ELT_SDEV;
static nsHtml5ElementName* ELT_TIME;
static nsHtml5ElementName* ELT_TRUE;
static nsHtml5ElementName* ELT_TREF;
static nsHtml5ElementName* ELT_TANH;
static nsHtml5ElementName* ELT_TEXT;
static nsHtml5ElementName* ELT_VIEW;
static nsHtml5ElementName* ELT_ASIDE;
static nsHtml5ElementName* ELT_AUDIO;
static nsHtml5ElementName* ELT_APPLY;
static nsHtml5ElementName* ELT_EMBED;
static nsHtml5ElementName* ELT_FRAME;
static nsHtml5ElementName* ELT_FALSE;
static nsHtml5ElementName* ELT_FLOOR;
static nsHtml5ElementName* ELT_GLYPH;
static nsHtml5ElementName* ELT_HKERN;
static nsHtml5ElementName* ELT_IMAGE;
static nsHtml5ElementName* ELT_IDENT;
static nsHtml5ElementName* ELT_INPUT;
static nsHtml5ElementName* ELT_LABEL;
static nsHtml5ElementName* ELT_LIMIT;
static nsHtml5ElementName* ELT_MFRAC;
static nsHtml5ElementName* ELT_MPATH;
static nsHtml5ElementName* ELT_METER;
static nsHtml5ElementName* ELT_MOVER;
static nsHtml5ElementName* ELT_MINUS;
static nsHtml5ElementName* ELT_MROOT;
static nsHtml5ElementName* ELT_MSQRT;
static nsHtml5ElementName* ELT_MTEXT;
static nsHtml5ElementName* ELT_NOTIN;
static nsHtml5ElementName* ELT_PIECE;
static nsHtml5ElementName* ELT_PARAM;
static nsHtml5ElementName* ELT_POWER;
static nsHtml5ElementName* ELT_REALS;
static nsHtml5ElementName* ELT_STYLE;
static nsHtml5ElementName* ELT_SMALL;
static nsHtml5ElementName* ELT_THEAD;
static nsHtml5ElementName* ELT_TABLE;
static nsHtml5ElementName* ELT_TITLE;
static nsHtml5ElementName* ELT_TRACK;
static nsHtml5ElementName* ELT_TSPAN;
static nsHtml5ElementName* ELT_TIMES;
static nsHtml5ElementName* ELT_TFOOT;
static nsHtml5ElementName* ELT_TBODY;
static nsHtml5ElementName* ELT_UNION;
static nsHtml5ElementName* ELT_VKERN;
static nsHtml5ElementName* ELT_VIDEO;
static nsHtml5ElementName* ELT_ARCSEC;
static nsHtml5ElementName* ELT_ARCCSC;
static nsHtml5ElementName* ELT_ARCTAN;
static nsHtml5ElementName* ELT_ARCSIN;
static nsHtml5ElementName* ELT_ARCCOS;
static nsHtml5ElementName* ELT_APPLET;
static nsHtml5ElementName* ELT_ARCCOT;
static nsHtml5ElementName* ELT_APPROX;
static nsHtml5ElementName* ELT_BUTTON;
static nsHtml5ElementName* ELT_CIRCLE;
static nsHtml5ElementName* ELT_CENTER;
static nsHtml5ElementName* ELT_CURSOR;
static nsHtml5ElementName* ELT_CANVAS;
static nsHtml5ElementName* ELT_DIVIDE;
static nsHtml5ElementName* ELT_DEGREE;
static nsHtml5ElementName* ELT_DOMAIN;
static nsHtml5ElementName* ELT_EXISTS;
static nsHtml5ElementName* ELT_FETILE;
static nsHtml5ElementName* ELT_FIGURE;
static nsHtml5ElementName* ELT_FORALL;
static nsHtml5ElementName* ELT_FILTER;
static nsHtml5ElementName* ELT_FOOTER;
static nsHtml5ElementName* ELT_HGROUP;
static nsHtml5ElementName* ELT_HEADER;
static nsHtml5ElementName* ELT_IFRAME;
static nsHtml5ElementName* ELT_KEYGEN;
static nsHtml5ElementName* ELT_LAMBDA;
static nsHtml5ElementName* ELT_LEGEND;
static nsHtml5ElementName* ELT_MSPACE;
static nsHtml5ElementName* ELT_MTABLE;
static nsHtml5ElementName* ELT_MSTYLE;
static nsHtml5ElementName* ELT_MGLYPH;
static nsHtml5ElementName* ELT_MEDIAN;
static nsHtml5ElementName* ELT_MUNDER;
static nsHtml5ElementName* ELT_MARKER;
static nsHtml5ElementName* ELT_MERROR;
static nsHtml5ElementName* ELT_MOMENT;
static nsHtml5ElementName* ELT_MATRIX;
static nsHtml5ElementName* ELT_OPTION;
static nsHtml5ElementName* ELT_OBJECT;
static nsHtml5ElementName* ELT_OUTPUT;
static nsHtml5ElementName* ELT_PRIMES;
static nsHtml5ElementName* ELT_SOURCE;
static nsHtml5ElementName* ELT_STRIKE;
static nsHtml5ElementName* ELT_STRONG;
static nsHtml5ElementName* ELT_SWITCH;
static nsHtml5ElementName* ELT_SYMBOL;
static nsHtml5ElementName* ELT_SELECT;
static nsHtml5ElementName* ELT_SUBSET;
static nsHtml5ElementName* ELT_SCRIPT;
static nsHtml5ElementName* ELT_TBREAK;
static nsHtml5ElementName* ELT_VECTOR;
static nsHtml5ElementName* ELT_ARTICLE;
static nsHtml5ElementName* ELT_ANIMATE;
static nsHtml5ElementName* ELT_ARCSECH;
static nsHtml5ElementName* ELT_ARCCSCH;
static nsHtml5ElementName* ELT_ARCTANH;
static nsHtml5ElementName* ELT_ARCSINH;
static nsHtml5ElementName* ELT_ARCCOSH;
static nsHtml5ElementName* ELT_ARCCOTH;
static nsHtml5ElementName* ELT_ACRONYM;
static nsHtml5ElementName* ELT_ADDRESS;
static nsHtml5ElementName* ELT_BGSOUND;
static nsHtml5ElementName* ELT_COMPOSE;
static nsHtml5ElementName* ELT_CEILING;
static nsHtml5ElementName* ELT_CSYMBOL;
static nsHtml5ElementName* ELT_CAPTION;
static nsHtml5ElementName* ELT_DISCARD;
static nsHtml5ElementName* ELT_DECLARE;
static nsHtml5ElementName* ELT_DETAILS;
static nsHtml5ElementName* ELT_ELLIPSE;
static nsHtml5ElementName* ELT_FEFUNCA;
static nsHtml5ElementName* ELT_FEFUNCB;
static nsHtml5ElementName* ELT_FEBLEND;
static nsHtml5ElementName* ELT_FEFLOOD;
static nsHtml5ElementName* ELT_FEIMAGE;
static nsHtml5ElementName* ELT_FEMERGE;
static nsHtml5ElementName* ELT_FEFUNCG;
static nsHtml5ElementName* ELT_FEFUNCR;
static nsHtml5ElementName* ELT_HANDLER;
static nsHtml5ElementName* ELT_INVERSE;
static nsHtml5ElementName* ELT_IMPLIES;
static nsHtml5ElementName* ELT_ISINDEX;
static nsHtml5ElementName* ELT_LOGBASE;
static nsHtml5ElementName* ELT_LISTING;
static nsHtml5ElementName* ELT_MFENCED;
static nsHtml5ElementName* ELT_MPADDED;
static nsHtml5ElementName* ELT_MARQUEE;
static nsHtml5ElementName* ELT_MACTION;
static nsHtml5ElementName* ELT_MSUBSUP;
static nsHtml5ElementName* ELT_NOEMBED;
static nsHtml5ElementName* ELT_POLYGON;
static nsHtml5ElementName* ELT_PATTERN;
static nsHtml5ElementName* ELT_PICTURE;
static nsHtml5ElementName* ELT_PRODUCT;
static nsHtml5ElementName* ELT_SETDIFF;
static nsHtml5ElementName* ELT_SECTION;
static nsHtml5ElementName* ELT_SUMMARY;
static nsHtml5ElementName* ELT_TENDSTO;
static nsHtml5ElementName* ELT_UPLIMIT;
static nsHtml5ElementName* ELT_ALTGLYPH;
static nsHtml5ElementName* ELT_BASEFONT;
static nsHtml5ElementName* ELT_CLIPPATH;
static nsHtml5ElementName* ELT_CODOMAIN;
static nsHtml5ElementName* ELT_COLGROUP;
static nsHtml5ElementName* ELT_EMPTYSET;
static nsHtml5ElementName* ELT_FACTOROF;
static nsHtml5ElementName* ELT_FIELDSET;
static nsHtml5ElementName* ELT_FRAMESET;
static nsHtml5ElementName* ELT_FEOFFSET;
static nsHtml5ElementName* ELT_GLYPHREF;
static nsHtml5ElementName* ELT_INTERVAL;
static nsHtml5ElementName* ELT_INTEGERS;
static nsHtml5ElementName* ELT_INFINITY;
static nsHtml5ElementName* ELT_LISTENER;
static nsHtml5ElementName* ELT_LOWLIMIT;
static nsHtml5ElementName* ELT_METADATA;
static nsHtml5ElementName* ELT_MENCLOSE;
static nsHtml5ElementName* ELT_MENUITEM;
static nsHtml5ElementName* ELT_MPHANTOM;
static nsHtml5ElementName* ELT_NOFRAMES;
static nsHtml5ElementName* ELT_NOSCRIPT;
static nsHtml5ElementName* ELT_OPTGROUP;
static nsHtml5ElementName* ELT_POLYLINE;
static nsHtml5ElementName* ELT_PREFETCH;
static nsHtml5ElementName* ELT_PROGRESS;
static nsHtml5ElementName* ELT_PRSUBSET;
static nsHtml5ElementName* ELT_QUOTIENT;
static nsHtml5ElementName* ELT_SELECTOR;
static nsHtml5ElementName* ELT_TEXTAREA;
static nsHtml5ElementName* ELT_TEMPLATE;
static nsHtml5ElementName* ELT_TEXTPATH;
static nsHtml5ElementName* ELT_VARIANCE;
static nsHtml5ElementName* ELT_ANIMATION;
static nsHtml5ElementName* ELT_CONJUGATE;
static nsHtml5ElementName* ELT_CONDITION;
static nsHtml5ElementName* ELT_COMPLEXES;
static nsHtml5ElementName* ELT_FONT_FACE;
static nsHtml5ElementName* ELT_FACTORIAL;
static nsHtml5ElementName* ELT_INTERSECT;
static nsHtml5ElementName* ELT_IMAGINARY;
static nsHtml5ElementName* ELT_LAPLACIAN;
static nsHtml5ElementName* ELT_MATRIXROW;
static nsHtml5ElementName* ELT_NOTSUBSET;
static nsHtml5ElementName* ELT_OTHERWISE;
static nsHtml5ElementName* ELT_PIECEWISE;
static nsHtml5ElementName* ELT_PLAINTEXT;
static nsHtml5ElementName* ELT_RATIONALS;
static nsHtml5ElementName* ELT_SEMANTICS;
static nsHtml5ElementName* ELT_TRANSPOSE;
static nsHtml5ElementName* ELT_ANNOTATION;
static nsHtml5ElementName* ELT_BLOCKQUOTE;
static nsHtml5ElementName* ELT_DIVERGENCE;
static nsHtml5ElementName* ELT_EULERGAMMA;
static nsHtml5ElementName* ELT_EQUIVALENT;
static nsHtml5ElementName* ELT_FIGCAPTION;
static nsHtml5ElementName* ELT_IMAGINARYI;
static nsHtml5ElementName* ELT_MALIGNMARK;
static nsHtml5ElementName* ELT_MUNDEROVER;
static nsHtml5ElementName* ELT_MLABELEDTR;
static nsHtml5ElementName* ELT_NOTANUMBER;
static nsHtml5ElementName* ELT_SOLIDCOLOR;
static nsHtml5ElementName* ELT_ALTGLYPHDEF;
static nsHtml5ElementName* ELT_DETERMINANT;
static nsHtml5ElementName* ELT_FEMERGENODE;
static nsHtml5ElementName* ELT_FECOMPOSITE;
static nsHtml5ElementName* ELT_FESPOTLIGHT;
static nsHtml5ElementName* ELT_MALIGNGROUP;
static nsHtml5ElementName* ELT_MPRESCRIPTS;
static nsHtml5ElementName* ELT_MOMENTABOUT;
static nsHtml5ElementName* ELT_NOTPRSUBSET;
static nsHtml5ElementName* ELT_PARTIALDIFF;
static nsHtml5ElementName* ELT_ALTGLYPHITEM;
static nsHtml5ElementName* ELT_ANIMATECOLOR;
static nsHtml5ElementName* ELT_DATATEMPLATE;
static nsHtml5ElementName* ELT_EXPONENTIALE;
static nsHtml5ElementName* ELT_FETURBULENCE;
static nsHtml5ElementName* ELT_FEPOINTLIGHT;
static nsHtml5ElementName* ELT_FEDROPSHADOW;
static nsHtml5ElementName* ELT_FEMORPHOLOGY;
static nsHtml5ElementName* ELT_OUTERPRODUCT;
static nsHtml5ElementName* ELT_ANIMATEMOTION;
static nsHtml5ElementName* ELT_COLOR_PROFILE;
static nsHtml5ElementName* ELT_FONT_FACE_SRC;
static nsHtml5ElementName* ELT_FONT_FACE_URI;
static nsHtml5ElementName* ELT_FOREIGNOBJECT;
static nsHtml5ElementName* ELT_FECOLORMATRIX;
static nsHtml5ElementName* ELT_MISSING_GLYPH;
static nsHtml5ElementName* ELT_MMULTISCRIPTS;
static nsHtml5ElementName* ELT_SCALARPRODUCT;
static nsHtml5ElementName* ELT_VECTORPRODUCT;
static nsHtml5ElementName* ELT_ANNOTATION_XML;
static nsHtml5ElementName* ELT_DEFINITION_SRC;
static nsHtml5ElementName* ELT_FONT_FACE_NAME;
static nsHtml5ElementName* ELT_FEGAUSSIANBLUR;
static nsHtml5ElementName* ELT_FEDISTANTLIGHT;
static nsHtml5ElementName* ELT_LINEARGRADIENT;
static nsHtml5ElementName* ELT_NATURALNUMBERS;
static nsHtml5ElementName* ELT_RADIALGRADIENT;
static nsHtml5ElementName* ELT_ANIMATETRANSFORM;
static nsHtml5ElementName* ELT_CARTESIANPRODUCT;
static nsHtml5ElementName* ELT_FONT_FACE_FORMAT;
static nsHtml5ElementName* ELT_FECONVOLVEMATRIX;
static nsHtml5ElementName* ELT_FEDIFFUSELIGHTING;
static nsHtml5ElementName* ELT_FEDISPLACEMENTMAP;
static nsHtml5ElementName* ELT_FESPECULARLIGHTING;
static nsHtml5ElementName* ELT_DOMAINOFAPPLICATION;
static nsHtml5ElementName* ELT_FECOMPONENTTRANSFER;
private:
static nsHtml5ElementName** ELEMENT_NAMES;
static staticJArray<int32_t,int32_t> ELEMENT_HASHES;
public:
static void initializeStatics();
static void releaseStatics();
};
#define NS_HTML5ELEMENT_NAME_GROUP_MASK 127
#define NS_HTML5ELEMENT_NAME_CUSTOM (1 << 30)
#define NS_HTML5ELEMENT_NAME_SPECIAL (1 << 29)
#define NS_HTML5ELEMENT_NAME_FOSTER_PARENTING (1 << 28)
#define NS_HTML5ELEMENT_NAME_SCOPING (1 << 27)
#define NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG (1 << 26)
#define NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML (1 << 25)
#define NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT (1 << 24)
#define NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG (1 << 23)
#endif

View file

@ -0,0 +1,802 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsHtml5Highlighter.h"
#include "nsDebug.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5AttributeName.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsHtml5ViewSourceUtils.h"
#include "mozilla/Attributes.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
// The old code had a limit of 16 tokens. 1300 is a number picked my measuring
// the size of 16 tokens on cnn.com.
#define NS_HTML5_HIGHLIGHTER_PRE_BREAK_THRESHOLD 1300
char16_t nsHtml5Highlighter::sComment[] =
{ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0 };
char16_t nsHtml5Highlighter::sCdata[] =
{ 'c', 'd', 'a', 't', 'a', 0 };
char16_t nsHtml5Highlighter::sEntity[] =
{ 'e', 'n', 't', 'i', 't', 'y', 0 };
char16_t nsHtml5Highlighter::sEndTag[] =
{ 'e', 'n', 'd', '-', 't', 'a', 'g', 0 };
char16_t nsHtml5Highlighter::sStartTag[] =
{ 's', 't', 'a', 'r', 't', '-', 't', 'a', 'g', 0 };
char16_t nsHtml5Highlighter::sAttributeName[] =
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-', 'n', 'a', 'm', 'e', 0 };
char16_t nsHtml5Highlighter::sAttributeValue[] =
{ 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', '-',
'v', 'a', 'l', 'u', 'e', 0 };
char16_t nsHtml5Highlighter::sDoctype[] =
{ 'd', 'o', 'c', 't', 'y', 'p', 'e', 0 };
char16_t nsHtml5Highlighter::sPi[] =
{ 'p', 'i', 0 };
nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
: mState(NS_HTML5TOKENIZER_DATA)
, mCStart(INT32_MAX)
, mPos(0)
, mLineNumber(1)
, mInlinesOpen(0)
, mInCharacters(false)
, mBuffer(nullptr)
, mOpSink(aOpSink)
, mCurrentRun(nullptr)
, mAmpersand(nullptr)
, mSlash(nullptr)
, mHandles(MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH))
, mHandlesUsed(0)
, mSeenBase(false)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
nsHtml5Highlighter::~nsHtml5Highlighter()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
void
nsHtml5Highlighter::Start(const nsAutoString& aTitle)
{
// Doctype
mOpQueue.AppendElement()->Init(nsGkAtoms::html, EmptyString(), EmptyString());
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
nsIContent** root = CreateElement(nsHtml5Atoms::html, nullptr, nullptr);
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
mStack.AppendElement(root);
Push(nsGkAtoms::head, nullptr);
Push(nsGkAtoms::title, nullptr);
// XUL will add the "Source of: " prefix.
uint32_t length = aTitle.Length();
if (length > INT32_MAX) {
length = INT32_MAX;
}
AppendCharacters(aTitle.get(), 0, (int32_t)length);
Pop(); // title
Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
Pop(); // link
Pop(); // head
Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
nsString* preId = new nsString(NS_LITERAL_STRING("line1"));
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId, -1);
Push(nsGkAtoms::pre, preAttrs);
StartCharacters();
mOpQueue.AppendElement()->Init(eTreeOpStartLayout);
}
int32_t
nsHtml5Highlighter::Transition(int32_t aState, bool aReconsume, int32_t aPos)
{
mPos = aPos;
switch (mState) {
case NS_HTML5TOKENIZER_SCRIPT_DATA:
case NS_HTML5TOKENIZER_RAWTEXT:
case NS_HTML5TOKENIZER_RCDATA:
case NS_HTML5TOKENIZER_DATA:
// We can transition on < and on &. Either way, we don't yet know the
// role of the token, so open a span without class.
if (aState == NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE) {
StartSpan();
// Start another span for highlighting the ampersand
StartSpan();
mAmpersand = CurrentNode();
} else {
EndCharactersAndStartMarkupRun();
}
break;
case NS_HTML5TOKENIZER_TAG_OPEN:
switch (aState) {
case NS_HTML5TOKENIZER_TAG_NAME:
StartSpan(sStartTag);
break;
case NS_HTML5TOKENIZER_DATA:
FinishTag(); // DATA
break;
case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION:
AddClass(sPi);
break;
}
break;
case NS_HTML5TOKENIZER_TAG_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
EndSpanOrA(); // NS_HTML5TOKENIZER_TAG_NAME
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
StartSpan(sAttributeName);
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
EndSpanOrA(); // NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
switch (aState) {
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
FlushCurrent();
StartA();
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
StartA();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
StartSpan();
StartSpan(); // for ampersand itself
mAmpersand = CurrentNode();
break;
default:
NS_NOTREACHED("Impossible transition.");
break;
}
break;
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
EndSpanOrA(); // end the slash highlight
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
StartSpan();
StartSpan(); // for ampersand itself
mAmpersand = CurrentNode();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE:
break;
case NS_HTML5TOKENIZER_ATTRIBUTE_NAME:
StartSpan(sAttributeName);
break;
default:
FinishTag();
break;
}
break;
// most comment states are omitted, because they don't matter to
// highlighting
case NS_HTML5TOKENIZER_COMMENT_START:
case NS_HTML5TOKENIZER_COMMENT_END:
case NS_HTML5TOKENIZER_COMMENT_END_BANG:
case NS_HTML5TOKENIZER_COMMENT_START_DASH:
case NS_HTML5TOKENIZER_BOGUS_COMMENT:
case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
if (aState == NS_HTML5TOKENIZER_DATA) {
AddClass(sComment);
FinishTag();
}
break;
// most cdata states are omitted, because they don't matter to
// highlighting
case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
if (aState == NS_HTML5TOKENIZER_DATA) {
AddClass(sCdata);
FinishTag();
}
break;
case NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE:
EndSpanOrA(); // the span for the ampersand
switch (aState) {
case NS_HTML5TOKENIZER_CONSUME_NCR:
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
break;
default:
// not actually a character reference
EndSpanOrA();
break;
}
break;
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP:
if (aState == NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL) {
break;
}
// not actually a character reference
EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL:
if (!aReconsume) {
FlushCurrent();
}
EndSpanOrA();
break;
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
switch (aState) {
case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE:
AddClass(sEntity);
FlushCurrent();
break;
case NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME:
AddClass(sEntity);
break;
}
EndSpanOrA();
break;
case NS_HTML5TOKENIZER_CLOSE_TAG_OPEN:
switch (aState) {
case NS_HTML5TOKENIZER_DATA:
FinishTag();
break;
case NS_HTML5TOKENIZER_TAG_NAME:
StartSpan(sEndTag);
break;
}
break;
case NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN:
if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
FlushCurrent();
StartSpan(); // don't know if it is "end-tag" yet :-(
break;
}
EndSpanOrA();
StartCharacters();
break;
case NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME:
switch (aState) {
case NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME:
AddClass(sEndTag);
EndSpanOrA();
break;
case NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG:
AddClass(sEndTag);
EndSpanOrA();
StartSpan(); // for highlighting the slash
mSlash = CurrentNode();
break;
case NS_HTML5TOKENIZER_DATA: // yes, as a result of emitting the token
AddClass(sEndTag);
FinishTag();
break;
default:
FinishTag();
break;
}
break;
case NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN:
if (aState == NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME) {
FlushCurrent();
StartSpan(); // don't know if it is "end-tag" yet :-(
break;
}
FinishTag();
break;
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED:
case NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH:
if (aState == NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN) {
EndCharactersAndStartMarkupRun();
}
break;
// Lots of double escape states omitted, because they don't highlight.
// Likewise, only doctype states that can emit the doctype are of
// interest. Otherwise, the transition out of bogus comment deals.
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
if (aState == NS_HTML5TOKENIZER_DATA) {
AddClass(sDoctype);
FinishTag();
}
break;
case NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK:
if (aState == NS_HTML5TOKENIZER_DATA) {
FinishTag();
}
break;
default:
break;
}
mState = aState;
return aState;
}
void
nsHtml5Highlighter::End()
{
switch (mState) {
case NS_HTML5TOKENIZER_COMMENT_END:
case NS_HTML5TOKENIZER_COMMENT_END_BANG:
case NS_HTML5TOKENIZER_COMMENT_START_DASH:
case NS_HTML5TOKENIZER_BOGUS_COMMENT:
case NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN:
AddClass(sComment);
break;
case NS_HTML5TOKENIZER_CDATA_RSQB_RSQB:
AddClass(sCdata);
break;
case NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP:
case NS_HTML5TOKENIZER_HEX_NCR_LOOP:
// XXX need tokenizer help here
break;
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER:
case NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_BOGUS_DOCTYPE:
case NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD:
case NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER:
case NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED:
case NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED:
AddClass(sDoctype);
break;
default:
break;
}
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(eTreeOpStreamEnded);
FlushOps();
}
void
nsHtml5Highlighter::SetBuffer(nsHtml5UTF16Buffer* aBuffer)
{
NS_PRECONDITION(!mBuffer, "Old buffer still here!");
mBuffer = aBuffer;
mCStart = aBuffer->getStart();
}
void
nsHtml5Highlighter::DropBuffer(int32_t aPos)
{
NS_PRECONDITION(mBuffer, "No buffer to drop!");
mPos = aPos;
FlushChars();
mBuffer = nullptr;
}
void
nsHtml5Highlighter::StartSpan()
{
FlushChars();
Push(nsGkAtoms::span, nullptr);
++mInlinesOpen;
}
void
nsHtml5Highlighter::StartSpan(const char16_t* aClass)
{
StartSpan();
AddClass(aClass);
}
void
nsHtml5Highlighter::EndSpanOrA()
{
FlushChars();
Pop();
--mInlinesOpen;
}
void
nsHtml5Highlighter::StartCharacters()
{
NS_PRECONDITION(!mInCharacters, "Already in characters!");
FlushChars();
Push(nsGkAtoms::span, nullptr);
mCurrentRun = CurrentNode();
mInCharacters = true;
}
void
nsHtml5Highlighter::EndCharactersAndStartMarkupRun()
{
NS_PRECONDITION(mInCharacters, "Not in characters!");
FlushChars();
Pop();
mInCharacters = false;
// Now start markup run
StartSpan();
mCurrentRun = CurrentNode();
}
void
nsHtml5Highlighter::StartA()
{
FlushChars();
Push(nsGkAtoms::a, nullptr);
AddClass(sAttributeValue);
++mInlinesOpen;
}
void
nsHtml5Highlighter::FinishTag()
{
while (mInlinesOpen > 1) {
EndSpanOrA();
}
FlushCurrent(); // >
EndSpanOrA(); // DATA
NS_ASSERTION(!mInlinesOpen, "mInlinesOpen got out of sync!");
StartCharacters();
}
void
nsHtml5Highlighter::FlushChars()
{
if (mCStart < mPos) {
char16_t* buf = mBuffer->getBuffer();
int32_t i = mCStart;
while (i < mPos) {
char16_t c = buf[i];
switch (c) {
case '\r':
// The input this code sees has been normalized so that there are
// CR breaks and LF breaks but no CRLF breaks. Overwrite CR with LF
// to show consistent LF line breaks to layout. It is OK to mutate
// the input data, because there are no reparses in the View Source
// case, so we won't need the original data in the buffer anymore.
buf[i] = '\n';
MOZ_FALLTHROUGH;
case '\n': {
++i;
if (mCStart < i) {
int32_t len = i - mCStart;
AppendCharacters(buf, mCStart, len);
mCStart = i;
}
++mLineNumber;
Push(nsGkAtoms::span, nullptr);
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
Pop();
break;
}
default:
++i;
break;
}
}
if (mCStart < mPos) {
int32_t len = mPos - mCStart;
AppendCharacters(buf, mCStart, len);
mCStart = mPos;
}
}
}
void
nsHtml5Highlighter::FlushCurrent()
{
mPos++;
FlushChars();
}
bool
nsHtml5Highlighter::FlushOps()
{
bool hasOps = !mOpQueue.IsEmpty();
if (hasOps) {
mOpSink->MoveOpsFrom(mOpQueue);
}
return hasOps;
}
void
nsHtml5Highlighter::MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue)
{
if (!(nsHtml5AttributeName::ATTR_HREF == aName ||
nsHtml5AttributeName::ATTR_SRC == aName ||
nsHtml5AttributeName::ATTR_ACTION == aName ||
nsHtml5AttributeName::ATTR_CITE == aName ||
nsHtml5AttributeName::ATTR_BACKGROUND == aName ||
nsHtml5AttributeName::ATTR_LONGDESC == aName ||
nsHtml5AttributeName::ATTR_XLINK_HREF == aName ||
nsHtml5AttributeName::ATTR_DEFINITIONURL == aName)) {
return;
}
AddViewSourceHref(*aValue);
}
void
nsHtml5Highlighter::CompletedNamedCharacterReference()
{
AddClass(sEntity);
}
nsIContent**
nsHtml5Highlighter::AllocateContentHandle()
{
if (mHandlesUsed == NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH) {
mOldHandles.AppendElement(Move(mHandles));
mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH);
mHandlesUsed = 0;
}
#ifdef DEBUG
mHandles[mHandlesUsed] = reinterpret_cast<nsIContent*>(uintptr_t(0xC0DEDBAD));
#endif
return &mHandles[mHandlesUsed++];
}
nsIContent**
nsHtml5Highlighter::CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent)
{
NS_PRECONDITION(aName, "Got null name.");
nsIContent** content = AllocateContentHandle();
mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
aName,
aAttributes,
content,
aIntendedParent,
true);
return content;
}
nsIContent**
nsHtml5Highlighter::CurrentNode()
{
NS_PRECONDITION(mStack.Length() >= 1, "Must have something on stack.");
return mStack[mStack.Length() - 1];
}
void
nsHtml5Highlighter::Push(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
{
NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode()); // Don't inline below!
mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
mStack.AppendElement(elt);
}
void
nsHtml5Highlighter::Pop()
{
NS_PRECONDITION(mStack.Length() >= 2, "Popping when stack too short.");
mStack.RemoveElementAt(mStack.Length() - 1);
}
void
nsHtml5Highlighter::AppendCharacters(const char16_t* aBuffer,
int32_t aStart,
int32_t aLength)
{
NS_PRECONDITION(aBuffer, "Null buffer");
char16_t* bufferCopy = new char16_t[aLength];
memcpy(bufferCopy, aBuffer + aStart, aLength * sizeof(char16_t));
mOpQueue.AppendElement()->Init(eTreeOpAppendText,
bufferCopy,
aLength,
CurrentNode());
}
void
nsHtml5Highlighter::AddClass(const char16_t* aClass)
{
mOpQueue.AppendElement()->InitAddClass(CurrentNode(), aClass);
}
void
nsHtml5Highlighter::AddViewSourceHref(const nsString& aValue)
{
char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t));
bufferCopy[aValue.Length()] = 0;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceHref,
bufferCopy,
aValue.Length(),
CurrentNode());
}
void
nsHtml5Highlighter::AddBase(const nsString& aValue)
{
if(mSeenBase) {
return;
}
mSeenBase = true;
char16_t* bufferCopy = new char16_t[aValue.Length() + 1];
memcpy(bufferCopy, aValue.get(), aValue.Length() * sizeof(char16_t));
bufferCopy[aValue.Length()] = 0;
mOpQueue.AppendElement()->Init(eTreeOpAddViewSourceBase,
bufferCopy,
aValue.Length());
}
void
nsHtml5Highlighter::AddErrorToCurrentNode(const char* aMsgId)
{
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(CurrentNode(), aMsgId);
}
void
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId)
{
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mCurrentRun, aMsgId);
}
void
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
nsIAtom* aName)
{
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mCurrentRun, aMsgId, aName);
}
void
nsHtml5Highlighter::AddErrorToCurrentRun(const char* aMsgId,
nsIAtom* aName,
nsIAtom* aOther)
{
NS_PRECONDITION(mCurrentRun, "Adding error to run without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mCurrentRun, aMsgId, aName, aOther);
}
void
nsHtml5Highlighter::AddErrorToCurrentAmpersand(const char* aMsgId)
{
NS_PRECONDITION(mAmpersand, "Adding error to ampersand without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mAmpersand, aMsgId);
}
void
nsHtml5Highlighter::AddErrorToCurrentSlash(const char* aMsgId)
{
NS_PRECONDITION(mSlash, "Adding error to slash without one!");
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->Init(mSlash, aMsgId);
}

View file

@ -0,0 +1,413 @@
/* 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 nsHtml5Highlighter_h
#define nsHtml5Highlighter_h
#include "nsCOMPtr.h"
#include "nsHtml5TreeOperation.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5TreeOperation.h"
#include "nsAHtml5TreeOpSink.h"
#define NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH 512
/**
* A state machine for generating HTML for display in View Source based on
* the transitions the tokenizer makes on the source being viewed.
*/
class nsHtml5Highlighter
{
public:
/**
* The constructor.
*
* @param aOpSink the sink for the tree ops generated by this highlighter
*/
explicit nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink);
/**
* The destructor.
*/
~nsHtml5Highlighter();
/**
* Starts the generated document.
*/
void Start(const nsAutoString& aTitle);
/**
* Report a tokenizer state transition.
*
* @param aState the state being transitioned to
* @param aReconsume whether this is a reconsuming transition
* @param aPos the tokenizer's current position into the buffer
*/
int32_t Transition(int32_t aState, bool aReconsume, int32_t aPos);
/**
* Report end of file.
*/
void End();
/**
* Set the current buffer being tokenized
*/
void SetBuffer(nsHtml5UTF16Buffer* aBuffer);
/**
* Let go of the buffer being tokenized but first, flush text from it.
*
* @param aPos the first UTF-16 code unit not to flush
*/
void DropBuffer(int32_t aPos);
/**
* Flush the tree ops into the sink.
*
* @return true if there were ops to flush
*/
bool FlushOps();
/**
* Linkify the current attribute value if the attribute name is one of
* known URL attributes. (When executing tree ops, javascript: URLs will
* not be linkified, though.)
*
* @param aName the name of the attribute
* @param aValue the value of the attribute
*/
void MaybeLinkifyAttributeValue(nsHtml5AttributeName* aName,
nsString* aValue);
/**
* Inform the highlighter that the tokenizer successfully completed a
* named character reference.
*/
void CompletedNamedCharacterReference();
/**
* Adds an error annotation to the node that's currently on top of
* mStack.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentNode(const char* aMsgId);
/**
* Adds an error annotation to the node that corresponds to the most
* recently opened markup declaration/tag span, character reference or
* run of text.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentRun(const char* aMsgId);
/**
* Adds an error annotation to the node that corresponds to the most
* recently opened markup declaration/tag span, character reference or
* run of text with one atom to use when formatting the message.
*
* @param aMsgId the id of the message in the property file
* @param aName the atom
*/
void AddErrorToCurrentRun(const char* aMsgId, nsIAtom* aName);
/**
* Adds an error annotation to the node that corresponds to the most
* recently opened markup declaration/tag span, character reference or
* run of text with two atoms to use when formatting the message.
*
* @param aMsgId the id of the message in the property file
* @param aName the first atom
* @param aOther the second atom
*/
void AddErrorToCurrentRun(const char* aMsgId,
nsIAtom* aName,
nsIAtom* aOther);
/**
* Adds an error annotation to the node that corresponds to the most
* recent potentially character reference-starting ampersand.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentAmpersand(const char* aMsgId);
/**
* Adds an error annotation to the node that corresponds to the most
* recent potentially self-closing slash.
*
* @param aMsgId the id of the message in the property file
*/
void AddErrorToCurrentSlash(const char* aMsgId);
/**
* Enqueues a tree op for adding base to the urls with the view-source:
*
* @param aValue the base URL to add
*/
void AddBase(const nsString& aValue);
private:
/**
* Starts a span with no class.
*/
void StartSpan();
/**
* Starts a <span> and sets the class attribute on it.
*
* @param aClass the class to set (MUST be a static string that does not
* need to be released!)
*/
void StartSpan(const char16_t* aClass);
/**
* End the current <span> or <a> in the highlighter output.
*/
void EndSpanOrA();
/**
* Starts a wrapper around a run of characters.
*/
void StartCharacters();
/**
* Ends a wrapper around a run of characters.
*/
void EndCharactersAndStartMarkupRun();
/**
* Starts an <a>.
*/
void StartA();
/**
* Flushes characters up to but not including the current one.
*/
void FlushChars();
/**
* Flushes characters up to and including the current one.
*/
void FlushCurrent();
/**
* Finishes highlighting a tag in the input data by closing the open
* <span> and <a> elements in the highlighter output and then starts
* another <span> for potentially highlighting characters potentially
* appearing next.
*/
void FinishTag();
/**
* Adds a class attribute to the current node.
*
* @param aClass the class to set (MUST be a static string that does not
* need to be released!)
*/
void AddClass(const char16_t* aClass);
/**
* Allocates a handle for an element.
*
* See the documentation for nsHtml5TreeBuilder::AllocateContentHandle()
* in nsHtml5TreeBuilderHSupplement.h.
*
* @return the handle
*/
nsIContent** AllocateContentHandle();
/**
* Enqueues an element creation tree operation.
*
* @param aName the name of the element
* @param aAttributes the attribute holder (ownership will be taken) or
* nullptr for no attributes
* @param aIntendedParent the intended parent node for the created element
* @return the handle for the element that will be created
*/
nsIContent** CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent);
/**
* Gets the handle for the current node. May be called only after the
* root element has been set.
*
* @return the handle for the current node
*/
nsIContent** CurrentNode();
/**
* Create an element and push it (its handle) on the stack.
*
* @param aName the name of the element
* @param aAttributes the attribute holder (ownership will be taken) or
* nullptr for no attributes
*/
void Push(nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes);
/**
* Pops the current node off the stack.
*/
void Pop();
/**
* Appends text content to the current node.
*
* @param aBuffer the buffer to copy from
* @param aStart the index of the first code unit to copy
* @param aLength the number of code units to copy
*/
void AppendCharacters(const char16_t* aBuffer,
int32_t aStart,
int32_t aLength);
/**
* Enqueues a tree op for adding an href attribute with the view-source:
* URL scheme to the current node.
*
* @param aValue the (potentially relative) URL to link to
*/
void AddViewSourceHref(const nsString& aValue);
/**
* The state we are transitioning away from.
*/
int32_t mState;
/**
* The index of the first UTF-16 code unit in mBuffer that hasn't been
* flushed yet.
*/
int32_t mCStart;
/**
* The position of the code unit in mBuffer that caused the current
* transition.
*/
int32_t mPos;
/**
* The current line number.
*/
int32_t mLineNumber;
/**
* The number of inline elements open inside the <pre> excluding the
* span potentially wrapping a run of characters.
*/
int32_t mInlinesOpen;
/**
* Whether there's a span wrapping a run of characters (excluding CDATA
* section) open.
*/
bool mInCharacters;
/**
* The current buffer being tokenized.
*/
nsHtml5UTF16Buffer* mBuffer;
/**
* The outgoing tree op queue.
*/
nsTArray<nsHtml5TreeOperation> mOpQueue;
/**
* The tree op stage for the tree op executor.
*/
nsAHtml5TreeOpSink* mOpSink;
/**
* The most recently opened markup declaration/tag or run of characters.
*/
nsIContent** mCurrentRun;
/**
* The most recent ampersand in a place where character references were
* allowed.
*/
nsIContent** mAmpersand;
/**
* The most recent slash that might become a self-closing slash.
*/
nsIContent** mSlash;
/**
* Memory for element handles.
*/
mozilla::UniquePtr<nsIContent*[]> mHandles;
/**
* Number of handles used in mHandles
*/
int32_t mHandlesUsed;
/**
* A holder for old contents of mHandles
*/
nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
/**
* The element stack.
*/
nsTArray<nsIContent**> mStack;
/**
* The string "comment"
*/
static char16_t sComment[];
/**
* The string "cdata"
*/
static char16_t sCdata[];
/**
* The string "start-tag"
*/
static char16_t sStartTag[];
/**
* The string "attribute-name"
*/
static char16_t sAttributeName[];
/**
* The string "attribute-value"
*/
static char16_t sAttributeValue[];
/**
* The string "end-tag"
*/
static char16_t sEndTag[];
/**
* The string "doctype"
*/
static char16_t sDoctype[];
/**
* The string "entity"
*/
static char16_t sEntity[];
/**
* The string "pi"
*/
static char16_t sPi[];
/**
* Whether base is already visited once.
*/
bool mSeenBase;
};
#endif // nsHtml5Highlighter_h

View file

@ -0,0 +1,269 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit HtmlAttributes.java instead and regenerate.
*/
#define nsHtml5HtmlAttributes_cpp__
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5MetaScanner.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5Portability.h"
#include "nsHtml5HtmlAttributes.h"
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))
{
MOZ_COUNT_CTOR(nsHtml5HtmlAttributes);
}
nsHtml5HtmlAttributes::~nsHtml5HtmlAttributes()
{
MOZ_COUNT_DTOR(nsHtml5HtmlAttributes);
clear(0);
}
int32_t
nsHtml5HtmlAttributes::getIndex(nsHtml5AttributeName* name)
{
for (int32_t i = 0; i < length; i++) {
if (names[i] == name) {
return i;
}
}
return -1;
}
nsString*
nsHtml5HtmlAttributes::getValue(nsHtml5AttributeName* name)
{
int32_t index = getIndex(name);
if (index == -1) {
return nullptr;
} else {
return getValueNoBoundsCheck(index);
}
}
int32_t
nsHtml5HtmlAttributes::getLength()
{
return length;
}
nsIAtom*
nsHtml5HtmlAttributes::getLocalNameNoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
return names[index]->getLocal(mode);
}
int32_t
nsHtml5HtmlAttributes::getURINoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
return names[index]->getUri(mode);
}
nsIAtom*
nsHtml5HtmlAttributes::getPrefixNoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
return names[index]->getPrefix(mode);
}
nsString*
nsHtml5HtmlAttributes::getValueNoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
return values[index];
}
nsHtml5AttributeName*
nsHtml5HtmlAttributes::getAttributeNameNoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
return names[index];
}
int32_t
nsHtml5HtmlAttributes::getLineNoBoundsCheck(int32_t index)
{
MOZ_ASSERT(index < length && index >= 0, "Index out of bounds");
return lines[index];
}
void
nsHtml5HtmlAttributes::addAttribute(nsHtml5AttributeName* name, nsString* 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);
nsHtml5ArrayCopy::arraycopy(values, newValues, values.length);
values = newValues;
jArray<int32_t,int32_t> newLines = jArray<int32_t,int32_t>::newJArray(newLen);
nsHtml5ArrayCopy::arraycopy(lines, newLines, lines.length);
lines = newLines;
}
names[length] = name;
values[length] = value;
lines[length] = line;
length++;
}
void
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] = nullptr;
}
length = 0;
mode = m;
}
void
nsHtml5HtmlAttributes::releaseValue(int32_t i)
{
nsHtml5Portability::releaseString(values[i]);
}
void
nsHtml5HtmlAttributes::clearWithoutReleasingContents()
{
for (int32_t i = 0; i < length; i++) {
names[i] = nullptr;
values[i] = nullptr;
}
length = 0;
}
bool
nsHtml5HtmlAttributes::contains(nsHtml5AttributeName* name)
{
for (int32_t i = 0; i < length; i++) {
if (name->equalsAnother(names[i])) {
return true;
}
}
return false;
}
void
nsHtml5HtmlAttributes::adjustForMath()
{
mode = NS_HTML5ATTRIBUTE_NAME_MATHML;
}
void
nsHtml5HtmlAttributes::adjustForSvg()
{
mode = NS_HTML5ATTRIBUTE_NAME_SVG;
}
nsHtml5HtmlAttributes*
nsHtml5HtmlAttributes::cloneAttributes(nsHtml5AtomTable* interner)
{
MOZ_ASSERT((!length) || !mode || mode == 3);
nsHtml5HtmlAttributes* clone = new nsHtml5HtmlAttributes(0);
for (int32_t i = 0; i < length; i++) {
clone->addAttribute(names[i]->cloneAttributeName(interner), nsHtml5Portability::newStringFromString(values[i]), lines[i]);
}
return clone;
}
bool
nsHtml5HtmlAttributes::equalsAnother(nsHtml5HtmlAttributes* other)
{
MOZ_ASSERT(!mode || mode == 3, "Trying to compare attributes in foreign content.");
int32_t otherLength = other->getLength();
if (length != otherLength) {
return false;
}
for (int32_t i = 0; i < length; i++) {
bool found = false;
nsIAtom* ownLocal = names[i]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML);
for (int32_t j = 0; j < otherLength; j++) {
if (ownLocal == other->names[j]->getLocal(NS_HTML5ATTRIBUTE_NAME_HTML)) {
found = true;
if (!nsHtml5Portability::stringEqualsString(values[i], other->values[j])) {
return false;
}
}
}
if (!found) {
return false;
}
}
return true;
}
void
nsHtml5HtmlAttributes::initializeStatics()
{
EMPTY_ATTRIBUTES = new nsHtml5HtmlAttributes(NS_HTML5ATTRIBUTE_NAME_HTML);
}
void
nsHtml5HtmlAttributes::releaseStatics()
{
delete EMPTY_ATTRIBUTES;
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit HtmlAttributes.java instead and regenerate.
*/
#ifndef nsHtml5HtmlAttributes_h
#define nsHtml5HtmlAttributes_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5HtmlAttributes
{
public:
static nsHtml5HtmlAttributes* EMPTY_ATTRIBUTES;
private:
int32_t mode;
int32_t length;
autoJArray<nsHtml5AttributeName*,int32_t> names;
autoJArray<nsString*,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);
int32_t getLength();
nsIAtom* getLocalNameNoBoundsCheck(int32_t index);
int32_t getURINoBoundsCheck(int32_t index);
nsIAtom* getPrefixNoBoundsCheck(int32_t index);
nsString* 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 clear(int32_t m);
void releaseValue(int32_t i);
void clearWithoutReleasingContents();
bool contains(nsHtml5AttributeName* name);
void adjustForMath();
void adjustForSvg();
nsHtml5HtmlAttributes* cloneAttributes(nsHtml5AtomTable* interner);
bool equalsAnother(nsHtml5HtmlAttributes* other);
static void initializeStatics();
static void releaseStatics();
};
#endif

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef nsHtml5Macros_h
#define nsHtml5Macros_h
#define NS_HTML5_CONTINUE(target) \
goto target
#define NS_HTML5_BREAK(target) \
goto target ## _end
#endif /* nsHtml5Macros_h */

View file

@ -0,0 +1,812 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2015 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit MetaScanner.java instead and regenerate.
*/
#define nsHtml5MetaScanner_cpp__
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5Portability.h"
#include "nsHtml5MetaScanner.h"
static char16_t const CHARSET_DATA[] = { 'h', 'a', 'r', 's', 'e', 't' };
staticJArray<char16_t,int32_t> nsHtml5MetaScanner::CHARSET = { CHARSET_DATA, MOZ_ARRAY_LENGTH(CHARSET_DATA) };
static char16_t const CONTENT_DATA[] = { 'o', 'n', 't', 'e', 'n', 't' };
staticJArray<char16_t,int32_t> nsHtml5MetaScanner::CONTENT = { CONTENT_DATA, MOZ_ARRAY_LENGTH(CONTENT_DATA) };
static char16_t const HTTP_EQUIV_DATA[] = { 't', 't', 'p', '-', 'e', 'q', 'u', 'i', 'v' };
staticJArray<char16_t,int32_t> nsHtml5MetaScanner::HTTP_EQUIV = { HTTP_EQUIV_DATA, MOZ_ARRAY_LENGTH(HTTP_EQUIV_DATA) };
static char16_t const CONTENT_TYPE_DATA[] = { 'c', 'o', 'n', 't', 'e', 'n', 't', '-', 't', 'y', 'p', 'e' };
staticJArray<char16_t,int32_t> nsHtml5MetaScanner::CONTENT_TYPE = { CONTENT_TYPE_DATA, MOZ_ARRAY_LENGTH(CONTENT_TYPE_DATA) };
nsHtml5MetaScanner::nsHtml5MetaScanner(nsHtml5TreeBuilder* tb)
: readable(nullptr),
metaState(NS_HTML5META_SCANNER_NO),
contentIndex(INT32_MAX),
charsetIndex(INT32_MAX),
httpEquivIndex(INT32_MAX),
contentTypeIndex(INT32_MAX),
stateSave(NS_HTML5META_SCANNER_DATA),
strBufLen(0),
strBuf(jArray<char16_t,int32_t>::newJArray(36)),
content(nullptr),
charset(nullptr),
httpEquivState(NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN),
treeBuilder(tb)
{
MOZ_COUNT_CTOR(nsHtml5MetaScanner);
}
nsHtml5MetaScanner::~nsHtml5MetaScanner()
{
MOZ_COUNT_DTOR(nsHtml5MetaScanner);
nsHtml5Portability::releaseString(content);
nsHtml5Portability::releaseString(charset);
}
void
nsHtml5MetaScanner::stateLoop(int32_t state)
{
int32_t c = -1;
bool reconsume = false;
stateloop: for (; ; ) {
switch(state) {
case NS_HTML5META_SCANNER_DATA: {
for (; ; ) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '<': {
state = NS_HTML5META_SCANNER_TAG_OPEN;
NS_HTML5_BREAK(dataloop);
}
default: {
continue;
}
}
}
dataloop_end: ;
}
case NS_HTML5META_SCANNER_TAG_OPEN: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case 'm':
case 'M': {
metaState = NS_HTML5META_SCANNER_M;
state = NS_HTML5META_SCANNER_TAG_NAME;
NS_HTML5_BREAK(tagopenloop);
}
case '!': {
state = NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN;
NS_HTML5_CONTINUE(stateloop);
}
case '\?':
case '/': {
state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
metaState = NS_HTML5META_SCANNER_NO;
state = NS_HTML5META_SCANNER_TAG_NAME;
NS_HTML5_BREAK(tagopenloop);
}
state = NS_HTML5META_SCANNER_DATA;
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
}
}
}
tagopenloop_end: ;
}
case NS_HTML5META_SCANNER_TAG_NAME: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
NS_HTML5_BREAK(tagnameloop);
}
case '/': {
state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
case 'e':
case 'E': {
if (metaState == NS_HTML5META_SCANNER_M) {
metaState = NS_HTML5META_SCANNER_E;
} else {
metaState = NS_HTML5META_SCANNER_NO;
}
continue;
}
case 't':
case 'T': {
if (metaState == NS_HTML5META_SCANNER_E) {
metaState = NS_HTML5META_SCANNER_T;
} else {
metaState = NS_HTML5META_SCANNER_NO;
}
continue;
}
case 'a':
case 'A': {
if (metaState == NS_HTML5META_SCANNER_T) {
metaState = NS_HTML5META_SCANNER_A;
} else {
metaState = NS_HTML5META_SCANNER_NO;
}
continue;
}
default: {
metaState = NS_HTML5META_SCANNER_NO;
continue;
}
}
}
tagnameloop_end: ;
}
case NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME: {
for (; ; ) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
continue;
}
case '/': {
state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
case 'c':
case 'C': {
contentIndex = 0;
charsetIndex = 0;
httpEquivIndex = INT32_MAX;
contentTypeIndex = INT32_MAX;
state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
NS_HTML5_BREAK(beforeattributenameloop);
}
case 'h':
case 'H': {
contentIndex = INT32_MAX;
charsetIndex = INT32_MAX;
httpEquivIndex = 0;
contentTypeIndex = INT32_MAX;
state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
NS_HTML5_BREAK(beforeattributenameloop);
}
default: {
contentIndex = INT32_MAX;
charsetIndex = INT32_MAX;
httpEquivIndex = INT32_MAX;
contentTypeIndex = INT32_MAX;
state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
NS_HTML5_BREAK(beforeattributenameloop);
}
}
}
beforeattributenameloop_end: ;
}
case NS_HTML5META_SCANNER_ATTRIBUTE_NAME: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME;
NS_HTML5_CONTINUE(stateloop);
}
case '/': {
state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
NS_HTML5_CONTINUE(stateloop);
}
case '=': {
strBufLen = 0;
contentTypeIndex = 0;
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE;
NS_HTML5_BREAK(attributenameloop);
}
case '>': {
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
if (metaState == NS_HTML5META_SCANNER_A) {
if (c >= 'A' && c <= 'Z') {
c += 0x20;
}
if (contentIndex < CONTENT.length && c == CONTENT[contentIndex]) {
++contentIndex;
} else {
contentIndex = INT32_MAX;
}
if (charsetIndex < CHARSET.length && c == CHARSET[charsetIndex]) {
++charsetIndex;
} else {
charsetIndex = INT32_MAX;
}
if (httpEquivIndex < HTTP_EQUIV.length && c == HTTP_EQUIV[httpEquivIndex]) {
++httpEquivIndex;
} else {
httpEquivIndex = INT32_MAX;
}
}
continue;
}
}
}
attributenameloop_end: ;
}
case NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
continue;
}
case '\"': {
state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
NS_HTML5_BREAK(beforeattributevalueloop);
}
case '\'': {
state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
handleCharInAttributeValue(c);
state = NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED;
NS_HTML5_CONTINUE(stateloop);
}
}
}
beforeattributevalueloop_end: ;
}
case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
for (; ; ) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '\"': {
handleAttributeValue();
state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED;
NS_HTML5_BREAK(attributevaluedoublequotedloop);
}
default: {
handleCharInAttributeValue(c);
continue;
}
}
}
attributevaluedoublequotedloop_end: ;
}
case NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
NS_HTML5_CONTINUE(stateloop);
}
case '/': {
state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
NS_HTML5_BREAK(afterattributevaluequotedloop);
}
case '>': {
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
}
}
}
afterattributevaluequotedloop_end: ;
}
case NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG: {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '>': {
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
}
}
}
case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED: {
for (; ; ) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
handleAttributeValue();
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
handleAttributeValue();
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
handleCharInAttributeValue(c);
continue;
}
}
}
}
case NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case ' ':
case '\t':
case '\n':
case '\f': {
continue;
}
case '/': {
handleAttributeValue();
state = NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG;
NS_HTML5_CONTINUE(stateloop);
}
case '=': {
strBufLen = 0;
contentTypeIndex = 0;
state = NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
handleAttributeValue();
if (handleTag()) {
NS_HTML5_BREAK(stateloop);
}
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
case 'c':
case 'C': {
contentIndex = 0;
charsetIndex = 0;
state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
NS_HTML5_CONTINUE(stateloop);
}
default: {
contentIndex = INT32_MAX;
charsetIndex = INT32_MAX;
state = NS_HTML5META_SCANNER_ATTRIBUTE_NAME;
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '-': {
state = NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN;
NS_HTML5_BREAK(markupdeclarationopenloop);
}
default: {
state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
}
}
}
markupdeclarationopenloop_end: ;
}
case NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '-': {
state = NS_HTML5META_SCANNER_COMMENT_START;
NS_HTML5_BREAK(markupdeclarationhyphenloop);
}
default: {
state = NS_HTML5META_SCANNER_SCAN_UNTIL_GT;
reconsume = true;
NS_HTML5_CONTINUE(stateloop);
}
}
}
markupdeclarationhyphenloop_end: ;
}
case NS_HTML5META_SCANNER_COMMENT_START: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '-': {
state = NS_HTML5META_SCANNER_COMMENT_START_DASH;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
state = NS_HTML5META_SCANNER_COMMENT;
NS_HTML5_BREAK(commentstartloop);
}
}
}
commentstartloop_end: ;
}
case NS_HTML5META_SCANNER_COMMENT: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '-': {
state = NS_HTML5META_SCANNER_COMMENT_END_DASH;
NS_HTML5_BREAK(commentloop);
}
default: {
continue;
}
}
}
commentloop_end: ;
}
case NS_HTML5META_SCANNER_COMMENT_END_DASH: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '-': {
state = NS_HTML5META_SCANNER_COMMENT_END;
NS_HTML5_BREAK(commentenddashloop);
}
default: {
state = NS_HTML5META_SCANNER_COMMENT;
NS_HTML5_CONTINUE(stateloop);
}
}
}
commentenddashloop_end: ;
}
case NS_HTML5META_SCANNER_COMMENT_END: {
for (; ; ) {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '>': {
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
case '-': {
continue;
}
default: {
state = NS_HTML5META_SCANNER_COMMENT;
NS_HTML5_CONTINUE(stateloop);
}
}
}
}
case NS_HTML5META_SCANNER_COMMENT_START_DASH: {
c = read();
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '-': {
state = NS_HTML5META_SCANNER_COMMENT_END;
NS_HTML5_CONTINUE(stateloop);
}
case '>': {
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
state = NS_HTML5META_SCANNER_COMMENT;
NS_HTML5_CONTINUE(stateloop);
}
}
}
case NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
for (; ; ) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '\'': {
handleAttributeValue();
state = NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED;
NS_HTML5_CONTINUE(stateloop);
}
default: {
handleCharInAttributeValue(c);
continue;
}
}
}
}
case NS_HTML5META_SCANNER_SCAN_UNTIL_GT: {
for (; ; ) {
if (reconsume) {
reconsume = false;
} else {
c = read();
}
switch(c) {
case -1: {
NS_HTML5_BREAK(stateloop);
}
case '>': {
state = NS_HTML5META_SCANNER_DATA;
NS_HTML5_CONTINUE(stateloop);
}
default: {
continue;
}
}
}
}
}
}
stateloop_end: ;
stateSave = state;
}
void
nsHtml5MetaScanner::handleCharInAttributeValue(int32_t c)
{
if (metaState == NS_HTML5META_SCANNER_A) {
if (contentIndex == CONTENT.length || charsetIndex == CHARSET.length) {
addToBuffer(c);
} else if (httpEquivIndex == HTTP_EQUIV.length) {
if (contentTypeIndex < CONTENT_TYPE.length && toAsciiLowerCase(c) == CONTENT_TYPE[contentTypeIndex]) {
++contentTypeIndex;
} else {
contentTypeIndex = INT32_MAX;
}
}
}
}
void
nsHtml5MetaScanner::addToBuffer(int32_t c)
{
if (strBufLen == strBuf.length) {
jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newJArray(strBuf.length + (strBuf.length << 1));
nsHtml5ArrayCopy::arraycopy(strBuf, newBuf, strBuf.length);
strBuf = newBuf;
}
strBuf[strBufLen++] = (char16_t) c;
}
void
nsHtml5MetaScanner::handleAttributeValue()
{
if (metaState != NS_HTML5META_SCANNER_A) {
return;
}
if (contentIndex == CONTENT.length && !content) {
content = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, treeBuilder);
return;
}
if (charsetIndex == CHARSET.length && !charset) {
charset = nsHtml5Portability::newStringFromBuffer(strBuf, 0, strBufLen, treeBuilder);
return;
}
if (httpEquivIndex == HTTP_EQUIV.length && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN) {
httpEquivState = (contentTypeIndex == CONTENT_TYPE.length) ? NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE : NS_HTML5META_SCANNER_HTTP_EQUIV_OTHER;
return;
}
}
bool
nsHtml5MetaScanner::handleTag()
{
bool stop = handleTagInner();
nsHtml5Portability::releaseString(content);
content = nullptr;
nsHtml5Portability::releaseString(charset);
charset = nullptr;
httpEquivState = NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN;
return stop;
}
bool
nsHtml5MetaScanner::handleTagInner()
{
if (!!charset && tryCharset(charset)) {
return true;
}
if (!!content && httpEquivState == NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE) {
nsString* extract = nsHtml5TreeBuilder::extractCharsetFromContent(content, treeBuilder);
if (!extract) {
return false;
}
bool success = tryCharset(extract);
nsHtml5Portability::releaseString(extract);
return success;
}
return false;
}
void
nsHtml5MetaScanner::initializeStatics()
{
}
void
nsHtml5MetaScanner::releaseStatics()
{
}
#include "nsHtml5MetaScannerCppSupplement.h"

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2008-2015 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit MetaScanner.java instead and regenerate.
*/
#ifndef nsHtml5MetaScanner_h
#define nsHtml5MetaScanner_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5MetaScanner
{
private:
static staticJArray<char16_t,int32_t> CHARSET;
static staticJArray<char16_t,int32_t> CONTENT;
static staticJArray<char16_t,int32_t> HTTP_EQUIV;
static staticJArray<char16_t,int32_t> CONTENT_TYPE;
protected:
nsHtml5ByteReadable* readable;
private:
int32_t metaState;
int32_t contentIndex;
int32_t charsetIndex;
int32_t httpEquivIndex;
int32_t contentTypeIndex;
protected:
int32_t stateSave;
private:
int32_t strBufLen;
autoJArray<char16_t,int32_t> strBuf;
nsString* content;
nsString* charset;
int32_t httpEquivState;
nsHtml5TreeBuilder* treeBuilder;
public:
explicit nsHtml5MetaScanner(nsHtml5TreeBuilder* tb);
~nsHtml5MetaScanner();
protected:
void stateLoop(int32_t state);
private:
void handleCharInAttributeValue(int32_t c);
inline int32_t toAsciiLowerCase(int32_t c)
{
if (c >= 'A' && c <= 'Z') {
return c + 0x20;
}
return c;
}
void addToBuffer(int32_t c);
void handleAttributeValue();
bool handleTag();
bool handleTagInner();
protected:
bool tryCharset(nsString* encoding);
public:
static void initializeStatics();
static void releaseStatics();
#include "nsHtml5MetaScannerHSupplement.h"
};
#define NS_HTML5META_SCANNER_NO 0
#define NS_HTML5META_SCANNER_M 1
#define NS_HTML5META_SCANNER_E 2
#define NS_HTML5META_SCANNER_T 3
#define NS_HTML5META_SCANNER_A 4
#define NS_HTML5META_SCANNER_DATA 0
#define NS_HTML5META_SCANNER_TAG_OPEN 1
#define NS_HTML5META_SCANNER_SCAN_UNTIL_GT 2
#define NS_HTML5META_SCANNER_TAG_NAME 3
#define NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_NAME 4
#define NS_HTML5META_SCANNER_ATTRIBUTE_NAME 5
#define NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_NAME 6
#define NS_HTML5META_SCANNER_BEFORE_ATTRIBUTE_VALUE 7
#define NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_DOUBLE_QUOTED 8
#define NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_SINGLE_QUOTED 9
#define NS_HTML5META_SCANNER_ATTRIBUTE_VALUE_UNQUOTED 10
#define NS_HTML5META_SCANNER_AFTER_ATTRIBUTE_VALUE_QUOTED 11
#define NS_HTML5META_SCANNER_MARKUP_DECLARATION_OPEN 13
#define NS_HTML5META_SCANNER_MARKUP_DECLARATION_HYPHEN 14
#define NS_HTML5META_SCANNER_COMMENT_START 15
#define NS_HTML5META_SCANNER_COMMENT_START_DASH 16
#define NS_HTML5META_SCANNER_COMMENT 17
#define NS_HTML5META_SCANNER_COMMENT_END_DASH 18
#define NS_HTML5META_SCANNER_COMMENT_END 19
#define NS_HTML5META_SCANNER_SELF_CLOSING_START_TAG 20
#define NS_HTML5META_SCANNER_HTTP_EQUIV_NOT_SEEN 0
#define NS_HTML5META_SCANNER_HTTP_EQUIV_CONTENT_TYPE 1
#define NS_HTML5META_SCANNER_HTTP_EQUIV_OTHER 2
#endif

View file

@ -0,0 +1,45 @@
/* 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 "nsEncoderDecoderUtils.h"
#include "nsISupportsImpl.h"
#include "mozilla/dom/EncodingUtils.h"
using mozilla::dom::EncodingUtils;
void
nsHtml5MetaScanner::sniff(nsHtml5ByteReadable* bytes, nsACString& charset)
{
readable = bytes;
stateLoop(stateSave);
readable = nullptr;
charset.Assign(mCharset);
}
bool
nsHtml5MetaScanner::tryCharset(nsString* 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);
nsAutoCString encoding;
if (!EncodingUtils::FindEncodingForLabel(label, encoding)) {
return false;
}
if (encoding.EqualsLiteral("UTF-16BE") ||
encoding.EqualsLiteral("UTF-16LE")) {
mCharset.AssignLiteral("UTF-8");
return true;
}
if (encoding.EqualsLiteral("x-user-defined")) {
// WebKit/Blink hack for Indian and Armenian legacy sites
mCharset.AssignLiteral("windows-1252");
return true;
}
mCharset.Assign(encoding);
return true;
}

View file

@ -0,0 +1,12 @@
/* 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/. */
private:
nsCString mCharset;
inline int32_t read()
{
return readable->read();
}
public:
void sniff(nsHtml5ByteReadable* bytes, nsACString& charset);

View file

@ -0,0 +1,137 @@
/* 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 "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsHtml5NamedCharacters.h"
#include "nsHtml5Portability.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5Module.h"
#include "nsIObserverService.h"
#include "nsIServiceManager.h"
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
#include "mozilla/Attributes.h"
using namespace mozilla;
// static
bool nsHtml5Module::sOffMainThread = true;
nsIThread* nsHtml5Module::sStreamParserThread = nullptr;
nsIThread* nsHtml5Module::sMainThread = nullptr;
// static
void
nsHtml5Module::InitializeStatics()
{
Preferences::AddBoolVarCache(&sOffMainThread, "html5.offmainthread");
nsHtml5AttributeName::initializeStatics();
nsHtml5ElementName::initializeStatics();
nsHtml5HtmlAttributes::initializeStatics();
nsHtml5NamedCharacters::initializeStatics();
nsHtml5Portability::initializeStatics();
nsHtml5StackNode::initializeStatics();
nsHtml5Tokenizer::initializeStatics();
nsHtml5TreeBuilder::initializeStatics();
nsHtml5UTF16Buffer::initializeStatics();
nsHtml5StreamParser::InitializeStatics();
nsHtml5TreeOpExecutor::InitializeStatics();
#ifdef DEBUG
sNsHtml5ModuleInitialized = true;
#endif
}
// static
void
nsHtml5Module::ReleaseStatics()
{
#ifdef DEBUG
sNsHtml5ModuleInitialized = false;
#endif
nsHtml5AttributeName::releaseStatics();
nsHtml5ElementName::releaseStatics();
nsHtml5HtmlAttributes::releaseStatics();
nsHtml5NamedCharacters::releaseStatics();
nsHtml5Portability::releaseStatics();
nsHtml5StackNode::releaseStatics();
nsHtml5Tokenizer::releaseStatics();
nsHtml5TreeBuilder::releaseStatics();
nsHtml5UTF16Buffer::releaseStatics();
NS_IF_RELEASE(sStreamParserThread);
NS_IF_RELEASE(sMainThread);
}
// static
already_AddRefed<nsIParser>
nsHtml5Module::NewHtml5Parser()
{
MOZ_ASSERT(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized.");
nsCOMPtr<nsIParser> rv = new nsHtml5Parser();
return rv.forget();
}
// static
nsresult
nsHtml5Module::Initialize(nsIParser* aParser, nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer, nsIChannel* aChannel)
{
MOZ_ASSERT(sNsHtml5ModuleInitialized, "nsHtml5Module not initialized.");
nsHtml5Parser* parser = static_cast<nsHtml5Parser*> (aParser);
return parser->Initialize(aDoc, aURI, aContainer, aChannel);
}
class nsHtml5ParserThreadTerminator final : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
explicit nsHtml5ParserThreadTerminator(nsIThread* aThread)
: mThread(aThread)
{}
NS_IMETHOD Observe(nsISupports *, const char *topic, const char16_t *) override
{
NS_ASSERTION(!strcmp(topic, "xpcom-shutdown-threads"),
"Unexpected topic");
if (mThread) {
mThread->Shutdown();
mThread = nullptr;
}
return NS_OK;
}
private:
~nsHtml5ParserThreadTerminator() {}
nsCOMPtr<nsIThread> mThread;
};
NS_IMPL_ISUPPORTS(nsHtml5ParserThreadTerminator, nsIObserver)
// static
nsIThread*
nsHtml5Module::GetStreamParserThread()
{
if (sOffMainThread) {
if (!sStreamParserThread) {
NS_NewNamedThread("HTML5 Parser", &sStreamParserThread);
NS_ASSERTION(sStreamParserThread, "Thread creation failed!");
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
NS_ASSERTION(os, "do_GetService failed");
os->AddObserver(new nsHtml5ParserThreadTerminator(sStreamParserThread),
"xpcom-shutdown-threads",
false);
}
return sStreamParserThread;
}
if (!sMainThread) {
NS_GetMainThread(&sMainThread);
NS_ASSERTION(sMainThread, "Main thread getter failed");
}
return sMainThread;
}
#ifdef DEBUG
bool nsHtml5Module::sNsHtml5ModuleInitialized = false;
#endif

View file

@ -0,0 +1,28 @@
/* 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 nsHtml5Module_h
#define nsHtml5Module_h
#include "nsIParser.h"
#include "nsIThread.h"
class nsHtml5Module
{
public:
static void InitializeStatics();
static void ReleaseStatics();
static already_AddRefed<nsIParser> NewHtml5Parser();
static nsresult Initialize(nsIParser* aParser, nsIDocument* aDoc, nsIURI* aURI, nsISupports* aContainer, nsIChannel* aChannel);
static nsIThread* GetStreamParserThread();
static bool sOffMainThread;
private:
#ifdef DEBUG
static bool sNsHtml5ModuleInitialized;
#endif
static nsIThread* sStreamParserThread;
static nsIThread* sMainThread;
};
#endif // nsHtml5Module_h

View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 2008-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#define nsHtml5NamedCharacters_cpp_
#include "jArray.h"
#include "nscore.h"
#include "nsDebug.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Logging.h"
#include "nsHtml5NamedCharacters.h"
const char16_t nsHtml5NamedCharacters::VALUES[][2] = {
#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
{ VALUE },
#include "nsHtml5NamedCharactersInclude.h"
#undef NAMED_CHARACTER_REFERENCE
{0, 0} };
char16_t** nsHtml5NamedCharacters::WINDOWS_1252;
static char16_t const WINDOWS_1252_DATA[] = {
0x20AC,
0x0081,
0x201A,
0x0192,
0x201E,
0x2026,
0x2020,
0x2021,
0x02C6,
0x2030,
0x0160,
0x2039,
0x0152,
0x008D,
0x017D,
0x008F,
0x0090,
0x2018,
0x2019,
0x201C,
0x201D,
0x2022,
0x2013,
0x2014,
0x02DC,
0x2122,
0x0161,
0x203A,
0x0153,
0x009D,
0x017E,
0x0178
};
/**
* To avoid having lots of pointers in the |charData| array, below,
* which would cause us to have to do lots of relocations at library
* load time, store all the string data for the names in one big array.
* Then use tricks with enums to help us build an array that contains
* the positions of each within the big arrays.
*/
static const int8_t ALL_NAMES[] = {
#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
CHARS ,
#include "nsHtml5NamedCharactersInclude.h"
#undef NAMED_CHARACTER_REFERENCE
};
enum NamePositions {
DUMMY_INITIAL_NAME_POSITION = 0,
/* enums don't take up space, so generate _START and _END */
#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
NAME_##N##_DUMMY, /* automatically one higher than previous */ \
NAME_##N##_START = NAME_##N##_DUMMY - 1, \
NAME_##N##_END = NAME_##N##_START + LEN + FLAG,
#include "nsHtml5NamedCharactersInclude.h"
#undef NAMED_CHARACTER_REFERENCE
DUMMY_FINAL_NAME_VALUE
};
static_assert(MOZ_ARRAY_LENGTH(ALL_NAMES) < 0x10000, "Start positions should fit in 16 bits");
const nsHtml5CharacterName nsHtml5NamedCharacters::NAMES[] = {
#ifdef DEBUG
#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
{ NAME_##N##_START, LEN, N },
#else
#define NAMED_CHARACTER_REFERENCE(N, CHARS, LEN, FLAG, VALUE) \
{ NAME_##N##_START, LEN, },
#endif
#include "nsHtml5NamedCharactersInclude.h"
#undef NAMED_CHARACTER_REFERENCE
};
int32_t
nsHtml5CharacterName::length() const
{
return nameLen;
}
char16_t
nsHtml5CharacterName::charAt(int32_t index) const
{
return static_cast<char16_t> (ALL_NAMES[nameStart + index]);
}
void
nsHtml5NamedCharacters::initializeStatics()
{
WINDOWS_1252 = new char16_t*[32];
for (int32_t i = 0; i < 32; ++i) {
WINDOWS_1252[i] = (char16_t*)&(WINDOWS_1252_DATA[i]);
}
}
void
nsHtml5NamedCharacters::releaseStatics()
{
delete[] WINDOWS_1252;
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2008-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef nsHtml5NamedCharacters_h
#define nsHtml5NamedCharacters_h
#include "jArray.h"
#include "nscore.h"
#include "nsDebug.h"
#include "mozilla/Logging.h"
#include "nsMemory.h"
struct nsHtml5CharacterName {
uint16_t nameStart;
uint16_t nameLen;
#ifdef DEBUG
int32_t n;
#endif
int32_t length() const;
char16_t charAt(int32_t index) const;
};
class nsHtml5NamedCharacters
{
public:
static const nsHtml5CharacterName NAMES[];
static const char16_t VALUES[][2];
static char16_t** WINDOWS_1252;
static void initializeStatics();
static void releaseStatics();
};
#endif // nsHtml5NamedCharacters_h

View file

@ -0,0 +1,313 @@
/*
* Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and Opera
* Software ASA.
*
* You are granted a license to use, reproduce and create derivative works of
* this document.
*/
#include "nsHtml5NamedCharactersAccel.h"
static int32_t const HILO_ACCEL_65[] = {
0, 0, 0, 0, 0, 0, 0, 12386493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40174181, 0, 0, 0, 0, 60162966, 0, 0, 0, 75367550, 0, 0, 0, 82183396, 0, 0, 0, 0, 0, 115148507, 0, 0, 135989275, 139397199, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_66[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28770743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82248935, 0, 0, 0, 0, 0, 115214046, 0, 0, 0, 139528272, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_68[] = {
0, 0, 0, 4980811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38470219, 0, 0, 0, 0, 0, 0, 0, 0, 64553944, 0, 0, 0, 0, 0, 0, 0, 92145022, 0, 0, 0, 0, 0, 0, 0, 0, 139593810, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_69[] = {
65536, 0, 0, 0, 0, 0, 0, 0, 13172937, 0, 0, 0, 0, 0, 25297282, 0, 0, 28901816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71500866, 0, 0, 0, 0, 82380008, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_71[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94897574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_72[] = {
0, 0, 2555943, 0, 0, 0, 0, 0, 0, 0, 15532269, 0, 0, 0, 0, 0, 0, 0, 31785444, 34406924, 0, 0, 0, 0, 0, 40895088, 0, 0, 0, 60228503, 0, 0, 0, 0, 0, 0, 0, 82445546, 0, 0, 0, 0, 0, 115279583, 0, 0, 136054812, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_73[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40239718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_74[] = {
0, 0, 0, 5046349, 0, 0, 10944679, 0, 13238474, 0, 15597806, 16056565, 0, 20578618, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_76[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95225257, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_77[] = {
196610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_78[] = {
0, 0, 0, 0, 8454273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46072511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_79[] = {
0, 0, 2687016, 0, 0, 0, 0, 0, 13304011, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31850982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_82[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34472462, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95290798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_83[] = {
0, 0, 0, 5111886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34603535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105776718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_84[] = {
0, 0, 0, 0, 8585346, 0, 11075752, 0, 0, 0, 0, 16187638, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_85[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28508594, 0, 0, 0, 0, 0, 0, 0, 40305255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_86[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95421871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_90[] = {
0, 0, 0, 5177423, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_97[] = {
327684, 1900571, 2949162, 5374032, 8716420, 0, 11206826, 12517566, 13435084, 0, 15663343, 16515320, 19988785, 20644155, 25428355, 27197855, 0, 29163962, 31916519, 34734609, 36045347, 0, 0, 0, 40436328, 40960625, 41615994, 46596800, 54264627, 60556184, 64750554, 68879387, 71763012, 75826303, 77268122, 0, 81462490, 83952875, 92865919, 96142769, 105973327, 110167691, 0, 116917984, 121833283, 132253665, 136251421, 140707923, 0, 0, 144574620, 145361066
};
static int32_t const HILO_ACCEL_98[] = {
393222, 0, 0, 0, 0, 0, 11272364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36176423, 38535756, 0, 0, 0, 0, 41681532, 46727880, 0, 60687261, 0, 0, 71828552, 75891846, 0, 0, 0, 84411650, 0, 96404924, 0, 0, 0, 117376761, 121898820, 132319203, 136382496, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_99[] = {
589831, 1966110, 3276846, 5505107, 8978566, 10420383, 11468973, 12583104, 13631694, 15139046, 15794416, 16711933, 20054322, 20840764, 25624965, 27263392, 0, 29360574, 32244200, 34931219, 36373033, 38601293, 39584348, 0, 40567402, 41091698, 42205821, 46858954, 54723389, 60818335, 65143773, 68944924, 71959625, 75957383, 77530268, 80938194, 81593564, 84739337, 92997002, 96863680, 106235474, 110233234, 0, 117704448, 122816325, 132515812, 136579106, 140773476, 142149753, 143001732, 144705695, 145492139
};
static int32_t const HILO_ACCEL_100[] = {
0, 0, 3342387, 0, 9044106, 0, 11534512, 0, 13697233, 0, 0, 0, 0, 0, 25690504, 0, 0, 0, 0, 0, 36438572, 38732366, 0, 0, 0, 41157236, 0, 46924492, 54788932, 61080481, 65209315, 0, 72025163, 0, 0, 0, 0, 85132558, 93062540, 96929223, 106563158, 0, 0, 118032133, 123012947, 132581351, 136775717, 140839013, 0, 143067271, 0, 145557677
};
static int32_t const HILO_ACCEL_101[] = {
0, 2162719, 3473460, 5636181, 0, 0, 0, 0, 0, 0, 0, 18809088, 20185395, 21299519, 0, 0, 0, 29622721, 0, 0, 0, 39256656, 39649885, 0, 0, 41288309, 42336901, 47448781, 55182149, 61342629, 65274852, 69010461, 72811596, 76219528, 77726880, 0, 0, 86967572, 93128077, 97650120, 106628699, 110560915, 0, 118490890, 123733846, 132646888, 0, 141232230, 142411898, 0, 144836769, 145688750
};
static int32_t const HILO_ACCEL_102[] = {
655370, 2228258, 3538998, 5701719, 9109643, 10485920, 11600049, 12648641, 13762770, 15204584, 15859954, 18874656, 20250933, 21365062, 25756041, 27328929, 28574132, 29688261, 32309741, 34996758, 36504109, 39322200, 39715422, 39912033, 40632940, 41353847, 42467975, 47514325, 55247691, 61473705, 65405925, 69272606, 72877144, 76285068, 77857955, 81003732, 81659102, 87164208, 93193614, 97715667, 106759772, 110626456, 114296528, 118687505, 123864929, 132712425, 136906792, 141297772, 142477438, 143132808, 144902307, 145754288
};
static int32_t const HILO_ACCEL_103[] = {
786443, 0, 0, 0, 9240716, 0, 11665586, 0, 13893843, 0, 0, 0, 0, 0, 25887114, 0, 0, 0, 0, 0, 36635182, 0, 0, 0, 0, 0, 42599049, 0, 0, 0, 65733607, 0, 73008217, 0, 77989029, 0, 81724639, 87295283, 0, 98305492, 107021918, 0, 0, 0, 0, 0, 137037866, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_104[] = {
0, 0, 3604535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27394466, 0, 29753798, 32571886, 35258903, 0, 0, 0, 0, 0, 0, 0, 0, 55509836, 61604779, 0, 0, 0, 0, 0, 0, 81790176, 87557429, 93259151, 98502109, 107152994, 110888601, 0, 119015188, 124323683, 133498858, 137234476, 0, 0, 143263881, 0, 145819825
};
static int32_t const HILO_ACCEL_105[] = {
0, 0, 3866680, 6160472, 0, 10616993, 0, 12714178, 0, 0, 0, 0, 20316470, 0, 0, 27460003, 0, 31261127, 32637426, 35521051, 0, 0, 0, 39977570, 0, 0, 0, 48366294, 56492880, 62391213, 0, 69338146, 73073755, 0, 78316711, 0, 0, 0, 93980048, 98764256, 107218532, 111085213, 114362065, 119736089, 125241194, 133957622, 0, 0, 0, 143329419, 144967844, 145885362
};
static int32_t const HILO_ACCEL_106[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62456761, 0, 69403683, 73139292, 0, 78382252, 0, 81855713, 87622969, 0, 98829796, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_107[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48431843, 0, 0, 0, 0, 0, 76416141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_108[] = {
851981, 0, 4063292, 0, 9306254, 0, 0, 0, 0, 0, 0, 19005729, 0, 0, 0, 27525540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42795659, 49152740, 56623967, 62587834, 66061292, 69600292, 73401437, 0, 0, 0, 0, 87950650, 94111131, 99878373, 107546213, 112002720, 0, 119932708, 125306744, 0, 137496623, 141363309, 0, 143460492, 0, 0
};
static int32_t const HILO_ACCEL_109[] = {
917518, 0, 0, 0, 9502863, 0, 0, 0, 14155989, 0, 0, 19071267, 0, 0, 26083724, 0, 0, 0, 32702963, 0, 36700720, 0, 0, 0, 0, 0, 43057806, 0, 0, 0, 66520049, 0, 0, 0, 78841005, 81069269, 0, 88147263, 0, 99943925, 107873898, 112068270, 0, 120063783, 125831033, 0, 137693235, 0, 0, 143526030, 0, 0
};
static int32_t const HILO_ACCEL_110[] = {
983055, 0, 0, 0, 0, 0, 0, 0, 14483673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37093937, 0, 0, 0, 0, 0, 44565138, 49349359, 0, 0, 66651128, 69665831, 73860193, 0, 79561908, 0, 0, 88606018, 94176669, 0, 0, 0, 0, 120129321, 0, 0, 0, 141494382, 0, 143591567, 0, 0
};
static int32_t const HILO_ACCEL_111[] = {
1114128, 2293795, 4587583, 8257631, 9633938, 10813603, 11731123, 12845251, 14680286, 15270121, 15925491, 19661092, 20382007, 24969543, 26149263, 27656613, 28639669, 31392222, 32768500, 35586591, 37225015, 39387737, 39780959, 40043107, 40698477, 41419384, 44696233, 52495090, 57738081, 63439804, 66782202, 69927976, 73925736, 76809359, 79824063, 81134806, 81921250, 89785673, 94307742, 100795894, 107939439, 112330415, 114427602, 120588074, 126158721, 134416381, 137824310, 141559920, 142542975, 143853712, 145033381, 145950899
};
static int32_t const HILO_ACCEL_112[] = {
1179666, 0, 0, 0, 9699476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26280336, 0, 0, 0, 0, 0, 38076985, 0, 0, 0, 0, 0, 45220523, 52560674, 0, 0, 67175420, 69993516, 0, 0, 79889603, 0, 0, 89916763, 94373280, 101451267, 108136048, 0, 114493139, 120784689, 126355334, 134481924, 138414136, 141625457, 142608512, 0, 0, 0
};
static int32_t const HILO_ACCEL_113[] = {
0, 0, 0, 0, 9896085, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33292789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67830786, 0, 0, 0, 80020676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127403913, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_114[] = {
1310739, 2359332, 4653127, 0, 0, 0, 12189876, 0, 0, 0, 0, 0, 0, 0, 26345874, 28246439, 0, 31457760, 0, 35652128, 38142534, 0, 0, 0, 0, 0, 45351603, 52757283, 57869170, 63636425, 67961868, 71304237, 73991273, 0, 0, 0, 0, 90309981, 0, 101910029, 108988019, 114034355, 0, 120850228, 127469465, 135464965, 138741825, 141690994, 142739585, 143984788, 0, 0
};
static int32_t const HILO_ACCEL_115[] = {
1441813, 2424869, 4718664, 8388735, 10027160, 10879142, 12255419, 12976325, 14745825, 15401194, 15991028, 19857709, 20447544, 25035134, 26542483, 28377520, 28705206, 31588833, 33358333, 35783201, 38208071, 39453274, 39846496, 40108644, 40764014, 41484921, 45613749, 53216038, 58196852, 63898572, 68158478, 71369793, 74253418, 77005973, 80479430, 81265879, 81986787, 90965347, 94504353, 103679508, 109250176, 114165453, 114558676, 121243445, 127731610, 135727124, 138807366, 142018675, 142805123, 144115862, 145098918, 146016436
};
static int32_t const HILO_ACCEL_116[] = {
1572887, 0, 0, 0, 10092698, 0, 12320956, 0, 14811362, 0, 0, 19923248, 0, 25166207, 26739094, 0, 0, 0, 33423870, 0, 38273608, 0, 0, 0, 0, 0, 45744825, 0, 58262393, 64095184, 68355089, 0, 75170926, 0, 80610509, 0, 0, 91817325, 0, 104203823, 109512324, 0, 0, 121636667, 128059294, 0, 139069511, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_117[] = {
1703961, 2490406, 4849737, 0, 10223771, 0, 0, 13107399, 15007971, 15466732, 0, 0, 20513081, 25231745, 26870169, 0, 0, 31654371, 34275839, 0, 38404681, 0, 0, 0, 40829551, 0, 45875899, 53609261, 59900794, 64226259, 68551700, 0, 0, 0, 80807119, 81331417, 0, 91948410, 94700963, 104465975, 109643400, 114230991, 114951893, 121702209, 131663779, 0, 139266123, 0, 0, 144246936, 145295527, 0
};
static int32_t const HILO_ACCEL_118[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27132315, 0, 0, 0, 0, 0, 0, 39518811, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75302012, 0, 0, 0, 0, 92079484, 0, 105383483, 109708938, 0, 0, 0, 0, 0, 0, 0, 0, 144312474, 0, 0
};
static int32_t const HILO_ACCEL_119[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46006973, 0, 60031891, 64291797, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105711177, 0, 0, 0, 0, 131991514, 135923736, 139331662, 0, 0, 144378011, 0, 146147509
};
static int32_t const HILO_ACCEL_120[] = {
0, 0, 0, 0, 10354845, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68813847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121767746, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_121[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60097429, 0, 0, 0, 0, 77137048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int32_t const HILO_ACCEL_122[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64422870, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132122591, 0, 0, 142084216, 0, 0, 0, 0
};
const int32_t* const nsHtml5NamedCharactersAccel::HILO_ACCEL[] = {
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
HILO_ACCEL_65,
HILO_ACCEL_66,
0,
HILO_ACCEL_68,
HILO_ACCEL_69,
0,
HILO_ACCEL_71,
HILO_ACCEL_72,
HILO_ACCEL_73,
HILO_ACCEL_74,
0,
HILO_ACCEL_76,
HILO_ACCEL_77,
HILO_ACCEL_78,
HILO_ACCEL_79,
0,
0,
HILO_ACCEL_82,
HILO_ACCEL_83,
HILO_ACCEL_84,
HILO_ACCEL_85,
HILO_ACCEL_86,
0,
0,
0,
HILO_ACCEL_90,
0,
0,
0,
0,
0,
0,
HILO_ACCEL_97,
HILO_ACCEL_98,
HILO_ACCEL_99,
HILO_ACCEL_100,
HILO_ACCEL_101,
HILO_ACCEL_102,
HILO_ACCEL_103,
HILO_ACCEL_104,
HILO_ACCEL_105,
HILO_ACCEL_106,
HILO_ACCEL_107,
HILO_ACCEL_108,
HILO_ACCEL_109,
HILO_ACCEL_110,
HILO_ACCEL_111,
HILO_ACCEL_112,
HILO_ACCEL_113,
HILO_ACCEL_114,
HILO_ACCEL_115,
HILO_ACCEL_116,
HILO_ACCEL_117,
HILO_ACCEL_118,
HILO_ACCEL_119,
HILO_ACCEL_120,
HILO_ACCEL_121,
HILO_ACCEL_122
};

View file

@ -0,0 +1,24 @@
/*
* Copyright 2004-2010 Apple Computer, Inc., Mozilla Foundation, and Opera
* Software ASA.
*
* You are granted a license to use, reproduce and create derivative works of
* this document.
*/
#ifndef nsHtml5NamedCharactersAccel_h
#define nsHtml5NamedCharactersAccel_h
#include "jArray.h"
#include "nscore.h"
#include "nsDebug.h"
#include "mozilla/Logging.h"
#include "nsMemory.h"
class nsHtml5NamedCharactersAccel
{
public:
static const int32_t* const HILO_ACCEL[];
};
#endif // nsHtml5NamedCharactersAccel_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,49 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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 "nsHtml5OplessBuilder.h"
#include "nsScriptLoader.h"
#include "mozilla/css/Loader.h"
#include "nsIDocShell.h"
#include "nsIHTMLDocument.h"
nsHtml5OplessBuilder::nsHtml5OplessBuilder()
: nsHtml5DocumentBuilder(true)
{
}
nsHtml5OplessBuilder::~nsHtml5OplessBuilder()
{
}
void
nsHtml5OplessBuilder::Start()
{
mFlushState = eInFlush;
BeginDocUpdate();
}
void
nsHtml5OplessBuilder::Finish()
{
EndDocUpdate();
DropParserAndPerfHint();
mScriptLoader = nullptr;
mDocument = nullptr;
mNodeInfoManager = nullptr;
mCSSLoader = nullptr;
mDocumentURI = nullptr;
mDocShell = nullptr;
mOwnedElements.Clear();
mFlushState = eNotFlushing;
}
void
nsHtml5OplessBuilder::SetParser(nsParserBase* aParser)
{
mParser = aParser;
}

View file

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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 nsHtml5OplessBuilder_h
#define nsHtml5OplessBuilder_h
#include "nsHtml5DocumentBuilder.h"
class nsParserBase;
/**
* This class implements a minimal subclass of nsHtml5DocumentBuilder that
* works when tree operation queues that are part of the off-the-main-thread
* parsing machinery are not used and, therefore, nsHtml5TreeOpExecutor is
* not used.
*
* This class is mostly responsible for wrapping tree building in an update
* batch and resetting various fields in nsContentSink upon finishing.
*/
class nsHtml5OplessBuilder : public nsHtml5DocumentBuilder
{
public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
nsHtml5OplessBuilder();
~nsHtml5OplessBuilder();
void Start();
void Finish();
void SetParser(nsParserBase* aParser);
};
#endif // nsHtml5OplessBuilder_h

View file

@ -0,0 +1,86 @@
/* 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 "nsHtml5OwningUTF16Buffer.h"
nsHtml5OwningUTF16Buffer::nsHtml5OwningUTF16Buffer(char16_t* aBuffer)
: nsHtml5UTF16Buffer(aBuffer, 0),
next(nullptr),
key(nullptr)
{
MOZ_COUNT_CTOR(nsHtml5OwningUTF16Buffer);
}
nsHtml5OwningUTF16Buffer::nsHtml5OwningUTF16Buffer(void* aKey)
: nsHtml5UTF16Buffer(nullptr, 0),
next(nullptr),
key(aKey)
{
MOZ_COUNT_CTOR(nsHtml5OwningUTF16Buffer);
}
nsHtml5OwningUTF16Buffer::~nsHtml5OwningUTF16Buffer()
{
MOZ_COUNT_DTOR(nsHtml5OwningUTF16Buffer);
DeleteBuffer();
// This is to avoid dtor recursion on 'next', bug 706932.
RefPtr<nsHtml5OwningUTF16Buffer> tail;
tail.swap(next);
while (tail && tail->mRefCnt == 1) {
RefPtr<nsHtml5OwningUTF16Buffer> tmp;
tmp.swap(tail->next);
tail.swap(tmp);
}
}
// static
already_AddRefed<nsHtml5OwningUTF16Buffer>
nsHtml5OwningUTF16Buffer::FalliblyCreate(int32_t aLength)
{
char16_t* newBuf = new (mozilla::fallible) char16_t[aLength];
if (!newBuf) {
return nullptr;
}
RefPtr<nsHtml5OwningUTF16Buffer> newObj =
new (mozilla::fallible) nsHtml5OwningUTF16Buffer(newBuf);
if (!newObj) {
delete[] newBuf;
return nullptr;
}
return newObj.forget();
}
void
nsHtml5OwningUTF16Buffer::Swap(nsHtml5OwningUTF16Buffer* aOther)
{
nsHtml5UTF16Buffer::Swap(aOther);
}
// Not using macros for AddRef and Release in order to be able to refcount on
// and create on different threads.
nsrefcnt
nsHtml5OwningUTF16Buffer::AddRef()
{
NS_PRECONDITION(int32_t(mRefCnt) >= 0, "Illegal refcount.");
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsHtml5OwningUTF16Buffer", sizeof(*this));
return mRefCnt;
}
nsrefcnt
nsHtml5OwningUTF16Buffer::Release()
{
NS_PRECONDITION(0 != mRefCnt, "Release without AddRef.");
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsHtml5OwningUTF16Buffer");
if (mRefCnt == 0) {
mRefCnt = 1; /* stabilize */
delete this;
return 0;
}
return mRefCnt;
}

View file

@ -0,0 +1,58 @@
/* 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 nsHtml5OwningUTF16Buffer_h
#define nsHtml5OwningUTF16Buffer_h
#include "nsHtml5UTF16Buffer.h"
class nsHtml5OwningUTF16Buffer : public nsHtml5UTF16Buffer
{
private:
/**
* Passes a buffer and its length to the superclass constructor.
*/
explicit nsHtml5OwningUTF16Buffer(char16_t* aBuffer);
public:
/**
* Constructor for a parser key placeholder. (No actual buffer.)
* @param aKey a parser key
*/
explicit nsHtml5OwningUTF16Buffer(void* aKey);
protected:
/**
* Takes care of releasing the owned buffer.
*/
~nsHtml5OwningUTF16Buffer();
public:
/**
* The next buffer in a queue.
*/
RefPtr<nsHtml5OwningUTF16Buffer> next;
/**
* A parser key.
*/
void* key;
static already_AddRefed<nsHtml5OwningUTF16Buffer>
FalliblyCreate(int32_t aLength);
/**
* Swap start, end and buffer fields with another object.
*/
void Swap(nsHtml5OwningUTF16Buffer* aOther);
nsrefcnt AddRef();
nsrefcnt Release();
private:
nsAutoRefCnt mRefCnt;
};
#endif // nsHtml5OwningUTF16Buffer_h

View file

@ -0,0 +1,754 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=2 et tw=79: */
/* 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 "nsHtml5Parser.h"
#include "mozilla/AutoRestore.h"
#include "nsContentUtils.h" // for kLoadAsData
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5AtomTable.h"
#include "nsHtml5DependentUTF16Buffer.h"
#include "nsNetUtil.h"
NS_INTERFACE_TABLE_HEAD(nsHtml5Parser)
NS_INTERFACE_TABLE(nsHtml5Parser, nsIParser, nsISupportsWeakReference)
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsHtml5Parser)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mExecutor)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetStreamParser())
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHtml5Parser)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mExecutor)
tmp->DropStreamParser();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsHtml5Parser::nsHtml5Parser()
: mFirstBuffer(new nsHtml5OwningUTF16Buffer((void*)nullptr))
, mLastBuffer(mFirstBuffer)
, mExecutor(new nsHtml5TreeOpExecutor())
, mTreeBuilder(new nsHtml5TreeBuilder(mExecutor, nullptr))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
, mRootContextLineNumber(1)
{
mTokenizer->setInterner(&mAtomTable);
// There's a zeroing operator new for everything else
}
nsHtml5Parser::~nsHtml5Parser()
{
mTokenizer->end();
if (mDocWriteSpeculativeTokenizer) {
mDocWriteSpeculativeTokenizer->end();
}
}
NS_IMETHODIMP_(void)
nsHtml5Parser::SetContentSink(nsIContentSink* aSink)
{
NS_ASSERTION(aSink == static_cast<nsIContentSink*> (mExecutor),
"Attempt to set a foreign sink.");
}
NS_IMETHODIMP_(nsIContentSink*)
nsHtml5Parser::GetContentSink()
{
return static_cast<nsIContentSink*> (mExecutor);
}
NS_IMETHODIMP_(void)
nsHtml5Parser::GetCommand(nsCString& aCommand)
{
aCommand.AssignLiteral("view");
}
NS_IMETHODIMP_(void)
nsHtml5Parser::SetCommand(const char* aCommand)
{
NS_ASSERTION(!strcmp(aCommand, "view") ||
!strcmp(aCommand, "view-source") ||
!strcmp(aCommand, "external-resource") ||
!strcmp(aCommand, "import") ||
!strcmp(aCommand, kLoadAsData),
"Unsupported parser command");
}
NS_IMETHODIMP_(void)
nsHtml5Parser::SetCommand(eParserCommands aParserCommand)
{
NS_ASSERTION(aParserCommand == eViewNormal,
"Parser command was not eViewNormal.");
}
NS_IMETHODIMP_(void)
nsHtml5Parser::SetDocumentCharset(const nsACString& aCharset,
int32_t aCharsetSource)
{
NS_PRECONDITION(!mExecutor->HasStarted(),
"Document charset set too late.");
NS_PRECONDITION(GetStreamParser(), "Setting charset on a script-only parser.");
nsAutoCString trimmed;
trimmed.Assign(aCharset);
trimmed.Trim(" \t\r\n\f");
GetStreamParser()->SetDocumentCharset(trimmed, aCharsetSource);
mExecutor->SetDocumentCharsetAndSource(trimmed,
aCharsetSource);
}
NS_IMETHODIMP
nsHtml5Parser::GetChannel(nsIChannel** aChannel)
{
if (GetStreamParser()) {
return GetStreamParser()->GetChannel(aChannel);
} else {
return NS_ERROR_NOT_AVAILABLE;
}
}
NS_IMETHODIMP
nsHtml5Parser::GetDTD(nsIDTD** aDTD)
{
*aDTD = nullptr;
return NS_OK;
}
nsIStreamListener*
nsHtml5Parser::GetStreamListener()
{
return mStreamListener;
}
NS_IMETHODIMP
nsHtml5Parser::ContinueInterruptedParsing()
{
NS_NOTREACHED("Don't call. For interface compat only.");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP_(void)
nsHtml5Parser::BlockParser()
{
mBlocked = true;
}
NS_IMETHODIMP_(void)
nsHtml5Parser::UnblockParser()
{
mBlocked = false;
mExecutor->ContinueInterruptedParsingAsync();
}
NS_IMETHODIMP_(void)
nsHtml5Parser::ContinueInterruptedParsingAsync()
{
mExecutor->ContinueInterruptedParsingAsync();
}
NS_IMETHODIMP_(bool)
nsHtml5Parser::IsParserEnabled()
{
return !mBlocked;
}
NS_IMETHODIMP_(bool)
nsHtml5Parser::IsComplete()
{
return mExecutor->IsComplete();
}
NS_IMETHODIMP
nsHtml5Parser::Parse(nsIURI* aURL,
nsIRequestObserver* aObserver,
void* aKey, // legacy; ignored
nsDTDMode aMode) // legacy; ignored
{
/*
* Do NOT cause WillBuildModel to be called synchronously from here!
* The document won't be ready for it until OnStartRequest!
*/
NS_PRECONDITION(!mExecutor->HasStarted(),
"Tried to start parse without initializing the parser.");
NS_PRECONDITION(GetStreamParser(),
"Can't call this Parse() variant on script-created parser");
GetStreamParser()->SetObserver(aObserver);
GetStreamParser()->SetViewSourceTitle(aURL); // In case we're viewing source
mExecutor->SetStreamParser(GetStreamParser());
mExecutor->SetParser(this);
return NS_OK;
}
nsresult
nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
void* aKey,
const nsACString& aContentType,
bool aLastCall,
nsDTDMode aMode) // ignored
{
nsresult rv;
if (NS_FAILED(rv = mExecutor->IsBroken())) {
return rv;
}
if (aSourceBuffer.Length() > INT32_MAX) {
return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
// Maintain a reference to ourselves so we don't go away
// till we're completely done. The old parser grips itself in this method.
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
// Gripping the other objects just in case, since the other old grip
// required grips to these, too.
RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip(GetStreamParser());
mozilla::Unused << streamKungFuDeathGrip; // Not used within function
RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
if (!executor->HasStarted()) {
NS_ASSERTION(!GetStreamParser(),
"Had stream parser but document.write started life cycle.");
// This is the first document.write() on a document.open()ed document
executor->SetParser(this);
mTreeBuilder->setScriptingEnabled(executor->IsScriptEnabled());
bool isSrcdoc = false;
nsCOMPtr<nsIChannel> channel;
rv = GetChannel(getter_AddRefs(channel));
if (NS_SUCCEEDED(rv)) {
isSrcdoc = NS_IsSrcdocChannel(channel);
}
mTreeBuilder->setIsSrcdocDocument(isSrcdoc);
mTokenizer->start();
executor->Start();
if (!aContentType.EqualsLiteral("text/html")) {
mTreeBuilder->StartPlainText();
mTokenizer->StartPlainText();
}
/*
* If you move the following line, be very careful not to cause
* WillBuildModel to be called before the document has had its
* script global object set.
*/
rv = executor->WillBuildModel(eDTDMode_unknown);
NS_ENSURE_SUCCESS(rv, rv);
}
// Return early if the parser has processed EOF
if (executor->IsComplete()) {
return NS_OK;
}
if (aLastCall && aSourceBuffer.IsEmpty() && !aKey) {
// document.close()
NS_ASSERTION(!GetStreamParser(),
"Had stream parser but got document.close().");
if (mDocumentClosed) {
// already closed
return NS_OK;
}
mDocumentClosed = true;
if (!mBlocked && !mInDocumentWrite) {
return ParseUntilBlocked();
}
return NS_OK;
}
// If we got this far, we are dealing with a document.write or
// document.writeln call--not document.close().
NS_ASSERTION(IsInsertionPointDefined(),
"Doc.write reached parser with undefined insertion point.");
NS_ASSERTION(!(GetStreamParser() && !aKey),
"Got a null key in a non-script-created parser");
// XXX is this optimization bogus?
if (aSourceBuffer.IsEmpty()) {
return NS_OK;
}
// This guard is here to prevent document.close from tokenizing synchronously
// while a document.write (that wrote the script that called document.close!)
// is still on the call stack.
mozilla::AutoRestore<bool> guard(mInDocumentWrite);
mInDocumentWrite = true;
// The script is identified by aKey. If there's nothing in the buffer
// chain for that key, we'll insert at the head of the queue.
// When the script leaves something in the queue, a zero-length
// key-holder "buffer" is inserted in the queue. If the same script
// leaves something in the chain again, it will be inserted immediately
// before the old key holder belonging to the same script.
//
// We don't do the actual data insertion yet in the hope that the data gets
// tokenized and there no data or less data to copy to the heap after
// tokenization. Also, this way, we avoid inserting one empty data buffer
// per document.write, which matters for performance when the parser isn't
// blocked and a badly-authored script calls document.write() once per
// input character. (As seen in a benchmark!)
//
// The insertion into the input stream happens conceptually before anything
// gets tokenized. To make sure multi-level document.write works right,
// it's necessary to establish the location of our parser key up front
// in case this is the first write with this key.
//
// In a document.open() case, the first write level has a null key, so that
// case is handled separately, because normal buffers containing data
// have null keys.
// These don't need to be owning references, because they always point to
// the buffer queue and buffers can't be removed from the buffer queue
// before document.write() returns. The buffer queue clean-up happens the
// next time ParseUntilBlocked() is called.
// However, they are made owning just in case the reasoning above is flawed
// and a flaw would lead to worse problems with plain pointers. If this
// turns out to be a perf problem, it's worthwhile to consider making
// prevSearchbuf a plain pointer again.
RefPtr<nsHtml5OwningUTF16Buffer> prevSearchBuf;
RefPtr<nsHtml5OwningUTF16Buffer> firstLevelMarker;
if (aKey) {
if (mFirstBuffer == mLastBuffer) {
nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
keyHolder->next = mLastBuffer;
mFirstBuffer = keyHolder;
} else if (mFirstBuffer->key != aKey) {
prevSearchBuf = mFirstBuffer;
for (;;) {
if (prevSearchBuf->next == mLastBuffer) {
// key was not found
nsHtml5OwningUTF16Buffer* keyHolder =
new nsHtml5OwningUTF16Buffer(aKey);
keyHolder->next = mFirstBuffer;
mFirstBuffer = keyHolder;
prevSearchBuf = nullptr;
break;
}
if (prevSearchBuf->next->key == aKey) {
// found a key holder
break;
}
prevSearchBuf = prevSearchBuf->next;
}
} // else mFirstBuffer is the keyholder
// prevSearchBuf is the previous buffer before the keyholder or null if
// there isn't one.
} else {
// We have a first-level write in the document.open() case. We insert before
// mLastBuffer, effectively, by making mLastBuffer be a new sentinel object
// and redesignating the previous mLastBuffer as our firstLevelMarker. We
// need to put a marker there, because otherwise additional document.writes
// from nested event loops would insert in the wrong place. Sigh.
mLastBuffer->next = new nsHtml5OwningUTF16Buffer((void*)nullptr);
firstLevelMarker = mLastBuffer;
mLastBuffer = mLastBuffer->next;
}
nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer);
while (!mBlocked && stackBuffer.hasMore()) {
stackBuffer.adjust(mLastWasCR);
mLastWasCR = false;
if (stackBuffer.hasMore()) {
int32_t lineNumberSave;
bool inRootContext = (!GetStreamParser() && !aKey);
if (inRootContext) {
mTokenizer->setLineNumber(mRootContextLineNumber);
} else {
// we aren't the root context, so save the line number on the
// *stack* so that we can restore it.
lineNumberSave = mTokenizer->getLineNumber();
}
if (!mTokenizer->EnsureBufferSpace(stackBuffer.getLength())) {
return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
mLastWasCR = mTokenizer->tokenizeBuffer(&stackBuffer);
if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
return executor->MarkAsBroken(rv);
}
if (inRootContext) {
mRootContextLineNumber = mTokenizer->getLineNumber();
} else {
mTokenizer->setLineNumber(lineNumberSave);
}
if (mTreeBuilder->HasScript()) {
mTreeBuilder->Flush(); // Move ops to the executor
rv = executor->FlushDocumentWrite(); // run the ops
NS_ENSURE_SUCCESS(rv, rv);
// Flushing tree ops can cause all sorts of things.
// Return early if the parser got terminated.
if (executor->IsComplete()) {
return NS_OK;
}
}
// Ignore suspension requests
}
}
RefPtr<nsHtml5OwningUTF16Buffer> heapBuffer;
if (stackBuffer.hasMore()) {
// The buffer wasn't tokenized to completion. Create a copy of the tail
// on the heap.
heapBuffer = stackBuffer.FalliblyCopyAsOwningBuffer();
if (!heapBuffer) {
// Allocation failed. The parser is now broken.
return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
}
if (heapBuffer) {
// We have something to insert before the keyholder holding in the non-null
// aKey case and we have something to swap into firstLevelMarker in the
// null aKey case.
if (aKey) {
NS_ASSERTION(mFirstBuffer != mLastBuffer,
"Where's the keyholder?");
// the key holder is still somewhere further down the list from
// prevSearchBuf (which may be null)
if (mFirstBuffer->key == aKey) {
NS_ASSERTION(!prevSearchBuf,
"Non-null prevSearchBuf when mFirstBuffer is the key holder?");
heapBuffer->next = mFirstBuffer;
mFirstBuffer = heapBuffer;
} else {
if (!prevSearchBuf) {
prevSearchBuf = mFirstBuffer;
}
// We created a key holder earlier, so we will find it without walking
// past the end of the list.
while (prevSearchBuf->next->key != aKey) {
prevSearchBuf = prevSearchBuf->next;
}
heapBuffer->next = prevSearchBuf->next;
prevSearchBuf->next = heapBuffer;
}
} else {
NS_ASSERTION(firstLevelMarker, "How come we don't have a marker.");
firstLevelMarker->Swap(heapBuffer);
}
}
if (!mBlocked) { // buffer was tokenized to completion
NS_ASSERTION(!stackBuffer.hasMore(),
"Buffer wasn't tokenized to completion?");
// Scripting semantics require a forced tree builder flush here
mTreeBuilder->Flush(); // Move ops to the executor
rv = executor->FlushDocumentWrite(); // run the ops
NS_ENSURE_SUCCESS(rv, rv);
} else if (stackBuffer.hasMore()) {
// The buffer wasn't tokenized to completion. Tokenize the untokenized
// content in order to preload stuff. This content will be retokenized
// later for normal parsing.
if (!mDocWriteSpeculatorActive) {
mDocWriteSpeculatorActive = true;
if (!mDocWriteSpeculativeTreeBuilder) {
// Lazily initialize if uninitialized
mDocWriteSpeculativeTreeBuilder =
new nsHtml5TreeBuilder(nullptr, executor->GetStage());
mDocWriteSpeculativeTreeBuilder->setScriptingEnabled(
mTreeBuilder->isScriptingEnabled());
mDocWriteSpeculativeTokenizer =
new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder, false);
mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable);
mDocWriteSpeculativeTokenizer->start();
}
mDocWriteSpeculativeTokenizer->resetToDataState();
mDocWriteSpeculativeTreeBuilder->loadState(mTreeBuilder, &mAtomTable);
mDocWriteSpeculativeLastWasCR = false;
}
// Note that with multilevel document.write if we didn't just activate the
// speculator, it's possible that the speculator is now in the wrong state.
// That's OK for the sake of simplicity. The worst that can happen is
// that the speculative loads aren't exactly right. The content will be
// reparsed anyway for non-preload purposes.
// The buffer position for subsequent non-speculative parsing now lives
// in heapBuffer, so it's ok to let the buffer position of stackBuffer
// to be overwritten and not restored below.
while (stackBuffer.hasMore()) {
stackBuffer.adjust(mDocWriteSpeculativeLastWasCR);
if (stackBuffer.hasMore()) {
if (!mDocWriteSpeculativeTokenizer->EnsureBufferSpace(
stackBuffer.getLength())) {
return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
mDocWriteSpeculativeLastWasCR =
mDocWriteSpeculativeTokenizer->tokenizeBuffer(&stackBuffer);
nsresult rv;
if (NS_FAILED((rv = mDocWriteSpeculativeTreeBuilder->IsBroken()))) {
return executor->MarkAsBroken(rv);
}
}
}
mDocWriteSpeculativeTreeBuilder->Flush();
mDocWriteSpeculativeTreeBuilder->DropHandles();
executor->FlushSpeculativeLoads();
}
return NS_OK;
}
NS_IMETHODIMP
nsHtml5Parser::Terminate()
{
// We should only call DidBuildModel once, so don't do anything if this is
// the second time that Terminate has been called.
if (mExecutor->IsComplete()) {
return NS_OK;
}
// XXX - [ until we figure out a way to break parser-sink circularity ]
// Hack - Hold a reference until we are completely done...
nsCOMPtr<nsIParser> kungFuDeathGrip(this);
RefPtr<nsHtml5StreamParser> streamParser(GetStreamParser());
RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
if (streamParser) {
streamParser->Terminate();
}
return executor->DidBuildModel(true);
}
NS_IMETHODIMP
nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
nsTArray<nsString>& aTagStack)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHtml5Parser::BuildModel()
{
NS_NOTREACHED("Don't call this!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHtml5Parser::CancelParsingEvents()
{
NS_NOTREACHED("Don't call this!");
return NS_ERROR_NOT_IMPLEMENTED;
}
void
nsHtml5Parser::Reset()
{
NS_NOTREACHED("Don't call this!");
}
bool
nsHtml5Parser::IsInsertionPointDefined()
{
return !mExecutor->IsFlushing() &&
(!GetStreamParser() || mInsertionPointPushLevel);
}
void
nsHtml5Parser::PushDefinedInsertionPoint()
{
++mInsertionPointPushLevel;
}
void
nsHtml5Parser::PopDefinedInsertionPoint()
{
--mInsertionPointPushLevel;
}
void
nsHtml5Parser::MarkAsNotScriptCreated(const char* aCommand)
{
NS_PRECONDITION(!mStreamListener, "Must not call this twice.");
eParserMode mode = NORMAL;
if (!nsCRT::strcmp(aCommand, "view-source")) {
mode = VIEW_SOURCE_HTML;
} else if (!nsCRT::strcmp(aCommand, "view-source-xml")) {
mode = VIEW_SOURCE_XML;
} else if (!nsCRT::strcmp(aCommand, "view-source-plain")) {
mode = VIEW_SOURCE_PLAIN;
} else if (!nsCRT::strcmp(aCommand, "plain-text")) {
mode = PLAIN_TEXT;
} else if (!nsCRT::strcmp(aCommand, kLoadAsData)) {
mode = LOAD_AS_DATA;
}
#ifdef DEBUG
else {
NS_ASSERTION(!nsCRT::strcmp(aCommand, "view") ||
!nsCRT::strcmp(aCommand, "external-resource") ||
!nsCRT::strcmp(aCommand, "import"),
"Unsupported parser command!");
}
#endif
mStreamListener =
new nsHtml5StreamListener(new nsHtml5StreamParser(mExecutor, this, mode));
}
bool
nsHtml5Parser::IsScriptCreated()
{
return !GetStreamParser();
}
/* End nsIParser */
// not from interface
nsresult
nsHtml5Parser::ParseUntilBlocked()
{
nsresult rv = mExecutor->IsBroken();
NS_ENSURE_SUCCESS(rv, rv);
if (mBlocked || mExecutor->IsComplete()) {
return NS_OK;
}
NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
NS_ASSERTION(!mInDocumentWrite,
"ParseUntilBlocked entered while in doc.write!");
mDocWriteSpeculatorActive = false;
for (;;) {
if (!mFirstBuffer->hasMore()) {
if (mFirstBuffer == mLastBuffer) {
if (mExecutor->IsComplete()) {
// something like cache manisfests stopped the parse in mid-flight
return NS_OK;
}
if (mDocumentClosed) {
nsresult rv;
NS_ASSERTION(!GetStreamParser(),
"This should only happen with script-created parser.");
if (NS_SUCCEEDED((rv = mExecutor->IsBroken()))) {
mTokenizer->eof();
if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
mExecutor->MarkAsBroken(rv);
} else {
mTreeBuilder->StreamEnded();
}
}
mTreeBuilder->Flush();
mExecutor->FlushDocumentWrite();
// The below call does memory cleanup, so call it even if the
// parser has been marked as broken.
mTokenizer->end();
return rv;
}
// never release the last buffer.
NS_ASSERTION(!mLastBuffer->getStart() && !mLastBuffer->getEnd(),
"Sentinel buffer had its indeces changed.");
if (GetStreamParser()) {
if (mReturnToStreamParserPermitted &&
!mExecutor->IsScriptExecuting()) {
mTreeBuilder->Flush();
mReturnToStreamParserPermitted = false;
GetStreamParser()->ContinueAfterScripts(mTokenizer,
mTreeBuilder,
mLastWasCR);
}
} else {
// Script-created parser
mTreeBuilder->Flush();
// No need to flush the executor, because the executor is already
// in a flush
NS_ASSERTION(mExecutor->IsInFlushLoop(),
"How did we come here without being in the flush loop?");
}
return NS_OK; // no more data for now but expecting more
}
mFirstBuffer = mFirstBuffer->next;
continue;
}
if (mBlocked || mExecutor->IsComplete()) {
return NS_OK;
}
// now we have a non-empty buffer
mFirstBuffer->adjust(mLastWasCR);
mLastWasCR = false;
if (mFirstBuffer->hasMore()) {
bool inRootContext = (!GetStreamParser() && !mFirstBuffer->key);
if (inRootContext) {
mTokenizer->setLineNumber(mRootContextLineNumber);
}
if (!mTokenizer->EnsureBufferSpace(mFirstBuffer->getLength())) {
return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
mLastWasCR = mTokenizer->tokenizeBuffer(mFirstBuffer);
nsresult rv;
if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
return mExecutor->MarkAsBroken(rv);
}
if (inRootContext) {
mRootContextLineNumber = mTokenizer->getLineNumber();
}
if (mTreeBuilder->HasScript()) {
mTreeBuilder->Flush();
rv = mExecutor->FlushDocumentWrite();
NS_ENSURE_SUCCESS(rv, rv);
}
if (mBlocked) {
return NS_OK;
}
}
continue;
}
}
nsresult
nsHtml5Parser::Initialize(nsIDocument* aDoc,
nsIURI* aURI,
nsISupports* aContainer,
nsIChannel* aChannel)
{
return mExecutor->Init(aDoc, aURI, aContainer, aChannel);
}
void
nsHtml5Parser::StartTokenizer(bool aScriptingEnabled) {
bool isSrcdoc = false;
nsCOMPtr<nsIChannel> channel;
nsresult rv = GetChannel(getter_AddRefs(channel));
if (NS_SUCCEEDED(rv)) {
isSrcdoc = NS_IsSrcdocChannel(channel);
}
mTreeBuilder->setIsSrcdocDocument(isSrcdoc);
mTreeBuilder->SetPreventScriptExecution(!aScriptingEnabled);
mTreeBuilder->setScriptingEnabled(aScriptingEnabled);
mTokenizer->start();
}
void
nsHtml5Parser::InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState,
int32_t aLine)
{
mTokenizer->resetToDataState();
mTokenizer->setLineNumber(aLine);
mTreeBuilder->loadState(aState, &mAtomTable);
mLastWasCR = false;
mReturnToStreamParserPermitted = true;
}
void
nsHtml5Parser::ContinueAfterFailedCharsetSwitch()
{
NS_PRECONDITION(GetStreamParser(),
"Tried to continue after failed charset switch without a stream parser");
GetStreamParser()->ContinueAfterFailedCharsetSwitch();
}

362
parser/html/nsHtml5Parser.h Normal file
View file

@ -0,0 +1,362 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 NS_HTML5_PARSER
#define NS_HTML5_PARSER
#include "nsAutoPtr.h"
#include "nsIParser.h"
#include "nsDeque.h"
#include "nsIURL.h"
#include "nsParserCIID.h"
#include "nsITokenizer.h"
#include "nsIContentSink.h"
#include "nsIRequest.h"
#include "nsIChannel.h"
#include "nsCOMArray.h"
#include "nsContentSink.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIInputStream.h"
#include "nsDetectionConfident.h"
#include "nsHtml5OwningUTF16Buffer.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5StreamParser.h"
#include "nsHtml5AtomTable.h"
#include "nsWeakReference.h"
#include "nsHtml5StreamListener.h"
class nsHtml5Parser final : public nsIParser,
public nsSupportsWeakReference
{
public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5Parser, nsIParser)
nsHtml5Parser();
/* Start nsIParser */
/**
* No-op for backwards compat.
*/
NS_IMETHOD_(void) SetContentSink(nsIContentSink* aSink) override;
/**
* Returns the tree op executor for backwards compat.
*/
NS_IMETHOD_(nsIContentSink*) GetContentSink() override;
/**
* Always returns "view" for backwards compat.
*/
NS_IMETHOD_(void) GetCommand(nsCString& aCommand) override;
/**
* No-op for backwards compat.
*/
NS_IMETHOD_(void) SetCommand(const char* aCommand) override;
/**
* No-op for backwards compat.
*/
NS_IMETHOD_(void) SetCommand(eParserCommands aParserCommand) override;
/**
* Call this method once you've created a parser, and want to instruct it
* about what charset to load
*
* @param aCharset the charset of a document
* @param aCharsetSource the source of the charset
*/
NS_IMETHOD_(void) SetDocumentCharset(const nsACString& aCharset, int32_t aSource) override;
/**
* Don't call. For interface compat only.
*/
NS_IMETHOD_(void) GetDocumentCharset(nsACString& aCharset, int32_t& aSource) override
{
NS_NOTREACHED("No one should call this.");
}
/**
* Get the channel associated with this parser
* @param aChannel out param that will contain the result
* @return NS_OK if successful or NS_NOT_AVAILABLE if not
*/
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
/**
* Return |this| for backwards compat.
*/
NS_IMETHOD GetDTD(nsIDTD** aDTD) override;
/**
* Get the stream parser for this parser
*/
virtual nsIStreamListener* GetStreamListener() override;
/**
* Don't call. For interface compat only.
*/
NS_IMETHOD ContinueInterruptedParsing() override;
/**
* Blocks the parser.
*/
NS_IMETHOD_(void) BlockParser() override;
/**
* Unblocks the parser.
*/
NS_IMETHOD_(void) UnblockParser() override;
/**
* Asynchronously continues parsing.
*/
NS_IMETHOD_(void) ContinueInterruptedParsingAsync() override;
/**
* Query whether the parser is enabled (i.e. not blocked) or not.
*/
NS_IMETHOD_(bool) IsParserEnabled() override;
/**
* Query whether the parser thinks it's done with parsing.
*/
NS_IMETHOD_(bool) IsComplete() override;
/**
* Set up request observer.
*
* @param aURL used for View Source title
* @param aListener a listener to forward notifications to
* @param aKey the root context key (used for document.write)
* @param aMode ignored (for interface compat only)
*/
NS_IMETHOD Parse(nsIURI* aURL,
nsIRequestObserver* aListener = nullptr,
void* aKey = 0,
nsDTDMode aMode = eDTDMode_autodetect) override;
/**
* document.write and document.close
*
* @param aSourceBuffer the argument of document.write (empty for .close())
* @param aKey a key unique to the script element that caused this call
* @param aContentType "text/html" for HTML mode, else text/plain mode
* @param aLastCall true if .close() false if .write()
* @param aMode ignored (for interface compat only)
*/
nsresult Parse(const nsAString& aSourceBuffer,
void* aKey,
const nsACString& aContentType,
bool aLastCall,
nsDTDMode aMode = eDTDMode_autodetect);
/**
* Stops the parser prematurely
*/
NS_IMETHOD Terminate() override;
/**
* Don't call. For interface backwards compat only.
*/
NS_IMETHOD ParseFragment(const nsAString& aSourceBuffer,
nsTArray<nsString>& aTagStack) override;
/**
* Don't call. For interface compat only.
*/
NS_IMETHOD BuildModel() override;
/**
* Don't call. For interface compat only.
*/
NS_IMETHOD CancelParsingEvents() override;
/**
* Don't call. For interface compat only.
*/
virtual void Reset() override;
/**
* True if the insertion point (per HTML5) is defined.
*/
virtual bool IsInsertionPointDefined() override;
/**
* Call immediately before starting to evaluate a parser-inserted script or
* in general when the spec says to define an insertion point.
*/
virtual void PushDefinedInsertionPoint() override;
/**
* Call immediately after having evaluated a parser-inserted script or
* generally want to restore to the state before the last
* PushDefinedInsertionPoint call.
*/
virtual void PopDefinedInsertionPoint() override;
/**
* Marks the HTML5 parser as not a script-created parser: Prepares the
* parser to be able to read a stream.
*
* @param aCommand the parser command (Yeah, this is bad API design. Let's
* make this better when retiring nsIParser)
*/
virtual void MarkAsNotScriptCreated(const char* aCommand) override;
/**
* True if this is a script-created HTML5 parser.
*/
virtual bool IsScriptCreated() override;
/* End nsIParser */
// Not from an external interface
// Non-inherited methods
public:
/**
* Initializes the parser to load from a channel.
*/
virtual nsresult Initialize(nsIDocument* aDoc,
nsIURI* aURI,
nsISupports* aContainer,
nsIChannel* aChannel);
inline nsHtml5Tokenizer* GetTokenizer() {
return mTokenizer;
}
void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine);
void DropStreamParser()
{
if (GetStreamParser()) {
GetStreamParser()->DropTimer();
mStreamListener->DropDelegate();
mStreamListener = nullptr;
}
}
void StartTokenizer(bool aScriptingEnabled);
void ContinueAfterFailedCharsetSwitch();
nsHtml5StreamParser* GetStreamParser()
{
if (!mStreamListener) {
return nullptr;
}
return mStreamListener->GetDelegate();
}
/**
* Parse until pending data is exhausted or a script blocks the parser
*/
nsresult ParseUntilBlocked();
private:
virtual ~nsHtml5Parser();
// State variables
/**
* Whether the last character tokenized was a carriage return (for CRLF)
*/
bool mLastWasCR;
/**
* Whether the last character tokenized was a carriage return (for CRLF)
* when preparsing document.write.
*/
bool mDocWriteSpeculativeLastWasCR;
/**
* The parser is blocking on a script
*/
bool mBlocked;
/**
* Whether the document.write() speculator is already active.
*/
bool mDocWriteSpeculatorActive;
/**
* The number of PushDefinedInsertionPoint calls we've seen without a
* matching PopDefinedInsertionPoint.
*/
int32_t mInsertionPointPushLevel;
/**
* True if document.close() has been called.
*/
bool mDocumentClosed;
bool mInDocumentWrite;
// Portable parser objects
/**
* The first buffer in the pending UTF-16 buffer queue
*/
RefPtr<nsHtml5OwningUTF16Buffer> mFirstBuffer;
/**
* The last buffer in the pending UTF-16 buffer queue. Always points
* to a sentinel object with nullptr as its parser key.
*/
nsHtml5OwningUTF16Buffer* mLastBuffer; // weak ref;
/**
* The tree operation executor
*/
RefPtr<nsHtml5TreeOpExecutor> mExecutor;
/**
* The HTML5 tree builder
*/
const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
/**
* The HTML5 tokenizer
*/
const nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
/**
* Another HTML5 tree builder for preloading document.written content.
*/
nsAutoPtr<nsHtml5TreeBuilder> mDocWriteSpeculativeTreeBuilder;
/**
* Another HTML5 tokenizer for preloading document.written content.
*/
nsAutoPtr<nsHtml5Tokenizer> mDocWriteSpeculativeTokenizer;
/**
* The stream listener holding the stream parser.
*/
RefPtr<nsHtml5StreamListener> mStreamListener;
/**
*
*/
int32_t mRootContextLineNumber;
/**
* Whether it's OK to transfer parsing back to the stream parser
*/
bool mReturnToStreamParserPermitted;
/**
* The scoped atom table
*/
nsHtml5AtomTable mAtomTable;
};
#endif

View file

@ -0,0 +1,40 @@
/* 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 "nsHtml5PlainTextUtils.h"
#include "nsHtml5AttributeName.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "mozilla/Preferences.h"
// static
nsHtml5HtmlAttributes*
nsHtml5PlainTextUtils::NewLinkAttributes()
{
nsHtml5HtmlAttributes* linkAttrs = new nsHtml5HtmlAttributes(0);
nsString* rel = new nsString(NS_LITERAL_STRING("alternate stylesheet"));
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_REL, rel, -1);
nsString* type = new nsString(NS_LITERAL_STRING("text/css"));
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TYPE, type, -1);
nsString* href = new nsString(
NS_LITERAL_STRING("resource://gre-resources/plaintext.css"));
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_HREF, href, -1);
nsresult rv;
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv) && bundleService, "The bundle service could not be loaded");
nsCOMPtr<nsIStringBundle> bundle;
rv = bundleService->CreateBundle("chrome://global/locale/browser.properties",
getter_AddRefs(bundle));
NS_ASSERTION(NS_SUCCEEDED(rv) && bundle, "chrome://global/locale/browser.properties could not be loaded");
nsXPIDLString title;
if (bundle) {
bundle->GetStringFromName(u"plainText.wordWrap", getter_Copies(title));
}
nsString* titleCopy = new nsString(title);
linkAttrs->addAttribute(nsHtml5AttributeName::ATTR_TITLE, titleCopy, -1);
return linkAttrs;
}

View file

@ -0,0 +1,16 @@
/* 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 nsHtml5PlainTextUtils_h
#define nsHtml5PlainTextUtils_h
#include "nsHtml5HtmlAttributes.h"
class nsHtml5PlainTextUtils
{
public:
static nsHtml5HtmlAttributes* NewLinkAttributes();
};
#endif // nsHtml5PlainTextUtils_h

View file

@ -0,0 +1,157 @@
/* 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 "nsIAtom.h"
#include "nsString.h"
#include "jArray.h"
#include "nsHtml5Portability.h"
#include "nsHtml5TreeBuilder.h"
nsIAtom*
nsHtml5Portability::newLocalNameFromBuffer(char16_t* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner)
{
NS_ASSERTION(!offset, "The offset should always be zero here.");
NS_ASSERTION(interner, "Didn't get an atom service.");
return interner->GetAtom(nsDependentSubstring(buf, buf + length));
}
nsString*
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;
}
nsString*
nsHtml5Portability::newEmptyString()
{
return new nsString();
}
nsString*
nsHtml5Portability::newStringFromLiteral(const char* literal)
{
nsString* str = new nsString();
str->AssignASCII(literal);
return str;
}
nsString*
nsHtml5Portability::newStringFromString(nsString* string) {
nsString* newStr = new nsString();
newStr->Assign(*string);
return newStr;
}
jArray<char16_t,int32_t>
nsHtml5Portability::newCharArrayFromLocal(nsIAtom* local)
{
nsAutoString temp;
local->ToString(temp);
int32_t len = temp.Length();
jArray<char16_t,int32_t> arr = jArray<char16_t,int32_t>::newJArray(len);
memcpy(arr, temp.BeginReading(), len * sizeof(char16_t));
return arr;
}
jArray<char16_t,int32_t>
nsHtml5Portability::newCharArrayFromString(nsString* string)
{
int32_t len = string->Length();
jArray<char16_t,int32_t> arr = jArray<char16_t,int32_t>::newJArray(len);
memcpy(arr, string->BeginReading(), len * sizeof(char16_t));
return arr;
}
nsIAtom*
nsHtml5Portability::newLocalFromLocal(nsIAtom* local, nsHtml5AtomTable* interner)
{
NS_PRECONDITION(local, "Atom was null.");
NS_PRECONDITION(interner, "Atom table was null");
if (!local->IsStaticAtom()) {
nsAutoString str;
local->ToString(str);
local = interner->GetAtom(str);
}
return local;
}
void
nsHtml5Portability::releaseString(nsString* str)
{
delete str;
}
bool
nsHtml5Portability::localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length)
{
return local->Equals(nsDependentSubstring(buf + offset, buf + offset + length));
}
bool
nsHtml5Portability::lowerCaseLiteralIsPrefixOfIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* 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;
}
bool
nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString(const char* lowerCaseLiteral, nsString* string)
{
if (!string) {
return false;
}
return string->LowerCaseEqualsASCII(lowerCaseLiteral);
}
bool
nsHtml5Portability::literalEqualsString(const char* literal, nsString* string)
{
if (!string) {
return false;
}
return string->EqualsASCII(literal);
}
bool
nsHtml5Portability::stringEqualsString(nsString* one, nsString* other)
{
return one->Equals(*other);
}
void
nsHtml5Portability::initializeStatics()
{
}
void
nsHtml5Portability::releaseStatics()
{
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2008-2015 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit Portability.java instead and regenerate.
*/
#ifndef nsHtml5Portability_h
#define nsHtml5Portability_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
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 jArray<char16_t,int32_t> newCharArrayFromLocal(nsIAtom* local);
static jArray<char16_t,int32_t> newCharArrayFromString(nsString* 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 void initializeStatics();
static void releaseStatics();
};
#endif

449
parser/html/nsHtml5RefPtr.h Normal file
View file

@ -0,0 +1,449 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 nsHtml5RefPtr_h
#define nsHtml5RefPtr_h
#include "nsThreadUtils.h"
template <class T>
class nsHtml5RefPtrReleaser : public mozilla::Runnable
{
private:
T* mPtr;
public:
explicit nsHtml5RefPtrReleaser(T* aPtr)
: mPtr(aPtr)
{}
NS_IMETHOD Run() override
{
mPtr->Release();
return NS_OK;
}
};
// template <class T> class nsHtml5RefPtrGetterAddRefs;
/**
* Like nsRefPtr except release is proxied to the main thread. Mostly copied
* from nsRefPtr.
*/
template <class T>
class nsHtml5RefPtr
{
private:
void
assign_with_AddRef( T* rawPtr )
{
if ( rawPtr )
rawPtr->AddRef();
assign_assuming_AddRef(rawPtr);
}
void**
begin_assignment()
{
assign_assuming_AddRef(0);
return reinterpret_cast<void**>(&mRawPtr);
}
void
assign_assuming_AddRef( T* newPtr )
{
T* oldPtr = mRawPtr;
mRawPtr = newPtr;
if ( oldPtr )
release(oldPtr);
}
void
release( T* aPtr )
{
nsCOMPtr<nsIRunnable> releaser = new nsHtml5RefPtrReleaser<T>(aPtr);
if (NS_FAILED(NS_DispatchToMainThread(releaser)))
{
NS_WARNING("Failed to dispatch releaser event.");
}
}
private:
T* mRawPtr;
public:
typedef T element_type;
~nsHtml5RefPtr()
{
if ( mRawPtr )
release(mRawPtr);
}
// Constructors
nsHtml5RefPtr()
: mRawPtr(0)
// default constructor
{
}
nsHtml5RefPtr( const nsHtml5RefPtr<T>& aSmartPtr )
: mRawPtr(aSmartPtr.mRawPtr)
// copy-constructor
{
if ( mRawPtr )
mRawPtr->AddRef();
}
explicit nsHtml5RefPtr( T* aRawPtr )
: mRawPtr(aRawPtr)
// construct from a raw pointer (of the right type)
{
if ( mRawPtr )
mRawPtr->AddRef();
}
explicit nsHtml5RefPtr( const already_AddRefed<T>& aSmartPtr )
: mRawPtr(aSmartPtr.mRawPtr)
// construct from |dont_AddRef(expr)|
{
}
// Assignment operators
nsHtml5RefPtr<T>&
operator=( const nsHtml5RefPtr<T>& rhs )
// copy assignment operator
{
assign_with_AddRef(rhs.mRawPtr);
return *this;
}
nsHtml5RefPtr<T>&
operator=( T* rhs )
// assign from a raw pointer (of the right type)
{
assign_with_AddRef(rhs);
return *this;
}
nsHtml5RefPtr<T>&
operator=( const already_AddRefed<T>& rhs )
// assign from |dont_AddRef(expr)|
{
assign_assuming_AddRef(rhs.mRawPtr);
return *this;
}
// Other pointer operators
void
swap( nsHtml5RefPtr<T>& rhs )
// ...exchange ownership with |rhs|; can save a pair of refcount operations
{
T* temp = rhs.mRawPtr;
rhs.mRawPtr = mRawPtr;
mRawPtr = temp;
}
void
swap( T*& rhs )
// ...exchange ownership with |rhs|; can save a pair of refcount operations
{
T* temp = rhs;
rhs = mRawPtr;
mRawPtr = temp;
}
already_AddRefed<T>
forget()
// return the value of mRawPtr and null out mRawPtr. Useful for
// already_AddRefed return values.
{
T* temp = 0;
swap(temp);
return temp;
}
template <typename I>
void
forget( I** rhs)
// Set the target of rhs to the value of mRawPtr and null out mRawPtr.
// Useful to avoid unnecessary AddRef/Release pairs with "out"
// parameters where rhs bay be a T** or an I** where I is a base class
// of T.
{
NS_ASSERTION(rhs, "Null pointer passed to forget!");
*rhs = mRawPtr;
mRawPtr = 0;
}
T*
get() const
/*
Prefer the implicit conversion provided automatically by |operator T*() const|.
Use |get()| to resolve ambiguity or to get a castable pointer.
*/
{
return const_cast<T*>(mRawPtr);
}
operator T*() const
/*
...makes an |nsHtml5RefPtr| act like its underlying raw pointer type whenever it
is used in a context where a raw pointer is expected. It is this operator
that makes an |nsHtml5RefPtr| substitutable for a raw pointer.
Prefer the implicit use of this operator to calling |get()|, except where
necessary to resolve ambiguity.
*/
{
return get();
}
T*
operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsHtml5RefPtr with operator->().");
return get();
}
nsHtml5RefPtr<T>*
get_address()
// This is not intended to be used by clients. See |address_of|
// below.
{
return this;
}
const nsHtml5RefPtr<T>*
get_address() const
// This is not intended to be used by clients. See |address_of|
// below.
{
return this;
}
public:
T&
operator*() const
{
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsHtml5RefPtr with operator*().");
return *get();
}
T**
StartAssignment()
{
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
return reinterpret_cast<T**>(begin_assignment());
#else
assign_assuming_AddRef(0);
return reinterpret_cast<T**>(&mRawPtr);
#endif
}
};
template <class T>
inline
nsHtml5RefPtr<T>*
address_of( nsHtml5RefPtr<T>& aPtr )
{
return aPtr.get_address();
}
template <class T>
inline
const nsHtml5RefPtr<T>*
address_of( const nsHtml5RefPtr<T>& aPtr )
{
return aPtr.get_address();
}
template <class T>
class nsHtml5RefPtrGetterAddRefs
/*
...
This class is designed to be used for anonymous temporary objects in the
argument list of calls that return COM interface pointers, e.g.,
nsHtml5RefPtr<IFoo> fooP;
...->GetAddRefedPointer(getter_AddRefs(fooP))
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
When initialized with a |nsHtml5RefPtr|, as in the example above, it returns
a |void**|, a |T**|, or an |nsISupports**| as needed, that the
outer call (|GetAddRefedPointer| in this case) can fill in.
This type should be a nested class inside |nsHtml5RefPtr<T>|.
*/
{
public:
explicit
nsHtml5RefPtrGetterAddRefs( nsHtml5RefPtr<T>& aSmartPtr )
: mTargetSmartPtr(aSmartPtr)
{
// nothing else to do
}
operator void**()
{
return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
}
operator T**()
{
return mTargetSmartPtr.StartAssignment();
}
T*&
operator*()
{
return *(mTargetSmartPtr.StartAssignment());
}
private:
nsHtml5RefPtr<T>& mTargetSmartPtr;
};
template <class T>
inline
nsHtml5RefPtrGetterAddRefs<T>
getter_AddRefs( nsHtml5RefPtr<T>& aSmartPtr )
/*
Used around a |nsHtml5RefPtr| when
...makes the class |nsHtml5RefPtrGetterAddRefs<T>| invisible.
*/
{
return nsHtml5RefPtrGetterAddRefs<T>(aSmartPtr);
}
// Comparing two |nsHtml5RefPtr|s
template <class T, class U>
inline
bool
operator==( const nsHtml5RefPtr<T>& lhs, const nsHtml5RefPtr<U>& rhs )
{
return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs.get());
}
template <class T, class U>
inline
bool
operator!=( const nsHtml5RefPtr<T>& lhs, const nsHtml5RefPtr<U>& rhs )
{
return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs.get());
}
// Comparing an |nsHtml5RefPtr| to a raw pointer
template <class T, class U>
inline
bool
operator==( const nsHtml5RefPtr<T>& lhs, const U* rhs )
{
return static_cast<const T*>(lhs.get()) == static_cast<const U*>(rhs);
}
template <class T, class U>
inline
bool
operator==( const U* lhs, const nsHtml5RefPtr<T>& rhs )
{
return static_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
}
template <class T, class U>
inline
bool
operator!=( const nsHtml5RefPtr<T>& lhs, const U* rhs )
{
return static_cast<const T*>(lhs.get()) != static_cast<const U*>(rhs);
}
template <class T, class U>
inline
bool
operator!=( const U* lhs, const nsHtml5RefPtr<T>& rhs )
{
return static_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
}
template <class T, class U>
inline
bool
operator==( const nsHtml5RefPtr<T>& lhs, U* rhs )
{
return static_cast<const T*>(lhs.get()) == const_cast<const U*>(rhs);
}
template <class T, class U>
inline
bool
operator==( U* lhs, const nsHtml5RefPtr<T>& rhs )
{
return const_cast<const U*>(lhs) == static_cast<const T*>(rhs.get());
}
template <class T, class U>
inline
bool
operator!=( const nsHtml5RefPtr<T>& lhs, U* rhs )
{
return static_cast<const T*>(lhs.get()) != const_cast<const U*>(rhs);
}
template <class T, class U>
inline
bool
operator!=( U* lhs, const nsHtml5RefPtr<T>& rhs )
{
return const_cast<const U*>(lhs) != static_cast<const T*>(rhs.get());
}
// Comparing an |nsHtml5RefPtr| to |0|
template <class T>
inline
bool
operator==( const nsHtml5RefPtr<T>& lhs, decltype(nullptr) )
{
return lhs.get() == nullptr;
}
template <class T>
inline
bool
operator==( decltype(nullptr), const nsHtml5RefPtr<T>& rhs )
{
return nullptr == rhs.get();
}
template <class T>
inline
bool
operator!=( const nsHtml5RefPtr<T>& lhs, decltype(nullptr) )
{
return lhs.get() != nullptr;
}
template <class T>
inline
bool
operator!=( decltype(nullptr), const nsHtml5RefPtr<T>& rhs )
{
return nullptr != rhs.get();
}
#endif // !defined(nsHtml5RefPtr_h)

View file

@ -0,0 +1,34 @@
/* 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 "nsHtml5ReleasableAttributeName.h"
#include "nsHtml5Portability.h"
#include "nsHtml5AtomTable.h"
nsHtml5ReleasableAttributeName::nsHtml5ReleasableAttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix)
: nsHtml5AttributeName(uri, local, prefix)
{
}
nsHtml5AttributeName*
nsHtml5ReleasableAttributeName::cloneAttributeName(nsHtml5AtomTable* aInterner)
{
nsIAtom* l = getLocal(0);
if (aInterner) {
if (!l->IsStaticAtom()) {
nsAutoString str;
l->ToString(str);
l = aInterner->GetAtom(str);
}
}
return new nsHtml5ReleasableAttributeName(nsHtml5AttributeName::ALL_NO_NS,
nsHtml5AttributeName::SAME_LOCAL(l),
nsHtml5AttributeName::ALL_NO_PREFIX);
}
void
nsHtml5ReleasableAttributeName::release()
{
delete this;
}

View file

@ -0,0 +1,21 @@
/* 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 nsHtml5ReleasableAttributeName_h
#define nsHtml5ReleasableAttributeName_h
#include "nsHtml5AttributeName.h"
#include "mozilla/Attributes.h"
class nsHtml5AtomTable;
class nsHtml5ReleasableAttributeName final : public nsHtml5AttributeName
{
public:
nsHtml5ReleasableAttributeName(int32_t* uri, nsIAtom** local, nsIAtom** prefix);
virtual nsHtml5AttributeName* cloneAttributeName(nsHtml5AtomTable* aInterner);
virtual void release();
};
#endif // nsHtml5ReleasableAttributeName_h

View file

@ -0,0 +1,30 @@
/* 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 "nsHtml5ReleasableElementName.h"
nsHtml5ReleasableElementName::nsHtml5ReleasableElementName(nsIAtom* name)
: nsHtml5ElementName(name)
{
}
void
nsHtml5ReleasableElementName::release()
{
delete this;
}
nsHtml5ElementName*
nsHtml5ReleasableElementName::cloneElementName(nsHtml5AtomTable* aInterner)
{
nsIAtom* l = name;
if (aInterner) {
if (!l->IsStaticAtom()) {
nsAutoString str;
l->ToString(str);
l = aInterner->GetAtom(str);
}
}
return new nsHtml5ReleasableElementName(l);
}

View file

@ -0,0 +1,19 @@
/* 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 nsHtml5ReleasableElementName_h
#define nsHtml5ReleasableElementName_h
#include "nsHtml5ElementName.h"
#include "mozilla/Attributes.h"
class nsHtml5ReleasableElementName final : public nsHtml5ElementName
{
public:
explicit nsHtml5ReleasableElementName(nsIAtom* name);
virtual void release();
virtual nsHtml5ElementName* cloneElementName(nsHtml5AtomTable* interner);
};
#endif // nsHtml5ReleasableElementName_h

View file

@ -0,0 +1,40 @@
/* 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 "nsHtml5SVGLoadDispatcher.h"
#include "nsPresContext.h"
#include "nsIPresShell.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/EventDispatcher.h"
#include "nsIDocument.h"
using namespace mozilla;
nsHtml5SVGLoadDispatcher::nsHtml5SVGLoadDispatcher(nsIContent* aElement)
: mElement(aElement)
, mDocument(mElement->OwnerDoc())
{
mDocument->BlockOnload();
}
NS_IMETHODIMP
nsHtml5SVGLoadDispatcher::Run()
{
WidgetEvent event(true, eSVGLoad);
event.mFlags.mBubbles = false;
// Do we care about forcing presshell creation if it hasn't happened yet?
// That is, should this code flush or something? Does it really matter?
// For that matter, do we really want to try getting the prescontext?
// Does this event ever want one?
RefPtr<nsPresContext> ctx;
nsCOMPtr<nsIPresShell> shell = mElement->OwnerDoc()->GetShell();
if (shell) {
ctx = shell->GetPresContext();
}
EventDispatcher::Dispatch(mElement, ctx, &event);
// Unblocking onload on the same document that it was blocked even if
// the element has moved between docs since blocking.
mDocument->UnblockOnload(false);
return NS_OK;
}

View file

@ -0,0 +1,21 @@
/* 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 nsHtml5SVGLoadDispatcher_h
#define nsHtml5SVGLoadDispatcher_h
#include "nsThreadUtils.h"
#include "nsIContent.h"
class nsHtml5SVGLoadDispatcher : public mozilla::Runnable
{
private:
nsCOMPtr<nsIContent> mElement;
nsCOMPtr<nsIDocument> mDocument;
public:
explicit nsHtml5SVGLoadDispatcher(nsIContent* aElement);
NS_IMETHOD Run();
};
#endif // nsHtml5SVGLoadDispatcher_h

View file

@ -0,0 +1,36 @@
/* 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 "nsHtml5Speculation.h"
using namespace mozilla;
nsHtml5Speculation::nsHtml5Speculation(nsHtml5OwningUTF16Buffer* aBuffer,
int32_t aStart,
int32_t aStartLineNumber,
nsAHtml5TreeBuilderState* aSnapshot)
: mBuffer(aBuffer)
, mStart(aStart)
, mStartLineNumber(aStartLineNumber)
, mSnapshot(aSnapshot)
{
MOZ_COUNT_CTOR(nsHtml5Speculation);
}
nsHtml5Speculation::~nsHtml5Speculation()
{
MOZ_COUNT_DTOR(nsHtml5Speculation);
}
void
nsHtml5Speculation::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
{
mOpQueue.AppendElements(Move(aOpQueue));
}
void
nsHtml5Speculation::FlushToSink(nsAHtml5TreeOpSink* aSink)
{
aSink->MoveOpsFrom(mOpQueue);
}

View file

@ -0,0 +1,75 @@
/* 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 nsHtml5Speculation_h
#define nsHtml5Speculation_h
#include "nsHtml5OwningUTF16Buffer.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5TreeOperation.h"
#include "nsAHtml5TreeOpSink.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "mozilla/Attributes.h"
class nsHtml5Speculation final : public nsAHtml5TreeOpSink
{
public:
nsHtml5Speculation(nsHtml5OwningUTF16Buffer* aBuffer,
int32_t aStart,
int32_t aStartLineNumber,
nsAHtml5TreeBuilderState* aSnapshot);
~nsHtml5Speculation();
nsHtml5OwningUTF16Buffer* GetBuffer()
{
return mBuffer;
}
int32_t GetStart()
{
return mStart;
}
int32_t GetStartLineNumber()
{
return mStartLineNumber;
}
nsAHtml5TreeBuilderState* GetSnapshot()
{
return mSnapshot;
}
/**
* Flush the operations from the tree operations from the argument
* queue unconditionally.
*/
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue);
void FlushToSink(nsAHtml5TreeOpSink* aSink);
private:
/**
* The first buffer in the pending UTF-16 buffer queue
*/
RefPtr<nsHtml5OwningUTF16Buffer> mBuffer;
/**
* The start index of this speculation in the first buffer
*/
int32_t mStart;
/**
* The current line number at the start of the speculation
*/
int32_t mStartLineNumber;
nsAutoPtr<nsAHtml5TreeBuilderState> mSnapshot;
nsTArray<nsHtml5TreeOperation> mOpQueue;
};
#endif // nsHtml5Speculation_h

View file

@ -0,0 +1,88 @@
/* 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 "nsHtml5SpeculativeLoad.h"
#include "nsHtml5TreeOpExecutor.h"
nsHtml5SpeculativeLoad::nsHtml5SpeculativeLoad()
#ifdef DEBUG
: mOpCode(eSpeculativeLoadUninitialized)
#endif
{
MOZ_COUNT_CTOR(nsHtml5SpeculativeLoad);
}
nsHtml5SpeculativeLoad::~nsHtml5SpeculativeLoad()
{
MOZ_COUNT_DTOR(nsHtml5SpeculativeLoad);
NS_ASSERTION(mOpCode != eSpeculativeLoadUninitialized,
"Uninitialized speculative load.");
}
void
nsHtml5SpeculativeLoad::Perform(nsHtml5TreeOpExecutor* aExecutor)
{
switch (mOpCode) {
case eSpeculativeLoadBase:
aExecutor->SetSpeculationBase(mUrl);
break;
case eSpeculativeLoadCSP:
aExecutor->AddSpeculationCSP(mMetaCSP);
break;
case eSpeculativeLoadMetaReferrer:
aExecutor->SetSpeculationReferrerPolicy(mReferrerPolicy);
break;
case eSpeculativeLoadImage:
aExecutor->PreloadImage(mUrl, mCrossOrigin, mSrcset, mSizes, mReferrerPolicy);
break;
case eSpeculativeLoadOpenPicture:
aExecutor->PreloadOpenPicture();
break;
case eSpeculativeLoadEndPicture:
aExecutor->PreloadEndPicture();
break;
case eSpeculativeLoadPictureSource:
aExecutor->PreloadPictureSource(mSrcset, mSizes, mTypeOrCharsetSourceOrDocumentMode,
mMedia);
break;
case eSpeculativeLoadScript:
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
mCrossOrigin, mIntegrity, false);
break;
case eSpeculativeLoadScriptFromHead:
aExecutor->PreloadScript(mUrl, mCharset, mTypeOrCharsetSourceOrDocumentMode,
mCrossOrigin, mIntegrity, true);
break;
case eSpeculativeLoadStyle:
aExecutor->PreloadStyle(mUrl, mCharset, mCrossOrigin, mIntegrity);
break;
case eSpeculativeLoadManifest:
aExecutor->ProcessOfflineManifest(mUrl);
break;
case eSpeculativeLoadSetDocumentCharset: {
nsAutoCString narrowName;
CopyUTF16toUTF8(mCharset, narrowName);
NS_ASSERTION(mTypeOrCharsetSourceOrDocumentMode.Length() == 1,
"Unexpected charset source string");
int32_t intSource = (int32_t)mTypeOrCharsetSourceOrDocumentMode.First();
aExecutor->SetDocumentCharsetAndSource(narrowName,
intSource);
}
break;
case eSpeculativeLoadSetDocumentMode: {
NS_ASSERTION(mTypeOrCharsetSourceOrDocumentMode.Length() == 1,
"Unexpected document mode string");
nsHtml5DocumentMode mode =
(nsHtml5DocumentMode)mTypeOrCharsetSourceOrDocumentMode.First();
aExecutor->SetDocumentMode(mode);
}
break;
case eSpeculativeLoadPreconnect:
aExecutor->Preconnect(mUrl, mCrossOrigin);
break;
default:
NS_NOTREACHED("Bogus speculative load.");
break;
}
}

View file

@ -0,0 +1,263 @@
/* 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 nsHtml5SpeculativeLoad_h
#define nsHtml5SpeculativeLoad_h
#include "nsString.h"
#include "nsContentUtils.h"
class nsHtml5TreeOpExecutor;
enum eHtml5SpeculativeLoad {
#ifdef DEBUG
eSpeculativeLoadUninitialized,
#endif
eSpeculativeLoadBase,
eSpeculativeLoadCSP,
eSpeculativeLoadMetaReferrer,
eSpeculativeLoadImage,
eSpeculativeLoadOpenPicture,
eSpeculativeLoadEndPicture,
eSpeculativeLoadPictureSource,
eSpeculativeLoadScript,
eSpeculativeLoadScriptFromHead,
eSpeculativeLoadStyle,
eSpeculativeLoadManifest,
eSpeculativeLoadSetDocumentCharset,
eSpeculativeLoadSetDocumentMode,
eSpeculativeLoadPreconnect
};
class nsHtml5SpeculativeLoad {
public:
nsHtml5SpeculativeLoad();
~nsHtml5SpeculativeLoad();
inline void InitBase(const nsAString& aUrl)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadBase;
mUrl.Assign(aUrl);
}
inline void InitMetaCSP(const nsAString& aCSP) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadCSP;
mMetaCSP.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aCSP));
}
inline void InitMetaReferrerPolicy(const nsAString& aReferrerPolicy) {
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadMetaReferrer;
mReferrerPolicy.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
}
inline void InitImage(const nsAString& aUrl,
const nsAString& aCrossOrigin,
const nsAString& aReferrerPolicy,
const nsAString& aSrcset,
const nsAString& aSizes)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadImage;
mUrl.Assign(aUrl);
mCrossOrigin.Assign(aCrossOrigin);
mReferrerPolicy.Assign(
nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(aReferrerPolicy));
mSrcset.Assign(aSrcset);
mSizes.Assign(aSizes);
}
// <picture> elements have multiple <source> nodes followed by an <img>,
// where we use the first valid source, which may be the img. Because we
// can't determine validity at this point without parsing CSS and getting
// main thread state, we push preload operations for picture pushed and
// popped, so that the target of the preload ops can determine what picture
// and nesting level each source/img from the main preloading code exists
// at.
inline void InitOpenPicture()
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadOpenPicture;
}
inline void InitEndPicture()
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadEndPicture;
}
inline void InitPictureSource(const nsAString& aSrcset,
const nsAString& aSizes,
const nsAString& aType,
const nsAString& 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);
}
inline void InitScript(const nsAString& aUrl,
const nsAString& aCharset,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& 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);
}
inline void InitStyle(const nsAString& aUrl, const nsAString& aCharset,
const nsAString& aCrossOrigin,
const nsAString& 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);
}
/**
* "Speculative" manifest loads aren't truly speculative--if a manifest
* gets loaded, we are committed to it. There can never be a <script>
* before the manifest, so the situation of having to undo a manifest due
* to document.write() never arises. The reason why a parser
* thread-discovered manifest gets loaded via the speculative load queue
* as opposed to tree operation queue is that the manifest must get
* processed before any actual speculative loads such as scripts. Thus,
* 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)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadManifest;
mUrl.Assign(aUrl);
}
/**
* "Speculative" charset setting isn't truly speculative. If the charset
* is set via this operation, we are committed to it unless chardet or
* a late meta cause a reload. The reason why a parser
* thread-discovered charset gets communicated via the speculative load
* queue as opposed to tree operation queue is that the charset change
* must get processed before any actual speculative loads such as style
* sheets. Thus, encoding decisions by the parser thread have to maintain
* the queue order relative to true speculative loads. See bug 675499.
*/
inline void InitSetDocumentCharset(nsACString& aCharset,
int32_t aCharsetSource)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadSetDocumentCharset;
CopyUTF8toUTF16(aCharset, mCharset);
mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aCharsetSource);
}
/**
* Speculative document mode setting isn't really speculative. Once it
* happens, we are committed to it. However, this information needs to
* travel in the speculation queue in order to have this information
* available before parsing the speculatively loaded style sheets.
*/
inline void InitSetDocumentMode(nsHtml5DocumentMode aMode)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadSetDocumentMode;
mTypeOrCharsetSourceOrDocumentMode.Assign((char16_t)aMode);
}
inline void InitPreconnect(const nsAString& aUrl,
const nsAString& aCrossOrigin)
{
NS_PRECONDITION(mOpCode == eSpeculativeLoadUninitialized,
"Trying to reinitialize a speculative load!");
mOpCode = eSpeculativeLoadPreconnect;
mUrl.Assign(aUrl);
mCrossOrigin.Assign(aCrossOrigin);
}
void Perform(nsHtml5TreeOpExecutor* aExecutor);
private:
eHtml5SpeculativeLoad mOpCode;
nsString mUrl;
nsString mReferrerPolicy;
nsString mMetaCSP;
/**
* If mOpCode is eSpeculativeLoadStyle or eSpeculativeLoadScript[FromHead]
* then this is the value of the "charset" attribute. For
* eSpeculativeLoadSetDocumentCharset it is the charset that the
* document's charset is being set to. Otherwise it's empty.
*/
nsString mCharset;
/**
* If mOpCode is eSpeculativeLoadSetDocumentCharset, this is a
* one-character string whose single character's code point is to be
* interpreted as a charset source integer. If mOpCode is
* eSpeculativeLoadSetDocumentMode, this is a one-character string whose
* single character's code point is to be interpreted as an
* nsHtml5DocumentMode. Otherwise, it is empty or the value of the type
* attribute.
*/
nsString mTypeOrCharsetSourceOrDocumentMode;
/**
* If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadScript[FromHead]
* or eSpeculativeLoadPreconnect this is the value of the "crossorigin"
* attribute. If the attribute is not set, this will be a void string.
*/
nsString mCrossOrigin;
/**
* If mOpCode is eSpeculativeLoadImage or eSpeculativeLoadPictureSource,
* this is the value of "srcset" attribute. If the attribute is not set,
* this will be a void string.
*/
nsString mSrcset;
/**
* If mOpCode is eSpeculativeLoadPictureSource, this is the value of "sizes"
* attribute. If the attribute is not set, this will be a void string.
*/
nsString mSizes;
/**
* If mOpCode is eSpeculativeLoadPictureSource, this is the value of "media"
* attribute. If the attribute is not set, this will be a void string.
*/
nsString mMedia;
/**
* If mOpCode is eSpeculativeLoadScript[FromHead], this is the value of the
* "integrity" attribute. If the attribute is not set, this will be a void
* string.
*/
nsString mIntegrity;
};
#endif // nsHtml5SpeculativeLoad_h

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2007-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit StackNode.java instead and regenerate.
*/
#define nsHtml5StackNode_cpp__
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5MetaScanner.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5Portability.h"
#include "nsHtml5StackNode.h"
int32_t
nsHtml5StackNode::getGroup()
{
return flags & NS_HTML5ELEMENT_NAME_GROUP_MASK;
}
bool
nsHtml5StackNode::isScoping()
{
return (flags & NS_HTML5ELEMENT_NAME_SCOPING);
}
bool
nsHtml5StackNode::isSpecial()
{
return (flags & NS_HTML5ELEMENT_NAME_SPECIAL);
}
bool
nsHtml5StackNode::isFosterParenting()
{
return (flags & NS_HTML5ELEMENT_NAME_FOSTER_PARENTING);
}
bool
nsHtml5StackNode::isHtmlIntegrationPoint()
{
return (flags & NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT);
}
nsHtml5StackNode::nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContentHandle* node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes)
: flags(flags),
name(name),
popName(popName),
ns(ns),
node(node),
attributes(attributes),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
}
nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node)
: flags(elementName->getFlags()),
name(elementName->name),
popName(elementName->name),
ns(kNameSpaceID_XHTML),
node(node),
attributes(nullptr),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
}
nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsHtml5HtmlAttributes* attributes)
: flags(elementName->getFlags()),
name(elementName->name),
popName(elementName->name),
ns(kNameSpaceID_XHTML),
node(node),
attributes(attributes),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
}
nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName)
: flags(elementName->getFlags()),
name(elementName->name),
popName(popName),
ns(kNameSpaceID_XHTML),
node(node),
attributes(nullptr),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
}
nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContentHandle* node)
: flags(prepareSvgFlags(elementName->getFlags())),
name(elementName->name),
popName(popName),
ns(kNameSpaceID_SVG),
node(node),
attributes(nullptr),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
}
nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName, bool markAsIntegrationPoint)
: flags(prepareMathFlags(elementName->getFlags(), markAsIntegrationPoint)),
name(elementName->name),
popName(popName),
ns(kNameSpaceID_MathML),
node(node),
attributes(nullptr),
refcount(1)
{
MOZ_COUNT_CTOR(nsHtml5StackNode);
}
int32_t
nsHtml5StackNode::prepareSvgFlags(int32_t flags)
{
flags &= ~(NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
if ((flags & NS_HTML5ELEMENT_NAME_SCOPING_AS_SVG)) {
flags |= (NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT);
}
return flags;
}
int32_t
nsHtml5StackNode::prepareMathFlags(int32_t flags, bool markAsIntegrationPoint)
{
flags &= ~(NS_HTML5ELEMENT_NAME_FOSTER_PARENTING | NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
if ((flags & NS_HTML5ELEMENT_NAME_SCOPING_AS_MATHML)) {
flags |= (NS_HTML5ELEMENT_NAME_SCOPING | NS_HTML5ELEMENT_NAME_SPECIAL);
}
if (markAsIntegrationPoint) {
flags |= NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT;
}
return flags;
}
nsHtml5StackNode::~nsHtml5StackNode()
{
MOZ_COUNT_DTOR(nsHtml5StackNode);
delete attributes;
}
void
nsHtml5StackNode::dropAttributes()
{
attributes = nullptr;
}
void
nsHtml5StackNode::retain()
{
refcount++;
}
void
nsHtml5StackNode::release()
{
refcount--;
if (!refcount) {
delete this;
}
}
void
nsHtml5StackNode::initializeStatics()
{
}
void
nsHtml5StackNode::releaseStatics()
{
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2007-2011 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit StackNode.java instead and regenerate.
*/
#ifndef nsHtml5StackNode_h
#define nsHtml5StackNode_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5StackNode
{
public:
int32_t flags;
nsIAtom* name;
nsIAtom* popName;
int32_t ns;
nsIContentHandle* node;
nsHtml5HtmlAttributes* attributes;
private:
int32_t refcount;
public:
inline int32_t getFlags()
{
return flags;
}
int32_t getGroup();
bool isScoping();
bool isSpecial();
bool isFosterParenting();
bool isHtmlIntegrationPoint();
nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContentHandle* node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes);
nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node);
nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsHtml5HtmlAttributes* attributes);
nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName);
nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContentHandle* node);
nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName, bool markAsIntegrationPoint);
private:
static int32_t prepareSvgFlags(int32_t flags);
static int32_t prepareMathFlags(int32_t flags, bool markAsIntegrationPoint);
public:
~nsHtml5StackNode();
void dropAttributes();
void retain();
void release();
static void initializeStatics();
static void releaseStatics();
};
#endif

View file

@ -0,0 +1,182 @@
/*
* Copyright (c) 2009-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit StateSnapshot.java instead and regenerate.
*/
#define nsHtml5StateSnapshot_cpp__
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5MetaScanner.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5UTF16Buffer.h"
#include "nsHtml5Portability.h"
#include "nsHtml5StateSnapshot.h"
nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContentHandle* formPointer, nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks)
: stack(stack),
listOfActiveFormattingElements(listOfActiveFormattingElements),
templateModeStack(templateModeStack),
formPointer(formPointer),
headPointer(headPointer),
deepTreeSurrogateParent(deepTreeSurrogateParent),
mode(mode),
originalMode(originalMode),
framesetOk(framesetOk),
needToDropLF(needToDropLF),
quirks(quirks)
{
MOZ_COUNT_CTOR(nsHtml5StateSnapshot);
}
jArray<nsHtml5StackNode*,int32_t>
nsHtml5StateSnapshot::getStack()
{
return stack;
}
jArray<int32_t,int32_t>
nsHtml5StateSnapshot::getTemplateModeStack()
{
return templateModeStack;
}
jArray<nsHtml5StackNode*,int32_t>
nsHtml5StateSnapshot::getListOfActiveFormattingElements()
{
return listOfActiveFormattingElements;
}
nsIContentHandle*
nsHtml5StateSnapshot::getFormPointer()
{
return formPointer;
}
nsIContentHandle*
nsHtml5StateSnapshot::getHeadPointer()
{
return headPointer;
}
nsIContentHandle*
nsHtml5StateSnapshot::getDeepTreeSurrogateParent()
{
return deepTreeSurrogateParent;
}
int32_t
nsHtml5StateSnapshot::getMode()
{
return mode;
}
int32_t
nsHtml5StateSnapshot::getOriginalMode()
{
return originalMode;
}
bool
nsHtml5StateSnapshot::isFramesetOk()
{
return framesetOk;
}
bool
nsHtml5StateSnapshot::isNeedToDropLF()
{
return needToDropLF;
}
bool
nsHtml5StateSnapshot::isQuirks()
{
return quirks;
}
int32_t
nsHtml5StateSnapshot::getListOfActiveFormattingElementsLength()
{
return listOfActiveFormattingElements.length;
}
int32_t
nsHtml5StateSnapshot::getStackLength()
{
return stack.length;
}
int32_t
nsHtml5StateSnapshot::getTemplateModeStackLength()
{
return templateModeStack.length;
}
nsHtml5StateSnapshot::~nsHtml5StateSnapshot()
{
MOZ_COUNT_DTOR(nsHtml5StateSnapshot);
for (int32_t i = 0; i < stack.length; i++) {
stack[i]->release();
}
for (int32_t i = 0; i < listOfActiveFormattingElements.length; i++) {
if (listOfActiveFormattingElements[i]) {
listOfActiveFormattingElements[i]->release();
}
}
}
void
nsHtml5StateSnapshot::initializeStatics()
{
}
void
nsHtml5StateSnapshot::releaseStatics()
{
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2009-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit StateSnapshot.java instead and regenerate.
*/
#ifndef nsHtml5StateSnapshot_h
#define nsHtml5StateSnapshot_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5Portability;
class nsHtml5StateSnapshot : public nsAHtml5TreeBuilderState
{
private:
autoJArray<nsHtml5StackNode*,int32_t> stack;
autoJArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements;
autoJArray<int32_t,int32_t> templateModeStack;
nsIContentHandle* formPointer;
nsIContentHandle* headPointer;
nsIContentHandle* deepTreeSurrogateParent;
int32_t mode;
int32_t originalMode;
bool framesetOk;
bool needToDropLF;
bool quirks;
public:
nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContentHandle* formPointer, nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks);
jArray<nsHtml5StackNode*,int32_t> getStack();
jArray<int32_t,int32_t> getTemplateModeStack();
jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements();
nsIContentHandle* getFormPointer();
nsIContentHandle* getHeadPointer();
nsIContentHandle* getDeepTreeSurrogateParent();
int32_t getMode();
int32_t getOriginalMode();
bool isFramesetOk();
bool isNeedToDropLF();
bool isQuirks();
int32_t getListOfActiveFormattingElementsLength();
int32_t getStackLength();
int32_t getTemplateModeStackLength();
~nsHtml5StateSnapshot();
static void initializeStatics();
static void releaseStatics();
};
#endif

View file

@ -0,0 +1,82 @@
/* 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 "nsHtml5StreamListener.h"
NS_IMPL_ADDREF(nsHtml5StreamListener)
NS_IMPL_RELEASE(nsHtml5StreamListener)
NS_INTERFACE_MAP_BEGIN(nsHtml5StreamListener)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
NS_INTERFACE_MAP_END_THREADSAFE
nsHtml5StreamListener::nsHtml5StreamListener(nsHtml5StreamParser* aDelegate)
: mDelegate(aDelegate)
{
}
nsHtml5StreamListener::~nsHtml5StreamListener()
{
}
void
nsHtml5StreamListener::DropDelegate()
{
MOZ_ASSERT(NS_IsMainThread(),
"Must not call DropDelegate from non-main threads.");
mDelegate = nullptr;
}
NS_IMETHODIMP
nsHtml5StreamListener::CheckListenerChain()
{
if (MOZ_UNLIKELY(!mDelegate)) {
return NS_ERROR_NOT_AVAILABLE;
}
return mDelegate->CheckListenerChain();
}
NS_IMETHODIMP
nsHtml5StreamListener::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
if (MOZ_UNLIKELY(!mDelegate)) {
return NS_ERROR_NOT_AVAILABLE;
}
return mDelegate->OnStartRequest(aRequest, aContext);
}
NS_IMETHODIMP
nsHtml5StreamListener::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus)
{
if (MOZ_UNLIKELY(!mDelegate)) {
return NS_ERROR_NOT_AVAILABLE;
}
return mDelegate->OnStopRequest(aRequest,
aContext,
aStatus);
}
NS_IMETHODIMP
nsHtml5StreamListener::OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aInStream,
uint64_t aSourceOffset,
uint32_t aLength)
{
if (MOZ_UNLIKELY(!mDelegate)) {
return NS_ERROR_NOT_AVAILABLE;
}
return mDelegate->OnDataAvailable(aRequest,
aContext,
aInStream,
aSourceOffset,
aLength);
}

View file

@ -0,0 +1,55 @@
/* 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 nsHtml5StreamListener_h
#define nsHtml5StreamListener_h
#include "nsIStreamListener.h"
#include "nsIThreadRetargetableStreamListener.h"
#include "nsHtml5RefPtr.h"
#include "nsHtml5StreamParser.h"
/**
* The purpose of this class is to reconcile the problem that
* nsHtml5StreamParser is a cycle collection participant, which means that it
* can only be refcounted on the main thread, but
* nsIThreadRetargetableStreamListener can be refcounted from another thread,
* so nsHtml5StreamParser being an nsIThreadRetargetableStreamListener was
* a memory corruption problem.
*
* mDelegate is an nsHtml5RefPtr, which releases the object that it points
* to from a runnable on the main thread. DropDelegate() is only called on
* the main thread. This call will finish before the main-thread derefs the
* nsHtml5StreamListener itself, so there is no risk of another thread making
* the refcount of nsHtml5StreamListener go to zero and running the destructor
* concurrently. Other than that, the thread-safe nsISupports implementation
* takes care of the destructor not running concurrently from different
* threads, so there is no need to have a mutex around nsHtml5RefPtr to
* prevent it from double-releasing nsHtml5StreamParser.
*/
class nsHtml5StreamListener : public nsIStreamListener,
public nsIThreadRetargetableStreamListener
{
public:
explicit nsHtml5StreamListener(nsHtml5StreamParser* aDelegate);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
inline nsHtml5StreamParser* GetDelegate()
{
return mDelegate;
}
void DropDelegate();
private:
virtual ~nsHtml5StreamListener();
nsHtml5RefPtr<nsHtml5StreamParser> mDelegate;
};
#endif // nsHtml5StreamListener_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,579 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsHtml5StreamParser_h
#define nsHtml5StreamParser_h
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsICharsetDetectionObserver.h"
#include "nsHtml5MetaScanner.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5OwningUTF16Buffer.h"
#include "nsIInputStream.h"
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
#include "nsHtml5AtomTable.h"
#include "nsHtml5Speculation.h"
#include "nsITimer.h"
#include "nsICharsetDetector.h"
class nsHtml5Parser;
#define NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE 1024
#define NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE 1024
enum eParserMode {
/**
* Parse a document normally as HTML.
*/
NORMAL,
/**
* View document as HTML source.
*/
VIEW_SOURCE_HTML,
/**
* View document as XML source
*/
VIEW_SOURCE_XML,
/**
* View document as plain text source
*/
VIEW_SOURCE_PLAIN,
/**
* View document as plain text
*/
PLAIN_TEXT,
/**
* Load as data (XHR)
*/
LOAD_AS_DATA
};
enum eBomState {
/**
* BOM sniffing hasn't started.
*/
BOM_SNIFFING_NOT_STARTED = 0,
/**
* BOM sniffing is ongoing, and the first byte of an UTF-16LE BOM has been
* seen.
*/
SEEN_UTF_16_LE_FIRST_BYTE = 1,
/**
* BOM sniffing is ongoing, and the first byte of an UTF-16BE BOM has been
* seen.
*/
SEEN_UTF_16_BE_FIRST_BYTE = 2,
/**
* BOM sniffing is ongoing, and the first byte of an UTF-8 BOM has been
* seen.
*/
SEEN_UTF_8_FIRST_BYTE = 3,
/**
* BOM sniffing is ongoing, and the first and second bytes of an UTF-8 BOM
* have been seen.
*/
SEEN_UTF_8_SECOND_BYTE = 4,
/**
* BOM sniffing was started but is now over for whatever reason.
*/
BOM_SNIFFING_OVER = 5
};
enum eHtml5StreamState {
STREAM_NOT_STARTED = 0,
STREAM_BEING_READ = 1,
STREAM_ENDED = 2
};
class nsHtml5StreamParser : public nsICharsetDetectionObserver {
friend class nsHtml5RequestStopper;
friend class nsHtml5DataAvailable;
friend class nsHtml5StreamParserContinuation;
friend class nsHtml5TimerKungFu;
public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHtml5StreamParser,
nsICharsetDetectionObserver)
static void InitializeStatics();
nsHtml5StreamParser(nsHtml5TreeOpExecutor* aExecutor,
nsHtml5Parser* aOwner,
eParserMode aMode);
// Methods that nsHtml5StreamListener calls
nsresult CheckListenerChain();
nsresult OnStartRequest(nsIRequest* aRequest, nsISupports* aContext);
nsresult OnDataAvailable(nsIRequest* aRequest,
nsISupports* aContext,
nsIInputStream* aInStream,
uint64_t aSourceOffset,
uint32_t aLength);
nsresult OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult status);
// nsICharsetDetectionObserver
/**
* Chardet calls this to report the detection result
*/
NS_IMETHOD Notify(const char* aCharset, nsDetectionConfident aConf) override;
// EncodingDeclarationHandler
// http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/common/EncodingDeclarationHandler.java
/**
* Tree builder uses this to report a late <meta charset>
*/
bool internalEncodingDeclaration(nsString* aEncoding);
// Not from an external interface
/**
* Call this method once you've created a parser, and want to instruct it
* about what charset to load
*
* @param aCharset the charset of a document
* @param aCharsetSource the source of the charset
*/
inline void SetDocumentCharset(const nsACString& aCharset, int32_t aSource) {
NS_PRECONDITION(mStreamState == STREAM_NOT_STARTED,
"SetDocumentCharset called too late.");
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mCharset = aCharset;
mCharsetSource = aSource;
}
inline void SetObserver(nsIRequestObserver* aObserver) {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mObserver = aObserver;
}
nsresult GetChannel(nsIChannel** aChannel);
/**
* The owner parser must call this after script execution
* when no scripts are executing and the document.written
* buffer has been exhausted.
*/
void ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
nsHtml5TreeBuilder* aTreeBuilder,
bool aLastWasCR);
/**
* Continues the stream parser if the charset switch failed.
*/
void ContinueAfterFailedCharsetSwitch();
void Terminate()
{
mozilla::MutexAutoLock autoLock(mTerminatedMutex);
mTerminated = true;
}
void DropTimer();
/**
* Sets mCharset and mCharsetSource appropriately for the XML View Source
* case if aEncoding names a supported rough ASCII superset and sets
* the mCharset and mCharsetSource to the UTF-8 default otherwise.
*/
void SetEncodingFromExpat(const char16_t* aEncoding);
/**
* Sets the URL for View Source title in case this parser ends up being
* used for View Source. If aURL is a view-source: URL, takes the inner
* URL. data: URLs are shown with an ellipsis instead of the actual data.
*/
void SetViewSourceTitle(nsIURI* aURL);
private:
virtual ~nsHtml5StreamParser();
#ifdef DEBUG
bool IsParserThread() {
bool ret;
mThread->IsOnCurrentThread(&ret);
return ret;
}
#endif
void MarkAsBroken(nsresult aRv);
/**
* Marks the stream parser as interrupted. If you ever add calls to this
* method, be sure to review Uninterrupt usage very, very carefully to
* avoid having a previous in-flight runnable cancel your Interrupt()
* call on the other thread too soon.
*/
void Interrupt()
{
mozilla::MutexAutoLock autoLock(mTerminatedMutex);
mInterrupted = true;
}
void Uninterrupt()
{
NS_ASSERTION(IsParserThread(), "Wrong thread!");
mTokenizerMutex.AssertCurrentThreadOwns();
// Not acquiring mTerminatedMutex because mTokenizerMutex is already
// held at this point and is already stronger.
mInterrupted = false;
}
/**
* Flushes the tree ops from the tree builder and disarms the flush
* timer.
*/
void FlushTreeOpsAndDisarmTimer();
void ParseAvailableData();
void DoStopRequest();
void DoDataAvailable(const uint8_t* aBuffer, uint32_t aLength);
static nsresult CopySegmentsToParser(nsIInputStream *aInStream,
void *aClosure,
const char *aFromSegment,
uint32_t aToOffset,
uint32_t aCount,
uint32_t *aWriteCount);
bool IsTerminatedOrInterrupted()
{
mozilla::MutexAutoLock autoLock(mTerminatedMutex);
return mTerminated || mInterrupted;
}
bool IsTerminated()
{
mozilla::MutexAutoLock autoLock(mTerminatedMutex);
return mTerminated;
}
/**
* True when there is a Unicode decoder already
*/
inline bool HasDecoder()
{
return !!mUnicodeDecoder;
}
/**
* Push bytes from network when there is no Unicode decoder yet
*/
nsresult SniffStreamBytes(const uint8_t* aFromSegment,
uint32_t aCount,
uint32_t* aWriteCount);
/**
* Push bytes from network when there is a Unicode decoder already
*/
nsresult WriteStreamBytes(const uint8_t* aFromSegment,
uint32_t aCount,
uint32_t* aWriteCount);
/**
* Check whether every other byte in the sniffing buffer is zero.
*/
void SniffBOMlessUTF16BasicLatin(const uint8_t* aFromSegment,
uint32_t aCountToSniffingLimit);
/**
* <meta charset> scan failed. Try chardet if applicable. After this, the
* the parser will have some encoding even if a last resolt fallback.
*
* @param aFromSegment The current network buffer or null if the sniffing
* buffer is being flushed due to network stream ending.
* @param aCount The number of bytes in aFromSegment (ignored if
* aFromSegment is null)
* @param aWriteCount Return value for how many bytes got read from the
* buffer.
* @param aCountToSniffingLimit The number of unfilled slots in
* mSniffingBuffer
*/
nsresult FinalizeSniffing(const uint8_t* aFromSegment,
uint32_t aCount,
uint32_t* aWriteCount,
uint32_t aCountToSniffingLimit);
/**
* Set up the Unicode decoder and write the sniffing buffer into it
* followed by the current network buffer.
*
* @param aFromSegment The current network buffer or null if the sniffing
* buffer is being flushed due to network stream ending.
* @param aCount The number of bytes in aFromSegment (ignored if
* aFromSegment is null)
* @param aWriteCount Return value for how many bytes got read from the
* buffer.
*/
nsresult SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const uint8_t* aFromSegment,
uint32_t aCount,
uint32_t* aWriteCount);
/**
* Initialize the Unicode decoder, mark the BOM as the source and
* drop the sniffer.
*
* @param aDecoderCharsetName The name for the decoder's charset
* (UTF-16BE, UTF-16LE or UTF-8; the BOM has
* been swallowed)
*/
nsresult SetupDecodingFromBom(const char* aDecoderCharsetName);
/**
* Become confident or resolve and encoding name to its preferred form.
* @param aEncoding the value of an internal encoding decl. Acts as an
* out param, too, when the method returns true.
* @return true if the parser needs to start using the new value of
* aEncoding and false if the parser became confident or if
* the encoding name did not specify a usable encoding
*/
bool PreferredForInternalEncodingDecl(nsACString& aEncoding);
/**
* Callback for mFlushTimer.
*/
static void TimerCallback(nsITimer* aTimer, void* aClosure);
/**
* Parser thread entry point for (maybe) flushing the ops and posting
* a flush runnable back on the main thread.
*/
void TimerFlush();
/**
* Called when speculation fails.
*/
void MaybeDisableFutureSpeculation()
{
mSpeculationFailureCount++;
}
/**
* Used to check whether we're getting too many speculation failures and
* should just stop trying. The 100 is picked pretty randomly to be not too
* small (so most pages are not affected) but small enough that we don't end
* up with failed speculations over and over in pathological cases.
*/
bool IsSpeculationEnabled()
{
return mSpeculationFailureCount < 100;
}
nsCOMPtr<nsIRequest> mRequest;
nsCOMPtr<nsIRequestObserver> mObserver;
/**
* The document title to use if this turns out to be a View Source parser.
*/
nsCString mViewSourceTitle;
/**
* The Unicode decoder
*/
nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
/**
* The buffer for sniffing the character encoding
*/
mozilla::UniquePtr<uint8_t[]> mSniffingBuffer;
/**
* The number of meaningful bytes in mSniffingBuffer
*/
uint32_t mSniffingLength;
/**
* BOM sniffing state
*/
eBomState mBomState;
/**
* <meta> prescan implementation
*/
nsAutoPtr<nsHtml5MetaScanner> mMetaScanner;
// encoding-related stuff
/**
* The source (confidence) of the character encoding in use
*/
int32_t mCharsetSource;
/**
* The character encoding in use
*/
nsCString mCharset;
/**
* Whether reparse is forbidden
*/
bool mReparseForbidden;
// Portable parser objects
/**
* The first buffer in the pending UTF-16 buffer queue
*/
RefPtr<nsHtml5OwningUTF16Buffer> mFirstBuffer;
/**
* The last buffer in the pending UTF-16 buffer queue
*/
nsHtml5OwningUTF16Buffer* mLastBuffer; // weak ref; always points to
// a buffer of the size NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE
/**
* The tree operation executor
*/
nsHtml5TreeOpExecutor* mExecutor;
/**
* The HTML5 tree builder
*/
nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
/**
* The HTML5 tokenizer
*/
nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
/**
* Makes sure the main thread can't mess the tokenizer state while it's
* tokenizing. This mutex also protects the current speculation.
*/
mozilla::Mutex mTokenizerMutex;
/**
* The scoped atom table
*/
nsHtml5AtomTable mAtomTable;
/**
* The owner parser.
*/
RefPtr<nsHtml5Parser> mOwner;
/**
* Whether the last character tokenized was a carriage return (for CRLF)
*/
bool mLastWasCR;
/**
* For tracking stream life cycle
*/
eHtml5StreamState mStreamState;
/**
* Whether we are speculating.
*/
bool mSpeculating;
/**
* Whether the tokenizer has reached EOF. (Reset when stream rewinded.)
*/
bool mAtEOF;
/**
* The speculations. The mutex protects the nsTArray itself.
* To access the queue of current speculation, mTokenizerMutex must be
* obtained.
* The current speculation is the last element
*/
nsTArray<nsAutoPtr<nsHtml5Speculation> > mSpeculations;
mozilla::Mutex mSpeculationMutex;
/**
* Number of times speculation has failed for this parser.
*/
uint32_t mSpeculationFailureCount;
/**
* True to terminate early; protected by mTerminatedMutex
*/
bool mTerminated;
bool mInterrupted;
mozilla::Mutex mTerminatedMutex;
/**
* The thread this stream parser runs on.
*/
nsCOMPtr<nsIThread> mThread;
nsCOMPtr<nsIRunnable> mExecutorFlusher;
nsCOMPtr<nsIRunnable> mLoadFlusher;
/**
* The chardet instance if chardet is enabled.
*/
nsCOMPtr<nsICharsetDetector> mChardet;
/**
* If false, don't push data to chardet.
*/
bool mFeedChardet;
/**
* Whether the initial charset source was kCharsetFromParentFrame
*/
bool mInitialEncodingWasFromParentFrame;
/**
* Timer for flushing tree ops once in a while when not speculating.
*/
nsCOMPtr<nsITimer> mFlushTimer;
/**
* Keeps track whether mFlushTimer has been armed. Unfortunately,
* nsITimer doesn't enable querying this from the timer itself.
*/
bool mFlushTimerArmed;
/**
* False initially and true after the timer has fired at least once.
*/
bool mFlushTimerEverFired;
/**
* Whether the parser is doing a normal parse, view source or plain text.
*/
eParserMode mMode;
/**
* The pref html5.flushtimer.initialdelay: Time in milliseconds between
* the time a network buffer is seen and the timer firing when the
* timer hasn't fired previously in this parse.
*/
static int32_t sTimerInitialDelay;
/**
* The pref html5.flushtimer.subsequentdelay: Time in milliseconds between
* the time a network buffer is seen and the timer firing when the
* timer has already fired previously in this parse.
*/
static int32_t sTimerSubsequentDelay;
};
#endif // nsHtml5StreamParser_h

View file

@ -0,0 +1,130 @@
/* 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 "nsHtml5StringParser.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5Tokenizer.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsHtml5DependentUTF16Buffer.h"
NS_IMPL_ISUPPORTS0(nsHtml5StringParser)
nsHtml5StringParser::nsHtml5StringParser()
: mBuilder(new nsHtml5OplessBuilder())
, mTreeBuilder(new nsHtml5TreeBuilder(mBuilder))
, mTokenizer(new nsHtml5Tokenizer(mTreeBuilder, false))
{
MOZ_COUNT_CTOR(nsHtml5StringParser);
mTokenizer->setInterner(&mAtomTable);
}
nsHtml5StringParser::~nsHtml5StringParser()
{
MOZ_COUNT_DTOR(nsHtml5StringParser);
}
nsresult
nsHtml5StringParser::ParseFragment(const nsAString& aSourceBuffer,
nsIContent* aTargetNode,
nsIAtom* aContextLocalName,
int32_t aContextNamespace,
bool aQuirks,
bool aPreventScriptExecution)
{
NS_ENSURE_TRUE(aSourceBuffer.Length() <= INT32_MAX,
NS_ERROR_OUT_OF_MEMORY);
nsIDocument* doc = aTargetNode->OwnerDoc();
nsIURI* uri = doc->GetDocumentURI();
NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE);
mTreeBuilder->setFragmentContext(aContextLocalName,
aContextNamespace,
aTargetNode,
aQuirks);
#ifdef DEBUG
if (!aPreventScriptExecution) {
NS_ASSERTION(!aTargetNode->IsInUncomposedDoc(),
"If script execution isn't prevented, "
"the target node must not be in doc.");
nsCOMPtr<nsIDOMDocumentFragment> domFrag = do_QueryInterface(aTargetNode);
NS_ASSERTION(domFrag,
"If script execution isn't prevented, must parse to DOM fragment.");
}
#endif
mTreeBuilder->SetPreventScriptExecution(aPreventScriptExecution);
return Tokenize(aSourceBuffer, doc, true);
}
nsresult
nsHtml5StringParser::ParseDocument(const nsAString& aSourceBuffer,
nsIDocument* aTargetDoc,
bool aScriptingEnabledForNoscriptParsing)
{
MOZ_ASSERT(!aTargetDoc->GetFirstChild());
NS_ENSURE_TRUE(aSourceBuffer.Length() <= INT32_MAX,
NS_ERROR_OUT_OF_MEMORY);
mTreeBuilder->setFragmentContext(nullptr,
kNameSpaceID_None,
nullptr,
false);
mTreeBuilder->SetPreventScriptExecution(true);
return Tokenize(aSourceBuffer, aTargetDoc, aScriptingEnabledForNoscriptParsing);
}
nsresult
nsHtml5StringParser::Tokenize(const nsAString& aSourceBuffer,
nsIDocument* aDocument,
bool aScriptingEnabledForNoscriptParsing) {
nsIURI* uri = aDocument->GetDocumentURI();
mBuilder->Init(aDocument, uri, nullptr, nullptr);
mBuilder->SetParser(this);
mBuilder->SetNodeInfoManager(aDocument->NodeInfoManager());
// Mark the parser as *not* broken by passing NS_OK
nsresult rv = mBuilder->MarkAsBroken(NS_OK);
mTreeBuilder->setScriptingEnabled(aScriptingEnabledForNoscriptParsing);
mTreeBuilder->setIsSrcdocDocument(aDocument->IsSrcdocDocument());
mBuilder->Start();
mTokenizer->start();
if (!aSourceBuffer.IsEmpty()) {
bool lastWasCR = false;
nsHtml5DependentUTF16Buffer buffer(aSourceBuffer);
while (buffer.hasMore()) {
buffer.adjust(lastWasCR);
lastWasCR = false;
if (buffer.hasMore()) {
if (!mTokenizer->EnsureBufferSpace(buffer.getLength())) {
rv = mBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
break;
}
lastWasCR = mTokenizer->tokenizeBuffer(&buffer);
if (NS_FAILED(rv = mBuilder->IsBroken())) {
break;
}
}
}
}
if (NS_SUCCEEDED(rv)) {
mTokenizer->eof();
}
mTokenizer->end();
mBuilder->Finish();
mAtomTable.Clear();
return rv;
}

View file

@ -0,0 +1,88 @@
/* 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 nsHtml5StringParser_h
#define nsHtml5StringParser_h
#include "nsHtml5AtomTable.h"
#include "nsParserBase.h"
class nsHtml5OplessBuilder;
class nsHtml5TreeBuilder;
class nsHtml5Tokenizer;
class nsIContent;
class nsIDocument;
class nsHtml5StringParser : public nsParserBase
{
public:
NS_DECL_ISUPPORTS
/**
* Constructor for use ONLY by nsContentUtils. Others, please call the
* nsContentUtils statics that wrap this.
*/
nsHtml5StringParser();
/**
* Invoke the fragment parsing algorithm (innerHTML).
* DO NOT CALL from outside nsContentUtils.cpp.
*
* @param aSourceBuffer the string being set as innerHTML
* @param aTargetNode the target container
* @param aContextLocalName local name of context node
* @param aContextNamespace namespace of context node
* @param aQuirks true to make <table> not close <p>
* @param aPreventScriptExecution true to prevent scripts from executing;
* don't set to false when parsing into a target node that has been bound
* to tree.
*/
nsresult ParseFragment(const nsAString& aSourceBuffer,
nsIContent* aTargetNode,
nsIAtom* aContextLocalName,
int32_t aContextNamespace,
bool aQuirks,
bool aPreventScriptExecution);
/**
* Parse an entire HTML document from a source string.
* DO NOT CALL from outside nsContentUtils.cpp.
*
*/
nsresult ParseDocument(const nsAString& aSourceBuffer,
nsIDocument* aTargetDoc,
bool aScriptingEnabledForNoscriptParsing);
private:
virtual ~nsHtml5StringParser();
nsresult Tokenize(const nsAString& aSourceBuffer,
nsIDocument* aDocument,
bool aScriptingEnabledForNoscriptParsing);
/**
* The tree operation executor
*/
RefPtr<nsHtml5OplessBuilder> mBuilder;
/**
* The HTML5 tree builder
*/
const nsAutoPtr<nsHtml5TreeBuilder> mTreeBuilder;
/**
* The HTML5 tokenizer
*/
const nsAutoPtr<nsHtml5Tokenizer> mTokenizer;
/**
* The scoped atom table
*/
nsHtml5AtomTable mAtomTable;
};
#endif // nsHtml5StringParser_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,387 @@
/*
* Copyright (c) 2005-2007 Henri Sivonen
* Copyright (c) 2007-2015 Mozilla Foundation
* Portions of comments Copyright 2004-2010 Apple Computer, Inc., Mozilla
* Foundation, and Opera Software ASA.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit Tokenizer.java instead and regenerate.
*/
#ifndef nsHtml5Tokenizer_h
#define nsHtml5Tokenizer_h
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h"
#include "nsHtml5NamedCharacters.h"
#include "nsHtml5NamedCharactersAccel.h"
#include "nsHtml5Atoms.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Macros.h"
#include "nsHtml5Highlighter.h"
#include "nsHtml5TokenizerLoopPolicies.h"
class nsHtml5StreamParser;
class nsHtml5TreeBuilder;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5Tokenizer
{
private:
static char16_t LT_GT[];
static char16_t LT_SOLIDUS[];
static char16_t RSQB_RSQB[];
static char16_t REPLACEMENT_CHARACTER[];
static char16_t LF[];
static char16_t CDATA_LSQB[];
static char16_t OCTYPE[];
static char16_t UBLIC[];
static char16_t YSTEM[];
static staticJArray<char16_t,int32_t> TITLE_ARR;
static staticJArray<char16_t,int32_t> SCRIPT_ARR;
static staticJArray<char16_t,int32_t> STYLE_ARR;
static staticJArray<char16_t,int32_t> PLAINTEXT_ARR;
static staticJArray<char16_t,int32_t> XMP_ARR;
static staticJArray<char16_t,int32_t> TEXTAREA_ARR;
static staticJArray<char16_t,int32_t> IFRAME_ARR;
static staticJArray<char16_t,int32_t> NOEMBED_ARR;
static staticJArray<char16_t,int32_t> NOSCRIPT_ARR;
static staticJArray<char16_t,int32_t> NOFRAMES_ARR;
protected:
nsHtml5TreeBuilder* tokenHandler;
nsHtml5StreamParser* encodingDeclarationHandler;
bool lastCR;
int32_t stateSave;
private:
int32_t returnStateSave;
protected:
int32_t index;
private:
bool forceQuirks;
char16_t additional;
int32_t entCol;
int32_t firstCharKey;
int32_t lo;
int32_t hi;
int32_t candidate;
int32_t charRefBufMark;
protected:
int32_t value;
private:
bool seenDigits;
protected:
int32_t cstart;
private:
nsString* publicId;
nsString* systemId;
autoJArray<char16_t,int32_t> strBuf;
int32_t strBufLen;
autoJArray<char16_t,int32_t> charRefBuf;
int32_t charRefBufLen;
autoJArray<char16_t,int32_t> bmpChar;
autoJArray<char16_t,int32_t> astralChar;
protected:
nsHtml5ElementName* endTagExpectation;
private:
jArray<char16_t,int32_t> endTagExpectationAsArray;
protected:
bool endTag;
private:
nsHtml5ElementName* tagName;
protected:
nsHtml5AttributeName* attributeName;
private:
nsIAtom* doctypeName;
nsString* publicIdentifier;
nsString* systemIdentifier;
nsHtml5HtmlAttributes* attributes;
bool newAttributesEachTime;
bool shouldSuspend;
protected:
bool confident;
private:
int32_t line;
int32_t attributeLine;
nsHtml5AtomTable* interner;
bool viewingXmlSource;
public:
nsHtml5Tokenizer(nsHtml5TreeBuilder* tokenHandler, bool viewingXmlSource);
void setInterner(nsHtml5AtomTable* interner);
void initLocation(nsString* newPublicId, nsString* newSystemId);
bool isViewingXmlSource();
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsIAtom* endTagExpectation);
void setStateAndEndTagExpectation(int32_t specialTokenizerState, nsHtml5ElementName* endTagExpectation);
private:
void endTagExpectationToArray();
public:
void setLineNumber(int32_t line);
inline int32_t getLineNumber()
{
return line;
}
nsHtml5HtmlAttributes* emptyAttributes();
private:
inline void appendCharRefBuf(char16_t c)
{
MOZ_RELEASE_ASSERT(charRefBufLen < charRefBuf.length, "Attempted to overrun charRefBuf!");
charRefBuf[charRefBufLen++] = c;
}
void emitOrAppendCharRefBuf(int32_t returnState);
inline void clearStrBufAfterUse()
{
strBufLen = 0;
}
inline void clearStrBufBeforeUse()
{
MOZ_ASSERT(!strBufLen, "strBufLen not reset after previous use!");
strBufLen = 0;
}
inline void clearStrBufAfterOneHyphen()
{
MOZ_ASSERT(strBufLen == 1, "strBufLen length not one!");
MOZ_ASSERT(strBuf[0] == '-', "strBuf does not start with a hyphen!");
strBufLen = 0;
}
inline void appendStrBuf(char16_t c)
{
MOZ_ASSERT(strBufLen < strBuf.length, "Previous buffer length insufficient.");
if (MOZ_UNLIKELY(strBufLen == strBuf.length)) {
if (MOZ_UNLIKELY(!EnsureBufferSpace(1))) {
MOZ_CRASH("Unable to recover from buffer reallocation failure");
}
}
strBuf[strBufLen++] = c;
}
protected:
nsString* strBufToString();
private:
void strBufToDoctypeName();
void emitStrBuf();
inline void appendSecondHyphenToBogusComment()
{
appendStrBuf('-');
}
inline void adjustDoubleHyphenAndAppendToStrBufAndErr(char16_t c)
{
errConsecutiveHyphens();
appendStrBuf(c);
}
void appendStrBuf(char16_t* buffer, int32_t offset, int32_t length);
inline void appendCharRefBufToStrBuf()
{
appendStrBuf(charRefBuf, 0, charRefBufLen);
charRefBufLen = 0;
}
void emitComment(int32_t provisionalHyphens, int32_t pos);
protected:
void flushChars(char16_t* buf, int32_t pos);
private:
void strBufToElementNameString();
int32_t emitCurrentTagToken(bool selfClosing, int32_t pos);
void attributeNameComplete();
void addAttributeWithoutValue();
void addAttributeWithValue();
public:
void start();
bool tokenizeBuffer(nsHtml5UTF16Buffer* buffer);
private:
template<class P> int32_t stateLoop(int32_t state, char16_t c, int32_t pos, char16_t* buf, bool reconsume, int32_t returnState, int32_t endPos);
void initDoctypeFields();
inline void adjustDoubleHyphenAndAppendToStrBufCarriageReturn()
{
silentCarriageReturn();
adjustDoubleHyphenAndAppendToStrBufAndErr('\n');
}
inline void adjustDoubleHyphenAndAppendToStrBufLineFeed()
{
silentLineFeed();
adjustDoubleHyphenAndAppendToStrBufAndErr('\n');
}
inline void appendStrBufLineFeed()
{
silentLineFeed();
appendStrBuf('\n');
}
inline void appendStrBufCarriageReturn()
{
silentCarriageReturn();
appendStrBuf('\n');
}
protected:
inline void silentCarriageReturn()
{
++line;
lastCR = true;
}
inline void silentLineFeed()
{
++line;
}
private:
void emitCarriageReturn(char16_t* buf, int32_t pos);
void emitReplacementCharacter(char16_t* buf, int32_t pos);
void emitPlaintextReplacementCharacter(char16_t* buf, int32_t pos);
void setAdditionalAndRememberAmpersandLocation(char16_t add);
void bogusDoctype();
void bogusDoctypeWithoutQuirks();
void handleNcrValue(int32_t returnState);
public:
void eof();
private:
void emitDoctypeToken(int32_t pos);
protected:
inline char16_t checkChar(char16_t* buf, int32_t pos)
{
return buf[pos];
}
public:
bool internalEncodingDeclaration(nsString* internalCharset);
private:
void emitOrAppendTwo(const char16_t* val, int32_t returnState);
void emitOrAppendOne(const char16_t* val, int32_t returnState);
public:
void end();
void requestSuspension();
bool isInDataState();
void resetToDataState();
void loadState(nsHtml5Tokenizer* other);
void initializeWithoutStarting();
void setEncodingDeclarationHandler(nsHtml5StreamParser* encodingDeclarationHandler);
~nsHtml5Tokenizer();
static void initializeStatics();
static void releaseStatics();
#include "nsHtml5TokenizerHSupplement.h"
};
#define NS_HTML5TOKENIZER_DATA_AND_RCDATA_MASK ~1
#define NS_HTML5TOKENIZER_DATA 0
#define NS_HTML5TOKENIZER_RCDATA 1
#define NS_HTML5TOKENIZER_SCRIPT_DATA 2
#define NS_HTML5TOKENIZER_RAWTEXT 3
#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED 4
#define NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_DOUBLE_QUOTED 5
#define NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_SINGLE_QUOTED 6
#define NS_HTML5TOKENIZER_ATTRIBUTE_VALUE_UNQUOTED 7
#define NS_HTML5TOKENIZER_PLAINTEXT 8
#define NS_HTML5TOKENIZER_TAG_OPEN 9
#define NS_HTML5TOKENIZER_CLOSE_TAG_OPEN 10
#define NS_HTML5TOKENIZER_TAG_NAME 11
#define NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_NAME 12
#define NS_HTML5TOKENIZER_ATTRIBUTE_NAME 13
#define NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_NAME 14
#define NS_HTML5TOKENIZER_BEFORE_ATTRIBUTE_VALUE 15
#define NS_HTML5TOKENIZER_AFTER_ATTRIBUTE_VALUE_QUOTED 16
#define NS_HTML5TOKENIZER_BOGUS_COMMENT 17
#define NS_HTML5TOKENIZER_MARKUP_DECLARATION_OPEN 18
#define NS_HTML5TOKENIZER_DOCTYPE 19
#define NS_HTML5TOKENIZER_BEFORE_DOCTYPE_NAME 20
#define NS_HTML5TOKENIZER_DOCTYPE_NAME 21
#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_NAME 22
#define NS_HTML5TOKENIZER_BEFORE_DOCTYPE_PUBLIC_IDENTIFIER 23
#define NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED 24
#define NS_HTML5TOKENIZER_DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED 25
#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_IDENTIFIER 26
#define NS_HTML5TOKENIZER_BEFORE_DOCTYPE_SYSTEM_IDENTIFIER 27
#define NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED 28
#define NS_HTML5TOKENIZER_DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED 29
#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_IDENTIFIER 30
#define NS_HTML5TOKENIZER_BOGUS_DOCTYPE 31
#define NS_HTML5TOKENIZER_COMMENT_START 32
#define NS_HTML5TOKENIZER_COMMENT_START_DASH 33
#define NS_HTML5TOKENIZER_COMMENT 34
#define NS_HTML5TOKENIZER_COMMENT_END_DASH 35
#define NS_HTML5TOKENIZER_COMMENT_END 36
#define NS_HTML5TOKENIZER_COMMENT_END_BANG 37
#define NS_HTML5TOKENIZER_NON_DATA_END_TAG_NAME 38
#define NS_HTML5TOKENIZER_MARKUP_DECLARATION_HYPHEN 39
#define NS_HTML5TOKENIZER_MARKUP_DECLARATION_OCTYPE 40
#define NS_HTML5TOKENIZER_DOCTYPE_UBLIC 41
#define NS_HTML5TOKENIZER_DOCTYPE_YSTEM 42
#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_PUBLIC_KEYWORD 43
#define NS_HTML5TOKENIZER_BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS 44
#define NS_HTML5TOKENIZER_AFTER_DOCTYPE_SYSTEM_KEYWORD 45
#define NS_HTML5TOKENIZER_CONSUME_CHARACTER_REFERENCE 46
#define NS_HTML5TOKENIZER_CONSUME_NCR 47
#define NS_HTML5TOKENIZER_CHARACTER_REFERENCE_TAIL 48
#define NS_HTML5TOKENIZER_HEX_NCR_LOOP 49
#define NS_HTML5TOKENIZER_DECIMAL_NRC_LOOP 50
#define NS_HTML5TOKENIZER_HANDLE_NCR_VALUE 51
#define NS_HTML5TOKENIZER_HANDLE_NCR_VALUE_RECONSUME 52
#define NS_HTML5TOKENIZER_CHARACTER_REFERENCE_HILO_LOOKUP 53
#define NS_HTML5TOKENIZER_SELF_CLOSING_START_TAG 54
#define NS_HTML5TOKENIZER_CDATA_START 55
#define NS_HTML5TOKENIZER_CDATA_SECTION 56
#define NS_HTML5TOKENIZER_CDATA_RSQB 57
#define NS_HTML5TOKENIZER_CDATA_RSQB_RSQB 58
#define NS_HTML5TOKENIZER_SCRIPT_DATA_LESS_THAN_SIGN 59
#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START 60
#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPE_START_DASH 61
#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH 62
#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_DASH_DASH 63
#define NS_HTML5TOKENIZER_BOGUS_COMMENT_HYPHEN 64
#define NS_HTML5TOKENIZER_RAWTEXT_RCDATA_LESS_THAN_SIGN 65
#define NS_HTML5TOKENIZER_SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN 66
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_START 67
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED 68
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN 69
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH 70
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH 71
#define NS_HTML5TOKENIZER_SCRIPT_DATA_DOUBLE_ESCAPE_END 72
#define NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION 73
#define NS_HTML5TOKENIZER_PROCESSING_INSTRUCTION_QUESTION_MARK 74
#define NS_HTML5TOKENIZER_LEAD_OFFSET (0xD800 - (0x10000 >> 10))
#endif

View file

@ -0,0 +1,585 @@
/* 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 "mozilla/Likely.h"
// INT32_MAX is (2^31)-1. Therefore, the highest power-of-two that fits
// is 2^30. Note that this is counting char16_t units. The underlying
// bytes will be twice that, but they fit even in 32-bit size_t even
// if a contiguous chunk of memory of that size is pretty unlikely to
// be available on a 32-bit system.
#define MAX_POWER_OF_TWO_IN_INT32 0x40000000
bool
nsHtml5Tokenizer::EnsureBufferSpace(int32_t aLength)
{
MOZ_RELEASE_ASSERT(aLength >= 0, "Negative length.");
if (aLength > MAX_POWER_OF_TWO_IN_INT32) {
// Can't happen when loading from network.
return false;
}
CheckedInt<int32_t> worstCase(strBufLen);
worstCase += aLength;
worstCase += charRefBufLen;
// Add 2 to account for emissions of LT_GT, LT_SOLIDUS and RSQB_RSQB.
// Adding to the general worst case instead of only the
// TreeBuilder-exposed worst case to avoid re-introducing a bug when
// unifying the tokenizer and tree builder buffers in the future.
worstCase += 2;
if (!worstCase.isValid()) {
return false;
}
if (worstCase.value() > MAX_POWER_OF_TWO_IN_INT32) {
return false;
}
// TODO: Unify nsHtml5Tokenizer::strBuf and nsHtml5TreeBuilder::charBuffer
// so that the call below becomes unnecessary.
if (!tokenHandler->EnsureBufferSpace(worstCase.value())) {
return false;
}
if (!strBuf) {
if (worstCase.value() < MAX_POWER_OF_TWO_IN_INT32) {
// Add one to round to the next power of two to avoid immediate
// reallocation once there are a few characters in the buffer.
worstCase += 1;
}
strBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
if (!strBuf) {
return false;
}
} else if (worstCase.value() > strBuf.length) {
jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newFallibleJArray(mozilla::RoundUpPow2(worstCase.value()));
if (!newBuf) {
return false;
}
memcpy(newBuf, strBuf, sizeof(char16_t) * size_t(strBufLen));
strBuf = newBuf;
}
return true;
}
void
nsHtml5Tokenizer::StartPlainText()
{
stateSave = NS_HTML5TOKENIZER_PLAINTEXT;
}
void
nsHtml5Tokenizer::EnableViewSource(nsHtml5Highlighter* aHighlighter)
{
mViewSource = aHighlighter;
}
bool
nsHtml5Tokenizer::FlushViewSource()
{
return mViewSource->FlushOps();
}
void
nsHtml5Tokenizer::StartViewSource(const nsAutoString& aTitle)
{
mViewSource->Start(aTitle);
}
void
nsHtml5Tokenizer::EndViewSource()
{
mViewSource->End();
}
void
nsHtml5Tokenizer::errWarnLtSlashInRcdata()
{
}
// The null checks below annotated MOZ_LIKELY are not actually necessary.
void
nsHtml5Tokenizer::errUnquotedAttributeValOrNull(char16_t c)
{
if (MOZ_LIKELY(mViewSource)) {
switch (c) {
case '<':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeLt");
return;
case '`':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeGrave");
return;
case '\'':
case '"':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeQuote");
return;
case '=':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeEquals");
return;
}
}
}
void
nsHtml5Tokenizer::errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char16_t c)
{
if (MOZ_LIKELY(mViewSource)) {
switch (c) {
case '=':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartEquals");
return;
case '<':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartLt");
return;
case '`':
mViewSource->AddErrorToCurrentNode("errUnquotedAttributeStartGrave");
return;
}
}
}
void
nsHtml5Tokenizer::errBadCharBeforeAttributeNameOrNull(char16_t c)
{
if (MOZ_LIKELY(mViewSource)) {
if (c == '<') {
mViewSource->AddErrorToCurrentNode("errBadCharBeforeAttributeNameLt");
} else if (c == '=') {
errEqualsSignBeforeAttributeName();
} else if (c != 0xFFFD) {
errQuoteBeforeAttributeName(c);
}
}
}
void
nsHtml5Tokenizer::errBadCharAfterLt(char16_t c)
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errBadCharAfterLt");
}
}
void
nsHtml5Tokenizer::errQuoteOrLtInAttributeNameOrNull(char16_t c)
{
if (MOZ_LIKELY(mViewSource)) {
if (c == '<') {
mViewSource->AddErrorToCurrentNode("errLtInAttributeName");
} else if (c != 0xFFFD) {
mViewSource->AddErrorToCurrentNode("errQuoteInAttributeName");
}
}
}
void
nsHtml5Tokenizer::maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs)
{
if (mViewSource && attrs->getLength() != 0) {
/*
* When an end tag token is emitted with attributes, that is a parse
* error.
*/
mViewSource->AddErrorToCurrentRun("maybeErrAttributesOnEndTag");
}
}
void
nsHtml5Tokenizer::maybeErrSlashInEndTag(bool selfClosing)
{
if (mViewSource && selfClosing && endTag) {
mViewSource->AddErrorToCurrentSlash("maybeErrSlashInEndTag");
}
}
char16_t
nsHtml5Tokenizer::errNcrNonCharacter(char16_t ch)
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
}
return ch;
}
void
nsHtml5Tokenizer::errAstralNonCharacter(int32_t ch)
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrNonCharacter");
}
}
char16_t
nsHtml5Tokenizer::errNcrControlChar(char16_t ch)
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrControlChar");
}
return ch;
}
void
nsHtml5Tokenizer::errGarbageAfterLtSlash()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errGarbageAfterLtSlash");
}
}
void
nsHtml5Tokenizer::errLtSlashGt()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errLtSlashGt");
}
}
void
nsHtml5Tokenizer::errCharRefLacksSemicolon()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errCharRefLacksSemicolon");
}
}
void
nsHtml5Tokenizer::errNoDigitsInNCR()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNoDigitsInNCR");
}
}
void
nsHtml5Tokenizer::errGtInSystemId()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errGtInSystemId");
}
}
void
nsHtml5Tokenizer::errGtInPublicId()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errGtInPublicId");
}
}
void
nsHtml5Tokenizer::errNamelessDoctype()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNamelessDoctype");
}
}
void
nsHtml5Tokenizer::errConsecutiveHyphens()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errConsecutiveHyphens");
}
}
void
nsHtml5Tokenizer::errPrematureEndOfComment()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errPrematureEndOfComment");
}
}
void
nsHtml5Tokenizer::errBogusComment()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errBogusComment");
}
}
void
nsHtml5Tokenizer::errSlashNotFollowedByGt()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentSlash("errSlashNotFollowedByGt");
}
}
void
nsHtml5Tokenizer::errNoSpaceBetweenAttributes()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenAttributes");
}
}
void
nsHtml5Tokenizer::errAttributeValueMissing()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errAttributeValueMissing");
}
}
void
nsHtml5Tokenizer::errEqualsSignBeforeAttributeName()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errEqualsSignBeforeAttributeName");
}
}
void
nsHtml5Tokenizer::errLtGt()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errLtGt");
}
}
void
nsHtml5Tokenizer::errProcessingInstruction()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errProcessingInstruction");
}
}
void
nsHtml5Tokenizer::errUnescapedAmpersandInterpretedAsCharacterReference()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentAmpersand("errUnescapedAmpersandInterpretedAsCharacterReference");
}
}
void
nsHtml5Tokenizer::errNotSemicolonTerminated()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNotSemicolonTerminated");
}
}
void
nsHtml5Tokenizer::errNoNamedCharacterMatch()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentAmpersand("errNoNamedCharacterMatch");
}
}
void
nsHtml5Tokenizer::errQuoteBeforeAttributeName(char16_t c)
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errQuoteBeforeAttributeName");
}
}
void
nsHtml5Tokenizer::errExpectedPublicId()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errExpectedPublicId");
}
}
void
nsHtml5Tokenizer::errBogusDoctype()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errBogusDoctype");
}
}
void
nsHtml5Tokenizer::errNcrSurrogate()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrSurrogate");
}
}
void
nsHtml5Tokenizer::errNcrCr()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrCr");
}
}
void
nsHtml5Tokenizer::errNcrInC1Range()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrInC1Range");
}
}
void
nsHtml5Tokenizer::errEofInPublicId()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInPublicId");
}
}
void
nsHtml5Tokenizer::errEofInComment()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInComment");
}
}
void
nsHtml5Tokenizer::errEofInDoctype()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInDoctype");
}
}
void
nsHtml5Tokenizer::errEofInAttributeValue()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInAttributeValue");
}
}
void
nsHtml5Tokenizer::errEofInAttributeName()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInAttributeName");
}
}
void
nsHtml5Tokenizer::errEofWithoutGt()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofWithoutGt");
}
}
void
nsHtml5Tokenizer::errEofInTagName()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInTagName");
}
}
void
nsHtml5Tokenizer::errEofInEndTag()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInEndTag");
}
}
void
nsHtml5Tokenizer::errEofAfterLt()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofAfterLt");
}
}
void
nsHtml5Tokenizer::errNcrOutOfRange()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrOutOfRange");
}
}
void
nsHtml5Tokenizer::errNcrUnassigned()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrUnassigned");
}
}
void
nsHtml5Tokenizer::errDuplicateAttribute()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errDuplicateAttribute");
}
}
void
nsHtml5Tokenizer::errEofInSystemId()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentRun("errEofInSystemId");
}
}
void
nsHtml5Tokenizer::errExpectedSystemId()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errExpectedSystemId");
}
}
void
nsHtml5Tokenizer::errMissingSpaceBeforeDoctypeName()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errMissingSpaceBeforeDoctypeName");
}
}
void
nsHtml5Tokenizer::errHyphenHyphenBang()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errHyphenHyphenBang");
}
}
void
nsHtml5Tokenizer::errNcrControlChar()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrControlChar");
}
}
void
nsHtml5Tokenizer::errNcrZero()
{
if (MOZ_UNLIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNcrZero");
}
}
void
nsHtml5Tokenizer::errNoSpaceBetweenDoctypeSystemKeywordAndQuote()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypeSystemKeywordAndQuote");
}
}
void
nsHtml5Tokenizer::errNoSpaceBetweenPublicAndSystemIds()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenPublicAndSystemIds");
}
}
void
nsHtml5Tokenizer::errNoSpaceBetweenDoctypePublicKeywordAndQuote()
{
if (MOZ_LIKELY(mViewSource)) {
mViewSource->AddErrorToCurrentNode("errNoSpaceBetweenDoctypePublicKeywordAndQuote");
}
}

View file

@ -0,0 +1,148 @@
/* 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/. */
inline nsHtml5HtmlAttributes* GetAttributes()
{
return attributes;
}
/**
* Makes sure the buffers are large enough to be able to tokenize aLength
* UTF-16 code units before having to make the buffers larger.
*
* @param aLength the number of UTF-16 code units to be tokenized before the
* next call to this method.
* @return true if successful; false if out of memory
*/
bool EnsureBufferSpace(int32_t aLength);
nsAutoPtr<nsHtml5Highlighter> mViewSource;
/**
* Starts handling text/plain. This is a one-way initialization. There is
* no corresponding EndPlainText() call.
*/
void StartPlainText();
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
bool FlushViewSource();
void StartViewSource(const nsAutoString& aTitle);
void EndViewSource();
void errGarbageAfterLtSlash();
void errLtSlashGt();
void errWarnLtSlashInRcdata();
void errCharRefLacksSemicolon();
void errNoDigitsInNCR();
void errGtInSystemId();
void errGtInPublicId();
void errNamelessDoctype();
void errConsecutiveHyphens();
void errPrematureEndOfComment();
void errBogusComment();
void errUnquotedAttributeValOrNull(char16_t c);
void errSlashNotFollowedByGt();
void errNoSpaceBetweenAttributes();
void errLtOrEqualsOrGraveInUnquotedAttributeOrNull(char16_t c);
void errAttributeValueMissing();
void errBadCharBeforeAttributeNameOrNull(char16_t c);
void errEqualsSignBeforeAttributeName();
void errBadCharAfterLt(char16_t c);
void errLtGt();
void errProcessingInstruction();
void errUnescapedAmpersandInterpretedAsCharacterReference();
void errNotSemicolonTerminated();
void errNoNamedCharacterMatch();
void errQuoteBeforeAttributeName(char16_t c);
void errQuoteOrLtInAttributeNameOrNull(char16_t c);
void errExpectedPublicId();
void errBogusDoctype();
void maybeErrAttributesOnEndTag(nsHtml5HtmlAttributes* attrs);
void maybeErrSlashInEndTag(bool selfClosing);
char16_t errNcrNonCharacter(char16_t ch);
void errAstralNonCharacter(int32_t ch);
void errNcrSurrogate();
char16_t errNcrControlChar(char16_t ch);
void errNcrCr();
void errNcrInC1Range();
void errEofInPublicId();
void errEofInComment();
void errEofInDoctype();
void errEofInAttributeValue();
void errEofInAttributeName();
void errEofWithoutGt();
void errEofInTagName();
void errEofInEndTag();
void errEofAfterLt();
void errNcrOutOfRange();
void errNcrUnassigned();
void errDuplicateAttribute();
void errEofInSystemId();
void errExpectedSystemId();
void errMissingSpaceBeforeDoctypeName();
void errHyphenHyphenBang();
void errNcrControlChar();
void errNcrZero();
void errNoSpaceBetweenDoctypeSystemKeywordAndQuote();
void errNoSpaceBetweenPublicAndSystemIds();
void errNoSpaceBetweenDoctypePublicKeywordAndQuote();

View file

@ -0,0 +1,47 @@
/* 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 nsHtml5TokenizerLoopPolicies_h
#define nsHtml5TokenizerLoopPolicies_h
/**
* This policy does not report tokenizer transitions anywhere. To be used
* when _not_ viewing source.
*/
struct nsHtml5SilentPolicy
{
static const bool reportErrors = false;
static int32_t transition(nsHtml5Highlighter* aHighlighter,
int32_t aState,
bool aReconsume,
int32_t aPos)
{
return aState;
}
static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter)
{
}
};
/**
* This policy reports the tokenizer transitions to a highlighter. To be used
* when viewing source.
*/
struct nsHtml5ViewSourcePolicy
{
static const bool reportErrors = true;
static int32_t transition(nsHtml5Highlighter* aHighlighter,
int32_t aState,
bool aReconsume,
int32_t aPos)
{
return aHighlighter->Transition(aState, aReconsume, aPos);
}
static void completedNamedCharacterReference(nsHtml5Highlighter* aHighlighter)
{
aHighlighter->CompletedNamedCharacterReference();
}
};
#endif // nsHtml5TokenizerLoopPolicies_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,384 @@
/*
* Copyright (c) 2007 Henri Sivonen
* Copyright (c) 2007-2015 Mozilla Foundation
* Portions of comments Copyright 2004-2008 Apple Computer, Inc., Mozilla
* Foundation, and Opera Software ASA.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit TreeBuilder.java instead and regenerate.
*/
#ifndef nsHtml5TreeBuilder_h
#define nsHtml5TreeBuilder_h
#include "nsContentUtils.h"
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsITimer.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5ArrayCopy.h"
#include "nsHtml5Parser.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5TreeOperation.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5TreeOpExecutor.h"
#include "nsHtml5StreamParser.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Highlighter.h"
#include "nsHtml5PlainTextUtils.h"
#include "nsHtml5ViewSourceUtils.h"
#include "mozilla/Likely.h"
#include "nsIContentHandle.h"
#include "nsHtml5OplessBuilder.h"
class nsHtml5StreamParser;
class nsHtml5Tokenizer;
class nsHtml5MetaScanner;
class nsHtml5AttributeName;
class nsHtml5ElementName;
class nsHtml5HtmlAttributes;
class nsHtml5UTF16Buffer;
class nsHtml5StateSnapshot;
class nsHtml5Portability;
class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
{
private:
static char16_t REPLACEMENT_CHARACTER[];
static staticJArray<const char*,int32_t> QUIRKY_PUBLIC_IDS;
int32_t mode;
int32_t originalMode;
bool framesetOk;
protected:
nsHtml5Tokenizer* tokenizer;
private:
bool scriptingEnabled;
bool needToDropLF;
bool fragment;
nsIAtom* contextName;
int32_t contextNamespace;
nsIContentHandle* contextNode;
autoJArray<int32_t,int32_t> templateModeStack;
int32_t templateModePtr;
autoJArray<nsHtml5StackNode*,int32_t> stack;
int32_t currentPtr;
autoJArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements;
int32_t listPtr;
nsIContentHandle* formPointer;
nsIContentHandle* headPointer;
nsIContentHandle* deepTreeSurrogateParent;
protected:
autoJArray<char16_t,int32_t> charBuffer;
int32_t charBufferLen;
private:
bool quirks;
bool isSrcdocDocument;
public:
void startTokenization(nsHtml5Tokenizer* self);
void doctype(nsIAtom* name, nsString* publicIdentifier, nsString* 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();
void eof();
void endTokenization();
void startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, bool selfClosing);
private:
void startTagTitleInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void startTagGenericRawText(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void startTagScriptInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void startTagTemplateInHead(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
bool isTemplateContents();
bool isTemplateModeStackEmpty();
bool isSpecialParentInForeign(nsHtml5StackNode* stackNode);
public:
static nsString* extractCharsetFromContent(nsString* attributeValue, nsHtml5TreeBuilder* tb);
private:
void checkMetaCharset(nsHtml5HtmlAttributes* attributes);
public:
void endTag(nsHtml5ElementName* elementName);
private:
void endTagTemplateInHead();
int32_t findLastInTableScopeOrRootTemplateTbodyTheadTfoot();
int32_t findLast(nsIAtom* name);
int32_t findLastInTableScope(nsIAtom* name);
int32_t findLastInButtonScope(nsIAtom* name);
int32_t findLastInScope(nsIAtom* name);
int32_t findLastInListScope(nsIAtom* name);
int32_t findLastInScopeHn();
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 closeTheCell(int32_t eltPos);
int32_t findLastInTableScopeTdTh();
void clearStackBackTo(int32_t eltPos);
void resetTheInsertionMode();
void implicitlyCloseP();
bool debugOnlyClearLastStackSlot();
bool debugOnlyClearLastListSlot();
void pushTemplateMode(int32_t mode);
void push(nsHtml5StackNode* node);
void silentPush(nsHtml5StackNode* node);
void append(nsHtml5StackNode* node);
inline void insertMarker()
{
append(nullptr);
}
void clearTheListOfActiveFormattingElementsUpToTheLastMarker();
inline bool isCurrent(nsIAtom* name)
{
return stack[currentPtr]->ns == kNameSpaceID_XHTML && name == stack[currentPtr]->name;
}
void removeFromStack(int32_t pos);
void removeFromStack(nsHtml5StackNode* node);
void removeFromListOfActiveFormattingElements(int32_t pos);
bool adoptionAgencyEndTag(nsIAtom* name);
void insertIntoStack(nsHtml5StackNode* node, int32_t position);
void insertIntoListOfActiveFormattingElements(nsHtml5StackNode* formattingClone, int32_t bookmark);
int32_t findInListOfActiveFormattingElements(nsHtml5StackNode* node);
int32_t findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsIAtom* name);
void maybeForgetEarlierDuplicateFormattingElement(nsIAtom* name, nsHtml5HtmlAttributes* attributes);
int32_t findLastOrRoot(nsIAtom* name);
int32_t findLastOrRoot(int32_t group);
bool addAttributesToBody(nsHtml5HtmlAttributes* attributes);
void addAttributesToHtml(nsHtml5HtmlAttributes* attributes);
void pushHeadPointerOntoStack();
void reconstructTheActiveFormattingElements();
void insertIntoFosterParent(nsIContentHandle* child);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
bool isInStack(nsHtml5StackNode* node);
void popTemplateMode();
void pop();
void silentPop();
void popOnEof();
void appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes);
void appendHtmlElementToDocumentAndPush();
void appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushBodyElement();
void appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
bool annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
void appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
void appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
void appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
void appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes);
protected:
void accumulateCharacters(const char16_t* buf, int32_t start, int32_t length);
void requestSuspension();
nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* intendedParent);
nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form, nsIContentHandle* intendedParent);
nsIContentHandle* createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
void detachFromParent(nsIContentHandle* element);
bool hasChildren(nsIContentHandle* element);
void appendElement(nsIContentHandle* child, nsIContentHandle* newParent);
void appendChildrenToNewParent(nsIContentHandle* oldParent, nsIContentHandle* newParent);
void insertFosterParentedChild(nsIContentHandle* child, nsIContentHandle* table, nsIContentHandle* stackParent);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form, nsIContentHandle* table, nsIContentHandle* stackParent);
;void insertFosterParentedCharacters(char16_t* buf, int32_t start, int32_t length, nsIContentHandle* table, nsIContentHandle* stackParent);
void appendCharacters(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
void appendIsindexPrompt(nsIContentHandle* parent);
void appendComment(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
void appendCommentToDocument(char16_t* buf, int32_t start, int32_t length);
void addAttributesToElement(nsIContentHandle* element, nsHtml5HtmlAttributes* attributes);
void markMalformedIfScript(nsIContentHandle* elt);
void start(bool fragmentMode);
void end();
void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier);
void elementPushed(int32_t ns, nsIAtom* name, nsIContentHandle* node);
void elementPopped(int32_t ns, nsIAtom* name, nsIContentHandle* node);
public:
inline bool cdataSectionAllowed()
{
return isInForeign();
}
private:
bool isInForeign();
bool isInForeignButNotHtmlOrMathTextIntegrationPoint();
public:
void setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks);
protected:
nsIContentHandle* currentNode();
public:
bool isScriptingEnabled();
void setScriptingEnabled(bool scriptingEnabled);
void setIsSrcdocDocument(bool isSrcdocDocument);
void flushCharacters();
private:
bool charBufferContainsNonWhitespace();
public:
nsAHtml5TreeBuilderState* newSnapshot();
bool snapshotMatches(nsAHtml5TreeBuilderState* snapshot);
void loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTable* interner);
private:
int32_t findInArray(nsHtml5StackNode* node, jArray<nsHtml5StackNode*,int32_t> arr);
public:
nsIContentHandle* getFormPointer();
nsIContentHandle* getHeadPointer();
nsIContentHandle* getDeepTreeSurrogateParent();
jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements();
jArray<nsHtml5StackNode*,int32_t> getStack();
jArray<int32_t,int32_t> getTemplateModeStack();
int32_t getMode();
int32_t getOriginalMode();
bool isFramesetOk();
bool isNeedToDropLF();
bool isQuirks();
int32_t getListOfActiveFormattingElementsLength();
int32_t getStackLength();
int32_t getTemplateModeStackLength();
static void initializeStatics();
static void releaseStatics();
#include "nsHtml5TreeBuilderHSupplement.h"
};
#define NS_HTML5TREE_BUILDER_OTHER 0
#define NS_HTML5TREE_BUILDER_A 1
#define NS_HTML5TREE_BUILDER_BASE 2
#define NS_HTML5TREE_BUILDER_BODY 3
#define NS_HTML5TREE_BUILDER_BR 4
#define NS_HTML5TREE_BUILDER_BUTTON 5
#define NS_HTML5TREE_BUILDER_CAPTION 6
#define NS_HTML5TREE_BUILDER_COL 7
#define NS_HTML5TREE_BUILDER_COLGROUP 8
#define NS_HTML5TREE_BUILDER_FORM 9
#define NS_HTML5TREE_BUILDER_FRAME 10
#define NS_HTML5TREE_BUILDER_FRAMESET 11
#define NS_HTML5TREE_BUILDER_IMAGE 12
#define NS_HTML5TREE_BUILDER_INPUT 13
#define NS_HTML5TREE_BUILDER_ISINDEX 14
#define NS_HTML5TREE_BUILDER_LI 15
#define NS_HTML5TREE_BUILDER_LINK_OR_BASEFONT_OR_BGSOUND 16
#define NS_HTML5TREE_BUILDER_MATH 17
#define NS_HTML5TREE_BUILDER_META 18
#define NS_HTML5TREE_BUILDER_SVG 19
#define NS_HTML5TREE_BUILDER_HEAD 20
#define NS_HTML5TREE_BUILDER_HR 22
#define NS_HTML5TREE_BUILDER_HTML 23
#define NS_HTML5TREE_BUILDER_NOBR 24
#define NS_HTML5TREE_BUILDER_NOFRAMES 25
#define NS_HTML5TREE_BUILDER_NOSCRIPT 26
#define NS_HTML5TREE_BUILDER_OPTGROUP 27
#define NS_HTML5TREE_BUILDER_OPTION 28
#define NS_HTML5TREE_BUILDER_P 29
#define NS_HTML5TREE_BUILDER_PLAINTEXT 30
#define NS_HTML5TREE_BUILDER_SCRIPT 31
#define NS_HTML5TREE_BUILDER_SELECT 32
#define NS_HTML5TREE_BUILDER_STYLE 33
#define NS_HTML5TREE_BUILDER_TABLE 34
#define NS_HTML5TREE_BUILDER_TEXTAREA 35
#define NS_HTML5TREE_BUILDER_TITLE 36
#define NS_HTML5TREE_BUILDER_TR 37
#define NS_HTML5TREE_BUILDER_XMP 38
#define NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT 39
#define NS_HTML5TREE_BUILDER_TD_OR_TH 40
#define NS_HTML5TREE_BUILDER_DD_OR_DT 41
#define NS_HTML5TREE_BUILDER_H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6 42
#define NS_HTML5TREE_BUILDER_MARQUEE_OR_APPLET 43
#define NS_HTML5TREE_BUILDER_PRE_OR_LISTING 44
#define NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U 45
#define NS_HTML5TREE_BUILDER_UL_OR_OL_OR_DL 46
#define NS_HTML5TREE_BUILDER_IFRAME 47
#define NS_HTML5TREE_BUILDER_EMBED 48
#define NS_HTML5TREE_BUILDER_AREA_OR_WBR 49
#define NS_HTML5TREE_BUILDER_DIV_OR_BLOCKQUOTE_OR_CENTER_OR_MENU 50
#define NS_HTML5TREE_BUILDER_ADDRESS_OR_ARTICLE_OR_ASIDE_OR_DETAILS_OR_DIR_OR_FIGCAPTION_OR_FIGURE_OR_FOOTER_OR_HEADER_OR_HGROUP_OR_MAIN_OR_NAV_OR_SECTION_OR_SUMMARY 51
#define NS_HTML5TREE_BUILDER_RUBY_OR_SPAN_OR_SUB_OR_SUP_OR_VAR 52
#define NS_HTML5TREE_BUILDER_RB_OR_RTC 53
#define NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK 55
#define NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK 56
#define NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT 57
#define NS_HTML5TREE_BUILDER_ANNOTATION_XML 58
#define NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC 59
#define NS_HTML5TREE_BUILDER_NOEMBED 60
#define NS_HTML5TREE_BUILDER_FIELDSET 61
#define NS_HTML5TREE_BUILDER_OUTPUT 62
#define NS_HTML5TREE_BUILDER_OBJECT 63
#define NS_HTML5TREE_BUILDER_FONT 64
#define NS_HTML5TREE_BUILDER_KEYGEN 65
#define NS_HTML5TREE_BUILDER_MENUITEM 66
#define NS_HTML5TREE_BUILDER_TEMPLATE 67
#define NS_HTML5TREE_BUILDER_IMG 68
#define NS_HTML5TREE_BUILDER_RT_OR_RP 69
#define NS_HTML5TREE_BUILDER_IN_ROW 0
#define NS_HTML5TREE_BUILDER_IN_TABLE_BODY 1
#define NS_HTML5TREE_BUILDER_IN_TABLE 2
#define NS_HTML5TREE_BUILDER_IN_CAPTION 3
#define NS_HTML5TREE_BUILDER_IN_CELL 4
#define NS_HTML5TREE_BUILDER_FRAMESET_OK 5
#define NS_HTML5TREE_BUILDER_IN_BODY 6
#define NS_HTML5TREE_BUILDER_IN_HEAD 7
#define NS_HTML5TREE_BUILDER_IN_HEAD_NOSCRIPT 8
#define NS_HTML5TREE_BUILDER_IN_COLUMN_GROUP 9
#define NS_HTML5TREE_BUILDER_IN_SELECT_IN_TABLE 10
#define NS_HTML5TREE_BUILDER_IN_SELECT 11
#define NS_HTML5TREE_BUILDER_AFTER_BODY 12
#define NS_HTML5TREE_BUILDER_IN_FRAMESET 13
#define NS_HTML5TREE_BUILDER_AFTER_FRAMESET 14
#define NS_HTML5TREE_BUILDER_INITIAL 15
#define NS_HTML5TREE_BUILDER_BEFORE_HTML 16
#define NS_HTML5TREE_BUILDER_BEFORE_HEAD 17
#define NS_HTML5TREE_BUILDER_AFTER_HEAD 18
#define NS_HTML5TREE_BUILDER_AFTER_AFTER_BODY 19
#define NS_HTML5TREE_BUILDER_AFTER_AFTER_FRAMESET 20
#define NS_HTML5TREE_BUILDER_TEXT 21
#define NS_HTML5TREE_BUILDER_IN_TEMPLATE 22
#define NS_HTML5TREE_BUILDER_CHARSET_INITIAL 0
#define NS_HTML5TREE_BUILDER_CHARSET_C 1
#define NS_HTML5TREE_BUILDER_CHARSET_H 2
#define NS_HTML5TREE_BUILDER_CHARSET_A 3
#define NS_HTML5TREE_BUILDER_CHARSET_R 4
#define NS_HTML5TREE_BUILDER_CHARSET_S 5
#define NS_HTML5TREE_BUILDER_CHARSET_E 6
#define NS_HTML5TREE_BUILDER_CHARSET_T 7
#define NS_HTML5TREE_BUILDER_CHARSET_EQUALS 8
#define NS_HTML5TREE_BUILDER_CHARSET_SINGLE_QUOTED 9
#define NS_HTML5TREE_BUILDER_CHARSET_DOUBLE_QUOTED 10
#define NS_HTML5TREE_BUILDER_CHARSET_UNQUOTED 11
#define NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK INT32_MAX
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,248 @@
/* 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/. */
#define NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH 512
private:
nsHtml5OplessBuilder* mBuilder;
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// If mBuilder is not null, the tree op machinery is not in use and
// the fields below aren't in use, either.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
nsHtml5Highlighter* mViewSource;
nsTArray<nsHtml5TreeOperation> mOpQueue;
nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
nsAHtml5TreeOpSink* mOpSink;
mozilla::UniquePtr<nsIContent*[]> mHandles;
int32_t mHandlesUsed;
nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
nsHtml5TreeOpStage* mSpeculativeLoadStage;
nsresult mBroken;
bool mCurrentHtmlScriptIsAsyncOrDefer;
bool mPreventScriptExecution;
#ifdef DEBUG
bool mActive;
#endif
// DocumentModeHandler
/**
* Tree builder uses this to report quirkiness of the document
*/
void documentMode(nsHtml5DocumentMode m);
nsIContentHandle* getDocumentFragmentForTemplate(nsIContentHandle* aTemplate);
nsIContentHandle* getFormPointerForContext(nsIContentHandle* aContext);
/**
* Using nsIContent** instead of nsIContent* is the parser deals with DOM
* nodes in a way that works off the main thread. Non-main-thread code
* can't refcount or otherwise touch nsIContent objects in any way.
* Yet, the off-the-main-thread code needs to have a way to hold onto a
* particular node and repeatedly operate on the same node.
*
* The way this works is that the off-the-main-thread code has an
* nsIContent** for each DOM node and a given nsIContent** is only ever
* actually dereferenced into an actual nsIContent* on the main thread.
* When the off-the-main-thread code requests a new node, it gets an
* nsIContent** immediately and a tree op is enqueued for later allocating
* an actual nsIContent object and writing a pointer to it into the memory
* location pointed to by the nsIContent**.
*
* Since tree ops are in a queue, the node creating tree op will always
* run before tree ops that try to further operate on the node that the
* nsIContent** is a handle to.
*
* On-the-main-thread parts of the parser use nsIContent* instead of
* nsIContent**. Since both cases share the same parser core, the parser
* core casts both to nsIContentHandle*.
*/
nsIContentHandle* AllocateContentHandle();
void accumulateCharactersForced(const char16_t* aBuf, int32_t aStart, int32_t aLength)
{
accumulateCharacters(aBuf, aStart, aLength);
}
void MarkAsBrokenAndRequestSuspension(nsresult aRv)
{
mBuilder->MarkAsBroken(aRv);
requestSuspension();
}
void MarkAsBrokenFromPortability(nsresult aRv);
public:
explicit nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder);
nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
nsHtml5TreeOpStage* aStage);
~nsHtml5TreeBuilder();
void StartPlainTextViewSource(const nsAutoString& aTitle);
void StartPlainText();
void StartPlainTextBody();
bool HasScript();
void SetOpSink(nsAHtml5TreeOpSink* aOpSink)
{
mOpSink = aOpSink;
}
void ClearOps()
{
mOpQueue.Clear();
}
bool Flush(bool aDiscretionary = false);
void FlushLoads();
void SetDocumentCharset(nsACString& aCharset, int32_t aCharsetSource);
void StreamEnded();
void NeedsCharsetSwitchTo(const nsACString& aEncoding,
int32_t aSource,
int32_t aLineNumber);
void MaybeComplainAboutCharset(const char* aMsgId,
bool aError,
int32_t aLineNumber);
void AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine);
void DropHandles();
void SetPreventScriptExecution(bool aPrevent)
{
mPreventScriptExecution = aPrevent;
}
bool HasBuilder()
{
return mBuilder;
}
/**
* Makes sure the buffers are large enough to be able to tokenize aLength
* UTF-16 code units before having to make the buffers larger.
*
* @param aLength the number of UTF-16 code units to be tokenized before the
* next call to this method.
* @return true if successful; false if out of memory
*/
bool EnsureBufferSpace(int32_t aLength);
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
void errStrayStartTag(nsIAtom* aName);
void errStrayEndTag(nsIAtom* aName);
void errUnclosedElements(int32_t aIndex, nsIAtom* aName);
void errUnclosedElementsImplied(int32_t aIndex, nsIAtom* aName);
void errUnclosedElementsCell(int32_t aIndex);
void errStrayDoctype();
void errAlmostStandardsDoctype();
void errQuirkyDoctype();
void errNonSpaceInTrailer();
void errNonSpaceAfterFrameset();
void errNonSpaceInFrameset();
void errNonSpaceAfterBody();
void errNonSpaceInColgroupInFragment();
void errNonSpaceInNoscriptInHead();
void errFooBetweenHeadAndBody(nsIAtom* aName);
void errStartTagWithoutDoctype();
void errNoSelectInTableScope();
void errStartSelectWhereEndSelectExpected();
void errStartTagWithSelectOpen(nsIAtom* aName);
void errBadStartTagInHead(nsIAtom* aName);
void errImage();
void errIsindex();
void errFooSeenWhenFooOpen(nsIAtom* aName);
void errHeadingWhenHeadingOpen();
void errFramesetStart();
void errNoCellToClose();
void errStartTagInTable(nsIAtom* aName);
void errFormWhenFormOpen();
void errTableSeenWhileTableOpen();
void errStartTagInTableBody(nsIAtom* aName);
void errEndTagSeenWithoutDoctype();
void errEndTagAfterBody();
void errEndTagSeenWithSelectOpen(nsIAtom* aName);
void errGarbageInColgroup();
void errEndTagBr();
void errNoElementToCloseButEndTagSeen(nsIAtom* aName);
void errHtmlStartTagInForeignContext(nsIAtom* aName);
void errTableClosedWhileCaptionOpen();
void errNoTableRowToClose();
void errNonSpaceInTable();
void errUnclosedChildrenInRuby();
void errStartTagSeenWithoutRuby(nsIAtom* aName);
void errSelfClosing();
void errNoCheckUnclosedElementsOnStack();
void errEndTagDidNotMatchCurrentOpenElement(nsIAtom* aName, nsIAtom* aOther);
void errEndTagViolatesNestingRules(nsIAtom* aName);
void errEndWithUnclosedElements(nsIAtom* aName);
void MarkAsBroken(nsresult aRv);
/**
* Checks if this parser is broken. Returns a non-NS_OK (i.e. non-0)
* value if broken.
*/
nsresult IsBroken()
{
return mBroken;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,306 @@
/* 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 nsHtml5TreeOpExecutor_h
#define nsHtml5TreeOpExecutor_h
#include "nsIAtom.h"
#include "nsTraceRefcnt.h"
#include "nsHtml5TreeOperation.h"
#include "nsHtml5SpeculativeLoad.h"
#include "nsTArray.h"
#include "nsContentSink.h"
#include "nsNodeInfoManager.h"
#include "nsHtml5DocumentMode.h"
#include "nsIScriptElement.h"
#include "nsIParser.h"
#include "nsAHtml5TreeOpSink.h"
#include "nsHtml5TreeOpStage.h"
#include "nsIURI.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "mozilla/LinkedList.h"
#include "nsHtml5DocumentBuilder.h"
#include "mozilla/net/ReferrerPolicy.h"
class nsHtml5Parser;
class nsHtml5StreamParser;
class nsIContent;
class nsIDocument;
class nsHtml5TreeOpExecutor final : public nsHtml5DocumentBuilder,
public nsIContentSink,
public nsAHtml5TreeOpSink,
public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
{
friend class nsHtml5FlushLoopGuard;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
public:
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
NS_DECL_ISUPPORTS_INHERITED
private:
static bool sExternalViewSource;
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
static uint32_t sAppendBatchMaxSize;
static uint32_t sAppendBatchSlotsExamined;
static uint32_t sAppendBatchExaminations;
static uint32_t sLongestTimeOffTheEventLoop;
static uint32_t sTimesFlushLoopInterrupted;
#endif
/**
* Whether EOF needs to be suppressed
*/
bool mSuppressEOF;
bool mReadingFromStage;
nsTArray<nsHtml5TreeOperation> mOpQueue;
nsHtml5StreamParser* mStreamParser;
/**
* URLs already preloaded/preloading.
*/
nsTHashtable<nsCStringHashKey> mPreloadedURLs;
nsCOMPtr<nsIURI> mSpeculationBaseURI;
/**
* Speculative referrer policy
*/
ReferrerPolicy mSpeculationReferrerPolicy;
nsCOMPtr<nsIURI> mViewSourceBaseURI;
/**
* Whether the parser has started
*/
bool mStarted;
nsHtml5TreeOpStage mStage;
bool mRunFlushLoopOnStack;
bool mCallContinueInterruptedParsingIfEnabled;
/**
* Whether this executor has already complained about matters related
* to character encoding declarations.
*/
bool mAlreadyComplainedAboutCharset;
public:
nsHtml5TreeOpExecutor();
protected:
virtual ~nsHtml5TreeOpExecutor();
public:
// nsIContentSink
/**
* Unimplemented. For interface compat only.
*/
NS_IMETHOD WillParse() override;
/**
*
*/
NS_IMETHOD WillBuildModel(nsDTDMode aDTDMode) override;
/**
* Emits EOF.
*/
NS_IMETHOD DidBuildModel(bool aTerminated) override;
/**
* Forwards to nsContentSink
*/
NS_IMETHOD WillInterrupt() override;
/**
* Unimplemented. For interface compat only.
*/
NS_IMETHOD WillResume() override;
/**
* Sets the parser.
*/
NS_IMETHOD SetParser(nsParserBase* aParser) override;
/**
* No-op for backwards compat.
*/
virtual void FlushPendingNotifications(mozFlushType aType) override;
/**
* Don't call. For interface compat only.
*/
NS_IMETHOD SetDocumentCharset(nsACString& aCharset) override {
NS_NOTREACHED("No one should call this.");
return NS_ERROR_NOT_IMPLEMENTED;
}
/**
* Returns the document.
*/
virtual nsISupports *GetTarget() override;
virtual void ContinueInterruptedParsingAsync() override;
bool IsScriptExecuting() override
{
return IsScriptExecutingImpl();
}
// Not from interface
void SetStreamParser(nsHtml5StreamParser* aStreamParser)
{
mStreamParser = aStreamParser;
}
void InitializeDocWriteParserState(nsAHtml5TreeBuilderState* aState, int32_t aLine);
bool IsScriptEnabled();
virtual nsresult MarkAsBroken(nsresult aReason) override;
void StartLayout();
void FlushSpeculativeLoads();
void RunFlushLoop();
nsresult FlushDocumentWrite();
void MaybeSuspend();
void Start();
void NeedsCharsetSwitchTo(const char* aEncoding,
int32_t aSource,
uint32_t aLineNumber);
void MaybeComplainAboutCharset(const char* aMsgId,
bool aError,
uint32_t aLineNumber);
void ComplainAboutBogusProtocolCharset(nsIDocument* aDoc);
bool IsComplete()
{
return !mParser;
}
bool HasStarted()
{
return mStarted;
}
bool IsFlushing()
{
return mFlushState >= eInFlush;
}
#ifdef DEBUG
bool IsInFlushLoop()
{
return mRunFlushLoopOnStack;
}
#endif
void RunScript(nsIContent* aScriptElement);
/**
* Flush the operations from the tree operations from the argument
* queue unconditionally. (This is for the main thread case.)
*/
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue) override;
nsHtml5TreeOpStage* GetStage()
{
return &mStage;
}
void StartReadingFromStage()
{
mReadingFromStage = true;
}
void StreamEnded();
#ifdef DEBUG
void AssertStageEmpty()
{
mStage.AssertEmpty();
}
#endif
nsIURI* GetViewSourceBaseURI();
void PreloadScript(const nsAString& aURL,
const nsAString& aCharset,
const nsAString& aType,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity,
bool aScriptFromHead);
void PreloadStyle(const nsAString& aURL, const nsAString& aCharset,
const nsAString& aCrossOrigin,
const nsAString& aIntegrity);
void PreloadImage(const nsAString& aURL,
const nsAString& aCrossOrigin,
const nsAString& aSrcset,
const nsAString& aSizes,
const nsAString& aImageReferrerPolicy);
void PreloadOpenPicture();
void PreloadEndPicture();
void PreloadPictureSource(const nsAString& aSrcset,
const nsAString& aSizes,
const nsAString& aType,
const nsAString& aMedia);
void SetSpeculationBase(const nsAString& aURL);
void SetSpeculationReferrerPolicy(ReferrerPolicy aReferrerPolicy);
void SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy);
void AddSpeculationCSP(const nsAString& aCSP);
void AddBase(const nsAString& aURL);
static void InitializeStatics();
private:
nsHtml5Parser* GetParser();
bool IsExternalViewSource();
/**
* Get a nsIURI for an nsString if the URL hasn't been preloaded yet.
*/
already_AddRefed<nsIURI> ConvertIfNotPreloadedYet(const nsAString& aURL);
/**
* The base URI we would use for current preload operations
*/
nsIURI* BaseURIForPreload();
/**
* Returns true if we haven't preloaded this URI yet, and adds it to the
* list of preloaded URIs
*/
bool ShouldPreloadURI(nsIURI *aURI);
};
#endif // nsHtml5TreeOpExecutor_h

View file

@ -0,0 +1,56 @@
/* 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 "nsHtml5TreeOpStage.h"
using namespace mozilla;
nsHtml5TreeOpStage::nsHtml5TreeOpStage()
: mMutex("nsHtml5TreeOpStage mutex")
{
}
nsHtml5TreeOpStage::~nsHtml5TreeOpStage()
{
}
void
nsHtml5TreeOpStage::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
{
mozilla::MutexAutoLock autoLock(mMutex);
mOpQueue.AppendElements(Move(aOpQueue));
}
void
nsHtml5TreeOpStage::MoveOpsAndSpeculativeLoadsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue,
nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue)
{
mozilla::MutexAutoLock autoLock(mMutex);
aOpQueue.AppendElements(Move(mOpQueue));
aSpeculativeLoadQueue.AppendElements(Move(mSpeculativeLoadQueue));
}
void
nsHtml5TreeOpStage::MoveSpeculativeLoadsFrom(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue)
{
mozilla::MutexAutoLock autoLock(mMutex);
mSpeculativeLoadQueue.AppendElements(Move(aSpeculativeLoadQueue));
}
void
nsHtml5TreeOpStage::MoveSpeculativeLoadsTo(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue)
{
mozilla::MutexAutoLock autoLock(mMutex);
aSpeculativeLoadQueue.AppendElements(Move(mSpeculativeLoadQueue));
}
#ifdef DEBUG
void
nsHtml5TreeOpStage::AssertEmpty()
{
mozilla::MutexAutoLock autoLock(mMutex);
// This shouldn't really need the mutex
NS_ASSERTION(mOpQueue.IsEmpty(), "The stage was supposed to be empty.");
}
#endif

View file

@ -0,0 +1,54 @@
/* 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 nsHtml5TreeOpStage_h
#define nsHtml5TreeOpStage_h
#include "mozilla/Mutex.h"
#include "nsHtml5TreeOperation.h"
#include "nsTArray.h"
#include "nsAHtml5TreeOpSink.h"
#include "nsHtml5SpeculativeLoad.h"
class nsHtml5TreeOpStage : public nsAHtml5TreeOpSink {
public:
nsHtml5TreeOpStage();
virtual ~nsHtml5TreeOpStage();
/**
* Flush the operations from the tree operations from the argument
* queue unconditionally.
*/
virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue);
/**
* Retrieve the staged operations and speculative loads into the arguments.
*/
void MoveOpsAndSpeculativeLoadsTo(nsTArray<nsHtml5TreeOperation>& aOpQueue,
nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
/**
* Move the speculative loads from the argument into the staging queue.
*/
void MoveSpeculativeLoadsFrom(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
/**
* Retrieve the staged speculative loads into the argument.
*/
void MoveSpeculativeLoadsTo(nsTArray<nsHtml5SpeculativeLoad>& aSpeculativeLoadQueue);
#ifdef DEBUG
void AssertEmpty();
#endif
private:
nsTArray<nsHtml5TreeOperation> mOpQueue;
nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
mozilla::Mutex mMutex;
};
#endif /* nsHtml5TreeOpStage_h */

View file

@ -0,0 +1,995 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* 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 "nsHtml5TreeOperation.h"
#include "nsContentUtils.h"
#include "nsDocElementCreatedNotificationRunner.h"
#include "nsNodeUtils.h"
#include "nsAttrName.h"
#include "nsHtml5TreeBuilder.h"
#include "nsIDOMMutationEvent.h"
#include "mozAutoDocUpdate.h"
#include "nsBindingManager.h"
#include "nsXBLBinding.h"
#include "nsHtml5DocumentMode.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsContentCreatorFunctions.h"
#include "nsIScriptElement.h"
#include "nsIDTD.h"
#include "nsISupportsImpl.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsIDOMDocumentType.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "nsIMutationObserver.h"
#include "nsIFormProcessor.h"
#include "nsIServiceManager.h"
#include "nsEscape.h"
#include "mozilla/dom/Comment.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLTemplateElement.h"
#include "nsHtml5SVGLoadDispatcher.h"
#include "nsIURI.h"
#include "nsIProtocolHandler.h"
#include "nsNetUtil.h"
#include "nsIHTMLDocument.h"
#include "mozilla/Likely.h"
#include "nsTextNode.h"
using namespace mozilla;
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
/**
* Helper class that opens a notification batch if the current doc
* is different from the executor doc.
*/
class MOZ_STACK_CLASS nsHtml5OtherDocUpdate {
public:
nsHtml5OtherDocUpdate(nsIDocument* aCurrentDoc, nsIDocument* aExecutorDoc)
{
NS_PRECONDITION(aCurrentDoc, "Node has no doc?");
NS_PRECONDITION(aExecutorDoc, "Executor has no doc?");
if (MOZ_LIKELY(aCurrentDoc == aExecutorDoc)) {
mDocument = nullptr;
} else {
mDocument = aCurrentDoc;
aCurrentDoc->BeginUpdate(UPDATE_CONTENT_MODEL);
}
}
~nsHtml5OtherDocUpdate()
{
if (MOZ_UNLIKELY(mDocument)) {
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
}
}
private:
nsCOMPtr<nsIDocument> mDocument;
};
nsHtml5TreeOperation::nsHtml5TreeOperation()
: mOpCode(eTreeOpUninitialized)
{
MOZ_COUNT_CTOR(nsHtml5TreeOperation);
}
nsHtml5TreeOperation::~nsHtml5TreeOperation()
{
MOZ_COUNT_DTOR(nsHtml5TreeOperation);
NS_ASSERTION(mOpCode != eTreeOpUninitialized, "Uninitialized tree op.");
switch(mOpCode) {
case eTreeOpAddAttributes:
delete mTwo.attributes;
break;
case eTreeOpCreateElementNetwork:
case eTreeOpCreateElementNotNetwork:
delete mThree.attributes;
break;
case eTreeOpAppendDoctypeToDocument:
delete mTwo.stringPair;
break;
case eTreeOpFosterParentText:
case eTreeOpAppendText:
case eTreeOpAppendComment:
case eTreeOpAppendCommentToDocument:
case eTreeOpAddViewSourceHref:
case eTreeOpAddViewSourceBase:
delete[] mTwo.unicharPtr;
break;
case eTreeOpSetDocumentCharset:
case eTreeOpNeedsCharsetSwitchTo:
delete[] mOne.charPtr;
break;
case eTreeOpProcessOfflineManifest:
free(mOne.unicharPtr);
break;
default: // keep the compiler happy
break;
}
}
nsresult
nsHtml5TreeOperation::AppendTextToTextNode(const char16_t* aBuffer,
uint32_t aLength,
nsIContent* aTextNode,
nsHtml5DocumentBuilder* aBuilder)
{
NS_PRECONDITION(aTextNode, "Got null text node.");
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->IsInDocUpdate());
uint32_t oldLength = aTextNode->TextLength();
CharacterDataChangeInfo info = {
true,
oldLength,
oldLength,
aLength
};
nsNodeUtils::CharacterDataWillChange(aTextNode, &info);
nsresult rv = aTextNode->AppendText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::CharacterDataChanged(aTextNode, &info);
return rv;
}
nsresult
nsHtml5TreeOperation::AppendText(const char16_t* aBuffer,
uint32_t aLength,
nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder)
{
nsresult rv = NS_OK;
nsIContent* lastChild = aParent->GetLastChild();
if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) {
nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
aBuilder->GetDocument());
return AppendTextToTextNode(aBuffer,
aLength,
lastChild,
aBuilder);
}
nsNodeInfoManager* nodeInfoManager = aParent->OwnerDoc()->NodeInfoManager();
RefPtr<nsTextNode> text = new nsTextNode(nodeInfoManager);
NS_ASSERTION(text, "Infallible malloc failed?");
rv = text->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
return Append(text, aParent, aBuilder);
}
nsresult
nsHtml5TreeOperation::Append(nsIContent* aNode,
nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder)
{
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->IsInDocUpdate());
nsresult rv = NS_OK;
nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
aBuilder->GetDocument());
uint32_t childCount = aParent->GetChildCount();
rv = aParent->AppendChildTo(aNode, false);
if (NS_SUCCEEDED(rv)) {
aNode->SetParserHasNotified();
nsNodeUtils::ContentAppended(aParent, aNode, childCount);
}
return rv;
}
nsresult
nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
nsHtml5DocumentBuilder* aBuilder)
{
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->GetDocument() == aNode->OwnerDoc());
MOZ_ASSERT(aBuilder->IsInDocUpdate());
nsresult rv = NS_OK;
nsIDocument* doc = aBuilder->GetDocument();
uint32_t childCount = doc->GetChildCount();
rv = doc->AppendChildTo(aNode, false);
if (rv == NS_ERROR_DOM_HIERARCHY_REQUEST_ERR) {
aNode->SetParserHasNotified();
return NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
aNode->SetParserHasNotified();
nsNodeUtils::ContentInserted(doc, aNode, childCount);
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot to block scripts");
if (aNode->IsElement()) {
nsContentUtils::AddScriptRunner(
new nsDocElementCreatedNotificationRunner(doc));
}
return rv;
}
static bool
IsElementOrTemplateContent(nsINode* aNode) {
if (aNode) {
if (aNode->IsElement()) {
return true;
} else if (aNode->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
// Check if the node is a template content.
mozilla::dom::DocumentFragment* frag =
static_cast<mozilla::dom::DocumentFragment*>(aNode);
nsIContent* fragHost = frag->GetHost();
if (fragHost && nsNodeUtils::IsTemplateElement(fragHost)) {
return true;
}
}
}
return false;
}
void
nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder)
{
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->IsInDocUpdate());
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
if (parent) {
nsHtml5OtherDocUpdate update(parent->OwnerDoc(),
aBuilder->GetDocument());
int32_t pos = parent->IndexOf(aNode);
NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
parent->RemoveChildAt(pos, true);
}
}
nsresult
nsHtml5TreeOperation::AppendChildrenToNewParent(nsIContent* aNode,
nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder)
{
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->IsInDocUpdate());
nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
aBuilder->GetDocument());
uint32_t childCount = aParent->GetChildCount();
bool didAppend = false;
while (aNode->HasChildren()) {
nsCOMPtr<nsIContent> child = aNode->GetFirstChild();
aNode->RemoveChildAt(0, true);
nsresult rv = aParent->AppendChildTo(child, false);
NS_ENSURE_SUCCESS(rv, rv);
didAppend = true;
}
if (didAppend) {
nsNodeUtils::ContentAppended(aParent, aParent->GetChildAt(childCount),
childCount);
}
return NS_OK;
}
nsresult
nsHtml5TreeOperation::FosterParent(nsIContent* aNode,
nsIContent* aParent,
nsIContent* aTable,
nsHtml5DocumentBuilder* aBuilder)
{
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->IsInDocUpdate());
nsIContent* foster = aTable->GetParent();
if (IsElementOrTemplateContent(foster)) {
nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
aBuilder->GetDocument());
uint32_t pos = foster->IndexOf(aTable);
nsresult rv = foster->InsertChildAt(aNode, pos, false);
NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::ContentInserted(foster, aNode, pos);
return rv;
}
return Append(aNode, aParent, aBuilder);
}
nsresult
nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
nsHtml5HtmlAttributes* aAttributes,
nsHtml5DocumentBuilder* aBuilder)
{
dom::Element* node = aNode->AsElement();
nsHtml5OtherDocUpdate update(node->OwnerDoc(),
aBuilder->GetDocument());
int32_t len = aAttributes->getLength();
for (int32_t i = len; i > 0;) {
--i;
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
nsCOMPtr<nsIAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
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);
// XXX what to do with nsresult?
}
}
return NS_OK;
}
nsIContent*
nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder)
{
bool isKeygen = (aName == nsHtml5Atoms::keygen && aNs == kNameSpaceID_XHTML);
if (MOZ_UNLIKELY(isKeygen)) {
aName = nsHtml5Atoms::select;
}
nsCOMPtr<dom::Element> newElement;
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->
GetNodeInfo(aName, nullptr, aNs, nsIDOMNode::ELEMENT_NODE);
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
NS_NewElement(getter_AddRefs(newElement),
nodeInfo.forget(),
aFromParser);
NS_ASSERTION(newElement, "Element creation created null pointer.");
dom::Element* newContent = newElement;
aBuilder->HoldElement(newElement.forget());
if (MOZ_UNLIKELY(aName == nsHtml5Atoms::style || aName == nsHtml5Atoms::link)) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(false);
ssle->SetEnableUpdates(false);
}
} else if (MOZ_UNLIKELY(isKeygen)) {
// Adapted from CNavDTD
nsresult rv;
nsCOMPtr<nsIFormProcessor> theFormProcessor =
do_GetService(kFormProcessorCID, &rv);
if (NS_FAILED(rv)) {
return newContent;
}
nsTArray<nsString> theContent;
nsAutoString theAttribute;
(void) theFormProcessor->ProvideContent(NS_LITERAL_STRING("select"),
theContent,
theAttribute);
newContent->SetAttr(kNameSpaceID_None,
nsGkAtoms::moztype,
nullptr,
theAttribute,
false);
RefPtr<dom::NodeInfo> optionNodeInfo =
aNodeInfoManager->GetNodeInfo(nsHtml5Atoms::option,
nullptr,
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
for (uint32_t i = 0; i < theContent.Length(); ++i) {
nsCOMPtr<dom::Element> optionElt;
RefPtr<dom::NodeInfo> ni = optionNodeInfo;
NS_NewElement(getter_AddRefs(optionElt),
ni.forget(),
aFromParser);
RefPtr<nsTextNode> optionText = new nsTextNode(aNodeInfoManager);
(void) optionText->SetText(theContent[i], false);
optionElt->AppendChildTo(optionText, false);
newContent->AppendChildTo(optionElt, false);
// XXXsmaug Shouldn't we call this after adding all the child nodes.
newContent->DoneAddingChildren(false);
}
}
if (!aAttributes) {
return newContent;
}
int32_t len = aAttributes->getLength();
for (int32_t i = 0; i < len; i++) {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
nsCOMPtr<nsIAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
nsCOMPtr<nsIAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
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_ConvertUTF8toUTF16 uv(nsUnescape(cname.BeginWriting()));
newContent->SetAttr(nsuri,
localName,
prefix,
uv,
false);
} else {
nsString& value = *(aAttributes->getValueNoBoundsCheck(i));
newContent->SetAttr(nsuri,
localName,
prefix,
value,
false);
// Custom element setup may be needed if there is an "is" attribute.
if (kNameSpaceID_None == nsuri && !prefix && nsGkAtoms::is == localName) {
nsContentUtils::SetupCustomElement(newContent, &value);
}
}
}
return newContent;
}
void
nsHtml5TreeOperation::SetFormElement(nsIContent* aNode, nsIContent* aParent)
{
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(aNode));
nsCOMPtr<nsIDOMHTMLImageElement> domImageElement = do_QueryInterface(aNode);
// NS_ASSERTION(formControl, "Form-associated element did not implement nsIFormControl.");
// TODO: uncomment the above line when <keygen> (bug 101019) is supported by Gecko
nsCOMPtr<nsIDOMHTMLFormElement> formElement(do_QueryInterface(aParent));
NS_ASSERTION(formElement, "The form element doesn't implement nsIDOMHTMLFormElement.");
// avoid crashing on <keygen>
if (formControl &&
!aNode->HasAttr(kNameSpaceID_None, nsGkAtoms::form)) {
formControl->SetForm(formElement);
} else if (domImageElement) {
RefPtr<dom::HTMLImageElement> imageElement =
static_cast<dom::HTMLImageElement*>(domImageElement.get());
MOZ_ASSERT(imageElement);
imageElement->SetForm(formElement);
}
}
nsresult
nsHtml5TreeOperation::AppendIsindexPrompt(nsIContent* parent, nsHtml5DocumentBuilder* aBuilder)
{
nsXPIDLString prompt;
nsresult rv =
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"IsIndexPromptWithSpace", prompt);
uint32_t len = prompt.Length();
if (NS_FAILED(rv)) {
return rv;
}
if (!len) {
// Don't bother appending a zero-length text node.
return NS_OK;
}
return AppendText(prompt.BeginReading(), len, parent, aBuilder);
}
nsresult
nsHtml5TreeOperation::FosterParentText(nsIContent* aStackParent,
char16_t* aBuffer,
uint32_t aLength,
nsIContent* aTable,
nsHtml5DocumentBuilder* aBuilder)
{
MOZ_ASSERT(aBuilder);
MOZ_ASSERT(aBuilder->IsInDocUpdate());
nsresult rv = NS_OK;
nsIContent* foster = aTable->GetParent();
if (IsElementOrTemplateContent(foster)) {
nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
aBuilder->GetDocument());
uint32_t pos = foster->IndexOf(aTable);
nsIContent* previousSibling = aTable->GetPreviousSibling();
if (previousSibling && previousSibling->IsNodeOfType(nsINode::eTEXT)) {
return AppendTextToTextNode(aBuffer,
aLength,
previousSibling,
aBuilder);
}
nsNodeInfoManager* nodeInfoManager = aStackParent->OwnerDoc()->NodeInfoManager();
RefPtr<nsTextNode> text = new nsTextNode(nodeInfoManager);
NS_ASSERTION(text, "Infallible malloc failed?");
rv = text->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = foster->InsertChildAt(text, pos, false);
NS_ENSURE_SUCCESS(rv, rv);
nsNodeUtils::ContentInserted(foster, text, pos);
return rv;
}
return AppendText(aBuffer, aLength, aStackParent, aBuilder);
}
nsresult
nsHtml5TreeOperation::AppendComment(nsIContent* aParent,
char16_t* aBuffer,
int32_t aLength,
nsHtml5DocumentBuilder* aBuilder)
{
nsNodeInfoManager* nodeInfoManager = aParent->OwnerDoc()->NodeInfoManager();
RefPtr<dom::Comment> comment = new dom::Comment(nodeInfoManager);
NS_ASSERTION(comment, "Infallible malloc failed?");
nsresult rv = comment->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
return Append(comment, aParent, aBuilder);
}
nsresult
nsHtml5TreeOperation::AppendCommentToDocument(char16_t* aBuffer,
int32_t aLength,
nsHtml5DocumentBuilder* aBuilder)
{
RefPtr<dom::Comment> comment =
new dom::Comment(aBuilder->GetNodeInfoManager());
NS_ASSERTION(comment, "Infallible malloc failed?");
nsresult rv = comment->SetText(aBuffer, aLength, false);
NS_ENSURE_SUCCESS(rv, rv);
return AppendToDocument(comment, aBuilder);
}
nsresult
nsHtml5TreeOperation::AppendDoctypeToDocument(nsIAtom* aName,
const nsAString& aPublicId,
const nsAString& aSystemId,
nsHtml5DocumentBuilder* aBuilder)
{
// Adapted from nsXMLContentSink
// Create a new doctype node
nsCOMPtr<nsIDOMDocumentType> docType;
NS_NewDOMDocumentType(getter_AddRefs(docType),
aBuilder->GetNodeInfoManager(),
aName,
aPublicId,
aSystemId,
NullString());
NS_ASSERTION(docType, "Doctype creation failed.");
nsCOMPtr<nsIContent> asContent = do_QueryInterface(docType);
return AppendToDocument(asContent, aBuilder);
}
nsIContent*
nsHtml5TreeOperation::GetDocumentFragmentForTemplate(nsIContent* aNode)
{
dom::HTMLTemplateElement* tempElem =
static_cast<dom::HTMLTemplateElement*>(aNode);
RefPtr<dom::DocumentFragment> frag = tempElem->Content();
return frag;
}
nsIContent*
nsHtml5TreeOperation::GetFosterParent(nsIContent* aTable, nsIContent* aStackParent)
{
nsIContent* tableParent = aTable->GetParent();
return IsElementOrTemplateContent(tableParent) ? tableParent : aStackParent;
}
void
nsHtml5TreeOperation::PreventScriptExecution(nsIContent* aNode)
{
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
MOZ_ASSERT(sele);
sele->PreventExecution();
}
void
nsHtml5TreeOperation::DoneAddingChildren(nsIContent* aNode)
{
aNode->DoneAddingChildren(aNode->HasParserNotified());
}
void
nsHtml5TreeOperation::DoneCreatingElement(nsIContent* aNode)
{
aNode->DoneCreatingElement();
}
void
nsHtml5TreeOperation::SvgLoad(nsIContent* aNode)
{
nsCOMPtr<nsIRunnable> event = new nsHtml5SVGLoadDispatcher(aNode);
if (NS_FAILED(NS_DispatchToMainThread(event))) {
NS_WARNING("failed to dispatch svg load dispatcher");
}
}
void
nsHtml5TreeOperation::MarkMalformedIfScript(nsIContent* aNode)
{
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
if (sele) {
// Make sure to serialize this script correctly, for nice round tripping.
sele->SetIsMalformed();
}
}
nsresult
nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
nsIContent** aScriptElement)
{
switch(mOpCode) {
case eTreeOpUninitialized: {
MOZ_CRASH("eTreeOpUninitialized");
}
case eTreeOpAppend: {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
return Append(node, parent, aBuilder);
}
case eTreeOpDetach: {
nsIContent* node = *(mOne.node);
Detach(node, aBuilder);
return NS_OK;
}
case eTreeOpAppendChildrenToNewParent: {
nsCOMPtr<nsIContent> node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
return AppendChildrenToNewParent(node, parent, aBuilder);
}
case eTreeOpFosterParent: {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
nsIContent* table = *(mThree.node);
return FosterParent(node, parent, table, aBuilder);
}
case eTreeOpAppendToDocument: {
nsIContent* node = *(mOne.node);
return AppendToDocument(node, aBuilder);
}
case eTreeOpAddAttributes: {
nsIContent* node = *(mOne.node);
nsHtml5HtmlAttributes* attributes = mTwo.attributes;
return AddAttributes(node, attributes, aBuilder);
}
case eTreeOpDocumentMode: {
aBuilder->SetDocumentMode(mOne.mode);
return NS_OK;
}
case eTreeOpCreateElementNetwork:
case eTreeOpCreateElementNotNetwork: {
nsIContent** target = mOne.node;
int32_t ns = mFour.integer;
nsCOMPtr<nsIAtom> name = Reget(mTwo.atom);
nsHtml5HtmlAttributes* attributes = mThree.attributes;
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
// intendedParent == nullptr is a special case where the
// intended parent is the document.
nsNodeInfoManager* nodeInfoManager = intendedParent ?
intendedParent->OwnerDoc()->NodeInfoManager() :
aBuilder->GetNodeInfoManager();
*target = CreateElement(ns,
name,
attributes,
mOpCode == eTreeOpCreateElementNetwork ?
dom::FROM_PARSER_NETWORK :
dom::FROM_PARSER_DOCUMENT_WRITE,
nodeInfoManager,
aBuilder);
return NS_OK;
}
case eTreeOpSetFormElement: {
nsIContent* node = *(mOne.node);
nsIContent* parent = *(mTwo.node);
SetFormElement(node, parent);
return NS_OK;
}
case eTreeOpAppendText: {
nsIContent* parent = *mOne.node;
char16_t* buffer = mTwo.unicharPtr;
uint32_t length = mFour.integer;
return AppendText(buffer, length, parent, aBuilder);
}
case eTreeOpAppendIsindexPrompt: {
nsIContent* parent = *mOne.node;
return AppendIsindexPrompt(parent, aBuilder);
}
case eTreeOpFosterParentText: {
nsIContent* stackParent = *mOne.node;
char16_t* buffer = mTwo.unicharPtr;
uint32_t length = mFour.integer;
nsIContent* table = *mThree.node;
return FosterParentText(stackParent, buffer, length, table, aBuilder);
}
case eTreeOpAppendComment: {
nsIContent* parent = *mOne.node;
char16_t* buffer = mTwo.unicharPtr;
int32_t length = mFour.integer;
return AppendComment(parent, buffer, length, aBuilder);
}
case eTreeOpAppendCommentToDocument: {
char16_t* buffer = mTwo.unicharPtr;
int32_t length = mFour.integer;
return AppendCommentToDocument(buffer, length, aBuilder);
}
case eTreeOpAppendDoctypeToDocument: {
nsCOMPtr<nsIAtom> name = Reget(mOne.atom);
nsHtml5TreeOperationStringPair* pair = mTwo.stringPair;
nsString publicId;
nsString systemId;
pair->Get(publicId, systemId);
return AppendDoctypeToDocument(name, publicId, systemId, aBuilder);
}
case eTreeOpGetDocumentFragmentForTemplate: {
nsIContent* node = *(mOne.node);
*mTwo.node = GetDocumentFragmentForTemplate(node);
return NS_OK;
}
case eTreeOpGetFosterParent: {
nsIContent* table = *(mOne.node);
nsIContent* stackParent = *(mTwo.node);
nsIContent* fosterParent = GetFosterParent(table, stackParent);
*mThree.node = fosterParent;
return NS_OK;
}
case eTreeOpMarkAsBroken: {
return mOne.result;
}
case eTreeOpRunScript: {
nsIContent* node = *(mOne.node);
nsAHtml5TreeBuilderState* snapshot = mTwo.state;
if (snapshot) {
aBuilder->InitializeDocWriteParserState(snapshot, mFour.integer);
}
*aScriptElement = node;
return NS_OK;
}
case eTreeOpRunScriptAsyncDefer: {
nsIContent* node = *(mOne.node);
aBuilder->RunScript(node);
return NS_OK;
}
case eTreeOpPreventScriptExecution: {
nsIContent* node = *(mOne.node);
PreventScriptExecution(node);
return NS_OK;
}
case eTreeOpDoneAddingChildren: {
nsIContent* node = *(mOne.node);
node->DoneAddingChildren(node->HasParserNotified());
return NS_OK;
}
case eTreeOpDoneCreatingElement: {
nsIContent* node = *(mOne.node);
DoneCreatingElement(node);
return NS_OK;
}
case eTreeOpSetDocumentCharset: {
char* str = mOne.charPtr;
int32_t charsetSource = mFour.integer;
nsDependentCString dependentString(str);
aBuilder->SetDocumentCharsetAndSource(dependentString, charsetSource);
return NS_OK;
}
case eTreeOpNeedsCharsetSwitchTo: {
char* str = mOne.charPtr;
int32_t charsetSource = mFour.integer;
int32_t lineNumber = mTwo.integer;
aBuilder->NeedsCharsetSwitchTo(str, charsetSource, (uint32_t)lineNumber);
return NS_OK;
}
case eTreeOpUpdateStyleSheet: {
nsIContent* node = *(mOne.node);
aBuilder->UpdateStyleSheet(node);
return NS_OK;
}
case eTreeOpProcessMeta: {
nsIContent* node = *(mOne.node);
return aBuilder->ProcessMETATag(node);
}
case eTreeOpProcessOfflineManifest: {
char16_t* str = mOne.unicharPtr;
nsDependentString dependentString(str);
aBuilder->ProcessOfflineManifest(dependentString);
return NS_OK;
}
case eTreeOpMarkMalformedIfScript: {
nsIContent* node = *(mOne.node);
MarkMalformedIfScript(node);
return NS_OK;
}
case eTreeOpStreamEnded: {
aBuilder->DidBuildModel(false); // this causes a notifications flush anyway
return NS_OK;
}
case eTreeOpSetStyleLineNumber: {
nsIContent* node = *(mOne.node);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(node);
NS_ASSERTION(ssle, "Node didn't QI to style.");
ssle->SetLineNumber(mFour.integer);
return NS_OK;
}
case eTreeOpSetScriptLineNumberAndFreeze: {
nsIContent* node = *(mOne.node);
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(node);
NS_ASSERTION(sele, "Node didn't QI to script.");
sele->SetScriptLineNumber(mFour.integer);
sele->FreezeUriAsyncDefer();
return NS_OK;
}
case eTreeOpSvgLoad: {
nsIContent* node = *(mOne.node);
SvgLoad(node);
return NS_OK;
}
case eTreeOpMaybeComplainAboutCharset: {
char* msgId = mOne.charPtr;
bool error = mTwo.integer;
int32_t lineNumber = mThree.integer;
aBuilder->MaybeComplainAboutCharset(msgId, error, (uint32_t)lineNumber);
return NS_OK;
}
case eTreeOpAddClass: {
nsIContent* node = *(mOne.node);
char16_t* str = mTwo.unicharPtr;
nsDependentString depStr(str);
// See viewsource.css for the possible classes
nsAutoString klass;
node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
if (!klass.IsEmpty()) {
klass.Append(' ');
klass.Append(depStr);
node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
} else {
node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, depStr, true);
}
return NS_OK;
}
case eTreeOpAddViewSourceHref: {
nsIContent* node = *mOne.node;
char16_t* buffer = mTwo.unicharPtr;
int32_t length = mFour.integer;
nsDependentString relative(buffer, length);
nsIDocument* doc = aBuilder->GetDocument();
const nsCString& charset = doc->GetDocumentCharacterSet();
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri),
relative,
charset.get(),
aBuilder->GetViewSourceBaseURI());
NS_ENSURE_SUCCESS(rv, NS_OK);
// Reuse the fix for bug 467852
// URLs that execute script (e.g. "javascript:" URLs) should just be
// ignored. There's nothing reasonable we can do with them, and allowing
// them to execute in the context of the view-source window presents a
// security risk. Just return the empty string in this case.
bool openingExecutesScript = false;
rv = NS_URIChainHasFlags(uri,
nsIProtocolHandler::URI_OPENING_EXECUTES_SCRIPT,
&openingExecutesScript);
if (NS_FAILED(rv) || openingExecutesScript) {
return NS_OK;
}
nsAutoCString viewSourceUrl;
// URLs that return data (e.g. "http:" URLs) should be prefixed with
// "view-source:". URLs that don't return data should just be returned
// undecorated.
bool doesNotReturnData = false;
rv = NS_URIChainHasFlags(uri,
nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
&doesNotReturnData);
NS_ENSURE_SUCCESS(rv, NS_OK);
if (!doesNotReturnData) {
viewSourceUrl.AssignLiteral("view-source:");
}
nsAutoCString spec;
rv = uri->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
viewSourceUrl.Append(spec);
nsAutoString utf16;
CopyUTF8toUTF16(viewSourceUrl, utf16);
node->SetAttr(kNameSpaceID_None, nsGkAtoms::href, utf16, true);
return NS_OK;
}
case eTreeOpAddViewSourceBase: {
char16_t* buffer = mTwo.unicharPtr;
int32_t length = mFour.integer;
nsDependentString baseUrl(buffer, length);
aBuilder->AddBase(baseUrl);
return NS_OK;
}
case eTreeOpAddError: {
nsIContent* node = *(mOne.node);
char* msgId = mTwo.charPtr;
nsCOMPtr<nsIAtom> atom = Reget(mThree.atom);
nsCOMPtr<nsIAtom> otherAtom = Reget(mFour.atom);
// See viewsource.css for the possible classes in addition to "error".
nsAutoString klass;
node->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);
if (!klass.IsEmpty()) {
klass.AppendLiteral(" error");
node->SetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass, true);
} else {
node->SetAttr(kNameSpaceID_None,
nsGkAtoms::_class,
NS_LITERAL_STRING("error"),
true);
}
nsresult rv;
nsXPIDLString message;
if (otherAtom) {
const char16_t* params[] = { atom->GetUTF16String(),
otherAtom->GetUTF16String() };
rv = nsContentUtils::FormatLocalizedString(
nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, params, message);
NS_ENSURE_SUCCESS(rv, NS_OK);
} else if (atom) {
const char16_t* params[] = { atom->GetUTF16String() };
rv = nsContentUtils::FormatLocalizedString(
nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, params, message);
NS_ENSURE_SUCCESS(rv, NS_OK);
} else {
rv = nsContentUtils::GetLocalizedString(
nsContentUtils::eHTMLPARSER_PROPERTIES, msgId, message);
NS_ENSURE_SUCCESS(rv, NS_OK);
}
nsAutoString title;
node->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
if (!title.IsEmpty()) {
title.Append('\n');
title.Append(message);
node->SetAttr(kNameSpaceID_None, nsGkAtoms::title, title, true);
} else {
node->SetAttr(kNameSpaceID_None, nsGkAtoms::title, message, true);
}
return rv;
}
case eTreeOpAddLineNumberId: {
nsIContent* node = *(mOne.node);
int32_t lineNumber = mFour.integer;
nsAutoString val(NS_LITERAL_STRING("line"));
val.AppendInt(lineNumber);
node->SetAttr(kNameSpaceID_None, nsGkAtoms::id, val, true);
return NS_OK;
}
case eTreeOpStartLayout: {
aBuilder->StartLayout(); // this causes a notification flush anyway
return NS_OK;
}
default: {
MOZ_CRASH("Bogus tree op");
}
}
return NS_OK; // keep compiler happy
}

View file

@ -0,0 +1,513 @@
/* 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 nsHtml5TreeOperation_h
#define nsHtml5TreeOperation_h
#include "nsHtml5DocumentMode.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsXPCOMStrings.h"
#include "mozilla/dom/FromParser.h"
class nsIContent;
class nsHtml5TreeOpExecutor;
class nsHtml5DocumentBuilder;
enum eHtml5TreeOperation {
eTreeOpUninitialized,
// main HTML5 ops
eTreeOpAppend,
eTreeOpDetach,
eTreeOpAppendChildrenToNewParent,
eTreeOpFosterParent,
eTreeOpAppendToDocument,
eTreeOpAddAttributes,
eTreeOpDocumentMode,
eTreeOpCreateElementNetwork,
eTreeOpCreateElementNotNetwork,
eTreeOpSetFormElement,
eTreeOpAppendText,
eTreeOpAppendIsindexPrompt,
eTreeOpFosterParentText,
eTreeOpAppendComment,
eTreeOpAppendCommentToDocument,
eTreeOpAppendDoctypeToDocument,
eTreeOpGetDocumentFragmentForTemplate,
eTreeOpGetFosterParent,
// Gecko-specific on-pop ops
eTreeOpMarkAsBroken,
eTreeOpRunScript,
eTreeOpRunScriptAsyncDefer,
eTreeOpPreventScriptExecution,
eTreeOpDoneAddingChildren,
eTreeOpDoneCreatingElement,
eTreeOpSetDocumentCharset,
eTreeOpNeedsCharsetSwitchTo,
eTreeOpUpdateStyleSheet,
eTreeOpProcessMeta,
eTreeOpProcessOfflineManifest,
eTreeOpMarkMalformedIfScript,
eTreeOpStreamEnded,
eTreeOpSetStyleLineNumber,
eTreeOpSetScriptLineNumberAndFreeze,
eTreeOpSvgLoad,
eTreeOpMaybeComplainAboutCharset,
eTreeOpAddClass,
eTreeOpAddViewSourceHref,
eTreeOpAddViewSourceBase,
eTreeOpAddError,
eTreeOpAddLineNumberId,
eTreeOpStartLayout
};
class nsHtml5TreeOperationStringPair {
private:
nsString mPublicId;
nsString mSystemId;
public:
nsHtml5TreeOperationStringPair(const nsAString& aPublicId,
const nsAString& aSystemId)
: mPublicId(aPublicId)
, mSystemId(aSystemId)
{
MOZ_COUNT_CTOR(nsHtml5TreeOperationStringPair);
}
~nsHtml5TreeOperationStringPair()
{
MOZ_COUNT_DTOR(nsHtml5TreeOperationStringPair);
}
inline void Get(nsAString& aPublicId, nsAString& aSystemId)
{
aPublicId.Assign(mPublicId);
aSystemId.Assign(mSystemId);
}
};
class nsHtml5TreeOperation {
public:
/**
* Atom is used inside the parser core are either static atoms that are
* the same as Gecko-wide static atoms or they are dynamic atoms scoped by
* both thread and parser to a particular nsHtml5AtomTable. In order to
* such scoped atoms coming into contact with the rest of Gecko, atoms
* that are about to exit the parser must go through this method which
* reobtains dynamic atoms from the Gecko-global atom table.
*
* @param aAtom a potentially parser-scoped atom
* @return an nsIAtom that's pointer comparable on the main thread with
* other not-parser atoms.
*/
static inline already_AddRefed<nsIAtom> Reget(nsIAtom* aAtom)
{
if (!aAtom || aAtom->IsStaticAtom()) {
return dont_AddRef(aAtom);
}
nsAutoString str;
aAtom->ToString(str);
return NS_Atomize(str);
}
static nsresult AppendTextToTextNode(const char16_t* aBuffer,
uint32_t aLength,
nsIContent* aTextNode,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendText(const char16_t* aBuffer,
uint32_t aLength,
nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder);
static nsresult Append(nsIContent* aNode,
nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendToDocument(nsIContent* aNode,
nsHtml5DocumentBuilder* aBuilder);
static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendChildrenToNewParent(nsIContent* aNode,
nsIContent* aParent,
nsHtml5DocumentBuilder* aBuilder);
static nsresult FosterParent(nsIContent* aNode,
nsIContent* aParent,
nsIContent* aTable,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AddAttributes(nsIContent* aNode,
nsHtml5HtmlAttributes* aAttributes,
nsHtml5DocumentBuilder* aBuilder);
static nsIContent* CreateElement(int32_t aNs,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder);
static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
static nsresult AppendIsindexPrompt(nsIContent* parent,
nsHtml5DocumentBuilder* aBuilder);
static nsresult FosterParentText(nsIContent* aStackParent,
char16_t* aBuffer,
uint32_t aLength,
nsIContent* aTable,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendComment(nsIContent* aParent,
char16_t* aBuffer,
int32_t aLength,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendCommentToDocument(char16_t* aBuffer,
int32_t aLength,
nsHtml5DocumentBuilder* aBuilder);
static nsresult AppendDoctypeToDocument(nsIAtom* aName,
const nsAString& aPublicId,
const nsAString& aSystemId,
nsHtml5DocumentBuilder* aBuilder);
static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
static nsIContent* GetFosterParent(nsIContent* aTable, nsIContent* aStackParent);
static void PreventScriptExecution(nsIContent* aNode);
static void DoneAddingChildren(nsIContent* aNode);
static void DoneCreatingElement(nsIContent* aNode);
static void SvgLoad(nsIContent* aNode);
static void MarkMalformedIfScript(nsIContent* aNode);
nsHtml5TreeOperation();
~nsHtml5TreeOperation();
inline void Init(eHtml5TreeOperation aOpCode)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
mOpCode = aOpCode;
}
inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
mOpCode = aOpCode;
mOne.node = static_cast<nsIContent**>(aNode);
}
inline void Init(eHtml5TreeOperation aOpCode,
nsIContentHandle* aNode,
nsIContentHandle* aParent)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
mOpCode = aOpCode;
mOne.node = static_cast<nsIContent**>(aNode);
mTwo.node = static_cast<nsIContent**>(aParent);
}
inline void Init(eHtml5TreeOperation aOpCode,
const nsACString& aString,
int32_t aInt32)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
int32_t len = aString.Length();
char* str = new char[len + 1];
const char* start = aString.BeginReading();
for (int32_t i = 0; i < len; ++i) {
str[i] = start[i];
}
str[len] = '\0';
mOpCode = aOpCode;
mOne.charPtr = str;
mFour.integer = aInt32;
}
inline void Init(eHtml5TreeOperation aOpCode,
const nsACString& aString,
int32_t aInt32,
int32_t aLineNumber)
{
Init(aOpCode, aString, aInt32);
mTwo.integer = aLineNumber;
}
inline void Init(eHtml5TreeOperation aOpCode,
nsIContentHandle* aNode,
nsIContentHandle* aParent,
nsIContentHandle* aTable)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
NS_PRECONDITION(aTable, "Initialized tree op with null table.");
mOpCode = aOpCode;
mOne.node = static_cast<nsIContent**>(aNode);
mTwo.node = static_cast<nsIContent**>(aParent);
mThree.node = static_cast<nsIContent**>(aTable);
}
inline void Init(nsHtml5DocumentMode aMode)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
mOpCode = eTreeOpDocumentMode;
mOne.mode = aMode;
}
inline void InitScript(nsIContentHandle* aNode)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
mOpCode = eTreeOpRunScript;
mOne.node = static_cast<nsIContent**>(aNode);
mTwo.state = nullptr;
}
inline void Init(int32_t aNamespace,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aTarget,
nsIContentHandle* aIntendedParent,
bool aFromNetwork)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aName, "Initialized tree op with null name.");
NS_PRECONDITION(aTarget, "Initialized tree op with null target node.");
mOpCode = aFromNetwork ?
eTreeOpCreateElementNetwork :
eTreeOpCreateElementNotNetwork;
mFour.integer = aNamespace;
mFive.node = static_cast<nsIContent**>(aIntendedParent);
mOne.node = static_cast<nsIContent**>(aTarget);
mTwo.atom = aName;
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
mThree.attributes = nullptr;
} else {
mThree.attributes = aAttributes;
}
}
inline void Init(eHtml5TreeOperation aOpCode,
char16_t* aBuffer,
int32_t aLength,
nsIContentHandle* aStackParent,
nsIContentHandle* aTable)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
mOpCode = aOpCode;
mOne.node = static_cast<nsIContent**>(aStackParent);
mTwo.unicharPtr = aBuffer;
mThree.node = static_cast<nsIContent**>(aTable);
mFour.integer = aLength;
}
inline void Init(eHtml5TreeOperation aOpCode,
char16_t* aBuffer,
int32_t aLength,
nsIContentHandle* aParent)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
mOpCode = aOpCode;
mOne.node = static_cast<nsIContent**>(aParent);
mTwo.unicharPtr = aBuffer;
mFour.integer = aLength;
}
inline void Init(eHtml5TreeOperation aOpCode,
char16_t* aBuffer,
int32_t aLength)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
mOpCode = aOpCode;
mTwo.unicharPtr = aBuffer;
mFour.integer = aLength;
}
inline void Init(nsIContentHandle* aElement,
nsHtml5HtmlAttributes* aAttributes)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aElement, "Initialized tree op with null element.");
mOpCode = eTreeOpAddAttributes;
mOne.node = static_cast<nsIContent**>(aElement);
mTwo.attributes = aAttributes;
}
inline void Init(nsIAtom* aName,
const nsAString& aPublicId,
const nsAString& aSystemId)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
mOpCode = eTreeOpAppendDoctypeToDocument;
mOne.atom = aName;
mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
}
inline void Init(nsIContentHandle* aElement,
const char* aMsgId,
nsIAtom* aAtom,
nsIAtom* aOtherAtom)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
mOpCode = eTreeOpAddError;
mOne.node = static_cast<nsIContent**>(aElement);
mTwo.charPtr = (char*)aMsgId;
mThree.atom = aAtom;
mFour.atom = aOtherAtom;
}
inline void Init(nsIContentHandle* aElement,
const char* aMsgId,
nsIAtom* aAtom)
{
Init(aElement, aMsgId, aAtom, nullptr);
}
inline void Init(nsIContentHandle* aElement,
const char* aMsgId)
{
Init(aElement, aMsgId, nullptr, nullptr);
}
inline void Init(const char* aMsgId,
bool aError,
int32_t aLineNumber)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
mOpCode = eTreeOpMaybeComplainAboutCharset;
mOne.charPtr = const_cast<char*>(aMsgId);
mTwo.integer = aError;
mThree.integer = aLineNumber;
}
inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
char16_t* str = NS_StringCloneData(aString);
mOpCode = aOpCode;
mOne.unicharPtr = str;
}
inline void Init(eHtml5TreeOperation aOpCode,
nsIContentHandle* aNode,
int32_t aInt)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
mOpCode = aOpCode;
mOne.node = static_cast<nsIContent**>(aNode);
mFour.integer = aInt;
}
inline void Init(nsresult aRv)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure.");
mOpCode = eTreeOpMarkAsBroken;
mOne.result = aRv;
}
inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
NS_PRECONDITION(aClass, "Initialized tree op with null string.");
// aClass must be a literal string that does not need freeing
mOpCode = eTreeOpAddClass;
mOne.node = static_cast<nsIContent**>(aNode);
mTwo.unicharPtr = (char16_t*)aClass;
}
inline void InitAddLineNumberId(nsIContentHandle* aNode,
const int32_t aLineNumber)
{
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
NS_PRECONDITION(aNode, "Initialized tree op with null node.");
NS_PRECONDITION(aLineNumber > 0, "Initialized tree op with line number.");
// aClass must be a literal string that does not need freeing
mOpCode = eTreeOpAddLineNumberId;
mOne.node = static_cast<nsIContent**>(aNode);
mFour.integer = aLineNumber;
}
inline bool IsRunScript()
{
return mOpCode == eTreeOpRunScript;
}
inline bool IsMarkAsBroken()
{
return mOpCode == eTreeOpMarkAsBroken;
}
inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine)
{
NS_ASSERTION(IsRunScript(),
"Setting a snapshot for a tree operation other than eTreeOpRunScript!");
NS_PRECONDITION(aSnapshot, "Initialized tree op with null snapshot.");
mTwo.state = aSnapshot;
mFour.integer = aLine;
}
nsresult Perform(nsHtml5TreeOpExecutor* aBuilder,
nsIContent** aScriptElement);
private:
// possible optimization:
// Make the queue take items the size of pointer and make the op code
// decide how many operands it dequeues after it.
eHtml5TreeOperation mOpCode;
union {
nsIContent** node;
nsIAtom* atom;
nsHtml5HtmlAttributes* attributes;
nsHtml5DocumentMode mode;
char16_t* unicharPtr;
char* charPtr;
nsHtml5TreeOperationStringPair* stringPair;
nsAHtml5TreeBuilderState* state;
int32_t integer;
nsresult result;
} mOne, mTwo, mThree, mFour, mFive;
};
#endif // nsHtml5TreeOperation_h

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2008-2010 Mozilla Foundation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* THIS IS A GENERATED FILE. PLEASE DO NOT EDIT.
* Please edit UTF16Buffer.java instead and regenerate.
*/
#define nsHtml5UTF16Buffer_cpp__
#include "nsIAtom.h"
#include "nsHtml5AtomTable.h"
#include "nsString.h"
#include "nsNameSpaceManager.h"
#include "nsIContent.h"
#include "nsTraceRefcnt.h"
#include "jArray.h"
#include "nsHtml5ArrayCopy.h"
#include "nsAHtml5TreeBuilderState.h"
#include "nsHtml5Atoms.h"
#include "nsHtml5ByteReadable.h"
#include "nsIUnicodeDecoder.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Tokenizer.h"
#include "nsHtml5TreeBuilder.h"
#include "nsHtml5MetaScanner.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5HtmlAttributes.h"
#include "nsHtml5StackNode.h"
#include "nsHtml5StateSnapshot.h"
#include "nsHtml5Portability.h"
#include "nsHtml5UTF16Buffer.h"
int32_t
nsHtml5UTF16Buffer::getStart()
{
return start;
}
void
nsHtml5UTF16Buffer::setStart(int32_t start)
{
this->start = start;
}
char16_t*
nsHtml5UTF16Buffer::getBuffer()
{
return buffer;
}
int32_t
nsHtml5UTF16Buffer::getEnd()
{
return end;
}
bool
nsHtml5UTF16Buffer::hasMore()
{
return start < end;
}
int32_t
nsHtml5UTF16Buffer::getLength()
{
return end - start;
}
void
nsHtml5UTF16Buffer::adjust(bool lastWasCR)
{
if (lastWasCR && buffer[start] == '\n') {
start++;
}
}
void
nsHtml5UTF16Buffer::setEnd(int32_t end)
{
this->end = end;
}
void
nsHtml5UTF16Buffer::initializeStatics()
{
}
void
nsHtml5UTF16Buffer::releaseStatics()
{
}
#include "nsHtml5UTF16BufferCppSupplement.h"

Some files were not shown because too many files have changed in this diff Show more