Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(101)

Unified Diff: pkg/shadow_dom/lib/shadow_dom.debug.js

Issue 158083002: introduce web_components pkg for consolidated polyfills (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/shadow_dom/lib/shadow_dom.debug.js
diff --git a/pkg/shadow_dom/lib/shadow_dom.debug.js b/pkg/shadow_dom/lib/shadow_dom.debug.js
deleted file mode 100644
index f411852d5eb1aea73001f3be60b3f21a61691b76..0000000000000000000000000000000000000000
--- a/pkg/shadow_dom/lib/shadow_dom.debug.js
+++ /dev/null
@@ -1,7551 +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';
-
- var PROP_ADD_TYPE = 'add';
- var PROP_UPDATE_TYPE = 'update';
- var PROP_RECONFIGURE_TYPE = 'reconfigure';
- var PROP_DELETE_TYPE = 'delete';
- var ARRAY_SPLICE_TYPE = 'splice';
-
- // Detect and do basic sanity checking on Object/Array.observe.
- function detectObjectObserve() {
- if (typeof Object.observe !== 'function' ||
- typeof Array.observe !== 'function') {
- return false;
- }
-
- var records = [];
-
- function callback(recs) {
- records = recs;
- }
-
- var test = {};
- Object.observe(test, callback);
- test.id = 1;
- test.id = 2;
- delete test.id;
- Object.deliverChangeRecords(callback);
- if (records.length !== 3)
- return false;
-
- // TODO(rafaelw): Remove this when new change record type names make it to
- // chrome release.
- if (records[0].type == 'new' &&
- records[1].type == 'updated' &&
- records[2].type == 'deleted') {
- PROP_ADD_TYPE = 'new';
- PROP_UPDATE_TYPE = 'updated';
- PROP_RECONFIGURE_TYPE = 'reconfigured';
- PROP_DELETE_TYPE = 'deleted';
- } else if (records[0].type != 'add' ||
- records[1].type != 'update' ||
- records[2].type != 'delete') {
- console.error('Unexpected change record names for Object.observe. ' +
- 'Using dirty-checking instead');
- return false;
- }
- Object.unobserve(test, callback);
-
- test = [0];
- Array.observe(test, callback);
- test[1] = 1;
- test.length = 0;
- Object.deliverChangeRecords(callback);
- if (records.length != 2)
- return false;
- if (records[0].type != ARRAY_SPLICE_TYPE ||
- records[1].type != ARRAY_SPLICE_TYPE) {
- return false;
- }
- Array.unobserve(test, callback);
-
- return true;
- }
-
- 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 && 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, directObserver) {
- for (var i = 0; i < this.length; i++) {
- if (obj == null)
- return;
- obj = obj[this[i]];
- }
- return obj;
- },
-
- iterateObjects: function(obj, observe) {
- for (var i = 0; i < this.length; i++) {
- if (i)
- obj = obj[this[i - 1]];
- if (!obj)
- return;
- observe(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_()) {
- cycles++;
- }
- if (global.testingExposeCycleCount)
- global.dirtyCheckCycleCount = cycles;
-
- return cycles > 0;
- }
-
- 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
- };
- }
-
- var eomTasks = [];
- function runEOMTasks() {
- if (!eomTasks.length)
- return false;
-
- for (var i = 0; i < eomTasks.length; i++) {
- eomTasks[i]();
- }
- eomTasks.length = 0;
- return true;
- }
-
- var runEOM = hasObserve ? (function(){
- var eomObj = { pingPong: true };
- var eomRunScheduled = false;
-
- Object.observe(eomObj, function() {
- runEOMTasks();
- eomRunScheduled = false;
- });
-
- return function(fn) {
- eomTasks.push(fn);
- if (!eomRunScheduled) {
- eomRunScheduled = true;
- eomObj.pingPong = !eomObj.pingPong;
- }
- };
- })() :
- (function() {
- return function(fn) {
- eomTasks.push(fn);
- };
- })();
-
- var observedObjectCache = [];
-
- function newObservedObject() {
- var observer;
- var object;
- var discardRecords = false;
- var first = true;
-
- function callback(records) {
- if (observer && observer.state_ === OPENED && !discardRecords)
- observer.check_(records);
- }
-
- return {
- open: function(obs) {
- if (observer)
- throw Error('ObservedObject in use');
-
- if (!first)
- Object.deliverChangeRecords(callback);
-
- observer = obs;
- first = false;
- },
- observe: function(obj, arrayObserve) {
- object = obj;
- if (arrayObserve)
- Array.observe(object, callback);
- else
- Object.observe(object, callback);
- },
- deliver: function(discard) {
- discardRecords = discard;
- Object.deliverChangeRecords(callback);
- discardRecords = false;
- },
- close: function() {
- observer = undefined;
- Object.unobserve(object, callback);
- observedObjectCache.push(this);
- }
- };
- }
-
- function getObservedObject(observer, object, arrayObserve) {
- var dir = observedObjectCache.pop() || newObservedObject();
- dir.open(observer);
- dir.observe(object, arrayObserve);
- return dir;
- }
-
- var emptyArray = [];
- var observedSetCache = [];
-
- function newObservedSet() {
- var observers = [];
- var observerCount = 0;
- var objects = [];
- var toRemove = emptyArray;
- var resetNeeded = false;
- var resetScheduled = false;
-
- function observe(obj) {
- if (!isObject(obj))
- return;
-
- var index = toRemove.indexOf(obj);
- if (index >= 0) {
- toRemove[index] = undefined;
- objects.push(obj);
- } else if (objects.indexOf(obj) < 0) {
- objects.push(obj);
- Object.observe(obj, callback);
- }
-
- observe(Object.getPrototypeOf(obj));
- }
-
- function reset() {
- resetScheduled = false;
- if (!resetNeeded)
- return;
-
- var objs = toRemove === emptyArray ? [] : toRemove;
- toRemove = objects;
- objects = objs;
-
- var observer;
- for (var id in observers) {
- observer = observers[id];
- if (!observer || observer.state_ != OPENED)
- continue;
-
- observer.iterateObjects_(observe);
- }
-
- for (var i = 0; i < toRemove.length; i++) {
- var obj = toRemove[i];
- if (obj)
- Object.unobserve(obj, callback);
- }
-
- toRemove.length = 0;
- }
-
- function scheduleReset() {
- if (resetScheduled)
- return;
-
- resetNeeded = true;
- resetScheduled = true;
- runEOM(reset);
- }
-
- function callback() {
- var observer;
-
- for (var id in observers) {
- observer = observers[id];
- if (!observer || observer.state_ != OPENED)
- continue;
-
- observer.check_();
- }
-
- scheduleReset();
- }
-
- var record = {
- object: undefined,
- objects: objects,
- open: function(obs) {
- observers[obs.id_] = obs;
- observerCount++;
- obs.iterateObjects_(observe);
- },
- close: function(obs) {
- var anyLeft = false;
-
- observers[obs.id_] = undefined;
- observerCount--;
-
- if (observerCount) {
- scheduleReset();
- return;
- }
- resetNeeded = false;
-
- for (var i = 0; i < objects.length; i++) {
- Object.unobserve(objects[i], callback);
- Observer.unobservedCount++;
- }
-
- observers.length = 0;
- objects.length = 0;
- observedSetCache.push(this);
- },
- reset: scheduleReset
- };
-
- return record;
- }
-
- var lastObservedSet;
-
- function getObservedSet(observer, obj) {
- if (!lastObservedSet || lastObservedSet.object !== obj) {
- lastObservedSet = observedSetCache.pop() || newObservedSet();
- lastObservedSet.object = obj;
- }
- lastObservedSet.open(observer);
- return lastObservedSet;
- }
-
- var UNOPENED = 0;
- var OPENED = 1;
- var CLOSED = 2;
- var RESETTING = 3;
-
- var nextObserverId = 1;
-
- function Observer() {
- this.state_ = UNOPENED;
- this.callback_ = undefined;
- this.target_ = undefined; // TODO(rafaelw): Should be WeakRef
- this.directObserver_ = undefined;
- this.value_ = undefined;
- this.id_ = nextObserverId++;
- }
-
- Observer.prototype = {
- open: function(callback, target) {
- if (this.state_ != UNOPENED)
- throw Error('Observer has already been opened.');
-
- addToAll(this);
- this.callback_ = callback;
- this.target_ = target;
- this.state_ = OPENED;
- this.connect_();
- return this.value_;
- },
-
- close: function() {
- if (this.state_ != OPENED)
- return;
-
- removeFromAll(this);
- this.state_ = CLOSED;
- this.disconnect_();
- this.value_ = undefined;
- this.callback_ = undefined;
- this.target_ = undefined;
- },
-
- deliver: function() {
- if (this.state_ != OPENED)
- return;
-
- dirtyCheck(this);
- },
-
- report_: function(changes) {
- try {
- this.callback_.apply(this.target_, changes);
- } catch (ex) {
- Observer._errorThrownDuringCallback = true;
- console.error('Exception caught during observer callback: ' +
- (ex.stack || ex));
- }
- },
-
- discardChanges: function() {
- this.check_(undefined, true);
- return this.value_;
- }
- }
-
- var collectObservers = !hasObserve;
- var allObservers;
- Observer._allObserversCount = 0;
-
- if (collectObservers) {
- allObservers = [];
- }
-
- function addToAll(observer) {
- Observer._allObserversCount++;
- if (!collectObservers)
- return;
-
- allObservers.push(observer);
- }
-
- function removeFromAll(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 anyChanged, toCheck;
-
- do {
- cycles++;
- toCheck = allObservers;
- allObservers = [];
- anyChanged = false;
-
- for (var i = 0; i < toCheck.length; i++) {
- var observer = toCheck[i];
- if (observer.state_ != OPENED)
- continue;
-
- if (observer.check_())
- anyChanged = true;
-
- allObservers.push(observer);
- }
- if (runEOMTasks())
- anyChanged = true;
- } while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);
-
- if (global.testingExposeCycleCount)
- global.dirtyCheckCycleCount = cycles;
-
- runningMicrotaskCheckpoint = false;
- };
-
- if (collectObservers) {
- global.Platform.clearObservers = function() {
- allObservers = [];
- };
- }
-
- function ObjectObserver(object) {
- Observer.call(this);
- this.value_ = object;
- this.oldObject_ = undefined;
- }
-
- ObjectObserver.prototype = createObject({
- __proto__: Observer.prototype,
-
- arrayObserve: false,
-
- connect_: function(callback, target) {
- if (hasObserve) {
- this.directObserver_ = getObservedObject(this, this.value_,
- this.arrayObserve);
- } else {
- this.oldObject_ = this.copyObject(this.value_);
- }
-
- },
-
- copyObject: function(object) {
- var copy = Array.isArray(object) ? [] : {};
- for (var prop in object) {
- copy[prop] = object[prop];
- };
- if (Array.isArray(object))
- copy.length = object.length;
- return copy;
- },
-
- check_: function(changeRecords, skipChanges) {
- var diff;
- var oldValues;
- if (hasObserve) {
- if (!changeRecords)
- return false;
-
- oldValues = {};
- diff = diffObjectFromChangeRecords(this.value_, changeRecords,
- oldValues);
- } else {
- oldValues = this.oldObject_;
- diff = diffObjectFromOldObject(this.value_, this.oldObject_);
- }
-
- if (diffIsEmpty(diff))
- return false;
-
- if (!hasObserve)
- this.oldObject_ = this.copyObject(this.value_);
-
- this.report_([
- diff.added || {},
- diff.removed || {},
- diff.changed || {},
- function(property) {
- return oldValues[property];
- }
- ]);
-
- return true;
- },
-
- disconnect_: function() {
- if (hasObserve) {
- this.directObserver_.close();
- this.directObserver_ = undefined;
- } else {
- this.oldObject_ = undefined;
- }
- },
-
- deliver: function() {
- if (this.state_ != OPENED)
- return;
-
- if (hasObserve)
- this.directObserver_.deliver(false);
- else
- dirtyCheck(this);
- },
-
- discardChanges: function() {
- if (this.directObserver_)
- this.directObserver_.deliver(true);
- else
- this.oldObject_ = this.copyObject(this.value_);
-
- return this.value_;
- }
- });
-
- function ArrayObserver(array) {
- if (!Array.isArray(array))
- throw Error('Provided object is not an Array');
- ObjectObserver.call(this, array);
- }
-
- ArrayObserver.prototype = createObject({
-
- __proto__: ObjectObserver.prototype,
-
- arrayObserve: true,
-
- copyObject: function(arr) {
- return arr.slice();
- },
-
- check_: function(changeRecords) {
- var splices;
- if (hasObserve) {
- if (!changeRecords)
- return false;
- splices = projectArraySplices(this.value_, changeRecords);
- } else {
- splices = calcSplices(this.value_, 0, this.value_.length,
- this.oldObject_, 0, this.oldObject_.length);
- }
-
- if (!splices || !splices.length)
- return false;
-
- if (!hasObserve)
- this.oldObject_ = this.copyObject(this.value_);
-
- this.report_([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 PathObserver(object, path) {
- Observer.call(this);
-
- this.object_ = object;
- this.path_ = path instanceof Path ? path : getPath(path);
- this.directObserver_ = undefined;
- }
-
- PathObserver.prototype = createObject({
- __proto__: Observer.prototype,
-
- connect_: function() {
- if (hasObserve)
- this.directObserver_ = getObservedSet(this, this.object_);
-
- this.check_(undefined, true);
- },
-
- disconnect_: function() {
- this.value_ = undefined;
-
- if (this.directObserver_) {
- this.directObserver_.close(this);
- this.directObserver_ = undefined;
- }
- },
-
- iterateObjects_: function(observe) {
- this.path_.iterateObjects(this.object_, observe);
- },
-
- check_: function(changeRecords, skipChanges) {
- var oldValue = this.value_;
- this.value_ = this.path_.getValueFrom(this.object_);
- if (skipChanges || areSameValue(this.value_, oldValue))
- return false;
-
- this.report_([this.value_, oldValue]);
- return true;
- },
-
- setValue: function(newValue) {
- if (this.path_)
- this.path_.setValueFrom(this.object_, newValue);
- }
- });
-
- function CompoundObserver() {
- Observer.call(this);
-
- this.value_ = [];
- this.directObserver_ = undefined;
- this.observed_ = [];
- }
-
- var observerSentinel = {};
-
- CompoundObserver.prototype = createObject({
- __proto__: Observer.prototype,
-
- connect_: function() {
- this.check_(undefined, true);
-
- if (!hasObserve)
- return;
-
- var object;
- var needsDirectObserver = false;
- for (var i = 0; i < this.observed_.length; i += 2) {
- object = this.observed_[i]
- if (object !== observerSentinel) {
- needsDirectObserver = true;
- break;
- }
- }
-
- if (this.directObserver_) {
- if (needsDirectObserver) {
- this.directObserver_.reset();
- return;
- }
- this.directObserver_.close();
- this.directObserver_ = undefined;
- return;
- }
-
- if (needsDirectObserver)
- this.directObserver_ = getObservedSet(this, object);
- },
-
- closeObservers_: function() {
- for (var i = 0; i < this.observed_.length; i += 2) {
- if (this.observed_[i] === observerSentinel)
- this.observed_[i + 1].close();
- }
- this.observed_.length = 0;
- },
-
- disconnect_: function() {
- this.value_ = undefined;
-
- if (this.directObserver_) {
- this.directObserver_.close(this);
- this.directObserver_ = undefined;
- }
-
- this.closeObservers_();
- },
-
- addPath: function(object, path) {
- if (this.state_ != UNOPENED && this.state_ != RESETTING)
- throw Error('Cannot add paths once started.');
-
- this.observed_.push(object, path instanceof Path ? path : getPath(path));
- },
-
- addObserver: function(observer) {
- if (this.state_ != UNOPENED && this.state_ != RESETTING)
- throw Error('Cannot add observers once started.');
-
- observer.open(this.deliver, this);
- this.observed_.push(observerSentinel, observer);
- },
-
- startReset: function() {
- if (this.state_ != OPENED)
- throw Error('Can only reset while open');
-
- this.state_ = RESETTING;
- this.closeObservers_();
- },
-
- finishReset: function() {
- if (this.state_ != RESETTING)
- throw Error('Can only finishReset after startReset');
- this.state_ = OPENED;
- this.connect_();
-
- return this.value_;
- },
-
- iterateObjects_: function(observe) {
- var object;
- for (var i = 0; i < this.observed_.length; i += 2) {
- object = this.observed_[i]
- if (object !== observerSentinel)
- this.observed_[i + 1].iterateObjects(object, observe)
- }
- },
-
- check_: function(changeRecords, skipChanges) {
- var oldValues;
- for (var i = 0; i < this.observed_.length; i += 2) {
- var pathOrObserver = this.observed_[i+1];
- var object = this.observed_[i];
- var value = object === observerSentinel ?
- pathOrObserver.discardChanges() :
- pathOrObserver.getValueFrom(object)
-
- if (skipChanges) {
- this.value_[i / 2] = value;
- continue;
- }
-
- if (areSameValue(value, this.value_[i / 2]))
- continue;
-
- oldValues = oldValues || [];
- oldValues[i / 2] = this.value_[i / 2];
- this.value_[i / 2] = value;
- }
-
- if (!oldValues)
- return false;
-
- // TODO(rafaelw): Having observed_ as the third callback arg here is
- // pretty lame API. Fix.
- this.report_([this.value_, oldValues, this.observed_]);
- return true;
- }
- });
-
- function identFn(value) { return value; }
-
- function ObserverTransform(observable, getValueFn, setValueFn,
- dontPassThroughSet) {
- this.callback_ = undefined;
- this.target_ = undefined;
- this.value_ = undefined;
- this.observable_ = observable;
- this.getValueFn_ = getValueFn || identFn;
- this.setValueFn_ = setValueFn || identFn;
- // TODO(rafaelw): This is a temporary hack. PolymerExpressions needs this
- // at the moment because of a bug in it's dependency tracking.
- this.dontPassThroughSet_ = dontPassThroughSet;
- }
-
- ObserverTransform.prototype = {
- open: function(callback, target) {
- this.callback_ = callback;
- this.target_ = target;
- this.value_ =
- this.getValueFn_(this.observable_.open(this.observedCallback_, this));
- return this.value_;
- },
-
- observedCallback_: function(value) {
- value = this.getValueFn_(value);
- if (areSameValue(value, this.value_))
- return;
- var oldValue = this.value_;
- this.value_ = value;
- this.callback_.call(this.target_, this.value_, oldValue);
- },
-
- discardChanges: function() {
- this.value_ = this.getValueFn_(this.observable_.discardChanges());
- return this.value_;
- },
-
- deliver: function() {
- return this.observable_.deliver();
- },
-
- setValue: function(value) {
- value = this.setValueFn_(value);
- if (!this.dontPassThroughSet_ && this.observable_.setValue)
- return this.observable_.setValue(value);
- },
-
- close: function() {
- if (this.observable_)
- this.observable_.close();
- this.callback_ = undefined;
- this.target_ = undefined;
- this.observable_ = undefined;
- this.value_ = undefined;
- this.getValueFn_ = undefined;
- this.setValueFn_ = undefined;
- }
- }
-
- var expectedRecordTypes = {};
- expectedRecordTypes[PROP_ADD_TYPE] = true;
- expectedRecordTypes[PROP_UPDATE_TYPE] = true;
- expectedRecordTypes[PROP_DELETE_TYPE] = 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);
- }
- }
-
- Observer.defineComputedProperty = function(target, name, observable) {
- var notify = notifyFunction(target, name);
- var value = observable.open(function(newValue, oldValue) {
- value = newValue;
- if (notify)
- notify(PROP_UPDATE_TYPE, oldValue);
- });
-
- Object.defineProperty(target, name, {
- get: function() {
- observable.deliver();
- return value;
- },
- set: function(newValue) {
- observable.setValue(newValue);
- return newValue;
- },
- configurable: true
- });
-
- return {
- close: function() {
- observable.close();
- Object.defineProperty(target, name, {
- value: value,
- 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 (!expectedRecordTypes[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 == PROP_UPDATE_TYPE)
- continue;
-
- if (record.type == PROP_ADD_TYPE) {
- if (record.name in removed)
- delete removed[record.name];
- else
- added[record.name] = true;
-
- continue;
- }
-
- // type = 'delete'
- 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 ARRAY_SPLICE_TYPE:
- mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);
- break;
- case PROP_ADD_TYPE:
- case PROP_UPDATE_TYPE:
- case PROP_DELETE_TYPE:
- 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.runEOM_ = runEOM;
- 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.CompoundObserver = CompoundObserver;
- global.Path = Path;
- global.ObserverTransform = ObserverTransform;
-
- // TODO(rafaelw): Only needed for testing until new change record names
- // make it to release.
- global.Observer.changeRecordTypes = {
- add: PROP_ADD_TYPE,
- update: PROP_UPDATE_TYPE,
- reconfigure: PROP_RECONFIGURE_TYPE,
- 'delete': PROP_DELETE_TYPE,
- splice: ARRAY_SPLICE_TYPE
- };
-})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
-
-/*
- * 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 (typeof WeakMap === 'undefined') {
- (function() {
- var defineProperty = Object.defineProperty;
- var counter = Date.now() % 1e9;
-
- var WeakMap = function() {
- this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
- };
-
- WeakMap.prototype = {
- set: function(key, value) {
- var entry = key[this.name];
- if (entry && entry[0] === key)
- entry[1] = value;
- else
- defineProperty(key, this.name, {value: [key, value], writable: true});
- },
- 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.
-
-window.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) {
- hasEval = false;
- }
- }
-
- function assert(b) {
- if (!b)
- throw new Error('Assertion failed');
- };
-
- var defineProperty = Object.defineProperty;
- var getOwnPropertyNames = Object.getOwnPropertyNames;
- var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
-
- function mixin(to, from) {
- getOwnPropertyNames(from).forEach(function(name) {
- defineProperty(to, name, getOwnPropertyDescriptor(from, name));
- });
- return to;
- };
-
- function mixinStatics(to, from) {
- getOwnPropertyNames(from).forEach(function(name) {
- switch (name) {
- case 'arguments':
- case 'caller':
- case 'length':
- case 'name':
- case 'prototype':
- case 'toString':
- return;
- }
- defineProperty(to, name, getOwnPropertyDescriptor(from, name));
- });
- return to;
- };
-
- function oneOf(object, propertyNames) {
- for (var i = 0; i < propertyNames.length; i++) {
- if (propertyNames[i] in object)
- return propertyNames[i];
- }
- }
-
- // 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.
- 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 isIdentifierName(name) {
- return /^\w[a-zA-Z_0-9]*$/.test(name);
- }
-
- function getGetter(name) {
- return hasEval && isIdentifierName(name) ?
- new Function('return this.impl.' + name) :
- function() { return this.impl[name]; };
- }
-
- function getSetter(name) {
- return hasEval && isIdentifierName(name) ?
- new Function('v', 'this.impl.' + name + ' = v') :
- function(v) { this.impl[name] = v; };
- }
-
- function getMethod(name) {
- return hasEval && isIdentifierName(name) ?
- new Function('return this.impl.' + name +
- '.apply(this.impl, arguments)') :
- function() { return this.impl[name].apply(this.impl, arguments); };
- }
-
- function getDescriptor(source, name) {
- try {
- return 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
- return dummyDescriptor;
- }
- }
-
- function installProperty(source, target, allowMethod, opt_blacklist) {
- var names = getOwnPropertyNames(source);
- for (var i = 0; i < names.length; i++) {
- var name = names[i];
- if (name === 'polymerBlackList_')
- continue;
-
- if (name in target)
- continue;
-
- if (source.polymerBlackList_ && source.polymerBlackList_[name])
- continue;
-
- if (isFirefox) {
- // Tickle Firefox's old bindings.
- source.__lookupGetter__(name);
- }
- var descriptor = getDescriptor(source, name);
- var getter, setter;
- if (allowMethod && typeof descriptor.value === 'function') {
- target[name] = getMethod(name);
- continue;
- }
-
- var isEvent = isEventHandlerName(name);
- if (isEvent)
- getter = scope.getEventHandlerGetter(name);
- else
- getter = getGetter(name);
-
- if (descriptor.writable || descriptor.set) {
- if (isEvent)
- setter = scope.getEventHandlerSetter(name);
- else
- setter = getSetter(name);
- }
-
- 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);
- defineProperty(wrapperPrototype, 'constructor', {
- value: wrapperConstructor,
- configurable: true,
- enumerable: false,
- writable: true
- });
- }
-
- function isWrapperFor(wrapperConstructor, nativeConstructor) {
- return constructorTable.get(nativeConstructor.prototype) ===
- wrapperConstructor;
- }
-
- /**
- * Creates a generic wrapper constructor based on |object| and its
- * constructor.
- * @param {Node} object
- * @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 = window.DOMImplementation;
- var OriginalEventTarget = window.EventTarget;
- var OriginalEvent = window.Event;
- var OriginalNode = window.Node;
- var OriginalWindow = window.Window;
- var OriginalRange = window.Range;
- var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
- var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
- var OriginalSVGElementInstance = window.SVGElementInstance;
-
- function isWrapper(object) {
- return object instanceof wrappers.EventTarget ||
- object instanceof wrappers.Event ||
- object instanceof wrappers.Range ||
- object instanceof wrappers.DOMImplementation ||
- object instanceof wrappers.CanvasRenderingContext2D ||
- wrappers.WebGLRenderingContext &&
- object instanceof wrappers.WebGLRenderingContext;
- }
-
- function isNative(object) {
- return OriginalEventTarget && object instanceof OriginalEventTarget ||
- object instanceof OriginalNode ||
- object instanceof OriginalEvent ||
- object instanceof OriginalWindow ||
- object instanceof OriginalRange ||
- object instanceof OriginalDOMImplementation ||
- object instanceof OriginalCanvasRenderingContext2D ||
- OriginalWebGLRenderingContext &&
- object instanceof OriginalWebGLRenderingContext ||
- OriginalSVGElementInstance &&
- object instanceof OriginalSVGElementInstance;
- }
-
- /**
- * 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) {
- 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.isWrapper = isWrapper;
- 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;
-
-})(window.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(context) {
- 'use strict';
-
- var OriginalMutationObserver = window.MutationObserver;
- var callbacks = [];
- var pending = false;
- var timerFunc;
-
- function handle() {
- pending = false;
- var copies = callbacks.slice(0);
- callbacks = [];
- for (var i = 0; i < copies.length; i++) {
- (0, copies[i])();
- }
- }
-
- if (OriginalMutationObserver) {
- var counter = 1;
- var observer = new OriginalMutationObserver(handle);
- var textNode = document.createTextNode(counter);
- observer.observe(textNode, {characterData: true});
-
- timerFunc = function() {
- counter = (counter + 1) % 2;
- textNode.data = counter;
- };
-
- } else {
- timerFunc = window.setImmediate || window.setTimeout;
- }
-
- function setEndOfMicrotask(func) {
- callbacks.push(func);
- if (pending)
- return;
- pending = true;
- timerFunc(handle, 0);
- }
-
- context.setEndOfMicrotask = setEndOfMicrotask;
-
-})(window.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 setEndOfMicrotask = scope.setEndOfMicrotask
- var wrapIfNeeded = scope.wrapIfNeeded
- var wrappers = scope.wrappers;
-
- var registrationsTable = new WeakMap();
- var globalMutationObservers = [];
- var isScheduled = false;
-
- function scheduleCallback(observer) {
- if (isScheduled)
- return;
- setEndOfMicrotask(notifyObservers);
- isScheduled = true;
- }
-
- // http://dom.spec.whatwg.org/#mutation-observers
- function notifyObservers() {
- isScheduled = false;
-
- do {
- var notifyList = globalMutationObservers.slice();
- var anyNonEmpty = false;
- for (var i = 0; i < notifyList.length; i++) {
- var mo = notifyList[i];
- var queue = mo.takeRecords();
- removeTransientObserversFor(mo);
- if (queue.length) {
- mo.callback_(queue, mo);
- anyNonEmpty = true;
- }
- }
- } while (anyNonEmpty);
- }
-
- /**
- * @param {string} type
- * @param {Node} target
- * @constructor
- */
- function MutationRecord(type, target) {
- this.type = type;
- this.target = target;
- this.addedNodes = new wrappers.NodeList();
- this.removedNodes = new wrappers.NodeList();
- this.previousSibling = null;
- this.nextSibling = null;
- this.attributeName = null;
- this.attributeNamespace = null;
- this.oldValue = null;
- }
-
- /**
- * Registers transient observers to ancestor and its ancesors for the node
- * which was removed.
- * @param {!Node} ancestor
- * @param {!Node} node
- */
- function registerTransientObservers(ancestor, node) {
- for (; ancestor; ancestor = ancestor.parentNode) {
- var registrations = registrationsTable.get(ancestor);
- if (!registrations)
- continue;
- for (var i = 0; i < registrations.length; i++) {
- var registration = registrations[i];
- if (registration.options.subtree)
- registration.addTransientObserver(node);
- }
- }
- }
-
- function removeTransientObserversFor(observer) {
- for (var i = 0; i < observer.nodes_.length; i++) {
- var node = observer.nodes_[i];
- var registrations = registrationsTable.get(node);
- if (!registrations)
- return;
- for (var j = 0; j < registrations.length; j++) {
- var registration = registrations[j];
- if (registration.observer === observer)
- registration.removeTransientObservers();
- }
- }
- }
-
- // http://dom.spec.whatwg.org/#queue-a-mutation-record
- function enqueueMutation(target, type, data) {
- // 1.
- var interestedObservers = Object.create(null);
- var associatedStrings = Object.create(null);
-
- // 2.
- for (var node = target; node; node = node.parentNode) {
- // 3.
- var registrations = registrationsTable.get(node);
- if (!registrations)
- continue;
- for (var j = 0; j < registrations.length; j++) {
- var registration = registrations[j];
- var options = registration.options;
- // 1.
- if (node !== target && !options.subtree)
- continue;
-
- // 2.
- if (type === 'attributes' && !options.attributes)
- continue;
-
- // 3. If type is "attributes", options's attributeFilter is present, and
- // either options's attributeFilter does not contain name or namespace
- // is non-null, continue.
- if (type === 'attributes' && options.attributeFilter &&
- (data.namespace !== null ||
- options.attributeFilter.indexOf(data.name) === -1)) {
- continue;
- }
-
- // 4.
- if (type === 'characterData' && !options.characterData)
- continue;
-
- // 5.
- if (type === 'childList' && !options.childList)
- continue;
-
- // 6.
- var observer = registration.observer;
- interestedObservers[observer.uid_] = observer;
-
- // 7. If either type is "attributes" and options's attributeOldValue is
- // true, or type is "characterData" and options's characterDataOldValue
- // is true, set the paired string of registered observer's observer in
- // interested observers to oldValue.
- if (type === 'attributes' && options.attributeOldValue ||
- type === 'characterData' && options.characterDataOldValue) {
- associatedStrings[observer.uid_] = data.oldValue;
- }
- }
- }
-
- var anyRecordsEnqueued = false;
-
- // 4.
- for (var uid in interestedObservers) {
- var observer = interestedObservers[uid];
- var record = new MutationRecord(type, target);
-
- // 2.
- if ('name' in data && 'namespace' in data) {
- record.attributeName = data.name;
- record.attributeNamespace = data.namespace;
- }
-
- // 3.
- if (data.addedNodes)
- record.addedNodes = data.addedNodes;
-
- // 4.
- if (data.removedNodes)
- record.removedNodes = data.removedNodes;
-
- // 5.
- if (data.previousSibling)
- record.previousSibling = data.previousSibling;
-
- // 6.
- if (data.nextSibling)
- record.nextSibling = data.nextSibling;
-
- // 7.
- if (associatedStrings[uid] !== undefined)
- record.oldValue = associatedStrings[uid];
-
- // 8.
- observer.records_.push(record);
-
- anyRecordsEnqueued = true;
- }
-
- if (anyRecordsEnqueued)
- scheduleCallback();
- }
-
- var slice = Array.prototype.slice;
-
- /**
- * @param {!Object} options
- * @constructor
- */
- function MutationObserverOptions(options) {
- this.childList = !!options.childList;
- this.subtree = !!options.subtree;
-
- // 1. If either options' attributeOldValue or attributeFilter is present
- // and options' attributes is omitted, set options' attributes to true.
- if (!('attributes' in options) &&
- ('attributeOldValue' in options || 'attributeFilter' in options)) {
- this.attributes = true;
- } else {
- this.attributes = !!options.attributes;
- }
-
- // 2. If options' characterDataOldValue is present and options'
- // characterData is omitted, set options' characterData to true.
- if ('characterDataOldValue' in options && !('characterData' in options))
- this.characterData = true;
- else
- this.characterData = !!options.characterData;
-
- // 3. & 4.
- if (!this.attributes &&
- (options.attributeOldValue || 'attributeFilter' in options) ||
- // 5.
- !this.characterData && options.characterDataOldValue) {
- throw new TypeError();
- }
-
- this.characterData = !!options.characterData;
- this.attributeOldValue = !!options.attributeOldValue;
- this.characterDataOldValue = !!options.characterDataOldValue;
- if ('attributeFilter' in options) {
- if (options.attributeFilter == null ||
- typeof options.attributeFilter !== 'object') {
- throw new TypeError();
- }
- this.attributeFilter = slice.call(options.attributeFilter);
- } else {
- this.attributeFilter = null;
- }
- }
-
- var uidCounter = 0;
-
- /**
- * The class that maps to the DOM MutationObserver interface.
- * @param {Function} callback.
- * @constructor
- */
- function MutationObserver(callback) {
- this.callback_ = callback;
- this.nodes_ = [];
- this.records_ = [];
- this.uid_ = ++uidCounter;
-
- // This will leak. There is no way to implement this without WeakRefs :'(
- globalMutationObservers.push(this);
- }
-
- MutationObserver.prototype = {
- // http://dom.spec.whatwg.org/#dom-mutationobserver-observe
- observe: function(target, options) {
- target = wrapIfNeeded(target);
-
- var newOptions = new MutationObserverOptions(options);
-
- // 6.
- var registration;
- var registrations = registrationsTable.get(target);
- if (!registrations)
- registrationsTable.set(target, registrations = []);
-
- for (var i = 0; i < registrations.length; i++) {
- if (registrations[i].observer === this) {
- registration = registrations[i];
- // 6.1.
- registration.removeTransientObservers();
- // 6.2.
- registration.options = newOptions;
- }
- }
-
- // 7.
- if (!registration) {
- registration = new Registration(this, target, newOptions);
- registrations.push(registration);
- this.nodes_.push(target);
- }
- },
-
- // http://dom.spec.whatwg.org/#dom-mutationobserver-disconnect
- disconnect: function() {
- this.nodes_.forEach(function(node) {
- var registrations = registrationsTable.get(node);
- for (var i = 0; i < registrations.length; i++) {
- var registration = registrations[i];
- if (registration.observer === this) {
- registrations.splice(i, 1);
- // Each node can only have one registered observer associated with
- // this observer.
- break;
- }
- }
- }, this);
- this.records_ = [];
- },
-
- takeRecords: function() {
- var copyOfRecords = this.records_;
- this.records_ = [];
- return copyOfRecords;
- }
- };
-
- /**
- * Class used to represent a registered observer.
- * @param {MutationObserver} observer
- * @param {Node} target
- * @param {MutationObserverOptions} options
- * @constructor
- */
- function Registration(observer, target, options) {
- this.observer = observer;
- this.target = target;
- this.options = options;
- this.transientObservedNodes = [];
- }
-
- Registration.prototype = {
- /**
- * Adds a transient observer on node. The transient observer gets removed
- * next time we deliver the change records.
- * @param {Node} node
- */
- addTransientObserver: function(node) {
- // Don't add transient observers on the target itself. We already have all
- // the required listeners set up on the target.
- if (node === this.target)
- return;
-
- this.transientObservedNodes.push(node);
- var registrations = registrationsTable.get(node);
- if (!registrations)
- registrationsTable.set(node, registrations = []);
-
- // We know that registrations does not contain this because we already
- // checked if node === this.target.
- registrations.push(this);
- },
-
- removeTransientObservers: function() {
- var transientObservedNodes = this.transientObservedNodes;
- this.transientObservedNodes = [];
-
- for (var i = 0; i < transientObservedNodes.length; i++) {
- var node = transientObservedNodes[i];
- var registrations = registrationsTable.get(node);
- for (var j = 0; j < registrations.length; j++) {
- if (registrations[j] === this) {
- registrations.splice(j, 1);
- // Each node can only have one registered observer associated with
- // this observer.
- break;
- }
- }
- }
- }
- };
-
- scope.enqueueMutation = enqueueMutation;
- scope.registerTransientObservers = registerTransientObservers;
- scope.wrappers.MutationObserver = MutationObserver;
- scope.wrappers.MutationRecord = MutationRecord;
-
-})(window.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 currentlyDispatchingEvents = new WeakMap();
- var targetTable = new WeakMap();
- var currentTargetTable = new WeakMap();
- var relatedTargetTable = new WeakMap();
- var eventPhaseTable = new WeakMap();
- var stopPropagationTable = new WeakMap();
- var stopImmediatePropagationTable = new WeakMap();
- var eventHandlersTable = new WeakMap();
- var eventPathTable = new WeakMap();
-
- function isShadowRoot(node) {
- return node instanceof wrappers.ShadowRoot;
- }
-
- function 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) || node.host;
-
- // 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 = target.host;
- 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)
- return enclosedBy(rootOfNode(a.host), b);
- return false;
- }
-
-
- function dispatchOriginalEvent(originalEvent) {
- // Make sure this event is only dispatched once.
- if (handledEventsTable.get(originalEvent))
- return;
- handledEventsTable.set(originalEvent, true);
-
- return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
- }
-
- function dispatchEvent(event, originalWrapperTarget) {
- if (currentlyDispatchingEvents.get(event))
- throw new Error('InvalidStateError')
- currentlyDispatchingEvents.set(event, true);
-
- // Render to ensure that the event path is correct.
- scope.renderAllPending();
- 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.delete(event, null);
- currentlyDispatchingEvents.delete(event);
-
- 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);
- // X-Tag sets relatedTarget on a CustomEvent. If they do that there is no
- // way to have relatedTarget return the adjusted target but worse is that
- // the originalEvent might not have a relatedTarget so we hit an assert
- // when we try to wrap it.
- if (originalEvent.relatedTarget) {
- 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, ex.stack);
- }
- }
-
- 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;
- OriginalEvent.prototype.polymerBlackList_ = {
- returnValue: true,
- // TODO(arv): keyLocation is part of KeyboardEvent but Firefox does not
- // support constructable KeyboardEvent so we keep it here for now.
- keyLocation: true
- };
-
- /**
- * 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) {
- // - Old versions of Safari fails on new FocusEvent (and others?).
- // - IE does not support event constructors.
- // - createEvent('FocusEvent') throws in Firefox.
- // => Try the best practice solution first and fallback to the old way
- // if needed.
- try {
- registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
- } catch (ex) {
- registerWrapper(OriginalEvent, GenericEvent,
- document.createEvent(name));
- }
- }
- return GenericEvent;
- }
-
- var UIEvent = registerGenericEvent('UIEvent', Event);
- var CustomEvent = registerGenericEvent('CustomEvent', Event);
-
- var relatedTargetProto = {
- get relatedTarget() {
- 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);
-
- // 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.FocusEvent('focus');
- } 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 BeforeUnloadEvent(impl) {
- Event.call(this);
- }
- BeforeUnloadEvent.prototype = Object.create(Event.prototype);
- mixin(BeforeUnloadEvent.prototype, {
- get returnValue() {
- return this.impl.returnValue;
- },
- set returnValue(v) {
- this.impl.returnValue = v;
- }
- });
-
- function isValidListener(fun) {
- if (typeof fun === 'function')
- return true;
- return fun && fun.handleEvent;
- }
-
- function isMutationEvent(type) {
- switch (type) {
- case 'DOMAttrModified':
- case 'DOMAttributeNameChanged':
- case 'DOMCharacterDataModified':
- case 'DOMElementNameChanged':
- case 'DOMNodeInserted':
- case 'DOMNodeInsertedIntoDocument':
- case 'DOMNodeRemoved':
- case 'DOMNodeRemovedFromDocument':
- case 'DOMSubtreeModified':
- return true;
- }
- return false;
- }
-
- var OriginalEventTarget = window.EventTarget;
-
- /**
- * 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 = wrapper.host;
- return unwrap(wrapper);
- }
-
- EventTarget.prototype = {
- addEventListener: function(type, fun, capture) {
- if (!isValidListener(fun) || isMutationEvent(type))
- return;
-
- var listener = new Listener(type, fun, capture);
- var listeners = listenersTable.get(this);
- if (!listeners) {
- listeners = [];
- 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) {
- // We want to use the native dispatchEvent because it triggers the default
- // actions (like checking a checkbox). However, if there are no listeners
- // in the composed tree then there are no events that will trigger and
- // listeners in the non composed tree that are part of the event path are
- // not notified.
- //
- // If we find out that there are no listeners in the composed tree we add
- // a temporary listener to the target which makes us get called back even
- // in that case.
-
- var nativeEvent = unwrap(event);
- var eventType = nativeEvent.type;
-
- // Allow dispatching the same event again. This is safe because if user
- // code calls this during an existing dispatch of the same event the
- // native dispatchEvent throws (that is required by the spec).
- handledEventsTable.set(nativeEvent, false);
-
- // Force rendering since we prefer native dispatch and that works on the
- // composed tree.
- scope.renderAllPending();
-
- var tempListener;
- if (!hasListenerInAncestors(this, eventType)) {
- tempListener = function() {};
- this.addEventListener(eventType, tempListener, true);
- }
-
- try {
- return unwrap(this).dispatchEvent_(nativeEvent);
- } finally {
- if (tempListener)
- this.removeEventListener(eventType, tempListener, true);
- }
- }
- };
-
- function hasListener(node, type) {
- var listeners = listenersTable.get(node);
- if (listeners) {
- for (var i = 0; i < listeners.length; i++) {
- if (!listeners[i].removed && listeners[i].type === type)
- return true;
- }
- }
- return false;
- }
-
- function hasListenerInAncestors(target, type) {
- for (var node = unwrap(target); node; node = node.parentNode) {
- if (hasListener(wrap(node), type))
- return true;
- }
- return false;
- }
-
- 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.BeforeUnloadEvent = BeforeUnloadEvent;
- scope.wrappers.CustomEvent = CustomEvent;
- scope.wrappers.Event = Event;
- scope.wrappers.EventTarget = EventTarget;
- scope.wrappers.FocusEvent = FocusEvent;
- scope.wrappers.MouseEvent = MouseEvent;
- scope.wrappers.UIEvent = UIEvent;
-
-})(window.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;
-
-})(window.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 assert = scope.assert;
- var defineWrapGetter = scope.defineWrapGetter;
- var enqueueMutation = scope.enqueueMutation;
- var isWrapper = scope.isWrapper;
- var mixin = scope.mixin;
- var registerTransientObservers = scope.registerTransientObservers;
- var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
- var wrap = scope.wrap;
- var wrapIfNeeded = scope.wrapIfNeeded;
-
- function assertIsNodeWrapper(node) {
- assert(node instanceof Node);
- }
-
- function createOneElementNodeList(node) {
- var nodes = new NodeList();
- nodes[0] = node;
- nodes.length = 1;
- return nodes;
- }
-
- var surpressMutations = false;
-
- /**
- * Called before node is inserted into a node to enqueue its removal from its
- * old parent.
- * @param {!Node} node The node that is about to be removed.
- * @param {!Node} parent The parent node that the node is being removed from.
- * @param {!NodeList} nodes The collected nodes.
- */
- function enqueueRemovalForInsertedNodes(node, parent, nodes) {
- enqueueMutation(parent, 'childList', {
- removedNodes: nodes,
- previousSibling: node.previousSibling,
- nextSibling: node.nextSibling
- });
- }
-
- function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
- enqueueMutation(df, 'childList', {
- removedNodes: nodes
- });
- }
-
- /**
- * 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) {
- var nodes = collectNodesForDocumentFragment(node);
-
- // The extra loop is to work around bugs with DocumentFragments in IE.
- surpressMutations = true;
- for (var i = nodes.length - 1; i >= 0; i--) {
- node.removeChild(nodes[i]);
- nodes[i].parentNode_ = parentNode;
- }
- surpressMutations = false;
-
- 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;
- }
-
- var nodes = createOneElementNodeList(node);
- var oldParent = node.parentNode;
- if (oldParent) {
- // This will enqueue the mutation record for the removal as needed.
- oldParent.removeChild(node);
- }
-
- node.parentNode_ = parentNode;
- node.previousSibling_ = previousNode;
- node.nextSibling_ = nextNode;
- if (previousNode)
- previousNode.nextSibling_ = node;
- if (nextNode)
- nextNode.previousSibling_ = node;
-
- return nodes;
- }
-
- function collectNodesNative(node) {
- if (node instanceof DocumentFragment)
- return collectNodesForDocumentFragment(node);
-
- var nodes = createOneElementNodeList(node);
- var oldParent = node.parentNode;
- if (oldParent)
- enqueueRemovalForInsertedNodes(node, oldParent, nodes);
- return nodes;
- }
-
- function collectNodesForDocumentFragment(node) {
- var nodes = new NodeList();
- var i = 0;
- for (var child = node.firstChild; child; child = child.nextSibling) {
- nodes[i++] = child;
- }
- nodes.length = i;
- enqueueRemovalForInsertedDocumentFragment(node, nodes);
- return nodes;
- }
-
- function snapshotNodeList(nodeList) {
- // NodeLists are not live at the moment so just return the same object.
- return nodeList;
- }
-
- // http://dom.spec.whatwg.org/#node-is-inserted
- function nodeWasAdded(node) {
- node.nodeIsInserted_();
- }
-
- function nodesWereAdded(nodes) {
- for (var i = 0; i < nodes.length; i++) {
- nodeWasAdded(nodes[i]);
- }
- }
-
- // http://dom.spec.whatwg.org/#node-is-removed
- function nodeWasRemoved(node) {
- // Nothing at this point in time.
- }
-
- function nodesWereRemoved(nodes) {
- // Nothing at this point in time.
- }
-
- 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 clearChildNodes(wrapper) {
- if (wrapper.firstChild_ !== undefined) {
- var child = wrapper.firstChild_;
- while (child) {
- var tmp = child;
- child = child.nextSibling_;
- tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
- }
- }
- wrapper.firstChild_ = wrapper.lastChild_ = undefined;
- }
-
- 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();
- }
-
- function cleanupNodes(nodes) {
- for (var i = 0, n; i < nodes.length; i++) {
- n = nodes[i];
- n.parentNode.removeChild(n);
- }
- }
-
- 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 OriginalDocumentFragment = window.DocumentFragment;
- var originalAppendChild = OriginalNode.prototype.appendChild;
- var originalCompareDocumentPosition =
- OriginalNode.prototype.compareDocumentPosition;
- var originalInsertBefore = OriginalNode.prototype.insertBefore;
- var originalRemoveChild = OriginalNode.prototype.removeChild;
- var originalReplaceChild = OriginalNode.prototype.replaceChild;
-
- var isIe = /Trident/.test(navigator.userAgent);
-
- var removeChildOriginalHelper = isIe ?
- function(parent, child) {
- try {
- originalRemoveChild.call(parent, child);
- } catch (ex) {
- if (!(parent instanceof OriginalDocumentFragment))
- throw ex;
- }
- } :
- function(parent, child) {
- originalRemoveChild.call(parent, child);
- };
-
- Node.prototype = Object.create(EventTarget.prototype);
- mixin(Node.prototype, {
- appendChild: function(childWrapper) {
- return this.insertBefore(childWrapper, null);
- },
-
- insertBefore: function(childWrapper, refWrapper) {
- assertIsNodeWrapper(childWrapper);
-
- var refNode;
- if (refWrapper) {
- if (isWrapper(refWrapper)) {
- refNode = unwrap(refWrapper);
- } else {
- refNode = refWrapper;
- refWrapper = wrap(refNode);
- }
- } else {
- refWrapper = null;
- refNode = null;
- }
-
- refWrapper && assert(refWrapper.parentNode === this);
-
- var nodes;
- var previousNode =
- refWrapper ? refWrapper.previousSibling : this.lastChild;
-
- var useNative = !this.invalidateShadowRenderer() &&
- !invalidateParent(childWrapper);
-
- if (useNative)
- nodes = collectNodesNative(childWrapper);
- else
- nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
-
- if (useNative) {
- ensureSameOwnerDocument(this, childWrapper);
- clearChildNodes(this);
- originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);
- } else {
- if (!previousNode)
- this.firstChild_ = nodes[0];
- if (!refWrapper)
- this.lastChild_ = nodes[nodes.length - 1];
-
- var parentNode = refNode ? refNode.parentNode : this.impl;
-
- // insertBefore refWrapper no matter what the parent is?
- if (parentNode) {
- originalInsertBefore.call(parentNode,
- unwrapNodesForInsertion(this, nodes), refNode);
- } else {
- adoptNodesIfNeeded(this, nodes);
- }
- }
-
- enqueueMutation(this, 'childList', {
- addedNodes: nodes,
- nextSibling: refWrapper,
- previousSibling: previousNode
- });
-
- nodesWereAdded(nodes);
-
- return childWrapper;
- },
-
- removeChild: function(childWrapper) {
- assertIsNodeWrapper(childWrapper);
- if (childWrapper.parentNode !== this) {
- // IE has invalid DOM trees at times.
- var found = false;
- var childNodes = this.childNodes;
- for (var ieChild = this.firstChild; ieChild;
- ieChild = ieChild.nextSibling) {
- if (ieChild === childWrapper) {
- found = true;
- break;
- }
- }
- if (!found) {
- // TODO(arv): DOMException
- throw new Error('NotFoundError');
- }
- }
-
- var childNode = unwrap(childWrapper);
- var childWrapperNextSibling = childWrapper.nextSibling;
- var childWrapperPreviousSibling = childWrapper.previousSibling;
-
- 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 parentNode = childNode.parentNode;
- if (parentNode)
- removeChildOriginalHelper(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 {
- clearChildNodes(this);
- removeChildOriginalHelper(this.impl, childNode);
- }
-
- if (!surpressMutations) {
- enqueueMutation(this, 'childList', {
- removedNodes: createOneElementNodeList(childWrapper),
- nextSibling: childWrapperNextSibling,
- previousSibling: childWrapperPreviousSibling
- });
- }
-
- registerTransientObservers(this, childWrapper);
-
- return childWrapper;
- },
-
- replaceChild: function(newChildWrapper, oldChildWrapper) {
- assertIsNodeWrapper(newChildWrapper);
-
- var oldChildNode;
- if (isWrapper(oldChildWrapper)) {
- oldChildNode = unwrap(oldChildWrapper);
- } else {
- oldChildNode = oldChildWrapper;
- oldChildWrapper = wrap(oldChildNode);
- }
-
- if (oldChildWrapper.parentNode !== this) {
- // TODO(arv): DOMException
- throw new Error('NotFoundError');
- }
-
- var nextNode = oldChildWrapper.nextSibling;
- var previousNode = oldChildWrapper.previousSibling;
- var nodes;
-
- var useNative = !this.invalidateShadowRenderer() &&
- !invalidateParent(newChildWrapper);
-
- if (useNative) {
- nodes = collectNodesNative(newChildWrapper);
- } else {
- if (nextNode === newChildWrapper)
- nextNode = newChildWrapper.nextSibling;
- nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
- }
-
- if (!useNative) {
- 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 {
- ensureSameOwnerDocument(this, newChildWrapper);
- clearChildNodes(this);
- originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
- oldChildNode);
- }
-
- enqueueMutation(this, 'childList', {
- addedNodes: nodes,
- removedNodes: createOneElementNodeList(oldChildWrapper),
- nextSibling: nextNode,
- previousSibling: previousNode
- });
-
- nodeWasRemoved(oldChildWrapper);
- nodesWereAdded(nodes);
-
- return oldChildWrapper;
- },
-
- /**
- * Called after a node was inserted. Subclasses override this to invalidate
- * the renderer as needed.
- * @private
- */
- nodeIsInserted_: function() {
- for (var child = this.firstChild; child; child = child.nextSibling) {
- child.nodeIsInserted_();
- }
- },
-
- 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) {
- if (child.nodeType != Node.COMMENT_NODE) {
- s += child.textContent;
- }
- }
- return s;
- },
- set textContent(textContent) {
- var removedNodes = snapshotNodeList(this.childNodes);
-
- if (this.invalidateShadowRenderer()) {
- removeAllChildNodes(this);
- if (textContent !== '') {
- var textNode = this.impl.ownerDocument.createTextNode(textContent);
- this.appendChild(textNode);
- }
- } else {
- clearChildNodes(this);
- this.impl.textContent = textContent;
- }
-
- var addedNodes = snapshotNodeList(this.childNodes);
-
- enqueueMutation(this, 'childList', {
- addedNodes: addedNodes,
- removedNodes: removedNodes
- });
-
- nodesWereRemoved(removedNodes);
- nodesWereAdded(addedNodes);
- },
-
- 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) {
- 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));
- },
-
- normalize: function() {
- var nodes = snapshotNodeList(this.childNodes);
- var remNodes = [];
- var s = '';
- var modNode;
-
- for (var i = 0, n; i < nodes.length; i++) {
- n = nodes[i];
- if (n.nodeType === Node.TEXT_NODE) {
- if (!modNode && !n.data.length)
- this.removeNode(n);
- else if (!modNode)
- modNode = n;
- else {
- s += n.data;
- remNodes.push(n);
- }
- } else {
- if (modNode && remNodes.length) {
- modNode.data += s;
- cleanUpNodes(remNodes);
- }
- remNodes = [];
- s = '';
- modNode = null;
- if (n.childNodes.length)
- n.normalize();
- }
- }
-
- // handle case where >1 text nodes are the last children
- if (modNode && remNodes.length) {
- modNode.data += s;
- cleanupNodes(remNodes);
- }
- }
- });
-
- 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.nodeWasAdded = nodeWasAdded;
- scope.nodeWasRemoved = nodeWasRemoved;
- scope.nodesWereAdded = nodesWereAdded;
- scope.nodesWereRemoved = nodesWereRemoved;
- scope.snapshotNodeList = snapshotNodeList;
- scope.wrappers.Node = Node;
-
-})(window.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;
-
-})(window.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;
-
-})(window.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 enqueueMutation = scope.enqueueMutation;
- 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;
- },
- get data() {
- return this.impl.data;
- },
- set data(value) {
- var oldValue = this.impl.data;
- enqueueMutation(this, 'characterData', {
- oldValue: oldValue
- });
- this.impl.data = value;
- }
- });
-
- mixin(CharacterData.prototype, ChildNodeInterface);
-
- registerWrapper(OriginalCharacterData, CharacterData,
- document.createTextNode(''));
-
- scope.wrappers.CharacterData = CharacterData;
-})(window.ShadowDOMPolyfill);
-
-// Copyright 2014 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 CharacterData = scope.wrappers.CharacterData;
- var enqueueMutation = scope.enqueueMutation;
- var mixin = scope.mixin;
- var registerWrapper = scope.registerWrapper;
-
- function toUInt32(x) {
- return x >>> 0;
- }
-
- var OriginalText = window.Text;
-
- function Text(node) {
- CharacterData.call(this, node);
- }
- Text.prototype = Object.create(CharacterData.prototype);
- mixin(Text.prototype, {
- splitText: function(offset) {
- offset = toUInt32(offset);
- var s = this.data;
- if (offset > s.length)
- throw new Error('IndexSizeError');
- var head = s.slice(0, offset);
- var tail = s.slice(offset);
- this.data = head;
- var newTextNode = this.ownerDocument.createTextNode(tail);
- if (this.parentNode)
- this.parentNode.insertBefore(newTextNode, this.nextSibling);
- return newTextNode;
- }
- });
-
- registerWrapper(OriginalText, Text, document.createTextNode(''));
-
- scope.wrappers.Text = Text;
-})(window.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 enqueueMutation = scope.enqueueMutation;
- var mixin = scope.mixin;
- var oneOf = scope.oneOf;
- var registerWrapper = scope.registerWrapper;
- var wrappers = scope.wrappers;
-
- var OriginalElement = window.Element;
-
- var matchesNames = [
- 'matches', // needs to come first.
- 'mozMatchesSelector',
- 'msMatchesSelector',
- 'webkitMatchesSelector',
- ].filter(function(name) {
- return OriginalElement.prototype[name];
- });
-
- var matchesName = matchesNames[0];
-
- 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 enqueAttributeChange(element, name, oldValue) {
- // This is not fully spec compliant. We should use localName (which might
- // have a different case than name) and the namespace (which requires us
- // to get the Attr object).
- enqueueMutation(element, 'attributes', {
- name: name,
- namespace: null,
- oldValue: oldValue
- });
- }
-
- 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) {
- var oldValue = this.impl.getAttribute(name);
- this.impl.setAttribute(name, value);
- enqueAttributeChange(this, name, oldValue);
- invalidateRendererBasedOnAttribute(this, name);
- },
-
- removeAttribute: function(name) {
- var oldValue = this.impl.getAttribute(name);
- this.impl.removeAttribute(name);
- enqueAttributeChange(this, name, oldValue);
- invalidateRendererBasedOnAttribute(this, name);
- },
-
- matches: function(selector) {
- return originalMatches.call(this.impl, selector);
- }
- });
-
- matchesNames.forEach(function(name) {
- if (name !== 'matches') {
- Element.prototype[name] = 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,
- document.createElementNS(null, 'x'));
-
- // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings
- // that reflect attributes.
- scope.matchesNames = matchesNames;
- scope.wrappers.Element = Element;
-})(window.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 enqueueMutation = scope.enqueueMutation;
- var mixin = scope.mixin;
- var nodesWereAdded = scope.nodesWereAdded;
- var nodesWereRemoved = scope.nodesWereRemoved;
- var registerWrapper = scope.registerWrapper;
- var snapshotNodeList = scope.snapshotNodeList;
- var unwrap = scope.unwrap;
- var wrap = scope.wrap;
-
- /////////////////////////////////////////////////////////////////////////////
- // innerHTML and outerHTML
-
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
- var escapeAttrRegExp = /[&\u00A0"]/g;
- var escapeDataRegExp = /[&\u00A0<>]/g;
-
- function escapeReplace(c) {
- switch (c) {
- case '&':
- return '&amp;';
- case '<':
- return '&lt;';
- case '>':
- return '&gt;';
- case '"':
- return '&quot;'
- case '\u00A0':
- return '&nbsp;';
- }
- }
-
- function escapeAttr(s) {
- return s.replace(escapeAttrRegExp, escapeReplace);
- }
-
- function escapeData(s) {
- return s.replace(escapeDataRegExp, escapeReplace);
- }
-
- function makeSet(arr) {
- var set = {};
- for (var i = 0; i < arr.length; i++) {
- set[arr[i]] = true;
- }
- return set;
- }
-
- // http://www.whatwg.org/specs/web-apps/current-work/#void-elements
- var voidElements = makeSet([
- 'area',
- 'base',
- 'br',
- 'col',
- 'command',
- 'embed',
- 'hr',
- 'img',
- 'input',
- 'keygen',
- 'link',
- 'meta',
- 'param',
- 'source',
- 'track',
- 'wbr'
- ]);
-
- var plaintextParents = makeSet([
- 'style',
- 'script',
- 'xmp',
- 'iframe',
- 'noembed',
- 'noframes',
- 'plaintext',
- 'noscript'
- ]);
-
- function getOuterHTML(node, parentNode) {
- 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 + '="' + escapeAttr(attr.value) + '"';
- }
- s += '>';
- if (voidElements[tagName])
- return s;
-
- return s + getInnerHTML(node) + '</' + tagName + '>';
-
- case Node.TEXT_NODE:
- var data = node.data;
- if (parentNode && plaintextParents[parentNode.localName])
- return data;
- return escapeData(data);
-
- case Node.COMMENT_NODE:
- return '<!--' + node.data + '-->';
-
- 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, node);
- }
- 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));
- }
- }
-
- // IE11 does not have MSIE in the user agent string.
- var oldIe = /MSIE/.test(navigator.userAgent);
-
- 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) {
- // IE9 does not handle set innerHTML correctly on plaintextParents. It
- // creates element children. For example
- //
- // scriptElement.innerHTML = '<a>test</a>'
- //
- // Creates a single HTMLAnchorElement child.
- if (oldIe && plaintextParents[this.localName]) {
- this.textContent = value;
- return;
- }
-
- var removedNodes = snapshotNodeList(this.childNodes);
-
- if (this.invalidateShadowRenderer())
- setInnerHTML(this, value, this.tagName);
- else
- this.impl.innerHTML = value;
- var addedNodes = snapshotNodeList(this.childNodes);
-
- enqueueMutation(this, 'childList', {
- addedNodes: addedNodes,
- removedNodes: removedNodes
- });
-
- nodesWereRemoved(removedNodes);
- nodesWereAdded(addedNodes);
- },
-
- get outerHTML() {
- return getOuterHTML(this, this.parentNode);
- },
- set outerHTML(value) {
- var p = this.parentNode;
- if (p) {
- p.invalidateShadowRenderer();
- var df = frag(p, value);
- p.replaceChild(df, this);
- }
- },
-
- insertAdjacentHTML: function(position, text) {
- var contextElement, refNode;
- switch (String(position).toLowerCase()) {
- case 'beforebegin':
- contextElement = this.parentNode;
- refNode = this;
- break;
- case 'afterend':
- contextElement = this.parentNode;
- refNode = this.nextSibling;
- break;
- case 'afterbegin':
- contextElement = this;
- refNode = this.firstChild;
- break;
- case 'beforeend':
- contextElement = this;
- refNode = null;
- break;
- default:
- return;
- }
-
- var df = frag(contextElement, text);
- contextElement.insertBefore(df, refNode);
- }
- });
-
- function frag(contextElement, html) {
- // TODO(arv): This does not work with SVG and other non HTML elements.
- var p = unwrap(contextElement.cloneNode(false));
- p.innerHTML = html;
- var df = unwrap(document.createDocumentFragment());
- var c;
- while (c = p.firstChild) {
- df.appendChild(c);
- }
- return wrap(df);
- }
-
- function getter(name) {
- return function() {
- scope.renderAllPending();
- return this.impl[name];
- };
- }
-
- function getterRequiresRendering(name) {
- defineGetter(HTMLElement, name, getter(name));
- }
-
- [
- 'clientHeight',
- 'clientLeft',
- 'clientTop',
- 'clientWidth',
- 'offsetHeight',
- 'offsetLeft',
- 'offsetTop',
- 'offsetWidth',
- 'scrollHeight',
- 'scrollWidth',
- ].forEach(getterRequiresRendering);
-
- function getterAndSetterRequiresRendering(name) {
- Object.defineProperty(HTMLElement.prototype, name, {
- get: getter(name),
- set: function(v) {
- scope.renderAllPending();
- this.impl[name] = v;
- },
- configurable: true,
- enumerable: true
- });
- }
-
- [
- 'scrollLeft',
- 'scrollTop',
- ].forEach(getterAndSetterRequiresRendering);
-
- 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
-})(window.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 wrap = scope.wrap;
-
- var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
-
- function HTMLCanvasElement(node) {
- HTMLElement.call(this, node);
- }
- HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
-
- mixin(HTMLCanvasElement.prototype, {
- getContext: function() {
- var context = this.impl.getContext.apply(this.impl, arguments);
- return context && wrap(context);
- }
- });
-
- registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement,
- document.createElement('canvas'));
-
- scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
-})(window.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;
-})(window.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 registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
- var rewrap = scope.rewrap;
-
- var OriginalHTMLImageElement = window.HTMLImageElement;
-
- function HTMLImageElement(node) {
- HTMLElement.call(this, node);
- }
- HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
-
- registerWrapper(OriginalHTMLImageElement, HTMLImageElement,
- document.createElement('img'));
-
- function Image(width, height) {
- if (!(this instanceof Image)) {
- throw new TypeError(
- 'DOM object constructor cannot be called as a function.');
- }
-
- var node = unwrap(document.createElement('img'));
- HTMLElement.call(this, node);
- rewrap(node, this);
-
- if (width !== undefined)
- node.width = width;
- if (height !== undefined)
- node.height = height;
- }
-
- Image.prototype = HTMLImageElement.prototype;
-
- scope.wrappers.HTMLImageElement = HTMLImageElement;
- scope.wrappers.Image = Image;
-})(window.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;
-})(window.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;
-})(window.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 registerWrapper = scope.registerWrapper;
-
- var OriginalHTMLMediaElement = window.HTMLMediaElement;
-
- function HTMLMediaElement(node) {
- HTMLElement.call(this, node);
- }
- HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
-
- registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement,
- document.createElement('audio'));
-
- scope.wrappers.HTMLMediaElement = HTMLMediaElement;
-})(window.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 HTMLMediaElement = scope.wrappers.HTMLMediaElement;
- var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
- var rewrap = scope.rewrap;
-
- var OriginalHTMLAudioElement = window.HTMLAudioElement;
-
- function HTMLAudioElement(node) {
- HTMLMediaElement.call(this, node);
- }
- HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
-
- registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement,
- document.createElement('audio'));
-
- function Audio(src) {
- if (!(this instanceof Audio)) {
- throw new TypeError(
- 'DOM object constructor cannot be called as a function.');
- }
-
- var node = unwrap(document.createElement('audio'));
- HTMLMediaElement.call(this, node);
- rewrap(node, this);
-
- node.setAttribute('preload', 'auto');
- if (src !== undefined)
- node.setAttribute('src', src);
- }
-
- Audio.prototype = HTMLAudioElement.prototype;
-
- scope.wrappers.HTMLAudioElement = HTMLAudioElement;
- scope.wrappers.Audio = Audio;
-})(window.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 rewrap = scope.rewrap;
- var unwrap = scope.unwrap;
- var wrap = scope.wrap;
-
- var OriginalHTMLOptionElement = window.HTMLOptionElement;
-
- function trimText(s) {
- return s.replace(/\s+/g, ' ').trim();
- }
-
- function HTMLOptionElement(node) {
- HTMLElement.call(this, node);
- }
- HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
- mixin(HTMLOptionElement.prototype, {
- get text() {
- return trimText(this.textContent);
- },
- set text(value) {
- this.textContent = trimText(String(value));
- },
- get form() {
- return wrap(unwrap(this).form);
- }
- });
-
- registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement,
- document.createElement('option'));
-
- function Option(text, value, defaultSelected, selected) {
- if (!(this instanceof Option)) {
- throw new TypeError(
- 'DOM object constructor cannot be called as a function.');
- }
-
- var node = unwrap(document.createElement('option'));
- HTMLElement.call(this, node);
- rewrap(node, this);
-
- if (text !== undefined)
- node.text = text;
- if (value !== undefined)
- node.setAttribute('value', value);
- if (defaultSelected === true)
- node.setAttribute('selected', '');
- node.selected = selected === true;
- }
-
- Option.prototype = HTMLOptionElement.prototype;
-
- scope.wrappers.HTMLOptionElement = HTMLOptionElement;
- scope.wrappers.Option = Option;
-})(window.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;
-})(window.ShadowDOMPolyfill);
-
-// Copyright 2014 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 registerObject = scope.registerObject;
-
- var SVG_NS = 'http://www.w3.org/2000/svg';
- var svgTitleElement = document.createElementNS(SVG_NS, 'title');
- var SVGTitleElement = registerObject(svgTitleElement);
- var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
-
- scope.wrappers.SVGElement = SVGElement;
-})(window.ShadowDOMPolyfill);
-
-// Copyright 2014 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 mixin = scope.mixin;
- var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
- var wrap = scope.wrap;
-
- var OriginalSVGUseElement = window.SVGUseElement;
-
- // IE uses SVGElement as parent interface, SVG2 (Blink & Gecko) uses
- // SVGGraphicsElement. Use the <g> element to get the right prototype.
-
- var SVG_NS = 'http://www.w3.org/2000/svg';
- var gWrapper = wrap(document.createElementNS(SVG_NS, 'g'));
- var useElement = document.createElementNS(SVG_NS, 'use');
- var SVGGElement = gWrapper.constructor;
- var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
- var parentInterface = parentInterfacePrototype.constructor;
-
- function SVGUseElement(impl) {
- parentInterface.call(this, impl);
- }
-
- SVGUseElement.prototype = Object.create(parentInterfacePrototype);
-
- // Firefox does not expose instanceRoot.
- if ('instanceRoot' in useElement) {
- mixin(SVGUseElement.prototype, {
- get instanceRoot() {
- return wrap(unwrap(this).instanceRoot);
- },
- get animatedInstanceRoot() {
- return wrap(unwrap(this).animatedInstanceRoot);
- },
- });
- }
-
- registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
-
- scope.wrappers.SVGUseElement = SVGUseElement;
-})(window.ShadowDOMPolyfill);
-
-// Copyright 2014 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 wrap = scope.wrap;
-
- var OriginalSVGElementInstance = window.SVGElementInstance;
- if (!OriginalSVGElementInstance)
- return;
-
- function SVGElementInstance(impl) {
- EventTarget.call(this, impl);
- }
-
- SVGElementInstance.prototype = Object.create(EventTarget.prototype);
- mixin(SVGElementInstance.prototype, {
- /** @type {SVGElement} */
- get correspondingElement() {
- return wrap(this.impl.correspondingElement);
- },
-
- /** @type {SVGUseElement} */
- get correspondingUseElement() {
- return wrap(this.impl.correspondingUseElement);
- },
-
- /** @type {SVGElementInstance} */
- get parentNode() {
- return wrap(this.impl.parentNode);
- },
-
- /** @type {SVGElementInstanceList} */
- get childNodes() {
- throw new Error('Not implemented');
- },
-
- /** @type {SVGElementInstance} */
- get firstChild() {
- return wrap(this.impl.firstChild);
- },
-
- /** @type {SVGElementInstance} */
- get lastChild() {
- return wrap(this.impl.lastChild);
- },
-
- /** @type {SVGElementInstance} */
- get previousSibling() {
- return wrap(this.impl.previousSibling);
- },
-
- /** @type {SVGElementInstance} */
- get nextSibling() {
- return wrap(this.impl.nextSibling);
- }
- });
-
- registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
-
- scope.wrappers.SVGElementInstance = SVGElementInstance;
-})(window.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 mixin = scope.mixin;
- var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
- var unwrapIfNeeded = scope.unwrapIfNeeded;
- var wrap = scope.wrap;
-
- var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
-
- function CanvasRenderingContext2D(impl) {
- this.impl = impl;
- }
-
- mixin(CanvasRenderingContext2D.prototype, {
- get canvas() {
- return wrap(this.impl.canvas);
- },
-
- drawImage: function() {
- arguments[0] = unwrapIfNeeded(arguments[0]);
- this.impl.drawImage.apply(this.impl, arguments);
- },
-
- createPattern: function() {
- arguments[0] = unwrap(arguments[0]);
- return this.impl.createPattern.apply(this.impl, arguments);
- }
- });
-
- registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D,
- document.createElement('canvas').getContext('2d'));
-
- scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
-})(window.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 mixin = scope.mixin;
- var registerWrapper = scope.registerWrapper;
- var unwrapIfNeeded = scope.unwrapIfNeeded;
- var wrap = scope.wrap;
-
- var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
-
- // IE10 does not have WebGL.
- if (!OriginalWebGLRenderingContext)
- return;
-
- function WebGLRenderingContext(impl) {
- this.impl = impl;
- }
-
- mixin(WebGLRenderingContext.prototype, {
- get canvas() {
- return wrap(this.impl.canvas);
- },
-
- texImage2D: function() {
- arguments[5] = unwrapIfNeeded(arguments[5]);
- this.impl.texImage2D.apply(this.impl, arguments);
- },
-
- texSubImage2D: function() {
- arguments[6] = unwrapIfNeeded(arguments[6]);
- this.impl.texSubImage2D.apply(this.impl, arguments);
- }
- });
-
- // Blink/WebKit has broken DOM bindings. Usually we would create an instance
- // of the object and pass it into registerWrapper as a "blueprint" but
- // creating WebGL contexts is expensive and might fail so we use a dummy
- // object with dummy instance properties for these broken browsers.
- var instanceProperties = /WebKit/.test(navigator.userAgent) ?
- {drawingBufferHeight: null, drawingBufferWidth: null} : {};
-
- registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext,
- instanceProperties);
-
- scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
-})(window.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));
- },
- toString: function() {
- return this.impl.toString();
- }
- };
-
- // IE9 does not have createContextualFragment.
- if (OriginalRange.prototype.createContextualFragment) {
- Range.prototype.createContextualFragment = function(html) {
- return wrap(this.impl.createContextualFragment(html));
- };
- }
-
- registerWrapper(window.Range, Range, document.createRange());
-
- scope.wrappers.Range = Range;
-
-})(window.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 Comment = registerObject(document.createComment(''));
-
- scope.wrappers.Comment = Comment;
- scope.wrappers.DocumentFragment = DocumentFragment;
-
-})(window.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();
-
- var spaceCharRe = /[ \t\n\r\f]/;
-
- 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;
- },
-
- get host() {
- return shadowHostTable.get(this) || null;
- },
-
- invalidateShadowRenderer: function() {
- return shadowHostTable.get(this).invalidateShadowRenderer();
- },
-
- elementFromPoint: function(x, y) {
- return elementFromPoint(this, this.ownerDocument, x, y);
- },
-
- getElementById: function(id) {
- if (spaceCharRe.test(id))
- return null;
- return this.querySelector('[id="' + id + '"]');
- }
- });
-
- scope.wrappers.ShadowRoot = ShadowRoot;
-
-})(window.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 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;
-
- // The native matches function in IE9 does not correctly work with elements
- // that are not in the document.
- // TODO(arv): Implement matching in JS.
- // https://github.com/Polymer/ShadowDOM/issues/361
- if (select === '*' || select === node.localName)
- return true;
-
- // TODO(arv): This does not seem right. Need to check for a simple selector.
- if (!selectorMatchRegExp.test(select))
- return false;
-
- // TODO(arv): This no longer matches the spec.
- 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(shadowRoot.host);
- }
-
- 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.nodeIsInserted_ =
- HTMLContentElement.prototype.nodeIsInserted_ = 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,
- };
-
-})(window.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 is handled in HTMLOptionElement.js
- '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);
-
-})(window.ShadowDOMPolyfill);
-
-// Copyright 2014 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 OriginalSelection = window.Selection;
-
- function Selection(impl) {
- this.impl = impl;
- }
- Selection.prototype = {
- get anchorNode() {
- return wrap(this.impl.anchorNode);
- },
- get focusNode() {
- return wrap(this.impl.focusNode);
- },
- addRange: function(range) {
- this.impl.addRange(unwrap(range));
- },
- collapse: function(node, index) {
- this.impl.collapse(unwrapIfNeeded(node), index);
- },
- containsNode: function(node, allowPartial) {
- return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);
- },
- extend: function(node, offset) {
- this.impl.extend(unwrapIfNeeded(node), offset);
- },
- getRangeAt: function(index) {
- return wrap(this.impl.getRangeAt(index));
- },
- removeRange: function(range) {
- this.impl.removeRange(unwrap(range));
- },
- selectAllChildren: function(node) {
- this.impl.selectAllChildren(unwrapIfNeeded(node));
- },
- toString: function() {
- return this.impl.toString();
- }
- };
-
- // WebKit extensions. Not implemented.
- // readonly attribute Node baseNode;
- // readonly attribute long baseOffset;
- // readonly attribute Node extentNode;
- // readonly attribute long extentOffset;
- // [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,
- // [Default=Undefined] optional long baseOffset,
- // [Default=Undefined] optional Node extentNode,
- // [Default=Undefined] optional long extentOffset);
- // [RaisesException, ImplementedAs=collapse] void setPosition([Default=Undefined] optional Node node,
- // [Default=Undefined] optional long offset);
-
- registerWrapper(window.Selection, Selection, window.getSelection());
-
- scope.wrappers.Selection = Selection;
-
-})(window.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 Selection = scope.wrappers.Selection;
- var SelectorsInterface = scope.SelectorsInterface;
- var ShadowRoot = scope.wrappers.ShadowRoot;
- var defineWrapGetter = scope.defineWrapGetter;
- var elementFromPoint = scope.elementFromPoint;
- var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
- var matchesNames = scope.matchesNames;
- var mixin = scope.mixin;
- var registerWrapper = scope.registerWrapper;
- var renderAllPending = scope.renderAllPending;
- var rewrap = scope.rewrap;
- 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);
- }
-
- var originalImportNode = document.importNode;
- var originalGetSelection = document.getSelection;
-
- 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);
- },
- importNode: function(node, deep) {
- // We need to manually walk the tree to ensure we do not include rendered
- // shadow trees.
- var clone = wrap(originalImportNode.call(this.impl, unwrap(node), false));
- if (deep) {
- for (var child = node.firstChild; child; child = child.nextSibling) {
- clone.appendChild(this.importNode(child, true));
- }
- }
- return clone;
- },
- getSelection: function() {
- renderAllPending();
- return new Selection(originalGetSelection.call(unwrap(this)));
- }
- });
-
- if (document.registerElement) {
- var originalRegisterElement = document.registerElement;
- Document.prototype.registerElement = 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',
- 'attachedCallback',
- 'detachedCallback',
- 'attributeChangedCallback',
- ].forEach(function(name) {
- var f = prototype[name];
- if (!f)
- return;
- newPrototype[name] = function() {
- // if this element has been wrapped prior to registration,
- // the wrapper is stale; in this case rewrap
- if (!(wrap(this) instanceof CustomElementConstructor)) {
- rewrap(this);
- }
- f.apply(wrap(this), arguments);
- };
- });
-
- var p = {prototype: newPrototype};
- if (object.extends)
- p.extends = object.extends;
-
- function CustomElementConstructor(node) {
- if (!node) {
- if (object.extends) {
- return document.createElement(object.extends, tagName);
- } else {
- return document.createElement(tagName);
- }
- }
- this.impl = node;
- }
- CustomElementConstructor.prototype = prototype;
- CustomElementConstructor.prototype.constructor = CustomElementConstructor;
-
- scope.constructorTable.set(newPrototype, CustomElementConstructor);
- scope.nativePrototypeTable.set(prototype, newPrototype);
-
- // registration is synchronous so do it last
- var nativeConstructor = originalRegisterElement.call(unwrap(this),
- tagName, p);
- return CustomElementConstructor;
- };
-
- forwardMethodsToWrapper([
- window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
- ], [
- 'registerElement',
- ]);
- }
-
- // 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',
- ].concat(matchesNames));
-
- forwardMethodsToWrapper([
- window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
- ], [
- 'adoptNode',
- 'importNode',
- 'contains',
- 'createComment',
- 'createDocumentFragment',
- 'createElement',
- 'createElementNS',
- 'createEvent',
- 'createEventNS',
- 'createRange',
- 'createTextNode',
- 'elementFromPoint',
- 'getElementById',
- 'getSelection',
- ]);
-
- 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;
-
-})(window.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 Selection = scope.wrappers.Selection;
- var mixin = scope.mixin;
- var registerWrapper = scope.registerWrapper;
- var renderAllPending = scope.renderAllPending;
- var unwrap = scope.unwrap;
- var unwrapIfNeeded = scope.unwrapIfNeeded;
- var wrap = scope.wrap;
-
- var OriginalWindow = window.Window;
- var originalGetComputedStyle = window.getComputedStyle;
- var originalGetSelection = window.getSelection;
-
- function Window(impl) {
- EventTarget.call(this, impl);
- }
- Window.prototype = Object.create(EventTarget.prototype);
-
- OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
- return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
- };
-
- OriginalWindow.prototype.getSelection = function() {
- return wrap(this || window).getSelection();
- };
-
- // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
- delete window.getComputedStyle;
- delete window.getSelection;
-
- ['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(
- function(name) {
- OriginalWindow.prototype[name] = function() {
- var w = wrap(this || window);
- return w[name].apply(w, arguments);
- };
-
- // Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
- delete window[name];
- });
-
- mixin(Window.prototype, {
- getComputedStyle: function(el, pseudo) {
- renderAllPending();
- return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),
- pseudo);
- },
- getSelection: function() {
- renderAllPending();
- return new Selection(originalGetSelection.call(unwrap(this)));
- },
- });
-
- registerWrapper(OriginalWindow, Window);
-
- scope.wrappers.Window = Window;
-
-})(window.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',
-
- // Do not create an applet element by default since it shows a warning in
- // IE.
- // https://github.com/Polymer/polymer/issues/217
- // 'applet': 'HTMLAppletElement',
-
- 'area': 'HTMLAreaElement',
- 'br': 'HTMLBRElement',
- 'base': 'HTMLBaseElement',
- 'body': 'HTMLBodyElement',
- 'button': 'HTMLButtonElement',
- // 'command': 'HTMLCommandElement', // Not fully implemented in Gecko.
- 'dl': 'HTMLDListElement',
- 'datalist': 'HTMLDataListElement',
- 'data': 'HTMLDataElement',
- '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',
- 'input': 'HTMLInputElement',
- 'li': 'HTMLLIElement',
- 'label': 'HTMLLabelElement',
- 'legend': 'HTMLLegendElement',
- 'link': 'HTMLLinkElement',
- 'map': 'HTMLMapElement',
- 'marquee': 'HTMLMarqueeElement',
- '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',
- 'time': 'HTMLTimeElement',
- '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',
- 'track': 'HTMLTrackElement',
- '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;
-
-})(window.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;
- }
- }
- });
-
- // ShadowCSS needs this:
- window.wrap = window.ShadowDOMPolyfill.wrap;
- window.unwrap = window.ShadowDOMPolyfill.unwrap;
-
- //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';
-
- // TODO(jmesserly): this prevents incorrect interaction between ShadowDOM
- // and dart:html's <template> polyfill. Essentially, ShadowDOM is
- // polyfilling native template, but our Dart polyfill fails to detect this
- // because the unwrapped node is an HTMLUnknownElement, leading it to
- // think the node has no content.
- if (obj instanceof HTMLTemplateElement) return 'HTMLTemplateElement';
-
- 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] { ... }
-
- * ::part(): These rules are converted to rules that take advantage of the
- part attribute. For example, a shadowRoot like this inside an x-foo
-
- <div part="special">Special</div>
-
- with a rule like this:
-
- x-foo::part(special) { ... }
-
- becomes:
-
- x-foo [part=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 loader = scope.loader;
-
-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 */ and /* @polyfill-rule */
- // 4. shim @host and scoping
- shimStyling: function(root, name, extendsName) {
- var typeExtension = this.isTypeExtension(extendsName);
- // 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);
- }
- var cssText = this.stylesToShimmedCssText(def.rootStyles, def.scopeStyles,
- name, typeExtension);
- // provide shimmedStyle for user extensibility
- def.shimmedStyle = cssTextToStyle(cssText);
- if (root) {
- root.shimmedStyle = def.shimmedStyle;
- }
- // remove existing style elements
- for (var i=0, l=def.rootStyles.length, s; (i<l) && (s=def.rootStyles[i]);
- i++) {
- s.parentNode.removeChild(s);
- }
- // add style to document
- addCssToDocument(cssText);
- },
- // apply @polyfill rules + @host and scope shimming
- stylesToShimmedCssText: function(rootStyles, scopeStyles, name,
- typeExtension) {
- name = name || '';
- // insert @polyfill and @polyfill-rule rules into style elements
- // scoping process takes care of shimming these
- this.insertPolyfillDirectives(rootStyles);
- this.insertPolyfillRules(rootStyles);
- var cssText = this.shimAtHost(scopeStyles, name, typeExtension) +
- this.shimScoping(scopeStyles, name, typeExtension);
- // note: we only need to do rootStyles since these are unscoped.
- cssText += this.extractPolyfillUnscopedRules(rootStyles);
- return cssText;
- },
- registerDefinition: function(root, name, extendsName) {
- var def = this.registry[name] = {
- root: root,
- name: name,
- extendsName: extendsName
- }
- var styles = root ? 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 && (!root || root.querySelector('shadow'))) {
- def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
- }
- return def;
- },
- isTypeExtension: function(extendsName) {
- return extendsName && extendsName.indexOf('-') < 0;
- },
- 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 menu-item (comment end)
- * shadow::-webkit-distributed(menu-item) {
- *
- * to this:
- *
- * scopeName menu-item {
- *
- **/
- insertPolyfillDirectives: function(styles) {
- if (styles) {
- Array.prototype.forEach.call(styles, function(s) {
- s.textContent = this.insertPolyfillDirectivesInCssText(s.textContent);
- }, this);
- }
- },
- insertPolyfillDirectivesInCssText: function(cssText) {
- return cssText.replace(cssPolyfillCommentRe, function(match, p1) {
- // remove end comment delimiter and add block start
- return p1.slice(0, -2) + '{';
- });
- },
- /*
- * Process styles to add rules which will only apply under the polyfill
- *
- * For example, we convert this rule:
- *
- * (comment start) @polyfill-rule :host menu-item {
- * ... } (comment end)
- *
- * to this:
- *
- * scopeName menu-item {...}
- *
- **/
- insertPolyfillRules: function(styles) {
- if (styles) {
- Array.prototype.forEach.call(styles, function(s) {
- s.textContent = this.insertPolyfillRulesInCssText(s.textContent);
- }, this);
- }
- },
- insertPolyfillRulesInCssText: function(cssText) {
- return cssText.replace(cssPolyfillRuleCommentRe, function(match, p1) {
- // remove end comment delimiter
- return p1.slice(0, -1);
- });
- },
- /*
- * Process styles to add rules which will only apply under the polyfill
- * and do not process via CSSOM. (CSSOM is destructive to rules on rare
- * occasions, e.g. -webkit-calc on Safari.)
- * For example, we convert this rule:
- *
- * (comment start) @polyfill-unscoped-rule menu-item {
- * ... } (comment end)
- *
- * to this:
- *
- * menu-item {...}
- *
- **/
- extractPolyfillUnscopedRules: function(styles) {
- var cssText = '';
- if (styles) {
- Array.prototype.forEach.call(styles, function(s) {
- cssText += this.extractPolyfillUnscopedRulesFromCssText(
- s.textContent) + '\n\n';
- }, this);
- }
- return cssText;
- },
- extractPolyfillUnscopedRulesFromCssText: function(cssText) {
- var r = '', matches;
- while (matches = cssPolyfillUnscopedRuleCommentRe.exec(cssText)) {
- r += matches[1].slice(0, -1) + '\n\n';
- }
- return r;
- },
- // form: @host { .foo { declarations } }
- // becomes: scopeName.foo { declarations }
- shimAtHost: function(styles, name, typeExtension) {
- if (styles) {
- return this.convertAtHostStyles(styles, name, typeExtension);
- }
- },
- convertAtHostStyles: function(styles, name, typeExtension) {
- var cssText = stylesToCssText(styles), self = this;
- cssText = cssText.replace(hostRuleRe, function(m, p1) {
- return self.scopeHostCss(p1, name, typeExtension);
- });
- cssText = rulesToCss(this.findAtHostRules(cssToRules(cssText),
- this.makeScopeMatcher(name, typeExtension)));
- return cssText;
- },
- scopeHostCss: function(cssText, name, typeExtension) {
- var self = this;
- return cssText.replace(selectorRe, function(m, p1, p2) {
- return self.scopeHostSelector(p1, name, typeExtension) + ' ' + p2 + '\n\t';
- });
- },
- // supports scopig by name and [is=name] syntax
- scopeHostSelector: function(selector, name, typeExtension) {
- 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, typeExtension ? is + '$1$3' :
- name + '$1$3');
- // selector: .foo -> name.foo (OR) [bar] -> name[bar]
- } else if (p.match(hostFixableRe)) {
- p = typeExtension ? is + p : name + 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, typeExtension) {
- if (styles) {
- return this.convertScopedStyles(styles, name, typeExtension);
- }
- },
- convertScopedStyles: function(styles, name, typeExtension) {
- var cssText = stylesToCssText(styles).replace(hostRuleRe, '');
- cssText = this.insertPolyfillHostInCssText(cssText);
- cssText = this.convertColonHost(cssText);
- cssText = this.convertColonAncestor(cssText);
- // TODO(sorvell): deprecated, remove
- cssText = this.convertPseudos(cssText);
- // TODO(sorvell): deprecated, remove
- cssText = this.convertParts(cssText);
- cssText = this.convertCombinators(cssText);
- var rules = cssToRules(cssText);
- if (name) {
- cssText = this.scopeRules(rules, name, typeExtension);
- }
- return cssText;
- },
- convertPseudos: function(cssText) {
- return cssText.replace(cssPseudoRe, ' [pseudo=$1]');
- },
- convertParts: function(cssText) {
- return cssText.replace(cssPartRe, ' [part=$1]');
- },
- /*
- * convert a rule like :host(.foo) > .bar { }
- *
- * to
- *
- * scopeName.foo > .bar
- */
- convertColonHost: function(cssText) {
- return this.convertColonRule(cssText, cssColonHostRe,
- this.colonHostPartReplacer);
- },
- /*
- * convert a rule like :ancestor(.foo) > .bar { }
- *
- * to
- *
- * scopeName.foo > .bar, .foo scopeName > .bar { }
- *
- * and
- *
- * :ancestor(.foo:host) .bar { ... }
- *
- * to
- *
- * scopeName.foo .bar { ... }
- */
- convertColonAncestor: function(cssText) {
- return this.convertColonRule(cssText, cssColonAncestorRe,
- this.colonAncestorPartReplacer);
- },
- convertColonRule: function(cssText, regExp, partReplacer) {
- // p1 = :host, p2 = contents of (), p3 rest of rule
- return cssText.replace(regExp, function(m, p1, p2, p3) {
- p1 = polyfillHostNoCombinator;
- if (p2) {
- var parts = p2.split(','), r = [];
- for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {
- p = p.trim();
- r.push(partReplacer(p1, p, p3));
- }
- return r.join(',');
- } else {
- return p1 + p3;
- }
- });
- },
- colonAncestorPartReplacer: function(host, part, suffix) {
- if (part.match(polyfillHost)) {
- return this.colonHostPartReplacer(host, part, suffix);
- } else {
- return host + part + suffix + ', ' + part + ' ' + host + suffix;
- }
- },
- colonHostPartReplacer: function(host, part, suffix) {
- return host + part.replace(polyfillHost, '') + suffix;
- },
- /*
- * Convert ^ and ^^ combinators by replacing with space.
- */
- convertCombinators: function(cssText) {
- return cssText.replace(/\^\^/g, ' ').replace(/\^/g, ' ');
- },
- // change a selector like 'div' to 'name div'
- scopeRules: function(cssRules, name, typeExtension) {
- var cssText = '';
- Array.prototype.forEach.call(cssRules, function(rule) {
- if (rule.selectorText && (rule.style && rule.style.cssText)) {
- cssText += this.scopeSelector(rule.selectorText, name, typeExtension,
- 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, typeExtension);
- cssText += '\n}\n\n';
- } else if (rule.cssText) {
- cssText += rule.cssText + '\n\n';
- }
- }, this);
- return cssText;
- },
- scopeSelector: function(selector, name, typeExtension, strict) {
- var r = [], parts = selector.split(',');
- parts.forEach(function(p) {
- p = p.trim();
- if (this.selectorNeedsScoping(p, name, typeExtension)) {
- p = (strict && !p.match(polyfillHostNoCombinator)) ?
- this.applyStrictSelectorScope(p, name) :
- this.applySimpleSelectorScope(p, name, typeExtension);
- }
- r.push(p);
- }, this);
- return r.join(', ');
- },
- selectorNeedsScoping: function(selector, name, typeExtension) {
- var re = this.makeScopeMatcher(name, typeExtension);
- return !selector.match(re);
- },
- makeScopeMatcher: function(name, typeExtension) {
- var matchScope = typeExtension ? '\\[is=[\'"]?' + name + '[\'"]?\\]' : name;
- return new RegExp('^(' + matchScope + ')' + selectorReSuffix, 'm');
- },
- // scope via name and [is=name]
- applySimpleSelectorScope: function(selector, name, typeExtension) {
- var scoper = typeExtension ? '[is=' + name + ']' : name;
- if (selector.match(polyfillHostRe)) {
- selector = selector.replace(polyfillHostNoCombinator, scoper);
- return selector.replace(polyfillHostRe, scoper + ' ');
- } else {
- return scoper + ' ' + 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) {
- // remove :host since it should be unnecessary
- var t = p.trim().replace(polyfillHostRe, '');
- if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {
- p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3')
- }
- return p;
- }).join(sep);
- });
- return scoped;
- },
- insertPolyfillHostInCssText: function(selector) {
- return selector.replace(hostRe, polyfillHost).replace(colonHostRe,
- polyfillHost).replace(colonAncestorRe, polyfillAncestor);
- },
- propertiesFromRule: function(rule) {
- // TODO(sorvell): Safari cssom incorrectly removes quotes from the content
- // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)
- if (rule.style.content && !rule.style.content.match(/['"]+/)) {
- return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' +
- rule.style.content + '\';');
- }
- return rule.style.cssText;
- }
-};
-
-var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,
- selectorRe = /([^{]*)({[\s\S]*?})/gim,
- hostElementRe = /(.*)((?:\*)|(?:\:scope))(.*)/,
- hostFixableRe = /^[.\[:]/,
- cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
- cssPolyfillCommentRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,
- cssPolyfillRuleCommentRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
- cssPolyfillUnscopedRuleCommentRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
- cssPseudoRe = /::(x-[^\s{,(]*)/gim,
- cssPartRe = /::part\(([^)]*)\)/gim,
- // note: :host pre-processed to -shadowcsshost.
- polyfillHost = '-shadowcsshost',
- // note: :ancestor pre-processed to -shadowcssancestor.
- polyfillAncestor = '-shadowcssancestor',
- parenSuffix = ')(?:\\((' +
- '(?:\\([^)(]*\\)|[^)(]*)+?' +
- ')\\))?([^,{]*)';
- cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),
- cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim'),
- selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
- hostRe = /@host/gim,
- colonHostRe = /\:host/gim,
- colonAncestorRe = /\:ancestor/gim,
- /* host name without combinator */
- polyfillHostNoCombinator = polyfillHost + '-no-combinator',
- polyfillHostRe = new RegExp(polyfillHost, 'gim');
- polyfillAncestorRe = new RegExp(polyfillAncestor, '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 cssTextToStyle(cssText) {
- var style = document.createElement('style');
- style.textContent = cssText;
- return style;
-}
-
-function cssToRules(cssText) {
- var style = cssTextToStyle(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', '');
- sheet.shadowCssShim = true;
- }
- return sheet;
-}
-
-// add polyfill stylesheet to document
-if (window.ShadowDOMPolyfill) {
- addCssToDocument('style { display: none !important; }\n');
- var doc = wrap(document);
- var head = doc.querySelector('head');
- head.insertBefore(getSheet(), head.childNodes[0]);
-
- document.addEventListener('DOMContentLoaded', function() {
- if (window.HTMLImports && !HTMLImports.useNative) {
- HTMLImports.importer.preloadSelectors +=
- ', link[rel=stylesheet]:not([nopolyfill])';
- HTMLImports.parser.parseGeneric = function(elt) {
- if (elt.shadowCssShim) {
- return;
- }
- var style = elt;
- if (!elt.hasAttribute('nopolyfill')) {
- if (elt.__resource) {
- style = elt.ownerDocument.createElement('style');
- style.textContent = Platform.loader.resolveUrlsInCssText(
- elt.__resource, elt.href);
- // remove links from main document
- if (elt.ownerDocument === doc) {
- elt.parentNode.removeChild(elt);
- }
- } else {
- Platform.loader.resolveUrlsInStyle(style);
- }
- var styles = [style];
- style.textContent = ShadowCSS.stylesToShimmedCssText(styles, styles);
- style.shadowCssShim = true;
- }
- // place in document
- if (style.parentNode !== head) {
- head.appendChild(style);
- }
- }
- }
- });
-}
-
-// exports
-scope.ShadowCSS = ShadowCSS;
-
-})(window.Platform);
-}

Powered by Google App Engine
This is Rietveld 408576698