| Index: src/site/docs/tutorials/fetchdata/examples/its_all_about_you/out/web/packages/shadow_dom/shadow_dom.debug.js
|
| diff --git a/src/site/docs/tutorials/fetchdata/examples/its_all_about_you/out/web/packages/shadow_dom/shadow_dom.debug.js b/src/site/docs/tutorials/fetchdata/examples/its_all_about_you/out/web/packages/shadow_dom/shadow_dom.debug.js
|
| deleted file mode 100644
|
| index 447f29c3a9926d8f8527e63278ded6ed60aa7876..0000000000000000000000000000000000000000
|
| --- a/src/site/docs/tutorials/fetchdata/examples/its_all_about_you/out/web/packages/shadow_dom/shadow_dom.debug.js
|
| +++ /dev/null
|
| @@ -1,5716 +0,0 @@
|
| -if (!HTMLElement.prototype.createShadowRoot
|
| - || window.__forceShadowDomPolyfill) {
|
| -
|
| -/*
|
| - * Copyright 2013 The Polymer Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style
|
| - * license that can be found in the LICENSE file.
|
| - */
|
| -(function() {
|
| - // TODO(jmesserly): fix dart:html to use unprefixed name
|
| - if (Element.prototype.webkitCreateShadowRoot) {
|
| - Element.prototype.webkitCreateShadowRoot = function() {
|
| - return window.ShadowDOMPolyfill.wrapIfNeeded(this).createShadowRoot();
|
| - };
|
| - }
|
| -})();
|
| -
|
| -// Copyright 2012 Google Inc.
|
| -//
|
| -// Licensed under the Apache License, Version 2.0 (the "License");
|
| -// you may not use this file except in compliance with the License.
|
| -// You may obtain a copy of the License at
|
| -//
|
| -// http://www.apache.org/licenses/LICENSE-2.0
|
| -//
|
| -// Unless required by applicable law or agreed to in writing, software
|
| -// distributed under the License is distributed on an "AS IS" BASIS,
|
| -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| -// See the License for the specific language governing permissions and
|
| -// limitations under the License.
|
| -
|
| -(function(global) {
|
| - 'use strict';
|
| -
|
| - function detectObjectObserve() {
|
| - if (typeof Object.observe !== 'function' ||
|
| - typeof Array.observe !== 'function') {
|
| - return false;
|
| - }
|
| -
|
| - var gotSplice = false;
|
| - function callback(records) {
|
| - if (records[0].type === 'splice' && records[1].type === 'splice')
|
| - gotSplice = true;
|
| - }
|
| -
|
| - var test = [0];
|
| - Array.observe(test, callback);
|
| - test[1] = 1;
|
| - test.length = 0;
|
| - Object.deliverChangeRecords(callback);
|
| - return gotSplice;
|
| - }
|
| -
|
| - var hasObserve = detectObjectObserve();
|
| -
|
| - function detectEval() {
|
| - // don't test for eval if document has CSP securityPolicy object and we can see that
|
| - // eval is not supported. This avoids an error message in console even when the exception
|
| - // is caught
|
| - if (global.document &&
|
| - 'securityPolicy' in global.document &&
|
| - !global.document.securityPolicy.allowsEval) {
|
| - return false;
|
| - }
|
| -
|
| - try {
|
| - var f = new Function('', 'return true;');
|
| - return f();
|
| - } catch (ex) {
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - var hasEval = detectEval();
|
| -
|
| - function isIndex(s) {
|
| - return +s === s >>> 0;
|
| - }
|
| -
|
| - function toNumber(s) {
|
| - return +s;
|
| - }
|
| -
|
| - function isObject(obj) {
|
| - return obj === Object(obj);
|
| - }
|
| -
|
| - var numberIsNaN = global.Number.isNaN || function isNaN(value) {
|
| - return typeof value === 'number' && global.isNaN(value);
|
| - }
|
| -
|
| - function areSameValue(left, right) {
|
| - if (left === right)
|
| - return left !== 0 || 1 / left === 1 / right;
|
| - if (numberIsNaN(left) && numberIsNaN(right))
|
| - return true;
|
| -
|
| - return left !== left && right !== right;
|
| - }
|
| -
|
| - var createObject = ('__proto__' in {}) ?
|
| - function(obj) { return obj; } :
|
| - function(obj) {
|
| - var proto = obj.__proto__;
|
| - if (!proto)
|
| - return obj;
|
| - var newObject = Object.create(proto);
|
| - Object.getOwnPropertyNames(obj).forEach(function(name) {
|
| - Object.defineProperty(newObject, name,
|
| - Object.getOwnPropertyDescriptor(obj, name));
|
| - });
|
| - return newObject;
|
| - };
|
| -
|
| - var identStart = '[\$_a-zA-Z]';
|
| - var identPart = '[\$_a-zA-Z0-9]';
|
| - var ident = identStart + '+' + identPart + '*';
|
| - var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)';
|
| - var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')';
|
| - var path = '(?:' + identOrElementIndex + ')(?:\\s*\\.\\s*' + identOrElementIndex + ')*';
|
| - var pathRegExp = new RegExp('^' + path + '$');
|
| -
|
| - function isPathValid(s) {
|
| - if (typeof s != 'string')
|
| - return false;
|
| - s = s.trim();
|
| -
|
| - if (s == '')
|
| - return true;
|
| -
|
| - if (s[0] == '.')
|
| - return false;
|
| -
|
| - return pathRegExp.test(s);
|
| - }
|
| -
|
| - var constructorIsPrivate = {};
|
| -
|
| - function Path(s, privateToken) {
|
| - if (privateToken !== constructorIsPrivate)
|
| - throw Error('Use Path.get to retrieve path objects');
|
| -
|
| - if (s.trim() == '')
|
| - return this;
|
| -
|
| - if (isIndex(s)) {
|
| - this.push(s);
|
| - return this;
|
| - }
|
| -
|
| - s.split(/\s*\.\s*/).filter(function(part) {
|
| - return part;
|
| - }).forEach(function(part) {
|
| - this.push(part);
|
| - }, this);
|
| -
|
| - if (hasEval && !hasObserve && this.length) {
|
| - this.getValueFrom = this.compiledGetValueFromFn();
|
| - }
|
| - }
|
| -
|
| - // TODO(rafaelw): Make simple LRU cache
|
| - var pathCache = {};
|
| -
|
| - function getPath(pathString) {
|
| - if (pathString instanceof Path)
|
| - return pathString;
|
| -
|
| - if (pathString == null)
|
| - pathString = '';
|
| -
|
| - if (typeof pathString !== 'string')
|
| - pathString = String(pathString);
|
| -
|
| - var path = pathCache[pathString];
|
| - if (path)
|
| - return path;
|
| - if (!isPathValid(pathString))
|
| - return invalidPath;
|
| - var path = new Path(pathString, constructorIsPrivate);
|
| - pathCache[pathString] = path;
|
| - return path;
|
| - }
|
| -
|
| - Path.get = getPath;
|
| -
|
| - Path.prototype = createObject({
|
| - __proto__: [],
|
| - valid: true,
|
| -
|
| - toString: function() {
|
| - return this.join('.');
|
| - },
|
| -
|
| - getValueFrom: function(obj, observedSet) {
|
| - for (var i = 0; i < this.length; i++) {
|
| - if (obj == null)
|
| - return;
|
| - if (observedSet)
|
| - observedSet.observe(obj);
|
| - obj = obj[this[i]];
|
| - }
|
| - return obj;
|
| - },
|
| -
|
| - compiledGetValueFromFn: function() {
|
| - var accessors = this.map(function(ident) {
|
| - return isIndex(ident) ? '["' + ident + '"]' : '.' + ident;
|
| - });
|
| -
|
| - var str = '';
|
| - var pathString = 'obj';
|
| - str += 'if (obj != null';
|
| - var i = 0;
|
| - for (; i < (this.length - 1); i++) {
|
| - var ident = this[i];
|
| - pathString += accessors[i];
|
| - str += ' &&\n ' + pathString + ' != null';
|
| - }
|
| - str += ')\n';
|
| -
|
| - pathString += accessors[i];
|
| -
|
| - str += ' return ' + pathString + ';\nelse\n return undefined;';
|
| - return new Function('obj', str);
|
| - },
|
| -
|
| - setValueFrom: function(obj, value) {
|
| - if (!this.length)
|
| - return false;
|
| -
|
| - for (var i = 0; i < this.length - 1; i++) {
|
| - if (!isObject(obj))
|
| - return false;
|
| - obj = obj[this[i]];
|
| - }
|
| -
|
| - if (!isObject(obj))
|
| - return false;
|
| -
|
| - obj[this[i]] = value;
|
| - return true;
|
| - }
|
| - });
|
| -
|
| - var invalidPath = new Path('', constructorIsPrivate);
|
| - invalidPath.valid = false;
|
| - invalidPath.getValueFrom = invalidPath.setValueFrom = function() {};
|
| -
|
| - var MAX_DIRTY_CHECK_CYCLES = 1000;
|
| -
|
| - function dirtyCheck(observer) {
|
| - var cycles = 0;
|
| - while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check()) {
|
| - observer.report();
|
| - cycles++;
|
| - }
|
| - if (global.testingExposeCycleCount)
|
| - global.dirtyCheckCycleCount = cycles;
|
| - }
|
| -
|
| - function objectIsEmpty(object) {
|
| - for (var prop in object)
|
| - return false;
|
| - return true;
|
| - }
|
| -
|
| - function diffIsEmpty(diff) {
|
| - return objectIsEmpty(diff.added) &&
|
| - objectIsEmpty(diff.removed) &&
|
| - objectIsEmpty(diff.changed);
|
| - }
|
| -
|
| - function diffObjectFromOldObject(object, oldObject) {
|
| - var added = {};
|
| - var removed = {};
|
| - var changed = {};
|
| - var oldObjectHas = {};
|
| -
|
| - for (var prop in oldObject) {
|
| - var newValue = object[prop];
|
| -
|
| - if (newValue !== undefined && newValue === oldObject[prop])
|
| - continue;
|
| -
|
| - if (!(prop in object)) {
|
| - removed[prop] = undefined;
|
| - continue;
|
| - }
|
| -
|
| - if (newValue !== oldObject[prop])
|
| - changed[prop] = newValue;
|
| - }
|
| -
|
| - for (var prop in object) {
|
| - if (prop in oldObject)
|
| - continue;
|
| -
|
| - added[prop] = object[prop];
|
| - }
|
| -
|
| - if (Array.isArray(object) && object.length !== oldObject.length)
|
| - changed.length = object.length;
|
| -
|
| - return {
|
| - added: added,
|
| - removed: removed,
|
| - changed: changed
|
| - };
|
| - }
|
| -
|
| - function copyObject(object, opt_copy) {
|
| - var copy = opt_copy || (Array.isArray(object) ? [] : {});
|
| - for (var prop in object) {
|
| - copy[prop] = object[prop];
|
| - };
|
| - if (Array.isArray(object))
|
| - copy.length = object.length;
|
| - return copy;
|
| - }
|
| -
|
| - function Observer(object, callback, target, token) {
|
| - this.closed = false;
|
| - this.object = object;
|
| - this.callback = callback;
|
| - // TODO(rafaelw): Hold this.target weakly when WeakRef is available.
|
| - this.target = target;
|
| - this.token = token;
|
| - this.reporting = true;
|
| - if (hasObserve) {
|
| - var self = this;
|
| - this.boundInternalCallback = function(records) {
|
| - self.internalCallback(records);
|
| - };
|
| - }
|
| -
|
| - addToAll(this);
|
| - }
|
| -
|
| - Observer.prototype = {
|
| - internalCallback: function(records) {
|
| - if (this.closed)
|
| - return;
|
| - if (this.reporting && this.check(records)) {
|
| - this.report();
|
| - if (this.testingResults)
|
| - this.testingResults.anyChanged = true;
|
| - }
|
| - },
|
| -
|
| - close: function() {
|
| - if (this.closed)
|
| - return;
|
| - if (this.object && typeof this.object.close === 'function')
|
| - this.object.close();
|
| -
|
| - this.disconnect();
|
| - this.object = undefined;
|
| - this.closed = true;
|
| - },
|
| -
|
| - deliver: function(testingResults) {
|
| - if (this.closed)
|
| - return;
|
| - if (hasObserve) {
|
| - this.testingResults = testingResults;
|
| - Object.deliverChangeRecords(this.boundInternalCallback);
|
| - this.testingResults = undefined;
|
| - } else {
|
| - dirtyCheck(this);
|
| - }
|
| - },
|
| -
|
| - report: function() {
|
| - if (!this.reporting)
|
| - return;
|
| -
|
| - this.sync(false);
|
| - if (this.callback) {
|
| - this.reportArgs.push(this.token);
|
| - this.invokeCallback(this.reportArgs);
|
| - }
|
| - this.reportArgs = undefined;
|
| - },
|
| -
|
| - invokeCallback: function(args) {
|
| - try {
|
| - this.callback.apply(this.target, args);
|
| - } catch (ex) {
|
| - Observer._errorThrownDuringCallback = true;
|
| - console.error('Exception caught during observer callback: ' + (ex.stack || ex));
|
| - }
|
| - },
|
| -
|
| - reset: function() {
|
| - if (this.closed)
|
| - return;
|
| -
|
| - if (hasObserve) {
|
| - this.reporting = false;
|
| - Object.deliverChangeRecords(this.boundInternalCallback);
|
| - this.reporting = true;
|
| - }
|
| -
|
| - this.sync(true);
|
| - }
|
| - }
|
| -
|
| - var collectObservers = !hasObserve || global.forceCollectObservers;
|
| - var allObservers;
|
| - Observer._allObserversCount = 0;
|
| -
|
| - if (collectObservers) {
|
| - allObservers = [];
|
| - }
|
| -
|
| - function addToAll(observer) {
|
| - if (!collectObservers)
|
| - return;
|
| -
|
| - allObservers.push(observer);
|
| - Observer._allObserversCount++;
|
| - }
|
| -
|
| - var runningMicrotaskCheckpoint = false;
|
| -
|
| - var hasDebugForceFullDelivery = typeof Object.deliverAllChangeRecords == 'function';
|
| -
|
| - global.Platform = global.Platform || {};
|
| -
|
| - global.Platform.performMicrotaskCheckpoint = function() {
|
| - if (runningMicrotaskCheckpoint)
|
| - return;
|
| -
|
| - if (hasDebugForceFullDelivery) {
|
| - Object.deliverAllChangeRecords();
|
| - return;
|
| - }
|
| -
|
| - if (!collectObservers)
|
| - return;
|
| -
|
| - runningMicrotaskCheckpoint = true;
|
| -
|
| - var cycles = 0;
|
| - var results = {};
|
| -
|
| - do {
|
| - cycles++;
|
| - var toCheck = allObservers;
|
| - allObservers = [];
|
| - results.anyChanged = false;
|
| -
|
| - for (var i = 0; i < toCheck.length; i++) {
|
| - var observer = toCheck[i];
|
| - if (observer.closed)
|
| - continue;
|
| -
|
| - if (hasObserve) {
|
| - observer.deliver(results);
|
| - } else if (observer.check()) {
|
| - results.anyChanged = true;
|
| - observer.report();
|
| - }
|
| -
|
| - allObservers.push(observer);
|
| - }
|
| - } while (cycles < MAX_DIRTY_CHECK_CYCLES && results.anyChanged);
|
| -
|
| - if (global.testingExposeCycleCount)
|
| - global.dirtyCheckCycleCount = cycles;
|
| -
|
| - Observer._allObserversCount = allObservers.length;
|
| - runningMicrotaskCheckpoint = false;
|
| - };
|
| -
|
| - if (collectObservers) {
|
| - global.Platform.clearObservers = function() {
|
| - allObservers = [];
|
| - };
|
| - }
|
| -
|
| - function ObjectObserver(object, callback, target, token) {
|
| - Observer.call(this, object, callback, target, token);
|
| - this.connect();
|
| - this.sync(true);
|
| - }
|
| -
|
| - ObjectObserver.prototype = createObject({
|
| - __proto__: Observer.prototype,
|
| -
|
| - connect: function() {
|
| - if (hasObserve)
|
| - Object.observe(this.object, this.boundInternalCallback);
|
| - },
|
| -
|
| - sync: function(hard) {
|
| - if (!hasObserve)
|
| - this.oldObject = copyObject(this.object);
|
| - },
|
| -
|
| - check: function(changeRecords) {
|
| - var diff;
|
| - var oldValues;
|
| - if (hasObserve) {
|
| - if (!changeRecords)
|
| - return false;
|
| -
|
| - oldValues = {};
|
| - diff = diffObjectFromChangeRecords(this.object, changeRecords,
|
| - oldValues);
|
| - } else {
|
| - oldValues = this.oldObject;
|
| - diff = diffObjectFromOldObject(this.object, this.oldObject);
|
| - }
|
| -
|
| - if (diffIsEmpty(diff))
|
| - return false;
|
| -
|
| - this.reportArgs =
|
| - [diff.added || {}, diff.removed || {}, diff.changed || {}];
|
| - this.reportArgs.push(function(property) {
|
| - return oldValues[property];
|
| - });
|
| -
|
| - return true;
|
| - },
|
| -
|
| - disconnect: function() {
|
| - if (!hasObserve)
|
| - this.oldObject = undefined;
|
| - else if (this.object)
|
| - Object.unobserve(this.object, this.boundInternalCallback);
|
| - }
|
| - });
|
| -
|
| - function ArrayObserver(array, callback, target, token) {
|
| - if (!Array.isArray(array))
|
| - throw Error('Provided object is not an Array');
|
| - ObjectObserver.call(this, array, callback, target, token);
|
| - }
|
| -
|
| - ArrayObserver.prototype = createObject({
|
| - __proto__: ObjectObserver.prototype,
|
| -
|
| - connect: function() {
|
| - if (hasObserve)
|
| - Array.observe(this.object, this.boundInternalCallback);
|
| - },
|
| -
|
| - sync: function() {
|
| - if (!hasObserve)
|
| - this.oldObject = this.object.slice();
|
| - },
|
| -
|
| - check: function(changeRecords) {
|
| - var splices;
|
| - if (hasObserve) {
|
| - if (!changeRecords)
|
| - return false;
|
| - splices = projectArraySplices(this.object, changeRecords);
|
| - } else {
|
| - splices = calcSplices(this.object, 0, this.object.length,
|
| - this.oldObject, 0, this.oldObject.length);
|
| - }
|
| -
|
| - if (!splices || !splices.length)
|
| - return false;
|
| -
|
| - this.reportArgs = [splices];
|
| - return true;
|
| - }
|
| - });
|
| -
|
| - ArrayObserver.applySplices = function(previous, current, splices) {
|
| - splices.forEach(function(splice) {
|
| - var spliceArgs = [splice.index, splice.removed.length];
|
| - var addIndex = splice.index;
|
| - while (addIndex < splice.index + splice.addedCount) {
|
| - spliceArgs.push(current[addIndex]);
|
| - addIndex++;
|
| - }
|
| -
|
| - Array.prototype.splice.apply(previous, spliceArgs);
|
| - });
|
| - };
|
| -
|
| - function ObservedSet(callback) {
|
| - this.arr = [];
|
| - this.callback = callback;
|
| - this.isObserved = true;
|
| - }
|
| -
|
| - var objProto = Object.getPrototypeOf({});
|
| - var arrayProto = Object.getPrototypeOf([]);
|
| - ObservedSet.prototype = {
|
| - reset: function() {
|
| - this.isObserved = !this.isObserved;
|
| - },
|
| -
|
| - observe: function(obj) {
|
| - if (!isObject(obj) || obj === objProto || obj === arrayProto)
|
| - return;
|
| - var i = this.arr.indexOf(obj);
|
| - if (i >= 0 && this.arr[i+1] === this.isObserved)
|
| - return;
|
| -
|
| - if (i < 0) {
|
| - i = this.arr.length;
|
| - this.arr[i] = obj;
|
| - Object.observe(obj, this.callback);
|
| - }
|
| -
|
| - this.arr[i+1] = this.isObserved;
|
| - this.observe(Object.getPrototypeOf(obj));
|
| - },
|
| -
|
| - cleanup: function() {
|
| - var i = 0, j = 0;
|
| - var isObserved = this.isObserved;
|
| - while(j < this.arr.length) {
|
| - var obj = this.arr[j];
|
| - if (this.arr[j + 1] == isObserved) {
|
| - if (i < j) {
|
| - this.arr[i] = obj;
|
| - this.arr[i + 1] = isObserved;
|
| - }
|
| - i += 2;
|
| - } else {
|
| - Object.unobserve(obj, this.callback);
|
| - }
|
| - j += 2;
|
| - }
|
| -
|
| - this.arr.length = i;
|
| - }
|
| - };
|
| -
|
| - function PathObserver(object, path, callback, target, token, valueFn,
|
| - setValueFn) {
|
| - var path = path instanceof Path ? path : getPath(path);
|
| - if (!path || !path.length || !isObject(object)) {
|
| - this.value_ = path ? path.getValueFrom(object) : undefined;
|
| - this.value = valueFn ? valueFn(this.value_) : this.value_;
|
| - this.closed = true;
|
| - return;
|
| - }
|
| -
|
| - Observer.call(this, object, callback, target, token);
|
| - this.valueFn = valueFn;
|
| - this.setValueFn = setValueFn;
|
| - this.path = path;
|
| -
|
| - this.connect();
|
| - this.sync(true);
|
| - }
|
| -
|
| - PathObserver.prototype = createObject({
|
| - __proto__: Observer.prototype,
|
| -
|
| - connect: function() {
|
| - if (hasObserve)
|
| - this.observedSet = new ObservedSet(this.boundInternalCallback);
|
| - },
|
| -
|
| - disconnect: function() {
|
| - this.value = undefined;
|
| - this.value_ = undefined;
|
| - if (this.observedSet) {
|
| - this.observedSet.reset();
|
| - this.observedSet.cleanup();
|
| - this.observedSet = undefined;
|
| - }
|
| - },
|
| -
|
| - check: function() {
|
| - // Note: Extracting this to a member function for use here and below
|
| - // regresses dirty-checking path perf by about 25% =-(.
|
| - if (this.observedSet)
|
| - this.observedSet.reset();
|
| -
|
| - this.value_ = this.path.getValueFrom(this.object, this.observedSet);
|
| -
|
| - if (this.observedSet)
|
| - this.observedSet.cleanup();
|
| -
|
| - if (areSameValue(this.value_, this.oldValue_))
|
| - return false;
|
| -
|
| - this.value = this.valueFn ? this.valueFn(this.value_) : this.value_;
|
| - this.reportArgs = [this.value, this.oldValue];
|
| - return true;
|
| - },
|
| -
|
| - sync: function(hard) {
|
| - if (hard) {
|
| - if (this.observedSet)
|
| - this.observedSet.reset();
|
| -
|
| - this.value_ = this.path.getValueFrom(this.object, this.observedSet);
|
| - this.value = this.valueFn ? this.valueFn(this.value_) : this.value_;
|
| -
|
| - if (this.observedSet)
|
| - this.observedSet.cleanup();
|
| - }
|
| -
|
| - this.oldValue_ = this.value_;
|
| - this.oldValue = this.value;
|
| - },
|
| -
|
| - setValue: function(newValue) {
|
| - if (!this.path)
|
| - return;
|
| - if (typeof this.setValueFn === 'function')
|
| - newValue = this.setValueFn(newValue);
|
| - this.path.setValueFrom(this.object, newValue);
|
| - }
|
| - });
|
| -
|
| - function CompoundPathObserver(callback, target, token, valueFn) {
|
| - Observer.call(this, undefined, callback, target, token);
|
| - this.valueFn = valueFn;
|
| -
|
| - this.observed = [];
|
| - this.values = [];
|
| - this.value = undefined;
|
| - this.oldValue = undefined;
|
| - this.oldValues = undefined;
|
| - this.changeFlags = undefined;
|
| - this.started = false;
|
| - }
|
| -
|
| - CompoundPathObserver.prototype = createObject({
|
| - __proto__: PathObserver.prototype,
|
| -
|
| - addPath: function(object, path) {
|
| - if (this.started)
|
| - throw Error('Cannot add more paths once started.');
|
| -
|
| - var path = path instanceof Path ? path : getPath(path);
|
| - var value = path ? path.getValueFrom(object) : undefined;
|
| -
|
| - this.observed.push(object, path);
|
| - this.values.push(value);
|
| - },
|
| -
|
| - start: function() {
|
| - this.connect();
|
| - this.sync(true);
|
| - },
|
| -
|
| - getValues: function() {
|
| - if (this.observedSet)
|
| - this.observedSet.reset();
|
| -
|
| - var anyChanged = false;
|
| - for (var i = 0; i < this.observed.length; i = i+2) {
|
| - var path = this.observed[i+1];
|
| - if (!path)
|
| - continue;
|
| - var object = this.observed[i];
|
| - var value = path.getValueFrom(object, this.observedSet);
|
| - var oldValue = this.values[i/2];
|
| - if (!areSameValue(value, oldValue)) {
|
| - if (!anyChanged && !this.valueFn) {
|
| - this.oldValues = this.oldValues || [];
|
| - this.changeFlags = this.changeFlags || [];
|
| - for (var j = 0; j < this.values.length; j++) {
|
| - this.oldValues[j] = this.values[j];
|
| - this.changeFlags[j] = false;
|
| - }
|
| - }
|
| -
|
| - if (!this.valueFn)
|
| - this.changeFlags[i/2] = true;
|
| -
|
| - this.values[i/2] = value;
|
| - anyChanged = true;
|
| - }
|
| - }
|
| -
|
| - if (this.observedSet)
|
| - this.observedSet.cleanup();
|
| -
|
| - return anyChanged;
|
| - },
|
| -
|
| - check: function() {
|
| - if (!this.getValues())
|
| - return;
|
| -
|
| - if (this.valueFn) {
|
| - this.value = this.valueFn(this.values);
|
| -
|
| - if (areSameValue(this.value, this.oldValue))
|
| - return false;
|
| -
|
| - this.reportArgs = [this.value, this.oldValue];
|
| - } else {
|
| - this.reportArgs = [this.values, this.oldValues, this.changeFlags];
|
| - }
|
| -
|
| - return true;
|
| - },
|
| -
|
| - sync: function(hard) {
|
| - if (hard) {
|
| - this.getValues();
|
| - if (this.valueFn)
|
| - this.value = this.valueFn(this.values);
|
| - }
|
| -
|
| - if (this.valueFn)
|
| - this.oldValue = this.value;
|
| - },
|
| -
|
| - close: function() {
|
| - if (this.observed) {
|
| - for (var i = 0; i < this.observed.length; i = i + 2) {
|
| - var object = this.observed[i];
|
| - if (object && typeof object.close === 'function')
|
| - object.close();
|
| - }
|
| - this.observed = undefined;
|
| - this.values = undefined;
|
| - }
|
| -
|
| - Observer.prototype.close.call(this);
|
| - }
|
| - });
|
| -
|
| - var knownRecordTypes = {
|
| - 'new': true,
|
| - 'updated': true,
|
| - 'deleted': true
|
| - };
|
| -
|
| - function notifyFunction(object, name) {
|
| - if (typeof Object.observe !== 'function')
|
| - return;
|
| -
|
| - var notifier = Object.getNotifier(object);
|
| - return function(type, oldValue) {
|
| - var changeRecord = {
|
| - object: object,
|
| - type: type,
|
| - name: name
|
| - };
|
| - if (arguments.length === 2)
|
| - changeRecord.oldValue = oldValue;
|
| - notifier.notify(changeRecord);
|
| - }
|
| - }
|
| -
|
| - // TODO(rafaelw): It should be possible for the Object.observe case to have
|
| - // every PathObserver used by defineProperty share a single Object.observe
|
| - // callback, and thus get() can simply call observer.deliver() and any changes
|
| - // to any dependent value will be observed.
|
| - PathObserver.defineProperty = function(object, name, descriptor) {
|
| - // TODO(rafaelw): Validate errors
|
| - var obj = descriptor.object;
|
| - var path = getPath(descriptor.path);
|
| - var notify = notifyFunction(object, name);
|
| -
|
| - var observer = new PathObserver(obj, descriptor.path,
|
| - function(newValue, oldValue) {
|
| - if (notify)
|
| - notify('updated', oldValue);
|
| - }
|
| - );
|
| -
|
| - Object.defineProperty(object, name, {
|
| - get: function() {
|
| - return path.getValueFrom(obj);
|
| - },
|
| - set: function(newValue) {
|
| - path.setValueFrom(obj, newValue);
|
| - },
|
| - configurable: true
|
| - });
|
| -
|
| - return {
|
| - close: function() {
|
| - var oldValue = path.getValueFrom(obj);
|
| - if (notify)
|
| - observer.deliver();
|
| - observer.close();
|
| - Object.defineProperty(object, name, {
|
| - value: oldValue,
|
| - writable: true,
|
| - configurable: true
|
| - });
|
| - }
|
| - };
|
| - }
|
| -
|
| - function diffObjectFromChangeRecords(object, changeRecords, oldValues) {
|
| - var added = {};
|
| - var removed = {};
|
| -
|
| - for (var i = 0; i < changeRecords.length; i++) {
|
| - var record = changeRecords[i];
|
| - if (!knownRecordTypes[record.type]) {
|
| - console.error('Unknown changeRecord type: ' + record.type);
|
| - console.error(record);
|
| - continue;
|
| - }
|
| -
|
| - if (!(record.name in oldValues))
|
| - oldValues[record.name] = record.oldValue;
|
| -
|
| - if (record.type == 'updated')
|
| - continue;
|
| -
|
| - if (record.type == 'new') {
|
| - if (record.name in removed)
|
| - delete removed[record.name];
|
| - else
|
| - added[record.name] = true;
|
| -
|
| - continue;
|
| - }
|
| -
|
| - // type = 'deleted'
|
| - if (record.name in added) {
|
| - delete added[record.name];
|
| - delete oldValues[record.name];
|
| - } else {
|
| - removed[record.name] = true;
|
| - }
|
| - }
|
| -
|
| - for (var prop in added)
|
| - added[prop] = object[prop];
|
| -
|
| - for (var prop in removed)
|
| - removed[prop] = undefined;
|
| -
|
| - var changed = {};
|
| - for (var prop in oldValues) {
|
| - if (prop in added || prop in removed)
|
| - continue;
|
| -
|
| - var newValue = object[prop];
|
| - if (oldValues[prop] !== newValue)
|
| - changed[prop] = newValue;
|
| - }
|
| -
|
| - return {
|
| - added: added,
|
| - removed: removed,
|
| - changed: changed
|
| - };
|
| - }
|
| -
|
| - 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 = {
|
| -
|
| - // Note: This function is *based* on the computation of the Levenshtein
|
| - // "edit" distance. The one change is that "updates" are treated as two
|
| - // edits - not one. With Array splices, an update is really a delete
|
| - // followed by an add. By retaining this, we optimize for "keeping" the
|
| - // maximum array items in the original array. For example:
|
| - //
|
| - // 'xxxx123' -> '123yyyy'
|
| - //
|
| - // With 1-edit updates, the shortest path would be just to update all seven
|
| - // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
|
| - // leaves the substring '123' intact.
|
| - calcEditDistances: function(current, currentStart, currentEnd,
|
| - old, oldStart, oldEnd) {
|
| - // "Deletion" columns
|
| - var rowCount = oldEnd - oldStart + 1;
|
| - var columnCount = currentEnd - currentStart + 1;
|
| - var distances = new Array(rowCount);
|
| -
|
| - // "Addition" rows. Initialize null column.
|
| - for (var i = 0; i < rowCount; i++) {
|
| - distances[i] = new Array(columnCount);
|
| - distances[i][0] = i;
|
| - }
|
| -
|
| - // Initialize null row
|
| - 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;
|
| - },
|
| -
|
| - // This starts at the final weight, and walks "backward" by finding
|
| - // the minimum previous weight recursively until the origin of the weight
|
| - // matrix.
|
| - 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;
|
| - },
|
| -
|
| - /**
|
| - * Splice Projection functions:
|
| - *
|
| - * A splice map is a representation of how a previous array of items
|
| - * was transformed into a new array of items. Conceptually it is a list of
|
| - * tuples of
|
| - *
|
| - * <index, removed, addedCount>
|
| - *
|
| - * which are kept in ascending index order of. The tuple represents that at
|
| - * the |index|, |removed| sequence of items were removed, and counting forward
|
| - * from |index|, |addedCount| items were added.
|
| - */
|
| -
|
| - /**
|
| - * Lacking individual splice mutation information, the minimal set of
|
| - * splices can be synthesized given the previous state and final state of an
|
| - * array. The basic approach is to calculate the edit distance matrix and
|
| - * choose the shortest path through it.
|
| - *
|
| - * Complexity: O(l * p)
|
| - * l: The length of the current array
|
| - * p: The length of the old array
|
| - */
|
| - 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;
|
| - }
|
| - };
|
| -
|
| - var arraySplice = new ArraySplice();
|
| -
|
| - function calcSplices(current, currentStart, currentEnd,
|
| - old, oldStart, oldEnd) {
|
| - return arraySplice.calcSplices(current, currentStart, currentEnd,
|
| - old, oldStart, oldEnd);
|
| - }
|
| -
|
| - function intersect(start1, end1, start2, end2) {
|
| - // Disjoint
|
| - if (end1 < start2 || end2 < start1)
|
| - return -1;
|
| -
|
| - // Adjacent
|
| - if (end1 == start2 || end2 == start1)
|
| - return 0;
|
| -
|
| - // Non-zero intersect, span1 first
|
| - if (start1 < start2) {
|
| - if (end1 < end2)
|
| - return end1 - start2; // Overlap
|
| - else
|
| - return end2 - start2; // Contained
|
| - } else {
|
| - // Non-zero intersect, span2 first
|
| - if (end2 < end1)
|
| - return end2 - start1; // Overlap
|
| - else
|
| - return end1 - start1; // Contained
|
| - }
|
| - }
|
| -
|
| - function mergeSplice(splices, index, removed, addedCount) {
|
| -
|
| - var splice = newSplice(index, removed, addedCount);
|
| -
|
| - var inserted = false;
|
| - var insertionOffset = 0;
|
| -
|
| - for (var i = 0; i < splices.length; i++) {
|
| - var current = splices[i];
|
| - current.index += insertionOffset;
|
| -
|
| - if (inserted)
|
| - continue;
|
| -
|
| - var intersectCount = intersect(splice.index,
|
| - splice.index + splice.removed.length,
|
| - current.index,
|
| - current.index + current.addedCount);
|
| -
|
| - if (intersectCount >= 0) {
|
| - // Merge the two splices
|
| -
|
| - splices.splice(i, 1);
|
| - i--;
|
| -
|
| - insertionOffset -= current.addedCount - current.removed.length;
|
| -
|
| - splice.addedCount += current.addedCount - intersectCount;
|
| - var deleteCount = splice.removed.length +
|
| - current.removed.length - intersectCount;
|
| -
|
| - if (!splice.addedCount && !deleteCount) {
|
| - // merged splice is a noop. discard.
|
| - inserted = true;
|
| - } else {
|
| - var removed = current.removed;
|
| -
|
| - if (splice.index < current.index) {
|
| - // some prefix of splice.removed is prepended to current.removed.
|
| - var prepend = splice.removed.slice(0, current.index - splice.index);
|
| - Array.prototype.push.apply(prepend, removed);
|
| - removed = prepend;
|
| - }
|
| -
|
| - if (splice.index + splice.removed.length > current.index + current.addedCount) {
|
| - // some suffix of splice.removed is appended to current.removed.
|
| - var append = splice.removed.slice(current.index + current.addedCount - splice.index);
|
| - Array.prototype.push.apply(removed, append);
|
| - }
|
| -
|
| - splice.removed = removed;
|
| - if (current.index < splice.index) {
|
| - splice.index = current.index;
|
| - }
|
| - }
|
| - } else if (splice.index < current.index) {
|
| - // Insert splice here.
|
| -
|
| - inserted = true;
|
| -
|
| - splices.splice(i, 0, splice);
|
| - i++;
|
| -
|
| - var offset = splice.addedCount - splice.removed.length
|
| - current.index += offset;
|
| - insertionOffset += offset;
|
| - }
|
| - }
|
| -
|
| - if (!inserted)
|
| - splices.push(splice);
|
| - }
|
| -
|
| - function createInitialSplices(array, changeRecords) {
|
| - var splices = [];
|
| -
|
| - for (var i = 0; i < changeRecords.length; i++) {
|
| - var record = changeRecords[i];
|
| - switch(record.type) {
|
| - case 'splice':
|
| - mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);
|
| - break;
|
| - case 'new':
|
| - case 'updated':
|
| - case 'deleted':
|
| - if (!isIndex(record.name))
|
| - continue;
|
| - var index = toNumber(record.name);
|
| - if (index < 0)
|
| - continue;
|
| - mergeSplice(splices, index, [record.oldValue], 1);
|
| - break;
|
| - default:
|
| - console.error('Unexpected record type: ' + JSON.stringify(record));
|
| - break;
|
| - }
|
| - }
|
| -
|
| - return splices;
|
| - }
|
| -
|
| - function projectArraySplices(array, changeRecords) {
|
| - var splices = [];
|
| -
|
| - createInitialSplices(array, changeRecords).forEach(function(splice) {
|
| - if (splice.addedCount == 1 && splice.removed.length == 1) {
|
| - if (splice.removed[0] !== array[splice.index])
|
| - splices.push(splice);
|
| -
|
| - return
|
| - };
|
| -
|
| - splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount,
|
| - splice.removed, 0, splice.removed.length));
|
| - });
|
| -
|
| - return splices;
|
| - }
|
| -
|
| - global.Observer = Observer;
|
| - global.Observer.hasObjectObserve = hasObserve;
|
| - global.ArrayObserver = ArrayObserver;
|
| - global.ArrayObserver.calculateSplices = function(current, previous) {
|
| - return arraySplice.calculateSplices(current, previous);
|
| - };
|
| -
|
| - global.ArraySplice = ArraySplice;
|
| - global.ObjectObserver = ObjectObserver;
|
| - global.PathObserver = PathObserver;
|
| - global.CompoundPathObserver = CompoundPathObserver;
|
| - global.Path = Path;
|
| -})(typeof global !== 'undefined' && global ? global : this);
|
| -
|
| -/*
|
| - * Copyright 2012 The Polymer Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style
|
| - * license that can be found in the LICENSE file.
|
| - */
|
| -
|
| -// If WeakMap is not available, the association is stored as an expando property on the "key".
|
| -// TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox
|
| -if (typeof WeakMap === 'undefined' || navigator.userAgent.indexOf('Firefox/') > -1) {
|
| - (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});
|
| - },
|
| - get: function(key) {
|
| - var entry;
|
| - return (entry = key[this.name]) && entry[0] === key ?
|
| - entry[1] : undefined;
|
| - },
|
| - delete: function(key) {
|
| - this.set(key, undefined);
|
| - }
|
| - };
|
| -
|
| - window.WeakMap = WeakMap;
|
| - })();
|
| -}
|
| -
|
| -// Copyright 2012 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -var ShadowDOMPolyfill = {};
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var constructorTable = new WeakMap();
|
| - var nativePrototypeTable = new WeakMap();
|
| - var wrappers = Object.create(null);
|
| -
|
| - // Don't test for eval if document has CSP securityPolicy object and we can
|
| - // see that eval is not supported. This avoids an error message in console
|
| - // even when the exception is caught
|
| - var hasEval = !('securityPolicy' in document) ||
|
| - document.securityPolicy.allowsEval;
|
| - if (hasEval) {
|
| - try {
|
| - var f = new Function('', 'return true;');
|
| - hasEval = f();
|
| - } catch (ex) {
|
| - }
|
| - }
|
| -
|
| - function assert(b) {
|
| - if (!b)
|
| - throw new Error('Assertion failed');
|
| - };
|
| -
|
| - function mixin(to, from) {
|
| - Object.getOwnPropertyNames(from).forEach(function(name) {
|
| - Object.defineProperty(to, name,
|
| - Object.getOwnPropertyDescriptor(from, name));
|
| - });
|
| - return to;
|
| - };
|
| -
|
| - function mixinStatics(to, from) {
|
| - Object.getOwnPropertyNames(from).forEach(function(name) {
|
| - switch (name) {
|
| - case 'arguments':
|
| - case 'caller':
|
| - case 'length':
|
| - case 'name':
|
| - case 'prototype':
|
| - case 'toString':
|
| - return;
|
| - }
|
| - Object.defineProperty(to, name,
|
| - Object.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];
|
| - }
|
| - }
|
| -
|
| - // Mozilla's old DOM bindings are bretty busted:
|
| - // https://bugzilla.mozilla.org/show_bug.cgi?id=855844
|
| - // Make sure they are create before we start modifying things.
|
| - Object.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);
|
| -
|
| - // This is used as a fallback when getting the descriptor fails in
|
| - // installProperty.
|
| - var dummyDescriptor = {
|
| - get: function() {},
|
| - set: function(v) {},
|
| - configurable: true,
|
| - enumerable: true
|
| - };
|
| -
|
| - function isEventHandlerName(name) {
|
| - return /^on[a-z]+$/.test(name);
|
| - }
|
| -
|
| - function getGetter(name) {
|
| - return hasEval ?
|
| - new Function('return this.impl.' + name) :
|
| - function() { return this.impl[name]; };
|
| - }
|
| -
|
| - function getSetter(name) {
|
| - return hasEval ?
|
| - new Function('v', 'this.impl.' + name + ' = v') :
|
| - function(v) { this.impl[name] = v; };
|
| - }
|
| -
|
| - function getMethod(name) {
|
| - return hasEval ?
|
| - new Function('return this.impl.' + name +
|
| - '.apply(this.impl, arguments)') :
|
| - function() { return this.impl[name].apply(this.impl, arguments); };
|
| - }
|
| -
|
| - function installProperty(source, target, allowMethod) {
|
| - Object.getOwnPropertyNames(source).forEach(function(name) {
|
| - if (name in target)
|
| - return;
|
| -
|
| - if (isFirefox) {
|
| - // Tickle Firefox's old bindings.
|
| - source.__lookupGetter__(name);
|
| - }
|
| - var descriptor;
|
| - try {
|
| - descriptor = Object.getOwnPropertyDescriptor(source, name);
|
| - } catch (ex) {
|
| - // JSC and V8 both use data properties instead of accessors which can
|
| - // cause getting the property desciptor to throw an exception.
|
| - // https://bugs.webkit.org/show_bug.cgi?id=49739
|
| - descriptor = dummyDescriptor;
|
| - }
|
| - var getter, setter;
|
| - if (allowMethod && typeof descriptor.value === 'function') {
|
| - target[name] = getMethod(name);
|
| - return;
|
| - }
|
| -
|
| - var isEvent = isEventHandlerName(name);
|
| - if (isEvent)
|
| - getter = scope.getEventHandlerGetter(name);
|
| - else
|
| - getter = getGetter(name);
|
| -
|
| - if (descriptor.writable || descriptor.set) {
|
| - if (isEvent)
|
| - setter = scope.getEventHandlerSetter(name);
|
| - else
|
| - setter = getSetter(name);
|
| - }
|
| -
|
| - Object.defineProperty(target, name, {
|
| - get: getter,
|
| - set: setter,
|
| - configurable: descriptor.configurable,
|
| - enumerable: descriptor.enumerable
|
| - });
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * @param {Function} nativeConstructor
|
| - * @param {Function} wrapperConstructor
|
| - * @param {Object=} opt_instance If present, this is used to extract
|
| - * properties from an instance object.
|
| - */
|
| - 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);
|
| - }
|
| -
|
| - function isWrapperFor(wrapperConstructor, nativeConstructor) {
|
| - return constructorTable.get(nativeConstructor.prototype) ===
|
| - wrapperConstructor;
|
| - }
|
| -
|
| - /**
|
| - * Creates a generic wrapper constructor based on |object| and its
|
| - * constructor.
|
| - * Sometimes the constructor does not have an associated instance
|
| - * (CharacterData for example). In that case you can pass the constructor that
|
| - * you want to map the object to using |opt_nativeConstructor|.
|
| - * @param {Node} object
|
| - * @param {Function=} opt_nativeConstructor
|
| - * @return {Function} The generated constructor.
|
| - */
|
| - 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);
|
| - }
|
| - GeneratedWrapper.prototype =
|
| - Object.create(superWrapperConstructor.prototype);
|
| - GeneratedWrapper.prototype.constructor = GeneratedWrapper;
|
| -
|
| - return GeneratedWrapper;
|
| - }
|
| -
|
| - var OriginalDOMImplementation = DOMImplementation;
|
| - var OriginalEvent = Event;
|
| - var OriginalNode = Node;
|
| - var OriginalWindow = Window;
|
| - var OriginalRange = Range;
|
| -
|
| - function isWrapper(object) {
|
| - return object instanceof wrappers.EventTarget ||
|
| - object instanceof wrappers.Event ||
|
| - object instanceof wrappers.Range ||
|
| - object instanceof wrappers.DOMImplementation;
|
| - }
|
| -
|
| - function isNative(object) {
|
| - return object instanceof OriginalNode ||
|
| - object instanceof OriginalEvent ||
|
| - object instanceof OriginalWindow ||
|
| - object instanceof OriginalRange ||
|
| - object instanceof OriginalDOMImplementation;
|
| - }
|
| -
|
| - /**
|
| - * Wraps a node in a WrapperNode. If there already exists a wrapper for the
|
| - * |node| that wrapper is returned instead.
|
| - * @param {Node} node
|
| - * @return {WrapperNode}
|
| - */
|
| - function wrap(impl) {
|
| - if (impl === null)
|
| - return null;
|
| -
|
| - assert(isNative(impl));
|
| - return impl.polymerWrapper_ ||
|
| - (impl.polymerWrapper_ = new (getWrapperConstructor(impl))(impl));
|
| - }
|
| -
|
| - /**
|
| - * Unwraps a wrapper and returns the node it is wrapping.
|
| - * @param {WrapperNode} wrapper
|
| - * @return {Node}
|
| - */
|
| - function unwrap(wrapper) {
|
| - if (wrapper === null)
|
| - return null;
|
| - assert(isWrapper(wrapper));
|
| - return wrapper.impl;
|
| - }
|
| -
|
| - /**
|
| - * Unwraps object if it is a wrapper.
|
| - * @param {Object} object
|
| - * @return {Object} The native implementation object.
|
| - */
|
| - function unwrapIfNeeded(object) {
|
| - return object && isWrapper(object) ? unwrap(object) : object;
|
| - }
|
| -
|
| - /**
|
| - * Wraps object if it is not a wrapper.
|
| - * @param {Object} object
|
| - * @return {Object} The wrapper for object.
|
| - */
|
| - function wrapIfNeeded(object) {
|
| - return object && !isWrapper(object) ? wrap(object) : object;
|
| - }
|
| -
|
| - /**
|
| - * Overrides the current wrapper (if any) for node.
|
| - * @param {Node} node
|
| - * @param {WrapperNode=} wrapper If left out the wrapper will be created as
|
| - * needed next time someone wraps the node.
|
| - */
|
| - function rewrap(node, wrapper) {
|
| - if (wrapper === null)
|
| - return;
|
| - assert(isNative(node));
|
| - assert(wrapper === undefined || isWrapper(wrapper));
|
| - node.polymerWrapper_ = wrapper;
|
| - }
|
| -
|
| - function defineGetter(constructor, name, getter) {
|
| - Object.defineProperty(constructor.prototype, name, {
|
| - get: getter,
|
| - configurable: true,
|
| - enumerable: true
|
| - });
|
| - }
|
| -
|
| - function defineWrapGetter(constructor, name) {
|
| - defineGetter(constructor, name, function() {
|
| - return wrap(this.impl[name]);
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * Forwards existing methods on the native object to the wrapper methods.
|
| - * This does not wrap any of the arguments or the return value since the
|
| - * wrapper implementation already takes care of that.
|
| - * @param {Array.<Function>} constructors
|
| - * @parem {Array.<string>} names
|
| - */
|
| - 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.isWrapperFor = isWrapperFor;
|
| - scope.mixin = mixin;
|
| - scope.nativePrototypeTable = nativePrototypeTable;
|
| - scope.oneOf = oneOf;
|
| - scope.registerObject = registerObject;
|
| - scope.registerWrapper = register;
|
| - scope.rewrap = rewrap;
|
| - scope.unwrap = unwrap;
|
| - scope.unwrapIfNeeded = unwrapIfNeeded;
|
| - scope.wrap = wrap;
|
| - scope.wrapIfNeeded = wrapIfNeeded;
|
| - scope.wrappers = wrappers;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - 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 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 isInsertionPoint(node) {
|
| - var localName = node.localName;
|
| - return localName === 'content' || localName === 'shadow';
|
| - }
|
| -
|
| - function isShadowHost(node) {
|
| - return !!node.shadowRoot;
|
| - }
|
| -
|
| - function getEventParent(node) {
|
| - var dv;
|
| - return node.parentNode || (dv = node.defaultView) && wrap(dv) || null;
|
| - }
|
| -
|
| - // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-parent
|
| - function calculateParents(node, context, ancestors) {
|
| - if (ancestors.length)
|
| - return ancestors.shift();
|
| -
|
| - // 1.
|
| - if (isShadowRoot(node))
|
| - return getInsertionParent(node) || scope.getHostForShadowRoot(node);
|
| -
|
| - // 2.
|
| - var eventParents = scope.eventParentsTable.get(node);
|
| - if (eventParents) {
|
| - // Copy over the remaining event parents for next iteration.
|
| - for (var i = 1; i < eventParents.length; i++) {
|
| - ancestors[i - 1] = eventParents[i];
|
| - }
|
| - return eventParents[0];
|
| - }
|
| -
|
| - // 3.
|
| - if (context && isInsertionPoint(node)) {
|
| - var parentNode = node.parentNode;
|
| - if (parentNode && isShadowHost(parentNode)) {
|
| - var trees = scope.getShadowTrees(parentNode);
|
| - var p = getInsertionParent(context);
|
| - for (var i = 0; i < trees.length; i++) {
|
| - if (trees[i].contains(p))
|
| - return p;
|
| - }
|
| - }
|
| - }
|
| -
|
| - return getEventParent(node);
|
| - }
|
| -
|
| - // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#event-retargeting
|
| - function retarget(node) {
|
| - var stack = []; // 1.
|
| - var ancestor = node; // 2.
|
| - var targets = [];
|
| - var ancestors = [];
|
| - while (ancestor) { // 3.
|
| - var context = null; // 3.2.
|
| - // TODO(arv): Change order of these. If the stack is empty we always end
|
| - // up pushing ancestor, no matter what.
|
| - if (isInsertionPoint(ancestor)) { // 3.1.
|
| - context = topMostNotInsertionPoint(stack); // 3.1.1.
|
| - var top = stack[stack.length - 1] || ancestor; // 3.1.2.
|
| - stack.push(top);
|
| - } else if (!stack.length) {
|
| - stack.push(ancestor); // 3.3.
|
| - }
|
| - var target = stack[stack.length - 1]; // 3.4.
|
| - targets.push({target: target, currentTarget: ancestor}); // 3.5.
|
| - if (isShadowRoot(ancestor)) // 3.6.
|
| - stack.pop(); // 3.6.1.
|
| -
|
| - ancestor = calculateParents(ancestor, context, ancestors); // 3.7.
|
| - }
|
| - return targets;
|
| - }
|
| -
|
| - function topMostNotInsertionPoint(stack) {
|
| - for (var i = stack.length - 1; i >= 0; i--) {
|
| - if (!isInsertionPoint(stack[i]))
|
| - return stack[i];
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-adjusted-related-target
|
| - function adjustRelatedTarget(target, related) {
|
| - var ancestors = [];
|
| - while (target) { // 3.
|
| - var stack = []; // 3.1.
|
| - var ancestor = related; // 3.2.
|
| - var last = undefined; // 3.3. Needs to be reset every iteration.
|
| - while (ancestor) {
|
| - var context = null;
|
| - if (!stack.length) {
|
| - stack.push(ancestor);
|
| - } else {
|
| - if (isInsertionPoint(ancestor)) { // 3.4.3.
|
| - context = topMostNotInsertionPoint(stack);
|
| - // isDistributed is more general than checking whether last is
|
| - // assigned into ancestor.
|
| - if (isDistributed(last)) { // 3.4.3.2.
|
| - var head = stack[stack.length - 1];
|
| - stack.push(head);
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (inSameTree(ancestor, target)) // 3.4.4.
|
| - return stack[stack.length - 1];
|
| -
|
| - if (isShadowRoot(ancestor)) // 3.4.5.
|
| - stack.pop();
|
| -
|
| - last = ancestor; // 3.4.6.
|
| - ancestor = calculateParents(ancestor, context, ancestors); // 3.4.7.
|
| - }
|
| - if (isShadowRoot(target)) // 3.5.
|
| - target = scope.getHostForShadowRoot(target);
|
| - else
|
| - target = target.parentNode; // 3.6.
|
| - }
|
| - }
|
| -
|
| - function getInsertionParent(node) {
|
| - return scope.insertionParentTable.get(node);
|
| - }
|
| -
|
| - function isDistributed(node) {
|
| - return getInsertionParent(node);
|
| - }
|
| -
|
| - function rootOfNode(node) {
|
| - var p;
|
| - while (p = node.parentNode) {
|
| - node = p;
|
| - }
|
| - return node;
|
| - }
|
| -
|
| - function inSameTree(a, b) {
|
| - return rootOfNode(a) === rootOfNode(b);
|
| - }
|
| -
|
| - function enclosedBy(a, b) {
|
| - if (a === b)
|
| - return true;
|
| - if (a instanceof wrappers.ShadowRoot) {
|
| - var host = scope.getHostForShadowRoot(a);
|
| - return enclosedBy(rootOfNode(host), b);
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - 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;
|
| - }
|
| -
|
| - function dispatchOriginalEvent(originalEvent) {
|
| - // Make sure this event is only dispatched once.
|
| - if (handledEventsTable.get(originalEvent))
|
| - return;
|
| - handledEventsTable.set(originalEvent, true);
|
| -
|
| - // Don't do rendering if this is a mutation event since rendering might
|
| - // mutate the DOM which would fire more events and we would most likely
|
| - // just iloop.
|
| - if (!isMutationEvent(originalEvent.type))
|
| - scope.renderAllPending();
|
| -
|
| - var target = wrap(originalEvent.target);
|
| - var event = wrap(originalEvent);
|
| - return dispatchEvent(event, target);
|
| - }
|
| -
|
| - function dispatchEvent(event, originalWrapperTarget) {
|
| - var eventPath = retarget(originalWrapperTarget);
|
| -
|
| - // For window load events the load event is dispatched at the window but
|
| - // the target is set to the document.
|
| - //
|
| - // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
|
| - //
|
| - // TODO(arv): Find a less hacky way to do this.
|
| - if (event.type === 'load' &&
|
| - eventPath.length === 2 &&
|
| - eventPath[0].target instanceof wrappers.Document) {
|
| - eventPath.shift();
|
| - }
|
| -
|
| - eventPathTable.set(event, eventPath);
|
| -
|
| - if (dispatchCapturing(event, eventPath)) {
|
| - if (dispatchAtTarget(event, eventPath)) {
|
| - dispatchBubbling(event, eventPath);
|
| - }
|
| - }
|
| -
|
| - eventPhaseTable.set(event, Event.NONE);
|
| - currentTargetTable.set(event, null);
|
| -
|
| - return event.defaultPrevented;
|
| - }
|
| -
|
| - function dispatchCapturing(event, eventPath) {
|
| - var phase;
|
| -
|
| - for (var i = eventPath.length - 1; i > 0; i--) {
|
| - var target = eventPath[i].target;
|
| - var currentTarget = eventPath[i].currentTarget;
|
| - if (target === currentTarget)
|
| - continue;
|
| -
|
| - phase = Event.CAPTURING_PHASE;
|
| - if (!invoke(eventPath[i], event, phase))
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| - }
|
| -
|
| - function dispatchAtTarget(event, eventPath) {
|
| - var phase = Event.AT_TARGET;
|
| - return invoke(eventPath[0], event, phase);
|
| - }
|
| -
|
| - function dispatchBubbling(event, eventPath) {
|
| - var bubbles = event.bubbles;
|
| - var phase;
|
| -
|
| - for (var i = 1; i < eventPath.length; i++) {
|
| - var target = eventPath[i].target;
|
| - var currentTarget = eventPath[i].currentTarget;
|
| - if (target === currentTarget)
|
| - phase = Event.AT_TARGET;
|
| - else if (bubbles && !stopImmediatePropagationTable.get(event))
|
| - phase = Event.BUBBLING_PHASE;
|
| - else
|
| - continue;
|
| -
|
| - if (!invoke(eventPath[i], event, phase))
|
| - return;
|
| - }
|
| - }
|
| -
|
| - function invoke(tuple, event, phase) {
|
| - var target = tuple.target;
|
| - var currentTarget = tuple.currentTarget;
|
| -
|
| - var listeners = listenersTable.get(currentTarget);
|
| - if (!listeners)
|
| - return true;
|
| -
|
| - if ('relatedTarget' in event) {
|
| - var originalEvent = unwrap(event);
|
| - var relatedTarget = wrap(originalEvent.relatedTarget);
|
| -
|
| - var adjusted = adjustRelatedTarget(currentTarget, relatedTarget);
|
| - if (adjusted === target)
|
| - return true;
|
| -
|
| - relatedTargetTable.set(event, adjusted);
|
| - }
|
| -
|
| - eventPhaseTable.set(event, phase);
|
| - var type = event.type;
|
| -
|
| - var anyRemoved = false;
|
| - targetTable.set(event, target);
|
| - currentTargetTable.set(event, currentTarget);
|
| -
|
| - for (var i = 0; i < listeners.length; i++) {
|
| - var listener = listeners[i];
|
| - if (listener.removed) {
|
| - anyRemoved = true;
|
| - continue;
|
| - }
|
| -
|
| - if (listener.type !== type ||
|
| - !listener.capture && phase === Event.CAPTURING_PHASE ||
|
| - listener.capture && phase === Event.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 (window.onerror)
|
| - window.onerror(ex.message);
|
| - else
|
| - console.error(ex);
|
| - }
|
| - }
|
| -
|
| - if (anyRemoved) {
|
| - 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;
|
| -
|
| - /**
|
| - * Creates a new Event wrapper or wraps an existin native Event object.
|
| - * @param {string|Event} type
|
| - * @param {Object=} options
|
| - * @constructor
|
| - */
|
| - function Event(type, options) {
|
| - if (type instanceof OriginalEvent)
|
| - this.impl = type;
|
| - 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 nodeList = new wrappers.NodeList();
|
| - var eventPath = eventPathTable.get(this);
|
| - if (eventPath) {
|
| - var index = 0;
|
| - var lastIndex = eventPath.length - 1;
|
| - var baseRoot = rootOfNode(currentTargetTable.get(this));
|
| -
|
| - for (var i = 0; i <= lastIndex; i++) {
|
| - var currentTarget = eventPath[i].currentTarget;
|
| - var currentRoot = rootOfNode(currentTarget);
|
| - if (enclosedBy(baseRoot, currentRoot) &&
|
| - // Make sure we do not add Window to the path.
|
| - (i !== lastIndex || currentTarget instanceof wrappers.Node)) {
|
| - nodeList[index++] = currentTarget;
|
| - }
|
| - }
|
| - nodeList.length = index;
|
| - }
|
| - return nodeList;
|
| - },
|
| - 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)
|
| - this.impl = type;
|
| - else
|
| - return wrap(constructEvent(OriginalEvent, name, type, options));
|
| - };
|
| - GenericEvent.prototype = Object.create(SuperEvent.prototype);
|
| - if (prototype)
|
| - mixin(GenericEvent.prototype, prototype);
|
| - if (OriginalEvent) {
|
| - // IE does not support event constructors but FocusEvent can only be
|
| - // created using new FocusEvent in Firefox.
|
| - // https://bugzilla.mozilla.org/show_bug.cgi?id=882165
|
| - if (OriginalEvent.prototype['init' + name]) {
|
| - registerWrapper(OriginalEvent, GenericEvent,
|
| - document.createEvent(name));
|
| - } else {
|
| - registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
|
| - }
|
| - }
|
| - return GenericEvent;
|
| - }
|
| -
|
| - var UIEvent = registerGenericEvent('UIEvent', Event);
|
| - var CustomEvent = registerGenericEvent('CustomEvent', Event);
|
| -
|
| - var relatedTargetProto = {
|
| - get relatedTarget() {
|
| - return relatedTargetTable.get(this) || 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 MutationEvent = registerGenericEvent('MutationEvent', Event, {
|
| - initMutationEvent: getInitFunction('initMutationEvent', 3),
|
| - get relatedNode() {
|
| - return wrap(this.impl.relatedNode);
|
| - },
|
| - });
|
| -
|
| - // In case the browser does not support event constructors we polyfill that
|
| - // by calling `createEvent('Foo')` and `initFooEvent` where the arguments to
|
| - // `initFooEvent` are derived from the registered default event init dict.
|
| - var defaultInitDicts = Object.create(null);
|
| -
|
| - var supportsEventConstructors = (function() {
|
| - try {
|
| - new window.MouseEvent('click');
|
| - } catch (ex) {
|
| - return false;
|
| - }
|
| - return true;
|
| - })();
|
| -
|
| - /**
|
| - * Constructs a new native event.
|
| - */
|
| - function constructEvent(OriginalEvent, name, type, options) {
|
| - if (supportsEventConstructors)
|
| - return new OriginalEvent(type, unwrapOptions(options));
|
| -
|
| - // Create the arguments from the default dictionary.
|
| - 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;
|
| - };
|
| -
|
| - // The order of the default event init dictionary keys is important, the
|
| - // arguments to initFooEvent is derived from that.
|
| - 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');
|
| - }
|
| -
|
| - function isValidListener(fun) {
|
| - if (typeof fun === 'function')
|
| - return true;
|
| - return fun && fun.handleEvent;
|
| - }
|
| -
|
| - var OriginalEventTarget = window.EventTarget;
|
| -
|
| - /**
|
| - * This represents a wrapper for an EventTarget.
|
| - * @param {!EventTarget} impl The original event target.
|
| - * @constructor
|
| - */
|
| - function EventTarget(impl) {
|
| - this.impl = impl;
|
| - }
|
| -
|
| - // Node and Window have different internal type checks in WebKit so we cannot
|
| - // use the same method as the original function.
|
| - 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 = scope.getHostForShadowRoot(wrapper);
|
| - return unwrap(wrapper);
|
| - }
|
| -
|
| - EventTarget.prototype = {
|
| - addEventListener: function(type, fun, capture) {
|
| - if (!isValidListener(fun))
|
| - return;
|
| -
|
| - var listener = new Listener(type, fun, capture);
|
| - var listeners = listenersTable.get(this);
|
| - if (!listeners) {
|
| - listeners = [];
|
| - listenersTable.set(this, listeners);
|
| - } else {
|
| - // Might have a duplicate.
|
| - 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 target = getTargetToListenAt(this);
|
| - return target.dispatchEvent_(unwrap(event));
|
| - }
|
| - };
|
| -
|
| - if (OriginalEventTarget)
|
| - registerWrapper(OriginalEventTarget, EventTarget);
|
| -
|
| - function wrapEventTargetMethods(constructors) {
|
| - forwardMethodsToWrapper(constructors, methodNames);
|
| - }
|
| -
|
| -
|
| - var originalElementFromPoint = document.elementFromPoint;
|
| -
|
| - function elementFromPoint(self, document, x, y) {
|
| - scope.renderAllPending();
|
| -
|
| - var element = wrap(originalElementFromPoint.call(document.impl, x, y));
|
| - var targets = retarget(element, this)
|
| - for (var i = 0; i < targets.length; i++) {
|
| - var target = targets[i];
|
| - if (target.currentTarget === self)
|
| - return target.target;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| - * Returns a function that is to be used as a getter for `onfoo` properties.
|
| - * @param {string} name
|
| - * @return {Function}
|
| - */
|
| - function getEventHandlerGetter(name) {
|
| - return function() {
|
| - var inlineEventHandlers = eventHandlersTable.get(this);
|
| - return inlineEventHandlers && inlineEventHandlers[name] &&
|
| - inlineEventHandlers[name].value || null;
|
| - };
|
| - }
|
| -
|
| - /**
|
| - * Returns a function that is to be used as a setter for `onfoo` properties.
|
| - * @param {string} name
|
| - * @return {Function}
|
| - */
|
| - function getEventHandlerSetter(name) {
|
| - var eventType = name.slice(2);
|
| - return function(value) {
|
| - var inlineEventHandlers = eventHandlersTable.get(this);
|
| - if (!inlineEventHandlers) {
|
| - inlineEventHandlers = Object.create(null);
|
| - eventHandlersTable.set(this, inlineEventHandlers);
|
| - }
|
| -
|
| - var old = inlineEventHandlers[name];
|
| - if (old)
|
| - this.removeEventListener(eventType, old.wrapped, false);
|
| -
|
| - if (typeof value === 'function') {
|
| - var wrapped = function(e) {
|
| - var rv = value.call(this, e);
|
| - if (rv === false)
|
| - e.preventDefault();
|
| - else if (name === 'onbeforeunload' && typeof rv === 'string')
|
| - e.returnValue = rv;
|
| - // mouseover uses true for preventDefault but preventDefault for
|
| - // mouseover is ignored by browsers these day.
|
| - };
|
| -
|
| - this.addEventListener(eventType, wrapped, false);
|
| - inlineEventHandlers[name] = {
|
| - value: value,
|
| - wrapped: wrapped
|
| - };
|
| - }
|
| - };
|
| - }
|
| -
|
| - scope.adjustRelatedTarget = adjustRelatedTarget;
|
| - scope.elementFromPoint = elementFromPoint;
|
| - scope.getEventHandlerGetter = getEventHandlerGetter;
|
| - scope.getEventHandlerSetter = getEventHandlerSetter;
|
| - scope.wrapEventTargetMethods = wrapEventTargetMethods;
|
| - scope.wrappers.CustomEvent = CustomEvent;
|
| - scope.wrappers.Event = Event;
|
| - scope.wrappers.EventTarget = EventTarget;
|
| - scope.wrappers.FocusEvent = FocusEvent;
|
| - scope.wrappers.MouseEvent = MouseEvent;
|
| - scope.wrappers.MutationEvent = MutationEvent;
|
| - scope.wrappers.UIEvent = UIEvent;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2012 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var wrap = scope.wrap;
|
| -
|
| - function nonEnum(obj, prop) {
|
| - Object.defineProperty(obj, prop, {enumerable: false});
|
| - }
|
| -
|
| - function NodeList() {
|
| - this.length = 0;
|
| - nonEnum(this, 'length');
|
| - }
|
| - NodeList.prototype = {
|
| - item: function(index) {
|
| - return this[index];
|
| - }
|
| - };
|
| - nonEnum(NodeList.prototype, 'item');
|
| -
|
| - function wrapNodeList(list) {
|
| - if (list == null)
|
| - return list;
|
| - var wrapperList = new NodeList();
|
| - for (var i = 0, length = list.length; i < length; i++) {
|
| - wrapperList[i] = wrap(list[i]);
|
| - }
|
| - wrapperList.length = length;
|
| - return wrapperList;
|
| - }
|
| -
|
| - function addWrapNodeListMethod(wrapperConstructor, name) {
|
| - wrapperConstructor.prototype[name] = function() {
|
| - return wrapNodeList(this.impl[name].apply(this.impl, arguments));
|
| - };
|
| - }
|
| -
|
| - scope.wrappers.NodeList = NodeList;
|
| - scope.addWrapNodeListMethod = addWrapNodeListMethod;
|
| - scope.wrapNodeList = wrapNodeList;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2012 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var EventTarget = scope.wrappers.EventTarget;
|
| - var NodeList = scope.wrappers.NodeList;
|
| - var defineWrapGetter = scope.defineWrapGetter;
|
| - var assert = scope.assert;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrap = scope.unwrap;
|
| - var wrap = scope.wrap;
|
| - var wrapIfNeeded = scope.wrapIfNeeded;
|
| -
|
| - function assertIsNodeWrapper(node) {
|
| - assert(node instanceof Node);
|
| - }
|
| -
|
| - /**
|
| - * Collects nodes from a DocumentFragment or a Node for removal followed
|
| - * by an insertion.
|
| - *
|
| - * This updates the internal pointers for node, previousNode and nextNode.
|
| - */
|
| - function collectNodes(node, parentNode, previousNode, nextNode) {
|
| - if (!(node instanceof DocumentFragment)) {
|
| - if (node.parentNode)
|
| - node.parentNode.removeChild(node);
|
| - node.parentNode_ = parentNode;
|
| - node.previousSibling_ = previousNode;
|
| - node.nextSibling_ = nextNode;
|
| - if (previousNode)
|
| - previousNode.nextSibling_ = node;
|
| - if (nextNode)
|
| - nextNode.previousSibling_ = node;
|
| - return [node];
|
| - }
|
| -
|
| - var nodes = [];
|
| - var firstChild;
|
| - while (firstChild = node.firstChild) {
|
| - node.removeChild(firstChild);
|
| - nodes.push(firstChild);
|
| - firstChild.parentNode_ = parentNode;
|
| - }
|
| -
|
| - for (var i = 0; i < nodes.length; i++) {
|
| - nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
|
| - nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
|
| - }
|
| -
|
| - if (previousNode)
|
| - previousNode.nextSibling_ = nodes[0];
|
| - if (nextNode)
|
| - nextNode.previousSibling_ = nodes[nodes.length - 1];
|
| -
|
| - return nodes;
|
| - }
|
| -
|
| - function collectNodesNoNeedToUpdatePointers(node) {
|
| - if (node instanceof DocumentFragment) {
|
| - var nodes = [];
|
| - var i = 0;
|
| - for (var child = node.firstChild; child; child = child.nextSibling) {
|
| - nodes[i++] = child;
|
| - }
|
| - return nodes;
|
| - }
|
| - return [node];
|
| - }
|
| -
|
| - function nodesWereAdded(nodes) {
|
| - for (var i = 0; i < nodes.length; i++) {
|
| - nodes[i].nodeWasAdded_();
|
| - }
|
| - }
|
| -
|
| - function ensureSameOwnerDocument(parent, child) {
|
| - var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ?
|
| - parent : parent.ownerDocument;
|
| - if (ownerDoc !== child.ownerDocument)
|
| - ownerDoc.adoptNode(child);
|
| - }
|
| -
|
| - function adoptNodesIfNeeded(owner, nodes) {
|
| - if (!nodes.length)
|
| - return;
|
| -
|
| - var ownerDoc = owner.ownerDocument;
|
| -
|
| - // All nodes have the same ownerDocument when we get here.
|
| - if (ownerDoc === nodes[0].ownerDocument)
|
| - return;
|
| -
|
| - for (var i = 0; i < nodes.length; i++) {
|
| - scope.adoptNodeNoRemove(nodes[i], ownerDoc);
|
| - }
|
| - }
|
| -
|
| - function unwrapNodesForInsertion(owner, nodes) {
|
| - adoptNodesIfNeeded(owner, nodes);
|
| - var length = nodes.length;
|
| -
|
| - if (length === 1)
|
| - return unwrap(nodes[0]);
|
| -
|
| - var df = unwrap(owner.ownerDocument.createDocumentFragment());
|
| - for (var i = 0; i < length; i++) {
|
| - df.appendChild(unwrap(nodes[i]));
|
| - }
|
| - return df;
|
| - }
|
| -
|
| - function removeAllChildNodes(wrapper) {
|
| - if (wrapper.invalidateShadowRenderer()) {
|
| - var childWrapper = wrapper.firstChild;
|
| - while (childWrapper) {
|
| - assert(childWrapper.parentNode === wrapper);
|
| - var nextSibling = childWrapper.nextSibling;
|
| - var childNode = unwrap(childWrapper);
|
| - var parentNode = childNode.parentNode;
|
| - if (parentNode)
|
| - originalRemoveChild.call(parentNode, childNode);
|
| - childWrapper.previousSibling_ = childWrapper.nextSibling_ =
|
| - childWrapper.parentNode_ = null;
|
| - childWrapper = nextSibling;
|
| - }
|
| - wrapper.firstChild_ = wrapper.lastChild_ = null;
|
| - } else {
|
| - var node = unwrap(wrapper);
|
| - var child = node.firstChild;
|
| - var nextSibling;
|
| - while (child) {
|
| - nextSibling = child.nextSibling;
|
| - originalRemoveChild.call(node, child);
|
| - child = nextSibling;
|
| - }
|
| - }
|
| - }
|
| -
|
| - function invalidateParent(node) {
|
| - var p = node.parentNode;
|
| - return p && p.invalidateShadowRenderer();
|
| - }
|
| -
|
| - var OriginalNode = window.Node;
|
| -
|
| - /**
|
| - * This represents a wrapper of a native DOM node.
|
| - * @param {!Node} original The original DOM node, aka, the visual DOM node.
|
| - * @constructor
|
| - * @extends {EventTarget}
|
| - */
|
| - function Node(original) {
|
| - assert(original instanceof OriginalNode);
|
| -
|
| - EventTarget.call(this, original);
|
| -
|
| - // These properties are used to override the visual references with the
|
| - // logical ones. If the value is undefined it means that the logical is the
|
| - // same as the visual.
|
| -
|
| - /**
|
| - * @type {Node|undefined}
|
| - * @private
|
| - */
|
| - this.parentNode_ = undefined;
|
| -
|
| - /**
|
| - * @type {Node|undefined}
|
| - * @private
|
| - */
|
| - this.firstChild_ = undefined;
|
| -
|
| - /**
|
| - * @type {Node|undefined}
|
| - * @private
|
| - */
|
| - this.lastChild_ = undefined;
|
| -
|
| - /**
|
| - * @type {Node|undefined}
|
| - * @private
|
| - */
|
| - this.nextSibling_ = undefined;
|
| -
|
| - /**
|
| - * @type {Node|undefined}
|
| - * @private
|
| - */
|
| - this.previousSibling_ = undefined;
|
| - };
|
| -
|
| - var originalAppendChild = OriginalNode.prototype.appendChild;
|
| - var originalInsertBefore = OriginalNode.prototype.insertBefore;
|
| - var originalReplaceChild = OriginalNode.prototype.replaceChild;
|
| - var originalRemoveChild = OriginalNode.prototype.removeChild;
|
| - var originalCompareDocumentPosition =
|
| - OriginalNode.prototype.compareDocumentPosition;
|
| -
|
| - Node.prototype = Object.create(EventTarget.prototype);
|
| - mixin(Node.prototype, {
|
| - appendChild: function(childWrapper) {
|
| - assertIsNodeWrapper(childWrapper);
|
| -
|
| - var nodes;
|
| -
|
| - if (this.invalidateShadowRenderer() || invalidateParent(childWrapper)) {
|
| - var previousNode = this.lastChild;
|
| - var nextNode = null;
|
| - nodes = collectNodes(childWrapper, this, previousNode, nextNode);
|
| -
|
| - this.lastChild_ = nodes[nodes.length - 1];
|
| - if (!previousNode)
|
| - this.firstChild_ = nodes[0];
|
| -
|
| - originalAppendChild.call(this.impl, unwrapNodesForInsertion(this, nodes));
|
| - } else {
|
| - nodes = collectNodesNoNeedToUpdatePointers(childWrapper)
|
| - ensureSameOwnerDocument(this, childWrapper);
|
| - originalAppendChild.call(this.impl, unwrap(childWrapper));
|
| - }
|
| -
|
| - nodesWereAdded(nodes);
|
| -
|
| - return childWrapper;
|
| - },
|
| -
|
| - insertBefore: function(childWrapper, refWrapper) {
|
| - // TODO(arv): Unify with appendChild
|
| - if (!refWrapper)
|
| - return this.appendChild(childWrapper);
|
| -
|
| - assertIsNodeWrapper(childWrapper);
|
| - assertIsNodeWrapper(refWrapper);
|
| - assert(refWrapper.parentNode === this);
|
| -
|
| - var nodes;
|
| -
|
| - if (this.invalidateShadowRenderer() || invalidateParent(childWrapper)) {
|
| - var previousNode = refWrapper.previousSibling;
|
| - var nextNode = refWrapper;
|
| - nodes = collectNodes(childWrapper, this, previousNode, nextNode);
|
| -
|
| - if (this.firstChild === refWrapper)
|
| - this.firstChild_ = nodes[0];
|
| -
|
| - // insertBefore refWrapper no matter what the parent is?
|
| - var refNode = unwrap(refWrapper);
|
| - var parentNode = refNode.parentNode;
|
| -
|
| - if (parentNode) {
|
| - originalInsertBefore.call(
|
| - parentNode,
|
| - unwrapNodesForInsertion(this, nodes),
|
| - refNode);
|
| - } else {
|
| - adoptNodesIfNeeded(this, nodes);
|
| - }
|
| - } else {
|
| - nodes = collectNodesNoNeedToUpdatePointers(childWrapper);
|
| - ensureSameOwnerDocument(this, childWrapper);
|
| - originalInsertBefore.call(this.impl, unwrap(childWrapper),
|
| - unwrap(refWrapper));
|
| - }
|
| -
|
| - nodesWereAdded(nodes);
|
| -
|
| - return childWrapper;
|
| - },
|
| -
|
| - removeChild: function(childWrapper) {
|
| - assertIsNodeWrapper(childWrapper);
|
| - if (childWrapper.parentNode !== this) {
|
| - // TODO(arv): DOMException
|
| - throw new Error('NotFoundError');
|
| - }
|
| -
|
| - var childNode = unwrap(childWrapper);
|
| - if (this.invalidateShadowRenderer()) {
|
| -
|
| - // We need to remove the real node from the DOM before updating the
|
| - // pointers. This is so that that mutation event is dispatched before
|
| - // the pointers have changed.
|
| - var thisFirstChild = this.firstChild;
|
| - var thisLastChild = this.lastChild;
|
| - var childWrapperNextSibling = childWrapper.nextSibling;
|
| - var childWrapperPreviousSibling = childWrapper.previousSibling;
|
| -
|
| - var parentNode = childNode.parentNode;
|
| - if (parentNode)
|
| - originalRemoveChild.call(parentNode, childNode);
|
| -
|
| - if (thisFirstChild === childWrapper)
|
| - this.firstChild_ = childWrapperNextSibling;
|
| - if (thisLastChild === childWrapper)
|
| - this.lastChild_ = childWrapperPreviousSibling;
|
| - if (childWrapperPreviousSibling)
|
| - childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
|
| - if (childWrapperNextSibling) {
|
| - childWrapperNextSibling.previousSibling_ =
|
| - childWrapperPreviousSibling;
|
| - }
|
| -
|
| - childWrapper.previousSibling_ = childWrapper.nextSibling_ =
|
| - childWrapper.parentNode_ = undefined;
|
| - } else {
|
| - originalRemoveChild.call(this.impl, childNode);
|
| - }
|
| -
|
| - return childWrapper;
|
| - },
|
| -
|
| - replaceChild: function(newChildWrapper, oldChildWrapper) {
|
| - assertIsNodeWrapper(newChildWrapper);
|
| - assertIsNodeWrapper(oldChildWrapper);
|
| -
|
| - if (oldChildWrapper.parentNode !== this) {
|
| - // TODO(arv): DOMException
|
| - throw new Error('NotFoundError');
|
| - }
|
| -
|
| - var oldChildNode = unwrap(oldChildWrapper);
|
| - var nodes;
|
| -
|
| - if (this.invalidateShadowRenderer() ||
|
| - invalidateParent(newChildWrapper)) {
|
| - var previousNode = oldChildWrapper.previousSibling;
|
| - var nextNode = oldChildWrapper.nextSibling;
|
| - if (nextNode === newChildWrapper)
|
| - nextNode = newChildWrapper.nextSibling;
|
| - nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
|
| -
|
| - if (this.firstChild === oldChildWrapper)
|
| - this.firstChild_ = nodes[0];
|
| - if (this.lastChild === oldChildWrapper)
|
| - this.lastChild_ = nodes[nodes.length - 1];
|
| -
|
| - oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ =
|
| - oldChildWrapper.parentNode_ = undefined;
|
| -
|
| - // replaceChild no matter what the parent is?
|
| - if (oldChildNode.parentNode) {
|
| - originalReplaceChild.call(
|
| - oldChildNode.parentNode,
|
| - unwrapNodesForInsertion(this, nodes),
|
| - oldChildNode);
|
| - }
|
| - } else {
|
| - nodes = collectNodesNoNeedToUpdatePointers(newChildWrapper);
|
| - ensureSameOwnerDocument(this, newChildWrapper);
|
| - originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
|
| - oldChildNode);
|
| - }
|
| -
|
| - nodesWereAdded(nodes);
|
| -
|
| - return oldChildWrapper;
|
| - },
|
| -
|
| - /**
|
| - * Called after a node was added. Subclasses override this to invalidate
|
| - * the renderer as needed.
|
| - * @private
|
| - */
|
| - nodeWasAdded_: function() {
|
| - for (var child = this.firstChild; child; child = child.nextSibling) {
|
| - child.nodeWasAdded_();
|
| - }
|
| - },
|
| -
|
| - hasChildNodes: function() {
|
| - return this.firstChild === null;
|
| - },
|
| -
|
| - /** @type {Node} */
|
| - get parentNode() {
|
| - // If the parentNode has not been overridden, use the original parentNode.
|
| - return this.parentNode_ !== undefined ?
|
| - this.parentNode_ : wrap(this.impl.parentNode);
|
| - },
|
| -
|
| - /** @type {Node} */
|
| - get firstChild() {
|
| - return this.firstChild_ !== undefined ?
|
| - this.firstChild_ : wrap(this.impl.firstChild);
|
| - },
|
| -
|
| - /** @type {Node} */
|
| - get lastChild() {
|
| - return this.lastChild_ !== undefined ?
|
| - this.lastChild_ : wrap(this.impl.lastChild);
|
| - },
|
| -
|
| - /** @type {Node} */
|
| - get nextSibling() {
|
| - return this.nextSibling_ !== undefined ?
|
| - this.nextSibling_ : wrap(this.impl.nextSibling);
|
| - },
|
| -
|
| - /** @type {Node} */
|
| - get previousSibling() {
|
| - return this.previousSibling_ !== undefined ?
|
| - this.previousSibling_ : wrap(this.impl.previousSibling);
|
| - },
|
| -
|
| - get parentElement() {
|
| - var p = this.parentNode;
|
| - while (p && p.nodeType !== Node.ELEMENT_NODE) {
|
| - p = p.parentNode;
|
| - }
|
| - return p;
|
| - },
|
| -
|
| - get textContent() {
|
| - // TODO(arv): This should fallback to this.impl.textContent if there
|
| - // are no shadow trees below or above the context node.
|
| - var s = '';
|
| - for (var child = this.firstChild; child; child = child.nextSibling) {
|
| - s += child.textContent;
|
| - }
|
| - return s;
|
| - },
|
| - set textContent(textContent) {
|
| - if (this.invalidateShadowRenderer()) {
|
| - removeAllChildNodes(this);
|
| - if (textContent !== '') {
|
| - var textNode = this.impl.ownerDocument.createTextNode(textContent);
|
| - this.appendChild(textNode);
|
| - }
|
| - } else {
|
| - this.impl.textContent = textContent;
|
| - }
|
| - },
|
| -
|
| - get childNodes() {
|
| - var wrapperList = new NodeList();
|
| - var i = 0;
|
| - for (var child = this.firstChild; child; child = child.nextSibling) {
|
| - wrapperList[i++] = child;
|
| - }
|
| - wrapperList.length = i;
|
| - return wrapperList;
|
| - },
|
| -
|
| - cloneNode: function(deep) {
|
| - if (!this.invalidateShadowRenderer())
|
| - return wrap(this.impl.cloneNode(deep));
|
| -
|
| - var clone = wrap(this.impl.cloneNode(false));
|
| - if (deep) {
|
| - for (var child = this.firstChild; child; child = child.nextSibling) {
|
| - clone.appendChild(child.cloneNode(true));
|
| - }
|
| - }
|
| - // TODO(arv): Some HTML elements also clone other data like value.
|
| - return clone;
|
| - },
|
| -
|
| - contains: function(child) {
|
| - if (!child)
|
| - return false;
|
| -
|
| - child = wrapIfNeeded(child);
|
| -
|
| - // TODO(arv): Optimize using ownerDocument etc.
|
| - if (child === this)
|
| - return true;
|
| - var parentNode = child.parentNode;
|
| - if (!parentNode)
|
| - return false;
|
| - return this.contains(parentNode);
|
| - },
|
| -
|
| - compareDocumentPosition: function(otherNode) {
|
| - // This only wraps, it therefore only operates on the composed DOM and not
|
| - // the logical DOM.
|
| - return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));
|
| - }
|
| - });
|
| -
|
| - defineWrapGetter(Node, 'ownerDocument');
|
| -
|
| - // We use a DocumentFragment as a base and then delete the properties of
|
| - // DocumentFragment.prototype from the wrapper Node. Since delete makes
|
| - // objects slow in some JS engines we recreate the prototype object.
|
| - registerWrapper(OriginalNode, Node, document.createDocumentFragment());
|
| - delete Node.prototype.querySelector;
|
| - delete Node.prototype.querySelectorAll;
|
| - Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
|
| -
|
| - scope.wrappers.Node = Node;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - function findOne(node, selector) {
|
| - var m, el = node.firstElementChild;
|
| - while (el) {
|
| - if (el.matches(selector))
|
| - return el;
|
| - m = findOne(el, selector);
|
| - if (m)
|
| - return m;
|
| - el = el.nextElementSibling;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - function findAll(node, selector, results) {
|
| - var el = node.firstElementChild;
|
| - while (el) {
|
| - if (el.matches(selector))
|
| - results[results.length++] = el;
|
| - findAll(el, selector, results);
|
| - el = el.nextElementSibling;
|
| - }
|
| - return results;
|
| - }
|
| -
|
| - // find and findAll will only match Simple Selectors,
|
| - // Structural Pseudo Classes are not guarenteed to be correct
|
| - // http://www.w3.org/TR/css3-selectors/#simple-selectors
|
| -
|
| - var SelectorsInterface = {
|
| - querySelector: function(selector) {
|
| - return findOne(this, selector);
|
| - },
|
| - querySelectorAll: function(selector) {
|
| - return findAll(this, selector, new NodeList())
|
| - }
|
| - };
|
| -
|
| - var GetElementsByInterface = {
|
| - getElementsByTagName: function(tagName) {
|
| - // TODO(arv): Check tagName?
|
| - return this.querySelectorAll(tagName);
|
| - },
|
| - getElementsByClassName: function(className) {
|
| - // TODO(arv): Check className?
|
| - return this.querySelectorAll('.' + className);
|
| - },
|
| - getElementsByTagNameNS: function(ns, tagName) {
|
| - if (ns === '*')
|
| - return this.getElementsByTagName(tagName);
|
| -
|
| - // TODO(arv): Check tagName?
|
| - var result = new NodeList;
|
| - var els = this.getElementsByTagName(tagName);
|
| - for (var i = 0, j = 0; i < els.length; i++) {
|
| - if (els[i].namespaceURI === ns)
|
| - result[j++] = els[i];
|
| - }
|
| - result.length = j;
|
| - return result;
|
| - }
|
| - };
|
| -
|
| - scope.GetElementsByInterface = GetElementsByInterface;
|
| - scope.SelectorsInterface = SelectorsInterface;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var NodeList = scope.wrappers.NodeList;
|
| -
|
| - function forwardElement(node) {
|
| - while (node && node.nodeType !== Node.ELEMENT_NODE) {
|
| - node = node.nextSibling;
|
| - }
|
| - return node;
|
| - }
|
| -
|
| - function backwardsElement(node) {
|
| - while (node && node.nodeType !== Node.ELEMENT_NODE) {
|
| - node = node.previousSibling;
|
| - }
|
| - return node;
|
| - }
|
| -
|
| - var ParentNodeInterface = {
|
| - get firstElementChild() {
|
| - return forwardElement(this.firstChild);
|
| - },
|
| -
|
| - get lastElementChild() {
|
| - return backwardsElement(this.lastChild);
|
| - },
|
| -
|
| - get childElementCount() {
|
| - var count = 0;
|
| - for (var child = this.firstElementChild;
|
| - child;
|
| - child = child.nextElementSibling) {
|
| - count++;
|
| - }
|
| - return count;
|
| - },
|
| -
|
| - get children() {
|
| - var wrapperList = new NodeList();
|
| - var i = 0;
|
| - for (var child = this.firstElementChild;
|
| - child;
|
| - child = child.nextElementSibling) {
|
| - wrapperList[i++] = child;
|
| - }
|
| - wrapperList.length = i;
|
| - return wrapperList;
|
| - }
|
| - };
|
| -
|
| - var ChildNodeInterface = {
|
| - get nextElementSibling() {
|
| - return forwardElement(this.nextSibling);
|
| - },
|
| -
|
| - get previousElementSibling() {
|
| - return backwardsElement(this.previousSibling);
|
| - }
|
| - };
|
| -
|
| - scope.ChildNodeInterface = ChildNodeInterface;
|
| - scope.ParentNodeInterface = ParentNodeInterface;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var ChildNodeInterface = scope.ChildNodeInterface;
|
| - var Node = scope.wrappers.Node;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| -
|
| - var OriginalCharacterData = window.CharacterData;
|
| -
|
| - function CharacterData(node) {
|
| - Node.call(this, node);
|
| - }
|
| - CharacterData.prototype = Object.create(Node.prototype);
|
| - mixin(CharacterData.prototype, {
|
| - get textContent() {
|
| - return this.data;
|
| - },
|
| - set textContent(value) {
|
| - this.data = value;
|
| - }
|
| - });
|
| -
|
| - mixin(CharacterData.prototype, ChildNodeInterface);
|
| -
|
| - registerWrapper(OriginalCharacterData, CharacterData,
|
| - document.createTextNode(''));
|
| -
|
| - scope.wrappers.CharacterData = CharacterData;
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var ChildNodeInterface = scope.ChildNodeInterface;
|
| - var GetElementsByInterface = scope.GetElementsByInterface;
|
| - var Node = scope.wrappers.Node;
|
| - var ParentNodeInterface = scope.ParentNodeInterface;
|
| - var SelectorsInterface = scope.SelectorsInterface;
|
| - var addWrapNodeListMethod = scope.addWrapNodeListMethod;
|
| - var mixin = scope.mixin;
|
| - var oneOf = scope.oneOf;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var wrappers = scope.wrappers;
|
| -
|
| - var OriginalElement = window.Element;
|
| -
|
| - var matchesName = oneOf(OriginalElement.prototype, [
|
| - 'matches',
|
| - 'mozMatchesSelector',
|
| - 'msMatchesSelector',
|
| - 'webkitMatchesSelector',
|
| - ]);
|
| -
|
| - var originalMatches = OriginalElement.prototype[matchesName];
|
| -
|
| - function invalidateRendererBasedOnAttribute(element, name) {
|
| - // Only invalidate if parent node is a shadow host.
|
| - var p = element.parentNode;
|
| - if (!p || !p.shadowRoot)
|
| - return;
|
| -
|
| - var renderer = scope.getRendererForHost(p);
|
| - if (renderer.dependsOnAttribute(name))
|
| - renderer.invalidate();
|
| - }
|
| -
|
| - function Element(node) {
|
| - Node.call(this, node);
|
| - }
|
| - Element.prototype = Object.create(Node.prototype);
|
| - mixin(Element.prototype, {
|
| - createShadowRoot: function() {
|
| - var newShadowRoot = new wrappers.ShadowRoot(this);
|
| - this.impl.polymerShadowRoot_ = newShadowRoot;
|
| -
|
| - var renderer = scope.getRendererForHost(this);
|
| - renderer.invalidate();
|
| -
|
| - return newShadowRoot;
|
| - },
|
| -
|
| - get shadowRoot() {
|
| - return this.impl.polymerShadowRoot_ || null;
|
| - },
|
| -
|
| - setAttribute: function(name, value) {
|
| - this.impl.setAttribute(name, value);
|
| - invalidateRendererBasedOnAttribute(this, name);
|
| - },
|
| -
|
| - removeAttribute: function(name) {
|
| - this.impl.removeAttribute(name);
|
| - invalidateRendererBasedOnAttribute(this, name);
|
| - },
|
| -
|
| - matches: function(selector) {
|
| - return originalMatches.call(this.impl, selector);
|
| - }
|
| - });
|
| -
|
| - Element.prototype[matchesName] = function(selector) {
|
| - return this.matches(selector);
|
| - };
|
| -
|
| - if (OriginalElement.prototype.webkitCreateShadowRoot) {
|
| - Element.prototype.webkitCreateShadowRoot =
|
| - Element.prototype.createShadowRoot;
|
| - }
|
| -
|
| - /**
|
| - * Useful for generating the accessor pair for a property that reflects an
|
| - * attribute.
|
| - */
|
| - function setterDirtiesAttribute(prototype, propertyName, opt_attrName) {
|
| - var attrName = opt_attrName || propertyName;
|
| - Object.defineProperty(prototype, propertyName, {
|
| - get: function() {
|
| - return this.impl[propertyName];
|
| - },
|
| - set: function(v) {
|
| - this.impl[propertyName] = v;
|
| - invalidateRendererBasedOnAttribute(this, attrName);
|
| - },
|
| - configurable: true,
|
| - enumerable: true
|
| - });
|
| - }
|
| -
|
| - setterDirtiesAttribute(Element.prototype, 'id');
|
| - setterDirtiesAttribute(Element.prototype, 'className', 'class');
|
| -
|
| - mixin(Element.prototype, ChildNodeInterface);
|
| - mixin(Element.prototype, GetElementsByInterface);
|
| - mixin(Element.prototype, ParentNodeInterface);
|
| - mixin(Element.prototype, SelectorsInterface);
|
| -
|
| - registerWrapper(OriginalElement, Element);
|
| -
|
| - // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings
|
| - // that reflect attributes.
|
| - scope.matchesName = matchesName;
|
| - scope.wrappers.Element = Element;
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var Element = scope.wrappers.Element;
|
| - var defineGetter = scope.defineGetter;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrap = scope.unwrap;
|
| - var wrap = scope.wrap;
|
| -
|
| - /////////////////////////////////////////////////////////////////////////////
|
| - // innerHTML and outerHTML
|
| -
|
| - var escapeRegExp = /&|<|"/g;
|
| -
|
| - function escapeReplace(c) {
|
| - switch (c) {
|
| - case '&':
|
| - return '&';
|
| - case '<':
|
| - return '<';
|
| - case '"':
|
| - return '"'
|
| - }
|
| - }
|
| -
|
| - function escape(s) {
|
| - return s.replace(escapeRegExp, escapeReplace);
|
| - }
|
| -
|
| - // http://www.whatwg.org/specs/web-apps/current-work/#void-elements
|
| - var voidElements = {
|
| - 'area': true,
|
| - 'base': true,
|
| - 'br': true,
|
| - 'col': true,
|
| - 'command': true,
|
| - 'embed': true,
|
| - 'hr': true,
|
| - 'img': true,
|
| - 'input': true,
|
| - 'keygen': true,
|
| - 'link': true,
|
| - 'meta': true,
|
| - 'param': true,
|
| - 'source': true,
|
| - 'track': true,
|
| - 'wbr': true
|
| - };
|
| -
|
| - function getOuterHTML(node) {
|
| - switch (node.nodeType) {
|
| - case Node.ELEMENT_NODE:
|
| - var tagName = node.tagName.toLowerCase();
|
| - var s = '<' + tagName;
|
| - var attrs = node.attributes;
|
| - for (var i = 0, attr; attr = attrs[i]; i++) {
|
| - s += ' ' + attr.name + '="' + escape(attr.value) + '"';
|
| - }
|
| - s += '>';
|
| - if (voidElements[tagName])
|
| - return s;
|
| -
|
| - return s + getInnerHTML(node) + '</' + tagName + '>';
|
| -
|
| - case Node.TEXT_NODE:
|
| - return escape(node.nodeValue);
|
| -
|
| - case Node.COMMENT_NODE:
|
| - return '<!--' + escape(node.nodeValue) + '-->';
|
| - default:
|
| - console.error(node);
|
| - throw new Error('not implemented');
|
| - }
|
| - }
|
| -
|
| - function getInnerHTML(node) {
|
| - var s = '';
|
| - for (var child = node.firstChild; child; child = child.nextSibling) {
|
| - s += getOuterHTML(child);
|
| - }
|
| - return s;
|
| - }
|
| -
|
| - function setInnerHTML(node, value, opt_tagName) {
|
| - var tagName = opt_tagName || 'div';
|
| - node.textContent = '';
|
| - var tempElement = unwrap(node.ownerDocument.createElement(tagName));
|
| - tempElement.innerHTML = value;
|
| - var firstChild;
|
| - while (firstChild = tempElement.firstChild) {
|
| - node.appendChild(wrap(firstChild));
|
| - }
|
| - }
|
| -
|
| - var OriginalHTMLElement = window.HTMLElement;
|
| -
|
| - function HTMLElement(node) {
|
| - Element.call(this, node);
|
| - }
|
| - HTMLElement.prototype = Object.create(Element.prototype);
|
| - mixin(HTMLElement.prototype, {
|
| - get innerHTML() {
|
| - // TODO(arv): This should fallback to this.impl.innerHTML if there
|
| - // are no shadow trees below or above the context node.
|
| - return getInnerHTML(this);
|
| - },
|
| - set innerHTML(value) {
|
| - if (this.invalidateShadowRenderer())
|
| - setInnerHTML(this, value, this.tagName);
|
| - else
|
| - this.impl.innerHTML = value;
|
| - },
|
| -
|
| - get outerHTML() {
|
| - // TODO(arv): This should fallback to HTMLElement_prototype.outerHTML if there
|
| - // are no shadow trees below or above the context node.
|
| - return getOuterHTML(this);
|
| - },
|
| - set outerHTML(value) {
|
| - var p = this.parentNode;
|
| - if (p) {
|
| - p.invalidateShadowRenderer();
|
| - this.impl.outerHTML = value;
|
| - }
|
| - }
|
| - });
|
| -
|
| - function getterRequiresRendering(name) {
|
| - defineGetter(HTMLElement, name, function() {
|
| - scope.renderAllPending();
|
| - return this.impl[name];
|
| - });
|
| - }
|
| -
|
| - [
|
| - 'clientHeight',
|
| - 'clientLeft',
|
| - 'clientTop',
|
| - 'clientWidth',
|
| - 'offsetHeight',
|
| - 'offsetLeft',
|
| - 'offsetTop',
|
| - 'offsetWidth',
|
| - 'scrollHeight',
|
| - 'scrollLeft',
|
| - 'scrollTop',
|
| - 'scrollWidth',
|
| - ].forEach(getterRequiresRendering);
|
| -
|
| - function methodRequiresRendering(name) {
|
| - Object.defineProperty(HTMLElement.prototype, name, {
|
| - value: function() {
|
| - scope.renderAllPending();
|
| - return this.impl[name].apply(this.impl, arguments);
|
| - },
|
| - configurable: true,
|
| - enumerable: true
|
| - });
|
| - }
|
| -
|
| - [
|
| - 'getBoundingClientRect',
|
| - 'getClientRects',
|
| - 'scrollIntoView'
|
| - ].forEach(methodRequiresRendering);
|
| -
|
| - // HTMLElement is abstract so we use a subclass that has no members.
|
| - registerWrapper(OriginalHTMLElement, HTMLElement,
|
| - document.createElement('b'));
|
| -
|
| - scope.wrappers.HTMLElement = HTMLElement;
|
| -
|
| - // TODO: Find a better way to share these two with WrapperShadowRoot.
|
| - scope.getInnerHTML = getInnerHTML;
|
| - scope.setInnerHTML = setInnerHTML
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var HTMLElement = scope.wrappers.HTMLElement;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| -
|
| - var OriginalHTMLContentElement = window.HTMLContentElement;
|
| -
|
| - function HTMLContentElement(node) {
|
| - HTMLElement.call(this, node);
|
| - }
|
| - HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
|
| - mixin(HTMLContentElement.prototype, {
|
| - get select() {
|
| - return this.getAttribute('select');
|
| - },
|
| - set select(value) {
|
| - this.setAttribute('select', value);
|
| - },
|
| -
|
| - setAttribute: function(n, v) {
|
| - HTMLElement.prototype.setAttribute.call(this, n, v);
|
| - if (String(n).toLowerCase() === 'select')
|
| - this.invalidateShadowRenderer(true);
|
| - }
|
| -
|
| - // getDistributedNodes is added in ShadowRenderer
|
| -
|
| - // TODO: attribute boolean resetStyleInheritance;
|
| - });
|
| -
|
| - if (OriginalHTMLContentElement)
|
| - registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
|
| -
|
| - scope.wrappers.HTMLContentElement = HTMLContentElement;
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var HTMLElement = scope.wrappers.HTMLElement;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| -
|
| - var OriginalHTMLShadowElement = window.HTMLShadowElement;
|
| -
|
| - function HTMLShadowElement(node) {
|
| - HTMLElement.call(this, node);
|
| - }
|
| - HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
|
| - mixin(HTMLShadowElement.prototype, {
|
| - // TODO: attribute boolean resetStyleInheritance;
|
| - });
|
| -
|
| - if (OriginalHTMLShadowElement)
|
| - registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
|
| -
|
| - scope.wrappers.HTMLShadowElement = HTMLShadowElement;
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var HTMLElement = scope.wrappers.HTMLElement;
|
| - var getInnerHTML = scope.getInnerHTML;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var setInnerHTML = scope.setInnerHTML;
|
| - var unwrap = scope.unwrap;
|
| - var wrap = scope.wrap;
|
| -
|
| - var contentTable = new WeakMap();
|
| - var templateContentsOwnerTable = new WeakMap();
|
| -
|
| - // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner
|
| - function getTemplateContentsOwner(doc) {
|
| - if (!doc.defaultView)
|
| - return doc;
|
| - var d = templateContentsOwnerTable.get(doc);
|
| - if (!d) {
|
| - // TODO(arv): This should either be a Document or HTMLDocument depending
|
| - // on doc.
|
| - d = doc.implementation.createHTMLDocument('');
|
| - while (d.lastChild) {
|
| - d.removeChild(d.lastChild);
|
| - }
|
| - templateContentsOwnerTable.set(doc, d);
|
| - }
|
| - return d;
|
| - }
|
| -
|
| - function extractContent(templateElement) {
|
| - // templateElement is not a wrapper here.
|
| - var doc = getTemplateContentsOwner(templateElement.ownerDocument);
|
| - var df = unwrap(doc.createDocumentFragment());
|
| - var child;
|
| - while (child = templateElement.firstChild) {
|
| - df.appendChild(child);
|
| - }
|
| - return df;
|
| - }
|
| -
|
| - var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
|
| -
|
| - function HTMLTemplateElement(node) {
|
| - HTMLElement.call(this, node);
|
| - if (!OriginalHTMLTemplateElement) {
|
| - var content = extractContent(node);
|
| - contentTable.set(this, wrap(content));
|
| - }
|
| - }
|
| - HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
|
| -
|
| - mixin(HTMLTemplateElement.prototype, {
|
| - get content() {
|
| - if (OriginalHTMLTemplateElement)
|
| - return wrap(this.impl.content);
|
| - return contentTable.get(this);
|
| - },
|
| -
|
| - get innerHTML() {
|
| - return getInnerHTML(this.content);
|
| - },
|
| - set innerHTML(value) {
|
| - setInnerHTML(this.content, value);
|
| - }
|
| -
|
| - // TODO(arv): cloneNode needs to clone content.
|
| -
|
| - });
|
| -
|
| - if (OriginalHTMLTemplateElement)
|
| - registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
|
| -
|
| - scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var HTMLContentElement = scope.wrappers.HTMLContentElement;
|
| - var HTMLElement = scope.wrappers.HTMLElement;
|
| - var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
|
| - var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| -
|
| - var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
|
| -
|
| - function HTMLUnknownElement(node) {
|
| - switch (node.localName) {
|
| - case 'content':
|
| - return new HTMLContentElement(node);
|
| - case 'shadow':
|
| - return new HTMLShadowElement(node);
|
| - case 'template':
|
| - return new HTMLTemplateElement(node);
|
| - }
|
| - HTMLElement.call(this, node);
|
| - }
|
| - HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
|
| - registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
|
| - scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var GetElementsByInterface = scope.GetElementsByInterface;
|
| - var ParentNodeInterface = scope.ParentNodeInterface;
|
| - var SelectorsInterface = scope.SelectorsInterface;
|
| - var mixin = scope.mixin;
|
| - var registerObject = scope.registerObject;
|
| -
|
| - var DocumentFragment = registerObject(document.createDocumentFragment());
|
| - mixin(DocumentFragment.prototype, ParentNodeInterface);
|
| - mixin(DocumentFragment.prototype, SelectorsInterface);
|
| - mixin(DocumentFragment.prototype, GetElementsByInterface);
|
| -
|
| - var Text = registerObject(document.createTextNode(''));
|
| - var Comment = registerObject(document.createComment(''));
|
| -
|
| - scope.wrappers.Comment = Comment;
|
| - scope.wrappers.DocumentFragment = DocumentFragment;
|
| - scope.wrappers.Text = Text;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var DocumentFragment = scope.wrappers.DocumentFragment;
|
| - var elementFromPoint = scope.elementFromPoint;
|
| - var getInnerHTML = scope.getInnerHTML;
|
| - var mixin = scope.mixin;
|
| - var rewrap = scope.rewrap;
|
| - var setInnerHTML = scope.setInnerHTML;
|
| - var unwrap = scope.unwrap;
|
| -
|
| - var shadowHostTable = new WeakMap();
|
| - var nextOlderShadowTreeTable = new WeakMap();
|
| -
|
| - function ShadowRoot(hostWrapper) {
|
| - var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());
|
| - DocumentFragment.call(this, node);
|
| -
|
| - // createDocumentFragment associates the node with a wrapper
|
| - // DocumentFragment instance. Override that.
|
| - rewrap(node, this);
|
| -
|
| - var oldShadowRoot = hostWrapper.shadowRoot;
|
| - nextOlderShadowTreeTable.set(this, oldShadowRoot);
|
| -
|
| - shadowHostTable.set(this, hostWrapper);
|
| - }
|
| - ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
|
| - mixin(ShadowRoot.prototype, {
|
| - get innerHTML() {
|
| - return getInnerHTML(this);
|
| - },
|
| - set innerHTML(value) {
|
| - setInnerHTML(this, value);
|
| - this.invalidateShadowRenderer();
|
| - },
|
| -
|
| - get olderShadowRoot() {
|
| - return nextOlderShadowTreeTable.get(this) || null;
|
| - },
|
| -
|
| - invalidateShadowRenderer: function() {
|
| - return shadowHostTable.get(this).invalidateShadowRenderer();
|
| - },
|
| -
|
| - elementFromPoint: function(x, y) {
|
| - return elementFromPoint(this, this.ownerDocument, x, y);
|
| - },
|
| -
|
| - getElementById: function(id) {
|
| - return this.querySelector('#' + id);
|
| - }
|
| - });
|
| -
|
| - scope.wrappers.ShadowRoot = ShadowRoot;
|
| - scope.getHostForShadowRoot = function(node) {
|
| - return shadowHostTable.get(node);
|
| - };
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var Element = scope.wrappers.Element;
|
| - var HTMLContentElement = scope.wrappers.HTMLContentElement;
|
| - var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
|
| - var Node = scope.wrappers.Node;
|
| - var ShadowRoot = scope.wrappers.ShadowRoot;
|
| - var assert = scope.assert;
|
| - var getHostForShadowRoot = scope.getHostForShadowRoot;
|
| - var mixin = scope.mixin;
|
| - var oneOf = scope.oneOf;
|
| - var unwrap = scope.unwrap;
|
| - var wrap = scope.wrap;
|
| -
|
| - /**
|
| - * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.
|
| - * Up means parentNode
|
| - * Sideways means previous and next sibling.
|
| - * @param {!Node} wrapper
|
| - */
|
| - function updateWrapperUpAndSideways(wrapper) {
|
| - wrapper.previousSibling_ = wrapper.previousSibling;
|
| - wrapper.nextSibling_ = wrapper.nextSibling;
|
| - wrapper.parentNode_ = wrapper.parentNode;
|
| - }
|
| -
|
| - /**
|
| - * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.
|
| - * Down means first and last child
|
| - * @param {!Node} wrapper
|
| - */
|
| - function updateWrapperDown(wrapper) {
|
| - wrapper.firstChild_ = wrapper.firstChild;
|
| - wrapper.lastChild_ = wrapper.lastChild;
|
| - }
|
| -
|
| - function updateAllChildNodes(parentNodeWrapper) {
|
| - assert(parentNodeWrapper instanceof Node);
|
| - for (var childWrapper = parentNodeWrapper.firstChild;
|
| - childWrapper;
|
| - childWrapper = childWrapper.nextSibling) {
|
| - updateWrapperUpAndSideways(childWrapper);
|
| - }
|
| - updateWrapperDown(parentNodeWrapper);
|
| - }
|
| -
|
| - function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
|
| - var parentNode = unwrap(parentNodeWrapper);
|
| - var newChild = unwrap(newChildWrapper);
|
| - var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
|
| -
|
| - remove(newChildWrapper);
|
| - updateWrapperUpAndSideways(newChildWrapper);
|
| -
|
| - if (!refChildWrapper) {
|
| - parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
|
| - if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild)
|
| - parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
|
| -
|
| - var lastChildWrapper = wrap(parentNode.lastChild);
|
| - if (lastChildWrapper)
|
| - lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
|
| - } else {
|
| - if (parentNodeWrapper.firstChild === refChildWrapper)
|
| - parentNodeWrapper.firstChild_ = refChildWrapper;
|
| -
|
| - refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
|
| - }
|
| -
|
| - parentNode.insertBefore(newChild, refChild);
|
| - }
|
| -
|
| - function remove(nodeWrapper) {
|
| - var node = unwrap(nodeWrapper)
|
| - var parentNode = node.parentNode;
|
| - if (!parentNode)
|
| - return;
|
| -
|
| - var parentNodeWrapper = wrap(parentNode);
|
| - updateWrapperUpAndSideways(nodeWrapper);
|
| -
|
| - if (nodeWrapper.previousSibling)
|
| - nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
|
| - if (nodeWrapper.nextSibling)
|
| - nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
|
| -
|
| - if (parentNodeWrapper.lastChild === nodeWrapper)
|
| - parentNodeWrapper.lastChild_ = nodeWrapper;
|
| - if (parentNodeWrapper.firstChild === nodeWrapper)
|
| - parentNodeWrapper.firstChild_ = nodeWrapper;
|
| -
|
| - parentNode.removeChild(node);
|
| - }
|
| -
|
| - var distributedChildNodesTable = new WeakMap();
|
| - var eventParentsTable = new WeakMap();
|
| - var insertionParentTable = new WeakMap();
|
| - var rendererForHostTable = new WeakMap();
|
| -
|
| - function distributeChildToInsertionPoint(child, insertionPoint) {
|
| - getDistributedChildNodes(insertionPoint).push(child);
|
| - assignToInsertionPoint(child, insertionPoint);
|
| -
|
| - var eventParents = eventParentsTable.get(child);
|
| - if (!eventParents)
|
| - eventParentsTable.set(child, eventParents = []);
|
| - eventParents.push(insertionPoint);
|
| - }
|
| -
|
| - function resetDistributedChildNodes(insertionPoint) {
|
| - distributedChildNodesTable.set(insertionPoint, []);
|
| - }
|
| -
|
| - function getDistributedChildNodes(insertionPoint) {
|
| - return distributedChildNodesTable.get(insertionPoint);
|
| - }
|
| -
|
| - function getChildNodesSnapshot(node) {
|
| - var result = [], i = 0;
|
| - for (var child = node.firstChild; child; child = child.nextSibling) {
|
| - result[i++] = child;
|
| - }
|
| - return result;
|
| - }
|
| -
|
| - /**
|
| - * Visits all nodes in the tree that fulfils the |predicate|. If the |visitor|
|
| - * function returns |false| the traversal is aborted.
|
| - * @param {!Node} tree
|
| - * @param {function(!Node) : boolean} predicate
|
| - * @param {function(!Node) : *} visitor
|
| - */
|
| - function visit(tree, predicate, visitor) {
|
| - // This operates on logical DOM.
|
| - for (var node = tree.firstChild; node; node = node.nextSibling) {
|
| - if (predicate(node)) {
|
| - if (visitor(node) === false)
|
| - return;
|
| - } else {
|
| - visit(node, predicate, visitor);
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Matching Insertion Points
|
| - // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#matching-insertion-points
|
| -
|
| - // TODO(arv): Verify this... I don't remember why I picked this regexp.
|
| - var selectorMatchRegExp = /^[*.:#[a-zA-Z_|]/;
|
| -
|
| - var allowedPseudoRegExp = new RegExp('^:(' + [
|
| - 'link',
|
| - 'visited',
|
| - 'target',
|
| - 'enabled',
|
| - 'disabled',
|
| - 'checked',
|
| - 'indeterminate',
|
| - 'nth-child',
|
| - 'nth-last-child',
|
| - 'nth-of-type',
|
| - 'nth-last-of-type',
|
| - 'first-child',
|
| - 'last-child',
|
| - 'first-of-type',
|
| - 'last-of-type',
|
| - 'only-of-type',
|
| - ].join('|') + ')');
|
| -
|
| -
|
| - /**
|
| - * @param {Element} node
|
| - * @oaram {Element} point The insertion point element.
|
| - * @return {boolean} Whether the node matches the insertion point.
|
| - */
|
| - function matchesCriteria(node, point) {
|
| - var select = point.getAttribute('select');
|
| - if (!select)
|
| - return true;
|
| -
|
| - // Here we know the select attribute is a non empty string.
|
| - select = select.trim();
|
| - if (!select)
|
| - return true;
|
| -
|
| - if (!(node instanceof Element))
|
| - return false;
|
| -
|
| - // TODO(arv): This does not seem right. Need to check for a simple selector.
|
| - if (!selectorMatchRegExp.test(select))
|
| - return false;
|
| -
|
| - if (select[0] === ':' && !allowedPseudoRegExp.test(select))
|
| - return false;
|
| -
|
| - try {
|
| - return node.matches(select);
|
| - } catch (ex) {
|
| - // Invalid selector.
|
| - return false;
|
| - }
|
| - }
|
| -
|
| - var request = oneOf(window, [
|
| - 'requestAnimationFrame',
|
| - 'mozRequestAnimationFrame',
|
| - 'webkitRequestAnimationFrame',
|
| - 'setTimeout'
|
| - ]);
|
| -
|
| - var pendingDirtyRenderers = [];
|
| - var renderTimer;
|
| -
|
| - function renderAllPending() {
|
| - for (var i = 0; i < pendingDirtyRenderers.length; i++) {
|
| - pendingDirtyRenderers[i].render();
|
| - }
|
| - pendingDirtyRenderers = [];
|
| - }
|
| -
|
| - function handleRequestAnimationFrame() {
|
| - renderTimer = null;
|
| - renderAllPending();
|
| - }
|
| -
|
| - /**
|
| - * Returns existing shadow renderer for a host or creates it if it is needed.
|
| - * @params {!Element} host
|
| - * @return {!ShadowRenderer}
|
| - */
|
| - function getRendererForHost(host) {
|
| - var renderer = rendererForHostTable.get(host);
|
| - if (!renderer) {
|
| - renderer = new ShadowRenderer(host);
|
| - rendererForHostTable.set(host, renderer);
|
| - }
|
| - return renderer;
|
| - }
|
| -
|
| - function getShadowRootAncestor(node) {
|
| - for (; node; node = node.parentNode) {
|
| - if (node instanceof ShadowRoot)
|
| - return node;
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - function getRendererForShadowRoot(shadowRoot) {
|
| - return getRendererForHost(getHostForShadowRoot(shadowRoot));
|
| - }
|
| -
|
| - var spliceDiff = new ArraySplice();
|
| - spliceDiff.equals = function(renderNode, rawNode) {
|
| - return unwrap(renderNode.node) === rawNode;
|
| - };
|
| -
|
| - /**
|
| - * RenderNode is used as an in memory "render tree". When we render the
|
| - * composed tree we create a tree of RenderNodes, then we diff this against
|
| - * the real DOM tree and make minimal changes as needed.
|
| - */
|
| - function RenderNode(node) {
|
| - this.skip = false;
|
| - this.node = node;
|
| - this.childNodes = [];
|
| - }
|
| -
|
| - RenderNode.prototype = {
|
| - append: function(node) {
|
| - var rv = new RenderNode(node);
|
| - this.childNodes.push(rv);
|
| - return rv;
|
| - },
|
| -
|
| - sync: function(opt_added) {
|
| - if (this.skip)
|
| - return;
|
| -
|
| - var nodeWrapper = this.node;
|
| - // plain array of RenderNodes
|
| - var newChildren = this.childNodes;
|
| - // plain array of real nodes.
|
| - var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
|
| - var added = opt_added || new WeakMap();
|
| -
|
| - var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
|
| -
|
| - var newIndex = 0, oldIndex = 0;
|
| - var lastIndex = 0;
|
| - for (var i = 0; i < splices.length; i++) {
|
| - var splice = splices[i];
|
| - for (; lastIndex < splice.index; lastIndex++) {
|
| - oldIndex++;
|
| - newChildren[newIndex++].sync(added);
|
| - }
|
| -
|
| - var removedCount = splice.removed.length;
|
| - for (var j = 0; j < removedCount; j++) {
|
| - var wrapper = wrap(oldChildren[oldIndex++]);
|
| - if (!added.get(wrapper))
|
| - remove(wrapper);
|
| - }
|
| -
|
| - var addedCount = splice.addedCount;
|
| - var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
|
| - for (var j = 0; j < addedCount; j++) {
|
| - var newChildRenderNode = newChildren[newIndex++];
|
| - var newChildWrapper = newChildRenderNode.node;
|
| - insertBefore(nodeWrapper, newChildWrapper, refNode);
|
| -
|
| - // Keep track of added so that we do not remove the node after it
|
| - // has been added.
|
| - added.set(newChildWrapper, true);
|
| -
|
| - newChildRenderNode.sync(added);
|
| - }
|
| -
|
| - lastIndex += addedCount;
|
| - }
|
| -
|
| - for (var i = lastIndex; i < newChildren.length; i++) {
|
| - newChildren[i++].sync(added);
|
| - }
|
| - }
|
| - };
|
| -
|
| - function ShadowRenderer(host) {
|
| - this.host = host;
|
| - this.dirty = false;
|
| - this.invalidateAttributes();
|
| - this.associateNode(host);
|
| - }
|
| -
|
| - ShadowRenderer.prototype = {
|
| -
|
| - // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees
|
| - render: function(opt_renderNode) {
|
| - if (!this.dirty)
|
| - return;
|
| -
|
| - this.invalidateAttributes();
|
| - this.treeComposition();
|
| -
|
| - var host = this.host;
|
| - var shadowRoot = host.shadowRoot;
|
| -
|
| - this.associateNode(host);
|
| - var topMostRenderer = !renderNode;
|
| - var renderNode = opt_renderNode || new RenderNode(host);
|
| -
|
| - for (var node = shadowRoot.firstChild; node; node = node.nextSibling) {
|
| - this.renderNode(shadowRoot, renderNode, node, false);
|
| - }
|
| -
|
| - if (topMostRenderer)
|
| - renderNode.sync();
|
| -
|
| - this.dirty = false;
|
| - },
|
| -
|
| - invalidate: function() {
|
| - if (!this.dirty) {
|
| - this.dirty = true;
|
| - pendingDirtyRenderers.push(this);
|
| - if (renderTimer)
|
| - return;
|
| - renderTimer = window[request](handleRequestAnimationFrame, 0);
|
| - }
|
| - },
|
| -
|
| - renderNode: function(shadowRoot, renderNode, node, isNested) {
|
| - if (isShadowHost(node)) {
|
| - renderNode = renderNode.append(node);
|
| - var renderer = getRendererForHost(node);
|
| - renderer.dirty = true; // Need to rerender due to reprojection.
|
| - renderer.render(renderNode);
|
| - } else if (isInsertionPoint(node)) {
|
| - this.renderInsertionPoint(shadowRoot, renderNode, node, isNested);
|
| - } else if (isShadowInsertionPoint(node)) {
|
| - this.renderShadowInsertionPoint(shadowRoot, renderNode, node);
|
| - } else {
|
| - this.renderAsAnyDomTree(shadowRoot, renderNode, node, isNested);
|
| - }
|
| - },
|
| -
|
| - renderAsAnyDomTree: function(shadowRoot, renderNode, node, isNested) {
|
| - renderNode = renderNode.append(node);
|
| -
|
| - if (isShadowHost(node)) {
|
| - var renderer = getRendererForHost(node);
|
| - renderNode.skip = !renderer.dirty;
|
| - renderer.render(renderNode);
|
| - } else {
|
| - for (var child = node.firstChild; child; child = child.nextSibling) {
|
| - this.renderNode(shadowRoot, renderNode, child, isNested);
|
| - }
|
| - }
|
| - },
|
| -
|
| - renderInsertionPoint: function(shadowRoot, renderNode, insertionPoint,
|
| - isNested) {
|
| - var distributedChildNodes = getDistributedChildNodes(insertionPoint);
|
| - if (distributedChildNodes.length) {
|
| - this.associateNode(insertionPoint);
|
| -
|
| - for (var i = 0; i < distributedChildNodes.length; i++) {
|
| - var child = distributedChildNodes[i];
|
| - if (isInsertionPoint(child) && isNested)
|
| - this.renderInsertionPoint(shadowRoot, renderNode, child, isNested);
|
| - else
|
| - this.renderAsAnyDomTree(shadowRoot, renderNode, child, isNested);
|
| - }
|
| - } else {
|
| - this.renderFallbackContent(shadowRoot, renderNode, insertionPoint);
|
| - }
|
| - this.associateNode(insertionPoint.parentNode);
|
| - },
|
| -
|
| - renderShadowInsertionPoint: function(shadowRoot, renderNode,
|
| - shadowInsertionPoint) {
|
| - var nextOlderTree = shadowRoot.olderShadowRoot;
|
| - if (nextOlderTree) {
|
| - assignToInsertionPoint(nextOlderTree, shadowInsertionPoint);
|
| - this.associateNode(shadowInsertionPoint.parentNode);
|
| - for (var node = nextOlderTree.firstChild;
|
| - node;
|
| - node = node.nextSibling) {
|
| - this.renderNode(nextOlderTree, renderNode, node, true);
|
| - }
|
| - } else {
|
| - this.renderFallbackContent(shadowRoot, renderNode,
|
| - shadowInsertionPoint);
|
| - }
|
| - },
|
| -
|
| - renderFallbackContent: function(shadowRoot, renderNode, fallbackHost) {
|
| - this.associateNode(fallbackHost);
|
| - this.associateNode(fallbackHost.parentNode);
|
| - for (var node = fallbackHost.firstChild; node; node = node.nextSibling) {
|
| - this.renderAsAnyDomTree(shadowRoot, renderNode, node, false);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Invalidates the attributes used to keep track of which attributes may
|
| - * cause the renderer to be invalidated.
|
| - */
|
| - invalidateAttributes: function() {
|
| - this.attributes = Object.create(null);
|
| - },
|
| -
|
| - /**
|
| - * Parses the selector and makes this renderer dependent on the attribute
|
| - * being used in the selector.
|
| - * @param {string} selector
|
| - */
|
| - updateDependentAttributes: function(selector) {
|
| - if (!selector)
|
| - return;
|
| -
|
| - var attributes = this.attributes;
|
| -
|
| - // .class
|
| - if (/\.\w+/.test(selector))
|
| - attributes['class'] = true;
|
| -
|
| - // #id
|
| - if (/#\w+/.test(selector))
|
| - attributes['id'] = true;
|
| -
|
| - selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
|
| - attributes[name] = true;
|
| - });
|
| -
|
| - // Pseudo selectors have been removed from the spec.
|
| - },
|
| -
|
| - dependsOnAttribute: function(name) {
|
| - return this.attributes[name];
|
| - },
|
| -
|
| - // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-distribution-algorithm
|
| - distribute: function(tree, pool) {
|
| - var self = this;
|
| -
|
| - visit(tree, isActiveInsertionPoint,
|
| - function(insertionPoint) {
|
| - resetDistributedChildNodes(insertionPoint);
|
| - self.updateDependentAttributes(
|
| - insertionPoint.getAttribute('select'));
|
| -
|
| - for (var i = 0; i < pool.length; i++) { // 1.2
|
| - var node = pool[i]; // 1.2.1
|
| - if (node === undefined) // removed
|
| - continue;
|
| - if (matchesCriteria(node, insertionPoint)) { // 1.2.2
|
| - distributeChildToInsertionPoint(node, insertionPoint); // 1.2.2.1
|
| - pool[i] = undefined; // 1.2.2.2
|
| - }
|
| - }
|
| - });
|
| - },
|
| -
|
| - // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#dfn-tree-composition
|
| - treeComposition: function () {
|
| - var shadowHost = this.host;
|
| - var tree = shadowHost.shadowRoot; // 1.
|
| - var pool = []; // 2.
|
| -
|
| - for (var child = shadowHost.firstChild;
|
| - child;
|
| - child = child.nextSibling) { // 3.
|
| - if (isInsertionPoint(child)) { // 3.2.
|
| - var reprojected = getDistributedChildNodes(child); // 3.2.1.
|
| - // if reprojected is undef... reset it?
|
| - if (!reprojected || !reprojected.length) // 3.2.2.
|
| - reprojected = getChildNodesSnapshot(child);
|
| - pool.push.apply(pool, reprojected); // 3.2.3.
|
| - } else {
|
| - pool.push(child); // 3.3.
|
| - }
|
| - }
|
| -
|
| - var shadowInsertionPoint, point;
|
| - while (tree) { // 4.
|
| - // 4.1.
|
| - shadowInsertionPoint = undefined; // Reset every iteration.
|
| - visit(tree, isActiveShadowInsertionPoint, function(point) {
|
| - shadowInsertionPoint = point;
|
| - return false;
|
| - });
|
| - point = shadowInsertionPoint;
|
| -
|
| - this.distribute(tree, pool); // 4.2.
|
| - if (point) { // 4.3.
|
| - var nextOlderTree = tree.olderShadowRoot; // 4.3.1.
|
| - if (!nextOlderTree) {
|
| - break; // 4.3.1.1.
|
| - } else {
|
| - tree = nextOlderTree; // 4.3.2.2.
|
| - assignToInsertionPoint(tree, point); // 4.3.2.2.
|
| - continue; // 4.3.2.3.
|
| - }
|
| - } else {
|
| - break; // 4.4.
|
| - }
|
| - }
|
| - },
|
| -
|
| - associateNode: function(node) {
|
| - node.impl.polymerShadowRenderer_ = this;
|
| - }
|
| - };
|
| -
|
| - function isInsertionPoint(node) {
|
| - // Should this include <shadow>?
|
| - return node instanceof HTMLContentElement;
|
| - }
|
| -
|
| - function isActiveInsertionPoint(node) {
|
| - // <content> inside another <content> or <shadow> is considered inactive.
|
| - return node instanceof HTMLContentElement;
|
| - }
|
| -
|
| - function isShadowInsertionPoint(node) {
|
| - return node instanceof HTMLShadowElement;
|
| - }
|
| -
|
| - function isActiveShadowInsertionPoint(node) {
|
| - // <shadow> inside another <content> or <shadow> is considered inactive.
|
| - return node instanceof HTMLShadowElement;
|
| - }
|
| -
|
| - function isShadowHost(shadowHost) {
|
| - return shadowHost.shadowRoot;
|
| - }
|
| -
|
| - function getShadowTrees(host) {
|
| - var trees = [];
|
| -
|
| - for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
|
| - trees.push(tree);
|
| - }
|
| - return trees;
|
| - }
|
| -
|
| - function assignToInsertionPoint(tree, point) {
|
| - insertionParentTable.set(tree, point);
|
| - }
|
| -
|
| - // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees
|
| - function render(host) {
|
| - new ShadowRenderer(host).render();
|
| - };
|
| -
|
| - // Need to rerender shadow host when:
|
| - //
|
| - // - a direct child to the ShadowRoot is added or removed
|
| - // - a direct child to the host is added or removed
|
| - // - a new shadow root is created
|
| - // - a direct child to a content/shadow element is added or removed
|
| - // - a sibling to a content/shadow element is added or removed
|
| - // - content[select] is changed
|
| - // - an attribute in a direct child to a host is modified
|
| -
|
| - /**
|
| - * This gets called when a node was added or removed to it.
|
| - */
|
| - Node.prototype.invalidateShadowRenderer = function(force) {
|
| - var renderer = this.impl.polymerShadowRenderer_;
|
| - if (renderer) {
|
| - renderer.invalidate();
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| - };
|
| -
|
| - HTMLContentElement.prototype.getDistributedNodes = function() {
|
| - // TODO(arv): We should only rerender the dirty ancestor renderers (from
|
| - // the root and down).
|
| - renderAllPending();
|
| - return getDistributedChildNodes(this);
|
| - };
|
| -
|
| - HTMLShadowElement.prototype.nodeWasAdded_ =
|
| - HTMLContentElement.prototype.nodeWasAdded_ = function() {
|
| - // Invalidate old renderer if any.
|
| - this.invalidateShadowRenderer();
|
| -
|
| - var shadowRoot = getShadowRootAncestor(this);
|
| - var renderer;
|
| - if (shadowRoot)
|
| - renderer = getRendererForShadowRoot(shadowRoot);
|
| - this.impl.polymerShadowRenderer_ = renderer;
|
| - if (renderer)
|
| - renderer.invalidate();
|
| - };
|
| -
|
| - scope.eventParentsTable = eventParentsTable;
|
| - scope.getRendererForHost = getRendererForHost;
|
| - scope.getShadowTrees = getShadowTrees;
|
| - scope.insertionParentTable = insertionParentTable;
|
| - scope.renderAllPending = renderAllPending;
|
| -
|
| - // Exposed for testing
|
| - scope.visual = {
|
| - insertBefore: insertBefore,
|
| - remove: remove,
|
| - };
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var HTMLElement = scope.wrappers.HTMLElement;
|
| - var assert = scope.assert;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrap = scope.unwrap;
|
| - var wrap = scope.wrap;
|
| -
|
| - var elementsWithFormProperty = [
|
| - 'HTMLButtonElement',
|
| - 'HTMLFieldSetElement',
|
| - 'HTMLInputElement',
|
| - 'HTMLKeygenElement',
|
| - 'HTMLLabelElement',
|
| - 'HTMLLegendElement',
|
| - 'HTMLObjectElement',
|
| - 'HTMLOptionElement',
|
| - 'HTMLOutputElement',
|
| - 'HTMLSelectElement',
|
| - 'HTMLTextAreaElement',
|
| - ];
|
| -
|
| - function createWrapperConstructor(name) {
|
| - if (!window[name])
|
| - return;
|
| -
|
| - // Ensure we are not overriding an already existing constructor.
|
| - assert(!scope.wrappers[name]);
|
| -
|
| - var GeneratedWrapper = function(node) {
|
| - // At this point all of them extend HTMLElement.
|
| - HTMLElement.call(this, node);
|
| - }
|
| - GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
|
| - mixin(GeneratedWrapper.prototype, {
|
| - get form() {
|
| - return wrap(unwrap(this).form);
|
| - },
|
| - });
|
| -
|
| - registerWrapper(window[name], GeneratedWrapper,
|
| - document.createElement(name.slice(4, -7)));
|
| - scope.wrappers[name] = GeneratedWrapper;
|
| - }
|
| -
|
| - elementsWithFormProperty.forEach(createWrapperConstructor);
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var GetElementsByInterface = scope.GetElementsByInterface;
|
| - var Node = scope.wrappers.Node;
|
| - var ParentNodeInterface = scope.ParentNodeInterface;
|
| - var SelectorsInterface = scope.SelectorsInterface;
|
| - var ShadowRoot = scope.wrappers.ShadowRoot;
|
| - var defineWrapGetter = scope.defineWrapGetter;
|
| - var elementFromPoint = scope.elementFromPoint;
|
| - var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
|
| - var matchesName = scope.matchesName;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrap = scope.unwrap;
|
| - var wrap = scope.wrap;
|
| - var wrapEventTargetMethods = scope.wrapEventTargetMethods;
|
| - var wrapNodeList = scope.wrapNodeList;
|
| -
|
| - var implementationTable = new WeakMap();
|
| -
|
| - function Document(node) {
|
| - Node.call(this, node);
|
| - }
|
| - Document.prototype = Object.create(Node.prototype);
|
| -
|
| - defineWrapGetter(Document, 'documentElement');
|
| -
|
| - // Conceptually both body and head can be in a shadow but suporting that seems
|
| - // overkill at this point.
|
| - defineWrapGetter(Document, 'body');
|
| - defineWrapGetter(Document, 'head');
|
| -
|
| - // document cannot be overridden so we override a bunch of its methods
|
| - // directly on the instance.
|
| -
|
| - function wrapMethod(name) {
|
| - var original = document[name];
|
| - Document.prototype[name] = function() {
|
| - return wrap(original.apply(this.impl, arguments));
|
| - };
|
| - }
|
| -
|
| - [
|
| - 'createComment',
|
| - 'createDocumentFragment',
|
| - 'createElement',
|
| - 'createElementNS',
|
| - 'createEvent',
|
| - 'createEventNS',
|
| - 'createRange',
|
| - 'createTextNode',
|
| - 'getElementById',
|
| - ].forEach(wrapMethod);
|
| -
|
| - var originalAdoptNode = document.adoptNode;
|
| -
|
| - function adoptNodeNoRemove(node, doc) {
|
| - originalAdoptNode.call(doc.impl, unwrap(node));
|
| - adoptSubtree(node, doc);
|
| - }
|
| -
|
| - function adoptSubtree(node, doc) {
|
| - if (node.shadowRoot)
|
| - doc.adoptNode(node.shadowRoot);
|
| - if (node instanceof ShadowRoot)
|
| - adoptOlderShadowRoots(node, doc);
|
| - for (var child = node.firstChild; child; child = child.nextSibling) {
|
| - adoptSubtree(child, doc);
|
| - }
|
| - }
|
| -
|
| - function adoptOlderShadowRoots(shadowRoot, doc) {
|
| - var oldShadowRoot = shadowRoot.olderShadowRoot;
|
| - if (oldShadowRoot)
|
| - doc.adoptNode(oldShadowRoot);
|
| - }
|
| -
|
| - mixin(Document.prototype, {
|
| - adoptNode: function(node) {
|
| - if (node.parentNode)
|
| - node.parentNode.removeChild(node);
|
| - adoptNodeNoRemove(node, this);
|
| - return node;
|
| - },
|
| - elementFromPoint: function(x, y) {
|
| - return elementFromPoint(this, this, x, y);
|
| - }
|
| - });
|
| -
|
| - if (document.register) {
|
| - var originalRegister = document.register;
|
| - Document.prototype.register = function(tagName, object) {
|
| - var prototype = object.prototype;
|
| -
|
| - // If we already used the object as a prototype for another custom
|
| - // element.
|
| - if (scope.nativePrototypeTable.get(prototype)) {
|
| - // TODO(arv): DOMException
|
| - throw new Error('NotSupportedError');
|
| - }
|
| -
|
| - // Find first object on the prototype chain that already have a native
|
| - // prototype. Keep track of all the objects before that so we can create
|
| - // a similar structure for the native case.
|
| - var proto = Object.getPrototypeOf(prototype);
|
| - var nativePrototype;
|
| - var prototypes = [];
|
| - while (proto) {
|
| - nativePrototype = scope.nativePrototypeTable.get(proto);
|
| - if (nativePrototype)
|
| - break;
|
| - prototypes.push(proto);
|
| - proto = Object.getPrototypeOf(proto);
|
| - }
|
| -
|
| - if (!nativePrototype) {
|
| - // TODO(arv): DOMException
|
| - throw new Error('NotSupportedError');
|
| - }
|
| -
|
| - // This works by creating a new prototype object that is empty, but has
|
| - // the native prototype as its proto. The original prototype object
|
| - // passed into register is used as the wrapper prototype.
|
| -
|
| - var newPrototype = Object.create(nativePrototype);
|
| - for (var i = prototypes.length - 1; i >= 0; i--) {
|
| - newPrototype = Object.create(newPrototype);
|
| - }
|
| -
|
| - // Add callbacks if present.
|
| - // Names are taken from:
|
| - // https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp&sq=package:chromium&type=cs&l=156
|
| - // and not from the spec since the spec is out of date.
|
| - [
|
| - 'createdCallback',
|
| - 'enteredDocumentCallback',
|
| - 'leftDocumentCallback',
|
| - 'attributeChangedCallback',
|
| - ].forEach(function(name) {
|
| - var f = prototype[name];
|
| - if (!f)
|
| - return;
|
| - newPrototype[name] = function() {
|
| - f.apply(wrap(this), arguments);
|
| - };
|
| - });
|
| -
|
| - var nativeConstructor = originalRegister.call(unwrap(this), tagName,
|
| - {prototype: newPrototype});
|
| -
|
| - function GeneratedWrapper(node) {
|
| - if (!node)
|
| - return document.createElement(tagName);
|
| - this.impl = node;
|
| - }
|
| - GeneratedWrapper.prototype = prototype;
|
| - GeneratedWrapper.prototype.constructor = GeneratedWrapper;
|
| -
|
| - scope.constructorTable.set(newPrototype, GeneratedWrapper);
|
| - scope.nativePrototypeTable.set(prototype, newPrototype);
|
| -
|
| - return GeneratedWrapper;
|
| - };
|
| -
|
| - forwardMethodsToWrapper([
|
| - window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
|
| - ], [
|
| - 'register',
|
| - ]);
|
| - }
|
| -
|
| - // We also override some of the methods on document.body and document.head
|
| - // for convenience.
|
| - forwardMethodsToWrapper([
|
| - window.HTMLBodyElement,
|
| - window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
|
| - window.HTMLHeadElement,
|
| - window.HTMLHtmlElement,
|
| - ], [
|
| - 'appendChild',
|
| - 'compareDocumentPosition',
|
| - 'contains',
|
| - 'getElementsByClassName',
|
| - 'getElementsByTagName',
|
| - 'getElementsByTagNameNS',
|
| - 'insertBefore',
|
| - 'querySelector',
|
| - 'querySelectorAll',
|
| - 'removeChild',
|
| - 'replaceChild',
|
| - matchesName,
|
| - ]);
|
| -
|
| - forwardMethodsToWrapper([
|
| - window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
|
| - ], [
|
| - 'adoptNode',
|
| - 'contains',
|
| - 'createComment',
|
| - 'createDocumentFragment',
|
| - 'createElement',
|
| - 'createElementNS',
|
| - 'createEvent',
|
| - 'createEventNS',
|
| - 'createRange',
|
| - 'createTextNode',
|
| - 'elementFromPoint',
|
| - 'getElementById',
|
| - ]);
|
| -
|
| - mixin(Document.prototype, GetElementsByInterface);
|
| - mixin(Document.prototype, ParentNodeInterface);
|
| - mixin(Document.prototype, SelectorsInterface);
|
| -
|
| - mixin(Document.prototype, {
|
| - get implementation() {
|
| - var implementation = implementationTable.get(this);
|
| - if (implementation)
|
| - return implementation;
|
| - implementation =
|
| - new DOMImplementation(unwrap(this).implementation);
|
| - implementationTable.set(this, implementation);
|
| - return implementation;
|
| - }
|
| - });
|
| -
|
| - registerWrapper(window.Document, Document,
|
| - document.implementation.createHTMLDocument(''));
|
| -
|
| - // Both WebKit and Gecko uses HTMLDocument for document. HTML5/DOM only has
|
| - // one Document interface and IE implements the standard correctly.
|
| - if (window.HTMLDocument)
|
| - registerWrapper(window.HTMLDocument, Document);
|
| -
|
| - wrapEventTargetMethods([
|
| - window.HTMLBodyElement,
|
| - window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
|
| - window.HTMLHeadElement,
|
| - ]);
|
| -
|
| - function DOMImplementation(impl) {
|
| - this.impl = impl;
|
| - }
|
| -
|
| - function wrapImplMethod(constructor, name) {
|
| - var original = document.implementation[name];
|
| - constructor.prototype[name] = function() {
|
| - return wrap(original.apply(this.impl, arguments));
|
| - };
|
| - }
|
| -
|
| - function forwardImplMethod(constructor, name) {
|
| - var original = document.implementation[name];
|
| - constructor.prototype[name] = function() {
|
| - return original.apply(this.impl, arguments);
|
| - };
|
| - }
|
| -
|
| - wrapImplMethod(DOMImplementation, 'createDocumentType');
|
| - wrapImplMethod(DOMImplementation, 'createDocument');
|
| - wrapImplMethod(DOMImplementation, 'createHTMLDocument');
|
| - forwardImplMethod(DOMImplementation, 'hasFeature');
|
| -
|
| - registerWrapper(window.DOMImplementation, DOMImplementation);
|
| -
|
| - forwardMethodsToWrapper([
|
| - window.DOMImplementation,
|
| - ], [
|
| - 'createDocumentType',
|
| - 'createDocument',
|
| - 'createHTMLDocument',
|
| - 'hasFeature',
|
| - ]);
|
| -
|
| - scope.adoptNodeNoRemove = adoptNodeNoRemove;
|
| - scope.wrappers.DOMImplementation = DOMImplementation;
|
| - scope.wrappers.Document = Document;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var EventTarget = scope.wrappers.EventTarget;
|
| - var mixin = scope.mixin;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrap = scope.unwrap;
|
| - var unwrapIfNeeded = scope.unwrapIfNeeded;
|
| - var wrap = scope.wrap;
|
| - var renderAllPending = scope.renderAllPending;
|
| -
|
| - var OriginalWindow = window.Window;
|
| -
|
| - function Window(impl) {
|
| - EventTarget.call(this, impl);
|
| - }
|
| - Window.prototype = Object.create(EventTarget.prototype);
|
| -
|
| - var originalGetComputedStyle = window.getComputedStyle;
|
| - OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
|
| - renderAllPending();
|
| - return originalGetComputedStyle.call(this || window, unwrapIfNeeded(el),
|
| - pseudo);
|
| - };
|
| -
|
| - ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(
|
| - function(name) {
|
| - OriginalWindow.prototype[name] = function() {
|
| - var w = wrap(this || window);
|
| - return w[name].apply(w, arguments);
|
| - };
|
| - });
|
| -
|
| - mixin(Window.prototype, {
|
| - getComputedStyle: function(el, pseudo) {
|
| - return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),
|
| - pseudo);
|
| - }
|
| - });
|
| -
|
| - registerWrapper(OriginalWindow, Window);
|
| -
|
| - scope.wrappers.Window = Window;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var defineGetter = scope.defineGetter;
|
| - var defineWrapGetter = scope.defineWrapGetter;
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrapIfNeeded = scope.unwrapIfNeeded;
|
| - var wrapNodeList = scope.wrapNodeList;
|
| - var wrappers = scope.wrappers;
|
| -
|
| - var OriginalMutationObserver = window.MutationObserver ||
|
| - window.WebKitMutationObserver;
|
| -
|
| - if (!OriginalMutationObserver)
|
| - return;
|
| -
|
| - var OriginalMutationRecord = window.MutationRecord;
|
| -
|
| - function MutationRecord(impl) {
|
| - this.impl = impl;
|
| - }
|
| -
|
| - MutationRecord.prototype = {
|
| - get addedNodes() {
|
| - return wrapNodeList(this.impl.addedNodes);
|
| - },
|
| - get removedNodes() {
|
| - return wrapNodeList(this.impl.removedNodes);
|
| - }
|
| - };
|
| -
|
| - ['target', 'previousSibling', 'nextSibling'].forEach(function(name) {
|
| - defineWrapGetter(MutationRecord, name);
|
| - });
|
| -
|
| - // WebKit/Blink treats these as instance properties so we override
|
| - [
|
| - 'type',
|
| - 'attributeName',
|
| - 'attributeNamespace',
|
| - 'oldValue'
|
| - ].forEach(function(name) {
|
| - defineGetter(MutationRecord, name, function() {
|
| - return this.impl[name];
|
| - });
|
| - });
|
| -
|
| - if (OriginalMutationRecord)
|
| - registerWrapper(OriginalMutationRecord, MutationRecord);
|
| -
|
| - function wrapRecord(record) {
|
| - return new MutationRecord(record);
|
| - }
|
| -
|
| - function wrapRecords(records) {
|
| - return records.map(wrapRecord);
|
| - }
|
| -
|
| - function MutationObserver(callback) {
|
| - var self = this;
|
| - this.impl = new OriginalMutationObserver(function(mutations, observer) {
|
| - callback.call(self, wrapRecords(mutations), self);
|
| - });
|
| - }
|
| -
|
| - var OriginalNode = window.Node;
|
| -
|
| - MutationObserver.prototype = {
|
| - observe: function(target, options) {
|
| - this.impl.observe(unwrapIfNeeded(target), options);
|
| - },
|
| - disconnect: function() {
|
| - this.impl.disconnect();
|
| - },
|
| - takeRecords: function() {
|
| - return wrapRecords(this.impl.takeRecords());
|
| - }
|
| - };
|
| -
|
| - scope.wrappers.MutationObserver = MutationObserver;
|
| - scope.wrappers.MutationRecord = MutationRecord;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var registerWrapper = scope.registerWrapper;
|
| - var unwrap = scope.unwrap;
|
| - var unwrapIfNeeded = scope.unwrapIfNeeded;
|
| - var wrap = scope.wrap;
|
| -
|
| - var OriginalRange = window.Range;
|
| -
|
| - function Range(impl) {
|
| - this.impl = impl;
|
| - }
|
| - Range.prototype = {
|
| - get startContainer() {
|
| - return wrap(this.impl.startContainer);
|
| - },
|
| - get endContainer() {
|
| - return wrap(this.impl.endContainer);
|
| - },
|
| - get commonAncestorContainer() {
|
| - return wrap(this.impl.commonAncestorContainer);
|
| - },
|
| - setStart: function(refNode,offset) {
|
| - this.impl.setStart(unwrapIfNeeded(refNode), offset);
|
| - },
|
| - setEnd: function(refNode,offset) {
|
| - this.impl.setEnd(unwrapIfNeeded(refNode), offset);
|
| - },
|
| - setStartBefore: function(refNode) {
|
| - this.impl.setStartBefore(unwrapIfNeeded(refNode));
|
| - },
|
| - setStartAfter: function(refNode) {
|
| - this.impl.setStartAfter(unwrapIfNeeded(refNode));
|
| - },
|
| - setEndBefore: function(refNode) {
|
| - this.impl.setEndBefore(unwrapIfNeeded(refNode));
|
| - },
|
| - setEndAfter: function(refNode) {
|
| - this.impl.setEndAfter(unwrapIfNeeded(refNode));
|
| - },
|
| - selectNode: function(refNode) {
|
| - this.impl.selectNode(unwrapIfNeeded(refNode));
|
| - },
|
| - selectNodeContents: function(refNode) {
|
| - this.impl.selectNodeContents(unwrapIfNeeded(refNode));
|
| - },
|
| - compareBoundaryPoints: function(how, sourceRange) {
|
| - return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));
|
| - },
|
| - extractContents: function() {
|
| - return wrap(this.impl.extractContents());
|
| - },
|
| - cloneContents: function() {
|
| - return wrap(this.impl.cloneContents());
|
| - },
|
| - insertNode: function(node) {
|
| - this.impl.insertNode(unwrapIfNeeded(node));
|
| - },
|
| - surroundContents: function(newParent) {
|
| - this.impl.surroundContents(unwrapIfNeeded(newParent));
|
| - },
|
| - cloneRange: function() {
|
| - return wrap(this.impl.cloneRange());
|
| - },
|
| - isPointInRange: function(node, offset) {
|
| - return this.impl.isPointInRange(unwrapIfNeeded(node), offset);
|
| - },
|
| - comparePoint: function(node, offset) {
|
| - return this.impl.comparePoint(unwrapIfNeeded(node), offset);
|
| - },
|
| - intersectsNode: function(node) {
|
| - return this.impl.intersectsNode(unwrapIfNeeded(node));
|
| - }
|
| - };
|
| -
|
| - // IE9 does not have createContextualFragment.
|
| - if (OriginalRange.prototype.createContextualFragment) {
|
| - Range.prototype.createContextualFragment = function(html) {
|
| - return wrap(this.impl.createContextualFragment(html));
|
| - };
|
| - }
|
| -
|
| - registerWrapper(window.Range, Range);
|
| -
|
| - scope.wrappers.Range = Range;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -
|
| -// Copyright 2013 The Polymer Authors. All rights reserved.
|
| -// Use of this source code is goverened by a BSD-style
|
| -// license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - 'use strict';
|
| -
|
| - var isWrapperFor = scope.isWrapperFor;
|
| -
|
| - // This is a list of the elements we currently override the global constructor
|
| - // for.
|
| - var elements = {
|
| - 'a': 'HTMLAnchorElement',
|
| - 'applet': 'HTMLAppletElement',
|
| - 'area': 'HTMLAreaElement',
|
| - 'audio': 'HTMLAudioElement',
|
| - 'br': 'HTMLBRElement',
|
| - 'base': 'HTMLBaseElement',
|
| - 'body': 'HTMLBodyElement',
|
| - 'button': 'HTMLButtonElement',
|
| - 'canvas': 'HTMLCanvasElement',
|
| - // 'command': 'HTMLCommandElement', // Not fully implemented in Gecko.
|
| - 'dl': 'HTMLDListElement',
|
| - 'datalist': 'HTMLDataListElement',
|
| - 'dir': 'HTMLDirectoryElement',
|
| - 'div': 'HTMLDivElement',
|
| - 'embed': 'HTMLEmbedElement',
|
| - 'fieldset': 'HTMLFieldSetElement',
|
| - 'font': 'HTMLFontElement',
|
| - 'form': 'HTMLFormElement',
|
| - 'frame': 'HTMLFrameElement',
|
| - 'frameset': 'HTMLFrameSetElement',
|
| - 'hr': 'HTMLHRElement',
|
| - 'head': 'HTMLHeadElement',
|
| - 'h1': 'HTMLHeadingElement',
|
| - 'html': 'HTMLHtmlElement',
|
| - 'iframe': 'HTMLIFrameElement',
|
| -
|
| - // Uses HTMLSpanElement in Firefox.
|
| - // https://bugzilla.mozilla.org/show_bug.cgi?id=843881
|
| - // 'image',
|
| -
|
| - 'input': 'HTMLInputElement',
|
| - 'li': 'HTMLLIElement',
|
| - 'label': 'HTMLLabelElement',
|
| - 'legend': 'HTMLLegendElement',
|
| - 'link': 'HTMLLinkElement',
|
| - 'map': 'HTMLMapElement',
|
| - // 'media', Covered by audio and video
|
| - 'menu': 'HTMLMenuElement',
|
| - 'menuitem': 'HTMLMenuItemElement',
|
| - 'meta': 'HTMLMetaElement',
|
| - 'meter': 'HTMLMeterElement',
|
| - 'del': 'HTMLModElement',
|
| - 'ol': 'HTMLOListElement',
|
| - 'object': 'HTMLObjectElement',
|
| - 'optgroup': 'HTMLOptGroupElement',
|
| - 'option': 'HTMLOptionElement',
|
| - 'output': 'HTMLOutputElement',
|
| - 'p': 'HTMLParagraphElement',
|
| - 'param': 'HTMLParamElement',
|
| - 'pre': 'HTMLPreElement',
|
| - 'progress': 'HTMLProgressElement',
|
| - 'q': 'HTMLQuoteElement',
|
| - 'script': 'HTMLScriptElement',
|
| - 'select': 'HTMLSelectElement',
|
| - 'source': 'HTMLSourceElement',
|
| - 'span': 'HTMLSpanElement',
|
| - 'style': 'HTMLStyleElement',
|
| - 'caption': 'HTMLTableCaptionElement',
|
| - // WebKit and Moz are wrong:
|
| - // https://bugs.webkit.org/show_bug.cgi?id=111469
|
| - // https://bugzilla.mozilla.org/show_bug.cgi?id=848096
|
| - // 'td': 'HTMLTableCellElement',
|
| - 'col': 'HTMLTableColElement',
|
| - 'table': 'HTMLTableElement',
|
| - 'tr': 'HTMLTableRowElement',
|
| - 'thead': 'HTMLTableSectionElement',
|
| - 'tbody': 'HTMLTableSectionElement',
|
| - 'textarea': 'HTMLTextAreaElement',
|
| - 'title': 'HTMLTitleElement',
|
| - 'ul': 'HTMLUListElement',
|
| - 'video': 'HTMLVideoElement',
|
| - };
|
| -
|
| - function overrideConstructor(tagName) {
|
| - var nativeConstructorName = elements[tagName];
|
| - var nativeConstructor = window[nativeConstructorName];
|
| - if (!nativeConstructor)
|
| - return;
|
| - var element = document.createElement(tagName);
|
| - var wrapperConstructor = element.constructor;
|
| - window[nativeConstructorName] = wrapperConstructor;
|
| - }
|
| -
|
| - Object.keys(elements).forEach(overrideConstructor);
|
| -
|
| - Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
|
| - window[name] = scope.wrappers[name]
|
| - });
|
| -
|
| - // Export for testing.
|
| - scope.knownElements = elements;
|
| -
|
| -})(this.ShadowDOMPolyfill);
|
| -/*
|
| - * Copyright 2013 The Polymer Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style
|
| - * license that can be found in the LICENSE file.
|
| - */
|
| -(function() {
|
| - var ShadowDOMPolyfill = window.ShadowDOMPolyfill;
|
| - var wrap = ShadowDOMPolyfill.wrap;
|
| -
|
| - // patch in prefixed name
|
| - Object.defineProperties(HTMLElement.prototype, {
|
| - //TODO(sjmiles): review accessor alias with Arv
|
| - webkitShadowRoot: {
|
| - get: function() {
|
| - return this.shadowRoot;
|
| - }
|
| - }
|
| - });
|
| -
|
| - //TODO(sjmiles): review method alias with Arv
|
| - HTMLElement.prototype.webkitCreateShadowRoot =
|
| - HTMLElement.prototype.createShadowRoot;
|
| -
|
| - // TODO(jmesserly): we need to wrap document somehow (a dart:html hook?)
|
| - window.dartExperimentalFixupGetTag = function(originalGetTag) {
|
| - var NodeList = ShadowDOMPolyfill.wrappers.NodeList;
|
| - var ShadowRoot = ShadowDOMPolyfill.wrappers.ShadowRoot;
|
| - var unwrapIfNeeded = ShadowDOMPolyfill.unwrapIfNeeded;
|
| - function getTag(obj) {
|
| - // TODO(jmesserly): do we still need these?
|
| - if (obj instanceof NodeList) return 'NodeList';
|
| - if (obj instanceof ShadowRoot) return 'ShadowRoot';
|
| - if (window.MutationRecord && (obj instanceof MutationRecord))
|
| - return 'MutationRecord';
|
| - if (window.MutationObserver && (obj instanceof MutationObserver))
|
| - return 'MutationObserver';
|
| -
|
| - var unwrapped = unwrapIfNeeded(obj);
|
| - if (obj !== unwrapped) {
|
| - // Fix up class names for Firefox.
|
| - // For some of them (like HTMLFormElement and HTMLInputElement),
|
| - // the "constructor" property of the unwrapped nodes points at the
|
| - // same constructor as the wrapper.
|
| - var ctor = obj.constructor
|
| - if (ctor === unwrapped.constructor) {
|
| - var name = ctor._ShadowDOMPolyfill$cacheTag_;
|
| - if (!name) {
|
| - name = Object.prototype.toString.call(unwrapped);
|
| - name = name.substring(8, name.length - 1);
|
| - ctor._ShadowDOMPolyfill$cacheTag_ = name;
|
| - }
|
| - return name;
|
| - }
|
| -
|
| - obj = unwrapped;
|
| - }
|
| - return originalGetTag(obj);
|
| - }
|
| -
|
| - return getTag;
|
| - };
|
| -})();
|
| -
|
| -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -var Platform = {};
|
| -
|
| -/*
|
| - * Copyright 2012 The Polymer Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style
|
| - * license that can be found in the LICENSE file.
|
| - */
|
| -
|
| -/*
|
| - This is a limited shim for ShadowDOM css styling.
|
| - https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles
|
| -
|
| - The intention here is to support only the styling features which can be
|
| - relatively simply implemented. The goal is to allow users to avoid the
|
| - most obvious pitfalls and do so without compromising performance significantly.
|
| - For ShadowDOM styling that's not covered here, a set of best practices
|
| - can be provided that should allow users to accomplish more complex styling.
|
| -
|
| - The following is a list of specific ShadowDOM styling features and a brief
|
| - discussion of the approach used to shim.
|
| -
|
| - Shimmed features:
|
| -
|
| - * @host: ShadowDOM allows styling of the shadowRoot's host element using the
|
| - @host rule. To shim this feature, the @host styles are reformatted and
|
| - prefixed with a given scope name and promoted to a document level stylesheet.
|
| - For example, given a scope name of .foo, a rule like this:
|
| -
|
| - @host {
|
| - * {
|
| - background: red;
|
| - }
|
| - }
|
| -
|
| - becomes:
|
| -
|
| - .foo {
|
| - background: red;
|
| - }
|
| -
|
| - * encapsultion: Styles defined within ShadowDOM, apply only to
|
| - dom inside the ShadowDOM. Polymer uses one of two techniques to imlement
|
| - this feature.
|
| -
|
| - By default, rules are prefixed with the host element tag name
|
| - as a descendant selector. This ensures styling does not leak out of the 'top'
|
| - of the element's ShadowDOM. For example,
|
| -
|
| - div {
|
| - font-weight: bold;
|
| - }
|
| -
|
| - becomes:
|
| -
|
| - x-foo div {
|
| - font-weight: bold;
|
| - }
|
| -
|
| - becomes:
|
| -
|
| -
|
| - Alternatively, if Platform.ShadowCSS.strictStyling is set to true then
|
| - selectors are scoped by adding an attribute selector suffix to each
|
| - simple selector that contains the host element tag name. Each element
|
| - in the element's ShadowDOM template is also given the scope attribute.
|
| - Thus, these rules match only elements that have the scope attribute.
|
| - For example, given a scope name of x-foo, a rule like this:
|
| -
|
| - div {
|
| - font-weight: bold;
|
| - }
|
| -
|
| - becomes:
|
| -
|
| - div[x-foo] {
|
| - font-weight: bold;
|
| - }
|
| -
|
| - Note that elements that are dynamically added to a scope must have the scope
|
| - selector added to them manually.
|
| -
|
| - * ::pseudo: These rules are converted to rules that take advantage of the
|
| - pseudo attribute. For example, a shadowRoot like this inside an x-foo
|
| -
|
| - <div pseudo="x-special">Special</div>
|
| -
|
| - with a rule like this:
|
| -
|
| - x-foo::x-special { ... }
|
| -
|
| - becomes:
|
| -
|
| - x-foo [pseudo=x-special] { ... }
|
| -
|
| - Unaddressed ShadowDOM styling features:
|
| -
|
| - * upper/lower bound encapsulation: Styles which are defined outside a
|
| - shadowRoot should not cross the ShadowDOM boundary and should not apply
|
| - inside a shadowRoot.
|
| -
|
| - This styling behavior is not emulated. Some possible ways to do this that
|
| - were rejected due to complexity and/or performance concerns include: (1) reset
|
| - every possible property for every possible selector for a given scope name;
|
| - (2) re-implement css in javascript.
|
| -
|
| - As an alternative, users should make sure to use selectors
|
| - specific to the scope in which they are working.
|
| -
|
| - * ::distributed: This behavior is not emulated. It's often not necessary
|
| - to style the contents of a specific insertion point and instead, descendants
|
| - of the host element can be styled selectively. Users can also create an
|
| - extra node around an insertion point and style that node's contents
|
| - via descendent selectors. For example, with a shadowRoot like this:
|
| -
|
| - <style>
|
| - content::-webkit-distributed(div) {
|
| - background: red;
|
| - }
|
| - </style>
|
| - <content></content>
|
| -
|
| - could become:
|
| -
|
| - <style>
|
| - / *@polyfill .content-container div * /
|
| - content::-webkit-distributed(div) {
|
| - background: red;
|
| - }
|
| - </style>
|
| - <div class="content-container">
|
| - <content></content>
|
| - </div>
|
| -
|
| - Note the use of @polyfill in the comment above a ShadowDOM specific style
|
| - declaration. This is a directive to the styling shim to use the selector
|
| - in comments in lieu of the next selector when running under polyfill.
|
| -*/
|
| -(function(scope) {
|
| -
|
| -var ShadowCSS = {
|
| - strictStyling: false,
|
| - registry: {},
|
| - // Shim styles for a given root associated with a name and extendsName
|
| - // 1. cache root styles by name
|
| - // 2. optionally tag root nodes with scope name
|
| - // 3. shim polyfill directives /* @polyfill */
|
| - // 4. shim @host and scoping
|
| - shimStyling: function(root, name, extendsName) {
|
| - if (root) {
|
| - // use caching to make working with styles nodes easier and to facilitate
|
| - // lookup of extendee
|
| - var def = this.registerDefinition(root, name, extendsName);
|
| - // find styles and apply shimming...
|
| - if (this.strictStyling) {
|
| - this.applyScopeToContent(root, name);
|
| - }
|
| - this.shimPolyfillDirectives(def.rootStyles, name);
|
| - this.applyShimming(def.scopeStyles, name);
|
| - }
|
| - },
|
| - // Shim styles to be placed inside a shadowRoot.
|
| - // 1. shim polyfill directives /* @polyfill */
|
| - // 2. shim @host and scoping
|
| - shimShadowDOMStyling: function(styles, name) {
|
| - this.shimPolyfillDirectives(styles, name);
|
| - this.applyShimming(styles, name);
|
| - },
|
| - registerDefinition: function(root, name, extendsName) {
|
| - var def = this.registry[name] = {
|
| - root: root,
|
| - name: name,
|
| - extendsName: extendsName
|
| - }
|
| - var styles = root.querySelectorAll('style');
|
| - styles = styles ? Array.prototype.slice.call(styles, 0) : [];
|
| - def.rootStyles = styles;
|
| - def.scopeStyles = def.rootStyles;
|
| - var extendee = this.registry[def.extendsName];
|
| - if (extendee) {
|
| - def.scopeStyles = def.scopeStyles.concat(extendee.scopeStyles);
|
| - }
|
| - return def;
|
| - },
|
| - applyScopeToContent: function(root, name) {
|
| - if (root) {
|
| - // add the name attribute to each node in root.
|
| - Array.prototype.forEach.call(root.querySelectorAll('*'),
|
| - function(node) {
|
| - node.setAttribute(name, '');
|
| - });
|
| - // and template contents too
|
| - Array.prototype.forEach.call(root.querySelectorAll('template'),
|
| - function(template) {
|
| - this.applyScopeToContent(template.content, name);
|
| - },
|
| - this);
|
| - }
|
| - },
|
| - /*
|
| - * Process styles to convert native ShadowDOM rules that will trip
|
| - * up the css parser; we rely on decorating the stylesheet with comments.
|
| - *
|
| - * For example, we convert this rule:
|
| - *
|
| - * (comment start) @polyfill @host g-menu-item (comment end)
|
| - * shadow::-webkit-distributed(g-menu-item) {
|
| - *
|
| - * to this:
|
| - *
|
| - * scopeName g-menu-item {
|
| - *
|
| - **/
|
| - shimPolyfillDirectives: function(styles, name) {
|
| - if (styles) {
|
| - Array.prototype.forEach.call(styles, function(s) {
|
| - s.textContent = this.convertPolyfillDirectives(s.textContent, name);
|
| - }, this);
|
| - }
|
| - },
|
| - convertPolyfillDirectives: function(cssText, name) {
|
| - var r = '', l = 0, matches, selector;
|
| - while (matches = cssPolyfillCommentRe.exec(cssText)) {
|
| - r += cssText.substring(l, matches.index);
|
| - // remove end comment delimiter (*/)
|
| - selector = matches[1].slice(0, -2).replace(hostRe, name);
|
| - r += this.scopeSelector(selector, name) + '{';
|
| - l = cssPolyfillCommentRe.lastIndex;
|
| - }
|
| - r += cssText.substring(l, cssText.length);
|
| - return r;
|
| - },
|
| - // apply @host and scope shimming
|
| - applyShimming: function(styles, name) {
|
| - var cssText = this.shimAtHost(styles, name);
|
| - cssText += this.shimScoping(styles, name);
|
| - addCssToDocument(cssText);
|
| - },
|
| - // form: @host { .foo { declarations } }
|
| - // becomes: scopeName.foo { declarations }
|
| - shimAtHost: function(styles, name) {
|
| - if (styles) {
|
| - return this.convertAtHostStyles(styles, name);
|
| - }
|
| - },
|
| - convertAtHostStyles: function(styles, name) {
|
| - var cssText = stylesToCssText(styles);
|
| - var r = '', l=0, matches;
|
| - while (matches = hostRuleRe.exec(cssText)) {
|
| - r += cssText.substring(l, matches.index);
|
| - r += this.scopeHostCss(matches[1], name);
|
| - l = hostRuleRe.lastIndex;
|
| - }
|
| - r += cssText.substring(l, cssText.length);
|
| - var re = new RegExp('^' + name + selectorReSuffix, 'm');
|
| - var cssText = rulesToCss(this.findAtHostRules(cssToRules(r),
|
| - re));
|
| - return cssText;
|
| - },
|
| - scopeHostCss: function(cssText, name) {
|
| - var r = '', matches;
|
| - while (matches = selectorRe.exec(cssText)) {
|
| - r += this.scopeHostSelector(matches[1], name) +' ' + matches[2] + '\n\t';
|
| - }
|
| - return r;
|
| - },
|
| - // supports scopig by name and [is=name] syntax
|
| - scopeHostSelector: function(selector, name) {
|
| - var r = [], parts = selector.split(','), is = '[is=' + name + ']';
|
| - parts.forEach(function(p) {
|
| - p = p.trim();
|
| - // selector: *|:scope -> name
|
| - if (p.match(hostElementRe)) {
|
| - p = p.replace(hostElementRe, name + '$1$3, ' + is + '$1$3');
|
| - // selector: .foo -> name.foo, [bar] -> name[bar]
|
| - } else if (p.match(hostFixableRe)) {
|
| - p = name + p + ', ' + is + p;
|
| - }
|
| - r.push(p);
|
| - }, this);
|
| - return r.join(', ');
|
| - },
|
| - // consider styles that do not include component name in the selector to be
|
| - // unscoped and in need of promotion;
|
| - // for convenience, also consider keyframe rules this way.
|
| - findAtHostRules: function(cssRules, matcher) {
|
| - return Array.prototype.filter.call(cssRules,
|
| - this.isHostRule.bind(this, matcher));
|
| - },
|
| - isHostRule: function(matcher, cssRule) {
|
| - return (cssRule.selectorText && cssRule.selectorText.match(matcher)) ||
|
| - (cssRule.cssRules && this.findAtHostRules(cssRule.cssRules, matcher).length) ||
|
| - (cssRule.type == CSSRule.WEBKIT_KEYFRAMES_RULE);
|
| - },
|
| - /* Ensure styles are scoped. Pseudo-scoping takes a rule like:
|
| - *
|
| - * .foo {... }
|
| - *
|
| - * and converts this to
|
| - *
|
| - * scopeName .foo { ... }
|
| - */
|
| - shimScoping: function(styles, name) {
|
| - if (styles) {
|
| - return this.convertScopedStyles(styles, name);
|
| - }
|
| - },
|
| - convertScopedStyles: function(styles, name) {
|
| - Array.prototype.forEach.call(styles, function(s) {
|
| - if (s.parentNode) {
|
| - s.parentNode.removeChild(s);
|
| - }
|
| - });
|
| - var cssText = stylesToCssText(styles).replace(hostRuleRe, '');
|
| - cssText = this.convertPseudos(cssText);
|
| - var rules = cssToRules(cssText);
|
| - cssText = this.scopeRules(rules, name);
|
| - return cssText;
|
| - },
|
| - convertPseudos: function(cssText) {
|
| - return cssText.replace(cssPseudoRe, ' [pseudo=$1]');
|
| - },
|
| - // change a selector like 'div' to 'name div'
|
| - scopeRules: function(cssRules, name) {
|
| - var cssText = '';
|
| - Array.prototype.forEach.call(cssRules, function(rule) {
|
| - if (rule.selectorText && (rule.style && rule.style.cssText)) {
|
| - cssText += this.scopeSelector(rule.selectorText, name,
|
| - this.strictStyling) + ' {\n\t';
|
| - cssText += this.propertiesFromRule(rule) + '\n}\n\n';
|
| - } else if (rule.media) {
|
| - cssText += '@media ' + rule.media.mediaText + ' {\n';
|
| - cssText += this.scopeRules(rule.cssRules, name);
|
| - cssText += '\n}\n\n';
|
| - } else if (rule.cssText) {
|
| - cssText += rule.cssText + '\n\n';
|
| - }
|
| - }, this);
|
| - return cssText;
|
| - },
|
| - scopeSelector: function(selector, name, strict) {
|
| - var r = [], parts = selector.split(',');
|
| - parts.forEach(function(p) {
|
| - p = p.trim();
|
| - if (this.selectorNeedsScoping(p, name)) {
|
| - p = strict ? this.applyStrictSelectorScope(p, name) :
|
| - this.applySimpleSelectorScope(p, name);
|
| - }
|
| - r.push(p);
|
| - }, this);
|
| - return r.join(', ');
|
| - },
|
| - selectorNeedsScoping: function(selector, name) {
|
| - var matchScope = '(' + name + '|\\[is=' + name + '\\])';
|
| - var re = new RegExp('^' + matchScope + selectorReSuffix, 'm');
|
| - return !selector.match(re);
|
| - },
|
| - // scope via name and [is=name]
|
| - applySimpleSelectorScope: function(selector, name) {
|
| - return name + ' ' + selector + ', ' + '[is=' + name + '] ' + selector;
|
| - },
|
| - // return a selector with [name] suffix on each simple selector
|
| - // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]
|
| - applyStrictSelectorScope: function(selector, name) {
|
| - var splits = [' ', '>', '+', '~'],
|
| - scoped = selector,
|
| - attrName = '[' + name + ']';
|
| - splits.forEach(function(sep) {
|
| - var parts = scoped.split(sep);
|
| - scoped = parts.map(function(p) {
|
| - var t = p.trim();
|
| - if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {
|
| - p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3')
|
| - }
|
| - return p;
|
| - }).join(sep);
|
| - });
|
| - return scoped;
|
| - },
|
| - propertiesFromRule: function(rule) {
|
| - var properties = rule.style.cssText;
|
| - // TODO(sorvell): Chrome cssom incorrectly removes quotes from the content
|
| - // property. (https://code.google.com/p/chromium/issues/detail?id=247231)
|
| - if (rule.style.content && !rule.style.content.match(/['"]+/)) {
|
| - properties = 'content: \'' + rule.style.content + '\';\n' +
|
| - rule.style.cssText.replace(/content:[^;]*;/g, '');
|
| - }
|
| - return properties;
|
| - }
|
| -};
|
| -
|
| -var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,
|
| - selectorRe = /([^{]*)({[\s\S]*?})/gim,
|
| - hostElementRe = /(.*)((?:\*)|(?:\:scope))(.*)/,
|
| - hostFixableRe = /^[.\[:]/,
|
| - cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
|
| - cssPolyfillCommentRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,
|
| - cssPseudoRe = /::(x-[^\s{,(]*)/gim,
|
| - selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
|
| - hostRe = /@host/gim;
|
| -
|
| -function stylesToCssText(styles, preserveComments) {
|
| - var cssText = '';
|
| - Array.prototype.forEach.call(styles, function(s) {
|
| - cssText += s.textContent + '\n\n';
|
| - });
|
| - // strip comments for easier processing
|
| - if (!preserveComments) {
|
| - cssText = cssText.replace(cssCommentRe, '');
|
| - }
|
| - return cssText;
|
| -}
|
| -
|
| -function cssToRules(cssText) {
|
| - var style = document.createElement('style');
|
| - style.textContent = cssText;
|
| - document.head.appendChild(style);
|
| - var rules = style.sheet.cssRules;
|
| - style.parentNode.removeChild(style);
|
| - return rules;
|
| -}
|
| -
|
| -function rulesToCss(cssRules) {
|
| - for (var i=0, css=[]; i < cssRules.length; i++) {
|
| - css.push(cssRules[i].cssText);
|
| - }
|
| - return css.join('\n\n');
|
| -}
|
| -
|
| -function addCssToDocument(cssText) {
|
| - if (cssText) {
|
| - getSheet().appendChild(document.createTextNode(cssText));
|
| - }
|
| -}
|
| -
|
| -var sheet;
|
| -function getSheet() {
|
| - if (!sheet) {
|
| - sheet = document.createElement("style");
|
| - sheet.setAttribute('ShadowCSSShim', '');
|
| - }
|
| - return sheet;
|
| -}
|
| -
|
| -// add polyfill stylesheet to document
|
| -if (window.ShadowDOMPolyfill) {
|
| - addCssToDocument('style { display: none !important; }\n');
|
| - var head = document.querySelector('head');
|
| - head.insertBefore(getSheet(), head.childNodes[0]);
|
| -}
|
| -
|
| -// exports
|
| -scope.ShadowCSS = ShadowCSS;
|
| -
|
| -})(window.Platform);
|
| -// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -(function(scope) {
|
| - // TODO(terry): Remove shimShadowDOMStyling2 until wrap/unwrap from a
|
| - // dart:html Element to a JS DOM node is available.
|
| - /**
|
| - * Given the content of a STYLE tag and the name of a component shim the CSS
|
| - * and return the new scoped CSS to replace the STYLE's content. The content
|
| - * is replaced in Dart's implementation of PolymerElement.
|
| - */
|
| - function shimShadowDOMStyling2(styleContent, name) {
|
| - if (window.ShadowDOMPolyfill) {
|
| - var content = this.convertPolyfillDirectives(styleContent, name);
|
| -
|
| - // applyShimming calls shimAtHost and shipScoping
|
| - // shimAtHost code:
|
| - var r = '', l=0, matches;
|
| - while (matches = hostRuleRe.exec(content)) {
|
| - r += content.substring(l, matches.index);
|
| - r += this.scopeHostCss(matches[1], name);
|
| - l = hostRuleRe.lastIndex;
|
| - }
|
| - r += content.substring(l, content.length);
|
| - var re = new RegExp('^' + name + selectorReSuffix, 'm');
|
| - var atHostCssText = rulesToCss(this.findAtHostRules(cssToRules(r), re));
|
| -
|
| - // shimScoping code:
|
| - // strip comments for easier processing
|
| - content = content.replace(cssCommentRe, '');
|
| -
|
| - content = this.convertPseudos(content);
|
| - var rules = cssToRules(content);
|
| - var cssText = this.scopeRules(rules, name);
|
| -
|
| - return atHostCssText + cssText;
|
| - }
|
| - }
|
| -
|
| - // Minimal copied code from ShadowCSS, that is not exposed in
|
| - // PlatForm.ShadowCSS (local code).
|
| - var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,
|
| - cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
|
| - selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$';
|
| -
|
| - function cssToRules(cssText) {
|
| - var style = document.createElement('style');
|
| - style.textContent = cssText;
|
| - document.head.appendChild(style);
|
| - var rules = style.sheet.cssRules;
|
| - style.parentNode.removeChild(style);
|
| - return rules;
|
| - }
|
| -
|
| - function rulesToCss(cssRules) {
|
| - for (var i=0, css=[]; i < cssRules.length; i++) {
|
| - css.push(cssRules[i].cssText);
|
| - }
|
| - return css.join('\n\n');
|
| - }
|
| -
|
| - // exports
|
| - scope.ShadowCSS.shimShadowDOMStyling2 = shimShadowDOMStyling2;
|
| -})(window.Platform);
|
| -
|
| -}
|
|
|