UNPKG

@polymer/polymer

Version:

The Polymer library makes it easy to create your own web components. Give your element some markup and properties, and then use it on a site. Polymer provides features like dynamic templates and data binding to reduce the amount of boilerplate you need to

1,113 lines (984 loc) 30.8 kB
<!doctype html> <!-- @license 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 --> <html> <head> <meta charset="utf-8"> <script src="../../../webcomponentsjs/webcomponents-lite.js"></script> <script src="../../../web-component-tester/browser.js"></script> <link rel="import" href="../../polymer.html"> <style> .variable-override { border-top-width: 10px; } </style> </head> <body> <simple-element></simple-element> <simple-element></simple-element> <x-scope></x-scope> <dom-module id="x-grand-child-scope"> <template> <style> :host { display: block; padding: 8px; } #scope { border: var(--scope-var); } #child { border: var(--child-scope-var); } #me { border: var(--grand-child-scope-var); } </style> <div id="me">x-grand-child-scope</div> <div id="scope">From x-scope</div> <div id="child">From x-child-scope</div> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-grand-child-scope'}); }); </script> </dom-module> <dom-module id="x-host-property"> <template> <style> :host { display: block; padding: 8px; border: var(--scope-var); } :host(.foo) { border: var(--scope-var-foo); } </style> Host property </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-host-property'}); }); </script> </dom-module> <dom-module id="x-host-host-property"> <template> <x-host-property id="hosted"></x-host-property> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-host-host-property'}); }); </script> </dom-module> <dom-module id="x-produce-use-property"> <template> <style> :host { --scope-var: 6px solid steelblue; --scope-var-foo: 8px solid steelblue; } </style> <x-host-host-property id="hosted"></x-host-host-property> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-produce-use-property'}); }); </script> </dom-module> <dom-module id="x-child-scope"> <template> <style> :host { display: block; padding: 8px; } :host > * { --gc4-scope: 5px solid green; } #me { border: var(--child-scope-var); } #gc2 { --grand-child-scope-var: 4px solid seagreen; } #gc4 { --grand-child-scope-var: var(--gc4-scope); } </style> <div id="me">x-child-scope</div> <x-grand-child-scope id="gc1"></x-grand-child-scope> <x-grand-child-scope id="gc2"></x-grand-child-scope> <x-grand-child-scope id="gc3"></x-grand-child-scope> <x-grand-child-scope id="gc4"></x-grand-child-scope> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-child-scope'}); }); </script> </dom-module> <dom-module id="x-overrides"> <template> <style> :host { border: 1px dashed gray; margin: 8px; padding: 8px; display: block; --grand-child-scope-var: var(--rename); } </style> overrides: <x-grand-child-scope id="gc1"></x-grand-child-scope> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-overrides'}); }); </script> </dom-module> <dom-module id="x-overrides2"> <template> <style> :host { border: 1px dashed gray; margin: 8px; padding: 8px; display: block; } :host > * { --grand-child-scope-var: var(--rename); } </style> overrides: <x-grand-child-scope id="gc1"></x-grand-child-scope> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-overrides2'}); }); </script> </dom-module> <dom-module id="x-late"> <template> <style> :host { border: var(--late); display: block; } </style> late </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-late'}); }); </script> </dom-module> <dom-module id="x-overrides3"> <template> <style> :host { border: 1px dashed gray; margin: 8px; padding: 8px; display: block; } :host > * { --fillin: 16px; } </style> overrides: <x-late id="late"></x-late> </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-overrides3'}); }); </script> </dom-module> <dom-module id="x-has-def"> <template> <style> :host { border: var(--border, var(--defaultBorder)); margin: 8px; padding: 8px; display: block; } </style> Element with default variable. </template> <script> HTMLImports.whenReady(function() { Polymer({is: 'x-has-def'}); }); </script> </dom-module> <dom-module id="x-has-if"> <template> <style> .iffy { border: var(--scope-var); } </style> <template is="dom-if" if="{{gogo}}"> <div class="iffy">iffy</div> </template> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-has-if', properties: { gogo: {value: true} } }); }); </script> </dom-module> <dom-module id="x-button"> <template> <style> :host { display: block; border: var(--button-border); } </style> Button! </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-button', extends: 'button' }); }); </script> </dom-module> <dom-module id="x-dynamic"> <template> <style> :host { display: block; margin: 20px; border: var(--dynamic); } </style> Dynamic </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-dynamic' }); }); </script> </dom-module> <dom-module id="x-keyframes"> <template> <style> :host { display: block; position: relative; border: 10px solid blue; left: 0px; /* Prefix required by Safari <= 8 */ -webkit-animation-duration: 0.3s; animation-duration: 0.3s; -webkit-animation-fill-mode: forwards; animation-fill-mode: forwards; } :host([animated]) { /* Prefix required by Safari <= 8 */ -webkit-animation-name: x-keyframes-animation; animation-name: x-keyframes-animation; } /* Prefix required by Safari <= 8 */ @-webkit-keyframes x-keyframes-animation { 0% { left: var(--a); } 100% { left: var(--b); } } @keyframes x-keyframes-animation { 0% { left: var(--a); } 100% { left: var(--b); } } </style> x-keyframes </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-keyframes', properties: { animated: { type: Boolean, value: false, reflectToAttribute: true } } }); }); </script> </dom-module> <dom-module id="x-scope"> <template> <style> :host { x--invalid: 15px solid gray; display: block; padding: 8px; --scope-var: 1px solid black; --fallback: 7px solid orange; --default1: var(--undefined, 6px solid yellow); --default2: var(--undefined, var(--fallback)); --default3: var(--undefined, rgb(128, 200, 250)); --defaultBorder: 22px solid green; --a: 10px; --b: 5px; --primary-color: rgb(128, 128, 128); --late: var(--fillin); --button-border: 16px solid tomato; --after: 17px solid brown; --end-term: 19px solid blue} :host > *{--ws-term: 18px solid orange} #me { border: var(--scope-var); } x-child-scope { --child-scope-var: 2px solid orange; --grand-child-scope-var: 3px solid steelblue; } x-child-scope.special { --child-scope-var: 12px solid orange; } #applyDefault1 { border: var(--undefined, 6px solid yellow); } #applyDefault2 { border: var(--undefined, var(--fallback)); } #default1 { border: var(--default1); } #default2 { border: var(--default2); } #default3 { padding: 8px; background-color: var(--default3); } #defaultElement2 { --defaultBorder: 23px solid goldenrod; } #overrides1a, #overrides1b, #overrides2 { --rename: 8px solid navy; } #overrides1b, #overrides2 { --grand-child-scope-var: 9px solid orange; } #overridesConcrete { border: var(--scope-var); border: 4px solid steelblue; } #calc { border: solid red; border-width: calc(var(--a) + var(--b)); } #shadow { box-shadow: 10px 10px 10px var(--primary-color); -webkit-box-shadow: 10px 10px 10px var(--primary-color); } x-host-property { border: 10px solid purple; } #invalid { border: var(--invalid); } #after::after { content: 'after'; border: var(--after); } #wsTerm { border: var(--ws-term) } x-keyframes:nth-of-type(2) { --b: -5px; } #endTerm {border: var(--end-term)} #parenthesis { background-image: var(--foo-background-image, url(http://placehold.it/400x300)); } #nestedFallback { border: var(--undefined, var(--undefined, 20px solid blue)); } #doubleNestedFallback { border: var(--undefined, var(--undefined, var(--undefined, 20px solid red))); } #cornerFallback { background-image: var(--undefined, var(--undefined, var(--undefined, url(http://placehold.it/400x300)))); } </style> <div id="me">x-scope</div> <x-keyframes id="keyframes"></x-keyframes> <x-keyframes id="keyframes2"></x-keyframes> <x-child-scope id="child"></x-child-scope> <x-child-scope id="child2"></x-child-scope> <x-overrides id="overrides1a"></x-overrides> <x-overrides id="overrides1b"></x-overrides> <x-overrides2 id="overrides2"></x-overrides2> <x-overrides3 id="overrides3"></x-overrides3> <div id="overridesConcrete">override concrete</div> <button id="button" is="x-button"></button> <div id="default1">default</div> <div id="default2">var default</div> <div id="default3">tricky property rgb(...) default</div> <x-has-def id="defaultElement1"></x-has-def> <x-has-def id="defaultElement2"></x-has-def> <div id="applyDefault1">default</div> <div id="applyDefault2">var default</div> <div id="calc">Calc</div> <div id="shadow">Shadow</div> <div id="invalid">invalid</div> <x-host-property id="hostProp"></x-host-property> <x-has-if id="iffy"></x-has-if> <div id="after"></div> <x-dynamic id="dynamic"></x-dynamic> <div id="wsTerm">new line var</div> <div id="endTerm">end var</div> <div id="parenthesis">parenthesis</div> <div id="nestedFallback"></div> <div id="doubleNestedFallback"></div> <div id="cornerFallback"></div> <div id="badFallback"></div> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-scope' }); }); </script> </dom-module> <dom-module id="x-inside"> <template> <style> :host { display: inline-block; border: var(--border) solid orange; height: 10px; width: 10px; background-color: tomato; } </style> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-inside' }); }); </script> </dom-module> <dom-module id="simple-element"> <template> <style> :host { display: block; } x-inside { color: var(--dne); --border: 10px; } </style> <x-inside id="inner"></x-inside> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'simple-element' }); }); </script> </dom-module> <dom-module id="x-variable-override"> <template> <style> :host { --b: 2px solid black; display: block; border: var(--b); } </style> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-variable-override' }); }); </script> </dom-module> <dom-module id="x-variable-consumer"> <template> <style> :host(.foo) { border: var(--consumer); } </style> test </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-variable-consumer' }); }); </script> </dom-module> <dom-module id="x-host-variable-consumer"> <template> <style> :host { --consumer: 2px solid orange; } .foo { display: block; /* should override */ border: 10px solid black; } </style> <x-variable-consumer id="consumer" class="foo"></x-variable-consumer> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-host-variable-consumer' }); }); </script> </dom-module> <dom-module id="x-var-produce-via-consume"> <template> <style> :host { display: block; border: 10px solid orange; --foo: var(--bar); } </style> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-var-produce-via-consume' }); }); </script> </dom-module> <dom-module id="x-non-media-matching"> <template> <style> @media (min-width: 100000px) { #inside { --consumer: 10px solid red; } } </style> <x-variable-consumer id="inside" class="foo"></x-variable-consumer> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-non-media-matching' }); }); </script> </dom-module> <dom-module id="x-non-media-matching-host"> <template> <style> @media (min-width: 100000px) { :host { --border: 10px solid red; } } :host { display: block; border: var(--border); } </style> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-non-media-matching-host' }); }); </script> </dom-module> <dom-module id="x-update-styles"> <template> <style> :host { --border: 10px solid red; } :host([active]) { --consumer: 6px solid orange; } :host { display: block; border: var(--border); } </style> <x-variable-consumer id="child" class="foo"></x-variable-consumer> </template> <script> HTMLImports.whenReady(function() { Polymer({ is: 'x-update-styles', properties: { active: { reflectToAttribute: true, observer: '_activeChanged' } }, _activeChanged: function() { this.updateStyles(); } }); }); </script> </dom-module> <script> suite('scoped-styling-var', function() { function assertComputed(element, value, pseudo, name) { // force a style-recalc for Safari missing updated CSS Custom Properties // https://bugs.webkit.org/show_bug.cgi?id=170708 element.offsetWidth; name = name || 'border-top-width'; var computed = element.getComputedStyleValue && !pseudo ? element.getComputedStyleValue(name) : getComputedStyle(element, pseudo)[name]; assert.equal(computed, value, 'computed style incorrect'); } function assertStylePropertyValue(element, name, includeValue) { var value = element.getComputedStyleValue(name); assert.include(value, includeValue); } var styled = document.querySelector('x-scope'); test('variables in @keyframes', function(done) { var xKeyframes = styled.$.keyframes; var onAnimationEnd = function() { assertStylePropertyValue(xKeyframes, 'left', '5px'); xKeyframes.removeEventListener('animationend', onAnimationEnd); xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd); xKeyframes.animated = false; done(); }; assertStylePropertyValue(xKeyframes, '--a', '10px'); assertStylePropertyValue(xKeyframes, '--b', '5px'); xKeyframes.addEventListener('animationend', onAnimationEnd); xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd); xKeyframes.animated = true; }); test('instances of scoped @keyframes', function(done) { if (navigator.userAgent.match(/Safari/) && ShadyCSS.nativeCss && ShadyCSS.nativeShadow) { // `:nth-of-type` is broken in shadow roots on Safari 10.1 // https://bugs.webkit.org/show_bug.cgi?id=166748 this.skip(); } var xKeyframes = styled.$.keyframes2; var onAnimationEnd = function() { assertStylePropertyValue(xKeyframes, 'left', '5px'); xKeyframes.removeEventListener('animationend', onAnimationEnd); xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd); xKeyframes.animated = false; done(); }; assertStylePropertyValue(xKeyframes, '--a', '10px'); assertStylePropertyValue(xKeyframes, '--b', '-5px'); xKeyframes.addEventListener('animationend', onAnimationEnd); xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd); xKeyframes.animated = true; }); test('multiple elements in document', function() { var e$ = document.querySelectorAll('simple-element'); assertComputed(e$[0].$.inner, '10px'); assertComputed(e$[1].$.inner, '10px'); }); test('simple variables calculated correctly between scopes', function() { assertStylePropertyValue(styled, '--scope-var', '1px'); // var child = styled.$.child; assertStylePropertyValue(child, '--scope-var', '1px'); assertStylePropertyValue(child, '--child-scope-var', '2px'); assertStylePropertyValue(child, '--grand-child-scope-var', '3px'); // var gc1 = child.$.gc1; assertStylePropertyValue(gc1, '--scope-var', '1px'); assertStylePropertyValue(gc1, '--child-scope-var', '2px'); assertStylePropertyValue(gc1, '--grand-child-scope-var', '3px'); // var gc2 = child.$.gc2; assertStylePropertyValue(gc2, '--scope-var', '1px'); assertStylePropertyValue(gc2, '--child-scope-var', '2px'); assertStylePropertyValue(gc2, '--grand-child-scope-var', '4px'); // var gc3 = child.$.gc3; assertStylePropertyValue(gc3, '--scope-var', '1px'); assertStylePropertyValue(gc3, '--child-scope-var', '2px'); assertStylePropertyValue(gc3, '--grand-child-scope-var', '3px'); }); test('invalid variables not parsed', function() { if (!window.ShadyCSS || ShadyCSS.nativeCss) { this.skip(); } assert.notOk(ShadyCSS.ScopingShim.getComputedStyleValue(styled, 'x--invalid')); assertComputed(styled.$.invalid, '0px'); }); test('simple variables applied correctly between scopes', function() { assertComputed(styled.$.me, '1px'); assertComputed(styled.$.child.$.me, '2px'); assertComputed(styled.$.child.$.gc1.$.me, '3px'); assertComputed(styled.$.child.$.gc1.$.scope, '1px'); assertComputed(styled.$.child.$.gc1.$.child, '2px'); assertComputed(styled.$.child.$.gc2.$.me, '4px'); assertComputed(styled.$.child.$.gc2.$.scope, '1px'); assertComputed(styled.$.child.$.gc2.$.child, '2px'); }); test('variable can be set to another variable', function() { var gc4 = styled.$.child.$.gc4; assertStylePropertyValue(gc4, '--grand-child-scope-var', '5px'); assertComputed(gc4.$.me, '5px'); }); test('variable default values can be assigned to other variables', function() { assertStylePropertyValue(styled, '--default1', '6px'); assertStylePropertyValue(styled, '--default2', '7px'); assertComputed(styled.$.default1, '6px'); assertComputed(styled.$.default2, '7px'); assertComputed(styled.$.applyDefault1, '6px'); assertComputed(styled.$.applyDefault2, '7px'); }); test('variable literal defaults can contain one (...)', function() { var b = getComputedStyle(styled.$.default3).backgroundColor; assert.match(b, /rgb\(128/, 'literal fallback containing (...) not set'); }); test('variable values can be used with calc', function() { assertComputed(styled.$.calc, '15px'); }); test('variable values can be used with box-shadow', function() { var b = getComputedStyle(styled.$.shadow).boxShadow; assert.match(b, /rgb\(128/, 'box shadow not set correctly'); }); test('host properties can be overridden with outer scope styles', function() { assertComputed(styled.$.hostProp, '10px'); }); test('updateStyles changes property values and using style cache', function() { styled.$.child.classList.add('special'); var l = document.querySelectorAll('style').length; styled.updateStyles(); if (styled.shadowRoot && window.ShadyCSS && !ShadyCSS.nativeCss) { assert.equal(document.querySelectorAll('style').length, l+4); } assertComputed(styled.$.child.$.me, '12px'); styled.$.child.classList.remove('special'); styled.updateStyles(); if (styled.shadowRoot && window.ShadyCSS && !ShadyCSS.nativeCss) { assert.equal(document.querySelectorAll('style').length, l); } assertComputed(styled.$.child.$.me, '2px'); }); test('Nested element uses style cache when attached and updateStyles is called', function() { var l = document.querySelectorAll('style').length; var e1 = document.createElement('x-produce-use-property'); document.body.appendChild(e1); var e1t = e1.$.hosted.$.hosted; var e2 = document.createElement('x-produce-use-property'); document.body.appendChild(e2); var e2t = e2.$.hosted.$.hosted; if (styled.shadowRoot && window.ShadyDOM) { assert.equal(document.querySelectorAll('style').length, l+1); } assertComputed(e1t, '6px'); assertComputed(e2t, '6px'); e1.updateStyles({'--scope-var': '8px solid purple'}); e2.updateStyles({'--scope-var': '8px solid purple'}); assertComputed(e1t, '8px'); assertComputed(e2t, '8px'); if (styled.shadowRoot && window.ShadyDOM) { assert.equal(document.querySelectorAll('style').length, l+1); } e1.updateStyles({'--scope-var': null}); e2.updateStyles({'--scope-var': null}); assertComputed(e1t, '6px'); assertComputed(e2t, '6px'); if (styled.shadowRoot && window.ShadyDOM) { assert.equal(document.querySelectorAll('style').length, l+1); } }); test('updateStyles with properties argument changes styles', function() { styled.$.child.updateStyles({'--child-scope-var': '26px solid seagreen'}); assertComputed(styled.$.child.$.me, '26px'); styled.$.child.updateStyles({'--child-scope-var': null}); assertComputed(styled.$.child.$.me, '2px'); }); test('updateStyles on when element when not attached', function() { var x = document.createElement('x-update-styles'); document.body.appendChild(x); assertComputed(x, '10px'); document.body.removeChild(x); x.updateStyles({'--border': '8px solid orange'}); document.body.appendChild(x); assertComputed(x, '8px'); }); test('updateStyles called in observer when element not attached', function() { var x = document.createElement('x-update-styles'); document.body.appendChild(x); assertComputed(x.$.child, '0px'); x.active = true; assertComputed(x.$.child, '6px'); x.active = false; assertComputed(x.$.child, '0px'); document.body.removeChild(x); x.active = true; // disable element's updateStyles to show that observer for `active`'s call to updateStyles // functions correctly. x.updateStyles = function(){}; document.body.appendChild(x); assertComputed(x.$.child, '6px'); }); test('styles update based on root customStyle changes', function() { assertComputed(styled.$.dynamic, '0px'); Polymer.updateStyles({'--dynamic': '4px solid navy'}); assertComputed(styled.$.dynamic, '4px'); Polymer.updateStyles({'--dynamic': '6px solid gray'}); assertComputed(styled.$.dynamic, '6px'); }); test('null customStyles unapply', function() { styled.$.dynamic.updateStyles({'--dynamic': '8px solid black'}); assertComputed(styled.$.dynamic, '8px'); styled.$.dynamic.updateStyles({'--dynamic': null}); assertComputed(styled.$.dynamic, '6px'); styled.$.dynamic.updateStyles({'--dynamic': '8px solid black'}); assertComputed(styled.$.dynamic, '8px'); styled.$.dynamic.updateStyles({'--dynamic': null}); assertComputed(styled.$.dynamic, '6px'); }); test('style properties with dom-if', function() { var e = styled.$.iffy; var c = Polymer.dom(e.root).querySelector('.iffy'); assert.ok(c, 'dom-if did not stamp'); assertComputed(c, '1px'); }); test('variable precedence and overrides', function() { // renamed property applied var o1a = styled.$.overrides1a; assertStylePropertyValue(o1a, '--rename', '8px'); assertStylePropertyValue(o1a, '--grand-child-scope-var', '8px'); assertComputed(o1a.$.gc1.$.me, '8px'); // :host property overridden by outer scope var o1b = styled.$.overrides1b; assertStylePropertyValue(o1b, '--rename', '8px'); assertStylePropertyValue(o1b, '--grand-child-scope-var', '9px'); assertComputed(o1b.$.gc1.$.me, '9px'); // own scope property overrides outer scope var o2 = styled.$.overrides2; assertStylePropertyValue(o2, '--rename', '8px'); assertStylePropertyValue(o2.$.gc1, '--grand-child-scope-var', '8px'); assertComputed(o2.$.gc1.$.me, '8px'); // late bound property does *not* resolve using inherited value var o3 = styled.$.overrides3; if (window.ShadyCSS && !ShadyCSS.nativeCss) { assert.equal(ShadyCSS.ScopingShim.getComputedStyleValue(o3, '--late'), '', 'property should not be late bound'); } assertStylePropertyValue(o3.$.late, '--fillin', '16px'); assertComputed(o3.$.late, '0px'); }); test('pseudo-elements can consume custom properties', function() { assertComputed(styled.$.after, '17px', '::after'); }); test('elements using only variable defaults are styled properly', function() { assertComputed(styled.$.defaultElement1, '22px'); assertComputed(styled.$.defaultElement2, '23px'); }); test('vars with trailing new line or } apply', function() { assertComputed(styled.$.wsTerm, '18px'); assertComputed(styled.$.endTerm, '19px'); }); test('variable with parenthesis', function() { var url = getComputedStyle(styled.$.parenthesis).backgroundImage.replace(/['"]/g, ''); assert.equal('url(http://placehold.it/400x300)', url); }); test('custom style class overrides css variable', function() { var d = document.createElement('x-variable-override'); d.classList.add('variable-override'); document.body.appendChild(d); assertComputed(d, '10px'); }); test('class selector overrides :host(class) property on element with only dynamic styles', function() { var d = document.createElement('x-host-variable-consumer'); document.body.appendChild(d); assertComputed(d.$.consumer, '10px'); }); test('var values can be overridden by subsequent concrete properties', function() { assertComputed(styled.$.overridesConcrete, '4px'); }); test('producing a var that consumes another var preserves static styling', function() { var d = document.createElement('x-var-produce-via-consume'); document.body.appendChild(d); assertComputed(d, '10px'); }); test('producing a var that consumes results in static and not dynamic stylesheet', function() { if (!window.ShadyCSS || ShadyCSS.nativeCss) { this.skip(); } var d = document.createElement('x-var-produce-via-consume'); document.body.appendChild(d); var styleRoot = (!window.ShadyCSS || ShadyCSS.nativeShadow) ? d.shadowRoot : document.head; var staticStyle = styleRoot.querySelector('style[scope=x-var-produce-via-consume]'); assert.ok(staticStyle); assert.match(staticStyle.textContent, /display/, 'static style does not contain style content'); assert.equal(styleRoot.querySelectorAll('style[scope~=x-var-produce-via-consume]').length, 1); }); test('Nested var fallback syntax', function() { assertComputed(styled.$.nestedFallback, '20px'); assertComputed(styled.$.doubleNestedFallback, '20px'); var url = getComputedStyle(styled.$.cornerFallback).backgroundImage.replace(/['"]/g, ''); assert.equal('url(http://placehold.it/400x300)', url); }); test('invalid @media rules do not match', function() { var e = document.createElement('x-non-media-matching'); document.body.appendChild(e); assertComputed(e.$.inside, '0px'); }); test('invalid @media rules do not match :host rule', function() { var e = document.createElement('x-non-media-matching-host'); document.body.appendChild(e); assertComputed(e, '0px'); }); }); </script> </body> </html>