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

metal-web-component #261

Merged
merged 28 commits into from
Oct 11, 2017
Merged

metal-web-component #261

merged 28 commits into from
Oct 11, 2017

Conversation

robframpton
Copy link

No description provided.

@robframpton
Copy link
Author

robframpton commented Sep 28, 2017

Hey @jbalsas

I addressed the issue that was causing metal to be incompatible with the webcomponents polyfill, and now the tests are passing on all browsers that the polyfill supports.

However the tests are still failing on IE9/10. I tried conditionally loading the polyfill, but the issue persists. Any thoughts on how we can get around this?

It will also now work with JSX components, I've added tests to cover that use case.

@jbalsas
Copy link
Contributor

jbalsas commented Sep 28, 2017

Hey @Robert-Frampton! Nice seeing this almost there!!

What about having two different karma.config files, one for those needing the polyfill and one for those that don't support it and triggering two different tests? 🤷‍♂️

@robframpton robframpton force-pushed the webcomponents branch 7 times, most recently from 9fad590 to 61f7d23 Compare September 28, 2017 19:34
@robframpton
Copy link
Author

@jbalsas the tests are passing now.

Originally we were extending HTMLElement with a class and using a babel-plugin-transform-custom-element-classes to get it to work, since extending that native class normally throws errors in certain browsers.

It turns out that the babel plugin was causing issues (the cause of the browserify error we were seeing). I removed the plugin, and just wrote the extension of HTMLElement without es2015 classes. The benefit is that we no longer have to have any special plugins to build it, so other devs could build this component from source if they wanted to without having to change their build tooling, and now it's more robust and doesn't break legacy browsers.

@jbalsas
Copy link
Contributor

jbalsas commented Sep 28, 2017

Awesome, @Robert-Frampton, great job!!

As part of closing this up... could we prepare a new tutorial in metaljs.com showing how to use this? We could maybe create a new branch where we push tutorials until we're ready to release a version with the updates.

What do you think?

@robframpton
Copy link
Author

robframpton commented Sep 28, 2017

Hey @jbalsas,

Sounds good. Were you thinking of these kinds of tutorials? Or something more generic?

@robframpton
Copy link
Author

I put together a quick guide on this branch. We could do something simple like this at first and provide a link to it in the metal-custom-element readme file, then later we can refactor some of these sections into actual tutorials like they have on wedeploy.

On another note, the naming is currently inconsistent in this package. The package name is metal-custom-element, but the method it exposes is called defineWebComponent. I'd like it to be consistent. Which one of these do you like more?

  1. metal-custom-element / defineCustomElement
  2. metal-web-component / defineWebComponent

@jbalsas
Copy link
Contributor

jbalsas commented Sep 29, 2017

Hey @Robert-Frampton, makes sense!

So, from "Web Components", we use the CustomElement and ShadowDOM (kinda) specs. We are not currently using neither Templates nor of course HTML imports.

I think I'd still rather go with the general metal-web-component / defineWebComponent approach, which would probably help us market it better... what do you think? Can you do the change here so we can merge it at once? 👼

The guide looks great, I think that is as much as we need right now 👍

@robframpton
Copy link
Author

Hey @jbalsas, I agree. I think metal-web-component will make more sense to people (even if it's maybe less "accurate").

I'll make the changes now 👍

@robframpton
Copy link
Author

@robframpton
Copy link
Author

Hey @jbalsas, updated the package name and sent the PR for the guide on metaljs.com.

@robframpton
Copy link
Author

Hey @jbalsas, I think this is ready to merge whenever. Let me know if you see anything you think we should change.

@jbalsas jbalsas mentioned this pull request Oct 3, 2017
3 tasks
@robframpton robframpton changed the title Try loading polyfill from test metal-web-component Oct 9, 2017
@@ -168,7 +168,7 @@ export function append(parent, child) {
if (isString(child)) {
child = buildFragment(child);
}
if (child instanceof NodeList) {
if (isArrayLike(child)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on this change in implementation we have now a different behaviour:

const child = ['a', 'b', 'c'];

dom.append(parent, child); // NOOP before -> 'abc' child after

Do we want to support this case? If so, we should probably add a test so it is clear. We might also simply do some duck-type-checking for NodeList... from the ones I've seen maybe one of these could be good enough:

const el = ??;

const isNodeList = (typeof el.length != 'undefined' && typeof el.item != 'undefined');
const isNodeList = (typeof el.length == 'number' && typeof el.item == 'function' && typeof el.nextNode == 'function' && typeof el.reset == 'function');

"name": "metal-web-component",
"version": "1.0.0",
"description": "Web component (CustomElement) registration for Metal.js components.",
"license": "BSD-3-Clause",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a bit of a mix between BSD, BSD-3-Clause and MIT in this repo... might be good to have legal take a look :)

script.src = '/base/packages/metal-web-component/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js';
script.type = 'text/javascript';

document.body.appendChild(script);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do something similar for the babel-polyfill, to make sure we don't load it when not necessary? I know it will probably noop in those cases, but it might have unintended side effects?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried conditionally loading this one as well, but it's harder to check if it's necessary than the webcomponents polyfill.

If you think it's necessary we can just explicitly check the user agent for every browser that needs it, but it won't be pretty.

* @param {?} val Variable to test.
* @return {boolean} Whether variable is an array/iterable.
*/
export function isArrayLike(val) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above... might be better to just check for isNodeListLike?

let el;

before(function() {
if (UA.matchUserAgent('MSIE') || isSafariVersion('8.0')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we don't have something in UA to match version and user agent? :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, it would be nice to have something in UA that simply returns the major version number of the browser, regardless of what browser it is. We have a method in Portal that does something like that.

});
});

describe('Define JSX component', function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this suite have different set of test cases than the Soy one? If they are the same, then maybe we should simply put them outside the soy one, or duplicate them in the jsx as well? Is there a chance one might work and not the other?

Object.setPrototypeOf(CustomElement, HTMLElement);

Object.assign(CustomElement.prototype, {
attributeChangedCallback: function(attrName, oldVal, newVal) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we document what goes on in each callback, just for reference?

@robframpton robframpton changed the base branch from master to develop October 10, 2017 16:23
@jbalsas
Copy link
Contributor

jbalsas commented Oct 11, 2017

Hey @Robert-Frampton, LGTM!

I'm going to go ahead and merge to develop. My only doubt is what is the default browserlist value from the env preset. We need to support all latest releases (that includes IE11). Could you double check, just to be sure?

@jbalsas jbalsas added this to the 2.14.0 milestone Oct 11, 2017
@jbalsas jbalsas merged commit 83a264c into metal:develop Oct 11, 2017
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

Successfully merging this pull request may close these issues.

2 participants