mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3163 from Polymer/allow-keyframe-style-transformation
Non-destructive `@keyframes` rule transformation.
This commit is contained in:
commit
9968266e74
@ -73,6 +73,8 @@ Polymer.CssParse = (function() {
|
|||||||
node.type = this.types.MEDIA_RULE;
|
node.type = this.types.MEDIA_RULE;
|
||||||
} else if (s.match(this._rx.keyframesRule)) {
|
} else if (s.match(this._rx.keyframesRule)) {
|
||||||
node.type = this.types.KEYFRAMES_RULE;
|
node.type = this.types.KEYFRAMES_RULE;
|
||||||
|
node.keyframesName =
|
||||||
|
node.selector.split(this._rx.multipleSpaces).pop();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (s.indexOf(this.VAR_START) === 0) {
|
if (s.indexOf(this.VAR_START) === 0) {
|
||||||
|
@ -139,7 +139,7 @@ Note, all features of `custom-style` are available when defining styles as part
|
|||||||
e.textContent;
|
e.textContent;
|
||||||
}
|
}
|
||||||
if (e.textContent) {
|
if (e.textContent) {
|
||||||
styleUtil.forEachStyleRule(styleUtil.rulesForStyle(e), function(rule) {
|
styleUtil.forEachRule(styleUtil.rulesForStyle(e), function(rule) {
|
||||||
styleTransformer.documentRule(rule);
|
styleTransformer.documentRule(rule);
|
||||||
});
|
});
|
||||||
// Allow all custom-styles defined in this turn to register
|
// Allow all custom-styles defined in this turn to register
|
||||||
|
@ -24,7 +24,7 @@ Polymer.StyleExtends = (function() {
|
|||||||
transform: function(style) {
|
transform: function(style) {
|
||||||
var rules = styleUtil.rulesForStyle(style);
|
var rules = styleUtil.rulesForStyle(style);
|
||||||
var self = this;
|
var self = this;
|
||||||
styleUtil.forEachStyleRule(rules, function(rule) {
|
styleUtil.forEachRule(rules, function(rule) {
|
||||||
var map = self._mapRule(rule);
|
var map = self._mapRule(rule);
|
||||||
if (rule.parent) {
|
if (rule.parent) {
|
||||||
var m;
|
var m;
|
||||||
|
@ -25,11 +25,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
// decorates styles with rule info and returns an array of used style
|
// decorates styles with rule info and returns an array of used style
|
||||||
// property names
|
// property names
|
||||||
decorateStyles: function(styles) {
|
decorateStyles: function(styles) {
|
||||||
var self = this, props = {};
|
var self = this, props = {}, keyframes = [];
|
||||||
styleUtil.forRulesInStyles(styles, function(rule) {
|
styleUtil.forRulesInStyles(styles, function(rule) {
|
||||||
self.decorateRule(rule);
|
self.decorateRule(rule);
|
||||||
self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
|
self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
|
||||||
|
}, function onKeyframesRule(rule) {
|
||||||
|
keyframes.push(rule);
|
||||||
});
|
});
|
||||||
|
// Cache all found keyframes rules for later reference:
|
||||||
|
styles._keyframes = keyframes;
|
||||||
// return this list of property names *consumes* in these styles.
|
// return this list of property names *consumes* in these styles.
|
||||||
var names = [];
|
var names = [];
|
||||||
for (var i in props) {
|
for (var i in props) {
|
||||||
@ -87,7 +91,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
var parts = cssText.split(';');
|
var parts = cssText.split(';');
|
||||||
for (var i=0, p; i<parts.length; i++) {
|
for (var i=0, p; i<parts.length; i++) {
|
||||||
p = parts[i];
|
p = parts[i];
|
||||||
if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {
|
if (p.match(this.rx.MIXIN_MATCH) ||
|
||||||
|
p.match(this.rx.VAR_MATCH) ||
|
||||||
|
this.rx.ANIMATION_MATCH.test(p) ||
|
||||||
|
styleUtil.isKeyframesSelector(rule)) {
|
||||||
customCssText += p + ';\n';
|
customCssText += p + ';\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,6 +188,46 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
rule.cssText = output;
|
rule.cssText = output;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Apply keyframe transformations to the cssText of a given rule. The
|
||||||
|
// keyframeTransforms object is a map of keyframe names to transformer
|
||||||
|
// functions which take in cssText and spit out transformed cssText.
|
||||||
|
applyKeyframeTransforms: function(rule, keyframeTransforms) {
|
||||||
|
var input = rule.cssText;
|
||||||
|
var output = rule.cssText;
|
||||||
|
if (rule.hasAnimations == null) {
|
||||||
|
// Cache whether or not the rule has any animations to begin with:
|
||||||
|
rule.hasAnimations = this.rx.ANIMATION_MATCH.test(input);
|
||||||
|
}
|
||||||
|
// If there are no animations referenced, we can skip transforms:
|
||||||
|
if (rule.hasAnimations) {
|
||||||
|
var transform;
|
||||||
|
// If we haven't transformed this rule before, we iterate over all
|
||||||
|
// transforms:
|
||||||
|
if (rule.keyframeNamesToTransform == null) {
|
||||||
|
rule.keyframeNamesToTransform = [];
|
||||||
|
for (var keyframe in keyframeTransforms) {
|
||||||
|
transform = keyframeTransforms[keyframe];
|
||||||
|
output = transform(input);
|
||||||
|
// If the transform actually changed the CSS text, we cache the
|
||||||
|
// transform name for future use:
|
||||||
|
if (input !== output) {
|
||||||
|
input = output;
|
||||||
|
rule.keyframeNamesToTransform.push(keyframe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we already have a list of keyframe names that apply to this
|
||||||
|
// rule, we apply only those keyframe name transforms:
|
||||||
|
for (var i = 0; i < rule.keyframeNamesToTransform.length; ++i) {
|
||||||
|
transform = keyframeTransforms[rule.keyframeNamesToTransform[i]];
|
||||||
|
input = transform(input);
|
||||||
|
}
|
||||||
|
output = input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rule.cssText = output;
|
||||||
|
},
|
||||||
|
|
||||||
// Test if the rules in these styles matches the given `element` and if so,
|
// Test if the rules in these styles matches the given `element` and if so,
|
||||||
// collect any custom properties into `props`.
|
// collect any custom properties into `props`.
|
||||||
propertyDataFromStyles: function(styles, element) {
|
propertyDataFromStyles: function(styles, element) {
|
||||||
@ -256,15 +303,60 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
hostSelector;
|
hostSelector;
|
||||||
var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector +
|
var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector +
|
||||||
this.rx.HOST_SUFFIX);
|
this.rx.HOST_SUFFIX);
|
||||||
|
var keyframeTransforms =
|
||||||
|
this._elementKeyframeTransforms(element, scopeSelector);
|
||||||
return styleTransformer.elementStyles(element, function(rule) {
|
return styleTransformer.elementStyles(element, function(rule) {
|
||||||
self.applyProperties(rule, properties);
|
self.applyProperties(rule, properties);
|
||||||
if (rule.cssText && !nativeShadow) {
|
if (!nativeShadow &&
|
||||||
|
!Polymer.StyleUtil.isKeyframesSelector(rule) &&
|
||||||
|
rule.cssText) {
|
||||||
|
// NOTE: keyframe transforms only scope munge animation names, so it
|
||||||
|
// is not necessary to apply them in ShadowDOM.
|
||||||
|
self.applyKeyframeTransforms(rule, keyframeTransforms);
|
||||||
self._scopeSelector(rule, hostRx, hostSelector,
|
self._scopeSelector(rule, hostRx, hostSelector,
|
||||||
element._scopeCssViaAttr, scopeSelector);
|
element._scopeCssViaAttr, scopeSelector);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_elementKeyframeTransforms: function(element, scopeSelector) {
|
||||||
|
var keyframesRules = element._styles._keyframes;
|
||||||
|
var keyframeTransforms = {};
|
||||||
|
if (!nativeShadow) {
|
||||||
|
// For non-ShadowDOM, we transform all known keyframes rules in
|
||||||
|
// advance for the current scope. This allows us to catch keyframes
|
||||||
|
// rules that appear anywhere in the stylesheet:
|
||||||
|
for (var i = 0, keyframesRule = keyframesRules[i];
|
||||||
|
i < keyframesRules.length;
|
||||||
|
keyframesRule = keyframesRules[++i]) {
|
||||||
|
this._scopeKeyframes(keyframesRule, scopeSelector);
|
||||||
|
keyframeTransforms[keyframesRule.keyframesName] =
|
||||||
|
this._keyframesRuleTransformer(keyframesRule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keyframeTransforms;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Generate a factory for transforming a chunk of CSS text to handle a
|
||||||
|
// particular scoped keyframes rule.
|
||||||
|
_keyframesRuleTransformer: function(keyframesRule) {
|
||||||
|
return function(cssText) {
|
||||||
|
return cssText.replace(
|
||||||
|
keyframesRule.keyframesNameRx,
|
||||||
|
keyframesRule.transformedKeyframesName);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Transforms `@keyframes` names to be unique for the current host.
|
||||||
|
// Example: @keyframes foo-anim -> @keyframes foo-anim-x-foo-0
|
||||||
|
_scopeKeyframes: function(rule, scopeId) {
|
||||||
|
rule.keyframesNameRx = new RegExp(rule.keyframesName, 'g');
|
||||||
|
rule.transformedKeyframesName = rule.keyframesName + '-' + scopeId;
|
||||||
|
rule.transformedSelector = rule.transformedSelector || rule.selector;
|
||||||
|
rule.selector = rule.transformedSelector.replace(
|
||||||
|
rule.keyframesName, rule.transformedKeyframesName);
|
||||||
|
},
|
||||||
|
|
||||||
// Strategy: x scope shim a selector e.g. to scope `.x-foo-42` (via classes):
|
// Strategy: x scope shim a selector e.g. to scope `.x-foo-42` (via classes):
|
||||||
// non-host selector: .a.x-foo -> .x-foo-42 .a.x-foo
|
// non-host selector: .a.x-foo -> .x-foo-42 .a.x-foo
|
||||||
// host selector: x-foo.wide -> x-foo.x-foo-42.wide
|
// host selector: x-foo.wide -> x-foo.x-foo-42.wide
|
||||||
@ -359,6 +451,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
// var(--a, fallback-literal(with-one-nested-parentheses))
|
// var(--a, fallback-literal(with-one-nested-parentheses))
|
||||||
VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi,
|
VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi,
|
||||||
VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
|
VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
|
||||||
|
ANIMATION_MATCH: /(animation\s*:)|(animation-name\s*:)/,
|
||||||
IS_VAR: /^--/,
|
IS_VAR: /^--/,
|
||||||
BRACKETED: /\{[^}]*\}/g,
|
BRACKETED: /\{[^}]*\}/g,
|
||||||
HOST_PREFIX: '(?:^|[^.#[:])',
|
HOST_PREFIX: '(?:^|[^.#[:])',
|
||||||
|
@ -146,8 +146,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
// transforms a css rule to a scoped rule.
|
// transforms a css rule to a scoped rule.
|
||||||
_transformRule: function(rule, transformer, scope, hostScope) {
|
_transformRule: function(rule, transformer, scope, hostScope) {
|
||||||
var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
|
var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
|
||||||
for (var i=0, l=p$.length, p; (i<l) && (p=p$[i]); i++) {
|
// we want to skip transformation of rules that appear in keyframes,
|
||||||
p$[i] = transformer.call(this, p, scope, hostScope);
|
// because they are keyframe selectors, not element selectors.
|
||||||
|
if (!styleUtil.isKeyframesSelector(rule)) {
|
||||||
|
for (var i=0, l=p$.length, p; (i<l) && (p=p$[i]); i++) {
|
||||||
|
p$[i] = transformer.call(this, p, scope, hostScope);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// NOTE: save transformedSelector for subsequent matching of elements
|
// NOTE: save transformedSelector for subsequent matching of elements
|
||||||
// against selectors (e.g. when calculating style properties)
|
// against selectors (e.g. when calculating style properties)
|
||||||
|
@ -24,15 +24,18 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
rules = this.parser.parse(rules);
|
rules = this.parser.parse(rules);
|
||||||
}
|
}
|
||||||
if (callback) {
|
if (callback) {
|
||||||
this.forEachStyleRule(rules, callback);
|
this.forEachRule(rules, callback);
|
||||||
}
|
}
|
||||||
return this.parser.stringify(rules, preserveProperties);
|
return this.parser.stringify(rules, preserveProperties);
|
||||||
},
|
},
|
||||||
|
|
||||||
forRulesInStyles: function(styles, callback) {
|
forRulesInStyles: function(styles, styleRuleCallback, keyframesRuleCallback) {
|
||||||
if (styles) {
|
if (styles) {
|
||||||
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
|
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
|
||||||
this.forEachStyleRule(this.rulesForStyle(s), callback);
|
this.forEachRule(
|
||||||
|
this.rulesForStyle(s),
|
||||||
|
styleRuleCallback,
|
||||||
|
keyframesRuleCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -44,21 +47,31 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
return style.__cssRules;
|
return style.__cssRules;
|
||||||
},
|
},
|
||||||
|
|
||||||
forEachStyleRule: function(node, callback) {
|
// Tests if a rule is a keyframes selector, which looks almost exactly
|
||||||
|
// like a normal selector but is not (it has nothing to do with scoping
|
||||||
|
// for example).
|
||||||
|
isKeyframesSelector: function(rule) {
|
||||||
|
return rule.parent &&
|
||||||
|
rule.parent.type === this.ruleTypes.KEYFRAMES_RULE;
|
||||||
|
},
|
||||||
|
|
||||||
|
forEachRule: function(node, styleRuleCallback, keyframesRuleCallback) {
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var skipRules = false;
|
var skipRules = false;
|
||||||
if (node.type === this.ruleTypes.STYLE_RULE) {
|
if (node.type === this.ruleTypes.STYLE_RULE) {
|
||||||
callback(node);
|
styleRuleCallback(node);
|
||||||
} else if (node.type === this.ruleTypes.KEYFRAMES_RULE ||
|
} else if (keyframesRuleCallback &&
|
||||||
node.type === this.ruleTypes.MIXIN_RULE) {
|
node.type === this.ruleTypes.KEYFRAMES_RULE) {
|
||||||
|
keyframesRuleCallback(node);
|
||||||
|
} else if (node.type === this.ruleTypes.MIXIN_RULE) {
|
||||||
skipRules = true;
|
skipRules = true;
|
||||||
}
|
}
|
||||||
var r$ = node.rules;
|
var r$ = node.rules;
|
||||||
if (r$ && !skipRules) {
|
if (r$ && !skipRules) {
|
||||||
for (var i=0, l=r$.length, r; (i<l) && (r=r$[i]); i++) {
|
for (var i=0, l=r$.length, r; (i<l) && (r=r$[i]); i++) {
|
||||||
this.forEachStyleRule(r, callback);
|
this.forEachRule(r, styleRuleCallback, keyframesRuleCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
60
test/smoke/keyframes.html
Normal file
60
test/smoke/keyframes.html
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<!--
|
||||||
|
@license
|
||||||
|
Copyright (c) 2014 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
|
||||||
|
-->
|
||||||
|
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
|
||||||
|
<link rel="import" href="../../polymer.html">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<style is="custom-style">
|
||||||
|
:root {
|
||||||
|
--color: blue;
|
||||||
|
--anim-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alternative {
|
||||||
|
--color: green;
|
||||||
|
--anim-color: blue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<dom-module id="test-keyframes">
|
||||||
|
<template><style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
color: var(--color);
|
||||||
|
animation: foo 3s;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes foo {
|
||||||
|
0% {
|
||||||
|
background: var(--anim-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style><content></content></template>
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'test-keyframes'
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<p>Text should be the color blue. Background should animate from the color red to the color yellow, and then become transparent.</p>
|
||||||
|
<test-keyframes>red</test-keyframes>
|
||||||
|
|
||||||
|
<p>Text should be the color green. Background should animate from the color blue to the color yellow, and then become transparent.</p>
|
||||||
|
<test-keyframes class="alternative">blue</test-keyframes>
|
||||||
|
|
||||||
|
</body>
|
@ -95,6 +95,67 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</script>
|
</script>
|
||||||
</dom-module>
|
</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>
|
||||||
|
HTMLImports.whenReady(function() {
|
||||||
|
Polymer({
|
||||||
|
is: 'x-keyframes',
|
||||||
|
properties: {
|
||||||
|
animated: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
reflectToAttribute: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-scope">
|
<dom-module id="x-scope">
|
||||||
<style>
|
<style>
|
||||||
:host {
|
:host {
|
||||||
@ -165,6 +226,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
@apply(--mixin5);
|
@apply(--mixin5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#keyframes2 {
|
||||||
|
--keyframe-finish: {
|
||||||
|
left: 20px;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
x-child-scope {
|
x-child-scope {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
@ -189,6 +256,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
<div id="mixin4">mixin4</div>
|
<div id="mixin4">mixin4</div>
|
||||||
<div id="mixin5">mixin5</div>
|
<div id="mixin5">mixin5</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
<x-keyframes id="keyframes1"></x-keyframes>
|
||||||
|
<x-keyframes id="keyframes2"></x-keyframes>
|
||||||
<x-child-scope id="child"></x-child-scope>
|
<x-child-scope id="child"></x-child-scope>
|
||||||
<story-card id="card"></story-card>
|
<story-card id="card"></story-card>
|
||||||
<div id="override">override</div>
|
<div id="override">override</div>
|
||||||
@ -267,6 +336,31 @@ suite('scoped-styling-apply', function() {
|
|||||||
assertComputed(styled.$.child.$.mixin7, '17px');
|
assertComputed(styled.$.child.$.mixin7, '17px');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('mixins apply to @keyframe rules', function(done) {
|
||||||
|
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.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;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// TODO(sorvell): fix for #1761 was reverted; include test once this issue is addressed
|
// TODO(sorvell): fix for #1761 was reverted; include test once this issue is addressed
|
||||||
// test('mixin values can be overridden by subsequent concrete properties', function() {
|
// test('mixin values can be overridden by subsequent concrete properties', function() {
|
||||||
// assertComputed(styled.$.override, '19px');
|
// assertComputed(styled.$.override, '19px');
|
||||||
|
@ -23,27 +23,26 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
<x-scope></x-scope>
|
<x-scope></x-scope>
|
||||||
|
|
||||||
<dom-module id="x-grand-child-scope">
|
<dom-module id="x-grand-child-scope">
|
||||||
<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>
|
|
||||||
|
|
||||||
<template>
|
<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="me">x-grand-child-scope</div>
|
||||||
<div id="scope">From x-scope</div>
|
<div id="scope">From x-scope</div>
|
||||||
<div id="child">From x-child-scope</div>
|
<div id="child">From x-child-scope</div>
|
||||||
@ -56,15 +55,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-host-property">
|
<dom-module id="x-host-property">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
padding: 8px;
|
|
||||||
border: var(--scope-var);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
padding: 8px;
|
||||||
|
border: var(--scope-var);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Host property
|
Host property
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -75,31 +73,30 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-child-scope">
|
<dom-module id="x-child-scope">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
padding: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--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>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--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>
|
<div id="me">x-child-scope</div>
|
||||||
<x-grand-child-scope id="gc1"></x-grand-child-scope>
|
<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="gc2"></x-grand-child-scope>
|
||||||
@ -114,17 +111,16 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-overrides">
|
<dom-module id="x-overrides">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
border: 1px dashed gray;
|
|
||||||
margin: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
display: block;
|
|
||||||
--grand-child-scope-var: var(--rename);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
border: 1px dashed gray;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
display: block;
|
||||||
|
--grand-child-scope-var: var(--rename);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
overrides:
|
overrides:
|
||||||
<x-grand-child-scope id="gc1"></x-grand-child-scope>
|
<x-grand-child-scope id="gc1"></x-grand-child-scope>
|
||||||
</template>
|
</template>
|
||||||
@ -136,20 +132,19 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-overrides2">
|
<dom-module id="x-overrides2">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
border: 1px dashed gray;
|
|
||||||
margin: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--grand-child-scope-var: var(--rename);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
border: 1px dashed gray;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--grand-child-scope-var: var(--rename);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
overrides:
|
overrides:
|
||||||
<x-grand-child-scope id="gc1"></x-grand-child-scope>
|
<x-grand-child-scope id="gc1"></x-grand-child-scope>
|
||||||
</template>
|
</template>
|
||||||
@ -161,14 +156,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-late">
|
<dom-module id="x-late">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
border: var(--late);
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
border: var(--late);
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
late
|
late
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -179,20 +173,19 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-overrides3">
|
<dom-module id="x-overrides3">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
border: 1px dashed gray;
|
|
||||||
margin: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--fillin: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
border: 1px dashed gray;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--fillin: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
overrides:
|
overrides:
|
||||||
<x-late id="late"></x-late>
|
<x-late id="late"></x-late>
|
||||||
</template>
|
</template>
|
||||||
@ -204,16 +197,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-has-def">
|
<dom-module id="x-has-def">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
border: var(--border, --defaultBorder);
|
|
||||||
margin: 8px;
|
|
||||||
padding: 8px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
border: var(--border, --defaultBorder);
|
||||||
|
margin: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Element with default variable.
|
Element with default variable.
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -224,13 +216,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-has-if">
|
<dom-module id="x-has-if">
|
||||||
<style>
|
|
||||||
.iffy {
|
|
||||||
border: var(--scope-var);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
.iffy {
|
||||||
|
border: var(--scope-var);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<template is="dom-if" if="{{gogo}}">
|
<template is="dom-if" if="{{gogo}}">
|
||||||
<div class="iffy">iffy</div>
|
<div class="iffy">iffy</div>
|
||||||
</template>
|
</template>
|
||||||
@ -248,13 +239,13 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-button">
|
<dom-module id="x-button">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
border: var(--button-border);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
border: var(--button-border);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Button!
|
Button!
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -268,14 +259,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-dynamic">
|
<dom-module id="x-dynamic">
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
margin: 20px;
|
|
||||||
border: var(--dynamic);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<template>
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
margin: 20px;
|
||||||
|
border: var(--dynamic);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Dynamic
|
Dynamic
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
@ -287,113 +278,177 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</script>
|
</script>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-scope">
|
<dom-module id="x-keyframes">
|
||||||
<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, --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}
|
|
||||||
|
|
||||||
:root{--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, --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)
|
|
||||||
}
|
|
||||||
|
|
||||||
#endTerm {border: var(--end-term)}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
<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, --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}
|
||||||
|
|
||||||
|
:root{--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, --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)}
|
||||||
|
</style>
|
||||||
<div id="me">x-scope</div>
|
<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="child"></x-child-scope>
|
||||||
<x-child-scope id="child2"></x-child-scope>
|
<x-child-scope id="child2"></x-child-scope>
|
||||||
<x-overrides id="overrides1a"></x-overrides>
|
<x-overrides id="overrides1a"></x-overrides>
|
||||||
@ -429,50 +484,49 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<dom-module id="x-inside">
|
<dom-module id="x-inside">
|
||||||
<style>
|
<template>
|
||||||
:host {
|
<style>
|
||||||
display: inline-block;
|
:host {
|
||||||
border: var(--border) solid orange;
|
display: inline-block;
|
||||||
height: 10px;
|
border: var(--border) solid orange;
|
||||||
width: 10px;
|
height: 10px;
|
||||||
background-color: tomato;
|
width: 10px;
|
||||||
}
|
background-color: tomato;
|
||||||
</style>
|
}
|
||||||
<template>
|
</style>
|
||||||
|
</template>
|
||||||
</template>
|
<script>
|
||||||
<script>
|
HTMLImports.whenReady(function() {
|
||||||
HTMLImports.whenReady(function() {
|
Polymer({
|
||||||
Polymer({
|
is: 'x-inside'
|
||||||
is: 'x-inside'
|
});
|
||||||
});
|
});
|
||||||
});
|
</script>
|
||||||
</script>
|
</dom-module>
|
||||||
</dom-module>
|
|
||||||
|
|
||||||
|
<dom-module id="simple-element">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
<dom-module id="simple-element">
|
x-inside {
|
||||||
<style>
|
color: var(--dne);
|
||||||
:host {
|
--border: 10px;
|
||||||
display: block;
|
}
|
||||||
}
|
</style>
|
||||||
|
<x-inside id="inner"></x-inside>
|
||||||
x-inside {
|
</template>
|
||||||
color: var(--dne);
|
<script>
|
||||||
--border: 10px;
|
HTMLImports.whenReady(function() {
|
||||||
}
|
Polymer({
|
||||||
</style>
|
is: 'simple-element'
|
||||||
<template>
|
});
|
||||||
<x-inside id="inner"></x-inside>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
HTMLImports.whenReady(function() {
|
|
||||||
Polymer({
|
|
||||||
is: 'simple-element'
|
|
||||||
});
|
});
|
||||||
});
|
</script>
|
||||||
</script>
|
</dom-module>
|
||||||
</dom-module>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.variable-override {
|
.variable-override {
|
||||||
@ -517,6 +571,46 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
var styled = document.querySelector('x-scope');
|
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) {
|
||||||
|
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('mutiple elements in document', function() {
|
test('mutiple elements in document', function() {
|
||||||
var e$ = document.querySelectorAll('simple-element');
|
var e$ = document.querySelectorAll('simple-element');
|
||||||
assertComputed(e$[0].$.inner, '10px');
|
assertComputed(e$[0].$.inner, '10px');
|
||||||
|
@ -1,3 +1,59 @@
|
|||||||
|
<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(--keyframes0, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
left: var(--keyframes100, 10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes x-keyframes-animation {
|
||||||
|
0% {
|
||||||
|
left: var(--keyframes0, 0px);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
left: var(--keyframes100, 10px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
x-keyframes
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'x-keyframes',
|
||||||
|
properties: {
|
||||||
|
animated: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
reflectToAttribute: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
<dom-module id="x-gchild">
|
<dom-module id="x-gchild">
|
||||||
<template>
|
<template>
|
||||||
<!-- styles can be in templates -->
|
<!-- styles can be in templates -->
|
||||||
@ -70,12 +126,17 @@
|
|||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
border: 1px solid orange;
|
border: 1px solid orange;
|
||||||
|
--keyframes100: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.wide) {
|
:host(.wide) {
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#keyframes2.special {
|
||||||
|
--keyframes100: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
#simple {
|
#simple {
|
||||||
border: 3px solid orange;
|
border: 3px solid orange;
|
||||||
}
|
}
|
||||||
@ -169,6 +230,8 @@
|
|||||||
<circle id="circle" cx="12" cy="12" r="10"></circle>
|
<circle id="circle" cx="12" cy="12" r="10"></circle>
|
||||||
</svg>
|
</svg>
|
||||||
<x-scope-class id="scopeClass"></x-scope-class>
|
<x-scope-class id="scopeClass"></x-scope-class>
|
||||||
|
<x-keyframes id="keyframes"></x-keyframes>
|
||||||
|
<x-keyframes id="keyframes2"></x-keyframes>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
<script>
|
<script>
|
||||||
|
@ -164,6 +164,38 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
assertComputed(d, '0px');
|
assertComputed(d, '0px');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('keyframes change scope', function(done) {
|
||||||
|
var xKeyframes = styled.$.keyframes;
|
||||||
|
|
||||||
|
var onAnimationEnd = function() {
|
||||||
|
xKeyframes.removeEventListener('animationend', onAnimationEnd);
|
||||||
|
xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
|
||||||
|
assertComputed(xKeyframes, '100px', 'left');
|
||||||
|
|
||||||
|
xKeyframes = styled.$.keyframes2;
|
||||||
|
|
||||||
|
onAnimationEnd = function() {
|
||||||
|
xKeyframes.removeEventListener('animationend', onAnimationEnd);
|
||||||
|
xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
|
||||||
|
assertComputed(xKeyframes, '200px', 'left');
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
xKeyframes.addEventListener('animationend', onAnimationEnd);
|
||||||
|
xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);
|
||||||
|
|
||||||
|
Polymer.dom(xKeyframes).classList.add('special');
|
||||||
|
xKeyframes.updateStyles();
|
||||||
|
xKeyframes.animated = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
xKeyframes.addEventListener('animationend', onAnimationEnd);
|
||||||
|
xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);
|
||||||
|
|
||||||
|
xKeyframes.animated = true;
|
||||||
|
assertComputed(xKeyframes, '0px', 'left');
|
||||||
|
});
|
||||||
|
|
||||||
test('elements with computed classes', function() {
|
test('elements with computed classes', function() {
|
||||||
assertComputed(styled.$.computed, '0px');
|
assertComputed(styled.$.computed, '0px');
|
||||||
styled.aClass = 'computed';
|
styled.aClass = 'computed';
|
||||||
@ -218,10 +250,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
|||||||
|
|
||||||
test('styles shimmed in registration order', function() {
|
test('styles shimmed in registration order', function() {
|
||||||
var s$ = document.head.querySelectorAll('style[scope]');
|
var s$ = document.head.querySelectorAll('style[scope]');
|
||||||
var expected = ['x-gchild', 'x-child2', 'x-styled', 'x-button', 'x-mixed-case',
|
var expected = ['x-keyframes', 'x-keyframes-1', 'x-keyframes-0', 'x-gchild', 'x-child2',
|
||||||
'x-mixed-case-button', 'x-dynamic-scope', 'x-dynamic-template',
|
'x-styled', 'x-button', 'x-mixed-case', 'x-mixed-case-button',
|
||||||
'x-dynamic-svg', 'x-specificity', 'x-overriding',
|
'x-dynamic-scope', 'x-dynamic-template', 'x-dynamic-svg',
|
||||||
'x-overriding-0', 'x-specificity-parent-0', 'x-specificity-nested-0'];
|
'x-specificity', 'x-overriding', 'x-overriding-0',
|
||||||
|
'x-specificity-parent-0', 'x-specificity-nested-0'];
|
||||||
var actual = [];
|
var actual = [];
|
||||||
for (var i=0; i<s$.length; i++) {
|
for (var i=0; i<s$.length; i++) {
|
||||||
actual.push(s$[i].getAttribute('scope'));
|
actual.push(s$[i].getAttribute('scope'));
|
||||||
|
Loading…
Reference in New Issue
Block a user