Bug 1330843 - Allow JS to create NAC pseudo-elements

Tag #1375
This commit is contained in:
Matt A. Tobin 2020-04-17 05:01:17 -04:00 committed by Roy Tam
commit c37b4d0c63
8 changed files with 115 additions and 4 deletions

View file

@ -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(),