OLD | NEW |
(Empty) | |
| 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 */ |
| 3287 |
| 3288 "use strict"; |
| 3289 |
| 3290 const IOElement = require("../js/io-element"); |
| 3291 |
| 3292 class IOClock extends IOElement |
| 3293 { |
| 3294 connectedCallback() |
| 3295 { |
| 3296 this._timer = setInterval(() => this.render(), 1000); |
| 3297 } |
| 3298 |
| 3299 disconnectedCallback() |
| 3300 { |
| 3301 clearInterval(this._timer); |
| 3302 } |
| 3303 |
| 3304 render() |
| 3305 { |
| 3306 this.html` |
| 3307 ${{i18n: "io_clock"}} |
| 3308 @${(new Date()).toLocaleTimeString()} |
| 3309 `; |
| 3310 } |
| 3311 } |
| 3312 |
| 3313 IOClock.define("io-clock"); |
| 3314 |
| 3315 },{"../js/io-element":1}]},{},[20]); |
OLD | NEW |