diff options
author | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 05:01:17 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2020-04-17 05:01:17 -0400 |
commit | 0d362ca50335d964a78dbba7e7d32574ee67899a (patch) | |
tree | 8b5de5f34019b97ad0b3c155c270a810608cd775 /dom/base/nsDocument.cpp | |
parent | de45820b64ab03768336c7242622ef9f499347cf (diff) | |
download | UXP-0d362ca50335d964a78dbba7e7d32574ee67899a.tar UXP-0d362ca50335d964a78dbba7e7d32574ee67899a.tar.gz UXP-0d362ca50335d964a78dbba7e7d32574ee67899a.tar.lz UXP-0d362ca50335d964a78dbba7e7d32574ee67899a.tar.xz UXP-0d362ca50335d964a78dbba7e7d32574ee67899a.zip |
Bug 1330843 - Allow JS to create NAC pseudo-elements
Tag #1375
Diffstat (limited to 'dom/base/nsDocument.cpp')
-rw-r--r-- | dom/base/nsDocument.cpp | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 45c80ca7f..d0e861b1a 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -5378,6 +5378,20 @@ nsDocument::GetCustomElementRegistry() return registry.forget(); } +// We only support pseudo-elements with two colons in this function. +static CSSPseudoElementType +GetPseudoElementType(const nsString& aString, ErrorResult& aRv) +{ + MOZ_ASSERT(!aString.IsEmpty(), "GetPseudoElementType aString should be non-null"); + if (aString.Length() <= 2 || aString[0] != ':' || aString[1] != ':') { + aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR); + return CSSPseudoElementType::NotPseudo; + } + nsCOMPtr<nsIAtom> pseudo = NS_Atomize(Substring(aString, 1)); + return nsCSSPseudoElements::GetPseudoType(pseudo, + nsCSSProps::EnabledState::eInUASheets); +} + already_AddRefed<Element> nsDocument::CreateElement(const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions, @@ -5395,10 +5409,36 @@ nsDocument::CreateElement(const nsAString& aTagName, } const nsString* is = nullptr; + CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo; + if (aOptions.IsElementCreationOptions()) { + const ElementCreationOptions& options = + aOptions.GetAsElementCreationOptions(); + + if (CustomElementRegistry::IsCustomElementEnabled() && + options.mIs.WasPassed()) { + is = &options.mIs.Value(); + } + + // Check 'pseudo' and throw an exception if it's not one allowed + // with CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC. + if (options.mPseudo.WasPassed()) { + pseudoType = GetPseudoElementType(options.mPseudo.Value(), rv); + if (rv.Failed() || + pseudoType == CSSPseudoElementType::NotPseudo || + !nsCSSPseudoElements::PseudoElementIsJSCreatedNAC(pseudoType)) { + rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); + return nullptr; + } + } + } RefPtr<Element> elem = CreateElem( needsLowercase ? lcTagName : aTagName, nullptr, mDefaultElementType, is); + if (pseudoType != CSSPseudoElementType::NotPseudo) { + elem->SetPseudoElementType(pseudoType); + } + if (is) { elem->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true); } @@ -5413,8 +5453,8 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI, { *aReturn = nullptr; ElementCreationOptionsOrString options; - options.SetAsString(); + options.SetAsString(); ErrorResult rv; nsCOMPtr<Element> element = CreateElementNS(aNamespaceURI, aQualifiedName, options, rv); @@ -5439,6 +5479,13 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI, } const nsString* is = nullptr; + if (CustomElementRegistry::IsCustomElementEnabled() && + aOptions.IsElementCreationOptions()) { + const ElementCreationOptions& options = aOptions.GetAsElementCreationOptions(); + if (options.mIs.WasPassed()) { + is = &options.mIs.Value(); + } + } nsCOMPtr<Element> element; rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(), |