mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-30 19:17:31 +09:00
parent
fda213de85
commit
c37b4d0c63
8 changed files with 115 additions and 4 deletions
|
|
@ -9871,3 +9871,16 @@ nsContentUtils::IsLocalRefURL(const nsString& aString)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ Element*
|
||||||
|
nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aElement);
|
||||||
|
MOZ_ASSERT(aElement->IsNativeAnonymous());
|
||||||
|
|
||||||
|
Element* e = aElement;
|
||||||
|
while (e && e->IsNativeAnonymous()) {
|
||||||
|
e = e->GetParentElement();
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2762,6 +2762,12 @@ public:
|
||||||
static bool
|
static bool
|
||||||
IsWebComponentsEnabled() { return sIsWebComponentsEnabled; }
|
IsWebComponentsEnabled() { return sIsWebComponentsEnabled; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walks up the tree from aElement until it finds an element that is
|
||||||
|
* not native anonymous content. aElement must be NAC itself.
|
||||||
|
*/
|
||||||
|
static Element* GetClosestNonNativeAnonymousAncestor(Element* aElement);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5378,6 +5378,20 @@ nsDocument::GetCustomElementRegistry()
|
||||||
return registry.forget();
|
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>
|
already_AddRefed<Element>
|
||||||
nsDocument::CreateElement(const nsAString& aTagName,
|
nsDocument::CreateElement(const nsAString& aTagName,
|
||||||
const ElementCreationOptionsOrString& aOptions,
|
const ElementCreationOptionsOrString& aOptions,
|
||||||
|
|
@ -5395,10 +5409,36 @@ nsDocument::CreateElement(const nsAString& aTagName,
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsString* is = nullptr;
|
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(
|
RefPtr<Element> elem = CreateElem(
|
||||||
needsLowercase ? lcTagName : aTagName, nullptr, mDefaultElementType, is);
|
needsLowercase ? lcTagName : aTagName, nullptr, mDefaultElementType, is);
|
||||||
|
|
||||||
|
if (pseudoType != CSSPseudoElementType::NotPseudo) {
|
||||||
|
elem->SetPseudoElementType(pseudoType);
|
||||||
|
}
|
||||||
|
|
||||||
if (is) {
|
if (is) {
|
||||||
elem->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true);
|
elem->SetAttr(kNameSpaceID_None, nsGkAtoms::is, *is, true);
|
||||||
}
|
}
|
||||||
|
|
@ -5413,8 +5453,8 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||||
{
|
{
|
||||||
*aReturn = nullptr;
|
*aReturn = nullptr;
|
||||||
ElementCreationOptionsOrString options;
|
ElementCreationOptionsOrString options;
|
||||||
options.SetAsString();
|
|
||||||
|
|
||||||
|
options.SetAsString();
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
nsCOMPtr<Element> element =
|
nsCOMPtr<Element> element =
|
||||||
CreateElementNS(aNamespaceURI, aQualifiedName, options, rv);
|
CreateElementNS(aNamespaceURI, aQualifiedName, options, rv);
|
||||||
|
|
@ -5439,6 +5479,13 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsString* is = nullptr;
|
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;
|
nsCOMPtr<Element> element;
|
||||||
rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(),
|
rv = NS_NewElement(getter_AddRefs(element), nodeInfo.forget(),
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ enum VisibilityState { "hidden", "visible", "prerender" };
|
||||||
/* https://dom.spec.whatwg.org/#dictdef-elementcreationoptions */
|
/* https://dom.spec.whatwg.org/#dictdef-elementcreationoptions */
|
||||||
dictionary ElementCreationOptions {
|
dictionary ElementCreationOptions {
|
||||||
DOMString is;
|
DOMString is;
|
||||||
|
|
||||||
|
[ChromeOnly]
|
||||||
|
DOMString pseudo;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* http://dom.spec.whatwg.org/#interface-document */
|
/* http://dom.spec.whatwg.org/#interface-document */
|
||||||
|
|
|
||||||
|
|
@ -1062,6 +1062,25 @@ ElementForStyleContext(nsIContent* aParentContent,
|
||||||
return f->GetContent()->AsElement();
|
return f->GetContent()->AsElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Element* frameElement = aFrame->GetContent()->AsElement();
|
||||||
|
if (frameElement->IsNativeAnonymous() &&
|
||||||
|
nsCSSPseudoElements::PseudoElementIsJSCreatedNAC(aPseudoType)) {
|
||||||
|
// NAC-implemented pseudos use the closest non-NAC element as their
|
||||||
|
// element to inherit from.
|
||||||
|
//
|
||||||
|
// FIXME(heycam): In theory we shouldn't need to limit this only to
|
||||||
|
// JS-created pseudo-implementing NAC, as all pseudo-implementing
|
||||||
|
// should use the closest non-native anonymous ancestor element as
|
||||||
|
// its originating element. But removing that part of the condition
|
||||||
|
// reveals some bugs in style resultion with display:contents and
|
||||||
|
// XBL. See bug 1345809.
|
||||||
|
Element* originatingElement =
|
||||||
|
nsContentUtils::GetClosestNonNativeAnonymousAncestor(frameElement);
|
||||||
|
if (originatingElement) {
|
||||||
|
return originatingElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (aParentContent) {
|
if (aParentContent) {
|
||||||
return aParentContent->AsElement();
|
return aParentContent->AsElement();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5041,8 +5041,19 @@ nsCSSFrameConstructor::ResolveStyleContext(nsStyleContext* aParentStyleContext,
|
||||||
aParentStyleContext);
|
aParentStyleContext);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(aOriginatingElementOrNull);
|
|
||||||
MOZ_ASSERT(aContent->IsInNativeAnonymousSubtree());
|
MOZ_ASSERT(aContent->IsInNativeAnonymousSubtree());
|
||||||
|
if (!aOriginatingElementOrNull) {
|
||||||
|
// For pseudo-implementing NAC created by JS using the ChromeOnly
|
||||||
|
// document.createElement(..., { pseudo: ... }) API, we find the
|
||||||
|
// originating element by lookup the tree until we find a non-NAC
|
||||||
|
// ancestor. (These are the correct semantics for C++-generated pseudo-
|
||||||
|
// implementing NAC as well, but for those cases we already have a
|
||||||
|
// correct originating element passed in.)
|
||||||
|
MOZ_ASSERT(nsCSSPseudoElements::PseudoElementIsJSCreatedNAC(pseudoType));
|
||||||
|
aOriginatingElementOrNull =
|
||||||
|
nsContentUtils::GetClosestNonNativeAnonymousAncestor(aContent->AsElement());
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(aOriginatingElementOrNull);
|
||||||
result = styleSet->ResolvePseudoElementStyle(aOriginatingElementOrNull,
|
result = styleSet->ResolvePseudoElementStyle(aOriginatingElementOrNull,
|
||||||
pseudoType,
|
pseudoType,
|
||||||
aParentStyleContext,
|
aParentStyleContext,
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@
|
||||||
#define CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE (1<<3)
|
#define CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE (1<<3)
|
||||||
// Is content prevented from parsing selectors containing this pseudo-element?
|
// Is content prevented from parsing selectors containing this pseudo-element?
|
||||||
#define CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY (1<<4)
|
#define CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY (1<<4)
|
||||||
|
// Can we use the ChromeOnly document.createElement(..., { pseudo: "::foo" })
|
||||||
|
// API for creating pseudo-implementing native anonymous content in JS with this
|
||||||
|
// pseudo-element?
|
||||||
|
#define CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC (1<<5)
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
|
@ -98,6 +102,11 @@ public:
|
||||||
|
|
||||||
static bool PseudoElementSupportsUserActionState(const Type aType);
|
static bool PseudoElementSupportsUserActionState(const Type aType);
|
||||||
|
|
||||||
|
static bool PseudoElementIsJSCreatedNAC(Type aType)
|
||||||
|
{
|
||||||
|
return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC);
|
||||||
|
}
|
||||||
|
|
||||||
static bool IsEnabled(Type aType, EnabledState aEnabledState)
|
static bool IsEnabled(Type aType, EnabledState aEnabledState)
|
||||||
{
|
{
|
||||||
return !PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY) ||
|
return !PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY) ||
|
||||||
|
|
|
||||||
|
|
@ -717,7 +717,9 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
|
||||||
// We want to check that going through this path because of
|
// We want to check that going through this path because of
|
||||||
// HasPseudoElementData is rare, because it slows us down a good
|
// HasPseudoElementData is rare, because it slows us down a good
|
||||||
// bit. So check that we're really inside something associated
|
// bit. So check that we're really inside something associated
|
||||||
// with a pseudo-element that contains elements.
|
// with a pseudo-element that contains elements. (We also allow
|
||||||
|
// the element to be NAC, just in case some chrome JS calls
|
||||||
|
// getComputedStyle on a NAC-implemented pseudo.)
|
||||||
nsStyleContext* topWithPseudoElementData = mStyleContext;
|
nsStyleContext* topWithPseudoElementData = mStyleContext;
|
||||||
while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) {
|
while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) {
|
||||||
topWithPseudoElementData = topWithPseudoElementData->GetParent();
|
topWithPseudoElementData = topWithPseudoElementData->GetParent();
|
||||||
|
|
@ -728,7 +730,8 @@ nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
|
||||||
NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements ("));
|
NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements ("));
|
||||||
assertMsg.Append(nsDependentString(pseudoAtom->GetUTF16String()));
|
assertMsg.Append(nsDependentString(pseudoAtom->GetUTF16String()));
|
||||||
assertMsg.Append(')');
|
assertMsg.Append(')');
|
||||||
NS_ASSERTION(nsCSSPseudoElements::PseudoElementContainsElements(pseudo),
|
NS_ASSERTION(nsCSSPseudoElements::PseudoElementContainsElements(pseudo) ||
|
||||||
|
mElement->IsNativeAnonymous(),
|
||||||
NS_LossyConvertUTF16toASCII(assertMsg).get());
|
NS_LossyConvertUTF16toASCII(assertMsg).get());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue