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

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

Issue 558673004: update polymer js to 0.4.0 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/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 6eea86858eae0662dae51b4d21570024a9388a2c..9b7ff43b306605248f61313126fcba359fd2e5f2 100644
--- a/pkg/web_components/lib/platform.concat.js
+++ b/pkg/web_components/lib/platform.concat.js
@@ -112,6 +112,9 @@ if (typeof WeakMap === 'undefined') {
})();
}
+// select ShadowDOM impl
+if (Platform.flags.shadow) {
+
// Copyright 2012 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -1840,9 +1843,6 @@ 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) {
-
// Copyright 2012 The Polymer Authors. All rights reserved.
// Use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE file.
@@ -8512,27 +8512,33 @@ var ShadowCSS = {
cssText += this.scopeRules(rule.cssRules, scopeSelector);
cssText += '\n}\n\n';
} else {
- // TODO(sjmiles): KEYFRAMES_RULE in IE11 throws when we query cssText
- // 'cssText' in rule returns true, but rule.cssText throws anyway
- // We can test the rule type, e.g.
- // else if (rule.type !== CSSRule.KEYFRAMES_RULE && rule.cssText) {
- // but this will prevent cssText propagation in other browsers which
- // support it.
- // KEYFRAMES_RULE has a CSSRuleSet, so the text can probably be reconstructed
- // from that collection; this would be a proper fix.
- // For now, I'm trapping the exception so IE11 is unblocked in other areas.
+ // KEYFRAMES_RULE in IE throws when we query cssText
+ // when it contains a -webkit- property.
+ // if this happens, we fallback to constructing the rule
+ // from the CSSRuleSet
+ // https://connect.microsoft.com/IE/feedbackdetail/view/955703/accessing-csstext-of-a-keyframe-rule-that-contains-a-webkit-property-via-cssom-generates-exception
try {
if (rule.cssText) {
cssText += rule.cssText + '\n\n';
}
} catch(x) {
- // squelch
+ if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {
+ cssText += this.ieSafeCssTextFromKeyFrameRule(rule);
+ }
}
}
}, this);
}
return cssText;
},
+ ieSafeCssTextFromKeyFrameRule: function(rule) {
+ var cssText = '@keyframes ' + rule.name + ' {';
+ Array.prototype.forEach.call(rule.cssRules, function(rule) {
+ cssText += ' ' + rule.keyText + ' {' + rule.style.cssText + '}';
+ });
+ cssText += ' }';
+ return cssText;
+ },
scopeSelector: function(selector, scopeSelector, strict) {
var r = [], parts = selector.split(',');
parts.forEach(function(p) {
@@ -8755,7 +8761,7 @@ function withCssRules(cssText, callback) {
var style = cssTextToStyle(cssText);
inFrame(function(doc) {
doc.head.appendChild(style.impl);
- rules = style.sheet.cssRules;
+ rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
callback(rules);
});
} else {
@@ -8836,11 +8842,10 @@ if (window.ShadowDOMPolyfill) {
}
if (elt.__resource) {
style = elt.ownerDocument.createElement('style');
- style.textContent = urlResolver.resolveCssText(
- elt.__resource, elt.href);
- } else {
- urlResolver.resolveStyle(style);
+ style.textContent = elt.__resource;
}
+ // relay on HTMLImports for path fixup
+ HTMLImports.path.resolveUrlsInStyle(style);
style.textContent = ShadowCSS.shimStyle(style);
style.removeAttribute(SHIM_ATTRIBUTE, '');
style.setAttribute(SHIMMED_ATTRIBUTE, '');
@@ -8906,23 +8911,6 @@ scope.ShadowCSS = ShadowCSS;
}
});
- Platform.templateContent = function(inTemplate) {
- // if MDV exists, it may need to boostrap this template to reveal content
- if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
- HTMLTemplateElement.bootstrap(inTemplate);
- }
- // fallback when there is no Shadow DOM polyfill, no MDV polyfill, and no
- // native template support
- if (!inTemplate.content && !inTemplate._content) {
- var frag = document.createDocumentFragment();
- while (inTemplate.firstChild) {
- frag.appendChild(inTemplate.firstChild);
- }
- inTemplate._content = frag;
- }
- return inTemplate.content || inTemplate._content;
- };
-
})(window.Platform);
}
@@ -9530,42 +9518,6 @@ if (!Function.prototype.bind) {
};
}
-// mixin
-
-// copy all properties from inProps (et al) to inObj
-function mixin(inObj/*, inProps, inMoreProps, ...*/) {
- var obj = inObj || {};
- for (var i = 1; i < arguments.length; i++) {
- var p = arguments[i];
- try {
- for (var n in p) {
- copyProperty(n, p, obj);
- }
- } catch(x) {
- }
- }
- return obj;
-}
-
-// copy property inName from inSource object to inTarget object
-function copyProperty(inName, inSource, inTarget) {
- var pd = getPropertyDescriptor(inSource, inName);
- Object.defineProperty(inTarget, inName, pd);
-}
-
-// get property descriptor for inName on inObject, even if
-// inName exists on some link in inObject's prototype chain
-function getPropertyDescriptor(inObject, inName) {
- if (inObject) {
- var pd = Object.getOwnPropertyDescriptor(inObject, inName);
- return pd || getPropertyDescriptor(Object.getPrototypeOf(inObject), inName);
- }
-}
-
-// export
-
-scope.mixin = mixin;
-
})(window.Platform);
/*
@@ -9581,46 +9533,6 @@ scope.mixin = mixin;
'use strict';
- // polyfill DOMTokenList
- // * add/remove: allow these methods to take multiple classNames
- // * toggle: add a 2nd argument which forces the given state rather
- // than toggling.
-
- var add = DOMTokenList.prototype.add;
- var remove = DOMTokenList.prototype.remove;
- DOMTokenList.prototype.add = function() {
- for (var i = 0; i < arguments.length; i++) {
- add.call(this, arguments[i]);
- }
- };
- DOMTokenList.prototype.remove = function() {
- for (var i = 0; i < arguments.length; i++) {
- remove.call(this, arguments[i]);
- }
- };
- DOMTokenList.prototype.toggle = function(name, bool) {
- if (arguments.length == 1) {
- bool = !this.contains(name);
- }
- bool ? this.add(name) : this.remove(name);
- };
- DOMTokenList.prototype.switch = function(oldName, newName) {
- oldName && this.remove(oldName);
- newName && this.add(newName);
- };
-
- // add array() to NodeList, NamedNodeMap, HTMLCollection
-
- var ArraySlice = function() {
- return Array.prototype.slice.call(this);
- };
-
- var namedNodeMap = (window.NamedNodeMap || window.MozNamedAttrMap || {});
-
- NodeList.prototype.array = ArraySlice;
- namedNodeMap.prototype.array = ArraySlice;
- HTMLCollection.prototype.array = ArraySlice;
-
// polyfill performance.now
if (!window.performance) {
@@ -9658,19 +9570,6 @@ scope.mixin = mixin;
})();
}
- // utility
-
- function createDOM(inTagOrNode, inHTML, inAttrs) {
- var dom = typeof inTagOrNode == 'string' ?
- document.createElement(inTagOrNode) : inTagOrNode.cloneNode(true);
- dom.innerHTML = inHTML;
- if (inAttrs) {
- for (var n in inAttrs) {
- dom.setAttribute(n, inAttrs[n]);
- }
- }
- return dom;
- }
// Make a stub for Polymer() for polyfill purposes; under the HTMLImports
// polyfill, scripts in the main document run before imports. That means
// if (1) polymer is imported and (2) Polymer() is called in the main document
@@ -9680,17 +9579,21 @@ scope.mixin = mixin;
var elementDeclarations = [];
var polymerStub = function(name, dictionary) {
+ Array.prototype.push.call(arguments, document._currentScript);
elementDeclarations.push(arguments);
- }
+ };
window.Polymer = polymerStub;
// deliver queued delcarations
- scope.deliverDeclarations = function() {
- scope.deliverDeclarations = function() {
+ scope.consumeDeclarations = function(callback) {
+ scope.consumeDeclarations = function() {
throw 'Possible attempt to load Polymer twice';
};
- return elementDeclarations;
- }
+ if (callback) {
+ callback(elementDeclarations);
+ }
+ elementDeclarations = null;
+ };
// Once DOMContent has loaded, any main document scripts that depend on
// Polymer() should have run. Calling Polymer() now is an error until
@@ -9705,583 +9608,107 @@ scope.mixin = mixin;
}
});
- // exports
- scope.createDOM = createDOM;
-
-})(window.Platform);
-
-/*
- * 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
- */
-
-// poor man's adapter for template.content on various platform scenarios
-(function(scope) {
- scope.templateContent = scope.templateContent || function(inTemplate) {
- return inTemplate.content;
- };
})(window.Platform);
/*
- * 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
+ * Copyright 2012 The Polymer Authors. All rights reserved.
+ * Use of this source code is goverened by a BSD-style
+ * license that can be found in the LICENSE file.
*/
-(function(scope) {
-
- scope = scope || (window.Inspector = {});
-
- var inspector;
-
- window.sinspect = function(inNode, inProxy) {
- if (!inspector) {
- inspector = window.open('', 'ShadowDOM Inspector', null, true);
- inspector.document.write(inspectorHTML);
- //inspector.document.close();
- inspector.api = {
- shadowize: shadowize
- };
- }
- inspect(inNode || wrap(document.body), inProxy);
- };
-
- var inspectorHTML = [
- '<!DOCTYPE html>',
- '<html>',
- ' <head>',
- ' <title>ShadowDOM Inspector</title>',
- ' <style>',
- ' body {',
- ' }',
- ' pre {',
- ' font: 9pt "Courier New", monospace;',
- ' line-height: 1.5em;',
- ' }',
- ' tag {',
- ' color: purple;',
- ' }',
- ' ul {',
- ' margin: 0;',
- ' padding: 0;',
- ' list-style: none;',
- ' }',
- ' li {',
- ' display: inline-block;',
- ' background-color: #f1f1f1;',
- ' padding: 4px 6px;',
- ' border-radius: 4px;',
- ' margin-right: 4px;',
- ' }',
- ' </style>',
- ' </head>',
- ' <body>',
- ' <ul id="crumbs">',
- ' </ul>',
- ' <div id="tree"></div>',
- ' </body>',
- '</html>'
- ].join('\n');
-
- var crumbs = [];
-
- var displayCrumbs = function() {
- // alias our document
- var d = inspector.document;
- // get crumbbar
- var cb = d.querySelector('#crumbs');
- // clear crumbs
- cb.textContent = '';
- // build new crumbs
- for (var i=0, c; c=crumbs[i]; i++) {
- var a = d.createElement('a');
- a.href = '#';
- a.textContent = c.localName;
- a.idx = i;
- a.onclick = function(event) {
- var c;
- while (crumbs.length > this.idx) {
- c = crumbs.pop();
- }
- inspect(c.shadow || c, c);
- event.preventDefault();
- };
- cb.appendChild(d.createElement('li')).appendChild(a);
- }
- };
-
- var inspect = function(inNode, inProxy) {
- // alias our document
- var d = inspector.document;
- // reset list of drillable nodes
- drillable = [];
- // memoize our crumb proxy
- var proxy = inProxy || inNode;
- crumbs.push(proxy);
- // update crumbs
- displayCrumbs();
- // reflect local tree
- d.body.querySelector('#tree').innerHTML =
- '<pre>' + output(inNode, inNode.childNodes) + '</pre>';
- };
+(function(global) {
- var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
+ var registrationsTable = new WeakMap();
- var blacklisted = {STYLE:1, SCRIPT:1, "#comment": 1, TEMPLATE: 1};
- var blacklist = function(inNode) {
- return blacklisted[inNode.nodeName];
- };
+ // We use setImmediate or postMessage for our future callback.
+ var setImmediate = window.msSetImmediate;
- var output = function(inNode, inChildNodes, inIndent) {
- if (blacklist(inNode)) {
- return '';
- }
- var indent = inIndent || '';
- if (inNode.localName || inNode.nodeType == 11) {
- var name = inNode.localName || 'shadow-root';
- //inChildNodes = ShadowDOM.localNodes(inNode);
- var info = indent + describe(inNode);
- // if only textNodes
- // TODO(sjmiles): make correct for ShadowDOM
- /*if (!inNode.children.length && inNode.localName !== 'content' && inNode.localName !== 'shadow') {
- info += catTextContent(inChildNodes);
- } else*/ {
- // TODO(sjmiles): native <shadow> has no reference to its projection
- if (name == 'content' /*|| name == 'shadow'*/) {
- inChildNodes = inNode.getDistributedNodes();
- }
- info += '<br/>';
- var ind = indent + '&nbsp;&nbsp;';
- forEach(inChildNodes, function(n) {
- info += output(n, n.childNodes, ind);
+ // Use post message to emulate setImmediate.
+ if (!setImmediate) {
+ var setImmediateQueue = [];
+ var sentinel = String(Math.random());
+ window.addEventListener('message', function(e) {
+ if (e.data === sentinel) {
+ var queue = setImmediateQueue;
+ setImmediateQueue = [];
+ queue.forEach(function(func) {
+ func();
});
- info += indent;
- }
- if (!({br:1}[name])) {
- info += '<tag>&lt;/' + name + '&gt;</tag>';
- info += '<br/>';
}
- } else {
- var text = inNode.textContent.trim();
- info = text ? indent + '"' + text + '"' + '<br/>' : '';
- }
- return info;
- };
-
- var catTextContent = function(inChildNodes) {
- var info = '';
- forEach(inChildNodes, function(n) {
- info += n.textContent.trim();
});
- return info;
- };
-
- var drillable = [];
+ setImmediate = function(func) {
+ setImmediateQueue.push(func);
+ window.postMessage(sentinel, '*');
+ };
+ }
- var describe = function(inNode) {
- var tag = '<tag>' + '&lt;';
- var name = inNode.localName || 'shadow-root';
- if (inNode.webkitShadowRoot || inNode.shadowRoot) {
- tag += ' <button idx="' + drillable.length +
- '" onclick="api.shadowize.call(this)">' + name + '</button>';
- drillable.push(inNode);
- } else {
- tag += name || 'shadow-root';
- }
- if (inNode.attributes) {
- forEach(inNode.attributes, function(a) {
- tag += ' ' + a.name + (a.value ? '="' + a.value + '"' : '');
- });
- }
- tag += '&gt;'+ '</tag>';
- return tag;
- };
+ // This is used to ensure that we never schedule 2 callas to setImmediate
+ var isScheduled = false;
- // remote api
+ // Keep track of observers that needs to be notified next time.
+ var scheduledObservers = [];
- shadowize = function() {
- var idx = Number(this.attributes.idx.value);
- //alert(idx);
- var node = drillable[idx];
- if (node) {
- inspect(node.webkitShadowRoot || node.shadowRoot, node)
- } else {
- console.log("bad shadowize node");
- console.dir(this);
+ /**
+ * Schedules |dispatchCallback| to be called in the future.
+ * @param {MutationObserver} observer
+ */
+ function scheduleCallback(observer) {
+ scheduledObservers.push(observer);
+ if (!isScheduled) {
+ isScheduled = true;
+ setImmediate(dispatchCallbacks);
}
- };
-
- // export
-
- scope.output = output;
-
-})(window.Inspector);
+ }
-/*
- * 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 wrapIfNeeded(node) {
+ return window.ShadowDOMPolyfill &&
+ window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
+ node;
+ }
-(function(scope) {
+ function dispatchCallbacks() {
+ // http://dom.spec.whatwg.org/#mutation-observers
- // TODO(sorvell): It's desireable to provide a default stylesheet
- // that's convenient for styling unresolved elements, but
- // it's cumbersome to have to include this manually in every page.
- // It would make sense to put inside some HTMLImport but
- // the HTMLImports polyfill does not allow loading of stylesheets
- // that block rendering. Therefore this injection is tolerated here.
+ isScheduled = false; // Used to allow a new setImmediate call above.
- var style = document.createElement('style');
- style.textContent = ''
- + 'body {'
- + 'transition: opacity ease-in 0.2s;'
- + ' } \n'
- + 'body[unresolved] {'
- + 'opacity: 0; display: block; overflow: hidden;'
- + ' } \n'
- ;
- var head = document.querySelector('head');
- head.insertBefore(style, head.firstChild);
+ var observers = scheduledObservers;
+ scheduledObservers = [];
+ // Sort observers based on their creation UID (incremental).
+ observers.sort(function(o1, o2) {
+ return o1.uid_ - o2.uid_;
+ });
-})(Platform);
+ var anyNonEmpty = false;
+ observers.forEach(function(observer) {
-/*
- * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
- * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
- * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
- * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
- * Code distributed by Google as part of the polymer project is also
- * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
- */
+ // 2.1, 2.2
+ var queue = observer.takeRecords();
+ // 2.3. Remove all transient registered observers whose observer is mo.
+ removeTransientObserversFor(observer);
-(function(scope) {
+ // 2.4
+ if (queue.length) {
+ observer.callback_(queue, observer);
+ anyNonEmpty = true;
+ }
+ });
- function withDependencies(task, depends) {
- depends = depends || [];
- if (!depends.map) {
- depends = [depends];
- }
- return task.apply(this, depends.map(marshal));
+ // 3.
+ if (anyNonEmpty)
+ dispatchCallbacks();
}
- function module(name, dependsOrFactory, moduleFactory) {
- var module;
- switch (arguments.length) {
- case 0:
+ function removeTransientObserversFor(observer) {
+ observer.nodes_.forEach(function(node) {
+ var registrations = registrationsTable.get(node);
+ if (!registrations)
return;
- case 1:
- module = null;
- break;
- case 2:
- // dependsOrFactory is `factory` in this case
- module = dependsOrFactory.apply(this);
- break;
- default:
- // dependsOrFactory is `depends` in this case
- module = withDependencies(moduleFactory, dependsOrFactory);
- break;
- }
- modules[name] = module;
- };
-
- function marshal(name) {
- return modules[name];
- }
-
- var modules = {};
-
- function using(depends, task) {
- HTMLImports.whenImportsReady(function() {
- withDependencies(task, depends);
+ registrations.forEach(function(registration) {
+ if (registration.observer === observer)
+ registration.removeTransientObservers();
+ });
});
- };
-
- // exports
-
- scope.marshal = marshal;
- // `module` confuses commonjs detectors
- scope.modularize = module;
- scope.using = using;
-
-})(window);
-
-/*
- * 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 iterations = 0;
-var callbacks = [];
-var twiddle = document.createTextNode('');
-
-function endOfMicrotask(callback) {
- twiddle.textContent = iterations++;
- callbacks.push(callback);
-}
-
-function atEndOfMicrotask() {
- while (callbacks.length) {
- callbacks.shift()();
- }
-}
-
-new (window.MutationObserver || JsMutationObserver)(atEndOfMicrotask)
- .observe(twiddle, {characterData: true})
- ;
-
-// exports
-
-scope.endOfMicrotask = endOfMicrotask;
-
-})(Platform);
-
-
-/*
- * 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 urlResolver = {
- resolveDom: function(root, url) {
- url = url || root.ownerDocument.baseURI;
- this.resolveAttributes(root, url);
- this.resolveStyles(root, url);
- // handle template.content
- var templates = root.querySelectorAll('template');
- if (templates) {
- for (var i = 0, l = templates.length, t; (i < l) && (t = templates[i]); i++) {
- if (t.content) {
- this.resolveDom(t.content, url);
- }
- }
- }
- },
- resolveTemplate: function(template) {
- this.resolveDom(template.content, template.ownerDocument.baseURI);
- },
- resolveStyles: function(root, url) {
- var styles = root.querySelectorAll('style');
- if (styles) {
- for (var i = 0, l = styles.length, s; (i < l) && (s = styles[i]); i++) {
- this.resolveStyle(s, url);
- }
- }
- },
- resolveStyle: function(style, url) {
- url = url || style.ownerDocument.baseURI;
- style.textContent = this.resolveCssText(style.textContent, url);
- },
- resolveCssText: function(cssText, baseUrl, keepAbsolute) {
- cssText = replaceUrlsInCssText(cssText, baseUrl, keepAbsolute, CSS_URL_REGEXP);
- return replaceUrlsInCssText(cssText, baseUrl, keepAbsolute, CSS_IMPORT_REGEXP);
- },
- resolveAttributes: function(root, url) {
- if (root.hasAttributes && root.hasAttributes()) {
- this.resolveElementAttributes(root, url);
- }
- // search for attributes that host urls
- var nodes = root && root.querySelectorAll(URL_ATTRS_SELECTOR);
- if (nodes) {
- for (var i = 0, l = nodes.length, n; (i < l) && (n = nodes[i]); i++) {
- this.resolveElementAttributes(n, url);
- }
- }
- },
- resolveElementAttributes: function(node, url) {
- url = url || node.ownerDocument.baseURI;
- URL_ATTRS.forEach(function(v) {
- var attr = node.attributes[v];
- var value = attr && attr.value;
- var replacement;
- if (value && value.search(URL_TEMPLATE_SEARCH) < 0) {
- if (v === 'style') {
- replacement = replaceUrlsInCssText(value, url, false, CSS_URL_REGEXP);
- } else {
- replacement = resolveRelativeUrl(url, value);
- }
- attr.value = replacement;
- }
- });
- }
-};
-
-var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
-var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
-var URL_ATTRS = ['href', 'src', 'action', 'style', 'url'];
-var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';
-var URL_TEMPLATE_SEARCH = '{{.*}}';
-
-function replaceUrlsInCssText(cssText, baseUrl, keepAbsolute, regexp) {
- return cssText.replace(regexp, function(m, pre, url, post) {
- var urlPath = url.replace(/["']/g, '');
- urlPath = resolveRelativeUrl(baseUrl, urlPath, keepAbsolute);
- return pre + '\'' + urlPath + '\'' + post;
- });
-}
-
-function resolveRelativeUrl(baseUrl, url, keepAbsolute) {
- // do not resolve '/' absolute urls
- if (url && url[0] === '/') {
- return url;
- }
- var u = new URL(url, baseUrl);
- return keepAbsolute ? u.href : makeDocumentRelPath(u.href);
-}
-
-function makeDocumentRelPath(url) {
- var root = new URL(document.baseURI);
- var u = new URL(url, root);
- if (u.host === root.host && u.port === root.port &&
- u.protocol === root.protocol) {
- return makeRelPath(root, u);
- } else {
- return url;
- }
-}
-
-// make a relative path from source to target
-function makeRelPath(sourceUrl, targetUrl) {
- var source = sourceUrl.pathname;
- var target = targetUrl.pathname;
- var s = source.split('/');
- var t = target.split('/');
- while (s.length && s[0] === t[0]){
- s.shift();
- t.shift();
- }
- for (var i = 0, l = s.length - 1; i < l; i++) {
- t.unshift('..');
- }
- return t.join('/') + targetUrl.search + targetUrl.hash;
-}
-
-// exports
-scope.urlResolver = urlResolver;
-
-})(Platform);
-
-/*
- * Copyright 2012 The Polymer Authors. All rights reserved.
- * Use of this source code is goverened by a BSD-style
- * license that can be found in the LICENSE file.
- */
-
-(function(global) {
-
- var registrationsTable = new WeakMap();
-
- // We use setImmediate or postMessage for our future callback.
- var setImmediate = window.msSetImmediate;
-
- // Use post message to emulate setImmediate.
- if (!setImmediate) {
- var setImmediateQueue = [];
- var sentinel = String(Math.random());
- window.addEventListener('message', function(e) {
- if (e.data === sentinel) {
- var queue = setImmediateQueue;
- setImmediateQueue = [];
- queue.forEach(function(func) {
- func();
- });
- }
- });
- setImmediate = function(func) {
- setImmediateQueue.push(func);
- window.postMessage(sentinel, '*');
- };
- }
-
- // This is used to ensure that we never schedule 2 callas to setImmediate
- var isScheduled = false;
-
- // Keep track of observers that needs to be notified next time.
- var scheduledObservers = [];
-
- /**
- * Schedules |dispatchCallback| to be called in the future.
- * @param {MutationObserver} observer
- */
- function scheduleCallback(observer) {
- scheduledObservers.push(observer);
- if (!isScheduled) {
- isScheduled = true;
- setImmediate(dispatchCallbacks);
- }
- }
-
- function wrapIfNeeded(node) {
- return window.ShadowDOMPolyfill &&
- window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
- node;
- }
-
- function dispatchCallbacks() {
- // http://dom.spec.whatwg.org/#mutation-observers
-
- isScheduled = false; // Used to allow a new setImmediate call above.
-
- var observers = scheduledObservers;
- scheduledObservers = [];
- // Sort observers based on their creation UID (incremental).
- observers.sort(function(o1, o2) {
- return o1.uid_ - o2.uid_;
- });
-
- var anyNonEmpty = false;
- observers.forEach(function(observer) {
-
- // 2.1, 2.2
- var queue = observer.takeRecords();
- // 2.3. Remove all transient registered observers whose observer is mo.
- removeTransientObserversFor(observer);
-
- // 2.4
- if (queue.length) {
- observer.callback_(queue, observer);
- anyNonEmpty = true;
- }
- });
-
- // 3.
- if (anyNonEmpty)
- dispatchCallbacks();
- }
-
- function removeTransientObserversFor(observer) {
- observer.nodes_.forEach(function(node) {
- var registrations = registrationsTable.get(node);
- if (!registrations)
- return;
- registrations.forEach(function(registration) {
- if (registration.observer === observer)
- registration.removeTransientObservers();
- });
- });
- }
+ }
/**
* This function is used for the "For each registered observer observer (with
@@ -10739,6 +10166,200 @@ scope.urlResolver = urlResolver;
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
window.HTMLImports = window.HTMLImports || {flags:{}};
+/*
+ * 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 hasNative = ('import' in document.createElement('link'));
+var useNative = hasNative;
+
+isIE = /Trident/.test(navigator.userAgent);
+
+// 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
+};
+
+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);
+ }
+ };
+ doc.addEventListener(READY_EVENT, checkReady);
+ } else if (callback) {
+ callback();
+ }
+}
+
+function markTargetLoaded(event) {
+ event.target.__loaded = true;
+}
+
+// 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) {
+ markTargetLoaded(e);
+ loaded++;
+ checkDone();
+ }
+ if (l) {
+ for (var i=0, imp; (i<l) && (imp=imports[i]); i++) {
+ if (isImportLoaded(imp)) {
+ loadedImport.call(imp, {target: imp});
+ } else {
+ imp.addEventListener('load', loadedImport);
+ imp.addEventListener('error', loadedImport);
+ }
+ }
+ } 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): Workaround for
+// https://www.w3.org/Bugs/Public/show_bug.cgi?id=25007, should be removed when
+// this bug is addressed.
+// (1) Install a mutation observer to see when HTMLImports have loaded
+// (2) if this script is run during document load it will watch any existing
+// imports for loading.
+//
+// NOTE: The workaround has restricted functionality: (1) it's only compatible
+// with imports that are added to document.head since the mutation observer
+// watches only head for perf reasons, (2) it requires this script
+// to run before any imports have completed loading.
+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);
+ }
+ }
+ }
+
+ 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);
+ }
+ }
+
+ // make sure to catch any imports that are in the process of loading
+ // when this script is run.
+ (function() {
+ if (document.readyState === 'loading') {
+ var imports = document.querySelectorAll('link[rel=import]');
+ for (var i=0, l=imports.length, imp; (i<l) && (imp=imports[i]); i++) {
+ handleImport(imp);
+ }
+ }
+ })();
+
+}
+
+// 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
@@ -10746,186 +10367,13 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
* 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 hasNative = ('import' in document.createElement('link'));
-var useNative = hasNative;
+ */
+(function(scope) {
-isIE = /Trident/.test(navigator.userAgent);
-
-// 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
-};
-
-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);
- }
- }
- 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();
- }
-}
-
-// 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);
- }
- }
- }).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;
+ // 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.
@@ -12730,110 +12178,27 @@ if (window.ShadowDOMPolyfill) {
*/
(function(scope) {
- var endOfMicrotask = scope.endOfMicrotask;
-
- // Generic url loader
- function Loader(regex) {
- this.cache = Object.create(null);
- this.map = Object.create(null);
- this.requests = 0;
- this.regex = regex;
- }
- Loader.prototype = {
-
- // TODO(dfreedm): there may be a better factoring here
- // extract absolute urls from the text (full of relative urls)
- extractUrls: function(text, base) {
- var matches = [];
- var matched, u;
- while ((matched = this.regex.exec(text))) {
- u = new URL(matched[1], base);
- matches.push({matched: matched[0], url: u.href});
- }
- return matches;
- },
- // take a text blob, a root url, and a callback and load all the urls found within the text
- // returns a map of absolute url to text
- process: function(text, root, callback) {
- var matches = this.extractUrls(text, root);
-
- // every call to process returns all the text this loader has ever received
- var done = callback.bind(null, this.map);
- this.fetch(matches, done);
- },
- // build a mapping of url -> text from matches
- fetch: function(matches, callback) {
- var inflight = matches.length;
-
- // return early if there is no fetching to be done
- if (!inflight) {
- return callback();
- }
-
- // wait for all subrequests to return
- var done = function() {
- if (--inflight === 0) {
- callback();
- }
- };
-
- // start fetching all subrequests
- var m, req, url;
- for (var i = 0; i < inflight; i++) {
- m = matches[i];
- url = m.url;
- req = this.cache[url];
- // if this url has already been requested, skip requesting it again
- if (!req) {
- req = this.xhr(url);
- req.match = m;
- this.cache[url] = req;
- }
- // wait for the request to process its subrequests
- req.wait(done);
- }
- },
- handleXhr: function(request) {
- var match = request.match;
- var url = match.url;
-
- // handle errors with an empty string
- var response = request.response || request.responseText || '';
- this.map[url] = response;
- this.fetch(this.extractUrls(response, url), request.resolve);
- },
- xhr: function(url) {
- this.requests++;
- var request = new XMLHttpRequest();
- request.open('GET', url, true);
- request.send();
- request.onerror = request.onload = this.handleXhr.bind(this, request);
-
- // queue of tasks to run after XHR returns
- request.pending = [];
- request.resolve = function() {
- var pending = request.pending;
- for(var i = 0; i < pending.length; i++) {
- pending[i]();
- }
- request.pending = null;
- };
- // if we have already resolved, pending is null, async call the callback
- request.wait = function(fn) {
- if (request.pending) {
- request.pending.push(fn);
- } else {
- endOfMicrotask(fn);
- }
- };
+ // TODO(sorvell): It's desireable to provide a default stylesheet
+ // that's convenient for styling unresolved elements, but
+ // it's cumbersome to have to include this manually in every page.
+ // It would make sense to put inside some HTMLImport but
+ // the HTMLImports polyfill does not allow loading of stylesheets
+ // that block rendering. Therefore this injection is tolerated here.
- return request;
- }
- };
+ var style = document.createElement('style');
+ style.textContent = ''
+ + 'body {'
+ + 'transition: opacity ease-in 0.2s;'
+ + ' } \n'
+ + 'body[unresolved] {'
+ + 'opacity: 0; display: block; overflow: hidden;'
+ + ' } \n'
+ ;
+ var head = document.querySelector('head');
+ head.insertBefore(style, head.firstChild);
- scope.Loader = Loader;
-})(window.Platform);
+})(Platform);
/*
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@@ -12846,1755 +12211,53 @@ if (window.ShadowDOMPolyfill) {
(function(scope) {
-var urlResolver = scope.urlResolver;
-var Loader = scope.Loader;
-
-function StyleResolver() {
- this.loader = new Loader(this.regex);
-}
-StyleResolver.prototype = {
- regex: /@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,
- // Recursively replace @imports with the text at that url
- resolve: function(text, url, callback) {
- var done = function(map) {
- callback(this.flatten(text, url, map));
- }.bind(this);
- this.loader.process(text, url, done);
- },
- // resolve the textContent of a style node
- resolveNode: function(style, url, callback) {
- var text = style.textContent;
- var done = function(text) {
- style.textContent = text;
- callback(style);
- };
- this.resolve(text, url, done);
- },
- // flatten all the @imports to text
- flatten: function(text, base, map) {
- var matches = this.loader.extractUrls(text, base);
- var match, url, intermediate;
- for (var i = 0; i < matches.length; i++) {
- match = matches[i];
- url = match.url;
- // resolve any css text to be relative to the importer, keep absolute url
- intermediate = urlResolver.resolveCssText(map[url], url, true);
- // flatten intermediate @imports
- intermediate = this.flatten(intermediate, base, map);
- text = text.replace(match.matched, intermediate);
- }
- return text;
- },
- loadStyles: function(styles, base, callback) {
- var loaded=0, l = styles.length;
- // called in the context of the style
- function loadedStyle(style) {
- loaded++;
- if (loaded === l && callback) {
- callback();
- }
- }
- for (var i=0, s; (i<l) && (s=styles[i]); i++) {
- this.resolveNode(s, base, loadedStyle);
+ function withDependencies(task, depends) {
+ depends = depends || [];
+ if (!depends.map) {
+ depends = [depends];
}
+ return task.apply(this, depends.map(marshal));
}
-};
-
-var styleResolver = new StyleResolver();
-
-// exports
-scope.styleResolver = styleResolver;
-})(window.Platform);
-
-// 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(global) {
- 'use strict';
-
- var filter = Array.prototype.filter.call.bind(Array.prototype.filter);
-
- function getTreeScope(node) {
- while (node.parentNode) {
- node = node.parentNode;
+ function module(name, dependsOrFactory, moduleFactory) {
+ var module;
+ switch (arguments.length) {
+ case 0:
+ return;
+ case 1:
+ module = null;
+ break;
+ case 2:
+ // dependsOrFactory is `factory` in this case
+ module = dependsOrFactory.apply(this);
+ break;
+ default:
+ // dependsOrFactory is `depends` in this case
+ module = withDependencies(moduleFactory, dependsOrFactory);
+ break;
}
-
- return typeof node.getElementById === 'function' ? node : null;
- }
-
- Node.prototype.bind = function(name, observable) {
- console.error('Unhandled binding to Node: ', this, name, observable);
+ modules[name] = module;
};
- Node.prototype.bindFinished = function() {};
-
- function updateBindings(node, name, binding) {
- var bindings = node.bindings_;
- if (!bindings)
- bindings = node.bindings_ = {};
-
- if (bindings[name])
- binding[name].close();
-
- return bindings[name] = binding;
- }
-
- function returnBinding(node, name, binding) {
- return binding;
- }
-
- function sanitizeValue(value) {
- return value == null ? '' : value;
- }
-
- function updateText(node, value) {
- node.data = sanitizeValue(value);
- }
-
- function textBinding(node) {
- return function(value) {
- return updateText(node, value);
- };
- }
-
- var maybeUpdateBindings = returnBinding;
-
- Object.defineProperty(Platform, 'enableBindingsReflection', {
- get: function() {
- return maybeUpdateBindings === updateBindings;
- },
- set: function(enable) {
- maybeUpdateBindings = enable ? updateBindings : returnBinding;
- return enable;
- },
- configurable: true
- });
-
- Text.prototype.bind = function(name, value, oneTime) {
- if (name !== 'textContent')
- return Node.prototype.bind.call(this, name, value, oneTime);
-
- if (oneTime)
- return updateText(this, value);
-
- var observable = value;
- updateText(this, observable.open(textBinding(this)));
- return maybeUpdateBindings(this, name, observable);
- }
-
- function updateAttribute(el, name, conditional, value) {
- if (conditional) {
- if (value)
- el.setAttribute(name, '');
- else
- el.removeAttribute(name);
- return;
- }
-
- el.setAttribute(name, sanitizeValue(value));
- }
-
- function attributeBinding(el, name, conditional) {
- return function(value) {
- updateAttribute(el, name, conditional, value);
- };
+ function marshal(name) {
+ return modules[name];
}
- Element.prototype.bind = function(name, value, oneTime) {
- var conditional = name[name.length - 1] == '?';
- if (conditional) {
- this.removeAttribute(name);
- name = name.slice(0, -1);
- }
-
- if (oneTime)
- return updateAttribute(this, name, conditional, value);
-
-
- var observable = value;
- updateAttribute(this, name, conditional,
- observable.open(attributeBinding(this, name, conditional)));
-
- return maybeUpdateBindings(this, name, observable);
- };
+ var modules = {};
- var checkboxEventType;
- (function() {
- // Attempt to feature-detect which event (change or click) is fired first
- // for checkboxes.
- var div = document.createElement('div');
- var checkbox = div.appendChild(document.createElement('input'));
- checkbox.setAttribute('type', 'checkbox');
- var first;
- var count = 0;
- checkbox.addEventListener('click', function(e) {
- count++;
- first = first || 'click';
- });
- checkbox.addEventListener('change', function() {
- count++;
- first = first || 'change';
+ function using(depends, task) {
+ HTMLImports.whenImportsReady(function() {
+ withDependencies(task, depends);
});
+ };
- var event = document.createEvent('MouseEvent');
- event.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false,
- false, false, false, 0, null);
- checkbox.dispatchEvent(event);
- // WebKit/Blink don't fire the change event if the element is outside the
- // document, so assume 'change' for that case.
- checkboxEventType = count == 1 ? 'change' : first;
- })();
-
- function getEventForInputType(element) {
- switch (element.type) {
- case 'checkbox':
- return checkboxEventType;
- case 'radio':
- case 'select-multiple':
- case 'select-one':
- return 'change';
- case 'range':
- if (/Trident|MSIE/.test(navigator.userAgent))
- return 'change';
- default:
- return 'input';
- }
- }
-
- function updateInput(input, property, value, santizeFn) {
- input[property] = (santizeFn || sanitizeValue)(value);
- }
-
- function inputBinding(input, property, santizeFn) {
- return function(value) {
- return updateInput(input, property, value, santizeFn);
- }
- }
-
- function noop() {}
-
- function bindInputEvent(input, property, observable, postEventFn) {
- var eventType = getEventForInputType(input);
-
- function eventHandler() {
- observable.setValue(input[property]);
- observable.discardChanges();
- (postEventFn || noop)(input);
- Platform.performMicrotaskCheckpoint();
- }
- input.addEventListener(eventType, eventHandler);
-
- return {
- close: function() {
- input.removeEventListener(eventType, eventHandler);
- observable.close();
- },
-
- observable_: observable
- }
- }
-
- function booleanSanitize(value) {
- return Boolean(value);
- }
-
- // |element| is assumed to be an HTMLInputElement with |type| == 'radio'.
- // Returns an array containing all radio buttons other than |element| that
- // have the same |name|, either in the form that |element| belongs to or,
- // if no form, in the document tree to which |element| belongs.
- //
- // This implementation is based upon the HTML spec definition of a
- // "radio button group":
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/number-state.html#radio-button-group
- //
- function getAssociatedRadioButtons(element) {
- if (element.form) {
- return filter(element.form.elements, function(el) {
- return el != element &&
- el.tagName == 'INPUT' &&
- el.type == 'radio' &&
- el.name == element.name;
- });
- } else {
- var treeScope = getTreeScope(element);
- if (!treeScope)
- return [];
- var radios = treeScope.querySelectorAll(
- 'input[type="radio"][name="' + element.name + '"]');
- return filter(radios, function(el) {
- return el != element && !el.form;
- });
- }
- }
-
- function checkedPostEvent(input) {
- // Only the radio button that is getting checked gets an event. We
- // therefore find all the associated radio buttons and update their
- // check binding manually.
- if (input.tagName === 'INPUT' &&
- input.type === 'radio') {
- getAssociatedRadioButtons(input).forEach(function(radio) {
- var checkedBinding = radio.bindings_.checked;
- if (checkedBinding) {
- // Set the value directly to avoid an infinite call stack.
- checkedBinding.observable_.setValue(false);
- }
- });
- }
- }
-
- HTMLInputElement.prototype.bind = function(name, value, oneTime) {
- if (name !== 'value' && name !== 'checked')
- return HTMLElement.prototype.bind.call(this, name, value, oneTime);
-
- this.removeAttribute(name);
- var sanitizeFn = name == 'checked' ? booleanSanitize : sanitizeValue;
- var postEventFn = name == 'checked' ? checkedPostEvent : noop;
-
- if (oneTime)
- return updateInput(this, name, value, sanitizeFn);
-
-
- var observable = value;
- var binding = bindInputEvent(this, name, observable, postEventFn);
- updateInput(this, name,
- observable.open(inputBinding(this, name, sanitizeFn)),
- sanitizeFn);
-
- // Checkboxes may need to update bindings of other checkboxes.
- return updateBindings(this, name, binding);
- }
-
- HTMLTextAreaElement.prototype.bind = function(name, value, oneTime) {
- if (name !== 'value')
- return HTMLElement.prototype.bind.call(this, name, value, oneTime);
-
- this.removeAttribute('value');
+ // exports
- if (oneTime)
- return updateInput(this, 'value', value);
-
- var observable = value;
- var binding = bindInputEvent(this, 'value', observable);
- updateInput(this, 'value',
- observable.open(inputBinding(this, 'value', sanitizeValue)));
- return maybeUpdateBindings(this, name, binding);
- }
-
- function updateOption(option, value) {
- var parentNode = option.parentNode;;
- var select;
- var selectBinding;
- var oldValue;
- if (parentNode instanceof HTMLSelectElement &&
- parentNode.bindings_ &&
- parentNode.bindings_.value) {
- select = parentNode;
- selectBinding = select.bindings_.value;
- oldValue = select.value;
- }
-
- option.value = sanitizeValue(value);
-
- if (select && select.value != oldValue) {
- selectBinding.observable_.setValue(select.value);
- selectBinding.observable_.discardChanges();
- Platform.performMicrotaskCheckpoint();
- }
- }
-
- function optionBinding(option) {
- return function(value) {
- updateOption(option, value);
- }
- }
-
- HTMLOptionElement.prototype.bind = function(name, value, oneTime) {
- if (name !== 'value')
- return HTMLElement.prototype.bind.call(this, name, value, oneTime);
-
- this.removeAttribute('value');
-
- if (oneTime)
- return updateOption(this, value);
-
- var observable = value;
- var binding = bindInputEvent(this, 'value', observable);
- updateOption(this, observable.open(optionBinding(this)));
- return maybeUpdateBindings(this, name, binding);
- }
-
- HTMLSelectElement.prototype.bind = function(name, value, oneTime) {
- if (name === 'selectedindex')
- name = 'selectedIndex';
-
- if (name !== 'selectedIndex' && name !== 'value')
- return HTMLElement.prototype.bind.call(this, name, value, oneTime);
-
- this.removeAttribute(name);
-
- if (oneTime)
- return updateInput(this, name, value);
-
- var observable = value;
- var binding = bindInputEvent(this, name, observable);
- updateInput(this, name,
- observable.open(inputBinding(this, name)));
-
- // Option update events may need to access select bindings.
- return updateBindings(this, name, binding);
- }
-})(this);
-
-// 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(global) {
- 'use strict';
-
- function assert(v) {
- if (!v)
- throw new Error('Assertion failed');
- }
-
- var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach);
-
- function getFragmentRoot(node) {
- var p;
- while (p = node.parentNode) {
- node = p;
- }
-
- return node;
- }
-
- function searchRefId(node, id) {
- if (!id)
- return;
-
- var ref;
- var selector = '#' + id;
- while (!ref) {
- node = getFragmentRoot(node);
-
- if (node.protoContent_)
- ref = node.protoContent_.querySelector(selector);
- else if (node.getElementById)
- ref = node.getElementById(id);
-
- if (ref || !node.templateCreator_)
- break
-
- node = node.templateCreator_;
- }
-
- return ref;
- }
-
- function getInstanceRoot(node) {
- while (node.parentNode) {
- node = node.parentNode;
- }
- return node.templateCreator_ ? node : null;
- }
-
- var Map;
- if (global.Map && typeof global.Map.prototype.forEach === 'function') {
- Map = global.Map;
- } else {
- Map = function() {
- this.keys = [];
- this.values = [];
- };
-
- Map.prototype = {
- set: function(key, value) {
- var index = this.keys.indexOf(key);
- if (index < 0) {
- this.keys.push(key);
- this.values.push(value);
- } else {
- this.values[index] = value;
- }
- },
-
- get: function(key) {
- var index = this.keys.indexOf(key);
- if (index < 0)
- return;
-
- return this.values[index];
- },
-
- delete: function(key, value) {
- var index = this.keys.indexOf(key);
- if (index < 0)
- return false;
-
- this.keys.splice(index, 1);
- this.values.splice(index, 1);
- return true;
- },
-
- forEach: function(f, opt_this) {
- for (var i = 0; i < this.keys.length; i++)
- f.call(opt_this || this, this.values[i], this.keys[i], this);
- }
- };
- }
-
- // JScript does not have __proto__. We wrap all object literals with
- // createObject which uses Object.create, Object.defineProperty and
- // Object.getOwnPropertyDescriptor to create a new object that does the exact
- // same thing. The main downside to this solution is that we have to extract
- // all those property descriptors for IE.
- var createObject = ('__proto__' in {}) ?
- function(obj) { return obj; } :
- function(obj) {
- var proto = obj.__proto__;
- if (!proto)
- return obj;
- var newObject = Object.create(proto);
- Object.getOwnPropertyNames(obj).forEach(function(name) {
- Object.defineProperty(newObject, name,
- Object.getOwnPropertyDescriptor(obj, name));
- });
- return newObject;
- };
-
- // IE does not support have Document.prototype.contains.
- if (typeof document.contains != 'function') {
- Document.prototype.contains = function(node) {
- if (node === this || node.parentNode === this)
- return true;
- return this.documentElement.contains(node);
- }
- }
-
- var BIND = 'bind';
- var REPEAT = 'repeat';
- var IF = 'if';
-
- var templateAttributeDirectives = {
- 'template': true,
- 'repeat': true,
- 'bind': true,
- 'ref': true
- };
-
- var semanticTemplateElements = {
- 'THEAD': true,
- 'TBODY': true,
- 'TFOOT': true,
- 'TH': true,
- 'TR': true,
- 'TD': true,
- 'COLGROUP': true,
- 'COL': true,
- 'CAPTION': true,
- 'OPTION': true,
- 'OPTGROUP': true
- };
-
- var hasTemplateElement = typeof HTMLTemplateElement !== 'undefined';
- if (hasTemplateElement) {
- // TODO(rafaelw): Remove when fix for
- // https://codereview.chromium.org/164803002/
- // makes it to Chrome release.
- (function() {
- var t = document.createElement('template');
- var d = t.content.ownerDocument;
- var html = d.appendChild(d.createElement('html'));
- var head = html.appendChild(d.createElement('head'));
- var base = d.createElement('base');
- base.href = document.baseURI;
- head.appendChild(base);
- })();
- }
-
- var allTemplatesSelectors = 'template, ' +
- Object.keys(semanticTemplateElements).map(function(tagName) {
- return tagName.toLowerCase() + '[template]';
- }).join(', ');
-
- function isSVGTemplate(el) {
- return el.tagName == 'template' &&
- el.namespaceURI == 'http://www.w3.org/2000/svg';
- }
-
- function isHTMLTemplate(el) {
- return el.tagName == 'TEMPLATE' &&
- el.namespaceURI == 'http://www.w3.org/1999/xhtml';
- }
-
- function isAttributeTemplate(el) {
- return Boolean(semanticTemplateElements[el.tagName] &&
- el.hasAttribute('template'));
- }
-
- function isTemplate(el) {
- if (el.isTemplate_ === undefined)
- el.isTemplate_ = el.tagName == 'TEMPLATE' || isAttributeTemplate(el);
-
- return el.isTemplate_;
- }
-
- // FIXME: Observe templates being added/removed from documents
- // FIXME: Expose imperative API to decorate and observe templates in
- // "disconnected tress" (e.g. ShadowRoot)
- document.addEventListener('DOMContentLoaded', function(e) {
- bootstrapTemplatesRecursivelyFrom(document);
- // FIXME: Is this needed? Seems like it shouldn't be.
- Platform.performMicrotaskCheckpoint();
- }, false);
-
- function forAllTemplatesFrom(node, fn) {
- var subTemplates = node.querySelectorAll(allTemplatesSelectors);
-
- if (isTemplate(node))
- fn(node)
- forEach(subTemplates, fn);
- }
-
- function bootstrapTemplatesRecursivelyFrom(node) {
- function bootstrap(template) {
- if (!HTMLTemplateElement.decorate(template))
- bootstrapTemplatesRecursivelyFrom(template.content);
- }
-
- forAllTemplatesFrom(node, bootstrap);
- }
-
- if (!hasTemplateElement) {
- /**
- * This represents a <template> element.
- * @constructor
- * @extends {HTMLElement}
- */
- global.HTMLTemplateElement = function() {
- throw TypeError('Illegal constructor');
- };
- }
-
- var hasProto = '__proto__' in {};
-
- function mixin(to, from) {
- Object.getOwnPropertyNames(from).forEach(function(name) {
- Object.defineProperty(to, name,
- Object.getOwnPropertyDescriptor(from, name));
- });
- }
-
- // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner
- function getOrCreateTemplateContentsOwner(template) {
- var doc = template.ownerDocument
- if (!doc.defaultView)
- return doc;
- var d = doc.templateContentsOwner_;
- if (!d) {
- // TODO(arv): This should either be a Document or HTMLDocument depending
- // on doc.
- d = doc.implementation.createHTMLDocument('');
- while (d.lastChild) {
- d.removeChild(d.lastChild);
- }
- doc.templateContentsOwner_ = d;
- }
- return d;
- }
-
- function getTemplateStagingDocument(template) {
- if (!template.stagingDocument_) {
- var owner = template.ownerDocument;
- if (!owner.stagingDocument_) {
- owner.stagingDocument_ = owner.implementation.createHTMLDocument('');
- owner.stagingDocument_.isStagingDocument = true;
- // TODO(rafaelw): Remove when fix for
- // https://codereview.chromium.org/164803002/
- // makes it to Chrome release.
- var base = owner.stagingDocument_.createElement('base');
- base.href = document.baseURI;
- owner.stagingDocument_.head.appendChild(base);
-
- owner.stagingDocument_.stagingDocument_ = owner.stagingDocument_;
- }
-
- template.stagingDocument_ = owner.stagingDocument_;
- }
-
- return template.stagingDocument_;
- }
-
- // For non-template browsers, the parser will disallow <template> in certain
- // locations, so we allow "attribute templates" which combine the template
- // element with the top-level container node of the content, e.g.
- //
- // <tr template repeat="{{ foo }}"" class="bar"><td>Bar</td></tr>
- //
- // becomes
- //
- // <template repeat="{{ foo }}">
- // + #document-fragment
- // + <tr class="bar">
- // + <td>Bar</td>
- //
- function extractTemplateFromAttributeTemplate(el) {
- var template = el.ownerDocument.createElement('template');
- el.parentNode.insertBefore(template, el);
-
- var attribs = el.attributes;
- var count = attribs.length;
- while (count-- > 0) {
- var attrib = attribs[count];
- if (templateAttributeDirectives[attrib.name]) {
- if (attrib.name !== 'template')
- template.setAttribute(attrib.name, attrib.value);
- el.removeAttribute(attrib.name);
- }
- }
-
- return template;
- }
-
- function extractTemplateFromSVGTemplate(el) {
- var template = el.ownerDocument.createElement('template');
- el.parentNode.insertBefore(template, el);
-
- var attribs = el.attributes;
- var count = attribs.length;
- while (count-- > 0) {
- var attrib = attribs[count];
- template.setAttribute(attrib.name, attrib.value);
- el.removeAttribute(attrib.name);
- }
-
- el.parentNode.removeChild(el);
- return template;
- }
-
- function liftNonNativeTemplateChildrenIntoContent(template, el, useRoot) {
- var content = template.content;
- if (useRoot) {
- content.appendChild(el);
- return;
- }
-
- var child;
- while (child = el.firstChild) {
- content.appendChild(child);
- }
- }
-
- var templateObserver;
- if (typeof MutationObserver == 'function') {
- templateObserver = new MutationObserver(function(records) {
- for (var i = 0; i < records.length; i++) {
- records[i].target.refChanged_();
- }
- });
- }
-
- /**
- * Ensures proper API and content model for template elements.
- * @param {HTMLTemplateElement} opt_instanceRef The template element which
- * |el| template element will return as the value of its ref(), and whose
- * content will be used as source when createInstance() is invoked.
- */
- HTMLTemplateElement.decorate = function(el, opt_instanceRef) {
- if (el.templateIsDecorated_)
- return false;
-
- var templateElement = el;
- templateElement.templateIsDecorated_ = true;
-
- var isNativeHTMLTemplate = isHTMLTemplate(templateElement) &&
- hasTemplateElement;
- var bootstrapContents = isNativeHTMLTemplate;
- var liftContents = !isNativeHTMLTemplate;
- var liftRoot = false;
-
- if (!isNativeHTMLTemplate) {
- if (isAttributeTemplate(templateElement)) {
- assert(!opt_instanceRef);
- templateElement = extractTemplateFromAttributeTemplate(el);
- templateElement.templateIsDecorated_ = true;
- isNativeHTMLTemplate = hasTemplateElement;
- liftRoot = true;
- } else if (isSVGTemplate(templateElement)) {
- templateElement = extractTemplateFromSVGTemplate(el);
- templateElement.templateIsDecorated_ = true;
- isNativeHTMLTemplate = hasTemplateElement;
- }
- }
-
- if (!isNativeHTMLTemplate) {
- fixTemplateElementPrototype(templateElement);
- var doc = getOrCreateTemplateContentsOwner(templateElement);
- templateElement.content_ = doc.createDocumentFragment();
- }
-
- if (opt_instanceRef) {
- // template is contained within an instance, its direct content must be
- // empty
- templateElement.instanceRef_ = opt_instanceRef;
- } else if (liftContents) {
- liftNonNativeTemplateChildrenIntoContent(templateElement,
- el,
- liftRoot);
- } else if (bootstrapContents) {
- bootstrapTemplatesRecursivelyFrom(templateElement.content);
- }
-
- return true;
- };
-
- // TODO(rafaelw): This used to decorate recursively all templates from a given
- // node. This happens by default on 'DOMContentLoaded', but may be needed
- // in subtrees not descendent from document (e.g. ShadowRoot).
- // Review whether this is the right public API.
- HTMLTemplateElement.bootstrap = bootstrapTemplatesRecursivelyFrom;
-
- var htmlElement = global.HTMLUnknownElement || HTMLElement;
-
- var contentDescriptor = {
- get: function() {
- return this.content_;
- },
- enumerable: true,
- configurable: true
- };
-
- if (!hasTemplateElement) {
- // Gecko is more picky with the prototype than WebKit. Make sure to use the
- // same prototype as created in the constructor.
- HTMLTemplateElement.prototype = Object.create(htmlElement.prototype);
-
- Object.defineProperty(HTMLTemplateElement.prototype, 'content',
- contentDescriptor);
- }
-
- function fixTemplateElementPrototype(el) {
- if (hasProto)
- el.__proto__ = HTMLTemplateElement.prototype;
- else
- mixin(el, HTMLTemplateElement.prototype);
- }
-
- function ensureSetModelScheduled(template) {
- if (!template.setModelFn_) {
- template.setModelFn_ = function() {
- template.setModelFnScheduled_ = false;
- var map = getBindings(template,
- template.delegate_ && template.delegate_.prepareBinding);
- processBindings(template, map, template.model_);
- };
- }
-
- if (!template.setModelFnScheduled_) {
- template.setModelFnScheduled_ = true;
- Observer.runEOM_(template.setModelFn_);
- }
- }
-
- mixin(HTMLTemplateElement.prototype, {
- bind: function(name, value, oneTime) {
- if (name != 'ref')
- return Element.prototype.bind.call(this, name, value, oneTime);
-
- var self = this;
- var ref = oneTime ? value : value.open(function(ref) {
- self.setAttribute('ref', ref);
- self.refChanged_();
- });
-
- this.setAttribute('ref', ref);
- this.refChanged_();
- if (oneTime)
- return;
-
- if (!this.bindings_) {
- this.bindings_ = { ref: value };
- } else {
- this.bindings_.ref = value;
- }
-
- return value;
- },
-
- processBindingDirectives_: function(directives) {
- if (this.iterator_)
- this.iterator_.closeDeps();
-
- if (!directives.if && !directives.bind && !directives.repeat) {
- if (this.iterator_) {
- this.iterator_.close();
- this.iterator_ = undefined;
- }
-
- return;
- }
-
- if (!this.iterator_) {
- this.iterator_ = new TemplateIterator(this);
- }
-
- this.iterator_.updateDependencies(directives, this.model_);
-
- if (templateObserver) {
- templateObserver.observe(this, { attributes: true,
- attributeFilter: ['ref'] });
- }
-
- return this.iterator_;
- },
-
- createInstance: function(model, bindingDelegate, delegate_) {
- if (bindingDelegate)
- delegate_ = this.newDelegate_(bindingDelegate);
- else if (!delegate_)
- delegate_ = this.delegate_;
-
- if (!this.refContent_)
- this.refContent_ = this.ref_.content;
- var content = this.refContent_;
- if (content.firstChild === null)
- return emptyInstance;
-
- var map = getInstanceBindingMap(content, delegate_);
- var stagingDocument = getTemplateStagingDocument(this);
- var instance = stagingDocument.createDocumentFragment();
- instance.templateCreator_ = this;
- instance.protoContent_ = content;
- instance.bindings_ = [];
- instance.terminator_ = null;
- var instanceRecord = instance.templateInstance_ = {
- firstNode: null,
- lastNode: null,
- model: model
- };
-
- var i = 0;
- var collectTerminator = false;
- for (var child = content.firstChild; child; child = child.nextSibling) {
- // The terminator of the instance is the clone of the last child of the
- // content. If the last child is an active template, it may produce
- // instances as a result of production, so simply collecting the last
- // child of the instance after it has finished producing may be wrong.
- if (child.nextSibling === null)
- collectTerminator = true;
-
- var clone = cloneAndBindInstance(child, instance, stagingDocument,
- map.children[i++],
- model,
- delegate_,
- instance.bindings_);
- clone.templateInstance_ = instanceRecord;
- if (collectTerminator)
- instance.terminator_ = clone;
- }
-
- instanceRecord.firstNode = instance.firstChild;
- instanceRecord.lastNode = instance.lastChild;
- instance.templateCreator_ = undefined;
- instance.protoContent_ = undefined;
- return instance;
- },
-
- get model() {
- return this.model_;
- },
-
- set model(model) {
- this.model_ = model;
- ensureSetModelScheduled(this);
- },
-
- get bindingDelegate() {
- return this.delegate_ && this.delegate_.raw;
- },
-
- refChanged_: function() {
- if (!this.iterator_ || this.refContent_ === this.ref_.content)
- return;
-
- this.refContent_ = undefined;
- this.iterator_.valueChanged();
- this.iterator_.updateIteratedValue(this.iterator_.getUpdatedValue());
- },
-
- clear: function() {
- this.model_ = undefined;
- this.delegate_ = undefined;
- if (this.bindings_ && this.bindings_.ref)
- this.bindings_.ref.close()
- this.refContent_ = undefined;
- if (!this.iterator_)
- return;
- this.iterator_.valueChanged();
- this.iterator_.close()
- this.iterator_ = undefined;
- },
-
- setDelegate_: function(delegate) {
- this.delegate_ = delegate;
- this.bindingMap_ = undefined;
- if (this.iterator_) {
- this.iterator_.instancePositionChangedFn_ = undefined;
- this.iterator_.instanceModelFn_ = undefined;
- }
- },
-
- newDelegate_: function(bindingDelegate) {
- if (!bindingDelegate)
- return;
-
- function delegateFn(name) {
- var fn = bindingDelegate && bindingDelegate[name];
- if (typeof fn != 'function')
- return;
-
- return function() {
- return fn.apply(bindingDelegate, arguments);
- };
- }
-
- return {
- bindingMaps: {},
- raw: bindingDelegate,
- prepareBinding: delegateFn('prepareBinding'),
- prepareInstanceModel: delegateFn('prepareInstanceModel'),
- prepareInstancePositionChanged:
- delegateFn('prepareInstancePositionChanged')
- };
- },
-
- set bindingDelegate(bindingDelegate) {
- if (this.delegate_) {
- throw Error('Template must be cleared before a new bindingDelegate ' +
- 'can be assigned');
- }
-
- this.setDelegate_(this.newDelegate_(bindingDelegate));
- },
-
- get ref_() {
- var ref = searchRefId(this, this.getAttribute('ref'));
- if (!ref)
- ref = this.instanceRef_;
-
- if (!ref)
- return this;
-
- var nextRef = ref.ref_;
- return nextRef ? nextRef : ref;
- }
- });
-
- // Returns
- // a) undefined if there are no mustaches.
- // b) [TEXT, (ONE_TIME?, PATH, DELEGATE_FN, TEXT)+] if there is at least one mustache.
- function parseMustaches(s, name, node, prepareBindingFn) {
- if (!s || !s.length)
- return;
-
- var tokens;
- var length = s.length;
- var startIndex = 0, lastIndex = 0, endIndex = 0;
- var onlyOneTime = true;
- while (lastIndex < length) {
- var startIndex = s.indexOf('{{', lastIndex);
- var oneTimeStart = s.indexOf('[[', lastIndex);
- var oneTime = false;
- var terminator = '}}';
-
- if (oneTimeStart >= 0 &&
- (startIndex < 0 || oneTimeStart < startIndex)) {
- startIndex = oneTimeStart;
- oneTime = true;
- terminator = ']]';
- }
-
- endIndex = startIndex < 0 ? -1 : s.indexOf(terminator, startIndex + 2);
-
- if (endIndex < 0) {
- if (!tokens)
- return;
-
- tokens.push(s.slice(lastIndex)); // TEXT
- break;
- }
-
- tokens = tokens || [];
- tokens.push(s.slice(lastIndex, startIndex)); // TEXT
- var pathString = s.slice(startIndex + 2, endIndex).trim();
- tokens.push(oneTime); // ONE_TIME?
- onlyOneTime = onlyOneTime && oneTime;
- var delegateFn = prepareBindingFn &&
- prepareBindingFn(pathString, name, node);
- // Don't try to parse the expression if there's a prepareBinding function
- if (delegateFn == null) {
- tokens.push(Path.get(pathString)); // PATH
- } else {
- tokens.push(null);
- }
- tokens.push(delegateFn); // DELEGATE_FN
- lastIndex = endIndex + 2;
- }
-
- if (lastIndex === length)
- tokens.push(''); // TEXT
-
- tokens.hasOnePath = tokens.length === 5;
- tokens.isSimplePath = tokens.hasOnePath &&
- tokens[0] == '' &&
- tokens[4] == '';
- tokens.onlyOneTime = onlyOneTime;
-
- tokens.combinator = function(values) {
- var newValue = tokens[0];
-
- for (var i = 1; i < tokens.length; i += 4) {
- var value = tokens.hasOnePath ? values : values[(i - 1) / 4];
- if (value !== undefined)
- newValue += value;
- newValue += tokens[i + 3];
- }
-
- return newValue;
- }
-
- return tokens;
- };
-
- function processOneTimeBinding(name, tokens, node, model) {
- if (tokens.hasOnePath) {
- var delegateFn = tokens[3];
- var value = delegateFn ? delegateFn(model, node, true) :
- tokens[2].getValueFrom(model);
- return tokens.isSimplePath ? value : tokens.combinator(value);
- }
-
- var values = [];
- for (var i = 1; i < tokens.length; i += 4) {
- var delegateFn = tokens[i + 2];
- values[(i - 1) / 4] = delegateFn ? delegateFn(model, node) :
- tokens[i + 1].getValueFrom(model);
- }
-
- return tokens.combinator(values);
- }
-
- function processSinglePathBinding(name, tokens, node, model) {
- var delegateFn = tokens[3];
- var observer = delegateFn ? delegateFn(model, node, false) :
- new PathObserver(model, tokens[2]);
-
- return tokens.isSimplePath ? observer :
- new ObserverTransform(observer, tokens.combinator);
- }
-
- function processBinding(name, tokens, node, model) {
- if (tokens.onlyOneTime)
- return processOneTimeBinding(name, tokens, node, model);
-
- if (tokens.hasOnePath)
- return processSinglePathBinding(name, tokens, node, model);
-
- var observer = new CompoundObserver();
-
- for (var i = 1; i < tokens.length; i += 4) {
- var oneTime = tokens[i];
- var delegateFn = tokens[i + 2];
-
- if (delegateFn) {
- var value = delegateFn(model, node, oneTime);
- if (oneTime)
- observer.addPath(value)
- else
- observer.addObserver(value);
- continue;
- }
-
- var path = tokens[i + 1];
- if (oneTime)
- observer.addPath(path.getValueFrom(model))
- else
- observer.addPath(model, path);
- }
-
- return new ObserverTransform(observer, tokens.combinator);
- }
-
- function processBindings(node, bindings, model, instanceBindings) {
- for (var i = 0; i < bindings.length; i += 2) {
- var name = bindings[i]
- var tokens = bindings[i + 1];
- var value = processBinding(name, tokens, node, model);
- var binding = node.bind(name, value, tokens.onlyOneTime);
- if (binding && instanceBindings)
- instanceBindings.push(binding);
- }
-
- node.bindFinished();
- if (!bindings.isTemplate)
- return;
-
- node.model_ = model;
- var iter = node.processBindingDirectives_(bindings);
- if (instanceBindings && iter)
- instanceBindings.push(iter);
- }
-
- function parseWithDefault(el, name, prepareBindingFn) {
- var v = el.getAttribute(name);
- return parseMustaches(v == '' ? '{{}}' : v, name, el, prepareBindingFn);
- }
-
- function parseAttributeBindings(element, prepareBindingFn) {
- assert(element);
-
- var bindings = [];
- var ifFound = false;
- var bindFound = false;
-
- for (var i = 0; i < element.attributes.length; i++) {
- var attr = element.attributes[i];
- var name = attr.name;
- var value = attr.value;
-
- // Allow bindings expressed in attributes to be prefixed with underbars.
- // We do this to allow correct semantics for browsers that don't implement
- // <template> where certain attributes might trigger side-effects -- and
- // for IE which sanitizes certain attributes, disallowing mustache
- // replacements in their text.
- while (name[0] === '_') {
- name = name.substring(1);
- }
-
- if (isTemplate(element) &&
- (name === IF || name === BIND || name === REPEAT)) {
- continue;
- }
-
- var tokens = parseMustaches(value, name, element,
- prepareBindingFn);
- if (!tokens)
- continue;
-
- bindings.push(name, tokens);
- }
-
- if (isTemplate(element)) {
- bindings.isTemplate = true;
- bindings.if = parseWithDefault(element, IF, prepareBindingFn);
- bindings.bind = parseWithDefault(element, BIND, prepareBindingFn);
- bindings.repeat = parseWithDefault(element, REPEAT, prepareBindingFn);
-
- if (bindings.if && !bindings.bind && !bindings.repeat)
- bindings.bind = parseMustaches('{{}}', BIND, element, prepareBindingFn);
- }
-
- return bindings;
- }
-
- function getBindings(node, prepareBindingFn) {
- if (node.nodeType === Node.ELEMENT_NODE)
- return parseAttributeBindings(node, prepareBindingFn);
-
- if (node.nodeType === Node.TEXT_NODE) {
- var tokens = parseMustaches(node.data, 'textContent', node,
- prepareBindingFn);
- if (tokens)
- return ['textContent', tokens];
- }
-
- return [];
- }
-
- function cloneAndBindInstance(node, parent, stagingDocument, bindings, model,
- delegate,
- instanceBindings,
- instanceRecord) {
- var clone = parent.appendChild(stagingDocument.importNode(node, false));
-
- var i = 0;
- for (var child = node.firstChild; child; child = child.nextSibling) {
- cloneAndBindInstance(child, clone, stagingDocument,
- bindings.children[i++],
- model,
- delegate,
- instanceBindings);
- }
-
- if (bindings.isTemplate) {
- HTMLTemplateElement.decorate(clone, node);
- if (delegate)
- clone.setDelegate_(delegate);
- }
-
- processBindings(clone, bindings, model, instanceBindings);
- return clone;
- }
-
- function createInstanceBindingMap(node, prepareBindingFn) {
- var map = getBindings(node, prepareBindingFn);
- map.children = {};
- var index = 0;
- for (var child = node.firstChild; child; child = child.nextSibling) {
- map.children[index++] = createInstanceBindingMap(child, prepareBindingFn);
- }
-
- return map;
- }
-
- var contentUidCounter = 1;
-
- // TODO(rafaelw): Setup a MutationObserver on content which clears the id
- // so that bindingMaps regenerate when the template.content changes.
- function getContentUid(content) {
- var id = content.id_;
- if (!id)
- id = content.id_ = contentUidCounter++;
- return id;
- }
-
- // Each delegate is associated with a set of bindingMaps, one for each
- // content which may be used by a template. The intent is that each binding
- // delegate gets the opportunity to prepare the instance (via the prepare*
- // delegate calls) once across all uses.
- // TODO(rafaelw): Separate out the parse map from the binding map. In the
- // current implementation, if two delegates need a binding map for the same
- // content, the second will have to reparse.
- function getInstanceBindingMap(content, delegate_) {
- var contentId = getContentUid(content);
- if (delegate_) {
- var map = delegate_.bindingMaps[contentId];
- if (!map) {
- map = delegate_.bindingMaps[contentId] =
- createInstanceBindingMap(content, delegate_.prepareBinding) || [];
- }
- return map;
- }
-
- var map = content.bindingMap_;
- if (!map) {
- map = content.bindingMap_ =
- createInstanceBindingMap(content, undefined) || [];
- }
- return map;
- }
-
- Object.defineProperty(Node.prototype, 'templateInstance', {
- get: function() {
- var instance = this.templateInstance_;
- return instance ? instance :
- (this.parentNode ? this.parentNode.templateInstance : undefined);
- }
- });
-
- var emptyInstance = document.createDocumentFragment();
- emptyInstance.bindings_ = [];
- emptyInstance.terminator_ = null;
-
- function TemplateIterator(templateElement) {
- this.closed = false;
- this.templateElement_ = templateElement;
- this.instances = [];
- this.deps = undefined;
- this.iteratedValue = [];
- this.presentValue = undefined;
- this.arrayObserver = undefined;
- }
-
- TemplateIterator.prototype = {
- closeDeps: function() {
- var deps = this.deps;
- if (deps) {
- if (deps.ifOneTime === false)
- deps.ifValue.close();
- if (deps.oneTime === false)
- deps.value.close();
- }
- },
-
- updateDependencies: function(directives, model) {
- this.closeDeps();
-
- 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 && !ifValue) {
- this.valueChanged();
- return;
- }
-
- if (!deps.ifOneTime)
- ifValue = ifValue.open(this.updateIfValue, this);
- }
-
- if (directives.repeat) {
- deps.repeat = true;
- deps.oneTime = directives.repeat.onlyOneTime;
- deps.value = processBinding(REPEAT, directives.repeat, template, model);
- } else {
- deps.repeat = false;
- deps.oneTime = directives.bind.onlyOneTime;
- deps.value = processBinding(BIND, directives.bind, template, model);
- }
-
- var value = deps.value;
- if (!deps.oneTime)
- value = value.open(this.updateIteratedValue, this);
-
- if (!ifValue) {
- this.valueChanged();
- return;
- }
-
- this.updateValue(value);
- },
-
- /**
- * 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(value) {
- if (this.deps.hasIf) {
- var ifValue = this.deps.ifValue;
- if (!this.deps.ifOneTime)
- ifValue = ifValue.discardChanges();
- if (!ifValue) {
- this.valueChanged();
- return;
- }
- }
-
- this.updateValue(value);
- },
-
- updateValue: function(value) {
- if (!this.deps.repeat)
- value = [value];
- var observe = this.deps.repeat &&
- !this.deps.oneTime &&
- Array.isArray(value);
- this.valueChanged(value, observe);
- },
-
- valueChanged: function(value, observeValue) {
- if (!Array.isArray(value))
- value = [];
-
- if (value === this.iteratedValue)
- return;
-
- this.unobserve();
- this.presentValue = value;
- if (observeValue) {
- this.arrayObserver = new ArrayObserver(this.presentValue);
- this.arrayObserver.open(this.handleSplices, this);
- }
-
- this.handleSplices(ArrayObserver.calculateSplices(this.presentValue,
- this.iteratedValue));
- },
-
- getLastInstanceNode: function(index) {
- if (index == -1)
- return this.templateElement_;
- var instance = this.instances[index];
- var terminator = instance.terminator_;
- if (!terminator)
- return this.getLastInstanceNode(index - 1);
-
- if (terminator.nodeType !== Node.ELEMENT_NODE ||
- this.templateElement_ === terminator) {
- return terminator;
- }
-
- var subtemplateIterator = terminator.iterator_;
- if (!subtemplateIterator)
- return terminator;
-
- return subtemplateIterator.getLastTemplateNode();
- },
-
- getLastTemplateNode: function() {
- return this.getLastInstanceNode(this.instances.length - 1);
- },
-
- insertInstanceAt: function(index, fragment) {
- var previousInstanceLast = this.getLastInstanceNode(index - 1);
- var parent = this.templateElement_.parentNode;
- this.instances.splice(index, 0, fragment);
-
- parent.insertBefore(fragment, previousInstanceLast.nextSibling);
- },
-
- extractInstanceAt: function(index) {
- var previousInstanceLast = this.getLastInstanceNode(index - 1);
- var lastNode = this.getLastInstanceNode(index);
- var parent = this.templateElement_.parentNode;
- var instance = this.instances.splice(index, 1)[0];
-
- while (lastNode !== previousInstanceLast) {
- var node = previousInstanceLast.nextSibling;
- if (node == lastNode)
- lastNode = previousInstanceLast;
-
- instance.appendChild(parent.removeChild(node));
- }
-
- return instance;
- },
-
- getDelegateFn: function(fn) {
- fn = fn && fn(this.templateElement_);
- return typeof fn === 'function' ? fn : null;
- },
-
- handleSplices: function(splices) {
- if (this.closed || !splices.length)
- return;
-
- var template = this.templateElement_;
-
- if (!template.parentNode) {
- this.close();
- return;
- }
-
- ArrayObserver.applySplices(this.iteratedValue, this.presentValue,
- splices);
-
- var delegate = template.delegate_;
- if (this.instanceModelFn_ === undefined) {
- this.instanceModelFn_ =
- this.getDelegateFn(delegate && delegate.prepareInstanceModel);
- }
-
- if (this.instancePositionChangedFn_ === undefined) {
- this.instancePositionChangedFn_ =
- this.getDelegateFn(delegate &&
- delegate.prepareInstancePositionChanged);
- }
-
- // Instance Removals
- var instanceCache = new Map;
- var removeDelta = 0;
- for (var i = 0; i < splices.length; i++) {
- var splice = splices[i];
- var removed = splice.removed;
- for (var j = 0; j < removed.length; j++) {
- var model = removed[j];
- var instance = this.extractInstanceAt(splice.index + removeDelta);
- if (instance !== emptyInstance) {
- instanceCache.set(model, instance);
- }
- }
-
- removeDelta -= splice.addedCount;
- }
-
- // Instance Insertions
- for (var i = 0; i < splices.length; i++) {
- var splice = splices[i];
- var addIndex = splice.index;
- for (; addIndex < splice.index + splice.addedCount; addIndex++) {
- var model = this.iteratedValue[addIndex];
- var instance = instanceCache.get(model);
- if (instance) {
- instanceCache.delete(model);
- } else {
- if (this.instanceModelFn_) {
- model = this.instanceModelFn_(model);
- }
-
- if (model === undefined) {
- instance = emptyInstance;
- } else {
- instance = template.createInstance(model, undefined, delegate);
- }
- }
-
- this.insertInstanceAt(addIndex, instance);
- }
- }
-
- instanceCache.forEach(function(instance) {
- this.closeInstanceBindings(instance);
- }, this);
-
- if (this.instancePositionChangedFn_)
- this.reportInstancesMoved(splices);
- },
-
- reportInstanceMoved: function(index) {
- var instance = this.instances[index];
- if (instance === emptyInstance)
- return;
-
- this.instancePositionChangedFn_(instance.templateInstance_, index);
- },
-
- reportInstancesMoved: function(splices) {
- var index = 0;
- var offset = 0;
- for (var i = 0; i < splices.length; i++) {
- var splice = splices[i];
- if (offset != 0) {
- while (index < splice.index) {
- this.reportInstanceMoved(index);
- index++;
- }
- } else {
- index = splice.index;
- }
-
- while (index < splice.index + splice.addedCount) {
- this.reportInstanceMoved(index);
- index++;
- }
-
- offset += splice.addedCount - splice.removed.length;
- }
-
- if (offset == 0)
- return;
-
- var length = this.instances.length;
- while (index < length) {
- this.reportInstanceMoved(index);
- index++;
- }
- },
-
- closeInstanceBindings: function(instance) {
- var bindings = instance.bindings_;
- for (var i = 0; i < bindings.length; i++) {
- bindings[i].close();
- }
- },
-
- unobserve: function() {
- if (!this.arrayObserver)
- return;
-
- this.arrayObserver.close();
- this.arrayObserver = undefined;
- },
-
- close: function() {
- if (this.closed)
- return;
- this.unobserve();
- for (var i = 0; i < this.instances.length; i++) {
- this.closeInstanceBindings(this.instances[i]);
- }
-
- this.instances.length = 0;
- this.closeDeps();
- this.templateElement_.iterator_ = undefined;
- this.closed = true;
- }
- };
-
- // Polyfill-specific API.
- HTMLTemplateElement.forAllTemplatesFrom_ = forAllTemplatesFrom;
-})(this);
-
-/*
- * 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) {
-
-// inject style sheet
-var style = document.createElement('style');
-style.textContent = 'template {display: none !important;} /* injected by platform.js */';
-var head = document.querySelector('head');
-head.insertBefore(style, head.firstChild);
-
-// flush (with logging)
-var flushing;
-function flush() {
- if (!flushing) {
- flushing = true;
- scope.endOfMicrotask(function() {
- flushing = false;
- logFlags.data && console.group('Platform.flush()');
- scope.performMicrotaskCheckpoint();
- logFlags.data && console.groupEnd();
- });
- }
-};
-
-// polling dirty checker
-// flush periodically if platform does not have object observe.
-if (!Observer.hasObjectObserve) {
- var FLUSH_POLL_INTERVAL = 125;
- window.addEventListener('WebComponentsReady', function() {
- flush();
- scope.flushPoll = setInterval(flush, FLUSH_POLL_INTERVAL);
- });
-} else {
- // make flush a no-op when we have Object.observe
- flush = function() {};
-}
-
-if (window.CustomElements && !CustomElements.useNative) {
- var originalImportNode = Document.prototype.importNode;
- Document.prototype.importNode = function(node, deep) {
- var imported = originalImportNode.call(this, node, deep);
- CustomElements.upgradeAll(imported);
- return imported;
- }
-}
-
-// exports
-scope.flush = flush;
-
-})(window.Platform);
+ scope.marshal = marshal;
+ // `module` confuses commonjs detectors
+ scope.modularize = module;
+ scope.using = using;
+})(window);
//# sourceMappingURL=platform.concat.js.map

Powered by Google App Engine
This is Rietveld 408576698