LEFT | RIGHT |
1 /* eslint-disable */(function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!
t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)ret
urn i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_N
OT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o
][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof r
equire=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e
})()({1:[function(require,module,exports){ | |
2 /* globals module, require */ | |
3 | |
4 "use strict"; | |
5 | |
6 // Custom Elements polyfill | |
7 const customElementsPonyfill = require("document-register-element/pony"); | |
8 if (typeof customElements !== "object") | |
9 customElementsPonyfill(window); | |
10 | |
11 // external dependencies | |
12 const {default: HyperHTMLElement} = require("hyperhtml-element/cjs"); | |
13 | |
14 // provides a unique-id suffix per each component | |
15 let counter = 0; | |
16 | |
17 // common Custom Element class to extend | |
18 class IOElement extends HyperHTMLElement | |
19 { | |
20 // get a unique ID or, if null, set one and returns it | |
21 static getID(element) | |
22 { | |
23 return element.getAttribute("id") || IOElement.setID(element); | |
24 } | |
25 | |
26 // set a unique ID to a generic element and returns the ID | |
27 static setID(element) | |
28 { | |
29 const id = `${element.nodeName.toLowerCase()}-${counter++}`; | |
30 element.setAttribute("id", id); | |
31 return id; | |
32 } | |
33 | |
34 // lazily retrieve or define a custom element ID | |
35 get id() | |
36 { | |
37 return IOElement.getID(this); | |
38 } | |
39 | |
40 // whenever an element is created, render its content once | |
41 created() { this.render(); } | |
42 | |
43 // by default, render is a no-op | |
44 render() {} | |
45 } | |
46 | |
47 // whenever an interpolation with ${{i18n: 'string-id'}} is found | |
48 // transform such value into the expected content | |
49 // example: | |
50 // render() { | |
51 // return this.html`<div>${{i18n:'about-abp'}}</div>`; | |
52 // } | |
53 const {setElementText} = ext.i18n; | |
54 IOElement.intent("i18n", id => | |
55 { | |
56 const fragment = document.createDocumentFragment(); | |
57 setElementText(fragment, id); | |
58 return fragment; | |
59 }); | |
60 | |
61 module.exports = IOElement; | |
62 | |
63 },{"document-register-element/pony":2,"hyperhtml-element/cjs":3}],2:[function(re
quire,module,exports){ | |
64 /*! | |
65 | |
66 Copyright (C) 2014-2016 by Andrea Giammarchi - @WebReflection | |
67 | |
68 Permission is hereby granted, free of charge, to any person obtaining a copy | |
69 of this software and associated documentation files (the "Software"), to deal | |
70 in the Software without restriction, including without limitation the rights | |
71 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
72 copies of the Software, and to permit persons to whom the Software is | |
73 furnished to do so, subject to the following conditions: | |
74 | |
75 The above copyright notice and this permission notice shall be included in | |
76 all copies or substantial portions of the Software. | |
77 | |
78 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
79 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
80 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
81 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
82 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
83 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
84 THE SOFTWARE. | |
85 | |
86 */ | |
87 // global window Object | |
88 // optional polyfill info | |
89 // 'auto' used by default, everything is feature detected | |
90 // 'force' use the polyfill even if not fully needed | |
91 function installCustomElements(window, polyfill) {'use strict'; | |
92 | |
93 // DO NOT USE THIS FILE DIRECTLY, IT WON'T WORK | |
94 // THIS IS A PROJECT BASED ON A BUILD SYSTEM | |
95 // THIS FILE IS JUST WRAPPED UP RESULTING IN | |
96 // build/document-register-element.node.js | |
97 | |
98 var | |
99 document = window.document, | |
100 Object = window.Object | |
101 ; | |
102 | |
103 var htmlClass = (function (info) { | |
104 // (C) Andrea Giammarchi - @WebReflection - MIT Style | |
105 var | |
106 catchClass = /^[A-Z]+[a-z]/, | |
107 filterBy = function (re) { | |
108 var arr = [], tag; | |
109 for (tag in register) { | |
110 if (re.test(tag)) arr.push(tag); | |
111 } | |
112 return arr; | |
113 }, | |
114 add = function (Class, tag) { | |
115 tag = tag.toLowerCase(); | |
116 if (!(tag in register)) { | |
117 register[Class] = (register[Class] || []).concat(tag); | |
118 register[tag] = (register[tag.toUpperCase()] = Class); | |
119 } | |
120 }, | |
121 register = (Object.create || Object)(null), | |
122 htmlClass = {}, | |
123 i, section, tags, Class | |
124 ; | |
125 for (section in info) { | |
126 for (Class in info[section]) { | |
127 tags = info[section][Class]; | |
128 register[Class] = tags; | |
129 for (i = 0; i < tags.length; i++) { | |
130 register[tags[i].toLowerCase()] = | |
131 register[tags[i].toUpperCase()] = Class; | |
132 } | |
133 } | |
134 } | |
135 htmlClass.get = function get(tagOrClass) { | |
136 return typeof tagOrClass === 'string' ? | |
137 (register[tagOrClass] || (catchClass.test(tagOrClass) ? [] : '')) : | |
138 filterBy(tagOrClass); | |
139 }; | |
140 htmlClass.set = function set(tag, Class) { | |
141 return (catchClass.test(tag) ? | |
142 add(tag, Class) : | |
143 add(Class, tag) | |
144 ), htmlClass; | |
145 }; | |
146 return htmlClass; | |
147 }({ | |
148 "collections": { | |
149 "HTMLAllCollection": [ | |
150 "all" | |
151 ], | |
152 "HTMLCollection": [ | |
153 "forms" | |
154 ], | |
155 "HTMLFormControlsCollection": [ | |
156 "elements" | |
157 ], | |
158 "HTMLOptionsCollection": [ | |
159 "options" | |
160 ] | |
161 }, | |
162 "elements": { | |
163 "Element": [ | |
164 "element" | |
165 ], | |
166 "HTMLAnchorElement": [ | |
167 "a" | |
168 ], | |
169 "HTMLAppletElement": [ | |
170 "applet" | |
171 ], | |
172 "HTMLAreaElement": [ | |
173 "area" | |
174 ], | |
175 "HTMLAttachmentElement": [ | |
176 "attachment" | |
177 ], | |
178 "HTMLAudioElement": [ | |
179 "audio" | |
180 ], | |
181 "HTMLBRElement": [ | |
182 "br" | |
183 ], | |
184 "HTMLBaseElement": [ | |
185 "base" | |
186 ], | |
187 "HTMLBodyElement": [ | |
188 "body" | |
189 ], | |
190 "HTMLButtonElement": [ | |
191 "button" | |
192 ], | |
193 "HTMLCanvasElement": [ | |
194 "canvas" | |
195 ], | |
196 "HTMLContentElement": [ | |
197 "content" | |
198 ], | |
199 "HTMLDListElement": [ | |
200 "dl" | |
201 ], | |
202 "HTMLDataElement": [ | |
203 "data" | |
204 ], | |
205 "HTMLDataListElement": [ | |
206 "datalist" | |
207 ], | |
208 "HTMLDetailsElement": [ | |
209 "details" | |
210 ], | |
211 "HTMLDialogElement": [ | |
212 "dialog" | |
213 ], | |
214 "HTMLDirectoryElement": [ | |
215 "dir" | |
216 ], | |
217 "HTMLDivElement": [ | |
218 "div" | |
219 ], | |
220 "HTMLDocument": [ | |
221 "document" | |
222 ], | |
223 "HTMLElement": [ | |
224 "element", | |
225 "abbr", | |
226 "address", | |
227 "article", | |
228 "aside", | |
229 "b", | |
230 "bdi", | |
231 "bdo", | |
232 "cite", | |
233 "code", | |
234 "command", | |
235 "dd", | |
236 "dfn", | |
237 "dt", | |
238 "em", | |
239 "figcaption", | |
240 "figure", | |
241 "footer", | |
242 "header", | |
243 "i", | |
244 "kbd", | |
245 "mark", | |
246 "nav", | |
247 "noscript", | |
248 "rp", | |
249 "rt", | |
250 "ruby", | |
251 "s", | |
252 "samp", | |
253 "section", | |
254 "small", | |
255 "strong", | |
256 "sub", | |
257 "summary", | |
258 "sup", | |
259 "u", | |
260 "var", | |
261 "wbr" | |
262 ], | |
263 "HTMLEmbedElement": [ | |
264 "embed" | |
265 ], | |
266 "HTMLFieldSetElement": [ | |
267 "fieldset" | |
268 ], | |
269 "HTMLFontElement": [ | |
270 "font" | |
271 ], | |
272 "HTMLFormElement": [ | |
273 "form" | |
274 ], | |
275 "HTMLFrameElement": [ | |
276 "frame" | |
277 ], | |
278 "HTMLFrameSetElement": [ | |
279 "frameset" | |
280 ], | |
281 "HTMLHRElement": [ | |
282 "hr" | |
283 ], | |
284 "HTMLHeadElement": [ | |
285 "head" | |
286 ], | |
287 "HTMLHeadingElement": [ | |
288 "h1", | |
289 "h2", | |
290 "h3", | |
291 "h4", | |
292 "h5", | |
293 "h6" | |
294 ], | |
295 "HTMLHtmlElement": [ | |
296 "html" | |
297 ], | |
298 "HTMLIFrameElement": [ | |
299 "iframe" | |
300 ], | |
301 "HTMLImageElement": [ | |
302 "img" | |
303 ], | |
304 "HTMLInputElement": [ | |
305 "input" | |
306 ], | |
307 "HTMLKeygenElement": [ | |
308 "keygen" | |
309 ], | |
310 "HTMLLIElement": [ | |
311 "li" | |
312 ], | |
313 "HTMLLabelElement": [ | |
314 "label" | |
315 ], | |
316 "HTMLLegendElement": [ | |
317 "legend" | |
318 ], | |
319 "HTMLLinkElement": [ | |
320 "link" | |
321 ], | |
322 "HTMLMapElement": [ | |
323 "map" | |
324 ], | |
325 "HTMLMarqueeElement": [ | |
326 "marquee" | |
327 ], | |
328 "HTMLMediaElement": [ | |
329 "media" | |
330 ], | |
331 "HTMLMenuElement": [ | |
332 "menu" | |
333 ], | |
334 "HTMLMenuItemElement": [ | |
335 "menuitem" | |
336 ], | |
337 "HTMLMetaElement": [ | |
338 "meta" | |
339 ], | |
340 "HTMLMeterElement": [ | |
341 "meter" | |
342 ], | |
343 "HTMLModElement": [ | |
344 "del", | |
345 "ins" | |
346 ], | |
347 "HTMLOListElement": [ | |
348 "ol" | |
349 ], | |
350 "HTMLObjectElement": [ | |
351 "object" | |
352 ], | |
353 "HTMLOptGroupElement": [ | |
354 "optgroup" | |
355 ], | |
356 "HTMLOptionElement": [ | |
357 "option" | |
358 ], | |
359 "HTMLOutputElement": [ | |
360 "output" | |
361 ], | |
362 "HTMLParagraphElement": [ | |
363 "p" | |
364 ], | |
365 "HTMLParamElement": [ | |
366 "param" | |
367 ], | |
368 "HTMLPictureElement": [ | |
369 "picture" | |
370 ], | |
371 "HTMLPreElement": [ | |
372 "pre" | |
373 ], | |
374 "HTMLProgressElement": [ | |
375 "progress" | |
376 ], | |
377 "HTMLQuoteElement": [ | |
378 "blockquote", | |
379 "q", | |
380 "quote" | |
381 ], | |
382 "HTMLScriptElement": [ | |
383 "script" | |
384 ], | |
385 "HTMLSelectElement": [ | |
386 "select" | |
387 ], | |
388 "HTMLShadowElement": [ | |
389 "shadow" | |
390 ], | |
391 "HTMLSlotElement": [ | |
392 "slot" | |
393 ], | |
394 "HTMLSourceElement": [ | |
395 "source" | |
396 ], | |
397 "HTMLSpanElement": [ | |
398 "span" | |
399 ], | |
400 "HTMLStyleElement": [ | |
401 "style" | |
402 ], | |
403 "HTMLTableCaptionElement": [ | |
404 "caption" | |
405 ], | |
406 "HTMLTableCellElement": [ | |
407 "td", | |
408 "th" | |
409 ], | |
410 "HTMLTableColElement": [ | |
411 "col", | |
412 "colgroup" | |
413 ], | |
414 "HTMLTableElement": [ | |
415 "table" | |
416 ], | |
417 "HTMLTableRowElement": [ | |
418 "tr" | |
419 ], | |
420 "HTMLTableSectionElement": [ | |
421 "thead", | |
422 "tbody", | |
423 "tfoot" | |
424 ], | |
425 "HTMLTemplateElement": [ | |
426 "template" | |
427 ], | |
428 "HTMLTextAreaElement": [ | |
429 "textarea" | |
430 ], | |
431 "HTMLTimeElement": [ | |
432 "time" | |
433 ], | |
434 "HTMLTitleElement": [ | |
435 "title" | |
436 ], | |
437 "HTMLTrackElement": [ | |
438 "track" | |
439 ], | |
440 "HTMLUListElement": [ | |
441 "ul" | |
442 ], | |
443 "HTMLUnknownElement": [ | |
444 "unknown", | |
445 "vhgroupv", | |
446 "vkeygen" | |
447 ], | |
448 "HTMLVideoElement": [ | |
449 "video" | |
450 ] | |
451 }, | |
452 "nodes": { | |
453 "Attr": [ | |
454 "node" | |
455 ], | |
456 "Audio": [ | |
457 "audio" | |
458 ], | |
459 "CDATASection": [ | |
460 "node" | |
461 ], | |
462 "CharacterData": [ | |
463 "node" | |
464 ], | |
465 "Comment": [ | |
466 "#comment" | |
467 ], | |
468 "Document": [ | |
469 "#document" | |
470 ], | |
471 "DocumentFragment": [ | |
472 "#document-fragment" | |
473 ], | |
474 "DocumentType": [ | |
475 "node" | |
476 ], | |
477 "HTMLDocument": [ | |
478 "#document" | |
479 ], | |
480 "Image": [ | |
481 "img" | |
482 ], | |
483 "Option": [ | |
484 "option" | |
485 ], | |
486 "ProcessingInstruction": [ | |
487 "node" | |
488 ], | |
489 "ShadowRoot": [ | |
490 "#shadow-root" | |
491 ], | |
492 "Text": [ | |
493 "#text" | |
494 ], | |
495 "XMLDocument": [ | |
496 "xml" | |
497 ] | |
498 } | |
499 })); | |
500 | |
501 | |
502 | |
503 // passed at runtime, configurable via nodejs module | |
504 if (typeof polyfill !== 'object') polyfill = {type: polyfill || 'auto'}; | |
505 | |
506 var | |
507 // V0 polyfill entry | |
508 REGISTER_ELEMENT = 'registerElement', | |
509 | |
510 // IE < 11 only + old WebKit for attributes + feature detection | |
511 EXPANDO_UID = '__' + REGISTER_ELEMENT + (window.Math.random() * 10e4 >> 0), | |
512 | |
513 // shortcuts and costants | |
514 ADD_EVENT_LISTENER = 'addEventListener', | |
515 ATTACHED = 'attached', | |
516 CALLBACK = 'Callback', | |
517 DETACHED = 'detached', | |
518 EXTENDS = 'extends', | |
519 | |
520 ATTRIBUTE_CHANGED_CALLBACK = 'attributeChanged' + CALLBACK, | |
521 ATTACHED_CALLBACK = ATTACHED + CALLBACK, | |
522 CONNECTED_CALLBACK = 'connected' + CALLBACK, | |
523 DISCONNECTED_CALLBACK = 'disconnected' + CALLBACK, | |
524 CREATED_CALLBACK = 'created' + CALLBACK, | |
525 DETACHED_CALLBACK = DETACHED + CALLBACK, | |
526 | |
527 ADDITION = 'ADDITION', | |
528 MODIFICATION = 'MODIFICATION', | |
529 REMOVAL = 'REMOVAL', | |
530 | |
531 DOM_ATTR_MODIFIED = 'DOMAttrModified', | |
532 DOM_CONTENT_LOADED = 'DOMContentLoaded', | |
533 DOM_SUBTREE_MODIFIED = 'DOMSubtreeModified', | |
534 | |
535 PREFIX_TAG = '<', | |
536 PREFIX_IS = '=', | |
537 | |
538 // valid and invalid node names | |
539 validName = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/, | |
540 invalidNames = [ | |
541 'ANNOTATION-XML', | |
542 'COLOR-PROFILE', | |
543 'FONT-FACE', | |
544 'FONT-FACE-SRC', | |
545 'FONT-FACE-URI', | |
546 'FONT-FACE-FORMAT', | |
547 'FONT-FACE-NAME', | |
548 'MISSING-GLYPH' | |
549 ], | |
550 | |
551 // registered types and their prototypes | |
552 types = [], | |
553 protos = [], | |
554 | |
555 // to query subnodes | |
556 query = '', | |
557 | |
558 // html shortcut used to feature detect | |
559 documentElement = document.documentElement, | |
560 | |
561 // ES5 inline helpers || basic patches | |
562 indexOf = types.indexOf || function (v) { | |
563 for(var i = this.length; i-- && this[i] !== v;){} | |
564 return i; | |
565 }, | |
566 | |
567 // other helpers / shortcuts | |
568 OP = Object.prototype, | |
569 hOP = OP.hasOwnProperty, | |
570 iPO = OP.isPrototypeOf, | |
571 | |
572 defineProperty = Object.defineProperty, | |
573 empty = [], | |
574 gOPD = Object.getOwnPropertyDescriptor, | |
575 gOPN = Object.getOwnPropertyNames, | |
576 gPO = Object.getPrototypeOf, | |
577 sPO = Object.setPrototypeOf, | |
578 | |
579 // jshint proto: true | |
580 hasProto = !!Object.__proto__, | |
581 | |
582 // V1 helpers | |
583 fixGetClass = false, | |
584 DRECEV1 = '__dreCEv1', | |
585 customElements = window.customElements, | |
586 usableCustomElements = !/^force/.test(polyfill.type) && !!( | |
587 customElements && | |
588 customElements.define && | |
589 customElements.get && | |
590 customElements.whenDefined | |
591 ), | |
592 Dict = Object.create || Object, | |
593 Map = window.Map || function Map() { | |
594 var K = [], V = [], i; | |
595 return { | |
596 get: function (k) { | |
597 return V[indexOf.call(K, k)]; | |
598 }, | |
599 set: function (k, v) { | |
600 i = indexOf.call(K, k); | |
601 if (i < 0) V[K.push(k) - 1] = v; | |
602 else V[i] = v; | |
603 } | |
604 }; | |
605 }, | |
606 Promise = window.Promise || function (fn) { | |
607 var | |
608 notify = [], | |
609 done = false, | |
610 p = { | |
611 'catch': function () { | |
612 return p; | |
613 }, | |
614 'then': function (cb) { | |
615 notify.push(cb); | |
616 if (done) setTimeout(resolve, 1); | |
617 return p; | |
618 } | |
619 } | |
620 ; | |
621 function resolve(value) { | |
622 done = true; | |
623 while (notify.length) notify.shift()(value); | |
624 } | |
625 fn(resolve); | |
626 return p; | |
627 }, | |
628 justCreated = false, | |
629 constructors = Dict(null), | |
630 waitingList = Dict(null), | |
631 nodeNames = new Map(), | |
632 secondArgument = function (is) { | |
633 return is.toLowerCase(); | |
634 }, | |
635 | |
636 // used to create unique instances | |
637 create = Object.create || function Bridge(proto) { | |
638 // silly broken polyfill probably ever used but short enough to work | |
639 return proto ? ((Bridge.prototype = proto), new Bridge()) : this; | |
640 }, | |
641 | |
642 // will set the prototype if possible | |
643 // or copy over all properties | |
644 setPrototype = sPO || ( | |
645 hasProto ? | |
646 function (o, p) { | |
647 o.__proto__ = p; | |
648 return o; | |
649 } : ( | |
650 (gOPN && gOPD) ? | |
651 (function(){ | |
652 function setProperties(o, p) { | |
653 for (var | |
654 key, | |
655 names = gOPN(p), | |
656 i = 0, length = names.length; | |
657 i < length; i++ | |
658 ) { | |
659 key = names[i]; | |
660 if (!hOP.call(o, key)) { | |
661 defineProperty(o, key, gOPD(p, key)); | |
662 } | |
663 } | |
664 } | |
665 return function (o, p) { | |
666 do { | |
667 setProperties(o, p); | |
668 } while ((p = gPO(p)) && !iPO.call(p, o)); | |
669 return o; | |
670 }; | |
671 }()) : | |
672 function (o, p) { | |
673 for (var key in p) { | |
674 o[key] = p[key]; | |
675 } | |
676 return o; | |
677 } | |
678 )), | |
679 | |
680 // DOM shortcuts and helpers, if any | |
681 | |
682 MutationObserver = window.MutationObserver || | |
683 window.WebKitMutationObserver, | |
684 | |
685 HTMLElementPrototype = ( | |
686 window.HTMLElement || | |
687 window.Element || | |
688 window.Node | |
689 ).prototype, | |
690 | |
691 IE8 = !iPO.call(HTMLElementPrototype, documentElement), | |
692 | |
693 safeProperty = IE8 ? function (o, k, d) { | |
694 o[k] = d.value; | |
695 return o; | |
696 } : defineProperty, | |
697 | |
698 isValidNode = IE8 ? | |
699 function (node) { | |
700 return node.nodeType === 1; | |
701 } : | |
702 function (node) { | |
703 return iPO.call(HTMLElementPrototype, node); | |
704 }, | |
705 | |
706 targets = IE8 && [], | |
707 | |
708 attachShadow = HTMLElementPrototype.attachShadow, | |
709 cloneNode = HTMLElementPrototype.cloneNode, | |
710 dispatchEvent = HTMLElementPrototype.dispatchEvent, | |
711 getAttribute = HTMLElementPrototype.getAttribute, | |
712 hasAttribute = HTMLElementPrototype.hasAttribute, | |
713 removeAttribute = HTMLElementPrototype.removeAttribute, | |
714 setAttribute = HTMLElementPrototype.setAttribute, | |
715 | |
716 // replaced later on | |
717 createElement = document.createElement, | |
718 patchedCreateElement = createElement, | |
719 | |
720 // shared observer for all attributes | |
721 attributesObserver = MutationObserver && { | |
722 attributes: true, | |
723 characterData: true, | |
724 attributeOldValue: true | |
725 }, | |
726 | |
727 // useful to detect only if there's no MutationObserver | |
728 DOMAttrModified = MutationObserver || function(e) { | |
729 doesNotSupportDOMAttrModified = false; | |
730 documentElement.removeEventListener( | |
731 DOM_ATTR_MODIFIED, | |
732 DOMAttrModified | |
733 ); | |
734 }, | |
735 | |
736 // will both be used to make DOMNodeInserted asynchronous | |
737 asapQueue, | |
738 asapTimer = 0, | |
739 | |
740 // internal flags | |
741 V0 = REGISTER_ELEMENT in document && | |
742 !/^force-all/.test(polyfill.type), | |
743 setListener = true, | |
744 justSetup = false, | |
745 doesNotSupportDOMAttrModified = true, | |
746 dropDomContentLoaded = true, | |
747 | |
748 // needed for the innerHTML helper | |
749 notFromInnerHTMLHelper = true, | |
750 | |
751 // optionally defined later on | |
752 onSubtreeModified, | |
753 callDOMAttrModified, | |
754 getAttributesMirror, | |
755 observer, | |
756 observe, | |
757 | |
758 // based on setting prototype capability | |
759 // will check proto or the expando attribute | |
760 // in order to setup the node once | |
761 patchIfNotAlready, | |
762 patch | |
763 ; | |
764 | |
765 // only if needed | |
766 if (!V0) { | |
767 | |
768 if (sPO || hasProto) { | |
769 patchIfNotAlready = function (node, proto) { | |
770 if (!iPO.call(proto, node)) { | |
771 setupNode(node, proto); | |
772 } | |
773 }; | |
774 patch = setupNode; | |
775 } else { | |
776 patchIfNotAlready = function (node, proto) { | |
777 if (!node[EXPANDO_UID]) { | |
778 node[EXPANDO_UID] = Object(true); | |
779 setupNode(node, proto); | |
780 } | |
781 }; | |
782 patch = patchIfNotAlready; | |
783 } | |
784 | |
785 if (IE8) { | |
786 doesNotSupportDOMAttrModified = false; | |
787 (function (){ | |
788 var | |
789 descriptor = gOPD(HTMLElementPrototype, ADD_EVENT_LISTENER), | |
790 addEventListener = descriptor.value, | |
791 patchedRemoveAttribute = function (name) { | |
792 var e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true}); | |
793 e.attrName = name; | |
794 e.prevValue = getAttribute.call(this, name); | |
795 e.newValue = null; | |
796 e[REMOVAL] = e.attrChange = 2; | |
797 removeAttribute.call(this, name); | |
798 dispatchEvent.call(this, e); | |
799 }, | |
800 patchedSetAttribute = function (name, value) { | |
801 var | |
802 had = hasAttribute.call(this, name), | |
803 old = had && getAttribute.call(this, name), | |
804 e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true}) | |
805 ; | |
806 setAttribute.call(this, name, value); | |
807 e.attrName = name; | |
808 e.prevValue = had ? old : null; | |
809 e.newValue = value; | |
810 if (had) { | |
811 e[MODIFICATION] = e.attrChange = 1; | |
812 } else { | |
813 e[ADDITION] = e.attrChange = 0; | |
814 } | |
815 dispatchEvent.call(this, e); | |
816 }, | |
817 onPropertyChange = function (e) { | |
818 // jshint eqnull:true | |
819 var | |
820 node = e.currentTarget, | |
821 superSecret = node[EXPANDO_UID], | |
822 propertyName = e.propertyName, | |
823 event | |
824 ; | |
825 if (superSecret.hasOwnProperty(propertyName)) { | |
826 superSecret = superSecret[propertyName]; | |
827 event = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true}); | |
828 event.attrName = superSecret.name; | |
829 event.prevValue = superSecret.value || null; | |
830 event.newValue = (superSecret.value = node[propertyName] || null); | |
831 if (event.prevValue == null) { | |
832 event[ADDITION] = event.attrChange = 0; | |
833 } else { | |
834 event[MODIFICATION] = event.attrChange = 1; | |
835 } | |
836 dispatchEvent.call(node, event); | |
837 } | |
838 } | |
839 ; | |
840 descriptor.value = function (type, handler, capture) { | |
841 if ( | |
842 type === DOM_ATTR_MODIFIED && | |
843 this[ATTRIBUTE_CHANGED_CALLBACK] && | |
844 this.setAttribute !== patchedSetAttribute | |
845 ) { | |
846 this[EXPANDO_UID] = { | |
847 className: { | |
848 name: 'class', | |
849 value: this.className | |
850 } | |
851 }; | |
852 this.setAttribute = patchedSetAttribute; | |
853 this.removeAttribute = patchedRemoveAttribute; | |
854 addEventListener.call(this, 'propertychange', onPropertyChange); | |
855 } | |
856 addEventListener.call(this, type, handler, capture); | |
857 }; | |
858 defineProperty(HTMLElementPrototype, ADD_EVENT_LISTENER, descriptor); | |
859 }()); | |
860 } else if (!MutationObserver) { | |
861 documentElement[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, DOMAttrModified); | |
862 documentElement.setAttribute(EXPANDO_UID, 1); | |
863 documentElement.removeAttribute(EXPANDO_UID); | |
864 if (doesNotSupportDOMAttrModified) { | |
865 onSubtreeModified = function (e) { | |
866 var | |
867 node = this, | |
868 oldAttributes, | |
869 newAttributes, | |
870 key | |
871 ; | |
872 if (node === e.target) { | |
873 oldAttributes = node[EXPANDO_UID]; | |
874 node[EXPANDO_UID] = (newAttributes = getAttributesMirror(node)); | |
875 for (key in newAttributes) { | |
876 if (!(key in oldAttributes)) { | |
877 // attribute was added | |
878 return callDOMAttrModified( | |
879 0, | |
880 node, | |
881 key, | |
882 oldAttributes[key], | |
883 newAttributes[key], | |
884 ADDITION | |
885 ); | |
886 } else if (newAttributes[key] !== oldAttributes[key]) { | |
887 // attribute was changed | |
888 return callDOMAttrModified( | |
889 1, | |
890 node, | |
891 key, | |
892 oldAttributes[key], | |
893 newAttributes[key], | |
894 MODIFICATION | |
895 ); | |
896 } | |
897 } | |
898 // checking if it has been removed | |
899 for (key in oldAttributes) { | |
900 if (!(key in newAttributes)) { | |
901 // attribute removed | |
902 return callDOMAttrModified( | |
903 2, | |
904 node, | |
905 key, | |
906 oldAttributes[key], | |
907 newAttributes[key], | |
908 REMOVAL | |
909 ); | |
910 } | |
911 } | |
912 } | |
913 }; | |
914 callDOMAttrModified = function ( | |
915 attrChange, | |
916 currentTarget, | |
917 attrName, | |
918 prevValue, | |
919 newValue, | |
920 action | |
921 ) { | |
922 var e = { | |
923 attrChange: attrChange, | |
924 currentTarget: currentTarget, | |
925 attrName: attrName, | |
926 prevValue: prevValue, | |
927 newValue: newValue | |
928 }; | |
929 e[action] = attrChange; | |
930 onDOMAttrModified(e); | |
931 }; | |
932 getAttributesMirror = function (node) { | |
933 for (var | |
934 attr, name, | |
935 result = {}, | |
936 attributes = node.attributes, | |
937 i = 0, length = attributes.length; | |
938 i < length; i++ | |
939 ) { | |
940 attr = attributes[i]; | |
941 name = attr.name; | |
942 if (name !== 'setAttribute') { | |
943 result[name] = attr.value; | |
944 } | |
945 } | |
946 return result; | |
947 }; | |
948 } | |
949 } | |
950 | |
951 // set as enumerable, writable and configurable | |
952 document[REGISTER_ELEMENT] = function registerElement(type, options) { | |
953 upperType = type.toUpperCase(); | |
954 if (setListener) { | |
955 // only first time document.registerElement is used | |
956 // we need to set this listener | |
957 // setting it by default might slow down for no reason | |
958 setListener = false; | |
959 if (MutationObserver) { | |
960 observer = (function(attached, detached){ | |
961 function checkEmAll(list, callback) { | |
962 for (var i = 0, length = list.length; i < length; callback(list[i+
+])){} | |
963 } | |
964 return new MutationObserver(function (records) { | |
965 for (var | |
966 current, node, newValue, | |
967 i = 0, length = records.length; i < length; i++ | |
968 ) { | |
969 current = records[i]; | |
970 if (current.type === 'childList') { | |
971 checkEmAll(current.addedNodes, attached); | |
972 checkEmAll(current.removedNodes, detached); | |
973 } else { | |
974 node = current.target; | |
975 if (notFromInnerHTMLHelper && | |
976 node[ATTRIBUTE_CHANGED_CALLBACK] && | |
977 current.attributeName !== 'style') { | |
978 newValue = getAttribute.call(node, current.attributeName); | |
979 if (newValue !== current.oldValue) { | |
980 node[ATTRIBUTE_CHANGED_CALLBACK]( | |
981 current.attributeName, | |
982 current.oldValue, | |
983 newValue | |
984 ); | |
985 } | |
986 } | |
987 } | |
988 } | |
989 }); | |
990 }(executeAction(ATTACHED), executeAction(DETACHED))); | |
991 observe = function (node) { | |
992 observer.observe( | |
993 node, | |
994 { | |
995 childList: true, | |
996 subtree: true | |
997 } | |
998 ); | |
999 return node; | |
1000 }; | |
1001 observe(document); | |
1002 if (attachShadow) { | |
1003 HTMLElementPrototype.attachShadow = function () { | |
1004 return observe(attachShadow.apply(this, arguments)); | |
1005 }; | |
1006 } | |
1007 } else { | |
1008 asapQueue = []; | |
1009 document[ADD_EVENT_LISTENER]('DOMNodeInserted', onDOMNode(ATTACHED)); | |
1010 document[ADD_EVENT_LISTENER]('DOMNodeRemoved', onDOMNode(DETACHED)); | |
1011 } | |
1012 | |
1013 document[ADD_EVENT_LISTENER](DOM_CONTENT_LOADED, onReadyStateChange); | |
1014 document[ADD_EVENT_LISTENER]('readystatechange', onReadyStateChange); | |
1015 | |
1016 HTMLElementPrototype.cloneNode = function (deep) { | |
1017 var | |
1018 node = cloneNode.call(this, !!deep), | |
1019 i = getTypeIndex(node) | |
1020 ; | |
1021 if (-1 < i) patch(node, protos[i]); | |
1022 if (deep && query.length) loopAndSetup(node.querySelectorAll(query)); | |
1023 return node; | |
1024 }; | |
1025 } | |
1026 | |
1027 if (justSetup) return (justSetup = false); | |
1028 | |
1029 if (-2 < ( | |
1030 indexOf.call(types, PREFIX_IS + upperType) + | |
1031 indexOf.call(types, PREFIX_TAG + upperType) | |
1032 )) { | |
1033 throwTypeError(type); | |
1034 } | |
1035 | |
1036 if (!validName.test(upperType) || -1 < indexOf.call(invalidNames, upperTyp
e)) { | |
1037 throw new Error('The type ' + type + ' is invalid'); | |
1038 } | |
1039 | |
1040 var | |
1041 constructor = function () { | |
1042 return extending ? | |
1043 document.createElement(nodeName, upperType) : | |
1044 document.createElement(nodeName); | |
1045 }, | |
1046 opt = options || OP, | |
1047 extending = hOP.call(opt, EXTENDS), | |
1048 nodeName = extending ? options[EXTENDS].toUpperCase() : upperType, | |
1049 upperType, | |
1050 i | |
1051 ; | |
1052 | |
1053 if (extending && -1 < ( | |
1054 indexOf.call(types, PREFIX_TAG + nodeName) | |
1055 )) { | |
1056 throwTypeError(nodeName); | |
1057 } | |
1058 | |
1059 i = types.push((extending ? PREFIX_IS : PREFIX_TAG) + upperType) - 1; | |
1060 | |
1061 query = query.concat( | |
1062 query.length ? ',' : '', | |
1063 extending ? nodeName + '[is="' + type.toLowerCase() + '"]' : nodeName | |
1064 ); | |
1065 | |
1066 constructor.prototype = ( | |
1067 protos[i] = hOP.call(opt, 'prototype') ? | |
1068 opt.prototype : | |
1069 create(HTMLElementPrototype) | |
1070 ); | |
1071 | |
1072 if (query.length) loopAndVerify( | |
1073 document.querySelectorAll(query), | |
1074 ATTACHED | |
1075 ); | |
1076 | |
1077 return constructor; | |
1078 }; | |
1079 | |
1080 document.createElement = (patchedCreateElement = function (localName, typeEx
tension) { | |
1081 var | |
1082 is = getIs(typeExtension), | |
1083 node = is ? | |
1084 createElement.call(document, localName, secondArgument(is)) : | |
1085 createElement.call(document, localName), | |
1086 name = '' + localName, | |
1087 i = indexOf.call( | |
1088 types, | |
1089 (is ? PREFIX_IS : PREFIX_TAG) + | |
1090 (is || name).toUpperCase() | |
1091 ), | |
1092 setup = -1 < i | |
1093 ; | |
1094 if (is) { | |
1095 node.setAttribute('is', is = is.toLowerCase()); | |
1096 if (setup) { | |
1097 setup = isInQSA(name.toUpperCase(), is); | |
1098 } | |
1099 } | |
1100 notFromInnerHTMLHelper = !document.createElement.innerHTMLHelper; | |
1101 if (setup) patch(node, protos[i]); | |
1102 return node; | |
1103 }); | |
1104 | |
1105 } | |
1106 | |
1107 function ASAP() { | |
1108 var queue = asapQueue.splice(0, asapQueue.length); | |
1109 asapTimer = 0; | |
1110 while (queue.length) { | |
1111 queue.shift().call( | |
1112 null, queue.shift() | |
1113 ); | |
1114 } | |
1115 } | |
1116 | |
1117 function loopAndVerify(list, action) { | |
1118 for (var i = 0, length = list.length; i < length; i++) { | |
1119 verifyAndSetupAndAction(list[i], action); | |
1120 } | |
1121 } | |
1122 | |
1123 function loopAndSetup(list) { | |
1124 for (var i = 0, length = list.length, node; i < length; i++) { | |
1125 node = list[i]; | |
1126 patch(node, protos[getTypeIndex(node)]); | |
1127 } | |
1128 } | |
1129 | |
1130 function executeAction(action) { | |
1131 return function (node) { | |
1132 if (isValidNode(node)) { | |
1133 verifyAndSetupAndAction(node, action); | |
1134 if (query.length) loopAndVerify( | |
1135 node.querySelectorAll(query), | |
1136 action | |
1137 ); | |
1138 } | |
1139 }; | |
1140 } | |
1141 | |
1142 function getTypeIndex(target) { | |
1143 var | |
1144 is = getAttribute.call(target, 'is'), | |
1145 nodeName = target.nodeName.toUpperCase(), | |
1146 i = indexOf.call( | |
1147 types, | |
1148 is ? | |
1149 PREFIX_IS + is.toUpperCase() : | |
1150 PREFIX_TAG + nodeName | |
1151 ) | |
1152 ; | |
1153 return is && -1 < i && !isInQSA(nodeName, is) ? -1 : i; | |
1154 } | |
1155 | |
1156 function isInQSA(name, type) { | |
1157 return -1 < query.indexOf(name + '[is="' + type + '"]'); | |
1158 } | |
1159 | |
1160 function onDOMAttrModified(e) { | |
1161 var | |
1162 node = e.currentTarget, | |
1163 attrChange = e.attrChange, | |
1164 attrName = e.attrName, | |
1165 target = e.target, | |
1166 addition = e[ADDITION] || 2, | |
1167 removal = e[REMOVAL] || 3 | |
1168 ; | |
1169 if (notFromInnerHTMLHelper && | |
1170 (!target || target === node) && | |
1171 node[ATTRIBUTE_CHANGED_CALLBACK] && | |
1172 attrName !== 'style' && ( | |
1173 e.prevValue !== e.newValue || | |
1174 // IE9, IE10, and Opera 12 gotcha | |
1175 e.newValue === '' && ( | |
1176 attrChange === addition || | |
1177 attrChange === removal | |
1178 ) | |
1179 )) { | |
1180 node[ATTRIBUTE_CHANGED_CALLBACK]( | |
1181 attrName, | |
1182 attrChange === addition ? null : e.prevValue, | |
1183 attrChange === removal ? null : e.newValue | |
1184 ); | |
1185 } | |
1186 } | |
1187 | |
1188 function onDOMNode(action) { | |
1189 var executor = executeAction(action); | |
1190 return function (e) { | |
1191 asapQueue.push(executor, e.target); | |
1192 if (asapTimer) clearTimeout(asapTimer); | |
1193 asapTimer = setTimeout(ASAP, 1); | |
1194 }; | |
1195 } | |
1196 | |
1197 function onReadyStateChange(e) { | |
1198 if (dropDomContentLoaded) { | |
1199 dropDomContentLoaded = false; | |
1200 e.currentTarget.removeEventListener(DOM_CONTENT_LOADED, onReadyStateChange
); | |
1201 } | |
1202 if (query.length) loopAndVerify( | |
1203 (e.target || document).querySelectorAll(query), | |
1204 e.detail === DETACHED ? DETACHED : ATTACHED | |
1205 ); | |
1206 if (IE8) purge(); | |
1207 } | |
1208 | |
1209 function patchedSetAttribute(name, value) { | |
1210 // jshint validthis:true | |
1211 var self = this; | |
1212 setAttribute.call(self, name, value); | |
1213 onSubtreeModified.call(self, {target: self}); | |
1214 } | |
1215 | |
1216 function setupNode(node, proto) { | |
1217 setPrototype(node, proto); | |
1218 if (observer) { | |
1219 observer.observe(node, attributesObserver); | |
1220 } else { | |
1221 if (doesNotSupportDOMAttrModified) { | |
1222 node.setAttribute = patchedSetAttribute; | |
1223 node[EXPANDO_UID] = getAttributesMirror(node); | |
1224 node[ADD_EVENT_LISTENER](DOM_SUBTREE_MODIFIED, onSubtreeModified); | |
1225 } | |
1226 node[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, onDOMAttrModified); | |
1227 } | |
1228 if (node[CREATED_CALLBACK] && notFromInnerHTMLHelper) { | |
1229 node.created = true; | |
1230 node[CREATED_CALLBACK](); | |
1231 node.created = false; | |
1232 } | |
1233 } | |
1234 | |
1235 function purge() { | |
1236 for (var | |
1237 node, | |
1238 i = 0, | |
1239 length = targets.length; | |
1240 i < length; i++ | |
1241 ) { | |
1242 node = targets[i]; | |
1243 if (!documentElement.contains(node)) { | |
1244 length--; | |
1245 targets.splice(i--, 1); | |
1246 verifyAndSetupAndAction(node, DETACHED); | |
1247 } | |
1248 } | |
1249 } | |
1250 | |
1251 function throwTypeError(type) { | |
1252 throw new Error('A ' + type + ' type is already registered'); | |
1253 } | |
1254 | |
1255 function verifyAndSetupAndAction(node, action) { | |
1256 var | |
1257 fn, | |
1258 i = getTypeIndex(node), | |
1259 counterAction | |
1260 ; | |
1261 if (-1 < i) { | |
1262 patchIfNotAlready(node, protos[i]); | |
1263 i = 0; | |
1264 if (action === ATTACHED && !node[ATTACHED]) { | |
1265 node[DETACHED] = false; | |
1266 node[ATTACHED] = true; | |
1267 counterAction = 'connected'; | |
1268 i = 1; | |
1269 if (IE8 && indexOf.call(targets, node) < 0) { | |
1270 targets.push(node); | |
1271 } | |
1272 } else if (action === DETACHED && !node[DETACHED]) { | |
1273 node[ATTACHED] = false; | |
1274 node[DETACHED] = true; | |
1275 counterAction = 'disconnected'; | |
1276 i = 1; | |
1277 } | |
1278 if (i && (fn = ( | |
1279 node[action + CALLBACK] || | |
1280 node[counterAction + CALLBACK] | |
1281 ))) fn.call(node); | |
1282 } | |
1283 } | |
1284 | |
1285 | |
1286 | |
1287 // V1 in da House! | |
1288 function CustomElementRegistry() {} | |
1289 | |
1290 CustomElementRegistry.prototype = { | |
1291 constructor: CustomElementRegistry, | |
1292 // a workaround for the stubborn WebKit | |
1293 define: usableCustomElements ? | |
1294 function (name, Class, options) { | |
1295 if (options) { | |
1296 CERDefine(name, Class, options); | |
1297 } else { | |
1298 var NAME = name.toUpperCase(); | |
1299 constructors[NAME] = { | |
1300 constructor: Class, | |
1301 create: [NAME] | |
1302 }; | |
1303 nodeNames.set(Class, NAME); | |
1304 customElements.define(name, Class); | |
1305 } | |
1306 } : | |
1307 CERDefine, | |
1308 get: usableCustomElements ? | |
1309 function (name) { | |
1310 return customElements.get(name) || get(name); | |
1311 } : | |
1312 get, | |
1313 whenDefined: usableCustomElements ? | |
1314 function (name) { | |
1315 return Promise.race([ | |
1316 customElements.whenDefined(name), | |
1317 whenDefined(name) | |
1318 ]); | |
1319 } : | |
1320 whenDefined | |
1321 }; | |
1322 | |
1323 function CERDefine(name, Class, options) { | |
1324 var | |
1325 is = options && options[EXTENDS] || '', | |
1326 CProto = Class.prototype, | |
1327 proto = create(CProto), | |
1328 attributes = Class.observedAttributes || empty, | |
1329 definition = {prototype: proto} | |
1330 ; | |
1331 // TODO: is this needed at all since it's inherited? | |
1332 // defineProperty(proto, 'constructor', {value: Class}); | |
1333 safeProperty(proto, CREATED_CALLBACK, { | |
1334 value: function () { | |
1335 if (justCreated) justCreated = false; | |
1336 else if (!this[DRECEV1]) { | |
1337 this[DRECEV1] = true; | |
1338 new Class(this); | |
1339 if (CProto[CREATED_CALLBACK]) | |
1340 CProto[CREATED_CALLBACK].call(this); | |
1341 var info = constructors[nodeNames.get(Class)]; | |
1342 if (!usableCustomElements || info.create.length > 1) { | |
1343 notifyAttributes(this); | |
1344 } | |
1345 } | |
1346 } | |
1347 }); | |
1348 safeProperty(proto, ATTRIBUTE_CHANGED_CALLBACK, { | |
1349 value: function (name) { | |
1350 if (-1 < indexOf.call(attributes, name)) | |
1351 CProto[ATTRIBUTE_CHANGED_CALLBACK].apply(this, arguments); | |
1352 } | |
1353 }); | |
1354 if (CProto[CONNECTED_CALLBACK]) { | |
1355 safeProperty(proto, ATTACHED_CALLBACK, { | |
1356 value: CProto[CONNECTED_CALLBACK] | |
1357 }); | |
1358 } | |
1359 if (CProto[DISCONNECTED_CALLBACK]) { | |
1360 safeProperty(proto, DETACHED_CALLBACK, { | |
1361 value: CProto[DISCONNECTED_CALLBACK] | |
1362 }); | |
1363 } | |
1364 if (is) definition[EXTENDS] = is; | |
1365 name = name.toUpperCase(); | |
1366 constructors[name] = { | |
1367 constructor: Class, | |
1368 create: is ? [is, secondArgument(name)] : [name] | |
1369 }; | |
1370 nodeNames.set(Class, name); | |
1371 document[REGISTER_ELEMENT](name.toLowerCase(), definition); | |
1372 whenDefined(name); | |
1373 waitingList[name].r(); | |
1374 } | |
1375 | |
1376 function get(name) { | |
1377 var info = constructors[name.toUpperCase()]; | |
1378 return info && info.constructor; | |
1379 } | |
1380 | |
1381 function getIs(options) { | |
1382 return typeof options === 'string' ? | |
1383 options : (options && options.is || ''); | |
1384 } | |
1385 | |
1386 function notifyAttributes(self) { | |
1387 var | |
1388 callback = self[ATTRIBUTE_CHANGED_CALLBACK], | |
1389 attributes = callback ? self.attributes : empty, | |
1390 i = attributes.length, | |
1391 attribute | |
1392 ; | |
1393 while (i--) { | |
1394 attribute = attributes[i]; // || attributes.item(i); | |
1395 callback.call( | |
1396 self, | |
1397 attribute.name || attribute.nodeName, | |
1398 null, | |
1399 attribute.value || attribute.nodeValue | |
1400 ); | |
1401 } | |
1402 } | |
1403 | |
1404 function whenDefined(name) { | |
1405 name = name.toUpperCase(); | |
1406 if (!(name in waitingList)) { | |
1407 waitingList[name] = {}; | |
1408 waitingList[name].p = new Promise(function (resolve) { | |
1409 waitingList[name].r = resolve; | |
1410 }); | |
1411 } | |
1412 return waitingList[name].p; | |
1413 } | |
1414 | |
1415 function polyfillV1() { | |
1416 if (customElements) delete window.customElements; | |
1417 defineProperty(window, 'customElements', { | |
1418 configurable: true, | |
1419 value: new CustomElementRegistry() | |
1420 }); | |
1421 defineProperty(window, 'CustomElementRegistry', { | |
1422 configurable: true, | |
1423 value: CustomElementRegistry | |
1424 }); | |
1425 for (var | |
1426 patchClass = function (name) { | |
1427 var Class = window[name]; | |
1428 if (Class) { | |
1429 window[name] = function CustomElementsV1(self) { | |
1430 var info, isNative; | |
1431 if (!self) self = this; | |
1432 if (!self[DRECEV1]) { | |
1433 justCreated = true; | |
1434 info = constructors[nodeNames.get(self.constructor)]; | |
1435 isNative = usableCustomElements && info.create.length === 1; | |
1436 self = isNative ? | |
1437 Reflect.construct(Class, empty, info.constructor) : | |
1438 document.createElement.apply(document, info.create); | |
1439 self[DRECEV1] = true; | |
1440 justCreated = false; | |
1441 if (!isNative) notifyAttributes(self); | |
1442 } | |
1443 return self; | |
1444 }; | |
1445 window[name].prototype = Class.prototype; | |
1446 try { | |
1447 Class.prototype.constructor = window[name]; | |
1448 } catch(WebKit) { | |
1449 fixGetClass = true; | |
1450 defineProperty(Class, DRECEV1, {value: window[name]}); | |
1451 } | |
1452 } | |
1453 }, | |
1454 Classes = htmlClass.get(/^HTML[A-Z]*[a-z]/), | |
1455 i = Classes.length; | |
1456 i--; | |
1457 patchClass(Classes[i]) | |
1458 ) {} | |
1459 (document.createElement = function (name, options) { | |
1460 var is = getIs(options); | |
1461 return is ? | |
1462 patchedCreateElement.call(this, name, secondArgument(is)) : | |
1463 patchedCreateElement.call(this, name); | |
1464 }); | |
1465 if (!V0) { | |
1466 justSetup = true; | |
1467 document[REGISTER_ELEMENT](''); | |
1468 } | |
1469 } | |
1470 | |
1471 // if customElements is not there at all | |
1472 if (!customElements || /^force/.test(polyfill.type)) polyfillV1(); | |
1473 else if(!polyfill.noBuiltIn) { | |
1474 // if available test extends work as expected | |
1475 try { | |
1476 (function (DRE, options, name) { | |
1477 options[EXTENDS] = 'a'; | |
1478 DRE.prototype = create(HTMLAnchorElement.prototype); | |
1479 DRE.prototype.constructor = DRE; | |
1480 window.customElements.define(name, DRE, options); | |
1481 if ( | |
1482 getAttribute.call(document.createElement('a', {is: name}), 'is') !== n
ame || | |
1483 (usableCustomElements && getAttribute.call(new DRE(), 'is') !== name) | |
1484 ) { | |
1485 throw options; | |
1486 } | |
1487 }( | |
1488 function DRE() { | |
1489 return Reflect.construct(HTMLAnchorElement, [], DRE); | |
1490 }, | |
1491 {}, | |
1492 'document-register-element-a' | |
1493 )); | |
1494 } catch(o_O) { | |
1495 // or force the polyfill if not | |
1496 // and keep internal original reference | |
1497 polyfillV1(); | |
1498 } | |
1499 } | |
1500 | |
1501 // FireFox only issue | |
1502 if(!polyfill.noBuiltIn) { | |
1503 try { | |
1504 createElement.call(document, 'a', 'a'); | |
1505 } catch(FireFox) { | |
1506 secondArgument = function (is) { | |
1507 return {is: is.toLowerCase()}; | |
1508 }; | |
1509 } | |
1510 } | |
1511 | |
1512 } | |
1513 | |
1514 module.exports = installCustomElements; | |
1515 | |
1516 },{}],3:[function(require,module,exports){ | |
1517 'use strict'; | |
1518 /*! (C) 2017 Andrea Giammarchi - ISC Style License */ | |
1519 | |
1520 const {Component, bind, define, hyper, wire} = require('hyperhtml/cjs'); | |
1521 | |
1522 const _init$ = {value: false}; | |
1523 | |
1524 const defineProperty = Object.defineProperty; | |
1525 | |
1526 const extend = (target, source) => { | |
1527 for (const key in source) target[key] = source[key]; | |
1528 }; | |
1529 | |
1530 class HyperHTMLElement extends HTMLElement { | |
1531 | |
1532 // define a custom-element in the CustomElementsRegistry | |
1533 // class MyEl extends HyperHTMLElement {} | |
1534 // MyEl.define('my-el'); | |
1535 static define(name) { | |
1536 const Class = this; | |
1537 const proto = Class.prototype; | |
1538 | |
1539 // if observedAttributes contains attributes to observe | |
1540 // HyperHTMLElement will directly reflect get/setAttribute | |
1541 // operation once these attributes are used, example: | |
1542 // el.observed = 123; | |
1543 // will automatically do | |
1544 // el.setAttribute('observed', 123); | |
1545 // triggering also the attributeChangedCallback | |
1546 (Class.observedAttributes || []).forEach(name => { | |
1547 if (!(name in proto)) defineProperty( | |
1548 proto, | |
1549 name.replace(/-([a-z])/g, ($0, $1) => $1.toUpperCase()), | |
1550 { | |
1551 configurable: true, | |
1552 get() { return this.getAttribute(name); }, | |
1553 set(value) { this.setAttribute(name, value); } | |
1554 } | |
1555 ); | |
1556 }); | |
1557 | |
1558 const onChanged = proto.attributeChangedCallback; | |
1559 const hasChange = !!onChanged; | |
1560 | |
1561 // created() {} is the entry point to do whatever you want. | |
1562 // Once the node is live and upgraded as Custom Element. | |
1563 // This method grants to be triggered at the right time, | |
1564 // which is always once, and right before either | |
1565 // attributeChangedCallback or connectedCallback | |
1566 const created = proto.created; | |
1567 if (created) { | |
1568 // used to ensure create() is called once and once only | |
1569 defineProperty( | |
1570 proto, | |
1571 '_init$', | |
1572 { | |
1573 configurable: true, | |
1574 writable: true, | |
1575 value: true | |
1576 } | |
1577 ); | |
1578 | |
1579 // ⚠️ if you need to overwrite/change attributeChangedCallback method | |
1580 // at runtime after class definition, be sure you do so | |
1581 // via Object.defineProperty to preserve its non-enumerable nature. | |
1582 defineProperty( | |
1583 proto, | |
1584 'attributeChangedCallback', | |
1585 { | |
1586 configurable: true, | |
1587 value(name, prev, curr) { | |
1588 if (this._init$) { | |
1589 created.call(defineProperty(this, '_init$', _init$)); | |
1590 } | |
1591 // ensure setting same value twice | |
1592 // won't trigger twice attributeChangedCallback | |
1593 if (hasChange && prev !== curr) { | |
1594 onChanged.apply(this, arguments); | |
1595 } | |
1596 } | |
1597 } | |
1598 ); | |
1599 | |
1600 // ⚠️ if you need to overwrite/change connectedCallback method | |
1601 // at runtime after class definition, be sure you do so | |
1602 // via Object.defineProperty to preserve its non-enumerable nature. | |
1603 const onConnected = proto.connectedCallback; | |
1604 const hasConnect = !!onConnected; | |
1605 defineProperty( | |
1606 proto, | |
1607 'connectedCallback', | |
1608 { | |
1609 configurable: true, | |
1610 value() { | |
1611 if (this._init$) { | |
1612 created.call(defineProperty(this, '_init$', _init$)); | |
1613 } | |
1614 if (hasConnect) { | |
1615 onConnected.apply(this, arguments); | |
1616 } | |
1617 } | |
1618 } | |
1619 ); | |
1620 } else if (hasChange) { | |
1621 // ⚠️ if you need to overwrite/change attributeChangedCallback method | |
1622 // at runtime after class definition, be sure you do so | |
1623 // via Object.defineProperty to preserve its non-enumerable nature. | |
1624 defineProperty( | |
1625 proto, | |
1626 'attributeChangedCallback', | |
1627 { | |
1628 configurable: true, | |
1629 value(name, prev, curr) { | |
1630 // ensure setting same value twice | |
1631 // won't trigger twice attributeChangedCallback | |
1632 if (prev !== curr) { | |
1633 onChanged.apply(this, arguments); | |
1634 } | |
1635 } | |
1636 } | |
1637 ); | |
1638 } | |
1639 | |
1640 // define lazily all handlers | |
1641 // class { handleClick() { ... } | |
1642 // render() { `<a onclick=${this.handleClick}>` } } | |
1643 Object.getOwnPropertyNames(proto).forEach(key => { | |
1644 if (/^handle[A-Z]/.test(key)) { | |
1645 const _key$ = '_' + key + '$'; | |
1646 const method = proto[key]; | |
1647 defineProperty(proto, key, { | |
1648 configurable: true, | |
1649 get() { | |
1650 return this[_key$] || | |
1651 (this[_key$] = method.bind(this)); | |
1652 } | |
1653 }); | |
1654 } | |
1655 }); | |
1656 | |
1657 // whenever you want to directly use the component itself | |
1658 // as EventListener, you can pass it directly. | |
1659 // https://medium.com/@WebReflection/dom-handleevent-a-cross-platform-standa
rd-since-year-2000-5bf17287fd38 | |
1660 // class Reactive extends HyperHTMLElement { | |
1661 // oninput(e) { console.log(this, 'changed', e.target.value); } | |
1662 // render() { this.html`<input oninput="${this}">`; } | |
1663 // } | |
1664 if (!('handleEvent' in proto)) { | |
1665 // ⚠️ if you need to overwrite/change handleEvent method | |
1666 // at runtime after class definition, be sure you do so | |
1667 // via Object.defineProperty to preserve its non-enumerable nature. | |
1668 defineProperty( | |
1669 proto, | |
1670 'handleEvent', | |
1671 { | |
1672 configurable: true, | |
1673 value(event) { | |
1674 this[ | |
1675 (event.currentTarget.dataset || {}).call || | |
1676 ('on' + event.type) | |
1677 ](event); | |
1678 } | |
1679 } | |
1680 ); | |
1681 } | |
1682 | |
1683 customElements.define(name, Class); | |
1684 return Class; | |
1685 } | |
1686 | |
1687 // lazily bind once hyperHTML logic | |
1688 // to either the shadowRoot, if present and open, | |
1689 // the _shadowRoot property, if set due closed shadow root, | |
1690 // or the custom-element itself if no Shadow DOM is used. | |
1691 get html() { | |
1692 return this._html$ || (this.html = bind( | |
1693 // in case of Shadow DOM {mode: "open"}, use it | |
1694 this.shadowRoot || | |
1695 // in case of Shadow DOM {mode: "close"}, use it | |
1696 // this needs the following reference created upfront | |
1697 // this._shadowRoot = this.attachShadow({mode: "close"}); | |
1698 this._shadowRoot || | |
1699 // if no Shadow DOM is used, simply use the component | |
1700 // as container for its own content (it just works too) | |
1701 this | |
1702 )); | |
1703 } | |
1704 | |
1705 // it can be set too if necessary, it won't invoke render() | |
1706 set html(value) { | |
1707 defineProperty(this, '_html$', {configurable: true, value: value}); | |
1708 } | |
1709 | |
1710 // ---------------------// | |
1711 // Basic State Handling // | |
1712 // ---------------------// | |
1713 | |
1714 // overwrite this method with your own render | |
1715 render() {} | |
1716 | |
1717 // define the default state object | |
1718 // you could use observed properties too | |
1719 get defaultState() { return {}; } | |
1720 | |
1721 // the state with a default | |
1722 get state() { | |
1723 return this._state$ || (this.state = this.defaultState); | |
1724 } | |
1725 | |
1726 // it can be set too if necessary, it won't invoke render() | |
1727 set state(value) { | |
1728 defineProperty(this, '_state$', {configurable: true, value: value}); | |
1729 } | |
1730 | |
1731 // currently a state is a shallow copy, like in Preact or other libraries. | |
1732 // after the state is updated, the render() method will be invoked. | |
1733 // ⚠️ do not ever call this.setState() inside this.render() | |
1734 setState(state) { | |
1735 extend( | |
1736 this.state, | |
1737 typeof state === 'function' ? | |
1738 state.call(this, this.state) : state | |
1739 ); | |
1740 this.render(); | |
1741 } | |
1742 | |
1743 }; | |
1744 | |
1745 // exposing hyperHTML utilities | |
1746 HyperHTMLElement.Component = Component; | |
1747 HyperHTMLElement.bind = bind; | |
1748 HyperHTMLElement.intent = define; | |
1749 HyperHTMLElement.wire = wire; | |
1750 HyperHTMLElement.hyper = hyper; | |
1751 | |
1752 Object.defineProperty(exports, '__esModule', {value: true}).default = HyperHTMLE
lement; | |
1753 | |
1754 },{"hyperhtml/cjs":8}],4:[function(require,module,exports){ | |
1755 'use strict'; | |
1756 const { UID } = require('../shared/constants.js'); | |
1757 const { WeakMap } = require('../shared/poorlyfills.js'); | |
1758 | |
1759 // hyperHTML.Component is a very basic class | |
1760 // able to create Custom Elements like components | |
1761 // including the ability to listen to connect/disconnect | |
1762 // events via onconnect/ondisconnect attributes | |
1763 // Components can be created imperatively or declaratively. | |
1764 // The main difference is that declared components | |
1765 // will not automatically render on setState(...) | |
1766 // to simplify state handling on render. | |
1767 function Component() {} | |
1768 Object.defineProperty(exports, '__esModule', {value: true}).default = Component | |
1769 | |
1770 // components will lazily define html or svg properties | |
1771 // as soon as these are invoked within the .render() method | |
1772 // Such render() method is not provided by the base class | |
1773 // but it must be available through the Component extend. | |
1774 // Declared components could implement a | |
1775 // render(props) method too and use props as needed. | |
1776 function setup(content) { | |
1777 const children = new WeakMap; | |
1778 const create = Object.create; | |
1779 const createEntry = (wm, id, component) => { | |
1780 wm.set(id, component); | |
1781 return component; | |
1782 }; | |
1783 const get = (Class, info, id) => { | |
1784 switch (typeof id) { | |
1785 case 'object': | |
1786 case 'function': | |
1787 const wm = info.w || (info.w = new WeakMap); | |
1788 return wm.get(id) || createEntry(wm, id, new Class); | |
1789 default: | |
1790 const sm = info.p || (info.p = create(null)); | |
1791 return sm[id] || (sm[id] = new Class); | |
1792 } | |
1793 }; | |
1794 const set = context => { | |
1795 const info = {w: null, p: null}; | |
1796 children.set(context, info); | |
1797 return info; | |
1798 }; | |
1799 Object.defineProperties( | |
1800 Component, | |
1801 { | |
1802 for: { | |
1803 configurable: true, | |
1804 value(context, id) { | |
1805 const info = children.get(context) || set(context); | |
1806 return get(this, info, id == null ? 'default' : id); | |
1807 } | |
1808 } | |
1809 } | |
1810 ); | |
1811 Object.defineProperties( | |
1812 Component.prototype, | |
1813 { | |
1814 handleEvent: {value(e) { | |
1815 const ct = e.currentTarget; | |
1816 this[ | |
1817 ('getAttribute' in ct && ct.getAttribute('data-call')) || | |
1818 ('on' + e.type) | |
1819 ](e); | |
1820 }}, | |
1821 html: lazyGetter('html', content), | |
1822 svg: lazyGetter('svg', content), | |
1823 state: lazyGetter('state', function () { return this.defaultState; }), | |
1824 defaultState: {get() { return {}; }}, | |
1825 setState: {value(state, render) { | |
1826 const target = this.state; | |
1827 const source = typeof state === 'function' ? state.call(this, target) :
state; | |
1828 for (const key in source) target[key] = source[key]; | |
1829 if (render !== false) this.render(); | |
1830 return this; | |
1831 }} | |
1832 } | |
1833 ); | |
1834 } | |
1835 exports.setup = setup | |
1836 | |
1837 // instead of a secret key I could've used a WeakMap | |
1838 // However, attaching a property directly will result | |
1839 // into better performance with thousands of components | |
1840 // hanging around, and less memory pressure caused by the WeakMap | |
1841 const lazyGetter = (type, fn) => { | |
1842 const secret = '_' + type + '$'; | |
1843 return { | |
1844 get() { | |
1845 return this[secret] || (this[type] = fn.call(this, type)); | |
1846 }, | |
1847 set(value) { | |
1848 Object.defineProperty(this, secret, {configurable: true, value}); | |
1849 } | |
1850 }; | |
1851 }; | |
1852 | |
1853 },{"../shared/constants.js":13,"../shared/poorlyfills.js":17}],5:[function(requi
re,module,exports){ | |
1854 'use strict'; | |
1855 const { append } = require('../shared/utils.js'); | |
1856 const { doc, fragment } = require('../shared/easy-dom.js'); | |
1857 | |
1858 function Wire(childNodes) { | |
1859 this.childNodes = childNodes; | |
1860 this.length = childNodes.length; | |
1861 this.first = childNodes[0]; | |
1862 this.last = childNodes[this.length - 1]; | |
1863 } | |
1864 Object.defineProperty(exports, '__esModule', {value: true}).default = Wire | |
1865 | |
1866 // when a wire is inserted, all its nodes will follow | |
1867 Wire.prototype.insert = function insert() { | |
1868 const df = fragment(this.first); | |
1869 append(df, this.childNodes); | |
1870 return df; | |
1871 }; | |
1872 | |
1873 // when a wire is removed, all its nodes must be removed as well | |
1874 Wire.prototype.remove = function remove() { | |
1875 const first = this.first; | |
1876 const last = this.last; | |
1877 if (this.length === 2) { | |
1878 last.parentNode.removeChild(last); | |
1879 } else { | |
1880 const range = doc(first).createRange(); | |
1881 range.setStartBefore(this.childNodes[1]); | |
1882 range.setEndAfter(last); | |
1883 range.deleteContents(); | |
1884 } | |
1885 return first; | |
1886 }; | |
1887 | |
1888 },{"../shared/easy-dom.js":15,"../shared/utils.js":19}],6:[function(require,modu
le,exports){ | |
1889 'use strict'; | |
1890 const {Map, WeakMap} = require('../shared/poorlyfills.js'); | |
1891 const {UIDC, VOID_ELEMENTS} = require('../shared/constants.js'); | |
1892 const Updates = (m => m.__esModule ? m.default : m)(require('../objects/Updates.
js')); | |
1893 const { | |
1894 createFragment, | |
1895 importNode, | |
1896 unique | |
1897 } = require('../shared/utils.js'); | |
1898 | |
1899 const {selfClosing} = require('../shared/re.js'); | |
1900 | |
1901 // a weak collection of contexts that | |
1902 // are already known to hyperHTML | |
1903 const bewitched = new WeakMap; | |
1904 | |
1905 // the collection of all template literals | |
1906 // since these are unique and immutable | |
1907 // for the whole application life-cycle | |
1908 const templates = new Map; | |
1909 | |
1910 // better known as hyper.bind(node), the render is | |
1911 // the main tag function in charge of fully upgrading | |
1912 // or simply updating, contexts used as hyperHTML targets. | |
1913 // The `this` context is either a regular DOM node or a fragment. | |
1914 function render(template) { | |
1915 const wicked = bewitched.get(this); | |
1916 if (wicked && wicked.template === unique(template)) { | |
1917 update.apply(wicked.updates, arguments); | |
1918 } else { | |
1919 upgrade.apply(this, arguments); | |
1920 } | |
1921 return this; | |
1922 } | |
1923 | |
1924 // an upgrade is in charge of collecting template info, | |
1925 // parse it once, if unknown, to map all interpolations | |
1926 // as single DOM callbacks, relate such template | |
1927 // to the current context, and render it after cleaning the context up | |
1928 function upgrade(template) { | |
1929 template = unique(template); | |
1930 const info = templates.get(template) || | |
1931 createTemplate.call(this, template); | |
1932 const fragment = importNode(this.ownerDocument, info.fragment); | |
1933 const updates = Updates.create(fragment, info.paths); | |
1934 bewitched.set(this, {template, updates}); | |
1935 update.apply(updates, arguments); | |
1936 this.textContent = ''; | |
1937 this.appendChild(fragment); | |
1938 } | |
1939 | |
1940 // an update simply loops over all mapped DOM operations | |
1941 function update() { | |
1942 const length = arguments.length; | |
1943 for (let i = 1; i < length; i++) { | |
1944 this[i - 1](arguments[i]); | |
1945 } | |
1946 } | |
1947 | |
1948 // a template can be used to create a document fragment | |
1949 // aware of all interpolations and with a list | |
1950 // of paths used to find once those nodes that need updates, | |
1951 // no matter if these are attributes, text nodes, or regular one | |
1952 function createTemplate(template) { | |
1953 const paths = []; | |
1954 const html = template.join(UIDC).replace(SC_RE, SC_PLACE); | |
1955 const fragment = createFragment(this, html); | |
1956 Updates.find(fragment, paths, template.slice()); | |
1957 const info = {fragment, paths}; | |
1958 templates.set(template, info); | |
1959 return info; | |
1960 } | |
1961 | |
1962 // some node could be special though, like a custom element | |
1963 // with a self closing tag, which should work through these changes. | |
1964 const SC_RE = selfClosing; | |
1965 const SC_PLACE = ($0, $1, $2) => { | |
1966 return VOID_ELEMENTS.test($1) ? $0 : ('<' + $1 + $2 + '></' + $1 + '>'); | |
1967 }; | |
1968 | |
1969 Object.defineProperty(exports, '__esModule', {value: true}).default = render; | |
1970 | |
1971 },{"../objects/Updates.js":12,"../shared/constants.js":13,"../shared/poorlyfills
.js":17,"../shared/re.js":18,"../shared/utils.js":19}],7:[function(require,modul
e,exports){ | |
1972 'use strict'; | |
1973 const {ELEMENT_NODE, SVG_NAMESPACE} = require('../shared/constants.js'); | |
1974 const {WeakMap, trim} = require('../shared/poorlyfills.js'); | |
1975 const {fragment} = require('../shared/easy-dom.js'); | |
1976 const {append, slice, unique} = require('../shared/utils.js'); | |
1977 const Wire = (m => m.__esModule ? m.default : m)(require('../classes/Wire.js')); | |
1978 const render = (m => m.__esModule ? m.default : m)(require('./render.js')); | |
1979 | |
1980 // all wires used per each context | |
1981 const wires = new WeakMap; | |
1982 | |
1983 // A wire is a callback used as tag function | |
1984 // to lazily relate a generic object to a template literal. | |
1985 // hyper.wire(user)`<div id=user>${user.name}</div>`; => the div#user | |
1986 // This provides the ability to have a unique DOM structure | |
1987 // related to a unique JS object through a reusable template literal. | |
1988 // A wire can specify a type, as svg or html, and also an id | |
1989 // via html:id or :id convention. Such :id allows same JS objects | |
1990 // to be associated to different DOM structures accordingly with | |
1991 // the used template literal without losing previously rendered parts. | |
1992 const wire = (obj, type) => obj == null ? | |
1993 content(type || 'html') : | |
1994 weakly(obj, type || 'html'); | |
1995 | |
1996 // A wire content is a virtual reference to one or more nodes. | |
1997 // It's represented by either a DOM node, or an Array. | |
1998 // In both cases, the wire content role is to simply update | |
1999 // all nodes through the list of related callbacks. | |
2000 // In few words, a wire content is like an invisible parent node | |
2001 // in charge of updating its content like a bound element would do. | |
2002 const content = type => { | |
2003 let wire, container, content, template, updates; | |
2004 return function (statics) { | |
2005 statics = unique(statics); | |
2006 let setup = template !== statics; | |
2007 if (setup) { | |
2008 template = statics; | |
2009 content = fragment(document); | |
2010 container = type === 'svg' ? | |
2011 document.createElementNS(SVG_NAMESPACE, 'svg') : | |
2012 content; | |
2013 updates = render.bind(container); | |
2014 } | |
2015 updates.apply(null, arguments); | |
2016 if (setup) { | |
2017 if (type === 'svg') { | |
2018 append(content, slice.call(container.childNodes)); | |
2019 } | |
2020 wire = wireContent(content); | |
2021 } | |
2022 return wire; | |
2023 }; | |
2024 }; | |
2025 | |
2026 // wires are weakly created through objects. | |
2027 // Each object can have multiple wires associated | |
2028 // and this is thanks to the type + :id feature. | |
2029 const weakly = (obj, type) => { | |
2030 const i = type.indexOf(':'); | |
2031 let wire = wires.get(obj); | |
2032 let id = type; | |
2033 if (-1 < i) { | |
2034 id = type.slice(i + 1); | |
2035 type = type.slice(0, i) || 'html'; | |
2036 } | |
2037 if (!wire) wires.set(obj, wire = {}); | |
2038 return wire[id] || (wire[id] = content(type)); | |
2039 }; | |
2040 | |
2041 // a document fragment loses its nodes as soon | |
2042 // as it's appended into another node. | |
2043 // This would easily lose wired content | |
2044 // so that on a second render call, the parent | |
2045 // node wouldn't know which node was there | |
2046 // associated to the interpolation. | |
2047 // To prevent hyperHTML to forget about wired nodes, | |
2048 // these are either returned as Array or, if there's ony one entry, | |
2049 // as single referenced node that won't disappear from the fragment. | |
2050 // The initial fragment, at this point, would be used as unique reference. | |
2051 const wireContent = node => { | |
2052 const childNodes = node.childNodes; | |
2053 const length = childNodes.length; | |
2054 const wireNodes = []; | |
2055 for (let i = 0; i < length; i++) { | |
2056 let child = childNodes[i]; | |
2057 if ( | |
2058 child.nodeType === ELEMENT_NODE || | |
2059 trim.call(child.textContent).length !== 0 | |
2060 ) { | |
2061 wireNodes.push(child); | |
2062 } | |
2063 } | |
2064 return wireNodes.length === 1 ? wireNodes[0] : new Wire(wireNodes); | |
2065 }; | |
2066 | |
2067 exports.content = content; | |
2068 exports.weakly = weakly; | |
2069 Object.defineProperty(exports, '__esModule', {value: true}).default = wire; | |
2070 | |
2071 },{"../classes/Wire.js":5,"../shared/constants.js":13,"../shared/easy-dom.js":15
,"../shared/poorlyfills.js":17,"../shared/utils.js":19,"./render.js":6}],8:[func
tion(require,module,exports){ | |
2072 'use strict'; | |
2073 /*! (c) Andrea Giammarchi (ISC) */ | |
2074 | |
2075 const Component = (m => m.__esModule ? m.default : m)(require('./classes/Compone
nt.js')); | |
2076 const {setup} = require('./classes/Component.js'); | |
2077 const Intent = (m => m.__esModule ? m.default : m)(require('./objects/Intent.js'
)); | |
2078 const wire = (m => m.__esModule ? m.default : m)(require('./hyper/wire.js')); | |
2079 const {content, weakly} = require('./hyper/wire.js'); | |
2080 const render = (m => m.__esModule ? m.default : m)(require('./hyper/render.js'))
; | |
2081 const diff = (m => m.__esModule ? m.default : m)(require('./shared/domdiff.js'))
; | |
2082 | |
2083 // all functions are self bound to the right context | |
2084 // you can do the following | |
2085 // const {bind, wire} = hyperHTML; | |
2086 // and use them right away: bind(node)`hello!`; | |
2087 const bind = context => render.bind(context); | |
2088 const define = Intent.define; | |
2089 | |
2090 hyper.Component = Component; | |
2091 hyper.bind = bind; | |
2092 hyper.define = define; | |
2093 hyper.diff = diff; | |
2094 hyper.hyper = hyper; | |
2095 hyper.wire = wire; | |
2096 | |
2097 // the wire content is the lazy defined | |
2098 // html or svg property of each hyper.Component | |
2099 setup(content); | |
2100 | |
2101 // everything is exported directly or through the | |
2102 // hyperHTML callback, when used as top level script | |
2103 exports.Component = Component; | |
2104 exports.bind = bind; | |
2105 exports.define = define; | |
2106 exports.diff = diff; | |
2107 exports.hyper = hyper; | |
2108 exports.wire = wire; | |
2109 | |
2110 // by default, hyperHTML is a smart function | |
2111 // that "magically" understands what's the best | |
2112 // thing to do with passed arguments | |
2113 function hyper(HTML) { | |
2114 return arguments.length < 2 ? | |
2115 (HTML == null ? | |
2116 content('html') : | |
2117 (typeof HTML === 'string' ? | |
2118 hyper.wire(null, HTML) : | |
2119 ('raw' in HTML ? | |
2120 content('html')(HTML) : | |
2121 ('nodeType' in HTML ? | |
2122 hyper.bind(HTML) : | |
2123 weakly(HTML, 'html') | |
2124 ) | |
2125 ) | |
2126 )) : | |
2127 ('raw' in HTML ? | |
2128 content('html') : hyper.wire | |
2129 ).apply(null, arguments); | |
2130 } | |
2131 Object.defineProperty(exports, '__esModule', {value: true}).default = hyper | |
2132 | |
2133 },{"./classes/Component.js":4,"./hyper/render.js":6,"./hyper/wire.js":7,"./objec
ts/Intent.js":9,"./shared/domdiff.js":14}],9:[function(require,module,exports){ | |
2134 'use strict'; | |
2135 const intents = {}; | |
2136 const keys = []; | |
2137 const hasOwnProperty = intents.hasOwnProperty; | |
2138 | |
2139 let length = 0; | |
2140 | |
2141 Object.defineProperty(exports, '__esModule', {value: true}).default = { | |
2142 | |
2143 // hyperHTML.define('intent', (object, update) => {...}) | |
2144 // can be used to define a third parts update mechanism | |
2145 // when every other known mechanism failed. | |
2146 // hyper.define('user', info => info.name); | |
2147 // hyper(node)`<p>${{user}}</p>`; | |
2148 define: (intent, callback) => { | |
2149 if (!(intent in intents)) { | |
2150 length = keys.push(intent); | |
2151 } | |
2152 intents[intent] = callback; | |
2153 }, | |
2154 | |
2155 // this method is used internally as last resort | |
2156 // to retrieve a value out of an object | |
2157 invoke: (object, callback) => { | |
2158 for (let i = 0; i < length; i++) { | |
2159 let key = keys[i]; | |
2160 if (hasOwnProperty.call(object, key)) { | |
2161 return intents[key](object[key], callback); | |
2162 } | |
2163 } | |
2164 } | |
2165 }; | |
2166 | |
2167 },{}],10:[function(require,module,exports){ | |
2168 'use strict'; | |
2169 const { | |
2170 COMMENT_NODE, | |
2171 DOCUMENT_FRAGMENT_NODE, | |
2172 ELEMENT_NODE | |
2173 } = require('../shared/constants.js'); | |
2174 | |
2175 // every template literal interpolation indicates | |
2176 // a precise target in the DOM the template is representing. | |
2177 // `<p id=${'attribute'}>some ${'content'}</p>` | |
2178 // hyperHTML finds only once per template literal, | |
2179 // hence once per entire application life-cycle, | |
2180 // all nodes that are related to interpolations. | |
2181 // These nodes are stored as indexes used to retrieve, | |
2182 // once per upgrade, nodes that will change on each future update. | |
2183 // A path example is [2, 0, 1] representing the operation: | |
2184 // node.childNodes[2].childNodes[0].childNodes[1] | |
2185 // Attributes are addressed via their owner node and their name. | |
2186 const createPath = node => { | |
2187 const path = []; | |
2188 let parentNode; | |
2189 switch (node.nodeType) { | |
2190 case ELEMENT_NODE: | |
2191 case DOCUMENT_FRAGMENT_NODE: | |
2192 parentNode = node; | |
2193 break; | |
2194 case COMMENT_NODE: | |
2195 parentNode = node.parentNode; | |
2196 prepend(path, parentNode, node); | |
2197 break; | |
2198 default: | |
2199 parentNode = node.ownerElement; | |
2200 break; | |
2201 } | |
2202 for ( | |
2203 node = parentNode; | |
2204 (parentNode = parentNode.parentNode); | |
2205 node = parentNode | |
2206 ) { | |
2207 prepend(path, parentNode, node); | |
2208 } | |
2209 return path; | |
2210 }; | |
2211 | |
2212 const prepend = (path, parent, node) => { | |
2213 path.unshift(path.indexOf.call(parent.childNodes, node)); | |
2214 }; | |
2215 | |
2216 Object.defineProperty(exports, '__esModule', {value: true}).default = { | |
2217 create: (type, node, name) => ({type, name, node, path: createPath(node)}), | |
2218 find: (node, path) => { | |
2219 const length = path.length; | |
2220 for (let i = 0; i < length; i++) { | |
2221 node = node.childNodes[path[i]]; | |
2222 } | |
2223 return node; | |
2224 } | |
2225 } | |
2226 | |
2227 },{"../shared/constants.js":13}],11:[function(require,module,exports){ | |
2228 'use strict'; | |
2229 // from https://github.com/developit/preact/blob/33fc697ac11762a1cb6e71e9847670d
047af7ce5/src/constants.js | |
2230 const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^or
d/i; | |
2231 | |
2232 // style is handled as both string and object | |
2233 // even if the target is an SVG element (consistency) | |
2234 Object.defineProperty(exports, '__esModule', {value: true}).default = (node, ori
ginal, isSVG) => { | |
2235 if (isSVG) { | |
2236 const style = original.cloneNode(true); | |
2237 style.value = ''; | |
2238 node.setAttributeNode(style); | |
2239 return update(style, isSVG); | |
2240 } | |
2241 return update(node.style, isSVG); | |
2242 }; | |
2243 | |
2244 // the update takes care or changing/replacing | |
2245 // only properties that are different or | |
2246 // in case of string, the whole node | |
2247 const update = (style, isSVG) => { | |
2248 let oldType, oldValue; | |
2249 return newValue => { | |
2250 switch (typeof newValue) { | |
2251 case 'object': | |
2252 if (newValue) { | |
2253 if (oldType === 'object') { | |
2254 if (!isSVG) { | |
2255 if (oldValue !== newValue) { | |
2256 for (const key in oldValue) { | |
2257 if (!(key in newValue)) { | |
2258 style[key] = ''; | |
2259 } | |
2260 } | |
2261 } | |
2262 } | |
2263 } else { | |
2264 if (isSVG) style.value = ''; | |
2265 else style.cssText = ''; | |
2266 } | |
2267 const info = isSVG ? {} : style; | |
2268 for (const key in newValue) { | |
2269 const value = newValue[key]; | |
2270 info[key] = typeof value === 'number' && | |
2271 !IS_NON_DIMENSIONAL.test(key) ? | |
2272 (value + 'px') : value; | |
2273 } | |
2274 oldType = 'object'; | |
2275 if (isSVG) style.value = toStyle((oldValue = info)); | |
2276 else oldValue = newValue; | |
2277 break; | |
2278 } | |
2279 default: | |
2280 if (oldValue != newValue) { | |
2281 oldType = 'string'; | |
2282 oldValue = newValue; | |
2283 if (isSVG) style.value = newValue || ''; | |
2284 else style.cssText = newValue || ''; | |
2285 } | |
2286 break; | |
2287 } | |
2288 }; | |
2289 }; | |
2290 | |
2291 const hyphen = /([^A-Z])([A-Z]+)/g; | |
2292 const ized = ($0, $1, $2) => $1 + '-' + $2.toLowerCase(); | |
2293 const toStyle = object => { | |
2294 const css = []; | |
2295 for (const key in object) { | |
2296 css.push(key.replace(hyphen, ized), ':', object[key], ';'); | |
2297 } | |
2298 return css.join(''); | |
2299 }; | |
2300 },{}],12:[function(require,module,exports){ | |
2301 'use strict'; | |
2302 const { | |
2303 CONNECTED, DISCONNECTED, COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, ELEMENT_NODE, T
EXT_NODE, OWNER_SVG_ELEMENT, SHOULD_USE_TEXT_CONTENT, UID, UIDC | |
2304 } = require('../shared/constants.js'); | |
2305 | |
2306 const Component = (m => m.__esModule ? m.default : m)(require('../classes/Compon
ent.js')); | |
2307 const Wire = (m => m.__esModule ? m.default : m)(require('../classes/Wire.js')); | |
2308 const Path = (m => m.__esModule ? m.default : m)(require('./Path.js')); | |
2309 const Style = (m => m.__esModule ? m.default : m)(require('./Style.js')); | |
2310 const Intent = (m => m.__esModule ? m.default : m)(require('./Intent.js')); | |
2311 const domdiff = (m => m.__esModule ? m.default : m)(require('../shared/domdiff.j
s')); | |
2312 const { create: createElement, text } = require('../shared/easy-dom.js'); | |
2313 const { Event, WeakSet, isArray, trim } = require('../shared/poorlyfills.js'); | |
2314 const { createFragment, slice } = require('../shared/utils.js'); | |
2315 | |
2316 // hyper.Component have a connected/disconnected | |
2317 // mechanism provided by MutationObserver | |
2318 // This weak set is used to recognize components | |
2319 // as DOM node that needs to trigger connected/disconnected events | |
2320 const components = new WeakSet; | |
2321 | |
2322 // a basic dictionary used to filter already cached attributes | |
2323 // while looking for special hyperHTML values. | |
2324 function Cache() {} | |
2325 Cache.prototype = Object.create(null); | |
2326 | |
2327 // returns an intent to explicitly inject content as html | |
2328 const asHTML = html => ({html}); | |
2329 | |
2330 // returns nodes from wires and components | |
2331 const asNode = (item, i) => { | |
2332 return 'ELEMENT_NODE' in item ? | |
2333 item : | |
2334 (item.constructor === Wire ? | |
2335 // in the Wire case, the content can be | |
2336 // removed, post-pended, inserted, or pre-pended and | |
2337 // all these cases are handled by domdiff already | |
2338 /* istanbul ignore next */ | |
2339 ((1 / i) < 0 ? | |
2340 (i ? item.remove() : item.last) : | |
2341 (i ? item.insert() : item.first)) : | |
2342 asNode(item.render(), i)); | |
2343 } | |
2344 | |
2345 // returns true if domdiff can handle the value | |
2346 const canDiff = value => 'ELEMENT_NODE' in value || | |
2347 value instanceof Wire || | |
2348 value instanceof Component; | |
2349 | |
2350 // updates are created once per context upgrade | |
2351 // within the main render function (../hyper/render.js) | |
2352 // These are an Array of callbacks to invoke passing | |
2353 // each interpolation value. | |
2354 // Updates can be related to any kind of content, | |
2355 // attributes, or special text-only cases such <style> | |
2356 // elements or <textarea> | |
2357 const create = (root, paths) => { | |
2358 const updates = []; | |
2359 const length = paths.length; | |
2360 for (let i = 0; i < length; i++) { | |
2361 const info = paths[i]; | |
2362 const node = Path.find(root, info.path); | |
2363 switch (info.type) { | |
2364 case 'any': | |
2365 updates.push(setAnyContent(node, [])); | |
2366 break; | |
2367 case 'attr': | |
2368 updates.push(setAttribute(node, info.name, info.node)); | |
2369 break; | |
2370 case 'text': | |
2371 updates.push(setTextContent(node)); | |
2372 break; | |
2373 } | |
2374 } | |
2375 return updates; | |
2376 }; | |
2377 | |
2378 // finding all paths is a one-off operation performed | |
2379 // when a new template literal is used. | |
2380 // The goal is to map all target nodes that will be | |
2381 // used to update content/attributes every time | |
2382 // the same template literal is used to create content. | |
2383 // The result is a list of paths related to the template | |
2384 // with all the necessary info to create updates as | |
2385 // list of callbacks that target directly affected nodes. | |
2386 const find = (node, paths, parts) => { | |
2387 const childNodes = node.childNodes; | |
2388 const length = childNodes.length; | |
2389 for (let i = 0; i < length; i++) { | |
2390 let child = childNodes[i]; | |
2391 switch (child.nodeType) { | |
2392 case ELEMENT_NODE: | |
2393 findAttributes(child, paths, parts); | |
2394 find(child, paths, parts); | |
2395 break; | |
2396 case COMMENT_NODE: | |
2397 if (child.textContent === UID) { | |
2398 parts.shift(); | |
2399 paths.push( | |
2400 // basicHTML or other non standard engines | |
2401 // might end up having comments in nodes | |
2402 // where they shouldn't, hence this check. | |
2403 SHOULD_USE_TEXT_CONTENT.test(node.nodeName) ? | |
2404 Path.create('text', node) : | |
2405 Path.create('any', child) | |
2406 ); | |
2407 } | |
2408 break; | |
2409 case TEXT_NODE: | |
2410 // the following ignore is actually covered by browsers | |
2411 // only basicHTML ends up on previous COMMENT_NODE case | |
2412 // instead of TEXT_NODE because it knows nothing about | |
2413 // special style or textarea behavior | |
2414 /* istanbul ignore if */ | |
2415 if ( | |
2416 SHOULD_USE_TEXT_CONTENT.test(node.nodeName) && | |
2417 trim.call(child.textContent) === UIDC | |
2418 ) { | |
2419 parts.shift(); | |
2420 paths.push(Path.create('text', node)); | |
2421 } | |
2422 break; | |
2423 } | |
2424 } | |
2425 }; | |
2426 | |
2427 // attributes are searched via unique hyperHTML id value. | |
2428 // Despite HTML being case insensitive, hyperHTML is able | |
2429 // to recognize attributes by name in a caseSensitive way. | |
2430 // This plays well with Custom Elements definitions | |
2431 // and also with XML-like environments, without trusting | |
2432 // the resulting DOM but the template literal as the source of truth. | |
2433 // IE/Edge has a funny bug with attributes and these might be duplicated. | |
2434 // This is why there is a cache in charge of being sure no duplicated | |
2435 // attributes are ever considered in future updates. | |
2436 const findAttributes = (node, paths, parts) => { | |
2437 const cache = new Cache; | |
2438 const attributes = node.attributes; | |
2439 const array = slice.call(attributes); | |
2440 const remove = []; | |
2441 const length = array.length; | |
2442 for (let i = 0; i < length; i++) { | |
2443 const attribute = array[i]; | |
2444 if (attribute.value === UID) { | |
2445 const name = attribute.name; | |
2446 // the following ignore is covered by IE | |
2447 // and the IE9 double viewBox test | |
2448 /* istanbul ignore else */ | |
2449 if (!(name in cache)) { | |
2450 const realName = parts.shift().replace(/^(?:|[\S\s]*?\s)(\S+?)=['"]?$/,
'$1'); | |
2451 cache[name] = attributes[realName] || | |
2452 // the following ignore is covered by browsers | |
2453 // while basicHTML is already case-sensitive | |
2454 /* istanbul ignore next */ | |
2455 attributes[realName.toLowerCase()]; | |
2456 paths.push(Path.create('attr', cache[name], realName)); | |
2457 } | |
2458 remove.push(attribute); | |
2459 } | |
2460 } | |
2461 const len = remove.length; | |
2462 for (let i = 0; i < len; i++) { | |
2463 node.removeAttributeNode(remove[i]); | |
2464 } | |
2465 | |
2466 // This is a very specific Firefox/Safari issue | |
2467 // but since it should be a not so common pattern, | |
2468 // it's probably worth patching regardless. | |
2469 // Basically, scripts created through strings are death. | |
2470 // You need to create fresh new scripts instead. | |
2471 // TODO: is there any other node that needs such nonsense ? | |
2472 const nodeName = node.nodeName; | |
2473 if (/^script$/i.test(nodeName)) { | |
2474 const script = createElement(node, nodeName); | |
2475 for (let i = 0; i < attributes.length; i++) { | |
2476 script.setAttributeNode(attributes[i].cloneNode(true)); | |
2477 } | |
2478 script.textContent = node.textContent; | |
2479 node.parentNode.replaceChild(script, node); | |
2480 } | |
2481 }; | |
2482 | |
2483 // when a Promise is used as interpolation value | |
2484 // its result must be parsed once resolved. | |
2485 // This callback is in charge of understanding what to do | |
2486 // with a returned value once the promise is resolved. | |
2487 const invokeAtDistance = (value, callback) => { | |
2488 callback(value.placeholder); | |
2489 if ('text' in value) { | |
2490 Promise.resolve(value.text).then(String).then(callback); | |
2491 } else if ('any' in value) { | |
2492 Promise.resolve(value.any).then(callback); | |
2493 } else if ('html' in value) { | |
2494 Promise.resolve(value.html).then(asHTML).then(callback); | |
2495 } else { | |
2496 Promise.resolve(Intent.invoke(value, callback)).then(callback); | |
2497 } | |
2498 }; | |
2499 | |
2500 // quick and dirty way to check for Promise/ish values | |
2501 const isPromise_ish = value => value != null && 'then' in value; | |
2502 | |
2503 // in a hyper(node)`<div>${content}</div>` case | |
2504 // everything could happen: | |
2505 // * it's a JS primitive, stored as text | |
2506 // * it's null or undefined, the node should be cleaned | |
2507 // * it's a component, update the content by rendering it | |
2508 // * it's a promise, update the content once resolved | |
2509 // * it's an explicit intent, perform the desired operation | |
2510 // * it's an Array, resolve all values if Promises and/or | |
2511 // update the node with the resulting list of content | |
2512 const setAnyContent = (node, childNodes) => { | |
2513 let fastPath = false; | |
2514 let oldValue; | |
2515 const anyContent = value => { | |
2516 switch (typeof value) { | |
2517 case 'string': | |
2518 case 'number': | |
2519 case 'boolean': | |
2520 if (fastPath) { | |
2521 if (oldValue !== value) { | |
2522 oldValue = value; | |
2523 childNodes[0].textContent = value; | |
2524 } | |
2525 } else { | |
2526 fastPath = true; | |
2527 oldValue = value; | |
2528 childNodes = domdiff( | |
2529 node.parentNode, | |
2530 childNodes, | |
2531 [text(node, value)], | |
2532 asNode, | |
2533 node | |
2534 ); | |
2535 } | |
2536 break; | |
2537 case 'object': | |
2538 case 'undefined': | |
2539 if (value == null) { | |
2540 fastPath = false; | |
2541 childNodes = domdiff( | |
2542 node.parentNode, | |
2543 childNodes, | |
2544 [], | |
2545 asNode, | |
2546 node | |
2547 ); | |
2548 break; | |
2549 } | |
2550 default: | |
2551 fastPath = false; | |
2552 oldValue = value; | |
2553 if (isArray(value)) { | |
2554 if (value.length === 0) { | |
2555 if (childNodes.length) { | |
2556 childNodes = domdiff( | |
2557 node.parentNode, | |
2558 childNodes, | |
2559 [], | |
2560 asNode, | |
2561 node | |
2562 ); | |
2563 } | |
2564 } else { | |
2565 switch (typeof value[0]) { | |
2566 case 'string': | |
2567 case 'number': | |
2568 case 'boolean': | |
2569 anyContent({html: value}); | |
2570 break; | |
2571 case 'object': | |
2572 if (isArray(value[0])) { | |
2573 value = value.concat.apply([], value); | |
2574 } | |
2575 if (isPromise_ish(value[0])) { | |
2576 Promise.all(value).then(anyContent); | |
2577 break; | |
2578 } | |
2579 default: | |
2580 childNodes = domdiff( | |
2581 node.parentNode, | |
2582 childNodes, | |
2583 value, | |
2584 asNode, | |
2585 node | |
2586 ); | |
2587 break; | |
2588 } | |
2589 } | |
2590 } else if (canDiff(value)) { | |
2591 childNodes = domdiff( | |
2592 node.parentNode, | |
2593 childNodes, | |
2594 value.nodeType === DOCUMENT_FRAGMENT_NODE ? | |
2595 slice.call(value.childNodes) : | |
2596 [value], | |
2597 asNode, | |
2598 node | |
2599 ); | |
2600 } else if (isPromise_ish(value)) { | |
2601 value.then(anyContent); | |
2602 } else if ('placeholder' in value) { | |
2603 invokeAtDistance(value, anyContent); | |
2604 } else if ('text' in value) { | |
2605 anyContent(String(value.text)); | |
2606 } else if ('any' in value) { | |
2607 anyContent(value.any); | |
2608 } else if ('html' in value) { | |
2609 childNodes = domdiff( | |
2610 node.parentNode, | |
2611 childNodes, | |
2612 slice.call( | |
2613 createFragment( | |
2614 node, | |
2615 [].concat(value.html).join('') | |
2616 ).childNodes | |
2617 ), | |
2618 asNode, | |
2619 node | |
2620 ); | |
2621 } else if ('length' in value) { | |
2622 anyContent(slice.call(value)); | |
2623 } else { | |
2624 anyContent(Intent.invoke(value, anyContent)); | |
2625 } | |
2626 break; | |
2627 } | |
2628 }; | |
2629 return anyContent; | |
2630 }; | |
2631 | |
2632 // there are four kind of attributes, and related behavior: | |
2633 // * events, with a name starting with `on`, to add/remove event listeners | |
2634 // * special, with a name present in their inherited prototype, accessed direct
ly | |
2635 // * regular, accessed through get/setAttribute standard DOM methods | |
2636 // * style, the only regular attribute that also accepts an object as value | |
2637 // so that you can style=${{width: 120}}. In this case, the behavior has been | |
2638 // fully inspired by Preact library and its simplicity. | |
2639 const setAttribute = (node, name, original) => { | |
2640 const isSVG = OWNER_SVG_ELEMENT in node; | |
2641 let oldValue; | |
2642 // if the attribute is the style one | |
2643 // handle it differently from others | |
2644 if (name === 'style') { | |
2645 return Style(node, original, isSVG); | |
2646 } | |
2647 // the name is an event one, | |
2648 // add/remove event listeners accordingly | |
2649 else if (/^on/.test(name)) { | |
2650 let type = name.slice(2); | |
2651 if (type === CONNECTED || type === DISCONNECTED) { | |
2652 if (notObserving) { | |
2653 notObserving = false; | |
2654 observe(); | |
2655 } | |
2656 components.add(node); | |
2657 } | |
2658 else if (name.toLowerCase() in node) { | |
2659 type = type.toLowerCase(); | |
2660 } | |
2661 return newValue => { | |
2662 if (oldValue !== newValue) { | |
2663 if (oldValue) node.removeEventListener(type, oldValue, false); | |
2664 oldValue = newValue; | |
2665 if (newValue) node.addEventListener(type, newValue, false); | |
2666 } | |
2667 }; | |
2668 } | |
2669 // the attribute is special ('value' in input) | |
2670 // and it's not SVG *or* the name is exactly data, | |
2671 // in this case assign the value directly | |
2672 else if (name === 'data' || (!isSVG && name in node)) { | |
2673 return newValue => { | |
2674 if (oldValue !== newValue) { | |
2675 oldValue = newValue; | |
2676 if (node[name] !== newValue) { | |
2677 node[name] = newValue; | |
2678 if (newValue == null) { | |
2679 node.removeAttribute(name); | |
2680 } | |
2681 } | |
2682 } | |
2683 }; | |
2684 } | |
2685 // in every other case, use the attribute node as it is | |
2686 // update only the value, set it as node only when/if needed | |
2687 else { | |
2688 let owner = false; | |
2689 const attribute = original.cloneNode(true); | |
2690 return newValue => { | |
2691 if (oldValue !== newValue) { | |
2692 oldValue = newValue; | |
2693 if (attribute.value !== newValue) { | |
2694 if (newValue == null) { | |
2695 if (owner) { | |
2696 owner = false; | |
2697 node.removeAttributeNode(attribute); | |
2698 } | |
2699 attribute.value = newValue; | |
2700 } else { | |
2701 attribute.value = newValue; | |
2702 if (!owner) { | |
2703 owner = true; | |
2704 node.setAttributeNode(attribute); | |
2705 } | |
2706 } | |
2707 } | |
2708 } | |
2709 }; | |
2710 } | |
2711 }; | |
2712 | |
2713 // style or textareas don't accept HTML as content | |
2714 // it's pointless to transform or analyze anything | |
2715 // different from text there but it's worth checking | |
2716 // for possible defined intents. | |
2717 const setTextContent = node => { | |
2718 // avoid hyper comments inside textarea/style when value is undefined | |
2719 let oldValue = ''; | |
2720 const textContent = value => { | |
2721 if (oldValue !== value) { | |
2722 oldValue = value; | |
2723 if (typeof value === 'object' && value) { | |
2724 if (isPromise_ish(value)) { | |
2725 value.then(textContent); | |
2726 } else if ('placeholder' in value) { | |
2727 invokeAtDistance(value, textContent); | |
2728 } else if ('text' in value) { | |
2729 textContent(String(value.text)); | |
2730 } else if ('any' in value) { | |
2731 textContent(value.any); | |
2732 } else if ('html' in value) { | |
2733 textContent([].concat(value.html).join('')); | |
2734 } else if ('length' in value) { | |
2735 textContent(slice.call(value).join('')); | |
2736 } else { | |
2737 textContent(Intent.invoke(value, textContent)); | |
2738 } | |
2739 } else { | |
2740 node.textContent = value == null ? '' : value; | |
2741 } | |
2742 } | |
2743 }; | |
2744 return textContent; | |
2745 }; | |
2746 | |
2747 Object.defineProperty(exports, '__esModule', {value: true}).default = {create, f
ind}; | |
2748 | |
2749 // hyper.Components might need connected/disconnected notifications | |
2750 // used by components and their onconnect/ondisconnect callbacks. | |
2751 // When one of these callbacks is encountered, | |
2752 // the document starts being observed. | |
2753 let notObserving = true; | |
2754 function observe() { | |
2755 | |
2756 // when hyper.Component related DOM nodes | |
2757 // are appended or removed from the live tree | |
2758 // these might listen to connected/disconnected events | |
2759 // This utility is in charge of finding all components | |
2760 // involved in the DOM update/change and dispatch | |
2761 // related information to them | |
2762 const dispatchAll = (nodes, type) => { | |
2763 const event = new Event(type); | |
2764 const length = nodes.length; | |
2765 for (let i = 0; i < length; i++) { | |
2766 let node = nodes[i]; | |
2767 if (node.nodeType === ELEMENT_NODE) { | |
2768 dispatchTarget(node, event); | |
2769 } | |
2770 } | |
2771 }; | |
2772 | |
2773 // the way it's done is via the components weak set | |
2774 // and recursively looking for nested components too | |
2775 const dispatchTarget = (node, event) => { | |
2776 if (components.has(node)) { | |
2777 node.dispatchEvent(event); | |
2778 } | |
2779 | |
2780 const children = node.children; | |
2781 const length = children.length; | |
2782 for (let i = 0; i < length; i++) { | |
2783 dispatchTarget(children[i], event); | |
2784 } | |
2785 } | |
2786 | |
2787 // The MutationObserver is the best way to implement that | |
2788 // but there is a fallback to deprecated DOMNodeInserted/Removed | |
2789 // so that even older browsers/engines can help components life-cycle | |
2790 try { | |
2791 (new MutationObserver(records => { | |
2792 const length = records.length; | |
2793 for (let i = 0; i < length; i++) { | |
2794 let record = records[i]; | |
2795 dispatchAll(record.removedNodes, DISCONNECTED); | |
2796 dispatchAll(record.addedNodes, CONNECTED); | |
2797 } | |
2798 })).observe(document, {subtree: true, childList: true}); | |
2799 } catch(o_O) { | |
2800 document.addEventListener('DOMNodeRemoved', event => { | |
2801 dispatchAll([event.target], DISCONNECTED); | |
2802 }, false); | |
2803 document.addEventListener('DOMNodeInserted', event => { | |
2804 dispatchAll([event.target], CONNECTED); | |
2805 }, false); | |
2806 } | |
2807 } | |
2808 | |
2809 },{"../classes/Component.js":4,"../classes/Wire.js":5,"../shared/constants.js":1
3,"../shared/domdiff.js":14,"../shared/easy-dom.js":15,"../shared/poorlyfills.js
":17,"../shared/utils.js":19,"./Intent.js":9,"./Path.js":10,"./Style.js":11}],13
:[function(require,module,exports){ | |
2810 'use strict'; | |
2811 const G = document.defaultView; | |
2812 exports.G = G; | |
2813 | |
2814 // Node.CONSTANTS | |
2815 // 'cause some engine has no global Node defined | |
2816 // (i.e. Node, NativeScript, basicHTML ... ) | |
2817 const ELEMENT_NODE = 1; | |
2818 exports.ELEMENT_NODE = ELEMENT_NODE; | |
2819 const ATTRIBUTE_NODE = 2; | |
2820 exports.ATTRIBUTE_NODE = ATTRIBUTE_NODE; | |
2821 const TEXT_NODE = 3; | |
2822 exports.TEXT_NODE = TEXT_NODE; | |
2823 const COMMENT_NODE = 8; | |
2824 exports.COMMENT_NODE = COMMENT_NODE; | |
2825 const DOCUMENT_FRAGMENT_NODE = 11; | |
2826 exports.DOCUMENT_FRAGMENT_NODE = DOCUMENT_FRAGMENT_NODE; | |
2827 | |
2828 // HTML related constants | |
2829 const VOID_ELEMENTS = /^area|base|br|col|embed|hr|img|input|keygen|link|menuitem
|meta|param|source|track|wbr$/i; | |
2830 exports.VOID_ELEMENTS = VOID_ELEMENTS; | |
2831 | |
2832 // SVG related constants | |
2833 const OWNER_SVG_ELEMENT = 'ownerSVGElement'; | |
2834 exports.OWNER_SVG_ELEMENT = OWNER_SVG_ELEMENT; | |
2835 const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; | |
2836 exports.SVG_NAMESPACE = SVG_NAMESPACE; | |
2837 | |
2838 // Custom Elements / MutationObserver constants | |
2839 const CONNECTED = 'connected'; | |
2840 exports.CONNECTED = CONNECTED; | |
2841 const DISCONNECTED = 'dis' + CONNECTED; | |
2842 exports.DISCONNECTED = DISCONNECTED; | |
2843 | |
2844 // hyperHTML related constants | |
2845 const EXPANDO = '_hyper: '; | |
2846 exports.EXPANDO = EXPANDO; | |
2847 const SHOULD_USE_TEXT_CONTENT = /^style|textarea$/i; | |
2848 exports.SHOULD_USE_TEXT_CONTENT = SHOULD_USE_TEXT_CONTENT; | |
2849 const UID = EXPANDO + ((Math.random() * new Date) | 0) + ';'; | |
2850 exports.UID = UID; | |
2851 const UIDC = '<!--' + UID + '-->'; | |
2852 exports.UIDC = UIDC; | |
2853 | |
2854 },{}],14:[function(require,module,exports){ | |
2855 'use strict'; | |
2856 /* AUTOMATICALLY IMPORTED, DO NOT MODIFY */ | |
2857 /*! (c) 2017 Andrea Giammarchi (ISC) */ | |
2858 | |
2859 /** | |
2860 * This code is a revisited port of the snabbdom vDOM diffing logic, | |
2861 * the same that fuels as fork Vue.js or other libraries. | |
2862 * @credits https://github.com/snabbdom/snabbdom | |
2863 */ | |
2864 | |
2865 const identity = O => O; | |
2866 | |
2867 const domdiff = ( | |
2868 parentNode, // where changes happen | |
2869 currentNodes, // Array of current items/nodes | |
2870 futureNodes, // Array of future items/nodes | |
2871 getNode, // optional way to retrieve a node from an item | |
2872 beforeNode // optional item/node to use as insertBefore delimiter | |
2873 ) => { | |
2874 const get = getNode || identity; | |
2875 const before = beforeNode == null ? null : get(beforeNode, 0); | |
2876 let currentStart = 0, futureStart = 0; | |
2877 let currentEnd = currentNodes.length - 1; | |
2878 let currentStartNode = currentNodes[0]; | |
2879 let currentEndNode = currentNodes[currentEnd]; | |
2880 let futureEnd = futureNodes.length - 1; | |
2881 let futureStartNode = futureNodes[0]; | |
2882 let futureEndNode = futureNodes[futureEnd]; | |
2883 while (currentStart <= currentEnd && futureStart <= futureEnd) { | |
2884 if (currentStartNode == null) { | |
2885 currentStartNode = currentNodes[++currentStart]; | |
2886 } | |
2887 else if (currentEndNode == null) { | |
2888 currentEndNode = currentNodes[--currentEnd]; | |
2889 } | |
2890 else if (futureStartNode == null) { | |
2891 futureStartNode = futureNodes[++futureStart]; | |
2892 } | |
2893 else if (futureEndNode == null) { | |
2894 futureEndNode = futureNodes[--futureEnd]; | |
2895 } | |
2896 else if (currentStartNode == futureStartNode) { | |
2897 currentStartNode = currentNodes[++currentStart]; | |
2898 futureStartNode = futureNodes[++futureStart]; | |
2899 } | |
2900 else if (currentEndNode == futureEndNode) { | |
2901 currentEndNode = currentNodes[--currentEnd]; | |
2902 futureEndNode = futureNodes[--futureEnd]; | |
2903 } | |
2904 else if (currentStartNode == futureEndNode) { | |
2905 parentNode.insertBefore( | |
2906 get(currentStartNode, 1), | |
2907 get(currentEndNode, -0).nextSibling | |
2908 ); | |
2909 currentStartNode = currentNodes[++currentStart]; | |
2910 futureEndNode = futureNodes[--futureEnd]; | |
2911 } | |
2912 else if (currentEndNode == futureStartNode) { | |
2913 parentNode.insertBefore( | |
2914 get(currentEndNode, 1), | |
2915 get(currentStartNode, 0) | |
2916 ); | |
2917 currentEndNode = currentNodes[--currentEnd]; | |
2918 futureStartNode = futureNodes[++futureStart]; | |
2919 } | |
2920 else { | |
2921 let index = currentNodes.indexOf(futureStartNode); | |
2922 if (index < 0) { | |
2923 parentNode.insertBefore( | |
2924 get(futureStartNode, 1), | |
2925 get(currentStartNode, 0) | |
2926 ); | |
2927 futureStartNode = futureNodes[++futureStart]; | |
2928 } | |
2929 else { | |
2930 let el = currentNodes[index]; | |
2931 currentNodes[index] = null; | |
2932 parentNode.insertBefore( | |
2933 get(el, 1), | |
2934 get(currentStartNode, 0) | |
2935 ); | |
2936 futureStartNode = futureNodes[++futureStart]; | |
2937 } | |
2938 } | |
2939 } | |
2940 if (currentStart <= currentEnd || futureStart <= futureEnd) { | |
2941 if (currentStart > currentEnd) { | |
2942 const pin = futureNodes[futureEnd + 1]; | |
2943 const place = pin == null ? before : get(pin, 0); | |
2944 if (futureStart === futureEnd) { | |
2945 parentNode.insertBefore(get(futureNodes[futureStart], 1), place); | |
2946 } | |
2947 else { | |
2948 const fragment = parentNode.ownerDocument.createDocumentFragment(); | |
2949 while (futureStart <= futureEnd) { | |
2950 fragment.appendChild(get(futureNodes[futureStart++], 1)); | |
2951 } | |
2952 parentNode.insertBefore(fragment, place); | |
2953 } | |
2954 } | |
2955 else { | |
2956 if (currentNodes[currentStart] == null) currentStart++; | |
2957 if (currentStart === currentEnd) { | |
2958 parentNode.removeChild(get(currentNodes[currentStart], -1)); | |
2959 } | |
2960 else { | |
2961 const range = parentNode.ownerDocument.createRange(); | |
2962 range.setStartBefore(get(currentNodes[currentStart], -1)); | |
2963 range.setEndAfter(get(currentNodes[currentEnd], -1)); | |
2964 range.deleteContents(); | |
2965 } | |
2966 } | |
2967 } | |
2968 return futureNodes; | |
2969 }; | |
2970 | |
2971 Object.defineProperty(exports, '__esModule', {value: true}).default = domdiff; | |
2972 | |
2973 },{}],15:[function(require,module,exports){ | |
2974 'use strict'; | |
2975 // these are tiny helpers to simplify most common operations needed here | |
2976 const create = (node, type) => doc(node).createElement(type); | |
2977 exports.create = create; | |
2978 const doc = node => node.ownerDocument || node; | |
2979 exports.doc = doc; | |
2980 const fragment = node => doc(node).createDocumentFragment(); | |
2981 exports.fragment = fragment; | |
2982 const text = (node, text) => doc(node).createTextNode(text); | |
2983 exports.text = text; | |
2984 | |
2985 },{}],16:[function(require,module,exports){ | |
2986 'use strict'; | |
2987 const {create, fragment, text} = require('./easy-dom.js'); | |
2988 | |
2989 const testFragment = fragment(document); | |
2990 | |
2991 // DOM4 node.append(...many) | |
2992 const hasAppend = 'append' in testFragment; | |
2993 exports.hasAppend = hasAppend; | |
2994 | |
2995 // detect old browsers without HTMLTemplateElement content support | |
2996 const hasContent = 'content' in create(document, 'template'); | |
2997 exports.hasContent = hasContent; | |
2998 | |
2999 // IE 11 has problems with cloning templates: it "forgets" empty childNodes | |
3000 testFragment.appendChild(text(testFragment, 'g')); | |
3001 testFragment.appendChild(text(testFragment, '')); | |
3002 const hasDoomedCloneNode = testFragment.cloneNode(true).childNodes.length === 1; | |
3003 exports.hasDoomedCloneNode = hasDoomedCloneNode; | |
3004 | |
3005 // old browsers need to fallback to cloneNode | |
3006 // Custom Elements V0 and V1 will work polyfilled | |
3007 // but native implementations need importNode instead | |
3008 // (specially Chromium and its old V0 implementation) | |
3009 const hasImportNode = 'importNode' in document; | |
3010 exports.hasImportNode = hasImportNode; | |
3011 | |
3012 },{"./easy-dom.js":15}],17:[function(require,module,exports){ | |
3013 'use strict'; | |
3014 const {G, UID} = require('./constants.js'); | |
3015 | |
3016 // you know that kind of basics you need to cover | |
3017 // your use case only but you don't want to bloat the library? | |
3018 // There's even a package in here: | |
3019 // https://www.npmjs.com/package/poorlyfills | |
3020 | |
3021 // used to dispatch simple events | |
3022 let Event = G.Event; | |
3023 try { | |
3024 new Event('Event'); | |
3025 } catch(o_O) { | |
3026 Event = function (type) { | |
3027 const e = document.createEvent('Event'); | |
3028 e.initEvent(type, false, false); | |
3029 return e; | |
3030 }; | |
3031 } | |
3032 exports.Event = Event; | |
3033 | |
3034 // used to store template literals | |
3035 const Map = G.Map || function Map() { | |
3036 const keys = [], values = []; | |
3037 return { | |
3038 get(obj) { | |
3039 return values[keys.indexOf(obj)]; | |
3040 }, | |
3041 set(obj, value) { | |
3042 values[keys.push(obj) - 1] = value; | |
3043 } | |
3044 }; | |
3045 }; | |
3046 exports.Map = Map; | |
3047 | |
3048 // used to store wired content | |
3049 const WeakMap = G.WeakMap || function WeakMap() { | |
3050 return { | |
3051 get(obj) { return obj[UID]; }, | |
3052 set(obj, value) { | |
3053 Object.defineProperty(obj, UID, { | |
3054 configurable: true, | |
3055 value | |
3056 }); | |
3057 } | |
3058 }; | |
3059 }; | |
3060 exports.WeakMap = WeakMap; | |
3061 | |
3062 // used to store hyper.Components | |
3063 const WeakSet = G.WeakSet || function WeakSet() { | |
3064 const wm = new WeakMap; | |
3065 return { | |
3066 add(obj) { wm.set(obj, true); }, | |
3067 has(obj) { return wm.get(obj) === true; } | |
3068 }; | |
3069 }; | |
3070 exports.WeakSet = WeakSet; | |
3071 | |
3072 // used to be sure IE9 or older Androids work as expected | |
3073 const isArray = Array.isArray || (toString => | |
3074 arr => toString.call(arr) === '[object Array]' | |
3075 )({}.toString); | |
3076 exports.isArray = isArray; | |
3077 | |
3078 const trim = UID.trim || function () { | |
3079 return this.replace(/^\s+|\s+$/g, ''); | |
3080 }; | |
3081 exports.trim = trim; | |
3082 | |
3083 },{"./constants.js":13}],18:[function(require,module,exports){ | |
3084 'use strict'; | |
3085 // TODO: I'd love to code-cover RegExp too here | |
3086 // these are fundamental for this library | |
3087 | |
3088 const spaces = ' \\f\\n\\r\\t'; | |
3089 const almostEverything = '[^ ' + spaces + '\\/>"\'=]+'; | |
3090 const attrName = '[ ' + spaces + ']+' + almostEverything; | |
3091 const tagName = '<([A-Za-z]+[A-Za-z0-9:_-]*)((?:'; | |
3092 const attrPartials = '(?:=(?:\'[^\']*?\'|"[^"]*?"|<[^>]*?>|' + almostEverything
+ '))?)'; | |
3093 | |
3094 const attrSeeker = new RegExp( | |
3095 tagName + attrName + attrPartials + '+)([ ' + spaces + ']*/?>)', | |
3096 'g' | |
3097 ); | |
3098 | |
3099 const selfClosing = new RegExp( | |
3100 tagName + attrName + attrPartials + '*)([ ' + spaces + ']*/>)', | |
3101 'g' | |
3102 ); | |
3103 | |
3104 exports.attrName = attrName; | |
3105 exports.attrSeeker = attrSeeker; | |
3106 exports.selfClosing = selfClosing; | |
3107 | |
3108 },{}],19:[function(require,module,exports){ | |
3109 'use strict'; | |
3110 const {attrName, attrSeeker} = require('./re.js'); | |
3111 | |
3112 const { | |
3113 G, | |
3114 OWNER_SVG_ELEMENT, | |
3115 SVG_NAMESPACE, | |
3116 UID, | |
3117 UIDC | |
3118 } = require('./constants.js'); | |
3119 | |
3120 const { | |
3121 hasAppend, | |
3122 hasContent, | |
3123 hasDoomedCloneNode, | |
3124 hasImportNode | |
3125 } = require('./features-detection.js'); | |
3126 | |
3127 const {create, doc, fragment} = require('./easy-dom.js'); | |
3128 | |
3129 // appends an array of nodes | |
3130 // to a generic node/fragment | |
3131 // When available, uses append passing all arguments at once | |
3132 // hoping that's somehow faster, even if append has more checks on type | |
3133 const append = hasAppend ? | |
3134 (node, childNodes) => { | |
3135 node.append.apply(node, childNodes); | |
3136 } : | |
3137 (node, childNodes) => { | |
3138 const length = childNodes.length; | |
3139 for (let i = 0; i < length; i++) { | |
3140 node.appendChild(childNodes[i]); | |
3141 } | |
3142 }; | |
3143 exports.append = append; | |
3144 | |
3145 const findAttributes = new RegExp('(' + attrName + '=)([\'"]?)' + UIDC + '\\2',
'gi'); | |
3146 const comments = ($0, $1, $2, $3) => | |
3147 '<' + $1 + $2.replace(findAttributes, replaceAttributes) + $3; | |
3148 const replaceAttributes = ($0, $1, $2) => $1 + ($2 || '"') + UID + ($2 || '"'); | |
3149 | |
3150 // given a node and a generic HTML content, | |
3151 // create either an SVG or an HTML fragment | |
3152 // where such content will be injected | |
3153 const createFragment = (node, html) => | |
3154 (OWNER_SVG_ELEMENT in node ? | |
3155 SVGFragment : | |
3156 HTMLFragment | |
3157 )(node, html.replace(attrSeeker, comments)); | |
3158 exports.createFragment = createFragment; | |
3159 | |
3160 // IE/Edge shenanigans proof cloneNode | |
3161 // it goes through all nodes manually | |
3162 // instead of relying the engine to suddenly | |
3163 // merge nodes together | |
3164 const cloneNode = hasDoomedCloneNode ? | |
3165 node => { | |
3166 const clone = node.cloneNode(); | |
3167 const childNodes = node.childNodes || | |
3168 // this is an excess of caution | |
3169 // but some node, in IE, might not | |
3170 // have childNodes property. | |
3171 // The following fallback ensure working code | |
3172 // in older IE without compromising performance | |
3173 // or any other browser/engine involved. | |
3174 /* istanbul ignore next */ | |
3175 []; | |
3176 const length = childNodes.length; | |
3177 for (let i = 0; i < length; i++) { | |
3178 clone.appendChild(cloneNode(childNodes[i])); | |
3179 } | |
3180 return clone; | |
3181 } : | |
3182 // the following ignore is due code-coverage | |
3183 // combination of not having document.importNode | |
3184 // but having a working node.cloneNode. | |
3185 // This shenario is common on older Android/WebKit browsers | |
3186 // but basicHTML here tests just two major cases: | |
3187 // with document.importNode or with broken cloneNode. | |
3188 /* istanbul ignore next */ | |
3189 node => node.cloneNode(true); | |
3190 | |
3191 // used to import html into fragments | |
3192 const importNode = hasImportNode ? | |
3193 (doc, node) => doc.importNode(node, true) : | |
3194 (doc, node) => cloneNode(node) | |
3195 exports.importNode = importNode | |
3196 | |
3197 // just recycling a one-off array to use slice | |
3198 // in every needed place | |
3199 const slice = [].slice; | |
3200 exports.slice = slice; | |
3201 | |
3202 // lazy evaluated, returns the unique identity | |
3203 // of a template literal, as tempalte literal itself. | |
3204 // By default, ES2015 template literals are unique | |
3205 // tag`a${1}z` === tag`a${2}z` | |
3206 // even if interpolated values are different | |
3207 // the template chunks are in a frozen Array | |
3208 // that is identical each time you use the same | |
3209 // literal to represent same static content | |
3210 // around its own interpolations. | |
3211 const unique = template => TL(template); | |
3212 exports.unique = unique; | |
3213 | |
3214 // TL returns a unique version of the template | |
3215 // it needs lazy feature detection | |
3216 // (cannot trust literals with transpiled code) | |
3217 let TL = template => { | |
3218 if ( | |
3219 // TypeScript template literals are not standard | |
3220 template.propertyIsEnumerable('raw') || | |
3221 ( | |
3222 // Firefox < 55 has not standard implementation neither | |
3223 /Firefox\/(\d+)/.test((G.navigator || {}).userAgent) && | |
3224 parseFloat(RegExp.$1) < 55 | |
3225 ) | |
3226 ) { | |
3227 // in these cases, address templates once | |
3228 const templateObjects = {}; | |
3229 // but always return the same template | |
3230 TL = template => { | |
3231 const key = '_' + template.join(UID); | |
3232 return templateObjects[key] || ( | |
3233 templateObjects[key] = template | |
3234 ); | |
3235 }; | |
3236 } | |
3237 else { | |
3238 // make TL an identity like function | |
3239 TL = template => template; | |
3240 } | |
3241 return TL(template); | |
3242 }; | |
3243 | |
3244 // create document fragments via native template | |
3245 // with a fallback for browsers that won't be able | |
3246 // to deal with some injected element such <td> or others | |
3247 const HTMLFragment = hasContent ? | |
3248 (node, html) => { | |
3249 const container = create(node, 'template'); | |
3250 container.innerHTML = html; | |
3251 return container.content; | |
3252 } : | |
3253 (node, html) => { | |
3254 const container = create(node, 'template'); | |
3255 const content = fragment(node); | |
3256 if (/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(html)) { | |
3257 const selector = RegExp.$1; | |
3258 container.innerHTML = '<table>' + html + '</table>'; | |
3259 append(content, slice.call(container.querySelectorAll(selector))); | |
3260 } else { | |
3261 container.innerHTML = html; | |
3262 append(content, slice.call(container.childNodes)); | |
3263 } | |
3264 return content; | |
3265 }; | |
3266 | |
3267 // creates SVG fragment with a fallback for IE that needs SVG | |
3268 // within the HTML content | |
3269 const SVGFragment = hasContent ? | |
3270 (node, html) => { | |
3271 const content = fragment(node); | |
3272 const container = doc(node).createElementNS(SVG_NAMESPACE, 'svg'); | |
3273 container.innerHTML = html; | |
3274 append(content, slice.call(container.childNodes)); | |
3275 return content; | |
3276 } : | |
3277 (node, html) => { | |
3278 const content = fragment(node); | |
3279 const container = create(node, 'div'); | |
3280 container.innerHTML = '<svg xmlns="' + SVG_NAMESPACE + '">' + html + '</svg>
'; | |
3281 append(content, slice.call(container.firstChild.childNodes)); | |
3282 return content; | |
3283 }; | |
3284 | |
3285 },{"./constants.js":13,"./easy-dom.js":15,"./features-detection.js":16,"./re.js"
:18}],20:[function(require,module,exports){ | |
3286 /* globals module, require */ | 1 /* globals module, require */ |
3287 | 2 |
3288 "use strict"; | 3 "use strict"; |
3289 | 4 |
3290 const IOElement = require("../js/io-element"); | 5 const IOElement = require("../js/io-element"); |
3291 | 6 |
3292 class IOClock extends IOElement | 7 class IOClock extends IOElement |
3293 { | 8 { |
3294 connectedCallback() | 9 connectedCallback() |
3295 { | 10 { |
3296 this._timer = setInterval(() => this.render(), 1000); | 11 this._timer = setInterval(() => this.render(), 1000); |
3297 } | 12 } |
3298 | 13 |
3299 disconnectedCallback() | 14 disconnectedCallback() |
3300 { | 15 { |
3301 clearInterval(this._timer); | 16 clearInterval(this._timer); |
3302 } | 17 } |
3303 | 18 |
3304 render() | 19 render() |
3305 { | 20 { |
3306 this.html` | 21 this.html` |
3307 ${{i18n: "io_clock"}} | 22 ${{i18n: "io_clock"}} |
3308 @${(new Date()).toLocaleTimeString()} | 23 @${(new Date()).toLocaleTimeString()} |
3309 `; | 24 `; |
3310 } | 25 } |
3311 } | 26 } |
3312 | 27 |
3313 IOClock.define("io-clock"); | 28 IOClock.define("io-clock"); |
3314 | |
3315 },{"../js/io-element":1}]},{},[20]); | |
LEFT | RIGHT |