Bug 1663878 - Only process form callbacks for form-associated custom elements. r=edgar

Differential Revision: https://phabricator.services.mozilla.com/D167827
This commit is contained in:
Adam Vandolder 2023-01-26 22:26:00 +00:00
Родитель e450188d9b
Коммит bb2a454e3a
4 изменённых файлов: 51 добавлений и 25 удалений

Просмотреть файл

@ -166,20 +166,26 @@ UniquePtr<CustomElementCallback> CustomElementCallback::Create(
break;
case ElementCallbackType::eFormAssociated:
if (aDefinition->mCallbacks->mFormAssociatedCallback.WasPassed()) {
func = aDefinition->mCallbacks->mFormAssociatedCallback.Value();
if (aDefinition->mFormAssociatedCallbacks->mFormAssociatedCallback
.WasPassed()) {
func = aDefinition->mFormAssociatedCallbacks->mFormAssociatedCallback
.Value();
}
break;
case ElementCallbackType::eFormReset:
if (aDefinition->mCallbacks->mFormResetCallback.WasPassed()) {
func = aDefinition->mCallbacks->mFormResetCallback.Value();
if (aDefinition->mFormAssociatedCallbacks->mFormResetCallback
.WasPassed()) {
func =
aDefinition->mFormAssociatedCallbacks->mFormResetCallback.Value();
}
break;
case ElementCallbackType::eFormDisabled:
if (aDefinition->mCallbacks->mFormDisabledCallback.WasPassed()) {
func = aDefinition->mCallbacks->mFormDisabledCallback.Value();
if (aDefinition->mFormAssociatedCallbacks->mFormDisabledCallback
.WasPassed()) {
func = aDefinition->mFormAssociatedCallbacks->mFormDisabledCallback
.Value();
}
break;
@ -573,7 +579,7 @@ void CustomElementRegistry::EnqueueLifecycleCallback(
return;
}
if (!definition->mCallbacks) {
if (!definition->mCallbacks && !definition->mFormAssociatedCallbacks) {
// definition has been unlinked. Don't try to mess with it.
return;
}
@ -907,6 +913,8 @@ void CustomElementRegistry::Define(
}
auto callbacksHolder = MakeUnique<LifecycleCallbacks>();
auto formAssociatedCallbacksHolder =
MakeUnique<FormAssociatedLifecycleCallbacks>();
nsTArray<RefPtr<nsAtom>> observedAttributes;
AutoTArray<RefPtr<nsAtom>, 2> disabledFeatures;
bool formAssociated = false;
@ -1017,6 +1025,22 @@ void CustomElementRegistry::Define(
aRv.NoteJSContextException(aCx);
return;
}
/**
* 14.13. If formAssociated is true, for each of "formAssociatedCallback",
* "formResetCallback", "formDisabledCallback", and
* "formStateRestoreCallback" callbackName:
* 1. Let callbackValue be ? Get(prototype, callbackName).
* 2. If callbackValue is not undefined, then set the value of the
* entry in lifecycleCallbacks with key callbackName to the result
* of converting callbackValue to the Web IDL Function callback
* type. Rethrow any exceptions from the conversion.
*/
if (formAssociated &&
!formAssociatedCallbacksHolder->Init(aCx, prototype)) {
aRv.NoteJSContextException(aCx);
return;
}
} // Unset mIsCustomDefinitionRunning
/**
@ -1038,7 +1062,8 @@ void CustomElementRegistry::Define(
RefPtr<CustomElementDefinition> definition = new CustomElementDefinition(
nameAtom, localNameAtom, nameSpaceID, &aFunctionConstructor,
std::move(observedAttributes), std::move(callbacksHolder), formAssociated,
std::move(observedAttributes), std::move(callbacksHolder),
std::move(formAssociatedCallbacksHolder), formAssociated,
disableInternals, disableShadow);
CustomElementDefinition* def = definition.get();
@ -1539,20 +1564,22 @@ void CustomElementReactionsStack::InvokeReactions(ElementQueue* aElementQueue,
// CustomElementDefinition
NS_IMPL_CYCLE_COLLECTION(CustomElementDefinition, mConstructor, mCallbacks,
mConstructionStack)
mFormAssociatedCallbacks, mConstructionStack)
CustomElementDefinition::CustomElementDefinition(
nsAtom* aType, nsAtom* aLocalName, int32_t aNamespaceID,
CustomElementConstructor* aConstructor,
nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
UniquePtr<LifecycleCallbacks>&& aCallbacks, bool aFormAssociated,
bool aDisableInternals, bool aDisableShadow)
UniquePtr<LifecycleCallbacks>&& aCallbacks,
UniquePtr<FormAssociatedLifecycleCallbacks>&& aFormAssociatedCallbacks,
bool aFormAssociated, bool aDisableInternals, bool aDisableShadow)
: mType(aType),
mLocalName(aLocalName),
mNamespaceID(aNamespaceID),
mConstructor(aConstructor),
mObservedAttributes(std::move(aObservedAttributes)),
mCallbacks(std::move(aCallbacks)),
mFormAssociatedCallbacks(std::move(aFormAssociatedCallbacks)),
mFormAssociated(aFormAssociated),
mDisableInternals(aDisableInternals),
mDisableShadow(aDisableShadow) {}

Просмотреть файл

@ -133,13 +133,13 @@ struct CustomElementDefinition {
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(CustomElementDefinition)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CustomElementDefinition)
CustomElementDefinition(nsAtom* aType, nsAtom* aLocalName,
int32_t aNamespaceID,
CustomElementConstructor* aConstructor,
nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
UniquePtr<LifecycleCallbacks>&& aCallbacks,
bool aFormAssociated, bool aDisableInternals,
bool aDisableShadow);
CustomElementDefinition(
nsAtom* aType, nsAtom* aLocalName, int32_t aNamespaceID,
CustomElementConstructor* aConstructor,
nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
UniquePtr<LifecycleCallbacks>&& aCallbacks,
UniquePtr<FormAssociatedLifecycleCallbacks>&& aFormAssociatedCallbacks,
bool aFormAssociated, bool aDisableInternals, bool aDisableShadow);
// The type (name) for this custom element, for <button is="x-foo"> or <x-foo>
// this would be x-foo.
@ -159,6 +159,7 @@ struct CustomElementDefinition {
// The lifecycle callbacks to call for this custom element.
UniquePtr<LifecycleCallbacks> mCallbacks;
UniquePtr<FormAssociatedLifecycleCallbacks> mFormAssociatedCallbacks;
// If this is true, user agent treats elements associated to this custom
// element definition as form-associated custom elements.

Просмотреть файл

@ -53,8 +53,12 @@ dictionary LifecycleCallbacks {
LifecycleDisconnectedCallback disconnectedCallback;
LifecycleAdoptedCallback adoptedCallback;
LifecycleAttributeChangedCallback attributeChangedCallback;
[ChromeOnly] LifecycleGetCustomInterfaceCallback getCustomInterfaceCallback;
};
[GenerateInit, Unsorted]
dictionary FormAssociatedLifecycleCallbacks {
LifecycleFormAssociatedCallback formAssociatedCallback;
LifecycleFormResetCallback formResetCallback;
LifecycleFormDisabledCallback formDisabledCallback;
[ChromeOnly] LifecycleGetCustomInterfaceCallback getCustomInterfaceCallback;
};

Просмотреть файл

@ -1,10 +1,4 @@
[CustomElementRegistry.html]
[customElements.define must get callbacks of the constructor prototype]
expected: FAIL
[customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present]
expected: FAIL
[customElements.define must get four additional callbacks on the prototype if formAssociated is converted to true]
expected: FAIL