UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

1,302 lines (1,206 loc) 777 kB
(function(){/* Copyright (c) 2017 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 */ 'use strict';var k={};function n(){this.end=this.start=0;this.rules=this.parent=this.previous=null;this.cssText=this.parsedCssText="";this.atRule=!1;this.type=0;this.parsedSelector=this.selector=this.keyframesName=""} function p(a){a=a.replace(aa,"").replace(ba,"");var b=q,c=a,d=new n;d.start=0;d.end=c.length;for(var e=d,f=0,h=c.length;f<h;f++)if("{"===c[f]){e.rules||(e.rules=[]);var g=e,m=g.rules[g.rules.length-1]||null,e=new n;e.start=f+1;e.parent=g;e.previous=m;g.rules.push(e)}else"}"===c[f]&&(e.end=f+1,e=e.parent||d);return b(d,a)} function q(a,b){var c=b.substring(a.start,a.end-1);a.parsedCssText=a.cssText=c.trim();a.parent&&((c=b.substring(a.previous?a.previous.end:a.parent.start,a.start-1),c=ca(c),c=c.replace(r," "),c=c.substring(c.lastIndexOf(";")+1),c=a.parsedSelector=a.selector=c.trim(),a.atRule=!c.indexOf("@"),a.atRule)?c.indexOf("@media")?c.match(da)&&(a.type=u,a.keyframesName=a.selector.split(r).pop()):a.type=t:a.type=c.indexOf("--")?v:x);if(c=a.rules)for(var d=0,e=c.length,f;d<e&&(f=c[d]);d++)q(f,b);return a} function ca(a){return a.replace(/\\([0-9a-f]{1,6})\s/gi,function(a,c){a=c;for(c=6-a.length;c--;)a="0"+a;return"\\"+a})} function y(a,b,c){c=void 0===c?"":c;var d="";if(a.cssText||a.rules){var e=a.rules,f;if(f=e)f=e[0],f=!(f&&f.selector&&0===f.selector.indexOf("--"));if(f){f=0;for(var h=e.length,g;f<h&&(g=e[f]);f++)d=y(g,b,d)}else b?b=a.cssText:(b=a.cssText,b=b.replace(ea,"").replace(fa,""),b=b.replace(ga,"").replace(ha,"")),(d=b.trim())&&(d=" "+d+"\n")}d&&(a.selector&&(c+=a.selector+" {\n"),c+=d,a.selector&&(c+="}\n\n"));return c} var v=1,u=7,t=4,x=1E3,aa=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,ba=/@import[^;]*;/gim,ea=/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,fa=/(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,ga=/@apply\s*\(?[^);]*\)?\s*(?:[;\n]|$)?/gim,ha=/[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,da=/^@[^\s]*keyframes/,r=/\s+/g;var ia=Promise.resolve();function ja(a){if(a=k[a])a._applyShimCurrentVersion=a._applyShimCurrentVersion||0,a._applyShimValidatingVersion=a._applyShimValidatingVersion||0,a._applyShimNextVersion=(a._applyShimNextVersion||0)+1}function z(a){return a._applyShimCurrentVersion===a._applyShimNextVersion}function ka(a){a._applyShimValidatingVersion=a._applyShimNextVersion;a.a||(a.a=!0,ia.then(function(){a._applyShimCurrentVersion=a._applyShimNextVersion;a.a=!1}))};var A=/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};{])+)|\{([^}]*)\}(?:(?=[;\s}])|$))/gi,B=/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,la=/@media\s(.*)/;var C=!(window.ShadyDOM&&window.ShadyDOM.inUse),E;function F(a){E=a&&a.shimcssproperties?!1:C||!(navigator.userAgent.match(/AppleWebKit\/601|Edge\/15/)||!window.CSS||!CSS.supports||!CSS.supports("box-shadow","0 0 0 var(--foo)"))}window.ShadyCSS&&void 0!==window.ShadyCSS.nativeCss?E=window.ShadyCSS.nativeCss:window.ShadyCSS?(F(window.ShadyCSS),window.ShadyCSS=void 0):F(window.WebComponents&&window.WebComponents.flags);var G=E;function H(a){if(!a)return"";"string"===typeof a&&(a=p(a));return y(a,G)}function I(a){!a.__cssRules&&a.textContent&&(a.__cssRules=p(a.textContent));return a.__cssRules||null}function J(a,b,c,d){if(a){var e=!1,f=a.type;if(d&&f===t){var h=a.selector.match(la);h&&(window.matchMedia(h[1]).matches||(e=!0))}f===v?b(a):c&&f===u?c(a):f===x&&(e=!0);if((a=a.rules)&&!e)for(var e=0,f=a.length,g;e<f&&(g=a[e]);e++)J(g,b,c,d)}} function K(a,b){var c=a.indexOf("var(");if(-1===c)return b(a,"","","");a:{var d=0;var e=c+3;for(var f=a.length;e<f;e++)if("("===a[e])d++;else if(")"===a[e]&&!--d)break a;e=-1}d=a.substring(c+4,e);c=a.substring(0,c);a=K(a.substring(e+1),b);e=d.indexOf(",");return-1===e?b(c,d.trim(),"",a):b(c,d.substring(0,e).trim(),d.substring(e+1).trim(),a)};var ma=/;\s*/m,na=/^\s*(initial)|(inherit)\s*$/;function L(){this.a={}}L.prototype.set=function(a,b){a=a.trim();this.a[a]={h:b,i:{}}};L.prototype.get=function(a){a=a.trim();return this.a[a]||null};var M=null;function N(){this.b=this.c=null;this.a=new L}N.prototype.o=function(a){a=B.test(a)||A.test(a);B.lastIndex=0;A.lastIndex=0;return a};N.prototype.m=function(a,b){a=a.content.querySelector("style");var c=null;a&&(c=this.j(a,b));return c}; N.prototype.j=function(a,b){b=void 0===b?"":b;var c=I(a);this.l(c,b);a.textContent=H(c);return c};N.prototype.f=function(a){var b=this,c=I(a);J(c,function(a){":root"===a.selector&&(a.selector="html");b.g(a)});a.textContent=H(c);return c};N.prototype.l=function(a,b){var c=this;this.c=b;J(a,function(a){c.g(a)});this.c=null};N.prototype.g=function(a){a.cssText=oa(this,a.parsedCssText);":root"===a.selector&&(a.selector=":host > *")}; function oa(a,b){b=b.replace(A,function(b,d,e,f){return pa(a,b,d,e,f)});return O(a,b)}function O(a,b){for(var c;c=B.exec(b);){var d=c[0],e=c[1];c=c.index;var f=b.slice(0,c+d.indexOf("@apply"));b=b.slice(c+d.length);var h=P(a,f),d=void 0;var g=a;var e=e.replace(ma,""),m=[];var l=g.a.get(e);l||(g.a.set(e,{}),l=g.a.get(e));if(l)for(d in g.c&&(l.i[g.c]=!0),l.h)g=h&&h[d],l=[d,": var(",e,"_-_",d],g&&l.push(",",g),l.push(")"),m.push(l.join(""));d=m.join("; ");b=""+f+d+b;B.lastIndex=c+d.length}return b} function P(a,b){b=b.split(";");for(var c,d,e={},f=0,h;f<b.length;f++)if(c=b[f])if(h=c.split(":"),1<h.length){c=h[0].trim();var g=a;d=c;h=h.slice(1).join(":");var m=na.exec(h);m&&(m[1]?(g.b||(g.b=document.createElement("meta"),g.b.setAttribute("apply-shim-measure",""),g.b.style.all="initial",document.head.appendChild(g.b)),d=window.getComputedStyle(g.b).getPropertyValue(d)):d="apply-shim-inherit",h=d);d=h;e[c]=d}return e}function qa(a,b){if(M)for(var c in b.i)c!==a.c&&M(c)} function pa(a,b,c,d,e){d&&K(d,function(b,c){c&&a.a.get(c)&&(e="@apply "+c+";")});if(!e)return b;var f=O(a,e),h=b.slice(0,b.indexOf("--")),g=f=P(a,f),m=a.a.get(c),l=m&&m.h;l?g=Object.assign(Object.create(l),f):a.a.set(c,g);var X=[],w,Y=!1;for(w in g){var D=f[w];void 0===D&&(D="initial");!l||w in l||(Y=!0);X.push(""+c+"_-_"+w+": "+D)}Y&&qa(a,m);m&&(m.h=g);d&&(h=b+";"+h);return""+h+X.join("; ")+";"}N.prototype.detectMixin=N.prototype.o;N.prototype.transformStyle=N.prototype.j; N.prototype.transformCustomStyle=N.prototype.f;N.prototype.transformRules=N.prototype.l;N.prototype.transformRule=N.prototype.g;N.prototype.transformTemplate=N.prototype.m;N.prototype._separator="_-_";Object.defineProperty(N.prototype,"invalidCallback",{get:function(){return M},set:function(a){M=a}});var Q=null,R=window.HTMLImports&&window.HTMLImports.whenReady||null,S;function ra(a){requestAnimationFrame(function(){R?R(a):(Q||(Q=new Promise(function(a){S=a}),"complete"===document.readyState?S():document.addEventListener("readystatechange",function(){"complete"===document.readyState&&S()})),Q.then(function(){a&&a()}))})};var T=new N;function U(){var a=this;this.a=null;ra(function(){V(a)});T.invalidCallback=ja}function V(a){a.a||(a.a=window.ShadyCSS.CustomStyleInterface,a.a&&(a.a.transformCallback=function(a){T.f(a)},a.a.validateCallback=function(){requestAnimationFrame(function(){a.a.enqueued&&W(a)})}))}U.prototype.prepareTemplate=function(a,b){V(this);k[b]=a;b=T.m(a,b);a._styleAst=b}; function W(a){V(a);if(a.a){var b=a.a.processStyles();if(a.a.enqueued){for(var c=0;c<b.length;c++){var d=a.a.getStyleForCustomStyle(b[c]);d&&T.f(d)}a.a.enqueued=!1}}}U.prototype.styleSubtree=function(a,b){V(this);if(b)for(var c in b)null===c?a.style.removeProperty(c):a.style.setProperty(c,b[c]);if(a.shadowRoot)for(this.styleElement(a),a=a.shadowRoot.children||a.shadowRoot.childNodes,b=0;b<a.length;b++)this.styleSubtree(a[b]);else for(a=a.children||a.childNodes,b=0;b<a.length;b++)this.styleSubtree(a[b])}; U.prototype.styleElement=function(a){V(this);var b=a.localName,c;b?-1<b.indexOf("-")?c=b:c=a.getAttribute&&a.getAttribute("is")||"":c=a.is;if((b=k[c])&&!z(b)){if(z(b)||b._applyShimValidatingVersion!==b._applyShimNextVersion)this.prepareTemplate(b,c),ka(b);if(a=a.shadowRoot)if(a=a.querySelector("style"))a.__cssRules=b._styleAst,a.textContent=H(b._styleAst)}};U.prototype.styleDocument=function(a){V(this);this.styleSubtree(document.body,a)}; if(!window.ShadyCSS||!window.ShadyCSS.ScopingShim){var Z=new U,sa=window.ShadyCSS&&window.ShadyCSS.CustomStyleInterface;window.ShadyCSS={prepareTemplate:function(a,b){W(Z);Z.prepareTemplate(a,b)},styleSubtree:function(a,b){W(Z);Z.styleSubtree(a,b)},styleElement:function(a){W(Z);Z.styleElement(a)},styleDocument:function(a){W(Z);Z.styleDocument(a)},getComputedStyleValue:function(a,b){return(a=window.getComputedStyle(a).getPropertyValue(b))?a.trim():""},nativeCss:G,nativeShadow:C};sa&&(window.ShadyCSS.CustomStyleInterface= sa)}window.ShadyCSS.ApplyShim=T;}).call(this); //# sourceMappingURL=apply-shim.min.js.map (function() { 'use strict'; const userPolymer = window.Polymer; /** * @namespace Polymer * @summary Polymer is a lightweight library built on top of the web * standards-based Web Components API's, and makes it easy to build your * own custom HTML elements. * @param {!PolymerInit} info Prototype for the custom element. It must contain * an `is` property to specify the element name. Other properties populate * the element prototype. The `properties`, `observers`, `hostAttributes`, * and `listeners` properties are processed to create element features. * @return {!Object} Returns a custom element class for the given provided * prototype `info` object. The name of the element if given by `info.is`. */ window.Polymer = function(info) { return window.Polymer._polymerFn(info); } // support user settings on the Polymer object if (userPolymer) { Object.assign(Polymer, userPolymer); } // To be plugged by legacy implementation if loaded /* eslint-disable valid-jsdoc */ /** * @param {!PolymerInit} info Prototype for the custom element. It must contain * an `is` property to specify the element name. Other properties populate * the element prototype. The `properties`, `observers`, `hostAttributes`, * and `listeners` properties are processed to create element features. * @return {!Object} Returns a custom element class for the given provided * prototype `info` object. The name of the element if given by `info.is`. */ window.Polymer._polymerFn = function(info) { // eslint-disable-line no-unused-vars throw new Error('Load polymer.html to use the Polymer() function.'); } /* eslint-enable */ window.Polymer.version = '2.0.1'; /* eslint-disable no-unused-vars */ /* When using Closure Compiler, JSCompiler_renameProperty(property, object) is replaced by the munged name for object[property] We cannot alias this function, so we have to use a small shim that has the same behavior when not compiling. */ window.JSCompiler_renameProperty = function(prop, obj) { return prop; } /* eslint-enable */ })(); (function() { 'use strict'; let CSS_URL_RX = /(url\()([^)]*)(\))/g; let ABS_URL = /(^\/)|(^#)|(^[\w-\d]*:)/; let workingURL; let resolveDoc; /** * Resolves the given URL against the provided `baseUri'. * * @memberof Polymer.ResolveUrl * @param {string} url Input URL to resolve * @param {?string=} baseURI Base URI to resolve the URL against * @return {string} resolved URL */ function resolveUrl(url, baseURI) { if (url && ABS_URL.test(url)) { return url; } // Lazy feature detection. if (workingURL === undefined) { workingURL = false; try { const u = new URL('b', 'http://a'); u.pathname = 'c%20d'; workingURL = (u.href === 'http://a/c%20d'); } catch (e) { // silently fail } } if (!baseURI) { baseURI = document.baseURI || window.location.href; } if (workingURL) { return (new URL(url, baseURI)).href; } // Fallback to creating an anchor into a disconnected document. if (!resolveDoc) { resolveDoc = document.implementation.createHTMLDocument('temp'); resolveDoc.base = resolveDoc.createElement('base'); resolveDoc.head.appendChild(resolveDoc.base); resolveDoc.anchor = resolveDoc.createElement('a'); resolveDoc.body.appendChild(resolveDoc.anchor); } resolveDoc.base.href = baseURI; resolveDoc.anchor.href = url; return resolveDoc.anchor.href || url; } /** * Resolves any relative URL's in the given CSS text against the provided * `ownerDocument`'s `baseURI`. * * @memberof Polymer.ResolveUrl * @param {string} cssText CSS text to process * @param {string} baseURI Base URI to resolve the URL against * @return {string} Processed CSS text with resolved URL's */ function resolveCss(cssText, baseURI) { return cssText.replace(CSS_URL_RX, function(m, pre, url, post) { return pre + '\'' + resolveUrl(url.replace(/["']/g, ''), baseURI) + '\'' + post; }); } /** * Returns a path from a given `url`. The path includes the trailing * `/` from the url. * * @memberof Polymer.ResolveUrl * @param {string} url Input URL to transform * @return {string} resolved path */ function pathFromUrl(url) { return url.substring(0, url.lastIndexOf('/') + 1); } /** * Module with utilities for resolving relative URL's. * * @namespace * @memberof Polymer * @summary Module with utilities for resolving relative URL's. */ Polymer.ResolveUrl = { resolveCss: resolveCss, resolveUrl: resolveUrl, pathFromUrl: pathFromUrl }; })(); /** @suppress {deprecated} */ (function() { 'use strict'; /** * Legacy settings. * @namespace * @memberof Polymer */ const settings = Polymer.Settings || {}; settings.useShadow = !(window.ShadyDOM); settings.useNativeCSSProperties = Boolean(!window.ShadyCSS || window.ShadyCSS.nativeCss); settings.useNativeCustomElements = !(window.customElements.polyfillWrapFlushCallback); /** * Sets the global, legacy settings. * * @deprecated * @memberof Polymer */ Polymer.Settings = settings; /** * Globally settable property that is automatically assigned to * `Polymer.ElementMixin` instances, useful for binding in templates to * make URL's relative to an application's root. Defaults to the main * document URL, but can be overridden by users. It may be useful to set * `Polymer.rootPath` to provide a stable application mount path when * using client side routing. * * @memberof Polymer */ let rootPath = Polymer.rootPath || Polymer.ResolveUrl.pathFromUrl(document.baseURI || window.location.href); Polymer.rootPath = rootPath; /** * Sets the global rootPath property used by `Polymer.ElementMixin` and * available via `Polymer.rootPath`. * * @memberof Polymer * @param {string} path The new root path */ Polymer.setRootPath = function(path) { Polymer.rootPath = path; } })(); (function() { 'use strict'; // unique global id for deduping mixins. let dedupeId = 0; /** * @constructor * @extends {Function} */ function MixinFunction(){} /** @type {(WeakMap | undefined)} */ MixinFunction.prototype.__mixinApplications; /** @type {(Object | undefined)} */ MixinFunction.prototype.__mixinSet; /* eslint-disable valid-jsdoc */ /** * Wraps an ES6 class expression mixin such that the mixin is only applied * if it has not already been applied its base argument. Also memoizes mixin * applications. * * @memberof Polymer * @template T * @param {T} mixin ES6 class expression mixin to wrap * @suppress {invalidCasts} */ Polymer.dedupingMixin = function(mixin) { let mixinApplications = /** @type {!MixinFunction} */(mixin).__mixinApplications; if (!mixinApplications) { mixinApplications = new WeakMap(); /** @type {!MixinFunction} */(mixin).__mixinApplications = mixinApplications; } // maintain a unique id for each mixin let mixinDedupeId = dedupeId++; function dedupingMixin(base) { let baseSet = /** @type {!MixinFunction} */(base).__mixinSet; if (baseSet && baseSet[mixinDedupeId]) { return base; } let map = mixinApplications; let extended = map.get(base); if (!extended) { extended = /** @type {!Function} */(mixin)(base); map.set(base, extended); } // copy inherited mixin set from the extended class, or the base class // NOTE: we avoid use of Set here because some browser (IE11) // cannot extend a base Set via the constructor. let mixinSet = Object.create(/** @type {!MixinFunction} */(extended).__mixinSet || baseSet || null); mixinSet[mixinDedupeId] = true; /** @type {!MixinFunction} */(extended).__mixinSet = mixinSet; return extended; } return dedupingMixin; }; /* eslint-enable valid-jsdoc */ })(); (function() { 'use strict'; const caseMap = {}; const DASH_TO_CAMEL = /-[a-z]/g; const CAMEL_TO_DASH = /([A-Z])/g; /** * Module with utilities for converting between "dash-case" and "camelCase" * identifiers. * * @namespace * @memberof Polymer * @summary Module that provides utilities for converting between "dash-case" * and "camelCase". */ const CaseMap = { /** * Converts "dash-case" identifier (e.g. `foo-bar-baz`) to "camelCase" * (e.g. `fooBarBaz`). * * @memberof Polymer.CaseMap * @param {string} dash Dash-case identifier * @return {string} Camel-case representation of the identifier */ dashToCamelCase(dash) { return caseMap[dash] || ( caseMap[dash] = dash.indexOf('-') < 0 ? dash : dash.replace(DASH_TO_CAMEL, (m) => m[1].toUpperCase() ) ); }, /** * Converts "camelCase" identifier (e.g. `fooBarBaz`) to "dash-case" * (e.g. `foo-bar-baz`). * * @memberof Polymer.CaseMap * @param {string} camel Camel-case identifier * @return {string} Dash-case representation of the identifier */ camelToDashCase(camel) { return caseMap[camel] || ( caseMap[camel] = camel.replace(CAMEL_TO_DASH, '-$1').toLowerCase() ); } }; Polymer.CaseMap = CaseMap; })(); (function() { 'use strict'; const MODULE_STYLE_LINK_SELECTOR = 'link[rel=import][type~=css]'; const INCLUDE_ATTR = 'include'; function importModule(moduleId) { if (!Polymer.DomModule) { return null; } return Polymer.DomModule.import(moduleId); } /** @typedef {{assetpath: string}} */ let templateWithAssetPath; // eslint-disable-line no-unused-vars /** * Module with utilities for collection CSS text from `<templates>`, external * stylesheets, and `dom-module`s. * * @namespace * @memberof Polymer * @summary Module with utilities for collection CSS text from various sources. */ const StyleGather = { /** * Returns CSS text of styles in a space-separated list of `dom-module`s. * * @memberof Polymer.StyleGather * @param {string} moduleIds List of dom-module id's within which to * search for css. * @return {string} Concatenated CSS content from specified `dom-module`s * @this {StyleGather} */ cssFromModules(moduleIds) { let modules = moduleIds.trim().split(' '); let cssText = ''; for (let i=0; i < modules.length; i++) { cssText += this.cssFromModule(modules[i]); } return cssText; }, /** * Returns CSS text of styles in a given `dom-module`. CSS in a `dom-module` * can come either from `<style>`s within the first `<template>`, or else * from one or more `<link rel="import" type="css">` links outside the * template. * * Any `<styles>` processed are removed from their original location. * * @memberof Polymer.StyleGather * @param {string} moduleId dom-module id to gather styles from * @return {string} Concatenated CSS content from specified `dom-module` * @this {StyleGather} */ cssFromModule(moduleId) { let m = importModule(moduleId); if (m && m._cssText === undefined) { let cssText = ''; // include css from the first template in the module let t = m.querySelector('template'); if (t) { cssText += this.cssFromTemplate(t, /** @type {templateWithAssetPath }*/(m).assetpath); } // module imports: <link rel="import" type="css"> cssText += this.cssFromModuleImports(moduleId); m._cssText = cssText || null; } if (!m) { console.warn('Could not find style data in module named', moduleId); } return m && m._cssText || ''; }, /** * Returns CSS text of `<styles>` within a given template. * * Any `<styles>` processed are removed from their original location. * * @memberof Polymer.StyleGather * @param {HTMLTemplateElement} template Template to gather styles from * @param {string} baseURI Base URI to resolve the URL against * @return {string} Concatenated CSS content from specified template * @this {StyleGather} */ cssFromTemplate(template, baseURI) { let cssText = ''; // if element is a template, get content from its .content let e$ = template.content.querySelectorAll('style'); for (let i=0; i < e$.length; i++) { let e = e$[i]; // support style sharing by allowing styles to "include" // other dom-modules that contain styling let include = e.getAttribute(INCLUDE_ATTR); if (include) { cssText += this.cssFromModules(include); } e.parentNode.removeChild(e); cssText += baseURI ? Polymer.ResolveUrl.resolveCss(e.textContent, baseURI) : e.textContent; } return cssText; }, /** * Returns CSS text from stylsheets loaded via `<link rel="import" type="css">` * links within the specified `dom-module`. * * @memberof Polymer.StyleGather * @param {string} moduleId Id of `dom-module` to gather CSS from * @return {string} Concatenated CSS content from links in specified `dom-module` * @this {StyleGather} */ cssFromModuleImports(moduleId) { let cssText = ''; let m = importModule(moduleId); if (!m) { return cssText; } let p$ = m.querySelectorAll(MODULE_STYLE_LINK_SELECTOR); for (let i=0; i < p$.length; i++) { let p = p$[i]; if (p.import) { let importDoc = p.import; // NOTE: polyfill affordance. // under the HTMLImports polyfill, there will be no 'body', // but the import pseudo-doc can be used directly. let container = importDoc.body ? importDoc.body : importDoc; cssText += Polymer.ResolveUrl.resolveCss(container.textContent, importDoc.baseURI); } } return cssText; } }; Polymer.StyleGather = StyleGather; })(); (function() { 'use strict'; let modules = {}; let lcModules = {}; function findModule(id) { return modules[id] || lcModules[id.toLowerCase()]; } function styleOutsideTemplateCheck(inst) { if (inst.querySelector('style')) { console.warn('dom-module %s has style outside template', inst.id); } } /** * The `dom-module` element registers the dom it contains to the name given * by the module's id attribute. It provides a unified database of dom * accessible via its static `import` API. * * A key use case of `dom-module` is for providing custom element `<template>`s * via HTML imports that are parsed by the native HTML parser, that can be * relocated during a bundling pass and still looked up by `id`. * * Example: * * <dom-module id="foo"> * <img src="stuff.png"> * </dom-module> * * Then in code in some other location that cannot access the dom-module above * * let img = document.createElement('dom-module').import('foo', 'img'); * * @customElement * @extends HTMLElement * @memberof Polymer * @summary Custom element that provides a registry of relocatable DOM content * by `id` that is agnostic to bundling. * @unrestricted */ class DomModule extends HTMLElement { static get observedAttributes() { return ['id'] } /** * Retrieves the element specified by the css `selector` in the module * registered by `id`. For example, this.import('foo', 'img'); * @param {string} id The id of the dom-module in which to search. * @param {string=} selector The css selector by which to find the element. * @return {Element} Returns the element which matches `selector` in the * module registered at the specified `id`. */ static import(id, selector) { if (id) { let m = findModule(id); if (m && selector) { return m.querySelector(selector); } return m; } return null; } attributeChangedCallback(name, old, value) { if (old !== value) { this.register(); } } /** * The absolute URL of the original location of this `dom-module`. * * This value will differ from this element's `ownerDocument` in the * following ways: * - Takes into account any `assetpath` attribute added during bundling * to indicate the original location relative to the bundled location * - Uses the HTMLImports polyfill's `importForElement` API to ensure * the path is relative to the import document's location since * `ownerDocument` is not currently polyfilled */ get assetpath() { // Don't override existing assetpath. if (!this.__assetpath) { // note: assetpath set via an attribute must be relative to this // element's location; accomodate polyfilled HTMLImports const owner = window.HTMLImports && HTMLImports.importForElement ? HTMLImports.importForElement(this) || document : this.ownerDocument; const url = Polymer.ResolveUrl.resolveUrl( this.getAttribute('assetpath') || '', owner.baseURI); this.__assetpath = Polymer.ResolveUrl.pathFromUrl(url); } return this.__assetpath; } /** * Registers the dom-module at a given id. This method should only be called * when a dom-module is imperatively created. For * example, `document.createElement('dom-module').register('foo')`. * @param {string=} id The id at which to register the dom-module. */ register(id) { id = id || this.id; if (id) { this.id = id; // store id separate from lowercased id so that // in all cases mixedCase id will stored distinctly // and lowercase version is a fallback modules[id] = this; lcModules[id.toLowerCase()] = this; styleOutsideTemplateCheck(this); } } } DomModule.prototype['modules'] = modules; customElements.define('dom-module', DomModule); // export Polymer.DomModule = DomModule; })(); (function() { 'use strict'; /** * Module with utilities for manipulating structured data path strings. * * @namespace * @memberof Polymer * @summary Module with utilities for manipulating structured data path strings. */ const Path = { /** * Returns true if the given string is a structured data path (has dots). * * Example: * * ``` * Polymer.Path.isPath('foo.bar.baz') // true * Polymer.Path.isPath('foo') // false * ``` * * @memberof Polymer.Path * @param {string} path Path string * @return {boolean} True if the string contained one or more dots */ isPath: function(path) { return path.indexOf('.') >= 0; }, /** * Returns the root property name for the given path. * * Example: * * ``` * Polymer.Path.root('foo.bar.baz') // 'foo' * Polymer.Path.root('foo') // 'foo' * ``` * * @memberof Polymer.Path * @param {string} path Path string * @return {string} Root property name */ root: function(path) { let dotIndex = path.indexOf('.'); if (dotIndex === -1) { return path; } return path.slice(0, dotIndex); }, /** * Given `base` is `foo.bar`, `foo` is an ancestor, `foo.bar` is not * Returns true if the given path is an ancestor of the base path. * * Example: * * ``` * Polymer.Path.isAncestor('foo.bar', 'foo') // true * Polymer.Path.isAncestor('foo.bar', 'foo.bar') // false * Polymer.Path.isAncestor('foo.bar', 'foo.bar.baz') // false * ``` * * @memberof Polymer.Path * @param {string} base Path string to test against. * @param {string} path Path string to test. * @return {boolean} True if `path` is an ancestor of `base`. */ isAncestor: function(base, path) { // base.startsWith(path + '.'); return base.indexOf(path + '.') === 0; }, /** * Given `base` is `foo.bar`, `foo.bar.baz` is an descendant * * Example: * * ``` * Polymer.Path.isDescendant('foo.bar', 'foo.bar.baz') // true * Polymer.Path.isDescendant('foo.bar', 'foo.bar') // false * Polymer.Path.isDescendant('foo.bar', 'foo') // false * ``` * * @memberof Polymer.Path * @param {string} base Path string to test against. * @param {string} path Path string to test. * @return {boolean} True if `path` is a descendant of `base`. */ isDescendant: function(base, path) { // path.startsWith(base + '.'); return path.indexOf(base + '.') === 0; }, /** * Replaces a previous base path with a new base path, preserving the * remainder of the path. * * User must ensure `path` has a prefix of `base`. * * Example: * * ``` * Polymer.Path.translate('foo.bar', 'zot' 'foo.bar.baz') // 'zot.baz' * ``` * * @memberof Polymer.Path * @param {string} base Current base string to remove * @param {string} newBase New base string to replace with * @param {string} path Path to translate * @return {string} Translated string */ translate: function(base, newBase, path) { return newBase + path.slice(base.length); }, /** * @param {string} base Path string to test against * @param {string} path Path string to test * @return {boolean} True if `path` is equal to `base` * @this {Path} */ matches: function(base, path) { return (base === path) || this.isAncestor(base, path) || this.isDescendant(base, path); }, /** * Converts array-based paths to flattened path. String-based paths * are returned as-is. * * Example: * * ``` * Polymer.Path.normalize(['foo.bar', 0, 'baz']) // 'foo.bar.0.baz' * Polymer.Path.normalize('foo.bar.0.baz') // 'foo.bar.0.baz' * ``` * * @memberof Polymer.Path * @param {string | !Array<string|number>} path Input path * @return {string} Flattened path */ normalize: function(path) { if (Array.isArray(path)) { let parts = []; for (let i=0; i<path.length; i++) { let args = path[i].toString().split('.'); for (let j=0; j<args.length; j++) { parts.push(args[j]); } } return parts.join('.'); } else { return path; } }, /** * Splits a path into an array of property names. Accepts either arrays * of path parts or strings. * * Example: * * ``` * Polymer.Path.split(['foo.bar', 0, 'baz']) // ['foo', 'bar', '0', 'baz'] * Polymer.Path.split('foo.bar.0.baz') // ['foo', 'bar', '0', 'baz'] * ``` * * @memberof Polymer.Path * @param {string | !Array<string|number>} path Input path * @return {!Array<string>} Array of path parts * @this {Path} * @suppress {checkTypes} */ split: function(path) { if (Array.isArray(path)) { return this.normalize(path).split('.'); } return path.toString().split('.'); }, /** * Reads a value from a path. If any sub-property in the path is `undefined`, * this method returns `undefined` (will never throw. * * @memberof Polymer.Path * @param {Object} root Object from which to dereference path from * @param {string | !Array<string|number>} path Path to read * @param {Object=} info If an object is provided to `info`, the normalized * (flattened) path will be set to `info.path`. * @return {*} Value at path, or `undefined` if the path could not be * fully dereferenced. * @this {Path} */ get: function(root, path, info) { let prop = root; let parts = this.split(path); // Loop over path parts[0..n-1] and dereference for (let i=0; i<parts.length; i++) { if (!prop) { return; } let part = parts[i]; prop = prop[part]; } if (info) { info.path = parts.join('.'); } return prop; }, /** * Sets a value to a path. If any sub-property in the path is `undefined`, * this method will no-op. * * @memberof Polymer.Path * @param {Object} root Object from which to dereference path from * @param {string | !Array<string|number>} path Path to set * @param {*} value Value to set to path * @return {string | undefined} The normalized version of the input path * @this {Path} */ set: function(root, path, value) { let prop = root; let parts = this.split(path); let last = parts[parts.length-1]; if (parts.length > 1) { // Loop over path parts[0..n-2] and dereference for (let i=0; i<parts.length-1; i++) { let part = parts[i]; prop = prop[part]; if (!prop) { return; } } // Set value to object at end of path prop[last] = value; } else { // Simple property set prop[path] = value; } return parts.join('.'); } }; /** * Returns true if the given string is a structured data path (has dots). * * This function is deprecated. Use `Polymer.Path.isPath` instead. * * Example: * * ``` * Polymer.Path.isDeep('foo.bar.baz') // true * Polymer.Path.isDeep('foo') // false * ``` * * @deprecated * @memberof Polymer.Path * @param {string} path Path string * @return {boolean} True if the string contained one or more dots */ Path.isDeep = Path.isPath; Polymer.Path = Path; })(); (function() { 'use strict'; /** @typedef {{run: function(function(), number=):number, cancel: function(number)}} */ let AsyncInterface; // eslint-disable-line no-unused-vars // Microtask implemented using Mutation Observer let microtaskCurrHandle = 0; let microtaskLastHandle = 0; let microtaskCallbacks = []; let microtaskNodeContent = 0; let microtaskNode = document.createTextNode(''); new window.MutationObserver(microtaskFlush).observe(microtaskNode, {characterData: true}); function microtaskFlush() { const len = microtaskCallbacks.length; for (let i = 0; i < len; i++) { let cb = microtaskCallbacks[i]; if (cb) { try { cb(); } catch (e) { setTimeout(() => { throw e }); } } } microtaskCallbacks.splice(0, len); microtaskLastHandle += len; } /** * Module that provides a number of strategies for enqueuing asynchronous * tasks. Each sub-module provides a standard `run(fn)` interface that returns a * handle, and a `cancel(handle)` interface for canceling async tasks before * they run. * * @namespace * @memberof Polymer * @summary Module that provides a number of strategies for enqueuing asynchronous * tasks. */ Polymer.Async = { /** * Async interface wrapper around `setTimeout`. * * @namespace * @memberof Polymer.Async * @summary Async interface wrapper around `setTimeout`. */ timeOut: { /** * Returns a sub-module with the async interface providing the provided * delay. * * @memberof Polymer.Async.timeOut * @param {number} delay Time to wait before calling callbacks in ms * @return {AsyncInterface} An async timeout interface */ after(delay) { return { run(fn) { return setTimeout(fn, delay) }, cancel: window.clearTimeout.bind(window) } }, /** * Enqueues a function called in the next task. * * @memberof Polymer.Async.timeOut * @param {Function} fn Callback to run * @return {number} Handle used for canceling task */ run: window.setTimeout.bind(window), /** * Cancels a previously enqueued `timeOut` callback. * * @memberof Polymer.Async.timeOut * @param {number} handle Handle returned from `run` of callback to cancel */ cancel: window.clearTimeout.bind(window) }, /** * Async interface wrapper around `requestAnimationFrame`. * * @namespace * @memberof Polymer.Async * @summary Async interface wrapper around `requestAnimationFrame`. */ animationFrame: { /** * Enqueues a function called at `requestAnimationFrame` timing. * * @memberof Polymer.Async.animationFrame * @param {Function} fn Callback to run * @return {number} Handle used for canceling task */ run: window.requestAnimationFrame.bind(window), /** * Cancels a previously enqueued `animationFrame` callback. * * @memberof Polymer.Async.timeOut * @param {number} handle Handle returned from `run` of callback to cancel */ cancel: window.cancelAnimationFrame.bind(window) }, /** * Async interface wrapper around `requestIdleCallback`. Falls back to * `setTimeout` on browsers that do not support `requestIdleCallback`. * * @namespace * @memberof Polymer.Async * @summary Async interface wrapper around `requestIdleCallback`. */ idlePeriod: { /** * Enqueues a function called at `requestIdleCallback` timing. * * @memberof Polymer.Async.idlePeriod * @param {function(IdleDeadline)} fn Callback to run * @return {number} Handle used for canceling task */ run(fn) { return window.requestIdleCallback ? window.requestIdleCallback(fn) : window.setTimeout(fn, 16); }, /** * Cancels a previously enqueued `idlePeriod` callback. * * @memberof Polymer.Async.idlePeriod * @param {number} handle Handle returned from `run` of callback to cancel */ cancel(handle) { window.cancelIdleCallback ? window.cancelIdleCallback(handle) : window.clearTimeout(handle); } }, /** * Async interface for enqueueing callbacks that run at microtask timing. * * Note that microtask timing is achieved via a single `MutationObserver`, * and thus callbacks enqueued with this API will all run in a single * batch, and not interleaved with other microtasks such as promises. * Promises are avoided as an implementation choice for the time being * due to Safari bugs that cause Promises to lack microtask guarantees. * * @namespace * @memberof Polymer.Async * @summary Async interface for enqueueing callbacks that run at microtask * timing. */ microTask: { /** * Enqueues a function called at microtask timing. * * @memberof Polymer.Async.microTask * @param {Function} callback Callback to run * @return {number} Handle used for canceling task */ run(callback) { microtaskNode.textContent = microtaskNodeContent++; microtaskCallbacks.push(callback); return microtaskCurrHandle++; }, /** * Cancels a previously enqueued `microTask` callback. * * @memberof Polymer.Async.microTask * @param {number} handle Handle returned from `run` of callback to cancel */ cancel(handle) { const idx = handle - microtaskLastHandle; if (idx >= 0) { if (!microtaskCallbacks[idx]) { throw new Error('invalid async handle: ' + handle); } microtaskCallbacks[idx] = null; } } } }; })(); (function() { 'use strict'; let caseMap = Polymer.CaseMap; let microtask = Polymer.Async.microTask; // Save map of native properties; this forms a blacklist or properties // that won't have their values "saved" by `saveAccessorValue`, since // reading from an HTMLElement accessor from the context of a prototype throws const nativeProperties = {}; let proto = HTMLElement.prototype; while (proto) { let props = Object.getOwnPropertyNames(proto); for (let i=0; i<props.length; i++) { nativeProperties[props[i]] = true; } proto = Object.getPrototypeOf(proto); } /** * Used to save the value of a property that will be overridden with * an accessor. If the `model` is a prototype, the values will be saved * in `__dataProto`, and it's up to the user (or downstream mixin) to * decide how/when to set these values back into the accessors. * If `model` is already an instance (it has a `__data` property), then * the value will be set as a pending property, meaning the user should * call `_invalidateProperties` or `_flushProperties` to take effect * * @param {Object} model Prototype or instance * @param {string} property Name of property * @private */ function saveAccessorValue(model, property) { // Don't read/store value for any native properties since they could throw if (!nativeProperties[property]) { let value = model[property]; if (value !== undefined) { if (model.__data) { // Adding accessor to instance; update the property // It is the user's responsibility to call _flushProperties model._setPendingProperty(property, value); } else { // Adding accessor to proto; save proto's value for instance-time use if (!model.__dataProto) { model.__dataProto = {}; } else if (!model.hasOwnProperty(JSCompiler_renameProperty('__dataProto', model))) { model.__dataProto = Object.create(model.__dataProto); } model.__dataProto[property] = value; } } } } /** * Element class mixin that provides basic meta-programming for creating one * or more property accessors (getter/setter pair) that enqueue an async * (batched) `_propertiesChanged` callback. * * For basic usage of this mixin, simply declare attributes to observe via * the standard `static get observedAttributes()`, implement `_propertiesChanged` * on the class, and then call `MyClass.createPropertiesForAttributes()` once * on the class to generate property accessors for each observed attribute * prior to instancing. Last, call `this._flushProperties()` once to enable * the accessors. * * Any `observedAttributes` will automatically be * deserialized via `attributeChangedCallback` and set to the associated * property using `dash-case`-to-`camelCase` convention. * * @mixinFunction * @polymer * @memberof Polymer * @summary Element class mixin for reacting to property changes from * generated property accessors. */ Polymer.PropertyAccessors = Polymer.dedupingMixin(superClass => { /** * @polymer * @mixinClass * @implements {Polymer_PropertyAccessors} * @extends HTMLElement * @unrestricted */ class PropertyAccessors extends superClass { /** * Generates property accessors for all attributes in the standard * static `observedAttributes` array. * * Attribute names are mapped to property names using the `dash-case` to * `camelCase` convention * */ static createPropertiesForAttributes() { let a$ = this.observedAttributes; for (let i=0; i < a$.length; i++) { this.prototype._createPropertyAccessor(caseMap.dashToCamelCase(a$[i])); } } constructor() { super(); /** @type {boolean} */ this.__serializing; /** @type {number} */ this.__dataCounter; /** @type {boolean} */ this.__dataEnabled; /** @type {boolean} */ this.__dataReady; /** @type {boolean} */ this.__dataInvalid; /** @type {!Object} */ this.__data; /** @type {Object} */ this.__dataPending; /** @type {Object} */ this.__dataOld; /** @type {Object} */ this.__dataProto; /** @type {Object} */ this.__dataHasAccessor; /** @type {Object} */ this.__dataInstanceProps; this._initializeProperties(); } /** * Implements native Custom Elements `attributeChangedCallback` to * set an attribute value to a property via `_attributeToProperty`. * * @param {string} name Name of attribute that changed * @param {?string} old Old attribute value * @param {?string} value New attribute value */ attributeChangedCallback(name, old, value) { if (old !== value) { this._attributeToProperty(name, value); } } /** * Initializes the local storage for property accessors. * * Provided as an override point for performing any setup work prior * to initializing the property accessor system. * * @protected */ _initializeProperties() { this.__serializing = false; this.__dataCounter = 0; this.__dataEnabled = false; this.__dataReady = false; this.__dataInvalid = false; this.__data = {}; this.__dataPending = null; this.__dataOld = null; if (this.__dataProto) { this._initializeProtoProperties(this.__dataProto); this.__dataProto = null; } // Capture instance properties; these will be set into accessors // during first flush. Don't set them here, since we want // these to overwrite defaults/constructor assignments for (let p in this.__dataHasAccessor) { if (this.hasOwnProperty(p)) { this.__dataInstanceProps = this.__dataInstanceProps || {}; this.__dataInstanceProps[p] = this[p]; delete this[p]; } } } /** * Called at instance time with bag of properties that were overwritten * by accessors on the prototype when accessors were created. * * The default implementation sets these properties back into the * setter at instance time. This method is provided as an override * point for customizing or providing more efficient initialization. * * @param {Object} props Bag of property values that were overwritten * when creating property accessors. * @protected */ _initializeProtoProperties(props) { for (let p in props) { this._setProperty(p, props[p]); } } /** * Called at ready time with bag of instance properties that overwrote * accessors when the element upgraded. * * The default implementation sets these properties back into the * setter at ready time. This method is provided as an override * point for customizing or providing more efficient initialization. * * @param {Object} props Bag of property values that were overwritten * when creating property accessors. * @protected */ _initializeInstanceProperties(props) { Object.assign(this, props); } /** * Ensures the element has the given attribute. If it does not, * assigns the given value to the attribute. * * * @param {string} attribute Name of attribute to ensure is set. * @param {string} value of the attribute. */ _ensureAttribute(attribute, value) { if (!this.hasAttribute(attribute)) { this._valueToNodeAttribute(this, value, attribute); } } /** * Deserializes an attribute to its associated property. * * This method calls the `_deserializeValue` method to convert the string to * a typed value. * * @param {string} attribute Name of attribute to deserialize. * @param {?string} value of the attribute. * @param {*=} type type to deserialize to. */ _attributeToProperty(attribute, value, type) { // Don't deserialize back to property if currently reflecting if (!this.__serializing) { let property = caseMap.dashToCam