blob: bac2b38c92aa1537e2041b11a247fb049483571f [file] [log] [blame]
<!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
-->
<html>
<head>
<meta charset="utf-8">
<script>
WCT = {waitFor: function (cb) {HTMLImports.whenReady(cb)}}
</script>
<script src="../../node_modules/wct-browser-legacy/browser.js"></script>
<script src="../../node_modules/@webcomponents/webcomponents-platform/webcomponents-platform.js"></script>
<script src="../../node_modules/es6-promise/dist/es6-promise.auto.min.js"></script>
<script src="../../node_modules/@webcomponents/template/template.js"></script>
<script src="../../node_modules/@webcomponents/html-imports/html-imports.min.js"></script>
<script src="../../node_modules/@webcomponents/shadydom/shadydom.min.js"></script>
<script src="../../node_modules/@webcomponents/custom-elements/custom-elements.min.js"></script>
<script src="../../apply-shim.min.js"></script>
<script src="../../custom-style-interface.min.js"></script>
<script src="../module/generated/make-element.js"></script>
<script src="../module/generated/custom-style-element.js"></script>
<script src="../module/generated/style-util.js"></script>
<title>Apply Shim</title>
</head>
<body>
<template id="basic">
<style>
:host {
--mixin: {
border: 2px solid black;
};
}
div {
@apply --mixin;
}
</style>
</template>
<template id="defaults">
<style>
:host {
--mixin: {
border: 2px solid black;
}
}
div {
border: 1px dotted orange;
@apply --mixin;
}
span {
border: inherit;
@apply --mixin;
}
span {
border: initial;
@apply --mixin;
}
</style>
</template>
<template id="override">
<style>
:host {
--override: {
padding: 2px;
};
}
:host([override]) {
--override: {
border: 2px solid black;
};
}
div {
@apply --override;
}
</style>
</template>
<template id="override-with-property">
<style>
:root {
--prop-mixin: {
border: 2px solid black;
};
}
x-foo {
--prop-mixin: blue;
color: var(--prop-mixin);
}
div {
@apply --prop-mixin;
}
</style>
</template>
<template id="define-with-var">
<style>
:root {
--mixin-var: {
border: 2px solid black;
};
}
div {
--mixin-var2: var(--mixin-var);
}
span {
--mixin-var: 20px;
--variable: var(--mixin-var);
}
</style>
</template>
<template id="x-element">
<style>
:host {
@apply --my-mixin;
}
</style>
</template>
<template id="x-element2">
<custom-style>
<style>
html {
--my-mixin: {
border: 2px solid black;
};
}
</style>
</custom-style>
</template>
<template id="css-build" css-build="shadow">
<style>:host{@apply --fake;}</style>
</template>
<template id="css-build-comment"><!--css-build:shadow-->
<style>:host{@apply --fake;}</style>
</template>
<script>
suite('Apply Shim', function() {
function copy(name) {
var template = document.querySelector('template#' + name);
return template.content.cloneNode(true);
}
function prep(templateName, elementName) {
var style = copy(templateName).querySelector('style');
var ast = window.ShadyCSS.ApplyShim.transformStyle(style, elementName);
return {style: style, ast: ast};
}
suite('Basic', function() {
var style, ast;
suiteSetup(function() {
var info = prep('basic');
style = info.style;
ast = info.ast;
style.textContent = window.StyleUtil.toCssText(ast);
});
test('style is transformed', function() {
var orig = copy('basic').querySelector('style');
assert.notEqual(style.textContent, orig.textContent);
});
test('mixin became custom properties', function() {
var definition = ast.rules[0];
var application = ast.rules[1];
assert.match(definition.cssText, /--mixin_-_border:\s*2px solid black/);
assert.match(application.cssText, /border:\s*var\(--mixin_-_border\)/);
});
});
suite('Defaults', function() {
var style, ast; // eslint-disable-line no-unused-vars
suiteSetup(function() {
var info = prep('defaults');
style = info.style;
ast = info.ast;
});
test('properties defined before mixin are used as defaults', function() {
var application = ast.rules[1];
assert.match(application.cssText, /border:\s*var\(--mixin_-_border,\s*1px dotted orange\)/);
});
test('inherit and initial default values are preserved', function () {
var application = ast.rules[2];
assert.match(application.cssText, /border:\s*var\(--mixin_-_border,\s*inherit\)/);
application = ast.rules[3];
assert.match(application.cssText, /border:\s*var\(--mixin_-_border,\s*initial\)/);
});
});
suite('override', function() {
var style, ast; // eslint-disable-line no-unused-vars
suiteSetup(function() {
var info = prep('override');
style = info.style;
ast = info.ast;
});
test('mixin redefinition sets unused properties to initial', function() {
var def1 = ast.rules[0];
assert.match(def1.cssText, /--override_-_padding:\s*2px/);
var def2 = ast.rules[1];
assert.match(def2.cssText, /--override_-_padding:\s*initial/);
assert.match(def2.cssText, /--override_-_border:\s*2px solid black/);
});
test('mixin application includes all values', function() {
var application = ast.rules[2];
assert.match(application.cssText, /padding:\s*var\(--override_-_padding\)/);
assert.match(application.cssText, /border:\s*var\(--override_-_border\)/);
});
});
suite('override with property', function() {
var style, ast; // eslint-disable-line no-unused-vars
suiteSetup(function() {
var info = prep('override-with-property');
style = info.style;
ast = info.ast;
});
test('mixin definition defers to property definition', function() {
var def = ast.rules[1];
assert.notMatch(def.cssText, /border:\s*var\(--prop-mixin_-_border\)/);
});
test('mixin can still be used by other parts of the page', function() {
var def = ast.rules[2];
assert.match(def.cssText, /border:\s*var\(--prop-mixin_-_border\)/);
});
});
suite('define with var()', function() {
var style, ast; // eslint-disable-line no-unused-vars
suiteSetup(function() {
var info = prep('define-with-var');
style = info.style;
ast = info.ast;
});
test('mixin-var2 is defined with mixin-var\'s values', function() {
var def = ast.rules[1];
assert.match(def.cssText, /--mixin-var2_-_border:\s*var\(--mixin-var_-_border\)/);
});
test('var usage of mixin is not removed, preserving override functionality', function() {
var def = ast.rules[2];
assert.match(def.cssText, /--variable:\s*var\(--mixin-var\)/);
});
});
suite('invalidation on new definitions', function() {
var style, ast, element;
suiteSetup(function() {
makeElement('x-element');
element = document.createElement('x-element');
document.body.appendChild(element);
style = element.shadowRoot ? element.shadowRoot.querySelector('style') : document.head.querySelector('style[scope=x-element]');
});
test('element initially has no definition', function() {
var ast = window.StyleUtil.rulesForStyle(style);
assert.equal(ast.rules[0].cssText, ';');
});
test('Revalidating Apply Shim on element template fills in properties', function() {
var nodes = copy('x-element2');
document.body.appendChild(nodes);
window.ShadyCSS.styleDocument();
var ast = window.StyleUtil.rulesForStyle(style);
assert.match(ast.rules[0].cssText, /border:\s*var\(--my-mixin_-_border\)/);
});
});
test('templates with "css-build" will not be processed by ApplyShim', function() {
makeElement('css-build');
const template = document.querySelector('template#css-build');
assert.equal(template._styleAst, undefined);
const style = template.content.querySelector('style');
assert.match(style.textContent.trim(), /:host\s*{\s*@apply --fake;\s*}/);
});
test('templates with "css-build" comment will not be processed by ApplyShim', function () {
const template = document.querySelector('template#css-build-comment');
const buildComment = template.content.firstChild;
assert.instanceOf(buildComment, Comment, 'first node in template content should be a Comment');
makeElement('css-build-comment');
assert.equal(template._styleAst, undefined);
const style = template.content.querySelector('style');
assert.match(style.textContent.trim(), /:host\s*{\s*@apply --fake;\s*}/);
assert.equal(buildComment.parentNode, null, 'build comment should be removed');
});
});
</script>
</body>
</html>