diff --git a/cmd/heapview/client/main.ts b/cmd/heapview/client/main.ts index 787c569e74..045e06925a 100644 --- a/cmd/heapview/client/main.ts +++ b/cmd/heapview/client/main.ts @@ -6,17 +6,17 @@ * A hamburger menu element. */ class HamburgerElement extends HTMLElement { - connectedCallback() { + attachedCallback() { this.innerHTML = '☰'; // Unicode character for hamburger menu. } } -window.customElements.define('heap-hamburger', HamburgerElement); +document.registerElement('heap-hamburger', HamburgerElement); /** * A heading for the page with a hamburger menu and a title. */ export class HeadingElement extends HTMLElement { - connectedCallback() { + attachedCallback() { this.style.display = 'block'; this.style.backgroundColor = '#2196F3'; this.style.webkitUserSelect = 'none'; @@ -28,8 +28,7 @@ export class HeadingElement extends HTMLElement { `; } } -window.customElements.define('heap-heading', HeadingElement); - +document.registerElement('heap-heading', HeadingElement); /** * Reset body's margin and padding, and set font. @@ -46,5 +45,5 @@ function clearStyle() { export function main() { document.title = 'Go Heap Viewer'; clearStyle(); - document.body.appendChild(new HeadingElement()); + document.body.appendChild(document.createElement("heap-heading")); } diff --git a/third_party/webcomponents/customelements.js b/third_party/webcomponents/customelements.js index aec587fe7d..931f6c22e1 100644 --- a/third_party/webcomponents/customelements.js +++ b/third_party/webcomponents/customelements.js @@ -1,597 +1,1029 @@ /** * @license - * Copyright (c) 2016 The Polymer Project Authors. All rights reserved. + * 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 */ - -/** - * 2.3 - * http://w3c.github.io/webcomponents/spec/custom/#dfn-element-definition - * @typedef {{ - * name: string, - * localName: string, - * constructor: Function, - * connectedCallback: Function, - * disconnectedCallback: Function, - * attributeChangedCallback: Function, - * observedAttributes: Array, - * }} - */ -var CustomElementDefinition; - -(function() { - 'use strict'; - - var doc = document; - var win = window; - - // name validation - // https://html.spec.whatwg.org/multipage/scripting.html#valid-custom-element-name - - /** - * @const - * @type {Array} - */ - var reservedTagList = [ - 'annotation-xml', - 'color-profile', - 'font-face', - 'font-face-src', - 'font-face-uri', - 'font-face-format', - 'font-face-name', - 'missing-glyph', - ]; - - /** @const */ - var customNameValidation = /^[a-z][.0-9_a-z]*-[\-.0-9_a-z]*$/; - function isValidCustomElementName(name) { - return customNameValidation.test(name) && reservedTagList.indexOf(name) === -1; - } - - function createTreeWalker(root) { - // IE 11 requires the third and fourth arguments be present. If the third - // arg is null, it applies the default behaviour. However IE also requires - // the fourth argument be present even though the other browsers ignore it. - return doc.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, null, false); - } - - function isElement(node) { - return node.nodeType === Node.ELEMENT_NODE - } - - /** - * A registry of custom element definitions. - * - * See https://html.spec.whatwg.org/multipage/scripting.html#customelementsregistry - * - * @constructor - * @property {boolean} polyfilled Whether this registry is polyfilled - * @property {boolean} enableFlush Set to true to enable the flush() method - * to work. This should only be done for tests, as it causes a memory leak. - */ - function CustomElementsRegistry() { - /** @private {Map} **/ - this._definitions = new Map(); - - /** @private {Map} **/ - this._constructors = new Map(); - - this._whenDefinedMap = new Map(); - - /** @private {Set} **/ - this._observers = new Set(); - - /** @private {MutationObserver} **/ - this._attributeObserver = - new MutationObserver(this._handleAttributeChange.bind(this)); - - /** @private {HTMLElement} **/ - this._newInstance = null; - - this.polyfilled = true; - this.enableFlush = false; - - this._observeRoot(document); - } - - CustomElementsRegistry.prototype = { - - // HTML spec part 4.13.4 - // https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregistry-define - define: function(name, constructor, options) { - name = name.toString().toLowerCase(); - - // 1: - if (typeof constructor !== 'function') { - throw new TypeError('constructor must be a Constructor'); - } - - // 2. If constructor is an interface object whose corresponding interface - // either is HTMLElement or has HTMLElement in its set of inherited - // interfaces, throw a TypeError and abort these steps. - // - // It doesn't appear possible to check this condition from script - - // 3: - if (!isValidCustomElementName(name)) { - throw new SyntaxError(`The element name '${name}' is not valid.`); - } - - // 4, 5: - // Note: we don't track being-defined names and constructors because - // define() isn't normally reentrant. The only time user code can run - // during define() is when getting callbacks off the prototype, which - // would be highly-unusual. We can make define() reentrant-safe if needed. - if (this._definitions.has(name)) { - throw new Error(`An element with name '${name}' is already defined`); - } - - // 6, 7: - if (this._constructors.has(constructor)) { - throw new Error(`Definition failed for '${name}': ` + - `The constructor is already used.`); - } - - // 8: - var localName = name; - - // 9, 10: We do not support extends currently. - - // 11, 12, 13: Our define() isn't rentrant-safe - - // 14.1: - var prototype = constructor.prototype; - - // 14.2: - if (typeof prototype !== 'object') { - throw new TypeError(`Definition failed for '${name}': ` + - `constructor.prototype must be an object`); - } - - function getCallback(calllbackName) { - var callback = prototype[calllbackName]; - if (callback !== undefined && typeof callback !== 'function') { - throw new Error(`${localName} '${calllbackName}' is not a Function`); - } - return callback; - } - - // 3, 4: - var connectedCallback = getCallback('connectedCallback'); - - // 5, 6: - var disconnectedCallback = getCallback('disconnectedCallback'); - - // Divergence from spec: we always throw if attributeChangedCallback is - // not a function, and always get observedAttributes. - - // 7, 9.1: - var attributeChangedCallback = getCallback('attributeChangedCallback'); - - // 8, 9.2, 9.3: - var observedAttributes = constructor['observedAttributes'] || []; - - // 15: - // @type {CustomElementDefinition} - var definition = { - name: name, - localName: localName, - constructor: constructor, - connectedCallback: connectedCallback, - disconnectedCallback: disconnectedCallback, - attributeChangedCallback: attributeChangedCallback, - observedAttributes: observedAttributes, - }; - - // 16: - this._definitions.set(localName, definition); - this._constructors.set(constructor, localName); - - // 17, 18, 19: - this._addNodes(doc.childNodes); - - // 20: - var deferred = this._whenDefinedMap.get(localName); - if (deferred) { - deferred.resolve(undefined); - this._whenDefinedMap.delete(localName); - } - }, - - /** - * Returns the constructor defined for `name`, or `null`. - * - * @param {string} name - * @return {Function|undefined} - */ - get: function(name) { - // https://html.spec.whatwg.org/multipage/scripting.html#custom-elements-api - var def = this._definitions.get(name); - return def ? def.constructor : undefined; - }, - - /** - * Returns a `Promise` that resolves when a custom element for `name` has - * been defined. - * - * @param {string} name - * @return {Promise} - */ - whenDefined: function(name) { - // https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregistry-whendefined - if (!customNameValidation.test(name)) { - return Promise.reject( - new SyntaxError(`The element name '${name}' is not valid.`)); - } - if (this._definitions.has(name)) { - return Promise.resolve(); - } - var deferred = { - promise: null, - }; - deferred.promise = new Promise(function(resolve, _) { - deferred.resolve = resolve; - }); - this._whenDefinedMap.set(name, deferred); - return deferred.promise; - }, - - /** - * Causes all pending mutation records to be processed, and thus all - * customization, upgrades and custom element reactions to be called. - * `enableFlush` must be true for this to work. Only use during tests! - */ - flush: function() { - if (this.enableFlush) { - console.warn("flush!!!"); - this._observers.forEach(function(observer) { - this._handleMutations(observer.takeRecords()); - }, this); - } - }, - - _setNewInstance: function(instance) { - this._newInstance = instance; - }, - - /** - * Observes a DOM root for mutations that trigger upgrades and reactions. - * @private - */ - _observeRoot: function(root) { - root.__observer = new MutationObserver(this._handleMutations.bind(this)); - root.__observer.observe(root, {childList: true, subtree: true}); - if (this.enableFlush) { - // this is memory leak, only use in tests - this._observers.add(root.__observer); - } - }, - - /** - * @private - */ - _unobserveRoot: function(root) { - if (root.__observer) { - root.__observer.disconnect(); - root.__observer = null; - if (this.enableFlush) { - this._observers.delete(root.__observer); - } - } - }, - - /** - * @private - */ - _handleMutations: function(mutations) { - for (var i = 0; i < mutations.length; i++) { - var mutation = mutations[i]; - if (mutation.type === 'childList') { - // Note: we can't get an ordering between additions and removals, and - // so might diverge from spec reaction ordering - this._addNodes(mutation.addedNodes); - this._removeNodes(mutation.removedNodes); - } - } - }, - - /** - * @param {NodeList} nodeList - * @private - */ - _addNodes: function(nodeList) { - for (var i = 0; i < nodeList.length; i++) { - var root = nodeList[i]; - - if (!isElement(root)) { - continue; - } - - // Since we're adding this node to an observed tree, we can unobserve - this._unobserveRoot(root); - - var walker = createTreeWalker(root); - do { - var node = /** @type {HTMLElement} */ (walker.currentNode); - var definition = this._definitions.get(node.localName); - if (definition) { - if (!node.__upgraded) { - this._upgradeElement(node, definition, true); - } - if (node.__upgraded && !node.__attached) { - node.__attached = true; - if (definition && definition.connectedCallback) { - definition.connectedCallback.call(node); - } - } - } - if (node.shadowRoot) { - // TODO(justinfagnani): do we need to check that the shadowRoot - // is observed? - this._addNodes(node.shadowRoot.childNodes); - } - if (node.tagName === 'LINK') { - var onLoad = (function() { - var link = node; - return function() { - link.removeEventListener('load', onLoad); - this._observeRoot(link.import); - this._addNodes(link.import.childNodes); - }.bind(this); - }).bind(this)(); - if (node.import) { - onLoad(); - } else { - node.addEventListener('load', onLoad); - } - } - } while (walker.nextNode()) - } - }, - - /** - * @param {NodeList} nodeList - * @private - */ - _removeNodes: function(nodeList) { - for (var i = 0; i < nodeList.length; i++) { - var root = nodeList[i]; - - if (!isElement(root)) { - continue; - } - - // Since we're detatching this element from an observed root, we need to - // reobserve it. - // TODO(justinfagnani): can we do this in a microtask so we don't thrash - // on creating and destroying MutationObservers on batch DOM mutations? - this._observeRoot(root); - - var walker = createTreeWalker(root); - do { - var node = walker.currentNode; - if (node.__upgraded && node.__attached) { - node.__attached = false; - var definition = this._definitions.get(node.localName); - if (definition && definition.disconnectedCallback) { - definition.disconnectedCallback.call(node); - } - } - } while (walker.nextNode()) - } - }, - - /** - * Upgrades or customizes a custom element. - * - * @param {HTMLElement} element - * @param {CustomElementDefinition} definition - * @param {boolean} callConstructor - * @private - */ - _upgradeElement: function(element, definition, callConstructor) { - var prototype = definition.constructor.prototype; - element.__proto__ = prototype; - if (callConstructor) { - this._setNewInstance(element); - element.__upgraded = true; - new (definition.constructor)(); - console.assert(this._newInstance == null); - } - - var observedAttributes = definition.observedAttributes; - if (definition.attributeChangedCallback && observedAttributes.length > 0) { - this._attributeObserver.observe(element, { - attributes: true, - attributeOldValue: true, - attributeFilter: observedAttributes, +// @version 0.7.22 +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 }); - - // Trigger attributeChangedCallback for existing attributes. - // https://html.spec.whatwg.org/multipage/scripting.html#upgrades - for (var i = 0; i < observedAttributes.length; i++) { - var name = observedAttributes[i]; - if (element.hasAttribute(name)) { - var value = element.getAttribute(name); - element.attributeChangedCallback(name, null, value); - } - } - } - }, - - /** - * @private - */ - _handleAttributeChange: function(mutations) { - for (var i = 0; i < mutations.length; i++) { - var mutation = mutations[i]; - if (mutation.type === 'attributes') { - var name = mutation.attributeName; - var oldValue = mutation.oldValue; - var target = mutation.target; - var newValue = target.getAttribute(name); - var namespace = mutation.attributeNamespace; - target['attributeChangedCallback'](name, oldValue, newValue, namespace); - } - } - }, - } - - // Closure Compiler Exports - window['CustomElementsRegistry'] = CustomElementsRegistry; - CustomElementsRegistry.prototype['define'] = CustomElementsRegistry.prototype.define; - CustomElementsRegistry.prototype['get'] = CustomElementsRegistry.prototype.get; - CustomElementsRegistry.prototype['whenDefined'] = CustomElementsRegistry.prototype.whenDefined; - CustomElementsRegistry.prototype['flush'] = CustomElementsRegistry.prototype.flush; - CustomElementsRegistry.prototype['polyfilled'] = CustomElementsRegistry.prototype.polyfilled; - CustomElementsRegistry.prototype['enableFlush'] = CustomElementsRegistry.prototype.enableFlush; - - // patch window.HTMLElement - - var origHTMLElement = win.HTMLElement; - win.HTMLElement = function HTMLElement() { - var customElements = win['customElements']; - if (customElements._newInstance) { - var i = customElements._newInstance; - customElements._newInstance = null; - return i; - } - if (this.constructor) { - var tagName = customElements._constructors.get(this.constructor); - return doc._createElement(tagName, false); - } - throw new Error('unknown constructor. Did you call customElements.define()?'); - } - win.HTMLElement.prototype = Object.create(origHTMLElement.prototype); - Object.defineProperty(win.HTMLElement.prototype, 'constructor', {value: win.HTMLElement}); - - // patch all built-in subclasses of HTMLElement to inherit from the new HTMLElement - // See https://html.spec.whatwg.org/multipage/indices.html#element-interfaces - - /** @const */ - var htmlElementSubclasses = [ - 'Button', - 'Canvas', - 'Data', - 'Head', - 'Mod', - 'TableCell', - 'TableCol', - 'Anchor', - 'Area', - 'Base', - 'Body', - 'BR', - 'DataList', - 'Details', - 'Dialog', - 'Div', - 'DList', - 'Embed', - 'FieldSet', - 'Form', - 'Heading', - 'HR', - 'Html', - 'IFrame', - 'Image', - 'Input', - 'Keygen', - 'Label', - 'Legend', - 'LI', - 'Link', - 'Map', - 'Media', - 'Menu', - 'MenuItem', - 'Meta', - 'Meter', - 'Object', - 'OList', - 'OptGroup', - 'Option', - 'Output', - 'Paragraph', - 'Param', - 'Picture', - 'Pre', - 'Progress', - 'Quote', - 'Script', - 'Select', - 'Slot', - 'Source', - 'Span', - 'Style', - 'TableCaption', - 'Table', - 'TableRow', - 'TableSection', - 'Template', - 'TextArea', - 'Time', - 'Title', - 'Track', - 'UList', - 'Unknown', - ]; - - for (var i = 0; i < htmlElementSubclasses.length; i++) { - var ctor = window['HTML' + htmlElementSubclasses[i] + 'Element']; - if (ctor) { - ctor.prototype.__proto__ = win.HTMLElement.prototype; - } - } - - // patch doc.createElement - - var rawCreateElement = doc.createElement; - doc._createElement = function(tagName, callConstructor) { - var customElements = win['customElements']; - var element = rawCreateElement.call(doc, tagName); - var definition = customElements._definitions.get(tagName.toLowerCase()); - if (definition) { - customElements._upgradeElement(element, definition, callConstructor); - } - customElements._observeRoot(element); - return element; - }; - doc.createElement = function(tagName) { - return doc._createElement(tagName, true); - } - - // patch doc.createElementNS - - var HTMLNS = 'http://www.w3.org/1999/xhtml'; - var _origCreateElementNS = doc.createElementNS; - doc.createElementNS = function(namespaceURI, qualifiedName) { - if (namespaceURI === 'http://www.w3.org/1999/xhtml') { - return doc.createElement(qualifiedName); - } else { - return _origCreateElementNS.call(document, namespaceURI, qualifiedName); - } - }; - - // patch Element.attachShadow - - var _origAttachShadow = Element.prototype['attachShadow']; - if (_origAttachShadow) { - Object.defineProperty(Element.prototype, 'attachShadow', { - value: function(options) { - var root = _origAttachShadow.call(this, options); - var customElements = win['customElements']; - customElements._observeRoot(root); - return root; + 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; + })(); +} + +(function(global) { + if (global.JsMutationObserver) { + return; + } + var registrationsTable = new WeakMap(); + var setImmediate; + if (/Trident|Edge/.test(navigator.userAgent)) { + setImmediate = setTimeout; + } else if (window.setImmediate) { + setImmediate = window.setImmediate; + } else { + var setImmediateQueue = []; + var sentinel = String(Math.random()); + window.addEventListener("message", function(e) { + if (e.data === sentinel) { + var queue = setImmediateQueue; + setImmediateQueue = []; + queue.forEach(function(func) { + func(); + }); + } + }); + setImmediate = function(func) { + setImmediateQueue.push(func); + window.postMessage(sentinel, "*"); + }; + } + var isScheduled = false; + var scheduledObservers = []; + function scheduleCallback(observer) { + scheduledObservers.push(observer); + if (!isScheduled) { + isScheduled = true; + setImmediate(dispatchCallbacks); + } + } + function wrapIfNeeded(node) { + return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(node) || node; + } + function dispatchCallbacks() { + isScheduled = false; + var observers = scheduledObservers; + scheduledObservers = []; + observers.sort(function(o1, o2) { + return o1.uid_ - o2.uid_; + }); + var anyNonEmpty = false; + observers.forEach(function(observer) { + var queue = observer.takeRecords(); + removeTransientObserversFor(observer); + if (queue.length) { + observer.callback_(queue, observer); + anyNonEmpty = true; + } + }); + if (anyNonEmpty) dispatchCallbacks(); + } + function removeTransientObserversFor(observer) { + observer.nodes_.forEach(function(node) { + var registrations = registrationsTable.get(node); + if (!registrations) return; + registrations.forEach(function(registration) { + if (registration.observer === observer) registration.removeTransientObservers(); + }); }); } + function forEachAncestorAndObserverEnqueueRecord(target, callback) { + for (var node = target; node; node = node.parentNode) { + var registrations = registrationsTable.get(node); + if (registrations) { + for (var j = 0; j < registrations.length; j++) { + var registration = registrations[j]; + var options = registration.options; + if (node !== target && !options.subtree) continue; + var record = callback(options); + if (record) registration.enqueue(record); + } + } + } + } + var uidCounter = 0; + function JsMutationObserver(callback) { + this.callback_ = callback; + this.nodes_ = []; + this.records_ = []; + this.uid_ = ++uidCounter; + } + JsMutationObserver.prototype = { + observe: function(target, options) { + target = wrapIfNeeded(target); + if (!options.childList && !options.attributes && !options.characterData || options.attributeOldValue && !options.attributes || options.attributeFilter && options.attributeFilter.length && !options.attributes || options.characterDataOldValue && !options.characterData) { + throw new SyntaxError(); + } + var registrations = registrationsTable.get(target); + if (!registrations) registrationsTable.set(target, registrations = []); + var registration; + for (var i = 0; i < registrations.length; i++) { + if (registrations[i].observer === this) { + registration = registrations[i]; + registration.removeListeners(); + registration.options = options; + break; + } + } + if (!registration) { + registration = new Registration(this, target, options); + registrations.push(registration); + this.nodes_.push(target); + } + registration.addListeners(); + }, + 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) { + registration.removeListeners(); + registrations.splice(i, 1); + break; + } + } + }, this); + this.records_ = []; + }, + takeRecords: function() { + var copyOfRecords = this.records_; + this.records_ = []; + return copyOfRecords; + } + }; + function MutationRecord(type, target) { + this.type = type; + this.target = target; + this.addedNodes = []; + this.removedNodes = []; + this.previousSibling = null; + this.nextSibling = null; + this.attributeName = null; + this.attributeNamespace = null; + this.oldValue = null; + } + function copyMutationRecord(original) { + var record = new MutationRecord(original.type, original.target); + record.addedNodes = original.addedNodes.slice(); + record.removedNodes = original.removedNodes.slice(); + record.previousSibling = original.previousSibling; + record.nextSibling = original.nextSibling; + record.attributeName = original.attributeName; + record.attributeNamespace = original.attributeNamespace; + record.oldValue = original.oldValue; + return record; + } + var currentRecord, recordWithOldValue; + function getRecord(type, target) { + return currentRecord = new MutationRecord(type, target); + } + function getRecordWithOldValue(oldValue) { + if (recordWithOldValue) return recordWithOldValue; + recordWithOldValue = copyMutationRecord(currentRecord); + recordWithOldValue.oldValue = oldValue; + return recordWithOldValue; + } + function clearRecords() { + currentRecord = recordWithOldValue = undefined; + } + function recordRepresentsCurrentMutation(record) { + return record === recordWithOldValue || record === currentRecord; + } + function selectRecord(lastRecord, newRecord) { + if (lastRecord === newRecord) return lastRecord; + if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) return recordWithOldValue; + return null; + } + function Registration(observer, target, options) { + this.observer = observer; + this.target = target; + this.options = options; + this.transientObservedNodes = []; + } + Registration.prototype = { + enqueue: function(record) { + var records = this.observer.records_; + var length = records.length; + if (records.length > 0) { + var lastRecord = records[length - 1]; + var recordToReplaceLast = selectRecord(lastRecord, record); + if (recordToReplaceLast) { + records[length - 1] = recordToReplaceLast; + return; + } + } else { + scheduleCallback(this.observer); + } + records[length] = record; + }, + addListeners: function() { + this.addListeners_(this.target); + }, + addListeners_: function(node) { + var options = this.options; + if (options.attributes) node.addEventListener("DOMAttrModified", this, true); + if (options.characterData) node.addEventListener("DOMCharacterDataModified", this, true); + if (options.childList) node.addEventListener("DOMNodeInserted", this, true); + if (options.childList || options.subtree) node.addEventListener("DOMNodeRemoved", this, true); + }, + removeListeners: function() { + this.removeListeners_(this.target); + }, + removeListeners_: function(node) { + var options = this.options; + if (options.attributes) node.removeEventListener("DOMAttrModified", this, true); + if (options.characterData) node.removeEventListener("DOMCharacterDataModified", this, true); + if (options.childList) node.removeEventListener("DOMNodeInserted", this, true); + if (options.childList || options.subtree) node.removeEventListener("DOMNodeRemoved", this, true); + }, + addTransientObserver: function(node) { + if (node === this.target) return; + this.addListeners_(node); + 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 = []; + transientObservedNodes.forEach(function(node) { + this.removeListeners_(node); + var registrations = registrationsTable.get(node); + for (var i = 0; i < registrations.length; i++) { + if (registrations[i] === this) { + registrations.splice(i, 1); + break; + } + } + }, this); + }, + handleEvent: function(e) { + e.stopImmediatePropagation(); + switch (e.type) { + case "DOMAttrModified": + var name = e.attrName; + var namespace = e.relatedNode.namespaceURI; + var target = e.target; + var record = new getRecord("attributes", target); + record.attributeName = name; + record.attributeNamespace = namespace; + var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevValue; + forEachAncestorAndObserverEnqueueRecord(target, function(options) { + if (!options.attributes) return; + if (options.attributeFilter && options.attributeFilter.length && options.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(namespace) === -1) { + return; + } + if (options.attributeOldValue) return getRecordWithOldValue(oldValue); + return record; + }); + break; - /** @type {CustomElementsRegistry} */ - window['customElements'] = new CustomElementsRegistry(); -})(); + case "DOMCharacterDataModified": + var target = e.target; + var record = getRecord("characterData", target); + var oldValue = e.prevValue; + forEachAncestorAndObserverEnqueueRecord(target, function(options) { + if (!options.characterData) return; + if (options.characterDataOldValue) return getRecordWithOldValue(oldValue); + return record; + }); + break; + + case "DOMNodeRemoved": + this.addTransientObserver(e.target); + + case "DOMNodeInserted": + var changedNode = e.target; + var addedNodes, removedNodes; + if (e.type === "DOMNodeInserted") { + addedNodes = [ changedNode ]; + removedNodes = []; + } else { + addedNodes = []; + removedNodes = [ changedNode ]; + } + var previousSibling = changedNode.previousSibling; + var nextSibling = changedNode.nextSibling; + var record = getRecord("childList", e.target.parentNode); + record.addedNodes = addedNodes; + record.removedNodes = removedNodes; + record.previousSibling = previousSibling; + record.nextSibling = nextSibling; + forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) { + if (!options.childList) return; + return record; + }); + } + clearRecords(); + } + }; + global.JsMutationObserver = JsMutationObserver; + if (!global.MutationObserver) { + global.MutationObserver = JsMutationObserver; + JsMutationObserver._isPolyfilled = true; + } +})(self); + +(function(scope) { + "use strict"; + if (!window.performance) { + var start = Date.now(); + window.performance = { + now: function() { + return Date.now() - start; + } + }; + } + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function() { + var nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame; + return nativeRaf ? function(callback) { + return nativeRaf(function() { + callback(performance.now()); + }); + } : function(callback) { + return window.setTimeout(callback, 1e3 / 60); + }; + }(); + } + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function() { + return window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) { + clearTimeout(id); + }; + }(); + } + var workingDefaultPrevented = function() { + var e = document.createEvent("Event"); + e.initEvent("foo", true, true); + e.preventDefault(); + return e.defaultPrevented; + }(); + if (!workingDefaultPrevented) { + var origPreventDefault = Event.prototype.preventDefault; + Event.prototype.preventDefault = function() { + if (!this.cancelable) { + return; + } + origPreventDefault.call(this); + Object.defineProperty(this, "defaultPrevented", { + get: function() { + return true; + }, + configurable: true + }); + }; + } + var isIE = /Trident/.test(navigator.userAgent); + if (!window.CustomEvent || isIE && typeof window.CustomEvent !== "function") { + window.CustomEvent = function(inType, params) { + params = params || {}; + var e = document.createEvent("CustomEvent"); + e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail); + return e; + }; + window.CustomEvent.prototype = window.Event.prototype; + } + if (!window.Event || isIE && typeof window.Event !== "function") { + var origEvent = window.Event; + window.Event = function(inType, params) { + params = params || {}; + var e = document.createEvent("Event"); + e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable)); + return e; + }; + window.Event.prototype = origEvent.prototype; + } +})(window.WebComponents); + +window.CustomElements = window.CustomElements || { + flags: {} +}; + +(function(scope) { + var flags = scope.flags; + var modules = []; + var addModule = function(module) { + modules.push(module); + }; + var initializeModules = function() { + modules.forEach(function(module) { + module(scope); + }); + }; + scope.addModule = addModule; + scope.initializeModules = initializeModules; + scope.hasNative = Boolean(document.registerElement); + scope.isIE = /Trident/.test(navigator.userAgent); + scope.useNative = !flags.register && scope.hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || window.HTMLImports.useNative); +})(window.CustomElements); + +window.CustomElements.addModule(function(scope) { + var IMPORT_LINK_TYPE = window.HTMLImports ? window.HTMLImports.IMPORT_LINK_TYPE : "none"; + function forSubtree(node, cb) { + findAllElements(node, function(e) { + if (cb(e)) { + return true; + } + forRoots(e, cb); + }); + forRoots(node, cb); + } + function findAllElements(node, find, data) { + var e = node.firstElementChild; + if (!e) { + e = node.firstChild; + while (e && e.nodeType !== Node.ELEMENT_NODE) { + e = e.nextSibling; + } + } + while (e) { + if (find(e, data) !== true) { + findAllElements(e, find, data); + } + e = e.nextElementSibling; + } + return null; + } + function forRoots(node, cb) { + var root = node.shadowRoot; + while (root) { + forSubtree(root, cb); + root = root.olderShadowRoot; + } + } + function forDocumentTree(doc, cb) { + _forDocumentTree(doc, cb, []); + } + function _forDocumentTree(doc, cb, processingDocuments) { + doc = window.wrap(doc); + if (processingDocuments.indexOf(doc) >= 0) { + return; + } + processingDocuments.push(doc); + var imports = doc.querySelectorAll("link[rel=" + IMPORT_LINK_TYPE + "]"); + for (var i = 0, l = imports.length, n; i < l && (n = imports[i]); i++) { + if (n.import) { + _forDocumentTree(n.import, cb, processingDocuments); + } + } + cb(doc); + } + scope.forDocumentTree = forDocumentTree; + scope.forSubtree = forSubtree; +}); + +window.CustomElements.addModule(function(scope) { + var flags = scope.flags; + var forSubtree = scope.forSubtree; + var forDocumentTree = scope.forDocumentTree; + function addedNode(node, isAttached) { + return added(node, isAttached) || addedSubtree(node, isAttached); + } + function added(node, isAttached) { + if (scope.upgrade(node, isAttached)) { + return true; + } + if (isAttached) { + attached(node); + } + } + function addedSubtree(node, isAttached) { + forSubtree(node, function(e) { + if (added(e, isAttached)) { + return true; + } + }); + } + var hasThrottledAttached = window.MutationObserver._isPolyfilled && flags["throttle-attached"]; + scope.hasPolyfillMutations = hasThrottledAttached; + scope.hasThrottledAttached = hasThrottledAttached; + var isPendingMutations = false; + var pendingMutations = []; + function deferMutation(fn) { + pendingMutations.push(fn); + if (!isPendingMutations) { + isPendingMutations = true; + setTimeout(takeMutations); + } + } + function takeMutations() { + isPendingMutations = false; + var $p = pendingMutations; + for (var i = 0, l = $p.length, p; i < l && (p = $p[i]); i++) { + p(); + } + pendingMutations = []; + } + function attached(element) { + if (hasThrottledAttached) { + deferMutation(function() { + _attached(element); + }); + } else { + _attached(element); + } + } + function _attached(element) { + if (element.__upgraded__ && !element.__attached) { + element.__attached = true; + if (element.attachedCallback) { + element.attachedCallback(); + } + } + } + function detachedNode(node) { + detached(node); + forSubtree(node, function(e) { + detached(e); + }); + } + function detached(element) { + if (hasThrottledAttached) { + deferMutation(function() { + _detached(element); + }); + } else { + _detached(element); + } + } + function _detached(element) { + if (element.__upgraded__ && element.__attached) { + element.__attached = false; + if (element.detachedCallback) { + element.detachedCallback(); + } + } + } + function inDocument(element) { + var p = element; + var doc = window.wrap(document); + while (p) { + if (p == doc) { + return true; + } + p = p.parentNode || p.nodeType === Node.DOCUMENT_FRAGMENT_NODE && p.host; + } + } + function watchShadow(node) { + if (node.shadowRoot && !node.shadowRoot.__watched) { + flags.dom && console.log("watching shadow-root for: ", node.localName); + var root = node.shadowRoot; + while (root) { + observe(root); + root = root.olderShadowRoot; + } + } + } + function handler(root, mutations) { + if (flags.dom) { + var mx = mutations[0]; + if (mx && mx.type === "childList" && mx.addedNodes) { + if (mx.addedNodes) { + var d = mx.addedNodes[0]; + while (d && d !== document && !d.host) { + d = d.parentNode; + } + var u = d && (d.URL || d._URL || d.host && d.host.localName) || ""; + u = u.split("/?").shift().split("/").pop(); + } + } + console.group("mutations (%d) [%s]", mutations.length, u || ""); + } + var isAttached = inDocument(root); + mutations.forEach(function(mx) { + if (mx.type === "childList") { + forEach(mx.addedNodes, function(n) { + if (!n.localName) { + return; + } + addedNode(n, isAttached); + }); + forEach(mx.removedNodes, function(n) { + if (!n.localName) { + return; + } + detachedNode(n); + }); + } + }); + flags.dom && console.groupEnd(); + } + function takeRecords(node) { + node = window.wrap(node); + if (!node) { + node = window.wrap(document); + } + while (node.parentNode) { + node = node.parentNode; + } + var observer = node.__observer; + if (observer) { + handler(node, observer.takeRecords()); + takeMutations(); + } + } + var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); + function observe(inRoot) { + if (inRoot.__observer) { + return; + } + var observer = new MutationObserver(handler.bind(this, inRoot)); + observer.observe(inRoot, { + childList: true, + subtree: true + }); + inRoot.__observer = observer; + } + function upgradeDocument(doc) { + doc = window.wrap(doc); + flags.dom && console.group("upgradeDocument: ", doc.baseURI.split("/").pop()); + var isMainDocument = doc === window.wrap(document); + addedNode(doc, isMainDocument); + observe(doc); + flags.dom && console.groupEnd(); + } + function upgradeDocumentTree(doc) { + forDocumentTree(doc, upgradeDocument); + } + var originalCreateShadowRoot = Element.prototype.createShadowRoot; + if (originalCreateShadowRoot) { + Element.prototype.createShadowRoot = function() { + var root = originalCreateShadowRoot.call(this); + window.CustomElements.watchShadow(this); + return root; + }; + } + scope.watchShadow = watchShadow; + scope.upgradeDocumentTree = upgradeDocumentTree; + scope.upgradeDocument = upgradeDocument; + scope.upgradeSubtree = addedSubtree; + scope.upgradeAll = addedNode; + scope.attached = attached; + scope.takeRecords = takeRecords; +}); + +window.CustomElements.addModule(function(scope) { + var flags = scope.flags; + function upgrade(node, isAttached) { + if (node.localName === "template") { + if (window.HTMLTemplateElement && HTMLTemplateElement.decorate) { + HTMLTemplateElement.decorate(node); + } + } + if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) { + var is = node.getAttribute("is"); + var definition = scope.getRegisteredDefinition(node.localName) || scope.getRegisteredDefinition(is); + if (definition) { + if (is && definition.tag == node.localName || !is && !definition.extends) { + return upgradeWithDefinition(node, definition, isAttached); + } + } + } + } + function upgradeWithDefinition(element, definition, isAttached) { + flags.upgrade && console.group("upgrade:", element.localName); + if (definition.is) { + element.setAttribute("is", definition.is); + } + implementPrototype(element, definition); + element.__upgraded__ = true; + created(element); + if (isAttached) { + scope.attached(element); + } + scope.upgradeSubtree(element, isAttached); + flags.upgrade && console.groupEnd(); + return element; + } + function implementPrototype(element, definition) { + if (Object.__proto__) { + element.__proto__ = definition.prototype; + } else { + customMixin(element, definition.prototype, definition.native); + element.__proto__ = definition.prototype; + } + } + function customMixin(inTarget, inSrc, inNative) { + var used = {}; + var p = inSrc; + while (p !== inNative && p !== HTMLElement.prototype) { + var keys = Object.getOwnPropertyNames(p); + for (var i = 0, k; k = keys[i]; i++) { + if (!used[k]) { + Object.defineProperty(inTarget, k, Object.getOwnPropertyDescriptor(p, k)); + used[k] = 1; + } + } + p = Object.getPrototypeOf(p); + } + } + function created(element) { + if (element.createdCallback) { + element.createdCallback(); + } + } + scope.upgrade = upgrade; + scope.upgradeWithDefinition = upgradeWithDefinition; + scope.implementPrototype = implementPrototype; +}); + +window.CustomElements.addModule(function(scope) { + var isIE = scope.isIE; + var upgradeDocumentTree = scope.upgradeDocumentTree; + var upgradeAll = scope.upgradeAll; + var upgradeWithDefinition = scope.upgradeWithDefinition; + var implementPrototype = scope.implementPrototype; + var useNative = scope.useNative; + function register(name, options) { + var definition = options || {}; + if (!name) { + throw new Error("document.registerElement: first argument `name` must not be empty"); + } + if (name.indexOf("-") < 0) { + throw new Error("document.registerElement: first argument ('name') must contain a dash ('-'). Argument provided was '" + String(name) + "'."); + } + if (isReservedTag(name)) { + throw new Error("Failed to execute 'registerElement' on 'Document': Registration failed for type '" + String(name) + "'. The type name is invalid."); + } + if (getRegisteredDefinition(name)) { + throw new Error("DuplicateDefinitionError: a type with name '" + String(name) + "' is already registered"); + } + if (!definition.prototype) { + definition.prototype = Object.create(HTMLElement.prototype); + } + definition.__name = name.toLowerCase(); + if (definition.extends) { + definition.extends = definition.extends.toLowerCase(); + } + definition.lifecycle = definition.lifecycle || {}; + definition.ancestry = ancestry(definition.extends); + resolveTagName(definition); + resolvePrototypeChain(definition); + overrideAttributeApi(definition.prototype); + registerDefinition(definition.__name, definition); + definition.ctor = generateConstructor(definition); + definition.ctor.prototype = definition.prototype; + definition.prototype.constructor = definition.ctor; + if (scope.ready) { + upgradeDocumentTree(document); + } + return definition.ctor; + } + function overrideAttributeApi(prototype) { + if (prototype.setAttribute._polyfilled) { + return; + } + var setAttribute = prototype.setAttribute; + prototype.setAttribute = function(name, value) { + changeAttribute.call(this, name, value, setAttribute); + }; + var removeAttribute = prototype.removeAttribute; + prototype.removeAttribute = function(name) { + changeAttribute.call(this, name, null, removeAttribute); + }; + prototype.setAttribute._polyfilled = true; + } + function changeAttribute(name, value, operation) { + name = name.toLowerCase(); + var oldValue = this.getAttribute(name); + operation.apply(this, arguments); + var newValue = this.getAttribute(name); + if (this.attributeChangedCallback && newValue !== oldValue) { + this.attributeChangedCallback(name, oldValue, newValue); + } + } + function isReservedTag(name) { + for (var i = 0; i < reservedTagList.length; i++) { + if (name === reservedTagList[i]) { + return true; + } + } + } + var reservedTagList = [ "annotation-xml", "color-profile", "font-face", "font-face-src", "font-face-uri", "font-face-format", "font-face-name", "missing-glyph" ]; + function ancestry(extnds) { + var extendee = getRegisteredDefinition(extnds); + if (extendee) { + return ancestry(extendee.extends).concat([ extendee ]); + } + return []; + } + function resolveTagName(definition) { + var baseTag = definition.extends; + for (var i = 0, a; a = definition.ancestry[i]; i++) { + baseTag = a.is && a.tag; + } + definition.tag = baseTag || definition.__name; + if (baseTag) { + definition.is = definition.__name; + } + } + function resolvePrototypeChain(definition) { + if (!Object.__proto__) { + var nativePrototype = HTMLElement.prototype; + if (definition.is) { + var inst = document.createElement(definition.tag); + nativePrototype = Object.getPrototypeOf(inst); + } + var proto = definition.prototype, ancestor; + var foundPrototype = false; + while (proto) { + if (proto == nativePrototype) { + foundPrototype = true; + } + ancestor = Object.getPrototypeOf(proto); + if (ancestor) { + proto.__proto__ = ancestor; + } + proto = ancestor; + } + if (!foundPrototype) { + console.warn(definition.tag + " prototype not found in prototype chain for " + definition.is); + } + definition.native = nativePrototype; + } + } + function instantiate(definition) { + return upgradeWithDefinition(domCreateElement(definition.tag), definition); + } + var registry = {}; + function getRegisteredDefinition(name) { + if (name) { + return registry[name.toLowerCase()]; + } + } + function registerDefinition(name, definition) { + registry[name] = definition; + } + function generateConstructor(definition) { + return function() { + return instantiate(definition); + }; + } + var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml"; + function createElementNS(namespace, tag, typeExtension) { + if (namespace === HTML_NAMESPACE) { + return createElement(tag, typeExtension); + } else { + return domCreateElementNS(namespace, tag); + } + } + function createElement(tag, typeExtension) { + if (tag) { + tag = tag.toLowerCase(); + } + if (typeExtension) { + typeExtension = typeExtension.toLowerCase(); + } + var definition = getRegisteredDefinition(typeExtension || tag); + if (definition) { + if (tag == definition.tag && typeExtension == definition.is) { + return new definition.ctor(); + } + if (!typeExtension && !definition.is) { + return new definition.ctor(); + } + } + var element; + if (typeExtension) { + element = createElement(tag); + element.setAttribute("is", typeExtension); + return element; + } + element = domCreateElement(tag); + if (tag.indexOf("-") >= 0) { + implementPrototype(element, HTMLElement); + } + return element; + } + var domCreateElement = document.createElement.bind(document); + var domCreateElementNS = document.createElementNS.bind(document); + var isInstance; + if (!Object.__proto__ && !useNative) { + isInstance = function(obj, ctor) { + if (obj instanceof ctor) { + return true; + } + var p = obj; + while (p) { + if (p === ctor.prototype) { + return true; + } + p = p.__proto__; + } + return false; + }; + } else { + isInstance = function(obj, base) { + return obj instanceof base; + }; + } + function wrapDomMethodToForceUpgrade(obj, methodName) { + var orig = obj[methodName]; + obj[methodName] = function() { + var n = orig.apply(this, arguments); + upgradeAll(n); + return n; + }; + } + wrapDomMethodToForceUpgrade(Node.prototype, "cloneNode"); + wrapDomMethodToForceUpgrade(document, "importNode"); + document.registerElement = register; + document.createElement = createElement; + document.createElementNS = createElementNS; + scope.registry = registry; + scope.instanceof = isInstance; + scope.reservedTagList = reservedTagList; + scope.getRegisteredDefinition = getRegisteredDefinition; + document.register = document.registerElement; +}); + +(function(scope) { + var useNative = scope.useNative; + var initializeModules = scope.initializeModules; + var isIE = scope.isIE; + if (useNative) { + var nop = function() {}; + scope.watchShadow = nop; + scope.upgrade = nop; + scope.upgradeAll = nop; + scope.upgradeDocumentTree = nop; + scope.upgradeSubtree = nop; + scope.takeRecords = nop; + scope.instanceof = function(obj, base) { + return obj instanceof base; + }; + } else { + initializeModules(); + } + var upgradeDocumentTree = scope.upgradeDocumentTree; + var upgradeDocument = scope.upgradeDocument; + if (!window.wrap) { + if (window.ShadowDOMPolyfill) { + window.wrap = window.ShadowDOMPolyfill.wrapIfNeeded; + window.unwrap = window.ShadowDOMPolyfill.unwrapIfNeeded; + } else { + window.wrap = window.unwrap = function(node) { + return node; + }; + } + } + if (window.HTMLImports) { + window.HTMLImports.__importsParsingHook = function(elt) { + if (elt.import) { + upgradeDocument(wrap(elt.import)); + } + }; + } + function bootstrap() { + upgradeDocumentTree(window.wrap(document)); + window.CustomElements.ready = true; + var requestAnimationFrame = window.requestAnimationFrame || function(f) { + setTimeout(f, 16); + }; + requestAnimationFrame(function() { + setTimeout(function() { + window.CustomElements.readyTime = Date.now(); + if (window.HTMLImports) { + window.CustomElements.elapsed = window.CustomElements.readyTime - window.HTMLImports.readyTime; + } + document.dispatchEvent(new CustomEvent("WebComponentsReady", { + bubbles: true + })); + }); + }); + } + if (document.readyState === "complete" || scope.flags.eager) { + bootstrap(); + } else if (document.readyState === "interactive" && !window.attachEvent && (!window.HTMLImports || window.HTMLImports.ready)) { + bootstrap(); + } else { + var loadEvent = window.HTMLImports && !window.HTMLImports.ready ? "HTMLImportsLoaded" : "DOMContentLoaded"; + window.addEventListener(loadEvent, bootstrap); + } +})(window.CustomElements); \ No newline at end of file