UNPKG

d2-ui

Version:
1,363 lines (1,358 loc) 232 kB
/** * @license * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt * @providesModule WebComponents */ // @version 0.5.1 window.WebComponents = window.WebComponents || {}; (function(scope) { var flags = scope.flags || {}; var file = "webcomponents.js"; var script = document.querySelector('script[src*="' + file + '"]'); var flags = {}; if (!flags.noOpts) { location.search.slice(1).split("&").forEach(function(o) { o = o.split("="); o[0] && (flags[o[0]] = o[1] || true); }); if (script) { for (var i = 0, a; a = script.attributes[i]; i++) { if (a.name !== "src") { flags[a.name] = a.value || true; } } } if (flags.log) { var parts = flags.log.split(","); flags.log = {}; parts.forEach(function(f) { flags.log[f] = true; }); } else { flags.log = {}; } } flags.shadow = flags.shadow || flags.shadowdom || flags.polyfill; if (flags.shadow === "native") { flags.shadow = false; } else { flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot; } if (flags.register) { window.CustomElements = window.CustomElements || { flags: {} }; window.CustomElements.flags.register = flags.register; } scope.flags = flags; })(WebComponents); if (WebComponents.flags.shadow) { if (typeof WeakMap === "undefined") { (function() { var defineProperty = Object.defineProperty; var counter = Date.now() % 1e9; var WeakMap = function() { this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__"); }; WeakMap.prototype = { set: function(key, value) { var entry = key[this.name]; if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, { value: [ key, value ], writable: true }); return this; }, get: function(key) { var entry; return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined; }, "delete": function(key) { var entry = key[this.name]; if (!entry || entry[0] !== key) return false; entry[0] = entry[1] = undefined; return true; }, has: function(key) { var entry = key[this.name]; if (!entry) return false; return entry[0] === key; } }; window.WeakMap = WeakMap; })(); } window.ShadowDOMPolyfill = {}; (function(scope) { "use strict"; var constructorTable = new WeakMap(); var nativePrototypeTable = new WeakMap(); var wrappers = Object.create(null); function detectEval() { if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) { return false; } if (navigator.getDeviceStorage) { return false; } try { var f = new Function("return true;"); return f(); } catch (ex) { return false; } } var hasEval = detectEval(); function assert(b) { if (!b) throw new Error("Assertion failed"); } var defineProperty = Object.defineProperty; var getOwnPropertyNames = Object.getOwnPropertyNames; var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; function mixin(to, from) { var names = getOwnPropertyNames(from); for (var i = 0; i < names.length; i++) { var name = names[i]; defineProperty(to, name, getOwnPropertyDescriptor(from, name)); } return to; } function mixinStatics(to, from) { var names = getOwnPropertyNames(from); for (var i = 0; i < names.length; i++) { var name = names[i]; switch (name) { case "arguments": case "caller": case "length": case "name": case "prototype": case "toString": continue; } defineProperty(to, name, getOwnPropertyDescriptor(from, name)); } return to; } function oneOf(object, propertyNames) { for (var i = 0; i < propertyNames.length; i++) { if (propertyNames[i] in object) return propertyNames[i]; } } var nonEnumerableDataDescriptor = { value: undefined, configurable: true, enumerable: false, writable: true }; function defineNonEnumerableDataProperty(object, name, value) { nonEnumerableDataDescriptor.value = value; defineProperty(object, name, nonEnumerableDataDescriptor); } getOwnPropertyNames(window); function getWrapperConstructor(node) { var nativePrototype = node.__proto__ || Object.getPrototypeOf(node); var wrapperConstructor = constructorTable.get(nativePrototype); if (wrapperConstructor) return wrapperConstructor; var parentWrapperConstructor = getWrapperConstructor(nativePrototype); var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor); registerInternal(nativePrototype, GeneratedWrapper, node); return GeneratedWrapper; } function addForwardingProperties(nativePrototype, wrapperPrototype) { installProperty(nativePrototype, wrapperPrototype, true); } function registerInstanceProperties(wrapperPrototype, instanceObject) { installProperty(instanceObject, wrapperPrototype, false); } var isFirefox = /Firefox/.test(navigator.userAgent); var dummyDescriptor = { get: function() {}, set: function(v) {}, configurable: true, enumerable: true }; function isEventHandlerName(name) { return /^on[a-z]+$/.test(name); } function isIdentifierName(name) { return /^\w[a-zA-Z_0-9]*$/.test(name); } function getGetter(name) { return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() { return this.__impl4cf1e782hg__[name]; }; } function getSetter(name) { return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) { this.__impl4cf1e782hg__[name] = v; }; } function getMethod(name) { return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() { return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments); }; } function getDescriptor(source, name) { try { return Object.getOwnPropertyDescriptor(source, name); } catch (ex) { return dummyDescriptor; } } var isBrokenSafari = function() { var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType"); return descr && !descr.get && !descr.set; }(); function installProperty(source, target, allowMethod, opt_blacklist) { var names = getOwnPropertyNames(source); for (var i = 0; i < names.length; i++) { var name = names[i]; if (name === "polymerBlackList_") continue; if (name in target) continue; if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue; if (isFirefox) { source.__lookupGetter__(name); } var descriptor = getDescriptor(source, name); var getter, setter; if (allowMethod && typeof descriptor.value === "function") { target[name] = getMethod(name); continue; } var isEvent = isEventHandlerName(name); if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name); if (descriptor.writable || descriptor.set || isBrokenSafari) { if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name); } defineProperty(target, name, { get: getter, set: setter, configurable: descriptor.configurable, enumerable: descriptor.enumerable }); } } function register(nativeConstructor, wrapperConstructor, opt_instance) { var nativePrototype = nativeConstructor.prototype; registerInternal(nativePrototype, wrapperConstructor, opt_instance); mixinStatics(wrapperConstructor, nativeConstructor); } function registerInternal(nativePrototype, wrapperConstructor, opt_instance) { var wrapperPrototype = wrapperConstructor.prototype; assert(constructorTable.get(nativePrototype) === undefined); constructorTable.set(nativePrototype, wrapperConstructor); nativePrototypeTable.set(wrapperPrototype, nativePrototype); addForwardingProperties(nativePrototype, wrapperPrototype); if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance); defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor); wrapperConstructor.prototype = wrapperPrototype; } function isWrapperFor(wrapperConstructor, nativeConstructor) { return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor; } function registerObject(object) { var nativePrototype = Object.getPrototypeOf(object); var superWrapperConstructor = getWrapperConstructor(nativePrototype); var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor); registerInternal(nativePrototype, GeneratedWrapper, object); return GeneratedWrapper; } function createWrapperConstructor(superWrapperConstructor) { function GeneratedWrapper(node) { superWrapperConstructor.call(this, node); } var p = Object.create(superWrapperConstructor.prototype); p.constructor = GeneratedWrapper; GeneratedWrapper.prototype = p; return GeneratedWrapper; } function isWrapper(object) { return object && object.__impl4cf1e782hg__; } function isNative(object) { return !isWrapper(object); } function wrap(impl) { if (impl === null) return null; assert(isNative(impl)); return impl.__wrapper8e3dd93a60__ || (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl)); } function unwrap(wrapper) { if (wrapper === null) return null; assert(isWrapper(wrapper)); return wrapper.__impl4cf1e782hg__; } function unsafeUnwrap(wrapper) { return wrapper.__impl4cf1e782hg__; } function setWrapper(impl, wrapper) { wrapper.__impl4cf1e782hg__ = impl; impl.__wrapper8e3dd93a60__ = wrapper; } function unwrapIfNeeded(object) { return object && isWrapper(object) ? unwrap(object) : object; } function wrapIfNeeded(object) { return object && !isWrapper(object) ? wrap(object) : object; } function rewrap(node, wrapper) { if (wrapper === null) return; assert(isNative(node)); assert(wrapper === undefined || isWrapper(wrapper)); node.__wrapper8e3dd93a60__ = wrapper; } var getterDescriptor = { get: undefined, configurable: true, enumerable: true }; function defineGetter(constructor, name, getter) { getterDescriptor.get = getter; defineProperty(constructor.prototype, name, getterDescriptor); } function defineWrapGetter(constructor, name) { defineGetter(constructor, name, function() { return wrap(this.__impl4cf1e782hg__[name]); }); } function forwardMethodsToWrapper(constructors, names) { constructors.forEach(function(constructor) { names.forEach(function(name) { constructor.prototype[name] = function() { var w = wrapIfNeeded(this); return w[name].apply(w, arguments); }; }); }); } scope.assert = assert; scope.constructorTable = constructorTable; scope.defineGetter = defineGetter; scope.defineWrapGetter = defineWrapGetter; scope.forwardMethodsToWrapper = forwardMethodsToWrapper; scope.isWrapper = isWrapper; scope.isWrapperFor = isWrapperFor; scope.mixin = mixin; scope.nativePrototypeTable = nativePrototypeTable; scope.oneOf = oneOf; scope.registerObject = registerObject; scope.registerWrapper = register; scope.rewrap = rewrap; scope.setWrapper = setWrapper; scope.unsafeUnwrap = unsafeUnwrap; scope.unwrap = unwrap; scope.unwrapIfNeeded = unwrapIfNeeded; scope.wrap = wrap; scope.wrapIfNeeded = wrapIfNeeded; scope.wrappers = wrappers; })(window.ShadowDOMPolyfill); (function(scope) { "use strict"; function newSplice(index, removed, addedCount) { return { index: index, removed: removed, addedCount: addedCount }; } var EDIT_LEAVE = 0; var EDIT_UPDATE = 1; var EDIT_ADD = 2; var EDIT_DELETE = 3; function ArraySplice() {} ArraySplice.prototype = { calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) { var rowCount = oldEnd - oldStart + 1; var columnCount = currentEnd - currentStart + 1; var distances = new Array(rowCount); for (var i = 0; i < rowCount; i++) { distances[i] = new Array(columnCount); distances[i][0] = i; } for (var j = 0; j < columnCount; j++) distances[0][j] = j; for (var i = 1; i < rowCount; i++) { for (var j = 1; j < columnCount; j++) { if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else { var north = distances[i - 1][j] + 1; var west = distances[i][j - 1] + 1; distances[i][j] = north < west ? north : west; } } } return distances; }, spliceOperationsFromEditDistances: function(distances) { var i = distances.length - 1; var j = distances[0].length - 1; var current = distances[i][j]; var edits = []; while (i > 0 || j > 0) { if (i == 0) { edits.push(EDIT_ADD); j--; continue; } if (j == 0) { edits.push(EDIT_DELETE); i--; continue; } var northWest = distances[i - 1][j - 1]; var west = distances[i - 1][j]; var north = distances[i][j - 1]; var min; if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest; if (min == northWest) { if (northWest == current) { edits.push(EDIT_LEAVE); } else { edits.push(EDIT_UPDATE); current = northWest; } i--; j--; } else if (min == west) { edits.push(EDIT_DELETE); i--; current = west; } else { edits.push(EDIT_ADD); j--; current = north; } } edits.reverse(); return edits; }, calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) { var prefixCount = 0; var suffixCount = 0; var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart); if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength); if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount); currentStart += prefixCount; oldStart += prefixCount; currentEnd -= suffixCount; oldEnd -= suffixCount; if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return []; if (currentStart == currentEnd) { var splice = newSplice(currentStart, [], 0); while (oldStart < oldEnd) splice.removed.push(old[oldStart++]); return [ splice ]; } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ]; var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd)); var splice = undefined; var splices = []; var index = currentStart; var oldIndex = oldStart; for (var i = 0; i < ops.length; i++) { switch (ops[i]) { case EDIT_LEAVE: if (splice) { splices.push(splice); splice = undefined; } index++; oldIndex++; break; case EDIT_UPDATE: if (!splice) splice = newSplice(index, [], 0); splice.addedCount++; index++; splice.removed.push(old[oldIndex]); oldIndex++; break; case EDIT_ADD: if (!splice) splice = newSplice(index, [], 0); splice.addedCount++; index++; break; case EDIT_DELETE: if (!splice) splice = newSplice(index, [], 0); splice.removed.push(old[oldIndex]); oldIndex++; break; } } if (splice) { splices.push(splice); } return splices; }, sharedPrefix: function(current, old, searchLength) { for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i; return searchLength; }, sharedSuffix: function(current, old, searchLength) { var index1 = current.length; var index2 = old.length; var count = 0; while (count < searchLength && this.equals(current[--index1], old[--index2])) count++; return count; }, calculateSplices: function(current, previous) { return this.calcSplices(current, 0, current.length, previous, 0, previous.length); }, equals: function(currentValue, previousValue) { return currentValue === previousValue; } }; scope.ArraySplice = ArraySplice; })(window.ShadowDOMPolyfill); (function(context) { "use strict"; var OriginalMutationObserver = window.MutationObserver; var callbacks = []; var pending = false; var timerFunc; function handle() { pending = false; var copies = callbacks.slice(0); callbacks = []; for (var i = 0; i < copies.length; i++) { (0, copies[i])(); } } if (OriginalMutationObserver) { var counter = 1; var observer = new OriginalMutationObserver(handle); var textNode = document.createTextNode(counter); observer.observe(textNode, { characterData: true }); timerFunc = function() { counter = (counter + 1) % 2; textNode.data = counter; }; } else { timerFunc = window.setTimeout; } function setEndOfMicrotask(func) { callbacks.push(func); if (pending) return; pending = true; timerFunc(handle, 0); } context.setEndOfMicrotask = setEndOfMicrotask; })(window.ShadowDOMPolyfill); (function(scope) { "use strict"; var setEndOfMicrotask = scope.setEndOfMicrotask; var wrapIfNeeded = scope.wrapIfNeeded; var wrappers = scope.wrappers; var registrationsTable = new WeakMap(); var globalMutationObservers = []; var isScheduled = false; function scheduleCallback(observer) { if (observer.scheduled_) return; observer.scheduled_ = true; globalMutationObservers.push(observer); if (isScheduled) return; setEndOfMicrotask(notifyObservers); isScheduled = true; } function notifyObservers() { isScheduled = false; while (globalMutationObservers.length) { var notifyList = globalMutationObservers; globalMutationObservers = []; notifyList.sort(function(x, y) { return x.uid_ - y.uid_; }); for (var i = 0; i < notifyList.length; i++) { var mo = notifyList[i]; mo.scheduled_ = false; var queue = mo.takeRecords(); removeTransientObserversFor(mo); if (queue.length) { mo.callback_(queue, mo); } } } } function MutationRecord(type, target) { this.type = type; this.target = target; this.addedNodes = new wrappers.NodeList(); this.removedNodes = new wrappers.NodeList(); this.previousSibling = null; this.nextSibling = null; this.attributeName = null; this.attributeNamespace = null; this.oldValue = null; } function registerTransientObservers(ancestor, node) { for (;ancestor; ancestor = ancestor.parentNode) { var registrations = registrationsTable.get(ancestor); if (!registrations) continue; for (var i = 0; i < registrations.length; i++) { var registration = registrations[i]; if (registration.options.subtree) registration.addTransientObserver(node); } } } function removeTransientObserversFor(observer) { for (var i = 0; i < observer.nodes_.length; i++) { var node = observer.nodes_[i]; var registrations = registrationsTable.get(node); if (!registrations) return; for (var j = 0; j < registrations.length; j++) { var registration = registrations[j]; if (registration.observer === observer) registration.removeTransientObservers(); } } } function enqueueMutation(target, type, data) { var interestedObservers = Object.create(null); var associatedStrings = Object.create(null); for (var node = target; node; node = node.parentNode) { var registrations = registrationsTable.get(node); if (!registrations) continue; for (var j = 0; j < registrations.length; j++) { var registration = registrations[j]; var options = registration.options; if (node !== target && !options.subtree) continue; if (type === "attributes" && !options.attributes) continue; if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) { continue; } if (type === "characterData" && !options.characterData) continue; if (type === "childList" && !options.childList) continue; var observer = registration.observer; interestedObservers[observer.uid_] = observer; if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) { associatedStrings[observer.uid_] = data.oldValue; } } } for (var uid in interestedObservers) { var observer = interestedObservers[uid]; var record = new MutationRecord(type, target); if ("name" in data && "namespace" in data) { record.attributeName = data.name; record.attributeNamespace = data.namespace; } if (data.addedNodes) record.addedNodes = data.addedNodes; if (data.removedNodes) record.removedNodes = data.removedNodes; if (data.previousSibling) record.previousSibling = data.previousSibling; if (data.nextSibling) record.nextSibling = data.nextSibling; if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid]; scheduleCallback(observer); observer.records_.push(record); } } var slice = Array.prototype.slice; function MutationObserverOptions(options) { this.childList = !!options.childList; this.subtree = !!options.subtree; if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) { this.attributes = true; } else { this.attributes = !!options.attributes; } if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData; if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) { throw new TypeError(); } this.characterData = !!options.characterData; this.attributeOldValue = !!options.attributeOldValue; this.characterDataOldValue = !!options.characterDataOldValue; if ("attributeFilter" in options) { if (options.attributeFilter == null || typeof options.attributeFilter !== "object") { throw new TypeError(); } this.attributeFilter = slice.call(options.attributeFilter); } else { this.attributeFilter = null; } } var uidCounter = 0; function MutationObserver(callback) { this.callback_ = callback; this.nodes_ = []; this.records_ = []; this.uid_ = ++uidCounter; this.scheduled_ = false; } MutationObserver.prototype = { constructor: MutationObserver, observe: function(target, options) { target = wrapIfNeeded(target); var newOptions = new MutationObserverOptions(options); var registration; var registrations = registrationsTable.get(target); if (!registrations) registrationsTable.set(target, registrations = []); for (var i = 0; i < registrations.length; i++) { if (registrations[i].observer === this) { registration = registrations[i]; registration.removeTransientObservers(); registration.options = newOptions; } } if (!registration) { registration = new Registration(this, target, newOptions); registrations.push(registration); this.nodes_.push(target); } }, disconnect: function() { this.nodes_.forEach(function(node) { var registrations = registrationsTable.get(node); for (var i = 0; i < registrations.length; i++) { var registration = registrations[i]; if (registration.observer === this) { registrations.splice(i, 1); break; } } }, this); this.records_ = []; }, takeRecords: function() { var copyOfRecords = this.records_; this.records_ = []; return copyOfRecords; } }; function Registration(observer, target, options) { this.observer = observer; this.target = target; this.options = options; this.transientObservedNodes = []; } Registration.prototype = { addTransientObserver: function(node) { if (node === this.target) return; scheduleCallback(this.observer); this.transientObservedNodes.push(node); var registrations = registrationsTable.get(node); if (!registrations) registrationsTable.set(node, registrations = []); registrations.push(this); }, removeTransientObservers: function() { var transientObservedNodes = this.transientObservedNodes; this.transientObservedNodes = []; for (var i = 0; i < transientObservedNodes.length; i++) { var node = transientObservedNodes[i]; var registrations = registrationsTable.get(node); for (var j = 0; j < registrations.length; j++) { if (registrations[j] === this) { registrations.splice(j, 1); break; } } } } }; scope.enqueueMutation = enqueueMutation; scope.registerTransientObservers = registerTransientObservers; scope.wrappers.MutationObserver = MutationObserver; scope.wrappers.MutationRecord = MutationRecord; })(window.ShadowDOMPolyfill); (function(scope) { "use strict"; function TreeScope(root, parent) { this.root = root; this.parent = parent; } TreeScope.prototype = { get renderer() { if (this.root instanceof scope.wrappers.ShadowRoot) { return scope.getRendererForHost(this.root.host); } return null; }, contains: function(treeScope) { for (;treeScope; treeScope = treeScope.parent) { if (treeScope === this) return true; } return false; } }; function setTreeScope(node, treeScope) { if (node.treeScope_ !== treeScope) { node.treeScope_ = treeScope; for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) { sr.treeScope_.parent = treeScope; } for (var child = node.firstChild; child; child = child.nextSibling) { setTreeScope(child, treeScope); } } } function getTreeScope(node) { if (node instanceof scope.wrappers.Window) { debugger; } if (node.treeScope_) return node.treeScope_; var parent = node.parentNode; var treeScope; if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null); return node.treeScope_ = treeScope; } scope.TreeScope = TreeScope; scope.getTreeScope = getTreeScope; scope.setTreeScope = setTreeScope; })(window.ShadowDOMPolyfill); (function(scope) { "use strict"; var forwardMethodsToWrapper = scope.forwardMethodsToWrapper; var getTreeScope = scope.getTreeScope; var mixin = scope.mixin; var registerWrapper = scope.registerWrapper; var setWrapper = scope.setWrapper; var unsafeUnwrap = scope.unsafeUnwrap; var unwrap = scope.unwrap; var wrap = scope.wrap; var wrappers = scope.wrappers; var wrappedFuns = new WeakMap(); var listenersTable = new WeakMap(); var handledEventsTable = new WeakMap(); var currentlyDispatchingEvents = new WeakMap(); var targetTable = new WeakMap(); var currentTargetTable = new WeakMap(); var relatedTargetTable = new WeakMap(); var eventPhaseTable = new WeakMap(); var stopPropagationTable = new WeakMap(); var stopImmediatePropagationTable = new WeakMap(); var eventHandlersTable = new WeakMap(); var eventPathTable = new WeakMap(); function isShadowRoot(node) { return node instanceof wrappers.ShadowRoot; } function rootOfNode(node) { return getTreeScope(node).root; } function getEventPath(node, event) { var path = []; var current = node; path.push(current); while (current) { var destinationInsertionPoints = getDestinationInsertionPoints(current); if (destinationInsertionPoints && destinationInsertionPoints.length > 0) { for (var i = 0; i < destinationInsertionPoints.length; i++) { var insertionPoint = destinationInsertionPoints[i]; if (isShadowInsertionPoint(insertionPoint)) { var shadowRoot = rootOfNode(insertionPoint); var olderShadowRoot = shadowRoot.olderShadowRoot; if (olderShadowRoot) path.push(olderShadowRoot); } path.push(insertionPoint); } current = destinationInsertionPoints[destinationInsertionPoints.length - 1]; } else { if (isShadowRoot(current)) { if (inSameTree(node, current) && eventMustBeStopped(event)) { break; } current = current.host; path.push(current); } else { current = current.parentNode; if (current) path.push(current); } } } return path; } function eventMustBeStopped(event) { if (!event) return false; switch (event.type) { case "abort": case "error": case "select": case "change": case "load": case "reset": case "resize": case "scroll": case "selectstart": return true; } return false; } function isShadowInsertionPoint(node) { return node instanceof HTMLShadowElement; } function getDestinationInsertionPoints(node) { return scope.getDestinationInsertionPoints(node); } function eventRetargetting(path, currentTarget) { if (path.length === 0) return currentTarget; if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document; var currentTargetTree = getTreeScope(currentTarget); var originalTarget = path[0]; var originalTargetTree = getTreeScope(originalTarget); var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree); for (var i = 0; i < path.length; i++) { var node = path[i]; if (getTreeScope(node) === relativeTargetTree) return node; } return path[path.length - 1]; } function getTreeScopeAncestors(treeScope) { var ancestors = []; for (;treeScope; treeScope = treeScope.parent) { ancestors.push(treeScope); } return ancestors; } function lowestCommonInclusiveAncestor(tsA, tsB) { var ancestorsA = getTreeScopeAncestors(tsA); var ancestorsB = getTreeScopeAncestors(tsB); var result = null; while (ancestorsA.length > 0 && ancestorsB.length > 0) { var a = ancestorsA.pop(); var b = ancestorsB.pop(); if (a === b) result = a; else break; } return result; } function getTreeScopeRoot(ts) { if (!ts.parent) return ts; return getTreeScopeRoot(ts.parent); } function relatedTargetResolution(event, currentTarget, relatedTarget) { if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document; var currentTargetTree = getTreeScope(currentTarget); var relatedTargetTree = getTreeScope(relatedTarget); var relatedTargetEventPath = getEventPath(relatedTarget, event); var lowestCommonAncestorTree; var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree); if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root; for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) { var adjustedRelatedTarget; for (var i = 0; i < relatedTargetEventPath.length; i++) { var node = relatedTargetEventPath[i]; if (getTreeScope(node) === commonAncestorTree) return node; } } return null; } function inSameTree(a, b) { return getTreeScope(a) === getTreeScope(b); } var NONE = 0; var CAPTURING_PHASE = 1; var AT_TARGET = 2; var BUBBLING_PHASE = 3; var pendingError; function dispatchOriginalEvent(originalEvent) { if (handledEventsTable.get(originalEvent)) return; handledEventsTable.set(originalEvent, true); dispatchEvent(wrap(originalEvent), wrap(originalEvent.target)); if (pendingError) { var err = pendingError; pendingError = null; throw err; } } function isLoadLikeEvent(event) { switch (event.type) { case "load": case "beforeunload": case "unload": return true; } return false; } function dispatchEvent(event, originalWrapperTarget) { if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError"); currentlyDispatchingEvents.set(event, true); scope.renderAllPending(); var eventPath; var overrideTarget; var win; if (isLoadLikeEvent(event) && !event.bubbles) { var doc = originalWrapperTarget; if (doc instanceof wrappers.Document && (win = doc.defaultView)) { overrideTarget = doc; eventPath = []; } } if (!eventPath) { if (originalWrapperTarget instanceof wrappers.Window) { win = originalWrapperTarget; eventPath = []; } else { eventPath = getEventPath(originalWrapperTarget, event); if (!isLoadLikeEvent(event)) { var doc = eventPath[eventPath.length - 1]; if (doc instanceof wrappers.Document) win = doc.defaultView; } } } eventPathTable.set(event, eventPath); if (dispatchCapturing(event, eventPath, win, overrideTarget)) { if (dispatchAtTarget(event, eventPath, win, overrideTarget)) { dispatchBubbling(event, eventPath, win, overrideTarget); } } eventPhaseTable.set(event, NONE); currentTargetTable.delete(event, null); currentlyDispatchingEvents.delete(event); return event.defaultPrevented; } function dispatchCapturing(event, eventPath, win, overrideTarget) { var phase = CAPTURING_PHASE; if (win) { if (!invoke(win, event, phase, eventPath, overrideTarget)) return false; } for (var i = eventPath.length - 1; i > 0; i--) { if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false; } return true; } function dispatchAtTarget(event, eventPath, win, overrideTarget) { var phase = AT_TARGET; var currentTarget = eventPath[0] || win; return invoke(currentTarget, event, phase, eventPath, overrideTarget); } function dispatchBubbling(event, eventPath, win, overrideTarget) { var phase = BUBBLING_PHASE; for (var i = 1; i < eventPath.length; i++) { if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return; } if (win && eventPath.length > 0) { invoke(win, event, phase, eventPath, overrideTarget); } } function invoke(currentTarget, event, phase, eventPath, overrideTarget) { var listeners = listenersTable.get(currentTarget); if (!listeners) return true; var target = overrideTarget || eventRetargetting(eventPath, currentTarget); if (target === currentTarget) { if (phase === CAPTURING_PHASE) return true; if (phase === BUBBLING_PHASE) phase = AT_TARGET; } else if (phase === BUBBLING_PHASE && !event.bubbles) { return true; } if ("relatedTarget" in event) { var originalEvent = unwrap(event); var unwrappedRelatedTarget = originalEvent.relatedTarget; if (unwrappedRelatedTarget) { if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) { var relatedTarget = wrap(unwrappedRelatedTarget); var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget); if (adjusted === target) return true; } else { adjusted = null; } relatedTargetTable.set(event, adjusted); } } eventPhaseTable.set(event, phase); var type = event.type; var anyRemoved = false; targetTable.set(event, target); currentTargetTable.set(event, currentTarget); listeners.depth++; for (var i = 0, len = listeners.length; i < len; i++) { var listener = listeners[i]; if (listener.removed) { anyRemoved = true; continue; } if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) { continue; } try { if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event); if (stopImmediatePropagationTable.get(event)) return false; } catch (ex) { if (!pendingError) pendingError = ex; } } listeners.depth--; if (anyRemoved && listeners.depth === 0) { var copy = listeners.slice(); listeners.length = 0; for (var i = 0; i < copy.length; i++) { if (!copy[i].removed) listeners.push(copy[i]); } } return !stopPropagationTable.get(event); } function Listener(type, handler, capture) { this.type = type; this.handler = handler; this.capture = Boolean(capture); } Listener.prototype = { equals: function(that) { return this.handler === that.handler && this.type === that.type && this.capture === that.capture; }, get removed() { return this.handler === null; }, remove: function() { this.handler = null; } }; var OriginalEvent = window.Event; OriginalEvent.prototype.polymerBlackList_ = { returnValue: true, keyLocation: true }; function Event(type, options) { if (type instanceof OriginalEvent) { var impl = type; if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) { return new BeforeUnloadEvent(impl); } setWrapper(impl, this); } else { return wrap(constructEvent(OriginalEvent, "Event", type, options)); } } Event.prototype = { get target() { return targetTable.get(this); }, get currentTarget() { return currentTargetTable.get(this); }, get eventPhase() { return eventPhaseTable.get(this); }, get path() { var eventPath = eventPathTable.get(this); if (!eventPath) return []; return eventPath.slice(); }, stopPropagation: function() { stopPropagationTable.set(this, true); }, stopImmediatePropagation: function() { stopPropagationTable.set(this, true); stopImmediatePropagationTable.set(this, true); } }; registerWrapper(OriginalEvent, Event, document.createEvent("Event")); function unwrapOptions(options) { if (!options || !options.relatedTarget) return options; return Object.create(options, { relatedTarget: { value: unwrap(options.relatedTarget) } }); } function registerGenericEvent(name, SuperEvent, prototype) { var OriginalEvent = window[name]; var GenericEvent = function(type, options) { if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options)); }; GenericEvent.prototype = Object.create(SuperEvent.prototype); if (prototype) mixin(GenericEvent.prototype, prototype); if (OriginalEvent) { try { registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp")); } catch (ex) { registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name)); } } return GenericEvent; } var UIEvent = registerGenericEvent("UIEvent", Event); var CustomEvent = registerGenericEvent("CustomEvent", Event); var relatedTargetProto = { get relatedTarget() { var relatedTarget = relatedTargetTable.get(this); if (relatedTarget !== undefined) return relatedTarget; return wrap(unwrap(this).relatedTarget); } }; function getInitFunction(name, relatedTargetIndex) { return function() { arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]); var impl = unwrap(this); impl[name].apply(impl, arguments); }; } var mouseEventProto = mixin({ initMouseEvent: getInitFunction("initMouseEvent", 14) }, relatedTargetProto); var focusEventProto = mixin({ initFocusEvent: getInitFunction("initFocusEvent", 5) }, relatedTargetProto); var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto); var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto); var defaultInitDicts = Object.create(null); var supportsEventConstructors = function() { try { new window.FocusEvent("focus"); } catch (ex) { return false; } return true; }(); function constructEvent(OriginalEvent, name, type, options) { if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options)); var event = unwrap(document.createEvent(name)); var defaultDict = defaultInitDicts[name]; var args = [ type ]; Object.keys(defaultDict).forEach(function(key) { var v = options != null && key in options ? options[key] : defaultDict[key]; if (key === "relatedTarget") v = unwrap(v); args.push(v); }); event["init" + name].apply(event, args); return event; } if (!supportsEventConstructors) { var configureEventConstructor = function(name, initDict, superName) { if (superName) { var superDict = defaultInitDicts[superName]; initDict = mixin(mixin({}, superDict), initDict); } defaultInitDicts[name] = initDict; }; configureEventConstructor("Event", { bubbles: false, cancelable: false }); configureEventConstructor("CustomEvent", { detail: null }, "Event"); configureEventConstructor("UIEvent", { view: null, detail: 0 }, "Event"); configureEventConstructor("MouseEvent", { screenX: 0, screenY: 0, clientX: 0, clientY: 0, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, button: 0, relatedTarget: null }, "UIEvent"); configureEventConstructor("FocusEvent", { relatedTarget: null }, "UIEvent"); } var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent; function BeforeUnloadEvent(impl) { Event.call(this, impl); } BeforeUnloadEvent.prototype = Object.create(Event.prototype); mixin(BeforeUnloadEvent.prototype, { get returnValue() { return unsafeUnwrap(this).returnValue; }, set returnValue(v) { unsafeUnwrap(this).returnValue = v; } }); if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent); function isValidListener(fun) { if (typeof fun === "function") return true; return fun && fun.handleEvent; } function isMutationEvent(type) { switch (type) { case "DOMAttrModified": case "DOMAttributeNameChanged": case "DOMCharacterDataModified": case "DOMElementNameChanged": case "DOMNodeInserted": case "DOMNodeInsertedIntoDocument": case "DOMNodeRemoved": case "DOMNodeRemovedFromDocument": case "DOMSubtreeModified": return true; } return false; } var OriginalEventTarget = window.EventTarget; function EventTarget(impl) { setWrapper(impl, this); } var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ]; [ Node, Window ].forEach(function(constructor) { var p = constructor.prototype; methodNames.forEach(function(name) { Object.defineProperty(p, name + "_", { value: p[name] }); }); }); function getTargetToListenAt(wrapper) { if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host; return unwrap(wrapper); } EventTarget.prototype = { addEventListener: function(type, fun, capture) { if (!isValidListener(fun) || isMutationEvent(type)) return; var listener = new Listener(type, fun, capture); var listeners = listenersTable.get(this); if (!listeners) { listeners = []; listeners.depth = 0; listenersTable.set(this, listeners); } else { for (var i = 0; i < listeners.length; i++) { if (listener.equals(listeners[i])) return; } } listeners.push(listener); var target = getTargetToListenAt(this); target.addEventListener_(type, dispatchOriginalEvent, true); }, removeEventListener: function(type, fun, capture) { capture = Boolean(capture); var listeners = listenersTable.get(this); if (!listeners) return; var count = 0, found = false; for (var i = 0; i < listeners.length; i++) { if (listeners[i].type === type && listeners[i].capture === capture) { count++; if (listeners[i].handler === fun) { found = true; listeners[i].remove(); } } } if (found && count === 1) { var target = getTargetToListenAt(this); target.removeEventListener_(type, dispatchOriginalEvent, true); } }, dispatchEvent: function(event) { var nativeEvent = unwrap(event); var eventType = nativeEvent.type; handledEventsTable.set(nativeEvent, false); scope.renderAllPending(); var tempListener; if (!hasListenerInAncestors(this, eventType)) { tempListener = function() {}; this.addEventListener(eventType, tempListener, true); } try { return unwrap(this).dispatchEvent_(nativeEvent); } finally { if (tempListener) this.removeEventListener(eventType, tempListener, true); } } }; function hasListener(node, type) { var listeners = listenersTable.get(node); if (listeners) { for (var i = 0; i < listeners.length; i++) { if (!listeners[i].removed && listeners[i].type === type) return true; } } return false; } function hasListenerInAncestors(target, type) { for (var node = unwrap(target); node; node = node.parentNode) { if