Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup doesn't work with dom-module #2

Open
ebidel opened this issue Aug 13, 2015 · 7 comments
Open

Setup doesn't work with dom-module #2

ebidel opened this issue Aug 13, 2015 · 7 comments

Comments

@ebidel
Copy link

ebidel commented Aug 13, 2015

Hey @JanMiksovsky, I couldn't get this setup to actually work with Polymer's registration system. Namely, it doesn't respect the dom-module for the element or create shady dom.

<dom-module id="my-element">
  <template>
    <span>my element</span>
  </template>
</dom-module>

class PolymerElement extends Polymer.Class({}) {
  get is() { return 'my-element'; }
}

class MyElement extends PolymerElement {
  created() {
    this.textContent = "Hello, " + this.textContent + "!";
  }
}

document.registerElement('my-element', MyElement);

<my-element>eric</my-element>
@JanMiksovsky
Copy link
Owner

I'd just done this as a quick experiment, mostly see if Polymer would play at all nice with ES6. At the time, Polymer 0.8 was still in the works, so I didn't try to get this to work with and Shady DOM.

As originally written, this experiment used document.registerElement() on its own, but Polymer appears does a bunch of its own registration work. That registration needs to be performed per-class. As originally written, only a single anonymous class, Polymer.Class({}), was getting registered.

Partial progress: I can't claim to really understand the complexities of Polymer's internals. That said, I've just checked in a fix (read: total hack) that manually invokes a function called registerCallback(). This in turn invokes _registerFeatures(), which looks like it forces some preparation of the element template as desired. I've updated the demo so that the sample element's template is now provided via a <dom-module>. That's cool.

This doesn't use Shadow DOM (or Shady DOM), however. More hackery might be able to get that to work, but for today this as far as I can push it. If you're interested in this, let me know. I think even hacky ES6 support for Polymer is kind of cool, but going further will probably involve some advice from the Polymer folks.

@JanMiksovsky
Copy link
Owner

Shoot... the dom-module fix works in Polymer 0.8, but when I upgrade the bower.json to use Polymer 1.0, there's a regression. Sigh.

@ebidel
Copy link
Author

ebidel commented Aug 13, 2015

Thanks @JanMiksovsky. I've been playing around with classes a bit. I've come up with 3 different ways: http://jsbin.com/zifituqaxu/edit?html,output. Yours works for me as well in 1.0.

It would be nice if we could get rid of the registration call in each of those. I'll poke around a bit more and inquire with the core team. Thanks for your help!

@JanMiksovsky
Copy link
Owner

Glad it works for you. I had an issue with Polymer 1.x (Polymer 1.0.9), but just checked in a fix. Things now mostly work as I expect.

One issue I'm concerned about is class identity. In two of the approaches you show (yours and Scott's), the top-level class doesn't look like it's going to be end up as the actual class of the resulting elements. That is, I suspect that the following:

let elt = document.createElement('my-element');
console.log(elt instanceof MyElement);

will be false for approaches that pass MyElement.prototype to the Polymer function. The approach I've been pursuing should ensure that instanceof tests pass as expected.

In any event, I'm interested in see where ES6 class support goes. Please keep me looped in.

@olegomon
Copy link

Hi, thanks for this examples. What I came up with is this. I used Babel with es7.decorators enabled.

/**
 * Component annotation to extend from Polymer base class
 *
 * @decorator
 * @param {string} name - WebComponent name
 * @returns {Function} decorator
 */
function Component(name) {
    if(!name) {
        throw new TypeError('Component name is required');
    }
    if(typeof name !== 'string') {
        throw new TypeError('Component name must be a string');
    }
    if(name.indexOf('-') === -1) {
        throw new TypeError('Component name must have at least one dash "-" character')
    }
    return function decorator(target) {
        Object.defineProperty(target.prototype, 'is', {
            value: name,
            writable: false,
            enumerable: true,
            configurable: false
        });
        Polymer(target.prototype);
    };
}

@Component('my-component')
class MyComponent {
    get properties() {
        return {
            title: String
        }
    }
}

It is basically @ebidel 's way of extending the actual Polymer class with Polymer(MyElement.prototype). Using Es7 decorators I don't have to think about registering the component manually. When I declare my component template I include the following script using System.JS to load the component:

<dom-module id="my-component">
    <template>
        <span>{{title}}</span>
    </template>
   <script>System.import('components/MyComponent');</script>
</dom-module>

What are your thoughts on this approach?

@safizn
Copy link

safizn commented Aug 17, 2016

I think using the Polymer function to register the element is safer. But using 'extends' makes it cleaner. Any new recommendations ?

@JanMiksovsky
Copy link
Owner

@myuseringithub No, sorry. Using Polymer 1.0 with ES6 is still a pretty experimental thing. That said, in the past year the browsers have made huge strides towards full ES6 compatibility, so I think it's reasonable to expect the Polymer team to directly address this as a framework feature in a future release. Their next venue is the Polymer Summit this coming October — I'd look for them to share plans at that point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants