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