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

Unified Diff: tests/io-element.js

Issue 29723623: Issue 6487 - IOElement as base component for ABP UI (Closed)
Patch Set: Created March 15, 2018, 2:42 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tests/io-element.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/tests/io-element.js
@@ -0,0 +1,3315 @@
+/* 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)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_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 require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}return e})()({1:[function(require,module,exports){
+/* globals module, require */
+
+"use strict";
+
+// Custom Elements polyfill
+const customElementsPonyfill = require("document-register-element/pony");
+if (typeof customElements !== "object")
+ customElementsPonyfill(window);
+
+// external dependencies
+const {default: HyperHTMLElement} = require("hyperhtml-element/cjs");
+
+// provides a unique-id suffix per each component
+let counter = 0;
+
+// common Custom Element class to extend
+class IOElement extends HyperHTMLElement
+{
+ // get a unique ID or, if null, set one and returns it
+ static getID(element)
+ {
+ return element.getAttribute("id") || IOElement.setID(element);
+ }
+
+ // set a unique ID to a generic element and returns the ID
+ static setID(element)
+ {
+ const id = `${element.nodeName.toLowerCase()}-${counter++}`;
+ element.setAttribute("id", id);
+ return id;
+ }
+
+ // lazily retrieve or define a custom element ID
+ get id()
+ {
+ return IOElement.getID(this);
+ }
+
+ // whenever an element is created, render its content once
+ created() { this.render(); }
+
+ // by default, render is a no-op
+ render() {}
+}
+
+// whenever an interpolation with ${{i18n: 'string-id'}} is found
+// transform such value into the expected content
+// example:
+// render() {
+// return this.html`<div>${{i18n:'about-abp'}}</div>`;
+// }
+const {setElementText} = ext.i18n;
+IOElement.intent("i18n", id =>
+{
+ const fragment = document.createDocumentFragment();
+ setElementText(fragment, id);
+ return fragment;
+});
+
+module.exports = IOElement;
+
+},{"document-register-element/pony":2,"hyperhtml-element/cjs":3}],2:[function(require,module,exports){
+/*!
+
+Copyright (C) 2014-2016 by Andrea Giammarchi - @WebReflection
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*/
+// global window Object
+// optional polyfill info
+// 'auto' used by default, everything is feature detected
+// 'force' use the polyfill even if not fully needed
+function installCustomElements(window, polyfill) {'use strict';
+
+ // DO NOT USE THIS FILE DIRECTLY, IT WON'T WORK
+ // THIS IS A PROJECT BASED ON A BUILD SYSTEM
+ // THIS FILE IS JUST WRAPPED UP RESULTING IN
+ // build/document-register-element.node.js
+
+ var
+ document = window.document,
+ Object = window.Object
+ ;
+
+ var htmlClass = (function (info) {
+ // (C) Andrea Giammarchi - @WebReflection - MIT Style
+ var
+ catchClass = /^[A-Z]+[a-z]/,
+ filterBy = function (re) {
+ var arr = [], tag;
+ for (tag in register) {
+ if (re.test(tag)) arr.push(tag);
+ }
+ return arr;
+ },
+ add = function (Class, tag) {
+ tag = tag.toLowerCase();
+ if (!(tag in register)) {
+ register[Class] = (register[Class] || []).concat(tag);
+ register[tag] = (register[tag.toUpperCase()] = Class);
+ }
+ },
+ register = (Object.create || Object)(null),
+ htmlClass = {},
+ i, section, tags, Class
+ ;
+ for (section in info) {
+ for (Class in info[section]) {
+ tags = info[section][Class];
+ register[Class] = tags;
+ for (i = 0; i < tags.length; i++) {
+ register[tags[i].toLowerCase()] =
+ register[tags[i].toUpperCase()] = Class;
+ }
+ }
+ }
+ htmlClass.get = function get(tagOrClass) {
+ return typeof tagOrClass === 'string' ?
+ (register[tagOrClass] || (catchClass.test(tagOrClass) ? [] : '')) :
+ filterBy(tagOrClass);
+ };
+ htmlClass.set = function set(tag, Class) {
+ return (catchClass.test(tag) ?
+ add(tag, Class) :
+ add(Class, tag)
+ ), htmlClass;
+ };
+ return htmlClass;
+ }({
+ "collections": {
+ "HTMLAllCollection": [
+ "all"
+ ],
+ "HTMLCollection": [
+ "forms"
+ ],
+ "HTMLFormControlsCollection": [
+ "elements"
+ ],
+ "HTMLOptionsCollection": [
+ "options"
+ ]
+ },
+ "elements": {
+ "Element": [
+ "element"
+ ],
+ "HTMLAnchorElement": [
+ "a"
+ ],
+ "HTMLAppletElement": [
+ "applet"
+ ],
+ "HTMLAreaElement": [
+ "area"
+ ],
+ "HTMLAttachmentElement": [
+ "attachment"
+ ],
+ "HTMLAudioElement": [
+ "audio"
+ ],
+ "HTMLBRElement": [
+ "br"
+ ],
+ "HTMLBaseElement": [
+ "base"
+ ],
+ "HTMLBodyElement": [
+ "body"
+ ],
+ "HTMLButtonElement": [
+ "button"
+ ],
+ "HTMLCanvasElement": [
+ "canvas"
+ ],
+ "HTMLContentElement": [
+ "content"
+ ],
+ "HTMLDListElement": [
+ "dl"
+ ],
+ "HTMLDataElement": [
+ "data"
+ ],
+ "HTMLDataListElement": [
+ "datalist"
+ ],
+ "HTMLDetailsElement": [
+ "details"
+ ],
+ "HTMLDialogElement": [
+ "dialog"
+ ],
+ "HTMLDirectoryElement": [
+ "dir"
+ ],
+ "HTMLDivElement": [
+ "div"
+ ],
+ "HTMLDocument": [
+ "document"
+ ],
+ "HTMLElement": [
+ "element",
+ "abbr",
+ "address",
+ "article",
+ "aside",
+ "b",
+ "bdi",
+ "bdo",
+ "cite",
+ "code",
+ "command",
+ "dd",
+ "dfn",
+ "dt",
+ "em",
+ "figcaption",
+ "figure",
+ "footer",
+ "header",
+ "i",
+ "kbd",
+ "mark",
+ "nav",
+ "noscript",
+ "rp",
+ "rt",
+ "ruby",
+ "s",
+ "samp",
+ "section",
+ "small",
+ "strong",
+ "sub",
+ "summary",
+ "sup",
+ "u",
+ "var",
+ "wbr"
+ ],
+ "HTMLEmbedElement": [
+ "embed"
+ ],
+ "HTMLFieldSetElement": [
+ "fieldset"
+ ],
+ "HTMLFontElement": [
+ "font"
+ ],
+ "HTMLFormElement": [
+ "form"
+ ],
+ "HTMLFrameElement": [
+ "frame"
+ ],
+ "HTMLFrameSetElement": [
+ "frameset"
+ ],
+ "HTMLHRElement": [
+ "hr"
+ ],
+ "HTMLHeadElement": [
+ "head"
+ ],
+ "HTMLHeadingElement": [
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6"
+ ],
+ "HTMLHtmlElement": [
+ "html"
+ ],
+ "HTMLIFrameElement": [
+ "iframe"
+ ],
+ "HTMLImageElement": [
+ "img"
+ ],
+ "HTMLInputElement": [
+ "input"
+ ],
+ "HTMLKeygenElement": [
+ "keygen"
+ ],
+ "HTMLLIElement": [
+ "li"
+ ],
+ "HTMLLabelElement": [
+ "label"
+ ],
+ "HTMLLegendElement": [
+ "legend"
+ ],
+ "HTMLLinkElement": [
+ "link"
+ ],
+ "HTMLMapElement": [
+ "map"
+ ],
+ "HTMLMarqueeElement": [
+ "marquee"
+ ],
+ "HTMLMediaElement": [
+ "media"
+ ],
+ "HTMLMenuElement": [
+ "menu"
+ ],
+ "HTMLMenuItemElement": [
+ "menuitem"
+ ],
+ "HTMLMetaElement": [
+ "meta"
+ ],
+ "HTMLMeterElement": [
+ "meter"
+ ],
+ "HTMLModElement": [
+ "del",
+ "ins"
+ ],
+ "HTMLOListElement": [
+ "ol"
+ ],
+ "HTMLObjectElement": [
+ "object"
+ ],
+ "HTMLOptGroupElement": [
+ "optgroup"
+ ],
+ "HTMLOptionElement": [
+ "option"
+ ],
+ "HTMLOutputElement": [
+ "output"
+ ],
+ "HTMLParagraphElement": [
+ "p"
+ ],
+ "HTMLParamElement": [
+ "param"
+ ],
+ "HTMLPictureElement": [
+ "picture"
+ ],
+ "HTMLPreElement": [
+ "pre"
+ ],
+ "HTMLProgressElement": [
+ "progress"
+ ],
+ "HTMLQuoteElement": [
+ "blockquote",
+ "q",
+ "quote"
+ ],
+ "HTMLScriptElement": [
+ "script"
+ ],
+ "HTMLSelectElement": [
+ "select"
+ ],
+ "HTMLShadowElement": [
+ "shadow"
+ ],
+ "HTMLSlotElement": [
+ "slot"
+ ],
+ "HTMLSourceElement": [
+ "source"
+ ],
+ "HTMLSpanElement": [
+ "span"
+ ],
+ "HTMLStyleElement": [
+ "style"
+ ],
+ "HTMLTableCaptionElement": [
+ "caption"
+ ],
+ "HTMLTableCellElement": [
+ "td",
+ "th"
+ ],
+ "HTMLTableColElement": [
+ "col",
+ "colgroup"
+ ],
+ "HTMLTableElement": [
+ "table"
+ ],
+ "HTMLTableRowElement": [
+ "tr"
+ ],
+ "HTMLTableSectionElement": [
+ "thead",
+ "tbody",
+ "tfoot"
+ ],
+ "HTMLTemplateElement": [
+ "template"
+ ],
+ "HTMLTextAreaElement": [
+ "textarea"
+ ],
+ "HTMLTimeElement": [
+ "time"
+ ],
+ "HTMLTitleElement": [
+ "title"
+ ],
+ "HTMLTrackElement": [
+ "track"
+ ],
+ "HTMLUListElement": [
+ "ul"
+ ],
+ "HTMLUnknownElement": [
+ "unknown",
+ "vhgroupv",
+ "vkeygen"
+ ],
+ "HTMLVideoElement": [
+ "video"
+ ]
+ },
+ "nodes": {
+ "Attr": [
+ "node"
+ ],
+ "Audio": [
+ "audio"
+ ],
+ "CDATASection": [
+ "node"
+ ],
+ "CharacterData": [
+ "node"
+ ],
+ "Comment": [
+ "#comment"
+ ],
+ "Document": [
+ "#document"
+ ],
+ "DocumentFragment": [
+ "#document-fragment"
+ ],
+ "DocumentType": [
+ "node"
+ ],
+ "HTMLDocument": [
+ "#document"
+ ],
+ "Image": [
+ "img"
+ ],
+ "Option": [
+ "option"
+ ],
+ "ProcessingInstruction": [
+ "node"
+ ],
+ "ShadowRoot": [
+ "#shadow-root"
+ ],
+ "Text": [
+ "#text"
+ ],
+ "XMLDocument": [
+ "xml"
+ ]
+ }
+ }));
+
+
+
+ // passed at runtime, configurable via nodejs module
+ if (typeof polyfill !== 'object') polyfill = {type: polyfill || 'auto'};
+
+ var
+ // V0 polyfill entry
+ REGISTER_ELEMENT = 'registerElement',
+
+ // IE < 11 only + old WebKit for attributes + feature detection
+ EXPANDO_UID = '__' + REGISTER_ELEMENT + (window.Math.random() * 10e4 >> 0),
+
+ // shortcuts and costants
+ ADD_EVENT_LISTENER = 'addEventListener',
+ ATTACHED = 'attached',
+ CALLBACK = 'Callback',
+ DETACHED = 'detached',
+ EXTENDS = 'extends',
+
+ ATTRIBUTE_CHANGED_CALLBACK = 'attributeChanged' + CALLBACK,
+ ATTACHED_CALLBACK = ATTACHED + CALLBACK,
+ CONNECTED_CALLBACK = 'connected' + CALLBACK,
+ DISCONNECTED_CALLBACK = 'disconnected' + CALLBACK,
+ CREATED_CALLBACK = 'created' + CALLBACK,
+ DETACHED_CALLBACK = DETACHED + CALLBACK,
+
+ ADDITION = 'ADDITION',
+ MODIFICATION = 'MODIFICATION',
+ REMOVAL = 'REMOVAL',
+
+ DOM_ATTR_MODIFIED = 'DOMAttrModified',
+ DOM_CONTENT_LOADED = 'DOMContentLoaded',
+ DOM_SUBTREE_MODIFIED = 'DOMSubtreeModified',
+
+ PREFIX_TAG = '<',
+ PREFIX_IS = '=',
+
+ // valid and invalid node names
+ validName = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,
+ invalidNames = [
+ 'ANNOTATION-XML',
+ 'COLOR-PROFILE',
+ 'FONT-FACE',
+ 'FONT-FACE-SRC',
+ 'FONT-FACE-URI',
+ 'FONT-FACE-FORMAT',
+ 'FONT-FACE-NAME',
+ 'MISSING-GLYPH'
+ ],
+
+ // registered types and their prototypes
+ types = [],
+ protos = [],
+
+ // to query subnodes
+ query = '',
+
+ // html shortcut used to feature detect
+ documentElement = document.documentElement,
+
+ // ES5 inline helpers || basic patches
+ indexOf = types.indexOf || function (v) {
+ for(var i = this.length; i-- && this[i] !== v;){}
+ return i;
+ },
+
+ // other helpers / shortcuts
+ OP = Object.prototype,
+ hOP = OP.hasOwnProperty,
+ iPO = OP.isPrototypeOf,
+
+ defineProperty = Object.defineProperty,
+ empty = [],
+ gOPD = Object.getOwnPropertyDescriptor,
+ gOPN = Object.getOwnPropertyNames,
+ gPO = Object.getPrototypeOf,
+ sPO = Object.setPrototypeOf,
+
+ // jshint proto: true
+ hasProto = !!Object.__proto__,
+
+ // V1 helpers
+ fixGetClass = false,
+ DRECEV1 = '__dreCEv1',
+ customElements = window.customElements,
+ usableCustomElements = !/^force/.test(polyfill.type) && !!(
+ customElements &&
+ customElements.define &&
+ customElements.get &&
+ customElements.whenDefined
+ ),
+ Dict = Object.create || Object,
+ Map = window.Map || function Map() {
+ var K = [], V = [], i;
+ return {
+ get: function (k) {
+ return V[indexOf.call(K, k)];
+ },
+ set: function (k, v) {
+ i = indexOf.call(K, k);
+ if (i < 0) V[K.push(k) - 1] = v;
+ else V[i] = v;
+ }
+ };
+ },
+ Promise = window.Promise || function (fn) {
+ var
+ notify = [],
+ done = false,
+ p = {
+ 'catch': function () {
+ return p;
+ },
+ 'then': function (cb) {
+ notify.push(cb);
+ if (done) setTimeout(resolve, 1);
+ return p;
+ }
+ }
+ ;
+ function resolve(value) {
+ done = true;
+ while (notify.length) notify.shift()(value);
+ }
+ fn(resolve);
+ return p;
+ },
+ justCreated = false,
+ constructors = Dict(null),
+ waitingList = Dict(null),
+ nodeNames = new Map(),
+ secondArgument = function (is) {
+ return is.toLowerCase();
+ },
+
+ // used to create unique instances
+ create = Object.create || function Bridge(proto) {
+ // silly broken polyfill probably ever used but short enough to work
+ return proto ? ((Bridge.prototype = proto), new Bridge()) : this;
+ },
+
+ // will set the prototype if possible
+ // or copy over all properties
+ setPrototype = sPO || (
+ hasProto ?
+ function (o, p) {
+ o.__proto__ = p;
+ return o;
+ } : (
+ (gOPN && gOPD) ?
+ (function(){
+ function setProperties(o, p) {
+ for (var
+ key,
+ names = gOPN(p),
+ i = 0, length = names.length;
+ i < length; i++
+ ) {
+ key = names[i];
+ if (!hOP.call(o, key)) {
+ defineProperty(o, key, gOPD(p, key));
+ }
+ }
+ }
+ return function (o, p) {
+ do {
+ setProperties(o, p);
+ } while ((p = gPO(p)) && !iPO.call(p, o));
+ return o;
+ };
+ }()) :
+ function (o, p) {
+ for (var key in p) {
+ o[key] = p[key];
+ }
+ return o;
+ }
+ )),
+
+ // DOM shortcuts and helpers, if any
+
+ MutationObserver = window.MutationObserver ||
+ window.WebKitMutationObserver,
+
+ HTMLElementPrototype = (
+ window.HTMLElement ||
+ window.Element ||
+ window.Node
+ ).prototype,
+
+ IE8 = !iPO.call(HTMLElementPrototype, documentElement),
+
+ safeProperty = IE8 ? function (o, k, d) {
+ o[k] = d.value;
+ return o;
+ } : defineProperty,
+
+ isValidNode = IE8 ?
+ function (node) {
+ return node.nodeType === 1;
+ } :
+ function (node) {
+ return iPO.call(HTMLElementPrototype, node);
+ },
+
+ targets = IE8 && [],
+
+ attachShadow = HTMLElementPrototype.attachShadow,
+ cloneNode = HTMLElementPrototype.cloneNode,
+ dispatchEvent = HTMLElementPrototype.dispatchEvent,
+ getAttribute = HTMLElementPrototype.getAttribute,
+ hasAttribute = HTMLElementPrototype.hasAttribute,
+ removeAttribute = HTMLElementPrototype.removeAttribute,
+ setAttribute = HTMLElementPrototype.setAttribute,
+
+ // replaced later on
+ createElement = document.createElement,
+ patchedCreateElement = createElement,
+
+ // shared observer for all attributes
+ attributesObserver = MutationObserver && {
+ attributes: true,
+ characterData: true,
+ attributeOldValue: true
+ },
+
+ // useful to detect only if there's no MutationObserver
+ DOMAttrModified = MutationObserver || function(e) {
+ doesNotSupportDOMAttrModified = false;
+ documentElement.removeEventListener(
+ DOM_ATTR_MODIFIED,
+ DOMAttrModified
+ );
+ },
+
+ // will both be used to make DOMNodeInserted asynchronous
+ asapQueue,
+ asapTimer = 0,
+
+ // internal flags
+ V0 = REGISTER_ELEMENT in document &&
+ !/^force-all/.test(polyfill.type),
+ setListener = true,
+ justSetup = false,
+ doesNotSupportDOMAttrModified = true,
+ dropDomContentLoaded = true,
+
+ // needed for the innerHTML helper
+ notFromInnerHTMLHelper = true,
+
+ // optionally defined later on
+ onSubtreeModified,
+ callDOMAttrModified,
+ getAttributesMirror,
+ observer,
+ observe,
+
+ // based on setting prototype capability
+ // will check proto or the expando attribute
+ // in order to setup the node once
+ patchIfNotAlready,
+ patch
+ ;
+
+ // only if needed
+ if (!V0) {
+
+ if (sPO || hasProto) {
+ patchIfNotAlready = function (node, proto) {
+ if (!iPO.call(proto, node)) {
+ setupNode(node, proto);
+ }
+ };
+ patch = setupNode;
+ } else {
+ patchIfNotAlready = function (node, proto) {
+ if (!node[EXPANDO_UID]) {
+ node[EXPANDO_UID] = Object(true);
+ setupNode(node, proto);
+ }
+ };
+ patch = patchIfNotAlready;
+ }
+
+ if (IE8) {
+ doesNotSupportDOMAttrModified = false;
+ (function (){
+ var
+ descriptor = gOPD(HTMLElementPrototype, ADD_EVENT_LISTENER),
+ addEventListener = descriptor.value,
+ patchedRemoveAttribute = function (name) {
+ var e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true});
+ e.attrName = name;
+ e.prevValue = getAttribute.call(this, name);
+ e.newValue = null;
+ e[REMOVAL] = e.attrChange = 2;
+ removeAttribute.call(this, name);
+ dispatchEvent.call(this, e);
+ },
+ patchedSetAttribute = function (name, value) {
+ var
+ had = hasAttribute.call(this, name),
+ old = had && getAttribute.call(this, name),
+ e = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true})
+ ;
+ setAttribute.call(this, name, value);
+ e.attrName = name;
+ e.prevValue = had ? old : null;
+ e.newValue = value;
+ if (had) {
+ e[MODIFICATION] = e.attrChange = 1;
+ } else {
+ e[ADDITION] = e.attrChange = 0;
+ }
+ dispatchEvent.call(this, e);
+ },
+ onPropertyChange = function (e) {
+ // jshint eqnull:true
+ var
+ node = e.currentTarget,
+ superSecret = node[EXPANDO_UID],
+ propertyName = e.propertyName,
+ event
+ ;
+ if (superSecret.hasOwnProperty(propertyName)) {
+ superSecret = superSecret[propertyName];
+ event = new CustomEvent(DOM_ATTR_MODIFIED, {bubbles: true});
+ event.attrName = superSecret.name;
+ event.prevValue = superSecret.value || null;
+ event.newValue = (superSecret.value = node[propertyName] || null);
+ if (event.prevValue == null) {
+ event[ADDITION] = event.attrChange = 0;
+ } else {
+ event[MODIFICATION] = event.attrChange = 1;
+ }
+ dispatchEvent.call(node, event);
+ }
+ }
+ ;
+ descriptor.value = function (type, handler, capture) {
+ if (
+ type === DOM_ATTR_MODIFIED &&
+ this[ATTRIBUTE_CHANGED_CALLBACK] &&
+ this.setAttribute !== patchedSetAttribute
+ ) {
+ this[EXPANDO_UID] = {
+ className: {
+ name: 'class',
+ value: this.className
+ }
+ };
+ this.setAttribute = patchedSetAttribute;
+ this.removeAttribute = patchedRemoveAttribute;
+ addEventListener.call(this, 'propertychange', onPropertyChange);
+ }
+ addEventListener.call(this, type, handler, capture);
+ };
+ defineProperty(HTMLElementPrototype, ADD_EVENT_LISTENER, descriptor);
+ }());
+ } else if (!MutationObserver) {
+ documentElement[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, DOMAttrModified);
+ documentElement.setAttribute(EXPANDO_UID, 1);
+ documentElement.removeAttribute(EXPANDO_UID);
+ if (doesNotSupportDOMAttrModified) {
+ onSubtreeModified = function (e) {
+ var
+ node = this,
+ oldAttributes,
+ newAttributes,
+ key
+ ;
+ if (node === e.target) {
+ oldAttributes = node[EXPANDO_UID];
+ node[EXPANDO_UID] = (newAttributes = getAttributesMirror(node));
+ for (key in newAttributes) {
+ if (!(key in oldAttributes)) {
+ // attribute was added
+ return callDOMAttrModified(
+ 0,
+ node,
+ key,
+ oldAttributes[key],
+ newAttributes[key],
+ ADDITION
+ );
+ } else if (newAttributes[key] !== oldAttributes[key]) {
+ // attribute was changed
+ return callDOMAttrModified(
+ 1,
+ node,
+ key,
+ oldAttributes[key],
+ newAttributes[key],
+ MODIFICATION
+ );
+ }
+ }
+ // checking if it has been removed
+ for (key in oldAttributes) {
+ if (!(key in newAttributes)) {
+ // attribute removed
+ return callDOMAttrModified(
+ 2,
+ node,
+ key,
+ oldAttributes[key],
+ newAttributes[key],
+ REMOVAL
+ );
+ }
+ }
+ }
+ };
+ callDOMAttrModified = function (
+ attrChange,
+ currentTarget,
+ attrName,
+ prevValue,
+ newValue,
+ action
+ ) {
+ var e = {
+ attrChange: attrChange,
+ currentTarget: currentTarget,
+ attrName: attrName,
+ prevValue: prevValue,
+ newValue: newValue
+ };
+ e[action] = attrChange;
+ onDOMAttrModified(e);
+ };
+ getAttributesMirror = function (node) {
+ for (var
+ attr, name,
+ result = {},
+ attributes = node.attributes,
+ i = 0, length = attributes.length;
+ i < length; i++
+ ) {
+ attr = attributes[i];
+ name = attr.name;
+ if (name !== 'setAttribute') {
+ result[name] = attr.value;
+ }
+ }
+ return result;
+ };
+ }
+ }
+
+ // set as enumerable, writable and configurable
+ document[REGISTER_ELEMENT] = function registerElement(type, options) {
+ upperType = type.toUpperCase();
+ if (setListener) {
+ // only first time document.registerElement is used
+ // we need to set this listener
+ // setting it by default might slow down for no reason
+ setListener = false;
+ if (MutationObserver) {
+ observer = (function(attached, detached){
+ function checkEmAll(list, callback) {
+ for (var i = 0, length = list.length; i < length; callback(list[i++])){}
+ }
+ return new MutationObserver(function (records) {
+ for (var
+ current, node, newValue,
+ i = 0, length = records.length; i < length; i++
+ ) {
+ current = records[i];
+ if (current.type === 'childList') {
+ checkEmAll(current.addedNodes, attached);
+ checkEmAll(current.removedNodes, detached);
+ } else {
+ node = current.target;
+ if (notFromInnerHTMLHelper &&
+ node[ATTRIBUTE_CHANGED_CALLBACK] &&
+ current.attributeName !== 'style') {
+ newValue = getAttribute.call(node, current.attributeName);
+ if (newValue !== current.oldValue) {
+ node[ATTRIBUTE_CHANGED_CALLBACK](
+ current.attributeName,
+ current.oldValue,
+ newValue
+ );
+ }
+ }
+ }
+ }
+ });
+ }(executeAction(ATTACHED), executeAction(DETACHED)));
+ observe = function (node) {
+ observer.observe(
+ node,
+ {
+ childList: true,
+ subtree: true
+ }
+ );
+ return node;
+ };
+ observe(document);
+ if (attachShadow) {
+ HTMLElementPrototype.attachShadow = function () {
+ return observe(attachShadow.apply(this, arguments));
+ };
+ }
+ } else {
+ asapQueue = [];
+ document[ADD_EVENT_LISTENER]('DOMNodeInserted', onDOMNode(ATTACHED));
+ document[ADD_EVENT_LISTENER]('DOMNodeRemoved', onDOMNode(DETACHED));
+ }
+
+ document[ADD_EVENT_LISTENER](DOM_CONTENT_LOADED, onReadyStateChange);
+ document[ADD_EVENT_LISTENER]('readystatechange', onReadyStateChange);
+
+ HTMLElementPrototype.cloneNode = function (deep) {
+ var
+ node = cloneNode.call(this, !!deep),
+ i = getTypeIndex(node)
+ ;
+ if (-1 < i) patch(node, protos[i]);
+ if (deep && query.length) loopAndSetup(node.querySelectorAll(query));
+ return node;
+ };
+ }
+
+ if (justSetup) return (justSetup = false);
+
+ if (-2 < (
+ indexOf.call(types, PREFIX_IS + upperType) +
+ indexOf.call(types, PREFIX_TAG + upperType)
+ )) {
+ throwTypeError(type);
+ }
+
+ if (!validName.test(upperType) || -1 < indexOf.call(invalidNames, upperType)) {
+ throw new Error('The type ' + type + ' is invalid');
+ }
+
+ var
+ constructor = function () {
+ return extending ?
+ document.createElement(nodeName, upperType) :
+ document.createElement(nodeName);
+ },
+ opt = options || OP,
+ extending = hOP.call(opt, EXTENDS),
+ nodeName = extending ? options[EXTENDS].toUpperCase() : upperType,
+ upperType,
+ i
+ ;
+
+ if (extending && -1 < (
+ indexOf.call(types, PREFIX_TAG + nodeName)
+ )) {
+ throwTypeError(nodeName);
+ }
+
+ i = types.push((extending ? PREFIX_IS : PREFIX_TAG) + upperType) - 1;
+
+ query = query.concat(
+ query.length ? ',' : '',
+ extending ? nodeName + '[is="' + type.toLowerCase() + '"]' : nodeName
+ );
+
+ constructor.prototype = (
+ protos[i] = hOP.call(opt, 'prototype') ?
+ opt.prototype :
+ create(HTMLElementPrototype)
+ );
+
+ if (query.length) loopAndVerify(
+ document.querySelectorAll(query),
+ ATTACHED
+ );
+
+ return constructor;
+ };
+
+ document.createElement = (patchedCreateElement = function (localName, typeExtension) {
+ var
+ is = getIs(typeExtension),
+ node = is ?
+ createElement.call(document, localName, secondArgument(is)) :
+ createElement.call(document, localName),
+ name = '' + localName,
+ i = indexOf.call(
+ types,
+ (is ? PREFIX_IS : PREFIX_TAG) +
+ (is || name).toUpperCase()
+ ),
+ setup = -1 < i
+ ;
+ if (is) {
+ node.setAttribute('is', is = is.toLowerCase());
+ if (setup) {
+ setup = isInQSA(name.toUpperCase(), is);
+ }
+ }
+ notFromInnerHTMLHelper = !document.createElement.innerHTMLHelper;
+ if (setup) patch(node, protos[i]);
+ return node;
+ });
+
+ }
+
+ function ASAP() {
+ var queue = asapQueue.splice(0, asapQueue.length);
+ asapTimer = 0;
+ while (queue.length) {
+ queue.shift().call(
+ null, queue.shift()
+ );
+ }
+ }
+
+ function loopAndVerify(list, action) {
+ for (var i = 0, length = list.length; i < length; i++) {
+ verifyAndSetupAndAction(list[i], action);
+ }
+ }
+
+ function loopAndSetup(list) {
+ for (var i = 0, length = list.length, node; i < length; i++) {
+ node = list[i];
+ patch(node, protos[getTypeIndex(node)]);
+ }
+ }
+
+ function executeAction(action) {
+ return function (node) {
+ if (isValidNode(node)) {
+ verifyAndSetupAndAction(node, action);
+ if (query.length) loopAndVerify(
+ node.querySelectorAll(query),
+ action
+ );
+ }
+ };
+ }
+
+ function getTypeIndex(target) {
+ var
+ is = getAttribute.call(target, 'is'),
+ nodeName = target.nodeName.toUpperCase(),
+ i = indexOf.call(
+ types,
+ is ?
+ PREFIX_IS + is.toUpperCase() :
+ PREFIX_TAG + nodeName
+ )
+ ;
+ return is && -1 < i && !isInQSA(nodeName, is) ? -1 : i;
+ }
+
+ function isInQSA(name, type) {
+ return -1 < query.indexOf(name + '[is="' + type + '"]');
+ }
+
+ function onDOMAttrModified(e) {
+ var
+ node = e.currentTarget,
+ attrChange = e.attrChange,
+ attrName = e.attrName,
+ target = e.target,
+ addition = e[ADDITION] || 2,
+ removal = e[REMOVAL] || 3
+ ;
+ if (notFromInnerHTMLHelper &&
+ (!target || target === node) &&
+ node[ATTRIBUTE_CHANGED_CALLBACK] &&
+ attrName !== 'style' && (
+ e.prevValue !== e.newValue ||
+ // IE9, IE10, and Opera 12 gotcha
+ e.newValue === '' && (
+ attrChange === addition ||
+ attrChange === removal
+ )
+ )) {
+ node[ATTRIBUTE_CHANGED_CALLBACK](
+ attrName,
+ attrChange === addition ? null : e.prevValue,
+ attrChange === removal ? null : e.newValue
+ );
+ }
+ }
+
+ function onDOMNode(action) {
+ var executor = executeAction(action);
+ return function (e) {
+ asapQueue.push(executor, e.target);
+ if (asapTimer) clearTimeout(asapTimer);
+ asapTimer = setTimeout(ASAP, 1);
+ };
+ }
+
+ function onReadyStateChange(e) {
+ if (dropDomContentLoaded) {
+ dropDomContentLoaded = false;
+ e.currentTarget.removeEventListener(DOM_CONTENT_LOADED, onReadyStateChange);
+ }
+ if (query.length) loopAndVerify(
+ (e.target || document).querySelectorAll(query),
+ e.detail === DETACHED ? DETACHED : ATTACHED
+ );
+ if (IE8) purge();
+ }
+
+ function patchedSetAttribute(name, value) {
+ // jshint validthis:true
+ var self = this;
+ setAttribute.call(self, name, value);
+ onSubtreeModified.call(self, {target: self});
+ }
+
+ function setupNode(node, proto) {
+ setPrototype(node, proto);
+ if (observer) {
+ observer.observe(node, attributesObserver);
+ } else {
+ if (doesNotSupportDOMAttrModified) {
+ node.setAttribute = patchedSetAttribute;
+ node[EXPANDO_UID] = getAttributesMirror(node);
+ node[ADD_EVENT_LISTENER](DOM_SUBTREE_MODIFIED, onSubtreeModified);
+ }
+ node[ADD_EVENT_LISTENER](DOM_ATTR_MODIFIED, onDOMAttrModified);
+ }
+ if (node[CREATED_CALLBACK] && notFromInnerHTMLHelper) {
+ node.created = true;
+ node[CREATED_CALLBACK]();
+ node.created = false;
+ }
+ }
+
+ function purge() {
+ for (var
+ node,
+ i = 0,
+ length = targets.length;
+ i < length; i++
+ ) {
+ node = targets[i];
+ if (!documentElement.contains(node)) {
+ length--;
+ targets.splice(i--, 1);
+ verifyAndSetupAndAction(node, DETACHED);
+ }
+ }
+ }
+
+ function throwTypeError(type) {
+ throw new Error('A ' + type + ' type is already registered');
+ }
+
+ function verifyAndSetupAndAction(node, action) {
+ var
+ fn,
+ i = getTypeIndex(node),
+ counterAction
+ ;
+ if (-1 < i) {
+ patchIfNotAlready(node, protos[i]);
+ i = 0;
+ if (action === ATTACHED && !node[ATTACHED]) {
+ node[DETACHED] = false;
+ node[ATTACHED] = true;
+ counterAction = 'connected';
+ i = 1;
+ if (IE8 && indexOf.call(targets, node) < 0) {
+ targets.push(node);
+ }
+ } else if (action === DETACHED && !node[DETACHED]) {
+ node[ATTACHED] = false;
+ node[DETACHED] = true;
+ counterAction = 'disconnected';
+ i = 1;
+ }
+ if (i && (fn = (
+ node[action + CALLBACK] ||
+ node[counterAction + CALLBACK]
+ ))) fn.call(node);
+ }
+ }
+
+
+
+ // V1 in da House!
+ function CustomElementRegistry() {}
+
+ CustomElementRegistry.prototype = {
+ constructor: CustomElementRegistry,
+ // a workaround for the stubborn WebKit
+ define: usableCustomElements ?
+ function (name, Class, options) {
+ if (options) {
+ CERDefine(name, Class, options);
+ } else {
+ var NAME = name.toUpperCase();
+ constructors[NAME] = {
+ constructor: Class,
+ create: [NAME]
+ };
+ nodeNames.set(Class, NAME);
+ customElements.define(name, Class);
+ }
+ } :
+ CERDefine,
+ get: usableCustomElements ?
+ function (name) {
+ return customElements.get(name) || get(name);
+ } :
+ get,
+ whenDefined: usableCustomElements ?
+ function (name) {
+ return Promise.race([
+ customElements.whenDefined(name),
+ whenDefined(name)
+ ]);
+ } :
+ whenDefined
+ };
+
+ function CERDefine(name, Class, options) {
+ var
+ is = options && options[EXTENDS] || '',
+ CProto = Class.prototype,
+ proto = create(CProto),
+ attributes = Class.observedAttributes || empty,
+ definition = {prototype: proto}
+ ;
+ // TODO: is this needed at all since it's inherited?
+ // defineProperty(proto, 'constructor', {value: Class});
+ safeProperty(proto, CREATED_CALLBACK, {
+ value: function () {
+ if (justCreated) justCreated = false;
+ else if (!this[DRECEV1]) {
+ this[DRECEV1] = true;
+ new Class(this);
+ if (CProto[CREATED_CALLBACK])
+ CProto[CREATED_CALLBACK].call(this);
+ var info = constructors[nodeNames.get(Class)];
+ if (!usableCustomElements || info.create.length > 1) {
+ notifyAttributes(this);
+ }
+ }
+ }
+ });
+ safeProperty(proto, ATTRIBUTE_CHANGED_CALLBACK, {
+ value: function (name) {
+ if (-1 < indexOf.call(attributes, name))
+ CProto[ATTRIBUTE_CHANGED_CALLBACK].apply(this, arguments);
+ }
+ });
+ if (CProto[CONNECTED_CALLBACK]) {
+ safeProperty(proto, ATTACHED_CALLBACK, {
+ value: CProto[CONNECTED_CALLBACK]
+ });
+ }
+ if (CProto[DISCONNECTED_CALLBACK]) {
+ safeProperty(proto, DETACHED_CALLBACK, {
+ value: CProto[DISCONNECTED_CALLBACK]
+ });
+ }
+ if (is) definition[EXTENDS] = is;
+ name = name.toUpperCase();
+ constructors[name] = {
+ constructor: Class,
+ create: is ? [is, secondArgument(name)] : [name]
+ };
+ nodeNames.set(Class, name);
+ document[REGISTER_ELEMENT](name.toLowerCase(), definition);
+ whenDefined(name);
+ waitingList[name].r();
+ }
+
+ function get(name) {
+ var info = constructors[name.toUpperCase()];
+ return info && info.constructor;
+ }
+
+ function getIs(options) {
+ return typeof options === 'string' ?
+ options : (options && options.is || '');
+ }
+
+ function notifyAttributes(self) {
+ var
+ callback = self[ATTRIBUTE_CHANGED_CALLBACK],
+ attributes = callback ? self.attributes : empty,
+ i = attributes.length,
+ attribute
+ ;
+ while (i--) {
+ attribute = attributes[i]; // || attributes.item(i);
+ callback.call(
+ self,
+ attribute.name || attribute.nodeName,
+ null,
+ attribute.value || attribute.nodeValue
+ );
+ }
+ }
+
+ function whenDefined(name) {
+ name = name.toUpperCase();
+ if (!(name in waitingList)) {
+ waitingList[name] = {};
+ waitingList[name].p = new Promise(function (resolve) {
+ waitingList[name].r = resolve;
+ });
+ }
+ return waitingList[name].p;
+ }
+
+ function polyfillV1() {
+ if (customElements) delete window.customElements;
+ defineProperty(window, 'customElements', {
+ configurable: true,
+ value: new CustomElementRegistry()
+ });
+ defineProperty(window, 'CustomElementRegistry', {
+ configurable: true,
+ value: CustomElementRegistry
+ });
+ for (var
+ patchClass = function (name) {
+ var Class = window[name];
+ if (Class) {
+ window[name] = function CustomElementsV1(self) {
+ var info, isNative;
+ if (!self) self = this;
+ if (!self[DRECEV1]) {
+ justCreated = true;
+ info = constructors[nodeNames.get(self.constructor)];
+ isNative = usableCustomElements && info.create.length === 1;
+ self = isNative ?
+ Reflect.construct(Class, empty, info.constructor) :
+ document.createElement.apply(document, info.create);
+ self[DRECEV1] = true;
+ justCreated = false;
+ if (!isNative) notifyAttributes(self);
+ }
+ return self;
+ };
+ window[name].prototype = Class.prototype;
+ try {
+ Class.prototype.constructor = window[name];
+ } catch(WebKit) {
+ fixGetClass = true;
+ defineProperty(Class, DRECEV1, {value: window[name]});
+ }
+ }
+ },
+ Classes = htmlClass.get(/^HTML[A-Z]*[a-z]/),
+ i = Classes.length;
+ i--;
+ patchClass(Classes[i])
+ ) {}
+ (document.createElement = function (name, options) {
+ var is = getIs(options);
+ return is ?
+ patchedCreateElement.call(this, name, secondArgument(is)) :
+ patchedCreateElement.call(this, name);
+ });
+ if (!V0) {
+ justSetup = true;
+ document[REGISTER_ELEMENT]('');
+ }
+ }
+
+ // if customElements is not there at all
+ if (!customElements || /^force/.test(polyfill.type)) polyfillV1();
+ else if(!polyfill.noBuiltIn) {
+ // if available test extends work as expected
+ try {
+ (function (DRE, options, name) {
+ options[EXTENDS] = 'a';
+ DRE.prototype = create(HTMLAnchorElement.prototype);
+ DRE.prototype.constructor = DRE;
+ window.customElements.define(name, DRE, options);
+ if (
+ getAttribute.call(document.createElement('a', {is: name}), 'is') !== name ||
+ (usableCustomElements && getAttribute.call(new DRE(), 'is') !== name)
+ ) {
+ throw options;
+ }
+ }(
+ function DRE() {
+ return Reflect.construct(HTMLAnchorElement, [], DRE);
+ },
+ {},
+ 'document-register-element-a'
+ ));
+ } catch(o_O) {
+ // or force the polyfill if not
+ // and keep internal original reference
+ polyfillV1();
+ }
+ }
+
+ // FireFox only issue
+ if(!polyfill.noBuiltIn) {
+ try {
+ createElement.call(document, 'a', 'a');
+ } catch(FireFox) {
+ secondArgument = function (is) {
+ return {is: is.toLowerCase()};
+ };
+ }
+ }
+
+}
+
+module.exports = installCustomElements;
+
+},{}],3:[function(require,module,exports){
+'use strict';
+/*! (C) 2017 Andrea Giammarchi - ISC Style License */
+
+const {Component, bind, define, hyper, wire} = require('hyperhtml/cjs');
+
+const _init$ = {value: false};
+
+const defineProperty = Object.defineProperty;
+
+const extend = (target, source) => {
+ for (const key in source) target[key] = source[key];
+};
+
+class HyperHTMLElement extends HTMLElement {
+
+ // define a custom-element in the CustomElementsRegistry
+ // class MyEl extends HyperHTMLElement {}
+ // MyEl.define('my-el');
+ static define(name) {
+ const Class = this;
+ const proto = Class.prototype;
+
+ // if observedAttributes contains attributes to observe
+ // HyperHTMLElement will directly reflect get/setAttribute
+ // operation once these attributes are used, example:
+ // el.observed = 123;
+ // will automatically do
+ // el.setAttribute('observed', 123);
+ // triggering also the attributeChangedCallback
+ (Class.observedAttributes || []).forEach(name => {
+ if (!(name in proto)) defineProperty(
+ proto,
+ name.replace(/-([a-z])/g, ($0, $1) => $1.toUpperCase()),
+ {
+ configurable: true,
+ get() { return this.getAttribute(name); },
+ set(value) { this.setAttribute(name, value); }
+ }
+ );
+ });
+
+ const onChanged = proto.attributeChangedCallback;
+ const hasChange = !!onChanged;
+
+ // created() {} is the entry point to do whatever you want.
+ // Once the node is live and upgraded as Custom Element.
+ // This method grants to be triggered at the right time,
+ // which is always once, and right before either
+ // attributeChangedCallback or connectedCallback
+ const created = proto.created;
+ if (created) {
+ // used to ensure create() is called once and once only
+ defineProperty(
+ proto,
+ '_init$',
+ {
+ configurable: true,
+ writable: true,
+ value: true
+ }
+ );
+
+ // ⚠️ if you need to overwrite/change attributeChangedCallback method
+ // at runtime after class definition, be sure you do so
+ // via Object.defineProperty to preserve its non-enumerable nature.
+ defineProperty(
+ proto,
+ 'attributeChangedCallback',
+ {
+ configurable: true,
+ value(name, prev, curr) {
+ if (this._init$) {
+ created.call(defineProperty(this, '_init$', _init$));
+ }
+ // ensure setting same value twice
+ // won't trigger twice attributeChangedCallback
+ if (hasChange && prev !== curr) {
+ onChanged.apply(this, arguments);
+ }
+ }
+ }
+ );
+
+ // ⚠️ if you need to overwrite/change connectedCallback method
+ // at runtime after class definition, be sure you do so
+ // via Object.defineProperty to preserve its non-enumerable nature.
+ const onConnected = proto.connectedCallback;
+ const hasConnect = !!onConnected;
+ defineProperty(
+ proto,
+ 'connectedCallback',
+ {
+ configurable: true,
+ value() {
+ if (this._init$) {
+ created.call(defineProperty(this, '_init$', _init$));
+ }
+ if (hasConnect) {
+ onConnected.apply(this, arguments);
+ }
+ }
+ }
+ );
+ } else if (hasChange) {
+ // ⚠️ if you need to overwrite/change attributeChangedCallback method
+ // at runtime after class definition, be sure you do so
+ // via Object.defineProperty to preserve its non-enumerable nature.
+ defineProperty(
+ proto,
+ 'attributeChangedCallback',
+ {
+ configurable: true,
+ value(name, prev, curr) {
+ // ensure setting same value twice
+ // won't trigger twice attributeChangedCallback
+ if (prev !== curr) {
+ onChanged.apply(this, arguments);
+ }
+ }
+ }
+ );
+ }
+
+ // define lazily all handlers
+ // class { handleClick() { ... }
+ // render() { `<a onclick=${this.handleClick}>` } }
+ Object.getOwnPropertyNames(proto).forEach(key => {
+ if (/^handle[A-Z]/.test(key)) {
+ const _key$ = '_' + key + '$';
+ const method = proto[key];
+ defineProperty(proto, key, {
+ configurable: true,
+ get() {
+ return this[_key$] ||
+ (this[_key$] = method.bind(this));
+ }
+ });
+ }
+ });
+
+ // whenever you want to directly use the component itself
+ // as EventListener, you can pass it directly.
+ // https://medium.com/@WebReflection/dom-handleevent-a-cross-platform-standard-since-year-2000-5bf17287fd38
+ // class Reactive extends HyperHTMLElement {
+ // oninput(e) { console.log(this, 'changed', e.target.value); }
+ // render() { this.html`<input oninput="${this}">`; }
+ // }
+ if (!('handleEvent' in proto)) {
+ // ⚠️ if you need to overwrite/change handleEvent method
+ // at runtime after class definition, be sure you do so
+ // via Object.defineProperty to preserve its non-enumerable nature.
+ defineProperty(
+ proto,
+ 'handleEvent',
+ {
+ configurable: true,
+ value(event) {
+ this[
+ (event.currentTarget.dataset || {}).call ||
+ ('on' + event.type)
+ ](event);
+ }
+ }
+ );
+ }
+
+ customElements.define(name, Class);
+ return Class;
+ }
+
+ // lazily bind once hyperHTML logic
+ // to either the shadowRoot, if present and open,
+ // the _shadowRoot property, if set due closed shadow root,
+ // or the custom-element itself if no Shadow DOM is used.
+ get html() {
+ return this._html$ || (this.html = bind(
+ // in case of Shadow DOM {mode: "open"}, use it
+ this.shadowRoot ||
+ // in case of Shadow DOM {mode: "close"}, use it
+ // this needs the following reference created upfront
+ // this._shadowRoot = this.attachShadow({mode: "close"});
+ this._shadowRoot ||
+ // if no Shadow DOM is used, simply use the component
+ // as container for its own content (it just works too)
+ this
+ ));
+ }
+
+ // it can be set too if necessary, it won't invoke render()
+ set html(value) {
+ defineProperty(this, '_html$', {configurable: true, value: value});
+ }
+
+ // ---------------------//
+ // Basic State Handling //
+ // ---------------------//
+
+ // overwrite this method with your own render
+ render() {}
+
+ // define the default state object
+ // you could use observed properties too
+ get defaultState() { return {}; }
+
+ // the state with a default
+ get state() {
+ return this._state$ || (this.state = this.defaultState);
+ }
+
+ // it can be set too if necessary, it won't invoke render()
+ set state(value) {
+ defineProperty(this, '_state$', {configurable: true, value: value});
+ }
+
+ // currently a state is a shallow copy, like in Preact or other libraries.
+ // after the state is updated, the render() method will be invoked.
+ // ⚠️ do not ever call this.setState() inside this.render()
+ setState(state) {
+ extend(
+ this.state,
+ typeof state === 'function' ?
+ state.call(this, this.state) : state
+ );
+ this.render();
+ }
+
+};
+
+// exposing hyperHTML utilities
+HyperHTMLElement.Component = Component;
+HyperHTMLElement.bind = bind;
+HyperHTMLElement.intent = define;
+HyperHTMLElement.wire = wire;
+HyperHTMLElement.hyper = hyper;
+
+Object.defineProperty(exports, '__esModule', {value: true}).default = HyperHTMLElement;
+
+},{"hyperhtml/cjs":8}],4:[function(require,module,exports){
+'use strict';
+const { UID } = require('../shared/constants.js');
+const { WeakMap } = require('../shared/poorlyfills.js');
+
+// hyperHTML.Component is a very basic class
+// able to create Custom Elements like components
+// including the ability to listen to connect/disconnect
+// events via onconnect/ondisconnect attributes
+// Components can be created imperatively or declaratively.
+// The main difference is that declared components
+// will not automatically render on setState(...)
+// to simplify state handling on render.
+function Component() {}
+Object.defineProperty(exports, '__esModule', {value: true}).default = Component
+
+// components will lazily define html or svg properties
+// as soon as these are invoked within the .render() method
+// Such render() method is not provided by the base class
+// but it must be available through the Component extend.
+// Declared components could implement a
+// render(props) method too and use props as needed.
+function setup(content) {
+ const children = new WeakMap;
+ const create = Object.create;
+ const createEntry = (wm, id, component) => {
+ wm.set(id, component);
+ return component;
+ };
+ const get = (Class, info, id) => {
+ switch (typeof id) {
+ case 'object':
+ case 'function':
+ const wm = info.w || (info.w = new WeakMap);
+ return wm.get(id) || createEntry(wm, id, new Class);
+ default:
+ const sm = info.p || (info.p = create(null));
+ return sm[id] || (sm[id] = new Class);
+ }
+ };
+ const set = context => {
+ const info = {w: null, p: null};
+ children.set(context, info);
+ return info;
+ };
+ Object.defineProperties(
+ Component,
+ {
+ for: {
+ configurable: true,
+ value(context, id) {
+ const info = children.get(context) || set(context);
+ return get(this, info, id == null ? 'default' : id);
+ }
+ }
+ }
+ );
+ Object.defineProperties(
+ Component.prototype,
+ {
+ handleEvent: {value(e) {
+ const ct = e.currentTarget;
+ this[
+ ('getAttribute' in ct && ct.getAttribute('data-call')) ||
+ ('on' + e.type)
+ ](e);
+ }},
+ html: lazyGetter('html', content),
+ svg: lazyGetter('svg', content),
+ state: lazyGetter('state', function () { return this.defaultState; }),
+ defaultState: {get() { return {}; }},
+ setState: {value(state, render) {
+ const target = this.state;
+ const source = typeof state === 'function' ? state.call(this, target) : state;
+ for (const key in source) target[key] = source[key];
+ if (render !== false) this.render();
+ return this;
+ }}
+ }
+ );
+}
+exports.setup = setup
+
+// instead of a secret key I could've used a WeakMap
+// However, attaching a property directly will result
+// into better performance with thousands of components
+// hanging around, and less memory pressure caused by the WeakMap
+const lazyGetter = (type, fn) => {
+ const secret = '_' + type + '$';
+ return {
+ get() {
+ return this[secret] || (this[type] = fn.call(this, type));
+ },
+ set(value) {
+ Object.defineProperty(this, secret, {configurable: true, value});
+ }
+ };
+};
+
+},{"../shared/constants.js":13,"../shared/poorlyfills.js":17}],5:[function(require,module,exports){
+'use strict';
+const { append } = require('../shared/utils.js');
+const { doc, fragment } = require('../shared/easy-dom.js');
+
+function Wire(childNodes) {
+ this.childNodes = childNodes;
+ this.length = childNodes.length;
+ this.first = childNodes[0];
+ this.last = childNodes[this.length - 1];
+}
+Object.defineProperty(exports, '__esModule', {value: true}).default = Wire
+
+// when a wire is inserted, all its nodes will follow
+Wire.prototype.insert = function insert() {
+ const df = fragment(this.first);
+ append(df, this.childNodes);
+ return df;
+};
+
+// when a wire is removed, all its nodes must be removed as well
+Wire.prototype.remove = function remove() {
+ const first = this.first;
+ const last = this.last;
+ if (this.length === 2) {
+ last.parentNode.removeChild(last);
+ } else {
+ const range = doc(first).createRange();
+ range.setStartBefore(this.childNodes[1]);
+ range.setEndAfter(last);
+ range.deleteContents();
+ }
+ return first;
+};
+
+},{"../shared/easy-dom.js":15,"../shared/utils.js":19}],6:[function(require,module,exports){
+'use strict';
+const {Map, WeakMap} = require('../shared/poorlyfills.js');
+const {UIDC, VOID_ELEMENTS} = require('../shared/constants.js');
+const Updates = (m => m.__esModule ? m.default : m)(require('../objects/Updates.js'));
+const {
+ createFragment,
+ importNode,
+ unique
+} = require('../shared/utils.js');
+
+const {selfClosing} = require('../shared/re.js');
+
+// a weak collection of contexts that
+// are already known to hyperHTML
+const bewitched = new WeakMap;
+
+// the collection of all template literals
+// since these are unique and immutable
+// for the whole application life-cycle
+const templates = new Map;
+
+// better known as hyper.bind(node), the render is
+// the main tag function in charge of fully upgrading
+// or simply updating, contexts used as hyperHTML targets.
+// The `this` context is either a regular DOM node or a fragment.
+function render(template) {
+ const wicked = bewitched.get(this);
+ if (wicked && wicked.template === unique(template)) {
+ update.apply(wicked.updates, arguments);
+ } else {
+ upgrade.apply(this, arguments);
+ }
+ return this;
+}
+
+// an upgrade is in charge of collecting template info,
+// parse it once, if unknown, to map all interpolations
+// as single DOM callbacks, relate such template
+// to the current context, and render it after cleaning the context up
+function upgrade(template) {
+ template = unique(template);
+ const info = templates.get(template) ||
+ createTemplate.call(this, template);
+ const fragment = importNode(this.ownerDocument, info.fragment);
+ const updates = Updates.create(fragment, info.paths);
+ bewitched.set(this, {template, updates});
+ update.apply(updates, arguments);
+ this.textContent = '';
+ this.appendChild(fragment);
+}
+
+// an update simply loops over all mapped DOM operations
+function update() {
+ const length = arguments.length;
+ for (let i = 1; i < length; i++) {
+ this[i - 1](arguments[i]);
+ }
+}
+
+// a template can be used to create a document fragment
+// aware of all interpolations and with a list
+// of paths used to find once those nodes that need updates,
+// no matter if these are attributes, text nodes, or regular one
+function createTemplate(template) {
+ const paths = [];
+ const html = template.join(UIDC).replace(SC_RE, SC_PLACE);
+ const fragment = createFragment(this, html);
+ Updates.find(fragment, paths, template.slice());
+ const info = {fragment, paths};
+ templates.set(template, info);
+ return info;
+}
+
+// some node could be special though, like a custom element
+// with a self closing tag, which should work through these changes.
+const SC_RE = selfClosing;
+const SC_PLACE = ($0, $1, $2) => {
+ return VOID_ELEMENTS.test($1) ? $0 : ('<' + $1 + $2 + '></' + $1 + '>');
+};
+
+Object.defineProperty(exports, '__esModule', {value: true}).default = render;
+
+},{"../objects/Updates.js":12,"../shared/constants.js":13,"../shared/poorlyfills.js":17,"../shared/re.js":18,"../shared/utils.js":19}],7:[function(require,module,exports){
+'use strict';
+const {ELEMENT_NODE, SVG_NAMESPACE} = require('../shared/constants.js');
+const {WeakMap, trim} = require('../shared/poorlyfills.js');
+const {fragment} = require('../shared/easy-dom.js');
+const {append, slice, unique} = require('../shared/utils.js');
+const Wire = (m => m.__esModule ? m.default : m)(require('../classes/Wire.js'));
+const render = (m => m.__esModule ? m.default : m)(require('./render.js'));
+
+// all wires used per each context
+const wires = new WeakMap;
+
+// A wire is a callback used as tag function
+// to lazily relate a generic object to a template literal.
+// hyper.wire(user)`<div id=user>${user.name}</div>`; => the div#user
+// This provides the ability to have a unique DOM structure
+// related to a unique JS object through a reusable template literal.
+// A wire can specify a type, as svg or html, and also an id
+// via html:id or :id convention. Such :id allows same JS objects
+// to be associated to different DOM structures accordingly with
+// the used template literal without losing previously rendered parts.
+const wire = (obj, type) => obj == null ?
+ content(type || 'html') :
+ weakly(obj, type || 'html');
+
+// A wire content is a virtual reference to one or more nodes.
+// It's represented by either a DOM node, or an Array.
+// In both cases, the wire content role is to simply update
+// all nodes through the list of related callbacks.
+// In few words, a wire content is like an invisible parent node
+// in charge of updating its content like a bound element would do.
+const content = type => {
+ let wire, container, content, template, updates;
+ return function (statics) {
+ statics = unique(statics);
+ let setup = template !== statics;
+ if (setup) {
+ template = statics;
+ content = fragment(document);
+ container = type === 'svg' ?
+ document.createElementNS(SVG_NAMESPACE, 'svg') :
+ content;
+ updates = render.bind(container);
+ }
+ updates.apply(null, arguments);
+ if (setup) {
+ if (type === 'svg') {
+ append(content, slice.call(container.childNodes));
+ }
+ wire = wireContent(content);
+ }
+ return wire;
+ };
+};
+
+// wires are weakly created through objects.
+// Each object can have multiple wires associated
+// and this is thanks to the type + :id feature.
+const weakly = (obj, type) => {
+ const i = type.indexOf(':');
+ let wire = wires.get(obj);
+ let id = type;
+ if (-1 < i) {
+ id = type.slice(i + 1);
+ type = type.slice(0, i) || 'html';
+ }
+ if (!wire) wires.set(obj, wire = {});
+ return wire[id] || (wire[id] = content(type));
+};
+
+// a document fragment loses its nodes as soon
+// as it's appended into another node.
+// This would easily lose wired content
+// so that on a second render call, the parent
+// node wouldn't know which node was there
+// associated to the interpolation.
+// To prevent hyperHTML to forget about wired nodes,
+// these are either returned as Array or, if there's ony one entry,
+// as single referenced node that won't disappear from the fragment.
+// The initial fragment, at this point, would be used as unique reference.
+const wireContent = node => {
+ const childNodes = node.childNodes;
+ const length = childNodes.length;
+ const wireNodes = [];
+ for (let i = 0; i < length; i++) {
+ let child = childNodes[i];
+ if (
+ child.nodeType === ELEMENT_NODE ||
+ trim.call(child.textContent).length !== 0
+ ) {
+ wireNodes.push(child);
+ }
+ }
+ return wireNodes.length === 1 ? wireNodes[0] : new Wire(wireNodes);
+};
+
+exports.content = content;
+exports.weakly = weakly;
+Object.defineProperty(exports, '__esModule', {value: true}).default = wire;
+
+},{"../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:[function(require,module,exports){
+'use strict';
+/*! (c) Andrea Giammarchi (ISC) */
+
+const Component = (m => m.__esModule ? m.default : m)(require('./classes/Component.js'));
+const {setup} = require('./classes/Component.js');
+const Intent = (m => m.__esModule ? m.default : m)(require('./objects/Intent.js'));
+const wire = (m => m.__esModule ? m.default : m)(require('./hyper/wire.js'));
+const {content, weakly} = require('./hyper/wire.js');
+const render = (m => m.__esModule ? m.default : m)(require('./hyper/render.js'));
+const diff = (m => m.__esModule ? m.default : m)(require('./shared/domdiff.js'));
+
+// all functions are self bound to the right context
+// you can do the following
+// const {bind, wire} = hyperHTML;
+// and use them right away: bind(node)`hello!`;
+const bind = context => render.bind(context);
+const define = Intent.define;
+
+hyper.Component = Component;
+hyper.bind = bind;
+hyper.define = define;
+hyper.diff = diff;
+hyper.hyper = hyper;
+hyper.wire = wire;
+
+// the wire content is the lazy defined
+// html or svg property of each hyper.Component
+setup(content);
+
+// everything is exported directly or through the
+// hyperHTML callback, when used as top level script
+exports.Component = Component;
+exports.bind = bind;
+exports.define = define;
+exports.diff = diff;
+exports.hyper = hyper;
+exports.wire = wire;
+
+// by default, hyperHTML is a smart function
+// that "magically" understands what's the best
+// thing to do with passed arguments
+function hyper(HTML) {
+ return arguments.length < 2 ?
+ (HTML == null ?
+ content('html') :
+ (typeof HTML === 'string' ?
+ hyper.wire(null, HTML) :
+ ('raw' in HTML ?
+ content('html')(HTML) :
+ ('nodeType' in HTML ?
+ hyper.bind(HTML) :
+ weakly(HTML, 'html')
+ )
+ )
+ )) :
+ ('raw' in HTML ?
+ content('html') : hyper.wire
+ ).apply(null, arguments);
+}
+Object.defineProperty(exports, '__esModule', {value: true}).default = hyper
+
+},{"./classes/Component.js":4,"./hyper/render.js":6,"./hyper/wire.js":7,"./objects/Intent.js":9,"./shared/domdiff.js":14}],9:[function(require,module,exports){
+'use strict';
+const intents = {};
+const keys = [];
+const hasOwnProperty = intents.hasOwnProperty;
+
+let length = 0;
+
+Object.defineProperty(exports, '__esModule', {value: true}).default = {
+
+ // hyperHTML.define('intent', (object, update) => {...})
+ // can be used to define a third parts update mechanism
+ // when every other known mechanism failed.
+ // hyper.define('user', info => info.name);
+ // hyper(node)`<p>${{user}}</p>`;
+ define: (intent, callback) => {
+ if (!(intent in intents)) {
+ length = keys.push(intent);
+ }
+ intents[intent] = callback;
+ },
+
+ // this method is used internally as last resort
+ // to retrieve a value out of an object
+ invoke: (object, callback) => {
+ for (let i = 0; i < length; i++) {
+ let key = keys[i];
+ if (hasOwnProperty.call(object, key)) {
+ return intents[key](object[key], callback);
+ }
+ }
+ }
+};
+
+},{}],10:[function(require,module,exports){
+'use strict';
+const {
+ COMMENT_NODE,
+ DOCUMENT_FRAGMENT_NODE,
+ ELEMENT_NODE
+} = require('../shared/constants.js');
+
+// every template literal interpolation indicates
+// a precise target in the DOM the template is representing.
+// `<p id=${'attribute'}>some ${'content'}</p>`
+// hyperHTML finds only once per template literal,
+// hence once per entire application life-cycle,
+// all nodes that are related to interpolations.
+// These nodes are stored as indexes used to retrieve,
+// once per upgrade, nodes that will change on each future update.
+// A path example is [2, 0, 1] representing the operation:
+// node.childNodes[2].childNodes[0].childNodes[1]
+// Attributes are addressed via their owner node and their name.
+const createPath = node => {
+ const path = [];
+ let parentNode;
+ switch (node.nodeType) {
+ case ELEMENT_NODE:
+ case DOCUMENT_FRAGMENT_NODE:
+ parentNode = node;
+ break;
+ case COMMENT_NODE:
+ parentNode = node.parentNode;
+ prepend(path, parentNode, node);
+ break;
+ default:
+ parentNode = node.ownerElement;
+ break;
+ }
+ for (
+ node = parentNode;
+ (parentNode = parentNode.parentNode);
+ node = parentNode
+ ) {
+ prepend(path, parentNode, node);
+ }
+ return path;
+};
+
+const prepend = (path, parent, node) => {
+ path.unshift(path.indexOf.call(parent.childNodes, node));
+};
+
+Object.defineProperty(exports, '__esModule', {value: true}).default = {
+ create: (type, node, name) => ({type, name, node, path: createPath(node)}),
+ find: (node, path) => {
+ const length = path.length;
+ for (let i = 0; i < length; i++) {
+ node = node.childNodes[path[i]];
+ }
+ return node;
+ }
+}
+
+},{"../shared/constants.js":13}],11:[function(require,module,exports){
+'use strict';
+// from https://github.com/developit/preact/blob/33fc697ac11762a1cb6e71e9847670d047af7ce5/src/constants.js
+const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
+
+// style is handled as both string and object
+// even if the target is an SVG element (consistency)
+Object.defineProperty(exports, '__esModule', {value: true}).default = (node, original, isSVG) => {
+ if (isSVG) {
+ const style = original.cloneNode(true);
+ style.value = '';
+ node.setAttributeNode(style);
+ return update(style, isSVG);
+ }
+ return update(node.style, isSVG);
+};
+
+// the update takes care or changing/replacing
+// only properties that are different or
+// in case of string, the whole node
+const update = (style, isSVG) => {
+ let oldType, oldValue;
+ return newValue => {
+ switch (typeof newValue) {
+ case 'object':
+ if (newValue) {
+ if (oldType === 'object') {
+ if (!isSVG) {
+ if (oldValue !== newValue) {
+ for (const key in oldValue) {
+ if (!(key in newValue)) {
+ style[key] = '';
+ }
+ }
+ }
+ }
+ } else {
+ if (isSVG) style.value = '';
+ else style.cssText = '';
+ }
+ const info = isSVG ? {} : style;
+ for (const key in newValue) {
+ const value = newValue[key];
+ info[key] = typeof value === 'number' &&
+ !IS_NON_DIMENSIONAL.test(key) ?
+ (value + 'px') : value;
+ }
+ oldType = 'object';
+ if (isSVG) style.value = toStyle((oldValue = info));
+ else oldValue = newValue;
+ break;
+ }
+ default:
+ if (oldValue != newValue) {
+ oldType = 'string';
+ oldValue = newValue;
+ if (isSVG) style.value = newValue || '';
+ else style.cssText = newValue || '';
+ }
+ break;
+ }
+ };
+};
+
+const hyphen = /([^A-Z])([A-Z]+)/g;
+const ized = ($0, $1, $2) => $1 + '-' + $2.toLowerCase();
+const toStyle = object => {
+ const css = [];
+ for (const key in object) {
+ css.push(key.replace(hyphen, ized), ':', object[key], ';');
+ }
+ return css.join('');
+};
+},{}],12:[function(require,module,exports){
+'use strict';
+const {
+ CONNECTED, DISCONNECTED, COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, ELEMENT_NODE, TEXT_NODE, OWNER_SVG_ELEMENT, SHOULD_USE_TEXT_CONTENT, UID, UIDC
+} = require('../shared/constants.js');
+
+const Component = (m => m.__esModule ? m.default : m)(require('../classes/Component.js'));
+const Wire = (m => m.__esModule ? m.default : m)(require('../classes/Wire.js'));
+const Path = (m => m.__esModule ? m.default : m)(require('./Path.js'));
+const Style = (m => m.__esModule ? m.default : m)(require('./Style.js'));
+const Intent = (m => m.__esModule ? m.default : m)(require('./Intent.js'));
+const domdiff = (m => m.__esModule ? m.default : m)(require('../shared/domdiff.js'));
+const { create: createElement, text } = require('../shared/easy-dom.js');
+const { Event, WeakSet, isArray, trim } = require('../shared/poorlyfills.js');
+const { createFragment, slice } = require('../shared/utils.js');
+
+// hyper.Component have a connected/disconnected
+// mechanism provided by MutationObserver
+// This weak set is used to recognize components
+// as DOM node that needs to trigger connected/disconnected events
+const components = new WeakSet;
+
+// a basic dictionary used to filter already cached attributes
+// while looking for special hyperHTML values.
+function Cache() {}
+Cache.prototype = Object.create(null);
+
+// returns an intent to explicitly inject content as html
+const asHTML = html => ({html});
+
+// returns nodes from wires and components
+const asNode = (item, i) => {
+ return 'ELEMENT_NODE' in item ?
+ item :
+ (item.constructor === Wire ?
+ // in the Wire case, the content can be
+ // removed, post-pended, inserted, or pre-pended and
+ // all these cases are handled by domdiff already
+ /* istanbul ignore next */
+ ((1 / i) < 0 ?
+ (i ? item.remove() : item.last) :
+ (i ? item.insert() : item.first)) :
+ asNode(item.render(), i));
+}
+
+// returns true if domdiff can handle the value
+const canDiff = value => 'ELEMENT_NODE' in value ||
+value instanceof Wire ||
+value instanceof Component;
+
+// updates are created once per context upgrade
+// within the main render function (../hyper/render.js)
+// These are an Array of callbacks to invoke passing
+// each interpolation value.
+// Updates can be related to any kind of content,
+// attributes, or special text-only cases such <style>
+// elements or <textarea>
+const create = (root, paths) => {
+ const updates = [];
+ const length = paths.length;
+ for (let i = 0; i < length; i++) {
+ const info = paths[i];
+ const node = Path.find(root, info.path);
+ switch (info.type) {
+ case 'any':
+ updates.push(setAnyContent(node, []));
+ break;
+ case 'attr':
+ updates.push(setAttribute(node, info.name, info.node));
+ break;
+ case 'text':
+ updates.push(setTextContent(node));
+ break;
+ }
+ }
+ return updates;
+};
+
+// finding all paths is a one-off operation performed
+// when a new template literal is used.
+// The goal is to map all target nodes that will be
+// used to update content/attributes every time
+// the same template literal is used to create content.
+// The result is a list of paths related to the template
+// with all the necessary info to create updates as
+// list of callbacks that target directly affected nodes.
+const find = (node, paths, parts) => {
+ const childNodes = node.childNodes;
+ const length = childNodes.length;
+ for (let i = 0; i < length; i++) {
+ let child = childNodes[i];
+ switch (child.nodeType) {
+ case ELEMENT_NODE:
+ findAttributes(child, paths, parts);
+ find(child, paths, parts);
+ break;
+ case COMMENT_NODE:
+ if (child.textContent === UID) {
+ parts.shift();
+ paths.push(
+ // basicHTML or other non standard engines
+ // might end up having comments in nodes
+ // where they shouldn't, hence this check.
+ SHOULD_USE_TEXT_CONTENT.test(node.nodeName) ?
+ Path.create('text', node) :
+ Path.create('any', child)
+ );
+ }
+ break;
+ case TEXT_NODE:
+ // the following ignore is actually covered by browsers
+ // only basicHTML ends up on previous COMMENT_NODE case
+ // instead of TEXT_NODE because it knows nothing about
+ // special style or textarea behavior
+ /* istanbul ignore if */
+ if (
+ SHOULD_USE_TEXT_CONTENT.test(node.nodeName) &&
+ trim.call(child.textContent) === UIDC
+ ) {
+ parts.shift();
+ paths.push(Path.create('text', node));
+ }
+ break;
+ }
+ }
+};
+
+// attributes are searched via unique hyperHTML id value.
+// Despite HTML being case insensitive, hyperHTML is able
+// to recognize attributes by name in a caseSensitive way.
+// This plays well with Custom Elements definitions
+// and also with XML-like environments, without trusting
+// the resulting DOM but the template literal as the source of truth.
+// IE/Edge has a funny bug with attributes and these might be duplicated.
+// This is why there is a cache in charge of being sure no duplicated
+// attributes are ever considered in future updates.
+const findAttributes = (node, paths, parts) => {
+ const cache = new Cache;
+ const attributes = node.attributes;
+ const array = slice.call(attributes);
+ const remove = [];
+ const length = array.length;
+ for (let i = 0; i < length; i++) {
+ const attribute = array[i];
+ if (attribute.value === UID) {
+ const name = attribute.name;
+ // the following ignore is covered by IE
+ // and the IE9 double viewBox test
+ /* istanbul ignore else */
+ if (!(name in cache)) {
+ const realName = parts.shift().replace(/^(?:|[\S\s]*?\s)(\S+?)=['"]?$/, '$1');
+ cache[name] = attributes[realName] ||
+ // the following ignore is covered by browsers
+ // while basicHTML is already case-sensitive
+ /* istanbul ignore next */
+ attributes[realName.toLowerCase()];
+ paths.push(Path.create('attr', cache[name], realName));
+ }
+ remove.push(attribute);
+ }
+ }
+ const len = remove.length;
+ for (let i = 0; i < len; i++) {
+ node.removeAttributeNode(remove[i]);
+ }
+
+ // This is a very specific Firefox/Safari issue
+ // but since it should be a not so common pattern,
+ // it's probably worth patching regardless.
+ // Basically, scripts created through strings are death.
+ // You need to create fresh new scripts instead.
+ // TODO: is there any other node that needs such nonsense ?
+ const nodeName = node.nodeName;
+ if (/^script$/i.test(nodeName)) {
+ const script = createElement(node, nodeName);
+ for (let i = 0; i < attributes.length; i++) {
+ script.setAttributeNode(attributes[i].cloneNode(true));
+ }
+ script.textContent = node.textContent;
+ node.parentNode.replaceChild(script, node);
+ }
+};
+
+// when a Promise is used as interpolation value
+// its result must be parsed once resolved.
+// This callback is in charge of understanding what to do
+// with a returned value once the promise is resolved.
+const invokeAtDistance = (value, callback) => {
+ callback(value.placeholder);
+ if ('text' in value) {
+ Promise.resolve(value.text).then(String).then(callback);
+ } else if ('any' in value) {
+ Promise.resolve(value.any).then(callback);
+ } else if ('html' in value) {
+ Promise.resolve(value.html).then(asHTML).then(callback);
+ } else {
+ Promise.resolve(Intent.invoke(value, callback)).then(callback);
+ }
+};
+
+// quick and dirty way to check for Promise/ish values
+const isPromise_ish = value => value != null && 'then' in value;
+
+// in a hyper(node)`<div>${content}</div>` case
+// everything could happen:
+// * it's a JS primitive, stored as text
+// * it's null or undefined, the node should be cleaned
+// * it's a component, update the content by rendering it
+// * it's a promise, update the content once resolved
+// * it's an explicit intent, perform the desired operation
+// * it's an Array, resolve all values if Promises and/or
+// update the node with the resulting list of content
+const setAnyContent = (node, childNodes) => {
+ let fastPath = false;
+ let oldValue;
+ const anyContent = value => {
+ switch (typeof value) {
+ case 'string':
+ case 'number':
+ case 'boolean':
+ if (fastPath) {
+ if (oldValue !== value) {
+ oldValue = value;
+ childNodes[0].textContent = value;
+ }
+ } else {
+ fastPath = true;
+ oldValue = value;
+ childNodes = domdiff(
+ node.parentNode,
+ childNodes,
+ [text(node, value)],
+ asNode,
+ node
+ );
+ }
+ break;
+ case 'object':
+ case 'undefined':
+ if (value == null) {
+ fastPath = false;
+ childNodes = domdiff(
+ node.parentNode,
+ childNodes,
+ [],
+ asNode,
+ node
+ );
+ break;
+ }
+ default:
+ fastPath = false;
+ oldValue = value;
+ if (isArray(value)) {
+ if (value.length === 0) {
+ if (childNodes.length) {
+ childNodes = domdiff(
+ node.parentNode,
+ childNodes,
+ [],
+ asNode,
+ node
+ );
+ }
+ } else {
+ switch (typeof value[0]) {
+ case 'string':
+ case 'number':
+ case 'boolean':
+ anyContent({html: value});
+ break;
+ case 'object':
+ if (isArray(value[0])) {
+ value = value.concat.apply([], value);
+ }
+ if (isPromise_ish(value[0])) {
+ Promise.all(value).then(anyContent);
+ break;
+ }
+ default:
+ childNodes = domdiff(
+ node.parentNode,
+ childNodes,
+ value,
+ asNode,
+ node
+ );
+ break;
+ }
+ }
+ } else if (canDiff(value)) {
+ childNodes = domdiff(
+ node.parentNode,
+ childNodes,
+ value.nodeType === DOCUMENT_FRAGMENT_NODE ?
+ slice.call(value.childNodes) :
+ [value],
+ asNode,
+ node
+ );
+ } else if (isPromise_ish(value)) {
+ value.then(anyContent);
+ } else if ('placeholder' in value) {
+ invokeAtDistance(value, anyContent);
+ } else if ('text' in value) {
+ anyContent(String(value.text));
+ } else if ('any' in value) {
+ anyContent(value.any);
+ } else if ('html' in value) {
+ childNodes = domdiff(
+ node.parentNode,
+ childNodes,
+ slice.call(
+ createFragment(
+ node,
+ [].concat(value.html).join('')
+ ).childNodes
+ ),
+ asNode,
+ node
+ );
+ } else if ('length' in value) {
+ anyContent(slice.call(value));
+ } else {
+ anyContent(Intent.invoke(value, anyContent));
+ }
+ break;
+ }
+ };
+ return anyContent;
+};
+
+// there are four kind of attributes, and related behavior:
+// * events, with a name starting with `on`, to add/remove event listeners
+// * special, with a name present in their inherited prototype, accessed directly
+// * regular, accessed through get/setAttribute standard DOM methods
+// * style, the only regular attribute that also accepts an object as value
+// so that you can style=${{width: 120}}. In this case, the behavior has been
+// fully inspired by Preact library and its simplicity.
+const setAttribute = (node, name, original) => {
+ const isSVG = OWNER_SVG_ELEMENT in node;
+ let oldValue;
+ // if the attribute is the style one
+ // handle it differently from others
+ if (name === 'style') {
+ return Style(node, original, isSVG);
+ }
+ // the name is an event one,
+ // add/remove event listeners accordingly
+ else if (/^on/.test(name)) {
+ let type = name.slice(2);
+ if (type === CONNECTED || type === DISCONNECTED) {
+ if (notObserving) {
+ notObserving = false;
+ observe();
+ }
+ components.add(node);
+ }
+ else if (name.toLowerCase() in node) {
+ type = type.toLowerCase();
+ }
+ return newValue => {
+ if (oldValue !== newValue) {
+ if (oldValue) node.removeEventListener(type, oldValue, false);
+ oldValue = newValue;
+ if (newValue) node.addEventListener(type, newValue, false);
+ }
+ };
+ }
+ // the attribute is special ('value' in input)
+ // and it's not SVG *or* the name is exactly data,
+ // in this case assign the value directly
+ else if (name === 'data' || (!isSVG && name in node)) {
+ return newValue => {
+ if (oldValue !== newValue) {
+ oldValue = newValue;
+ if (node[name] !== newValue) {
+ node[name] = newValue;
+ if (newValue == null) {
+ node.removeAttribute(name);
+ }
+ }
+ }
+ };
+ }
+ // in every other case, use the attribute node as it is
+ // update only the value, set it as node only when/if needed
+ else {
+ let owner = false;
+ const attribute = original.cloneNode(true);
+ return newValue => {
+ if (oldValue !== newValue) {
+ oldValue = newValue;
+ if (attribute.value !== newValue) {
+ if (newValue == null) {
+ if (owner) {
+ owner = false;
+ node.removeAttributeNode(attribute);
+ }
+ attribute.value = newValue;
+ } else {
+ attribute.value = newValue;
+ if (!owner) {
+ owner = true;
+ node.setAttributeNode(attribute);
+ }
+ }
+ }
+ }
+ };
+ }
+};
+
+// style or textareas don't accept HTML as content
+// it's pointless to transform or analyze anything
+// different from text there but it's worth checking
+// for possible defined intents.
+const setTextContent = node => {
+ // avoid hyper comments inside textarea/style when value is undefined
+ let oldValue = '';
+ const textContent = value => {
+ if (oldValue !== value) {
+ oldValue = value;
+ if (typeof value === 'object' && value) {
+ if (isPromise_ish(value)) {
+ value.then(textContent);
+ } else if ('placeholder' in value) {
+ invokeAtDistance(value, textContent);
+ } else if ('text' in value) {
+ textContent(String(value.text));
+ } else if ('any' in value) {
+ textContent(value.any);
+ } else if ('html' in value) {
+ textContent([].concat(value.html).join(''));
+ } else if ('length' in value) {
+ textContent(slice.call(value).join(''));
+ } else {
+ textContent(Intent.invoke(value, textContent));
+ }
+ } else {
+ node.textContent = value == null ? '' : value;
+ }
+ }
+ };
+ return textContent;
+};
+
+Object.defineProperty(exports, '__esModule', {value: true}).default = {create, find};
+
+// hyper.Components might need connected/disconnected notifications
+// used by components and their onconnect/ondisconnect callbacks.
+// When one of these callbacks is encountered,
+// the document starts being observed.
+let notObserving = true;
+function observe() {
+
+ // when hyper.Component related DOM nodes
+ // are appended or removed from the live tree
+ // these might listen to connected/disconnected events
+ // This utility is in charge of finding all components
+ // involved in the DOM update/change and dispatch
+ // related information to them
+ const dispatchAll = (nodes, type) => {
+ const event = new Event(type);
+ const length = nodes.length;
+ for (let i = 0; i < length; i++) {
+ let node = nodes[i];
+ if (node.nodeType === ELEMENT_NODE) {
+ dispatchTarget(node, event);
+ }
+ }
+ };
+
+ // the way it's done is via the components weak set
+ // and recursively looking for nested components too
+ const dispatchTarget = (node, event) => {
+ if (components.has(node)) {
+ node.dispatchEvent(event);
+ }
+
+ const children = node.children;
+ const length = children.length;
+ for (let i = 0; i < length; i++) {
+ dispatchTarget(children[i], event);
+ }
+ }
+
+ // The MutationObserver is the best way to implement that
+ // but there is a fallback to deprecated DOMNodeInserted/Removed
+ // so that even older browsers/engines can help components life-cycle
+ try {
+ (new MutationObserver(records => {
+ const length = records.length;
+ for (let i = 0; i < length; i++) {
+ let record = records[i];
+ dispatchAll(record.removedNodes, DISCONNECTED);
+ dispatchAll(record.addedNodes, CONNECTED);
+ }
+ })).observe(document, {subtree: true, childList: true});
+ } catch(o_O) {
+ document.addEventListener('DOMNodeRemoved', event => {
+ dispatchAll([event.target], DISCONNECTED);
+ }, false);
+ document.addEventListener('DOMNodeInserted', event => {
+ dispatchAll([event.target], CONNECTED);
+ }, false);
+ }
+}
+
+},{"../classes/Component.js":4,"../classes/Wire.js":5,"../shared/constants.js":13,"../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){
+'use strict';
+const G = document.defaultView;
+exports.G = G;
+
+// Node.CONSTANTS
+// 'cause some engine has no global Node defined
+// (i.e. Node, NativeScript, basicHTML ... )
+const ELEMENT_NODE = 1;
+exports.ELEMENT_NODE = ELEMENT_NODE;
+const ATTRIBUTE_NODE = 2;
+exports.ATTRIBUTE_NODE = ATTRIBUTE_NODE;
+const TEXT_NODE = 3;
+exports.TEXT_NODE = TEXT_NODE;
+const COMMENT_NODE = 8;
+exports.COMMENT_NODE = COMMENT_NODE;
+const DOCUMENT_FRAGMENT_NODE = 11;
+exports.DOCUMENT_FRAGMENT_NODE = DOCUMENT_FRAGMENT_NODE;
+
+// HTML related constants
+const VOID_ELEMENTS = /^area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr$/i;
+exports.VOID_ELEMENTS = VOID_ELEMENTS;
+
+// SVG related constants
+const OWNER_SVG_ELEMENT = 'ownerSVGElement';
+exports.OWNER_SVG_ELEMENT = OWNER_SVG_ELEMENT;
+const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
+exports.SVG_NAMESPACE = SVG_NAMESPACE;
+
+// Custom Elements / MutationObserver constants
+const CONNECTED = 'connected';
+exports.CONNECTED = CONNECTED;
+const DISCONNECTED = 'dis' + CONNECTED;
+exports.DISCONNECTED = DISCONNECTED;
+
+// hyperHTML related constants
+const EXPANDO = '_hyper: ';
+exports.EXPANDO = EXPANDO;
+const SHOULD_USE_TEXT_CONTENT = /^style|textarea$/i;
+exports.SHOULD_USE_TEXT_CONTENT = SHOULD_USE_TEXT_CONTENT;
+const UID = EXPANDO + ((Math.random() * new Date) | 0) + ';';
+exports.UID = UID;
+const UIDC = '<!--' + UID + '-->';
+exports.UIDC = UIDC;
+
+},{}],14:[function(require,module,exports){
+'use strict';
+/* AUTOMATICALLY IMPORTED, DO NOT MODIFY */
+/*! (c) 2017 Andrea Giammarchi (ISC) */
+
+/**
+ * This code is a revisited port of the snabbdom vDOM diffing logic,
+ * the same that fuels as fork Vue.js or other libraries.
+ * @credits https://github.com/snabbdom/snabbdom
+ */
+
+const identity = O => O;
+
+const domdiff = (
+ parentNode, // where changes happen
+ currentNodes, // Array of current items/nodes
+ futureNodes, // Array of future items/nodes
+ getNode, // optional way to retrieve a node from an item
+ beforeNode // optional item/node to use as insertBefore delimiter
+) => {
+ const get = getNode || identity;
+ const before = beforeNode == null ? null : get(beforeNode, 0);
+ let currentStart = 0, futureStart = 0;
+ let currentEnd = currentNodes.length - 1;
+ let currentStartNode = currentNodes[0];
+ let currentEndNode = currentNodes[currentEnd];
+ let futureEnd = futureNodes.length - 1;
+ let futureStartNode = futureNodes[0];
+ let futureEndNode = futureNodes[futureEnd];
+ while (currentStart <= currentEnd && futureStart <= futureEnd) {
+ if (currentStartNode == null) {
+ currentStartNode = currentNodes[++currentStart];
+ }
+ else if (currentEndNode == null) {
+ currentEndNode = currentNodes[--currentEnd];
+ }
+ else if (futureStartNode == null) {
+ futureStartNode = futureNodes[++futureStart];
+ }
+ else if (futureEndNode == null) {
+ futureEndNode = futureNodes[--futureEnd];
+ }
+ else if (currentStartNode == futureStartNode) {
+ currentStartNode = currentNodes[++currentStart];
+ futureStartNode = futureNodes[++futureStart];
+ }
+ else if (currentEndNode == futureEndNode) {
+ currentEndNode = currentNodes[--currentEnd];
+ futureEndNode = futureNodes[--futureEnd];
+ }
+ else if (currentStartNode == futureEndNode) {
+ parentNode.insertBefore(
+ get(currentStartNode, 1),
+ get(currentEndNode, -0).nextSibling
+ );
+ currentStartNode = currentNodes[++currentStart];
+ futureEndNode = futureNodes[--futureEnd];
+ }
+ else if (currentEndNode == futureStartNode) {
+ parentNode.insertBefore(
+ get(currentEndNode, 1),
+ get(currentStartNode, 0)
+ );
+ currentEndNode = currentNodes[--currentEnd];
+ futureStartNode = futureNodes[++futureStart];
+ }
+ else {
+ let index = currentNodes.indexOf(futureStartNode);
+ if (index < 0) {
+ parentNode.insertBefore(
+ get(futureStartNode, 1),
+ get(currentStartNode, 0)
+ );
+ futureStartNode = futureNodes[++futureStart];
+ }
+ else {
+ let el = currentNodes[index];
+ currentNodes[index] = null;
+ parentNode.insertBefore(
+ get(el, 1),
+ get(currentStartNode, 0)
+ );
+ futureStartNode = futureNodes[++futureStart];
+ }
+ }
+ }
+ if (currentStart <= currentEnd || futureStart <= futureEnd) {
+ if (currentStart > currentEnd) {
+ const pin = futureNodes[futureEnd + 1];
+ const place = pin == null ? before : get(pin, 0);
+ if (futureStart === futureEnd) {
+ parentNode.insertBefore(get(futureNodes[futureStart], 1), place);
+ }
+ else {
+ const fragment = parentNode.ownerDocument.createDocumentFragment();
+ while (futureStart <= futureEnd) {
+ fragment.appendChild(get(futureNodes[futureStart++], 1));
+ }
+ parentNode.insertBefore(fragment, place);
+ }
+ }
+ else {
+ if (currentNodes[currentStart] == null) currentStart++;
+ if (currentStart === currentEnd) {
+ parentNode.removeChild(get(currentNodes[currentStart], -1));
+ }
+ else {
+ const range = parentNode.ownerDocument.createRange();
+ range.setStartBefore(get(currentNodes[currentStart], -1));
+ range.setEndAfter(get(currentNodes[currentEnd], -1));
+ range.deleteContents();
+ }
+ }
+ }
+ return futureNodes;
+};
+
+Object.defineProperty(exports, '__esModule', {value: true}).default = domdiff;
+
+},{}],15:[function(require,module,exports){
+'use strict';
+// these are tiny helpers to simplify most common operations needed here
+const create = (node, type) => doc(node).createElement(type);
+exports.create = create;
+const doc = node => node.ownerDocument || node;
+exports.doc = doc;
+const fragment = node => doc(node).createDocumentFragment();
+exports.fragment = fragment;
+const text = (node, text) => doc(node).createTextNode(text);
+exports.text = text;
+
+},{}],16:[function(require,module,exports){
+'use strict';
+const {create, fragment, text} = require('./easy-dom.js');
+
+const testFragment = fragment(document);
+
+// DOM4 node.append(...many)
+const hasAppend = 'append' in testFragment;
+exports.hasAppend = hasAppend;
+
+// detect old browsers without HTMLTemplateElement content support
+const hasContent = 'content' in create(document, 'template');
+exports.hasContent = hasContent;
+
+// IE 11 has problems with cloning templates: it "forgets" empty childNodes
+testFragment.appendChild(text(testFragment, 'g'));
+testFragment.appendChild(text(testFragment, ''));
+const hasDoomedCloneNode = testFragment.cloneNode(true).childNodes.length === 1;
+exports.hasDoomedCloneNode = hasDoomedCloneNode;
+
+// old browsers need to fallback to cloneNode
+// Custom Elements V0 and V1 will work polyfilled
+// but native implementations need importNode instead
+// (specially Chromium and its old V0 implementation)
+const hasImportNode = 'importNode' in document;
+exports.hasImportNode = hasImportNode;
+
+},{"./easy-dom.js":15}],17:[function(require,module,exports){
+'use strict';
+const {G, UID} = require('./constants.js');
+
+// you know that kind of basics you need to cover
+// your use case only but you don't want to bloat the library?
+// There's even a package in here:
+// https://www.npmjs.com/package/poorlyfills
+
+// used to dispatch simple events
+let Event = G.Event;
+try {
+ new Event('Event');
+} catch(o_O) {
+ Event = function (type) {
+ const e = document.createEvent('Event');
+ e.initEvent(type, false, false);
+ return e;
+ };
+}
+exports.Event = Event;
+
+// used to store template literals
+const Map = G.Map || function Map() {
+ const keys = [], values = [];
+ return {
+ get(obj) {
+ return values[keys.indexOf(obj)];
+ },
+ set(obj, value) {
+ values[keys.push(obj) - 1] = value;
+ }
+ };
+};
+exports.Map = Map;
+
+// used to store wired content
+const WeakMap = G.WeakMap || function WeakMap() {
+ return {
+ get(obj) { return obj[UID]; },
+ set(obj, value) {
+ Object.defineProperty(obj, UID, {
+ configurable: true,
+ value
+ });
+ }
+ };
+};
+exports.WeakMap = WeakMap;
+
+// used to store hyper.Components
+const WeakSet = G.WeakSet || function WeakSet() {
+ const wm = new WeakMap;
+ return {
+ add(obj) { wm.set(obj, true); },
+ has(obj) { return wm.get(obj) === true; }
+ };
+};
+exports.WeakSet = WeakSet;
+
+// used to be sure IE9 or older Androids work as expected
+const isArray = Array.isArray || (toString =>
+ arr => toString.call(arr) === '[object Array]'
+)({}.toString);
+exports.isArray = isArray;
+
+const trim = UID.trim || function () {
+ return this.replace(/^\s+|\s+$/g, '');
+};
+exports.trim = trim;
+
+},{"./constants.js":13}],18:[function(require,module,exports){
+'use strict';
+// TODO: I'd love to code-cover RegExp too here
+// these are fundamental for this library
+
+const spaces = ' \\f\\n\\r\\t';
+const almostEverything = '[^ ' + spaces + '\\/>"\'=]+';
+const attrName = '[ ' + spaces + ']+' + almostEverything;
+const tagName = '<([A-Za-z]+[A-Za-z0-9:_-]*)((?:';
+const attrPartials = '(?:=(?:\'[^\']*?\'|"[^"]*?"|<[^>]*?>|' + almostEverything + '))?)';
+
+const attrSeeker = new RegExp(
+ tagName + attrName + attrPartials + '+)([ ' + spaces + ']*/?>)',
+ 'g'
+);
+
+const selfClosing = new RegExp(
+ tagName + attrName + attrPartials + '*)([ ' + spaces + ']*/>)',
+ 'g'
+);
+
+exports.attrName = attrName;
+exports.attrSeeker = attrSeeker;
+exports.selfClosing = selfClosing;
+
+},{}],19:[function(require,module,exports){
+'use strict';
+const {attrName, attrSeeker} = require('./re.js');
+
+const {
+ G,
+ OWNER_SVG_ELEMENT,
+ SVG_NAMESPACE,
+ UID,
+ UIDC
+} = require('./constants.js');
+
+const {
+ hasAppend,
+ hasContent,
+ hasDoomedCloneNode,
+ hasImportNode
+} = require('./features-detection.js');
+
+const {create, doc, fragment} = require('./easy-dom.js');
+
+// appends an array of nodes
+// to a generic node/fragment
+// When available, uses append passing all arguments at once
+// hoping that's somehow faster, even if append has more checks on type
+const append = hasAppend ?
+ (node, childNodes) => {
+ node.append.apply(node, childNodes);
+ } :
+ (node, childNodes) => {
+ const length = childNodes.length;
+ for (let i = 0; i < length; i++) {
+ node.appendChild(childNodes[i]);
+ }
+ };
+exports.append = append;
+
+const findAttributes = new RegExp('(' + attrName + '=)([\'"]?)' + UIDC + '\\2', 'gi');
+const comments = ($0, $1, $2, $3) =>
+ '<' + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
+const replaceAttributes = ($0, $1, $2) => $1 + ($2 || '"') + UID + ($2 || '"');
+
+// given a node and a generic HTML content,
+// create either an SVG or an HTML fragment
+// where such content will be injected
+const createFragment = (node, html) =>
+ (OWNER_SVG_ELEMENT in node ?
+ SVGFragment :
+ HTMLFragment
+ )(node, html.replace(attrSeeker, comments));
+exports.createFragment = createFragment;
+
+// IE/Edge shenanigans proof cloneNode
+// it goes through all nodes manually
+// instead of relying the engine to suddenly
+// merge nodes together
+const cloneNode = hasDoomedCloneNode ?
+ node => {
+ const clone = node.cloneNode();
+ const childNodes = node.childNodes ||
+ // this is an excess of caution
+ // but some node, in IE, might not
+ // have childNodes property.
+ // The following fallback ensure working code
+ // in older IE without compromising performance
+ // or any other browser/engine involved.
+ /* istanbul ignore next */
+ [];
+ const length = childNodes.length;
+ for (let i = 0; i < length; i++) {
+ clone.appendChild(cloneNode(childNodes[i]));
+ }
+ return clone;
+ } :
+ // the following ignore is due code-coverage
+ // combination of not having document.importNode
+ // but having a working node.cloneNode.
+ // This shenario is common on older Android/WebKit browsers
+ // but basicHTML here tests just two major cases:
+ // with document.importNode or with broken cloneNode.
+ /* istanbul ignore next */
+ node => node.cloneNode(true);
+
+// used to import html into fragments
+const importNode = hasImportNode ?
+ (doc, node) => doc.importNode(node, true) :
+ (doc, node) => cloneNode(node)
+exports.importNode = importNode
+
+// just recycling a one-off array to use slice
+// in every needed place
+const slice = [].slice;
+exports.slice = slice;
+
+// lazy evaluated, returns the unique identity
+// of a template literal, as tempalte literal itself.
+// By default, ES2015 template literals are unique
+// tag`a${1}z` === tag`a${2}z`
+// even if interpolated values are different
+// the template chunks are in a frozen Array
+// that is identical each time you use the same
+// literal to represent same static content
+// around its own interpolations.
+const unique = template => TL(template);
+exports.unique = unique;
+
+// TL returns a unique version of the template
+// it needs lazy feature detection
+// (cannot trust literals with transpiled code)
+let TL = template => {
+ if (
+ // TypeScript template literals are not standard
+ template.propertyIsEnumerable('raw') ||
+ (
+ // Firefox < 55 has not standard implementation neither
+ /Firefox\/(\d+)/.test((G.navigator || {}).userAgent) &&
+ parseFloat(RegExp.$1) < 55
+ )
+ ) {
+ // in these cases, address templates once
+ const templateObjects = {};
+ // but always return the same template
+ TL = template => {
+ const key = '_' + template.join(UID);
+ return templateObjects[key] || (
+ templateObjects[key] = template
+ );
+ };
+ }
+ else {
+ // make TL an identity like function
+ TL = template => template;
+ }
+ return TL(template);
+};
+
+// create document fragments via native template
+// with a fallback for browsers that won't be able
+// to deal with some injected element such <td> or others
+const HTMLFragment = hasContent ?
+ (node, html) => {
+ const container = create(node, 'template');
+ container.innerHTML = html;
+ return container.content;
+ } :
+ (node, html) => {
+ const container = create(node, 'template');
+ const content = fragment(node);
+ if (/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(html)) {
+ const selector = RegExp.$1;
+ container.innerHTML = '<table>' + html + '</table>';
+ append(content, slice.call(container.querySelectorAll(selector)));
+ } else {
+ container.innerHTML = html;
+ append(content, slice.call(container.childNodes));
+ }
+ return content;
+ };
+
+// creates SVG fragment with a fallback for IE that needs SVG
+// within the HTML content
+const SVGFragment = hasContent ?
+ (node, html) => {
+ const content = fragment(node);
+ const container = doc(node).createElementNS(SVG_NAMESPACE, 'svg');
+ container.innerHTML = html;
+ append(content, slice.call(container.childNodes));
+ return content;
+ } :
+ (node, html) => {
+ const content = fragment(node);
+ const container = create(node, 'div');
+ container.innerHTML = '<svg xmlns="' + SVG_NAMESPACE + '">' + html + '</svg>';
+ append(content, slice.call(container.firstChild.childNodes));
+ return content;
+ };
+
+},{"./constants.js":13,"./easy-dom.js":15,"./features-detection.js":16,"./re.js":18}],20:[function(require,module,exports){
+/* globals module, require */
+
+"use strict";
+
+const IOElement = require("../js/io-element");
+
+class IOClock extends IOElement
+{
+ connectedCallback()
+ {
+ this._timer = setInterval(() => this.render(), 1000);
+ }
+
+ disconnectedCallback()
+ {
+ clearInterval(this._timer);
+ }
+
+ render()
+ {
+ this.html`
+ ${{i18n: "io_clock"}}
+ @${(new Date()).toLocaleTimeString()}
+ `;
+ }
+}
+
+IOClock.define("io-clock");
+
+},{"../js/io-element":1}]},{},[20]);
« js/io-element.js ('K') | « tests/io-element.html ('k') | tests/io-element.test.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld