Custom elements - ES5 constructor support? #1704
Comments
You use |
I don't believe that addresses the problem. |
<!DOCTYPE html>
<html>
<script>
function MyCustomElement() {
return Reflect.construct(HTMLElement, [], MyCustomElement);
}
MyCustomElement.prototype.attributeChangedCallback = function (name, oldValue, newValue) {
alert(newValue);
}
MyCustomElement.observedAttributes = ['class'];
MyCustomElement.prototype.__proto__ = HTMLElement.prototype;
MyCustomElement.__proto__ = HTMLElement;
customElements.define('my-custom-element', MyCustomElement);
</script>
<my-custom-element class="hi">world</my-custom-element>
</html> |
If you have Google Chrome Canary, you can try it on |
I had been trying in Canary, but not using I'm on a Chromebook while traveling, so can't easily test flagged features at the moment, but will check on my Windows box when I get home. Thanks! |
I still need to test this in Canary, but in Chrome beta it's not possible to use HTMLElement as the target for |
Hello @rniwa ! MyCustomElement.prototype = Object.create(HTMLElement.prototype);
MyCustomElement.prototype.constructor = MyCustomElement; instead of MyCustomElement.prototype.__proto__ = HTMLElement.prototype;
MyCustomElement.__proto__ = HTMLElement; ? And, what about if use function MyCustomElement() {
HTMLElement.call(this); // this is just an idea for super();
} |
HTMLElement cannot be called directly as a constructor in most browsers, it throws an error. Canary will not accept that in a custom element definition. |
@thomaswilburn thanks for the quote )) I didn't know about this restriction. The next question as consumer of this spec... should I care about the super? When I write class MyCustomElement extends HTMLElement {
constructor() {
super(); // can I omit this? Can browser call it somewhere else?
}
} My motivation is that I describe a CustomElement that in fact is an Please, this is just an idea... I'm newbie in JS )) |
While those aren't bad questions, it may make sense to ask them in a separate bug, as opposed to this one, which is trying to find out how to backfill the spec successfully in both legacy browsers and those that actually implement the V1 spec. |
Please go read https://esdiscuss.org/topic/extending-an-es6-class-using-es5-syntax, and ask related JS questions on http://stackoverflow.com. This is an issue tracker for the HTML specification, not a support forum for every new feature in HTML / JS.
You can call
You could do: class MyCustomElement {
constructor() {
return Reflect.construct(HTMLElement, [], MyCustomElement);
}
}
customElements.define('my-custom-element', MyCustomElement); Although this has a weird behavior that the constructed custom element would not have |
Closing, since as @rniwa noted this is not a support forum, and there is no spec bug being reported here. Everyone should remember that every browser that implements custom elements also implements ES6 class syntax, with super(). The features are designed to work together and there is no desire to make things work with ES5 syntax or with older browsers, since the specification is made for newer browsers. |
I realize that your response is probably shorthand for a lot of the long-standing debate that happened while this spec was being hashed out, but that's... an unfortunate stance to take for those of us who would like to take advantage of this soon-ish, instead of several years from now. |
@rniwa Thanks a lot for your meticulous answer. My intention wasn't to turn this issue into a forum-story. I just was curios why you mentioned And, if talk about the possibilities, I understood clearly
|
@thomaswilburn: You can use ES5 polyfil in older browsers as long as you call @rianby64: I don't have any intention to judge anyone's knowledge here. I'm just saying that we can't answer every question you may have about custom elements or related technology beyond the scope of discussing the specification itself as we all have limited resources and time. |
@rniwa Both of the polyfills that I'm aware of are in fact having to monkey-patch the HTMLElement constructor (and its subclasses), because you can't call var XCustomElement = function() {
try {
var self = Reflect.construct(HTMLElement, [], XCustomElement);
return self;
} catch (_) {
HTMLElement.call(this); // the polyfill will have monkeypatched the constructor
}
} It looks like this will be doable with the monkey-patch in place, but that's an ugly solution at best (welcome to the web, I guess). It seems ironic to me that I've found bugs commenting on this spec having too much "tutorial" content--as someone who's trying to get it to work in a real-world environment, I would argue that there's not enough. |
That's why I had the qualifier new browsers that implements It can be shown that one can write a framework that lets users of the said framework write code as such: function MyCustomElement() {}
defineCustomElement('my-custom-element', MyCustomElement); e.g. function defineCustomElement(localName, elementInterface) {
elementInterface.prototype.__proto__ = HTMLElement.prototype;
elementInterface.__proto___ HTMLElement.prototype;
if (window.customElements) {
window.customElements(localName, function () {
var newElement = Reflect.construct(HTMLElement, [], elementInterface);
var returendElement = elementInterface.call(newElement);
return returnedElement !== undefined ? returnedElement : newElement;
});
} else {
// Polyfil code
}
} I'm going to unsubscribe from this thread because I feel like I'm just telling how to write a framework / polyfll, and that's not really my job. |
https://html.spec.whatwg.org/multipage/scripting.html#custom-element-conformance
How does this work for ES5 constructors, which can't call
super()
(but can have the prototype chain andthis
set up)?Using the flagged version of V1 that's in Chrome as of a couple of weeks ago, it didn't seem possible to create an ES5 constructor that would pass
customElements.define()
without throwing an InvalidStateError. That's a huge problem for people who want to polyfill this in older browsers that don't support theclass
syntax, and seems weird given that ES6 classes are just sugar over the older constructor functions.Without a good story on this, my team is going to end up sticking with the document.registerElement() polyfill for a long time, until IE 11 drops off our support matrix. I don't particularly want to, but if it'll work with transpiled code and
customElements.define()
won't, I don't see that we have a choice.The text was updated successfully, but these errors were encountered: