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

Unified Diff: pkg/web_components/lib/platform.concat.js

Issue 507653004: update polymer to 0.3.5 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review updates Created 6 years, 4 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
« no previous file with comments | « pkg/web_components/lib/platform.js ('k') | pkg/web_components/pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/web_components/lib/platform.concat.js
diff --git a/pkg/web_components/lib/platform.concat.js b/pkg/web_components/lib/platform.concat.js
index 68b593d8b5c85d4d4a269cfe1ef246007fbe0745..c4407a2a52284e9023072bf64672016794c062ef 100644
--- a/pkg/web_components/lib/platform.concat.js
+++ b/pkg/web_components/lib/platform.concat.js
@@ -95,7 +95,16 @@ if (typeof WeakMap === 'undefined') {
entry[1] : undefined;
},
delete: function(key) {
- this.set(key, undefined);
+ var entry = key[this.name];
+ if (!entry) return false;
+ var hasValue = entry[0] === key;
+ entry[0] = entry[1] = undefined;
+ return hasValue;
+ },
+ has: function(key) {
+ var entry = key[this.name];
+ if (!entry) return false;
+ return entry[0] === key;
}
};
@@ -120,6 +129,8 @@ if (typeof WeakMap === 'undefined') {
(function(global) {
'use strict';
+ var testingExposeCycleCount = global.testingExposeCycleCount;
+
// Detect and do basic sanity checking on Object/Array.observe.
function detectObjectObserve() {
if (typeof Object.observe !== 'function' ||
@@ -170,6 +181,13 @@ if (typeof WeakMap === 'undefined') {
return false;
}
+ // Firefox OS Apps do not allow eval. This feature detection is very hacky
+ // but even if some other platform adds support for this function this code
+ // will continue to work.
+ if (navigator.getDeviceStorage) {
+ return false;
+ }
+
try {
var f = new Function('', 'return true;');
return f();
@@ -544,7 +562,7 @@ if (typeof WeakMap === 'undefined') {
while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check_()) {
cycles++;
}
- if (global.testingExposeCycleCount)
+ if (testingExposeCycleCount)
global.dirtyCheckCycleCount = cycles;
return cycles > 0;
@@ -943,7 +961,7 @@ if (typeof WeakMap === 'undefined') {
anyChanged = true;
} while (cycles < MAX_DIRTY_CHECK_CYCLES && anyChanged);
- if (global.testingExposeCycleCount)
+ if (testingExposeCycleCount)
global.dirtyCheckCycleCount = cycles;
runningMicrotaskCheckpoint = false;
@@ -1822,8 +1840,8 @@ if (typeof WeakMap === 'undefined') {
global.ObserverTransform = ObserverTransform;
})(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
-// select ShadowDOM impl
-if (Platform.flags.shadow) {
+// select ShadowDOM impl
+if (Platform.flags.shadow) {
// Copyright 2012 The Polymer Authors. All rights reserved.
// Use of this source code is goverened by a BSD-style
@@ -1845,6 +1863,13 @@ window.ShadowDOMPolyfill = {};
return false;
}
+ // Firefox OS Apps do not allow eval. This feature detection is very hacky
+ // but even if some other platform adds support for this function this code
+ // will continue to work.
+ if (navigator.getDeviceStorage) {
+ return false;
+ }
+
try {
var f = new Function('return true;');
return f();
@@ -1956,23 +1981,31 @@ window.ShadowDOMPolyfill = {};
return /^\w[a-zA-Z_0-9]*$/.test(name);
}
+ // The name of the implementation property is intentionally hard to
+ // remember. Unfortunately, browsers are slower doing obj[expr] than
+ // obj.foo so we resort to repeat this ugly name. This ugly name is never
+ // used outside of this file though.
+
function getGetter(name) {
return hasEval && isIdentifierName(name) ?
- new Function('return this.impl.' + name) :
- function() { return this.impl[name]; };
+ new Function('return this.__impl4cf1e782hg__.' + name) :
+ function() { return this.__impl4cf1e782hg__[name]; };
}
function getSetter(name) {
return hasEval && isIdentifierName(name) ?
- new Function('v', 'this.impl.' + name + ' = v') :
- function(v) { this.impl[name] = v; };
+ new Function('v', 'this.__impl4cf1e782hg__.' + name + ' = v') :
+ function(v) { this.__impl4cf1e782hg__[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); };
+ new Function('return this.__impl4cf1e782hg__.' + name +
+ '.apply(this.__impl4cf1e782hg__, arguments)') :
+ function() {
+ return this.__impl4cf1e782hg__[name].apply(
+ this.__impl4cf1e782hg__, arguments);
+ };
}
function getDescriptor(source, name) {
@@ -2093,38 +2126,12 @@ window.ShadowDOMPolyfill = {};
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;
+ return object && object.__impl4cf1e782hg__;
}
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;
+ return !isWrapper(object);
}
/**
@@ -2138,8 +2145,8 @@ window.ShadowDOMPolyfill = {};
return null;
assert(isNative(impl));
- return impl.polymerWrapper_ ||
- (impl.polymerWrapper_ = new (getWrapperConstructor(impl))(impl));
+ return impl.__wrapper8e3dd93a60__ ||
+ (impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl))(impl));
}
/**
@@ -2151,7 +2158,16 @@ window.ShadowDOMPolyfill = {};
if (wrapper === null)
return null;
assert(isWrapper(wrapper));
- return wrapper.impl;
+ return wrapper.__impl4cf1e782hg__;
+ }
+
+ function unsafeUnwrap(wrapper) {
+ return wrapper.__impl4cf1e782hg__;
+ }
+
+ function setWrapper(impl, wrapper) {
+ wrapper.__impl4cf1e782hg__ = impl;
+ impl.__wrapper8e3dd93a60__ = wrapper;
}
/**
@@ -2183,7 +2199,7 @@ window.ShadowDOMPolyfill = {};
return;
assert(isNative(node));
assert(wrapper === undefined || isWrapper(wrapper));
- node.polymerWrapper_ = wrapper;
+ node.__wrapper8e3dd93a60__ = wrapper;
}
var getterDescriptor = {
@@ -2199,7 +2215,7 @@ window.ShadowDOMPolyfill = {};
function defineWrapGetter(constructor, name) {
defineGetter(constructor, name, function() {
- return wrap(this.impl[name]);
+ return wrap(this.__impl4cf1e782hg__[name]);
});
}
@@ -2234,6 +2250,8 @@ window.ShadowDOMPolyfill = {};
scope.registerObject = registerObject;
scope.registerWrapper = register;
scope.rewrap = rewrap;
+ scope.setWrapper = setWrapper;
+ scope.unsafeUnwrap = unsafeUnwrap;
scope.unwrap = unwrap;
scope.unwrapIfNeeded = unwrapIfNeeded;
scope.wrap = wrap;
@@ -2549,6 +2567,8 @@ window.ShadowDOMPolyfill = {};
}
MutationObserver.prototype = {
+ constructor: MutationObserver,
+
// http://dom.spec.whatwg.org/#dom-mutationobserver-observe
observe: function(target, options) {
target = wrapIfNeeded(target);
@@ -2758,6 +2778,8 @@ window.ShadowDOMPolyfill = {};
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrappers = scope.wrappers;
@@ -3212,9 +3234,10 @@ window.ShadowDOMPolyfill = {};
function Event(type, options) {
if (type instanceof OriginalEvent) {
var impl = type;
- if (!OriginalBeforeUnloadEvent && impl.type === 'beforeunload')
+ if (!OriginalBeforeUnloadEvent && impl.type === 'beforeunload') {
return new BeforeUnloadEvent(impl);
- this.impl = impl;
+ }
+ setWrapper(impl, this);
} else {
return wrap(constructEvent(OriginalEvent, 'Event', type, options));
}
@@ -3258,7 +3281,7 @@ window.ShadowDOMPolyfill = {};
var OriginalEvent = window[name];
var GenericEvent = function(type, options) {
if (type instanceof OriginalEvent)
- this.impl = type;
+ setWrapper(type, this);
else
return wrap(constructEvent(OriginalEvent, name, type, options));
};
@@ -3389,10 +3412,10 @@ window.ShadowDOMPolyfill = {};
BeforeUnloadEvent.prototype = Object.create(Event.prototype);
mixin(BeforeUnloadEvent.prototype, {
get returnValue() {
- return this.impl.returnValue;
+ return unsafeUnwrap(this).returnValue;
},
set returnValue(v) {
- this.impl.returnValue = v;
+ unsafeUnwrap(this).returnValue = v;
}
});
@@ -3429,7 +3452,7 @@ window.ShadowDOMPolyfill = {};
* @constructor
*/
function EventTarget(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
// Node and Window have different internal type checks in WebKit so we cannot
@@ -3567,7 +3590,8 @@ window.ShadowDOMPolyfill = {};
function elementFromPoint(self, document, x, y) {
scope.renderAllPending();
- var element = wrap(originalElementFromPoint.call(document.impl, x, y));
+ var element =
+ wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
if (!element)
return null;
var path = getEventPath(element, null);
@@ -3660,7 +3684,8 @@ window.ShadowDOMPolyfill = {};
var UIEvent = scope.wrappers.UIEvent;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
// TouchEvent is WebKit/Blink only.
@@ -3684,12 +3709,12 @@ window.ShadowDOMPolyfill = {};
}
function Touch(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
Touch.prototype = {
get target() {
- return wrap(this.impl.target);
+ return wrap(unsafeUnwrap(this).target);
}
};
@@ -3713,7 +3738,7 @@ window.ShadowDOMPolyfill = {};
'webkitForce'
].forEach(function(name) {
descr.get = function() {
- return this.impl[name];
+ return unsafeUnwrap(this)[name];
};
Object.defineProperty(Touch.prototype, name, descr);
});
@@ -3746,15 +3771,15 @@ window.ShadowDOMPolyfill = {};
mixin(TouchEvent.prototype, {
get touches() {
- return wrapTouchList(unwrap(this).touches);
+ return wrapTouchList(unsafeUnwrap(this).touches);
},
get targetTouches() {
- return wrapTouchList(unwrap(this).targetTouches);
+ return wrapTouchList(unsafeUnwrap(this).targetTouches);
},
get changedTouches() {
- return wrapTouchList(unwrap(this).changedTouches);
+ return wrapTouchList(unsafeUnwrap(this).changedTouches);
},
initTouchEvent: function() {
@@ -3781,6 +3806,7 @@ window.ShadowDOMPolyfill = {};
(function(scope) {
'use strict';
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var nonEnumDescriptor = {enumerable: false};
@@ -3813,7 +3839,8 @@ window.ShadowDOMPolyfill = {};
function addWrapNodeListMethod(wrapperConstructor, name) {
wrapperConstructor.prototype[name] = function() {
- return wrapNodeList(this.impl[name].apply(this.impl, arguments));
+ return wrapNodeList(
+ unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
};
}
@@ -3860,6 +3887,7 @@ window.ShadowDOMPolyfill = {};
var registerTransientObservers = scope.registerTransientObservers;
var registerWrapper = scope.registerWrapper;
var setTreeScope = scope.setTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -4093,9 +4121,9 @@ window.ShadowDOMPolyfill = {};
function cloneNode(node, deep, opt_doc) {
var clone;
if (opt_doc)
- clone = wrap(originalImportNode.call(opt_doc, node.impl, false));
+ clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false));
else
- clone = wrap(originalCloneNode.call(node.impl, false));
+ clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
if (deep) {
for (var child = node.firstChild; child; child = child.nextSibling) {
@@ -4238,7 +4266,7 @@ window.ShadowDOMPolyfill = {};
if (useNative) {
ensureSameOwnerDocument(this, childWrapper);
clearChildNodes(this);
- originalInsertBefore.call(this.impl, unwrap(childWrapper), refNode);
+ originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
} else {
if (!previousNode)
this.firstChild_ = nodes[0];
@@ -4248,7 +4276,7 @@ window.ShadowDOMPolyfill = {};
this.firstChild_ = this.firstChild;
}
- var parentNode = refNode ? refNode.parentNode : this.impl;
+ var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
// insertBefore refWrapper no matter what the parent is?
if (parentNode) {
@@ -4319,7 +4347,7 @@ window.ShadowDOMPolyfill = {};
childWrapper.parentNode_ = undefined;
} else {
clearChildNodes(this);
- removeChildOriginalHelper(this.impl, childNode);
+ removeChildOriginalHelper(unsafeUnwrap(this), childNode);
}
if (!surpressMutations) {
@@ -4385,7 +4413,7 @@ window.ShadowDOMPolyfill = {};
} else {
ensureSameOwnerDocument(this, newChildWrapper);
clearChildNodes(this);
- originalReplaceChild.call(this.impl, unwrap(newChildWrapper),
+ originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper),
oldChildNode);
}
@@ -4421,31 +4449,31 @@ window.ShadowDOMPolyfill = {};
get parentNode() {
// If the parentNode has not been overridden, use the original parentNode.
return this.parentNode_ !== undefined ?
- this.parentNode_ : wrap(this.impl.parentNode);
+ this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
},
/** @type {Node} */
get firstChild() {
return this.firstChild_ !== undefined ?
- this.firstChild_ : wrap(this.impl.firstChild);
+ this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
},
/** @type {Node} */
get lastChild() {
return this.lastChild_ !== undefined ?
- this.lastChild_ : wrap(this.impl.lastChild);
+ this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
},
/** @type {Node} */
get nextSibling() {
return this.nextSibling_ !== undefined ?
- this.nextSibling_ : wrap(this.impl.nextSibling);
+ this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
},
/** @type {Node} */
get previousSibling() {
return this.previousSibling_ !== undefined ?
- this.previousSibling_ : wrap(this.impl.previousSibling);
+ this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
},
get parentElement() {
@@ -4457,7 +4485,7 @@ window.ShadowDOMPolyfill = {};
},
get textContent() {
- // TODO(arv): This should fallback to this.impl.textContent if there
+ // TODO(arv): This should fallback to unsafeUnwrap(this).textContent if there
// are no shadow trees below or above the context node.
var s = '';
for (var child = this.firstChild; child; child = child.nextSibling) {
@@ -4473,12 +4501,12 @@ window.ShadowDOMPolyfill = {};
if (this.invalidateShadowRenderer()) {
removeAllChildNodes(this);
if (textContent !== '') {
- var textNode = this.impl.ownerDocument.createTextNode(textContent);
+ var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
this.appendChild(textNode);
}
} else {
clearChildNodes(this);
- this.impl.textContent = textContent;
+ unsafeUnwrap(this).textContent = textContent;
}
var addedNodes = snapshotNodeList(this.childNodes);
@@ -4513,7 +4541,7 @@ window.ShadowDOMPolyfill = {};
compareDocumentPosition: function(otherNode) {
// This only wraps, it therefore only operates on the composed DOM and not
// the logical DOM.
- return originalCompareDocumentPosition.call(this.impl,
+ return originalCompareDocumentPosition.call(unsafeUnwrap(this),
unwrapIfNeeded(otherNode));
},
@@ -4584,6 +4612,44 @@ window.ShadowDOMPolyfill = {};
var HTMLCollection = scope.wrappers.HTMLCollection;
var NodeList = scope.wrappers.NodeList;
+ var getTreeScope = scope.getTreeScope;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+ var wrap = scope.wrap;
+
+ var originalDocumentQuerySelector = document.querySelector;
+ var originalElementQuerySelector = document.documentElement.querySelector;
+
+ var originalDocumentQuerySelectorAll = document.querySelectorAll;
+ var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
+
+ var originalDocumentGetElementsByTagName = document.getElementsByTagName;
+ var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
+
+ var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
+ var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
+
+ var OriginalElement = window.Element;
+ var OriginalDocument = window.HTMLDocument || window.Document;
+
+ function filterNodeList(list, index, result, deep) {
+ var wrappedItem = null;
+ var root = null;
+ for (var i = 0, length = list.length; i < length; i++) {
+ wrappedItem = wrap(list[i]);
+ if (!deep && (root = getTreeScope(wrappedItem).root)) {
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ continue;
+ }
+ }
+ result[index++] = wrappedItem;
+ }
+
+ return index;
+ }
+
+ function shimSelector(selector) {
+ return String(selector).replace(/\/deep\//g, ' ');
+ }
function findOne(node, selector) {
var m, el = node.firstElementChild;
@@ -4614,7 +4680,7 @@ window.ShadowDOMPolyfill = {};
return true;
}
- function matchesLocalName(el, localName) {
+ function matchesLocalNameOnly(el, ns, localName) {
return el.localName === localName;
}
@@ -4626,40 +4692,155 @@ window.ShadowDOMPolyfill = {};
return el.namespaceURI === ns && el.localName === localName;
}
- function findElements(node, result, p, arg0, arg1) {
+ function findElements(node, index, result, p, arg0, arg1) {
var el = node.firstElementChild;
while (el) {
if (p(el, arg0, arg1))
- result[result.length++] = el;
- findElements(el, result, p, arg0, arg1);
+ result[index++] = el;
+ index = findElements(el, index, result, p, arg0, arg1);
el = el.nextElementSibling;
}
- return result;
+ return index;
}
// 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
+ function querySelectorAllFiltered(p, index, result, selector, deep) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ // We are in the shadow tree and the logical tree is
+ // going to be disconnected so we do a manual tree traversal
+ return findElements(this, index, result, p, selector, null);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementQuerySelectorAll.call(target, selector);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentQuerySelectorAll.call(target, selector);
+ } else {
+ // When we get a ShadowRoot the logical tree is going to be disconnected
+ // so we do a manual tree traversal
+ return findElements(this, index, result, p, selector, null);
+ }
+
+ return filterNodeList(list, index, result, deep);
+ }
+
var SelectorsInterface = {
querySelector: function(selector) {
- return findOne(this, selector);
+ var shimmed = shimSelector(selector);
+ var deep = shimmed !== selector;
+ selector = shimmed;
+
+ var target = unsafeUnwrap(this);
+ var wrappedItem;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ // We are in the shadow tree and the logical tree is
+ // going to be disconnected so we do a manual tree traversal
+ return findOne(this, selector);
+ } else if (target instanceof OriginalElement) {
+ wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
+ } else if (target instanceof OriginalDocument) {
+ wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
+ } else {
+ // When we get a ShadowRoot the logical tree is going to be disconnected
+ // so we do a manual tree traversal
+ return findOne(this, selector);
+ }
+
+ if (!wrappedItem) {
+ // When the original query returns nothing
+ // we return nothing (to be consistent with the other wrapped calls)
+ return wrappedItem;
+ } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ // When the original query returns an element in the ShadowDOM
+ // we must do a manual tree traversal
+ return findOne(this, selector);
+ }
+ }
+
+ return wrappedItem;
},
querySelectorAll: function(selector) {
- return findElements(this, new NodeList(), matchesSelector, selector);
+ var shimmed = shimSelector(selector);
+ var deep = shimmed !== selector;
+ selector = shimmed;
+
+ var result = new NodeList();
+
+ result.length = querySelectorAllFiltered.call(this,
+ matchesSelector,
+ 0,
+ result,
+ selector,
+ deep);
+
+ return result;
}
};
+ function getElementsByTagNameFiltered(p, index, result, localName,
+ lowercase) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ // We are in the shadow tree and the logical tree is
+ // going to be disconnected so we do a manual tree traversal
+ return findElements(this, index, result, p, localName, lowercase);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementGetElementsByTagName.call(target, localName,
+ lowercase);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentGetElementsByTagName.call(target, localName,
+ lowercase);
+ } else {
+ // When we get a ShadowRoot the logical tree is going to be disconnected
+ // so we do a manual tree traversal
+ return findElements(this, index, result, p, localName, lowercase);
+ }
+
+ return filterNodeList(list, index, result, false);
+ }
+
+ function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
+ var target = unsafeUnwrap(this);
+ var list;
+ var root = getTreeScope(this).root;
+ if (root instanceof scope.wrappers.ShadowRoot) {
+ // We are in the shadow tree and the logical tree is
+ // going to be disconnected so we do a manual tree traversal
+ return findElements(this, index, result, p, ns, localName);
+ } else if (target instanceof OriginalElement) {
+ list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
+ } else if (target instanceof OriginalDocument) {
+ list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
+ } else {
+ // When we get a ShadowRoot the logical tree is going to be disconnected
+ // so we do a manual tree traversal
+ return findElements(this, index, result, p, ns, localName);
+ }
+
+ return filterNodeList(list, index, result, false);
+ }
+
var GetElementsByInterface = {
getElementsByTagName: function(localName) {
var result = new HTMLCollection();
- if (localName === '*')
- return findElements(this, result, matchesEveryThing);
+ var match = localName === '*' ? matchesEveryThing : matchesTagName;
- return findElements(this, result,
- matchesTagName,
+ result.length = getElementsByTagNameFiltered.call(this,
+ match,
+ 0,
+ result,
localName,
localName.toLowerCase());
+
+ return result;
},
getElementsByClassName: function(className) {
@@ -4669,19 +4850,22 @@ window.ShadowDOMPolyfill = {};
getElementsByTagNameNS: function(ns, localName) {
var result = new HTMLCollection();
+ var match = null;
- if (ns === '') {
- ns = null;
- } else if (ns === '*') {
- if (localName === '*')
- return findElements(this, result, matchesEveryThing);
- return findElements(this, result, matchesLocalName, localName);
+ if (ns === '*') {
+ match = localName === '*' ? matchesEveryThing : matchesLocalNameOnly;
+ } else {
+ match = localName === '*' ? matchesNameSpace : matchesLocalNameNS;
}
- if (localName === '*')
- return findElements(this, result, matchesNameSpace, ns);
+ result.length = getElementsByTagNameNSFiltered.call(this,
+ match,
+ 0,
+ result,
+ ns || null,
+ localName);
- return findElements(this, result, matchesLocalNameNS, ns, localName);
+ return result;
}
};
@@ -4778,6 +4962,7 @@ window.ShadowDOMPolyfill = {};
var enqueueMutation = scope.enqueueMutation;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var OriginalCharacterData = window.CharacterData;
@@ -4793,14 +4978,14 @@ window.ShadowDOMPolyfill = {};
this.data = value;
},
get data() {
- return this.impl.data;
+ return unsafeUnwrap(this).data;
},
set data(value) {
- var oldValue = this.impl.data;
+ var oldValue = unsafeUnwrap(this).data;
enqueueMutation(this, 'characterData', {
oldValue: oldValue
});
- this.impl.data = value;
+ unsafeUnwrap(this).data = value;
}
});
@@ -4862,40 +5047,44 @@ window.ShadowDOMPolyfill = {};
(function(scope) {
'use strict';
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
+
function invalidateClass(el) {
scope.invalidateRendererBasedOnAttribute(el, 'class');
}
function DOMTokenList(impl, ownerElement) {
- this.impl = impl;
+ setWrapper(impl, this);
this.ownerElement_ = ownerElement;
}
DOMTokenList.prototype = {
+ constructor: DOMTokenList,
get length() {
- return this.impl.length;
+ return unsafeUnwrap(this).length;
},
item: function(index) {
- return this.impl.item(index);
+ return unsafeUnwrap(this).item(index);
},
contains: function(token) {
- return this.impl.contains(token);
+ return unsafeUnwrap(this).contains(token);
},
add: function() {
- this.impl.add.apply(this.impl, arguments);
+ unsafeUnwrap(this).add.apply(unsafeUnwrap(this), arguments);
invalidateClass(this.ownerElement_);
},
remove: function() {
- this.impl.remove.apply(this.impl, arguments);
+ unsafeUnwrap(this).remove.apply(unsafeUnwrap(this), arguments);
invalidateClass(this.ownerElement_);
},
toggle: function(token) {
- var rv = this.impl.toggle.apply(this.impl, arguments);
+ var rv = unsafeUnwrap(this).toggle.apply(unsafeUnwrap(this), arguments);
invalidateClass(this.ownerElement_);
return rv;
},
toString: function() {
- return this.impl.toString();
+ return unsafeUnwrap(this).toString();
}
};
@@ -4920,7 +5109,7 @@ window.ShadowDOMPolyfill = {};
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var registerWrapper = scope.registerWrapper;
- var unwrap = scope.unwrap;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrappers = scope.wrappers;
var OriginalElement = window.Element;
@@ -4969,7 +5158,7 @@ window.ShadowDOMPolyfill = {};
mixin(Element.prototype, {
createShadowRoot: function() {
var newShadowRoot = new wrappers.ShadowRoot(this);
- this.impl.polymerShadowRoot_ = newShadowRoot;
+ unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
var renderer = scope.getRendererForHost(this);
renderer.invalidate();
@@ -4978,40 +5167,40 @@ window.ShadowDOMPolyfill = {};
},
get shadowRoot() {
- return this.impl.polymerShadowRoot_ || null;
+ return unsafeUnwrap(this).polymerShadowRoot_ || null;
},
// getDestinationInsertionPoints added in ShadowRenderer.js
setAttribute: function(name, value) {
- var oldValue = this.impl.getAttribute(name);
- this.impl.setAttribute(name, value);
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).setAttribute(name, value);
enqueAttributeChange(this, name, oldValue);
invalidateRendererBasedOnAttribute(this, name);
},
removeAttribute: function(name) {
- var oldValue = this.impl.getAttribute(name);
- this.impl.removeAttribute(name);
+ var oldValue = unsafeUnwrap(this).getAttribute(name);
+ unsafeUnwrap(this).removeAttribute(name);
enqueAttributeChange(this, name, oldValue);
invalidateRendererBasedOnAttribute(this, name);
},
matches: function(selector) {
- return originalMatches.call(this.impl, selector);
+ return originalMatches.call(unsafeUnwrap(this), selector);
},
get classList() {
var list = classListTable.get(this);
if (!list) {
classListTable.set(this,
- list = new DOMTokenList(unwrap(this).classList, this));
+ list = new DOMTokenList(unsafeUnwrap(this).classList, this));
}
return list;
},
get className() {
- return unwrap(this).className;
+ return unsafeUnwrap(this).className;
},
set className(v) {
@@ -5019,7 +5208,7 @@ window.ShadowDOMPolyfill = {};
},
get id() {
- return unwrap(this).id;
+ return unsafeUnwrap(this).id;
},
set id(v) {
@@ -5068,6 +5257,7 @@ window.ShadowDOMPolyfill = {};
var nodesWereRemoved = scope.nodesWereRemoved;
var registerWrapper = scope.registerWrapper;
var snapshotNodeList = scope.snapshotNodeList;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrappers = scope.wrappers;
@@ -5234,7 +5424,7 @@ window.ShadowDOMPolyfill = {};
this instanceof wrappers.HTMLTemplateElement) {
setInnerHTML(this.content, value);
} else {
- this.impl.innerHTML = value;
+ unsafeUnwrap(this).innerHTML = value;
}
var addedNodes = snapshotNodeList(this.childNodes);
@@ -5285,6 +5475,17 @@ window.ShadowDOMPolyfill = {};
var df = frag(contextElement, text);
contextElement.insertBefore(df, refNode);
+ },
+
+ get hidden() {
+ return this.hasAttribute('hidden');
+ },
+ set hidden(v) {
+ if (v) {
+ this.setAttribute('hidden', '');
+ } else {
+ this.removeAttribute('hidden');
+ }
}
});
@@ -5303,7 +5504,7 @@ window.ShadowDOMPolyfill = {};
function getter(name) {
return function() {
scope.renderAllPending();
- return this.impl[name];
+ return unsafeUnwrap(this)[name];
};
}
@@ -5329,7 +5530,7 @@ window.ShadowDOMPolyfill = {};
get: getter(name),
set: function(v) {
scope.renderAllPending();
- this.impl[name] = v;
+ unsafeUnwrap(this)[name] = v;
},
configurable: true,
enumerable: true
@@ -5345,7 +5546,7 @@ window.ShadowDOMPolyfill = {};
Object.defineProperty(HTMLElement.prototype, name, {
value: function() {
scope.renderAllPending();
- return this.impl[name].apply(this.impl, arguments);
+ return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
},
configurable: true,
enumerable: true
@@ -5379,6 +5580,7 @@ window.ShadowDOMPolyfill = {};
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
@@ -5390,7 +5592,7 @@ window.ShadowDOMPolyfill = {};
mixin(HTMLCanvasElement.prototype, {
getContext: function() {
- var context = this.impl.getContext.apply(this.impl, arguments);
+ var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
return context && wrap(context);
}
});
@@ -5419,6 +5621,8 @@ window.ShadowDOMPolyfill = {};
}
HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLContentElement.prototype, {
+ constructor: HTMLContentElement,
+
get select() {
return this.getAttribute('select');
},
@@ -5539,6 +5743,7 @@ window.ShadowDOMPolyfill = {};
HTMLElement.call(this, node);
}
HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
+ HTMLShadowElement.prototype.constructor = HTMLShadowElement;
// getDistributedNodes is added in ShadowRenderer
@@ -5558,6 +5763,7 @@ window.ShadowDOMPolyfill = {};
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
@@ -5604,9 +5810,10 @@ window.ShadowDOMPolyfill = {};
HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLTemplateElement.prototype, {
+ constructor: HTMLTemplateElement,
get content() {
if (OriginalHTMLTemplateElement)
- return wrap(this.impl.content);
+ return wrap(unsafeUnwrap(this).content);
return contentTable.get(this);
},
@@ -5632,6 +5839,8 @@ window.ShadowDOMPolyfill = {};
var OriginalHTMLMediaElement = window.HTMLMediaElement;
+ if (!OriginalHTMLMediaElement) return;
+
function HTMLMediaElement(node) {
HTMLElement.call(this, node);
}
@@ -5657,6 +5866,8 @@ window.ShadowDOMPolyfill = {};
var OriginalHTMLAudioElement = window.HTMLAudioElement;
+ if (!OriginalHTMLAudioElement) return;
+
function HTMLAudioElement(node) {
HTMLMediaElement.call(this, node);
}
@@ -5889,6 +6100,7 @@ window.ShadowDOMPolyfill = {};
}
HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLTableSectionElement.prototype, {
+ constructor: HTMLTableSectionElement,
get rows() {
return wrapHTMLCollection(unwrap(this).rows);
},
@@ -6059,6 +6271,7 @@ window.ShadowDOMPolyfill = {};
var EventTarget = scope.wrappers.EventTarget;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var OriginalSVGElementInstance = window.SVGElementInstance;
@@ -6073,17 +6286,17 @@ window.ShadowDOMPolyfill = {};
mixin(SVGElementInstance.prototype, {
/** @type {SVGElement} */
get correspondingElement() {
- return wrap(this.impl.correspondingElement);
+ return wrap(unsafeUnwrap(this).correspondingElement);
},
/** @type {SVGUseElement} */
get correspondingUseElement() {
- return wrap(this.impl.correspondingUseElement);
+ return wrap(unsafeUnwrap(this).correspondingUseElement);
},
/** @type {SVGElementInstance} */
get parentNode() {
- return wrap(this.impl.parentNode);
+ return wrap(unsafeUnwrap(this).parentNode);
},
/** @type {SVGElementInstanceList} */
@@ -6093,22 +6306,22 @@ window.ShadowDOMPolyfill = {};
/** @type {SVGElementInstance} */
get firstChild() {
- return wrap(this.impl.firstChild);
+ return wrap(unsafeUnwrap(this).firstChild);
},
/** @type {SVGElementInstance} */
get lastChild() {
- return wrap(this.impl.lastChild);
+ return wrap(unsafeUnwrap(this).lastChild);
},
/** @type {SVGElementInstance} */
get previousSibling() {
- return wrap(this.impl.previousSibling);
+ return wrap(unsafeUnwrap(this).previousSibling);
},
/** @type {SVGElementInstance} */
get nextSibling() {
- return wrap(this.impl.nextSibling);
+ return wrap(unsafeUnwrap(this).nextSibling);
}
});
@@ -6126,6 +6339,8 @@ window.ShadowDOMPolyfill = {};
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -6133,22 +6348,22 @@ window.ShadowDOMPolyfill = {};
var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
function CanvasRenderingContext2D(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
mixin(CanvasRenderingContext2D.prototype, {
get canvas() {
- return wrap(this.impl.canvas);
+ return wrap(unsafeUnwrap(this).canvas);
},
drawImage: function() {
arguments[0] = unwrapIfNeeded(arguments[0]);
- this.impl.drawImage.apply(this.impl, arguments);
+ unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
},
createPattern: function() {
arguments[0] = unwrap(arguments[0]);
- return this.impl.createPattern.apply(this.impl, arguments);
+ return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
}
});
@@ -6167,6 +6382,8 @@ window.ShadowDOMPolyfill = {};
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -6177,22 +6394,22 @@ window.ShadowDOMPolyfill = {};
return;
function WebGLRenderingContext(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
mixin(WebGLRenderingContext.prototype, {
get canvas() {
- return wrap(this.impl.canvas);
+ return wrap(unsafeUnwrap(this).canvas);
},
texImage2D: function() {
arguments[5] = unwrapIfNeeded(arguments[5]);
- this.impl.texImage2D.apply(this.impl, arguments);
+ unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
},
texSubImage2D: function() {
arguments[6] = unwrapIfNeeded(arguments[6]);
- this.impl.texSubImage2D.apply(this.impl, arguments);
+ unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
}
});
@@ -6217,6 +6434,8 @@ window.ShadowDOMPolyfill = {};
'use strict';
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -6224,78 +6443,78 @@ window.ShadowDOMPolyfill = {};
var OriginalRange = window.Range;
function Range(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
Range.prototype = {
get startContainer() {
- return wrap(this.impl.startContainer);
+ return wrap(unsafeUnwrap(this).startContainer);
},
get endContainer() {
- return wrap(this.impl.endContainer);
+ return wrap(unsafeUnwrap(this).endContainer);
},
get commonAncestorContainer() {
- return wrap(this.impl.commonAncestorContainer);
+ return wrap(unsafeUnwrap(this).commonAncestorContainer);
},
setStart: function(refNode,offset) {
- this.impl.setStart(unwrapIfNeeded(refNode), offset);
+ unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
},
setEnd: function(refNode,offset) {
- this.impl.setEnd(unwrapIfNeeded(refNode), offset);
+ unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
},
setStartBefore: function(refNode) {
- this.impl.setStartBefore(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
},
setStartAfter: function(refNode) {
- this.impl.setStartAfter(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
},
setEndBefore: function(refNode) {
- this.impl.setEndBefore(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
},
setEndAfter: function(refNode) {
- this.impl.setEndAfter(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
},
selectNode: function(refNode) {
- this.impl.selectNode(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
},
selectNodeContents: function(refNode) {
- this.impl.selectNodeContents(unwrapIfNeeded(refNode));
+ unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
},
compareBoundaryPoints: function(how, sourceRange) {
- return this.impl.compareBoundaryPoints(how, unwrap(sourceRange));
+ return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
},
extractContents: function() {
- return wrap(this.impl.extractContents());
+ return wrap(unsafeUnwrap(this).extractContents());
},
cloneContents: function() {
- return wrap(this.impl.cloneContents());
+ return wrap(unsafeUnwrap(this).cloneContents());
},
insertNode: function(node) {
- this.impl.insertNode(unwrapIfNeeded(node));
+ unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
},
surroundContents: function(newParent) {
- this.impl.surroundContents(unwrapIfNeeded(newParent));
+ unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
},
cloneRange: function() {
- return wrap(this.impl.cloneRange());
+ return wrap(unsafeUnwrap(this).cloneRange());
},
isPointInRange: function(node, offset) {
- return this.impl.isPointInRange(unwrapIfNeeded(node), offset);
+ return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
},
comparePoint: function(node, offset) {
- return this.impl.comparePoint(unwrapIfNeeded(node), offset);
+ return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
},
intersectsNode: function(node) {
- return this.impl.intersectsNode(unwrapIfNeeded(node));
+ return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
},
toString: function() {
- return this.impl.toString();
+ return unsafeUnwrap(this).toString();
}
};
// IE9 does not have createContextualFragment.
if (OriginalRange.prototype.createContextualFragment) {
Range.prototype.createContextualFragment = function(html) {
- return wrap(this.impl.createContextualFragment(html));
+ return wrap(unsafeUnwrap(this).createContextualFragment(html));
};
}
@@ -6345,6 +6564,7 @@ window.ShadowDOMPolyfill = {};
var mixin = scope.mixin;
var rewrap = scope.rewrap;
var setInnerHTML = scope.setInnerHTML;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var shadowHostTable = new WeakMap();
@@ -6353,7 +6573,7 @@ window.ShadowDOMPolyfill = {};
var spaceCharRe = /[ \t\n\r\f]/;
function ShadowRoot(hostWrapper) {
- var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());
+ var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
DocumentFragment.call(this, node);
// createDocumentFragment associates the node with a wrapper
@@ -6370,6 +6590,8 @@ window.ShadowDOMPolyfill = {};
}
ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
mixin(ShadowRoot.prototype, {
+ constructor: ShadowRoot,
+
get innerHTML() {
return getInnerHTML(this);
},
@@ -6421,6 +6643,7 @@ window.ShadowDOMPolyfill = {};
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var oneOf = scope.oneOf;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
@@ -6891,7 +7114,7 @@ window.ShadowDOMPolyfill = {};
},
associateNode: function(node) {
- node.impl.polymerShadowRenderer_ = this;
+ unsafeUnwrap(node).polymerShadowRenderer_ = this;
}
};
@@ -6945,7 +7168,8 @@ window.ShadowDOMPolyfill = {};
// ClassSelector
// IDSelector
// AttributeSelector
- var selectorStartCharRe = /^[*.#[a-zA-Z_|]/;
+ // negation
+ var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
function matches(node, contentElement) {
var select = contentElement.getAttribute('select');
@@ -7014,7 +7238,7 @@ window.ShadowDOMPolyfill = {};
* This gets called when a node was added or removed to it.
*/
Node.prototype.invalidateShadowRenderer = function(force) {
- var renderer = this.impl.polymerShadowRenderer_;
+ var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
if (renderer) {
renderer.invalidate();
return true;
@@ -7045,7 +7269,7 @@ window.ShadowDOMPolyfill = {};
var renderer;
if (shadowRoot)
renderer = getRendererForShadowRoot(shadowRoot);
- this.impl.polymerShadowRenderer_ = renderer;
+ unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
if (renderer)
renderer.invalidate();
};
@@ -7127,6 +7351,8 @@ window.ShadowDOMPolyfill = {};
'use strict';
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
@@ -7134,38 +7360,38 @@ window.ShadowDOMPolyfill = {};
var OriginalSelection = window.Selection;
function Selection(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
Selection.prototype = {
get anchorNode() {
- return wrap(this.impl.anchorNode);
+ return wrap(unsafeUnwrap(this).anchorNode);
},
get focusNode() {
- return wrap(this.impl.focusNode);
+ return wrap(unsafeUnwrap(this).focusNode);
},
addRange: function(range) {
- this.impl.addRange(unwrap(range));
+ unsafeUnwrap(this).addRange(unwrap(range));
},
collapse: function(node, index) {
- this.impl.collapse(unwrapIfNeeded(node), index);
+ unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
},
containsNode: function(node, allowPartial) {
- return this.impl.containsNode(unwrapIfNeeded(node), allowPartial);
+ return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
},
extend: function(node, offset) {
- this.impl.extend(unwrapIfNeeded(node), offset);
+ unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
},
getRangeAt: function(index) {
- return wrap(this.impl.getRangeAt(index));
+ return wrap(unsafeUnwrap(this).getRangeAt(index));
},
removeRange: function(range) {
- this.impl.removeRange(unwrap(range));
+ unsafeUnwrap(this).removeRange(unwrap(range));
},
selectAllChildren: function(node) {
- this.impl.selectAllChildren(unwrapIfNeeded(node));
+ unsafeUnwrap(this).selectAllChildren(unwrapIfNeeded(node));
},
toString: function() {
- return this.impl.toString();
+ return unsafeUnwrap(this).toString();
}
};
@@ -7210,6 +7436,8 @@ window.ShadowDOMPolyfill = {};
var registerWrapper = scope.registerWrapper;
var renderAllPending = scope.renderAllPending;
var rewrap = scope.rewrap;
+ var setWrapper = scope.setWrapper;
+ var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrapEventTargetMethods = scope.wrapEventTargetMethods;
@@ -7236,7 +7464,7 @@ window.ShadowDOMPolyfill = {};
function wrapMethod(name) {
var original = document[name];
Document.prototype[name] = function() {
- return wrap(original.apply(this.impl, arguments));
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
};
}
@@ -7255,7 +7483,7 @@ window.ShadowDOMPolyfill = {};
var originalAdoptNode = document.adoptNode;
function adoptNodeNoRemove(node, doc) {
- originalAdoptNode.call(doc.impl, unwrap(node));
+ originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
adoptSubtree(node, doc);
}
@@ -7288,7 +7516,7 @@ window.ShadowDOMPolyfill = {};
return elementFromPoint(this, this, x, y);
},
importNode: function(node, deep) {
- return cloneNode(node, deep, this.impl);
+ return cloneNode(node, deep, unsafeUnwrap(this));
},
getSelection: function() {
renderAllPending();
@@ -7383,7 +7611,7 @@ window.ShadowDOMPolyfill = {};
return document.createElement(tagName);
}
}
- this.impl = node;
+ setWrapper(node, this);
}
CustomElementConstructor.prototype = prototype;
CustomElementConstructor.prototype.constructor = CustomElementConstructor;
@@ -7480,20 +7708,20 @@ window.ShadowDOMPolyfill = {};
]);
function DOMImplementation(impl) {
- this.impl = impl;
+ setWrapper(impl, this);
}
function wrapImplMethod(constructor, name) {
var original = document.implementation[name];
constructor.prototype[name] = function() {
- return wrap(original.apply(this.impl, arguments));
+ return wrap(original.apply(unsafeUnwrap(this), arguments));
};
}
function forwardImplMethod(constructor, name) {
var original = document.implementation[name];
constructor.prototype[name] = function() {
- return original.apply(this.impl, arguments);
+ return original.apply(unsafeUnwrap(this), arguments);
};
}
@@ -7537,6 +7765,7 @@ window.ShadowDOMPolyfill = {};
var OriginalWindow = window.Window;
var originalGetComputedStyle = window.getComputedStyle;
+ var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
var originalGetSelection = window.getSelection;
function Window(impl) {
@@ -7548,6 +7777,14 @@ window.ShadowDOMPolyfill = {};
return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
};
+ // Mozilla proprietary extension.
+ if (originalGetDefaultComputedStyle) {
+ OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
+ return wrap(this || window).getDefaultComputedStyle(
+ unwrapIfNeeded(el), pseudo);
+ };
+ }
+
OriginalWindow.prototype.getSelection = function() {
return wrap(this || window).getSelection();
};
@@ -7583,6 +7820,15 @@ window.ShadowDOMPolyfill = {};
}
});
+ // Mozilla proprietary extension.
+ if (originalGetDefaultComputedStyle) {
+ Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
+ renderAllPending();
+ return originalGetDefaultComputedStyle.call(unwrap(this),
+ unwrapIfNeeded(el),pseudo);
+ };
+ }
+
registerWrapper(OriginalWindow, Window, window);
scope.wrappers.Window = Window;
@@ -7626,12 +7872,19 @@ window.ShadowDOMPolyfill = {};
'use strict';
var registerWrapper = scope.registerWrapper;
+ var setWrapper = scope.setWrapper;
var unwrap = scope.unwrap;
var OriginalFormData = window.FormData;
function FormData(formElement) {
- this.impl = new OriginalFormData(formElement && unwrap(formElement));
+ var impl;
+ if (formElement instanceof OriginalFormData) {
+ impl = formElement;
+ } else {
+ impl = new OriginalFormData(formElement && unwrap(formElement));
+ }
+ setWrapper(impl, this);
}
registerWrapper(OriginalFormData, FormData, new OriginalFormData());
@@ -8395,13 +8648,13 @@ var selectorRe = /([^{]*)({[\s\S]*?})/gim,
cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
// TODO(sorvell): remove either content or comment
cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,
- cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*['|"]([^'"]*)['|"][^}]*}([^{]*?){/gim,
+ cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim,
// TODO(sorvell): remove either content or comment
cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
- cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['|"]([^'"]*)['|"][^;]*;)[^}]*}/gim,
+ cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,
// TODO(sorvell): remove either content or comment
cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
- cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['|"]([^'"]*)['|"][^;]*;)[^}]*}/gim,
+ cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,
cssPseudoRe = /::(x-[^\s{,(]*)/gim,
cssPartRe = /::part\(([^)]*)\)/gim,
// note: :host pre-processed to -shadowcsshost.
@@ -8597,7 +8850,7 @@ if (window.ShadowDOMPolyfill) {
if (elt.parentNode === head) {
head.replaceChild(style, elt);
} else {
- head.appendChild(style);
+ this.addElementToDocument(style);
}
}
style.__importParsed = true;
@@ -9234,9 +9487,22 @@ scope.ShadowCSS = ShadowCSS;
}
};
+ // Copy over the static methods
+ var OriginalURL = scope.URL;
+ if (OriginalURL) {
+ jURL.createObjectURL = function(blob) {
+ // IE extension allows a second optional options argument.
+ // http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx
+ return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
+ };
+ jURL.revokeObjectURL = function(url) {
+ OriginalURL.revokeObjectURL(url);
+ };
+ }
+
scope.URL = jURL;
-})(window);
+})(this);
/*
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@@ -10464,79 +10730,257 @@ scope.urlResolver = urlResolver;
})(this);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
window.HTMLImports = window.HTMLImports || {flags:{}};
/*
- * 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.
- */
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */(function(scope) {
-(function(scope) {
+var hasNative = ('import' in document.createElement('link'));
+var useNative = hasNative;
- // imports
- var path = scope.path;
- var xhr = scope.xhr;
- var flags = scope.flags;
+isIE = /Trident/.test(navigator.userAgent);
- // TODO(sorvell): this loader supports a dynamic list of urls
- // and an oncomplete callback that is called when the loader is done.
- // The polyfill currently does *not* need this dynamism or the onComplete
- // concept. Because of this, the loader could be simplified quite a bit.
- var Loader = function(onLoad, onComplete) {
- this.cache = {};
- this.onload = onLoad;
- this.oncomplete = onComplete;
- this.inflight = 0;
- this.pending = {};
- };
+// TODO(sorvell): SD polyfill intrusion
+var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
+var wrap = function(node) {
+ return hasShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node) : node;
+};
+var mainDoc = wrap(document);
+
+// NOTE: We cannot polyfill document.currentScript because it's not possible
+// both to override and maintain the ability to capture the native value;
+// therefore we choose to expose _currentScript both when native imports
+// and the polyfill are in use.
+var currentScriptDescriptor = {
+ get: function() {
+ var script = HTMLImports.currentScript || document.currentScript ||
+ // NOTE: only works when called in synchronously executing code.
+ // readyState should check if `loading` but IE10 is
+ // interactive when scripts run so we cheat.
+ (document.readyState !== 'complete' ?
+ document.scripts[document.scripts.length - 1] : null);
+ return wrap(script);
+ },
+ configurable: true
+};
- Loader.prototype = {
- addNodes: function(nodes) {
- // number of transactions to complete
- this.inflight += nodes.length;
- // commence transactions
- for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
- this.require(n);
+Object.defineProperty(document, '_currentScript', currentScriptDescriptor);
+Object.defineProperty(mainDoc, '_currentScript', currentScriptDescriptor);
+
+// call a callback when all HTMLImports in the document at call (or at least
+// document ready) time have loaded.
+// 1. ensure the document is in a ready state (has dom), then
+// 2. watch for loading of imports and call callback when done
+function whenImportsReady(callback, doc) {
+ doc = doc || mainDoc;
+ // if document is loading, wait and try again
+ whenDocumentReady(function() {
+ watchImportsLoad(callback, doc);
+ }, doc);
+}
+
+// call the callback when the document is in a ready state (has dom)
+var requiredReadyState = isIE ? 'complete' : 'interactive';
+var READY_EVENT = 'readystatechange';
+function isDocumentReady(doc) {
+ return (doc.readyState === 'complete' ||
+ doc.readyState === requiredReadyState);
+}
+
+// call <callback> when we ensure the document is in a ready state
+function whenDocumentReady(callback, doc) {
+ if (!isDocumentReady(doc)) {
+ var checkReady = function() {
+ if (doc.readyState === 'complete' ||
+ doc.readyState === requiredReadyState) {
+ doc.removeEventListener(READY_EVENT, checkReady);
+ whenDocumentReady(callback, doc);
}
- // anything to do?
- this.checkDone();
- },
- addNode: function(node) {
- // number of transactions to complete
- this.inflight++;
- // commence transactions
- this.require(node);
- // anything to do?
- this.checkDone();
- },
- require: function(elt) {
- var url = elt.src || elt.href;
- // ensure we have a standard url that can be used
- // reliably for deduping.
- // TODO(sjmiles): ad-hoc
- elt.__nodeUrl = url;
- // deduplication
- if (!this.dedupe(url, elt)) {
- // fetch this resource
- this.fetch(url, elt);
+ }
+ doc.addEventListener(READY_EVENT, checkReady);
+ } else if (callback) {
+ callback();
+ }
+}
+
+// call <callback> when we ensure all imports have loaded
+function watchImportsLoad(callback, doc) {
+ var imports = doc.querySelectorAll('link[rel=import]');
+ var loaded = 0, l = imports.length;
+ function checkDone(d) {
+ if (loaded == l) {
+ callback && callback();
+ }
+ }
+ function loadedImport(e) {
+ loaded++;
+ checkDone();
+ }
+ if (l) {
+ for (var i=0, imp; (i<l) && (imp=imports[i]); i++) {
+ if (isImportLoaded(imp)) {
+ loadedImport.call(imp);
+ } else {
+ imp.addEventListener('load', loadedImport);
+ imp.addEventListener('error', loadedImport);
}
- },
- dedupe: function(url, elt) {
- if (this.pending[url]) {
- // add to list of nodes waiting for inUrl
- this.pending[url].push(elt);
- // don't need fetch
- return true;
+ }
+ } else {
+ checkDone();
+ }
+}
+
+// NOTE: test for native imports loading is based on explicitly watching
+// all imports (see below).
+function isImportLoaded(link) {
+ return useNative ? link.__loaded : link.__importParsed;
+}
+
+// TODO(sorvell): install a mutation observer to see if HTMLImports have loaded
+// this is a workaround for https://www.w3.org/Bugs/Public/show_bug.cgi?id=25007
+// and should be removed when this bug is addressed.
+if (useNative) {
+ new MutationObserver(function(mxns) {
+ for (var i=0, l=mxns.length, m; (i < l) && (m=mxns[i]); i++) {
+ if (m.addedNodes) {
+ handleImports(m.addedNodes);
}
- var resource;
- if (this.cache[url]) {
- this.onload(url, elt, this.cache[url]);
- // finished this transaction
- this.tail();
+ }
+ }).observe(document.head, {childList: true});
+
+ function handleImports(nodes) {
+ for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
+ if (isImport(n)) {
+ handleImport(n);
+ }
+ }
+ }
+
+ function isImport(element) {
+ return element.localName === 'link' && element.rel === 'import';
+ }
+
+ function handleImport(element) {
+ var loaded = element.import;
+ if (loaded) {
+ markTargetLoaded({target: element});
+ } else {
+ element.addEventListener('load', markTargetLoaded);
+ element.addEventListener('error', markTargetLoaded);
+ }
+ }
+
+ function markTargetLoaded(event) {
+ event.target.__loaded = true;
+ }
+
+}
+
+// Fire the 'HTMLImportsLoaded' event when imports in document at load time
+// have loaded. This event is required to simulate the script blocking
+// behavior of native imports. A main document script that needs to be sure
+// imports have loaded should wait for this event.
+whenImportsReady(function() {
+ HTMLImports.ready = true;
+ HTMLImports.readyTime = new Date().getTime();
+ mainDoc.dispatchEvent(
+ new CustomEvent('HTMLImportsLoaded', {bubbles: true})
+ );
+});
+
+// exports
+scope.useNative = useNative;
+scope.isImportLoaded = isImportLoaded;
+scope.whenReady = whenImportsReady;
+scope.isIE = isIE;
+
+// deprecated
+scope.whenImportsReady = whenImportsReady;
+
+})(window.HTMLImports);
+
+/*
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+(function(scope) {
+
+ // imports
+ var path = scope.path;
+ var xhr = scope.xhr;
+ var flags = scope.flags;
+
+ // TODO(sorvell): this loader supports a dynamic list of urls
+ // and an oncomplete callback that is called when the loader is done.
+ // The polyfill currently does *not* need this dynamism or the onComplete
+ // concept. Because of this, the loader could be simplified quite a bit.
+ var Loader = function(onLoad, onComplete) {
+ this.cache = {};
+ this.onload = onLoad;
+ this.oncomplete = onComplete;
+ this.inflight = 0;
+ this.pending = {};
+ };
+
+ Loader.prototype = {
+ addNodes: function(nodes) {
+ // number of transactions to complete
+ this.inflight += nodes.length;
+ // commence transactions
+ for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
+ this.require(n);
+ }
+ // anything to do?
+ this.checkDone();
+ },
+ addNode: function(node) {
+ // number of transactions to complete
+ this.inflight++;
+ // commence transactions
+ this.require(node);
+ // anything to do?
+ this.checkDone();
+ },
+ require: function(elt) {
+ var url = elt.src || elt.href;
+ // ensure we have a standard url that can be used
+ // reliably for deduping.
+ // TODO(sjmiles): ad-hoc
+ elt.__nodeUrl = url;
+ // deduplication
+ if (!this.dedupe(url, elt)) {
+ // fetch this resource
+ this.fetch(url, elt);
+ }
+ },
+ dedupe: function(url, elt) {
+ if (this.pending[url]) {
+ // add to list of nodes waiting for inUrl
+ this.pending[url].push(elt);
+ // don't need fetch
+ return true;
+ }
+ var resource;
+ if (this.cache[url]) {
+ this.onload(url, elt, this.cache[url]);
+ // finished this transaction
+ this.tail();
// don't need fetch
return true;
}
@@ -10583,22 +11027,13 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
receive: function(url, elt, err, resource, redirectedUrl) {
this.cache[url] = resource;
var $p = this.pending[url];
- if ( redirectedUrl && redirectedUrl !== url ) {
- this.cache[redirectedUrl] = resource;
- $p = $p.concat(this.pending[redirectedUrl]);
- }
for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
- //if (!err) {
- // If url was redirected, use the redirected location so paths are
- // calculated relative to that.
- this.onload(redirectedUrl || url, p, resource);
- //}
+ // If url was redirected, use the redirected location so paths are
+ // calculated relative to that.
+ this.onload(url, p, resource, err, redirectedUrl);
this.tail();
}
this.pending[url] = null;
- if ( redirectedUrl && redirectedUrl !== url ) {
- this.pending[redirectedUrl] = null;
- }
},
tail: function() {
--this.inflight;
@@ -10633,7 +11068,7 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
if (locationHeader) {
var redirectedUrl = (locationHeader.substr( 0, 1 ) === "/")
? location.origin + locationHeader // Location is a relative path
- : redirectedUrl; // Full path
+ : locationHeader; // Full path
}
next.call(nextContext, !xhr.ok(request) && request,
request.response || request.responseText, redirectedUrl);
@@ -10654,16 +11089,18 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
})(window.HTMLImports);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
-
(function(scope) {
var IMPORT_LINK_TYPE = 'import';
var flags = scope.flags;
-var isIe = /Trident/.test(navigator.userAgent);
+var isIE = scope.isIE;
// TODO(sorvell): SD polyfill intrusion
var mainDoc = window.ShadowDOMPolyfill ?
window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;
@@ -10752,10 +11189,12 @@ var importParser = {
if (HTMLImports.__importsParsingHook) {
HTMLImports.__importsParsingHook(elt);
}
- elt.import.__importParsed = true;
+ if (elt.import) {
+ elt.import.__importParsed = true;
+ }
this.markParsingComplete(elt);
// fire load event
- if (elt.__resource) {
+ if (elt.__resource && !elt.__error) {
elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
} else {
elt.dispatchEvent(new CustomEvent('error', {bubbles: false}));
@@ -10791,7 +11230,23 @@ var importParser = {
},
parseGeneric: function(elt) {
this.trackElement(elt);
- document.head.appendChild(elt);
+ this.addElementToDocument(elt);
+ },
+ rootImportForElement: function(elt) {
+ var n = elt;
+ while (n.ownerDocument.__importLink) {
+ n = n.ownerDocument.__importLink;
+ }
+ return n;
+ },
+ addElementToDocument: function(elt) {
+ var port = this.rootImportForElement(elt.__importElement || elt);
+ var l = port.__insertedElements = port.__insertedElements || 0;
+ var refNode = port.nextElementSibling;
+ for (var i=0; i < l; i++) {
+ refNode = refNode && refNode.nextElementSibling;
+ }
+ port.parentNode.insertBefore(elt, refNode);
},
// tracks when a loadable element has loaded
trackElement: function(elt, callback) {
@@ -10808,7 +11263,7 @@ var importParser = {
// NOTE: IE does not fire "load" event for styles that have already loaded
// This is in violation of the spec, so we try our hardest to work around it
- if (isIe && elt.localName === 'style') {
+ if (isIE && elt.localName === 'style') {
var fakeLoad = false;
// If there's not @import in the textContent, assume it has loaded
if (elt.textContent.indexOf('@import') == -1) {
@@ -10848,20 +11303,22 @@ var importParser = {
script.parentNode.removeChild(script);
scope.currentScript = null;
});
- document.head.appendChild(script);
+ this.addElementToDocument(script);
},
// determine the next element in the tree which should be parsed
nextToParse: function() {
return !this.parsingElement && this.nextToParseInDoc(mainDoc);
},
nextToParseInDoc: function(doc, link) {
- var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
- for (var i=0, l=nodes.length, p=0, n; (i<l) && (n=nodes[i]); i++) {
- if (!this.isParsed(n)) {
- if (this.hasResource(n)) {
- return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
- } else {
- return;
+ if (doc) {
+ var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
+ for (var i=0, l=nodes.length, p=0, n; (i<l) && (n=nodes[i]); i++) {
+ if (!this.isParsed(n)) {
+ if (this.hasResource(n)) {
+ return nodeIsImport(n) ? this.nextToParseInDoc(n.import, n) : n;
+ } else {
+ return;
+ }
}
}
}
@@ -10877,7 +11334,7 @@ var importParser = {
return node.__importParsed;
},
hasResource: function(node) {
- if (nodeIsImport(node) && !node.import) {
+ if (nodeIsImport(node) && (node.import === undefined)) {
return false;
}
return true;
@@ -10890,15 +11347,7 @@ function nodeIsImport(elt) {
function generateScriptDataUrl(script) {
var scriptContent = generateScriptContent(script);
- var b64 = 'data:text/javascript';
- // base64 may be smaller, but does not handle unicode characters
- // attempt base64 first, fall back to escaped text
- try {
- b64 += (';base64,' + btoa(scriptContent));
- } catch(e) {
- b64 += (';charset=utf-8,' + encodeURIComponent(scriptContent));
- }
- return b64;
+ return 'data:text/javascript;charset=utf-8,' + encodeURIComponent(scriptContent);
}
function generateScriptContent(script) {
@@ -10963,20 +11412,20 @@ var path = {
// exports
scope.parser = importParser;
scope.path = path;
-scope.isIE = isIe;
})(HTMLImports);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
+ (function(scope) {
-(function(scope) {
-
-var hasNative = ('import' in document.createElement('link'));
-var useNative = hasNative;
+var useNative = scope.useNative;
var flags = scope.flags;
var IMPORT_LINK_TYPE = 'import';
@@ -11024,22 +11473,25 @@ if (!useNative) {
return doc === mainDoc ? this.documentPreloadSelectors :
this.importsPreloadSelectors;
},
- loaded: function(url, elt, resource) {
+ loaded: function(url, elt, resource, err, redirectedUrl) {
flags.load && console.log('loaded', url, elt);
// store generic resource
// TODO(sorvell): fails for nodes inside <template>.content
// see https://code.google.com/p/chromium/issues/detail?id=249381.
elt.__resource = resource;
+ elt.__error = err;
if (isDocumentLink(elt)) {
var doc = this.documents[url];
// if we've never seen a document at this url
- if (!doc) {
+ if (doc === undefined) {
// generate an HTMLDocument from data
- doc = makeDocument(resource, url);
- doc.__importLink = elt;
- // TODO(sorvell): we cannot use MO to detect parsed nodes because
- // SD polyfill does not report these as mutations.
- this.bootDocument(doc);
+ doc = err ? null : makeDocument(resource, redirectedUrl || url);
+ if (doc) {
+ doc.__importLink = elt;
+ // note, we cannot use MO to detect parsed nodes because
+ // SD polyfill does not report these as mutations.
+ this.bootDocument(doc);
+ }
// cache document
this.documents[url] = doc;
}
@@ -11105,173 +11557,61 @@ if (!useNative) {
// install html
doc.body.innerHTML = resource;
}
- // TODO(sorvell): ideally this code is not aware of Template polyfill,
- // but for now the polyfill needs help to bootstrap these templates
- if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
- HTMLTemplateElement.bootstrap(doc);
- }
- return doc;
- }
-} else {
- // do nothing if using native imports
- var importer = {};
-}
-
-// NOTE: We cannot polyfill document.currentScript because it's not possible
-// both to override and maintain the ability to capture the native value;
-// therefore we choose to expose _currentScript both when native imports
-// and the polyfill are in use.
-var currentScriptDescriptor = {
- get: function() {
- return HTMLImports.currentScript || document.currentScript;
- },
- configurable: true
-};
-
-Object.defineProperty(document, '_currentScript', currentScriptDescriptor);
-Object.defineProperty(mainDoc, '_currentScript', currentScriptDescriptor);
-
-// Polyfill document.baseURI for browsers without it.
-if (!document.baseURI) {
- var baseURIDescriptor = {
- get: function() {
- return window.location.href;
- },
- configurable: true
- };
-
- Object.defineProperty(document, 'baseURI', baseURIDescriptor);
- Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor);
-}
-
-// call a callback when all HTMLImports in the document at call (or at least
-// document ready) time have loaded.
-// 1. ensure the document is in a ready state (has dom), then
-// 2. watch for loading of imports and call callback when done
-function whenImportsReady(callback, doc) {
- doc = doc || mainDoc;
- // if document is loading, wait and try again
- whenDocumentReady(function() {
- watchImportsLoad(callback, doc);
- }, doc);
-}
-
-// call the callback when the document is in a ready state (has dom)
-var requiredReadyState = HTMLImports.isIE ? 'complete' : 'interactive';
-var READY_EVENT = 'readystatechange';
-function isDocumentReady(doc) {
- return (doc.readyState === 'complete' ||
- doc.readyState === requiredReadyState);
-}
-
-// call <callback> when we ensure the document is in a ready state
-function whenDocumentReady(callback, doc) {
- if (!isDocumentReady(doc)) {
- var checkReady = function() {
- if (doc.readyState === 'complete' ||
- doc.readyState === requiredReadyState) {
- doc.removeEventListener(READY_EVENT, checkReady);
- whenDocumentReady(callback, doc);
- }
- }
- doc.addEventListener(READY_EVENT, checkReady);
- } else if (callback) {
- callback();
- }
-}
-
-// call <callback> when we ensure all imports have loaded
-function watchImportsLoad(callback, doc) {
- var imports = doc.querySelectorAll('link[rel=import]');
- var loaded = 0, l = imports.length;
- function checkDone(d) {
- if (loaded == l) {
- callback && callback();
- }
- }
- function loadedImport(e) {
- loaded++;
- checkDone();
- }
- if (l) {
- for (var i=0, imp; (i<l) && (imp=imports[i]); i++) {
- if (isImportLoaded(imp)) {
- loadedImport.call(imp);
- } else {
- imp.addEventListener('load', loadedImport);
- imp.addEventListener('error', loadedImport);
- }
- }
- } else {
- checkDone();
- }
-}
-
-function isImportLoaded(link) {
- return useNative ? (link.import && (link.import.readyState !== 'loading')) || link.__loaded :
- link.__importParsed;
-}
-
-// TODO(sorvell): install a mutation observer to see if HTMLImports have loaded
-// this is a workaround for https://www.w3.org/Bugs/Public/show_bug.cgi?id=25007
-// and should be removed when this bug is addressed.
-if (useNative) {
- new MutationObserver(function(mxns) {
- for (var i=0, l=mxns.length, m; (i < l) && (m=mxns[i]); i++) {
- if (m.addedNodes) {
- handleImports(m.addedNodes);
- }
- }
- }).observe(document.head, {childList: true});
-
- function handleImports(nodes) {
- for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
- if (isImport(n)) {
- handleImport(n);
- }
- }
+ // TODO(sorvell): ideally this code is not aware of Template polyfill,
+ // but for now the polyfill needs help to bootstrap these templates
+ if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
+ HTMLTemplateElement.bootstrap(doc);
+ }
+ return doc;
}
- function isImport(element) {
- return element.localName === 'link' && element.rel === 'import';
- }
+ // Polyfill document.baseURI for browsers without it.
+ if (!document.baseURI) {
+ var baseURIDescriptor = {
+ get: function() {
+ var base = document.querySelector('base');
+ return base ? base.href : window.location.href;
+ },
+ configurable: true
+ };
- function handleImport(element) {
- var loaded = element.import;
- if (loaded) {
- markTargetLoaded({target: element});
- } else {
- element.addEventListener('load', markTargetLoaded);
- element.addEventListener('error', markTargetLoaded);
- }
+ Object.defineProperty(document, 'baseURI', baseURIDescriptor);
+ Object.defineProperty(mainDoc, 'baseURI', baseURIDescriptor);
}
- function markTargetLoaded(event) {
- event.target.__loaded = true;
+ // IE shim for CustomEvent
+ if (typeof window.CustomEvent !== 'function') {
+ window.CustomEvent = function(inType, dictionary) {
+ var e = document.createEvent('HTMLEvents');
+ e.initEvent(inType,
+ dictionary.bubbles === false ? false : true,
+ dictionary.cancelable === false ? false : true,
+ dictionary.detail);
+ return e;
+ };
}
+} else {
+ // do nothing if using native imports
+ var importer = {};
}
// exports
-scope.hasNative = hasNative;
-scope.useNative = useNative;
scope.importer = importer;
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
-scope.isImportLoaded = isImportLoaded;
scope.importLoader = importLoader;
-scope.whenReady = whenImportsReady;
-// deprecated
-scope.whenImportsReady = whenImportsReady;
})(window.HTMLImports);
- /*
-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.
-*/
-
+/*
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
(function(scope){
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
@@ -11337,43 +11677,21 @@ importer.observe = observe;
})(HTMLImports);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function(){
// bootstrap
-// IE shim for CustomEvent
-if (typeof window.CustomEvent !== 'function') {
- window.CustomEvent = function(inType, dictionary) {
- var e = document.createEvent('HTMLEvents');
- e.initEvent(inType,
- dictionary.bubbles === false ? false : true,
- dictionary.cancelable === false ? false : true,
- dictionary.detail);
- return e;
- };
-}
-
// TODO(sorvell): SD polyfill intrusion
var doc = window.ShadowDOMPolyfill ?
window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;
-// Fire the 'HTMLImportsLoaded' event when imports in document at load time
-// have loaded. This event is required to simulate the script blocking
-// behavior of native imports. A main document script that needs to be sure
-// imports have loaded should wait for this event.
-HTMLImports.whenImportsReady(function() {
- HTMLImports.ready = true;
- HTMLImports.readyTime = new Date().getTime();
- doc.dispatchEvent(
- new CustomEvent('HTMLImportsLoaded', {bubbles: true})
- );
-});
-
-
// no need to bootstrap the polyfill when native imports is available.
if (!HTMLImports.useNative) {
function bootstrap() {
@@ -11394,364 +11712,373 @@ if (!HTMLImports.useNative) {
})();
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
window.CustomElements = window.CustomElements || {flags:{}};
- /*
-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){
-
-var logFlags = window.logFlags || {};
-var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';
-
-// walk the subtree rooted at node, applying 'find(element, data)' function
-// to each element
-// if 'find' returns true for 'element', do not search element's subtree
-function findAll(node, find, data) {
- var e = node.firstElementChild;
- if (!e) {
- e = node.firstChild;
- while (e && e.nodeType !== Node.ELEMENT_NODE) {
- e = e.nextSibling;
- }
- }
- while (e) {
- if (find(e, data) !== true) {
- findAll(e, find, data);
- }
- e = e.nextElementSibling;
- }
- return null;
-}
-
-// walk all shadowRoots on a given node.
-function forRoots(node, cb) {
- var root = node.shadowRoot;
- while(root) {
- forSubtree(root, cb);
- root = root.olderShadowRoot;
- }
-}
-
-// walk the subtree rooted at node, including descent into shadow-roots,
-// applying 'cb' to each element
-function forSubtree(node, cb) {
- //logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);
- findAll(node, function(e) {
- if (cb(e)) {
- return true;
- }
- forRoots(e, cb);
- });
- forRoots(node, cb);
- //logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();
-}
-
-// manage lifecycle on added node
-function added(node) {
- if (upgrade(node)) {
- insertedNode(node);
- return true;
- }
- inserted(node);
-}
-
-// manage lifecycle on added node's subtree only
-function addedSubtree(node) {
- forSubtree(node, function(e) {
- if (added(e)) {
- return true;
- }
- });
-}
-
-// manage lifecycle on added node and it's subtree
-function addedNode(node) {
- return added(node) || addedSubtree(node);
-}
-
-// upgrade custom elements at node, if applicable
-function upgrade(node) {
- if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
- var type = node.getAttribute('is') || node.localName;
- var definition = scope.registry[type];
- if (definition) {
- logFlags.dom && console.group('upgrade:', node.localName);
- scope.upgrade(node);
- logFlags.dom && console.groupEnd();
- return true;
- }
- }
-}
-
-function insertedNode(node) {
- inserted(node);
- if (inDocument(node)) {
- forSubtree(node, function(e) {
- inserted(e);
- });
- }
-}
-
-// TODO(sorvell): on platforms without MutationObserver, mutations may not be
-// reliable and therefore attached/detached are not reliable.
-// To make these callbacks less likely to fail, we defer all inserts and removes
-// to give a chance for elements to be inserted into dom.
-// This ensures attachedCallback fires for elements that are created and
-// immediately added to dom.
-var hasPolyfillMutations = (!window.MutationObserver ||
- (window.MutationObserver === window.JsMutationObserver));
-scope.hasPolyfillMutations = hasPolyfillMutations;
-
-var isPendingMutations = false;
-var pendingMutations = [];
-function deferMutation(fn) {
- pendingMutations.push(fn);
- if (!isPendingMutations) {
- isPendingMutations = true;
- var async = (window.Platform && window.Platform.endOfMicrotask) ||
- setTimeout;
- async(takeMutations);
- }
-}
-
-function takeMutations() {
- isPendingMutations = false;
- var $p = pendingMutations;
- for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
- p();
- }
- pendingMutations = [];
-}
-
-function inserted(element) {
- if (hasPolyfillMutations) {
- deferMutation(function() {
- _inserted(element);
- });
- } else {
- _inserted(element);
- }
-}
-
-// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this
-function _inserted(element) {
- // TODO(sjmiles): it's possible we were inserted and removed in the space
- // of one microtask, in which case we won't be 'inDocument' here
- // But there are other cases where we are testing for inserted without
- // specific knowledge of mutations, and must test 'inDocument' to determine
- // whether to call inserted
- // If we can factor these cases into separate code paths we can have
- // better diagnostics.
- // TODO(sjmiles): when logging, do work on all custom elements so we can
- // track behavior even when callbacks not defined
- //console.log('inserted: ', element.localName);
- if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {
- logFlags.dom && console.group('inserted:', element.localName);
- if (inDocument(element)) {
- element.__inserted = (element.__inserted || 0) + 1;
- // if we are in a 'removed' state, bluntly adjust to an 'inserted' state
- if (element.__inserted < 1) {
- element.__inserted = 1;
- }
- // if we are 'over inserted', squelch the callback
- if (element.__inserted > 1) {
- logFlags.dom && console.warn('inserted:', element.localName,
- 'insert/remove count:', element.__inserted)
- } else if (element.attachedCallback) {
- logFlags.dom && console.log('inserted:', element.localName);
- element.attachedCallback();
- }
- }
- logFlags.dom && console.groupEnd();
- }
-}
-
-function removedNode(node) {
- removed(node);
- forSubtree(node, function(e) {
- removed(e);
- });
-}
-
-function removed(element) {
- if (hasPolyfillMutations) {
- deferMutation(function() {
- _removed(element);
- });
- } else {
- _removed(element);
- }
-}
-
-function _removed(element) {
- // TODO(sjmiles): temporary: do work on all custom elements so we can track
- // behavior even when callbacks not defined
- if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {
- logFlags.dom && console.group('removed:', element.localName);
- if (!inDocument(element)) {
- element.__inserted = (element.__inserted || 0) - 1;
- // if we are in a 'inserted' state, bluntly adjust to an 'removed' state
- if (element.__inserted > 0) {
- element.__inserted = 0;
- }
- // if we are 'over removed', squelch the callback
- if (element.__inserted < 0) {
- logFlags.dom && console.warn('removed:', element.localName,
- 'insert/remove count:', element.__inserted)
- } else if (element.detachedCallback) {
- element.detachedCallback();
- }
- }
- logFlags.dom && console.groupEnd();
- }
-}
-
-// SD polyfill intrustion due mainly to the fact that 'document'
-// is not entirely wrapped
-function wrapIfNeeded(node) {
- return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)
- : node;
-}
-
-function inDocument(element) {
- var p = element;
- var doc = wrapIfNeeded(document);
- while (p) {
- if (p == doc) {
- return true;
- }
- p = p.parentNode || p.host;
- }
-}
-
-function watchShadow(node) {
- if (node.shadowRoot && !node.shadowRoot.__watched) {
- logFlags.dom && console.log('watching shadow-root for: ', node.localName);
- // watch all unwatched roots...
- var root = node.shadowRoot;
- while (root) {
- watchRoot(root);
- root = root.olderShadowRoot;
- }
- }
-}
-
-function watchRoot(root) {
- if (!root.__watched) {
- observe(root);
- root.__watched = true;
- }
-}
-
-function handler(mutations) {
- //
- if (logFlags.dom) {
- var mx = mutations[0];
- if (mx && mx.type === 'childList' && mx.addedNodes) {
- if (mx.addedNodes) {
- var d = mx.addedNodes[0];
- while (d && d !== document && !d.host) {
- d = d.parentNode;
- }
- var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';
- u = u.split('/?').shift().split('/').pop();
- }
- }
- console.group('mutations (%d) [%s]', mutations.length, u || '');
- }
- //
- mutations.forEach(function(mx) {
- //logFlags.dom && console.group('mutation');
- if (mx.type === 'childList') {
- forEach(mx.addedNodes, function(n) {
- //logFlags.dom && console.log(n.localName);
- if (!n.localName) {
- return;
- }
- // nodes added may need lifecycle management
- addedNode(n);
- });
- // removed nodes may need lifecycle management
- forEach(mx.removedNodes, function(n) {
- //logFlags.dom && console.log(n.localName);
- if (!n.localName) {
- return;
- }
- removedNode(n);
- });
- }
- //logFlags.dom && console.groupEnd();
- });
- logFlags.dom && console.groupEnd();
-};
-
-var observer = new MutationObserver(handler);
-
-function takeRecords() {
- // TODO(sjmiles): ask Raf why we have to call handler ourselves
- handler(observer.takeRecords());
- takeMutations();
-}
-
-var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
-
-function observe(inRoot) {
- observer.observe(inRoot, {childList: true, subtree: true});
-}
-
-function observeDocument(doc) {
- observe(doc);
-}
-
-function upgradeDocument(doc) {
- logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());
- addedNode(doc);
- logFlags.dom && console.groupEnd();
-}
-
-function upgradeDocumentTree(doc) {
- doc = wrapIfNeeded(doc);
- //console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());
- // upgrade contained imported documents
- var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');
- for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {
- if (n.import && n.import.__parsed) {
- upgradeDocumentTree(n.import);
- }
- }
- upgradeDocument(doc);
-}
-
-// exports
-scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
-scope.watchShadow = watchShadow;
-scope.upgradeDocumentTree = upgradeDocumentTree;
-scope.upgradeAll = addedNode;
-scope.upgradeSubtree = addedSubtree;
-scope.insertedNode = insertedNode;
-
-scope.observeDocument = observeDocument;
-scope.upgradeDocument = upgradeDocument;
-
-scope.takeRecords = takeRecords;
-
-})(window.CustomElements);
+/*
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+ */
+
+(function(scope){
+
+var logFlags = window.logFlags || {};
+var IMPORT_LINK_TYPE = window.HTMLImports ? HTMLImports.IMPORT_LINK_TYPE : 'none';
+
+// walk the subtree rooted at node, applying 'find(element, data)' function
+// to each element
+// if 'find' returns true for 'element', do not search element's subtree
+function findAll(node, find, data) {
+ var e = node.firstElementChild;
+ if (!e) {
+ e = node.firstChild;
+ while (e && e.nodeType !== Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ }
+ while (e) {
+ if (find(e, data) !== true) {
+ findAll(e, find, data);
+ }
+ e = e.nextElementSibling;
+ }
+ return null;
+}
+
+// walk all shadowRoots on a given node.
+function forRoots(node, cb) {
+ var root = node.shadowRoot;
+ while(root) {
+ forSubtree(root, cb);
+ root = root.olderShadowRoot;
+ }
+}
+
+// walk the subtree rooted at node, including descent into shadow-roots,
+// applying 'cb' to each element
+function forSubtree(node, cb) {
+ //logFlags.dom && node.childNodes && node.childNodes.length && console.group('subTree: ', node);
+ findAll(node, function(e) {
+ if (cb(e)) {
+ return true;
+ }
+ forRoots(e, cb);
+ });
+ forRoots(node, cb);
+ //logFlags.dom && node.childNodes && node.childNodes.length && console.groupEnd();
+}
+
+// manage lifecycle on added node
+function added(node) {
+ if (upgrade(node)) {
+ insertedNode(node);
+ return true;
+ }
+ inserted(node);
+}
+
+// manage lifecycle on added node's subtree only
+function addedSubtree(node) {
+ forSubtree(node, function(e) {
+ if (added(e)) {
+ return true;
+ }
+ });
+}
+
+// manage lifecycle on added node and it's subtree
+function addedNode(node) {
+ return added(node) || addedSubtree(node);
+}
+
+// upgrade custom elements at node, if applicable
+function upgrade(node) {
+ if (!node.__upgraded__ && node.nodeType === Node.ELEMENT_NODE) {
+ var type = node.getAttribute('is') || node.localName;
+ var definition = scope.registry[type];
+ if (definition) {
+ logFlags.dom && console.group('upgrade:', node.localName);
+ scope.upgrade(node);
+ logFlags.dom && console.groupEnd();
+ return true;
+ }
+ }
+}
+
+function insertedNode(node) {
+ inserted(node);
+ if (inDocument(node)) {
+ forSubtree(node, function(e) {
+ inserted(e);
+ });
+ }
+}
+
+// TODO(sorvell): on platforms without MutationObserver, mutations may not be
+// reliable and therefore attached/detached are not reliable.
+// To make these callbacks less likely to fail, we defer all inserts and removes
+// to give a chance for elements to be inserted into dom.
+// This ensures attachedCallback fires for elements that are created and
+// immediately added to dom.
+var hasPolyfillMutations = (!window.MutationObserver ||
+ (window.MutationObserver === window.JsMutationObserver));
+scope.hasPolyfillMutations = hasPolyfillMutations;
+
+var isPendingMutations = false;
+var pendingMutations = [];
+function deferMutation(fn) {
+ pendingMutations.push(fn);
+ if (!isPendingMutations) {
+ isPendingMutations = true;
+ var async = (window.Platform && window.Platform.endOfMicrotask) ||
+ setTimeout;
+ async(takeMutations);
+ }
+}
+
+function takeMutations() {
+ isPendingMutations = false;
+ var $p = pendingMutations;
+ for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
+ p();
+ }
+ pendingMutations = [];
+}
+
+function inserted(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _inserted(element);
+ });
+ } else {
+ _inserted(element);
+ }
+}
+
+// TODO(sjmiles): if there are descents into trees that can never have inDocument(*) true, fix this
+function _inserted(element) {
+ // TODO(sjmiles): it's possible we were inserted and removed in the space
+ // of one microtask, in which case we won't be 'inDocument' here
+ // But there are other cases where we are testing for inserted without
+ // specific knowledge of mutations, and must test 'inDocument' to determine
+ // whether to call inserted
+ // If we can factor these cases into separate code paths we can have
+ // better diagnostics.
+ // TODO(sjmiles): when logging, do work on all custom elements so we can
+ // track behavior even when callbacks not defined
+ //console.log('inserted: ', element.localName);
+ if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {
+ logFlags.dom && console.group('inserted:', element.localName);
+ if (inDocument(element)) {
+ element.__inserted = (element.__inserted || 0) + 1;
+ // if we are in a 'removed' state, bluntly adjust to an 'inserted' state
+ if (element.__inserted < 1) {
+ element.__inserted = 1;
+ }
+ // if we are 'over inserted', squelch the callback
+ if (element.__inserted > 1) {
+ logFlags.dom && console.warn('inserted:', element.localName,
+ 'insert/remove count:', element.__inserted)
+ } else if (element.attachedCallback) {
+ logFlags.dom && console.log('inserted:', element.localName);
+ element.attachedCallback();
+ }
+ }
+ logFlags.dom && console.groupEnd();
+ }
+}
+
+function removedNode(node) {
+ removed(node);
+ forSubtree(node, function(e) {
+ removed(e);
+ });
+}
+
+function removed(element) {
+ if (hasPolyfillMutations) {
+ deferMutation(function() {
+ _removed(element);
+ });
+ } else {
+ _removed(element);
+ }
+}
+
+function _removed(element) {
+ // TODO(sjmiles): temporary: do work on all custom elements so we can track
+ // behavior even when callbacks not defined
+ if (element.attachedCallback || element.detachedCallback || (element.__upgraded__ && logFlags.dom)) {
+ logFlags.dom && console.group('removed:', element.localName);
+ if (!inDocument(element)) {
+ element.__inserted = (element.__inserted || 0) - 1;
+ // if we are in a 'inserted' state, bluntly adjust to an 'removed' state
+ if (element.__inserted > 0) {
+ element.__inserted = 0;
+ }
+ // if we are 'over removed', squelch the callback
+ if (element.__inserted < 0) {
+ logFlags.dom && console.warn('removed:', element.localName,
+ 'insert/remove count:', element.__inserted)
+ } else if (element.detachedCallback) {
+ element.detachedCallback();
+ }
+ }
+ logFlags.dom && console.groupEnd();
+ }
+}
+
+// SD polyfill intrustion due mainly to the fact that 'document'
+// is not entirely wrapped
+function wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill ? ShadowDOMPolyfill.wrapIfNeeded(node)
+ : node;
+}
+
+function inDocument(element) {
+ var p = element;
+ var doc = wrapIfNeeded(document);
+ while (p) {
+ if (p == doc) {
+ return true;
+ }
+ p = p.parentNode || p.host;
+ }
+}
+
+function watchShadow(node) {
+ if (node.shadowRoot && !node.shadowRoot.__watched) {
+ logFlags.dom && console.log('watching shadow-root for: ', node.localName);
+ // watch all unwatched roots...
+ var root = node.shadowRoot;
+ while (root) {
+ watchRoot(root);
+ root = root.olderShadowRoot;
+ }
+ }
+}
+
+function watchRoot(root) {
+ if (!root.__watched) {
+ observe(root);
+ root.__watched = true;
+ }
+}
+
+function handler(mutations) {
+ //
+ if (logFlags.dom) {
+ var mx = mutations[0];
+ if (mx && mx.type === 'childList' && mx.addedNodes) {
+ if (mx.addedNodes) {
+ var d = mx.addedNodes[0];
+ while (d && d !== document && !d.host) {
+ d = d.parentNode;
+ }
+ var u = d && (d.URL || d._URL || (d.host && d.host.localName)) || '';
+ u = u.split('/?').shift().split('/').pop();
+ }
+ }
+ console.group('mutations (%d) [%s]', mutations.length, u || '');
+ }
+ //
+ mutations.forEach(function(mx) {
+ //logFlags.dom && console.group('mutation');
+ if (mx.type === 'childList') {
+ forEach(mx.addedNodes, function(n) {
+ //logFlags.dom && console.log(n.localName);
+ if (!n.localName) {
+ return;
+ }
+ // nodes added may need lifecycle management
+ addedNode(n);
+ });
+ // removed nodes may need lifecycle management
+ forEach(mx.removedNodes, function(n) {
+ //logFlags.dom && console.log(n.localName);
+ if (!n.localName) {
+ return;
+ }
+ removedNode(n);
+ });
+ }
+ //logFlags.dom && console.groupEnd();
+ });
+ logFlags.dom && console.groupEnd();
+};
+
+var observer = new MutationObserver(handler);
+
+function takeRecords() {
+ // TODO(sjmiles): ask Raf why we have to call handler ourselves
+ handler(observer.takeRecords());
+ takeMutations();
+}
+
+var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+
+function observe(inRoot) {
+ observer.observe(inRoot, {childList: true, subtree: true});
+}
+
+function observeDocument(doc) {
+ observe(doc);
+}
+
+function upgradeDocument(doc) {
+ logFlags.dom && console.group('upgradeDocument: ', (doc.baseURI).split('/').pop());
+ addedNode(doc);
+ logFlags.dom && console.groupEnd();
+}
+
+function upgradeDocumentTree(doc) {
+ doc = wrapIfNeeded(doc);
+ //console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());
+ // upgrade contained imported documents
+ var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');
+ for (var i=0, l=imports.length, n; (i<l) && (n=imports[i]); i++) {
+ if (n.import && n.import.__parsed) {
+ upgradeDocumentTree(n.import);
+ }
+ }
+ upgradeDocument(doc);
+}
+
+// exports
+scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
+scope.watchShadow = watchShadow;
+scope.upgradeDocumentTree = upgradeDocumentTree;
+scope.upgradeAll = addedNode;
+scope.upgradeSubtree = addedSubtree;
+scope.insertedNode = insertedNode;
+
+scope.observeDocument = observeDocument;
+scope.upgradeDocument = upgradeDocument;
+
+scope.takeRecords = takeRecords;
+
+})(window.CustomElements);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
/**
- * Implements `document.register`
+ * Implements `document.registerElement`
* @module CustomElements
*/
@@ -11983,8 +12310,6 @@ if (useNative) {
if (definition.is) {
element.setAttribute('is', definition.is);
}
- // remove 'unresolved' attr, which is a standin for :unresolved.
- element.removeAttribute('unresolved');
// make 'element' implement definition.prototype
implement(element, definition);
// flag as upgraded
@@ -12222,9 +12547,12 @@ scope.useNative = useNative;
})(window.CustomElements);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function(scope) {
@@ -12286,9 +12614,12 @@ scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
})(window.CustomElements);
/*
- * 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.
+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+ * Code distributed by Google as part of the polymer project is also
+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function(scope){
@@ -12298,14 +12629,19 @@ function bootstrap() {
CustomElements.parser.parse(document);
// one more pass before register is 'live'
CustomElements.upgradeDocument(document);
- // choose async
- var async = window.Platform && Platform.endOfMicrotask ?
- Platform.endOfMicrotask :
- setTimeout;
- async(function() {
- // set internal 'ready' flag, now document.registerElement will trigger
- // synchronous upgrades
- CustomElements.ready = true;
+ // install upgrade hook if HTMLImports are available
+ if (window.HTMLImports) {
+ HTMLImports.__importsParsingHook = function(elt) {
+ CustomElements.parser.parse(elt.import);
+ }
+ }
+ // set internal 'ready' flag, now document.registerElement will trigger
+ // synchronous upgrades
+ CustomElements.ready = true;
+ // async to ensure *native* custom elements upgrade prior to this
+ // DOMContentLoaded can fire before elements upgrade (e.g. when there's
+ // an external script)
+ setTimeout(function() {
// capture blunt profiling data
CustomElements.readyTime = Date.now();
if (window.HTMLImports) {
@@ -12315,23 +12651,18 @@ function bootstrap() {
document.dispatchEvent(
new CustomEvent('WebComponentsReady', {bubbles: true})
);
-
- // install upgrade hook if HTMLImports are available
- if (window.HTMLImports) {
- HTMLImports.__importsParsingHook = function(elt) {
- CustomElements.parser.parse(elt.import);
- }
- }
});
}
// CustomEvent shim for IE
if (typeof window.CustomEvent !== 'function') {
- window.CustomEvent = function(inType) {
- var e = document.createEvent('HTMLEvents');
- e.initEvent(inType, true, true);
+ window.CustomEvent = function(inType, params) {
+ params = params || {};
+ var e = document.createEvent('CustomEvent');
+ e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
return e;
};
+ window.CustomEvent.prototype = window.Event.prototype;
}
// When loading at readyState complete time (or via flag), boot custom elements
@@ -13496,7 +13827,7 @@ scope.styleResolver = styleResolver;
this.refContent_ = undefined;
this.iterator_.valueChanged();
- this.iterator_.updateIteratedValue();
+ this.iterator_.updateIteratedValue(this.iterator_.getUpdatedValue());
},
clear: function() {
@@ -13900,19 +14231,22 @@ scope.styleResolver = styleResolver;
var deps = this.deps = {};
var template = this.templateElement_;
+ var ifValue = true;
if (directives.if) {
deps.hasIf = true;
deps.ifOneTime = directives.if.onlyOneTime;
deps.ifValue = processBinding(IF, directives.if, template, model);
+ ifValue = deps.ifValue;
+
// oneTime if & predicate is false. nothing else to do.
- if (deps.ifOneTime && !deps.ifValue) {
- this.updateIteratedValue();
+ if (deps.ifOneTime && !ifValue) {
+ this.valueChanged();
return;
}
if (!deps.ifOneTime)
- deps.ifValue.open(this.updateIteratedValue, this);
+ ifValue = ifValue.open(this.updateIfValue, this);
}
if (directives.repeat) {
@@ -13925,13 +14259,40 @@ scope.styleResolver = styleResolver;
deps.value = processBinding(BIND, directives.bind, template, model);
}
+ var value = deps.value;
if (!deps.oneTime)
- deps.value.open(this.updateIteratedValue, this);
+ value = value.open(this.updateIteratedValue, this);
+
+ if (!ifValue) {
+ this.valueChanged();
+ return;
+ }
+
+ this.updateValue(value);
+ },
- this.updateIteratedValue();
+ /**
+ * Gets the updated value of the bind/repeat. This can potentially call
+ * user code (if a bindingDelegate is set up) so we try to avoid it if we
+ * already have the value in hand (from Observer.open).
+ */
+ getUpdatedValue: function() {
+ var value = this.deps.value;
+ if (!this.deps.oneTime)
+ value = value.discardChanges();
+ return value;
+ },
+
+ updateIfValue: function(ifValue) {
+ if (!ifValue) {
+ this.valueChanged();
+ return;
+ }
+
+ this.updateValue(this.getUpdatedValue());
},
- updateIteratedValue: function() {
+ updateIteratedValue: function(value) {
if (this.deps.hasIf) {
var ifValue = this.deps.ifValue;
if (!this.deps.ifOneTime)
@@ -13942,9 +14303,10 @@ scope.styleResolver = styleResolver;
}
}
- var value = this.deps.value;
- if (!this.deps.oneTime)
- value = value.discardChanges();
+ this.updateValue(value);
+ },
+
+ updateValue: function(value) {
if (!this.deps.repeat)
value = [value];
var observe = this.deps.repeat &&
@@ -14234,4 +14596,4 @@ scope.flush = flush;
})(window.Platform);
-//# sourceMappingURL=platform.concat.js.map
+//# sourceMappingURL=platform.concat.js.map
« no previous file with comments | « pkg/web_components/lib/platform.js ('k') | pkg/web_components/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698