├── .gitignore
├── .travis.yml
├── .npmignore
├── test
├── es5
│ ├── wc.html
│ ├── index.html
│ ├── ce.html
│ ├── min.js
│ └── index.js
├── index.html
├── my-button.js
├── nightmare.js
└── table.html
├── LICENSE
├── package.json
├── min.js
├── README.md
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | test/coverage.json
4 | package-lock.json
5 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - stable
4 | git:
5 | depth: 1
6 | branches:
7 | only:
8 | - master
9 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | coverage/*
2 | node_modules/*
3 | test/*
4 | test/index.js
5 | .DS_Store
6 | .gitignore
7 | .travis.yml
8 | package-lock.json
9 |
--------------------------------------------------------------------------------
/test/es5/wc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Elements Built-in Extends + WebComponents
8 |
9 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/test/es5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Elements Built-in Extends - Transpiled
8 |
9 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/test/es5/ce.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Elements Built-in Extends over 3rd parts polyfill
8 |
9 |
10 |
11 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Elements Built-in Extends
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
--------------------------------------------------------------------------------
/test/my-button.js:
--------------------------------------------------------------------------------
1 | customElements.define(
2 | 'my-button',
3 | class MyButton extends HTMLButtonElement {
4 | static get observedAttributes() { return ['color']; }
5 | attributeChangedCallback(name, oldValue, newValue, nsValue) {
6 | this.style.color = newValue;
7 | }
8 | connectedCallback() {
9 | this.addEventListener('click', this);
10 | }
11 | disconnectedCallback() {
12 | this.removeEventListener('click', this);
13 | }
14 | handleEvent(event) {
15 | const next = this.nextElementSibling ||
16 | this.parentNode.appendChild(
17 | document.createElement('div')
18 | );
19 | next.textContent = `${event.type} @ ${new Date}`;
20 | }
21 | },
22 | {'extends': 'button'}
23 | );
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2018, Andrea Giammarchi, @WebReflection
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 | PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/test/nightmare.js:
--------------------------------------------------------------------------------
1 | const Nightmare = require('nightmare');
2 | const nightmare = Nightmare({show: false});
3 |
4 | nightmare
5 | .goto(`http://localhost:8080/`)
6 | .evaluate(() => {
7 | window.assert = (ok, message) =>
8 | console.warn('nightmare', !!ok, message || 'unknown');
9 | })
10 | .on('console', (type, ...args) => {
11 | if (type === 'warn' && args[0] === 'nightmare') {
12 | type = 'assert';
13 | args.shift();
14 | }
15 | switch (type) {
16 | case 'assert':
17 | const [ok, message] = args;
18 | if (!ok) exit(new Error(message));
19 | else console.log(` \x1B[0;32m✔\x1B[0;0m ${message}`);
20 | break;
21 | case 'error':
22 | exit(new Error(args[0]));
23 | default:
24 | console[type](...args);
25 | }
26 | })
27 | .evaluate(() => {
28 | const constructor = customElements.get('my-button');
29 | assert(typeof constructor === 'function', 'MyButton is registered');
30 | const mybtn = document.querySelector('button[is="my-button"]');
31 | assert(mybtn instanceof constructor, 'DOM node was upgraded');
32 | assert(mybtn.style.color === 'blue', 'attribute change applied');
33 | })
34 | .end()
35 | .catch(exit);
36 |
37 | function exit(error) {
38 | console.error(error);
39 | process.exit(1);
40 | }
41 |
--------------------------------------------------------------------------------
/test/table.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Custom Elements Built-in Extends
8 |
9 |
10 |
40 |
41 |
42 |
46 |
47 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "built-in-element",
3 | "version": "0.2.4",
4 | "description": "A polyfill for Custom Element built-in",
5 | "main": "index.js",
6 | "module": "index.js",
7 | "unpkg": "min.js",
8 | "scripts": {
9 | "build": "npm run min && npm run es5 && npm run size && npm run test",
10 | "es5": "cp index.js tmp.js && cat test/my-button.js >> tmp.js && cat tmp.js | babel --no-babelrc --presets=@babel/env > test/es5/index.js && rm tmp.js && npm run min5",
11 | "min": "uglifyjs index.js --comments=/^!/ -c -m -o min.js",
12 | "min5": "uglifyjs test/es5/index.js --comments=/^!/ -c -m -o test/es5/min.js",
13 | "size": "cat index.js | wc -c;cat min.js | wc -c;gzip -c9 min.js | wc -c;cat min.js | brotli | wc -c && rm -f min.js.br",
14 | "test": "npm run server & (sleep 1 && npm run nightmare && npm run kill)",
15 | "nightmare": "node test/nightmare.js || (npm run kill && exit 1)",
16 | "server": "node -e 'require(`fs`).writeFileSync(`pid`,require(`child_process`).spawn(`http-server`,[`test`,`-s`]).pid);'",
17 | "kill": "kill -9 $(cat pid) && rm -f pid"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/WebReflection/built-in-element.git"
22 | },
23 | "keywords": [
24 | "Custom",
25 | "Element",
26 | "built-in",
27 | "polyfill"
28 | ],
29 | "author": "Andrea Giammarchi",
30 | "license": "ISC",
31 | "bugs": {
32 | "url": "https://github.com/WebReflection/built-in-element/issues"
33 | },
34 | "homepage": "https://github.com/WebReflection/built-in-element#readme",
35 | "devDependencies": {
36 | "@babel/cli": "^7.1.2",
37 | "@babel/core": "^7.1.2",
38 | "@babel/preset-env": "^7.1.0",
39 | "http-server": "^0.11.1",
40 | "nightmare": "^3.0.1",
41 | "uglify-es": "^3.3.9"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/min.js:
--------------------------------------------------------------------------------
1 | /*! (c) Andrea Giammarchi - ISC */
2 | !function(e,t){"use strict";if(t.get("li-li"))return;try{class l extends HTMLLIElement{}if(t.define("li-li",l,{extends:"li"}),!/is="li-li"/.test((new l).outerHTML))throw{}}catch(l){const n="attributeChangedCallback",s="connectedCallback",r="disconnectedCallback",{assign:i,create:o,defineProperties:a,setPrototypeOf:u}=Object,{define:c,get:d,upgrade:f,whenDefined:b}=t,g=o(null),h=e=>{for(let t=0,{length:l}=e;t{let t=e.getAttribute("is");return t&&(t=t.toLowerCase())in g?g[t]:null},v=(e,t)=>{const{Class:l}=t,n=l.observedAttributes||[];if(u(e,l.prototype),n.length){new MutationObserver(h).observe(e,{attributes:!0,attributeFilter:n,attributeOldValue:!0});const t=[];for(let l=0,{length:s}=n;l{const l=e.querySelectorAll("[is]");for(let e=0,{length:n}=l;e{if(1!==e.nodeType)return;C(e,m);const t=p(e);t&&(e instanceof t.Class||v(e,t),s in e&&e[s]())},w=e=>{if(1!==e.nodeType)return;C(e,w);const t=p(e);t&&e instanceof t.Class&&r in e&&e[r]()};new MutationObserver(e=>{for(let t=0,{length:l}=e;te in g?g[e].Class:d.call(t,e)},upgrade:{value(e){const l=p(e);!l||e instanceof l.Class?f.call(t,e):v(e,l)}},whenDefined:{value:e=>e in g?Promise.resolve():b.call(t,e)}});const{createElement:y}=e;a(e,{createElement:{value(l,n){const s=y.call(e,l);return n&&"is"in n&&(s.setAttribute("is",n.is),t.upgrade(s)),s}}})}}(document,customElements);
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # built-in-element
2 |
3 | [](https://travis-ci.com/WebReflection/built-in-element) 
4 |
5 | ## Project moved to [@ungap/custom-elements-builtin](https://github.com/ungap/custom-elements-builtin)
6 |
7 | A polyfill for Custom Elements built-in that patches the native registry in Safari and WebKit and it's [compatible with the Custom Elements polyfill](https://github.com/WebReflection/document-register-element).
8 |
9 | It doesn't touch Chrome and Firefox 63+ with native support, and it weights less than 1K.
10 |
11 | ### Caveat
12 |
13 | You cannot use the `constructor` in any meaningful way if you want to ensure API consistency.
14 |
15 | Create new elements via `document.createElement('button', {is: 'my-button'})` but do not use `new MyButton` or incompatible browsers will throw right away because they made `HTMLButtonElement` and all others not usable as classes.
16 |
17 | If you need a reliable entry point to setup your custom builtins use the `connectedCallback` method instead of the `constructor` so you're also sure all attributes are eventually already known and you'll have full control.
18 |
19 | Alternatively, use a `WeakSet` to optionally invoke a setup.
20 |
21 | ```js
22 | const initialized = new WeakSet;
23 | const setup = node => {
24 | initialized.add(node);
25 | node.live = true;
26 | };
27 | class MyButton extends HTMLButtonElement {
28 | connectedCallback() {
29 | if (!initialized.has(this))
30 | setup(this);
31 | // anything else
32 | }
33 | }
34 | ```
35 |
36 | You can do the same at the beginning of `attributeChangedCallback`.
37 |
38 | ### Compatible with ...
39 |
40 | Any engine that supports genuine ES2015 syntax and the following features:
41 |
42 | * global `MutationObserver`, `customElements`, and `Promise`
43 | * `assign`, `create`, `defineProperties`, and `setPrototypeOf` from the `Object`
44 |
45 | Alternatively, you can polyfill custom elements upfront and use Babel 7 to target older browsers.
46 |
47 | Feel free to live test the [native ES2015 version](https://webreflection.github.io/built-in-element/test/) or the [transpiled one](https://webreflection.github.io/built-in-element/test/es5/), which works down to IE9.
48 |
--------------------------------------------------------------------------------
/test/es5/min.js:
--------------------------------------------------------------------------------
1 | "use strict";function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function _defineProperties(e,t){for(var n=0;n {
19 | for (let i = 0, {length} = changes; i < length; i++) {
20 | const {attributeName, oldValue, target} = changes[i];
21 | const newValue = target.getAttribute(attributeName);
22 | if (
23 | ATTRIBUTE_CHANGED_CALLBACK in target &&
24 | !(oldValue == newValue && newValue == null)
25 | )
26 | target[ATTRIBUTE_CHANGED_CALLBACK](
27 | attributeName,
28 | oldValue,
29 | target.getAttribute(attributeName),
30 | // TODO: add getAttributeNS if the node is XML
31 | null
32 | );
33 | }
34 | };
35 | const getInfo = node => {
36 | let is = node.getAttribute('is');
37 | if (is) {
38 | is = is.toLowerCase();
39 | if (is in registry)
40 | return registry[is];
41 | }
42 | return null;
43 | };
44 | const setup = (node, info) => {
45 | const {Class} = info;
46 | const oa = Class.observedAttributes || [];
47 | setPrototypeOf(node, Class.prototype);
48 | if (oa.length) {
49 | new MutationObserver(attributeChanged).observe(
50 | node,
51 | {
52 | attributes: true,
53 | attributeFilter: oa,
54 | attributeOldValue: true
55 | }
56 | );
57 | const changes = [];
58 | for (let i = 0, {length} = oa; i < length; i++)
59 | changes.push({attributeName: oa[i], oldValue: null, target: node});
60 | attributeChanged(changes);
61 | }
62 | };
63 | const setupSubNodes = (node, setup) => {
64 | const nodes = node.querySelectorAll('[is]');
65 | for (let i = 0, {length} = nodes; i < length; i++)
66 | setup(nodes[i]);
67 | };
68 | const setupIfNeeded = node => {
69 | if (node.nodeType !== 1)
70 | return;
71 | setupSubNodes(node, setupIfNeeded);
72 | const info = getInfo(node);
73 | if (info) {
74 | if (!(node instanceof info.Class))
75 | setup(node, info);
76 | if (CONNECTED_CALLBACK in node)
77 | node[CONNECTED_CALLBACK]();
78 | }
79 | };
80 | const disconnectIfNeeded = node => {
81 | if (node.nodeType !== 1)
82 | return;
83 | setupSubNodes(node, disconnectIfNeeded);
84 | const info = getInfo(node);
85 | if (
86 | info &&
87 | node instanceof info.Class &&
88 | DISCONNECTED_CALLBACK in node
89 | )
90 | node[DISCONNECTED_CALLBACK]();
91 | };
92 | new MutationObserver(changes => {
93 | for (let i = 0, {length} = changes; i < length; i++) {
94 | const {addedNodes, removedNodes} = changes[i];
95 | for (let j = 0, {length} = addedNodes; j < length; j++)
96 | setupIfNeeded(addedNodes[j]);
97 | for (let j = 0, {length} = removedNodes; j < length; j++)
98 | disconnectIfNeeded(removedNodes[j]);
99 | }
100 | }).observe(
101 | document,
102 | {childList: true, subtree: true}
103 | );
104 | defineProperties(
105 | customElements,
106 | {
107 | define: {
108 | value(name, Class, options) {
109 | name = name.toLowerCase();
110 | if (options && EXTENDS in options) {
111 | // currently options is not used but preserved for the future
112 | registry[name] = assign({}, options, {Class});
113 | const query = options[EXTENDS] + '[is="' + name + '"]';
114 | const changes = document.querySelectorAll(query);
115 | for (let i = 0, {length} = changes; i < length; i++)
116 | setupIfNeeded(changes[i]);
117 | }
118 | else
119 | define.apply(customElements, arguments);
120 | }
121 | },
122 | get: {
123 | value(name) {
124 | return name in registry ?
125 | registry[name].Class :
126 | get.call(customElements, name);
127 | }
128 | },
129 | upgrade: {
130 | value(node) {
131 | const info = getInfo(node);
132 | if (info && !(node instanceof info.Class))
133 | setup(node, info);
134 | else
135 | upgrade.call(customElements, node);
136 | }
137 | },
138 | whenDefined: {
139 | value(name) {
140 | return name in registry ?
141 | Promise.resolve() :
142 | whenDefined.call(customElements, name);
143 | }
144 | }
145 | }
146 | );
147 | const {createElement} = document;
148 | defineProperties(
149 | document,
150 | {
151 | createElement: {
152 | value(name, options) {
153 | const node = createElement.call(document, name);
154 | if (options && 'is' in options) {
155 | node.setAttribute('is', options.is);
156 | customElements.upgrade(node);
157 | }
158 | return node;
159 | }
160 | }
161 | }
162 | );
163 | }
164 | }(document, customElements));
165 |
--------------------------------------------------------------------------------
/test/es5/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4 |
5 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
6 |
7 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
8 |
9 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
10 |
11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
12 |
13 | function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
14 |
15 | function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
16 |
17 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
18 |
19 | function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
20 |
21 | function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
22 |
23 | function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
24 |
25 | function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
26 |
27 | function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
28 |
29 | function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
30 |
31 | /*! (c) Andrea Giammarchi - ISC */
32 | (function (document, customElements) {
33 | 'use strict';
34 |
35 | if (customElements.get('li-li')) return;
36 | var EXTENDS = 'extends';
37 |
38 | try {
39 | var LI =
40 | /*#__PURE__*/
41 | function (_HTMLLIElement) {
42 | _inherits(LI, _HTMLLIElement);
43 |
44 | function LI() {
45 | _classCallCheck(this, LI);
46 |
47 | return _possibleConstructorReturn(this, _getPrototypeOf(LI).apply(this, arguments));
48 | }
49 |
50 | return LI;
51 | }(_wrapNativeSuper(HTMLLIElement));
52 |
53 | customElements.define('li-li', LI, _defineProperty({}, EXTENDS, 'li'));
54 | if (!/is="li-li"/.test(new LI().outerHTML)) throw {};
55 | } catch (o_O) {
56 | var ATTRIBUTE_CHANGED_CALLBACK = 'attributeChangedCallback';
57 | var CONNECTED_CALLBACK = 'connectedCallback';
58 | var DISCONNECTED_CALLBACK = 'disconnectedCallback';
59 | var assign = Object.assign,
60 | create = Object.create,
61 | defineProperties = Object.defineProperties,
62 | setPrototypeOf = Object.setPrototypeOf;
63 | var define = customElements.define,
64 | get = customElements.get,
65 | upgrade = customElements.upgrade,
66 | whenDefined = customElements.whenDefined;
67 | var registry = create(null);
68 |
69 | var attributeChanged = function attributeChanged(changes) {
70 | for (var i = 0, length = changes.length; i < length; i++) {
71 | var _changes$i = changes[i],
72 | attributeName = _changes$i.attributeName,
73 | oldValue = _changes$i.oldValue,
74 | target = _changes$i.target;
75 | var newValue = target.getAttribute(attributeName);
76 | if (ATTRIBUTE_CHANGED_CALLBACK in target && !(oldValue == newValue && newValue == null)) target[ATTRIBUTE_CHANGED_CALLBACK](attributeName, oldValue, target.getAttribute(attributeName), // TODO: add getAttributeNS if the node is XML
77 | null);
78 | }
79 | };
80 |
81 | var getInfo = function getInfo(node) {
82 | var is = node.getAttribute('is');
83 |
84 | if (is) {
85 | is = is.toLowerCase();
86 | if (is in registry) return registry[is];
87 | }
88 |
89 | return null;
90 | };
91 |
92 | var setup = function setup(node, info) {
93 | var Class = info.Class;
94 | var oa = Class.observedAttributes || [];
95 | setPrototypeOf(node, Class.prototype);
96 |
97 | if (oa.length) {
98 | new MutationObserver(attributeChanged).observe(node, {
99 | attributes: true,
100 | attributeFilter: oa,
101 | attributeOldValue: true
102 | });
103 | var changes = [];
104 |
105 | for (var i = 0, length = oa.length; i < length; i++) {
106 | changes.push({
107 | attributeName: oa[i],
108 | oldValue: null,
109 | target: node
110 | });
111 | }
112 |
113 | attributeChanged(changes);
114 | }
115 | };
116 |
117 | var setupSubNodes = function setupSubNodes(node, setup) {
118 | var nodes = node.querySelectorAll('[is]');
119 |
120 | for (var i = 0, length = nodes.length; i < length; i++) {
121 | setup(nodes[i]);
122 | }
123 | };
124 |
125 | var setupIfNeeded = function setupIfNeeded(node) {
126 | if (node.nodeType !== 1) return;
127 | setupSubNodes(node, setupIfNeeded);
128 | var info = getInfo(node);
129 |
130 | if (info) {
131 | if (!(node instanceof info.Class)) setup(node, info);
132 | if (CONNECTED_CALLBACK in node) node[CONNECTED_CALLBACK]();
133 | }
134 | };
135 |
136 | var disconnectIfNeeded = function disconnectIfNeeded(node) {
137 | if (node.nodeType !== 1) return;
138 | setupSubNodes(node, disconnectIfNeeded);
139 | var info = getInfo(node);
140 | if (info && node instanceof info.Class && DISCONNECTED_CALLBACK in node) node[DISCONNECTED_CALLBACK]();
141 | };
142 |
143 | new MutationObserver(function (changes) {
144 | for (var i = 0, length = changes.length; i < length; i++) {
145 | var _changes$i2 = changes[i],
146 | addedNodes = _changes$i2.addedNodes,
147 | removedNodes = _changes$i2.removedNodes;
148 |
149 | for (var j = 0, _length = addedNodes.length; j < _length; j++) {
150 | setupIfNeeded(addedNodes[j]);
151 | }
152 |
153 | for (var _j = 0, _length2 = removedNodes.length; _j < _length2; _j++) {
154 | disconnectIfNeeded(removedNodes[_j]);
155 | }
156 | }
157 | }).observe(document, {
158 | childList: true,
159 | subtree: true
160 | });
161 | defineProperties(customElements, {
162 | define: {
163 | value: function value(name, Class, options) {
164 | name = name.toLowerCase();
165 |
166 | if (options && EXTENDS in options) {
167 | // currently options is not used but preserved for the future
168 | registry[name] = assign({}, options, {
169 | Class: Class
170 | });
171 | var query = options[EXTENDS] + '[is="' + name + '"]';
172 | var changes = document.querySelectorAll(query);
173 |
174 | for (var i = 0, length = changes.length; i < length; i++) {
175 | setupIfNeeded(changes[i]);
176 | }
177 | } else define.apply(customElements, arguments);
178 | }
179 | },
180 | get: {
181 | value: function value(name) {
182 | return name in registry ? registry[name].Class : get.call(customElements, name);
183 | }
184 | },
185 | upgrade: {
186 | value: function value(node) {
187 | var info = getInfo(node);
188 | if (info && !(node instanceof info.Class)) setup(node, info);else upgrade.call(customElements, node);
189 | }
190 | },
191 | whenDefined: {
192 | value: function value(name) {
193 | return name in registry ? Promise.resolve() : whenDefined.call(customElements, name);
194 | }
195 | }
196 | });
197 | var createElement = document.createElement;
198 | defineProperties(document, {
199 | createElement: {
200 | value: function value(name, options) {
201 | var node = createElement.call(document, name);
202 |
203 | if (options && 'is' in options) {
204 | node.setAttribute('is', options.is);
205 | customElements.upgrade(node);
206 | }
207 |
208 | return node;
209 | }
210 | }
211 | });
212 | }
213 | })(document, customElements);
214 |
215 | customElements.define('my-button',
216 | /*#__PURE__*/
217 | function (_HTMLButtonElement) {
218 | _inherits(MyButton, _HTMLButtonElement);
219 |
220 | function MyButton() {
221 | _classCallCheck(this, MyButton);
222 |
223 | return _possibleConstructorReturn(this, _getPrototypeOf(MyButton).apply(this, arguments));
224 | }
225 |
226 | _createClass(MyButton, [{
227 | key: "attributeChangedCallback",
228 | value: function attributeChangedCallback(name, oldValue, newValue, nsValue) {
229 | this.style.color = newValue;
230 | }
231 | }, {
232 | key: "connectedCallback",
233 | value: function connectedCallback() {
234 | this.addEventListener('click', this);
235 | }
236 | }, {
237 | key: "disconnectedCallback",
238 | value: function disconnectedCallback() {
239 | this.removeEventListener('click', this);
240 | }
241 | }, {
242 | key: "handleEvent",
243 | value: function handleEvent(event) {
244 | var next = this.nextElementSibling || this.parentNode.appendChild(document.createElement('div'));
245 | next.textContent = "".concat(event.type, " @ ").concat(new Date());
246 | }
247 | }], [{
248 | key: "observedAttributes",
249 | get: function get() {
250 | return ['color'];
251 | }
252 | }]);
253 |
254 | return MyButton;
255 | }(_wrapNativeSuper(HTMLButtonElement)), {
256 | 'extends': 'button'
257 | });
258 |
259 |
--------------------------------------------------------------------------------