UNPKG

5.9 kBJavaScriptView Raw
1/*! (c) Andrea Giammarchi - ISC */
2(function (document, customElements, Object) {
3 'use strict';
4 if (customElements.get('ungap-li') || typeof Reflect == typeof EXTENDS)
5 return;
6 var EXTENDS = 'extends';
7 try {
8 // class LI extends HTMLLIElement {}
9 var desc = {};
10 desc[EXTENDS] = 'li';
11 var HtmlLI = HTMLLIElement;
12 var LI = function () {
13 return Reflect.construct(HtmlLI, [], LI);
14 };
15 LI.prototype = Object.create(HtmlLI.prototype);
16 customElements.define('ungap-li', LI, desc);
17 if (!/is="ungap-li"/.test((new LI).outerHTML))
18 throw {};
19 } catch (o_O) {
20 var ATTRIBUTE_CHANGED_CALLBACK = 'attributeChangedCallback';
21 var CONNECTED_CALLBACK = 'connectedCallback';
22 var DISCONNECTED_CALLBACK = 'disconnectedCallback';
23 var assign = Object.assign;
24 var create = Object.create;
25 var defineProperties = Object.defineProperties;
26 var setPrototypeOf = Object.setPrototypeOf;
27 var define = customElements.define;
28 var get = customElements.get;
29 var upgrade = customElements.upgrade;
30 var whenDefined = customElements.whenDefined;
31 var registry = create(null);
32 new MutationObserver(function (changes) {
33 for (var i = 0, length = changes.length; i < length; i++) {
34 var change = changes[i];
35 var addedNodes = change.addedNodes;
36 var removedNodes = change.removedNodes;
37 for (var j = 0, len = addedNodes.length; j < len; j++)
38 setupIfNeeded(addedNodes[j]);
39 for (var j = 0, len = removedNodes.length; j < len; j++)
40 disconnectIfNeeded(removedNodes[j]);
41 }
42 }).observe(
43 document,
44 {childList: true, subtree: true}
45 );
46 defineProperties(
47 customElements,
48 {
49 define: {
50 value: function (name, Class, options) {
51 name = name.toLowerCase();
52 if (options && EXTENDS in options) {
53 // currently options is not used but preserved for the future
54 registry[name] = assign({}, options, {Class: Class});
55 var query = options[EXTENDS] + '[is="' + name + '"]';
56 var changes = document.querySelectorAll(query);
57 for (var i = 0, length = changes.length; i < length; i++)
58 setupIfNeeded(changes[i]);
59 }
60 else
61 define.apply(customElements, arguments);
62 }
63 },
64 get: {
65 value: function (name) {
66 return name in registry ?
67 registry[name].Class :
68 get.call(customElements, name);
69 }
70 },
71 upgrade: {
72 value: function (node) {
73 var info = getInfo(node);
74 if (info && !(node instanceof info.Class))
75 setup(node, info);
76 else
77 upgrade.call(customElements, node);
78 }
79 },
80 whenDefined: {
81 value: function (name) {
82 return name in registry ?
83 Promise.resolve() :
84 whenDefined.call(customElements, name);
85 }
86 }
87 }
88 );
89 var createElement = document.createElement;
90 defineProperties(
91 document,
92 {
93 createElement: {
94 value: function (name, options) {
95 var node = createElement.call(document, name);
96 if (options && 'is' in options) {
97 node.setAttribute('is', options.is);
98 customElements.upgrade(node);
99 }
100 return node;
101 }
102 }
103 }
104 );
105 function attributeChanged(changes) {
106 for (var i = 0, length = changes.length; i < length; i++) {
107 var change = changes[i];
108 var attributeName = change.attributeName;
109 var oldValue = change.oldValue;
110 var target = change.target;
111 var newValue = target.getAttribute(attributeName);
112 if (
113 ATTRIBUTE_CHANGED_CALLBACK in target &&
114 !(oldValue == newValue && newValue == null)
115 )
116 target[ATTRIBUTE_CHANGED_CALLBACK](
117 attributeName,
118 oldValue,
119 target.getAttribute(attributeName),
120 // TODO: add getAttributeNS if the node is XML
121 null
122 );
123 }
124 }
125 function disconnectIfNeeded(node) {
126 if (node.nodeType !== 1)
127 return;
128 setupSubNodes(node, disconnectIfNeeded);
129 var info = getInfo(node);
130 if (
131 info &&
132 node instanceof info.Class &&
133 DISCONNECTED_CALLBACK in node
134 )
135 node[DISCONNECTED_CALLBACK]();
136 }
137 function getInfo(node) {
138 var is = node.getAttribute('is');
139 if (is) {
140 is = is.toLowerCase();
141 if (is in registry)
142 return registry[is];
143 }
144 return null;
145 }
146 function setup(node, info) {
147 var Class = info.Class;
148 var oa = Class.observedAttributes || [];
149 setPrototypeOf(node, Class.prototype);
150 if (oa.length) {
151 new MutationObserver(attributeChanged).observe(
152 node,
153 {
154 attributes: true,
155 attributeFilter: oa,
156 attributeOldValue: true
157 }
158 );
159 var changes = [];
160 for (var i = 0, length = oa.length; i < length; i++)
161 changes.push({attributeName: oa[i], oldValue: null, target: node});
162 attributeChanged(changes);
163 }
164 }
165 function setupIfNeeded(node) {
166 if (node.nodeType !== 1)
167 return;
168 setupSubNodes(node, setupIfNeeded);
169 var info = getInfo(node);
170 if (info) {
171 if (!(node instanceof info.Class))
172 setup(node, info);
173 if (CONNECTED_CALLBACK in node)
174 node[CONNECTED_CALLBACK]();
175 }
176 }
177 function setupSubNodes(node, setup) {
178 var nodes = node.querySelectorAll('[is]');
179 for (var i = 0, length = nodes.length; i < length; i++)
180 setup(nodes[i]);
181 }
182 }
183}(document, customElements, Object));