calebdwilliams / element-internals-polyfill Goto Github PK
View Code? Open in Web Editor NEWA polyfill for the element internals specification
License: MIT License
A polyfill for the element internals specification
License: MIT License
When a formAssociated web component is disabled it doesn't report as valid when using the polyfilled version. The current implementation within the latest versions of Firefox and Chrome acts differently. To demonstrate this behaviour I created this example code sandbox:
https://codesandbox.io/s/litelement-formcontrol-example-d3jbut
When you open de sandbox directly in a browser without support for element internals the checkValidity evaluates too false in Chrome and Firefox checkValidity evaluates to true. I intentionally left the input in the Shadow DOM enabled so fiddling with the components value is possible.
Im definitely interested in the AOM properties of this polyfill, but I dont see any examples in the README of how to set it up inside a custom element.
i would assume its something like calling initAom
from https://github.com/calebdwilliams/element-internals-polyfill/blob/master/src/aom.ts#L43 in the custom element constructor, but it would be good for an example to be provided.
If I'm right about that, I'd be glad to send a small PR to update the readme to include the examples :)
Buttons can associate to forms that they are a descendant of, or forms that have an id specified by the form
attribute.
So can form associated custom buttons in Chrome (107), see for example this sandbox: https://codesandbox.io/s/loving-lena-p56owk?file=/index.html . Both the button inside the form, as well as the one specified by the form
attribute can find the form it is associated to. (printed to the console on click).
However, in browsers that require this polyfill, such as Safari, only the form associated button that is a descendant of the form can properly find its form.
Hey @calebdwilliams,
i have seen that the "disabled" attribute is on the filter list of the MutationObserver. Is there any reason for that?
I can't see in the official documentation any information about that.
To reproduce my issue with that:
checked
and value="test"
disabled
attribute on-the-flyexpected behaviour:
but current behavior:
In Chrome, where the polyfill will not be used, it behaves like expected, the value of a disabled checkbox will not be submitted.
Thank you
Christoph
Consider this example switch component
import {html, css, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
@customElement('x-switch')
export class XSwitch extends LitElement {
static formAssociated = true;
#internals = this.attachInternals();
@property({ type: Boolean }) checked = false;
connectedCallback() {
super.connectedCallback();
this.addEventListener('click', this.onClick);
}
render() {
return this.checked ? 'x' : 'o';
}
onClick() {
this.checked = !this.checked;
}
}
When it is labeled, clicking the label should toggle the switch:
<x-switch id="x"></x-switch>
<label for="x">LABEL</label>
In Firefox and Chromium (supporting), clicking the label will toggle the switch
However, in epiphany (webkit) clicking the label will not toggle the switch.
The polyfill should add click listeners to labels associated with the control via for
Thanx for the polyfill!
I did manage to break it though (did not mean to :) )
I'm using multiple forms, not all forms contain form associated custom elements.
Therefor the used weakmap does not contain each form.
On a form change event , this breaks:
element-internals-polyfill/src/utils.ts
Line 216 in dc04339
It does not validate the elements variable, and this is empty in our case
src/radio-group/radio.ts:1:15 - error TS2459: Module '"element-internals-polyfill"' declares 'IElementInternals' locally, but it is not exported.
1 import type { IElementInternals } from 'element-internals-polyfill';
~~~~~~~~~~~~~~~~~
../../node_modules/element-internals-polyfill/dist/index.d.ts:4:10
4 import { IElementInternals } from './types';
~~~~~~~~~~~~~~~~~
'IElementInternals' is declared here.
Found 1 error.
With typescript 4.9.5.
This polyfill is great! So I'm working on integrating Element Internals into my Web Components framework WebCell, but I found no .d.ts
...
The override method is used for calling the 'reportValidity'and 'checkValidity' methods of the custom-element.
But it uses the registered internals for calling these methods, therefor the own handler is never called.
// this works
let _elWidget = document.querySelector('test-example');
_elWidget.reportValidity(); // the own internal handler is called and performs additional checks
// this does not work :
let _elForm = document.querySelector('form');
_elForm.reportValidity(); // the internal handlers of the used web components are skipped
I made a change to the override method: (no typescript)
const overrideFormMethod = (form, returnValue, method) => {
const elements = formElementsMap.get(form);
if (elements) {
for (const element of elements) {
let _fncToCall;
if ('function' === typeof element[method]) {
_fncToCall = element[method];
} else {
const internals = internalsMap.get(element);
_fncToCall = (internals && 'function' === typeof internals[method]) ? _fncToCall : undefined;
}
if (_fncToCall && !_fncToCall()) {
returnValue = false;
}
}
}
return returnValue;
};
The line before "Current Limitations" section seems to be incomplete:
The currently-supported features of ElementInternals for form-associated custom elements are
Would you like to add a list of features, or maybe remove it for now?
Hi there,
I have tried this project in different browsers and discovered a problem, especially in Chromes
as per Caniuse, chrome supports ElementInternals from 77: https://caniuse.com/mdn-api_elementinternals
but ":is" from 88: https://caniuse.com/?search=%3Ais
so in browsers < 77 the polyfill fails with "not a valid selector"
same in safari < 14
I need to support Chrome browsers >= 63 any Safari >= 11. I can babel modern syntax like optional changing etc. But ":is" is not that simple.
The question is if it would be possible to rewrite the query with "flatMap" and "matches" (I can PR this).
And whether it even is considered an issue.
Thanks in advance.
element-internals-polyfill/src/utils.ts
Line 133 in 8aa2b3d
Consider the following code:
const form = document.createElement('form');
const control = new CustomControl();
form.appendChild(control);
document.body.appendChild(form);
The control
will not be polyfilled. Executing control.internal.setValidity(..)
will throw:
Uncaught TypeError: items is undefined index.js:74:41
setFormValidity index.js:74
reconcileValidity index.js:283
setValidity index.js:509
...
The MutationObserver
will only check if the added node (which is the form
element) is a form-associated custom element, but the subtree is not searched for form-associated custom elements, so the control
in the example is never associated with the form.
We would like to include this polyfill with our Lit components we are building that use element internals. This makes it very easy for consumers of the component to have a single import and not have to worry about polyfilling. However, we import these components in a server-side rendering setup and this polyfill runs and tries to instantiate a new MutationObserver, which causes it to break.
We'd really like to not have to separate the import of the component from the import of the polyfill.
I'd be willing to submit a PR to address this, but would like feedback on posssible solutions.
typeof window !== "undefined"
)exports
field in the package.json to point to a different noop version for node
vs. the default
Custom form elements appear in the elements list of the associated form control in Chromium. But when I check this in Firefox, using this polyfill, the custom elements do not appear in the elements list.
All the elements have their name property set, as suggested in the readme: "If the element has a name, a refernce to the host element will be saved on the form object.".
When I upgraded to the latest version of element-internals-polyfill (0.1.47) our webpack bundle command started failing with the following error:
ERROR in ./node_modules/element-internals-polyfill/dist/index.js 224:17
Module parse failed: Unexpected token (224:17)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| class ValidityState {
> badInput = false;
| customError = false;
| patternMismatch = false;
@ ./src/main.js 2:0-36
./src/main.js line 2 is simply
import "element-internals-polyfill";
We are using webpack 4.46.0
I tried doing an npm ci
(clean install) and the issue persisted. Downgrading back to element-internals-polyfill 0.1.46 resolved the issue.
Hi all,
We have a design system project named Baklava. We built it with lit and esbuild.
We want to dynamically import this polyfill when the user's browser is Safari. However, we don't want to add this in the released package, because it will add ~5KB in gzip. Is there any way to do this?
Thank you in advance.
form:valid does match/form:invalid does not match a form with an invalid form-associated custom element.
I created a quick patch because I needed this functionality in a project I was working on. My solution was to attach an input event listener to the form that toggles "internals-valid" and "internals-invalid" attributes on the form based on the result of form.checkValidity(). You can then select the form as expected using some variation the following:
form:is(:invalid, [internals-valid])
form:is(:valid:not([internals-invalid]), [internals-valid])
I'm not sure whether there is a better way to implement this. If this seems like a reasonable solution, I'd be happy to submit a PR!
Current behavior:
Expected behavior:
Hey,
I invoke the setFormValue method multiple times for a custom checkbox component, e.g. on connected callback or on attribute change callback. The polyfill then seems to add for each invocation a new hidden input field, but will never remove the existing ones before. Have debugged some parts of your code, code lines like "hiddenInput.remove() will be invoked, but the hidden input field will never be removed from DOM properly.
Is this an known issue, or any recommendations how to handle that?
I am using lit with version 2.0.0-rc.2 and the latest version of this element internals polyfill.
Thanks
- setFormValue(value: string)
+ setFormValue(value: string | File | FormData, state: string | File | FormData)
Since Chrome extensions do not allow for creating Web Components, we recommend our users force the custom elements polyfill. The issue is that if your elements are using the polyfill on a browser that supports elementInternals, you get an error that you are attaching ElementInternals to a non-custom element. In these cases it would be great to have a flag to force the CE polyfill or a way for users to invoke it without the checks.
This patch fixed it for me
diff --git a/node_modules/element-internals-polyfill/dist/element-internals.d.ts b/node_modules/element-internals-polyfill/dist/element-internals.d.ts
index c428619..36d542b 100644
--- a/node_modules/element-internals-polyfill/dist/element-internals.d.ts
+++ b/node_modules/element-internals-polyfill/dist/element-internals.d.ts
@@ -64,12 +64,12 @@ export declare class ElementInternals implements IElementInternals {
*
* If the field is valid and a message is specified, the method will throw a TypeError.
*/
- setValidity(validityChanges: Partial<globalThis.ValidityState>, validationMessage?: string, anchor?: HTMLElement): void;
+ setValidity(validityChanges: Partial<ValidityState>, validationMessage?: string, anchor?: HTMLElement): void;
get shadowRoot(): ShadowRoot | null;
/** The element's validation message set during a call to ElementInternals.setValidity */
get validationMessage(): string;
/** The current validity state of the object */
- get validity(): globalThis.ValidityState;
+ get validity(): ValidityState;
/** If true the element will participate in a form's constraint validation. */
get willValidate(): boolean;
}
First a big thank you + a star for publishing this polyfill !
While testing it I realized that although using the FormData
API works, more traditional form usage such as in the following snippet does not:
class MyTest extends HTMLElement {
static get formAssociated() { return true; }
constructor() {
super();
this._internals = this.attachInternals();
}
}
customElements.define("my-element", MyTest);
<form>
<my-element name="myel"></my-element>
</form>
onSubmit(ev) {
ev.preventDefault();
const form = ev.target;
alert('submit with value: ' + (form.myel && form.myel.value));
}
Like with a regular input element, under Chrome (so polyfill not used) the form
object includes form.myel
and form[0]
. With Firefox (so with polyfill) those entries are missing.
This issue is to request that the polyfill adds those definitions. Possibly a simple change to the polyfill's initForm()
method is all it takes, or maybe there is a better way ?
It seems that the polyfill dispatches more invalid
events than expected.
Please have a look a the following demo.
If you enter something in the input field you'll see that in firefox on each input an invalid
event is fired, while in Chrome it's not (the latter is the correct behavior, I guess).
https://codesandbox.io/s/nifty-glade-vm1ju?file=/src/index.js
Used FF version: 95.0.1 (Windows), used Chrome version: 96.0.4664.110 (Windows)
Hi, thanks for your awesome project ! We try it in IE 11, run most code correctly but find some wrong in webcomponents polyfill.
You can find detail in this issue: webcomponents/polyfills#504 .
I think it can be fixed very simple by modify attachShadowObserver
like this:
try {
observer.observe(shadowRoot, observerConfig);
} catch (err) {
console.info('observe shadowRoot to this');
// we can just observe parent element in IE11, the code will run correctly.
observer.observe(this, observerConfig);
}
I found another inconsistency while using lit-html to render associated-components.
Basically, if you run attachInternals()
inside the constructor, it fails to initialize when using a lit-html template inside another template.
I do not know enough about the internals of lit-html but I assume it is caused by the additional step of <template>
ing the component, without any connection to the outer form
and later connecting it to the actual DOM.
Moving attachInternals()
over into the connectedCallback()
works reliably.
I again created a glitch with a reproduction: https://glitch.com/edit/#!/dog-glib-beluga?path=script.js%3A12%3A0
Thank you so much for your work!
The scoped custom element registry polyfill has different patch for attachInternals
, this polyfill should shift to be compatible.
Hi! 👋
Firstly, thanks for your work on this project!
It seems that when a custom-element internals are of type FormData, the value are attached in the page in the opposite order.
The probelm is probably caused by createHiddenInput that directly appends the input tag below the custom element.
When the function is called multiple times with the "formdata order" the elements are appended in reverse.
Here is a code snippet to reproduce the issue:
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]/dist/index.js"></script>
</head>
<body>
<form>
<sample-element></sample-element>
<input type="submit">
</form>
<script>
class SampleElement extends HTMLElement {
static formAssociated = true
constructor() {
super()
this.attachShadow({mode: 'open'})
this._internals = this.attachInternals()
}
connectedCallback() {
this._internals.setFormValue(this._formValue())
this.shadowRoot.innerHTML = '<span> Test </span>'
}
_formValue() {
const formData = new FormData()
formData.append('one', 1)
formData.append('two', 2)
formData.append('three', 3)
return formData
}
}
window.customElements.define('sample-element', SampleElement)
</script>
</body>
</html>
When submitted on a browser that does not support attachInternals the resulting querystring is: ?three=3&two=2&one=1
, instead of the expected ?one=1&two=2&three=3
.
Using patch-package, here is is the diff that solved my problem:
diff --git a/node_modules/element-internals-polyfill/dist/index.js b/node_modules/element-internals-polyfill/dist/index.js
index 83f2d1c..debf61b 100644
--- a/node_modules/element-internals-polyfill/dist/index.js
+++ b/node_modules/element-internals-polyfill/dist/index.js
@@ -479,7 +479,7 @@
}
}
else if (value != null && value instanceof FormData) {
- value.forEach((formDataValue, formDataKey) => {
+ Array.from(value).reverse().forEach(([formDataKey, formDataValue]) => {
if (typeof formDataValue === 'string') {
const hiddenInput = createHiddenInput(ref, this);
hiddenInput.name = formDataKey;
The library somehow emulates custom states through attributes so they can be matched in CSS when the polyfill is used. Unfortunately this won't allow matching the custom states when the element is exposed as a shadow part, as ::part()
can only be followed by a non-structural state selector or pseudo-element selector.
For instance, given a custom element c-e-inner
with custom state --c-s
and another custom element c-e
whose shadow tree looks like:
<c-e-inner part="inner"></c-e-inner>
In browsers supporting custom states, you can match it using the following selector:
c-e::part(inner):--c-s { /* … */ }
But c-e::part(inner)[state--c-s]
is illegal and thus won't work in browsers not supporting custom states.
Proposal: expose custom states on shadow parts using other shadow parts.
Specifically, with the above example, make it work with the following selectors:
c-e::part(inner--state--c-s) { /* … */ }
c-e::part(inner inner--state--c-s) { /* … */ }
In terms of implementation, whenever a custom state is added/deleted, if the element as a non-empty part
DOMTokenList (ignoring any parts added to emulate the custom states), then add/delete as many corresponding parts whose name is composed as ${part}--state--${state}
. This conversely mean observing attribute mutations to detect part=""
changes so that whenever an element gains/loses a part, the corresponding parts added by the polyfill are added/deleted accordingly, all while trying to avoid an infinite recursion. (I would probably try to implement this by getting all non-state-related parts and ensuring that all the corresponding state-emulating parts are present, and to properly handle a removed part
name then either make sure all state-emulating part matches a non-state-related part, or parse the attribute's old value to determine which parts were removed if any)
Elements using exportparts
would have to manually export all possible parts, renaming them if needed:
<c-e exportparts="inner: renamed, inner--state--c-s: renamed--state--c-s"></c-e>
May I please know what are the license and terms of use for this "element-internals-polyfill" work and repo?
the package.json has "license": "MIT",
, does that cover it as MIT licensed?
Thank you.
Consider this example custom element codepen:
<x-menu>Menu</x-menu>
<script type="module">
import 'element-internals-polyfill';
customElements.define('x-menu', class XMenu extends HTMLElement {
#internals = this.attachInternals();
constructor() {
super();
this.#internals.role = 'menu';
}
});
</script>
Chromium 111 correctly reports the menu
role:
Firefox 110 does not
FWIW, GNOME Web 44 nightly also does not report the menu
role, but it's not clear to me why not, since it implements role
on ElementInternals
I believe that this happens because the polyfill just checks for the existence of ElementInternals
on globalThis
and quits when it finds one, assuming the vendor fully implemented everything.
As in Real Soon Now: https://twitter.com/rniwa_dev/status/1611516973770477568
How do you test a polyfill when all modern browsers support the API? Fix the playwright WebKit version to an older one?
Hey, thank you for this great polyfill! I am looking forward to browser implementation coming in!
During development I noticed a few inconsistencies regarding validity checking called on the associated form element.
Specifically form.reportValidity()
and form.checkValidity()
both return true
even if the internals validity is set to false. Additionally they do not cause the components invalid
event to fire.
The following glitch should show a reproducible inconsistency https://glitch.com/edit/#!/eminent-grape-soul (tested using FF 89 and Chome 90).
Secondly, I am curious about the inconsistency when hitting the in-form submit button. It appears that native inputs are preferred by the polyfill and no check happens on the custom inputs if one of the native ones is already invalid. This is also different on Chrome.
I also realized, that the invalid
selector is not supported. Maybe this would be great as an addition to the readme?
*edit: I accidentally tabbed out of the input and hit enter, so the initial issue was empty
Build successfully with TypeScript 4.9:
{
"compilerOptions": {
"strict": true,
"target": "ES5",
"module": "ES2022",
"moduleResolution": "Node",
"jsx": "react-jsx",
"jsxFactory": "",
"jsxFragmentFactory": "",
"lib": ["ES2022", "DOM"]
},
"include": ["source/**/*"],
}
node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/types.d.ts:56:18 - error
TS2430: Interface 'ICustomElement' incorrectly extends interface 'HTMLElement'.
The types returned by 'attachInternals()' are incompatible between these types.
Type 'ElementInternals' is missing the following properties from type 'ElementInternals': ariaColIndexText, ariaInvalid, ariaRowIndexText
56 export interface ICustomElement extends HTMLElement {
~~~~~~~~~~~~~~
ELIFECYCLE Command failed with exit code 3.
If I rollback to [email protected]
, this error disappears.
Software | Version(s) |
---|---|
Node | 16.18.0 |
PNPM | 7.16.0 |
Operating System | Windows 10 Pro 21H2 |
Hi @calebdwilliams. Thanx for this polyfill.
I am a programmer but not quite a JS expert and probably missing the obvious. So please be gentle :)
I have a form with a regular <input>
field and an <input>
wrapped in a minimalistic web component. Both fields get an initial value
, that show up nicely on the form. When modifying the initial values and submitting the form, the new values show up in my POST data as expected. However, if I don't modify the initial values, the initial value of the regular <input>
is present in the POST data but the initial value of the web component's <input>
is not. Why is that and is there a way to have unmodified web component data posted as well?
Please consider https://codepen.io/bennyp/pen/KKemLEG?editors=1010
<form id="form">
<fieldset id="set" disabled>
<legend>This fieldset controls <code>x-checkbox</code></legend>
<label for="xcheck">Check?</label>
<x-checkbox id="xcheck" name="checkit"></x-checkbox>
</fieldset>
</form>
In this case, using GNOME Web 43.0-66-g2cd7f8ec4+ (WebKitGTK 2.38.2), with the polyfill loaded, I observed that toggling disabled
on the fieldset had no effect on x-checkbox
.
Expected: :disabled
or known-limitations equivalent should be applied to the FACE, mouse clicks should be prevented.
createHiddenInput
tests if the element has a property updateComplete
, and if that exists it will insert the hidden input when that promise resolves:
const createHiddenInput = (ref, internals) => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = ref.getAttribute('name');
if (ref.updateComplete) {
ref.updateComplete.then(() => ref.after(input));
}
else {
ref.after(input);
}
hiddenInputMap.get(internals).push(input);
return input;
};
Looks like that was written with LitElement in mind - which has that updateComplete
property.
But it introduces two new issues when setFormValue()
is called in firstUpdated()
or updated()
:
setFormValue()
will result in multiple hidden inputs added,updateComplete
promise resolves.I wonder why the if( ref.updateComplete )
case was added, is it really required?
I'd suggest to remove that case, and always add the input immediately. That would resolve both issues.
The behavior of setValidity
in the ElementInternals polyfill does not match the behavior described in the ElementInternals
spec.
It calls reportValidity
, but it should not.
I have an error with element with id like "ex.ample[0]" because of chars ".", "[", "]"...
The error throw on element-internals.ts > get labels(): LabelsList
line:
return hostRoot.querySelectorAll<HTMLLabelElement>(
[for=${id}]) as unknown as LabelsList;
This error is fixed using "" in selector like that:
return hostRoot.querySelectorAll<HTMLLabelElement>(
[for="${id}"]) as unknown as LabelsList;
I think the fix coulb be correct but I'm not sure if it's correct to accept all types of selector.
error:
SyntaxError: '[for=CAB.LINE_list]' is not a valid selector
66972 | const hostRoot = ref.getRootNode();
66973 | if (hostRoot && id2) {
> 66974 | return hostRoot.querySelectorAll(`[for=${id2}]`);
| ^
66975 | }
66976 | return [];
66977 | }
at emit (node_modules/nwsapi/src/nwsapi.js:565:17)
at Object._querySelectorAll [as select] (node_modules/nwsapi/src/nwsapi.js:1513:9)
at DocumentImpl.querySelectorAll (node_modules/jsdom/lib/jsdom/living/nodes/ParentNode-impl.js:78:26)
at Document.querySelectorAll (node_modules/jsdom/lib/jsdom/living/generated/Document.js:992:58)
at ElementInternals.labels (dist/web-components.js:66974:27)
at upgradeInternals (dist/web-components.js:66697:17)
at new ElementInternals (dist/web-components.js:66934:9)
at HTMLElement.attachInternals (dist/web-components.js:67122:16)
As a workaround I added form._elements = initSet
in order to get the elements from the internal set. Better than nothing.
Expected Behavior:
When defining a checkbox in a form, checking the checkbox will set a form key value pair. When the checkbox is deselected, the [key,value] pair is remove.
Current Behavior:
When deselecting a checkbox, the key is still available with a value of "undefined".
If you have multiple form elements with the same name, the values are not appended to the form.
Example:
<form>
<input checked type="checkbox" name="name"/>
<input checked type="checkbox" name="name" value="greg" />
</form>
Expected:
In the example above, I will see two entries in the formData object resulting in name=['on','greg']
Current behavior:
I will only receive the last elements value name='greg'
.
I'm not really sure the best way to achieve this bit of parity with the native behavior. I've thought about creating a custom element to do this, but that feels kind of gross. I could just use a throwaway DOM node which seems better maybe? Help and ideas definitely welcomed.
Hi Caleb, Thanks for the wonderful Polyfill
I'm working on a UI web component library and have a test suite that runs tests in Chromium, WebKit, and Firefox.
For the most part, the element-internal-polyfill works great, but I'm having trouble using it with disabled elements.
In short, when an form-associated custom element has a disabled
attribute, Chrome automatically applies the :disabled
psedo-class, but this doesn't happen to the elements that get element internals behaviour from the polyfill.
I tried creating a sandbox, but couldn't get it working so I made a repro-repo instead.
If you clone it, install dependencies and run npm test
, you should be able to see what I mean.
I can give you more details if you want, but I'd also love to contribute a fix for this!
Ctrl + F ":disabled" in google's form participation docs should also give more context about the expected disabled behaviour:
EDIT:
The last section of the docs says:
It is currently impossible to set form states to :invalid and :valid so this polyfill replaces those with the [internals-invalid] and [internals-valid] attributes on the host element. The proper selector for invalid elements will be :host(:invalid), :host([internals-invalid]).
I imagine the same goes for disabled too?
The issue is that these listeners are registered before the polyfill has time to register its own listener to stop the propagation of the submit event.
Here I include 3 reproductions:
So, in the in this line the invalid event that is supposed to be emitted has an "false"
name, instead of the probably intended valid
or invalid
, so this polyfill is not triggering the invalid
event correctly.
This is an issue only affecting Firefox Developer Edition and experimental/nightly versions so I don't know if I'd call it a bug, but it tripped me up so I thought it might be useful to others to mention it here.
Specifically, after doing this._internals = this.attachInternals()
I found that this._internals.setFormValue()
was throwing the error Uncaught TypeError: this._internals.setFormValue is not a function
. The value of this._internals
was an EventInternals object, as expected, but it didn't have a setFormValue
method. It had but a single property, shadowRoot
.
What's happened is that ElementInternals is partially (but mostly not) implemented in Firefox, so window.ElementInternals
exists and element-internals-polyfill's check for its absence fails and the polyfill doesn't polyfill. This incomplete implementation lives behind a configuration flag called dom.webcomponents.elementInternals.enabled
, which is set to false
in standard Firefox releases but, as of 93.0, set to true
in Firefox Developer Edition and (I think) experimental/nightly releases.
Firefox bug 1552313 is related to this, but I'm not sure it's the relevant bug.
The fix—i.e. to make window.ElementInternals
undefined
again so the polyfill does its work—is to go to about:config
and search for dom.webcomponents.elementInternals.enabled
and toggle it to false
.
initRef()
calls useless console.log(input)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.