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
12 window.WebComponents = window.WebComponents || {
15 var file = "webcomponents.js";
16 var script = document.querySelector('script[src*="' + file + '"]');
19 location.search.slice(1).split("&").forEach(function(option) {
20 var parts = option.split("=");
22 if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {
23 flags[match[1]] = parts[1] || true;
27 for (var i = 0, a; a = script.attributes[i]; i++) {
28 if (a.name !== "src") {
29 flags[a.name] = a.value || true;
33 if (flags.log && flags.log.split) {
34 var parts = flags.log.split(",");
36 parts.forEach(function(f) {
43 flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill;
44 if (flags.shadow === "native") {
47 flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
50 window.CustomElements = window.CustomElements || {
53 window.CustomElements.flags.register = flags.register;
55 WebComponents.flags = flags;
58 if (WebComponents.flags.shadow) {
59 if (typeof WeakMap === "undefined") {
61 var defineProperty = Object.defineProperty;
62 var counter = Date.now() % 1e9;
63 var WeakMap = function() {
64 this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
67 set: function(key, value) {
68 var entry = key[this.name];
69 if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
70 value: [ key, value ],
77 return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
79 "delete": function(key) {
80 var entry = key[this.name];
81 if (!entry || entry[0] !== key) return false;
82 entry[0] = entry[1] = undefined;
86 var entry = key[this.name];
87 if (!entry) return false;
88 return entry[0] === key;
91 window.WeakMap = WeakMap;
94 window.ShadowDOMPolyfill = {};
97 var constructorTable = new WeakMap();
98 var nativePrototypeTable = new WeakMap();
99 var wrappers = Object.create(null);
100 function detectEval() {
101 if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
104 if (navigator.getDeviceStorage) {
108 var f = new Function("return true;");
114 var hasEval = detectEval();
116 if (!b) throw new Error("Assertion failed");
118 var defineProperty = Object.defineProperty;
119 var getOwnPropertyNames = Object.getOwnPropertyNames;
120 var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
121 function mixin(to, from) {
122 var names = getOwnPropertyNames(from);
123 for (var i = 0; i < names.length; i++) {
125 defineProperty(to, name, getOwnPropertyDescriptor(from, name));
129 function mixinStatics(to, from) {
130 var names = getOwnPropertyNames(from);
131 for (var i = 0; i < names.length; i++) {
142 defineProperty(to, name, getOwnPropertyDescriptor(from, name));
146 function oneOf(object, propertyNames) {
147 for (var i = 0; i < propertyNames.length; i++) {
148 if (propertyNames[i] in object) return propertyNames[i];
151 var nonEnumerableDataDescriptor = {
157 function defineNonEnumerableDataProperty(object, name, value) {
158 nonEnumerableDataDescriptor.value = value;
159 defineProperty(object, name, nonEnumerableDataDescriptor);
161 getOwnPropertyNames(window);
162 function getWrapperConstructor(node, opt_instance) {
163 var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
166 getOwnPropertyNames(nativePrototype);
168 nativePrototype = nativePrototype.__proto__;
171 var wrapperConstructor = constructorTable.get(nativePrototype);
172 if (wrapperConstructor) return wrapperConstructor;
173 var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
174 var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
175 registerInternal(nativePrototype, GeneratedWrapper, opt_instance);
176 return GeneratedWrapper;
178 function addForwardingProperties(nativePrototype, wrapperPrototype) {
179 installProperty(nativePrototype, wrapperPrototype, true);
181 function registerInstanceProperties(wrapperPrototype, instanceObject) {
182 installProperty(instanceObject, wrapperPrototype, false);
184 var isFirefox = /Firefox/.test(navigator.userAgent);
185 var dummyDescriptor = {
191 function isEventHandlerName(name) {
192 return /^on[a-z]+$/.test(name);
194 function isIdentifierName(name) {
195 return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);
197 function getGetter(name) {
198 return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
199 return this.__impl4cf1e782hg__[name];
202 function getSetter(name) {
203 return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
204 this.__impl4cf1e782hg__[name] = v;
207 function getMethod(name) {
208 return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
209 return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
212 function getDescriptor(source, name) {
214 return Object.getOwnPropertyDescriptor(source, name);
216 return dummyDescriptor;
219 var isBrokenSafari = function() {
220 var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
221 return descr && !descr.get && !descr.set;
223 function installProperty(source, target, allowMethod, opt_blacklist) {
224 var names = getOwnPropertyNames(source);
225 for (var i = 0; i < names.length; i++) {
227 if (name === "polymerBlackList_") continue;
228 if (name in target) continue;
229 if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
231 source.__lookupGetter__(name);
233 var descriptor = getDescriptor(source, name);
235 if (typeof descriptor.value === "function") {
237 target[name] = getMethod(name);
241 var isEvent = isEventHandlerName(name);
242 if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
243 if (descriptor.writable || descriptor.set || isBrokenSafari) {
244 if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
246 var configurable = isBrokenSafari || descriptor.configurable;
247 defineProperty(target, name, {
250 configurable: configurable,
251 enumerable: descriptor.enumerable
255 function register(nativeConstructor, wrapperConstructor, opt_instance) {
256 if (nativeConstructor == null) {
259 var nativePrototype = nativeConstructor.prototype;
260 registerInternal(nativePrototype, wrapperConstructor, opt_instance);
261 mixinStatics(wrapperConstructor, nativeConstructor);
263 function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
264 var wrapperPrototype = wrapperConstructor.prototype;
265 assert(constructorTable.get(nativePrototype) === undefined);
266 constructorTable.set(nativePrototype, wrapperConstructor);
267 nativePrototypeTable.set(wrapperPrototype, nativePrototype);
268 addForwardingProperties(nativePrototype, wrapperPrototype);
269 if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
270 defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
271 wrapperConstructor.prototype = wrapperPrototype;
273 function isWrapperFor(wrapperConstructor, nativeConstructor) {
274 return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
276 function registerObject(object) {
277 var nativePrototype = Object.getPrototypeOf(object);
278 var superWrapperConstructor = getWrapperConstructor(nativePrototype);
279 var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
280 registerInternal(nativePrototype, GeneratedWrapper, object);
281 return GeneratedWrapper;
283 function createWrapperConstructor(superWrapperConstructor) {
284 function GeneratedWrapper(node) {
285 superWrapperConstructor.call(this, node);
287 var p = Object.create(superWrapperConstructor.prototype);
288 p.constructor = GeneratedWrapper;
289 GeneratedWrapper.prototype = p;
290 return GeneratedWrapper;
292 function isWrapper(object) {
293 return object && object.__impl4cf1e782hg__;
295 function isNative(object) {
296 return !isWrapper(object);
298 function wrap(impl) {
299 if (impl === null) return null;
300 assert(isNative(impl));
301 var wrapper = impl.__wrapper8e3dd93a60__;
302 if (wrapper != null) {
305 return impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl, impl))(impl);
307 function unwrap(wrapper) {
308 if (wrapper === null) return null;
309 assert(isWrapper(wrapper));
310 return wrapper.__impl4cf1e782hg__;
312 function unsafeUnwrap(wrapper) {
313 return wrapper.__impl4cf1e782hg__;
315 function setWrapper(impl, wrapper) {
316 wrapper.__impl4cf1e782hg__ = impl;
317 impl.__wrapper8e3dd93a60__ = wrapper;
319 function unwrapIfNeeded(object) {
320 return object && isWrapper(object) ? unwrap(object) : object;
322 function wrapIfNeeded(object) {
323 return object && !isWrapper(object) ? wrap(object) : object;
325 function rewrap(node, wrapper) {
326 if (wrapper === null) return;
327 assert(isNative(node));
328 assert(wrapper === undefined || isWrapper(wrapper));
329 node.__wrapper8e3dd93a60__ = wrapper;
331 var getterDescriptor = {
336 function defineGetter(constructor, name, getter) {
337 getterDescriptor.get = getter;
338 defineProperty(constructor.prototype, name, getterDescriptor);
340 function defineWrapGetter(constructor, name) {
341 defineGetter(constructor, name, function() {
342 return wrap(this.__impl4cf1e782hg__[name]);
345 function forwardMethodsToWrapper(constructors, names) {
346 constructors.forEach(function(constructor) {
347 names.forEach(function(name) {
348 constructor.prototype[name] = function() {
349 var w = wrapIfNeeded(this);
350 return w[name].apply(w, arguments);
355 scope.assert = assert;
356 scope.constructorTable = constructorTable;
357 scope.defineGetter = defineGetter;
358 scope.defineWrapGetter = defineWrapGetter;
359 scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
360 scope.isIdentifierName = isIdentifierName;
361 scope.isWrapper = isWrapper;
362 scope.isWrapperFor = isWrapperFor;
364 scope.nativePrototypeTable = nativePrototypeTable;
366 scope.registerObject = registerObject;
367 scope.registerWrapper = register;
368 scope.rewrap = rewrap;
369 scope.setWrapper = setWrapper;
370 scope.unsafeUnwrap = unsafeUnwrap;
371 scope.unwrap = unwrap;
372 scope.unwrapIfNeeded = unwrapIfNeeded;
374 scope.wrapIfNeeded = wrapIfNeeded;
375 scope.wrappers = wrappers;
376 })(window.ShadowDOMPolyfill);
379 function newSplice(index, removed, addedCount) {
383 addedCount: addedCount
390 function ArraySplice() {}
391 ArraySplice.prototype = {
392 calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
393 var rowCount = oldEnd - oldStart + 1;
394 var columnCount = currentEnd - currentStart + 1;
395 var distances = new Array(rowCount);
396 for (var i = 0; i < rowCount; i++) {
397 distances[i] = new Array(columnCount);
400 for (var j = 0; j < columnCount; j++) distances[0][j] = j;
401 for (var i = 1; i < rowCount; i++) {
402 for (var j = 1; j < columnCount; j++) {
403 if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {
404 var north = distances[i - 1][j] + 1;
405 var west = distances[i][j - 1] + 1;
406 distances[i][j] = north < west ? north : west;
412 spliceOperationsFromEditDistances: function(distances) {
413 var i = distances.length - 1;
414 var j = distances[0].length - 1;
415 var current = distances[i][j];
417 while (i > 0 || j > 0) {
419 edits.push(EDIT_ADD);
424 edits.push(EDIT_DELETE);
428 var northWest = distances[i - 1][j - 1];
429 var west = distances[i - 1][j];
430 var north = distances[i][j - 1];
432 if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;
433 if (min == northWest) {
434 if (northWest == current) {
435 edits.push(EDIT_LEAVE);
437 edits.push(EDIT_UPDATE);
442 } else if (min == west) {
443 edits.push(EDIT_DELETE);
447 edits.push(EDIT_ADD);
455 calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
458 var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
459 if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);
460 if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
461 currentStart += prefixCount;
462 oldStart += prefixCount;
463 currentEnd -= suffixCount;
464 oldEnd -= suffixCount;
465 if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];
466 if (currentStart == currentEnd) {
467 var splice = newSplice(currentStart, [], 0);
468 while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);
470 } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];
471 var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
472 var splice = undefined;
474 var index = currentStart;
475 var oldIndex = oldStart;
476 for (var i = 0; i < ops.length; i++) {
480 splices.push(splice);
488 if (!splice) splice = newSplice(index, [], 0);
491 splice.removed.push(old[oldIndex]);
496 if (!splice) splice = newSplice(index, [], 0);
502 if (!splice) splice = newSplice(index, [], 0);
503 splice.removed.push(old[oldIndex]);
509 splices.push(splice);
513 sharedPrefix: function(current, old, searchLength) {
514 for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;
517 sharedSuffix: function(current, old, searchLength) {
518 var index1 = current.length;
519 var index2 = old.length;
521 while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;
524 calculateSplices: function(current, previous) {
525 return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
527 equals: function(currentValue, previousValue) {
528 return currentValue === previousValue;
531 scope.ArraySplice = ArraySplice;
532 })(window.ShadowDOMPolyfill);
535 var OriginalMutationObserver = window.MutationObserver;
541 var copies = callbacks.slice(0);
543 for (var i = 0; i < copies.length; i++) {
547 if (OriginalMutationObserver) {
549 var observer = new OriginalMutationObserver(handle);
550 var textNode = document.createTextNode(counter);
551 observer.observe(textNode, {
554 timerFunc = function() {
555 counter = (counter + 1) % 2;
556 textNode.data = counter;
559 timerFunc = window.setTimeout;
561 function setEndOfMicrotask(func) {
562 callbacks.push(func);
565 timerFunc(handle, 0);
567 context.setEndOfMicrotask = setEndOfMicrotask;
568 })(window.ShadowDOMPolyfill);
571 var setEndOfMicrotask = scope.setEndOfMicrotask;
572 var wrapIfNeeded = scope.wrapIfNeeded;
573 var wrappers = scope.wrappers;
574 var registrationsTable = new WeakMap();
575 var globalMutationObservers = [];
576 var isScheduled = false;
577 function scheduleCallback(observer) {
578 if (observer.scheduled_) return;
579 observer.scheduled_ = true;
580 globalMutationObservers.push(observer);
581 if (isScheduled) return;
582 setEndOfMicrotask(notifyObservers);
585 function notifyObservers() {
587 while (globalMutationObservers.length) {
588 var notifyList = globalMutationObservers;
589 globalMutationObservers = [];
590 notifyList.sort(function(x, y) {
591 return x.uid_ - y.uid_;
593 for (var i = 0; i < notifyList.length; i++) {
594 var mo = notifyList[i];
595 mo.scheduled_ = false;
596 var queue = mo.takeRecords();
597 removeTransientObserversFor(mo);
599 mo.callback_(queue, mo);
604 function MutationRecord(type, target) {
606 this.target = target;
607 this.addedNodes = new wrappers.NodeList();
608 this.removedNodes = new wrappers.NodeList();
609 this.previousSibling = null;
610 this.nextSibling = null;
611 this.attributeName = null;
612 this.attributeNamespace = null;
613 this.oldValue = null;
615 function registerTransientObservers(ancestor, node) {
616 for (;ancestor; ancestor = ancestor.parentNode) {
617 var registrations = registrationsTable.get(ancestor);
618 if (!registrations) continue;
619 for (var i = 0; i < registrations.length; i++) {
620 var registration = registrations[i];
621 if (registration.options.subtree) registration.addTransientObserver(node);
625 function removeTransientObserversFor(observer) {
626 for (var i = 0; i < observer.nodes_.length; i++) {
627 var node = observer.nodes_[i];
628 var registrations = registrationsTable.get(node);
629 if (!registrations) return;
630 for (var j = 0; j < registrations.length; j++) {
631 var registration = registrations[j];
632 if (registration.observer === observer) registration.removeTransientObservers();
636 function enqueueMutation(target, type, data) {
637 var interestedObservers = Object.create(null);
638 var associatedStrings = Object.create(null);
639 for (var node = target; node; node = node.parentNode) {
640 var registrations = registrationsTable.get(node);
641 if (!registrations) continue;
642 for (var j = 0; j < registrations.length; j++) {
643 var registration = registrations[j];
644 var options = registration.options;
645 if (node !== target && !options.subtree) continue;
646 if (type === "attributes" && !options.attributes) continue;
647 if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
650 if (type === "characterData" && !options.characterData) continue;
651 if (type === "childList" && !options.childList) continue;
652 var observer = registration.observer;
653 interestedObservers[observer.uid_] = observer;
654 if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
655 associatedStrings[observer.uid_] = data.oldValue;
659 for (var uid in interestedObservers) {
660 var observer = interestedObservers[uid];
661 var record = new MutationRecord(type, target);
662 if ("name" in data && "namespace" in data) {
663 record.attributeName = data.name;
664 record.attributeNamespace = data.namespace;
666 if (data.addedNodes) record.addedNodes = data.addedNodes;
667 if (data.removedNodes) record.removedNodes = data.removedNodes;
668 if (data.previousSibling) record.previousSibling = data.previousSibling;
669 if (data.nextSibling) record.nextSibling = data.nextSibling;
670 if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
671 scheduleCallback(observer);
672 observer.records_.push(record);
675 var slice = Array.prototype.slice;
676 function MutationObserverOptions(options) {
677 this.childList = !!options.childList;
678 this.subtree = !!options.subtree;
679 if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
680 this.attributes = true;
682 this.attributes = !!options.attributes;
684 if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
685 if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
686 throw new TypeError();
688 this.characterData = !!options.characterData;
689 this.attributeOldValue = !!options.attributeOldValue;
690 this.characterDataOldValue = !!options.characterDataOldValue;
691 if ("attributeFilter" in options) {
692 if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
693 throw new TypeError();
695 this.attributeFilter = slice.call(options.attributeFilter);
697 this.attributeFilter = null;
701 function MutationObserver(callback) {
702 this.callback_ = callback;
705 this.uid_ = ++uidCounter;
706 this.scheduled_ = false;
708 MutationObserver.prototype = {
709 constructor: MutationObserver,
710 observe: function(target, options) {
711 target = wrapIfNeeded(target);
712 var newOptions = new MutationObserverOptions(options);
714 var registrations = registrationsTable.get(target);
715 if (!registrations) registrationsTable.set(target, registrations = []);
716 for (var i = 0; i < registrations.length; i++) {
717 if (registrations[i].observer === this) {
718 registration = registrations[i];
719 registration.removeTransientObservers();
720 registration.options = newOptions;
724 registration = new Registration(this, target, newOptions);
725 registrations.push(registration);
726 this.nodes_.push(target);
729 disconnect: function() {
730 this.nodes_.forEach(function(node) {
731 var registrations = registrationsTable.get(node);
732 for (var i = 0; i < registrations.length; i++) {
733 var registration = registrations[i];
734 if (registration.observer === this) {
735 registrations.splice(i, 1);
742 takeRecords: function() {
743 var copyOfRecords = this.records_;
745 return copyOfRecords;
748 function Registration(observer, target, options) {
749 this.observer = observer;
750 this.target = target;
751 this.options = options;
752 this.transientObservedNodes = [];
754 Registration.prototype = {
755 addTransientObserver: function(node) {
756 if (node === this.target) return;
757 scheduleCallback(this.observer);
758 this.transientObservedNodes.push(node);
759 var registrations = registrationsTable.get(node);
760 if (!registrations) registrationsTable.set(node, registrations = []);
761 registrations.push(this);
763 removeTransientObservers: function() {
764 var transientObservedNodes = this.transientObservedNodes;
765 this.transientObservedNodes = [];
766 for (var i = 0; i < transientObservedNodes.length; i++) {
767 var node = transientObservedNodes[i];
768 var registrations = registrationsTable.get(node);
769 for (var j = 0; j < registrations.length; j++) {
770 if (registrations[j] === this) {
771 registrations.splice(j, 1);
778 scope.enqueueMutation = enqueueMutation;
779 scope.registerTransientObservers = registerTransientObservers;
780 scope.wrappers.MutationObserver = MutationObserver;
781 scope.wrappers.MutationRecord = MutationRecord;
782 })(window.ShadowDOMPolyfill);
785 function TreeScope(root, parent) {
787 this.parent = parent;
789 TreeScope.prototype = {
791 if (this.root instanceof scope.wrappers.ShadowRoot) {
792 return scope.getRendererForHost(this.root.host);
796 contains: function(treeScope) {
797 for (;treeScope; treeScope = treeScope.parent) {
798 if (treeScope === this) return true;
803 function setTreeScope(node, treeScope) {
804 if (node.treeScope_ !== treeScope) {
805 node.treeScope_ = treeScope;
806 for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
807 sr.treeScope_.parent = treeScope;
809 for (var child = node.firstChild; child; child = child.nextSibling) {
810 setTreeScope(child, treeScope);
814 function getTreeScope(node) {
815 if (node instanceof scope.wrappers.Window) {
818 if (node.treeScope_) return node.treeScope_;
819 var parent = node.parentNode;
821 if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
822 return node.treeScope_ = treeScope;
824 scope.TreeScope = TreeScope;
825 scope.getTreeScope = getTreeScope;
826 scope.setTreeScope = setTreeScope;
827 })(window.ShadowDOMPolyfill);
830 var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
831 var getTreeScope = scope.getTreeScope;
832 var mixin = scope.mixin;
833 var registerWrapper = scope.registerWrapper;
834 var setWrapper = scope.setWrapper;
835 var unsafeUnwrap = scope.unsafeUnwrap;
836 var unwrap = scope.unwrap;
837 var wrap = scope.wrap;
838 var wrappers = scope.wrappers;
839 var wrappedFuns = new WeakMap();
840 var listenersTable = new WeakMap();
841 var handledEventsTable = new WeakMap();
842 var currentlyDispatchingEvents = new WeakMap();
843 var targetTable = new WeakMap();
844 var currentTargetTable = new WeakMap();
845 var relatedTargetTable = new WeakMap();
846 var eventPhaseTable = new WeakMap();
847 var stopPropagationTable = new WeakMap();
848 var stopImmediatePropagationTable = new WeakMap();
849 var eventHandlersTable = new WeakMap();
850 var eventPathTable = new WeakMap();
851 function isShadowRoot(node) {
852 return node instanceof wrappers.ShadowRoot;
854 function rootOfNode(node) {
855 return getTreeScope(node).root;
857 function getEventPath(node, event) {
862 var destinationInsertionPoints = getDestinationInsertionPoints(current);
863 if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
864 for (var i = 0; i < destinationInsertionPoints.length; i++) {
865 var insertionPoint = destinationInsertionPoints[i];
866 if (isShadowInsertionPoint(insertionPoint)) {
867 var shadowRoot = rootOfNode(insertionPoint);
868 var olderShadowRoot = shadowRoot.olderShadowRoot;
869 if (olderShadowRoot) path.push(olderShadowRoot);
871 path.push(insertionPoint);
873 current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
875 if (isShadowRoot(current)) {
876 if (inSameTree(node, current) && eventMustBeStopped(event)) {
879 current = current.host;
882 current = current.parentNode;
883 if (current) path.push(current);
889 function eventMustBeStopped(event) {
890 if (!event) return false;
891 switch (event.type) {
905 function isShadowInsertionPoint(node) {
906 return node instanceof HTMLShadowElement;
908 function getDestinationInsertionPoints(node) {
909 return scope.getDestinationInsertionPoints(node);
911 function eventRetargetting(path, currentTarget) {
912 if (path.length === 0) return currentTarget;
913 if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
914 var currentTargetTree = getTreeScope(currentTarget);
915 var originalTarget = path[0];
916 var originalTargetTree = getTreeScope(originalTarget);
917 var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
918 for (var i = 0; i < path.length; i++) {
920 if (getTreeScope(node) === relativeTargetTree) return node;
922 return path[path.length - 1];
924 function getTreeScopeAncestors(treeScope) {
926 for (;treeScope; treeScope = treeScope.parent) {
927 ancestors.push(treeScope);
931 function lowestCommonInclusiveAncestor(tsA, tsB) {
932 var ancestorsA = getTreeScopeAncestors(tsA);
933 var ancestorsB = getTreeScopeAncestors(tsB);
935 while (ancestorsA.length > 0 && ancestorsB.length > 0) {
936 var a = ancestorsA.pop();
937 var b = ancestorsB.pop();
938 if (a === b) result = a; else break;
942 function getTreeScopeRoot(ts) {
943 if (!ts.parent) return ts;
944 return getTreeScopeRoot(ts.parent);
946 function relatedTargetResolution(event, currentTarget, relatedTarget) {
947 if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
948 var currentTargetTree = getTreeScope(currentTarget);
949 var relatedTargetTree = getTreeScope(relatedTarget);
950 var relatedTargetEventPath = getEventPath(relatedTarget, event);
951 var lowestCommonAncestorTree;
952 var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
953 if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
954 for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
955 var adjustedRelatedTarget;
956 for (var i = 0; i < relatedTargetEventPath.length; i++) {
957 var node = relatedTargetEventPath[i];
958 if (getTreeScope(node) === commonAncestorTree) return node;
963 function inSameTree(a, b) {
964 return getTreeScope(a) === getTreeScope(b);
967 var CAPTURING_PHASE = 1;
969 var BUBBLING_PHASE = 3;
971 function dispatchOriginalEvent(originalEvent) {
972 if (handledEventsTable.get(originalEvent)) return;
973 handledEventsTable.set(originalEvent, true);
974 dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
976 var err = pendingError;
981 function isLoadLikeEvent(event) {
982 switch (event.type) {
990 function dispatchEvent(event, originalWrapperTarget) {
991 if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
992 currentlyDispatchingEvents.set(event, true);
993 scope.renderAllPending();
997 if (isLoadLikeEvent(event) && !event.bubbles) {
998 var doc = originalWrapperTarget;
999 if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
1000 overrideTarget = doc;
1005 if (originalWrapperTarget instanceof wrappers.Window) {
1006 win = originalWrapperTarget;
1009 eventPath = getEventPath(originalWrapperTarget, event);
1010 if (!isLoadLikeEvent(event)) {
1011 var doc = eventPath[eventPath.length - 1];
1012 if (doc instanceof wrappers.Document) win = doc.defaultView;
1016 eventPathTable.set(event, eventPath);
1017 if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
1018 if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
1019 dispatchBubbling(event, eventPath, win, overrideTarget);
1022 eventPhaseTable.set(event, NONE);
1023 currentTargetTable.delete(event, null);
1024 currentlyDispatchingEvents.delete(event);
1025 return event.defaultPrevented;
1027 function dispatchCapturing(event, eventPath, win, overrideTarget) {
1028 var phase = CAPTURING_PHASE;
1030 if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
1032 for (var i = eventPath.length - 1; i > 0; i--) {
1033 if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
1037 function dispatchAtTarget(event, eventPath, win, overrideTarget) {
1038 var phase = AT_TARGET;
1039 var currentTarget = eventPath[0] || win;
1040 return invoke(currentTarget, event, phase, eventPath, overrideTarget);
1042 function dispatchBubbling(event, eventPath, win, overrideTarget) {
1043 var phase = BUBBLING_PHASE;
1044 for (var i = 1; i < eventPath.length; i++) {
1045 if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
1047 if (win && eventPath.length > 0) {
1048 invoke(win, event, phase, eventPath, overrideTarget);
1051 function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
1052 var listeners = listenersTable.get(currentTarget);
1053 if (!listeners) return true;
1054 var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
1055 if (target === currentTarget) {
1056 if (phase === CAPTURING_PHASE) return true;
1057 if (phase === BUBBLING_PHASE) phase = AT_TARGET;
1058 } else if (phase === BUBBLING_PHASE && !event.bubbles) {
1061 if ("relatedTarget" in event) {
1062 var originalEvent = unwrap(event);
1063 var unwrappedRelatedTarget = originalEvent.relatedTarget;
1064 if (unwrappedRelatedTarget) {
1065 if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
1066 var relatedTarget = wrap(unwrappedRelatedTarget);
1067 var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
1068 if (adjusted === target) return true;
1072 relatedTargetTable.set(event, adjusted);
1075 eventPhaseTable.set(event, phase);
1076 var type = event.type;
1077 var anyRemoved = false;
1078 targetTable.set(event, target);
1079 currentTargetTable.set(event, currentTarget);
1081 for (var i = 0, len = listeners.length; i < len; i++) {
1082 var listener = listeners[i];
1083 if (listener.removed) {
1087 if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
1091 if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
1092 if (stopImmediatePropagationTable.get(event)) return false;
1094 if (!pendingError) pendingError = ex;
1098 if (anyRemoved && listeners.depth === 0) {
1099 var copy = listeners.slice();
1100 listeners.length = 0;
1101 for (var i = 0; i < copy.length; i++) {
1102 if (!copy[i].removed) listeners.push(copy[i]);
1105 return !stopPropagationTable.get(event);
1107 function Listener(type, handler, capture) {
1109 this.handler = handler;
1110 this.capture = Boolean(capture);
1112 Listener.prototype = {
1113 equals: function(that) {
1114 return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
1117 return this.handler === null;
1119 remove: function() {
1120 this.handler = null;
1123 var OriginalEvent = window.Event;
1124 OriginalEvent.prototype.polymerBlackList_ = {
1128 function Event(type, options) {
1129 if (type instanceof OriginalEvent) {
1131 if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
1132 return new BeforeUnloadEvent(impl);
1134 setWrapper(impl, this);
1136 return wrap(constructEvent(OriginalEvent, "Event", type, options));
1141 return targetTable.get(this);
1143 get currentTarget() {
1144 return currentTargetTable.get(this);
1147 return eventPhaseTable.get(this);
1150 var eventPath = eventPathTable.get(this);
1151 if (!eventPath) return [];
1152 return eventPath.slice();
1154 stopPropagation: function() {
1155 stopPropagationTable.set(this, true);
1157 stopImmediatePropagation: function() {
1158 stopPropagationTable.set(this, true);
1159 stopImmediatePropagationTable.set(this, true);
1162 var supportsDefaultPrevented = function() {
1163 var e = document.createEvent("Event");
1164 e.initEvent("test", true, true);
1166 return e.defaultPrevented;
1168 if (!supportsDefaultPrevented) {
1169 Event.prototype.preventDefault = function() {
1170 if (!this.cancelable) return;
1171 unsafeUnwrap(this).preventDefault();
1172 Object.defineProperty(this, "defaultPrevented", {
1180 registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
1181 function unwrapOptions(options) {
1182 if (!options || !options.relatedTarget) return options;
1183 return Object.create(options, {
1185 value: unwrap(options.relatedTarget)
1189 function registerGenericEvent(name, SuperEvent, prototype) {
1190 var OriginalEvent = window[name];
1191 var GenericEvent = function(type, options) {
1192 if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
1194 GenericEvent.prototype = Object.create(SuperEvent.prototype);
1195 if (prototype) mixin(GenericEvent.prototype, prototype);
1196 if (OriginalEvent) {
1198 registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
1200 registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
1203 return GenericEvent;
1205 var UIEvent = registerGenericEvent("UIEvent", Event);
1206 var CustomEvent = registerGenericEvent("CustomEvent", Event);
1207 var relatedTargetProto = {
1208 get relatedTarget() {
1209 var relatedTarget = relatedTargetTable.get(this);
1210 if (relatedTarget !== undefined) return relatedTarget;
1211 return wrap(unwrap(this).relatedTarget);
1214 function getInitFunction(name, relatedTargetIndex) {
1216 arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
1217 var impl = unwrap(this);
1218 impl[name].apply(impl, arguments);
1221 var mouseEventProto = mixin({
1222 initMouseEvent: getInitFunction("initMouseEvent", 14)
1223 }, relatedTargetProto);
1224 var focusEventProto = mixin({
1225 initFocusEvent: getInitFunction("initFocusEvent", 5)
1226 }, relatedTargetProto);
1227 var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
1228 var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
1229 var defaultInitDicts = Object.create(null);
1230 var supportsEventConstructors = function() {
1232 new window.FocusEvent("focus");
1238 function constructEvent(OriginalEvent, name, type, options) {
1239 if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
1240 var event = unwrap(document.createEvent(name));
1241 var defaultDict = defaultInitDicts[name];
1242 var args = [ type ];
1243 Object.keys(defaultDict).forEach(function(key) {
1244 var v = options != null && key in options ? options[key] : defaultDict[key];
1245 if (key === "relatedTarget") v = unwrap(v);
1248 event["init" + name].apply(event, args);
1251 if (!supportsEventConstructors) {
1252 var configureEventConstructor = function(name, initDict, superName) {
1254 var superDict = defaultInitDicts[superName];
1255 initDict = mixin(mixin({}, superDict), initDict);
1257 defaultInitDicts[name] = initDict;
1259 configureEventConstructor("Event", {
1263 configureEventConstructor("CustomEvent", {
1266 configureEventConstructor("UIEvent", {
1270 configureEventConstructor("MouseEvent", {
1282 configureEventConstructor("FocusEvent", {
1286 var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
1287 function BeforeUnloadEvent(impl) {
1288 Event.call(this, impl);
1290 BeforeUnloadEvent.prototype = Object.create(Event.prototype);
1291 mixin(BeforeUnloadEvent.prototype, {
1293 return unsafeUnwrap(this).returnValue;
1295 set returnValue(v) {
1296 unsafeUnwrap(this).returnValue = v;
1299 if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
1300 function isValidListener(fun) {
1301 if (typeof fun === "function") return true;
1302 return fun && fun.handleEvent;
1304 function isMutationEvent(type) {
1306 case "DOMAttrModified":
1307 case "DOMAttributeNameChanged":
1308 case "DOMCharacterDataModified":
1309 case "DOMElementNameChanged":
1310 case "DOMNodeInserted":
1311 case "DOMNodeInsertedIntoDocument":
1312 case "DOMNodeRemoved":
1313 case "DOMNodeRemovedFromDocument":
1314 case "DOMSubtreeModified":
1319 var OriginalEventTarget = window.EventTarget;
1320 function EventTarget(impl) {
1321 setWrapper(impl, this);
1323 var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
1324 [ Node, Window ].forEach(function(constructor) {
1325 var p = constructor.prototype;
1326 methodNames.forEach(function(name) {
1327 Object.defineProperty(p, name + "_", {
1332 function getTargetToListenAt(wrapper) {
1333 if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
1334 return unwrap(wrapper);
1336 EventTarget.prototype = {
1337 addEventListener: function(type, fun, capture) {
1338 if (!isValidListener(fun) || isMutationEvent(type)) return;
1339 var listener = new Listener(type, fun, capture);
1340 var listeners = listenersTable.get(this);
1343 listeners.depth = 0;
1344 listenersTable.set(this, listeners);
1346 for (var i = 0; i < listeners.length; i++) {
1347 if (listener.equals(listeners[i])) return;
1350 listeners.push(listener);
1351 var target = getTargetToListenAt(this);
1352 target.addEventListener_(type, dispatchOriginalEvent, true);
1354 removeEventListener: function(type, fun, capture) {
1355 capture = Boolean(capture);
1356 var listeners = listenersTable.get(this);
1357 if (!listeners) return;
1358 var count = 0, found = false;
1359 for (var i = 0; i < listeners.length; i++) {
1360 if (listeners[i].type === type && listeners[i].capture === capture) {
1362 if (listeners[i].handler === fun) {
1364 listeners[i].remove();
1368 if (found && count === 1) {
1369 var target = getTargetToListenAt(this);
1370 target.removeEventListener_(type, dispatchOriginalEvent, true);
1373 dispatchEvent: function(event) {
1374 var nativeEvent = unwrap(event);
1375 var eventType = nativeEvent.type;
1376 handledEventsTable.set(nativeEvent, false);
1377 scope.renderAllPending();
1379 if (!hasListenerInAncestors(this, eventType)) {
1380 tempListener = function() {};
1381 this.addEventListener(eventType, tempListener, true);
1384 return unwrap(this).dispatchEvent_(nativeEvent);
1386 if (tempListener) this.removeEventListener(eventType, tempListener, true);
1390 function hasListener(node, type) {
1391 var listeners = listenersTable.get(node);
1393 for (var i = 0; i < listeners.length; i++) {
1394 if (!listeners[i].removed && listeners[i].type === type) return true;
1399 function hasListenerInAncestors(target, type) {
1400 for (var node = unwrap(target); node; node = node.parentNode) {
1401 if (hasListener(wrap(node), type)) return true;
1405 if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
1406 function wrapEventTargetMethods(constructors) {
1407 forwardMethodsToWrapper(constructors, methodNames);
1409 var originalElementFromPoint = document.elementFromPoint;
1410 function elementFromPoint(self, document, x, y) {
1411 scope.renderAllPending();
1412 var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
1413 if (!element) return null;
1414 var path = getEventPath(element, null);
1415 var idx = path.lastIndexOf(self);
1416 if (idx == -1) return null; else path = path.slice(0, idx);
1417 return eventRetargetting(path, self);
1419 function getEventHandlerGetter(name) {
1421 var inlineEventHandlers = eventHandlersTable.get(this);
1422 return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
1425 function getEventHandlerSetter(name) {
1426 var eventType = name.slice(2);
1427 return function(value) {
1428 var inlineEventHandlers = eventHandlersTable.get(this);
1429 if (!inlineEventHandlers) {
1430 inlineEventHandlers = Object.create(null);
1431 eventHandlersTable.set(this, inlineEventHandlers);
1433 var old = inlineEventHandlers[name];
1434 if (old) this.removeEventListener(eventType, old.wrapped, false);
1435 if (typeof value === "function") {
1436 var wrapped = function(e) {
1437 var rv = value.call(this, e);
1438 if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
1440 this.addEventListener(eventType, wrapped, false);
1441 inlineEventHandlers[name] = {
1448 scope.elementFromPoint = elementFromPoint;
1449 scope.getEventHandlerGetter = getEventHandlerGetter;
1450 scope.getEventHandlerSetter = getEventHandlerSetter;
1451 scope.wrapEventTargetMethods = wrapEventTargetMethods;
1452 scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
1453 scope.wrappers.CustomEvent = CustomEvent;
1454 scope.wrappers.Event = Event;
1455 scope.wrappers.EventTarget = EventTarget;
1456 scope.wrappers.FocusEvent = FocusEvent;
1457 scope.wrappers.MouseEvent = MouseEvent;
1458 scope.wrappers.UIEvent = UIEvent;
1459 })(window.ShadowDOMPolyfill);
1462 var UIEvent = scope.wrappers.UIEvent;
1463 var mixin = scope.mixin;
1464 var registerWrapper = scope.registerWrapper;
1465 var setWrapper = scope.setWrapper;
1466 var unsafeUnwrap = scope.unsafeUnwrap;
1467 var wrap = scope.wrap;
1468 var OriginalTouchEvent = window.TouchEvent;
1469 if (!OriginalTouchEvent) return;
1472 nativeEvent = document.createEvent("TouchEvent");
1476 var nonEnumDescriptor = {
1479 function nonEnum(obj, prop) {
1480 Object.defineProperty(obj, prop, nonEnumDescriptor);
1482 function Touch(impl) {
1483 setWrapper(impl, this);
1487 return wrap(unsafeUnwrap(this).target);
1495 [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
1496 descr.get = function() {
1497 return unsafeUnwrap(this)[name];
1499 Object.defineProperty(Touch.prototype, name, descr);
1501 function TouchList() {
1503 nonEnum(this, "length");
1505 TouchList.prototype = {
1506 item: function(index) {
1510 function wrapTouchList(nativeTouchList) {
1511 var list = new TouchList();
1512 for (var i = 0; i < nativeTouchList.length; i++) {
1513 list[i] = new Touch(nativeTouchList[i]);
1518 function TouchEvent(impl) {
1519 UIEvent.call(this, impl);
1521 TouchEvent.prototype = Object.create(UIEvent.prototype);
1522 mixin(TouchEvent.prototype, {
1524 return wrapTouchList(unsafeUnwrap(this).touches);
1526 get targetTouches() {
1527 return wrapTouchList(unsafeUnwrap(this).targetTouches);
1529 get changedTouches() {
1530 return wrapTouchList(unsafeUnwrap(this).changedTouches);
1532 initTouchEvent: function() {
1533 throw new Error("Not implemented");
1536 registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
1537 scope.wrappers.Touch = Touch;
1538 scope.wrappers.TouchEvent = TouchEvent;
1539 scope.wrappers.TouchList = TouchList;
1540 })(window.ShadowDOMPolyfill);
1543 var unsafeUnwrap = scope.unsafeUnwrap;
1544 var wrap = scope.wrap;
1545 var nonEnumDescriptor = {
1548 function nonEnum(obj, prop) {
1549 Object.defineProperty(obj, prop, nonEnumDescriptor);
1551 function NodeList() {
1553 nonEnum(this, "length");
1555 NodeList.prototype = {
1556 item: function(index) {
1560 nonEnum(NodeList.prototype, "item");
1561 function wrapNodeList(list) {
1562 if (list == null) return list;
1563 var wrapperList = new NodeList();
1564 for (var i = 0, length = list.length; i < length; i++) {
1565 wrapperList[i] = wrap(list[i]);
1567 wrapperList.length = length;
1570 function addWrapNodeListMethod(wrapperConstructor, name) {
1571 wrapperConstructor.prototype[name] = function() {
1572 return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
1575 scope.wrappers.NodeList = NodeList;
1576 scope.addWrapNodeListMethod = addWrapNodeListMethod;
1577 scope.wrapNodeList = wrapNodeList;
1578 })(window.ShadowDOMPolyfill);
1581 scope.wrapHTMLCollection = scope.wrapNodeList;
1582 scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
1583 })(window.ShadowDOMPolyfill);
1586 var EventTarget = scope.wrappers.EventTarget;
1587 var NodeList = scope.wrappers.NodeList;
1588 var TreeScope = scope.TreeScope;
1589 var assert = scope.assert;
1590 var defineWrapGetter = scope.defineWrapGetter;
1591 var enqueueMutation = scope.enqueueMutation;
1592 var getTreeScope = scope.getTreeScope;
1593 var isWrapper = scope.isWrapper;
1594 var mixin = scope.mixin;
1595 var registerTransientObservers = scope.registerTransientObservers;
1596 var registerWrapper = scope.registerWrapper;
1597 var setTreeScope = scope.setTreeScope;
1598 var unsafeUnwrap = scope.unsafeUnwrap;
1599 var unwrap = scope.unwrap;
1600 var unwrapIfNeeded = scope.unwrapIfNeeded;
1601 var wrap = scope.wrap;
1602 var wrapIfNeeded = scope.wrapIfNeeded;
1603 var wrappers = scope.wrappers;
1604 function assertIsNodeWrapper(node) {
1605 assert(node instanceof Node);
1607 function createOneElementNodeList(node) {
1608 var nodes = new NodeList();
1613 var surpressMutations = false;
1614 function enqueueRemovalForInsertedNodes(node, parent, nodes) {
1615 enqueueMutation(parent, "childList", {
1616 removedNodes: nodes,
1617 previousSibling: node.previousSibling,
1618 nextSibling: node.nextSibling
1621 function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
1622 enqueueMutation(df, "childList", {
1626 function collectNodes(node, parentNode, previousNode, nextNode) {
1627 if (node instanceof DocumentFragment) {
1628 var nodes = collectNodesForDocumentFragment(node);
1629 surpressMutations = true;
1630 for (var i = nodes.length - 1; i >= 0; i--) {
1631 node.removeChild(nodes[i]);
1632 nodes[i].parentNode_ = parentNode;
1634 surpressMutations = false;
1635 for (var i = 0; i < nodes.length; i++) {
1636 nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
1637 nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
1639 if (previousNode) previousNode.nextSibling_ = nodes[0];
1640 if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
1643 var nodes = createOneElementNodeList(node);
1644 var oldParent = node.parentNode;
1646 oldParent.removeChild(node);
1648 node.parentNode_ = parentNode;
1649 node.previousSibling_ = previousNode;
1650 node.nextSibling_ = nextNode;
1651 if (previousNode) previousNode.nextSibling_ = node;
1652 if (nextNode) nextNode.previousSibling_ = node;
1655 function collectNodesNative(node) {
1656 if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
1657 var nodes = createOneElementNodeList(node);
1658 var oldParent = node.parentNode;
1659 if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
1662 function collectNodesForDocumentFragment(node) {
1663 var nodes = new NodeList();
1665 for (var child = node.firstChild; child; child = child.nextSibling) {
1669 enqueueRemovalForInsertedDocumentFragment(node, nodes);
1672 function snapshotNodeList(nodeList) {
1675 function nodeWasAdded(node, treeScope) {
1676 setTreeScope(node, treeScope);
1677 node.nodeIsInserted_();
1679 function nodesWereAdded(nodes, parent) {
1680 var treeScope = getTreeScope(parent);
1681 for (var i = 0; i < nodes.length; i++) {
1682 nodeWasAdded(nodes[i], treeScope);
1685 function nodeWasRemoved(node) {
1686 setTreeScope(node, new TreeScope(node, null));
1688 function nodesWereRemoved(nodes) {
1689 for (var i = 0; i < nodes.length; i++) {
1690 nodeWasRemoved(nodes[i]);
1693 function ensureSameOwnerDocument(parent, child) {
1694 var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
1695 if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
1697 function adoptNodesIfNeeded(owner, nodes) {
1698 if (!nodes.length) return;
1699 var ownerDoc = owner.ownerDocument;
1700 if (ownerDoc === nodes[0].ownerDocument) return;
1701 for (var i = 0; i < nodes.length; i++) {
1702 scope.adoptNodeNoRemove(nodes[i], ownerDoc);
1705 function unwrapNodesForInsertion(owner, nodes) {
1706 adoptNodesIfNeeded(owner, nodes);
1707 var length = nodes.length;
1708 if (length === 1) return unwrap(nodes[0]);
1709 var df = unwrap(owner.ownerDocument.createDocumentFragment());
1710 for (var i = 0; i < length; i++) {
1711 df.appendChild(unwrap(nodes[i]));
1715 function clearChildNodes(wrapper) {
1716 if (wrapper.firstChild_ !== undefined) {
1717 var child = wrapper.firstChild_;
1720 child = child.nextSibling_;
1721 tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
1724 wrapper.firstChild_ = wrapper.lastChild_ = undefined;
1726 function removeAllChildNodes(wrapper) {
1727 if (wrapper.invalidateShadowRenderer()) {
1728 var childWrapper = wrapper.firstChild;
1729 while (childWrapper) {
1730 assert(childWrapper.parentNode === wrapper);
1731 var nextSibling = childWrapper.nextSibling;
1732 var childNode = unwrap(childWrapper);
1733 var parentNode = childNode.parentNode;
1734 if (parentNode) originalRemoveChild.call(parentNode, childNode);
1735 childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
1736 childWrapper = nextSibling;
1738 wrapper.firstChild_ = wrapper.lastChild_ = null;
1740 var node = unwrap(wrapper);
1741 var child = node.firstChild;
1744 nextSibling = child.nextSibling;
1745 originalRemoveChild.call(node, child);
1746 child = nextSibling;
1750 function invalidateParent(node) {
1751 var p = node.parentNode;
1752 return p && p.invalidateShadowRenderer();
1754 function cleanupNodes(nodes) {
1755 for (var i = 0, n; i < nodes.length; i++) {
1757 n.parentNode.removeChild(n);
1760 var originalImportNode = document.importNode;
1761 var originalCloneNode = window.Node.prototype.cloneNode;
1762 function cloneNode(node, deep, opt_doc) {
1764 if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
1766 for (var child = node.firstChild; child; child = child.nextSibling) {
1767 clone.appendChild(cloneNode(child, true, opt_doc));
1769 if (node instanceof wrappers.HTMLTemplateElement) {
1770 var cloneContent = clone.content;
1771 for (var child = node.content.firstChild; child; child = child.nextSibling) {
1772 cloneContent.appendChild(cloneNode(child, true, opt_doc));
1778 function contains(self, child) {
1779 if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
1780 for (var node = child; node; node = node.parentNode) {
1781 if (node === self) return true;
1785 var OriginalNode = window.Node;
1786 function Node(original) {
1787 assert(original instanceof OriginalNode);
1788 EventTarget.call(this, original);
1789 this.parentNode_ = undefined;
1790 this.firstChild_ = undefined;
1791 this.lastChild_ = undefined;
1792 this.nextSibling_ = undefined;
1793 this.previousSibling_ = undefined;
1794 this.treeScope_ = undefined;
1796 var OriginalDocumentFragment = window.DocumentFragment;
1797 var originalAppendChild = OriginalNode.prototype.appendChild;
1798 var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
1799 var originalIsEqualNode = OriginalNode.prototype.isEqualNode;
1800 var originalInsertBefore = OriginalNode.prototype.insertBefore;
1801 var originalRemoveChild = OriginalNode.prototype.removeChild;
1802 var originalReplaceChild = OriginalNode.prototype.replaceChild;
1803 var isIEOrEdge = /Trident|Edge/.test(navigator.userAgent);
1804 var removeChildOriginalHelper = isIEOrEdge ? function(parent, child) {
1806 originalRemoveChild.call(parent, child);
1808 if (!(parent instanceof OriginalDocumentFragment)) throw ex;
1810 } : function(parent, child) {
1811 originalRemoveChild.call(parent, child);
1813 Node.prototype = Object.create(EventTarget.prototype);
1814 mixin(Node.prototype, {
1815 appendChild: function(childWrapper) {
1816 return this.insertBefore(childWrapper, null);
1818 insertBefore: function(childWrapper, refWrapper) {
1819 assertIsNodeWrapper(childWrapper);
1822 if (isWrapper(refWrapper)) {
1823 refNode = unwrap(refWrapper);
1825 refNode = refWrapper;
1826 refWrapper = wrap(refNode);
1832 refWrapper && assert(refWrapper.parentNode === this);
1834 var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
1835 var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
1836 if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
1838 ensureSameOwnerDocument(this, childWrapper);
1839 clearChildNodes(this);
1840 originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
1842 if (!previousNode) this.firstChild_ = nodes[0];
1844 this.lastChild_ = nodes[nodes.length - 1];
1845 if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
1847 var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
1849 originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
1851 adoptNodesIfNeeded(this, nodes);
1854 enqueueMutation(this, "childList", {
1856 nextSibling: refWrapper,
1857 previousSibling: previousNode
1859 nodesWereAdded(nodes, this);
1860 return childWrapper;
1862 removeChild: function(childWrapper) {
1863 assertIsNodeWrapper(childWrapper);
1864 if (childWrapper.parentNode !== this) {
1866 var childNodes = this.childNodes;
1867 for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
1868 if (ieChild === childWrapper) {
1874 throw new Error("NotFoundError");
1877 var childNode = unwrap(childWrapper);
1878 var childWrapperNextSibling = childWrapper.nextSibling;
1879 var childWrapperPreviousSibling = childWrapper.previousSibling;
1880 if (this.invalidateShadowRenderer()) {
1881 var thisFirstChild = this.firstChild;
1882 var thisLastChild = this.lastChild;
1883 var parentNode = childNode.parentNode;
1884 if (parentNode) removeChildOriginalHelper(parentNode, childNode);
1885 if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
1886 if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
1887 if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
1888 if (childWrapperNextSibling) {
1889 childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
1891 childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
1893 clearChildNodes(this);
1894 removeChildOriginalHelper(unsafeUnwrap(this), childNode);
1896 if (!surpressMutations) {
1897 enqueueMutation(this, "childList", {
1898 removedNodes: createOneElementNodeList(childWrapper),
1899 nextSibling: childWrapperNextSibling,
1900 previousSibling: childWrapperPreviousSibling
1903 registerTransientObservers(this, childWrapper);
1904 return childWrapper;
1906 replaceChild: function(newChildWrapper, oldChildWrapper) {
1907 assertIsNodeWrapper(newChildWrapper);
1909 if (isWrapper(oldChildWrapper)) {
1910 oldChildNode = unwrap(oldChildWrapper);
1912 oldChildNode = oldChildWrapper;
1913 oldChildWrapper = wrap(oldChildNode);
1915 if (oldChildWrapper.parentNode !== this) {
1916 throw new Error("NotFoundError");
1918 var nextNode = oldChildWrapper.nextSibling;
1919 var previousNode = oldChildWrapper.previousSibling;
1921 var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
1923 nodes = collectNodesNative(newChildWrapper);
1925 if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
1926 nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
1929 if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
1930 if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
1931 oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
1932 if (oldChildNode.parentNode) {
1933 originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
1936 ensureSameOwnerDocument(this, newChildWrapper);
1937 clearChildNodes(this);
1938 originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
1940 enqueueMutation(this, "childList", {
1942 removedNodes: createOneElementNodeList(oldChildWrapper),
1943 nextSibling: nextNode,
1944 previousSibling: previousNode
1946 nodeWasRemoved(oldChildWrapper);
1947 nodesWereAdded(nodes, this);
1948 return oldChildWrapper;
1950 nodeIsInserted_: function() {
1951 for (var child = this.firstChild; child; child = child.nextSibling) {
1952 child.nodeIsInserted_();
1955 hasChildNodes: function() {
1956 return this.firstChild !== null;
1959 return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
1962 return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
1965 return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
1968 return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
1970 get previousSibling() {
1971 return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
1973 get parentElement() {
1974 var p = this.parentNode;
1975 while (p && p.nodeType !== Node.ELEMENT_NODE) {
1982 for (var child = this.firstChild; child; child = child.nextSibling) {
1983 if (child.nodeType != Node.COMMENT_NODE) {
1984 s += child.textContent;
1989 set textContent(textContent) {
1990 if (textContent == null) textContent = "";
1991 var removedNodes = snapshotNodeList(this.childNodes);
1992 if (this.invalidateShadowRenderer()) {
1993 removeAllChildNodes(this);
1994 if (textContent !== "") {
1995 var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
1996 this.appendChild(textNode);
1999 clearChildNodes(this);
2000 unsafeUnwrap(this).textContent = textContent;
2002 var addedNodes = snapshotNodeList(this.childNodes);
2003 enqueueMutation(this, "childList", {
2004 addedNodes: addedNodes,
2005 removedNodes: removedNodes
2007 nodesWereRemoved(removedNodes);
2008 nodesWereAdded(addedNodes, this);
2011 var wrapperList = new NodeList();
2013 for (var child = this.firstChild; child; child = child.nextSibling) {
2014 wrapperList[i++] = child;
2016 wrapperList.length = i;
2019 cloneNode: function(deep) {
2020 return cloneNode(this, deep);
2022 contains: function(child) {
2023 return contains(this, wrapIfNeeded(child));
2025 compareDocumentPosition: function(otherNode) {
2026 return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
2028 isEqualNode: function(otherNode) {
2029 return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
2031 normalize: function() {
2032 var nodes = snapshotNodeList(this.childNodes);
2036 for (var i = 0, n; i < nodes.length; i++) {
2038 if (n.nodeType === Node.TEXT_NODE) {
2039 if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
2044 if (modNode && remNodes.length) {
2046 cleanupNodes(remNodes);
2051 if (n.childNodes.length) n.normalize();
2054 if (modNode && remNodes.length) {
2056 cleanupNodes(remNodes);
2060 defineWrapGetter(Node, "ownerDocument");
2061 registerWrapper(OriginalNode, Node, document.createDocumentFragment());
2062 delete Node.prototype.querySelector;
2063 delete Node.prototype.querySelectorAll;
2064 Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
2065 scope.cloneNode = cloneNode;
2066 scope.nodeWasAdded = nodeWasAdded;
2067 scope.nodeWasRemoved = nodeWasRemoved;
2068 scope.nodesWereAdded = nodesWereAdded;
2069 scope.nodesWereRemoved = nodesWereRemoved;
2070 scope.originalInsertBefore = originalInsertBefore;
2071 scope.originalRemoveChild = originalRemoveChild;
2072 scope.snapshotNodeList = snapshotNodeList;
2073 scope.wrappers.Node = Node;
2074 })(window.ShadowDOMPolyfill);
2077 var HTMLCollection = scope.wrappers.HTMLCollection;
2078 var NodeList = scope.wrappers.NodeList;
2079 var getTreeScope = scope.getTreeScope;
2080 var unsafeUnwrap = scope.unsafeUnwrap;
2081 var wrap = scope.wrap;
2082 var originalDocumentQuerySelector = document.querySelector;
2083 var originalElementQuerySelector = document.documentElement.querySelector;
2084 var originalDocumentQuerySelectorAll = document.querySelectorAll;
2085 var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
2086 var originalDocumentGetElementsByTagName = document.getElementsByTagName;
2087 var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
2088 var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
2089 var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
2090 var OriginalElement = window.Element;
2091 var OriginalDocument = window.HTMLDocument || window.Document;
2092 function filterNodeList(list, index, result, deep) {
2093 var wrappedItem = null;
2095 for (var i = 0, length = list.length; i < length; i++) {
2096 wrappedItem = wrap(list[i]);
2097 if (!deep && (root = getTreeScope(wrappedItem).root)) {
2098 if (root instanceof scope.wrappers.ShadowRoot) {
2102 result[index++] = wrappedItem;
2106 function shimSelector(selector) {
2107 return String(selector).replace(/\/deep\/|::shadow|>>>/g, " ");
2109 function shimMatchesSelector(selector) {
2110 return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g, " ");
2112 function findOne(node, selector) {
2113 var m, el = node.firstElementChild;
2115 if (el.matches(selector)) return el;
2116 m = findOne(el, selector);
2118 el = el.nextElementSibling;
2122 function matchesSelector(el, selector) {
2123 return el.matches(selector);
2125 var XHTML_NS = "http://www.w3.org/1999/xhtml";
2126 function matchesTagName(el, localName, localNameLowerCase) {
2127 var ln = el.localName;
2128 return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
2130 function matchesEveryThing() {
2133 function matchesLocalNameOnly(el, ns, localName) {
2134 return el.localName === localName;
2136 function matchesNameSpace(el, ns) {
2137 return el.namespaceURI === ns;
2139 function matchesLocalNameNS(el, ns, localName) {
2140 return el.namespaceURI === ns && el.localName === localName;
2142 function findElements(node, index, result, p, arg0, arg1) {
2143 var el = node.firstElementChild;
2145 if (p(el, arg0, arg1)) result[index++] = el;
2146 index = findElements(el, index, result, p, arg0, arg1);
2147 el = el.nextElementSibling;
2151 function querySelectorAllFiltered(p, index, result, selector, deep) {
2152 var target = unsafeUnwrap(this);
2154 var root = getTreeScope(this).root;
2155 if (root instanceof scope.wrappers.ShadowRoot) {
2156 return findElements(this, index, result, p, selector, null);
2157 } else if (target instanceof OriginalElement) {
2158 list = originalElementQuerySelectorAll.call(target, selector);
2159 } else if (target instanceof OriginalDocument) {
2160 list = originalDocumentQuerySelectorAll.call(target, selector);
2162 return findElements(this, index, result, p, selector, null);
2164 return filterNodeList(list, index, result, deep);
2166 var SelectorsInterface = {
2167 querySelector: function(selector) {
2168 var shimmed = shimSelector(selector);
2169 var deep = shimmed !== selector;
2171 var target = unsafeUnwrap(this);
2173 var root = getTreeScope(this).root;
2174 if (root instanceof scope.wrappers.ShadowRoot) {
2175 return findOne(this, selector);
2176 } else if (target instanceof OriginalElement) {
2177 wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
2178 } else if (target instanceof OriginalDocument) {
2179 wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
2181 return findOne(this, selector);
2185 } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
2186 if (root instanceof scope.wrappers.ShadowRoot) {
2187 return findOne(this, selector);
2192 querySelectorAll: function(selector) {
2193 var shimmed = shimSelector(selector);
2194 var deep = shimmed !== selector;
2196 var result = new NodeList();
2197 result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
2201 var MatchesInterface = {
2202 matches: function(selector) {
2203 selector = shimMatchesSelector(selector);
2204 return scope.originalMatches.call(unsafeUnwrap(this), selector);
2207 function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
2208 var target = unsafeUnwrap(this);
2210 var root = getTreeScope(this).root;
2211 if (root instanceof scope.wrappers.ShadowRoot) {
2212 return findElements(this, index, result, p, localName, lowercase);
2213 } else if (target instanceof OriginalElement) {
2214 list = originalElementGetElementsByTagName.call(target, localName, lowercase);
2215 } else if (target instanceof OriginalDocument) {
2216 list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
2218 return findElements(this, index, result, p, localName, lowercase);
2220 return filterNodeList(list, index, result, false);
2222 function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
2223 var target = unsafeUnwrap(this);
2225 var root = getTreeScope(this).root;
2226 if (root instanceof scope.wrappers.ShadowRoot) {
2227 return findElements(this, index, result, p, ns, localName);
2228 } else if (target instanceof OriginalElement) {
2229 list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
2230 } else if (target instanceof OriginalDocument) {
2231 list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
2233 return findElements(this, index, result, p, ns, localName);
2235 return filterNodeList(list, index, result, false);
2237 var GetElementsByInterface = {
2238 getElementsByTagName: function(localName) {
2239 var result = new HTMLCollection();
2240 var match = localName === "*" ? matchesEveryThing : matchesTagName;
2241 result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
2244 getElementsByClassName: function(className) {
2245 return this.querySelectorAll("." + className);
2247 getElementsByTagNameNS: function(ns, localName) {
2248 var result = new HTMLCollection();
2251 match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
2253 match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
2255 result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
2259 scope.GetElementsByInterface = GetElementsByInterface;
2260 scope.SelectorsInterface = SelectorsInterface;
2261 scope.MatchesInterface = MatchesInterface;
2262 })(window.ShadowDOMPolyfill);
2265 var NodeList = scope.wrappers.NodeList;
2266 function forwardElement(node) {
2267 while (node && node.nodeType !== Node.ELEMENT_NODE) {
2268 node = node.nextSibling;
2272 function backwardsElement(node) {
2273 while (node && node.nodeType !== Node.ELEMENT_NODE) {
2274 node = node.previousSibling;
2278 var ParentNodeInterface = {
2279 get firstElementChild() {
2280 return forwardElement(this.firstChild);
2282 get lastElementChild() {
2283 return backwardsElement(this.lastChild);
2285 get childElementCount() {
2287 for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
2293 var wrapperList = new NodeList();
2295 for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
2296 wrapperList[i++] = child;
2298 wrapperList.length = i;
2301 remove: function() {
2302 var p = this.parentNode;
2303 if (p) p.removeChild(this);
2306 var ChildNodeInterface = {
2307 get nextElementSibling() {
2308 return forwardElement(this.nextSibling);
2310 get previousElementSibling() {
2311 return backwardsElement(this.previousSibling);
2314 var NonElementParentNodeInterface = {
2315 getElementById: function(id) {
2316 if (/[ \t\n\r\f]/.test(id)) return null;
2317 return this.querySelector('[id="' + id + '"]');
2320 scope.ChildNodeInterface = ChildNodeInterface;
2321 scope.NonElementParentNodeInterface = NonElementParentNodeInterface;
2322 scope.ParentNodeInterface = ParentNodeInterface;
2323 })(window.ShadowDOMPolyfill);
2326 var ChildNodeInterface = scope.ChildNodeInterface;
2327 var Node = scope.wrappers.Node;
2328 var enqueueMutation = scope.enqueueMutation;
2329 var mixin = scope.mixin;
2330 var registerWrapper = scope.registerWrapper;
2331 var unsafeUnwrap = scope.unsafeUnwrap;
2332 var OriginalCharacterData = window.CharacterData;
2333 function CharacterData(node) {
2334 Node.call(this, node);
2336 CharacterData.prototype = Object.create(Node.prototype);
2337 mixin(CharacterData.prototype, {
2341 set nodeValue(data) {
2347 set textContent(value) {
2351 return unsafeUnwrap(this).data;
2354 var oldValue = unsafeUnwrap(this).data;
2355 enqueueMutation(this, "characterData", {
2358 unsafeUnwrap(this).data = value;
2361 mixin(CharacterData.prototype, ChildNodeInterface);
2362 registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
2363 scope.wrappers.CharacterData = CharacterData;
2364 })(window.ShadowDOMPolyfill);
2367 var CharacterData = scope.wrappers.CharacterData;
2368 var enqueueMutation = scope.enqueueMutation;
2369 var mixin = scope.mixin;
2370 var registerWrapper = scope.registerWrapper;
2371 function toUInt32(x) {
2374 var OriginalText = window.Text;
2375 function Text(node) {
2376 CharacterData.call(this, node);
2378 Text.prototype = Object.create(CharacterData.prototype);
2379 mixin(Text.prototype, {
2380 splitText: function(offset) {
2381 offset = toUInt32(offset);
2383 if (offset > s.length) throw new Error("IndexSizeError");
2384 var head = s.slice(0, offset);
2385 var tail = s.slice(offset);
2387 var newTextNode = this.ownerDocument.createTextNode(tail);
2388 if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
2392 registerWrapper(OriginalText, Text, document.createTextNode(""));
2393 scope.wrappers.Text = Text;
2394 })(window.ShadowDOMPolyfill);
2397 if (!window.DOMTokenList) {
2398 console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
2401 var unsafeUnwrap = scope.unsafeUnwrap;
2402 var enqueueMutation = scope.enqueueMutation;
2403 function getClass(el) {
2404 return unsafeUnwrap(el).getAttribute("class");
2406 function enqueueClassAttributeChange(el, oldValue) {
2407 enqueueMutation(el, "attributes", {
2413 function invalidateClass(el) {
2414 scope.invalidateRendererBasedOnAttribute(el, "class");
2416 function changeClass(tokenList, method, args) {
2417 var ownerElement = tokenList.ownerElement_;
2418 if (ownerElement == null) {
2419 return method.apply(tokenList, args);
2421 var oldValue = getClass(ownerElement);
2422 var retv = method.apply(tokenList, args);
2423 if (getClass(ownerElement) !== oldValue) {
2424 enqueueClassAttributeChange(ownerElement, oldValue);
2425 invalidateClass(ownerElement);
2429 var oldAdd = DOMTokenList.prototype.add;
2430 DOMTokenList.prototype.add = function() {
2431 changeClass(this, oldAdd, arguments);
2433 var oldRemove = DOMTokenList.prototype.remove;
2434 DOMTokenList.prototype.remove = function() {
2435 changeClass(this, oldRemove, arguments);
2437 var oldToggle = DOMTokenList.prototype.toggle;
2438 DOMTokenList.prototype.toggle = function() {
2439 return changeClass(this, oldToggle, arguments);
2441 })(window.ShadowDOMPolyfill);
2444 var ChildNodeInterface = scope.ChildNodeInterface;
2445 var GetElementsByInterface = scope.GetElementsByInterface;
2446 var Node = scope.wrappers.Node;
2447 var ParentNodeInterface = scope.ParentNodeInterface;
2448 var SelectorsInterface = scope.SelectorsInterface;
2449 var MatchesInterface = scope.MatchesInterface;
2450 var addWrapNodeListMethod = scope.addWrapNodeListMethod;
2451 var enqueueMutation = scope.enqueueMutation;
2452 var mixin = scope.mixin;
2453 var oneOf = scope.oneOf;
2454 var registerWrapper = scope.registerWrapper;
2455 var unsafeUnwrap = scope.unsafeUnwrap;
2456 var wrappers = scope.wrappers;
2457 var OriginalElement = window.Element;
2458 var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
2459 return OriginalElement.prototype[name];
2461 var matchesName = matchesNames[0];
2462 var originalMatches = OriginalElement.prototype[matchesName];
2463 function invalidateRendererBasedOnAttribute(element, name) {
2464 var p = element.parentNode;
2465 if (!p || !p.shadowRoot) return;
2466 var renderer = scope.getRendererForHost(p);
2467 if (renderer.dependsOnAttribute(name)) renderer.invalidate();
2469 function enqueAttributeChange(element, name, oldValue) {
2470 enqueueMutation(element, "attributes", {
2476 var classListTable = new WeakMap();
2477 function Element(node) {
2478 Node.call(this, node);
2480 Element.prototype = Object.create(Node.prototype);
2481 mixin(Element.prototype, {
2482 createShadowRoot: function() {
2483 var newShadowRoot = new wrappers.ShadowRoot(this);
2484 unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
2485 var renderer = scope.getRendererForHost(this);
2486 renderer.invalidate();
2487 return newShadowRoot;
2490 return unsafeUnwrap(this).polymerShadowRoot_ || null;
2492 setAttribute: function(name, value) {
2493 var oldValue = unsafeUnwrap(this).getAttribute(name);
2494 unsafeUnwrap(this).setAttribute(name, value);
2495 enqueAttributeChange(this, name, oldValue);
2496 invalidateRendererBasedOnAttribute(this, name);
2498 removeAttribute: function(name) {
2499 var oldValue = unsafeUnwrap(this).getAttribute(name);
2500 unsafeUnwrap(this).removeAttribute(name);
2501 enqueAttributeChange(this, name, oldValue);
2502 invalidateRendererBasedOnAttribute(this, name);
2505 var list = classListTable.get(this);
2507 list = unsafeUnwrap(this).classList;
2509 list.ownerElement_ = this;
2510 classListTable.set(this, list);
2515 return unsafeUnwrap(this).className;
2518 this.setAttribute("class", v);
2521 return unsafeUnwrap(this).id;
2524 this.setAttribute("id", v);
2527 matchesNames.forEach(function(name) {
2528 if (name !== "matches") {
2529 Element.prototype[name] = function(selector) {
2530 return this.matches(selector);
2534 if (OriginalElement.prototype.webkitCreateShadowRoot) {
2535 Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
2537 mixin(Element.prototype, ChildNodeInterface);
2538 mixin(Element.prototype, GetElementsByInterface);
2539 mixin(Element.prototype, ParentNodeInterface);
2540 mixin(Element.prototype, SelectorsInterface);
2541 mixin(Element.prototype, MatchesInterface);
2542 registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
2543 scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
2544 scope.matchesNames = matchesNames;
2545 scope.originalMatches = originalMatches;
2546 scope.wrappers.Element = Element;
2547 })(window.ShadowDOMPolyfill);
2550 var Element = scope.wrappers.Element;
2551 var defineGetter = scope.defineGetter;
2552 var enqueueMutation = scope.enqueueMutation;
2553 var mixin = scope.mixin;
2554 var nodesWereAdded = scope.nodesWereAdded;
2555 var nodesWereRemoved = scope.nodesWereRemoved;
2556 var registerWrapper = scope.registerWrapper;
2557 var snapshotNodeList = scope.snapshotNodeList;
2558 var unsafeUnwrap = scope.unsafeUnwrap;
2559 var unwrap = scope.unwrap;
2560 var wrap = scope.wrap;
2561 var wrappers = scope.wrappers;
2562 var escapeAttrRegExp = /[&\u00A0"]/g;
2563 var escapeDataRegExp = /[&\u00A0<>]/g;
2564 function escapeReplace(c) {
2582 function escapeAttr(s) {
2583 return s.replace(escapeAttrRegExp, escapeReplace);
2585 function escapeData(s) {
2586 return s.replace(escapeDataRegExp, escapeReplace);
2588 function makeSet(arr) {
2590 for (var i = 0; i < arr.length; i++) {
2595 var voidElements = makeSet([ "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" ]);
2596 var plaintextParents = makeSet([ "style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript" ]);
2597 var XHTML_NS = "http://www.w3.org/1999/xhtml";
2598 function needsSelfClosingSlash(node) {
2599 if (node.namespaceURI !== XHTML_NS) return true;
2600 var doctype = node.ownerDocument.doctype;
2601 return doctype && doctype.publicId && doctype.systemId;
2603 function getOuterHTML(node, parentNode) {
2604 switch (node.nodeType) {
2605 case Node.ELEMENT_NODE:
2606 var tagName = node.tagName.toLowerCase();
2607 var s = "<" + tagName;
2608 var attrs = node.attributes;
2609 for (var i = 0, attr; attr = attrs[i]; i++) {
2610 s += " " + attr.name + '="' + escapeAttr(attr.value) + '"';
2612 if (voidElements[tagName]) {
2613 if (needsSelfClosingSlash(node)) s += "/";
2616 return s + ">" + getInnerHTML(node) + "</" + tagName + ">";
2618 case Node.TEXT_NODE:
2619 var data = node.data;
2620 if (parentNode && plaintextParents[parentNode.localName]) return data;
2621 return escapeData(data);
2623 case Node.COMMENT_NODE:
2624 return "<!--" + node.data + "-->";
2627 console.error(node);
2628 throw new Error("not implemented");
2631 function getInnerHTML(node) {
2632 if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
2634 for (var child = node.firstChild; child; child = child.nextSibling) {
2635 s += getOuterHTML(child, node);
2639 function setInnerHTML(node, value, opt_tagName) {
2640 var tagName = opt_tagName || "div";
2641 node.textContent = "";
2642 var tempElement = unwrap(node.ownerDocument.createElement(tagName));
2643 tempElement.innerHTML = value;
2645 while (firstChild = tempElement.firstChild) {
2646 node.appendChild(wrap(firstChild));
2649 var oldIe = /MSIE/.test(navigator.userAgent);
2650 var OriginalHTMLElement = window.HTMLElement;
2651 var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
2652 function HTMLElement(node) {
2653 Element.call(this, node);
2655 HTMLElement.prototype = Object.create(Element.prototype);
2656 mixin(HTMLElement.prototype, {
2658 return getInnerHTML(this);
2660 set innerHTML(value) {
2661 if (oldIe && plaintextParents[this.localName]) {
2662 this.textContent = value;
2665 var removedNodes = snapshotNodeList(this.childNodes);
2666 if (this.invalidateShadowRenderer()) {
2667 if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
2668 } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
2669 setInnerHTML(this.content, value);
2671 unsafeUnwrap(this).innerHTML = value;
2673 var addedNodes = snapshotNodeList(this.childNodes);
2674 enqueueMutation(this, "childList", {
2675 addedNodes: addedNodes,
2676 removedNodes: removedNodes
2678 nodesWereRemoved(removedNodes);
2679 nodesWereAdded(addedNodes, this);
2682 return getOuterHTML(this, this.parentNode);
2684 set outerHTML(value) {
2685 var p = this.parentNode;
2687 p.invalidateShadowRenderer();
2688 var df = frag(p, value);
2689 p.replaceChild(df, this);
2692 insertAdjacentHTML: function(position, text) {
2693 var contextElement, refNode;
2694 switch (String(position).toLowerCase()) {
2696 contextElement = this.parentNode;
2701 contextElement = this.parentNode;
2702 refNode = this.nextSibling;
2706 contextElement = this;
2707 refNode = this.firstChild;
2711 contextElement = this;
2718 var df = frag(contextElement, text);
2719 contextElement.insertBefore(df, refNode);
2722 return this.hasAttribute("hidden");
2726 this.setAttribute("hidden", "");
2728 this.removeAttribute("hidden");
2732 function frag(contextElement, html) {
2733 var p = unwrap(contextElement.cloneNode(false));
2735 var df = unwrap(document.createDocumentFragment());
2737 while (c = p.firstChild) {
2742 function getter(name) {
2744 scope.renderAllPending();
2745 return unsafeUnwrap(this)[name];
2748 function getterRequiresRendering(name) {
2749 defineGetter(HTMLElement, name, getter(name));
2751 [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
2752 function getterAndSetterRequiresRendering(name) {
2753 Object.defineProperty(HTMLElement.prototype, name, {
2756 scope.renderAllPending();
2757 unsafeUnwrap(this)[name] = v;
2763 [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
2764 function methodRequiresRendering(name) {
2765 Object.defineProperty(HTMLElement.prototype, name, {
2767 scope.renderAllPending();
2768 return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
2774 [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
2775 registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
2776 scope.wrappers.HTMLElement = HTMLElement;
2777 scope.getInnerHTML = getInnerHTML;
2778 scope.setInnerHTML = setInnerHTML;
2779 })(window.ShadowDOMPolyfill);
2782 var HTMLElement = scope.wrappers.HTMLElement;
2783 var mixin = scope.mixin;
2784 var registerWrapper = scope.registerWrapper;
2785 var unsafeUnwrap = scope.unsafeUnwrap;
2786 var wrap = scope.wrap;
2787 var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
2788 function HTMLCanvasElement(node) {
2789 HTMLElement.call(this, node);
2791 HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
2792 mixin(HTMLCanvasElement.prototype, {
2793 getContext: function() {
2794 var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
2795 return context && wrap(context);
2798 registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
2799 scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
2800 })(window.ShadowDOMPolyfill);
2803 var HTMLElement = scope.wrappers.HTMLElement;
2804 var mixin = scope.mixin;
2805 var registerWrapper = scope.registerWrapper;
2806 var OriginalHTMLContentElement = window.HTMLContentElement;
2807 function HTMLContentElement(node) {
2808 HTMLElement.call(this, node);
2810 HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
2811 mixin(HTMLContentElement.prototype, {
2812 constructor: HTMLContentElement,
2814 return this.getAttribute("select");
2817 this.setAttribute("select", value);
2819 setAttribute: function(n, v) {
2820 HTMLElement.prototype.setAttribute.call(this, n, v);
2821 if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
2824 if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
2825 scope.wrappers.HTMLContentElement = HTMLContentElement;
2826 })(window.ShadowDOMPolyfill);
2829 var HTMLElement = scope.wrappers.HTMLElement;
2830 var mixin = scope.mixin;
2831 var registerWrapper = scope.registerWrapper;
2832 var wrapHTMLCollection = scope.wrapHTMLCollection;
2833 var unwrap = scope.unwrap;
2834 var OriginalHTMLFormElement = window.HTMLFormElement;
2835 function HTMLFormElement(node) {
2836 HTMLElement.call(this, node);
2838 HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
2839 mixin(HTMLFormElement.prototype, {
2841 return wrapHTMLCollection(unwrap(this).elements);
2844 registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
2845 scope.wrappers.HTMLFormElement = HTMLFormElement;
2846 })(window.ShadowDOMPolyfill);
2849 var HTMLElement = scope.wrappers.HTMLElement;
2850 var registerWrapper = scope.registerWrapper;
2851 var unwrap = scope.unwrap;
2852 var rewrap = scope.rewrap;
2853 var OriginalHTMLImageElement = window.HTMLImageElement;
2854 function HTMLImageElement(node) {
2855 HTMLElement.call(this, node);
2857 HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
2858 registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
2859 function Image(width, height) {
2860 if (!(this instanceof Image)) {
2861 throw new TypeError("DOM object constructor cannot be called as a function.");
2863 var node = unwrap(document.createElement("img"));
2864 HTMLElement.call(this, node);
2866 if (width !== undefined) node.width = width;
2867 if (height !== undefined) node.height = height;
2869 Image.prototype = HTMLImageElement.prototype;
2870 scope.wrappers.HTMLImageElement = HTMLImageElement;
2871 scope.wrappers.Image = Image;
2872 })(window.ShadowDOMPolyfill);
2875 var HTMLElement = scope.wrappers.HTMLElement;
2876 var mixin = scope.mixin;
2877 var NodeList = scope.wrappers.NodeList;
2878 var registerWrapper = scope.registerWrapper;
2879 var OriginalHTMLShadowElement = window.HTMLShadowElement;
2880 function HTMLShadowElement(node) {
2881 HTMLElement.call(this, node);
2883 HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
2884 HTMLShadowElement.prototype.constructor = HTMLShadowElement;
2885 if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
2886 scope.wrappers.HTMLShadowElement = HTMLShadowElement;
2887 })(window.ShadowDOMPolyfill);
2890 var HTMLElement = scope.wrappers.HTMLElement;
2891 var mixin = scope.mixin;
2892 var registerWrapper = scope.registerWrapper;
2893 var unsafeUnwrap = scope.unsafeUnwrap;
2894 var unwrap = scope.unwrap;
2895 var wrap = scope.wrap;
2896 var contentTable = new WeakMap();
2897 var templateContentsOwnerTable = new WeakMap();
2898 function getTemplateContentsOwner(doc) {
2899 if (!doc.defaultView) return doc;
2900 var d = templateContentsOwnerTable.get(doc);
2902 d = doc.implementation.createHTMLDocument("");
2903 while (d.lastChild) {
2904 d.removeChild(d.lastChild);
2906 templateContentsOwnerTable.set(doc, d);
2910 function extractContent(templateElement) {
2911 var doc = getTemplateContentsOwner(templateElement.ownerDocument);
2912 var df = unwrap(doc.createDocumentFragment());
2914 while (child = templateElement.firstChild) {
2915 df.appendChild(child);
2919 var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
2920 function HTMLTemplateElement(node) {
2921 HTMLElement.call(this, node);
2922 if (!OriginalHTMLTemplateElement) {
2923 var content = extractContent(node);
2924 contentTable.set(this, wrap(content));
2927 HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
2928 mixin(HTMLTemplateElement.prototype, {
2929 constructor: HTMLTemplateElement,
2931 if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
2932 return contentTable.get(this);
2935 if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
2936 scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
2937 })(window.ShadowDOMPolyfill);
2940 var HTMLElement = scope.wrappers.HTMLElement;
2941 var registerWrapper = scope.registerWrapper;
2942 var OriginalHTMLMediaElement = window.HTMLMediaElement;
2943 if (!OriginalHTMLMediaElement) return;
2944 function HTMLMediaElement(node) {
2945 HTMLElement.call(this, node);
2947 HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
2948 registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
2949 scope.wrappers.HTMLMediaElement = HTMLMediaElement;
2950 })(window.ShadowDOMPolyfill);
2953 var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
2954 var registerWrapper = scope.registerWrapper;
2955 var unwrap = scope.unwrap;
2956 var rewrap = scope.rewrap;
2957 var OriginalHTMLAudioElement = window.HTMLAudioElement;
2958 if (!OriginalHTMLAudioElement) return;
2959 function HTMLAudioElement(node) {
2960 HTMLMediaElement.call(this, node);
2962 HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
2963 registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
2964 function Audio(src) {
2965 if (!(this instanceof Audio)) {
2966 throw new TypeError("DOM object constructor cannot be called as a function.");
2968 var node = unwrap(document.createElement("audio"));
2969 HTMLMediaElement.call(this, node);
2971 node.setAttribute("preload", "auto");
2972 if (src !== undefined) node.setAttribute("src", src);
2974 Audio.prototype = HTMLAudioElement.prototype;
2975 scope.wrappers.HTMLAudioElement = HTMLAudioElement;
2976 scope.wrappers.Audio = Audio;
2977 })(window.ShadowDOMPolyfill);
2980 var HTMLElement = scope.wrappers.HTMLElement;
2981 var mixin = scope.mixin;
2982 var registerWrapper = scope.registerWrapper;
2983 var rewrap = scope.rewrap;
2984 var unwrap = scope.unwrap;
2985 var wrap = scope.wrap;
2986 var OriginalHTMLOptionElement = window.HTMLOptionElement;
2987 function trimText(s) {
2988 return s.replace(/\s+/g, " ").trim();
2990 function HTMLOptionElement(node) {
2991 HTMLElement.call(this, node);
2993 HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
2994 mixin(HTMLOptionElement.prototype, {
2996 return trimText(this.textContent);
2999 this.textContent = trimText(String(value));
3002 return wrap(unwrap(this).form);
3005 registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
3006 function Option(text, value, defaultSelected, selected) {
3007 if (!(this instanceof Option)) {
3008 throw new TypeError("DOM object constructor cannot be called as a function.");
3010 var node = unwrap(document.createElement("option"));
3011 HTMLElement.call(this, node);
3013 if (text !== undefined) node.text = text;
3014 if (value !== undefined) node.setAttribute("value", value);
3015 if (defaultSelected === true) node.setAttribute("selected", "");
3016 node.selected = selected === true;
3018 Option.prototype = HTMLOptionElement.prototype;
3019 scope.wrappers.HTMLOptionElement = HTMLOptionElement;
3020 scope.wrappers.Option = Option;
3021 })(window.ShadowDOMPolyfill);
3024 var HTMLElement = scope.wrappers.HTMLElement;
3025 var mixin = scope.mixin;
3026 var registerWrapper = scope.registerWrapper;
3027 var unwrap = scope.unwrap;
3028 var wrap = scope.wrap;
3029 var OriginalHTMLSelectElement = window.HTMLSelectElement;
3030 function HTMLSelectElement(node) {
3031 HTMLElement.call(this, node);
3033 HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
3034 mixin(HTMLSelectElement.prototype, {
3035 add: function(element, before) {
3036 if (typeof before === "object") before = unwrap(before);
3037 unwrap(this).add(unwrap(element), before);
3039 remove: function(indexOrNode) {
3040 if (indexOrNode === undefined) {
3041 HTMLElement.prototype.remove.call(this);
3044 if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
3045 unwrap(this).remove(indexOrNode);
3048 return wrap(unwrap(this).form);
3051 registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
3052 scope.wrappers.HTMLSelectElement = HTMLSelectElement;
3053 })(window.ShadowDOMPolyfill);
3056 var HTMLElement = scope.wrappers.HTMLElement;
3057 var mixin = scope.mixin;
3058 var registerWrapper = scope.registerWrapper;
3059 var unwrap = scope.unwrap;
3060 var wrap = scope.wrap;
3061 var wrapHTMLCollection = scope.wrapHTMLCollection;
3062 var OriginalHTMLTableElement = window.HTMLTableElement;
3063 function HTMLTableElement(node) {
3064 HTMLElement.call(this, node);
3066 HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
3067 mixin(HTMLTableElement.prototype, {
3069 return wrap(unwrap(this).caption);
3071 createCaption: function() {
3072 return wrap(unwrap(this).createCaption());
3075 return wrap(unwrap(this).tHead);
3077 createTHead: function() {
3078 return wrap(unwrap(this).createTHead());
3080 createTFoot: function() {
3081 return wrap(unwrap(this).createTFoot());
3084 return wrap(unwrap(this).tFoot);
3087 return wrapHTMLCollection(unwrap(this).tBodies);
3089 createTBody: function() {
3090 return wrap(unwrap(this).createTBody());
3093 return wrapHTMLCollection(unwrap(this).rows);
3095 insertRow: function(index) {
3096 return wrap(unwrap(this).insertRow(index));
3099 registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
3100 scope.wrappers.HTMLTableElement = HTMLTableElement;
3101 })(window.ShadowDOMPolyfill);
3104 var HTMLElement = scope.wrappers.HTMLElement;
3105 var mixin = scope.mixin;
3106 var registerWrapper = scope.registerWrapper;
3107 var wrapHTMLCollection = scope.wrapHTMLCollection;
3108 var unwrap = scope.unwrap;
3109 var wrap = scope.wrap;
3110 var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
3111 function HTMLTableSectionElement(node) {
3112 HTMLElement.call(this, node);
3114 HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
3115 mixin(HTMLTableSectionElement.prototype, {
3116 constructor: HTMLTableSectionElement,
3118 return wrapHTMLCollection(unwrap(this).rows);
3120 insertRow: function(index) {
3121 return wrap(unwrap(this).insertRow(index));
3124 registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
3125 scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
3126 })(window.ShadowDOMPolyfill);
3129 var HTMLElement = scope.wrappers.HTMLElement;
3130 var mixin = scope.mixin;
3131 var registerWrapper = scope.registerWrapper;
3132 var wrapHTMLCollection = scope.wrapHTMLCollection;
3133 var unwrap = scope.unwrap;
3134 var wrap = scope.wrap;
3135 var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
3136 function HTMLTableRowElement(node) {
3137 HTMLElement.call(this, node);
3139 HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
3140 mixin(HTMLTableRowElement.prototype, {
3142 return wrapHTMLCollection(unwrap(this).cells);
3144 insertCell: function(index) {
3145 return wrap(unwrap(this).insertCell(index));
3148 registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
3149 scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
3150 })(window.ShadowDOMPolyfill);
3153 var HTMLContentElement = scope.wrappers.HTMLContentElement;
3154 var HTMLElement = scope.wrappers.HTMLElement;
3155 var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
3156 var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
3157 var mixin = scope.mixin;
3158 var registerWrapper = scope.registerWrapper;
3159 var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
3160 function HTMLUnknownElement(node) {
3161 switch (node.localName) {
3163 return new HTMLContentElement(node);
3166 return new HTMLShadowElement(node);
3169 return new HTMLTemplateElement(node);
3171 HTMLElement.call(this, node);
3173 HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
3174 registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
3175 scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
3176 })(window.ShadowDOMPolyfill);
3179 var Element = scope.wrappers.Element;
3180 var HTMLElement = scope.wrappers.HTMLElement;
3181 var registerWrapper = scope.registerWrapper;
3182 var defineWrapGetter = scope.defineWrapGetter;
3183 var unsafeUnwrap = scope.unsafeUnwrap;
3184 var wrap = scope.wrap;
3185 var mixin = scope.mixin;
3186 var SVG_NS = "http://www.w3.org/2000/svg";
3187 var OriginalSVGElement = window.SVGElement;
3188 var svgTitleElement = document.createElementNS(SVG_NS, "title");
3189 if (!("classList" in svgTitleElement)) {
3190 var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
3191 Object.defineProperty(HTMLElement.prototype, "classList", descr);
3192 delete Element.prototype.classList;
3194 function SVGElement(node) {
3195 Element.call(this, node);
3197 SVGElement.prototype = Object.create(Element.prototype);
3198 mixin(SVGElement.prototype, {
3199 get ownerSVGElement() {
3200 return wrap(unsafeUnwrap(this).ownerSVGElement);
3203 registerWrapper(OriginalSVGElement, SVGElement, document.createElementNS(SVG_NS, "title"));
3204 scope.wrappers.SVGElement = SVGElement;
3205 })(window.ShadowDOMPolyfill);
3208 var mixin = scope.mixin;
3209 var registerWrapper = scope.registerWrapper;
3210 var unwrap = scope.unwrap;
3211 var wrap = scope.wrap;
3212 var OriginalSVGUseElement = window.SVGUseElement;
3213 var SVG_NS = "http://www.w3.org/2000/svg";
3214 var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
3215 var useElement = document.createElementNS(SVG_NS, "use");
3216 var SVGGElement = gWrapper.constructor;
3217 var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
3218 var parentInterface = parentInterfacePrototype.constructor;
3219 function SVGUseElement(impl) {
3220 parentInterface.call(this, impl);
3222 SVGUseElement.prototype = Object.create(parentInterfacePrototype);
3223 if ("instanceRoot" in useElement) {
3224 mixin(SVGUseElement.prototype, {
3225 get instanceRoot() {
3226 return wrap(unwrap(this).instanceRoot);
3228 get animatedInstanceRoot() {
3229 return wrap(unwrap(this).animatedInstanceRoot);
3233 registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
3234 scope.wrappers.SVGUseElement = SVGUseElement;
3235 })(window.ShadowDOMPolyfill);
3238 var EventTarget = scope.wrappers.EventTarget;
3239 var mixin = scope.mixin;
3240 var registerWrapper = scope.registerWrapper;
3241 var unsafeUnwrap = scope.unsafeUnwrap;
3242 var wrap = scope.wrap;
3243 var OriginalSVGElementInstance = window.SVGElementInstance;
3244 if (!OriginalSVGElementInstance) return;
3245 function SVGElementInstance(impl) {
3246 EventTarget.call(this, impl);
3248 SVGElementInstance.prototype = Object.create(EventTarget.prototype);
3249 mixin(SVGElementInstance.prototype, {
3250 get correspondingElement() {
3251 return wrap(unsafeUnwrap(this).correspondingElement);
3253 get correspondingUseElement() {
3254 return wrap(unsafeUnwrap(this).correspondingUseElement);
3257 return wrap(unsafeUnwrap(this).parentNode);
3260 throw new Error("Not implemented");
3263 return wrap(unsafeUnwrap(this).firstChild);
3266 return wrap(unsafeUnwrap(this).lastChild);
3268 get previousSibling() {
3269 return wrap(unsafeUnwrap(this).previousSibling);
3272 return wrap(unsafeUnwrap(this).nextSibling);
3275 registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
3276 scope.wrappers.SVGElementInstance = SVGElementInstance;
3277 })(window.ShadowDOMPolyfill);
3280 var mixin = scope.mixin;
3281 var registerWrapper = scope.registerWrapper;
3282 var setWrapper = scope.setWrapper;
3283 var unsafeUnwrap = scope.unsafeUnwrap;
3284 var unwrap = scope.unwrap;
3285 var unwrapIfNeeded = scope.unwrapIfNeeded;
3286 var wrap = scope.wrap;
3287 var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
3288 function CanvasRenderingContext2D(impl) {
3289 setWrapper(impl, this);
3291 mixin(CanvasRenderingContext2D.prototype, {
3293 return wrap(unsafeUnwrap(this).canvas);
3295 drawImage: function() {
3296 arguments[0] = unwrapIfNeeded(arguments[0]);
3297 unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
3299 createPattern: function() {
3300 arguments[0] = unwrap(arguments[0]);
3301 return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
3304 registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
3305 scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
3306 })(window.ShadowDOMPolyfill);
3309 var mixin = scope.mixin;
3310 var registerWrapper = scope.registerWrapper;
3311 var setWrapper = scope.setWrapper;
3312 var unsafeUnwrap = scope.unsafeUnwrap;
3313 var unwrapIfNeeded = scope.unwrapIfNeeded;
3314 var wrap = scope.wrap;
3315 var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
3316 if (!OriginalWebGLRenderingContext) return;
3317 function WebGLRenderingContext(impl) {
3318 setWrapper(impl, this);
3320 mixin(WebGLRenderingContext.prototype, {
3322 return wrap(unsafeUnwrap(this).canvas);
3324 texImage2D: function() {
3325 arguments[5] = unwrapIfNeeded(arguments[5]);
3326 unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
3328 texSubImage2D: function() {
3329 arguments[6] = unwrapIfNeeded(arguments[6]);
3330 unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
3333 var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
3334 drawingBufferHeight: null,
3335 drawingBufferWidth: null
3337 registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
3338 scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
3339 })(window.ShadowDOMPolyfill);
3342 var Node = scope.wrappers.Node;
3343 var GetElementsByInterface = scope.GetElementsByInterface;
3344 var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
3345 var ParentNodeInterface = scope.ParentNodeInterface;
3346 var SelectorsInterface = scope.SelectorsInterface;
3347 var mixin = scope.mixin;
3348 var registerObject = scope.registerObject;
3349 var registerWrapper = scope.registerWrapper;
3350 var OriginalDocumentFragment = window.DocumentFragment;
3351 function DocumentFragment(node) {
3352 Node.call(this, node);
3354 DocumentFragment.prototype = Object.create(Node.prototype);
3355 mixin(DocumentFragment.prototype, ParentNodeInterface);
3356 mixin(DocumentFragment.prototype, SelectorsInterface);
3357 mixin(DocumentFragment.prototype, GetElementsByInterface);
3358 mixin(DocumentFragment.prototype, NonElementParentNodeInterface);
3359 registerWrapper(OriginalDocumentFragment, DocumentFragment, document.createDocumentFragment());
3360 scope.wrappers.DocumentFragment = DocumentFragment;
3361 var Comment = registerObject(document.createComment(""));
3362 scope.wrappers.Comment = Comment;
3363 })(window.ShadowDOMPolyfill);
3366 var DocumentFragment = scope.wrappers.DocumentFragment;
3367 var TreeScope = scope.TreeScope;
3368 var elementFromPoint = scope.elementFromPoint;
3369 var getInnerHTML = scope.getInnerHTML;
3370 var getTreeScope = scope.getTreeScope;
3371 var mixin = scope.mixin;
3372 var rewrap = scope.rewrap;
3373 var setInnerHTML = scope.setInnerHTML;
3374 var unsafeUnwrap = scope.unsafeUnwrap;
3375 var unwrap = scope.unwrap;
3376 var shadowHostTable = new WeakMap();
3377 var nextOlderShadowTreeTable = new WeakMap();
3378 function ShadowRoot(hostWrapper) {
3379 var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
3380 DocumentFragment.call(this, node);
3382 var oldShadowRoot = hostWrapper.shadowRoot;
3383 nextOlderShadowTreeTable.set(this, oldShadowRoot);
3384 this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
3385 shadowHostTable.set(this, hostWrapper);
3387 ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
3388 mixin(ShadowRoot.prototype, {
3389 constructor: ShadowRoot,
3391 return getInnerHTML(this);
3393 set innerHTML(value) {
3394 setInnerHTML(this, value);
3395 this.invalidateShadowRenderer();
3397 get olderShadowRoot() {
3398 return nextOlderShadowTreeTable.get(this) || null;
3401 return shadowHostTable.get(this) || null;
3403 invalidateShadowRenderer: function() {
3404 return shadowHostTable.get(this).invalidateShadowRenderer();
3406 elementFromPoint: function(x, y) {
3407 return elementFromPoint(this, this.ownerDocument, x, y);
3409 getSelection: function() {
3410 return document.getSelection();
3413 scope.wrappers.ShadowRoot = ShadowRoot;
3414 })(window.ShadowDOMPolyfill);
3417 var registerWrapper = scope.registerWrapper;
3418 var setWrapper = scope.setWrapper;
3419 var unsafeUnwrap = scope.unsafeUnwrap;
3420 var unwrap = scope.unwrap;
3421 var unwrapIfNeeded = scope.unwrapIfNeeded;
3422 var wrap = scope.wrap;
3423 var getTreeScope = scope.getTreeScope;
3424 var OriginalRange = window.Range;
3425 var ShadowRoot = scope.wrappers.ShadowRoot;
3426 function getHost(node) {
3427 var root = getTreeScope(node).root;
3428 if (root instanceof ShadowRoot) {
3433 function hostNodeToShadowNode(refNode, offset) {
3434 if (refNode.shadowRoot) {
3435 offset = Math.min(refNode.childNodes.length - 1, offset);
3436 var child = refNode.childNodes[offset];
3438 var insertionPoint = scope.getDestinationInsertionPoints(child);
3439 if (insertionPoint.length > 0) {
3440 var parentNode = insertionPoint[0].parentNode;
3441 if (parentNode.nodeType == Node.ELEMENT_NODE) {
3442 refNode = parentNode;
3449 function shadowNodeToHostNode(node) {
3451 return getHost(node) || node;
3453 function Range(impl) {
3454 setWrapper(impl, this);
3457 get startContainer() {
3458 return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);
3460 get endContainer() {
3461 return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);
3463 get commonAncestorContainer() {
3464 return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);
3466 setStart: function(refNode, offset) {
3467 refNode = hostNodeToShadowNode(refNode, offset);
3468 unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
3470 setEnd: function(refNode, offset) {
3471 refNode = hostNodeToShadowNode(refNode, offset);
3472 unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
3474 setStartBefore: function(refNode) {
3475 unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
3477 setStartAfter: function(refNode) {
3478 unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
3480 setEndBefore: function(refNode) {
3481 unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
3483 setEndAfter: function(refNode) {
3484 unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
3486 selectNode: function(refNode) {
3487 unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
3489 selectNodeContents: function(refNode) {
3490 unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
3492 compareBoundaryPoints: function(how, sourceRange) {
3493 return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
3495 extractContents: function() {
3496 return wrap(unsafeUnwrap(this).extractContents());
3498 cloneContents: function() {
3499 return wrap(unsafeUnwrap(this).cloneContents());
3501 insertNode: function(node) {
3502 unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
3504 surroundContents: function(newParent) {
3505 unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
3507 cloneRange: function() {
3508 return wrap(unsafeUnwrap(this).cloneRange());
3510 isPointInRange: function(node, offset) {
3511 return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
3513 comparePoint: function(node, offset) {
3514 return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
3516 intersectsNode: function(node) {
3517 return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
3519 toString: function() {
3520 return unsafeUnwrap(this).toString();
3523 if (OriginalRange.prototype.createContextualFragment) {
3524 Range.prototype.createContextualFragment = function(html) {
3525 return wrap(unsafeUnwrap(this).createContextualFragment(html));
3528 registerWrapper(window.Range, Range, document.createRange());
3529 scope.wrappers.Range = Range;
3530 })(window.ShadowDOMPolyfill);
3533 var Element = scope.wrappers.Element;
3534 var HTMLContentElement = scope.wrappers.HTMLContentElement;
3535 var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
3536 var Node = scope.wrappers.Node;
3537 var ShadowRoot = scope.wrappers.ShadowRoot;
3538 var assert = scope.assert;
3539 var getTreeScope = scope.getTreeScope;
3540 var mixin = scope.mixin;
3541 var oneOf = scope.oneOf;
3542 var unsafeUnwrap = scope.unsafeUnwrap;
3543 var unwrap = scope.unwrap;
3544 var wrap = scope.wrap;
3545 var ArraySplice = scope.ArraySplice;
3546 function updateWrapperUpAndSideways(wrapper) {
3547 wrapper.previousSibling_ = wrapper.previousSibling;
3548 wrapper.nextSibling_ = wrapper.nextSibling;
3549 wrapper.parentNode_ = wrapper.parentNode;
3551 function updateWrapperDown(wrapper) {
3552 wrapper.firstChild_ = wrapper.firstChild;
3553 wrapper.lastChild_ = wrapper.lastChild;
3555 function updateAllChildNodes(parentNodeWrapper) {
3556 assert(parentNodeWrapper instanceof Node);
3557 for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
3558 updateWrapperUpAndSideways(childWrapper);
3560 updateWrapperDown(parentNodeWrapper);
3562 function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
3563 var parentNode = unwrap(parentNodeWrapper);
3564 var newChild = unwrap(newChildWrapper);
3565 var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
3566 remove(newChildWrapper);
3567 updateWrapperUpAndSideways(newChildWrapper);
3568 if (!refChildWrapper) {
3569 parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
3570 if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
3571 var lastChildWrapper = wrap(parentNode.lastChild);
3572 if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
3574 if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
3575 refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
3577 scope.originalInsertBefore.call(parentNode, newChild, refChild);
3579 function remove(nodeWrapper) {
3580 var node = unwrap(nodeWrapper);
3581 var parentNode = node.parentNode;
3582 if (!parentNode) return;
3583 var parentNodeWrapper = wrap(parentNode);
3584 updateWrapperUpAndSideways(nodeWrapper);
3585 if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
3586 if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
3587 if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
3588 if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
3589 scope.originalRemoveChild.call(parentNode, node);
3591 var distributedNodesTable = new WeakMap();
3592 var destinationInsertionPointsTable = new WeakMap();
3593 var rendererForHostTable = new WeakMap();
3594 function resetDistributedNodes(insertionPoint) {
3595 distributedNodesTable.set(insertionPoint, []);
3597 function getDistributedNodes(insertionPoint) {
3598 var rv = distributedNodesTable.get(insertionPoint);
3599 if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
3602 function getChildNodesSnapshot(node) {
3603 var result = [], i = 0;
3604 for (var child = node.firstChild; child; child = child.nextSibling) {
3605 result[i++] = child;
3609 var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
3610 var pendingDirtyRenderers = [];
3612 function renderAllPending() {
3613 for (var i = 0; i < pendingDirtyRenderers.length; i++) {
3614 var renderer = pendingDirtyRenderers[i];
3615 var parentRenderer = renderer.parentRenderer;
3616 if (parentRenderer && parentRenderer.dirty) continue;
3619 pendingDirtyRenderers = [];
3621 function handleRequestAnimationFrame() {
3625 function getRendererForHost(host) {
3626 var renderer = rendererForHostTable.get(host);
3628 renderer = new ShadowRenderer(host);
3629 rendererForHostTable.set(host, renderer);
3633 function getShadowRootAncestor(node) {
3634 var root = getTreeScope(node).root;
3635 if (root instanceof ShadowRoot) return root;
3638 function getRendererForShadowRoot(shadowRoot) {
3639 return getRendererForHost(shadowRoot.host);
3641 var spliceDiff = new ArraySplice();
3642 spliceDiff.equals = function(renderNode, rawNode) {
3643 return unwrap(renderNode.node) === rawNode;
3645 function RenderNode(node) {
3648 this.childNodes = [];
3650 RenderNode.prototype = {
3651 append: function(node) {
3652 var rv = new RenderNode(node);
3653 this.childNodes.push(rv);
3656 sync: function(opt_added) {
3657 if (this.skip) return;
3658 var nodeWrapper = this.node;
3659 var newChildren = this.childNodes;
3660 var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
3661 var added = opt_added || new WeakMap();
3662 var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
3663 var newIndex = 0, oldIndex = 0;
3665 for (var i = 0; i < splices.length; i++) {
3666 var splice = splices[i];
3667 for (;lastIndex < splice.index; lastIndex++) {
3669 newChildren[newIndex++].sync(added);
3671 var removedCount = splice.removed.length;
3672 for (var j = 0; j < removedCount; j++) {
3673 var wrapper = wrap(oldChildren[oldIndex++]);
3674 if (!added.get(wrapper)) remove(wrapper);
3676 var addedCount = splice.addedCount;
3677 var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
3678 for (var j = 0; j < addedCount; j++) {
3679 var newChildRenderNode = newChildren[newIndex++];
3680 var newChildWrapper = newChildRenderNode.node;
3681 insertBefore(nodeWrapper, newChildWrapper, refNode);
3682 added.set(newChildWrapper, true);
3683 newChildRenderNode.sync(added);
3685 lastIndex += addedCount;
3687 for (var i = lastIndex; i < newChildren.length; i++) {
3688 newChildren[i].sync(added);
3692 function ShadowRenderer(host) {
3695 this.invalidateAttributes();
3696 this.associateNode(host);
3698 ShadowRenderer.prototype = {
3699 render: function(opt_renderNode) {
3700 if (!this.dirty) return;
3701 this.invalidateAttributes();
3702 var host = this.host;
3703 this.distribution(host);
3704 var renderNode = opt_renderNode || new RenderNode(host);
3705 this.buildRenderTree(renderNode, host);
3706 var topMostRenderer = !opt_renderNode;
3707 if (topMostRenderer) renderNode.sync();
3710 get parentRenderer() {
3711 return getTreeScope(this.host).renderer;
3713 invalidate: function() {
3716 var parentRenderer = this.parentRenderer;
3717 if (parentRenderer) parentRenderer.invalidate();
3718 pendingDirtyRenderers.push(this);
3719 if (renderTimer) return;
3720 renderTimer = window[request](handleRequestAnimationFrame, 0);
3723 distribution: function(root) {
3724 this.resetAllSubtrees(root);
3725 this.distributionResolution(root);
3727 resetAll: function(node) {
3728 if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
3729 this.resetAllSubtrees(node);
3731 resetAllSubtrees: function(node) {
3732 for (var child = node.firstChild; child; child = child.nextSibling) {
3733 this.resetAll(child);
3735 if (node.shadowRoot) this.resetAll(node.shadowRoot);
3736 if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
3738 distributionResolution: function(node) {
3739 if (isShadowHost(node)) {
3740 var shadowHost = node;
3741 var pool = poolPopulation(shadowHost);
3742 var shadowTrees = getShadowTrees(shadowHost);
3743 for (var i = 0; i < shadowTrees.length; i++) {
3744 this.poolDistribution(shadowTrees[i], pool);
3746 for (var i = shadowTrees.length - 1; i >= 0; i--) {
3747 var shadowTree = shadowTrees[i];
3748 var shadow = getShadowInsertionPoint(shadowTree);
3750 var olderShadowRoot = shadowTree.olderShadowRoot;
3751 if (olderShadowRoot) {
3752 pool = poolPopulation(olderShadowRoot);
3754 for (var j = 0; j < pool.length; j++) {
3755 destributeNodeInto(pool[j], shadow);
3758 this.distributionResolution(shadowTree);
3761 for (var child = node.firstChild; child; child = child.nextSibling) {
3762 this.distributionResolution(child);
3765 poolDistribution: function(node, pool) {
3766 if (node instanceof HTMLShadowElement) return;
3767 if (node instanceof HTMLContentElement) {
3769 this.updateDependentAttributes(content.getAttribute("select"));
3770 var anyDistributed = false;
3771 for (var i = 0; i < pool.length; i++) {
3773 if (!node) continue;
3774 if (matches(node, content)) {
3775 destributeNodeInto(node, content);
3776 pool[i] = undefined;
3777 anyDistributed = true;
3780 if (!anyDistributed) {
3781 for (var child = content.firstChild; child; child = child.nextSibling) {
3782 destributeNodeInto(child, content);
3787 for (var child = node.firstChild; child; child = child.nextSibling) {
3788 this.poolDistribution(child, pool);
3791 buildRenderTree: function(renderNode, node) {
3792 var children = this.compose(node);
3793 for (var i = 0; i < children.length; i++) {
3794 var child = children[i];
3795 var childRenderNode = renderNode.append(child);
3796 this.buildRenderTree(childRenderNode, child);
3798 if (isShadowHost(node)) {
3799 var renderer = getRendererForHost(node);
3800 renderer.dirty = false;
3803 compose: function(node) {
3805 var p = node.shadowRoot || node;
3806 for (var child = p.firstChild; child; child = child.nextSibling) {
3807 if (isInsertionPoint(child)) {
3808 this.associateNode(p);
3809 var distributedNodes = getDistributedNodes(child);
3810 for (var j = 0; j < distributedNodes.length; j++) {
3811 var distributedNode = distributedNodes[j];
3812 if (isFinalDestination(child, distributedNode)) children.push(distributedNode);
3815 children.push(child);
3820 invalidateAttributes: function() {
3821 this.attributes = Object.create(null);
3823 updateDependentAttributes: function(selector) {
3824 if (!selector) return;
3825 var attributes = this.attributes;
3826 if (/\.\w+/.test(selector)) attributes["class"] = true;
3827 if (/#\w+/.test(selector)) attributes["id"] = true;
3828 selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
3829 attributes[name] = true;
3832 dependsOnAttribute: function(name) {
3833 return this.attributes[name];
3835 associateNode: function(node) {
3836 unsafeUnwrap(node).polymerShadowRenderer_ = this;
3839 function poolPopulation(node) {
3841 for (var child = node.firstChild; child; child = child.nextSibling) {
3842 if (isInsertionPoint(child)) {
3843 pool.push.apply(pool, getDistributedNodes(child));
3850 function getShadowInsertionPoint(node) {
3851 if (node instanceof HTMLShadowElement) return node;
3852 if (node instanceof HTMLContentElement) return null;
3853 for (var child = node.firstChild; child; child = child.nextSibling) {
3854 var res = getShadowInsertionPoint(child);
3855 if (res) return res;
3859 function destributeNodeInto(child, insertionPoint) {
3860 getDistributedNodes(insertionPoint).push(child);
3861 var points = destinationInsertionPointsTable.get(child);
3862 if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
3864 function getDestinationInsertionPoints(node) {
3865 return destinationInsertionPointsTable.get(node);
3867 function resetDestinationInsertionPoints(node) {
3868 destinationInsertionPointsTable.set(node, undefined);
3870 var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
3871 function matches(node, contentElement) {
3872 var select = contentElement.getAttribute("select");
3873 if (!select) return true;
3874 select = select.trim();
3875 if (!select) return true;
3876 if (!(node instanceof Element)) return false;
3877 if (!selectorStartCharRe.test(select)) return false;
3879 return node.matches(select);
3884 function isFinalDestination(insertionPoint, node) {
3885 var points = getDestinationInsertionPoints(node);
3886 return points && points[points.length - 1] === insertionPoint;
3888 function isInsertionPoint(node) {
3889 return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
3891 function isShadowHost(shadowHost) {
3892 return shadowHost.shadowRoot;
3894 function getShadowTrees(host) {
3896 for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
3901 function render(host) {
3902 new ShadowRenderer(host).render();
3904 Node.prototype.invalidateShadowRenderer = function(force) {
3905 var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
3907 renderer.invalidate();
3912 HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
3914 return getDistributedNodes(this);
3916 Element.prototype.getDestinationInsertionPoints = function() {
3918 return getDestinationInsertionPoints(this) || [];
3920 HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
3921 this.invalidateShadowRenderer();
3922 var shadowRoot = getShadowRootAncestor(this);
3924 if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
3925 unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
3926 if (renderer) renderer.invalidate();
3928 scope.getRendererForHost = getRendererForHost;
3929 scope.getShadowTrees = getShadowTrees;
3930 scope.renderAllPending = renderAllPending;
3931 scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
3933 insertBefore: insertBefore,
3936 })(window.ShadowDOMPolyfill);
3939 var HTMLElement = scope.wrappers.HTMLElement;
3940 var assert = scope.assert;
3941 var mixin = scope.mixin;
3942 var registerWrapper = scope.registerWrapper;
3943 var unwrap = scope.unwrap;
3944 var wrap = scope.wrap;
3945 var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
3946 function createWrapperConstructor(name) {
3947 if (!window[name]) return;
3948 assert(!scope.wrappers[name]);
3949 var GeneratedWrapper = function(node) {
3950 HTMLElement.call(this, node);
3952 GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
3953 mixin(GeneratedWrapper.prototype, {
3955 return wrap(unwrap(this).form);
3958 registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
3959 scope.wrappers[name] = GeneratedWrapper;
3961 elementsWithFormProperty.forEach(createWrapperConstructor);
3962 })(window.ShadowDOMPolyfill);
3965 var registerWrapper = scope.registerWrapper;
3966 var setWrapper = scope.setWrapper;
3967 var unsafeUnwrap = scope.unsafeUnwrap;
3968 var unwrap = scope.unwrap;
3969 var unwrapIfNeeded = scope.unwrapIfNeeded;
3970 var wrap = scope.wrap;
3971 var OriginalSelection = window.Selection;
3972 function Selection(impl) {
3973 setWrapper(impl, this);
3975 Selection.prototype = {
3977 return wrap(unsafeUnwrap(this).anchorNode);
3980 return wrap(unsafeUnwrap(this).focusNode);
3982 addRange: function(range) {
3983 unsafeUnwrap(this).addRange(unwrapIfNeeded(range));
3985 collapse: function(node, index) {
3986 unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
3988 containsNode: function(node, allowPartial) {
3989 return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
3991 getRangeAt: function(index) {
3992 return wrap(unsafeUnwrap(this).getRangeAt(index));
3994 removeRange: function(range) {
3995 unsafeUnwrap(this).removeRange(unwrap(range));
3997 selectAllChildren: function(node) {
3998 unsafeUnwrap(this).selectAllChildren(node instanceof ShadowRoot ? unsafeUnwrap(node.host) : unwrapIfNeeded(node));
4000 toString: function() {
4001 return unsafeUnwrap(this).toString();
4004 if (OriginalSelection.prototype.extend) {
4005 Selection.prototype.extend = function(node, offset) {
4006 unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
4009 registerWrapper(window.Selection, Selection, window.getSelection());
4010 scope.wrappers.Selection = Selection;
4011 })(window.ShadowDOMPolyfill);
4014 var registerWrapper = scope.registerWrapper;
4015 var setWrapper = scope.setWrapper;
4016 var unsafeUnwrap = scope.unsafeUnwrap;
4017 var unwrapIfNeeded = scope.unwrapIfNeeded;
4018 var wrap = scope.wrap;
4019 var OriginalTreeWalker = window.TreeWalker;
4020 function TreeWalker(impl) {
4021 setWrapper(impl, this);
4023 TreeWalker.prototype = {
4025 return wrap(unsafeUnwrap(this).root);
4028 return wrap(unsafeUnwrap(this).currentNode);
4030 set currentNode(node) {
4031 unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);
4034 return unsafeUnwrap(this).filter;
4036 parentNode: function() {
4037 return wrap(unsafeUnwrap(this).parentNode());
4039 firstChild: function() {
4040 return wrap(unsafeUnwrap(this).firstChild());
4042 lastChild: function() {
4043 return wrap(unsafeUnwrap(this).lastChild());
4045 previousSibling: function() {
4046 return wrap(unsafeUnwrap(this).previousSibling());
4048 previousNode: function() {
4049 return wrap(unsafeUnwrap(this).previousNode());
4051 nextNode: function() {
4052 return wrap(unsafeUnwrap(this).nextNode());
4055 registerWrapper(OriginalTreeWalker, TreeWalker);
4056 scope.wrappers.TreeWalker = TreeWalker;
4057 })(window.ShadowDOMPolyfill);
4060 var GetElementsByInterface = scope.GetElementsByInterface;
4061 var Node = scope.wrappers.Node;
4062 var ParentNodeInterface = scope.ParentNodeInterface;
4063 var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
4064 var Selection = scope.wrappers.Selection;
4065 var SelectorsInterface = scope.SelectorsInterface;
4066 var ShadowRoot = scope.wrappers.ShadowRoot;
4067 var TreeScope = scope.TreeScope;
4068 var cloneNode = scope.cloneNode;
4069 var defineWrapGetter = scope.defineWrapGetter;
4070 var elementFromPoint = scope.elementFromPoint;
4071 var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
4072 var matchesNames = scope.matchesNames;
4073 var mixin = scope.mixin;
4074 var registerWrapper = scope.registerWrapper;
4075 var renderAllPending = scope.renderAllPending;
4076 var rewrap = scope.rewrap;
4077 var setWrapper = scope.setWrapper;
4078 var unsafeUnwrap = scope.unsafeUnwrap;
4079 var unwrap = scope.unwrap;
4080 var wrap = scope.wrap;
4081 var wrapEventTargetMethods = scope.wrapEventTargetMethods;
4082 var wrapNodeList = scope.wrapNodeList;
4083 var implementationTable = new WeakMap();
4084 function Document(node) {
4085 Node.call(this, node);
4086 this.treeScope_ = new TreeScope(this, null);
4088 Document.prototype = Object.create(Node.prototype);
4089 defineWrapGetter(Document, "documentElement");
4090 defineWrapGetter(Document, "body");
4091 defineWrapGetter(Document, "head");
4092 function wrapMethod(name) {
4093 var original = document[name];
4094 Document.prototype[name] = function() {
4095 return wrap(original.apply(unsafeUnwrap(this), arguments));
4098 [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode" ].forEach(wrapMethod);
4099 var originalAdoptNode = document.adoptNode;
4100 function adoptNodeNoRemove(node, doc) {
4101 originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
4102 adoptSubtree(node, doc);
4104 function adoptSubtree(node, doc) {
4105 if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
4106 if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
4107 for (var child = node.firstChild; child; child = child.nextSibling) {
4108 adoptSubtree(child, doc);
4111 function adoptOlderShadowRoots(shadowRoot, doc) {
4112 var oldShadowRoot = shadowRoot.olderShadowRoot;
4113 if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
4115 var originalGetSelection = document.getSelection;
4116 mixin(Document.prototype, {
4117 adoptNode: function(node) {
4118 if (node.parentNode) node.parentNode.removeChild(node);
4119 adoptNodeNoRemove(node, this);
4122 elementFromPoint: function(x, y) {
4123 return elementFromPoint(this, this, x, y);
4125 importNode: function(node, deep) {
4126 return cloneNode(node, deep, unsafeUnwrap(this));
4128 getSelection: function() {
4130 return new Selection(originalGetSelection.call(unwrap(this)));
4132 getElementsByName: function(name) {
4133 return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
4136 var originalCreateTreeWalker = document.createTreeWalker;
4137 var TreeWalkerWrapper = scope.wrappers.TreeWalker;
4138 Document.prototype.createTreeWalker = function(root, whatToShow, filter, expandEntityReferences) {
4139 var newFilter = null;
4141 if (filter.acceptNode && typeof filter.acceptNode === "function") {
4143 acceptNode: function(node) {
4144 return filter.acceptNode(wrap(node));
4147 } else if (typeof filter === "function") {
4148 newFilter = function(node) {
4149 return filter(wrap(node));
4153 return new TreeWalkerWrapper(originalCreateTreeWalker.call(unwrap(this), unwrap(root), whatToShow, newFilter, expandEntityReferences));
4155 if (document.registerElement) {
4156 var originalRegisterElement = document.registerElement;
4157 Document.prototype.registerElement = function(tagName, object) {
4158 var prototype, extendsOption;
4159 if (object !== undefined) {
4160 prototype = object.prototype;
4161 extendsOption = object.extends;
4163 if (!prototype) prototype = Object.create(HTMLElement.prototype);
4164 if (scope.nativePrototypeTable.get(prototype)) {
4165 throw new Error("NotSupportedError");
4167 var proto = Object.getPrototypeOf(prototype);
4168 var nativePrototype;
4169 var prototypes = [];
4171 nativePrototype = scope.nativePrototypeTable.get(proto);
4172 if (nativePrototype) break;
4173 prototypes.push(proto);
4174 proto = Object.getPrototypeOf(proto);
4176 if (!nativePrototype) {
4177 throw new Error("NotSupportedError");
4179 var newPrototype = Object.create(nativePrototype);
4180 for (var i = prototypes.length - 1; i >= 0; i--) {
4181 newPrototype = Object.create(newPrototype);
4183 [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
4184 var f = prototype[name];
4186 newPrototype[name] = function() {
4187 if (!(wrap(this) instanceof CustomElementConstructor)) {
4190 f.apply(wrap(this), arguments);
4194 prototype: newPrototype
4196 if (extendsOption) p.extends = extendsOption;
4197 function CustomElementConstructor(node) {
4199 if (extendsOption) {
4200 return document.createElement(extendsOption, tagName);
4202 return document.createElement(tagName);
4205 setWrapper(node, this);
4207 CustomElementConstructor.prototype = prototype;
4208 CustomElementConstructor.prototype.constructor = CustomElementConstructor;
4209 scope.constructorTable.set(newPrototype, CustomElementConstructor);
4210 scope.nativePrototypeTable.set(prototype, newPrototype);
4211 var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
4212 return CustomElementConstructor;
4214 forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
4216 forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
4217 forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
4218 forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "createTreeWalker", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
4219 mixin(Document.prototype, GetElementsByInterface);
4220 mixin(Document.prototype, ParentNodeInterface);
4221 mixin(Document.prototype, SelectorsInterface);
4222 mixin(Document.prototype, NonElementParentNodeInterface);
4223 mixin(Document.prototype, {
4224 get implementation() {
4225 var implementation = implementationTable.get(this);
4226 if (implementation) return implementation;
4227 implementation = new DOMImplementation(unwrap(this).implementation);
4228 implementationTable.set(this, implementation);
4229 return implementation;
4232 return wrap(unwrap(this).defaultView);
4235 registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
4236 if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
4237 wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
4238 function DOMImplementation(impl) {
4239 setWrapper(impl, this);
4241 var originalCreateDocument = document.implementation.createDocument;
4242 DOMImplementation.prototype.createDocument = function() {
4243 arguments[2] = unwrap(arguments[2]);
4244 return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));
4246 function wrapImplMethod(constructor, name) {
4247 var original = document.implementation[name];
4248 constructor.prototype[name] = function() {
4249 return wrap(original.apply(unsafeUnwrap(this), arguments));
4252 function forwardImplMethod(constructor, name) {
4253 var original = document.implementation[name];
4254 constructor.prototype[name] = function() {
4255 return original.apply(unsafeUnwrap(this), arguments);
4258 wrapImplMethod(DOMImplementation, "createDocumentType");
4259 wrapImplMethod(DOMImplementation, "createHTMLDocument");
4260 forwardImplMethod(DOMImplementation, "hasFeature");
4261 registerWrapper(window.DOMImplementation, DOMImplementation);
4262 forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocument", "createDocumentType", "createHTMLDocument", "hasFeature" ]);
4263 scope.adoptNodeNoRemove = adoptNodeNoRemove;
4264 scope.wrappers.DOMImplementation = DOMImplementation;
4265 scope.wrappers.Document = Document;
4266 })(window.ShadowDOMPolyfill);
4269 var EventTarget = scope.wrappers.EventTarget;
4270 var Selection = scope.wrappers.Selection;
4271 var mixin = scope.mixin;
4272 var registerWrapper = scope.registerWrapper;
4273 var renderAllPending = scope.renderAllPending;
4274 var unwrap = scope.unwrap;
4275 var unwrapIfNeeded = scope.unwrapIfNeeded;
4276 var wrap = scope.wrap;
4277 var OriginalWindow = window.Window;
4278 var originalGetComputedStyle = window.getComputedStyle;
4279 var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
4280 var originalGetSelection = window.getSelection;
4281 function Window(impl) {
4282 EventTarget.call(this, impl);
4284 Window.prototype = Object.create(EventTarget.prototype);
4285 OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
4286 return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
4288 if (originalGetDefaultComputedStyle) {
4289 OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
4290 return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
4293 OriginalWindow.prototype.getSelection = function() {
4294 return wrap(this || window).getSelection();
4296 delete window.getComputedStyle;
4297 delete window.getDefaultComputedStyle;
4298 delete window.getSelection;
4299 [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
4300 OriginalWindow.prototype[name] = function() {
4301 var w = wrap(this || window);
4302 return w[name].apply(w, arguments);
4304 delete window[name];
4306 mixin(Window.prototype, {
4307 getComputedStyle: function(el, pseudo) {
4309 return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
4311 getSelection: function() {
4313 return new Selection(originalGetSelection.call(unwrap(this)));
4316 return wrap(unwrap(this).document);
4319 if (originalGetDefaultComputedStyle) {
4320 Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
4322 return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
4325 registerWrapper(OriginalWindow, Window, window);
4326 scope.wrappers.Window = Window;
4327 })(window.ShadowDOMPolyfill);
4330 var unwrap = scope.unwrap;
4331 var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
4332 var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
4333 if (OriginalDataTransferSetDragImage) {
4334 OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
4335 OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
4338 })(window.ShadowDOMPolyfill);
4341 var registerWrapper = scope.registerWrapper;
4342 var setWrapper = scope.setWrapper;
4343 var unwrap = scope.unwrap;
4344 var OriginalFormData = window.FormData;
4345 if (!OriginalFormData) return;
4346 function FormData(formElement) {
4348 if (formElement instanceof OriginalFormData) {
4351 impl = new OriginalFormData(formElement && unwrap(formElement));
4353 setWrapper(impl, this);
4355 registerWrapper(OriginalFormData, FormData, new OriginalFormData());
4356 scope.wrappers.FormData = FormData;
4357 })(window.ShadowDOMPolyfill);
4360 var unwrapIfNeeded = scope.unwrapIfNeeded;
4361 var originalSend = XMLHttpRequest.prototype.send;
4362 XMLHttpRequest.prototype.send = function(obj) {
4363 return originalSend.call(this, unwrapIfNeeded(obj));
4365 })(window.ShadowDOMPolyfill);
4368 var isWrapperFor = scope.isWrapperFor;
4370 a: "HTMLAnchorElement",
4371 area: "HTMLAreaElement",
4372 audio: "HTMLAudioElement",
4373 base: "HTMLBaseElement",
4374 body: "HTMLBodyElement",
4375 br: "HTMLBRElement",
4376 button: "HTMLButtonElement",
4377 canvas: "HTMLCanvasElement",
4378 caption: "HTMLTableCaptionElement",
4379 col: "HTMLTableColElement",
4380 content: "HTMLContentElement",
4381 data: "HTMLDataElement",
4382 datalist: "HTMLDataListElement",
4383 del: "HTMLModElement",
4384 dir: "HTMLDirectoryElement",
4385 div: "HTMLDivElement",
4386 dl: "HTMLDListElement",
4387 embed: "HTMLEmbedElement",
4388 fieldset: "HTMLFieldSetElement",
4389 font: "HTMLFontElement",
4390 form: "HTMLFormElement",
4391 frame: "HTMLFrameElement",
4392 frameset: "HTMLFrameSetElement",
4393 h1: "HTMLHeadingElement",
4394 head: "HTMLHeadElement",
4395 hr: "HTMLHRElement",
4396 html: "HTMLHtmlElement",
4397 iframe: "HTMLIFrameElement",
4398 img: "HTMLImageElement",
4399 input: "HTMLInputElement",
4400 keygen: "HTMLKeygenElement",
4401 label: "HTMLLabelElement",
4402 legend: "HTMLLegendElement",
4403 li: "HTMLLIElement",
4404 link: "HTMLLinkElement",
4405 map: "HTMLMapElement",
4406 marquee: "HTMLMarqueeElement",
4407 menu: "HTMLMenuElement",
4408 menuitem: "HTMLMenuItemElement",
4409 meta: "HTMLMetaElement",
4410 meter: "HTMLMeterElement",
4411 object: "HTMLObjectElement",
4412 ol: "HTMLOListElement",
4413 optgroup: "HTMLOptGroupElement",
4414 option: "HTMLOptionElement",
4415 output: "HTMLOutputElement",
4416 p: "HTMLParagraphElement",
4417 param: "HTMLParamElement",
4418 pre: "HTMLPreElement",
4419 progress: "HTMLProgressElement",
4420 q: "HTMLQuoteElement",
4421 script: "HTMLScriptElement",
4422 select: "HTMLSelectElement",
4423 shadow: "HTMLShadowElement",
4424 source: "HTMLSourceElement",
4425 span: "HTMLSpanElement",
4426 style: "HTMLStyleElement",
4427 table: "HTMLTableElement",
4428 tbody: "HTMLTableSectionElement",
4429 template: "HTMLTemplateElement",
4430 textarea: "HTMLTextAreaElement",
4431 thead: "HTMLTableSectionElement",
4432 time: "HTMLTimeElement",
4433 title: "HTMLTitleElement",
4434 tr: "HTMLTableRowElement",
4435 track: "HTMLTrackElement",
4436 ul: "HTMLUListElement",
4437 video: "HTMLVideoElement"
4439 function overrideConstructor(tagName) {
4440 var nativeConstructorName = elements[tagName];
4441 var nativeConstructor = window[nativeConstructorName];
4442 if (!nativeConstructor) return;
4443 var element = document.createElement(tagName);
4444 var wrapperConstructor = element.constructor;
4445 window[nativeConstructorName] = wrapperConstructor;
4447 Object.keys(elements).forEach(overrideConstructor);
4448 Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
4449 window[name] = scope.wrappers[name];
4451 })(window.ShadowDOMPolyfill);
4454 strictStyling: false,
4456 shimStyling: function(root, name, extendsName) {
4457 var scopeStyles = this.prepareRoot(root, name, extendsName);
4458 var typeExtension = this.isTypeExtension(extendsName);
4459 var scopeSelector = this.makeScopeSelector(name, typeExtension);
4460 var cssText = stylesToCssText(scopeStyles, true);
4461 cssText = this.scopeCssText(cssText, scopeSelector);
4463 root.shimmedStyle = cssText;
4465 this.addCssToDocument(cssText, name);
4467 shimStyle: function(style, selector) {
4468 return this.shimCssText(style.textContent, selector);
4470 shimCssText: function(cssText, selector) {
4471 cssText = this.insertDirectives(cssText);
4472 return this.scopeCssText(cssText, selector);
4474 makeScopeSelector: function(name, typeExtension) {
4476 return typeExtension ? "[is=" + name + "]" : name;
4480 isTypeExtension: function(extendsName) {
4481 return extendsName && extendsName.indexOf("-") < 0;
4483 prepareRoot: function(root, name, extendsName) {
4484 var def = this.registerRoot(root, name, extendsName);
4485 this.replaceTextInStyles(def.rootStyles, this.insertDirectives);
4486 this.removeStyles(root, def.rootStyles);
4487 if (this.strictStyling) {
4488 this.applyScopeToContent(root, name);
4490 return def.scopeStyles;
4492 removeStyles: function(root, styles) {
4493 for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
4494 s.parentNode.removeChild(s);
4497 registerRoot: function(root, name, extendsName) {
4498 var def = this.registry[name] = {
4501 extendsName: extendsName
4503 var styles = this.findStyles(root);
4504 def.rootStyles = styles;
4505 def.scopeStyles = def.rootStyles;
4506 var extendee = this.registry[def.extendsName];
4508 def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
4512 findStyles: function(root) {
4516 var styles = root.querySelectorAll("style");
4517 return Array.prototype.filter.call(styles, function(s) {
4518 return !s.hasAttribute(NO_SHIM_ATTRIBUTE);
4521 applyScopeToContent: function(root, name) {
4523 Array.prototype.forEach.call(root.querySelectorAll("*"), function(node) {
4524 node.setAttribute(name, "");
4526 Array.prototype.forEach.call(root.querySelectorAll("template"), function(template) {
4527 this.applyScopeToContent(template.content, name);
4531 insertDirectives: function(cssText) {
4532 cssText = this.insertPolyfillDirectivesInCssText(cssText);
4533 return this.insertPolyfillRulesInCssText(cssText);
4535 insertPolyfillDirectivesInCssText: function(cssText) {
4536 cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {
4537 return p1.slice(0, -2) + "{";
4539 return cssText.replace(cssContentNextSelectorRe, function(match, p1) {
4543 insertPolyfillRulesInCssText: function(cssText) {
4544 cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {
4545 return p1.slice(0, -1);
4547 return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {
4548 var rule = match.replace(p1, "").replace(p2, "");
4552 scopeCssText: function(cssText, scopeSelector) {
4553 var unscoped = this.extractUnscopedRulesFromCssText(cssText);
4554 cssText = this.insertPolyfillHostInCssText(cssText);
4555 cssText = this.convertColonHost(cssText);
4556 cssText = this.convertColonHostContext(cssText);
4557 cssText = this.convertShadowDOMSelectors(cssText);
4558 if (scopeSelector) {
4559 var self = this, cssText;
4560 withCssRules(cssText, function(rules) {
4561 cssText = self.scopeRules(rules, scopeSelector);
4564 cssText = cssText + "\n" + unscoped;
4565 return cssText.trim();
4567 extractUnscopedRulesFromCssText: function(cssText) {
4569 while (m = cssCommentUnscopedRuleRe.exec(cssText)) {
4570 r += m[1].slice(0, -1) + "\n\n";
4572 while (m = cssContentUnscopedRuleRe.exec(cssText)) {
4573 r += m[0].replace(m[2], "").replace(m[1], m[3]) + "\n\n";
4577 convertColonHost: function(cssText) {
4578 return this.convertColonRule(cssText, cssColonHostRe, this.colonHostPartReplacer);
4580 convertColonHostContext: function(cssText) {
4581 return this.convertColonRule(cssText, cssColonHostContextRe, this.colonHostContextPartReplacer);
4583 convertColonRule: function(cssText, regExp, partReplacer) {
4584 return cssText.replace(regExp, function(m, p1, p2, p3) {
4585 p1 = polyfillHostNoCombinator;
4587 var parts = p2.split(","), r = [];
4588 for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
4590 r.push(partReplacer(p1, p, p3));
4598 colonHostContextPartReplacer: function(host, part, suffix) {
4599 if (part.match(polyfillHost)) {
4600 return this.colonHostPartReplacer(host, part, suffix);
4602 return host + part + suffix + ", " + part + " " + host + suffix;
4605 colonHostPartReplacer: function(host, part, suffix) {
4606 return host + part.replace(polyfillHost, "") + suffix;
4608 convertShadowDOMSelectors: function(cssText) {
4609 for (var i = 0; i < shadowDOMSelectorsRe.length; i++) {
4610 cssText = cssText.replace(shadowDOMSelectorsRe[i], " ");
4614 scopeRules: function(cssRules, scopeSelector) {
4617 Array.prototype.forEach.call(cssRules, function(rule) {
4618 if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {
4619 cssText += this.scopeSelector(rule.selectorText, scopeSelector, this.strictStyling) + " {\n ";
4620 cssText += this.propertiesFromRule(rule) + "\n}\n\n";
4621 } else if (rule.type === CSSRule.MEDIA_RULE) {
4622 cssText += "@media " + rule.media.mediaText + " {\n";
4623 cssText += this.scopeRules(rule.cssRules, scopeSelector);
4624 cssText += "\n}\n\n";
4628 cssText += rule.cssText + "\n\n";
4631 if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {
4632 cssText += this.ieSafeCssTextFromKeyFrameRule(rule);
4640 ieSafeCssTextFromKeyFrameRule: function(rule) {
4641 var cssText = "@keyframes " + rule.name + " {";
4642 Array.prototype.forEach.call(rule.cssRules, function(rule) {
4643 cssText += " " + rule.keyText + " {" + rule.style.cssText + "}";
4648 scopeSelector: function(selector, scopeSelector, strict) {
4649 var r = [], parts = selector.split(",");
4650 parts.forEach(function(p) {
4652 if (this.selectorNeedsScoping(p, scopeSelector)) {
4653 p = strict && !p.match(polyfillHostNoCombinator) ? this.applyStrictSelectorScope(p, scopeSelector) : this.applySelectorScope(p, scopeSelector);
4657 return r.join(", ");
4659 selectorNeedsScoping: function(selector, scopeSelector) {
4660 if (Array.isArray(scopeSelector)) {
4663 var re = this.makeScopeMatcher(scopeSelector);
4664 return !selector.match(re);
4666 makeScopeMatcher: function(scopeSelector) {
4667 scopeSelector = scopeSelector.replace(/\[/g, "\\[").replace(/\]/g, "\\]");
4668 return new RegExp("^(" + scopeSelector + ")" + selectorReSuffix, "m");
4670 applySelectorScope: function(selector, selectorScope) {
4671 return Array.isArray(selectorScope) ? this.applySelectorScopeList(selector, selectorScope) : this.applySimpleSelectorScope(selector, selectorScope);
4673 applySelectorScopeList: function(selector, scopeSelectorList) {
4675 for (var i = 0, s; s = scopeSelectorList[i]; i++) {
4676 r.push(this.applySimpleSelectorScope(selector, s));
4678 return r.join(", ");
4680 applySimpleSelectorScope: function(selector, scopeSelector) {
4681 if (selector.match(polyfillHostRe)) {
4682 selector = selector.replace(polyfillHostNoCombinator, scopeSelector);
4683 return selector.replace(polyfillHostRe, scopeSelector + " ");
4685 return scopeSelector + " " + selector;
4688 applyStrictSelectorScope: function(selector, scopeSelector) {
4689 scopeSelector = scopeSelector.replace(/\[is=([^\]]*)\]/g, "$1");
4690 var splits = [ " ", ">", "+", "~" ], scoped = selector, attrName = "[" + scopeSelector + "]";
4691 splits.forEach(function(sep) {
4692 var parts = scoped.split(sep);
4693 scoped = parts.map(function(p) {
4694 var t = p.trim().replace(polyfillHostRe, "");
4695 if (t && splits.indexOf(t) < 0 && t.indexOf(attrName) < 0) {
4696 p = t.replace(/([^:]*)(:*)(.*)/, "$1" + attrName + "$2$3");
4703 insertPolyfillHostInCssText: function(selector) {
4704 return selector.replace(colonHostContextRe, polyfillHostContext).replace(colonHostRe, polyfillHost);
4706 propertiesFromRule: function(rule) {
4707 var cssText = rule.style.cssText;
4708 if (rule.style.content && !rule.style.content.match(/['"]+|attr/)) {
4709 cssText = cssText.replace(/content:[^;]*;/g, "content: '" + rule.style.content + "';");
4711 var style = rule.style;
4712 for (var i in style) {
4713 if (style[i] === "initial") {
4714 cssText += i + ": initial; ";
4719 replaceTextInStyles: function(styles, action) {
4720 if (styles && action) {
4721 if (!(styles instanceof Array)) {
4722 styles = [ styles ];
4724 Array.prototype.forEach.call(styles, function(s) {
4725 s.textContent = action.call(this, s.textContent);
4729 addCssToDocument: function(cssText, name) {
4730 if (cssText.match("@import")) {
4731 addOwnSheet(cssText, name);
4733 addCssToDocument(cssText);
4737 var selectorRe = /([^{]*)({[\s\S]*?})/gim, cssCommentRe = /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim, cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^\/*][^*]*\*+)*\/)([^{]*?){/gim, cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim, cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim, cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^\/*][^*]*\*+)*)\//gim, cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim, cssPseudoRe = /::(x-[^\s{,(]*)/gim, cssPartRe = /::part\(([^)]*)\)/gim, polyfillHost = "-shadowcsshost", polyfillHostContext = "-shadowcsscontext", parenSuffix = ")(?:\\((" + "(?:\\([^)(]*\\)|[^)(]*)+?" + ")\\))?([^,{]*)";
4738 var cssColonHostRe = new RegExp("(" + polyfillHost + parenSuffix, "gim"), cssColonHostContextRe = new RegExp("(" + polyfillHostContext + parenSuffix, "gim"), selectorReSuffix = "([>\\s~+[.,{:][\\s\\S]*)?$", colonHostRe = /\:host/gim, colonHostContextRe = /\:host-context/gim, polyfillHostNoCombinator = polyfillHost + "-no-combinator", polyfillHostRe = new RegExp(polyfillHost, "gim"), polyfillHostContextRe = new RegExp(polyfillHostContext, "gim"), shadowDOMSelectorsRe = [ />>>/g, /::shadow/g, /::content/g, /\/deep\//g, /\/shadow\//g, /\/shadow-deep\//g, /\^\^/g, /\^/g ];
4739 function stylesToCssText(styles, preserveComments) {
4741 Array.prototype.forEach.call(styles, function(s) {
4742 cssText += s.textContent + "\n\n";
4744 if (!preserveComments) {
4745 cssText = cssText.replace(cssCommentRe, "");
4749 function cssTextToStyle(cssText) {
4750 var style = document.createElement("style");
4751 style.textContent = cssText;
4754 function cssToRules(cssText) {
4755 var style = cssTextToStyle(cssText);
4756 document.head.appendChild(style);
4760 rules = style.sheet.cssRules;
4763 console.warn("sheet not found", style);
4765 style.parentNode.removeChild(style);
4768 var frame = document.createElement("iframe");
4769 frame.style.display = "none";
4770 function initFrame() {
4771 frame.initialized = true;
4772 document.body.appendChild(frame);
4773 var doc = frame.contentDocument;
4774 var base = doc.createElement("base");
4775 base.href = document.baseURI;
4776 doc.head.appendChild(base);
4778 function inFrame(fn) {
4779 if (!frame.initialized) {
4782 document.body.appendChild(frame);
4783 fn(frame.contentDocument);
4784 document.body.removeChild(frame);
4786 var isChrome = navigator.userAgent.match("Chrome");
4787 function withCssRules(cssText, callback) {
4792 if (cssText.match("@import") && isChrome) {
4793 var style = cssTextToStyle(cssText);
4794 inFrame(function(doc) {
4795 doc.head.appendChild(style.impl);
4796 rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
4800 rules = cssToRules(cssText);
4804 function rulesToCss(cssRules) {
4805 for (var i = 0, css = []; i < cssRules.length; i++) {
4806 css.push(cssRules[i].cssText);
4808 return css.join("\n\n");
4810 function addCssToDocument(cssText) {
4812 getSheet().appendChild(document.createTextNode(cssText));
4815 function addOwnSheet(cssText, name) {
4816 var style = cssTextToStyle(cssText);
4817 style.setAttribute(name, "");
4818 style.setAttribute(SHIMMED_ATTRIBUTE, "");
4819 document.head.appendChild(style);
4821 var SHIM_ATTRIBUTE = "shim-shadowdom";
4822 var SHIMMED_ATTRIBUTE = "shim-shadowdom-css";
4823 var NO_SHIM_ATTRIBUTE = "no-shim";
4825 function getSheet() {
4827 sheet = document.createElement("style");
4828 sheet.setAttribute(SHIMMED_ATTRIBUTE, "");
4829 sheet[SHIMMED_ATTRIBUTE] = true;
4833 if (window.ShadowDOMPolyfill) {
4834 addCssToDocument("style { display: none !important; }\n");
4835 var doc = ShadowDOMPolyfill.wrap(document);
4836 var head = doc.querySelector("head");
4837 head.insertBefore(getSheet(), head.childNodes[0]);
4838 document.addEventListener("DOMContentLoaded", function() {
4839 var urlResolver = scope.urlResolver;
4840 if (window.HTMLImports && !HTMLImports.useNative) {
4841 var SHIM_SHEET_SELECTOR = "link[rel=stylesheet]" + "[" + SHIM_ATTRIBUTE + "]";
4842 var SHIM_STYLE_SELECTOR = "style[" + SHIM_ATTRIBUTE + "]";
4843 HTMLImports.importer.documentPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
4844 HTMLImports.importer.importsPreloadSelectors += "," + SHIM_SHEET_SELECTOR;
4845 HTMLImports.parser.documentSelectors = [ HTMLImports.parser.documentSelectors, SHIM_SHEET_SELECTOR, SHIM_STYLE_SELECTOR ].join(",");
4846 var originalParseGeneric = HTMLImports.parser.parseGeneric;
4847 HTMLImports.parser.parseGeneric = function(elt) {
4848 if (elt[SHIMMED_ATTRIBUTE]) {
4851 var style = elt.__importElement || elt;
4852 if (!style.hasAttribute(SHIM_ATTRIBUTE)) {
4853 originalParseGeneric.call(this, elt);
4856 if (elt.__resource) {
4857 style = elt.ownerDocument.createElement("style");
4858 style.textContent = elt.__resource;
4860 HTMLImports.path.resolveUrlsInStyle(style, elt.href);
4861 style.textContent = ShadowCSS.shimStyle(style);
4862 style.removeAttribute(SHIM_ATTRIBUTE, "");
4863 style.setAttribute(SHIMMED_ATTRIBUTE, "");
4864 style[SHIMMED_ATTRIBUTE] = true;
4865 if (style.parentNode !== head) {
4866 if (elt.parentNode === head) {
4867 head.replaceChild(style, elt);
4869 this.addElementToDocument(style);
4872 style.__importParsed = true;
4873 this.markParsingComplete(elt);
4876 var hasResource = HTMLImports.parser.hasResource;
4877 HTMLImports.parser.hasResource = function(node) {
4878 if (node.localName === "link" && node.rel === "stylesheet" && node.hasAttribute(SHIM_ATTRIBUTE)) {
4879 return node.__resource;
4881 return hasResource.call(this, node);
4887 scope.ShadowCSS = ShadowCSS;
4888 })(window.WebComponents);
4892 if (window.ShadowDOMPolyfill) {
4893 window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
4894 window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
4896 window.wrap = window.unwrap = function(n) {
4900 })(window.WebComponents);
4904 var hasWorkingUrl = false;
4905 if (!scope.forceJURL) {
4907 var u = new URL("b", "http://a");
4908 u.pathname = "c%20d";
4909 hasWorkingUrl = u.href === "http://a/c%20d";
4912 if (hasWorkingUrl) return;
4913 var relative = Object.create(null);
4914 relative["ftp"] = 21;
4915 relative["file"] = 0;
4916 relative["gopher"] = 70;
4917 relative["http"] = 80;
4918 relative["https"] = 443;
4919 relative["ws"] = 80;
4920 relative["wss"] = 443;
4921 var relativePathDotMapping = Object.create(null);
4922 relativePathDotMapping["%2e"] = ".";
4923 relativePathDotMapping[".%2e"] = "..";
4924 relativePathDotMapping["%2e."] = "..";
4925 relativePathDotMapping["%2e%2e"] = "..";
4926 function isRelativeScheme(scheme) {
4927 return relative[scheme] !== undefined;
4929 function invalid() {
4931 this._isInvalid = true;
4933 function IDNAToASCII(h) {
4937 return h.toLowerCase();
4939 function percentEscape(c) {
4940 var unicode = c.charCodeAt(0);
4941 if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 63, 96 ].indexOf(unicode) == -1) {
4944 return encodeURIComponent(c);
4946 function percentEscapeQuery(c) {
4947 var unicode = c.charCodeAt(0);
4948 if (unicode > 32 && unicode < 127 && [ 34, 35, 60, 62, 96 ].indexOf(unicode) == -1) {
4951 return encodeURIComponent(c);
4953 var EOF = undefined, ALPHA = /[a-zA-Z]/, ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
4954 function parse(input, stateOverride, base) {
4955 function err(message) {
4956 errors.push(message);
4958 var state = stateOverride || "scheme start", cursor = 0, buffer = "", seenAt = false, seenBracket = false, errors = [];
4959 loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {
4960 var c = input[cursor];
4962 case "scheme start":
4963 if (c && ALPHA.test(c)) {
4964 buffer += c.toLowerCase();
4966 } else if (!stateOverride) {
4968 state = "no scheme";
4971 err("Invalid scheme.");
4977 if (c && ALPHANUMERIC.test(c)) {
4978 buffer += c.toLowerCase();
4979 } else if (":" == c) {
4980 this._scheme = buffer;
4982 if (stateOverride) {
4985 if (isRelativeScheme(this._scheme)) {
4986 this._isRelative = true;
4988 if ("file" == this._scheme) {
4990 } else if (this._isRelative && base && base._scheme == this._scheme) {
4991 state = "relative or authority";
4992 } else if (this._isRelative) {
4993 state = "authority first slash";
4995 state = "scheme data";
4997 } else if (!stateOverride) {
5000 state = "no scheme";
5002 } else if (EOF == c) {
5005 err("Code point not allowed in scheme: " + c);
5014 } else if ("#" == c) {
5015 this._fragment = "#";
5018 if (EOF != c && " " != c && "\n" != c && "\r" != c) {
5019 this._schemeData += percentEscape(c);
5025 if (!base || !isRelativeScheme(base._scheme)) {
5026 err("Missing scheme.");
5034 case "relative or authority":
5035 if ("/" == c && "/" == input[cursor + 1]) {
5036 state = "authority ignore slashes";
5038 err("Expected /, got: " + c);
5045 this._isRelative = true;
5046 if ("file" != this._scheme) this._scheme = base._scheme;
5048 this._host = base._host;
5049 this._port = base._port;
5050 this._path = base._path.slice();
5051 this._query = base._query;
5052 this._username = base._username;
5053 this._password = base._password;
5055 } else if ("/" == c || "\\" == c) {
5056 if ("\\" == c) err("\\ is an invalid code point.");
5057 state = "relative slash";
5058 } else if ("?" == c) {
5059 this._host = base._host;
5060 this._port = base._port;
5061 this._path = base._path.slice();
5063 this._username = base._username;
5064 this._password = base._password;
5066 } else if ("#" == c) {
5067 this._host = base._host;
5068 this._port = base._port;
5069 this._path = base._path.slice();
5070 this._query = base._query;
5071 this._fragment = "#";
5072 this._username = base._username;
5073 this._password = base._password;
5076 var nextC = input[cursor + 1];
5077 var nextNextC = input[cursor + 2];
5078 if ("file" != this._scheme || !ALPHA.test(c) || nextC != ":" && nextC != "|" || EOF != nextNextC && "/" != nextNextC && "\\" != nextNextC && "?" != nextNextC && "#" != nextNextC) {
5079 this._host = base._host;
5080 this._port = base._port;
5081 this._username = base._username;
5082 this._password = base._password;
5083 this._path = base._path.slice();
5086 state = "relative path";
5091 case "relative slash":
5092 if ("/" == c || "\\" == c) {
5094 err("\\ is an invalid code point.");
5096 if ("file" == this._scheme) {
5097 state = "file host";
5099 state = "authority ignore slashes";
5102 if ("file" != this._scheme) {
5103 this._host = base._host;
5104 this._port = base._port;
5105 this._username = base._username;
5106 this._password = base._password;
5108 state = "relative path";
5113 case "authority first slash":
5115 state = "authority second slash";
5117 err("Expected '/', got: " + c);
5118 state = "authority ignore slashes";
5123 case "authority second slash":
5124 state = "authority ignore slashes";
5126 err("Expected '/', got: " + c);
5131 case "authority ignore slashes":
5132 if ("/" != c && "\\" != c) {
5133 state = "authority";
5136 err("Expected authority, got: " + c);
5143 err("@ already seen.");
5147 for (var i = 0; i < buffer.length; i++) {
5149 if (" " == cp || "\n" == cp || "\r" == cp) {
5150 err("Invalid whitespace in authority.");
5153 if (":" == cp && null === this._password) {
5154 this._password = "";
5157 var tempC = percentEscape(cp);
5158 null !== this._password ? this._password += tempC : this._username += tempC;
5161 } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
5162 cursor -= buffer.length;
5172 if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
5173 if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ":" || buffer[1] == "|")) {
5174 state = "relative path";
5175 } else if (buffer.length == 0) {
5176 state = "relative path start";
5178 this._host = IDNAToASCII.call(this, buffer);
5180 state = "relative path start";
5183 } else if (" " == c || "\n" == c || "\r" == c) {
5184 err("Invalid whitespace in file host.");
5192 if (":" == c && !seenBracket) {
5193 this._host = IDNAToASCII.call(this, buffer);
5196 if ("hostname" == stateOverride) {
5199 } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c) {
5200 this._host = IDNAToASCII.call(this, buffer);
5202 state = "relative path start";
5203 if (stateOverride) {
5207 } else if (" " != c && "\n" != c && "\r" != c) {
5210 } else if ("]" == c) {
5211 seenBracket = false;
5215 err("Invalid code point in host/hostname: " + c);
5220 if (/[0-9]/.test(c)) {
5222 } else if (EOF == c || "/" == c || "\\" == c || "?" == c || "#" == c || stateOverride) {
5224 var temp = parseInt(buffer, 10);
5225 if (temp != relative[this._scheme]) {
5226 this._port = temp + "";
5230 if (stateOverride) {
5233 state = "relative path start";
5235 } else if (" " == c || "\n" == c || "\r" == c) {
5236 err("Invalid code point in port: " + c);
5242 case "relative path start":
5243 if ("\\" == c) err("'\\' not allowed in path.");
5244 state = "relative path";
5245 if ("/" != c && "\\" != c) {
5250 case "relative path":
5251 if (EOF == c || "/" == c || "\\" == c || !stateOverride && ("?" == c || "#" == c)) {
5253 err("\\ not allowed in relative path.");
5256 if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {
5259 if (".." == buffer) {
5261 if ("/" != c && "\\" != c) {
5262 this._path.push("");
5264 } else if ("." == buffer && "/" != c && "\\" != c) {
5265 this._path.push("");
5266 } else if ("." != buffer) {
5267 if ("file" == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == "|") {
5268 buffer = buffer[0] + ":";
5270 this._path.push(buffer);
5276 } else if ("#" == c) {
5277 this._fragment = "#";
5280 } else if (" " != c && "\n" != c && "\r" != c) {
5281 buffer += percentEscape(c);
5286 if (!stateOverride && "#" == c) {
5287 this._fragment = "#";
5289 } else if (EOF != c && " " != c && "\n" != c && "\r" != c) {
5290 this._query += percentEscapeQuery(c);
5295 if (EOF != c && " " != c && "\n" != c && "\r" != c) {
5296 this._fragment += c;
5305 this._schemeData = "";
5306 this._username = "";
5307 this._password = null;
5312 this._fragment = "";
5313 this._isInvalid = false;
5314 this._isRelative = false;
5316 function jURL(url, base) {
5317 if (base !== undefined && !(base instanceof jURL)) base = new jURL(String(base));
5320 var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, "");
5321 parse.call(this, input, null, base);
5324 toString: function() {
5328 if (this._isInvalid) return this._url;
5330 if ("" != this._username || null != this._password) {
5331 authority = this._username + (null != this._password ? ":" + this._password : "") + "@";
5333 return this.protocol + (this._isRelative ? "//" + authority + this.host : "") + this.pathname + this._query + this._fragment;
5337 parse.call(this, href);
5340 return this._scheme + ":";
5342 set protocol(protocol) {
5343 if (this._isInvalid) return;
5344 parse.call(this, protocol + ":", "scheme start");
5347 return this._isInvalid ? "" : this._port ? this._host + ":" + this._port : this._host;
5350 if (this._isInvalid || !this._isRelative) return;
5351 parse.call(this, host, "host");
5356 set hostname(hostname) {
5357 if (this._isInvalid || !this._isRelative) return;
5358 parse.call(this, hostname, "hostname");
5364 if (this._isInvalid || !this._isRelative) return;
5365 parse.call(this, port, "port");
5368 return this._isInvalid ? "" : this._isRelative ? "/" + this._path.join("/") : this._schemeData;
5370 set pathname(pathname) {
5371 if (this._isInvalid || !this._isRelative) return;
5373 parse.call(this, pathname, "relative path start");
5376 return this._isInvalid || !this._query || "?" == this._query ? "" : this._query;
5378 set search(search) {
5379 if (this._isInvalid || !this._isRelative) return;
5381 if ("?" == search[0]) search = search.slice(1);
5382 parse.call(this, search, "query");
5385 return this._isInvalid || !this._fragment || "#" == this._fragment ? "" : this._fragment;
5388 if (this._isInvalid) return;
5389 this._fragment = "#";
5390 if ("#" == hash[0]) hash = hash.slice(1);
5391 parse.call(this, hash, "fragment");
5395 if (this._isInvalid || !this._scheme) {
5398 switch (this._scheme) {
5409 return this._scheme + "://" + host;
5412 var OriginalURL = scope.URL;
5414 jURL.createObjectURL = function(blob) {
5415 return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
5417 jURL.revokeObjectURL = function(url) {
5418 OriginalURL.revokeObjectURL(url);
5425 if (global.JsMutationObserver) {
5428 var registrationsTable = new WeakMap();
5430 if (/Trident|Edge/.test(navigator.userAgent)) {
5431 setImmediate = setTimeout;
5432 } else if (window.setImmediate) {
5433 setImmediate = window.setImmediate;
5435 var setImmediateQueue = [];
5436 var sentinel = String(Math.random());
5437 window.addEventListener("message", function(e) {
5438 if (e.data === sentinel) {
5439 var queue = setImmediateQueue;
5440 setImmediateQueue = [];
5441 queue.forEach(function(func) {
5446 setImmediate = function(func) {
5447 setImmediateQueue.push(func);
5448 window.postMessage(sentinel, "*");
5451 var isScheduled = false;
5452 var scheduledObservers = [];
5453 function scheduleCallback(observer) {
5454 scheduledObservers.push(observer);
5457 setImmediate(dispatchCallbacks);
5460 function wrapIfNeeded(node) {
5461 return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node;
5463 function dispatchCallbacks() {
5464 isScheduled = false;
5465 var observers = scheduledObservers;
5466 scheduledObservers = [];
5467 observers.sort(function(o1, o2) {
5468 return o1.uid_ - o2.uid_;
5470 var anyNonEmpty = false;
5471 observers.forEach(function(observer) {
5472 var queue = observer.takeRecords();
5473 removeTransientObserversFor(observer);
5475 observer.callback_(queue, observer);
5479 if (anyNonEmpty) dispatchCallbacks();
5481 function removeTransientObserversFor(observer) {
5482 observer.nodes_.forEach(function(node) {
5483 var registrations = registrationsTable.get(node);
5484 if (!registrations) return;
5485 registrations.forEach(function(registration) {
5486 if (registration.observer === observer) registration.removeTransientObservers();
5490 function forEachAncestorAndObserverEnqueueRecord(target, callback) {
5491 for (var node = target; node; node = node.parentNode) {
5492 var registrations = registrationsTable.get(node);
5493 if (registrations) {
5494 for (var j = 0; j < registrations.length; j++) {
5495 var registration = registrations[j];
5496 var options = registration.options;
5497 if (node !== target && !options.subtree) continue;
5498 var record = callback(options);
5499 if (record) registration.enqueue(record);
5505 function JsMutationObserver(callback) {
5506 this.callback_ = callback;
5509 this.uid_ = ++uidCounter;
5511 JsMutationObserver.prototype = {
5512 observe: function(target, options) {
5513 target = wrapIfNeeded(target);
5514 if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) {
5515 throw new SyntaxError();
5517 var registrations = registrationsTable.get(target);
5518 if (!registrations) registrationsTable.set(target, registrations = []);
5520 for (var i = 0; i < registrations.length; i++) {
5521 if (registrations[i].observer === this) {
5522 registration = registrations[i];
5523 registration.removeListeners();
5524 registration.options = options;
5528 if (!registration) {
5529 registration = new Registration(this, target, options);
5530 registrations.push(registration);
5531 this.nodes_.push(target);
5533 registration.addListeners();
5535 disconnect: function() {
5536 this.nodes_.forEach(function(node) {
5537 var registrations = registrationsTable.get(node);
5538 for (var i = 0; i < registrations.length; i++) {
5539 var registration = registrations[i];
5540 if (registration.observer === this) {
5541 registration.removeListeners();
5542 registrations.splice(i, 1);
5549 takeRecords: function() {
5550 var copyOfRecords = this.records_;
5552 return copyOfRecords;
5555 function MutationRecord(type, target) {
5557 this.target = target;
5558 this.addedNodes = [];
5559 this.removedNodes = [];
5560 this.previousSibling = null;
5561 this.nextSibling = null;
5562 this.attributeName = null;
5563 this.attributeNamespace = null;
5564 this.oldValue = null;
5566 function copyMutationRecord(original) {
5567 var record = new MutationRecord(original.type, original.target);
5568 record.addedNodes = original.addedNodes.slice();
5569 record.removedNodes = original.removedNodes.slice();
5570 record.previousSibling = original.previousSibling;
5571 record.nextSibling = original.nextSibling;
5572 record.attributeName = original.attributeName;
5573 record.attributeNamespace = original.attributeNamespace;
5574 record.oldValue = original.oldValue;
5577 var currentRecord, recordWithOldValue;
5578 function getRecord(type, target) {
5579 return currentRecord = new MutationRecord(type, target);
5581 function getRecordWithOldValue(oldValue) {
5582 if (recordWithOldValue) return recordWithOldValue;
5583 recordWithOldValue = copyMutationRecord(currentRecord);
5584 recordWithOldValue.oldValue = oldValue;
5585 return recordWithOldValue;
5587 function clearRecords() {
5588 currentRecord = recordWithOldValue = undefined;
5590 function recordRepresentsCurrentMutation(record) {
5591 return record === recordWithOldValue || record === currentRecord;
5593 function selectRecord(lastRecord, newRecord) {
5594 if (lastRecord === newRecord) return lastRecord;
5595 if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue;
5598 function Registration(observer, target, options) {
5599 this.observer = observer;
5600 this.target = target;
5601 this.options = options;
5602 this.transientObservedNodes = [];
5604 Registration.prototype = {
5605 enqueue: function(record) {
5606 var records = this.observer.records_;
5607 var length = records.length;
5608 if (records.length > 0) {
5609 var lastRecord = records[length - 1];
5610 var recordToReplaceLast = selectRecord(lastRecord, record);
5611 if (recordToReplaceLast) {
5612 records[length - 1] = recordToReplaceLast;
5616 scheduleCallback(this.observer);
5618 records[length] = record;
5620 addListeners: function() {
5621 this.addListeners_(this.target);
5623 addListeners_: function(node) {
5624 var options = this.options;
5625 if (options.attributes) node.addEventListener("DOMAttrModified", this, true);
5626 if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true);
5627 if (options.childList) node.addEventListener("DOMNodeInserted", this, true);
5628 if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true);
5630 removeListeners: function() {
5631 this.removeListeners_(this.target);
5633 removeListeners_: function(node) {
5634 var options = this.options;
5635 if (options.attributes) node.removeEventListener("DOMAttrModified", this, true);
5636 if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true);
5637 if (options.childList) node.removeEventListener("DOMNodeInserted", this, true);
5638 if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true);
5640 addTransientObserver: function(node) {
5641 if (node === this.target) return;
5642 this.addListeners_(node);
5643 this.transientObservedNodes.push(node);
5644 var registrations = registrationsTable.get(node);
5645 if (!registrations) registrationsTable.set(node, registrations = []);
5646 registrations.push(this);
5648 removeTransientObservers: function() {
5649 var transientObservedNodes = this.transientObservedNodes;
5650 this.transientObservedNodes = [];
5651 transientObservedNodes.forEach(function(node) {
5652 this.removeListeners_(node);
5653 var registrations = registrationsTable.get(node);
5654 for (var i = 0; i < registrations.length; i++) {
5655 if (registrations[i] === this) {
5656 registrations.splice(i, 1);
5662 handleEvent: function(e) {
5663 e.stopImmediatePropagation();
5665 case "DOMAttrModified":
5666 var name = e.attrName;
5667 var namespace = e.relatedNode.namespaceURI;
5668 var target = e.target;
5669 var record = new getRecord("attributes", target);
5670 record.attributeName = name;
5671 record.attributeNamespace = namespace;
5672 var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
5673 forEachAncestorAndObserverEnqueueRecord(target, function(options) {
5674 if (!options.attributes) return;
5675 if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) {
5678 if (options.attributeOldValue) return getRecordWithOldValue(oldValue);
5683 case "DOMCharacterDataModified":
5684 var target = e.target;
5685 var record = getRecord("characterData", target);
5686 var oldValue = e.prevValue;
5687 forEachAncestorAndObserverEnqueueRecord(target, function(options) {
5688 if (!options.characterData) return;
5689 if (options.characterDataOldValue) return getRecordWithOldValue(oldValue);
5694 case "DOMNodeRemoved":
5695 this.addTransientObserver(e.target);
5697 case "DOMNodeInserted":
5698 var changedNode = e.target;
5699 var addedNodes, removedNodes;
5700 if (e.type === "DOMNodeInserted") {
5701 addedNodes = [ changedNode ];
5705 removedNodes = [ changedNode ];
5707 var previousSibling = changedNode.previousSibling;
5708 var nextSibling = changedNode.nextSibling;
5709 var record = getRecord("childList", e.target.parentNode);
5710 record.addedNodes = addedNodes;
5711 record.removedNodes = removedNodes;
5712 record.previousSibling = previousSibling;
5713 record.nextSibling = nextSibling;
5714 forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
5715 if (!options.childList) return;
5722 global.JsMutationObserver = JsMutationObserver;
5723 if (!global.MutationObserver) {
5724 global.MutationObserver = JsMutationObserver;
5725 JsMutationObserver._isPolyfilled = true;
5731 if (!window.performance) {
5732 var start = Date.now();
5733 window.performance = {
5735 return Date.now() - start;
5739 if (!window.requestAnimationFrame) {
5740 window.requestAnimationFrame = function() {
5741 var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
5742 return nativeRaf ? function(callback) {
5743 return nativeRaf(function() {
5744 callback(performance.now());
5746 } : function(callback) {
5747 return window.setTimeout(callback, 1e3 / 60);
5751 if (!window.cancelAnimationFrame) {
5752 window.cancelAnimationFrame = function() {
5753 return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) {
5758 var workingDefaultPrevented = function() {
5759 var e = document.createEvent("Event");
5760 e.initEvent("foo", true, true);
5762 return e.defaultPrevented;
5764 if (!workingDefaultPrevented) {
5765 var origPreventDefault = Event.prototype.preventDefault;
5766 Event.prototype.preventDefault = function() {
5767 if (!this.cancelable) {
5770 origPreventDefault.call(this);
5771 Object.defineProperty(this, "defaultPrevented", {
5779 var isIE = /Trident/.test(navigator.userAgent);
5780 if (!window.CustomEvent || isIE && typeof window.CustomEvent !== "function") {
5781 window.CustomEvent = function(inType, params) {
5782 params = params || {};
5783 var e = document.createEvent("CustomEvent");
5784 e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
5787 window.CustomEvent.prototype = window.Event.prototype;
5789 if (!window.Event || isIE && typeof window.Event !== "function") {
5790 var origEvent = window.Event;
5791 window.Event = function(inType, params) {
5792 params = params || {};
5793 var e = document.createEvent("Event");
5794 e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable));
5797 window.Event.prototype = origEvent.prototype;
5799 })(window.WebComponents);
5801 window.HTMLImports = window.HTMLImports || {
5806 var IMPORT_LINK_TYPE = "import";
5807 var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement("link"));
5808 var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
5809 var wrap = function(node) {
5810 return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;
5812 var rootDocument = wrap(document);
5813 var currentScriptDescriptor = {
5815 var script = window.HTMLImports.currentScript || document.currentScript || (document.readyState !== "complete" ? document.scripts[document.scripts.length - 1] : null);
5816 return wrap(script);
5820 Object.defineProperty(document, "_currentScript", currentScriptDescriptor);
5821 Object.defineProperty(rootDocument, "_currentScript", currentScriptDescriptor);
5822 var isIE = /Trident/.test(navigator.userAgent);
5823 function whenReady(callback, doc) {
5824 doc = doc || rootDocument;
5825 whenDocumentReady(function() {
5826 watchImportsLoad(callback, doc);
5829 var requiredReadyState = isIE ? "complete" : "interactive";
5830 var READY_EVENT = "readystatechange";
5831 function isDocumentReady(doc) {
5832 return doc.readyState === "complete" || doc.readyState === requiredReadyState;
5834 function whenDocumentReady(callback, doc) {
5835 if (!isDocumentReady(doc)) {
5836 var checkReady = function() {
5837 if (doc.readyState === "complete" || doc.readyState === requiredReadyState) {
5838 doc.removeEventListener(READY_EVENT, checkReady);
5839 whenDocumentReady(callback, doc);
5842 doc.addEventListener(READY_EVENT, checkReady);
5843 } else if (callback) {
5847 function markTargetLoaded(event) {
5848 event.target.__loaded = true;
5850 function watchImportsLoad(callback, doc) {
5851 var imports = doc.querySelectorAll("link[rel=import]");
5852 var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];
5853 function checkDone() {
5854 if (parsedCount == importCount && callback) {
5856 allImports: imports,
5857 loadedImports: newImports,
5858 errorImports: errorImports
5862 function loadedImport(e) {
5863 markTargetLoaded(e);
5864 newImports.push(this);
5868 function errorLoadingImport(e) {
5869 errorImports.push(this);
5874 for (var i = 0, imp; i < importCount && (imp = imports[i]); i++) {
5875 if (isImportLoaded(imp)) {
5879 imp.addEventListener("load", loadedImport);
5880 imp.addEventListener("error", errorLoadingImport);
5887 function isImportLoaded(link) {
5888 return useNative ? link.__loaded || link.import && link.import.readyState !== "loading" : link.__importParsed;
5891 new MutationObserver(function(mxns) {
5892 for (var i = 0, l = mxns.length, m; i < l && (m = mxns[i]); i++) {
5894 handleImports(m.addedNodes);
5897 }).observe(document.head, {
5900 function handleImports(nodes) {
5901 for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
5907 function isImport(element) {
5908 return element.localName === "link" && element.rel === "import";
5910 function handleImport(element) {
5911 var loaded = element.import;
5917 element.addEventListener("load", markTargetLoaded);
5918 element.addEventListener("error", markTargetLoaded);
5922 if (document.readyState === "loading") {
5923 var imports = document.querySelectorAll("link[rel=import]");
5924 for (var i = 0, l = imports.length, imp; i < l && (imp = imports[i]); i++) {
5930 whenReady(function(detail) {
5931 window.HTMLImports.ready = true;
5932 window.HTMLImports.readyTime = new Date().getTime();
5933 var evt = rootDocument.createEvent("CustomEvent");
5934 evt.initCustomEvent("HTMLImportsLoaded", true, true, detail);
5935 rootDocument.dispatchEvent(evt);
5937 scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
5938 scope.useNative = useNative;
5939 scope.rootDocument = rootDocument;
5940 scope.whenReady = whenReady;
5942 })(window.HTMLImports);
5946 var addModule = function(module) {
5947 modules.push(module);
5949 var initializeModules = function() {
5950 modules.forEach(function(module) {
5954 scope.addModule = addModule;
5955 scope.initializeModules = initializeModules;
5956 })(window.HTMLImports);
5958 window.HTMLImports.addModule(function(scope) {
5959 var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
5960 var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
5962 resolveUrlsInStyle: function(style, linkUrl) {
5963 var doc = style.ownerDocument;
5964 var resolver = doc.createElement("a");
5965 style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);
5968 resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {
5969 var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);
5970 r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);
5973 replaceUrls: function(text, urlObj, linkUrl, regexp) {
5974 return text.replace(regexp, function(m, pre, url, post) {
5975 var urlPath = url.replace(/["']/g, "");
5977 urlPath = new URL(urlPath, linkUrl).href;
5979 urlObj.href = urlPath;
5980 urlPath = urlObj.href;
5981 return pre + "'" + urlPath + "'" + post;
5988 window.HTMLImports.addModule(function(scope) {
5991 ok: function(request) {
5992 return request.status >= 200 && request.status < 300 || request.status === 304 || request.status === 0;
5994 load: function(url, next, nextContext) {
5995 var request = new XMLHttpRequest();
5996 if (scope.flags.debug || scope.flags.bust) {
5997 url += "?" + Math.random();
5999 request.open("GET", url, xhr.async);
6000 request.addEventListener("readystatechange", function(e) {
6001 if (request.readyState === 4) {
6002 var redirectedUrl = null;
6004 var locationHeader = request.getResponseHeader("Location");
6005 if (locationHeader) {
6006 redirectedUrl = locationHeader.substr(0, 1) === "/" ? location.origin + locationHeader : locationHeader;
6009 console.error(e.message);
6011 next.call(nextContext, !xhr.ok(request) && request, request.response || request.responseText, redirectedUrl);
6017 loadDocument: function(url, next, nextContext) {
6018 this.load(url, next, nextContext).responseType = "document";
6024 window.HTMLImports.addModule(function(scope) {
6025 var xhr = scope.xhr;
6026 var flags = scope.flags;
6027 var Loader = function(onLoad, onComplete) {
6029 this.onload = onLoad;
6030 this.oncomplete = onComplete;
6034 Loader.prototype = {
6035 addNodes: function(nodes) {
6036 this.inflight += nodes.length;
6037 for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
6042 addNode: function(node) {
6047 require: function(elt) {
6048 var url = elt.src || elt.href;
6049 elt.__nodeUrl = url;
6050 if (!this.dedupe(url, elt)) {
6051 this.fetch(url, elt);
6054 dedupe: function(url, elt) {
6055 if (this.pending[url]) {
6056 this.pending[url].push(elt);
6060 if (this.cache[url]) {
6061 this.onload(url, elt, this.cache[url]);
6065 this.pending[url] = [ elt ];
6068 fetch: function(url, elt) {
6069 flags.load && console.log("fetch", url, elt);
6071 setTimeout(function() {
6072 this.receive(url, elt, {
6073 error: "href must be specified"
6076 } else if (url.match(/^data:/)) {
6077 var pieces = url.split(",");
6078 var header = pieces[0];
6079 var body = pieces[1];
6080 if (header.indexOf(";base64") > -1) {
6083 body = decodeURIComponent(body);
6085 setTimeout(function() {
6086 this.receive(url, elt, null, body);
6089 var receiveXhr = function(err, resource, redirectedUrl) {
6090 this.receive(url, elt, err, resource, redirectedUrl);
6092 xhr.load(url, receiveXhr);
6095 receive: function(url, elt, err, resource, redirectedUrl) {
6096 this.cache[url] = resource;
6097 var $p = this.pending[url];
6098 for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
6099 this.onload(url, p, resource, err, redirectedUrl);
6102 this.pending[url] = null;
6108 checkDone: function() {
6109 if (!this.inflight) {
6114 scope.Loader = Loader;
6117 window.HTMLImports.addModule(function(scope) {
6118 var Observer = function(addCallback) {
6119 this.addCallback = addCallback;
6120 this.mo = new MutationObserver(this.handler.bind(this));
6122 Observer.prototype = {
6123 handler: function(mutations) {
6124 for (var i = 0, l = mutations.length, m; i < l && (m = mutations[i]); i++) {
6125 if (m.type === "childList" && m.addedNodes.length) {
6126 this.addedNodes(m.addedNodes);
6130 addedNodes: function(nodes) {
6131 if (this.addCallback) {
6132 this.addCallback(nodes);
6134 for (var i = 0, l = nodes.length, n, loading; i < l && (n = nodes[i]); i++) {
6135 if (n.children && n.children.length) {
6136 this.addedNodes(n.children);
6140 observe: function(root) {
6141 this.mo.observe(root, {
6147 scope.Observer = Observer;
6150 window.HTMLImports.addModule(function(scope) {
6151 var path = scope.path;
6152 var rootDocument = scope.rootDocument;
6153 var flags = scope.flags;
6154 var isIE = scope.isIE;
6155 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
6156 var IMPORT_SELECTOR = "link[rel=" + IMPORT_LINK_TYPE + "]";
6157 var importParser = {
6158 documentSelectors: IMPORT_SELECTOR,
6159 importsSelectors: [ IMPORT_SELECTOR, "link[rel=stylesheet]:not([type])", "style:not([type])", "script:not([type])", 'script[type="application/javascript"]', 'script[type="text/javascript"]' ].join(","),
6162 script: "parseScript",
6165 dynamicElements: [],
6166 parseNext: function() {
6167 var next = this.nextToParse();
6172 parse: function(elt) {
6173 if (this.isParsed(elt)) {
6174 flags.parse && console.log("[%s] is already parsed", elt.localName);
6177 var fn = this[this.map[elt.localName]];
6179 this.markParsing(elt);
6183 parseDynamic: function(elt, quiet) {
6184 this.dynamicElements.push(elt);
6189 markParsing: function(elt) {
6190 flags.parse && console.log("parsing", elt);
6191 this.parsingElement = elt;
6193 markParsingComplete: function(elt) {
6194 elt.__importParsed = true;
6195 this.markDynamicParsingComplete(elt);
6196 if (elt.__importElement) {
6197 elt.__importElement.__importParsed = true;
6198 this.markDynamicParsingComplete(elt.__importElement);
6200 this.parsingElement = null;
6201 flags.parse && console.log("completed", elt);
6203 markDynamicParsingComplete: function(elt) {
6204 var i = this.dynamicElements.indexOf(elt);
6206 this.dynamicElements.splice(i, 1);
6209 parseImport: function(elt) {
6210 elt.import = elt.__doc;
6211 if (window.HTMLImports.__importsParsingHook) {
6212 window.HTMLImports.__importsParsingHook(elt);
6215 elt.import.__importParsed = true;
6217 this.markParsingComplete(elt);
6218 if (elt.__resource && !elt.__error) {
6219 elt.dispatchEvent(new CustomEvent("load", {
6223 elt.dispatchEvent(new CustomEvent("error", {
6227 if (elt.__pending) {
6229 while (elt.__pending.length) {
6230 fn = elt.__pending.shift();
6240 parseLink: function(linkElt) {
6241 if (nodeIsImport(linkElt)) {
6242 this.parseImport(linkElt);
6244 linkElt.href = linkElt.href;
6245 this.parseGeneric(linkElt);
6248 parseStyle: function(elt) {
6250 elt = cloneStyle(elt);
6251 src.__appliedElement = elt;
6252 elt.__importElement = src;
6253 this.parseGeneric(elt);
6255 parseGeneric: function(elt) {
6256 this.trackElement(elt);
6257 this.addElementToDocument(elt);
6259 rootImportForElement: function(elt) {
6261 while (n.ownerDocument.__importLink) {
6262 n = n.ownerDocument.__importLink;
6266 addElementToDocument: function(elt) {
6267 var port = this.rootImportForElement(elt.__importElement || elt);
6268 port.parentNode.insertBefore(elt, port);
6270 trackElement: function(elt, callback) {
6272 var done = function(e) {
6273 elt.removeEventListener("load", done);
6274 elt.removeEventListener("error", done);
6278 self.markParsingComplete(elt);
6281 elt.addEventListener("load", done);
6282 elt.addEventListener("error", done);
6283 if (isIE && elt.localName === "style") {
6284 var fakeLoad = false;
6285 if (elt.textContent.indexOf("@import") == -1) {
6287 } else if (elt.sheet) {
6289 var csr = elt.sheet.cssRules;
6290 var len = csr ? csr.length : 0;
6291 for (var i = 0, r; i < len && (r = csr[i]); i++) {
6292 if (r.type === CSSRule.IMPORT_RULE) {
6293 fakeLoad = fakeLoad && Boolean(r.styleSheet);
6298 setTimeout(function() {
6299 elt.dispatchEvent(new CustomEvent("load", {
6306 parseScript: function(scriptElt) {
6307 var script = document.createElement("script");
6308 script.__importElement = scriptElt;
6309 script.src = scriptElt.src ? scriptElt.src : generateScriptDataUrl(scriptElt);
6310 scope.currentScript = scriptElt;
6311 this.trackElement(script, function(e) {
6312 if (script.parentNode) {
6313 script.parentNode.removeChild(script);
6315 scope.currentScript = null;
6317 this.addElementToDocument(script);
6319 nextToParse: function() {
6320 this._mayParse = [];
6321 return !this.parsingElement && (this.nextToParseInDoc(rootDocument) || this.nextToParseDynamic());
6323 nextToParseInDoc: function(doc, link) {
6324 if (doc && this._mayParse.indexOf(doc) < 0) {
6325 this._mayParse.push(doc);
6326 var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
6327 for (var i = 0, l = nodes.length, p = 0, n; i < l && (n = nodes[i]); i++) {
6328 if (!this.isParsed(n)) {
6329 if (this.hasResource(n)) {
6330 return nodeIsImport(n) ? this.nextToParseInDoc(n.__doc, n) : n;
6339 nextToParseDynamic: function() {
6340 return this.dynamicElements[0];
6342 parseSelectorsForNode: function(node) {
6343 var doc = node.ownerDocument || node;
6344 return doc === rootDocument ? this.documentSelectors : this.importsSelectors;
6346 isParsed: function(node) {
6347 return node.__importParsed;
6349 needsDynamicParsing: function(elt) {
6350 return this.dynamicElements.indexOf(elt) >= 0;
6352 hasResource: function(node) {
6353 if (nodeIsImport(node) && node.__doc === undefined) {
6359 function nodeIsImport(elt) {
6360 return elt.localName === "link" && elt.rel === IMPORT_LINK_TYPE;
6362 function generateScriptDataUrl(script) {
6363 var scriptContent = generateScriptContent(script);
6364 return "data:text/javascript;charset=utf-8," + encodeURIComponent(scriptContent);
6366 function generateScriptContent(script) {
6367 return script.textContent + generateSourceMapHint(script);
6369 function generateSourceMapHint(script) {
6370 var owner = script.ownerDocument;
6371 owner.__importedScripts = owner.__importedScripts || 0;
6372 var moniker = script.ownerDocument.baseURI;
6373 var num = owner.__importedScripts ? "-" + owner.__importedScripts : "";
6374 owner.__importedScripts++;
6375 return "\n//# sourceURL=" + moniker + num + ".js\n";
6377 function cloneStyle(style) {
6378 var clone = style.ownerDocument.createElement("style");
6379 clone.textContent = style.textContent;
6380 path.resolveUrlsInStyle(clone);
6383 scope.parser = importParser;
6384 scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
6387 window.HTMLImports.addModule(function(scope) {
6388 var flags = scope.flags;
6389 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
6390 var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
6391 var rootDocument = scope.rootDocument;
6392 var Loader = scope.Loader;
6393 var Observer = scope.Observer;
6394 var parser = scope.parser;
6397 documentPreloadSelectors: IMPORT_SELECTOR,
6398 importsPreloadSelectors: [ IMPORT_SELECTOR ].join(","),
6399 loadNode: function(node) {
6400 importLoader.addNode(node);
6402 loadSubtree: function(parent) {
6403 var nodes = this.marshalNodes(parent);
6404 importLoader.addNodes(nodes);
6406 marshalNodes: function(parent) {
6407 return parent.querySelectorAll(this.loadSelectorsForNode(parent));
6409 loadSelectorsForNode: function(node) {
6410 var doc = node.ownerDocument || node;
6411 return doc === rootDocument ? this.documentPreloadSelectors : this.importsPreloadSelectors;
6413 loaded: function(url, elt, resource, err, redirectedUrl) {
6414 flags.load && console.log("loaded", url, elt);
6415 elt.__resource = resource;
6417 if (isImportLink(elt)) {
6418 var doc = this.documents[url];
6419 if (doc === undefined) {
6420 doc = err ? null : makeDocument(resource, redirectedUrl || url);
6422 doc.__importLink = elt;
6423 this.bootDocument(doc);
6425 this.documents[url] = doc;
6431 bootDocument: function(doc) {
6432 this.loadSubtree(doc);
6433 this.observer.observe(doc);
6436 loadedAll: function() {
6440 var importLoader = new Loader(importer.loaded.bind(importer), importer.loadedAll.bind(importer));
6441 importer.observer = new Observer();
6442 function isImportLink(elt) {
6443 return isLinkRel(elt, IMPORT_LINK_TYPE);
6445 function isLinkRel(elt, rel) {
6446 return elt.localName === "link" && elt.getAttribute("rel") === rel;
6448 function hasBaseURIAccessor(doc) {
6449 return !!Object.getOwnPropertyDescriptor(doc, "baseURI");
6451 function makeDocument(resource, url) {
6452 var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
6454 var base = doc.createElement("base");
6455 base.setAttribute("href", url);
6456 if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
6457 Object.defineProperty(doc, "baseURI", {
6461 var meta = doc.createElement("meta");
6462 meta.setAttribute("charset", "utf-8");
6463 doc.head.appendChild(meta);
6464 doc.head.appendChild(base);
6465 doc.body.innerHTML = resource;
6466 if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
6467 HTMLTemplateElement.bootstrap(doc);
6471 if (!document.baseURI) {
6472 var baseURIDescriptor = {
6474 var base = document.querySelector("base");
6475 return base ? base.href : window.location.href;
6479 Object.defineProperty(document, "baseURI", baseURIDescriptor);
6480 Object.defineProperty(rootDocument, "baseURI", baseURIDescriptor);
6482 scope.importer = importer;
6483 scope.importLoader = importLoader;
6486 window.HTMLImports.addModule(function(scope) {
6487 var parser = scope.parser;
6488 var importer = scope.importer;
6490 added: function(nodes) {
6491 var owner, parsed, loading;
6492 for (var i = 0, l = nodes.length, n; i < l && (n = nodes[i]); i++) {
6494 owner = n.ownerDocument;
6495 parsed = parser.isParsed(owner);
6497 loading = this.shouldLoadNode(n);
6499 importer.loadNode(n);
6501 if (this.shouldParseNode(n) && parsed) {
6502 parser.parseDynamic(n, loading);
6506 shouldLoadNode: function(node) {
6507 return node.nodeType === 1 && matches.call(node, importer.loadSelectorsForNode(node));
6509 shouldParseNode: function(node) {
6510 return node.nodeType === 1 && matches.call(node, parser.parseSelectorsForNode(node));
6513 importer.observer.addCallback = dynamic.added.bind(dynamic);
6514 var matches = HTMLElement.prototype.matches || HTMLElement.prototype.matchesSelector || HTMLElement.prototype.webkitMatchesSelector || HTMLElement.prototype.mozMatchesSelector || HTMLElement.prototype.msMatchesSelector;
6518 var initializeModules = scope.initializeModules;
6519 var isIE = scope.isIE;
6520 if (scope.useNative) {
6523 initializeModules();
6524 var rootDocument = scope.rootDocument;
6525 function bootstrap() {
6526 window.HTMLImports.importer.bootDocument(rootDocument);
6528 if (document.readyState === "complete" || document.readyState === "interactive" && !window.attachEvent) {
6531 document.addEventListener("DOMContentLoaded", bootstrap);
6533 })(window.HTMLImports);
6535 window.CustomElements = window.CustomElements || {
6540 var flags = scope.flags;
6542 var addModule = function(module) {
6543 modules.push(module);
6545 var initializeModules = function() {
6546 modules.forEach(function(module) {
6550 scope.addModule = addModule;
6551 scope.initializeModules = initializeModules;
6552 scope.hasNative = Boolean(document.registerElement);
6553 scope.isIE = /Trident/.test(navigator.userAgent);
6554 scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative);
6555 })(window.CustomElements);
6557 window.CustomElements.addModule(function(scope) {
6558 var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none";
6559 function forSubtree(node, cb) {
6560 findAllElements(node, function(e) {
6568 function findAllElements(node, find, data) {
6569 var e = node.firstElementChild;
6571 e = node.firstChild;
6572 while (e && e.nodeType !== Node.ELEMENT_NODE) {
6577 if (find(e, data) !== true) {
6578 findAllElements(e, find, data);
6580 e = e.nextElementSibling;
6584 function forRoots(node, cb) {
6585 var root = node.shadowRoot;
6587 forSubtree(root, cb);
6588 root = root.olderShadowRoot;
6591 function forDocumentTree(doc, cb) {
6592 _forDocumentTree(doc, cb, []);
6594 function _forDocumentTree(doc, cb, processingDocuments) {
6595 doc = window.wrap(doc);
6596 if (processingDocuments.indexOf(doc) >= 0) {
6599 processingDocuments.push(doc);
6600 var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]");
6601 for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) {
6603 _forDocumentTree(n.import, cb, processingDocuments);
6608 scope.forDocumentTree = forDocumentTree;
6609 scope.forSubtree = forSubtree;
6612 window.CustomElements.addModule(function(scope) {
6613 var flags = scope.flags;
6614 var forSubtree = scope.forSubtree;
6615 var forDocumentTree = scope.forDocumentTree;
6616 function addedNode(node, isAttached) {
6617 return added(node, isAttached) || addedSubtree(node, isAttached);
6619 function added(node, isAttached) {
6620 if (scope.upgrade(node, isAttached)) {
6627 function addedSubtree(node, isAttached) {
6628 forSubtree(node, function(e) {
6629 if (added(e, isAttached)) {
6634 var hasThrottledAttached = window.MutationObserver._isPolyfilled && flags["throttle-attached"];
6635 scope.hasPolyfillMutations = hasThrottledAttached;
6636 scope.hasThrottledAttached = hasThrottledAttached;
6637 var isPendingMutations = false;
6638 var pendingMutations = [];
6639 function deferMutation(fn) {
6640 pendingMutations.push(fn);
6641 if (!isPendingMutations) {
6642 isPendingMutations = true;
6643 setTimeout(takeMutations);
6646 function takeMutations() {
6647 isPendingMutations = false;
6648 var $p = pendingMutations;
6649 for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) {
6652 pendingMutations = [];
6654 function attached(element) {
6655 if (hasThrottledAttached) {
6656 deferMutation(function() {
6663 function _attached(element) {
6664 if (element.__upgraded__ && !element.__attached) {
6665 element.__attached = true;
6666 if (element.attachedCallback) {
6667 element.attachedCallback();
6671 function detachedNode(node) {
6673 forSubtree(node, function(e) {
6677 function detached(element) {
6678 if (hasThrottledAttached) {
6679 deferMutation(function() {
6686 function _detached(element) {
6687 if (element.__upgraded__ && element.__attached) {
6688 element.__attached = false;
6689 if (element.detachedCallback) {
6690 element.detachedCallback();
6694 function inDocument(element) {
6696 var doc = window.wrap(document);
6701 p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host;
6704 function watchShadow(node) {
6705 if (node.shadowRoot && !node.shadowRoot.__watched) {
6706 flags.dom && console.log("watching shadow-root for: ", node.localName);
6707 var root = node.shadowRoot;
6710 root = root.olderShadowRoot;
6714 function handler(root, mutations) {
6716 var mx = mutations[0];
6717 if (mx && mx.type === "childList" && mx.addedNodes) {
6718 if (mx.addedNodes) {
6719 var d = mx.addedNodes[0];
6720 while (d && d !== document && !d.host) {
6723 var u = d && (d.URL || d._URL || d.host && d.host.localName) || "";
6724 u = u.split("/?").shift().split("/").pop();
6727 console.group("mutations (%d) [%s]", mutations.length, u || "");
6729 var isAttached = inDocument(root);
6730 mutations.forEach(function(mx) {
6731 if (mx.type === "childList") {
6732 forEach(mx.addedNodes, function(n) {
6736 addedNode(n, isAttached);
6738 forEach(mx.removedNodes, function(n) {
6746 flags.dom && console.groupEnd();
6748 function takeRecords(node) {
6749 node = window.wrap(node);
6751 node = window.wrap(document);
6753 while (node.parentNode) {
6754 node = node.parentNode;
6756 var observer = node.__observer;
6758 handler(node, observer.takeRecords());
6762 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
6763 function observe(inRoot) {
6764 if (inRoot.__observer) {
6767 var observer = new MutationObserver(handler.bind(this, inRoot));
6768 observer.observe(inRoot, {
6772 inRoot.__observer = observer;
6774 function upgradeDocument(doc) {
6775 doc = window.wrap(doc);
6776 flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop());
6777 var isMainDocument = doc === window.wrap(document);
6778 addedNode(doc, isMainDocument);
6780 flags.dom && console.groupEnd();
6782 function upgradeDocumentTree(doc) {
6783 forDocumentTree(doc, upgradeDocument);
6785 var originalCreateShadowRoot = Element.prototype.createShadowRoot;
6786 if (originalCreateShadowRoot) {
6787 Element.prototype.createShadowRoot = function() {
6788 var root = originalCreateShadowRoot.call(this);
6789 window.CustomElements.watchShadow(this);
6793 scope.watchShadow = watchShadow;
6794 scope.upgradeDocumentTree = upgradeDocumentTree;
6795 scope.upgradeDocument = upgradeDocument;
6796 scope.upgradeSubtree = addedSubtree;
6797 scope.upgradeAll = addedNode;
6798 scope.attached = attached;
6799 scope.takeRecords = takeRecords;
6802 window.CustomElements.addModule(function(scope) {
6803 var flags = scope.flags;
6804 function upgrade(node, isAttached) {
6805 if (node.localName === "template") {
6806 if (window.HTMLTemplateElement && HTMLTemplateElement.decorate) {
6807 HTMLTemplateElement.decorate(node);
6810 if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
6811 var is = node.getAttribute("is");
6812 var definition = scope.getRegisteredDefinition(node.localName) || scope.getRegisteredDefinition(is);
6814 if (is && definition.tag == node.localName || !is && !definition.extends) {
6815 return upgradeWithDefinition(node, definition, isAttached);
6820 function upgradeWithDefinition(element, definition, isAttached) {
6821 flags.upgrade && console.group("upgrade:", element.localName);
6822 if (definition.is) {
6823 element.setAttribute("is", definition.is);
6825 implementPrototype(element, definition);
6826 element.__upgraded__ = true;
6829 scope.attached(element);
6831 scope.upgradeSubtree(element, isAttached);
6832 flags.upgrade && console.groupEnd();
6835 function implementPrototype(element, definition) {
6836 if (Object.__proto__) {
6837 element.__proto__ = definition.prototype;
6839 customMixin(element, definition.prototype, definition.native);
6840 element.__proto__ = definition.prototype;
6843 function customMixin(inTarget, inSrc, inNative) {
6846 while (p !== inNative && p !== HTMLElement.prototype) {
6847 var keys = Object.getOwnPropertyNames(p);
6848 for (var i = 0, k; k = keys[i]; i++) {
6850 Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k));
6854 p = Object.getPrototypeOf(p);
6857 function created(element) {
6858 if (element.createdCallback) {
6859 element.createdCallback();
6862 scope.upgrade = upgrade;
6863 scope.upgradeWithDefinition = upgradeWithDefinition;
6864 scope.implementPrototype = implementPrototype;
6867 window.CustomElements.addModule(function(scope) {
6868 var isIE = scope.isIE;
6869 var upgradeDocumentTree = scope.upgradeDocumentTree;
6870 var upgradeAll = scope.upgradeAll;
6871 var upgradeWithDefinition = scope.upgradeWithDefinition;
6872 var implementPrototype = scope.implementPrototype;
6873 var useNative = scope.useNative;
6874 function register(name, options) {
6875 var definition = options || {};
6877 throw new Error("document.registerElement: first argument `name` must not be empty");
6879 if (name.indexOf("-") < 0) {
6880 throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'.");
6882 if (isReservedTag(name)) {
6883 throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid.");
6885 if (getRegisteredDefinition(name)) {
6886 throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered");
6888 if (!definition.prototype) {
6889 definition.prototype = Object.create(HTMLElement.prototype);
6891 definition.__name = name.toLowerCase();
6892 definition.lifecycle = definition.lifecycle || {};
6893 definition.ancestry = ancestry(definition.extends);
6894 resolveTagName(definition);
6895 resolvePrototypeChain(definition);
6896 overrideAttributeApi(definition.prototype);
6897 registerDefinition(definition.__name, definition);
6898 definition.ctor = generateConstructor(definition);
6899 definition.ctor.prototype = definition.prototype;
6900 definition.prototype.constructor = definition.ctor;
6902 upgradeDocumentTree(document);
6904 return definition.ctor;
6906 function overrideAttributeApi(prototype) {
6907 if (prototype.setAttribute._polyfilled) {
6910 var setAttribute = prototype.setAttribute;
6911 prototype.setAttribute = function(name, value) {
6912 changeAttribute.call(this, name, value, setAttribute);
6914 var removeAttribute = prototype.removeAttribute;
6915 prototype.removeAttribute = function(name) {
6916 changeAttribute.call(this, name, null, removeAttribute);
6918 prototype.setAttribute._polyfilled = true;
6920 function changeAttribute(name, value, operation) {
6921 name = name.toLowerCase();
6922 var oldValue = this.getAttribute(name);
6923 operation.apply(this, arguments);
6924 var newValue = this.getAttribute(name);
6925 if (this.attributeChangedCallback && newValue !== oldValue) {
6926 this.attributeChangedCallback(name, oldValue, newValue);
6929 function isReservedTag(name) {
6930 for (var i = 0; i < reservedTagList.length; i++) {
6931 if (name === reservedTagList[i]) {
6936 var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ];
6937 function ancestry(extnds) {
6938 var extendee = getRegisteredDefinition(extnds);
6940 return ancestry(extendee.extends).concat([ extendee ]);
6944 function resolveTagName(definition) {
6945 var baseTag = definition.extends;
6946 for (var i = 0, a; a = definition.ancestry[i]; i++) {
6947 baseTag = a.is && a.tag;
6949 definition.tag = baseTag || definition.__name;
6951 definition.is = definition.__name;
6954 function resolvePrototypeChain(definition) {
6955 if (!Object.__proto__) {
6956 var nativePrototype = HTMLElement.prototype;
6957 if (definition.is) {
6958 var inst = document.createElement(definition.tag);
6959 nativePrototype = Object.getPrototypeOf(inst);
6961 var proto = definition.prototype, ancestor;
6962 var foundPrototype = false;
6964 if (proto == nativePrototype) {
6965 foundPrototype = true;
6967 ancestor = Object.getPrototypeOf(proto);
6969 proto.__proto__ = ancestor;
6973 if (!foundPrototype) {
6974 console.warn(definition.tag + " prototype not found in prototype chain for " + definition.is);
6976 definition.native = nativePrototype;
6979 function instantiate(definition) {
6980 return upgradeWithDefinition(domCreateElement(definition.tag), definition);
6983 function getRegisteredDefinition(name) {
6985 return registry[name.toLowerCase()];
6988 function registerDefinition(name, definition) {
6989 registry[name] = definition;
6991 function generateConstructor(definition) {
6993 return instantiate(definition);
6996 var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
6997 function createElementNS(namespace, tag, typeExtension) {
6998 if (namespace === HTML_NAMESPACE) {
6999 return createElement(tag, typeExtension);
7001 return domCreateElementNS(namespace, tag);
7004 function createElement(tag, typeExtension) {
7006 tag = tag.toLowerCase();
7008 if (typeExtension) {
7009 typeExtension = typeExtension.toLowerCase();
7011 var definition = getRegisteredDefinition(typeExtension || tag);
7013 if (tag == definition.tag && typeExtension == definition.is) {
7014 return new definition.ctor();
7016 if (!typeExtension && !definition.is) {
7017 return new definition.ctor();
7021 if (typeExtension) {
7022 element = createElement(tag);
7023 element.setAttribute("is", typeExtension);
7026 element = domCreateElement(tag);
7027 if (tag.indexOf("-") >= 0) {
7028 implementPrototype(element, HTMLElement);
7032 var domCreateElement = document.createElement.bind(document);
7033 var domCreateElementNS = document.createElementNS.bind(document);
7035 if (!Object.__proto__ && !useNative) {
7036 isInstance = function(obj, ctor) {
7037 if (obj instanceof ctor) {
7042 if (p === ctor.prototype) {
7050 isInstance = function(obj, base) {
7051 return obj instanceof base;
7054 function wrapDomMethodToForceUpgrade(obj, methodName) {
7055 var orig = obj[methodName];
7056 obj[methodName] = function() {
7057 var n = orig.apply(this, arguments);
7062 wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode");
7063 wrapDomMethodToForceUpgrade(document, "importNode");
7066 var importNode = document.importNode;
7067 document.importNode = function() {
7068 var n = importNode.apply(document, arguments);
7069 if (n.nodeType == n.DOCUMENT_FRAGMENT_NODE) {
7070 var f = document.createDocumentFragment();
7079 document.registerElement = register;
7080 document.createElement = createElement;
7081 document.createElementNS = createElementNS;
7082 scope.registry = registry;
7083 scope.instanceof = isInstance;
7084 scope.reservedTagList = reservedTagList;
7085 scope.getRegisteredDefinition = getRegisteredDefinition;
7086 document.register = document.registerElement;
7090 var useNative = scope.useNative;
7091 var initializeModules = scope.initializeModules;
7092 var isIE = scope.isIE;
7094 var nop = function() {};
7095 scope.watchShadow = nop;
7096 scope.upgrade = nop;
7097 scope.upgradeAll = nop;
7098 scope.upgradeDocumentTree = nop;
7099 scope.upgradeSubtree = nop;
7100 scope.takeRecords = nop;
7101 scope.instanceof = function(obj, base) {
7102 return obj instanceof base;
7105 initializeModules();
7107 var upgradeDocumentTree = scope.upgradeDocumentTree;
7108 var upgradeDocument = scope.upgradeDocument;
7110 if (window.ShadowDOMPolyfill) {
7111 window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded;
7112 window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded;
7114 window.wrap = window.unwrap = function(node) {
7119 if (window.HTMLImports) {
7120 window.HTMLImports.__importsParsingHook = function(elt) {
7122 upgradeDocument(wrap(elt.import));
7126 function bootstrap() {
7127 upgradeDocumentTree(window.wrap(document));
7128 window.CustomElements.ready = true;
7129 var requestAnimationFrame = window.requestAnimationFrame || function(f) {
7132 requestAnimationFrame(function() {
7133 setTimeout(function() {
7134 window.CustomElements.readyTime = Date.now();
7135 if (window.HTMLImports) {
7136 window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime;
7138 document.dispatchEvent(new CustomEvent("WebComponentsReady", {
7144 if (document.readyState === "complete" || scope.flags.eager) {
7146 } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) {
7149 var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded";
7150 window.addEventListener(loadEvent, bootstrap);
7152 })(window.CustomElements);
7155 if (!Function.prototype.bind) {
7156 Function.prototype.bind = function(scope) {
7158 var args = Array.prototype.slice.call(arguments, 1);
7160 var args2 = args.slice();
7161 args2.push.apply(args2, arguments);
7162 return self.apply(scope, args2);
7166 })(window.WebComponents);
7169 var style = document.createElement("style");
7170 style.textContent = "" + "body {" + "transition: opacity ease-in 0.2s;" + " } \n" + "body[unresolved] {" + "opacity: 0; display: block; overflow: hidden; position: relative;" + " } \n";
7171 var head = document.querySelector("head");
7172 head.insertBefore(style, head.firstChild);
7173 })(window.WebComponents);
7176 window.Platform = scope;
7177 })(window.WebComponents);