polyfills
polyfills copied to clipboard
[Custom Elements] Incorrect `observedAttributes` behavior when using mixed-case attributes
Description
Another issue that is somewhat related, and may be relevant to also see for context: https://github.com/webcomponents/polyfills/issues/111
With native Custom Elements, the attributes declared in the static observedAttributes getter must be lower-case in order for the attributeChangedCallback to be triggered when they change. This is how the implementation in Chrome, Firefox, and Safari works.
In the following example, the attributeChangedCallback will never be called in browsers that natively support Custom Elements:
class A extends HTMLElement {
static get observedAttributes () {
return ["fooBarBaz"];
}
attributeChangedCallback (name, oldValue, newValue) {
console.log("changed!:", {
name, oldValue, newValue
});
}
}
customElements.define("a-el", A);
const a = new A();
// Won't trigger attributeChangedCallback
console.log("setting attribute with name: 'foobarbaz'");
a.setAttribute("foobarbaz", "");
// Wait a bit since MutationObserver operates on the microtask queue
setTimeout(() => {
// *Will* trigger attributeChangedCallback but **only when using the Custom Elements polyfill**
console.log("setting attribute with name: 'fooBarBaz'");
a.setAttribute("fooBarBaz", "");
}, 1000);
However, using the Custom Elements polyfill, the attributeChangedCallback will be called when there is a direct case-sensitive match between the observed attribute name and the attribute named passed on to setAttribute. In the example above, the second call (a.setAttribute("fooBarBaz", "")) will trigger the attributeChangedCallback.
While - according to the HTML spec - attribute names can mix lower- with uppercase letters that are an ASCII case-insensitive match for the attribute's name, the actual behavior of observedAttributes does require, at least as evidenced by its implementation in Chromium/WebKit/Firefox, that these names are all lowercased when returned from that getter.
For lit-html/LitElement users and users of other tools and libraries that leverages Custom Elements, this can cause problems when binding to attributes or boolean attributes with mixed-case property names as is very common to do (camelCased property names that reflect to/from attributes) when leveraging the Custom Elements polyfill.
Example
Here's a repro. Open the page, and check out the console. What is printed there depends on whether or not the polyfill is being used.
https://ce-bug-demo.surge.sh/
Steps to reproduce
A repro example is provided in the code example above
Expected behavior
The behavior of observedAttributes aligns with native behavior.
Actual behavior
The behavior of observedAttributes does not align with native behavior.
Version
@webcomponents/[email protected]
Browsers affected
- [x] Chrome
- [x] Firefox
- [x] Edge
- [x] Safari
- [x] IE 11
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue is very much still relevant, and it should not be marked as stale.
Agreed, I just had this absurd behavior effect me as well.
this affected me well - is this getting prioritized?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Affecting me too. It doesn't seem to be documented anywhere, but observedAttributes only works for attributes which are specified in lower case.