Bug 483155 - Put content creator function pointers onto nsHtml5ElementName. r=smaug

MozReview-Commit-ID: E2AAx7Zz2UF

--HG--
extra : rebase_source : 989c11459e16076a043aa7311c95941686e86ef7
This commit is contained in:
Henri Sivonen 2017-07-04 11:00:03 +03:00
parent 5ca6d3bc4c
commit dacb0e05f1
39 changed files with 3444 additions and 1354 deletions

View File

@ -15,7 +15,6 @@
#include "mozilla/dom/NodeInfo.h"
#include "nsCOMArray.h"
#include "nsContentCreatorFunctions.h"
#include "nsContentUtils.h"
#include "nsGkAtoms.h"
#include "nsIDocument.h"
#include "nsString.h"
@ -190,9 +189,7 @@ NS_NewElement(Element** aResult,
if (ns == kNameSpaceID_MathML) {
// If the mathml.disabled pref. is true, convert all MathML nodes into
// disabled MathML nodes by swapping the namespace.
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
if ((nsmgr && !nsmgr->mMathMLDisabled) ||
nsContentUtils::IsSystemPrincipal(ni->GetDocument()->NodePrincipal())) {
if (ni->NodeInfoManager()->MathMLEnabled()) {
return NS_NewMathMLElement(aResult, ni.forget());
}
@ -205,29 +202,7 @@ NS_NewElement(Element** aResult,
if (ns == kNameSpaceID_SVG) {
// If the svg.disabled pref. is true, convert all SVG nodes into
// disabled SVG nodes by swapping the namespace.
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
nsCOMPtr<nsILoadInfo> loadInfo;
bool SVGEnabled = false;
if (nsmgr && !nsmgr->mSVGDisabled) {
SVGEnabled = true;
} else {
nsCOMPtr<nsIChannel> channel = ni->GetDocument()->GetChannel();
// We don't have a channel for SVGs constructed inside a SVG script
if (channel) {
loadInfo = channel->GetLoadInfo();
}
}
if (SVGEnabled ||
nsContentUtils::IsSystemPrincipal(ni->GetDocument()->NodePrincipal()) ||
(loadInfo &&
(loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_IMAGE ||
loadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_OTHER) &&
(nsContentUtils::IsSystemPrincipal(loadInfo->LoadingPrincipal()) ||
nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal())
)
)
) {
if (ni->NodeInfoManager()->SVGEnabled()) {
return NS_NewSVGElement(aResult, ni.forget(), aFromParser);
}
RefPtr<mozilla::dom::NodeInfo> genericXMLNI =

View File

@ -463,3 +463,46 @@ nsNodeInfoManager::RemoveNodeInfo(NodeInfo *aNodeInfo)
NS_POSTCONDITION(ret, "Can't find mozilla::dom::NodeInfo to remove!!!");
}
bool
nsNodeInfoManager::InternalSVGEnabled()
{
// If the svg.disabled pref. is true, convert all SVG nodes into
// disabled SVG nodes by swapping the namespace.
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
nsCOMPtr<nsILoadInfo> loadInfo;
bool SVGEnabled = false;
if (nsmgr && !nsmgr->mSVGDisabled) {
SVGEnabled = true;
} else {
nsCOMPtr<nsIChannel> channel = mDocument->GetChannel();
// We don't have a channel for SVGs constructed inside a SVG script
if (channel) {
loadInfo = channel->GetLoadInfo();
}
}
bool conclusion =
(SVGEnabled || nsContentUtils::IsSystemPrincipal(mPrincipal) ||
(loadInfo &&
(loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_IMAGE ||
loadInfo->GetExternalContentPolicyType() ==
nsIContentPolicy::TYPE_OTHER) &&
(nsContentUtils::IsSystemPrincipal(loadInfo->LoadingPrincipal()) ||
nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal()))));
mSVGEnabled = conclusion ? eTriTrue : eTriFalse;
return conclusion;
}
bool
nsNodeInfoManager::InternalMathMLEnabled()
{
// If the mathml.disabled pref. is true, convert all MathML nodes into
// disabled MathML nodes by swapping the namespace.
nsNameSpaceManager* nsmgr = nsNameSpaceManager::GetInstance();
bool conclusion = ((nsmgr && !nsmgr->mMathMLDisabled) ||
nsContentUtils::IsSystemPrincipal(mPrincipal));
mMathMLEnabled = conclusion ? eTriTrue : eTriFalse;
return conclusion;
}

View File

@ -109,6 +109,33 @@ public:
return mBindingManager;
}
enum Tri
{
eTriUnset = 0,
eTriFalse,
eTriTrue
};
/**
* Returns true if SVG nodes in this document have real SVG semantics.
*/
bool SVGEnabled()
{
return mSVGEnabled == eTriTrue
? true
: mSVGEnabled == eTriFalse ? false : InternalSVGEnabled();
}
/**
* Returns true if MathML nodes in this document have real MathML semantics.
*/
bool MathMLEnabled()
{
return mMathMLEnabled == eTriTrue
? true
: mMathMLEnabled == eTriFalse ? false : InternalMathMLEnabled();
}
protected:
friend class nsDocument;
friend class nsXULPrototypeDocument;
@ -130,6 +157,9 @@ private:
static int DropNodeInfoDocument(PLHashEntry *he, int hashIndex,
void *arg);
bool InternalSVGEnabled();
bool InternalMathMLEnabled();
PLHashTable *mNodeInfoHash;
nsIDocument * MOZ_NON_OWNING_REF mDocument; // WEAK
uint32_t mNonDocumentNodeInfos;
@ -140,6 +170,8 @@ private:
mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mDocumentNodeInfo; // WEAK to avoid circular ownership
RefPtr<nsBindingManager> mBindingManager;
mozilla::dom::NodeInfo* mRecentlyUsedNodeInfos[RECENTLY_USED_NODEINFOS_SIZE];
Tri mSVGEnabled;
Tri mMathMLEnabled;
};
#endif /* nsNodeInfoManager_h___ */

View File

@ -53,3 +53,12 @@ NS_NewHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
{
return new mozilla::dom::HTMLElement(aNodeInfo);
}
// Distinct from the above in order to have function pointer that compared unequal
// to a function pointer to the above.
nsGenericHTMLElement*
NS_NewCustomElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser)
{
return new mozilla::dom::HTMLElement(aNodeInfo);
}

View File

@ -1472,6 +1472,15 @@ protected:
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface, \
mNodeInfo->Equals(nsGkAtoms::_tag))
namespace mozilla {
namespace dom {
typedef nsGenericHTMLElement* (*HTMLContentCreatorFunction)(
already_AddRefed<mozilla::dom::NodeInfo>&&,
mozilla::dom::FromParser aFromParser);
} // namespace dom
} // namespace mozilla
/**
* A macro to declare the NS_NewHTMLXXXElement() functions.
@ -1520,6 +1529,13 @@ nsGenericHTMLElement*
NS_NewHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
// Distinct from the above in order to have function pointer that compared unequal
// to a function pointer to the above.
nsGenericHTMLElement*
NS_NewCustomElement(
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
NS_DECLARE_NS_NEW_HTML_ELEMENT(Shared)
NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedList)

View File

@ -83,10 +83,6 @@ using namespace mozilla::dom;
//----------------------------------------------------------------------
typedef nsGenericHTMLElement*
(*contentCreatorCallback)(already_AddRefed<mozilla::dom::NodeInfo>&&,
FromParser aFromParser);
nsGenericHTMLElement*
NS_NewHTMLNOTUSEDElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
FromParser aFromParser)
@ -97,7 +93,7 @@ NS_NewHTMLNOTUSEDElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
#define HTML_TAG(_tag, _classname, _interfacename) NS_NewHTML##_classname##Element,
#define HTML_OTHER(_tag) NS_NewHTMLNOTUSEDElement,
static const contentCreatorCallback sContentCreatorCallbacks[] = {
static const HTMLContentCreatorFunction sHTMLContentCreatorFunctions[] = {
NS_NewHTMLUnknownElement,
#include "nsHTMLTagList.h"
#undef HTML_TAG
@ -279,7 +275,7 @@ CreateHTMLElement(uint32_t aNodeType,
aNodeType == eHTMLTag_userdefined,
"aNodeType is out of bounds");
contentCreatorCallback cb = sContentCreatorCallbacks[aNodeType];
HTMLContentCreatorFunction cb = sHTMLContentCreatorFunctions[aNodeType];
NS_ASSERTION(cb != NS_NewHTMLNOTUSEDElement,
"Don't know how to construct tag element!");

View File

@ -15,31 +15,28 @@ using namespace mozilla;
using namespace mozilla::dom;
// Hash table that maps nsIAtom* SVG tags to an offset index
// within the array sContentCreatorCallbacks (offset by TABLE_VALUE_OFFSET)
// within the array sSVGContentCreatorFunctions (offset by TABLE_VALUE_OFFSET)
static PLHashTable* sTagAtomTable = nullptr;
// We don't want to store 0 in the hash table as a return value of 0 from
// PL_HashTableLookupConst indicates that the value is not found
#define TABLE_VALUE_OFFSET 1
#define SVG_TAG(_tag, _classname) \
nsresult \
NS_NewSVG##_classname##Element(nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); \
\
static inline nsresult \
Create##_classname##Element(nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
FromParser aFromParser) \
{ \
return NS_NewSVG##_classname##Element(aResult, mozilla::Move(aNodeInfo)); \
}
#define SVG_TAG(_tag, _classname) \
nsresult NS_NewSVG##_classname##Element( \
nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo); \
\
nsresult NS_NewSVG##_classname##Element( \
nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
FromParser aFromParser) \
{ \
return NS_NewSVG##_classname##Element(aResult, mozilla::Move(aNodeInfo)); \
}
#define SVG_FROM_PARSER_TAG(_tag, _classname)
#define SVG_FROM_PARSER_TAG(_tag, _classname) \
nsresult \
NS_NewSVG##_classname##Element(nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
FromParser aFromParser);
#include "SVGTagList.h"
#undef SVG_TAG
#undef SVG_FROM_PARSER_TAG
@ -48,13 +45,8 @@ nsresult
NS_NewSVGElement(Element** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
typedef nsresult
(*contentCreatorCallback)(nsIContent** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
FromParser aFromParser);
static const contentCreatorCallback sContentCreatorCallbacks[] = {
#define SVG_TAG(_tag, _classname) Create##_classname##Element,
static const SVGContentCreatorFunction sSVGContentCreatorFunctions[] = {
#define SVG_TAG(_tag, _classname) NS_NewSVG##_classname##Element,
#define SVG_FROM_PARSER_TAG(_tag, _classname) NS_NewSVG##_classname##Element,
#include "SVGTagList.h"
#undef SVG_TAG
@ -124,7 +116,7 @@ NS_NewSVGElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& a
MOZ_CRASH();
}
contentCreatorCallback cb = sContentCreatorCallbacks[index];
SVGContentCreatorFunction cb = sSVGContentCreatorFunctions[index];
nsCOMPtr<nsIContent> content;
nsresult rv = cb(getter_AddRefs(content), ni.forget(), aFromParser);
@ -135,3 +127,15 @@ NS_NewSVGElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& a
// if we don't know what to create, just create a standard svg element:
return NS_NewSVGElement(aResult, ni.forget());
}
nsresult
NS_NewSVGUnknownElement(nsIContent** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
FromParser aFromParser)
{
RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
nsCOMPtr<Element> element;
nsresult rv = NS_NewSVGElement(getter_AddRefs(element), ni.forget());
element.forget(aResult);
return rv;
}

View File

@ -18,7 +18,32 @@ public:
static void Shutdown();
};
typedef nsresult (*SVGContentCreatorFunction)(
nsIContent** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser);
} // namespace dom
} // namespace mozilla
#define SVG_TAG(_tag, _classname) \
nsresult NS_NewSVG##_classname##Element( \
nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
mozilla::dom::FromParser aFromParser);
#define SVG_FROM_PARSER_TAG(_tag, _classname) \
nsresult NS_NewSVG##_classname##Element( \
nsIContent** aResult, \
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
mozilla::dom::FromParser aFromParser);
#include "SVGTagList.h"
#undef SVG_TAG
#undef SVG_FROM_PARSER_TAG
nsresult
NS_NewSVGUnknownElement(nsIContent** aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
mozilla::dom::FromParser aFromParser);
#endif /* mozilla_dom_SVGElementFactory_h */

