mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
1091 lines
30 KiB
HTML
1091 lines
30 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-bundle.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>
|
|
<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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({is: 'x-overrides2'});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<dom-module id="x-late">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
border: var(--late);
|
|
display: block;
|
|
}
|
|
</style>
|
|
late
|
|
</template>
|
|
<script type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 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 {
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
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 type="module">
|
|
import { Polymer } from '../../polymer-legacy.js';
|
|
Polymer({
|
|
is: 'x-update-styles',
|
|
properties: {
|
|
active: {
|
|
reflectToAttribute: true,
|
|
observer: '_activeChanged'
|
|
}
|
|
},
|
|
|
|
_activeChanged: function() {
|
|
this.updateStyles();
|
|
}
|
|
});
|
|
</script>
|
|
</dom-module>
|
|
|
|
<script type="module">
|
|
import { updateStyles as updateStyles$0 } from '../../lib/mixins/element-mixin.js';
|
|
import { dom } from '../../lib/legacy/polymer.dom.js';
|
|
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\/60(3|4)/) && 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');
|
|
updateStyles$0({'--dynamic': '4px solid navy'});
|
|
assertComputed(styled.$.dynamic, '4px');
|
|
updateStyles$0({'--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 = 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>
|