Skip to content

Commit

Permalink
Bug 483155 - Put content creator function pointers onto nsHtml5Elemen…
Browse files Browse the repository at this point in the history
…tName. r=smaug

MozReview-Commit-ID: E2AAx7Zz2UF

--HG--
extra : rebase_source : 1b85ba3b1c699e71e6ecacf4d1dc4271f3416b08
  • Loading branch information
hsivonen committed Jul 4, 2017
1 parent 56587ad commit 3d387ac
Show file tree
Hide file tree
Showing 39 changed files with 3,446 additions and 1,354 deletions.
29 changes: 2 additions & 27 deletions dom/base/nsNameSpaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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());
}

Expand All @@ -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 =
Expand Down
47 changes: 46 additions & 1 deletion dom/base/nsNodeInfoManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ nsNodeInfoManager::nsNodeInfoManager()
mTextNodeInfo(nullptr),
mCommentNodeInfo(nullptr),
mDocumentNodeInfo(nullptr),
mRecentlyUsedNodeInfos{}
mRecentlyUsedNodeInfos{},
mSVGEnabled(eTriUnset),
mMathMLEnabled(eTriUnset)
{
nsLayoutStatics::AddRef();

Expand Down Expand Up @@ -463,3 +465,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;
}
32 changes: 32 additions & 0 deletions dom/base/nsNodeInfoManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,33 @@ class nsNodeInfoManager final
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;
Expand All @@ -130,6 +157,9 @@ class nsNodeInfoManager final
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;
Expand All @@ -140,6 +170,8 @@ class nsNodeInfoManager final
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___ */
9 changes: 9 additions & 0 deletions dom/html/HTMLElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
16 changes: 16 additions & 0 deletions dom/html/nsGenericHTMLElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -1471,6 +1471,15 @@ class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
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.
Expand Down Expand Up @@ -1519,6 +1528,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)

Expand Down
8 changes: 2 additions & 6 deletions dom/html/nsHTMLContentSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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!");
Expand Down
56 changes: 30 additions & 26 deletions dom/svg/SVGElementFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
25 changes: 25 additions & 0 deletions dom/svg/SVGElementFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,32 @@ class SVGElementFactory {
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 */
9 changes: 8 additions & 1 deletion dom/svg/SVGTagList.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions dom/svg/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ EXPORTS += [
'SVGContentUtils.h',
'SVGPreserveAspectRatio.h',
'SVGStringList.h',
'SVGTagList.h',
]

EXPORTS.mozilla.dom += [
Expand All @@ -42,6 +43,7 @@ EXPORTS.mozilla.dom += [
'SVGDefsElement.h',
'SVGDescElement.h',
'SVGDocument.h',
'SVGElementFactory.h',
'SVGEllipseElement.h',
'SVGFEBlendElement.h',
'SVGFEColorMatrixElement.h',
Expand Down
Loading

0 comments on commit 3d387ac

Please sign in to comment.