View File

@ -9,7 +9,14 @@
This file contains the list of all SVG tags.
It is designed to be used as inline input to SVGElementFactory.cpp
*only* through the magic of C preprocessing.
through the magic of C preprocessing.
Additionally, it is consumed by the self-regeneration code in
ElementName.java from which nsHtml5ElementName.cpp/h is translated.
See parser/html/java/README.txt.
If you edit this list, you need to re-run ElementName.java
self-regeneration and the HTML parser Java to C++ translation.
All entries must be enclosed in the macro SVG_TAG or SVG_FROM_PARSER_TAG
which will have cruel and unusual things done to them.

View File

@ -17,6 +17,7 @@ EXPORTS += [
'SVGContentUtils.h',
'SVGPreserveAspectRatio.h',
'SVGStringList.h',
'SVGTagList.h',
]
EXPORTS.mozilla.dom += [
@ -42,6 +43,7 @@ EXPORTS.mozilla.dom += [
'SVGDefsElement.h',
'SVGDescElement.h',
'SVGDocument.h',
'SVGElementFactory.h',
'SVGEllipseElement.h',
'SVGFEBlendElement.h',
'SVGFEColorMatrixElement.h',

View File

@ -2,36 +2,36 @@ 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
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
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
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.
Builds the javaparser library retrieved earlier by sync_javaparser.
translator:
Runs the javaparser target and then builds the Java to C++ translator from
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
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
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.
@ -42,5 +42,52 @@ clean_htmlparser:
clean:
Runs both clean_javaparser and clean_htmlparser.
## How to add an attribute
# starting from the root of a mozilla-central checkout
cd parser/html/java/
make sync
# now you have a clone of https://hg.mozilla.org/projects/htmlparser/ in parser/html/java/htmlparser/
cd htmlparser/src/
$EDITOR nu/validator/htmlparser/impl/AttributeName.java
# Search for the word "uncomment" and uncomment stuff according to the comments that talk about uncommenting
# Duplicate the declaration a normal attribute (nothings special in SVG mode, etc.). Let's use "alt", since it's the first one.
# In the duplicate, replace ALT with the new name in all caps and "alt" with the new name in quotes in lower case.
# Search for "ALT,", duplicate that line and change the duplicate to say the new name in all caps followed by comma.
# Save.
javac nu/validator/htmlparser/impl/AttributeName.java
java nu.validator.htmlparser.impl.AttributeName
# Copy and paste the output into nu/validator/htmlparser/impl/AttributeName.java replacing the text below the comment "START GENERATED CODE" and above the very last "}".
# Recomment the bits that you uncommented earlier.
# Save.
cd ../.. # Back to parser/html/java/
make translate
cd ../../..
./mach clang-format
## How to add an element
# First, add an entry to parser/htmlparser/nsHTMLTagList.h or dom/svg/SVGTagList.h!
# Then, starting from the root of a mozilla-central checkout
cd parser/html/java/
make sync
# now you have a clone of https://hg.mozilla.org/projects/htmlparser/ in parser/html/java/htmlparser/
cd htmlparser/src/
$EDITOR nu/validator/htmlparser/impl/ElementName.java
# Search for the word "uncomment" and uncomment stuff according to the comments that talk about uncommenting
# Duplicate the declaration a normal element. Let's use "bdo", since it's the first normal one.
# In the duplicate, replace BDO with the new name in all caps and "bdo" with the new name in quotes in lower case (twice).
# Search for "BDO,", duplicate that line and change the duplicate to say the new name in all caps followed by comma.
# Save.
javac nu/validator/htmlparser/impl/ElementName.java
java nu.validator.htmlparser.impl.ElementName ../../../../../parser/htmlparser/nsHTMLTagList.h ../../../../../dom/svg/SVGTagList.h
# Copy and paste the output into nu/validator/htmlparser/impl/ElementName.java replacing the text below the comment "START GENERATED CODE" and above the very last "}".
# Recomment the bits that you uncommented earlier.
# Save.
cd ../.. # Back to parser/html/java/
make translate
cd ../../..
./mach clang-format
Ben Newman (23 September 2009)
Henri Sivonen (11 August 2016)
Henri Sivonen (10 August 2017)

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,11 @@ final class StackNode<T> {
private int refcount = 0;
/*
* Only valid for formatting elements
*/
// CPPONLY: private @HtmlCreator Object htmlCreator;
// [NOCPP[
private TaintableLocatorImpl locator;
@ -95,6 +100,10 @@ final class StackNode<T> {
this.refcount = 0;
}
// CPPONLY: public @HtmlCreator Object getHtmlCreator() {
// CPPONLY: return htmlCreator;
// CPPONLY: }
/**
* Setter for copying. This doesn't take another <code>StackNode</code>
* because in C++ the caller is responsible for reobtaining the local names
@ -108,9 +117,10 @@ final class StackNode<T> {
* @param attributes
*/
void setValues(int flags, @NsUri String ns, @Local String name, T node,
@Local String popName, HtmlAttributes attributes
@Local String popName, HtmlAttributes attributes,
// CPPONLY: @HtmlCreator Object htmlCreator
// [NOCPP[
, TaintableLocatorImpl locator
TaintableLocatorImpl locator
// ]NOCPP]
) {
assert isUnused();
@ -121,6 +131,10 @@ final class StackNode<T> {
this.node = node;
this.attributes = attributes;
this.refcount = 1;
/*
* Need to track creator for formatting elements when copying.
*/
// CPPONLY: this.htmlCreator = htmlCreator;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
@ -146,6 +160,10 @@ final class StackNode<T> {
this.attributes = null;
this.refcount = 1;
assert elementName.isInterned() : "Don't use this constructor for custom elements.";
/*
* Not used for formatting elements, so no need to track creator.
*/
// CPPONLY: this.htmlCreator = null;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
@ -172,6 +190,11 @@ final class StackNode<T> {
this.attributes = attributes;
this.refcount = 1;
assert elementName.isInterned() : "Don't use this constructor for custom elements.";
/*
* Need to track creator for formatting elements in order to be able
* to clone them.
*/
// CPPONLY: this.htmlCreator = elementName.getHtmlCreator();
// [NOCPP[
this.locator = locator;
// ]NOCPP]
@ -197,6 +220,10 @@ final class StackNode<T> {
this.node = node;
this.attributes = null;
this.refcount = 1;
/*
* Not used for formatting elements, so no need to track creator.
*/
// CPPONLY: this.htmlCreator = null;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
@ -225,6 +252,10 @@ final class StackNode<T> {
this.node = node;
this.attributes = null;
this.refcount = 1;
/*
* Not used for formatting elements, so no need to track creator.
*/
// CPPONLY: this.htmlCreator = null;
// [NOCPP[
this.locator = locator;
// ]NOCPP]
@ -253,6 +284,10 @@ final class StackNode<T> {
this.node = node;
this.attributes = null;
this.refcount = 1;
/*
* Not used for formatting elements, so no need to track creator.
*/
// CPPONLY: this.htmlCreator = null;
// [NOCPP[
this.locator = locator;
// ]NOCPP]

View File

@ -1120,7 +1120,9 @@ public class Tokenizer implements Locator {
tagName = ElementName.ANNOTATION_XML;
} else {
nonInternedTagName.setNameForNonInterned(Portability.newLocalNameFromBuffer(strBuf, 0, strBufLen,
interner));
interner)
// CPPONLY: , true
);
tagName = nonInternedTagName;
}
} else {
@ -1128,7 +1130,9 @@ public class Tokenizer implements Locator {
interner);
if (tagName == null) {
nonInternedTagName.setNameForNonInterned(Portability.newLocalNameFromBuffer(strBuf, 0, strBufLen,
interner));
interner)
// CPPONLY: , false
);
tagName = nonInternedTagName;
}
}
@ -6686,7 +6690,9 @@ public class Tokenizer implements Locator {
publicIdentifier = null;
}
tagName = null;
nonInternedTagName.setNameForNonInterned(null);
nonInternedTagName.setNameForNonInterned(null
// CPPONLY: , false
);
attributeName = null;
// CPPONLY: nonInternedAttributeName.setNameForNonInterned(null);
tokenHandler.endTokenization();
@ -6836,7 +6842,9 @@ public class Tokenizer implements Locator {
// In the C++ case, the atoms in the other tokenizer are from a
// different tokenizer-scoped atom table. Therefore, we have to
// obtain the correspoding atom from our own atom table.
nonInternedTagName.setNameForNonInterned(Portability.newLocalFromLocal(other.tagName.getName(), interner));
nonInternedTagName.setNameForNonInterned(Portability.newLocalFromLocal(other.tagName.getName(), interner)
// CPPONLY: , other.tagName.isCustom()
);
tagName = nonInternedTagName;
}

View File

@ -483,6 +483,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
protected void fatal() throws SAXException {
}
// CPPONLY: @Inline private @Creator Object htmlCreator(@HtmlCreator Object htmlCreator) {
// CPPONLY: @Creator Object creator;
// CPPONLY: creator.html = htmlCreator;
// CPPONLY: return creator;
// CPPONLY: }
// CPPONLY:
// CPPONLY: @Inline private @Creator Object svgCreator(@SvgCreator Object svgCreator) {
// CPPONLY: @Creator Object creator;
// CPPONLY: creator.svg = svgCreator;
// CPPONLY: return creator;
// CPPONLY: }
// [NOCPP[
protected final void fatal(Exception e) throws SAXException {
@ -729,7 +741,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// CPPONLY: if (tokenizer.isViewingXmlSource()) {
// CPPONLY: T elt = createElement("http://www.w3.org/2000/svg",
// CPPONLY: "svg",
// CPPONLY: tokenizer.emptyAttributes(), null);
// CPPONLY: tokenizer.emptyAttributes(), null,
// CPPONLY: svgCreator(NS_NewSVGSVGElement));
// CPPONLY: StackNode<T> node = createStackNode(ElementName.SVG,
// CPPONLY: "svg",
// CPPONLY: elt);
@ -1982,8 +1995,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
attributes.getValue(AttributeName.TYPE))) {
break intableloop;
}
appendVoidElementToCurrent(
name, attributes,
appendVoidInputToCurrent(
attributes,
formPointer);
selfClosing = false;
attributes = null; // CPP
@ -2345,7 +2358,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
case INPUT:
reconstructTheActiveFormattingElements();
appendVoidElementToCurrentMayFoster(
name, attributes,
elementName, attributes,
formPointer);
selfClosing = false;
attributes = null; // CPP
@ -4753,9 +4766,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
assert node == listOfActiveFormattingElements[nodeListPos];
assert node == stack[nodePos];
T clone = createElement("http://www.w3.org/1999/xhtml",
node.name, node.attributes.cloneAttributes(null), commonAncestor.node);
node.name, node.attributes.cloneAttributes(null), commonAncestor.node
// CPPONLY: , htmlCreator(node.getHtmlCreator())
);
StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
node.name, clone, node.popName, node.attributes
// CPPONLY: , node.getHtmlCreator()
// [NOCPP[
, node.getLocator()
// ]NOCPP]
@ -4782,11 +4798,14 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
T clone = createElement("http://www.w3.org/1999/xhtml",
formattingElt.name,
formattingElt.attributes.cloneAttributes(null), furthestBlock.node);
formattingElt.attributes.cloneAttributes(null), furthestBlock.node
// CPPONLY: , htmlCreator(formattingElt.getHtmlCreator())
);
StackNode<T> formattingClone = createStackNode(
formattingElt.getFlags(), formattingElt.ns,
formattingElt.name, clone, formattingElt.popName,
formattingElt.attributes
// CPPONLY: , formattingElt.getHtmlCreator()
// [NOCPP[
, errorHandler == null ? null : new TaintableLocatorImpl(tokenizer)
// ]NOCPP]
@ -4966,16 +4985,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
T clone;
if (currentNode.isFosterParenting()) {
clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes(null));
entry.attributes.cloneAttributes(null)
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
);
} else {
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
entry.attributes.cloneAttributes(null), currentNode.node);
entry.attributes.cloneAttributes(null), currentNode.node
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
);
appendElement(clone, currentNode.node);
}
StackNode<T> entryClone = createStackNode(entry.getFlags(),
entry.ns, entry.name, clone, entry.popName,
entry.attributes
// CPPONLY: , entry.getHtmlCreator()
// [NOCPP[
, entry.getLocator()
// ]NOCPP]
@ -5029,12 +5053,14 @@ public abstract class TreeBuilder<T> implements TokenHandler,
private StackNode<T> createStackNode(int flags, @NsUri String ns, @Local String name, T node,
@Local String popName, HtmlAttributes attributes
// CPPONLY: , @HtmlCreator Object htmlCreator
// [NOCPP[
, TaintableLocatorImpl locator
// ]NOCPP]
) {
StackNode<T> instance = getUnusedStackNode();
instance.setValues(flags, ns, name, node, popName, attributes
// CPPONLY: , htmlCreator
// [NOCPP[
, locator
// ]NOCPP]
@ -5127,23 +5153,33 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes) throws SAXException {
return createAndInsertFosterParentedElement(ns, name, attributes, null);
HtmlAttributes attributes
// CPPONLY: , @Creator Object creator
) throws SAXException {
return createAndInsertFosterParentedElement(ns, name, attributes, null
// CPPONLY: , creator
);
}
private T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T form) throws SAXException {
HtmlAttributes attributes, T form
// CPPONLY: , @Creator Object creator
) throws SAXException {
int tablePos = findLastOrRoot(TreeBuilder.TABLE);
int templatePos = findLastOrRoot(TreeBuilder.TEMPLATE);
if (templatePos >= tablePos) {
T child = createElement(ns, name, attributes, form, stack[templatePos].node);
T child = createElement(ns, name, attributes, form, stack[templatePos].node
// CPPONLY: , creator
);
appendElement(child, stack[templatePos].node);
return child;
}
StackNode<T> node = stack[tablePos];
return createAndInsertFosterParentedElement(ns, name, attributes, form, node.node, stack[tablePos - 1].node);
return createAndInsertFosterParentedElement(ns, name, attributes, form, node.node, stack[tablePos - 1].node
// CPPONLY: , creator
);
}
private boolean isInStack(StackNode<T> node) {
@ -5301,7 +5337,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode);
T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode
/*
* head uses NS_NewHTMLSharedElement creator
*/
// CPPONLY: , htmlCreator(NS_NewHTMLSharedElement)
);
appendElement(elt, currentNode);
headPointer = elt;
StackNode<T> node = createStackNode(ElementName.HEAD,
@ -5333,9 +5374,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", "form", attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", "form", attributes
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node);
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
);
appendElement(elt, current.node);
}
@ -5366,9 +5411,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, current.node);
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
}
StackNode<T> node = createStackNode(elementName, elt, clone
@ -5389,7 +5438,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// ]NOCPP]
// This method can't be called for custom elements
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode);
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, currentNode);
if (ElementName.TEMPLATE == elementName) {
elt = getDocumentFragmentForTemplate(elt);
@ -5416,9 +5467,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node);
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
}
StackNode<T> node = createStackNode(elementName, elt, popName
@ -5450,9 +5505,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes
// CPPONLY: , htmlCreator(null)
);
} else {
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node);
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
// CPPONLY: , htmlCreator(null)
);
appendElement(elt, current.node);
}
StackNode<T> node = createStackNode(elementName, elt, popName,
@ -5499,9 +5558,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
} else {
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node);
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
appendElement(elt, current.node);
}
StackNode<T> node = createStackNode(elementName, popName, elt
@ -5525,10 +5588,14 @@ public abstract class TreeBuilder<T> implements TokenHandler,
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", elementName.getName(),
attributes, formOwner);
attributes, formOwner
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(),
attributes, formOwner, current.node);
attributes, formOwner, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
}
StackNode<T> node = createStackNode(elementName, elt
@ -5540,7 +5607,8 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
private void appendVoidElementToCurrentMayFoster(
@Local String name, HtmlAttributes attributes, T form) throws SAXException {
ElementName elementName, HtmlAttributes attributes, T form) throws SAXException {
@Local String name = elementName.getName();
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
@ -5551,10 +5619,14 @@ public abstract class TreeBuilder<T> implements TokenHandler,
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", name,
attributes, formOwner);
attributes, formOwner
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", name,
attributes, formOwner, current.node);
attributes, formOwner, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
@ -5575,9 +5647,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", popName, attributes
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
} else {
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node);
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
@ -5598,9 +5674,13 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/2000/svg", popName, attributes
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
} else {
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node);
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
// CPPONLY: , svgCreator(elementName.getSvgCreator())
);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/2000/svg", popName, elt);
@ -5621,27 +5701,32 @@ public abstract class TreeBuilder<T> implements TokenHandler,
StackNode<T> current = stack[currentPtr];
if (current.isFosterParenting()) {
fatal();
elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes);
elt = createAndInsertFosterParentedElement("http://www.w3.org/1998/Math/MathML", popName, attributes
// CPPONLY: , htmlCreator(null)
);
} else {
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node);
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
// CPPONLY: , htmlCreator(null)
);
appendElement(elt, current.node);
}
elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
elementPopped("http://www.w3.org/1998/Math/MathML", popName, elt);
}
private void appendVoidElementToCurrent(
@Local String name, HtmlAttributes attributes, T form) throws SAXException {
private void appendVoidInputToCurrent(HtmlAttributes attributes, T form) throws SAXException {
// [NOCPP[
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
// ]NOCPP]
// Can't be called for custom elements
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", name, attributes,
form == null || fragment || isTemplateContents() ? null : form, currentNode);
T elt = createElement("http://www.w3.org/1999/xhtml", "input", attributes,
form == null || fragment || isTemplateContents() ? null : form, currentNode
// CPPONLY: , htmlCreator(NS_NewHTMLInputElement)
);
appendElement(elt, currentNode);
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
elementPopped("http://www.w3.org/1999/xhtml", name, elt);
elementPushed("http://www.w3.org/1999/xhtml", "input", elt);
elementPopped("http://www.w3.org/1999/xhtml", "input", elt);
}
private void appendVoidFormToCurrent(HtmlAttributes attributes) throws SAXException {
@ -5650,7 +5735,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// ]NOCPP]
T currentNode = stack[currentPtr].node;
T elt = createElement("http://www.w3.org/1999/xhtml", "form",
attributes, currentNode);
attributes, currentNode
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
);
formPointer = elt;
// ownership transferred to form pointer
appendElement(elt, currentNode);
@ -5702,11 +5789,17 @@ public abstract class TreeBuilder<T> implements TokenHandler,
}
protected abstract T createElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T intendedParent) throws SAXException;
HtmlAttributes attributes, T intendedParent
// CPPONLY: , @Creator Object creator
) throws SAXException;
protected T createElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T form, T intendedParent) throws SAXException {
return createElement("http://www.w3.org/1999/xhtml", name, attributes, intendedParent);
HtmlAttributes attributes, T form, T intendedParent
// CPPONLY: , @Creator Object creator
) throws SAXException {
return createElement("http://www.w3.org/1999/xhtml", name, attributes, intendedParent
// CPPONLY: , creator
);
}
protected abstract T createHtmlElementSetAsRoot(HtmlAttributes attributes)
@ -5735,7 +5828,9 @@ public abstract class TreeBuilder<T> implements TokenHandler,
// ]NOCPP]
protected T createAndInsertFosterParentedElement(@NsUri String ns, @Local String name,
HtmlAttributes attributes, T form, T table, T stackParent) throws SAXException {
HtmlAttributes attributes, T form, T table, T stackParent
// CPPONLY: , @Creator Object creator
) throws SAXException {
return createAndInsertFosterParentedElement(ns, name, attributes, table, stackParent);
};
@ -6016,6 +6111,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
newNode.setValues(node.getFlags(), node.ns,
node.name, node.node, node.popName,
node.attributes.cloneAttributes(null)
// CPPONLY: , node.getHtmlCreator()
// [NOCPP[
, node.getLocator()
// ]NOCPP]
@ -6034,6 +6130,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
newNode.setValues(node.getFlags(), node.ns,
node.name, node.node, node.popName,
null
// CPPONLY: , node.getHtmlCreator()
// [NOCPP[
, node.getLocator()
// ]NOCPP]
@ -6139,6 +6236,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
Portability.newLocalFromLocal(node.name, interner), node.node,
Portability.newLocalFromLocal(node.popName, interner),
node.attributes.cloneAttributes(null)
// CPPONLY: , node.getHtmlCreator()
// [NOCPP[
, node.getLocator()
// ]NOCPP]
@ -6156,6 +6254,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
Portability.newLocalFromLocal(node.name, interner), node.node,
Portability.newLocalFromLocal(node.popName, interner),
null
// CPPONLY: , node.getHtmlCreator()
// [NOCPP[
, node.getLocator()
// ]NOCPP]

View File

@ -20,6 +20,7 @@ EXPORTS += [
'nsHtml5AttributeEntry.h',
'nsHtml5AttributeName.h',
'nsHtml5ByteReadable.h',
'nsHtml5ContentCreatorFunction.h',
'nsHtml5DependentUTF16Buffer.h',
'nsHtml5DocumentBuilder.h',
'nsHtml5DocumentMode.h',

View File

@ -41,6 +41,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
#include "nsHtml5ElementName.h"
#include "nsHtml5Tokenizer.h"

View File

@ -42,6 +42,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;

View File

@ -0,0 +1,17 @@
/* 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 nsHtml5ContentCreatorFunction_h
#define nsHtml5ContentCreatorFunction_h
#include "nsGenericHTMLElement.h"
#include "mozilla/dom/SVGElementFactory.h"
union nsHtml5ContentCreatorFunction
{
mozilla::dom::HTMLContentCreatorFunction html;
mozilla::dom::SVGContentCreatorFunction svg;
};
#endif // nsHtml5ContentCreatorFunction_h

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;
@ -78,6 +79,8 @@ public:
private:
nsIAtom* name;
nsIAtom* camelCaseName;
mozilla::dom::HTMLContentCreatorFunction htmlCreator;
mozilla::dom::SVGContentCreatorFunction svgCreator;
public:
int32_t flags;
@ -85,6 +88,16 @@ public:
inline nsIAtom* getCamelCaseName() { return camelCaseName; }
inline mozilla::dom::HTMLContentCreatorFunction getHtmlCreator()
{
return htmlCreator;
}
inline mozilla::dom::SVGContentCreatorFunction getSvgCreator()
{
return svgCreator;
}
inline int32_t getFlags() { return flags; }
inline int32_t getGroup() { return flags & nsHtml5ElementName::GROUP_MASK; }
@ -92,24 +105,24 @@ public:
inline bool isInterned()
{
return !(flags & nsHtml5ElementName::NOT_INTERNED);
}
inline static int32_t levelOrderBinarySearch(jArray<int32_t, int32_t> data,
int32_t key)
{
int32_t n = data.length;
int32_t i = 0;
while (i < n) {
int32_t val = data[i];
if (val < key) {
i = 2 * i + 2;
} else if (val > key) {
i = 2 * i + 1;
} else {
return i;
}
}
return -1;
inline static int32_t levelOrderBinarySearch(jArray<int32_t, int32_t> data,
int32_t key)
{
int32_t n = data.length;
int32_t i = 0;
while (i < n) {
int32_t val = data[i];
if (val < key) {
i = 2 * i + 2;
} else if (val > key) {
i = 2 * i + 1;
} else {
return i;
}
}
return -1;
}
inline static nsHtml5ElementName* elementNameByBuffer(
@ -166,17 +179,29 @@ public:
return len + first + second + third + fourth + fifth;
}
nsHtml5ElementName(nsIAtom* name, nsIAtom* camelCaseName, int32_t flags);
nsHtml5ElementName(nsIAtom* name,
nsIAtom* camelCaseName,
mozilla::dom::HTMLContentCreatorFunction htmlCreator,
mozilla::dom::SVGContentCreatorFunction svgCreator,
int32_t flags);
public:
nsHtml5ElementName();
~nsHtml5ElementName();
inline void setNameForNonInterned(nsIAtom* name)
inline void setNameForNonInterned(nsIAtom* name, bool custom)
{
this->name = name;
this->camelCaseName = name;
if (custom) {
this->htmlCreator = NS_NewCustomElement;
} else {
this->htmlCreator = NS_NewHTMLUnknownElement;
}
MOZ_ASSERT(this->flags == nsHtml5ElementName::NOT_INTERNED);
}
inline bool isCustom() { return this->htmlCreator == NS_NewCustomElement; }
static nsHtml5ElementName* ELT_ANNOTATION_XML;
static nsHtml5ElementName* ELT_BIG;
static nsHtml5ElementName* ELT_BDO;
@ -215,6 +240,7 @@ public:
static nsHtml5ElementName* ELT_H5;
static nsHtml5ElementName* ELT_H6;
static nsHtml5ElementName* ELT_AREA;
static nsHtml5ElementName* ELT_DATA;
static nsHtml5ElementName* ELT_FEFUNCA;
static nsHtml5ElementName* ELT_METADATA;
static nsHtml5ElementName* ELT_META;
@ -348,6 +374,8 @@ public:
static nsHtml5ElementName* ELT_DT;
static nsHtml5ElementName* ELT_APPLET;
static nsHtml5ElementName* ELT_BASEFONT;
static nsHtml5ElementName* ELT_CONTENT;
static nsHtml5ElementName* ELT_DATALIST;
static nsHtml5ElementName* ELT_FOREIGNOBJECT;
static nsHtml5ElementName* ELT_FIELDSET;
static nsHtml5ElementName* ELT_FRAMESET;
@ -373,6 +401,7 @@ public:
static nsHtml5ElementName* ELT_TEXT;
static nsHtml5ElementName* ELT_MENU;
static nsHtml5ElementName* ELT_FEDROPSHADOW;
static nsHtml5ElementName* ELT_SHADOW;
static nsHtml5ElementName* ELT_VIEW;
static nsHtml5ElementName* ELT_FECOLORMATRIX;
static nsHtml5ElementName* ELT_FECONVOLVEMATRIX;

View File

@ -80,13 +80,16 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
mOpQueue.AppendElement()->Init(STANDARDS_MODE);
nsIContent** root = CreateElement(nsGkAtoms::html, nullptr, nullptr);
// <html> uses NS_NewHTMLSharedElement creator
nsIContent** root =
CreateElement(nsGkAtoms::html, nullptr, nullptr, NS_NewHTMLSharedElement);
mOpQueue.AppendElement()->Init(eTreeOpAppendToDocument, root);
mStack.AppendElement(root);
Push(nsGkAtoms::head, nullptr);
// <head> uses NS_NewHTMLSharedElement creator
Push(nsGkAtoms::head, nullptr, NS_NewHTMLSharedElement);
Push(nsGkAtoms::title, nullptr);
Push(nsGkAtoms::title, nullptr, NS_NewHTMLTitleElement);
// XUL will add the "Source of: " prefix.
uint32_t length = aTitle.Length();
if (length > INT32_MAX) {
@ -95,7 +98,9 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
AppendCharacters(aTitle.BeginReading(), 0, (int32_t)length);
Pop(); // title
Push(nsGkAtoms::link, nsHtml5ViewSourceUtils::NewLinkAttributes());
Push(nsGkAtoms::link,
nsHtml5ViewSourceUtils::NewLinkAttributes(),
NS_NewHTMLLinkElement);
mOpQueue.AppendElement()->Init(eTreeOpUpdateStyleSheet, CurrentNode());
@ -103,12 +108,14 @@ nsHtml5Highlighter::Start(const nsAutoString& aTitle)
Pop(); // head
Push(nsGkAtoms::body, nsHtml5ViewSourceUtils::NewBodyAttributes());
Push(nsGkAtoms::body,
nsHtml5ViewSourceUtils::NewBodyAttributes(),
NS_NewHTMLBodyElement);
nsHtml5HtmlAttributes* preAttrs = new nsHtml5HtmlAttributes(0);
nsHtml5String preId = nsHtml5Portability::newStringFromLiteral("line1");
preAttrs->addAttribute(nsHtml5AttributeName::ATTR_ID, preId, -1);
Push(nsGkAtoms::pre, preAttrs);
Push(nsGkAtoms::pre, preAttrs, NS_NewHTMLPreElement);
StartCharacters();
@ -493,7 +500,7 @@ void
nsHtml5Highlighter::StartSpan()
{
FlushChars();
Push(nsGkAtoms::span, nullptr);
Push(nsGkAtoms::span, nullptr, NS_NewHTMLSpanElement);
++mInlinesOpen;
}
@ -517,7 +524,7 @@ nsHtml5Highlighter::StartCharacters()
{
NS_PRECONDITION(!mInCharacters, "Already in characters!");
FlushChars();
Push(nsGkAtoms::span, nullptr);
Push(nsGkAtoms::span, nullptr, NS_NewHTMLSpanElement);
mCurrentRun = CurrentNode();
mInCharacters = true;
}
@ -538,7 +545,7 @@ void
nsHtml5Highlighter::StartA()
{
FlushChars();
Push(nsGkAtoms::a, nullptr);
Push(nsGkAtoms::a, nullptr, NS_NewHTMLAnchorElement);
AddClass(sAttributeValue);
++mInlinesOpen;
}
@ -580,7 +587,7 @@ nsHtml5Highlighter::FlushChars()
mCStart = i;
}
++mLineNumber;
Push(nsGkAtoms::span, nullptr);
Push(nsGkAtoms::span, nullptr, NS_NewHTMLSpanElement);
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
NS_ASSERTION(treeOp, "Tree op allocation failed.");
treeOp->InitAddLineNumberId(CurrentNode(), mLineNumber);
@ -655,18 +662,23 @@ nsHtml5Highlighter::AllocateContentHandle()
}
nsIContent**
nsHtml5Highlighter::CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent)
nsHtml5Highlighter::CreateElement(
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent,
mozilla::dom::HTMLContentCreatorFunction aCreator)
{
NS_PRECONDITION(aName, "Got null name.");
nsHtml5ContentCreatorFunction creator;
creator.html = aCreator;
nsIContent** content = AllocateContentHandle();
mOpQueue.AppendElement()->Init(kNameSpaceID_XHTML,
aName,
aAttributes,
content,
aIntendedParent,
true);
true,
creator);
return content;
}
@ -679,10 +691,12 @@ nsHtml5Highlighter::CurrentNode()
void
nsHtml5Highlighter::Push(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes)
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::HTMLContentCreatorFunction aCreator)
{
NS_PRECONDITION(mStack.Length() >= 1, "Pushing without root.");
nsIContent** elt = CreateElement(aName, aAttributes, CurrentNode()); // Don't inline below!
nsIContent** elt = CreateElement(
aName, aAttributes, CurrentNode(), aCreator); // Don't inline below!
mOpQueue.AppendElement()->Init(eTreeOpAppend, elt, CurrentNode());
mStack.AppendElement(elt);
}

View File

@ -227,11 +227,14 @@ class nsHtml5Highlighter
* @param aAttributes the attribute holder (ownership will be taken) or
* nullptr for no attributes
* @param aIntendedParent the intended parent node for the created element
* @param aCreator the content creator function
* @return the handle for the element that will be created
*/
nsIContent** CreateElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent);
nsIContent** CreateElement(
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContent** aIntendedParent,
mozilla::dom::HTMLContentCreatorFunction aCreator);
/**
* Gets the handle for the current node. May be called only after the
@ -247,8 +250,11 @@ class nsHtml5Highlighter
* @param aName the name of the element
* @param aAttributes the attribute holder (ownership will be taken) or
* nullptr for no attributes
* @param aCreator the content creator function
*/
void Push(nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes);
void Push(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::HTMLContentCreatorFunction aCreator);
/**
* Pops the current node off the stack.

View File

@ -42,6 +42,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"

View File

@ -43,6 +43,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;

View File

@ -41,6 +41,7 @@
#include "nsHtml5ByteReadable.h"
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;

View File

@ -42,6 +42,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"
@ -91,13 +92,21 @@ nsHtml5StackNode::nsHtml5StackNode(int32_t idxInTreeBuilder)
MOZ_COUNT_CTOR(nsHtml5StackNode);
}
mozilla::dom::HTMLContentCreatorFunction
nsHtml5StackNode::getHtmlCreator()
{
return htmlCreator;
}
void
nsHtml5StackNode::setValues(int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes)
nsHtml5StackNode::setValues(
int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes,
mozilla::dom::HTMLContentCreatorFunction htmlCreator)
{
MOZ_ASSERT(isUnused());
this->flags = flags;
@ -107,6 +116,7 @@ nsHtml5StackNode::setValues(int32_t flags,
this->node = node;
this->attributes = attributes;
this->refcount = 1;
this->htmlCreator = htmlCreator;
}
void
@ -123,6 +133,7 @@ nsHtml5StackNode::setValues(nsHtml5ElementName* elementName,
this->refcount = 1;
MOZ_ASSERT(elementName->isInterned(),
"Don't use this constructor for custom elements.");
this->htmlCreator = nullptr;
}
void
@ -140,6 +151,7 @@ nsHtml5StackNode::setValues(nsHtml5ElementName* elementName,
this->refcount = 1;
MOZ_ASSERT(elementName->isInterned(),
"Don't use this constructor for custom elements.");
this->htmlCreator = elementName->getHtmlCreator();
}
void
@ -155,6 +167,7 @@ nsHtml5StackNode::setValues(nsHtml5ElementName* elementName,
this->node = node;
this->attributes = nullptr;
this->refcount = 1;
this->htmlCreator = nullptr;
}
void
@ -170,6 +183,7 @@ nsHtml5StackNode::setValues(nsHtml5ElementName* elementName,
this->node = node;
this->attributes = nullptr;
this->refcount = 1;
this->htmlCreator = nullptr;
}
void
@ -187,6 +201,7 @@ nsHtml5StackNode::setValues(nsHtml5ElementName* elementName,
this->node = node;
this->attributes = nullptr;
this->refcount = 1;
this->htmlCreator = nullptr;
}
int32_t

View File

@ -43,6 +43,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;
@ -68,6 +69,8 @@ class nsHtml5StackNode
nsHtml5HtmlAttributes* attributes;
private:
int32_t refcount;
mozilla::dom::HTMLContentCreatorFunction htmlCreator;
public:
inline int32_t getFlags()
{
@ -80,12 +83,14 @@ class nsHtml5StackNode
bool isFosterParenting();
bool isHtmlIntegrationPoint();
explicit nsHtml5StackNode(int32_t idxInTreeBuilder);
mozilla::dom::HTMLContentCreatorFunction getHtmlCreator();
void setValues(int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes);
nsHtml5HtmlAttributes* attributes,
mozilla::dom::HTMLContentCreatorFunction htmlCreator);
void setValues(nsHtml5ElementName* elementName, nsIContentHandle* node);
void setValues(nsHtml5ElementName* elementName,
nsIContentHandle* node,

View File

@ -41,6 +41,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"

View File

@ -42,6 +42,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;

View File

@ -295,7 +295,8 @@ nsHtml5Tokenizer::strBufToElementNameString()
} else {
nonInternedTagName->setNameForNonInterned(
nsHtml5Portability::newLocalNameFromBuffer(
strBuf, 0, strBufLen, interner));
strBuf, 0, strBufLen, interner),
true);
tagName = nonInternedTagName;
}
} else {
@ -304,7 +305,8 @@ nsHtml5Tokenizer::strBufToElementNameString()
if (!tagName) {
nonInternedTagName->setNameForNonInterned(
nsHtml5Portability::newLocalNameFromBuffer(
strBuf, 0, strBufLen, interner));
strBuf, 0, strBufLen, interner),
false);
tagName = nonInternedTagName;
}
}
@ -1806,6 +1808,7 @@ nsHtml5Tokenizer::stateLoop(int32_t state, char16_t c, int32_t pos, char16_t* bu
NS_HTML5_BREAK(outer);
}
appendCharRefBuf(c);
continue;
}
outer_end: ;
if (candidate == -1) {
@ -4354,6 +4357,7 @@ nsHtml5Tokenizer::eof()
if (hi < lo) {
NS_HTML5_BREAK(outer);
}
continue;
}
outer_end: ;
if (candidate == -1) {
@ -4433,6 +4437,7 @@ nsHtml5Tokenizer::eof()
}
eofloop_end: ;
tokenHandler->eof();
return;
}
void
@ -4491,7 +4496,7 @@ nsHtml5Tokenizer::end()
publicIdentifier = nullptr;
}
tagName = nullptr;
nonInternedTagName->setNameForNonInterned(nullptr);
nonInternedTagName->setNameForNonInterned(nullptr, false);
attributeName = nullptr;
nonInternedAttributeName->setNameForNonInterned(nullptr);
tokenHandler->endTokenization();
@ -4597,7 +4602,8 @@ nsHtml5Tokenizer::loadState(nsHtml5Tokenizer* other)
} else {
nonInternedTagName->setNameForNonInterned(
nsHtml5Portability::newLocalFromLocal(other->tagName->getName(),
interner));
interner),
other->tagName->isCustom());
tagName = nonInternedTagName;
}
if (!other->attributeName) {

View File

@ -169,7 +169,8 @@ nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self)
nsIContentHandle* elt = createElement(kNameSpaceID_SVG,
nsGkAtoms::svg,
tokenizer->emptyAttributes(),
nullptr);
nullptr,
svgCreator(NS_NewSVGSVGElement));
nsHtml5StackNode* node =
createStackNode(nsHtml5ElementName::ELT_SVG, nsGkAtoms::svg, elt);
currentPtr++;
@ -204,6 +205,7 @@ nsHtml5TreeBuilder::doctype(nsIAtom* name,
return;
}
errStrayDoctype();
return;
}
void
@ -231,6 +233,7 @@ nsHtml5TreeBuilder::comment(char16_t* buf, int32_t start, int32_t length)
}
flushCharacters();
appendComment(stack[currentPtr]->node, buf, start, length);
return;
}
void
@ -932,7 +935,7 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
if (!nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("hidden", attributes->getValue(nsHtml5AttributeName::ATTR_TYPE))) {
NS_HTML5_BREAK(intableloop);
}
appendVoidElementToCurrent(name, attributes, formPointer);
appendVoidInputToCurrent(attributes, formPointer);
selfClosing = false;
attributes = nullptr;
NS_HTML5_BREAK(starttagloop);
@ -1292,7 +1295,8 @@ nsHtml5TreeBuilder::startTag(nsHtml5ElementName* elementName, nsHtml5HtmlAttribu
case KEYGEN:
case INPUT: {
reconstructTheActiveFormattingElements();
appendVoidElementToCurrentMayFoster(name, attributes, formPointer);
appendVoidElementToCurrentMayFoster(
elementName, attributes, formPointer);
selfClosing = false;
attributes = nullptr;
NS_HTML5_BREAK(starttagloop);
@ -3341,6 +3345,7 @@ nsHtml5TreeBuilder::closeTheCell(int32_t eltPos)
}
clearTheListOfActiveFormattingElementsUpToTheLastMarker();
mode = IN_ROW;
return;
}
int32_t
@ -3706,13 +3711,19 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
}
MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]);
MOZ_ASSERT(node == stack[nodePos]);
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr), commonAncestor->node);
nsIContentHandle* clone =
createElement(kNameSpaceID_XHTML,
node->name,
node->attributes->cloneAttributes(nullptr),
commonAncestor->node,
htmlCreator(node->getHtmlCreator()));
nsHtml5StackNode* newNode = createStackNode(node->getFlags(),
node->ns,
node->name,
clone,
node->popName,
node->attributes);
node->attributes,
node->getHtmlCreator());
node->dropAttributes();
stack[nodePos] = newNode;
newNode->retain();
@ -3732,14 +3743,20 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag(nsIAtom* name)
detachFromParent(lastNode->node);
appendElement(lastNode->node, commonAncestor->node);
}
nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr), furthestBlock->node);
nsIContentHandle* clone =
createElement(kNameSpaceID_XHTML,
formattingElt->name,
formattingElt->attributes->cloneAttributes(nullptr),
furthestBlock->node,
htmlCreator(formattingElt->getHtmlCreator()));
nsHtml5StackNode* formattingClone =
createStackNode(formattingElt->getFlags(),
formattingElt->ns,
formattingElt->name,
clone,
formattingElt->popName,
formattingElt->attributes);
formattingElt->attributes,
formattingElt->getHtmlCreator());
formattingElt->dropAttributes();
appendChildrenToNewParent(furthestBlock->node, clone);
appendElement(clone, furthestBlock->node);
@ -3902,9 +3919,17 @@ nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
nsHtml5StackNode* currentNode = stack[currentPtr];
nsIContentHandle* clone;
if (currentNode->isFosterParenting()) {
clone = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
clone = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML,
entry->name,
entry->attributes->cloneAttributes(nullptr),
htmlCreator(entry->getHtmlCreator()));
} else {
clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr), currentNode->node);
clone = createElement(kNameSpaceID_XHTML,
entry->name,
entry->attributes->cloneAttributes(nullptr),
currentNode->node,
htmlCreator(entry->getHtmlCreator()));
appendElement(clone, currentNode->node);
}
nsHtml5StackNode* entryClone = createStackNode(entry->getFlags(),
@ -3912,7 +3937,8 @@ nsHtml5TreeBuilder::reconstructTheActiveFormattingElements()
entry->name,
clone,
entry->popName,
entry->attributes);
entry->attributes,
entry->getHtmlCreator());
entry->dropAttributes();
push(entryClone);
listOfActiveFormattingElements[entryPos] = entryClone;
@ -3953,15 +3979,17 @@ nsHtml5TreeBuilder::getUnusedStackNode()
}
nsHtml5StackNode*
nsHtml5TreeBuilder::createStackNode(int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes)
nsHtml5TreeBuilder::createStackNode(
int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes,
mozilla::dom::HTMLContentCreatorFunction htmlCreator)
{
nsHtml5StackNode* instance = getUnusedStackNode();
instance->setValues(flags, ns, name, node, popName, attributes);
instance->setValues(flags, ns, name, node, popName, attributes, htmlCreator);
return instance;
}
@ -4028,24 +4056,36 @@ nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle* child)
insertFosterParentedChild(child, node->node, stack[tablePos - 1]->node);
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes)
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsHtml5ContentCreatorFunction creator)
{
return createAndInsertFosterParentedElement(ns, name, attributes, nullptr);
return createAndInsertFosterParentedElement(
ns, name, attributes, nullptr, creator);
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsIContentHandle* form,
nsHtml5ContentCreatorFunction creator)
{
int32_t tablePos = findLastOrRoot(nsHtml5TreeBuilder::TABLE);
int32_t templatePos = findLastOrRoot(nsHtml5TreeBuilder::TEMPLATE);
if (templatePos >= tablePos) {
nsIContentHandle* child = createElement(ns, name, attributes, form, stack[templatePos]->node);
nsIContentHandle* child = createElement(
ns, name, attributes, form, stack[templatePos]->node, creator);
appendElement(child, stack[templatePos]->node);
return child;
}
nsHtml5StackNode* node = stack[tablePos];
return createAndInsertFosterParentedElement(ns, name, attributes, form, node->node, stack[tablePos - 1]->node);
return createAndInsertFosterParentedElement(
ns, name, attributes, form, node->node, stack[tablePos - 1]->node, creator);
}
bool
@ -4113,8 +4153,11 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt =
createElement(kNameSpaceID_XHTML, nsGkAtoms::head, attributes, currentNode);
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML,
nsGkAtoms::head,
attributes,
currentNode,
htmlCreator(NS_NewHTMLSharedElement));
appendElement(elt, currentNode);
headPointer = elt;
nsHtml5StackNode* node = createStackNode(nsHtml5ElementName::ELT_HEAD, elt);
@ -4140,11 +4183,17 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAt
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML, nsGkAtoms::form, attributes);
elt =
createAndInsertFosterParentedElement(kNameSpaceID_XHTML,
nsGkAtoms::form,
attributes,
htmlCreator(NS_NewHTMLFormElement));
} else {
elt = createElement(
kNameSpaceID_XHTML, nsGkAtoms::form, attributes, current->node);
elt = createElement(kNameSpaceID_XHTML,
nsGkAtoms::form,
attributes,
current->node,
htmlCreator(NS_NewHTMLFormElement));
appendElement(elt, current->node);
}
if (!isTemplateContents()) {
@ -4163,10 +4212,16 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML, elementName->getName(), attributes);
kNameSpaceID_XHTML,
elementName->getName(),
attributes,
htmlCreator(elementName->getHtmlCreator()));
} else {
elt = createElement(
kNameSpaceID_XHTML, elementName->getName(), attributes, current->node);
elt = createElement(kNameSpaceID_XHTML,
elementName->getName(),
attributes,
current->node,
htmlCreator(elementName->getHtmlCreator()));
appendElement(elt, current->node);
}
nsHtml5StackNode* node = createStackNode(elementName, elt, clone);
@ -4179,8 +4234,12 @@ void
nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt = createElement(
kNameSpaceID_XHTML, elementName->getName(), attributes, currentNode);
nsIContentHandle* elt =
createElement(kNameSpaceID_XHTML,
elementName->getName(),
attributes,
currentNode,
htmlCreator(elementName->getHtmlCreator()));
appendElement(elt, currentNode);
if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
elt = getDocumentFragmentForTemplate(elt);
@ -4197,9 +4256,17 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementNam
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, popName, attributes);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML,
popName,
attributes,
htmlCreator(elementName->getHtmlCreator()));
} else {
elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node);
elt = createElement(kNameSpaceID_XHTML,
popName,
attributes,
current->node,
htmlCreator(elementName->getHtmlCreator()));
appendElement(elt, current->node);
}
nsHtml5StackNode* node = createStackNode(elementName, elt, popName);
@ -4218,9 +4285,14 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5Elem
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_MathML, popName, attributes);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_MathML, popName, attributes, htmlCreator(nullptr));
} else {
elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node);
elt = createElement(kNameSpaceID_MathML,
popName,
attributes,
current->node,
htmlCreator(nullptr));
appendElement(elt, current->node);
}
nsHtml5StackNode* node =
@ -4247,9 +4319,17 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5Element
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_SVG, popName, attributes);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_SVG,
popName,
attributes,
svgCreator(elementName->getSvgCreator()));
} else {
elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node);
elt = createElement(kNameSpaceID_SVG,
popName,
attributes,
current->node,
svgCreator(elementName->getSvgCreator()));
appendElement(elt, current->node);
}
nsHtml5StackNode* node = createStackNode(elementName, popName, elt);
@ -4265,30 +4345,49 @@ nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementNam
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML, elementName->getName(), attributes, formOwner);
kNameSpaceID_XHTML,
elementName->getName(),
attributes,
formOwner,
htmlCreator(elementName->getHtmlCreator()));
} else {
elt = createElement(kNameSpaceID_XHTML,
elementName->getName(),
attributes,
formOwner,
current->node);
current->node,
htmlCreator(elementName->getHtmlCreator()));
appendElement(elt, current->node);
}
nsHtml5StackNode* node = createStackNode(elementName, elt);
push(node);
}
void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
void
nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
nsHtml5ElementName* elementName,
nsHtml5HtmlAttributes* attributes,
nsIContentHandle* form)
{
nsIAtom* name = elementName->getName();
nsIContentHandle* elt;
nsIContentHandle* formOwner = !form || fragment || isTemplateContents() ? nullptr : form;
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, name, attributes, formOwner);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML,
name,
attributes,
formOwner,
htmlCreator(elementName->getHtmlCreator()));
} else {
elt = createElement(kNameSpaceID_XHTML, name, attributes, formOwner, current->node);
elt = createElement(kNameSpaceID_XHTML,
name,
attributes,
formOwner,
current->node,
htmlCreator(elementName->getHtmlCreator()));
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_XHTML, name, elt);
@ -4303,9 +4402,17 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elem
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_XHTML, popName, attributes);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_XHTML,
popName,
attributes,
htmlCreator(elementName->getHtmlCreator()));
} else {
elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node);
elt = createElement(kNameSpaceID_XHTML,
popName,
attributes,
current->node,
htmlCreator(elementName->getHtmlCreator()));
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_XHTML, popName, elt);
@ -4320,9 +4427,17 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* e
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_SVG, popName, attributes);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_SVG,
popName,
attributes,
svgCreator(elementName->getSvgCreator()));
} else {
elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node);
elt = createElement(kNameSpaceID_SVG,
popName,
attributes,
current->node,
svgCreator(elementName->getSvgCreator()));
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_SVG, popName, elt);
@ -4337,31 +4452,46 @@ nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName
nsHtml5StackNode* current = stack[currentPtr];
if (current->isFosterParenting()) {
elt = createAndInsertFosterParentedElement(kNameSpaceID_MathML, popName, attributes);
elt = createAndInsertFosterParentedElement(
kNameSpaceID_MathML, popName, attributes, htmlCreator(nullptr));
} else {
elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node);
elt = createElement(kNameSpaceID_MathML,
popName,
attributes,
current->node,
htmlCreator(nullptr));
appendElement(elt, current->node);
}
elementPushed(kNameSpaceID_MathML, popName, elt);
elementPopped(kNameSpaceID_MathML, popName, elt);
}
void
nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
void
nsHtml5TreeBuilder::appendVoidInputToCurrent(nsHtml5HtmlAttributes* attributes,
nsIContentHandle* form)
{
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form, currentNode);
nsIContentHandle* elt =
createElement(kNameSpaceID_XHTML,
nsGkAtoms::input,
attributes,
!form || fragment || isTemplateContents() ? nullptr : form,
currentNode,
htmlCreator(NS_NewHTMLInputElement));
appendElement(elt, currentNode);
elementPushed(kNameSpaceID_XHTML, name, elt);
elementPopped(kNameSpaceID_XHTML, name, elt);
elementPushed(kNameSpaceID_XHTML, nsGkAtoms::input, elt);
elementPopped(kNameSpaceID_XHTML, nsGkAtoms::input, elt);
}
void
nsHtml5TreeBuilder::appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes)
{
nsIContentHandle* currentNode = stack[currentPtr]->node;
nsIContentHandle* elt =
createElement(kNameSpaceID_XHTML, nsGkAtoms::form, attributes, currentNode);
nsIContentHandle* elt = createElement(kNameSpaceID_XHTML,
nsGkAtoms::form,
attributes,
currentNode,
htmlCreator(NS_NewHTMLFormElement));
formPointer = elt;
appendElement(elt, currentNode);
elementPushed(kNameSpaceID_XHTML, nsGkAtoms::form, elt);
@ -4486,7 +4616,8 @@ nsHtml5TreeBuilder::newSnapshot()
node->name,
node->node,
node->popName,
node->attributes->cloneAttributes(nullptr));
node->attributes->cloneAttributes(nullptr),
node->getHtmlCreator());
listCopy[i] = newNode;
} else {
listCopy[i] = nullptr;
@ -4503,7 +4634,8 @@ nsHtml5TreeBuilder::newSnapshot()
node->name,
node->node,
node->popName,
nullptr);
nullptr,
node->getHtmlCreator());
stackCopy[i] = newNode;
} else {
stackCopy[i] = listCopy[listIndex];
@ -4588,7 +4720,8 @@ nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTab
nsHtml5Portability::newLocalFromLocal(node->name, interner),
node->node,
nsHtml5Portability::newLocalFromLocal(node->popName, interner),
node->attributes->cloneAttributes(nullptr));
node->attributes->cloneAttributes(nullptr),
node->getHtmlCreator());
listOfActiveFormattingElements[i] = newNode;
} else {
listOfActiveFormattingElements[i] = nullptr;
@ -4604,7 +4737,8 @@ nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTab
nsHtml5Portability::newLocalFromLocal(node->name, interner),
node->node,
nsHtml5Portability::newLocalFromLocal(node->popName, interner),
nullptr);
nullptr,
node->getHtmlCreator());
stack[i] = newNode;
} else {
stack[i] = listOfActiveFormattingElements[listIndex];

View File

@ -315,6 +315,22 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
private:
bool quirks;
bool isSrcdocDocument;
inline nsHtml5ContentCreatorFunction htmlCreator(
mozilla::dom::HTMLContentCreatorFunction htmlCreator)
{
nsHtml5ContentCreatorFunction creator;
creator.html = htmlCreator;
return creator;
}
inline nsHtml5ContentCreatorFunction svgCreator(
mozilla::dom::SVGContentCreatorFunction svgCreator)
{
nsHtml5ContentCreatorFunction creator;
creator.svg = svgCreator;
return creator;
}
public:
void startTokenization(nsHtml5Tokenizer* self);
void doctype(nsIAtom* name,
@ -406,12 +422,14 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
void notifyUnusedStackNode(int32_t idxInStackNodes);
private:
nsHtml5StackNode* getUnusedStackNode();
nsHtml5StackNode* createStackNode(int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes);
nsHtml5StackNode* createStackNode(
int32_t flags,
int32_t ns,
nsIAtom* name,
nsIContentHandle* node,
nsIAtom* popName,
nsHtml5HtmlAttributes* attributes,
mozilla::dom::HTMLContentCreatorFunction htmlCreator);
nsHtml5StackNode* createStackNode(nsHtml5ElementName* elementName,
nsIContentHandle* node);
nsHtml5StackNode* createStackNode(nsHtml5ElementName* elementName,
@ -428,8 +446,17 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
nsIAtom* popName,
bool markAsIntegrationPoint);
void insertIntoFosterParent(nsIContentHandle* child);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
nsIContentHandle* createAndInsertFosterParentedElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
nsIContentHandle* createAndInsertFosterParentedElement(
int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsHtml5ContentCreatorFunction creator);
nsIContentHandle* createAndInsertFosterParentedElement(
int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsIContentHandle* form,
nsHtml5ContentCreatorFunction creator);
bool isInStack(nsHtml5StackNode* node);
void popTemplateMode();
void pop();
@ -448,24 +475,43 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
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,
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 appendVoidInputToCurrent(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* createElement(int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsIContentHandle* intendedParent,
nsHtml5ContentCreatorFunction creator);
nsIContentHandle* createElement(int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsIContentHandle* form,
nsIContentHandle* intendedParent,
nsHtml5ContentCreatorFunction creator);
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);
nsIContentHandle* createAndInsertFosterParentedElement(
int32_t ns,
nsIAtom* name,
nsHtml5HtmlAttributes* attributes,
nsIContentHandle* form,
nsIContentHandle* table,
nsIContentHandle* stackParent,
nsHtml5ContentCreatorFunction creator);
;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 appendComment(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);

View File

@ -68,9 +68,11 @@ nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
}
nsIContentHandle*
nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
nsHtml5TreeBuilder::createElement(int32_t aNamespace,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aIntendedParent)
nsIContentHandle* aIntendedParent,
nsHtml5ContentCreatorFunction aCreator)
{
NS_PRECONDITION(aAttributes, "Got null attributes.");
NS_PRECONDITION(aName, "Got null name.");
@ -91,13 +93,28 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
intendedParent->OwnerDoc()->NodeInfoManager() :
mBuilder->GetNodeInfoManager();
nsIContent* elem =
nsHtml5TreeOperation::CreateElement(aNamespace,
name,
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
nodeInfoManager,
mBuilder);
nsIContent* elem;
if (aNamespace == kNameSpaceID_XHTML) {
elem = nsHtml5TreeOperation::CreateHTMLElement(
name,
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
nodeInfoManager,
mBuilder,
aCreator.html);
} else if (aNamespace == kNameSpaceID_SVG) {
elem = nsHtml5TreeOperation::CreateSVGElement(
name,
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
nodeInfoManager,
mBuilder,
aCreator.svg);
} else {
MOZ_ASSERT(aNamespace == kNameSpaceID_MathML);
elem = nsHtml5TreeOperation::CreateMathMLElement(
name, aAttributes, nodeInfoManager, mBuilder);
}
if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
delete aAttributes;
@ -113,7 +130,8 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
aAttributes,
content,
aIntendedParent,
!!mSpeculativeLoadStage);
!!mSpeculativeLoadStage,
aCreator);
// mSpeculativeLoadStage is non-null only in the off-the-main-thread
// tree builder, which handles the network stream
@ -345,13 +363,15 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
}
nsIContentHandle*
nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
nsHtml5TreeBuilder::createElement(int32_t aNamespace,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aFormElement,
nsIContentHandle* aIntendedParent)
nsIContentHandle* aIntendedParent,
nsHtml5ContentCreatorFunction aCreator)
{
nsIContentHandle* content = createElement(aNamespace, aName, aAttributes,
aIntendedParent);
nsIContentHandle* content =
createElement(aNamespace, aName, aAttributes, aIntendedParent, aCreator);
if (aFormElement) {
if (mBuilder) {
nsHtml5TreeOperation::SetFormElement(static_cast<nsIContent*>(content),
@ -368,8 +388,11 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
nsIContentHandle*
nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
{
nsIContentHandle* content =
createElement(kNameSpaceID_XHTML, nsGkAtoms::html, aAttributes, nullptr);
nsHtml5ContentCreatorFunction creator;
// <html> uses NS_NewHTMLSharedElement creator
creator.html = NS_NewHTMLSharedElement;
nsIContentHandle* content = createElement(
kNameSpaceID_XHTML, nsGkAtoms::html, aAttributes, nullptr, creator);
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendToDocument(static_cast<nsIContent*>(content),
mBuilder);
@ -385,11 +408,14 @@ nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttribute
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t aNamespace, nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aFormElement,
nsIContentHandle* aTable,
nsIContentHandle* aStackParent)
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
int32_t aNamespace,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aFormElement,
nsIContentHandle* aTable,
nsIContentHandle* aStackParent,
nsHtml5ContentCreatorFunction aCreator)
{
NS_PRECONDITION(aTable, "Null table");
NS_PRECONDITION(aStackParent, "Null stack parent");
@ -401,8 +427,8 @@ nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t aNamespace, nsI
static_cast<nsIContent*>(aTable),
static_cast<nsIContent*>(aStackParent));
nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
aFormElement, fosterParent);
nsIContentHandle* child = createElement(
aNamespace, aName, aAttributes, aFormElement, fosterParent, aCreator);
insertFosterParentedChild(child, aTable, aStackParent);
@ -418,8 +444,8 @@ nsHtml5TreeBuilder::createAndInsertFosterParentedElement(int32_t aNamespace, nsI
aStackParent, fosterParentHandle);
// Create the element with the correct intended parent.
nsIContentHandle* child = createElement(aNamespace, aName, aAttributes,
aFormElement, fosterParentHandle);
nsIContentHandle* child = createElement(
aNamespace, aName, aAttributes, aFormElement, fosterParentHandle, aCreator);
// Insert the child into the foster parent.
insertFosterParentedChild(child, aTable, aStackParent);

View File

@ -88,8 +88,11 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation()
case eTreeOpAddAttributes:
delete mTwo.attributes;
break;
case eTreeOpCreateElementNetwork:
case eTreeOpCreateElementNotNetwork:
case eTreeOpCreateHTMLElementNetwork:
case eTreeOpCreateHTMLElementNotNetwork:
case eTreeOpCreateSVGElementNetwork:
case eTreeOpCreateSVGElementNotNetwork:
case eTreeOpCreateMathMLElement:
delete mThree.attributes;
break;
case eTreeOpAppendDoctypeToDocument:
@ -328,32 +331,39 @@ nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
return NS_OK;
}
nsIContent*
nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder)
nsHtml5TreeOperation::CreateHTMLElement(
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder,
mozilla::dom::HTMLContentCreatorFunction aCreator)
{
bool isKeygen = (aName == nsGkAtoms::keygen && aNs == kNameSpaceID_XHTML);
bool isKeygen = (aName == nsGkAtoms::keygen);
if (MOZ_UNLIKELY(isKeygen)) {
aName = nsGkAtoms::select;
aCreator = NS_NewHTMLSelectElement;
}
nsCOMPtr<dom::Element> newElement;
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->
GetNodeInfo(aName, nullptr, aNs, nsIDOMNode::ELEMENT_NODE);
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->GetNodeInfo(
aName, nullptr, kNameSpaceID_XHTML, 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.");
nsCOMPtr<dom::Element> newElement = aCreator(nodeInfo.forget(), aFromParser);
MOZ_ASSERT(newElement, "Element creation created null pointer.");
dom::Element* newContent = newElement;
aBuilder->HoldElement(newElement.forget());
if (aCreator == NS_NewCustomElement) {
// Not inlining the call below into NS_NewCustomElement itself, because
// in the near future, the code here will need to break out of an update
// batch here.
nsContentUtils::SetupCustomElement(newContent);
}
if (MOZ_UNLIKELY(aName == nsGkAtoms::style || aName == nsGkAtoms::link)) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
@ -386,18 +396,15 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsGkAtoms::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);
nsCOMPtr<dom::Element> optionElt =
NS_NewHTMLOptionElement(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);
}
newContent->DoneAddingChildren(false);
}
if (!aAttributes) {
@ -415,8 +422,7 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
nsString value; // Not Auto, because using it to hold nsStringBuffer*
aAttributes->getValueNoBoundsCheck(i).ToString(value);
if (aNs == kNameSpaceID_XHTML && nsGkAtoms::a == aName &&
nsGkAtoms::name == localName) {
if (nsGkAtoms::a == aName && nsGkAtoms::name == localName) {
// This is an HTML5-incompliant Geckoism.
// Remove when fixing bug 582361
NS_ConvertUTF16toUTF8 cname(value);
@ -442,6 +448,117 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
return newContent;
}
nsIContent*
nsHtml5TreeOperation::CreateSVGElement(
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder,
mozilla::dom::SVGContentCreatorFunction aCreator)
{
nsCOMPtr<nsIContent> newElement;
if (MOZ_LIKELY(aNodeInfoManager->SVGEnabled())) {
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->GetNodeInfo(
aName, nullptr, kNameSpaceID_SVG, nsIDOMNode::ELEMENT_NODE);
MOZ_ASSERT(nodeInfo, "Got null nodeinfo.");
mozilla::DebugOnly<nsresult> rv =
aCreator(getter_AddRefs(newElement), nodeInfo.forget(), aFromParser);
MOZ_ASSERT(NS_SUCCEEDED(rv) && newElement);
} else {
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->GetNodeInfo(
aName, nullptr, kNameSpaceID_disabled_SVG, nsIDOMNode::ELEMENT_NODE);
MOZ_ASSERT(nodeInfo, "Got null nodeinfo.");
// The mismatch between NS_NewXMLElement and SVGContentCreatorFunction
// argument types is annoying.
nsCOMPtr<dom::Element> xmlElement;
mozilla::DebugOnly<nsresult> rv =
NS_NewXMLElement(getter_AddRefs(xmlElement), nodeInfo.forget());
MOZ_ASSERT(NS_SUCCEEDED(rv) && xmlElement);
newElement = xmlElement;
}
dom::Element* newContent = newElement->AsElement();
aBuilder->HoldElement(newElement.forget());
if (MOZ_UNLIKELY(aName == nsGkAtoms::style)) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
if (ssle) {
ssle->InitStyleLinkElement(false);
ssle->SetEnableUpdates(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);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
aAttributes->getValueNoBoundsCheck(i).ToString(value);
newContent->SetAttr(nsuri, localName, prefix, value, false);
}
return newContent;
}
nsIContent*
nsHtml5TreeOperation::CreateMathMLElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder)
{
nsCOMPtr<dom::Element> newElement;
if (MOZ_LIKELY(aNodeInfoManager->MathMLEnabled())) {
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->GetNodeInfo(
aName, nullptr, kNameSpaceID_MathML, nsIDOMNode::ELEMENT_NODE);
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
mozilla::DebugOnly<nsresult> rv =
NS_NewMathMLElement(getter_AddRefs(newElement), nodeInfo.forget());
MOZ_ASSERT(NS_SUCCEEDED(rv) && newElement);
} else {
RefPtr<dom::NodeInfo> nodeInfo = aNodeInfoManager->GetNodeInfo(
aName, nullptr, kNameSpaceID_disabled_MathML, nsIDOMNode::ELEMENT_NODE);
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
mozilla::DebugOnly<nsresult> rv =
NS_NewXMLElement(getter_AddRefs(newElement), nodeInfo.forget());
MOZ_ASSERT(NS_SUCCEEDED(rv) && newElement);
}
dom::Element* newContent = newElement;
aBuilder->HoldElement(newElement.forget());
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);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
aAttributes->getValueNoBoundsCheck(i).ToString(value);
newContent->SetAttr(nsuri, localName, prefix, value, false);
}
return newContent;
}
void
nsHtml5TreeOperation::SetFormElement(nsIContent* aNode, nsIContent* aParent)
{
@ -658,10 +775,56 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
aBuilder->SetDocumentMode(mOne.mode);
return NS_OK;
}
case eTreeOpCreateElementNetwork:
case eTreeOpCreateElementNotNetwork: {
case eTreeOpCreateHTMLElementNetwork:
case eTreeOpCreateHTMLElementNotNetwork: {
nsIContent** target = mOne.node;
mozilla::dom::HTMLContentCreatorFunction creator = mFour.htmlCreator;
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 = CreateHTMLElement(name,
attributes,
mOpCode == eTreeOpCreateHTMLElementNetwork
? dom::FROM_PARSER_NETWORK
: dom::FROM_PARSER_DOCUMENT_WRITE,
nodeInfoManager,
aBuilder,
creator);
return NS_OK;
}
case eTreeOpCreateSVGElementNetwork:
case eTreeOpCreateSVGElementNotNetwork: {
nsIContent** target = mOne.node;
mozilla::dom::SVGContentCreatorFunction creator = mFour.svgCreator;
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 = CreateSVGElement(name,
attributes,
mOpCode == eTreeOpCreateSVGElementNetwork
? dom::FROM_PARSER_NETWORK
: dom::FROM_PARSER_DOCUMENT_WRITE,
nodeInfoManager,
aBuilder,
creator);
return NS_OK;
}
case eTreeOpCreateMathMLElement: {
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;
@ -672,14 +835,8 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
intendedParent->OwnerDoc()->NodeInfoManager() :
aBuilder->GetNodeInfoManager();
*target = CreateElement(ns,
name,
attributes,
mOpCode == eTreeOpCreateElementNetwork ?
dom::FROM_PARSER_NETWORK :
dom::FROM_PARSER_DOCUMENT_WRITE,
nodeInfoManager,
aBuilder);
*target =
CreateMathMLElement(name, attributes, nodeInfoManager, aBuilder);
return NS_OK;
}
case eTreeOpSetFormElement: {

View File

@ -17,7 +17,8 @@ namespace mozilla {
class Encoding;
}
enum eHtml5TreeOperation {
enum eHtml5TreeOperation
{
eTreeOpUninitialized,
// main HTML5 ops
eTreeOpAppend,
@ -27,8 +28,11 @@ enum eHtml5TreeOperation {
eTreeOpAppendToDocument,
eTreeOpAddAttributes,
eTreeOpDocumentMode,
eTreeOpCreateElementNetwork,
eTreeOpCreateElementNotNetwork,
eTreeOpCreateHTMLElementNetwork,
eTreeOpCreateHTMLElementNotNetwork,
eTreeOpCreateSVGElementNetwork,
eTreeOpCreateSVGElementNotNetwork,
eTreeOpCreateMathMLElement,
eTreeOpSetFormElement,
eTreeOpAppendText,
eTreeOpFosterParentText,
@ -147,12 +151,26 @@ class nsHtml5TreeOperation final {
nsHtml5HtmlAttributes* aAttributes,
nsHtml5DocumentBuilder* aBuilder);
static nsIContent* CreateElement(int32_t aNs,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder);
static nsIContent* CreateHTMLElement(
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder,
mozilla::dom::HTMLContentCreatorFunction aCreator);
static nsIContent* CreateSVGElement(
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
mozilla::dom::FromParser aFromParser,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder,
mozilla::dom::SVGContentCreatorFunction aCreator);
static nsIContent* CreateMathMLElement(nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsNodeInfoManager* aNodeInfoManager,
nsHtml5DocumentBuilder* aBuilder);
static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
@ -309,22 +327,31 @@ class nsHtml5TreeOperation final {
mOne.node = static_cast<nsIContent**>(aNode);
mTwo.state = nullptr;
}
inline void Init(int32_t aNamespace,
nsIAtom* aName,
inline void Init(int32_t aNamespace,
nsIAtom* aName,
nsHtml5HtmlAttributes* aAttributes,
nsIContentHandle* aTarget,
nsIContentHandle* aIntendedParent,
bool aFromNetwork)
bool aFromNetwork,
nsHtml5ContentCreatorFunction aCreator)
{
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;
if (aNamespace == kNameSpaceID_XHTML) {
mOpCode = aFromNetwork ? eTreeOpCreateHTMLElementNetwork
: eTreeOpCreateHTMLElementNotNetwork;
mFour.htmlCreator = aCreator.html;
} else if (aNamespace == kNameSpaceID_SVG) {
mOpCode = aFromNetwork ? eTreeOpCreateSVGElementNetwork
: eTreeOpCreateSVGElementNotNetwork;
mFour.svgCreator = aCreator.svg;
} else {
MOZ_ASSERT(aNamespace == kNameSpaceID_MathML);
mOpCode = eTreeOpCreateMathMLElement;
}
mFive.node = static_cast<nsIContent**>(aIntendedParent);
mOne.node = static_cast<nsIContent**>(aTarget);
mTwo.atom = aName;
@ -534,6 +561,8 @@ class nsHtml5TreeOperation final {
int32_t integer;
nsresult result;
const Encoding* encoding;
mozilla::dom::HTMLContentCreatorFunction htmlCreator;
mozilla::dom::SVGContentCreatorFunction svgCreator;
} mOne, mTwo, mThree, mFour, mFive;
};

View File

@ -41,6 +41,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
#include "nsHtml5AttributeName.h"
#include "nsHtml5ElementName.h"

View File

@ -42,6 +42,7 @@
#include "nsHtml5Macros.h"
#include "nsIContentHandle.h"
#include "nsHtml5Portability.h"
#include "nsHtml5ContentCreatorFunction.h"
class nsHtml5StreamParser;

View File

@ -12,6 +12,12 @@
It is designed to be used as input to various places that will define the
HTML_TAG macro in useful ways through the magic of C preprocessing.
Additionally, it is consumed by the self-regeneration code in
ElementName.java from which nsHtml5ElementName.cpp/h is translated.
See parser/html/java/README.txt.
If you edit this list, you need to re-run ElementName.java
self-regeneration and the HTML parser Java to C++ translation.
All entries must be enclosed in the macro HTML_TAG which will have cruel
and unusual things done to it.