Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: tests/io-element.js

Issue 29723623: Issue 6487 - IOElement as base component for ABP UI (Closed)
Left Patch Set: Created March 15, 2018, 2:42 p.m.
Right Patch Set: Created March 21, 2018, 2:20 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « tests/io-element.html ('k') | tests/locale/en_US/common.json » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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]);
LEFTRIGHT

Powered by Google App Engine
This is Rietveld