Hi!
I'm trying to create custom elements in various ways.
I can compile an element using classic or goog.defineClass.
Using Reflect.construct is required (probably can be done with calling new/inherits):
goog.provide('com.example.legacy.CustomElement'); /* @extends {HTMLElement} */ com.example.legacy.CustomElement = goog.defineClass(HTMLElement, { constructor: function(instanceProperty){ var instance = Reflect.construct(HTMLElement, [], com.example.legacy.CustomElement); instance.instanceProperty = instanceProperty; return instance; }, connectedCallback: function(){ console.log('connected'); if(!this.instanceProperty){ // load properties from attributes this.instanceProperty = this.getAttribute("instanceProperty"); } var span = document.createElement("span"); span.innerHTML = this.instanceProperty; this.appendChild(span); } });
The ES6 version fails:
/** @customElement */ class Test extends HTMLElement { constructor(){ super() } connectedCallback(){ alert('!') } } window.customElements && window.customElements.define('testy-test', Test)
Getting compiled into:
var module$customcomponent_es6 = {}; module$customcomponent_es6.CustomComponent = CustomComponent$$module$customcomponent_es6; var Test$$module$test_es6 = function() { return HTMLElement.call(this) || this; }; $jscomp.inherits(Test$$module$test_es6, HTMLElement); Test$$module$test_es6.prototype.connectedCallback = function() { alert("!"); }; window.customElements && window.customElements.define("testy-tester", Test$$module$test_es6);
When the element is constructed (in html or new Test), chrome will raise Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function., at the the line: return HTMLElement.call(this) || this
Taking a look at the compiler, I'm assuming the code Es6ConvertSuperConstructorCalls.createNewSuperCall is responsible for this transformation. See: https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/Es6ConvertSuperConstructorCalls.java#L266
Special casing HTMLElement in Es6ConvertSuperConstructorCalls seems to be one option to get this working.
I also noticed a customElement annotation. Seems to be only docs related. Having to remember an extra annotation might be asking too much, though, it could be used instead of potentially having to traverse the class parents looking for an HTMLElement... Wondering at this point how to get the correct es6 -> es5 transformation for custom elements, and if anyone is working on it.
Thanks!
(NOTE: deleted cross post in clsoure-library-discuss)