mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
669 lines
17 KiB
HTML
669 lines
17 KiB
HTML
<!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="../../node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
|
|
<script src="wct-browser-config.js"></script>
|
|
<script src="../../node_modules/wct-browser-legacy/browser.js"></script>
|
|
<script type="module" src="../../polymer-legacy.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<x-scope></x-scope>
|
|
|
|
<dom-module id="story-card">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
}
|
|
|
|
#story-card .story-content {
|
|
font-family: 'Roboto', sans-serif;
|
|
font-size: 1.2em;
|
|
@apply --story-content;
|
|
}
|
|
</style>
|
|
|
|
<div id="story-card">
|
|
<div class="story-content" id="content">Content</div>
|
|
</div>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'story-card'});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-child-scope">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
|
|
--mixin2: {
|
|
border: 3px solid seagreen;
|
|
background: url(http://www.google.com/icon.png);
|
|
};
|
|
}
|
|
|
|
#mixin1 {
|
|
@apply --mixin1;
|
|
}
|
|
|
|
#mixin2 {
|
|
@apply --mixin2;
|
|
}
|
|
|
|
#mixin3 {
|
|
padding: 3px;
|
|
@apply --mixin3;
|
|
}
|
|
|
|
#mixin4 {
|
|
@apply --mixin4;
|
|
}
|
|
|
|
#mixin6 {
|
|
@apply --mixin6
|
|
}
|
|
|
|
#mixin7 {@apply --mixin7}
|
|
|
|
#mixin8 {
|
|
@apply --mixin8
|
|
}
|
|
|
|
#mixin9 {
|
|
@apply --mixin9
|
|
}
|
|
</style>
|
|
|
|
<div id="mixin1">mixin1</div>
|
|
<div id="mixin2">mixin2</div>
|
|
<div id="mixin3">mixin3</div>
|
|
<div id="mixin4">mixin4</div>
|
|
<div id="mixin6">mixin6</div>
|
|
<div id="mixin7">mixin7</div>
|
|
<div id="mixin8">mixin8</div>
|
|
<div id="mixin9">mixin9</div>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'x-child-scope'});
|
|
</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(--c1);
|
|
}
|
|
|
|
100% {
|
|
left: var(--c2);
|
|
@apply --keyframe-finish;
|
|
}
|
|
}
|
|
@keyframes x-keyframes-animation {
|
|
0% {
|
|
left: var(--c1);
|
|
}
|
|
|
|
100% {
|
|
left: var(--c2);
|
|
@apply --keyframe-finish;
|
|
}
|
|
}
|
|
</style>
|
|
x-keyframes
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-keyframes',
|
|
properties: {
|
|
animated: {
|
|
type: Boolean,
|
|
value: false,
|
|
reflectToAttribute: true
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-scope">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
padding: 8px;
|
|
|
|
--override-me: {
|
|
border: 11px solid black;
|
|
};
|
|
|
|
--mixin1: {
|
|
border: 1px solid black;
|
|
};
|
|
|
|
--b: 2px solid orange;
|
|
|
|
--m1: 1px;
|
|
--m2: 2px;
|
|
|
|
--c1: 5px;
|
|
--c2: 10px;
|
|
|
|
--mixin2: {
|
|
border: var(--b);
|
|
};
|
|
|
|
--mixin3: {
|
|
@apply --mixin2;
|
|
};
|
|
|
|
--mixin4: {
|
|
padding: 2px;
|
|
@apply --mixin3;
|
|
margin: var(--m2);
|
|
};
|
|
|
|
--mixin5: {
|
|
border: calc(var(--c1) + var(--c2)) solid orange;
|
|
};
|
|
|
|
--mixin6: {
|
|
border: 16px solid orange;
|
|
};
|
|
|
|
--mixin7: {
|
|
border: 17px solid navy;
|
|
};
|
|
|
|
--mixin8: {
|
|
border: 17px dotted navy;
|
|
};
|
|
|
|
--mixin9: var(--mixin8);
|
|
}
|
|
|
|
#mixin1 {
|
|
@apply --mixin1;
|
|
}
|
|
|
|
#mixin2 {
|
|
@apply --mixin2;
|
|
}
|
|
|
|
#mixin3 {
|
|
padding: 1px;
|
|
margin: var(--m1);
|
|
@apply --mixin3;
|
|
}
|
|
|
|
#mixin4 {
|
|
@apply --mixin4;
|
|
}
|
|
|
|
#mixin5 {
|
|
@apply --mixin5;
|
|
}
|
|
|
|
#keyframes2 {
|
|
--keyframe-finish: {
|
|
left: 20px;
|
|
};
|
|
}
|
|
|
|
x-child-scope {
|
|
padding: 10px;
|
|
}
|
|
|
|
#card {
|
|
--story-content: {
|
|
border: 11px solid orange;
|
|
};
|
|
}
|
|
|
|
#override {
|
|
@apply --override-me;
|
|
border: 19px solid steelblue;
|
|
}
|
|
|
|
</style>
|
|
|
|
<div id="mixin1">mixin1</div>
|
|
<div id="mixin2">mixin2</div>
|
|
<div id="mixin3">mixin3</div>
|
|
<div id="mixin4">mixin4</div>
|
|
<div id="mixin5">mixin5</div>
|
|
<hr>
|
|
<x-keyframes id="keyframes1"></x-keyframes>
|
|
<x-keyframes id="keyframes2"></x-keyframes>
|
|
<x-child-scope id="child"></x-child-scope>
|
|
<story-card id="card"></story-card>
|
|
<div id="override">override</div>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'x-scope'});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-var-produce-via-consume">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
border: 10px solid orange;
|
|
--foo: {
|
|
color: var(--bar);
|
|
}
|
|
}
|
|
</style>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-var-produce-via-consume'
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-cache-child">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
color: var(--foo);
|
|
@apply --bar;
|
|
}
|
|
</style>
|
|
X
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-cache-child'
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-cache-host-1">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
--foo: blue;
|
|
--bar: {
|
|
border: 10px solid black;
|
|
};
|
|
}
|
|
</style>
|
|
<x-cache-child id="child"></x-bad-child>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-cache-host-1'
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-cache-host-2">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
--foo: blue;
|
|
--bar: {
|
|
border: 1px dotted green;
|
|
};
|
|
}
|
|
</style>
|
|
<x-cache-child id="child"></x-bad-child>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-cache-host-2'
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-no-paren-apply-only">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
--bar: {
|
|
border: 2px solid green;
|
|
}
|
|
}
|
|
#child {
|
|
@apply --bar;
|
|
}
|
|
</style>
|
|
<div id="child">X</div>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-no-paren-apply-only'
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-redefine-three">
|
|
<template>
|
|
<style>
|
|
div {
|
|
@apply --redefine;
|
|
}
|
|
</style>
|
|
<div id="div"></div>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'x-redefine-three'});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-redefine-two">
|
|
<template>
|
|
<style>
|
|
x-redefine-three {
|
|
--redefine: {
|
|
border: 2px solid gray;
|
|
};
|
|
}
|
|
</style>
|
|
<x-redefine-three id="three"></x-redefine-three>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'x-redefine-two'});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-redefine-one">
|
|
<template>
|
|
<style>
|
|
x-redefine-two {
|
|
--redefine: {
|
|
height: 100px;
|
|
width: 100px;
|
|
};
|
|
}
|
|
</style>
|
|
<x-redefine-two id="two"></x-redefine-two>
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'x-redefine-one'});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="order-child">
|
|
<template>
|
|
<style>
|
|
div {
|
|
@apply --order-mixin;
|
|
}
|
|
</style>
|
|
<div id="target"></div>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<dom-module id="order-parent">
|
|
<template>
|
|
<style>
|
|
order-child {
|
|
--order-mixin: {
|
|
border: 10px solid black;
|
|
};
|
|
}
|
|
</style>
|
|
<order-child id="child"></order-child>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<dom-module id="order-gp">
|
|
<template>
|
|
<style>
|
|
order-child {
|
|
--order-mixin: {
|
|
};
|
|
}
|
|
</style>
|
|
<order-child id="child"></order-child>
|
|
<order-parent id="parent"></order-parent>
|
|
</template>
|
|
</dom-module>
|
|
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'order-child'});
|
|
Polymer({is: 'order-parent'});
|
|
Polymer({is: 'order-gp'});
|
|
</script>
|
|
<script type="module">
|
|
import { flush } from '../../lib/utils/flush.js';
|
|
suite('scoped-styling-apply', function() {
|
|
function assertComputed(element, value, property) {
|
|
var computed = getComputedStyle(element);
|
|
property = property || 'border-top-width';
|
|
assert.equal(computed[property], value, 'computed style incorrect for ' + property);
|
|
}
|
|
|
|
var styled = document.querySelector('x-scope');
|
|
|
|
test('variable mixins calculated correctly and inherit', function() {
|
|
if (!window.ShadyCSS || ShadyCSS.nativeCss) {
|
|
this.skip();
|
|
}
|
|
var suffix = window.ShadyCSS.ApplyShim._separator + 'border';
|
|
var e = styled;
|
|
let mixin1 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin1' + suffix);
|
|
let mixin2 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin2' + suffix);
|
|
let mixin3 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin3' + suffix);
|
|
let mixin4 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin4' + suffix);
|
|
e = styled.$.child;
|
|
let cmixin1 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin1' + suffix);
|
|
let cmixin2 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin2' + suffix);
|
|
let cmixin3 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin3' + suffix);
|
|
let cmixin4 = ShadyCSS.ScopingShim.getComputedStyleValue(e, '--mixin4' + suffix);
|
|
assert.equal(mixin1, cmixin1);
|
|
assert.equal(mixin2, cmixin2);
|
|
assert.equal(mixin3, cmixin3);
|
|
assert.equal(mixin4, cmixin4);
|
|
});
|
|
|
|
test('variable mixins apply', function() {
|
|
assertComputed(styled.$.mixin1, '1px');
|
|
assertComputed(styled.$.mixin2, '2px');
|
|
assertComputed(styled.$.mixin3, '2px');
|
|
assertComputed(styled.$.mixin3, '1px', 'padding-top');
|
|
assertComputed(styled.$.mixin3, '1px', 'margin-top');
|
|
assertComputed(styled.$.mixin4, '2px');
|
|
assertComputed(styled.$.mixin4, '2px', 'padding-top');
|
|
assertComputed(styled.$.mixin4, '2px', 'margin-top');
|
|
});
|
|
|
|
test('mixins apply with url values', function() {
|
|
var url = 'http://www.google.com/icon.png';
|
|
var e = styled.$.child;
|
|
var actual, unescaped, propertyName;
|
|
if (window.ShadyCSS && ShadyCSS.nativeCssApply) {
|
|
actual = getComputedStyle(e).getPropertyValue('--mixin2');
|
|
// if strings aren't used in the url, getPropertyValue will escape the string, which breaks assert.include
|
|
unescaped = actual.replace(/\\/g, '');
|
|
assert.include(unescaped, url);
|
|
} else if (!window.ShadyCSS || ShadyCSS.nativeCss) {
|
|
propertyName = '--mixin2' + window.ShadyCSS.ApplyShim._separator + 'background';
|
|
actual = getComputedStyle(e).getPropertyValue(propertyName);
|
|
// if strings aren't used in the url, getPropertyValue will escape the string, which breaks assert.include
|
|
unescaped = actual.replace(/\\/g, '');
|
|
assert.include(unescaped, url);
|
|
} else {
|
|
propertyName = '--mixin2';
|
|
actual = ShadyCSS.ScopingShim.getComputedStyleValue(e, propertyName);
|
|
unescaped = actual.replace(/\\/g, '');
|
|
assert.include(unescaped, url);
|
|
}
|
|
});
|
|
|
|
test('variable mixins inherit and override', function() {
|
|
var e = styled.$.child;
|
|
assertComputed(e.$.mixin1, '1px');
|
|
assertComputed(e.$.mixin2, '3px');
|
|
assertComputed(e.$.mixin3, '2px');
|
|
assertComputed(e.$.mixin3, '3px', 'padding-top');
|
|
assertComputed(e.$.mixin4, '2px');
|
|
assertComputed(e.$.mixin4, '2px', 'padding-top');
|
|
assertComputed(e.$.mixin4, '2px', 'margin-top');
|
|
});
|
|
|
|
test('calc can be used in mixins', function() {
|
|
assertComputed(styled.$.mixin5, '15px');
|
|
});
|
|
|
|
test('mixins work with selectors that contain element name', function() {
|
|
assertComputed(styled.$.card.$.content, '11px');
|
|
});
|
|
|
|
test('mixins with trailing new line or } apply', function() {
|
|
assertComputed(styled.$.child.$.mixin6, '16px');
|
|
assertComputed(styled.$.child.$.mixin7, '17px');
|
|
});
|
|
|
|
test('mixins with new `@apply --foo` syntax', function() {
|
|
assertComputed(styled.$.child.$.mixin8, '17px');
|
|
});
|
|
|
|
test('mixins can be realiased with var()', function() {
|
|
assertComputed(styled.$.child.$.mixin9, '17px');
|
|
});
|
|
|
|
test('mixins apply to @keyframe rules', function(done) {
|
|
if (navigator.userAgent.match('Edge/16') && (!window.ShadyCSS || window.ShadyCSS.nativeCss)) {
|
|
// skip test due to missing variable support in keyframes
|
|
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12084341/
|
|
this.skip();
|
|
}
|
|
var xKeyframes1 = styled.$.keyframes1;
|
|
var xKeyframes2 = styled.$.keyframes2;
|
|
var completed = 0;
|
|
|
|
[xKeyframes1, xKeyframes2].forEach(function(xKeyframes, index) {
|
|
var target = index === 0 ? '10px' : '20px';
|
|
var onAnimationEnd = function() {
|
|
assert.include(xKeyframes.getComputedStyleValue('left'), target, xKeyframes.id);
|
|
|
|
xKeyframes.removeEventListener('animationend', onAnimationEnd);
|
|
xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
|
|
xKeyframes.animated = false;
|
|
if (++completed > 1) {
|
|
done();
|
|
}
|
|
};
|
|
|
|
xKeyframes.addEventListener('animationend', onAnimationEnd);
|
|
xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);
|
|
|
|
xKeyframes.animated = true;
|
|
});
|
|
});
|
|
|
|
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() {
|
|
var d = document.createElement('x-var-produce-via-consume');
|
|
document.body.appendChild(d);
|
|
var styleRoot = (!window.ShadyDOM || !ShadyDOM.isShadyRoot(d.shadowRoot)) ? d.shadowRoot : document.head;
|
|
var selector = window.ShadyDOM ? 'style[scope~=x-var-produce-via-consume]' : 'style';
|
|
var staticStyle = styleRoot.querySelector(selector);
|
|
assert.ok(staticStyle);
|
|
assert.match(staticStyle.textContent, /display/, 'static style does not contain style content');
|
|
assert.equal(styleRoot.querySelectorAll(selector).length, 1);
|
|
});
|
|
|
|
test('mixin values can be overridden by subsequent concrete properties', function() {
|
|
assertComputed(styled.$.override, '19px');
|
|
});
|
|
|
|
test('@apply without parens is included in style cache behavior', function() {
|
|
var e1 = document.createElement('x-cache-host-1');
|
|
var e2 = document.createElement('x-cache-host-2');
|
|
document.body.appendChild(e1);
|
|
document.body.appendChild(e2);
|
|
flush();
|
|
assertComputed(e1.$.child, '10px');
|
|
assertComputed(e2.$.child, '1px');
|
|
});
|
|
|
|
test('@apply without parens triggers property shim', function() {
|
|
var e = document.createElement('x-no-paren-apply-only');
|
|
document.body.appendChild(e);
|
|
flush();
|
|
assertComputed(e.$.child, '2px');
|
|
});
|
|
|
|
test('mixin redefinition resets old properties', function() {
|
|
var e = document.createElement('x-redefine-one');
|
|
document.body.appendChild(e);
|
|
flush();
|
|
var div = e.$.two.$.three.$.div;
|
|
assertComputed(div, '2px');
|
|
assertComputed(div, '0px', 'height');
|
|
});
|
|
|
|
test('mixin redefinition applies to complicated hierarchies', function() {
|
|
var e = document.createElement('order-gp');
|
|
document.body.appendChild(e);
|
|
flush();
|
|
var childDiv = e.$.child.$.target;
|
|
var parentDiv = e.$.parent.$.child.$.target;
|
|
assertComputed(childDiv, '0px');
|
|
assertComputed(parentDiv, '10px');
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|