custom-elements-es5-adapter.js

This commit is contained in:
valdrinkoshi
2017-03-21 14:02:56 -07:00
parent 3b3bd26f28
commit f8b627e722
10 changed files with 136 additions and 116 deletions

View File

@@ -60,15 +60,22 @@ elements, etc.). Here's an example:
</script>
```
## `webcomponents-es5-loader.js`
## `custom-elements-es5-adapter.js`
According to the spec, Custom Elements must be ES6 classes (https://html.spec.whatwg.org/multipage/scripting.html#custom-element-conformance). Since most projects need to support a wide range of browsers that don't necessary support ES6, it may make sense to compile your project to ES5. However, ES5-style custom element classes will **not** work with native Custom Elements because ES5-style classes cannot properly extend ES6 classes, like `HTMLElement`.
To work around this, `webcomponents-es5-loader.js` first loads an extra ES5 compatibility [shim](https://github.com/webcomponents/custom-elements/blob/master/src/native-shim.js) before
loading the minimum polyfill bundle, like `webcomponents-loader.js` does.
To work around this, load `custom-elements-es5-adapter.js` before declaring new Custom Elements. **The adapter must NOT be compiled.**
The reason for having two different loaders (`webcomponents-loader.js` for ES6 deployed code and `webcomponents-es5-loader.js` for ES5) is that the polyfill can't know if you're deploying ES5 or ES6 code -- it runs before your code, and only _you_ as an author of the code know what you're going to deploy. This means that _you_ have to make the decision about which loader to use.
**TL; DR: ** Use `webcomponents-es5-loader.js` only if you want to deploy ES5 code to _all_ browsers (both with and without native custom elements support) -- if this isn't a requirement, then use
`webcomponents-loader.js` instead.
```html
<!-- Load Custom Elements es5 adapter -->
<script src="bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<!-- Load polyfills; note that "loader" will load these async -->
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
<!-- Load the es5 compiled custom element definition -->
<link rel="import" href="my-es5-element.html">
<!-- Use the custom element -->
<my-es5-element></my-es5-element>
```
## Browser Support

View File

@@ -3,8 +3,6 @@
(()=>{'use strict';if(!window.customElements)return;const a=window.HTMLElement,b=window.customElements.define,c=window.customElements.get,d=new Map,e=new Map;let f=!1,g=!1;window.HTMLElement=function(){if(!f){const h=d.get(this.constructor),i=c.call(window.customElements,h);g=!0;const j=new i;return j}f=!1;},window.HTMLElement.prototype=a.prototype,window.customElements.define=(h,i)=>{const j=i.prototype,k=class extends a{constructor(){super(),Object.setPrototypeOf(this,j),g||(f=!0,i.call(this)),g=!1;}},l=k.prototype;k.observedAttributes=i.observedAttributes,l.connectedCallback=j.connectedCallback,l.disconnectedCallback=j.disconnectedCallback,l.attributeChangedCallback=j.attributeChangedCallback,l.adoptedCallback=j.adoptedCallback,d.set(i,h),e.set(h,i),b.call(window.customElements,h,k);},window.customElements.get=(h)=>e.get(h);})();
(function(){'use strict';var a=document.createElement('style');a.textContent='body {transition: opacity ease-in 0.2s; } \\nbody[unresolved] {opacity: 0; display: block; overflow: hidden; position: relative; } \\n';var b=document.querySelector('head');b.insertBefore(a,b.firstChild);})();
/**
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
@@ -13,6 +11,6 @@ The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/requestAnimationFrame(()=>{window.dispatchEvent(new CustomEvent('WebComponentsReady'));});
*/
}());

View File

@@ -11,13 +11,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
/*
* Polyfills loaded: Custom Elements ES5 Shim
* Used in: Chrome
*/
import '../bower_components/custom-elements/src/native-shim.js'
import '../src/unresolved.js'
requestAnimationFrame(() => {
window.dispatchEvent(new CustomEvent('WebComponentsReady'));
});

View File

@@ -1,21 +0,0 @@
/**
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
'use strict';
/*
* Polyfills loaded: HTML Imports + Custom Elements ES5 shim
* Used in: Safari Tech Preview, Chrome
*/
import '../bower_components/custom-elements/src/native-shim.js'
import '../bower_components/html-imports/src/html-imports.js'
import '../src/post-polyfill.js'
import '../src/unresolved.js'

View File

@@ -162,14 +162,10 @@ const babelOptions = {
shouldPrintComment: singleLicenseComment()
};
gulp.task('debugify-ce-es5', () => {
return debugify('webcomponents-ce-es5', '', {plugins: [babel(babelOptions)]});
gulp.task('debugify-ce-es5-adapter', () => {
return debugify('custom-elements-es5-adapter', '', {plugins: [babel(babelOptions)]});
});
gulp.task('debugify-hi-ce-es5', () => {
return debugify('webcomponents-hi-ce-es5', '', {plugins: [babel(babelOptions)]});
})
gulp.task('refresh-bower', () => {
return del('bower_components').then(() => {
let resolve, reject;
@@ -184,7 +180,7 @@ gulp.task('default', (cb) => {
});
gulp.task('clean-builds', () => {
return del(['webcomponents*.js{,.map}', '!webcomponents-{es5-,}loader.js']);
return del(['custom-elements-es5-adapter.js{,.map}', 'webcomponents*.js{,.map}', '!webcomponents-loader.js']);
});
gulp.task('debug', (cb) => {
@@ -194,8 +190,7 @@ gulp.task('debug', (cb) => {
'debugify-hi-sd-ce',
'debugify-hi-sd-ce-pf',
'debugify-sd-ce',
'debugify-ce-es5',
'debugify-hi-ce-es5'
'debugify-ce-es5-adapter'
];
runseq('clean-builds', tasks, cb);
});
@@ -207,8 +202,7 @@ gulp.task('closure', (cb) => {
'closurify-hi-sd-ce',
'closurify-hi-sd-ce-pf',
'closurify-sd-ce',
'debugify-ce-es5',
'debugify-hi-ce-es5'
'debugify-ce-es5-adapter'
];
runseq('clean-builds', ...tasks, cb);
});

View File

@@ -0,0 +1,54 @@
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<script>
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
// Kick off shady CSS.
var template = document.createElement('template');
template.innerHTML =
`
<style>:host {color: blue;} .red-text {color: red;} </style>
<p class="red-text">Shadow DOM</p>
<slot id="slot"></slot>
`;
if (template) {
if (window.ShadyCSS) {
window.ShadyCSS.prepareTemplate(template, 'simple-element');
}
}
var SimpleElement = function (_HTMLElement) {
_inherits(SimpleElement, _HTMLElement);
function SimpleElement() {
_classCallCheck(this, SimpleElement);
var _this = _possibleConstructorReturn(this, (SimpleElement.__proto__ || Object.getPrototypeOf(SimpleElement)).call(this));
_this.bestName = 'batman';
if (window.ShadyCSS) {
window.ShadyCSS.styleElement(_this);
}
if (template && !_this.shadowRoot) {
_this.attachShadow({ mode: 'open' });
_this.shadowRoot.appendChild(document.importNode(template.content, true));
}
return _this;
}
return SimpleElement;
}(HTMLElement);
window.customElements.define('simple-element', SimpleElement);
</script>

View File

@@ -0,0 +1,62 @@
<!doctype html>
<!--
@license
Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
<title>Integration Test</title>
<script src="../custom-elements-es5-adapter.js"></script>
<script src="../webcomponents-loader.js"></script>
<script src="../../web-component-tester/browser.js"></script>
<link rel="import" href="imports/simple-element-es5.html">
</head>
<body>
<!-- Don't break this into multiple lines or you'll have to count text nodes -->
<simple-element id="basic"><span>Light DOM</span></simple-element>
<script>
suite('integration es5', function() {
var el;
setup(function() {
el = document.querySelector('#basic');
});
test('element is imported & upgraded', function() {
assert.equal(el.bestName, 'batman',
'doesn\'t have property set in constructor');
});
test('element has shadow DOM content', function() {
var shadowRoot = el.shadowRoot;
assert.ok(shadowRoot, 'does not have a shadow root');
assert.equal(shadowRoot.querySelector('p').textContent, 'Shadow DOM',
'does not have <p> in the shadow dom');
assert.equal(getComputedStyle(shadowRoot.querySelector('p')).color, 'rgb(255, 0, 0)',
'does not style <p> in the shadow dom');
});
test('element has distributed content', function() {
var slot = el.shadowRoot.querySelector('slot');
assert.ok(slot, 'does not have a slot');
var distributedNodes = slot.assignedNodes()
assert.equal(distributedNodes.length, 1,
'does not have exactly one element distributed');
assert.equal(distributedNodes[0].textContent, 'Light DOM',
'does not have the right content distributed');
assert.equal(getComputedStyle(distributedNodes[0]).color, 'rgb(0, 0, 255)',
'does not style light dom');
});
});
</script>
</body>
</html>

View File

@@ -19,6 +19,7 @@
'template-and-CE.html',
// 'template-and-imports.html',
'integration.html',
'integration-es5.html',
'load.html',
'dev-loader.html',
'dev-loader-swizzled.html',

View File

@@ -1,52 +0,0 @@
/**
* @license
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function() {
'use strict';
var name = 'webcomponents-es5-loader.js';
// Feature detect which polyfill needs to be imported.
var polyfills = [];
if (!('import' in document.createElement('link'))) {
polyfills.push('hi');
}
if (!('attachShadow' in Element.prototype && 'getRootNode' in Element.prototype) ||
(window.ShadyDOM && window.ShadyDOM.force)) {
polyfills.push('sd');
}
if (!window.customElements || window.customElements.forcePolyfill) {
polyfills.push('ce');
} else {
polyfills.push('ce-es5');
}
if (!('content' in document.createElement('template')) || !window.Promise ||
// Edge has broken fragment cloning which means you cannot clone template.content
!(document.createDocumentFragment().cloneNode() instanceof DocumentFragment)) {
polyfills.push('pf');
}
if (polyfills.length === 4) { // hi-ce-sd-pf is actually called lite.
polyfills = ['lite'];
}
if (polyfills.length) {
var script = document.querySelector('script[src*="' + name + '"]');
var newScript = document.createElement('script');
// Load it from the right place.
var replacement = 'webcomponents-' + polyfills.join('-') + '.js';
var url = script.src.replace(name, replacement);
newScript.src = url;
document.head.appendChild(newScript);
} else {
// Ensure `WebComponentsReady` is fired also when there are no polyfills loaded.
requestAnimationFrame(function() {
window.dispatchEvent(new CustomEvent('WebComponentsReady'));
});
}
})();

File diff suppressed because one or more lines are too long