зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1556342 - Implement customElements.define's form-associated; r=edgar,smaug
Differential Revision: https://phabricator.services.mozilla.com/D85734
This commit is contained in:
Родитель
4711a353c1
Коммит
7e2fb3fe0d
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/CustomElementRegistryBinding.h"
|
||||
#include "mozilla/dom/ElementBinding.h"
|
||||
#include "mozilla/dom/HTMLElementBinding.h"
|
||||
#include "mozilla/dom/PrimitiveConversions.h"
|
||||
#include "mozilla/dom/ShadowIncludingTreeIterator.h"
|
||||
#include "mozilla/dom/XULElementBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
|
@ -847,6 +848,7 @@ void CustomElementRegistry::Define(
|
|||
auto callbacksHolder = MakeUnique<LifecycleCallbacks>();
|
||||
nsTArray<RefPtr<nsAtom>> observedAttributes;
|
||||
AutoTArray<RefPtr<nsAtom>, 2> disabledFeatures;
|
||||
bool formAssociated = false;
|
||||
bool disableInternals = false;
|
||||
bool disableShadow = false;
|
||||
{ // Set mIsCustomDefinitionRunning.
|
||||
|
@ -921,7 +923,7 @@ void CustomElementRegistry::Define(
|
|||
* disabledFeaturesIterable to a sequence<DOMString>.
|
||||
* Rethrow any exceptions from the conversion.
|
||||
*/
|
||||
if (StaticPrefs::dom_webcomponents_elementInternals_enabled()) {
|
||||
if (StaticPrefs::dom_webcomponents_formAssociatedCustomElement_enabled()) {
|
||||
if (!JSObjectToAtomArray(aCx, constructor, u"disabledFeatures"_ns,
|
||||
disabledFeatures, aRv)) {
|
||||
return;
|
||||
|
@ -936,6 +938,24 @@ void CustomElementRegistry::Define(
|
|||
// "shadow".
|
||||
disableShadow = disabledFeatures.Contains(
|
||||
static_cast<nsStaticAtom*>(nsGkAtoms::shadow));
|
||||
|
||||
// 14.11. Let formAssociatedValue be Get(constructor, "formAssociated").
|
||||
// Rethrow any exceptions.
|
||||
JS::Rooted<JS::Value> formAssociatedValue(aCx);
|
||||
if (!JS_GetProperty(aCx, constructor, "formAssociated",
|
||||
&formAssociatedValue)) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
// 14.12. Set formAssociated to the result of converting
|
||||
// formAssociatedValue to a boolean. Rethrow any exceptions from
|
||||
// the conversion.
|
||||
if (!ValueToPrimitive<bool, eDefault>(
|
||||
aCx, formAssociatedValue, "formAssociated", &formAssociated)) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // Unset mIsCustomDefinitionRunning
|
||||
|
||||
|
@ -958,7 +978,7 @@ void CustomElementRegistry::Define(
|
|||
|
||||
RefPtr<CustomElementDefinition> definition = new CustomElementDefinition(
|
||||
nameAtom, localNameAtom, nameSpaceID, &aFunctionConstructor,
|
||||
std::move(observedAttributes), std::move(callbacksHolder),
|
||||
std::move(observedAttributes), std::move(callbacksHolder), formAssociated,
|
||||
disableInternals, disableShadow);
|
||||
|
||||
CustomElementDefinition* def = definition.get();
|
||||
|
@ -1470,14 +1490,15 @@ CustomElementDefinition::CustomElementDefinition(
|
|||
nsAtom* aType, nsAtom* aLocalName, int32_t aNamespaceID,
|
||||
CustomElementConstructor* aConstructor,
|
||||
nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
|
||||
UniquePtr<LifecycleCallbacks>&& aCallbacks, bool aDisableInternals,
|
||||
bool aDisableShadow)
|
||||
UniquePtr<LifecycleCallbacks>&& aCallbacks, bool aFormAssociated,
|
||||
bool aDisableInternals, bool aDisableShadow)
|
||||
: mType(aType),
|
||||
mLocalName(aLocalName),
|
||||
mNamespaceID(aNamespaceID),
|
||||
mConstructor(aConstructor),
|
||||
mObservedAttributes(std::move(aObservedAttributes)),
|
||||
mCallbacks(std::move(aCallbacks)),
|
||||
mFormAssociated(aFormAssociated),
|
||||
mDisableInternals(aDisableInternals),
|
||||
mDisableShadow(aDisableShadow) {}
|
||||
|
||||
|
|
|
@ -141,7 +141,8 @@ struct CustomElementDefinition {
|
|||
CustomElementConstructor* aConstructor,
|
||||
nsTArray<RefPtr<nsAtom>>&& aObservedAttributes,
|
||||
UniquePtr<LifecycleCallbacks>&& aCallbacks,
|
||||
bool aDisableInternals, bool aDisableShadow);
|
||||
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.
|
||||
|
@ -162,6 +163,10 @@ struct CustomElementDefinition {
|
|||
// The lifecycle callbacks to call for this custom element.
|
||||
UniquePtr<LifecycleCallbacks> mCallbacks;
|
||||
|
||||
// If this is true, user agent treats elements associated to this custom
|
||||
// element definition as form-associated custom elements.
|
||||
bool mFormAssociated = false;
|
||||
|
||||
// Determine whether to allow to attachInternals() for this custom element.
|
||||
bool mDisableInternals = false;
|
||||
|
||||
|
|
|
@ -1029,7 +1029,8 @@ bool Element::CanAttachShadowDOM() const {
|
|||
// It will always have CustomElementData when the element is a valid custom
|
||||
// element or has is value.
|
||||
CustomElementData* ceData = GetCustomElementData();
|
||||
if (StaticPrefs::dom_webcomponents_elementInternals_enabled() && ceData) {
|
||||
if (StaticPrefs::dom_webcomponents_formAssociatedCustomElement_enabled() &&
|
||||
ceData) {
|
||||
CustomElementDefinition* definition = ceData->GetCustomElementDefinition();
|
||||
// If the definition is null, the element possible hasn't yet upgraded.
|
||||
// Fallback to use LookupCustomElementDefinition to find its definition.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* https://html.spec.whatwg.org/#elementinternals
|
||||
*/
|
||||
|
||||
[Pref="dom.webcomponents.elementInternals.enabled", Exposed=Window]
|
||||
[Pref="dom.webcomponents.formAssociatedCustomElement.enabled", Exposed=Window]
|
||||
interface ElementInternals {
|
||||
};
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ interface HTMLElement : Element {
|
|||
//readonly attribute boolean? commandChecked;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/custom-elements.html#dom-attachinternals
|
||||
[Pref="dom.webcomponents.elementInternals.enabled", Throws]
|
||||
[Pref="dom.webcomponents.formAssociatedCustomElement.enabled", Throws]
|
||||
ElementInternals attachInternals();
|
||||
};
|
||||
|
||||
|
|
|
@ -3232,8 +3232,8 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
# Is support for elementInternals enabled?
|
||||
- name: dom.webcomponents.elementInternals.enabled
|
||||
# Is support for form-associated custom element enabled?
|
||||
- name: dom.webcomponents.formAssociatedCustomElement.enabled
|
||||
type: bool
|
||||
value: @IS_NIGHTLY_BUILD@
|
||||
mirror: always
|
||||
|
|
|
@ -11,18 +11,9 @@
|
|||
[customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present]
|
||||
expected: FAIL
|
||||
|
||||
[customElements.define must rethrow an exception thrown while getting formAssociated on the constructor prototype]
|
||||
expected: FAIL
|
||||
|
||||
[customElements.define must rethrow an exception thrown while getting additional formAssociated callbacks on the constructor prototype]
|
||||
expected: FAIL
|
||||
|
||||
[customElements.define must get four additional callbacks on the prototype if formAssociated is converted to true]
|
||||
expected: FAIL
|
||||
|
||||
[customElements.define must get "prototype", "disabledFeatures", and "formAssociated" property of the constructor]
|
||||
expected: FAIL
|
||||
|
||||
[customElements.define must not throw when defining another custom element in a different global object during Get(constructor, "prototype")]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
prefs: [dom.webcomponents.elementInternals.enabled:true]
|
||||
prefs: [dom.webcomponents.formAssociatedCustomElement.enabled:true]
|
||||
leak-threshold: [default:51200]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.experimental.enabled:true, dom.security.featurePolicy.header.enabled:true, dom.security.featurePolicy.webidl.enabled:true, dom.webcomponents.elementInternals.enabled:true, dom.forms.requestsubmit.enabled:true, dom.forms.inputmode:true, dom.forms.enterkeyhint:true]
|
||||
prefs: [dom.security.featurePolicy.enabled:true, dom.security.featurePolicy.experimental.enabled:true, dom.security.featurePolicy.header.enabled:true, dom.security.featurePolicy.webidl.enabled:true, dom.webcomponents.formAssociatedCustomElement.enabled:true, dom.forms.requestsubmit.enabled:true, dom.forms.inputmode:true, dom.forms.enterkeyhint:true]
|
||||
[idlharness.https.html?exclude=(Document|Window|HTML.*)]
|
||||
[OffscreenCanvasRenderingContext2D interface: operation lineTo(unrestricted double, unrestricted double)]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1 +1 @@
|
|||
prefs: [dom.webcomponents.elementInternals.enabled:true]
|
||||
prefs: [dom.webcomponents.formAssociatedCustomElement.enabled:true]
|
||||
|
|
Загрузка…
Ссылка в новой задаче