Home | History | Annotate | Download | only in webcomponentsjs
      1 /**
      2  * @license
      3  * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
      4  * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5  * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6  * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7  * Code distributed by Google as part of the polymer project is also
      8  * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
      9  */
     10 // @version 0.5.5
     11 if (typeof WeakMap === "undefined") {
     12   (function() {
     13     var defineProperty = Object.defineProperty;
     14     var counter = Date.now() % 1e9;
     15     var WeakMap = function() {
     16       this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
     17     };
     18     WeakMap.prototype = {
     19       set: function(key, value) {
     20         var entry = key[this.name];
     21         if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
     22           value: [ key, value ],
     23           writable: true
     24         });
     25         return this;
     26       },
     27       get: function(key) {
     28         var entry;
     29         return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
     30       },
     31       "delete": function(key) {
     32         var entry = key[this.name];
     33         if (!entry || entry[0] !== key) return false;
     34         entry[0] = entry[1] = undefined;
     35         return true;
     36       },
     37       has: function(key) {
     38         var entry = key[this.name];
     39         if (!entry) return false;
     40         return entry[0] === key;
     41       }
     42     };
     43     window.WeakMap = WeakMap;
     44   })();
     45 }
     46 
     47 window.ShadowDOMPolyfill = {};
     48 
     49 (function(scope) {
     50   "use strict";
     51   var constructorTable = new WeakMap();
     52   var nativePrototypeTable = new WeakMap();
     53   var wrappers = Object.create(null);
     54   function detectEval() {
     55     if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
     56       return false;
     57     }
     58     if (navigator.getDeviceStorage) {
     59       return false;
     60     }
     61     try {
     62       var f = new Function("return true;");
     63       return f();
     64     } catch (ex) {
     65       return false;
     66     }
     67   }
     68   var hasEval = detectEval();
     69   function assert(b) {
     70     if (!b) throw new Error("Assertion failed");
     71   }
     72   var defineProperty = Object.defineProperty;
     73   var getOwnPropertyNames = Object.getOwnPropertyNames;
     74   var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
     75   function mixin(to, from) {
     76     var names = getOwnPropertyNames(from);
     77     for (var i = 0; i < names.length; i++) {
     78       var name = names[i];
     79       defineProperty(to, name, getOwnPropertyDescriptor(from, name));
     80     }
     81     return to;
     82   }
     83   function mixinStatics(to, from) {
     84     var names = getOwnPropertyNames(from);
     85     for (var i = 0; i < names.length; i++) {
     86       var name = names[i];
     87       switch (name) {
     88        case "arguments":
     89        case "caller":
     90        case "length":
     91        case "name":
     92        case "prototype":
     93        case "toString":
     94         continue;
     95       }
     96       defineProperty(to, name, getOwnPropertyDescriptor(from, name));
     97     }
     98     return to;
     99   }
    100   function oneOf(object, propertyNames) {
    101     for (var i = 0; i < propertyNames.length; i++) {
    102       if (propertyNames[i] in object) return propertyNames[i];
    103     }
    104   }
    105   var nonEnumerableDataDescriptor = {
    106     value: undefined,
    107     configurable: true,
    108     enumerable: false,
    109     writable: true
    110   };
    111   function defineNonEnumerableDataProperty(object, name, value) {
    112     nonEnumerableDataDescriptor.value = value;
    113     defineProperty(object, name, nonEnumerableDataDescriptor);
    114   }
    115   getOwnPropertyNames(window);
    116   function getWrapperConstructor(node) {
    117     var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
    118     if (isFirefox) {
    119       try {
    120         getOwnPropertyNames(nativePrototype);
    121       } catch (error) {
    122         nativePrototype = nativePrototype.__proto__;
    123       }
    124     }
    125     var wrapperConstructor = constructorTable.get(nativePrototype);
    126     if (wrapperConstructor) return wrapperConstructor;
    127     var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
    128     var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
    129     registerInternal(nativePrototype, GeneratedWrapper, node);
    130     return GeneratedWrapper;
    131   }
    132   function addForwardingProperties(nativePrototype, wrapperPrototype) {
    133     installProperty(nativePrototype, wrapperPrototype, true);
    134   }
    135   function registerInstanceProperties(wrapperPrototype, instanceObject) {
    136     installProperty(instanceObject, wrapperPrototype, false);
    137   }
    138   var isFirefox = /Firefox/.test(navigator.userAgent);
    139   var dummyDescriptor = {
    140     get: function() {},
    141     set: function(v) {},
    142     configurable: true,
    143     enumerable: true
    144   };
    145   function isEventHandlerName(name) {
    146     return /^on[a-z]+$/.test(name);
    147   }
    148   function isIdentifierName(name) {
    149     return /^\w[a-zA-Z_0-9]*$/.test(name);
    150   }
    151   function getGetter(name) {
    152     return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
    153       return this.__impl4cf1e782hg__[name];
    154     };
    155   }
    156   function getSetter(name) {
    157     return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
    158       this.__impl4cf1e782hg__[name] = v;
    159     };
    160   }
    161   function getMethod(name) {
    162     return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
    163       return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
    164     };
    165   }
    166   function getDescriptor(source, name) {
    167     try {
    168       return Object.getOwnPropertyDescriptor(source, name);
    169     } catch (ex) {
    170       return dummyDescriptor;
    171     }
    172   }
    173   var isBrokenSafari = function() {
    174     var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
    175     return descr && !descr.get && !descr.set;
    176   }();
    177   function installProperty(source, target, allowMethod, opt_blacklist) {
    178     var names = getOwnPropertyNames(source);
    179     for (var i = 0; i < names.length; i++) {
    180       var name = names[i];
    181       if (name === "polymerBlackList_") continue;
    182       if (name in target) continue;
    183       if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
    184       if (isFirefox) {
    185         source.__lookupGetter__(name);
    186       }
    187       var descriptor = getDescriptor(source, name);
    188       var getter, setter;
    189       if (allowMethod && typeof descriptor.value === "function") {
    190         target[name] = getMethod(name);
    191         continue;
    192       }
    193       var isEvent = isEventHandlerName(name);
    194       if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
    195       if (descriptor.writable || descriptor.set || isBrokenSafari) {
    196         if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
    197       }
    198       var configurable = isBrokenSafari || descriptor.configurable;
    199       defineProperty(target, name, {
    200         get: getter,
    201         set: setter,
    202         configurable: configurable,
    203         enumerable: descriptor.enumerable
    204       });
    205     }
    206   }
    207   function register(nativeConstructor, wrapperConstructor, opt_instance) {
    208     var nativePrototype = nativeConstructor.prototype;
    209     registerInternal(nativePrototype, wrapperConstructor, opt_instance);
    210     mixinStatics(wrapperConstructor, nativeConstructor);
    211   }
    212   function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
    213     var wrapperPrototype = wrapperConstructor.prototype;
    214     assert(constructorTable.get(nativePrototype) === undefined);
    215     constructorTable.set(nativePrototype, wrapperConstructor);
    216     nativePrototypeTable.set(wrapperPrototype, nativePrototype);
    217     addForwardingProperties(nativePrototype, wrapperPrototype);
    218     if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
    219     defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
    220     wrapperConstructor.prototype = wrapperPrototype;
    221   }
    222   function isWrapperFor(wrapperConstructor, nativeConstructor) {
    223     return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
    224   }
    225   function registerObject(object) {
    226     var nativePrototype = Object.getPrototypeOf(object);
    227     var superWrapperConstructor = getWrapperConstructor(nativePrototype);
    228     var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
    229     registerInternal(nativePrototype, GeneratedWrapper, object);
    230     return GeneratedWrapper;
    231   }
    232   function createWrapperConstructor(superWrapperConstructor) {
    233     function GeneratedWrapper(node) {
    234       superWrapperConstructor.call(this, node);
    235     }
    236     var p = Object.create(superWrapperConstructor.prototype);
    237     p.constructor = GeneratedWrapper;
    238     GeneratedWrapper.prototype = p;
    239     return GeneratedWrapper;
    240   }
    241   function isWrapper(object) {
    242     return object && object.__impl4cf1e782hg__;
    243   }
    244   function isNative(object) {
    245     return !isWrapper(object);
    246   }
    247   function wrap(impl) {
    248     if (impl === null) return null;
    249     assert(isNative(impl));
    250     return impl.__wrapper8e3dd93a60__ || (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
    251   }
    252   function unwrap(wrapper) {
    253     if (wrapper === null) return null;
    254     assert(isWrapper(wrapper));
    255     return wrapper.__impl4cf1e782hg__;
    256   }
    257   function unsafeUnwrap(wrapper) {
    258     return wrapper.__impl4cf1e782hg__;
    259   }
    260   function setWrapper(impl, wrapper) {
    261     wrapper.__impl4cf1e782hg__ = impl;
    262     impl.__wrapper8e3dd93a60__ = wrapper;
    263   }
    264   function unwrapIfNeeded(object) {
    265     return object && isWrapper(object) ? unwrap(object) : object;
    266   }
    267   function wrapIfNeeded(object) {
    268     return object && !isWrapper(object) ? wrap(object) : object;
    269   }
    270   function rewrap(node, wrapper) {
    271     if (wrapper === null) return;
    272     assert(isNative(node));
    273     assert(wrapper === undefined || isWrapper(wrapper));
    274     node.__wrapper8e3dd93a60__ = wrapper;
    275   }
    276   var getterDescriptor = {
    277     get: undefined,
    278     configurable: true,
    279     enumerable: true
    280   };
    281   function defineGetter(constructor, name, getter) {
    282     getterDescriptor.get = getter;
    283     defineProperty(constructor.prototype, name, getterDescriptor);
    284   }
    285   function defineWrapGetter(constructor, name) {
    286     defineGetter(constructor, name, function() {
    287       return wrap(this.__impl4cf1e782hg__[name]);
    288     });
    289   }
    290   function forwardMethodsToWrapper(constructors, names) {
    291     constructors.forEach(function(constructor) {
    292       names.forEach(function(name) {
    293         constructor.prototype[name] = function() {
    294           var w = wrapIfNeeded(this);
    295           return w[name].apply(w, arguments);
    296         };
    297       });
    298     });
    299   }
    300   scope.assert = assert;
    301   scope.constructorTable = constructorTable;
    302   scope.defineGetter = defineGetter;
    303   scope.defineWrapGetter = defineWrapGetter;
    304   scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
    305   scope.isWrapper = isWrapper;
    306   scope.isWrapperFor = isWrapperFor;
    307   scope.mixin = mixin;
    308   scope.nativePrototypeTable = nativePrototypeTable;
    309   scope.oneOf = oneOf;
    310   scope.registerObject = registerObject;
    311   scope.registerWrapper = register;
    312   scope.rewrap = rewrap;
    313   scope.setWrapper = setWrapper;
    314   scope.unsafeUnwrap = unsafeUnwrap;
    315   scope.unwrap = unwrap;
    316   scope.unwrapIfNeeded = unwrapIfNeeded;
    317   scope.wrap = wrap;
    318   scope.wrapIfNeeded = wrapIfNeeded;
    319   scope.wrappers = wrappers;
    320 })(window.ShadowDOMPolyfill);
    321 
    322 (function(scope) {
    323   "use strict";
    324   function newSplice(index, removed, addedCount) {
    325     return {
    326       index: index,
    327       removed: removed,
    328       addedCount: addedCount
    329     };
    330   }
    331   var EDIT_LEAVE = 0;
    332   var EDIT_UPDATE = 1;
    333   var EDIT_ADD = 2;
    334   var EDIT_DELETE = 3;
    335   function ArraySplice() {}
    336   ArraySplice.prototype = {
    337     calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
    338       var rowCount = oldEnd - oldStart + 1;
    339       var columnCount = currentEnd - currentStart + 1;
    340       var distances = new Array(rowCount);
    341       for (var i = 0; i < rowCount; i++) {
    342         distances[i] = new Array(columnCount);
    343         distances[i][0] = i;
    344       }
    345       for (var j = 0; j < columnCount; j++) distances[0][j] = j;
    346       for (var i = 1; i < rowCount; i++) {
    347         for (var j = 1; j < columnCount; j++) {
    348           if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {
    349             var north = distances[i - 1][j] + 1;
    350             var west = distances[i][j - 1] + 1;
    351             distances[i][j] = north < west ? north : west;
    352           }
    353         }
    354       }
    355       return distances;
    356     },
    357     spliceOperationsFromEditDistances: function(distances) {
    358       var i = distances.length - 1;
    359       var j = distances[0].length - 1;
    360       var current = distances[i][j];
    361       var edits = [];
    362       while (i > 0 || j > 0) {
    363         if (i == 0) {
    364           edits.push(EDIT_ADD);
    365           j--;
    366           continue;
    367         }
    368         if (j == 0) {
    369           edits.push(EDIT_DELETE);
    370           i--;
    371           continue;
    372         }
    373         var northWest = distances[i - 1][j - 1];
    374         var west = distances[i - 1][j];
    375         var north = distances[i][j - 1];
    376         var min;
    377         if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;
    378         if (min == northWest) {
    379           if (northWest == current) {
    380             edits.push(EDIT_LEAVE);
    381           } else {
    382             edits.push(EDIT_UPDATE);
    383             current = northWest;
    384           }
    385           i--;
    386           j--;
    387         } else if (min == west) {
    388           edits.push(EDIT_DELETE);
    389           i--;
    390           current = west;
    391         } else {
    392           edits.push(EDIT_ADD);
    393           j--;
    394           current = north;
    395         }
    396       }
    397       edits.reverse();
    398       return edits;
    399     },
    400     calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
    401       var prefixCount = 0;
    402       var suffixCount = 0;
    403       var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
    404       if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);
    405       if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
    406       currentStart += prefixCount;
    407       oldStart += prefixCount;
    408       currentEnd -= suffixCount;
    409       oldEnd -= suffixCount;
    410       if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];
    411       if (currentStart == currentEnd) {
    412         var splice = newSplice(currentStart, [], 0);
    413         while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);
    414         return [ splice ];
    415       } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];
    416       var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
    417       var splice = undefined;
    418       var splices = [];
    419       var index = currentStart;
    420       var oldIndex = oldStart;
    421       for (var i = 0; i < ops.length; i++) {
    422         switch (ops[i]) {
    423          case EDIT_LEAVE:
    424           if (splice) {
    425             splices.push(splice);
    426             splice = undefined;
    427           }
    428           index++;
    429           oldIndex++;
    430           break;
    431 
    432          case EDIT_UPDATE:
    433           if (!splice) splice = newSplice(index, [], 0);
    434           splice.addedCount++;
    435           index++;
    436           splice.removed.push(old[oldIndex]);
    437           oldIndex++;
    438           break;
    439 
    440          case EDIT_ADD:
    441           if (!splice) splice = newSplice(index, [], 0);
    442           splice.addedCount++;
    443           index++;
    444           break;
    445 
    446          case EDIT_DELETE:
    447           if (!splice) splice = newSplice(index, [], 0);
    448           splice.removed.push(old[oldIndex]);
    449           oldIndex++;
    450           break;
    451         }
    452       }
    453       if (splice) {
    454         splices.push(splice);
    455       }
    456       return splices;
    457     },
    458     sharedPrefix: function(current, old, searchLength) {
    459       for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;
    460       return searchLength;
    461     },
    462     sharedSuffix: function(current, old, searchLength) {
    463       var index1 = current.length;
    464       var index2 = old.length;
    465       var count = 0;
    466       while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;
    467       return count;
    468     },
    469     calculateSplices: function(current, previous) {
    470       return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
    471     },
    472     equals: function(currentValue, previousValue) {
    473       return currentValue === previousValue;
    474     }
    475   };
    476   scope.ArraySplice = ArraySplice;
    477 })(window.ShadowDOMPolyfill);
    478 
    479 (function(context) {
    480   "use strict";
    481   var OriginalMutationObserver = window.MutationObserver;
    482   var callbacks = [];
    483   var pending = false;
    484   var timerFunc;
    485   function handle() {
    486     pending = false;
    487     var copies = callbacks.slice(0);
    488     callbacks = [];
    489     for (var i = 0; i < copies.length; i++) {
    490       (0, copies[i])();
    491     }
    492   }
    493   if (OriginalMutationObserver) {
    494     var counter = 1;
    495     var observer = new OriginalMutationObserver(handle);
    496     var textNode = document.createTextNode(counter);
    497     observer.observe(textNode, {
    498       characterData: true
    499     });
    500     timerFunc = function() {
    501       counter = (counter + 1) % 2;
    502       textNode.data = counter;
    503     };
    504   } else {
    505     timerFunc = window.setTimeout;
    506   }
    507   function setEndOfMicrotask(func) {
    508     callbacks.push(func);
    509     if (pending) return;
    510     pending = true;
    511     timerFunc(handle, 0);
    512   }
    513   context.setEndOfMicrotask = setEndOfMicrotask;
    514 })(window.ShadowDOMPolyfill);
    515 
    516 (function(scope) {
    517   "use strict";
    518   var setEndOfMicrotask = scope.setEndOfMicrotask;
    519   var wrapIfNeeded = scope.wrapIfNeeded;
    520   var wrappers = scope.wrappers;
    521   var registrationsTable = new WeakMap();
    522   var globalMutationObservers = [];
    523   var isScheduled = false;
    524   function scheduleCallback(observer) {
    525     if (observer.scheduled_) return;
    526     observer.scheduled_ = true;
    527     globalMutationObservers.push(observer);
    528     if (isScheduled) return;
    529     setEndOfMicrotask(notifyObservers);
    530     isScheduled = true;
    531   }
    532   function notifyObservers() {
    533     isScheduled = false;
    534     while (globalMutationObservers.length) {
    535       var notifyList = globalMutationObservers;
    536       globalMutationObservers = [];
    537       notifyList.sort(function(x, y) {
    538         return x.uid_ - y.uid_;
    539       });
    540       for (var i = 0; i < notifyList.length; i++) {
    541         var mo = notifyList[i];
    542         mo.scheduled_ = false;
    543         var queue = mo.takeRecords();
    544         removeTransientObserversFor(mo);
    545         if (queue.length) {
    546           mo.callback_(queue, mo);
    547         }
    548       }
    549     }
    550   }
    551   function MutationRecord(type, target) {
    552     this.type = type;
    553     this.target = target;
    554     this.addedNodes = new wrappers.NodeList();
    555     this.removedNodes = new wrappers.NodeList();
    556     this.previousSibling = null;
    557     this.nextSibling = null;
    558     this.attributeName = null;
    559     this.attributeNamespace = null;
    560     this.oldValue = null;
    561   }
    562   function registerTransientObservers(ancestor, node) {
    563     for (;ancestor; ancestor = ancestor.parentNode) {
    564       var registrations = registrationsTable.get(ancestor);
    565       if (!registrations) continue;
    566       for (var i = 0; i < registrations.length; i++) {
    567         var registration = registrations[i];
    568         if (registration.options.subtree) registration.addTransientObserver(node);
    569       }
    570     }
    571   }
    572   function removeTransientObserversFor(observer) {
    573     for (var i = 0; i < observer.nodes_.length; i++) {
    574       var node = observer.nodes_[i];
    575       var registrations = registrationsTable.get(node);
    576       if (!registrations) return;
    577       for (var j = 0; j < registrations.length; j++) {
    578         var registration = registrations[j];
    579         if (registration.observer === observer) registration.removeTransientObservers();
    580       }
    581     }
    582   }
    583   function enqueueMutation(target, type, data) {
    584     var interestedObservers = Object.create(null);
    585     var associatedStrings = Object.create(null);
    586     for (var node = target; node; node = node.parentNode) {
    587       var registrations = registrationsTable.get(node);
    588       if (!registrations) continue;
    589       for (var j = 0; j < registrations.length; j++) {
    590         var registration = registrations[j];
    591         var options = registration.options;
    592         if (node !== target && !options.subtree) continue;
    593         if (type === "attributes" && !options.attributes) continue;
    594         if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
    595           continue;
    596         }
    597         if (type === "characterData" && !options.characterData) continue;
    598         if (type === "childList" && !options.childList) continue;
    599         var observer = registration.observer;
    600         interestedObservers[observer.uid_] = observer;
    601         if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
    602           associatedStrings[observer.uid_] = data.oldValue;
    603         }
    604       }
    605     }
    606     for (var uid in interestedObservers) {
    607       var observer = interestedObservers[uid];
    608       var record = new MutationRecord(type, target);
    609       if ("name" in data && "namespace" in data) {
    610         record.attributeName = data.name;
    611         record.attributeNamespace = data.namespace;
    612       }
    613       if (data.addedNodes) record.addedNodes = data.addedNodes;
    614       if (data.removedNodes) record.removedNodes = data.removedNodes;
    615       if (data.previousSibling) record.previousSibling = data.previousSibling;
    616       if (data.nextSibling) record.nextSibling = data.nextSibling;
    617       if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
    618       scheduleCallback(observer);
    619       observer.records_.push(record);
    620     }
    621   }
    622   var slice = Array.prototype.slice;
    623   function MutationObserverOptions(options) {
    624     this.childList = !!options.childList;
    625     this.subtree = !!options.subtree;
    626     if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
    627       this.attributes = true;
    628     } else {
    629       this.attributes = !!options.attributes;
    630     }
    631     if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
    632     if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
    633       throw new TypeError();
    634     }
    635     this.characterData = !!options.characterData;
    636     this.attributeOldValue = !!options.attributeOldValue;
    637     this.characterDataOldValue = !!options.characterDataOldValue;
    638     if ("attributeFilter" in options) {
    639       if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
    640         throw new TypeError();
    641       }
    642       this.attributeFilter = slice.call(options.attributeFilter);
    643     } else {
    644       this.attributeFilter = null;
    645     }
    646   }
    647   var uidCounter = 0;
    648   function MutationObserver(callback) {
    649     this.callback_ = callback;
    650     this.nodes_ = [];
    651     this.records_ = [];
    652     this.uid_ = ++uidCounter;
    653     this.scheduled_ = false;
    654   }
    655   MutationObserver.prototype = {
    656     constructor: MutationObserver,
    657     observe: function(target, options) {
    658       target = wrapIfNeeded(target);
    659       var newOptions = new MutationObserverOptions(options);
    660       var registration;
    661       var registrations = registrationsTable.get(target);
    662       if (!registrations) registrationsTable.set(target, registrations = []);
    663       for (var i = 0; i < registrations.length; i++) {
    664         if (registrations[i].observer === this) {
    665           registration = registrations[i];
    666           registration.removeTransientObservers();
    667           registration.options = newOptions;
    668         }
    669       }
    670       if (!registration) {
    671         registration = new Registration(this, target, newOptions);
    672         registrations.push(registration);
    673         this.nodes_.push(target);
    674       }
    675     },
    676     disconnect: function() {
    677       this.nodes_.forEach(function(node) {
    678         var registrations = registrationsTable.get(node);
    679         for (var i = 0; i < registrations.length; i++) {
    680           var registration = registrations[i];
    681           if (registration.observer === this) {
    682             registrations.splice(i, 1);
    683             break;
    684           }
    685         }
    686       }, this);
    687       this.records_ = [];
    688     },
    689     takeRecords: function() {
    690       var copyOfRecords = this.records_;
    691       this.records_ = [];
    692       return copyOfRecords;
    693     }
    694   };
    695   function Registration(observer, target, options) {
    696     this.observer = observer;
    697     this.target = target;
    698     this.options = options;
    699     this.transientObservedNodes = [];
    700   }
    701   Registration.prototype = {
    702     addTransientObserver: function(node) {
    703       if (node === this.target) return;
    704       scheduleCallback(this.observer);
    705       this.transientObservedNodes.push(node);
    706       var registrations = registrationsTable.get(node);
    707       if (!registrations) registrationsTable.set(node, registrations = []);
    708       registrations.push(this);
    709     },
    710     removeTransientObservers: function() {
    711       var transientObservedNodes = this.transientObservedNodes;
    712       this.transientObservedNodes = [];
    713       for (var i = 0; i < transientObservedNodes.length; i++) {
    714         var node = transientObservedNodes[i];
    715         var registrations = registrationsTable.get(node);
    716         for (var j = 0; j < registrations.length; j++) {
    717           if (registrations[j] === this) {
    718             registrations.splice(j, 1);
    719             break;
    720           }
    721         }
    722       }
    723     }
    724   };
    725   scope.enqueueMutation = enqueueMutation;
    726   scope.registerTransientObservers = registerTransientObservers;
    727   scope.wrappers.MutationObserver = MutationObserver;
    728   scope.wrappers.MutationRecord = MutationRecord;
    729 })(window.ShadowDOMPolyfill);
    730 
    731 (function(scope) {
    732   "use strict";
    733   function TreeScope(root, parent) {
    734     this.root = root;
    735     this.parent = parent;
    736   }
    737   TreeScope.prototype = {
    738     get renderer() {
    739       if (this.root instanceof scope.wrappers.ShadowRoot) {
    740         return scope.getRendererForHost(this.root.host);
    741       }
    742       return null;
    743     },
    744     contains: function(treeScope) {
    745       for (;treeScope; treeScope = treeScope.parent) {
    746         if (treeScope === this) return true;
    747       }
    748       return false;
    749     }
    750   };
    751   function setTreeScope(node, treeScope) {
    752     if (node.treeScope_ !== treeScope) {
    753       node.treeScope_ = treeScope;
    754       for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
    755         sr.treeScope_.parent = treeScope;
    756       }
    757       for (var child = node.firstChild; child; child = child.nextSibling) {
    758         setTreeScope(child, treeScope);
    759       }
    760     }
    761   }
    762   function getTreeScope(node) {
    763     if (node instanceof scope.wrappers.Window) {
    764       debugger;
    765     }
    766     if (node.treeScope_) return node.treeScope_;
    767     var parent = node.parentNode;
    768     var treeScope;
    769     if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
    770     return node.treeScope_ = treeScope;
    771   }
    772   scope.TreeScope = TreeScope;
    773   scope.getTreeScope = getTreeScope;
    774   scope.setTreeScope = setTreeScope;
    775 })(window.ShadowDOMPolyfill);
    776 
    777 (function(scope) {
    778   "use strict";
    779   var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
    780   var getTreeScope = scope.getTreeScope;
    781   var mixin = scope.mixin;
    782   var registerWrapper = scope.registerWrapper;
    783   var setWrapper = scope.setWrapper;
    784   var unsafeUnwrap = scope.unsafeUnwrap;
    785   var unwrap = scope.unwrap;
    786   var wrap = scope.wrap;
    787   var wrappers = scope.wrappers;
    788   var wrappedFuns = new WeakMap();
    789   var listenersTable = new WeakMap();
    790   var handledEventsTable = new WeakMap();
    791   var currentlyDispatchingEvents = new WeakMap();
    792   var targetTable = new WeakMap();
    793   var currentTargetTable = new WeakMap();
    794   var relatedTargetTable = new WeakMap();
    795   var eventPhaseTable = new WeakMap();
    796   var stopPropagationTable = new WeakMap();
    797   var stopImmediatePropagationTable = new WeakMap();
    798   var eventHandlersTable = new WeakMap();
    799   var eventPathTable = new WeakMap();
    800   function isShadowRoot(node) {
    801     return node instanceof wrappers.ShadowRoot;
    802   }
    803   function rootOfNode(node) {
    804     return getTreeScope(node).root;
    805   }
    806   function getEventPath(node, event) {
    807     var path = [];
    808     var current = node;
    809     path.push(current);
    810     while (current) {
    811       var destinationInsertionPoints = getDestinationInsertionPoints(current);
    812       if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
    813         for (var i = 0; i < destinationInsertionPoints.length; i++) {
    814           var insertionPoint = destinationInsertionPoints[i];
    815           if (isShadowInsertionPoint(insertionPoint)) {
    816             var shadowRoot = rootOfNode(insertionPoint);
    817             var olderShadowRoot = shadowRoot.olderShadowRoot;
    818             if (olderShadowRoot) path.push(olderShadowRoot);
    819           }
    820           path.push(insertionPoint);
    821         }
    822         current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
    823       } else {
    824         if (isShadowRoot(current)) {
    825           if (inSameTree(node, current) && eventMustBeStopped(event)) {
    826             break;
    827           }
    828           current = current.host;
    829           path.push(current);
    830         } else {
    831           current = current.parentNode;
    832           if (current) path.push(current);
    833         }
    834       }
    835     }
    836     return path;
    837   }
    838   function eventMustBeStopped(event) {
    839     if (!event) return false;
    840     switch (event.type) {
    841      case "abort":
    842      case "error":
    843      case "select":
    844      case "change":
    845      case "load":
    846      case "reset":
    847      case "resize":
    848      case "scroll":
    849      case "selectstart":
    850       return true;
    851     }
    852     return false;
    853   }
    854   function isShadowInsertionPoint(node) {
    855     return node instanceof HTMLShadowElement;
    856   }
    857   function getDestinationInsertionPoints(node) {
    858     return scope.getDestinationInsertionPoints(node);
    859   }
    860   function eventRetargetting(path, currentTarget) {
    861     if (path.length === 0) return currentTarget;
    862     if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
    863     var currentTargetTree = getTreeScope(currentTarget);
    864     var originalTarget = path[0];
    865     var originalTargetTree = getTreeScope(originalTarget);
    866     var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
    867     for (var i = 0; i < path.length; i++) {
    868       var node = path[i];
    869       if (getTreeScope(node) === relativeTargetTree) return node;
    870     }
    871     return path[path.length - 1];
    872   }
    873   function getTreeScopeAncestors(treeScope) {
    874     var ancestors = [];
    875     for (;treeScope; treeScope = treeScope.parent) {
    876       ancestors.push(treeScope);
    877     }
    878     return ancestors;
    879   }
    880   function lowestCommonInclusiveAncestor(tsA, tsB) {
    881     var ancestorsA = getTreeScopeAncestors(tsA);
    882     var ancestorsB = getTreeScopeAncestors(tsB);
    883     var result = null;
    884     while (ancestorsA.length > 0 && ancestorsB.length > 0) {
    885       var a = ancestorsA.pop();
    886       var b = ancestorsB.pop();
    887       if (a === b) result = a; else break;
    888     }
    889     return result;
    890   }
    891   function getTreeScopeRoot(ts) {
    892     if (!ts.parent) return ts;
    893     return getTreeScopeRoot(ts.parent);
    894   }
    895   function relatedTargetResolution(event, currentTarget, relatedTarget) {
    896     if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
    897     var currentTargetTree = getTreeScope(currentTarget);
    898     var relatedTargetTree = getTreeScope(relatedTarget);
    899     var relatedTargetEventPath = getEventPath(relatedTarget, event);
    900     var lowestCommonAncestorTree;
    901     var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
    902     if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
    903     for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
    904       var adjustedRelatedTarget;
    905       for (var i = 0; i < relatedTargetEventPath.length; i++) {
    906         var node = relatedTargetEventPath[i];
    907         if (getTreeScope(node) === commonAncestorTree) return node;
    908       }
    909     }
    910     return null;
    911   }
    912   function inSameTree(a, b) {
    913     return getTreeScope(a) === getTreeScope(b);
    914   }
    915   var NONE = 0;
    916   var CAPTURING_PHASE = 1;
    917   var AT_TARGET = 2;
    918   var BUBBLING_PHASE = 3;
    919   var pendingError;
    920   function dispatchOriginalEvent(originalEvent) {
    921     if (handledEventsTable.get(originalEvent)) return;
    922     handledEventsTable.set(originalEvent, true);
    923     dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
    924     if (pendingError) {
    925       var err = pendingError;
    926       pendingError = null;
    927       throw err;
    928     }
    929   }
    930   function isLoadLikeEvent(event) {
    931     switch (event.type) {
    932      case "load":
    933      case "beforeunload":
    934      case "unload":
    935       return true;
    936     }
    937     return false;
    938   }
    939   function dispatchEvent(event, originalWrapperTarget) {
    940     if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
    941     currentlyDispatchingEvents.set(event, true);
    942     scope.renderAllPending();
    943     var eventPath;
    944     var overrideTarget;
    945     var win;
    946     if (isLoadLikeEvent(event) && !event.bubbles) {
    947       var doc = originalWrapperTarget;
    948       if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
    949         overrideTarget = doc;
    950         eventPath = [];
    951       }
    952     }
    953     if (!eventPath) {
    954       if (originalWrapperTarget instanceof wrappers.Window) {
    955         win = originalWrapperTarget;
    956         eventPath = [];
    957       } else {
    958         eventPath = getEventPath(originalWrapperTarget, event);
    959         if (!isLoadLikeEvent(event)) {
    960           var doc = eventPath[eventPath.length - 1];
    961           if (doc instanceof wrappers.Document) win = doc.defaultView;
    962         }
    963       }
    964     }
    965     eventPathTable.set(event, eventPath);
    966     if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
    967       if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
    968         dispatchBubbling(event, eventPath, win, overrideTarget);
    969       }
    970     }
    971     eventPhaseTable.set(event, NONE);
    972     currentTargetTable.delete(event, null);
    973     currentlyDispatchingEvents.delete(event);
    974     return event.defaultPrevented;
    975   }
    976   function dispatchCapturing(event, eventPath, win, overrideTarget) {
    977     var phase = CAPTURING_PHASE;
    978     if (win) {
    979       if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
    980     }
    981     for (var i = eventPath.length - 1; i > 0; i--) {
    982       if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
    983     }
    984     return true;
    985   }
    986   function dispatchAtTarget(event, eventPath, win, overrideTarget) {
    987     var phase = AT_TARGET;
    988     var currentTarget = eventPath[0] || win;
    989     return invoke(currentTarget, event, phase, eventPath, overrideTarget);
    990   }
    991   function dispatchBubbling(event, eventPath, win, overrideTarget) {
    992     var phase = BUBBLING_PHASE;
    993     for (var i = 1; i < eventPath.length; i++) {
    994       if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
    995     }
    996     if (win && eventPath.length > 0) {
    997       invoke(win, event, phase, eventPath, overrideTarget);
    998     }
    999   }
   1000   function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
   1001     var listeners = listenersTable.get(currentTarget);
   1002     if (!listeners) return true;
   1003     var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
   1004     if (target === currentTarget) {
   1005       if (phase === CAPTURING_PHASE) return true;
   1006       if (phase === BUBBLING_PHASE) phase = AT_TARGET;
   1007     } else if (phase === BUBBLING_PHASE && !event.bubbles) {
   1008       return true;
   1009     }
   1010     if ("relatedTarget" in event) {
   1011       var originalEvent = unwrap(event);
   1012       var unwrappedRelatedTarget = originalEvent.relatedTarget;
   1013       if (unwrappedRelatedTarget) {
   1014         if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
   1015           var relatedTarget = wrap(unwrappedRelatedTarget);
   1016           var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
   1017           if (adjusted === target) return true;
   1018         } else {
   1019           adjusted = null;
   1020         }
   1021         relatedTargetTable.set(event, adjusted);
   1022       }
   1023     }
   1024     eventPhaseTable.set(event, phase);
   1025     var type = event.type;
   1026     var anyRemoved = false;
   1027     targetTable.set(event, target);
   1028     currentTargetTable.set(event, currentTarget);
   1029     listeners.depth++;
   1030     for (var i = 0, len = listeners.length; i < len; i++) {
   1031       var listener = listeners[i];
   1032       if (listener.removed) {
   1033         anyRemoved = true;
   1034         continue;
   1035       }
   1036       if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
   1037         continue;
   1038       }
   1039       try {
   1040         if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
   1041         if (stopImmediatePropagationTable.get(event)) return false;
   1042       } catch (ex) {
   1043         if (!pendingError) pendingError = ex;
   1044       }
   1045     }
   1046     listeners.depth--;
   1047     if (anyRemoved && listeners.depth === 0) {
   1048       var copy = listeners.slice();
   1049       listeners.length = 0;
   1050       for (var i = 0; i < copy.length; i++) {
   1051         if (!copy[i].removed) listeners.push(copy[i]);
   1052       }
   1053     }
   1054     return !stopPropagationTable.get(event);
   1055   }
   1056   function Listener(type, handler, capture) {
   1057     this.type = type;
   1058     this.handler = handler;
   1059     this.capture = Boolean(capture);
   1060   }
   1061   Listener.prototype = {
   1062     equals: function(that) {
   1063       return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
   1064     },
   1065     get removed() {
   1066       return this.handler === null;
   1067     },
   1068     remove: function() {
   1069       this.handler = null;
   1070     }
   1071   };
   1072   var OriginalEvent = window.Event;
   1073   OriginalEvent.prototype.polymerBlackList_ = {
   1074     returnValue: true,
   1075     keyLocation: true
   1076   };
   1077   function Event(type, options) {
   1078     if (type instanceof OriginalEvent) {
   1079       var impl = type;
   1080       if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
   1081         return new BeforeUnloadEvent(impl);
   1082       }
   1083       setWrapper(impl, this);
   1084     } else {
   1085       return wrap(constructEvent(OriginalEvent, "Event", type, options));
   1086     }
   1087   }
   1088   Event.prototype = {
   1089     get target() {
   1090       return targetTable.get(this);
   1091     },
   1092     get currentTarget() {
   1093       return currentTargetTable.get(this);
   1094     },
   1095     get eventPhase() {
   1096       return eventPhaseTable.get(this);
   1097     },
   1098     get path() {
   1099       var eventPath = eventPathTable.get(this);
   1100       if (!eventPath) return [];
   1101       return eventPath.slice();
   1102     },
   1103     stopPropagation: function() {
   1104       stopPropagationTable.set(this, true);
   1105     },
   1106     stopImmediatePropagation: function() {
   1107       stopPropagationTable.set(this, true);
   1108       stopImmediatePropagationTable.set(this, true);
   1109     }
   1110   };
   1111   registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
   1112   function unwrapOptions(options) {
   1113     if (!options || !options.relatedTarget) return options;
   1114     return Object.create(options, {
   1115       relatedTarget: {
   1116         value: unwrap(options.relatedTarget)
   1117       }
   1118     });
   1119   }
   1120   function registerGenericEvent(name, SuperEvent, prototype) {
   1121     var OriginalEvent = window[name];
   1122     var GenericEvent = function(type, options) {
   1123       if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
   1124     };
   1125     GenericEvent.prototype = Object.create(SuperEvent.prototype);
   1126     if (prototype) mixin(GenericEvent.prototype, prototype);
   1127     if (OriginalEvent) {
   1128       try {
   1129         registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
   1130       } catch (ex) {
   1131         registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
   1132       }
   1133     }
   1134     return GenericEvent;
   1135   }
   1136   var UIEvent = registerGenericEvent("UIEvent", Event);
   1137   var CustomEvent = registerGenericEvent("CustomEvent", Event);
   1138   var relatedTargetProto = {
   1139     get relatedTarget() {
   1140       var relatedTarget = relatedTargetTable.get(this);
   1141       if (relatedTarget !== undefined) return relatedTarget;
   1142       return wrap(unwrap(this).relatedTarget);
   1143     }
   1144   };
   1145   function getInitFunction(name, relatedTargetIndex) {
   1146     return function() {
   1147       arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
   1148       var impl = unwrap(this);
   1149       impl[name].apply(impl, arguments);
   1150     };
   1151   }
   1152   var mouseEventProto = mixin({
   1153     initMouseEvent: getInitFunction("initMouseEvent", 14)
   1154   }, relatedTargetProto);
   1155   var focusEventProto = mixin({
   1156     initFocusEvent: getInitFunction("initFocusEvent", 5)
   1157   }, relatedTargetProto);
   1158   var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
   1159   var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
   1160   var defaultInitDicts = Object.create(null);
   1161   var supportsEventConstructors = function() {
   1162     try {
   1163       new window.FocusEvent("focus");
   1164     } catch (ex) {
   1165       return false;
   1166     }
   1167     return true;
   1168   }();
   1169   function constructEvent(OriginalEvent, name, type, options) {
   1170     if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
   1171     var event = unwrap(document.createEvent(name));
   1172     var defaultDict = defaultInitDicts[name];
   1173     var args = [ type ];
   1174     Object.keys(defaultDict).forEach(function(key) {
   1175       var v = options != null && key in options ? options[key] : defaultDict[key];
   1176       if (key === "relatedTarget") v = unwrap(v);
   1177       args.push(v);
   1178     });
   1179     event["init" + name].apply(event, args);
   1180     return event;
   1181   }
   1182   if (!supportsEventConstructors) {
   1183     var configureEventConstructor = function(name, initDict, superName) {
   1184       if (superName) {
   1185         var superDict = defaultInitDicts[superName];
   1186         initDict = mixin(mixin({}, superDict), initDict);
   1187       }
   1188       defaultInitDicts[name] = initDict;
   1189     };
   1190     configureEventConstructor("Event", {
   1191       bubbles: false,
   1192       cancelable: false
   1193     });
   1194     configureEventConstructor("CustomEvent", {
   1195       detail: null
   1196     }, "Event");
   1197     configureEventConstructor("UIEvent", {
   1198       view: null,
   1199       detail: 0
   1200     }, "Event");
   1201     configureEventConstructor("MouseEvent", {
   1202       screenX: 0,
   1203       screenY: 0,
   1204       clientX: 0,
   1205       clientY: 0,
   1206       ctrlKey: false,
   1207       altKey: false,
   1208       shiftKey: false,
   1209       metaKey: false,
   1210       button: 0,
   1211       relatedTarget: null
   1212     }, "UIEvent");
   1213     configureEventConstructor("FocusEvent", {
   1214       relatedTarget: null
   1215     }, "UIEvent");
   1216   }
   1217   var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
   1218   function BeforeUnloadEvent(impl) {
   1219     Event.call(this, impl);
   1220   }
   1221   BeforeUnloadEvent.prototype = Object.create(Event.prototype);
   1222   mixin(BeforeUnloadEvent.prototype, {
   1223     get returnValue() {
   1224       return unsafeUnwrap(this).returnValue;
   1225     },
   1226     set returnValue(v) {
   1227       unsafeUnwrap(this).returnValue = v;
   1228     }
   1229   });
   1230   if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
   1231   function isValidListener(fun) {
   1232     if (typeof fun === "function") return true;
   1233     return fun && fun.handleEvent;
   1234   }
   1235   function isMutationEvent(type) {
   1236     switch (type) {
   1237      case "DOMAttrModified":
   1238      case "DOMAttributeNameChanged":
   1239      case "DOMCharacterDataModified":
   1240      case "DOMElementNameChanged":
   1241      case "DOMNodeInserted":
   1242      case "DOMNodeInsertedIntoDocument":
   1243      case "DOMNodeRemoved":
   1244      case "DOMNodeRemovedFromDocument":
   1245      case "DOMSubtreeModified":
   1246       return true;
   1247     }
   1248     return false;
   1249   }
   1250   var OriginalEventTarget = window.EventTarget;
   1251   function EventTarget(impl) {
   1252     setWrapper(impl, this);
   1253   }
   1254   var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
   1255   [ Node, Window ].forEach(function(constructor) {
   1256     var p = constructor.prototype;
   1257     methodNames.forEach(function(name) {
   1258       Object.defineProperty(p, name + "_", {
   1259         value: p[name]
   1260       });
   1261     });
   1262   });
   1263   function getTargetToListenAt(wrapper) {
   1264     if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
   1265     return unwrap(wrapper);
   1266   }
   1267   EventTarget.prototype = {
   1268     addEventListener: function(type, fun, capture) {
   1269       if (!isValidListener(fun) || isMutationEvent(type)) return;
   1270       var listener = new Listener(type, fun, capture);
   1271       var listeners = listenersTable.get(this);
   1272       if (!listeners) {
   1273         listeners = [];
   1274         listeners.depth = 0;
   1275         listenersTable.set(this, listeners);
   1276       } else {
   1277         for (var i = 0; i < listeners.length; i++) {
   1278           if (listener.equals(listeners[i])) return;
   1279         }
   1280       }
   1281       listeners.push(listener);
   1282       var target = getTargetToListenAt(this);
   1283       target.addEventListener_(type, dispatchOriginalEvent, true);
   1284     },
   1285     removeEventListener: function(type, fun, capture) {
   1286       capture = Boolean(capture);
   1287       var listeners = listenersTable.get(this);
   1288       if (!listeners) return;
   1289       var count = 0, found = false;
   1290       for (var i = 0; i < listeners.length; i++) {
   1291         if (listeners[i].type === type && listeners[i].capture === capture) {
   1292           count++;
   1293           if (listeners[i].handler === fun) {
   1294             found = true;
   1295             listeners[i].remove();
   1296           }
   1297         }
   1298       }
   1299       if (found && count === 1) {
   1300         var target = getTargetToListenAt(this);
   1301         target.removeEventListener_(type, dispatchOriginalEvent, true);
   1302       }
   1303     },
   1304     dispatchEvent: function(event) {
   1305       var nativeEvent = unwrap(event);
   1306       var eventType = nativeEvent.type;
   1307       handledEventsTable.set(nativeEvent, false);
   1308       scope.renderAllPending();
   1309       var tempListener;
   1310       if (!hasListenerInAncestors(this, eventType)) {
   1311         tempListener = function() {};
   1312         this.addEventListener(eventType, tempListener, true);
   1313       }
   1314       try {
   1315         return unwrap(this).dispatchEvent_(nativeEvent);
   1316       } finally {
   1317         if (tempListener) this.removeEventListener(eventType, tempListener, true);
   1318       }
   1319     }
   1320   };
   1321   function hasListener(node, type) {
   1322     var listeners = listenersTable.get(node);
   1323     if (listeners) {
   1324       for (var i = 0; i < listeners.length; i++) {
   1325         if (!listeners[i].removed && listeners[i].type === type) return true;
   1326       }
   1327     }
   1328     return false;
   1329   }
   1330   function hasListenerInAncestors(target, type) {
   1331     for (var node = unwrap(target); node; node = node.parentNode) {
   1332       if (hasListener(wrap(node), type)) return true;
   1333     }
   1334     return false;
   1335   }
   1336   if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
   1337   function wrapEventTargetMethods(constructors) {
   1338     forwardMethodsToWrapper(constructors, methodNames);
   1339   }
   1340   var originalElementFromPoint = document.elementFromPoint;
   1341   function elementFromPoint(self, document, x, y) {
   1342     scope.renderAllPending();
   1343     var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
   1344     if (!element) return null;
   1345     var path = getEventPath(element, null);
   1346     var idx = path.lastIndexOf(self);
   1347     if (idx == -1) return null; else path = path.slice(0, idx);
   1348     return eventRetargetting(path, self);
   1349   }
   1350   function getEventHandlerGetter(name) {
   1351     return function() {
   1352       var inlineEventHandlers = eventHandlersTable.get(this);
   1353       return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
   1354     };
   1355   }
   1356   function getEventHandlerSetter(name) {
   1357     var eventType = name.slice(2);
   1358     return function(value) {
   1359       var inlineEventHandlers = eventHandlersTable.get(this);
   1360       if (!inlineEventHandlers) {
   1361         inlineEventHandlers = Object.create(null);
   1362         eventHandlersTable.set(this, inlineEventHandlers);
   1363       }
   1364       var old = inlineEventHandlers[name];
   1365       if (old) this.removeEventListener(eventType, old.wrapped, false);
   1366       if (typeof value === "function") {
   1367         var wrapped = function(e) {
   1368           var rv = value.call(this, e);
   1369           if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
   1370         };
   1371         this.addEventListener(eventType, wrapped, false);
   1372         inlineEventHandlers[name] = {
   1373           value: value,
   1374           wrapped: wrapped
   1375         };
   1376       }
   1377     };
   1378   }
   1379   scope.elementFromPoint = elementFromPoint;
   1380   scope.getEventHandlerGetter = getEventHandlerGetter;
   1381   scope.getEventHandlerSetter = getEventHandlerSetter;
   1382   scope.wrapEventTargetMethods = wrapEventTargetMethods;
   1383   scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
   1384   scope.wrappers.CustomEvent = CustomEvent;
   1385   scope.wrappers.Event = Event;
   1386   scope.wrappers.EventTarget = EventTarget;
   1387   scope.wrappers.FocusEvent = FocusEvent;
   1388   scope.wrappers.MouseEvent = MouseEvent;
   1389   scope.wrappers.UIEvent = UIEvent;
   1390 })(window.ShadowDOMPolyfill);
   1391 
   1392 (function(scope) {
   1393   "use strict";
   1394   var UIEvent = scope.wrappers.UIEvent;
   1395   var mixin = scope.mixin;
   1396   var registerWrapper = scope.registerWrapper;
   1397   var setWrapper = scope.setWrapper;
   1398   var unsafeUnwrap = scope.unsafeUnwrap;
   1399   var wrap = scope.wrap;
   1400   var OriginalTouchEvent = window.TouchEvent;
   1401   if (!OriginalTouchEvent) return;
   1402   var nativeEvent;
   1403   try {
   1404     nativeEvent = document.createEvent("TouchEvent");
   1405   } catch (ex) {
   1406     return;
   1407   }
   1408   var nonEnumDescriptor = {
   1409     enumerable: false
   1410   };
   1411   function nonEnum(obj, prop) {
   1412     Object.defineProperty(obj, prop, nonEnumDescriptor);
   1413   }
   1414   function Touch(impl) {
   1415     setWrapper(impl, this);
   1416   }
   1417   Touch.prototype = {
   1418     get target() {
   1419       return wrap(unsafeUnwrap(this).target);
   1420     }
   1421   };
   1422   var descr = {
   1423     configurable: true,
   1424     enumerable: true,
   1425     get: null
   1426   };
   1427   [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
   1428     descr.get = function() {
   1429       return unsafeUnwrap(this)[name];
   1430     };
   1431     Object.defineProperty(Touch.prototype, name, descr);
   1432   });
   1433   function TouchList() {
   1434     this.length = 0;
   1435     nonEnum(this, "length");
   1436   }
   1437   TouchList.prototype = {
   1438     item: function(index) {
   1439       return this[index];
   1440     }
   1441   };
   1442   function wrapTouchList(nativeTouchList) {
   1443     var list = new TouchList();
   1444     for (var i = 0; i < nativeTouchList.length; i++) {
   1445       list[i] = new Touch(nativeTouchList[i]);
   1446     }
   1447     list.length = i;
   1448     return list;
   1449   }
   1450   function TouchEvent(impl) {
   1451     UIEvent.call(this, impl);
   1452   }
   1453   TouchEvent.prototype = Object.create(UIEvent.prototype);
   1454   mixin(TouchEvent.prototype, {
   1455     get touches() {
   1456       return wrapTouchList(unsafeUnwrap(this).touches);
   1457     },
   1458     get targetTouches() {
   1459       return wrapTouchList(unsafeUnwrap(this).targetTouches);
   1460     },
   1461     get changedTouches() {
   1462       return wrapTouchList(unsafeUnwrap(this).changedTouches);
   1463     },
   1464     initTouchEvent: function() {
   1465       throw new Error("Not implemented");
   1466     }
   1467   });
   1468   registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
   1469   scope.wrappers.Touch = Touch;
   1470   scope.wrappers.TouchEvent = TouchEvent;
   1471   scope.wrappers.TouchList = TouchList;
   1472 })(window.ShadowDOMPolyfill);
   1473 
   1474 (function(scope) {
   1475   "use strict";
   1476   var unsafeUnwrap = scope.unsafeUnwrap;
   1477   var wrap = scope.wrap;
   1478   var nonEnumDescriptor = {
   1479     enumerable: false
   1480   };
   1481   function nonEnum(obj, prop) {
   1482     Object.defineProperty(obj, prop, nonEnumDescriptor);
   1483   }
   1484   function NodeList() {
   1485     this.length = 0;
   1486     nonEnum(this, "length");
   1487   }
   1488   NodeList.prototype = {
   1489     item: function(index) {
   1490       return this[index];
   1491     }
   1492   };
   1493   nonEnum(NodeList.prototype, "item");
   1494   function wrapNodeList(list) {
   1495     if (list == null) return list;
   1496     var wrapperList = new NodeList();
   1497     for (var i = 0, length = list.length; i < length; i++) {
   1498       wrapperList[i] = wrap(list[i]);
   1499     }
   1500     wrapperList.length = length;
   1501     return wrapperList;
   1502   }
   1503   function addWrapNodeListMethod(wrapperConstructor, name) {
   1504     wrapperConstructor.prototype[name] = function() {
   1505       return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
   1506     };
   1507   }
   1508   scope.wrappers.NodeList = NodeList;
   1509   scope.addWrapNodeListMethod = addWrapNodeListMethod;
   1510   scope.wrapNodeList = wrapNodeList;
   1511 })(window.ShadowDOMPolyfill);
   1512 
   1513 (function(scope) {
   1514   "use strict";
   1515   scope.wrapHTMLCollection = scope.wrapNodeList;
   1516   scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
   1517 })(window.ShadowDOMPolyfill);
   1518 
   1519 (function(scope) {
   1520   "use strict";
   1521   var EventTarget = scope.wrappers.EventTarget;
   1522   var NodeList = scope.wrappers.NodeList;
   1523   var TreeScope = scope.TreeScope;
   1524   var assert = scope.assert;
   1525   var defineWrapGetter = scope.defineWrapGetter;
   1526   var enqueueMutation = scope.enqueueMutation;
   1527   var getTreeScope = scope.getTreeScope;
   1528   var isWrapper = scope.isWrapper;
   1529   var mixin = scope.mixin;
   1530   var registerTransientObservers = scope.registerTransientObservers;
   1531   var registerWrapper = scope.registerWrapper;
   1532   var setTreeScope = scope.setTreeScope;
   1533   var unsafeUnwrap = scope.unsafeUnwrap;
   1534   var unwrap = scope.unwrap;
   1535   var unwrapIfNeeded = scope.unwrapIfNeeded;
   1536   var wrap = scope.wrap;
   1537   var wrapIfNeeded = scope.wrapIfNeeded;
   1538   var wrappers = scope.wrappers;
   1539   function assertIsNodeWrapper(node) {
   1540     assert(node instanceof Node);
   1541   }
   1542   function createOneElementNodeList(node) {
   1543     var nodes = new NodeList();
   1544     nodes[0] = node;
   1545     nodes.length = 1;
   1546     return nodes;
   1547   }
   1548   var surpressMutations = false;
   1549   function enqueueRemovalForInsertedNodes(node, parent, nodes) {
   1550     enqueueMutation(parent, "childList", {
   1551       removedNodes: nodes,
   1552       previousSibling: node.previousSibling,
   1553       nextSibling: node.nextSibling
   1554     });
   1555   }
   1556   function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
   1557     enqueueMutation(df, "childList", {
   1558       removedNodes: nodes
   1559     });
   1560   }
   1561   function collectNodes(node, parentNode, previousNode, nextNode) {
   1562     if (node instanceof DocumentFragment) {
   1563       var nodes = collectNodesForDocumentFragment(node);
   1564       surpressMutations = true;
   1565       for (var i = nodes.length - 1; i >= 0; i--) {
   1566         node.removeChild(nodes[i]);
   1567         nodes[i].parentNode_ = parentNode;
   1568       }
   1569       surpressMutations = false;
   1570       for (var i = 0; i < nodes.length; i++) {
   1571         nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
   1572         nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
   1573       }
   1574       if (previousNode) previousNode.nextSibling_ = nodes[0];
   1575       if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
   1576       return nodes;
   1577     }
   1578     var nodes = createOneElementNodeList(node);
   1579     var oldParent = node.parentNode;
   1580     if (oldParent) {
   1581       oldParent.removeChild(node);
   1582     }
   1583     node.parentNode_ = parentNode;
   1584     node.previousSibling_ = previousNode;
   1585     node.nextSibling_ = nextNode;
   1586     if (previousNode) previousNode.nextSibling_ = node;
   1587     if (nextNode) nextNode.previousSibling_ = node;
   1588     return nodes;
   1589   }
   1590   function collectNodesNative(node) {
   1591     if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
   1592     var nodes = createOneElementNodeList(node);
   1593     var oldParent = node.parentNode;
   1594     if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
   1595     return nodes;
   1596   }
   1597   function collectNodesForDocumentFragment(node) {
   1598     var nodes = new NodeList();
   1599     var i = 0;
   1600     for (var child = node.firstChild; child; child = child.nextSibling) {
   1601       nodes[i++] = child;
   1602     }
   1603     nodes.length = i;
   1604     enqueueRemovalForInsertedDocumentFragment(node, nodes);
   1605     return nodes;
   1606   }
   1607   function snapshotNodeList(nodeList) {
   1608     return nodeList;
   1609   }
   1610   function nodeWasAdded(node, treeScope) {
   1611     setTreeScope(node, treeScope);
   1612     node.nodeIsInserted_();
   1613   }
   1614   function nodesWereAdded(nodes, parent) {
   1615     var treeScope = getTreeScope(parent);
   1616     for (var i = 0; i < nodes.length; i++) {
   1617       nodeWasAdded(nodes[i], treeScope);
   1618     }
   1619   }
   1620   function nodeWasRemoved(node) {
   1621     setTreeScope(node, new TreeScope(node, null));
   1622   }
   1623   function nodesWereRemoved(nodes) {
   1624     for (var i = 0; i < nodes.length; i++) {
   1625       nodeWasRemoved(nodes[i]);
   1626     }
   1627   }
   1628   function ensureSameOwnerDocument(parent, child) {
   1629     var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
   1630     if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
   1631   }
   1632   function adoptNodesIfNeeded(owner, nodes) {
   1633     if (!nodes.length) return;
   1634     var ownerDoc = owner.ownerDocument;
   1635     if (ownerDoc === nodes[0].ownerDocument) return;
   1636     for (var i = 0; i < nodes.length; i++) {
   1637       scope.adoptNodeNoRemove(nodes[i], ownerDoc);
   1638     }
   1639   }
   1640   function unwrapNodesForInsertion(owner, nodes) {
   1641     adoptNodesIfNeeded(owner, nodes);
   1642     var length = nodes.length;
   1643     if (length === 1) return unwrap(nodes[0]);
   1644     var df = unwrap(owner.ownerDocument.createDocumentFragment());
   1645     for (var i = 0; i < length; i++) {
   1646       df.appendChild(unwrap(nodes[i]));
   1647     }
   1648     return df;
   1649   }
   1650   function clearChildNodes(wrapper) {
   1651     if (wrapper.firstChild_ !== undefined) {
   1652       var child = wrapper.firstChild_;
   1653       while (child) {
   1654         var tmp = child;
   1655         child = child.nextSibling_;
   1656         tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
   1657       }
   1658     }
   1659     wrapper.firstChild_ = wrapper.lastChild_ = undefined;
   1660   }
   1661   function removeAllChildNodes(wrapper) {
   1662     if (wrapper.invalidateShadowRenderer()) {
   1663       var childWrapper = wrapper.firstChild;
   1664       while (childWrapper) {
   1665         assert(childWrapper.parentNode === wrapper);
   1666         var nextSibling = childWrapper.nextSibling;
   1667         var childNode = unwrap(childWrapper);
   1668         var parentNode = childNode.parentNode;
   1669         if (parentNode) originalRemoveChild.call(parentNode, childNode);
   1670         childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
   1671         childWrapper = nextSibling;
   1672       }
   1673       wrapper.firstChild_ = wrapper.lastChild_ = null;
   1674     } else {
   1675       var node = unwrap(wrapper);
   1676       var child = node.firstChild;
   1677       var nextSibling;
   1678       while (child) {
   1679         nextSibling = child.nextSibling;
   1680         originalRemoveChild.call(node, child);
   1681         child = nextSibling;
   1682       }
   1683     }
   1684   }
   1685   function invalidateParent(node) {
   1686     var p = node.parentNode;
   1687     return p && p.invalidateShadowRenderer();
   1688   }
   1689   function cleanupNodes(nodes) {
   1690     for (var i = 0, n; i < nodes.length; i++) {
   1691       n = nodes[i];
   1692       n.parentNode.removeChild(n);
   1693     }
   1694   }
   1695   var originalImportNode = document.importNode;
   1696   var originalCloneNode = window.Node.prototype.cloneNode;
   1697   function cloneNode(node, deep, opt_doc) {
   1698     var clone;
   1699     if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
   1700     if (deep) {
   1701       for (var child = node.firstChild; child; child = child.nextSibling) {
   1702         clone.appendChild(cloneNode(child, true, opt_doc));
   1703       }
   1704       if (node instanceof wrappers.HTMLTemplateElement) {
   1705         var cloneContent = clone.content;
   1706         for (var child = node.content.firstChild; child; child = child.nextSibling) {
   1707           cloneContent.appendChild(cloneNode(child, true, opt_doc));
   1708         }
   1709       }
   1710     }
   1711     return clone;
   1712   }
   1713   function contains(self, child) {
   1714     if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
   1715     for (var node = child; node; node = node.parentNode) {
   1716       if (node === self) return true;
   1717     }
   1718     return false;
   1719   }
   1720   var OriginalNode = window.Node;
   1721   function Node(original) {
   1722     assert(original instanceof OriginalNode);
   1723     EventTarget.call(this, original);
   1724     this.parentNode_ = undefined;
   1725     this.firstChild_ = undefined;
   1726     this.lastChild_ = undefined;
   1727     this.nextSibling_ = undefined;
   1728     this.previousSibling_ = undefined;
   1729     this.treeScope_ = undefined;
   1730   }
   1731   var OriginalDocumentFragment = window.DocumentFragment;
   1732   var originalAppendChild = OriginalNode.prototype.appendChild;
   1733   var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
   1734   var originalInsertBefore = OriginalNode.prototype.insertBefore;
   1735   var originalRemoveChild = OriginalNode.prototype.removeChild;
   1736   var originalReplaceChild = OriginalNode.prototype.replaceChild;
   1737   var isIe = /Trident|Edge/.test(navigator.userAgent);
   1738   var removeChildOriginalHelper = isIe ? function(parent, child) {
   1739     try {
   1740       originalRemoveChild.call(parent, child);
   1741     } catch (ex) {
   1742       if (!(parent instanceof OriginalDocumentFragment)) throw ex;
   1743     }
   1744   } : function(parent, child) {
   1745     originalRemoveChild.call(parent, child);
   1746   };
   1747   Node.prototype = Object.create(EventTarget.prototype);
   1748   mixin(Node.prototype, {
   1749     appendChild: function(childWrapper) {
   1750       return this.insertBefore(childWrapper, null);
   1751     },
   1752     insertBefore: function(childWrapper, refWrapper) {
   1753       assertIsNodeWrapper(childWrapper);
   1754       var refNode;
   1755       if (refWrapper) {
   1756         if (isWrapper(refWrapper)) {
   1757           refNode = unwrap(refWrapper);
   1758         } else {
   1759           refNode = refWrapper;
   1760           refWrapper = wrap(refNode);
   1761         }
   1762       } else {
   1763         refWrapper = null;
   1764         refNode = null;
   1765       }
   1766       refWrapper && assert(refWrapper.parentNode === this);
   1767       var nodes;
   1768       var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
   1769       var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
   1770       if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
   1771       if (useNative) {
   1772         ensureSameOwnerDocument(this, childWrapper);
   1773         clearChildNodes(this);
   1774         originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
   1775       } else {
   1776         if (!previousNode) this.firstChild_ = nodes[0];
   1777         if (!refWrapper) {
   1778           this.lastChild_ = nodes[nodes.length - 1];
   1779           if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
   1780         }
   1781         var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
   1782         if (parentNode) {
   1783           originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
   1784         } else {
   1785           adoptNodesIfNeeded(this, nodes);
   1786         }
   1787       }
   1788       enqueueMutation(this, "childList", {
   1789         addedNodes: nodes,
   1790         nextSibling: refWrapper,
   1791         previousSibling: previousNode
   1792       });
   1793       nodesWereAdded(nodes, this);
   1794       return childWrapper;
   1795     },
   1796     removeChild: function(childWrapper) {
   1797       assertIsNodeWrapper(childWrapper);
   1798       if (childWrapper.parentNode !== this) {
   1799         var found = false;
   1800         var childNodes = this.childNodes;
   1801         for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
   1802           if (ieChild === childWrapper) {
   1803             found = true;
   1804             break;
   1805           }
   1806         }
   1807         if (!found) {
   1808           throw new Error("NotFoundError");
   1809         }
   1810       }
   1811       var childNode = unwrap(childWrapper);
   1812       var childWrapperNextSibling = childWrapper.nextSibling;
   1813       var childWrapperPreviousSibling = childWrapper.previousSibling;
   1814       if (this.invalidateShadowRenderer()) {
   1815         var thisFirstChild = this.firstChild;
   1816         var thisLastChild = this.lastChild;
   1817         var parentNode = childNode.parentNode;
   1818         if (parentNode) removeChildOriginalHelper(parentNode, childNode);
   1819         if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
   1820         if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
   1821         if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
   1822         if (childWrapperNextSibling) {
   1823           childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
   1824         }
   1825         childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
   1826       } else {
   1827         clearChildNodes(this);
   1828         removeChildOriginalHelper(unsafeUnwrap(this), childNode);
   1829       }
   1830       if (!surpressMutations) {
   1831         enqueueMutation(this, "childList", {
   1832           removedNodes: createOneElementNodeList(childWrapper),
   1833           nextSibling: childWrapperNextSibling,
   1834           previousSibling: childWrapperPreviousSibling
   1835         });
   1836       }
   1837       registerTransientObservers(this, childWrapper);
   1838       return childWrapper;
   1839     },
   1840     replaceChild: function(newChildWrapper, oldChildWrapper) {
   1841       assertIsNodeWrapper(newChildWrapper);
   1842       var oldChildNode;
   1843       if (isWrapper(oldChildWrapper)) {
   1844         oldChildNode = unwrap(oldChildWrapper);
   1845       } else {
   1846         oldChildNode = oldChildWrapper;
   1847         oldChildWrapper = wrap(oldChildNode);
   1848       }
   1849       if (oldChildWrapper.parentNode !== this) {
   1850         throw new Error("NotFoundError");
   1851       }
   1852       var nextNode = oldChildWrapper.nextSibling;
   1853       var previousNode = oldChildWrapper.previousSibling;
   1854       var nodes;
   1855       var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
   1856       if (useNative) {
   1857         nodes = collectNodesNative(newChildWrapper);
   1858       } else {
   1859         if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
   1860         nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
   1861       }
   1862       if (!useNative) {
   1863         if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
   1864         if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
   1865         oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
   1866         if (oldChildNode.parentNode) {
   1867           originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
   1868         }
   1869       } else {
   1870         ensureSameOwnerDocument(this, newChildWrapper);
   1871         clearChildNodes(this);
   1872         originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
   1873       }
   1874       enqueueMutation(this, "childList", {
   1875         addedNodes: nodes,
   1876         removedNodes: createOneElementNodeList(oldChildWrapper),
   1877         nextSibling: nextNode,
   1878         previousSibling: previousNode
   1879       });
   1880       nodeWasRemoved(oldChildWrapper);
   1881       nodesWereAdded(nodes, this);
   1882       return oldChildWrapper;
   1883     },
   1884     nodeIsInserted_: function() {
   1885       for (var child = this.firstChild; child; child = child.nextSibling) {
   1886         child.nodeIsInserted_();
   1887       }
   1888     },
   1889     hasChildNodes: function() {
   1890       return this.firstChild !== null;
   1891     },
   1892     get parentNode() {
   1893       return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
   1894     },
   1895     get firstChild() {
   1896       return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
   1897     },
   1898     get lastChild() {
   1899       return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
   1900     },
   1901     get nextSibling() {
   1902       return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
   1903     },
   1904     get previousSibling() {
   1905       return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
   1906     },
   1907     get parentElement() {
   1908       var p = this.parentNode;
   1909       while (p && p.nodeType !== Node.ELEMENT_NODE) {
   1910         p = p.parentNode;
   1911       }
   1912       return p;
   1913     },
   1914     get textContent() {
   1915       var s = "";
   1916       for (var child = this.firstChild; child; child = child.nextSibling) {
   1917         if (child.nodeType != Node.COMMENT_NODE) {
   1918           s += child.textContent;
   1919         }
   1920       }
   1921       return s;
   1922     },
   1923     set textContent(textContent) {
   1924       if (textContent == null) textContent = "";
   1925       var removedNodes = snapshotNodeList(this.childNodes);
   1926       if (this.invalidateShadowRenderer()) {
   1927         removeAllChildNodes(this);
   1928         if (textContent !== "") {
   1929           var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
   1930           this.appendChild(textNode);
   1931         }
   1932       } else {
   1933         clearChildNodes(this);
   1934         unsafeUnwrap(this).textContent = textContent;
   1935       }
   1936       var addedNodes = snapshotNodeList(this.childNodes);
   1937       enqueueMutation(this, "childList", {
   1938         addedNodes: addedNodes,
   1939         removedNodes: removedNodes
   1940       });
   1941       nodesWereRemoved(removedNodes);
   1942       nodesWereAdded(addedNodes, this);
   1943     },
   1944     get childNodes() {
   1945       var wrapperList = new NodeList();
   1946       var i = 0;
   1947       for (var child = this.firstChild; child; child = child.nextSibling) {
   1948         wrapperList[i++] = child;
   1949       }
   1950       wrapperList.length = i;
   1951       return wrapperList;
   1952     },
   1953     cloneNode: function(deep) {
   1954       return cloneNode(this, deep);
   1955     },
   1956     contains: function(child) {
   1957       return contains(this, wrapIfNeeded(child));
   1958     },
   1959     compareDocumentPosition: function(otherNode) {
   1960       return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
   1961     },
   1962     normalize: function() {
   1963       var nodes = snapshotNodeList(this.childNodes);
   1964       var remNodes = [];
   1965       var s = "";
   1966       var modNode;
   1967       for (var i = 0, n; i < nodes.length; i++) {
   1968         n = nodes[i];
   1969         if (n.nodeType === Node.TEXT_NODE) {
   1970           if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
   1971             s += n.data;
   1972             remNodes.push(n);
   1973           }
   1974         } else {
   1975           if (modNode && remNodes.length) {
   1976             modNode.data += s;
   1977             cleanupNodes(remNodes);
   1978           }
   1979           remNodes = [];
   1980           s = "";
   1981           modNode = null;
   1982           if (n.childNodes.length) n.normalize();
   1983         }
   1984       }
   1985       if (modNode && remNodes.length) {
   1986         modNode.data += s;
   1987         cleanupNodes(remNodes);
   1988       }
   1989     }
   1990   });
   1991   defineWrapGetter(Node, "ownerDocument");
   1992   registerWrapper(OriginalNode, Node, document.createDocumentFragment());
   1993   delete Node.prototype.querySelector;
   1994   delete Node.prototype.querySelectorAll;
   1995   Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
   1996   scope.cloneNode = cloneNode;
   1997   scope.nodeWasAdded = nodeWasAdded;
   1998   scope.nodeWasRemoved = nodeWasRemoved;
   1999   scope.nodesWereAdded = nodesWereAdded;
   2000   scope.nodesWereRemoved = nodesWereRemoved;
   2001   scope.originalInsertBefore = originalInsertBefore;
   2002   scope.originalRemoveChild = originalRemoveChild;
   2003   scope.snapshotNodeList = snapshotNodeList;
   2004   scope.wrappers.Node = Node;
   2005 })(window.ShadowDOMPolyfill);
   2006 
   2007 (function(scope) {
   2008   "use strict";
   2009   var HTMLCollection = scope.wrappers.HTMLCollection;
   2010   var NodeList = scope.wrappers.NodeList;
   2011   var getTreeScope = scope.getTreeScope;
   2012   var unsafeUnwrap = scope.unsafeUnwrap;
   2013   var wrap = scope.wrap;
   2014   var originalDocumentQuerySelector = document.querySelector;
   2015   var originalElementQuerySelector = document.documentElement.querySelector;
   2016   var originalDocumentQuerySelectorAll = document.querySelectorAll;
   2017   var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
   2018   var originalDocumentGetElementsByTagName = document.getElementsByTagName;
   2019   var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
   2020   var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
   2021   var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
   2022   var OriginalElement = window.Element;
   2023   var OriginalDocument = window.HTMLDocument || window.Document;
   2024   function filterNodeList(list, index, result, deep) {
   2025     var wrappedItem = null;
   2026     var root = null;
   2027     for (var i = 0, length = list.length; i < length; i++) {
   2028       wrappedItem = wrap(list[i]);
   2029       if (!deep && (root = getTreeScope(wrappedItem).root)) {
   2030         if (root instanceof scope.wrappers.ShadowRoot) {
   2031           continue;
   2032         }
   2033       }
   2034       result[index++] = wrappedItem;
   2035     }
   2036     return index;
   2037   }
   2038   function shimSelector(selector) {
   2039     return String(selector).replace(/\/deep\/|::shadow/g, " ");
   2040   }
   2041   function shimMatchesSelector(selector) {
   2042     return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content/g, " ");
   2043   }
   2044   function findOne(node, selector) {
   2045     var m, el = node.firstElementChild;
   2046     while (el) {
   2047       if (el.matches(selector)) return el;
   2048       m = findOne(el, selector);
   2049       if (m) return m;
   2050       el = el.nextElementSibling;
   2051     }
   2052     return null;
   2053   }
   2054   function matchesSelector(el, selector) {
   2055     return el.matches(selector);
   2056   }
   2057   var XHTML_NS = "http://www.w3.org/1999/xhtml";
   2058   function matchesTagName(el, localName, localNameLowerCase) {
   2059     var ln = el.localName;
   2060     return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
   2061   }
   2062   function matchesEveryThing() {
   2063     return true;
   2064   }
   2065   function matchesLocalNameOnly(el, ns, localName) {
   2066     return el.localName === localName;
   2067   }
   2068   function matchesNameSpace(el, ns) {
   2069     return el.namespaceURI === ns;
   2070   }
   2071   function matchesLocalNameNS(el, ns, localName) {
   2072     return el.namespaceURI === ns && el.localName === localName;
   2073   }
   2074   function findElements(node, index, result, p, arg0, arg1) {
   2075     var el = node.firstElementChild;
   2076     while (el) {
   2077       if (p(el, arg0, arg1)) result[index++] = el;
   2078       index = findElements(el, index, result, p, arg0, arg1);
   2079       el = el.nextElementSibling;
   2080     }
   2081     return index;
   2082   }
   2083   function querySelectorAllFiltered(p, index, result, selector, deep) {
   2084     var target = unsafeUnwrap(this);
   2085     var list;
   2086     var root = getTreeScope(this).root;
   2087     if (root instanceof scope.wrappers.ShadowRoot) {
   2088       return findElements(this, index, result, p, selector, null);
   2089     } else if (target instanceof OriginalElement) {
   2090       list = originalElementQuerySelectorAll.call(target, selector);
   2091     } else if (target instanceof OriginalDocument) {
   2092       list = originalDocumentQuerySelectorAll.call(target, selector);
   2093     } else {
   2094       return findElements(this, index, result, p, selector, null);
   2095     }
   2096     return filterNodeList(list, index, result, deep);
   2097   }
   2098   var SelectorsInterface = {
   2099     querySelector: function(selector) {
   2100       var shimmed = shimSelector(selector);
   2101       var deep = shimmed !== selector;
   2102       selector = shimmed;
   2103       var target = unsafeUnwrap(this);
   2104       var wrappedItem;
   2105       var root = getTreeScope(this).root;
   2106       if (root instanceof scope.wrappers.ShadowRoot) {
   2107         return findOne(this, selector);
   2108       } else if (target instanceof OriginalElement) {
   2109         wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
   2110       } else if (target instanceof OriginalDocument) {
   2111         wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
   2112       } else {
   2113         return findOne(this, selector);
   2114       }
   2115       if (!wrappedItem) {
   2116         return wrappedItem;
   2117       } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
   2118         if (root instanceof scope.wrappers.ShadowRoot) {
   2119           return findOne(this, selector);
   2120         }
   2121       }
   2122       return wrappedItem;
   2123     },
   2124     querySelectorAll: function(selector) {
   2125       var shimmed = shimSelector(selector);
   2126       var deep = shimmed !== selector;
   2127       selector = shimmed;
   2128       var result = new NodeList();
   2129       result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
   2130       return result;
   2131     }
   2132   };
   2133   var MatchesInterface = {
   2134     matches: function(selector) {
   2135       selector = shimMatchesSelector(selector);
   2136       return scope.originalMatches.call(unsafeUnwrap(this), selector);
   2137     }
   2138   };
   2139   function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
   2140     var target = unsafeUnwrap(this);
   2141     var list;
   2142     var root = getTreeScope(this).root;
   2143     if (root instanceof scope.wrappers.ShadowRoot) {
   2144       return findElements(this, index, result, p, localName, lowercase);
   2145     } else if (target instanceof OriginalElement) {
   2146       list = originalElementGetElementsByTagName.call(target, localName, lowercase);
   2147     } else if (target instanceof OriginalDocument) {
   2148       list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
   2149     } else {
   2150       return findElements(this, index, result, p, localName, lowercase);
   2151     }
   2152     return filterNodeList(list, index, result, false);
   2153   }
   2154   function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
   2155     var target = unsafeUnwrap(this);
   2156     var list;
   2157     var root = getTreeScope(this).root;
   2158     if (root instanceof scope.wrappers.ShadowRoot) {
   2159       return findElements(this, index, result, p, ns, localName);
   2160     } else if (target instanceof OriginalElement) {
   2161       list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
   2162     } else if (target instanceof OriginalDocument) {
   2163       list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
   2164     } else {
   2165       return findElements(this, index, result, p, ns, localName);
   2166     }
   2167     return filterNodeList(list, index, result, false);
   2168   }
   2169   var GetElementsByInterface = {
   2170     getElementsByTagName: function(localName) {
   2171       var result = new HTMLCollection();
   2172       var match = localName === "*" ? matchesEveryThing : matchesTagName;
   2173       result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
   2174       return result;
   2175     },
   2176     getElementsByClassName: function(className) {
   2177       return this.querySelectorAll("." + className);
   2178     },
   2179     getElementsByTagNameNS: function(ns, localName) {
   2180       var result = new HTMLCollection();
   2181       var match = null;
   2182       if (ns === "*") {
   2183         match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
   2184       } else {
   2185         match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
   2186       }
   2187       result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
   2188       return result;
   2189     }
   2190   };
   2191   scope.GetElementsByInterface = GetElementsByInterface;
   2192   scope.SelectorsInterface = SelectorsInterface;
   2193   scope.MatchesInterface = MatchesInterface;
   2194 })(window.ShadowDOMPolyfill);
   2195 
   2196 (function(scope) {
   2197   "use strict";
   2198   var NodeList = scope.wrappers.NodeList;
   2199   function forwardElement(node) {
   2200     while (node && node.nodeType !== Node.ELEMENT_NODE) {
   2201       node = node.nextSibling;
   2202     }
   2203     return node;
   2204   }
   2205   function backwardsElement(node) {
   2206     while (node && node.nodeType !== Node.ELEMENT_NODE) {
   2207       node = node.previousSibling;
   2208     }
   2209     return node;
   2210   }
   2211   var ParentNodeInterface = {
   2212     get firstElementChild() {
   2213       return forwardElement(this.firstChild);
   2214     },
   2215     get lastElementChild() {
   2216       return backwardsElement(this.lastChild);
   2217     },
   2218     get childElementCount() {
   2219       var count = 0;
   2220       for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
   2221         count++;
   2222       }
   2223       return count;
   2224     },
   2225     get children() {
   2226       var wrapperList = new NodeList();
   2227       var i = 0;
   2228       for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
   2229         wrapperList[i++] = child;
   2230       }
   2231       wrapperList.length = i;
   2232       return wrapperList;
   2233     },
   2234     remove: function() {
   2235       var p = this.parentNode;
   2236       if (p) p.removeChild(this);
   2237     }
   2238   };
   2239   var ChildNodeInterface = {
   2240     get nextElementSibling() {
   2241       return forwardElement(this.nextSibling);
   2242     },
   2243     get previousElementSibling() {
   2244       return backwardsElement(this.previousSibling);
   2245     }
   2246   };
   2247   scope.ChildNodeInterface = ChildNodeInterface;
   2248   scope.ParentNodeInterface = ParentNodeInterface;
   2249 })(window.ShadowDOMPolyfill);
   2250 
   2251 (function(scope) {
   2252   "use strict";
   2253   var ChildNodeInterface = scope.ChildNodeInterface;
   2254   var Node = scope.wrappers.Node;
   2255   var enqueueMutation = scope.enqueueMutation;
   2256   var mixin = scope.mixin;
   2257   var registerWrapper = scope.registerWrapper;
   2258   var unsafeUnwrap = scope.unsafeUnwrap;
   2259   var OriginalCharacterData = window.CharacterData;
   2260   function CharacterData(node) {
   2261     Node.call(this, node);
   2262   }
   2263   CharacterData.prototype = Object.create(Node.prototype);
   2264   mixin(CharacterData.prototype, {
   2265     get textContent() {
   2266       return this.data;
   2267     },
   2268     set textContent(value) {
   2269       this.data = value;
   2270     },
   2271     get data() {
   2272       return unsafeUnwrap(this).data;
   2273     },
   2274     set data(value) {
   2275       var oldValue = unsafeUnwrap(this).data;
   2276       enqueueMutation(this, "characterData", {
   2277         oldValue: oldValue
   2278       });
   2279       unsafeUnwrap(this).data = value;
   2280     }
   2281   });
   2282   mixin(CharacterData.prototype, ChildNodeInterface);
   2283   registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
   2284   scope.wrappers.CharacterData = CharacterData;
   2285 })(window.ShadowDOMPolyfill);
   2286 
   2287 (function(scope) {
   2288   "use strict";
   2289   var CharacterData = scope.wrappers.CharacterData;
   2290   var enqueueMutation = scope.enqueueMutation;
   2291   var mixin = scope.mixin;
   2292   var registerWrapper = scope.registerWrapper;
   2293   function toUInt32(x) {
   2294     return x >>> 0;
   2295   }
   2296   var OriginalText = window.Text;
   2297   function Text(node) {
   2298     CharacterData.call(this, node);
   2299   }
   2300   Text.prototype = Object.create(CharacterData.prototype);
   2301   mixin(Text.prototype, {
   2302     splitText: function(offset) {
   2303       offset = toUInt32(offset);
   2304       var s = this.data;
   2305       if (offset > s.length) throw new Error("IndexSizeError");
   2306       var head = s.slice(0, offset);
   2307       var tail = s.slice(offset);
   2308       this.data = head;
   2309       var newTextNode = this.ownerDocument.createTextNode(tail);
   2310       if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
   2311       return newTextNode;
   2312     }
   2313   });
   2314   registerWrapper(OriginalText, Text, document.createTextNode(""));
   2315   scope.wrappers.Text = Text;
   2316 })(window.ShadowDOMPolyfill);
   2317 
   2318 (function(scope) {
   2319   "use strict";
   2320   if (!window.DOMTokenList) {
   2321     console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
   2322     return;
   2323   }
   2324   var unsafeUnwrap = scope.unsafeUnwrap;
   2325   var enqueueMutation = scope.enqueueMutation;
   2326   function getClass(el) {
   2327     return unsafeUnwrap(el).getAttribute("class");
   2328   }
   2329   function enqueueClassAttributeChange(el, oldValue) {
   2330     enqueueMutation(el, "attributes", {
   2331       name: "class",
   2332       namespace: null,
   2333       oldValue: oldValue
   2334     });
   2335   }
   2336   function invalidateClass(el) {
   2337     scope.invalidateRendererBasedOnAttribute(el, "class");
   2338   }
   2339   function changeClass(tokenList, method, args) {
   2340     var ownerElement = tokenList.ownerElement_;
   2341     if (ownerElement == null) {
   2342       return method.apply(tokenList, args);
   2343     }
   2344     var oldValue = getClass(ownerElement);
   2345     var retv = method.apply(tokenList, args);
   2346     if (getClass(ownerElement) !== oldValue) {
   2347       enqueueClassAttributeChange(ownerElement, oldValue);
   2348       invalidateClass(ownerElement);
   2349     }
   2350     return retv;
   2351   }
   2352   var oldAdd = DOMTokenList.prototype.add;
   2353   DOMTokenList.prototype.add = function() {
   2354     changeClass(this, oldAdd, arguments);
   2355   };
   2356   var oldRemove = DOMTokenList.prototype.remove;
   2357   DOMTokenList.prototype.remove = function() {
   2358     changeClass(this, oldRemove, arguments);
   2359   };
   2360   var oldToggle = DOMTokenList.prototype.toggle;
   2361   DOMTokenList.prototype.toggle = function() {
   2362     return changeClass(this, oldToggle, arguments);
   2363   };
   2364 })(window.ShadowDOMPolyfill);
   2365 
   2366 (function(scope) {
   2367   "use strict";
   2368   var ChildNodeInterface = scope.ChildNodeInterface;
   2369   var GetElementsByInterface = scope.GetElementsByInterface;
   2370   var Node = scope.wrappers.Node;
   2371   var ParentNodeInterface = scope.ParentNodeInterface;
   2372   var SelectorsInterface = scope.SelectorsInterface;
   2373   var MatchesInterface = scope.MatchesInterface;
   2374   var addWrapNodeListMethod = scope.addWrapNodeListMethod;
   2375   var enqueueMutation = scope.enqueueMutation;
   2376   var mixin = scope.mixin;
   2377   var oneOf = scope.oneOf;
   2378   var registerWrapper = scope.registerWrapper;
   2379   var unsafeUnwrap = scope.unsafeUnwrap;
   2380   var wrappers = scope.wrappers;
   2381   var OriginalElement = window.Element;
   2382   var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
   2383     return OriginalElement.prototype[name];
   2384   });
   2385   var matchesName = matchesNames[0];
   2386   var originalMatches = OriginalElement.prototype[matchesName];
   2387   function invalidateRendererBasedOnAttribute(element, name) {
   2388     var p = element.parentNode;
   2389     if (!p || !p.shadowRoot) return;
   2390     var renderer = scope.getRendererForHost(p);
   2391     if (renderer.dependsOnAttribute(name)) renderer.invalidate();
   2392   }
   2393   function enqueAttributeChange(element, name, oldValue) {
   2394     enqueueMutation(element, "attributes", {
   2395       name: name,
   2396       namespace: null,
   2397       oldValue: oldValue
   2398     });
   2399   }
   2400   var classListTable = new WeakMap();
   2401   function Element(node) {
   2402     Node.call(this, node);
   2403   }
   2404   Element.prototype = Object.create(Node.prototype);
   2405   mixin(Element.prototype, {
   2406     createShadowRoot: function() {
   2407       var newShadowRoot = new wrappers.ShadowRoot(this);
   2408       unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
   2409       var renderer = scope.getRendererForHost(this);
   2410       renderer.invalidate();
   2411       return newShadowRoot;
   2412     },
   2413     get shadowRoot() {
   2414       return unsafeUnwrap(this).polymerShadowRoot_ || null;
   2415     },
   2416     setAttribute: function(name, value) {
   2417       var oldValue = unsafeUnwrap(this).getAttribute(name);
   2418       unsafeUnwrap(this).setAttribute(name, value);
   2419       enqueAttributeChange(this, name, oldValue);
   2420       invalidateRendererBasedOnAttribute(this, name);
   2421     },
   2422     removeAttribute: function(name) {
   2423       var oldValue = unsafeUnwrap(this).getAttribute(name);
   2424       unsafeUnwrap(this).removeAttribute(name);
   2425       enqueAttributeChange(this, name, oldValue);
   2426       invalidateRendererBasedOnAttribute(this, name);
   2427     },
   2428     get classList() {
   2429       var list = classListTable.get(this);
   2430       if (!list) {
   2431         list = unsafeUnwrap(this).classList;
   2432         if (!list) return;
   2433         list.ownerElement_ = this;
   2434         classListTable.set(this, list);
   2435       }
   2436       return list;
   2437     },
   2438     get className() {
   2439       return unsafeUnwrap(this).className;
   2440     },
   2441     set className(v) {
   2442       this.setAttribute("class", v);
   2443     },
   2444     get id() {
   2445       return unsafeUnwrap(this).id;
   2446     },
   2447     set id(v) {
   2448       this.setAttribute("id", v);
   2449     }
   2450   });
   2451   matchesNames.forEach(function(name) {
   2452     if (name !== "matches") {
   2453       Element.prototype[name] = function(selector) {
   2454         return this.matches(selector);
   2455       };
   2456     }
   2457   });
   2458   if (OriginalElement.prototype.webkitCreateShadowRoot) {
   2459     Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
   2460   }
   2461   mixin(Element.prototype, ChildNodeInterface);
   2462   mixin(Element.prototype, GetElementsByInterface);
   2463   mixin(Element.prototype, ParentNodeInterface);
   2464   mixin(Element.prototype, SelectorsInterface);
   2465   mixin(Element.prototype, MatchesInterface);
   2466   registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
   2467   scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
   2468   scope.matchesNames = matchesNames;
   2469   scope.originalMatches = originalMatches;
   2470   scope.wrappers.Element = Element;
   2471 })(window.ShadowDOMPolyfill);
   2472 
   2473 (function(scope) {
   2474   "use strict";
   2475   var Element = scope.wrappers.Element;
   2476   var defineGetter = scope.defineGetter;
   2477   var enqueueMutation = scope.enqueueMutation;
   2478   var mixin = scope.mixin;
   2479   var nodesWereAdded = scope.nodesWereAdded;
   2480   var nodesWereRemoved = scope.nodesWereRemoved;
   2481   var registerWrapper = scope.registerWrapper;
   2482   var snapshotNodeList = scope.snapshotNodeList;
   2483   var unsafeUnwrap = scope.unsafeUnwrap;
   2484   var unwrap = scope.unwrap;
   2485   var wrap = scope.wrap;
   2486   var wrappers = scope.wrappers;
   2487   var escapeAttrRegExp = /[&\u00A0"]/g;
   2488   var escapeDataRegExp = /[&\u00A0<>]/g;
   2489   function escapeReplace(c) {
   2490     switch (c) {
   2491      case "&":
   2492       return "&amp;";
   2493 
   2494      case "<":
   2495       return "&lt;";
   2496 
   2497      case ">":
   2498       return "&gt;";
   2499 
   2500      case '"':
   2501       return "&quot;";
   2502 
   2503      case "":
   2504       return "&nbsp;";
   2505     }
   2506   }
   2507   function escapeAttr(s) {
   2508     return s.replace(escapeAttrRegExp, escapeReplace);
   2509   }
   2510   function escapeData(s) {
   2511     return s.replace(escapeDataRegExp, escapeReplace);
   2512   }
   2513   function makeSet(arr) {
   2514     var set = {};
   2515     for (var i = 0; i < arr.length; i++) {
   2516       set[arr[i]] = true;
   2517     }
   2518     return set;
   2519   }
   2520   var voidElements = makeSet([ "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" ]);
   2521   var plaintextParents = makeSet([ "style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript" ]);
   2522   function getOuterHTML(node, parentNode) {
   2523     switch (node.nodeType) {
   2524      case Node.ELEMENT_NODE:
   2525       var tagName = node.tagName.toLowerCase();
   2526       var s = "<" + tagName;
   2527       var attrs = node.attributes;
   2528       for (var i = 0, attr; attr = attrs[i]; i++) {
   2529         s += " " + attr.name + '="' + escapeAttr(attr.value) + '"';
   2530       }
   2531       s += ">";
   2532       if (voidElements[tagName]) return s;
   2533       return s + getInnerHTML(node) + "</" + tagName + ">";
   2534 
   2535      case Node.TEXT_NODE:
   2536       var data = node.data;
   2537       if (parentNode && plaintextParents[parentNode.localName]) return data;
   2538       return escapeData(data);
   2539 
   2540      case Node.COMMENT_NODE:
   2541       return "<!--" + node.data + "-->";
   2542 
   2543      default:
   2544       console.error(node);
   2545       throw new Error("not implemented");
   2546     }
   2547   }
   2548   function getInnerHTML(node) {
   2549     if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
   2550     var s = "";
   2551     for (var child = node.firstChild; child; child = child.nextSibling) {
   2552       s += getOuterHTML(child, node);
   2553     }
   2554     return s;
   2555   }
   2556   function setInnerHTML(node, value, opt_tagName) {
   2557     var tagName = opt_tagName || "div";
   2558     node.textContent = "";
   2559     var tempElement = unwrap(node.ownerDocument.createElement(tagName));
   2560     tempElement.innerHTML = value;
   2561     var firstChild;
   2562     while (firstChild = tempElement.firstChild) {
   2563       node.appendChild(wrap(firstChild));
   2564     }
   2565   }
   2566   var oldIe = /MSIE/.test(navigator.userAgent);
   2567   var OriginalHTMLElement = window.HTMLElement;
   2568   var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
   2569   function HTMLElement(node) {
   2570     Element.call(this, node);
   2571   }
   2572   HTMLElement.prototype = Object.create(Element.prototype);
   2573   mixin(HTMLElement.prototype, {
   2574     get innerHTML() {
   2575       return getInnerHTML(this);
   2576     },
   2577     set innerHTML(value) {
   2578       if (oldIe && plaintextParents[this.localName]) {
   2579         this.textContent = value;
   2580         return;
   2581       }
   2582       var removedNodes = snapshotNodeList(this.childNodes);
   2583       if (this.invalidateShadowRenderer()) {
   2584         if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
   2585       } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
   2586         setInnerHTML(this.content, value);
   2587       } else {
   2588         unsafeUnwrap(this).innerHTML = value;
   2589       }
   2590       var addedNodes = snapshotNodeList(this.childNodes);
   2591       enqueueMutation(this, "childList", {
   2592         addedNodes: addedNodes,
   2593         removedNodes: removedNodes
   2594       });
   2595       nodesWereRemoved(removedNodes);
   2596       nodesWereAdded(addedNodes, this);
   2597     },
   2598     get outerHTML() {
   2599       return getOuterHTML(this, this.parentNode);
   2600     },
   2601     set outerHTML(value) {
   2602       var p = this.parentNode;
   2603       if (p) {
   2604         p.invalidateShadowRenderer();
   2605         var df = frag(p, value);
   2606         p.replaceChild(df, this);
   2607       }
   2608     },
   2609     insertAdjacentHTML: function(position, text) {
   2610       var contextElement, refNode;
   2611       switch (String(position).toLowerCase()) {
   2612        case "beforebegin":
   2613         contextElement = this.parentNode;
   2614         refNode = this;
   2615         break;
   2616 
   2617        case "afterend":
   2618         contextElement = this.parentNode;
   2619         refNode = this.nextSibling;
   2620         break;
   2621 
   2622        case "afterbegin":
   2623         contextElement = this;
   2624         refNode = this.firstChild;
   2625         break;
   2626 
   2627        case "beforeend":
   2628         contextElement = this;
   2629         refNode = null;
   2630         break;
   2631 
   2632        default:
   2633         return;
   2634       }
   2635       var df = frag(contextElement, text);
   2636       contextElement.insertBefore(df, refNode);
   2637     },
   2638     get hidden() {
   2639       return this.hasAttribute("hidden");
   2640     },
   2641     set hidden(v) {
   2642       if (v) {
   2643         this.setAttribute("hidden", "");
   2644       } else {
   2645         this.removeAttribute("hidden");
   2646       }
   2647     }
   2648   });
   2649   function frag(contextElement, html) {
   2650     var p = unwrap(contextElement.cloneNode(false));
   2651     p.innerHTML = html;
   2652     var df = unwrap(document.createDocumentFragment());
   2653     var c;
   2654     while (c = p.firstChild) {
   2655       df.appendChild(c);
   2656     }
   2657     return wrap(df);
   2658   }
   2659   function getter(name) {
   2660     return function() {
   2661       scope.renderAllPending();
   2662       return unsafeUnwrap(this)[name];
   2663     };
   2664   }
   2665   function getterRequiresRendering(name) {
   2666     defineGetter(HTMLElement, name, getter(name));
   2667   }
   2668   [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
   2669   function getterAndSetterRequiresRendering(name) {
   2670     Object.defineProperty(HTMLElement.prototype, name, {
   2671       get: getter(name),
   2672       set: function(v) {
   2673         scope.renderAllPending();
   2674         unsafeUnwrap(this)[name] = v;
   2675       },
   2676       configurable: true,
   2677       enumerable: true
   2678     });
   2679   }
   2680   [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
   2681   function methodRequiresRendering(name) {
   2682     Object.defineProperty(HTMLElement.prototype, name, {
   2683       value: function() {
   2684         scope.renderAllPending();
   2685         return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
   2686       },
   2687       configurable: true,
   2688       enumerable: true
   2689     });
   2690   }
   2691   [ "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
   2692   registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
   2693   scope.wrappers.HTMLElement = HTMLElement;
   2694   scope.getInnerHTML = getInnerHTML;
   2695   scope.setInnerHTML = setInnerHTML;
   2696 })(window.ShadowDOMPolyfill);
   2697 
   2698 (function(scope) {
   2699   "use strict";
   2700   var HTMLElement = scope.wrappers.HTMLElement;
   2701   var mixin = scope.mixin;
   2702   var registerWrapper = scope.registerWrapper;
   2703   var unsafeUnwrap = scope.unsafeUnwrap;
   2704   var wrap = scope.wrap;
   2705   var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
   2706   function HTMLCanvasElement(node) {
   2707     HTMLElement.call(this, node);
   2708   }
   2709   HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
   2710   mixin(HTMLCanvasElement.prototype, {
   2711     getContext: function() {
   2712       var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
   2713       return context && wrap(context);
   2714     }
   2715   });
   2716   registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
   2717   scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
   2718 })(window.ShadowDOMPolyfill);
   2719 
   2720 (function(scope) {
   2721   "use strict";
   2722   var HTMLElement = scope.wrappers.HTMLElement;
   2723   var mixin = scope.mixin;
   2724   var registerWrapper = scope.registerWrapper;
   2725   var OriginalHTMLContentElement = window.HTMLContentElement;
   2726   function HTMLContentElement(node) {
   2727     HTMLElement.call(this, node);
   2728   }
   2729   HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
   2730   mixin(HTMLContentElement.prototype, {
   2731     constructor: HTMLContentElement,
   2732     get select() {
   2733       return this.getAttribute("select");
   2734     },
   2735     set select(value) {
   2736       this.setAttribute("select", value);
   2737     },
   2738     setAttribute: function(n, v) {
   2739       HTMLElement.prototype.setAttribute.call(this, n, v);
   2740       if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
   2741     }
   2742   });
   2743   if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
   2744   scope.wrappers.HTMLContentElement = HTMLContentElement;
   2745 })(window.ShadowDOMPolyfill);
   2746 
   2747 (function(scope) {
   2748   "use strict";
   2749   var HTMLElement = scope.wrappers.HTMLElement;
   2750   var mixin = scope.mixin;
   2751   var registerWrapper = scope.registerWrapper;
   2752   var wrapHTMLCollection = scope.wrapHTMLCollection;
   2753   var unwrap = scope.unwrap;
   2754   var OriginalHTMLFormElement = window.HTMLFormElement;
   2755   function HTMLFormElement(node) {
   2756     HTMLElement.call(this, node);
   2757   }
   2758   HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
   2759   mixin(HTMLFormElement.prototype, {
   2760     get elements() {
   2761       return wrapHTMLCollection(unwrap(this).elements);
   2762     }
   2763   });
   2764   registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
   2765   scope.wrappers.HTMLFormElement = HTMLFormElement;
   2766 })(window.ShadowDOMPolyfill);
   2767 
   2768 (function(scope) {
   2769   "use strict";
   2770   var HTMLElement = scope.wrappers.HTMLElement;
   2771   var registerWrapper = scope.registerWrapper;
   2772   var unwrap = scope.unwrap;
   2773   var rewrap = scope.rewrap;
   2774   var OriginalHTMLImageElement = window.HTMLImageElement;
   2775   function HTMLImageElement(node) {
   2776     HTMLElement.call(this, node);
   2777   }
   2778   HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
   2779   registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
   2780   function Image(width, height) {
   2781     if (!(this instanceof Image)) {
   2782       throw new TypeError("DOM object constructor cannot be called as a function.");
   2783     }
   2784     var node = unwrap(document.createElement("img"));
   2785     HTMLElement.call(this, node);
   2786     rewrap(node, this);
   2787     if (width !== undefined) node.width = width;
   2788     if (height !== undefined) node.height = height;
   2789   }
   2790   Image.prototype = HTMLImageElement.prototype;
   2791   scope.wrappers.HTMLImageElement = HTMLImageElement;
   2792   scope.wrappers.Image = Image;
   2793 })(window.ShadowDOMPolyfill);
   2794 
   2795 (function(scope) {
   2796   "use strict";
   2797   var HTMLElement = scope.wrappers.HTMLElement;
   2798   var mixin = scope.mixin;
   2799   var NodeList = scope.wrappers.NodeList;
   2800   var registerWrapper = scope.registerWrapper;
   2801   var OriginalHTMLShadowElement = window.HTMLShadowElement;
   2802   function HTMLShadowElement(node) {
   2803     HTMLElement.call(this, node);
   2804   }
   2805   HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
   2806   HTMLShadowElement.prototype.constructor = HTMLShadowElement;
   2807   if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
   2808   scope.wrappers.HTMLShadowElement = HTMLShadowElement;
   2809 })(window.ShadowDOMPolyfill);
   2810 
   2811 (function(scope) {
   2812   "use strict";
   2813   var HTMLElement = scope.wrappers.HTMLElement;
   2814   var mixin = scope.mixin;
   2815   var registerWrapper = scope.registerWrapper;
   2816   var unsafeUnwrap = scope.unsafeUnwrap;
   2817   var unwrap = scope.unwrap;
   2818   var wrap = scope.wrap;
   2819   var contentTable = new WeakMap();
   2820   var templateContentsOwnerTable = new WeakMap();
   2821   function getTemplateContentsOwner(doc) {
   2822     if (!doc.defaultView) return doc;
   2823     var d = templateContentsOwnerTable.get(doc);
   2824     if (!d) {
   2825       d = doc.implementation.createHTMLDocument("");
   2826       while (d.lastChild) {
   2827         d.removeChild(d.lastChild);
   2828       }
   2829       templateContentsOwnerTable.set(doc, d);
   2830     }
   2831     return d;
   2832   }
   2833   function extractContent(templateElement) {
   2834     var doc = getTemplateContentsOwner(templateElement.ownerDocument);
   2835     var df = unwrap(doc.createDocumentFragment());
   2836     var child;
   2837     while (child = templateElement.firstChild) {
   2838       df.appendChild(child);
   2839     }
   2840     return df;
   2841   }
   2842   var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
   2843   function HTMLTemplateElement(node) {
   2844     HTMLElement.call(this, node);
   2845     if (!OriginalHTMLTemplateElement) {
   2846       var content = extractContent(node);
   2847       contentTable.set(this, wrap(content));
   2848     }
   2849   }
   2850   HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
   2851   mixin(HTMLTemplateElement.prototype, {
   2852     constructor: HTMLTemplateElement,
   2853     get content() {
   2854       if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
   2855       return contentTable.get(this);
   2856     }
   2857   });
   2858   if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
   2859   scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
   2860 })(window.ShadowDOMPolyfill);
   2861 
   2862 (function(scope) {
   2863   "use strict";
   2864   var HTMLElement = scope.wrappers.HTMLElement;
   2865   var registerWrapper = scope.registerWrapper;
   2866   var OriginalHTMLMediaElement = window.HTMLMediaElement;
   2867   if (!OriginalHTMLMediaElement) return;
   2868   function HTMLMediaElement(node) {
   2869     HTMLElement.call(this, node);
   2870   }
   2871   HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
   2872   registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
   2873   scope.wrappers.HTMLMediaElement = HTMLMediaElement;
   2874 })(window.ShadowDOMPolyfill);
   2875 
   2876 (function(scope) {
   2877   "use strict";
   2878   var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
   2879   var registerWrapper = scope.registerWrapper;
   2880   var unwrap = scope.unwrap;
   2881   var rewrap = scope.rewrap;
   2882   var OriginalHTMLAudioElement = window.HTMLAudioElement;
   2883   if (!OriginalHTMLAudioElement) return;
   2884   function HTMLAudioElement(node) {
   2885     HTMLMediaElement.call(this, node);
   2886   }
   2887   HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
   2888   registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
   2889   function Audio(src) {
   2890     if (!(this instanceof Audio)) {
   2891       throw new TypeError("DOM object constructor cannot be called as a function.");
   2892     }
   2893     var node = unwrap(document.createElement("audio"));
   2894     HTMLMediaElement.call(this, node);
   2895     rewrap(node, this);
   2896     node.setAttribute("preload", "auto");
   2897     if (src !== undefined) node.setAttribute("src", src);
   2898   }
   2899   Audio.prototype = HTMLAudioElement.prototype;
   2900   scope.wrappers.HTMLAudioElement = HTMLAudioElement;
   2901   scope.wrappers.Audio = Audio;
   2902 })(window.ShadowDOMPolyfill);
   2903 
   2904 (function(scope) {
   2905   "use strict";
   2906   var HTMLElement = scope.wrappers.HTMLElement;
   2907   var mixin = scope.mixin;
   2908   var registerWrapper = scope.registerWrapper;
   2909   var rewrap = scope.rewrap;
   2910   var unwrap = scope.unwrap;
   2911   var wrap = scope.wrap;
   2912   var OriginalHTMLOptionElement = window.HTMLOptionElement;
   2913   function trimText(s) {
   2914     return s.replace(/\s+/g, " ").trim();
   2915   }
   2916   function HTMLOptionElement(node) {
   2917     HTMLElement.call(this, node);
   2918   }
   2919   HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
   2920   mixin(HTMLOptionElement.prototype, {
   2921     get text() {
   2922       return trimText(this.textContent);
   2923     },
   2924     set text(value) {
   2925       this.textContent = trimText(String(value));
   2926     },
   2927     get form() {
   2928       return wrap(unwrap(this).form);
   2929     }
   2930   });
   2931   registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
   2932   function Option(text, value, defaultSelected, selected) {
   2933     if (!(this instanceof Option)) {
   2934       throw new TypeError("DOM object constructor cannot be called as a function.");
   2935     }
   2936     var node = unwrap(document.createElement("option"));
   2937     HTMLElement.call(this, node);
   2938     rewrap(node, this);
   2939     if (text !== undefined) node.text = text;
   2940     if (value !== undefined) node.setAttribute("value", value);
   2941     if (defaultSelected === true) node.setAttribute("selected", "");
   2942     node.selected = selected === true;
   2943   }
   2944   Option.prototype = HTMLOptionElement.prototype;
   2945   scope.wrappers.HTMLOptionElement = HTMLOptionElement;
   2946   scope.wrappers.Option = Option;
   2947 })(window.ShadowDOMPolyfill);
   2948 
   2949 (function(scope) {
   2950   "use strict";
   2951   var HTMLElement = scope.wrappers.HTMLElement;
   2952   var mixin = scope.mixin;
   2953   var registerWrapper = scope.registerWrapper;
   2954   var unwrap = scope.unwrap;
   2955   var wrap = scope.wrap;
   2956   var OriginalHTMLSelectElement = window.HTMLSelectElement;
   2957   function HTMLSelectElement(node) {
   2958     HTMLElement.call(this, node);
   2959   }
   2960   HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
   2961   mixin(HTMLSelectElement.prototype, {
   2962     add: function(element, before) {
   2963       if (typeof before === "object") before = unwrap(before);
   2964       unwrap(this).add(unwrap(element), before);
   2965     },
   2966     remove: function(indexOrNode) {
   2967       if (indexOrNode === undefined) {
   2968         HTMLElement.prototype.remove.call(this);
   2969         return;
   2970       }
   2971       if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
   2972       unwrap(this).remove(indexOrNode);
   2973     },
   2974     get form() {
   2975       return wrap(unwrap(this).form);
   2976     }
   2977   });
   2978   registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
   2979   scope.wrappers.HTMLSelectElement = HTMLSelectElement;
   2980 })(window.ShadowDOMPolyfill);
   2981 
   2982 (function(scope) {
   2983   "use strict";
   2984   var HTMLElement = scope.wrappers.HTMLElement;
   2985   var mixin = scope.mixin;
   2986   var registerWrapper = scope.registerWrapper;
   2987   var unwrap = scope.unwrap;
   2988   var wrap = scope.wrap;
   2989   var wrapHTMLCollection = scope.wrapHTMLCollection;
   2990   var OriginalHTMLTableElement = window.HTMLTableElement;
   2991   function HTMLTableElement(node) {
   2992     HTMLElement.call(this, node);
   2993   }
   2994   HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
   2995   mixin(HTMLTableElement.prototype, {
   2996     get caption() {
   2997       return wrap(unwrap(this).caption);
   2998     },
   2999     createCaption: function() {
   3000       return wrap(unwrap(this).createCaption());
   3001     },
   3002     get tHead() {
   3003       return wrap(unwrap(this).tHead);
   3004     },
   3005     createTHead: function() {
   3006       return wrap(unwrap(this).createTHead());
   3007     },
   3008     createTFoot: function() {
   3009       return wrap(unwrap(this).createTFoot());
   3010     },
   3011     get tFoot() {
   3012       return wrap(unwrap(this).tFoot);
   3013     },
   3014     get tBodies() {
   3015       return wrapHTMLCollection(unwrap(this).tBodies);
   3016     },
   3017     createTBody: function() {
   3018       return wrap(unwrap(this).createTBody());
   3019     },
   3020     get rows() {
   3021       return wrapHTMLCollection(unwrap(this).rows);
   3022     },
   3023     insertRow: function(index) {
   3024       return wrap(unwrap(this).insertRow(index));
   3025     }
   3026   });
   3027   registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
   3028   scope.wrappers.HTMLTableElement = HTMLTableElement;
   3029 })(window.ShadowDOMPolyfill);
   3030 
   3031 (function(scope) {
   3032   "use strict";
   3033   var HTMLElement = scope.wrappers.HTMLElement;
   3034   var mixin = scope.mixin;
   3035   var registerWrapper = scope.registerWrapper;
   3036   var wrapHTMLCollection = scope.wrapHTMLCollection;
   3037   var unwrap = scope.unwrap;
   3038   var wrap = scope.wrap;
   3039   var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
   3040   function HTMLTableSectionElement(node) {
   3041     HTMLElement.call(this, node);
   3042   }
   3043   HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
   3044   mixin(HTMLTableSectionElement.prototype, {
   3045     constructor: HTMLTableSectionElement,
   3046     get rows() {
   3047       return wrapHTMLCollection(unwrap(this).rows);
   3048     },
   3049     insertRow: function(index) {
   3050       return wrap(unwrap(this).insertRow(index));
   3051     }
   3052   });
   3053   registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
   3054   scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
   3055 })(window.ShadowDOMPolyfill);
   3056 
   3057 (function(scope) {
   3058   "use strict";
   3059   var HTMLElement = scope.wrappers.HTMLElement;
   3060   var mixin = scope.mixin;
   3061   var registerWrapper = scope.registerWrapper;
   3062   var wrapHTMLCollection = scope.wrapHTMLCollection;
   3063   var unwrap = scope.unwrap;
   3064   var wrap = scope.wrap;
   3065   var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
   3066   function HTMLTableRowElement(node) {
   3067     HTMLElement.call(this, node);
   3068   }
   3069   HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
   3070   mixin(HTMLTableRowElement.prototype, {
   3071     get cells() {
   3072       return wrapHTMLCollection(unwrap(this).cells);
   3073     },
   3074     insertCell: function(index) {
   3075       return wrap(unwrap(this).insertCell(index));
   3076     }
   3077   });
   3078   registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
   3079   scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
   3080 })(window.ShadowDOMPolyfill);
   3081 
   3082 (function(scope) {
   3083   "use strict";
   3084   var HTMLContentElement = scope.wrappers.HTMLContentElement;
   3085   var HTMLElement = scope.wrappers.HTMLElement;
   3086   var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
   3087   var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
   3088   var mixin = scope.mixin;
   3089   var registerWrapper = scope.registerWrapper;
   3090   var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
   3091   function HTMLUnknownElement(node) {
   3092     switch (node.localName) {
   3093      case "content":
   3094       return new HTMLContentElement(node);
   3095 
   3096      case "shadow":
   3097       return new HTMLShadowElement(node);
   3098 
   3099      case "template":
   3100       return new HTMLTemplateElement(node);
   3101     }
   3102     HTMLElement.call(this, node);
   3103   }
   3104   HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
   3105   registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
   3106   scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
   3107 })(window.ShadowDOMPolyfill);
   3108 
   3109 (function(scope) {
   3110   "use strict";
   3111   var Element = scope.wrappers.Element;
   3112   var HTMLElement = scope.wrappers.HTMLElement;
   3113   var registerObject = scope.registerObject;
   3114   var defineWrapGetter = scope.defineWrapGetter;
   3115   var SVG_NS = "http://www.w3.org/2000/svg";
   3116   var svgTitleElement = document.createElementNS(SVG_NS, "title");
   3117   var SVGTitleElement = registerObject(svgTitleElement);
   3118   var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
   3119   if (!("classList" in svgTitleElement)) {
   3120     var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
   3121     Object.defineProperty(HTMLElement.prototype, "classList", descr);
   3122     delete Element.prototype.classList;
   3123   }
   3124   defineWrapGetter(SVGElement, "ownerSVGElement");
   3125   scope.wrappers.SVGElement = SVGElement;
   3126 })(window.ShadowDOMPolyfill);
   3127 
   3128 (function(scope) {
   3129   "use strict";
   3130   var mixin = scope.mixin;
   3131   var registerWrapper = scope.registerWrapper;
   3132   var unwrap = scope.unwrap;
   3133   var wrap = scope.wrap;
   3134   var OriginalSVGUseElement = window.SVGUseElement;
   3135   var SVG_NS = "http://www.w3.org/2000/svg";
   3136   var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
   3137   var useElement = document.createElementNS(SVG_NS, "use");
   3138   var SVGGElement = gWrapper.constructor;
   3139   var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
   3140   var parentInterface = parentInterfacePrototype.constructor;
   3141   function SVGUseElement(impl) {
   3142     parentInterface.call(this, impl);
   3143   }
   3144   SVGUseElement.prototype = Object.create(parentInterfacePrototype);
   3145   if ("instanceRoot" in useElement) {
   3146     mixin(SVGUseElement.prototype, {
   3147       get instanceRoot() {
   3148         return wrap(unwrap(this).instanceRoot);
   3149       },
   3150       get animatedInstanceRoot() {
   3151         return wrap(unwrap(this).animatedInstanceRoot);
   3152       }
   3153     });
   3154   }
   3155   registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
   3156   scope.wrappers.SVGUseElement = SVGUseElement;
   3157 })(window.ShadowDOMPolyfill);
   3158 
   3159 (function(scope) {
   3160   "use strict";
   3161   var EventTarget = scope.wrappers.EventTarget;
   3162   var mixin = scope.mixin;
   3163   var registerWrapper = scope.registerWrapper;
   3164   var unsafeUnwrap = scope.unsafeUnwrap;
   3165   var wrap = scope.wrap;
   3166   var OriginalSVGElementInstance = window.SVGElementInstance;
   3167   if (!OriginalSVGElementInstance) return;
   3168   function SVGElementInstance(impl) {
   3169     EventTarget.call(this, impl);
   3170   }
   3171   SVGElementInstance.prototype = Object.create(EventTarget.prototype);
   3172   mixin(SVGElementInstance.prototype, {
   3173     get correspondingElement() {
   3174       return wrap(unsafeUnwrap(this).correspondingElement);
   3175     },
   3176     get correspondingUseElement() {
   3177       return wrap(unsafeUnwrap(this).correspondingUseElement);
   3178     },
   3179     get parentNode() {
   3180       return wrap(unsafeUnwrap(this).parentNode);
   3181     },
   3182     get childNodes() {
   3183       throw new Error("Not implemented");
   3184     },
   3185     get firstChild() {
   3186       return wrap(unsafeUnwrap(this).firstChild);
   3187     },
   3188     get lastChild() {
   3189       return wrap(unsafeUnwrap(this).lastChild);
   3190     },
   3191     get previousSibling() {
   3192       return wrap(unsafeUnwrap(this).previousSibling);
   3193     },
   3194     get nextSibling() {
   3195       return wrap(unsafeUnwrap(this).nextSibling);
   3196     }
   3197   });
   3198   registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
   3199   scope.wrappers.SVGElementInstance = SVGElementInstance;
   3200 })(window.ShadowDOMPolyfill);
   3201 
   3202 (function(scope) {
   3203   "use strict";
   3204   var mixin = scope.mixin;
   3205   var registerWrapper = scope.registerWrapper;
   3206   var setWrapper = scope.setWrapper;
   3207   var unsafeUnwrap = scope.unsafeUnwrap;
   3208   var unwrap = scope.unwrap;
   3209   var unwrapIfNeeded = scope.unwrapIfNeeded;
   3210   var wrap = scope.wrap;
   3211   var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
   3212   function CanvasRenderingContext2D(impl) {
   3213     setWrapper(impl, this);
   3214   }
   3215   mixin(CanvasRenderingContext2D.prototype, {
   3216     get canvas() {
   3217       return wrap(unsafeUnwrap(this).canvas);
   3218     },
   3219     drawImage: function() {
   3220       arguments[0] = unwrapIfNeeded(arguments[0]);
   3221       unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
   3222     },
   3223     createPattern: function() {
   3224       arguments[0] = unwrap(arguments[0]);
   3225       return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
   3226     }
   3227   });
   3228   registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
   3229   scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
   3230 })(window.ShadowDOMPolyfill);
   3231 
   3232 (function(scope) {
   3233   "use strict";
   3234   var mixin = scope.mixin;
   3235   var registerWrapper = scope.registerWrapper;
   3236   var setWrapper = scope.setWrapper;
   3237   var unsafeUnwrap = scope.unsafeUnwrap;
   3238   var unwrapIfNeeded = scope.unwrapIfNeeded;
   3239   var wrap = scope.wrap;
   3240   var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
   3241   if (!OriginalWebGLRenderingContext) return;
   3242   function WebGLRenderingContext(impl) {
   3243     setWrapper(impl, this);
   3244   }
   3245   mixin(WebGLRenderingContext.prototype, {
   3246     get canvas() {
   3247       return wrap(unsafeUnwrap(this).canvas);
   3248     },
   3249     texImage2D: function() {
   3250       arguments[5] = unwrapIfNeeded(arguments[5]);
   3251       unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
   3252     },
   3253     texSubImage2D: function() {
   3254       arguments[6] = unwrapIfNeeded(arguments[6]);
   3255       unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
   3256     }
   3257   });
   3258   var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
   3259     drawingBufferHeight: null,
   3260     drawingBufferWidth: null
   3261   } : {};
   3262   registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
   3263   scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
   3264 })(window.ShadowDOMPolyfill);
   3265 
   3266 (function(scope) {
   3267   "use strict";
   3268   var registerWrapper = scope.registerWrapper;
   3269   var setWrapper = scope.setWrapper;
   3270   var unsafeUnwrap = scope.unsafeUnwrap;
   3271   var unwrap = scope.unwrap;
   3272   var unwrapIfNeeded = scope.unwrapIfNeeded;
   3273   var wrap = scope.wrap;
   3274   var OriginalRange = window.Range;
   3275   function Range(impl) {
   3276     setWrapper(impl, this);
   3277   }
   3278   Range.prototype = {
   3279     get startContainer() {
   3280       return wrap(unsafeUnwrap(this).startContainer);
   3281     },
   3282     get endContainer() {
   3283       return wrap(unsafeUnwrap(this).endContainer);
   3284     },
   3285     get commonAncestorContainer() {
   3286       return wrap(unsafeUnwrap(this).commonAncestorContainer);
   3287     },
   3288     setStart: function(refNode, offset) {
   3289       unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
   3290     },
   3291     setEnd: function(refNode, offset) {
   3292       unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
   3293     },
   3294     setStartBefore: function(refNode) {
   3295       unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
   3296     },
   3297     setStartAfter: function(refNode) {
   3298       unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
   3299     },
   3300     setEndBefore: function(refNode) {
   3301       unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
   3302     },
   3303     setEndAfter: function(refNode) {
   3304       unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
   3305     },
   3306     selectNode: function(refNode) {
   3307       unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
   3308     },
   3309     selectNodeContents: function(refNode) {
   3310       unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
   3311     },
   3312     compareBoundaryPoints: function(how, sourceRange) {
   3313       return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
   3314     },
   3315     extractContents: function() {
   3316       return wrap(unsafeUnwrap(this).extractContents());
   3317     },
   3318     cloneContents: function() {
   3319       return wrap(unsafeUnwrap(this).cloneContents());
   3320     },
   3321     insertNode: function(node) {
   3322       unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
   3323     },
   3324     surroundContents: function(newParent) {
   3325       unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
   3326     },
   3327     cloneRange: function() {
   3328       return wrap(unsafeUnwrap(this).cloneRange());
   3329     },
   3330     isPointInRange: function(node, offset) {
   3331       return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
   3332     },
   3333     comparePoint: function(node, offset) {
   3334       return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
   3335     },
   3336     intersectsNode: function(node) {
   3337       return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
   3338     },
   3339     toString: function() {
   3340       return unsafeUnwrap(this).toString();
   3341     }
   3342   };
   3343   if (OriginalRange.prototype.createContextualFragment) {
   3344     Range.prototype.createContextualFragment = function(html) {
   3345       return wrap(unsafeUnwrap(this).createContextualFragment(html));
   3346     };
   3347   }
   3348   registerWrapper(window.Range, Range, document.createRange());
   3349   scope.wrappers.Range = Range;
   3350 })(window.ShadowDOMPolyfill);
   3351 
   3352 (function(scope) {
   3353   "use strict";
   3354   var GetElementsByInterface = scope.GetElementsByInterface;
   3355   var ParentNodeInterface = scope.ParentNodeInterface;
   3356   var SelectorsInterface = scope.SelectorsInterface;
   3357   var mixin = scope.mixin;
   3358   var registerObject = scope.registerObject;
   3359   var DocumentFragment = registerObject(document.createDocumentFragment());
   3360   mixin(DocumentFragment.prototype, ParentNodeInterface);
   3361   mixin(DocumentFragment.prototype, SelectorsInterface);
   3362   mixin(DocumentFragment.prototype, GetElementsByInterface);
   3363   var Comment = registerObject(document.createComment(""));
   3364   scope.wrappers.Comment = Comment;
   3365   scope.wrappers.DocumentFragment = DocumentFragment;
   3366 })(window.ShadowDOMPolyfill);
   3367 
   3368 (function(scope) {
   3369   "use strict";
   3370   var DocumentFragment = scope.wrappers.DocumentFragment;
   3371   var TreeScope = scope.TreeScope;
   3372   var elementFromPoint = scope.elementFromPoint;
   3373   var getInnerHTML = scope.getInnerHTML;
   3374   var getTreeScope = scope.getTreeScope;
   3375   var mixin = scope.mixin;
   3376   var rewrap = scope.rewrap;
   3377   var setInnerHTML = scope.setInnerHTML;
   3378   var unsafeUnwrap = scope.unsafeUnwrap;
   3379   var unwrap = scope.unwrap;
   3380   var shadowHostTable = new WeakMap();
   3381   var nextOlderShadowTreeTable = new WeakMap();
   3382   var spaceCharRe = /[ \t\n\r\f]/;
   3383   function ShadowRoot(hostWrapper) {
   3384     var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
   3385     DocumentFragment.call(this, node);
   3386     rewrap(node, this);
   3387     var oldShadowRoot = hostWrapper.shadowRoot;
   3388     nextOlderShadowTreeTable.set(this, oldShadowRoot);
   3389     this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
   3390     shadowHostTable.set(this, hostWrapper);
   3391   }
   3392   ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
   3393   mixin(ShadowRoot.prototype, {
   3394     constructor: ShadowRoot,
   3395     get innerHTML() {
   3396       return getInnerHTML(this);
   3397     },
   3398     set innerHTML(value) {
   3399       setInnerHTML(this, value);
   3400       this.invalidateShadowRenderer();
   3401     },
   3402     get olderShadowRoot() {
   3403       return nextOlderShadowTreeTable.get(this) || null;
   3404     },
   3405     get host() {
   3406       return shadowHostTable.get(this) || null;
   3407     },
   3408     invalidateShadowRenderer: function() {
   3409       return shadowHostTable.get(this).invalidateShadowRenderer();
   3410     },
   3411     elementFromPoint: function(x, y) {
   3412       return elementFromPoint(this, this.ownerDocument, x, y);
   3413     },
   3414     getElementById: function(id) {
   3415       if (spaceCharRe.test(id)) return null;
   3416       return this.querySelector('[id="' + id + '"]');
   3417     }
   3418   });
   3419   scope.wrappers.ShadowRoot = ShadowRoot;
   3420 })(window.ShadowDOMPolyfill);
   3421 
   3422 (function(scope) {
   3423   "use strict";
   3424   var Element = scope.wrappers.Element;
   3425   var HTMLContentElement = scope.wrappers.HTMLContentElement;
   3426   var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
   3427   var Node = scope.wrappers.Node;
   3428   var ShadowRoot = scope.wrappers.ShadowRoot;
   3429   var assert = scope.assert;
   3430   var getTreeScope = scope.getTreeScope;
   3431   var mixin = scope.mixin;
   3432   var oneOf = scope.oneOf;
   3433   var unsafeUnwrap = scope.unsafeUnwrap;
   3434   var unwrap = scope.unwrap;
   3435   var wrap = scope.wrap;
   3436   var ArraySplice = scope.ArraySplice;
   3437   function updateWrapperUpAndSideways(wrapper) {
   3438     wrapper.previousSibling_ = wrapper.previousSibling;
   3439     wrapper.nextSibling_ = wrapper.nextSibling;
   3440     wrapper.parentNode_ = wrapper.parentNode;
   3441   }
   3442   function updateWrapperDown(wrapper) {
   3443     wrapper.firstChild_ = wrapper.firstChild;
   3444     wrapper.lastChild_ = wrapper.lastChild;
   3445   }
   3446   function updateAllChildNodes(parentNodeWrapper) {
   3447     assert(parentNodeWrapper instanceof Node);
   3448     for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
   3449       updateWrapperUpAndSideways(childWrapper);
   3450     }
   3451     updateWrapperDown(parentNodeWrapper);
   3452   }
   3453   function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
   3454     var parentNode = unwrap(parentNodeWrapper);
   3455     var newChild = unwrap(newChildWrapper);
   3456     var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
   3457     remove(newChildWrapper);
   3458     updateWrapperUpAndSideways(newChildWrapper);
   3459     if (!refChildWrapper) {
   3460       parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
   3461       if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
   3462       var lastChildWrapper = wrap(parentNode.lastChild);
   3463       if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
   3464     } else {
   3465       if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
   3466       refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
   3467     }
   3468     scope.originalInsertBefore.call(parentNode, newChild, refChild);
   3469   }
   3470   function remove(nodeWrapper) {
   3471     var node = unwrap(nodeWrapper);
   3472     var parentNode = node.parentNode;
   3473     if (!parentNode) return;
   3474     var parentNodeWrapper = wrap(parentNode);
   3475     updateWrapperUpAndSideways(nodeWrapper);
   3476     if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
   3477     if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
   3478     if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
   3479     if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
   3480     scope.originalRemoveChild.call(parentNode, node);
   3481   }
   3482   var distributedNodesTable = new WeakMap();
   3483   var destinationInsertionPointsTable = new WeakMap();
   3484   var rendererForHostTable = new WeakMap();
   3485   function resetDistributedNodes(insertionPoint) {
   3486     distributedNodesTable.set(insertionPoint, []);
   3487   }
   3488   function getDistributedNodes(insertionPoint) {
   3489     var rv = distributedNodesTable.get(insertionPoint);
   3490     if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
   3491     return rv;
   3492   }
   3493   function getChildNodesSnapshot(node) {
   3494     var result = [], i = 0;
   3495     for (var child = node.firstChild; child; child = child.nextSibling) {
   3496       result[i++] = child;
   3497     }
   3498     return result;
   3499   }
   3500   var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
   3501   var pendingDirtyRenderers = [];
   3502   var renderTimer;
   3503   function renderAllPending() {
   3504     for (var i = 0; i < pendingDirtyRenderers.length; i++) {
   3505       var renderer = pendingDirtyRenderers[i];
   3506       var parentRenderer = renderer.parentRenderer;
   3507       if (parentRenderer && parentRenderer.dirty) continue;
   3508       renderer.render();
   3509     }
   3510     pendingDirtyRenderers = [];
   3511   }
   3512   function handleRequestAnimationFrame() {
   3513     renderTimer = null;
   3514     renderAllPending();
   3515   }
   3516   function getRendererForHost(host) {
   3517     var renderer = rendererForHostTable.get(host);
   3518     if (!renderer) {
   3519       renderer = new ShadowRenderer(host);
   3520       rendererForHostTable.set(host, renderer);
   3521     }
   3522     return renderer;
   3523   }
   3524   function getShadowRootAncestor(node) {
   3525     var root = getTreeScope(node).root;
   3526     if (root instanceof ShadowRoot) return root;
   3527     return null;
   3528   }
   3529   function getRendererForShadowRoot(shadowRoot) {
   3530     return getRendererForHost(shadowRoot.host);
   3531   }
   3532   var spliceDiff = new ArraySplice();
   3533   spliceDiff.equals = function(renderNode, rawNode) {
   3534     return unwrap(renderNode.node) === rawNode;
   3535   };
   3536   function RenderNode(node) {
   3537     this.skip = false;
   3538     this.node = node;
   3539     this.childNodes = [];
   3540   }
   3541   RenderNode.prototype = {
   3542     append: function(node) {
   3543       var rv = new RenderNode(node);
   3544       this.childNodes.push(rv);
   3545       return rv;
   3546     },
   3547     sync: function(opt_added) {
   3548       if (this.skip) return;
   3549       var nodeWrapper = this.node;
   3550       var newChildren = this.childNodes;
   3551       var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
   3552       var added = opt_added || new WeakMap();
   3553       var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
   3554       var newIndex = 0, oldIndex = 0;
   3555       var lastIndex = 0;
   3556       for (var i = 0; i < splices.length; i++) {
   3557         var splice = splices[i];
   3558         for (;lastIndex < splice.index; lastIndex++) {
   3559           oldIndex++;
   3560           newChildren[newIndex++].sync(added);
   3561         }
   3562         var removedCount = splice.removed.length;
   3563         for (var j = 0; j < removedCount; j++) {
   3564           var wrapper = wrap(oldChildren[oldIndex++]);
   3565           if (!added.get(wrapper)) remove(wrapper);
   3566         }
   3567         var addedCount = splice.addedCount;
   3568         var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
   3569         for (var j = 0; j < addedCount; j++) {
   3570           var newChildRenderNode = newChildren[newIndex++];
   3571           var newChildWrapper = newChildRenderNode.node;
   3572           insertBefore(nodeWrapper, newChildWrapper, refNode);
   3573           added.set(newChildWrapper, true);
   3574           newChildRenderNode.sync(added);
   3575         }
   3576         lastIndex += addedCount;
   3577       }
   3578       for (var i = lastIndex; i < newChildren.length; i++) {
   3579         newChildren[i].sync(added);
   3580       }
   3581     }
   3582   };
   3583   function ShadowRenderer(host) {
   3584     this.host = host;
   3585     this.dirty = false;
   3586     this.invalidateAttributes();
   3587     this.associateNode(host);
   3588   }
   3589   ShadowRenderer.prototype = {
   3590     render: function(opt_renderNode) {
   3591       if (!this.dirty) return;
   3592       this.invalidateAttributes();
   3593       var host = this.host;
   3594       this.distribution(host);
   3595       var renderNode = opt_renderNode || new RenderNode(host);
   3596       this.buildRenderTree(renderNode, host);
   3597       var topMostRenderer = !opt_renderNode;
   3598       if (topMostRenderer) renderNode.sync();
   3599       this.dirty = false;
   3600     },
   3601     get parentRenderer() {
   3602       return getTreeScope(this.host).renderer;
   3603     },
   3604     invalidate: function() {
   3605       if (!this.dirty) {
   3606         this.dirty = true;
   3607         var parentRenderer = this.parentRenderer;
   3608         if (parentRenderer) parentRenderer.invalidate();
   3609         pendingDirtyRenderers.push(this);
   3610         if (renderTimer) return;
   3611         renderTimer = window[request](handleRequestAnimationFrame, 0);
   3612       }
   3613     },
   3614     distribution: function(root) {
   3615       this.resetAllSubtrees(root);
   3616       this.distributionResolution(root);
   3617     },
   3618     resetAll: function(node) {
   3619       if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
   3620       this.resetAllSubtrees(node);
   3621     },
   3622     resetAllSubtrees: function(node) {
   3623       for (var child = node.firstChild; child; child = child.nextSibling) {
   3624         this.resetAll(child);
   3625       }
   3626       if (node.shadowRoot) this.resetAll(node.shadowRoot);
   3627       if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
   3628     },
   3629     distributionResolution: function(node) {
   3630       if (isShadowHost(node)) {
   3631         var shadowHost = node;
   3632         var pool = poolPopulation(shadowHost);
   3633         var shadowTrees = getShadowTrees(shadowHost);
   3634         for (var i = 0; i < shadowTrees.length; i++) {
   3635           this.poolDistribution(shadowTrees[i], pool);
   3636         }
   3637         for (var i = shadowTrees.length - 1; i >= 0; i--) {
   3638           var shadowTree = shadowTrees[i];
   3639           var shadow = getShadowInsertionPoint(shadowTree);
   3640           if (shadow) {
   3641             var olderShadowRoot = shadowTree.olderShadowRoot;
   3642             if (olderShadowRoot) {
   3643               pool = poolPopulation(olderShadowRoot);
   3644             }
   3645             for (var j = 0; j < pool.length; j++) {
   3646               destributeNodeInto(pool[j], shadow);
   3647             }
   3648           }
   3649           this.distributionResolution(shadowTree);
   3650         }
   3651       }
   3652       for (var child = node.firstChild; child; child = child.nextSibling) {
   3653         this.distributionResolution(child);
   3654       }
   3655     },
   3656     poolDistribution: function(node, pool) {
   3657       if (node instanceof HTMLShadowElement) return;
   3658       if (node instanceof HTMLContentElement) {
   3659         var content = node;
   3660         this.updateDependentAttributes(content.getAttribute("select"));
   3661         var anyDistributed = false;
   3662         for (var i = 0; i < pool.length; i++) {
   3663           var node = pool[i];
   3664           if (!node) continue;
   3665           if (matches(node, content)) {
   3666             destributeNodeInto(node, content);
   3667             pool[i] = undefined;
   3668             anyDistributed = true;
   3669           }
   3670         }
   3671         if (!anyDistributed) {
   3672           for (var child = content.firstChild; child; child = child.nextSibling) {
   3673             destributeNodeInto(child, content);
   3674           }
   3675         }
   3676         return;
   3677       }
   3678       for (var child = node.firstChild; child; child = child.nextSibling) {
   3679         this.poolDistribution(child, pool);
   3680       }
   3681     },
   3682     buildRenderTree: function(renderNode, node) {
   3683       var children = this.compose(node);
   3684       for (var i = 0; i < children.length; i++) {
   3685         var child = children[i];
   3686         var childRenderNode = renderNode.append(child);
   3687         this.buildRenderTree(childRenderNode, child);
   3688       }
   3689       if (isShadowHost(node)) {
   3690         var renderer = getRendererForHost(node);
   3691         renderer.dirty = false;
   3692       }
   3693     },
   3694     compose: function(node) {
   3695       var children = [];
   3696       var p = node.shadowRoot || node;
   3697       for (var child = p.firstChild; child; child = child.nextSibling) {
   3698         if (isInsertionPoint(child)) {
   3699           this.associateNode(p);
   3700           var distributedNodes = getDistributedNodes(child);
   3701           for (var j = 0; j < distributedNodes.length; j++) {
   3702             var distributedNode = distributedNodes[j];
   3703             if (isFinalDestination(child, distributedNode)) children.push(distributedNode);
   3704           }
   3705         } else {
   3706           children.push(child);
   3707         }
   3708       }
   3709       return children;
   3710     },
   3711     invalidateAttributes: function() {
   3712       this.attributes = Object.create(null);
   3713     },
   3714     updateDependentAttributes: function(selector) {
   3715       if (!selector) return;
   3716       var attributes = this.attributes;
   3717       if (/\.\w+/.test(selector)) attributes["class"] = true;
   3718       if (/#\w+/.test(selector)) attributes["id"] = true;
   3719       selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
   3720         attributes[name] = true;
   3721       });
   3722     },
   3723     dependsOnAttribute: function(name) {
   3724       return this.attributes[name];
   3725     },
   3726     associateNode: function(node) {
   3727       unsafeUnwrap(node).polymerShadowRenderer_ = this;
   3728     }
   3729   };
   3730   function poolPopulation(node) {
   3731     var pool = [];
   3732     for (var child = node.firstChild; child; child = child.nextSibling) {
   3733       if (isInsertionPoint(child)) {
   3734         pool.push.apply(pool, getDistributedNodes(child));
   3735       } else {
   3736         pool.push(child);
   3737       }
   3738     }
   3739     return pool;
   3740   }
   3741   function getShadowInsertionPoint(node) {
   3742     if (node instanceof HTMLShadowElement) return node;
   3743     if (node instanceof HTMLContentElement) return null;
   3744     for (var child = node.firstChild; child; child = child.nextSibling) {
   3745       var res = getShadowInsertionPoint(child);
   3746       if (res) return res;
   3747     }
   3748     return null;
   3749   }
   3750   function destributeNodeInto(child, insertionPoint) {
   3751     getDistributedNodes(insertionPoint).push(child);
   3752     var points = destinationInsertionPointsTable.get(child);
   3753     if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
   3754   }
   3755   function getDestinationInsertionPoints(node) {
   3756     return destinationInsertionPointsTable.get(node);
   3757   }
   3758   function resetDestinationInsertionPoints(node) {
   3759     destinationInsertionPointsTable.set(node, undefined);
   3760   }
   3761   var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
   3762   function matches(node, contentElement) {
   3763     var select = contentElement.getAttribute("select");
   3764     if (!select) return true;
   3765     select = select.trim();
   3766     if (!select) return true;
   3767     if (!(node instanceof Element)) return false;
   3768     if (!selectorStartCharRe.test(select)) return false;
   3769     try {
   3770       return node.matches(select);
   3771     } catch (ex) {
   3772       return false;
   3773     }
   3774   }
   3775   function isFinalDestination(insertionPoint, node) {
   3776     var points = getDestinationInsertionPoints(node);
   3777     return points && points[points.length - 1] === insertionPoint;
   3778   }
   3779   function isInsertionPoint(node) {
   3780     return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
   3781   }
   3782   function isShadowHost(shadowHost) {
   3783     return shadowHost.shadowRoot;
   3784   }
   3785   function getShadowTrees(host) {
   3786     var trees = [];
   3787     for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
   3788       trees.push(tree);
   3789     }
   3790     return trees;
   3791   }
   3792   function render(host) {
   3793     new ShadowRenderer(host).render();
   3794   }
   3795   Node.prototype.invalidateShadowRenderer = function(force) {
   3796     var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
   3797     if (renderer) {
   3798       renderer.invalidate();
   3799       return true;
   3800     }
   3801     return false;
   3802   };
   3803   HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
   3804     renderAllPending();
   3805     return getDistributedNodes(this);
   3806   };
   3807   Element.prototype.getDestinationInsertionPoints = function() {
   3808     renderAllPending();
   3809     return getDestinationInsertionPoints(this) || [];
   3810   };
   3811   HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
   3812     this.invalidateShadowRenderer();
   3813     var shadowRoot = getShadowRootAncestor(this);
   3814     var renderer;
   3815     if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
   3816     unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
   3817     if (renderer) renderer.invalidate();
   3818   };
   3819   scope.getRendererForHost = getRendererForHost;
   3820   scope.getShadowTrees = getShadowTrees;
   3821   scope.renderAllPending = renderAllPending;
   3822   scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
   3823   scope.visual = {
   3824     insertBefore: insertBefore,
   3825     remove: remove
   3826   };
   3827 })(window.ShadowDOMPolyfill);
   3828 
   3829 (function(scope) {
   3830   "use strict";
   3831   var HTMLElement = scope.wrappers.HTMLElement;
   3832   var assert = scope.assert;
   3833   var mixin = scope.mixin;
   3834   var registerWrapper = scope.registerWrapper;
   3835   var unwrap = scope.unwrap;
   3836   var wrap = scope.wrap;
   3837   var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
   3838   function createWrapperConstructor(name) {
   3839     if (!window[name]) return;
   3840     assert(!scope.wrappers[name]);
   3841     var GeneratedWrapper = function(node) {
   3842       HTMLElement.call(this, node);
   3843     };
   3844     GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
   3845     mixin(GeneratedWrapper.prototype, {
   3846       get form() {
   3847         return wrap(unwrap(this).form);
   3848       }
   3849     });
   3850     registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
   3851     scope.wrappers[name] = GeneratedWrapper;
   3852   }
   3853   elementsWithFormProperty.forEach(createWrapperConstructor);
   3854 })(window.ShadowDOMPolyfill);
   3855 
   3856 (function(scope) {
   3857   "use strict";
   3858   var registerWrapper = scope.registerWrapper;
   3859   var setWrapper = scope.setWrapper;
   3860   var unsafeUnwrap = scope.unsafeUnwrap;
   3861   var unwrap = scope.unwrap;
   3862   var unwrapIfNeeded = scope.unwrapIfNeeded;
   3863   var wrap = scope.wrap;
   3864   var OriginalSelection = window.Selection;
   3865   function Selection(impl) {
   3866     setWrapper(impl, this);
   3867   }
   3868   Selection.prototype = {
   3869     get anchorNode() {
   3870       return wrap(unsafeUnwrap(this).anchorNode);
   3871     },
   3872     get focusNode() {
   3873       return wrap(unsafeUnwrap(this).focusNode);
   3874     },
   3875     addRange: function(range) {
   3876       unsafeUnwrap(this).addRange(unwrap(range));
   3877     },
   3878     collapse: function(node, index) {
   3879       unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
   3880     },
   3881     containsNode: function(node, allowPartial) {
   3882       return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
   3883     },
   3884     extend: function(node, offset) {
   3885       unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
   3886     },
   3887     getRangeAt: function(index) {
   3888       return wrap(unsafeUnwrap(this).getRangeAt(index));
   3889     },
   3890     removeRange: function(range) {
   3891       unsafeUnwrap(this).removeRange(unwrap(range));
   3892     },
   3893     selectAllChildren: function(node) {
   3894       unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
   3895     },
   3896     toString: function() {
   3897       return unsafeUnwrap(this).toString();
   3898     }
   3899   };
   3900   registerWrapper(window.Selection, Selection, window.getSelection());
   3901   scope.wrappers.Selection = Selection;
   3902 })(window.ShadowDOMPolyfill);
   3903 
   3904 (function(scope) {
   3905   "use strict";
   3906   var GetElementsByInterface = scope.GetElementsByInterface;
   3907   var Node = scope.wrappers.Node;
   3908   var ParentNodeInterface = scope.ParentNodeInterface;
   3909   var Selection = scope.wrappers.Selection;
   3910   var SelectorsInterface = scope.SelectorsInterface;
   3911   var ShadowRoot = scope.wrappers.ShadowRoot;
   3912   var TreeScope = scope.TreeScope;
   3913   var cloneNode = scope.cloneNode;
   3914   var defineWrapGetter = scope.defineWrapGetter;
   3915   var elementFromPoint = scope.elementFromPoint;
   3916   var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
   3917   var matchesNames = scope.matchesNames;
   3918   var mixin = scope.mixin;
   3919   var registerWrapper = scope.registerWrapper;
   3920   var renderAllPending = scope.renderAllPending;
   3921   var rewrap = scope.rewrap;
   3922   var setWrapper = scope.setWrapper;
   3923   var unsafeUnwrap = scope.unsafeUnwrap;
   3924   var unwrap = scope.unwrap;
   3925   var wrap = scope.wrap;
   3926   var wrapEventTargetMethods = scope.wrapEventTargetMethods;
   3927   var wrapNodeList = scope.wrapNodeList;
   3928   var implementationTable = new WeakMap();
   3929   function Document(node) {
   3930     Node.call(this, node);
   3931     this.treeScope_ = new TreeScope(this, null);
   3932   }
   3933   Document.prototype = Object.create(Node.prototype);
   3934   defineWrapGetter(Document, "documentElement");
   3935   defineWrapGetter(Document, "body");
   3936   defineWrapGetter(Document, "head");
   3937   function wrapMethod(name) {
   3938     var original = document[name];
   3939     Document.prototype[name] = function() {
   3940       return wrap(original.apply(unsafeUnwrap(this), arguments));
   3941     };
   3942   }
   3943   [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "getElementById" ].forEach(wrapMethod);
   3944   var originalAdoptNode = document.adoptNode;
   3945   function adoptNodeNoRemove(node, doc) {
   3946     originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
   3947     adoptSubtree(node, doc);
   3948   }
   3949   function adoptSubtree(node, doc) {
   3950     if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
   3951     if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
   3952     for (var child = node.firstChild; child; child = child.nextSibling) {
   3953       adoptSubtree(child, doc);
   3954     }
   3955   }
   3956   function adoptOlderShadowRoots(shadowRoot, doc) {
   3957     var oldShadowRoot = shadowRoot.olderShadowRoot;
   3958     if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
   3959   }
   3960   var originalGetSelection = document.getSelection;
   3961   mixin(Document.prototype, {
   3962     adoptNode: function(node) {
   3963       if (node.parentNode) node.parentNode.removeChild(node);
   3964       adoptNodeNoRemove(node, this);
   3965       return node;
   3966     },
   3967     elementFromPoint: function(x, y) {
   3968       return elementFromPoint(this, this, x, y);
   3969     },
   3970     importNode: function(node, deep) {
   3971       return cloneNode(node, deep, unsafeUnwrap(this));
   3972     },
   3973     getSelection: function() {
   3974       renderAllPending();
   3975       return new Selection(originalGetSelection.call(unwrap(this)));
   3976     },
   3977     getElementsByName: function(name) {
   3978       return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
   3979     }
   3980   });
   3981   if (document.registerElement) {
   3982     var originalRegisterElement = document.registerElement;
   3983     Document.prototype.registerElement = function(tagName, object) {
   3984       var prototype, extendsOption;
   3985       if (object !== undefined) {
   3986         prototype = object.prototype;
   3987         extendsOption = object.extends;
   3988       }
   3989       if (!prototype) prototype = Object.create(HTMLElement.prototype);
   3990       if (scope.nativePrototypeTable.get(prototype)) {
   3991         throw new Error("NotSupportedError");
   3992       }
   3993       var proto = Object.getPrototypeOf(prototype);
   3994       var nativePrototype;
   3995       var prototypes = [];
   3996       while (proto) {
   3997         nativePrototype = scope.nativePrototypeTable.get(proto);
   3998         if (nativePrototype) break;
   3999         prototypes.push(proto);
   4000         proto = Object.getPrototypeOf(proto);
   4001       }
   4002       if (!nativePrototype) {
   4003         throw new Error("NotSupportedError");
   4004       }
   4005       var newPrototype = Object.create(nativePrototype);
   4006       for (var i = prototypes.length - 1; i >= 0; i--) {
   4007         newPrototype = Object.create(newPrototype);
   4008       }
   4009       [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
   4010         var f = prototype[name];
   4011         if (!f) return;
   4012         newPrototype[name] = function() {
   4013           if (!(wrap(this) instanceof CustomElementConstructor)) {
   4014             rewrap(this);
   4015           }
   4016           f.apply(wrap(this), arguments);
   4017         };
   4018       });
   4019       var p = {
   4020         prototype: newPrototype
   4021       };
   4022       if (extendsOption) p.extends = extendsOption;
   4023       function CustomElementConstructor(node) {
   4024         if (!node) {
   4025           if (extendsOption) {
   4026             return document.createElement(extendsOption, tagName);
   4027           } else {
   4028             return document.createElement(tagName);
   4029           }
   4030         }
   4031         setWrapper(node, this);
   4032       }
   4033       CustomElementConstructor.prototype = prototype;
   4034       CustomElementConstructor.prototype.constructor = CustomElementConstructor;
   4035       scope.constructorTable.set(newPrototype, CustomElementConstructor);
   4036       scope.nativePrototypeTable.set(prototype, newPrototype);
   4037       var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
   4038       return CustomElementConstructor;
   4039     };
   4040     forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
   4041   }
   4042   forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
   4043   forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
   4044   forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
   4045   mixin(Document.prototype, GetElementsByInterface);
   4046   mixin(Document.prototype, ParentNodeInterface);
   4047   mixin(Document.prototype, SelectorsInterface);
   4048   mixin(Document.prototype, {
   4049     get implementation() {
   4050       var implementation = implementationTable.get(this);
   4051       if (implementation) return implementation;
   4052       implementation = new DOMImplementation(unwrap(this).implementation);
   4053       implementationTable.set(this, implementation);
   4054       return implementation;
   4055     },
   4056     get defaultView() {
   4057       return wrap(unwrap(this).defaultView);
   4058     }
   4059   });
   4060   registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
   4061   if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
   4062   wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
   4063   function DOMImplementation(impl) {
   4064     setWrapper(impl, this);
   4065   }
   4066   function wrapImplMethod(constructor, name) {
   4067     var original = document.implementation[name];
   4068     constructor.prototype[name] = function() {
   4069       return wrap(original.apply(unsafeUnwrap(this), arguments));
   4070     };
   4071   }
   4072   function forwardImplMethod(constructor, name) {
   4073     var original = document.implementation[name];
   4074     constructor.prototype[name] = function() {
   4075       return original.apply(unsafeUnwrap(this), arguments);
   4076     };
   4077   }
   4078   wrapImplMethod(DOMImplementation, "createDocumentType");
   4079   wrapImplMethod(DOMImplementation, "createDocument");
   4080   wrapImplMethod(DOMImplementation, "createHTMLDocument");
   4081   forwardImplMethod(DOMImplementation, "hasFeature");
   4082   registerWrapper(window.DOMImplementation, DOMImplementation);
   4083   forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocumentType", "createDocument", "createHTMLDocument", "hasFeature" ]);
   4084   scope.adoptNodeNoRemove = adoptNodeNoRemove;
   4085   scope.wrappers.DOMImplementation = DOMImplementation;
   4086   scope.wrappers.Document = Document;
   4087 })(window.ShadowDOMPolyfill);
   4088 
   4089 (function(scope) {
   4090   "use strict";
   4091   var EventTarget = scope.wrappers.EventTarget;
   4092   var Selection = scope.wrappers.Selection;
   4093   var mixin = scope.mixin;
   4094   var registerWrapper = scope.registerWrapper;
   4095   var renderAllPending = scope.renderAllPending;
   4096   var unwrap = scope.unwrap;
   4097   var unwrapIfNeeded = scope.unwrapIfNeeded;
   4098   var wrap = scope.wrap;
   4099   var OriginalWindow = window.Window;
   4100   var originalGetComputedStyle = window.getComputedStyle;
   4101   var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
   4102   var originalGetSelection = window.getSelection;
   4103   function Window(impl) {
   4104     EventTarget.call(this, impl);
   4105   }
   4106   Window.prototype = Object.create(EventTarget.prototype);
   4107   OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
   4108     return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
   4109   };
   4110   if (originalGetDefaultComputedStyle) {
   4111     OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
   4112       return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
   4113     };
   4114   }
   4115   OriginalWindow.prototype.getSelection = function() {
   4116     return wrap(this || window).getSelection();
   4117   };
   4118   delete window.getComputedStyle;
   4119   delete window.getDefaultComputedStyle;
   4120   delete window.getSelection;
   4121   [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
   4122     OriginalWindow.prototype[name] = function() {
   4123       var w = wrap(this || window);
   4124       return w[name].apply(w, arguments);
   4125     };
   4126     delete window[name];
   4127   });
   4128   mixin(Window.prototype, {
   4129     getComputedStyle: function(el, pseudo) {
   4130       renderAllPending();
   4131       return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
   4132     },
   4133     getSelection: function() {
   4134       renderAllPending();
   4135       return new Selection(originalGetSelection.call(unwrap(this)));
   4136     },
   4137     get document() {
   4138       return wrap(unwrap(this).document);
   4139     }
   4140   });
   4141   if (originalGetDefaultComputedStyle) {
   4142     Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
   4143       renderAllPending();
   4144       return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
   4145     };
   4146   }
   4147   registerWrapper(OriginalWindow, Window, window);
   4148   scope.wrappers.Window = Window;
   4149 })(window.ShadowDOMPolyfill);
   4150 
   4151 (function(scope) {
   4152   "use strict";
   4153   var unwrap = scope.unwrap;
   4154   var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
   4155   var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
   4156   if (OriginalDataTransferSetDragImage) {
   4157     OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
   4158       OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
   4159     };
   4160   }
   4161 })(window.ShadowDOMPolyfill);
   4162 
   4163 (function(scope) {
   4164   "use strict";
   4165   var registerWrapper = scope.registerWrapper;
   4166   var setWrapper = scope.setWrapper;
   4167   var unwrap = scope.unwrap;
   4168   var OriginalFormData = window.FormData;
   4169   if (!OriginalFormData) return;
   4170   function FormData(formElement) {
   4171     var impl;
   4172     if (formElement instanceof OriginalFormData) {
   4173       impl = formElement;
   4174     } else {
   4175       impl = new OriginalFormData(formElement && unwrap(formElement));
   4176     }
   4177     setWrapper(impl, this);
   4178   }
   4179   registerWrapper(OriginalFormData, FormData, new OriginalFormData());
   4180   scope.wrappers.FormData = FormData;
   4181 })(window.ShadowDOMPolyfill);
   4182 
   4183 (function(scope) {
   4184   "use strict";
   4185   var unwrapIfNeeded = scope.unwrapIfNeeded;
   4186   var originalSend = XMLHttpRequest.prototype.send;
   4187   XMLHttpRequest.prototype.send = function(obj) {
   4188     return originalSend.call(this, unwrapIfNeeded(obj));
   4189   };
   4190 })(window.ShadowDOMPolyfill);
   4191 
   4192 (function(scope) {
   4193   "use strict";
   4194   var isWrapperFor = scope.isWrapperFor;
   4195   var elements = {
   4196     a: "HTMLAnchorElement",
   4197     area: "HTMLAreaElement",
   4198     audio: "HTMLAudioElement",
   4199     base: "HTMLBaseElement",
   4200     body: "HTMLBodyElement",
   4201     br: "HTMLBRElement",
   4202     button: "HTMLButtonElement",
   4203     canvas: "HTMLCanvasElement",
   4204     caption: "HTMLTableCaptionElement",
   4205     col: "HTMLTableColElement",
   4206     content: "HTMLContentElement",
   4207     data: "HTMLDataElement",
   4208     datalist: "HTMLDataListElement",
   4209     del: "HTMLModElement",
   4210     dir: "HTMLDirectoryElement",
   4211     div: "HTMLDivElement",
   4212     dl: "HTMLDListElement",
   4213     embed: "HTMLEmbedElement",
   4214     fieldset: "HTMLFieldSetElement",
   4215     font: "HTMLFontElement",
   4216     form: "HTMLFormElement",
   4217     frame: "HTMLFrameElement",
   4218     frameset: "HTMLFrameSetElement",
   4219     h1: "HTMLHeadingElement",
   4220     head: "HTMLHeadElement",
   4221     hr: "HTMLHRElement",
   4222     html: "HTMLHtmlElement",
   4223     iframe: "HTMLIFrameElement",
   4224     img: "HTMLImageElement",
   4225     input: "HTMLInputElement",
   4226     keygen: "HTMLKeygenElement",
   4227     label: "HTMLLabelElement",
   4228     legend: "HTMLLegendElement",
   4229     li: "HTMLLIElement",
   4230     link: "HTMLLinkElement",
   4231     map: "HTMLMapElement",
   4232     marquee: "HTMLMarqueeElement",
   4233     menu: "HTMLMenuElement",
   4234     menuitem: "HTMLMenuItemElement",
   4235     meta: "HTMLMetaElement",
   4236     meter: "HTMLMeterElement",
   4237     object: "HTMLObjectElement",
   4238     ol: "HTMLOListElement",
   4239     optgroup: "HTMLOptGroupElement",
   4240     option: "HTMLOptionElement",
   4241     output: "HTMLOutputElement",
   4242     p: "HTMLParagraphElement",
   4243     param: "HTMLParamElement",
   4244     pre: "HTMLPreElement",
   4245     progress: "HTMLProgressElement",
   4246     q: "HTMLQuoteElement",
   4247     script: "HTMLScriptElement",
   4248     select: "HTMLSelectElement",
   4249     shadow: "HTMLShadowElement",
   4250     source: "HTMLSourceElement",
   4251     span: "HTMLSpanElement",
   4252     style: "HTMLStyleElement",
   4253     table: "HTMLTableElement",
   4254     tbody: "HTMLTableSectionElement",
   4255     template: "HTMLTemplateElement",
   4256     textarea: "HTMLTextAreaElement",
   4257     thead: "HTMLTableSectionElement",
   4258     time: "HTMLTimeElement",
   4259     title: "HTMLTitleElement",
   4260     tr: "HTMLTableRowElement",
   4261     track: "HTMLTrackElement",
   4262     ul: "HTMLUListElement",
   4263     video: "HTMLVideoElement"
   4264   };
   4265   function overrideConstructor(tagName) {
   4266     var nativeConstructorName = elements[tagName];
   4267     var nativeConstructor = window[nativeConstructorName];
   4268     if (!nativeConstructor) return;
   4269     var element = document.createElement(tagName);
   4270     var wrapperConstructor = element.constructor;
   4271     window[nativeConstructorName] = wrapperConstructor;
   4272   }
   4273   Object.keys(elements).forEach(overrideConstructor);
   4274   Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
   4275     window[name] = scope.wrappers[name];
   4276   });
   4277 })(window.ShadowDOMPolyfill);