| 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 b1e80668ad486024b5432cae1dfe30600cd5bd3b..293c435aee306e4f9ae4adc6131324832b64a3ce 100644
|
| --- a/pkg/web_components/lib/platform.concat.js
|
| +++ b/pkg/web_components/lib/platform.concat.js
|
| @@ -1649,61 +1649,61 @@ if (typeof WeakMap === 'undefined') {
|
| };
|
| })(typeof global !== 'undefined' && global && typeof module !== 'undefined' && module ? global : this || window);
|
|
|
| -// prepoulate window.Platform.flags for default controls
|
| -window.Platform = window.Platform || {};
|
| -// prepopulate window.logFlags if necessary
|
| -window.logFlags = window.logFlags || {};
|
| -// process flags
|
| -(function(scope){
|
| - // import
|
| - var flags = scope.flags || {};
|
| - // populate flags from location
|
| - location.search.slice(1).split('&').forEach(function(o) {
|
| - o = o.split('=');
|
| - o[0] && (flags[o[0]] = o[1] || true);
|
| - });
|
| - var entryPoint = document.currentScript || document.querySelector('script[src*="platform.js"]');
|
| - if (entryPoint) {
|
| - var a = entryPoint.attributes;
|
| - for (var i = 0, n; i < a.length; i++) {
|
| - n = a[i];
|
| - if (n.name !== 'src') {
|
| - flags[n.name] = n.value || true;
|
| - }
|
| - }
|
| - }
|
| - if (flags.log) {
|
| - flags.log.split(',').forEach(function(f) {
|
| - window.logFlags[f] = true;
|
| - });
|
| - }
|
| - // If any of these flags match 'native', then force native ShadowDOM; any
|
| - // other truthy value, or failure to detect native
|
| - // ShadowDOM, results in polyfill
|
| - flags.shadow = (flags.shadow || flags.shadowdom || flags.polyfill);
|
| - if (flags.shadow === 'native') {
|
| - flags.shadow = false;
|
| - } else {
|
| - flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
|
| - }
|
| -
|
| - // CustomElements polyfill flag
|
| - if (flags.register) {
|
| - window.CustomElements = window.CustomElements || {flags: {}};
|
| - window.CustomElements.flags.register = flags.register;
|
| - }
|
| -
|
| - if (flags.imports) {
|
| - window.HTMLImports = window.HTMLImports || {flags: {}};
|
| - window.HTMLImports.flags.imports = flags.imports;
|
| - }
|
| -
|
| - // export
|
| - scope.flags = flags;
|
| -})(Platform);
|
| -
|
| -// select ShadowDOM impl
|
| -if (Platform.flags.shadow) {
|
| +// prepoulate window.Platform.flags for default controls
|
| +window.Platform = window.Platform || {};
|
| +// prepopulate window.logFlags if necessary
|
| +window.logFlags = window.logFlags || {};
|
| +// process flags
|
| +(function(scope){
|
| + // import
|
| + var flags = scope.flags || {};
|
| + // populate flags from location
|
| + location.search.slice(1).split('&').forEach(function(o) {
|
| + o = o.split('=');
|
| + o[0] && (flags[o[0]] = o[1] || true);
|
| + });
|
| + var entryPoint = document.currentScript || document.querySelector('script[src*="platform.js"]');
|
| + if (entryPoint) {
|
| + var a = entryPoint.attributes;
|
| + for (var i = 0, n; i < a.length; i++) {
|
| + n = a[i];
|
| + if (n.name !== 'src') {
|
| + flags[n.name] = n.value || true;
|
| + }
|
| + }
|
| + }
|
| + if (flags.log) {
|
| + flags.log.split(',').forEach(function(f) {
|
| + window.logFlags[f] = true;
|
| + });
|
| + }
|
| + // If any of these flags match 'native', then force native ShadowDOM; any
|
| + // other truthy value, or failure to detect native
|
| + // ShadowDOM, results in polyfill
|
| + flags.shadow = (flags.shadow || flags.shadowdom || flags.polyfill);
|
| + if (flags.shadow === 'native') {
|
| + flags.shadow = false;
|
| + } else {
|
| + flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
|
| + }
|
| +
|
| + // CustomElements polyfill flag
|
| + if (flags.register) {
|
| + window.CustomElements = window.CustomElements || {flags: {}};
|
| + window.CustomElements.flags.register = flags.register;
|
| + }
|
| +
|
| + if (flags.imports) {
|
| + window.HTMLImports = window.HTMLImports || {flags: {}};
|
| + window.HTMLImports.flags.imports = flags.imports;
|
| + }
|
| +
|
| + // export
|
| + scope.flags = flags;
|
| +})(Platform);
|
| +
|
| +// 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
|
| @@ -6907,10 +6907,10 @@ window.ShadowDOMPolyfill = {};
|
| /*
|
| This is a limited shim for ShadowDOM css styling.
|
| https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles
|
| -
|
| - The intention here is to support only the styling features which can be
|
| - relatively simply implemented. The goal is to allow users to avoid the
|
| - most obvious pitfalls and do so without compromising performance significantly.
|
| +
|
| + The intention here is to support only the styling features which can be
|
| + relatively simply implemented. The goal is to allow users to avoid the
|
| + most obvious pitfalls and do so without compromising performance significantly.
|
| For ShadowDOM styling that's not covered here, a set of best practices
|
| can be provided that should allow users to accomplish more complex styling.
|
|
|
| @@ -6920,56 +6920,56 @@ window.ShadowDOMPolyfill = {};
|
| Shimmed features:
|
|
|
| * :host, :ancestor: ShadowDOM allows styling of the shadowRoot's host
|
| - element using the :host rule. To shim this feature, the :host styles are
|
| - reformatted and prefixed with a given scope name and promoted to a
|
| + element using the :host rule. To shim this feature, the :host styles are
|
| + reformatted and prefixed with a given scope name and promoted to a
|
| document level stylesheet.
|
| For example, given a scope name of .foo, a rule like this:
|
| -
|
| +
|
| :host {
|
| background: red;
|
| }
|
| }
|
| -
|
| +
|
| becomes:
|
| -
|
| +
|
| .foo {
|
| background: red;
|
| }
|
| -
|
| - * encapsultion: Styles defined within ShadowDOM, apply only to
|
| +
|
| + * encapsultion: Styles defined within ShadowDOM, apply only to
|
| dom inside the ShadowDOM. Polymer uses one of two techniques to imlement
|
| this feature.
|
| -
|
| - By default, rules are prefixed with the host element tag name
|
| +
|
| + By default, rules are prefixed with the host element tag name
|
| as a descendant selector. This ensures styling does not leak out of the 'top'
|
| of the element's ShadowDOM. For example,
|
|
|
| div {
|
| font-weight: bold;
|
| }
|
| -
|
| +
|
| becomes:
|
|
|
| x-foo div {
|
| font-weight: bold;
|
| }
|
| -
|
| +
|
| becomes:
|
|
|
|
|
| - Alternatively, if Platform.ShadowCSS.strictStyling is set to true then
|
| + Alternatively, if Platform.ShadowCSS.strictStyling is set to true then
|
| selectors are scoped by adding an attribute selector suffix to each
|
| - simple selector that contains the host element tag name. Each element
|
| - in the element's ShadowDOM template is also given the scope attribute.
|
| + simple selector that contains the host element tag name. Each element
|
| + in the element's ShadowDOM template is also given the scope attribute.
|
| Thus, these rules match only elements that have the scope attribute.
|
| For example, given a scope name of x-foo, a rule like this:
|
| -
|
| +
|
| div {
|
| font-weight: bold;
|
| }
|
| -
|
| +
|
| becomes:
|
| -
|
| +
|
| div[x-foo] {
|
| font-weight: bold;
|
| }
|
| @@ -6981,31 +6981,31 @@ window.ShadowDOMPolyfill = {};
|
| shadowRoot should not cross the ShadowDOM boundary and should not apply
|
| inside a shadowRoot.
|
|
|
| - This styling behavior is not emulated. Some possible ways to do this that
|
| + This styling behavior is not emulated. Some possible ways to do this that
|
| were rejected due to complexity and/or performance concerns include: (1) reset
|
| every possible property for every possible selector for a given scope name;
|
| (2) re-implement css in javascript.
|
| -
|
| +
|
| As an alternative, users should make sure to use selectors
|
| specific to the scope in which they are working.
|
| -
|
| +
|
| * ::distributed: This behavior is not emulated. It's often not necessary
|
| to style the contents of a specific insertion point and instead, descendants
|
| - of the host element can be styled selectively. Users can also create an
|
| + of the host element can be styled selectively. Users can also create an
|
| extra node around an insertion point and style that node's contents
|
| via descendent selectors. For example, with a shadowRoot like this:
|
| -
|
| +
|
| <style>
|
| ::content(div) {
|
| background: red;
|
| }
|
| </style>
|
| <content></content>
|
| -
|
| +
|
| could become:
|
| -
|
| +
|
| <style>
|
| - / *@polyfill .content-container div * /
|
| + / *@polyfill .content-container div * /
|
| ::content(div) {
|
| background: red;
|
| }
|
| @@ -7013,9 +7013,9 @@ window.ShadowDOMPolyfill = {};
|
| <div class="content-container">
|
| <content></content>
|
| </div>
|
| -
|
| +
|
| Note the use of @polyfill in the comment above a ShadowDOM specific style
|
| - declaration. This is a directive to the styling shim to use the selector
|
| + declaration. This is a directive to the styling shim to use the selector
|
| in comments in lieu of the next selector when running under polyfill.
|
| */
|
| (function(scope) {
|
| @@ -7045,7 +7045,7 @@ var ShadowCSS = {
|
| root.shimmedStyle = def.shimmedStyle;
|
| }
|
| // remove existing style elements
|
| - for (var i=0, l=def.rootStyles.length, s; (i<l) && (s=def.rootStyles[i]);
|
| + for (var i=0, l=def.rootStyles.length, s; (i<l) && (s=def.rootStyles[i]);
|
| i++) {
|
| s.parentNode.removeChild(s);
|
| }
|
| @@ -7063,7 +7063,7 @@ var ShadowCSS = {
|
| var cssText = this.shimScoping(scopeStyles, name, typeExtension);
|
| // note: we only need to do rootStyles since these are unscoped.
|
| cssText += this.extractPolyfillUnscopedRules(rootStyles);
|
| - return cssText;
|
| + return cssText.trim();
|
| },
|
| registerDefinition: function(root, name, extendsName) {
|
| var def = this.registry[name] = {
|
| @@ -7102,14 +7102,14 @@ var ShadowCSS = {
|
| /*
|
| * Process styles to convert native ShadowDOM rules that will trip
|
| * up the css parser; we rely on decorating the stylesheet with comments.
|
| - *
|
| + *
|
| * For example, we convert this rule:
|
| - *
|
| + *
|
| * (comment start) @polyfill :host menu-item (comment end)
|
| * shadow::-webkit-distributed(menu-item) {
|
| - *
|
| + *
|
| * to this:
|
| - *
|
| + *
|
| * scopeName menu-item {
|
| *
|
| **/
|
| @@ -7128,14 +7128,14 @@ var ShadowCSS = {
|
| },
|
| /*
|
| * Process styles to add rules which will only apply under the polyfill
|
| - *
|
| + *
|
| * For example, we convert this rule:
|
| - *
|
| - * (comment start) @polyfill-rule :host menu-item {
|
| + *
|
| + * (comment start) @polyfill-rule :host menu-item {
|
| * ... } (comment end)
|
| - *
|
| + *
|
| * to this:
|
| - *
|
| + *
|
| * scopeName menu-item {...}
|
| *
|
| **/
|
| @@ -7154,15 +7154,15 @@ var ShadowCSS = {
|
| },
|
| /*
|
| * Process styles to add rules which will only apply under the polyfill
|
| - * and do not process via CSSOM. (CSSOM is destructive to rules on rare
|
| + * and do not process via CSSOM. (CSSOM is destructive to rules on rare
|
| * occasions, e.g. -webkit-calc on Safari.)
|
| * For example, we convert this rule:
|
| - *
|
| - * (comment start) @polyfill-unscoped-rule menu-item {
|
| + *
|
| + * (comment start) @polyfill-unscoped-rule menu-item {
|
| * ... } (comment end)
|
| - *
|
| + *
|
| * to this:
|
| - *
|
| + *
|
| * menu-item {...}
|
| *
|
| **/
|
| @@ -7184,11 +7184,11 @@ var ShadowCSS = {
|
| return r;
|
| },
|
| /* Ensure styles are scoped. Pseudo-scoping takes a rule like:
|
| - *
|
| - * .foo {... }
|
| - *
|
| + *
|
| + * .foo {... }
|
| + *
|
| * and converts this to
|
| - *
|
| + *
|
| * scopeName .foo { ... }
|
| */
|
| shimScoping: function(styles, name, typeExtension) {
|
| @@ -7202,8 +7202,8 @@ var ShadowCSS = {
|
| cssText = this.convertColonHost(cssText);
|
| cssText = this.convertColonAncestor(cssText);
|
| cssText = this.convertCombinators(cssText);
|
| - var rules = cssToRules(cssText);
|
| if (name) {
|
| + var rules = cssToRules(cssText);
|
| cssText = this.scopeRules(rules, name, typeExtension);
|
| }
|
| return cssText;
|
| @@ -7225,13 +7225,13 @@ var ShadowCSS = {
|
| * to
|
| *
|
| * scopeName.foo > .bar, .foo scopeName > .bar { }
|
| - *
|
| + *
|
| * and
|
| *
|
| * :ancestor(.foo:host) .bar { ... }
|
| - *
|
| + *
|
| * to
|
| - *
|
| + *
|
| * scopeName.foo .bar { ... }
|
| */
|
| convertColonAncestor: function(cssText) {
|
| @@ -7275,7 +7275,7 @@ var ShadowCSS = {
|
| var cssText = '';
|
| Array.prototype.forEach.call(cssRules, function(rule) {
|
| if (rule.selectorText && (rule.style && rule.style.cssText)) {
|
| - cssText += this.scopeSelector(rule.selectorText, name, typeExtension,
|
| + cssText += this.scopeSelector(rule.selectorText, name, typeExtension,
|
| this.strictStyling) + ' {\n\t';
|
| cssText += this.propertiesFromRule(rule) + '\n}\n\n';
|
| } else if (rule.media) {
|
| @@ -7293,7 +7293,7 @@ var ShadowCSS = {
|
| parts.forEach(function(p) {
|
| p = p.trim();
|
| if (this.selectorNeedsScoping(p, name, typeExtension)) {
|
| - p = (strict && !p.match(polyfillHostNoCombinator)) ?
|
| + p = (strict && !p.match(polyfillHostNoCombinator)) ?
|
| this.applyStrictSelectorScope(p, name) :
|
| this.applySimpleSelectorScope(p, name, typeExtension);
|
| }
|
| @@ -7346,7 +7346,7 @@ var ShadowCSS = {
|
| // TODO(sorvell): Safari cssom incorrectly removes quotes from the content
|
| // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)
|
| if (rule.style.content && !rule.style.content.match(/['"]+/)) {
|
| - return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' +
|
| + return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' +
|
| rule.style.content + '\';');
|
| }
|
| return rule.style.cssText;
|
| @@ -7441,7 +7441,7 @@ if (window.ShadowDOMPolyfill) {
|
| // consider a better solution.
|
| document.addEventListener('DOMContentLoaded', function() {
|
| var urlResolver = scope.urlResolver;
|
| -
|
| +
|
| if (window.HTMLImports && !HTMLImports.useNative) {
|
| var SHIM_SHEET_SELECTOR = 'link[rel=stylesheet]' +
|
| '[' + SHIM_ATTRIBUTE + ']';
|
| @@ -7454,18 +7454,24 @@ if (window.ShadowDOMPolyfill) {
|
| SHIM_SHEET_SELECTOR,
|
| SHIM_STYLE_SELECTOR
|
| ].join(',');
|
| +
|
| + var originalParseGeneric = HTMLImports.parser.parseGeneric;
|
|
|
| HTMLImports.parser.parseGeneric = function(elt) {
|
| if (elt[SHIMMED_ATTRIBUTE]) {
|
| return;
|
| }
|
| var style = elt.__importElement || elt;
|
| + if (!style.hasAttribute(SHIM_ATTRIBUTE)) {
|
| + originalParseGeneric.call(this, elt);
|
| + return;
|
| + }
|
| if (elt.__resource) {
|
| style = elt.ownerDocument.createElement('style');
|
| style.textContent = urlResolver.resolveCssText(
|
| elt.__resource, elt.href);
|
| } else {
|
| - urlResolver.resolveStyles(style);
|
| + urlResolver.resolveStyle(style);
|
| }
|
| var styles = [style];
|
| style.textContent = ShadowCSS.stylesToShimmedCssText(styles, styles);
|
| @@ -7481,7 +7487,7 @@ if (window.ShadowDOMPolyfill) {
|
| head.appendChild(style);
|
| }
|
| }
|
| - style.__importParsed = true
|
| + style.__importParsed = true;
|
| this.markParsingComplete(elt);
|
| }
|
|
|
| @@ -8293,7 +8299,7 @@ scope.mixin = mixin;
|
| var base = document.createElement('base');
|
| base.href = document.baseURI;
|
| template.content.ownerDocument.appendChild(base);
|
| -
|
| +
|
|
|
| // utility
|
|
|
| @@ -8334,7 +8340,7 @@ scope.mixin = mixin;
|
| if (window.Polymer === polymerStub) {
|
| window.Polymer = function() {
|
| console.error('You tried to use polymer without loading it first. To ' +
|
| - 'load polymer, <link rel="import" href="' +
|
| + 'load polymer, <link rel="import" href="' +
|
| 'components/polymer/polymer.html">');
|
| };
|
| }
|
| @@ -8356,9 +8362,9 @@ window.templateContent = window.templateContent || function(inTemplate) {
|
| return inTemplate.content;
|
| };
|
| (function(scope) {
|
| -
|
| +
|
| scope = scope || (window.Inspector = {});
|
| -
|
| +
|
| var inspector;
|
|
|
| window.sinspect = function(inNode, inProxy) {
|
| @@ -8409,7 +8415,7 @@ window.templateContent = window.templateContent || function(inTemplate) {
|
| ' </body>',
|
| '</html>'
|
| ].join('\n');
|
| -
|
| +
|
| var crumbs = [];
|
|
|
| var displayCrumbs = function() {
|
| @@ -8537,11 +8543,11 @@ window.templateContent = window.templateContent || function(inTemplate) {
|
| console.dir(this);
|
| }
|
| };
|
| -
|
| +
|
| // export
|
| -
|
| +
|
| scope.output = output;
|
| -
|
| +
|
| })(window.Inspector);
|
|
|
|
|
| @@ -8553,20 +8559,20 @@ window.templateContent = window.templateContent || function(inTemplate) {
|
| */
|
| (function(scope) {
|
|
|
| - // TODO(sorvell): It's desireable to provide a default stylesheet
|
| + // 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
|
| + // 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.
|
|
|
| var style = document.createElement('style');
|
| style.textContent = ''
|
| + 'body {'
|
| - + 'transition: opacity ease-in 0.2s;'
|
| + + 'transition: opacity ease-in 0.2s;'
|
| + ' } \n'
|
| + 'body[unresolved] {'
|
| - + 'opacity: 0; display: block; overflow: hidden;'
|
| + + 'opacity: 0; display: block; overflow: hidden;'
|
| + ' } \n'
|
| ;
|
| var head = document.querySelector('head');
|
| @@ -9483,7 +9489,7 @@ var IMPORT_LINK_TYPE = 'import';
|
| var flags = scope.flags;
|
| var isIe = /Trident/.test(navigator.userAgent);
|
| // TODO(sorvell): SD polyfill intrusion
|
| -var mainDoc = window.ShadowDOMPolyfill ?
|
| +var mainDoc = window.ShadowDOMPolyfill ?
|
| window.ShadowDOMPolyfill.wrapIfNeeded(document) : document;
|
|
|
| // importParser
|
| @@ -9554,7 +9560,7 @@ var importParser = {
|
| }
|
| // fire load event
|
| if (elt.__resource) {
|
| - elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
|
| + elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
|
| } else {
|
| elt.dispatchEvent(new CustomEvent('error', {bubbles: false}));
|
| }
|
| @@ -9636,7 +9642,7 @@ var importParser = {
|
| moniker = scriptElt.ownerDocument.baseURI;
|
| // there could be more than one script this url
|
| var tag = '[' + Math.floor((Math.random()+1)*1000) + ']';
|
| - // TODO(sjmiles): Polymer hack, should be pluggable if we need to allow
|
| + // TODO(sjmiles): Polymer hack, should be pluggable if we need to allow
|
| // this sort of thing
|
| var matches = code.match(/Polymer\(['"]([^'"]*)/);
|
| tag = matches && matches[1] || tag;
|
| @@ -9704,7 +9710,7 @@ function cloneStyle(style) {
|
| return clone;
|
| }
|
|
|
| -// path fixup: style elements in imports must be made relative to the main
|
| +// path fixup: style elements in imports must be made relative to the main
|
| // document. We fixup url's in url() and @import.
|
| var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
|
| var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
|
| @@ -9714,7 +9720,7 @@ var path = {
|
| var doc = style.ownerDocument;
|
| var resolver = doc.createElement('a');
|
| style.textContent = this.resolveUrlsInCssText(style.textContent, resolver);
|
| - return style;
|
| + return style;
|
| },
|
| resolveUrlsInCssText: function(cssText, urlObj) {
|
| var r = this.replaceUrls(cssText, urlObj, CSS_URL_REGEXP);
|
| @@ -9727,7 +9733,7 @@ var path = {
|
| urlObj.href = urlPath;
|
| urlPath = urlObj.href;
|
| return pre + '\'' + urlPath + '\'' + post;
|
| - });
|
| + });
|
| }
|
| }
|
|
|
| @@ -9752,7 +9758,7 @@ var flags = scope.flags;
|
| var IMPORT_LINK_TYPE = 'import';
|
|
|
| // TODO(sorvell): SD polyfill intrusion
|
| -var mainDoc = window.ShadowDOMPolyfill ?
|
| +var mainDoc = window.ShadowDOMPolyfill ?
|
| ShadowDOMPolyfill.wrapIfNeeded(document) : document;
|
|
|
| if (!useNative) {
|
| @@ -9835,7 +9841,7 @@ if (!useNative) {
|
| };
|
|
|
| // loader singleton
|
| - var importLoader = new Loader(importer.loaded.bind(importer),
|
| + var importLoader = new Loader(importer.loaded.bind(importer),
|
| importer.loadedAll.bind(importer));
|
|
|
| function isDocumentLink(elt) {
|
| @@ -9916,7 +9922,7 @@ if (!document.baseURI) {
|
|
|
| // 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
|
| +// 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;
|
| @@ -9938,7 +9944,7 @@ function isDocumentReady(doc) {
|
| function whenDocumentReady(callback, doc) {
|
| if (!isDocumentReady(doc)) {
|
| var checkReady = function() {
|
| - if (doc.readyState === 'complete' ||
|
| + if (doc.readyState === 'complete' ||
|
| doc.readyState === requiredReadyState) {
|
| doc.removeEventListener(READY_EVENT, checkReady);
|
| whenDocumentReady(callback, doc);
|
| @@ -9954,7 +9960,7 @@ function whenDocumentReady(callback, doc) {
|
| function watchImportsLoad(callback, doc) {
|
| var imports = doc.querySelectorAll('link[rel=import]');
|
| var loaded = 0, l = imports.length;
|
| - function checkDone(d) {
|
| + function checkDone(d) {
|
| if (loaded == l) {
|
| // go async to ensure parser isn't stuck on a script tag
|
| requestAnimationFrame(callback);
|
| @@ -10033,8 +10039,8 @@ function shouldLoadNode(node) {
|
| }
|
|
|
| // x-plat matches
|
| -var matches = HTMLElement.prototype.matches ||
|
| - HTMLElement.prototype.matchesSelector ||
|
| +var matches = HTMLElement.prototype.matches ||
|
| + HTMLElement.prototype.matchesSelector ||
|
| HTMLElement.prototype.webkitMatchesSelector ||
|
| HTMLElement.prototype.mozMatchesSelector ||
|
| HTMLElement.prototype.msMatchesSelector;
|
| @@ -10075,11 +10081,11 @@ if (typeof window.CustomEvent !== 'function') {
|
| }
|
|
|
| // TODO(sorvell): SD polyfill intrusion
|
| -var doc = window.ShadowDOMPolyfill ?
|
| +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
|
| +// 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() {
|
| @@ -10096,9 +10102,9 @@ if (!HTMLImports.useNative) {
|
| function bootstrap() {
|
| HTMLImports.importer.bootDocument(doc);
|
| }
|
| -
|
| +
|
| // TODO(sorvell): SD polyfill does *not* generate mutations for nodes added
|
| - // by the parser. For this reason, we must wait until the dom exists to
|
| + // by the parser. For this reason, we must wait until the dom exists to
|
| // bootstrap.
|
| if (document.readyState === 'complete' ||
|
| (document.readyState === 'interactive' && !window.attachEvent)) {
|
| @@ -10116,350 +10122,350 @@ if (!HTMLImports.useNative) {
|
| * license that can be found in the LICENSE file.
|
| */
|
| 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);
|
| - upgradeDocument(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);
|
| - }
|
| - }
|
| -}
|
| -
|
| -// exports
|
| -scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
|
| -scope.watchShadow = watchShadow;
|
| -scope.upgradeDocumentTree = upgradeDocumentTree;
|
| -scope.upgradeAll = addedNode;
|
| -scope.upgradeSubtree = addedSubtree;
|
| -
|
| -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.
|
| +*/
|
| +
|
| +(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);
|
| + upgradeDocument(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);
|
| + }
|
| + }
|
| +}
|
| +
|
| +// 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.
|
| @@ -10689,8 +10695,9 @@ if (useNative) {
|
| element.__upgraded__ = true;
|
| // lifecycle management
|
| created(element);
|
| + // attachedCallback fires in tree order, call before recursing
|
| + scope.insertedNode(element);
|
| // there should never be a shadow root on element at this point
|
| - // we require child nodes be upgraded before `created`
|
| scope.upgradeSubtree(element);
|
| // OUTPUT
|
| return element;
|
| @@ -10783,9 +10790,6 @@ if (useNative) {
|
| }
|
|
|
| function registerDefinition(name, definition) {
|
| - if (registry[name]) {
|
| - throw new Error('a type with that name is already registered.');
|
| - }
|
| registry[name] = definition;
|
| }
|
|
|
| @@ -10960,11 +10964,11 @@ function bootstrap() {
|
| // one more pass before register is 'live'
|
| CustomElements.upgradeDocument(document);
|
| // choose async
|
| - var async = window.Platform && Platform.endOfMicrotask ?
|
| + var async = window.Platform && Platform.endOfMicrotask ?
|
| Platform.endOfMicrotask :
|
| setTimeout;
|
| async(function() {
|
| - // set internal 'ready' flag, now document.registerElement will trigger
|
| + // set internal 'ready' flag, now document.registerElement will trigger
|
| // synchronous upgrades
|
| CustomElements.ready = true;
|
| // capture blunt profiling data
|
| @@ -11005,7 +11009,7 @@ if (document.readyState === 'complete' || scope.flags.eager) {
|
| } else if (document.readyState === 'interactive' && !window.attachEvent &&
|
| (!window.HTMLImports || window.HTMLImports.ready)) {
|
| bootstrap();
|
| -// When loading at other readyStates, wait for the appropriate DOM event to
|
| +// When loading at other readyStates, wait for the appropriate DOM event to
|
| // bootstrap.
|
| } else {
|
| var loadEvent = window.HTMLImports && !HTMLImports.ready ?
|
| @@ -11110,8 +11114,8 @@ function createStyleElement(cssText, scope) {
|
| }
|
|
|
| // TODO(sorvell): use a common loader shared with HTMLImports polyfill
|
| -// currently, this just loads the first @import per style element
|
| -// and does not recurse into loaded elements; we'll address this with a
|
| +// currently, this just loads the first @import per style element
|
| +// and does not recurse into loaded elements; we'll address this with a
|
| // generalized loader that's built out of the one in the HTMLImports polyfill.
|
| // polyfill the loading of a style element's @import via xhr
|
| function xhrLoadStyle(style, callback) {
|
| @@ -12078,7 +12082,7 @@ scope.loader = loader;
|
| // handler registration mechanism. Rather than try to predict how exactly to opt-in to
|
| // that we'll just leave this disabled until there is a build of Chrome to test.
|
| var HAS_TOUCH_ACTION_DELAY = false;
|
| -
|
| +
|
| // handler block for native touch events
|
| var touchEvents = {
|
| scrollType: new WeakMap(),
|
| @@ -14390,6 +14394,15 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| }
|
| }
|
|
|
| + 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
|
| @@ -14493,6 +14506,25 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| }
|
|
|
| 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;
|
| +
|
| + this.unbind('ref');
|
| + return this.bindings.ref = value;
|
| + },
|
| +
|
| processBindingDirectives_: function(directives) {
|
| if (this.iterator_)
|
| this.iterator_.closeDeps();
|
| @@ -14514,6 +14546,12 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| }
|
|
|
| this.iterator_.updateDependencies(directives, this.model_);
|
| +
|
| + if (templateObserver) {
|
| + templateObserver.observe(this, { attributes: true,
|
| + attributeFilter: ['ref'] });
|
| + }
|
| +
|
| return this.iterator_;
|
| },
|
|
|
| @@ -14522,7 +14560,9 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| if (bindingDelegate)
|
| delegate_ = this.newDelegate_(bindingDelegate);
|
|
|
| - var content = this.ref.content;
|
| + if (!this.refContent_)
|
| + this.refContent_ = this.ref_.content;
|
| + var content = this.refContent_;
|
| var map = this.bindingMap_;
|
| if (!map || map.content !== content) {
|
| // TODO(rafaelw): Setup a MutationObserver on content to detect
|
| @@ -14574,6 +14614,27 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| 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();
|
| + },
|
| +
|
| + clear: function() {
|
| + this.model_ = undefined;
|
| + this.delegate_ = undefined;
|
| + this.bindings_ = undefined;
|
| + 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;
|
| @@ -14610,10 +14671,15 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| // make sense to issue a warning or even throw if the template is already
|
| // "activated", since this would be a strange thing to do.
|
| 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() {
|
| + get ref_() {
|
| var ref = searchRefId(this, this.getAttribute('ref'));
|
| if (!ref)
|
| ref = this.instanceRef_;
|
| @@ -14621,7 +14687,7 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| if (!ref)
|
| return this;
|
|
|
| - var nextRef = ref.ref;
|
| + var nextRef = ref.ref_;
|
| return nextRef ? nextRef : ref;
|
| }
|
| });
|
| @@ -16357,6 +16423,9 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| },
|
|
|
| setValue: function(model, newValue) {
|
| + if (this.path.length == 1);
|
| + model = findScope(model, this.path[0]);
|
| +
|
| return this.path.setValueFrom(model, newValue);
|
| }
|
| };
|
| @@ -16750,21 +16819,58 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| mixedCaseEventTypes[e.toLowerCase()] = e;
|
| });
|
|
|
| - function prepareEventBinding(path, name) {
|
| + var parentScopeName = '@' + Math.random().toString(36).slice(2);
|
| +
|
| + // Single ident paths must bind directly to the appropriate scope object.
|
| + // I.e. Pushed values in two-bindings need to be assigned to the actual model
|
| + // object.
|
| + function findScope(model, prop) {
|
| + while (model[parentScopeName] &&
|
| + !Object.prototype.hasOwnProperty.call(model, prop)) {
|
| + model = model[parentScopeName];
|
| + }
|
| +
|
| + return model;
|
| + }
|
| +
|
| + function resolveEventReceiver(model, path, node) {
|
| + if (path.length == 0)
|
| + return undefined;
|
| +
|
| + if (path.length == 1)
|
| + return findScope(model, path[0]);
|
| +
|
| + for (var i = 0; model != null && i < path.length - 1; i++) {
|
| + model = model[path[i]];
|
| + }
|
| +
|
| + return model;
|
| + }
|
| +
|
| + function prepareEventBinding(path, name, polymerExpressions) {
|
| var eventType = name.substring(3);
|
| eventType = mixedCaseEventTypes[eventType] || eventType;
|
|
|
| return function(model, node, oneTime) {
|
| - var fn = path.getValueFrom(model);
|
| -
|
| - function handler(e) {
|
| - if (!oneTime)
|
| - fn = path.getValueFrom(model);
|
| + var fn, receiver, handler;
|
| + if (typeof polymerExpressions.resolveEventHandler == 'function') {
|
| + handler = function(e) {
|
| + fn = fn || polymerExpressions.resolveEventHandler(model, path, node);
|
| + fn(e, e.detail, e.currentTarget);
|
| +
|
| + if (Platform && typeof Platform.flush == 'function')
|
| + Platform.flush();
|
| + };
|
| + } else {
|
| + handler = function(e) {
|
| + fn = fn || path.getValueFrom(model);
|
| + receiver = receiver || resolveEventReceiver(model, path, node);
|
|
|
| - fn.apply(model, [e, e.detail, e.currentTarget]);
|
| + fn.apply(receiver, [e, e.detail, e.currentTarget]);
|
|
|
| - if (Platform && typeof Platform.flush == 'function')
|
| - Platform.flush();
|
| + if (Platform && typeof Platform.flush == 'function')
|
| + Platform.flush();
|
| + };
|
| }
|
|
|
| node.addEventListener(eventType, handler);
|
| @@ -16819,18 +16925,29 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| },
|
|
|
| prepareBinding: function(pathString, name, node) {
|
| + var path = Path.get(pathString);
|
| if (isEventHandler(name)) {
|
| - var path = Path.get(pathString);
|
| if (!path.valid) {
|
| console.error('on-* bindings must be simple path expressions');
|
| return;
|
| }
|
|
|
| - return prepareEventBinding(path, name);
|
| + return prepareEventBinding(path, name, this);
|
| }
|
|
|
| - if (Path.get(pathString).valid)
|
| + if (path.valid) {
|
| + if (path.length == 1) {
|
| + return function(model, node, oneTime) {
|
| + if (oneTime)
|
| + return path.getValueFrom(model);
|
| +
|
| + var scope = findScope(model, path[0]);
|
| + return new PathObserver(scope, path);
|
| + }
|
| + }
|
| +
|
| return; // bail out early if pathString is simple path.
|
| + }
|
|
|
| return prepareBinding(pathString, name, node, this);
|
| },
|
| @@ -16844,9 +16961,13 @@ PointerGestureEvent.prototype.preventTap = function() {
|
| template.templateInstance.model :
|
| template.model;
|
|
|
| + var indexName = template.polymerExpressionIndexIdent_;
|
| +
|
| return function(model) {
|
| var scope = Object.create(parentScope);
|
| scope[scopeName] = model;
|
| + scope[indexName] = undefined;
|
| + scope[parentScopeName] = parentScope;
|
| return scope;
|
| };
|
| }
|
|
|