1 /** 2 * @license 3 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 4 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7 * Code distributed by Google as part of the polymer project is also 8 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9 */ 10 // @version 0.6.1 11 if (typeof WeakMap === "undefined") { 12 (function() { 13 var defineProperty = Object.defineProperty; 14 var counter = Date.now() % 1e9; 15 var WeakMap = function() { 16 this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__"); 17 }; 18 WeakMap.prototype = { 19 set: function(key, value) { 20 var entry = key[this.name]; 21 if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, { 22 value: [ key, value ], 23 writable: true 24 }); 25 return this; 26 }, 27 get: function(key) { 28 var entry; 29 return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined; 30 }, 31 "delete": function(key) { 32 var entry = key[this.name]; 33 if (!entry || entry[0] !== key) return false; 34 entry[0] = entry[1] = undefined; 35 return true; 36 }, 37 has: function(key) { 38 var entry = key[this.name]; 39 if (!entry) return false; 40 return entry[0] === key; 41 } 42 }; 43 window.WeakMap = WeakMap; 44 })(); 45 } 46 47 (function(global) { 48 var registrationsTable = new WeakMap(); 49 var setImmediate; 50 if (/Trident|Edge/.test(navigator.userAgent)) { 51 setImmediate = setTimeout; 52 } else if (window.setImmediate) { 53 setImmediate = window.setImmediate; 54 } else { 55 var setImmediateQueue = []; 56 var sentinel = String(Math.random()); 57 window.addEventListener("message", function(e) { 58 if (e.data === sentinel) { 59 var queue = setImmediateQueue; 60 setImmediateQueue = []; 61 queue.forEach(function(func) { 62 func(); 63 }); 64 } 65 }); 66 setImmediate = function(func) { 67 setImmediateQueue.push(func); 68 window.postMessage(sentinel, "*"); 69 }; 70 } 71 var isScheduled = false; 72 var scheduledObservers = []; 73 function scheduleCallback(observer) { 74 scheduledObservers.push(observer); 75 if (!isScheduled) { 76 isScheduled = true; 77 setImmediate(dispatchCallbacks); 78 } 79 } 80 function wrapIfNeeded(node) { 81 return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node; 82 } 83 function dispatchCallbacks() { 84 isScheduled = false; 85 var observers = scheduledObservers; 86 scheduledObservers = []; 87 observers.sort(function(o1, o2) { 88 return o1.uid_ - o2.uid_; 89 }); 90 var anyNonEmpty = false; 91 observers.forEach(function(observer) { 92 var queue = observer.takeRecords(); 93 removeTransientObserversFor(observer); 94 if (queue.length) { 95 observer.callback_(queue, observer); 96 anyNonEmpty = true; 97 } 98 }); 99 if (anyNonEmpty) dispatchCallbacks(); 100 } 101 function removeTransientObserversFor(observer) { 102 observer.nodes_.forEach(function(node) { 103 var registrations = registrationsTable.get(node); 104 if (!registrations) return; 105 registrations.forEach(function(registration) { 106 if (registration.observer === observer) registration.removeTransientObservers(); 107 }); 108 }); 109 } 110 function forEachAncestorAndObserverEnqueueRecord(target, callback) { 111 for (var node = target; node; node = node.parentNode) { 112 var registrations = registrationsTable.get(node); 113 if (registrations) { 114 for (var j = 0; j < registrations.length; j++) { 115 var registration = registrations[j]; 116 var options = registration.options; 117 if (node !== target && !options.subtree) continue; 118 var record = callback(options); 119 if (record) registration.enqueue(record); 120 } 121 } 122 } 123 } 124 var uidCounter = 0; 125 function JsMutationObserver(callback) { 126 this.callback_ = callback; 127 this.nodes_ = []; 128 this.records_ = []; 129 this.uid_ = ++uidCounter; 130 } 131 JsMutationObserver.prototype = { 132 observe: function(target, options) { 133 target = wrapIfNeeded(target); 134 if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) { 135 throw new SyntaxError(); 136 } 137 var registrations = registrationsTable.get(target); 138 if (!registrations) registrationsTable.set(target, registrations = []); 139 var registration; 140 for (var i = 0; i < registrations.length; i++) { 141 if (registrations[i].observer === this) { 142 registration = registrations[i]; 143 registration.removeListeners(); 144 registration.options = options; 145 break; 146 } 147 } 148 if (!registration) { 149 registration = new Registration(this, target, options); 150 registrations.push(registration); 151 this.nodes_.push(target); 152 } 153 registration.addListeners(); 154 }, 155 disconnect: function() { 156 this.nodes_.forEach(function(node) { 157 var registrations = registrationsTable.get(node); 158 for (var i = 0; i < registrations.length; i++) { 159 var registration = registrations[i]; 160 if (registration.observer === this) { 161 registration.removeListeners(); 162 registrations.splice(i, 1); 163 break; 164 } 165 } 166 }, this); 167 this.records_ = []; 168 }, 169 takeRecords: function() { 170 var copyOfRecords = this.records_; 171 this.records_ = []; 172 return copyOfRecords; 173 } 174 }; 175 function MutationRecord(type, target) { 176 this.type = type; 177 this.target = target; 178 this.addedNodes = []; 179 this.removedNodes = []; 180 this.previousSibling = null; 181 this.nextSibling = null; 182 this.attributeName = null; 183 this.attributeNamespace = null; 184 this.oldValue = null; 185 } 186 function copyMutationRecord(original) { 187 var record = new MutationRecord(original.type, original.target); 188 record.addedNodes = original.addedNodes.slice(); 189 record.removedNodes = original.removedNodes.slice(); 190 record.previousSibling = original.previousSibling; 191 record.nextSibling = original.nextSibling; 192 record.attributeName = original.attributeName; 193 record.attributeNamespace = original.attributeNamespace; 194 record.oldValue = original.oldValue; 195 return record; 196 } 197 var currentRecord, recordWithOldValue; 198 function getRecord(type, target) { 199 return currentRecord = new MutationRecord(type, target); 200 } 201 function getRecordWithOldValue(oldValue) { 202 if (recordWithOldValue) return recordWithOldValue; 203 recordWithOldValue = copyMutationRecord(currentRecord); 204 recordWithOldValue.oldValue = oldValue; 205 return recordWithOldValue; 206 } 207 function clearRecords() { 208 currentRecord = recordWithOldValue = undefined; 209 } 210 function recordRepresentsCurrentMutation(record) { 211 return record === recordWithOldValue || record === currentRecord; 212 } 213 function selectRecord(lastRecord, newRecord) { 214 if (lastRecord === newRecord) return lastRecord; 215 if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue; 216 return null; 217 } 218 function Registration(observer, target, options) { 219 this.observer = observer; 220 this.target = target; 221 this.options = options; 222 this.transientObservedNodes = []; 223 } 224 Registration.prototype = { 225 enqueue: function(record) { 226 var records = this.observer.records_; 227 var length = records.length; 228 if (records.length > 0) { 229 var lastRecord = records[length - 1]; 230 var recordToReplaceLast = selectRecord(lastRecord, record); 231 if (recordToReplaceLast) { 232 records[length - 1] = recordToReplaceLast; 233 return; 234 } 235 } else { 236 scheduleCallback(this.observer); 237 } 238 records[length] = record; 239 }, 240 addListeners: function() { 241 this.addListeners_(this.target); 242 }, 243 addListeners_: function(node) { 244 var options = this.options; 245 if (options.attributes) node.addEventListener("DOMAttrModified", this, true); 246 if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true); 247 if (options.childList) node.addEventListener("DOMNodeInserted", this, true); 248 if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true); 249 }, 250 removeListeners: function() { 251 this.removeListeners_(this.target); 252 }, 253 removeListeners_: function(node) { 254 var options = this.options; 255 if (options.attributes) node.removeEventListener("DOMAttrModified", this, true); 256 if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true); 257 if (options.childList) node.removeEventListener("DOMNodeInserted", this, true); 258 if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true); 259 }, 260 addTransientObserver: function(node) { 261 if (node === this.target) return; 262 this.addListeners_(node); 263 this.transientObservedNodes.push(node); 264 var registrations = registrationsTable.get(node); 265 if (!registrations) registrationsTable.set(node, registrations = []); 266 registrations.push(this); 267 }, 268 removeTransientObservers: function() { 269 var transientObservedNodes = this.transientObservedNodes; 270 this.transientObservedNodes = []; 271 transientObservedNodes.forEach(function(node) { 272 this.removeListeners_(node); 273 var registrations = registrationsTable.get(node); 274 for (var i = 0; i < registrations.length; i++) { 275 if (registrations[i] === this) { 276 registrations.splice(i, 1); 277 break; 278 } 279 } 280 }, this); 281 }, 282 handleEvent: function(e) { 283 e.stopImmediatePropagation(); 284 switch (e.type) { 285 case "DOMAttrModified": 286 var name = e.attrName; 287 var namespace = e.relatedNode.namespaceURI; 288 var target = e.target; 289 var record = new getRecord("attributes", target); 290 record.attributeName = name; 291 record.attributeNamespace = namespace; 292 var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue; 293 forEachAncestorAndObserverEnqueueRecord(target, function(options) { 294 if (!options.attributes) return; 295 if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) { 296 return; 297 } 298 if (options.attributeOldValue) return getRecordWithOldValue(oldValue); 299 return record; 300 }); 301 break; 302 303 case "DOMCharacterDataModified": 304 var target = e.target; 305 var record = getRecord("characterData", target); 306 var oldValue = e.prevValue; 307 forEachAncestorAndObserverEnqueueRecord(target, function(options) { 308 if (!options.characterData) return; 309 if (options.characterDataOldValue) return getRecordWithOldValue(oldValue); 310 return record; 311 }); 312 break; 313 314 case "DOMNodeRemoved": 315 this.addTransientObserver(e.target); 316 317 case "DOMNodeInserted": 318 var changedNode = e.target; 319 var addedNodes, removedNodes; 320 if (e.type === "DOMNodeInserted") { 321 addedNodes = [ changedNode ]; 322 removedNodes = []; 323 } else { 324 addedNodes = []; 325 removedNodes = [ changedNode ]; 326 } 327 var previousSibling = changedNode.previousSibling; 328 var nextSibling = changedNode.nextSibling; 329 var record = getRecord("childList", e.target.parentNode); 330 record.addedNodes = addedNodes; 331 record.removedNodes = removedNodes; 332 record.previousSibling = previousSibling; 333 record.nextSibling = nextSibling; 334 forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) { 335 if (!options.childList) return; 336 return record; 337 }); 338 } 339 clearRecords(); 340 } 341 }; 342 global.JsMutationObserver = JsMutationObserver; 343 if (!global.MutationObserver) global.MutationObserver = JsMutationObserver; 344 })(this); 345 346 window.CustomElements = window.CustomElements || { 347 flags: {} 348 }; 349 350 (function(scope) { 351 var flags = scope.flags; 352 var modules = []; 353 var addModule = function(module) { 354 modules.push(module); 355 }; 356 var initializeModules = function() { 357 modules.forEach(function(module) { 358 module(scope); 359 }); 360 }; 361 scope.addModule = addModule; 362 scope.initializeModules = initializeModules; 363 scope.hasNative = Boolean(document.registerElement); 364 scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative); 365 })(CustomElements); 366 367 CustomElements.addModule(function(scope) { 368 var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : "none"; 369 function forSubtree(node, cb) { 370 findAllElements(node, function(e) { 371 if (cb(e)) { 372 return true; 373 } 374 forRoots(e, cb); 375 }); 376 forRoots(node, cb); 377 } 378 function findAllElements(node, find, data) { 379 var e = node.firstElementChild; 380 if (!e) { 381 e = node.firstChild; 382 while (e && e.nodeType !== Node.ELEMENT_NODE) { 383 e = e.nextSibling; 384 } 385 } 386 while (e) { 387 if (find(e, data) !== true) { 388 findAllElements(e, find, data); 389 } 390 e = e.nextElementSibling; 391 } 392 return null; 393 } 394 function forRoots(node, cb) { 395 var root = node.shadowRoot; 396 while (root) { 397 forSubtree(root, cb); 398 root = root.olderShadowRoot; 399 } 400 } 401 function forDocumentTree(doc, cb) { 402 _forDocumentTree(doc, cb, []); 403 } 404 function _forDocumentTree(doc, cb, processingDocuments) { 405 doc = wrap(doc); 406 if (processingDocuments.indexOf(doc) >= 0) { 407 return; 408 } 409 processingDocuments.push(doc); 410 var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]"); 411 for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) { 412 if (n.import) { 413 _forDocumentTree(n.import, cb, processingDocuments); 414 } 415 } 416 cb(doc); 417 } 418 scope.forDocumentTree = forDocumentTree; 419 scope.forSubtree = forSubtree; 420 }); 421 422 CustomElements.addModule(function(scope) { 423 var flags = scope.flags; 424 var forSubtree = scope.forSubtree; 425 var forDocumentTree = scope.forDocumentTree; 426 function addedNode(node) { 427 return added(node) || addedSubtree(node); 428 } 429 function added(node) { 430 if (scope.upgrade(node)) { 431 return true; 432 } 433 attached(node); 434 } 435 function addedSubtree(node) { 436 forSubtree(node, function(e) { 437 if (added(e)) { 438 return true; 439 } 440 }); 441 } 442 function attachedNode(node) { 443 attached(node); 444 if (inDocument(node)) { 445 forSubtree(node, function(e) { 446 attached(e); 447 }); 448 } 449 } 450 var hasPolyfillMutations = !window.MutationObserver || window.MutationObserver === window.JsMutationObserver; 451 scope.hasPolyfillMutations = hasPolyfillMutations; 452 var isPendingMutations = false; 453 var pendingMutations = []; 454 function deferMutation(fn) { 455 pendingMutations.push(fn); 456 if (!isPendingMutations) { 457 isPendingMutations = true; 458 setTimeout(takeMutations); 459 } 460 } 461 function takeMutations() { 462 isPendingMutations = false; 463 var $p = pendingMutations; 464 for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) { 465 p(); 466 } 467 pendingMutations = []; 468 } 469 function attached(element) { 470 if (hasPolyfillMutations) { 471 deferMutation(function() { 472 _attached(element); 473 }); 474 } else { 475 _attached(element); 476 } 477 } 478 function _attached(element) { 479 if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) { 480 if (!element.__attached && inDocument(element)) { 481 element.__attached = true; 482 if (element.attachedCallback) { 483 element.attachedCallback(); 484 } 485 } 486 } 487 } 488 function detachedNode(node) { 489 detached(node); 490 forSubtree(node, function(e) { 491 detached(e); 492 }); 493 } 494 function detached(element) { 495 if (hasPolyfillMutations) { 496 deferMutation(function() { 497 _detached(element); 498 }); 499 } else { 500 _detached(element); 501 } 502 } 503 function _detached(element) { 504 if (element.__upgraded__ && (element.attachedCallback || element.detachedCallback)) { 505 if (element.__attached && !inDocument(element)) { 506 element.__attached = false; 507 if (element.detachedCallback) { 508 element.detachedCallback(); 509 } 510 } 511 } 512 } 513 function inDocument(element) { 514 var p = element; 515 var doc = wrap(document); 516 while (p) { 517 if (p == doc) { 518 return true; 519 } 520 p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host; 521 } 522 } 523 function watchShadow(node) { 524 if (node.shadowRoot && !node.shadowRoot.__watched) { 525 flags.dom && console.log("watching shadow-root for: ", node.localName); 526 var root = node.shadowRoot; 527 while (root) { 528 observe(root); 529 root = root.olderShadowRoot; 530 } 531 } 532 } 533 function handler(mutations) { 534 if (flags.dom) { 535 var mx = mutations[0]; 536 if (mx && mx.type === "childList" && mx.addedNodes) { 537 if (mx.addedNodes) { 538 var d = mx.addedNodes[0]; 539 while (d && d !== document && !d.host) { 540 d = d.parentNode; 541 } 542 var u = d && (d.URL || d._URL || d.host && d.host.localName) || ""; 543 u = u.split("/?").shift().split("/").pop(); 544 } 545 } 546 console.group("mutations (%d) [%s]", mutations.length, u || ""); 547 } 548 mutations.forEach(function(mx) { 549 if (mx.type === "childList") { 550 forEach(mx.addedNodes, function(n) { 551 if (!n.localName) { 552 return; 553 } 554 addedNode(n); 555 }); 556 forEach(mx.removedNodes, function(n) { 557 if (!n.localName) { 558 return; 559 } 560 detachedNode(n); 561 }); 562 } 563 }); 564 flags.dom && console.groupEnd(); 565 } 566 function takeRecords(node) { 567 node = wrap(node); 568 if (!node) { 569 node = wrap(document); 570 } 571 while (node.parentNode) { 572 node = node.parentNode; 573 } 574 var observer = node.__observer; 575 if (observer) { 576 handler(observer.takeRecords()); 577 takeMutations(); 578 } 579 } 580 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); 581 function observe(inRoot) { 582 if (inRoot.__observer) { 583 return; 584 } 585 var observer = new MutationObserver(handler); 586 observer.observe(inRoot, { 587 childList: true, 588 subtree: true 589 }); 590 inRoot.__observer = observer; 591 } 592 function upgradeDocument(doc) { 593 doc = wrap(doc); 594 flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop()); 595 addedNode(doc); 596 observe(doc); 597 flags.dom && console.groupEnd(); 598 } 599 function upgradeDocumentTree(doc) { 600 forDocumentTree(doc, upgradeDocument); 601 } 602 var originalCreateShadowRoot = Element.prototype.createShadowRoot; 603 if (originalCreateShadowRoot) { 604 Element.prototype.createShadowRoot = function() { 605 var root = originalCreateShadowRoot.call(this); 606 CustomElements.watchShadow(this); 607 return root; 608 }; 609 } 610 scope.watchShadow = watchShadow; 611 scope.upgradeDocumentTree = upgradeDocumentTree; 612 scope.upgradeSubtree = addedSubtree; 613 scope.upgradeAll = addedNode; 614 scope.attachedNode = attachedNode; 615 scope.takeRecords = takeRecords; 616 }); 617 618 CustomElements.addModule(function(scope) { 619 var flags = scope.flags; 620 function upgrade(node) { 621 if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) { 622 var is = node.getAttribute("is"); 623 var definition = scope.getRegisteredDefinition(is || node.localName); 624 if (definition) { 625 if (is && definition.tag == node.localName) { 626 return upgradeWithDefinition(node, definition); 627 } else if (!is && !definition.extends) { 628 return upgradeWithDefinition(node, definition); 629 } 630 } 631 } 632 } 633 function upgradeWithDefinition(element, definition) { 634 flags.upgrade && console.group("upgrade:", element.localName); 635 if (definition.is) { 636 element.setAttribute("is", definition.is); 637 } 638 implementPrototype(element, definition); 639 element.__upgraded__ = true; 640 created(element); 641 scope.attachedNode(element); 642 scope.upgradeSubtree(element); 643 flags.upgrade && console.groupEnd(); 644 return element; 645 } 646 function implementPrototype(element, definition) { 647 if (Object.__proto__) { 648 element.__proto__ = definition.prototype; 649 } else { 650 customMixin(element, definition.prototype, definition.native); 651 element.__proto__ = definition.prototype; 652 } 653 } 654 function customMixin(inTarget, inSrc, inNative) { 655 var used = {}; 656 var p = inSrc; 657 while (p !== inNative && p !== HTMLElement.prototype) { 658 var keys = Object.getOwnPropertyNames(p); 659 for (var i = 0, k; k = keys[i]; i++) { 660 if (!used[k]) { 661 Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k)); 662 used[k] = 1; 663 } 664 } 665 p = Object.getPrototypeOf(p); 666 } 667 } 668 function created(element) { 669 if (element.createdCallback) { 670 element.createdCallback(); 671 } 672 } 673 scope.upgrade = upgrade; 674 scope.upgradeWithDefinition = upgradeWithDefinition; 675 scope.implementPrototype = implementPrototype; 676 }); 677 678 CustomElements.addModule(function(scope) { 679 var isIE11OrOlder = scope.isIE11OrOlder; 680 var upgradeDocumentTree = scope.upgradeDocumentTree; 681 var upgradeAll = scope.upgradeAll; 682 var upgradeWithDefinition = scope.upgradeWithDefinition; 683 var implementPrototype = scope.implementPrototype; 684 var useNative = scope.useNative; 685 function register(name, options) { 686 var definition = options || {}; 687 if (!name) { 688 throw new Error("document.registerElement: first argument `name` must not be empty"); 689 } 690 if (name.indexOf("-") < 0) { 691 throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'."); 692 } 693 if (isReservedTag(name)) { 694 throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid."); 695 } 696 if (getRegisteredDefinition(name)) { 697 throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered"); 698 } 699 if (!definition.prototype) { 700 definition.prototype = Object.create(HTMLElement.prototype); 701 } 702 definition.__name = name.toLowerCase(); 703 definition.lifecycle = definition.lifecycle || {}; 704 definition.ancestry = ancestry(definition.extends); 705 resolveTagName(definition); 706 resolvePrototypeChain(definition); 707 overrideAttributeApi(definition.prototype); 708 registerDefinition(definition.__name, definition); 709 definition.ctor = generateConstructor(definition); 710 definition.ctor.prototype = definition.prototype; 711 definition.prototype.constructor = definition.ctor; 712 if (scope.ready) { 713 upgradeDocumentTree(document); 714 } 715 return definition.ctor; 716 } 717 function overrideAttributeApi(prototype) { 718 if (prototype.setAttribute._polyfilled) { 719 return; 720 } 721 var setAttribute = prototype.setAttribute; 722 prototype.setAttribute = function(name, value) { 723 changeAttribute.call(this, name, value, setAttribute); 724 }; 725 var removeAttribute = prototype.removeAttribute; 726 prototype.removeAttribute = function(name) { 727 changeAttribute.call(this, name, null, removeAttribute); 728 }; 729 prototype.setAttribute._polyfilled = true; 730 } 731 function changeAttribute(name, value, operation) { 732 name = name.toLowerCase(); 733 var oldValue = this.getAttribute(name); 734 operation.apply(this, arguments); 735 var newValue = this.getAttribute(name); 736 if (this.attributeChangedCallback && newValue !== oldValue) { 737 this.attributeChangedCallback(name, oldValue, newValue); 738 } 739 } 740 function isReservedTag(name) { 741 for (var i = 0; i < reservedTagList.length; i++) { 742 if (name === reservedTagList[i]) { 743 return true; 744 } 745 } 746 } 747 var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ]; 748 function ancestry(extnds) { 749 var extendee = getRegisteredDefinition(extnds); 750 if (extendee) { 751 return ancestry(extendee.extends).concat([ extendee ]); 752 } 753 return []; 754 } 755 function resolveTagName(definition) { 756 var baseTag = definition.extends; 757 for (var i = 0, a; a = definition.ancestry[i]; i++) { 758 baseTag = a.is && a.tag; 759 } 760 definition.tag = baseTag || definition.__name; 761 if (baseTag) { 762 definition.is = definition.__name; 763 } 764 } 765 function resolvePrototypeChain(definition) { 766 if (!Object.__proto__) { 767 var nativePrototype = HTMLElement.prototype; 768 if (definition.is) { 769 var inst = document.createElement(definition.tag); 770 var expectedPrototype = Object.getPrototypeOf(inst); 771 if (expectedPrototype === definition.prototype) { 772 nativePrototype = expectedPrototype; 773 } 774 } 775 var proto = definition.prototype, ancestor; 776 while (proto && proto !== nativePrototype) { 777 ancestor = Object.getPrototypeOf(proto); 778 proto.__proto__ = ancestor; 779 proto = ancestor; 780 } 781 definition.native = nativePrototype; 782 } 783 } 784 function instantiate(definition) { 785 return upgradeWithDefinition(domCreateElement(definition.tag), definition); 786 } 787 var registry = {}; 788 function getRegisteredDefinition(name) { 789 if (name) { 790 return registry[name.toLowerCase()]; 791 } 792 } 793 function registerDefinition(name, definition) { 794 registry[name] = definition; 795 } 796 function generateConstructor(definition) { 797 return function() { 798 return instantiate(definition); 799 }; 800 } 801 var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; 802 function createElementNS(namespace, tag, typeExtension) { 803 if (namespace === HTML_NAMESPACE) { 804 return createElement(tag, typeExtension); 805 } else { 806 return domCreateElementNS(namespace, tag); 807 } 808 } 809 function createElement(tag, typeExtension) { 810 var definition = getRegisteredDefinition(typeExtension || tag); 811 if (definition) { 812 if (tag == definition.tag && typeExtension == definition.is) { 813 return new definition.ctor(); 814 } 815 if (!typeExtension && !definition.is) { 816 return new definition.ctor(); 817 } 818 } 819 var element; 820 if (typeExtension) { 821 element = createElement(tag); 822 element.setAttribute("is", typeExtension); 823 return element; 824 } 825 element = domCreateElement(tag); 826 if (tag.indexOf("-") >= 0) { 827 implementPrototype(element, HTMLElement); 828 } 829 return element; 830 } 831 var domCreateElement = document.createElement.bind(document); 832 var domCreateElementNS = document.createElementNS.bind(document); 833 var isInstance; 834 if (!Object.__proto__ && !useNative) { 835 isInstance = function(obj, ctor) { 836 var p = obj; 837 while (p) { 838 if (p === ctor.prototype) { 839 return true; 840 } 841 p = p.__proto__; 842 } 843 return false; 844 }; 845 } else { 846 isInstance = function(obj, base) { 847 return obj instanceof base; 848 }; 849 } 850 function wrapDomMethodToForceUpgrade(obj, methodName) { 851 var orig = obj[methodName]; 852 obj[methodName] = function() { 853 var n = orig.apply(this, arguments); 854 upgradeAll(n); 855 return n; 856 }; 857 } 858 wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode"); 859 wrapDomMethodToForceUpgrade(document, "importNode"); 860 if (isIE11OrOlder) { 861 (function() { 862 var importNode = document.importNode; 863 document.importNode = function() { 864 var n = importNode.apply(document, arguments); 865 if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) { 866 var f = document.createDocumentFragment(); 867 f.appendChild(n); 868 return f; 869 } else { 870 return n; 871 } 872 }; 873 })(); 874 } 875 document.registerElement = register; 876 document.createElement = createElement; 877 document.createElementNS = createElementNS; 878 scope.registry = registry; 879 scope.instanceof = isInstance; 880 scope.reservedTagList = reservedTagList; 881 scope.getRegisteredDefinition = getRegisteredDefinition; 882 document.register = document.registerElement; 883 }); 884 885 (function(scope) { 886 var useNative = scope.useNative; 887 var initializeModules = scope.initializeModules; 888 var isIE11OrOlder = /Trident/.test(navigator.userAgent); 889 if (useNative) { 890 var nop = function() {}; 891 scope.watchShadow = nop; 892 scope.upgrade = nop; 893 scope.upgradeAll = nop; 894 scope.upgradeDocumentTree = nop; 895 scope.upgradeSubtree = nop; 896 scope.takeRecords = nop; 897 scope.instanceof = function(obj, base) { 898 return obj instanceof base; 899 }; 900 } else { 901 initializeModules(); 902 } 903 var upgradeDocumentTree = scope.upgradeDocumentTree; 904 if (!window.wrap) { 905 if (window.ShadowDOMPolyfill) { 906 window.wrap = ShadowDOMPolyfill.wrapIfNeeded; 907 window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded; 908 } else { 909 window.wrap = window.unwrap = function(node) { 910 return node; 911 }; 912 } 913 } 914 function bootstrap() { 915 upgradeDocumentTree(wrap(document)); 916 if (window.HTMLImports) { 917 HTMLImports.__importsParsingHook = function(elt) { 918 upgradeDocumentTree(wrap(elt.import)); 919 }; 920 } 921 CustomElements.ready = true; 922 setTimeout(function() { 923 CustomElements.readyTime = Date.now(); 924 if (window.HTMLImports) { 925 CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime; 926 } 927 document.dispatchEvent(new CustomEvent("WebComponentsReady", { 928 bubbles: true 929 })); 930 }); 931 } 932 if (isIE11OrOlder && typeof window.CustomEvent !== "function") { 933 window.CustomEvent = function(inType, params) { 934 params = params || {}; 935 var e = document.createEvent("CustomEvent"); 936 e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail); 937 return e; 938 }; 939 window.CustomEvent.prototype = window.Event.prototype; 940 } 941 if (document.readyState === "complete" || scope.flags.eager) { 942 bootstrap(); 943 } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) { 944 bootstrap(); 945 } else { 946 var loadEvent = window.HTMLImports && !HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded"; 947 window.addEventListener(loadEvent, bootstrap); 948 } 949 scope.isIE11OrOlder = isIE11OrOlder; 950 })(window.CustomElements);