mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
660 lines
20 KiB
HTML
660 lines
20 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>
|
|
<script type="module" src="./custom-style-import.js"></script>
|
|
</head>
|
|
<body>
|
|
<!-- FIXME(polymer-modulizer):
|
|
These imperative modules that innerHTML your HTML are
|
|
a hacky way to be sure that any mixins in included style
|
|
modules are ready before any elements that reference them are
|
|
instantiated, otherwise the CSS @apply mixin polyfill won't be
|
|
able to expand the underlying CSS custom properties.
|
|
See: https://github.com/Polymer/polymer-modulizer/issues/154
|
|
-->
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<custom-style>
|
|
<style is="custom-style">
|
|
x-bar {
|
|
border: 1px solid red;
|
|
display: block;
|
|
}
|
|
|
|
html {
|
|
--bag2: {
|
|
border: 12px solid beige;
|
|
};
|
|
}
|
|
|
|
html {
|
|
--red-text : {
|
|
color : red;
|
|
};
|
|
}
|
|
|
|
html{--blue-text:{color:#0000ff};--dummy-mixin:{};--bold-text:{font-weight:700}}
|
|
|
|
|
|
html {
|
|
|
|
--italic: italic;
|
|
|
|
--bag: {
|
|
margin: 1px;
|
|
border: 1px solid black;
|
|
};
|
|
|
|
/* mocha.css in the testing environment is hosing this test;
|
|
use !important as a workaround */
|
|
margin: 10px !important;
|
|
width: auto;
|
|
|
|
--special: var(--primary);
|
|
|
|
--after: 11px solid orange;
|
|
@apply --bag2;
|
|
}
|
|
|
|
x-foo {
|
|
|
|
--primary: 10px;
|
|
--x-foo-more: 6px solid orange;
|
|
}
|
|
</style>
|
|
</custom-style>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<custom-style>
|
|
<style is="custom-style">
|
|
.bag {
|
|
;@apply --bag;
|
|
}
|
|
|
|
.italic {
|
|
font-style: var(--italic);
|
|
}
|
|
|
|
.import-mixin {
|
|
@apply --import-mixin;
|
|
}
|
|
|
|
.import-var {
|
|
border: var(--import-var);
|
|
}
|
|
|
|
.dynamic {
|
|
border: var(--dynamic);
|
|
}
|
|
|
|
#after::after {
|
|
content: 'after';
|
|
border: var(--after);
|
|
}
|
|
</style>
|
|
</custom-style>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<custom-style>
|
|
<style is="custom-style" include="shared-style2">
|
|
.zazz {
|
|
border: 20px solid blue;
|
|
}
|
|
</style>
|
|
<style>
|
|
.foo--bar {
|
|
border-top : 3px solid red;
|
|
}
|
|
</style>
|
|
</custom-style>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<custom-style>
|
|
<style is="custom-style">
|
|
@media (min-width: 1px) {
|
|
.foo--bar {
|
|
border-top : 20px solid blue;
|
|
}
|
|
}
|
|
</style>
|
|
</custom-style>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="italic">italic</div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="bag">bag</div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="mix">mix</div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="dynamic">dynamic</div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="import-mixin">import-mixin</div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="import-var">import-var</div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<x-bar></x-bar>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<x-foo></x-foo>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<x-red-text></x-red-text>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<x-blue-bold-text></x-blue-bold-text>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<parent-variable-with-var></parent-variable-with-var>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<br>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script><script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<br>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div id="after"></div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="foo"></div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
$_documentContainer.innerHTML = `<div class="foo--bar"></div>`;
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="x-baz">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
}
|
|
</style>
|
|
<div id="me">x-baz</div>
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="x-bar">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
}
|
|
</style>
|
|
<div>x-bar</div>
|
|
<x-baz id="baz"></x-baz>
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="x-foo">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
border: solid tomato;
|
|
border-width: var(--special);
|
|
}
|
|
|
|
div {
|
|
@apply --bag;
|
|
}
|
|
|
|
#more {
|
|
border: var(--x-foo-more);
|
|
}
|
|
</style>
|
|
<div id="me">x-foo</div>
|
|
<x-bar id="bar1"></x-bar>
|
|
<x-bar id="bar2"></x-bar>
|
|
<x-bar id="bar3"></x-bar>
|
|
<div id="more">deep</div>
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="x-red-text">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
@apply --red-text;
|
|
}
|
|
</style>
|
|
x-red-text
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="x-blue-bold-text">
|
|
<template>
|
|
<style>
|
|
:host {@apply --blue-text;@apply --bold-text;}
|
|
</style>
|
|
x-blue-bold-text
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="parent-variable-with-var">
|
|
<template>
|
|
<style>
|
|
child-variable-with-var {
|
|
--variable-property-own-line: 1px;
|
|
--variable-property-preceded-property: 2px;
|
|
--variable-property-before-property: yellow;
|
|
--variable-property-after-property: 3px;
|
|
--variable-property-after-assignment: 4px;
|
|
--variable-property-before-assignment: 5px;
|
|
--variable-into-first-variable: 9px;
|
|
--variable-into-second-variable: 10px;
|
|
--variable-into-third-variable: 11px;
|
|
}
|
|
</style>
|
|
<child-variable-with-var id="child"></child-variable-with-var>
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="child-variable-with-var">
|
|
<template>
|
|
<style>
|
|
child-of-child-with-var {
|
|
/* in certain browsers (e.g. Safari) \`top\`, \`bottom\`, \`left\`, \`right\` don't compute
|
|
when no explicit position is defined (\`relative\` / \`absolute\` / \`fixed\`) */
|
|
position: relative;
|
|
--variable-own-line: "Varela font";
|
|
margin-top: var(--variable-property-own-line);
|
|
margin-bottom: var(--variable-property-preceded-property);
|
|
--variable-between-properties: 6px;
|
|
background-color: var(--variable-property-before-property); padding-top: var(--variable-property-after-property);
|
|
--variable-assignment-before-property: 7px; padding-bottom: var(--variable-property-after-assignment);
|
|
padding-left: var(--variable-property-before-assignment);--variable-assignment-after-property: 8px;
|
|
top: 12px;--variable-from-other-variable: var(--variable-into-first-variable);--variable-from-another-variable: var(--variable-into-second-variable); --variable-from-last-variable: var(--variable-into-third-variable);
|
|
height: 20px;
|
|
}
|
|
</style>
|
|
<child-of-child-with-var id="child"></child-of-child-with-var>
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
const $_documentContainer = document.createElement('template');
|
|
|
|
$_documentContainer.innerHTML = `<dom-module id="child-of-child-with-var">
|
|
<template>
|
|
<style>
|
|
:host {
|
|
font-family: var(--variable-own-line);
|
|
padding-right: var(--variable-between-properties);
|
|
margin-left: var(--variable-assignment-before-property);
|
|
margin-right: var(--variable-assignment-after-property);
|
|
bottom: var(--variable-from-other-variable);
|
|
left: var(--variable-from-another-variable);
|
|
right: var(--variable-from-last-variable);
|
|
}
|
|
</style>
|
|
Text
|
|
</template>
|
|
</dom-module>`;
|
|
|
|
document.body.appendChild($_documentContainer.content);
|
|
</script>
|
|
|
|
<script type="module">
|
|
import './custom-style-import.js';
|
|
import { Polymer } from '../../lib/legacy/polymer-fn.js';
|
|
Polymer({
|
|
is: 'x-baz'
|
|
});
|
|
|
|
Polymer({
|
|
is: 'x-bar'
|
|
});
|
|
|
|
Polymer({
|
|
is: 'x-foo'
|
|
});
|
|
|
|
Polymer({
|
|
is: 'x-red-text'
|
|
});
|
|
|
|
Polymer({
|
|
is: 'x-blue-bold-text'
|
|
});
|
|
</script>
|
|
|
|
<script type="module">
|
|
import './custom-style-import.js';
|
|
import { updateStyles } from '../../lib/mixins/element-mixin.js';
|
|
import { Polymer } from '../../lib/legacy/polymer-fn.js';
|
|
|
|
suite('custom-style', function() {
|
|
|
|
var xBar, xFoo, stylesBuilt;
|
|
|
|
suiteSetup(function() {
|
|
xBar = document.querySelector('x-bar');
|
|
xFoo = document.querySelector('x-foo');
|
|
});
|
|
|
|
test('root styles applied', function() {
|
|
assertComputed(xBar, '1px');
|
|
});
|
|
|
|
test('root styles have lower bound encapsulation', function() {
|
|
assertComputed(xFoo.$.bar1, '0px');
|
|
});
|
|
|
|
test('custom properties registered as defaults', function() {
|
|
var propsToCheck = ['--italic'];
|
|
if (!window.ShadyCSS || ShadyCSS.nativeCss || stylesBuilt) {
|
|
var sep = window.ShadyCSS.ApplyShim._separator;
|
|
propsToCheck.push('--bag' + sep + 'margin', '--bag' + sep + 'border');
|
|
} else {
|
|
propsToCheck.push('--bag');
|
|
}
|
|
if (!window.ShadyCSS || ShadyCSS.nativeCss) {
|
|
var cs = getComputedStyle(document.documentElement);
|
|
propsToCheck.forEach(function(p) {
|
|
assert.ok(cs.getPropertyValue(p));
|
|
});
|
|
} else {
|
|
propsToCheck.forEach(function(p) {
|
|
assert.ok(ShadyCSS.ScopingShim.getComputedStyleValue(document.documentElement, p));
|
|
});
|
|
}
|
|
});
|
|
|
|
test('custom properties with space before semicolon', function() {
|
|
var red = document.querySelector('x-red-text');
|
|
assertComputed(red, 'rgb(255, 0, 0)', 'color');
|
|
});
|
|
|
|
test('custom properties in minified css', function() {
|
|
var blue = document.querySelector('x-blue-bold-text');
|
|
assertComputed(blue, 'rgb(0, 0, 255)', 'color');
|
|
|
|
var computed = getComputedStyle(blue);
|
|
// Firefox returns `700`, while Chrome returns original `bold`
|
|
assert.ok(computed.fontWeight == '700' || computed.fontWeight == 'bold', 'computed style incorrect for fontWeight');
|
|
});
|
|
|
|
test('custom-styles apply normal and property values to main document', function() {
|
|
var bag = document.querySelector('.bag');
|
|
var italic = document.querySelector('.italic');
|
|
assertComputed(bag, '1px');
|
|
assertComputed(italic, 'italic', 'font-style');
|
|
});
|
|
|
|
test('imported custom-styles apply', function() {
|
|
if (stylesBuilt && window.ShadyCSS && !ShadyCSS.nativeCss) {
|
|
// css build will test this by using vulcanize.
|
|
// this inlines the custom-style after the consumption point, and changes the timing for custom property shim
|
|
// Force an update style for this weird corner case in the tests
|
|
updateStyles();
|
|
}
|
|
var v = document.querySelector('.import-var');
|
|
var m = document.querySelector('.import-mixin');
|
|
assertComputed(v, '3px');
|
|
assertComputed(m, '4px');
|
|
});
|
|
|
|
test('dynamic custom-styles apply', function() {
|
|
var dynamic = document.querySelector('.dynamic');
|
|
assertComputed(dynamic, '0px');
|
|
var cs = document.createElement('custom-style');
|
|
var s = document.createElement('style');
|
|
s.textContent = ':root { --dynamic: 11px solid orange; }';
|
|
cs.appendChild(s);
|
|
document.body.appendChild(cs);
|
|
updateStyles();
|
|
assertComputed(dynamic, '11px');
|
|
});
|
|
|
|
test('custom-styles apply normal and property values to elements and cannot be late bound via inheritance', function() {
|
|
var e = document.querySelector('x-foo').$.me;
|
|
assertComputed(e, '1px');
|
|
});
|
|
|
|
test('custom-styles apply to pseudo elements', function() {
|
|
var e = document.querySelector('#after');
|
|
assertComputed(e, '11px', null, '::after');
|
|
});
|
|
|
|
test('style paths in included dom-modules loaded in import', function() {
|
|
var foo = document.querySelector('.foo');
|
|
var url = getComputedStyle(foo).backgroundImage;
|
|
assert.include(url, 'sub/google.png');
|
|
});
|
|
|
|
test('style paths can have arbitrary whitespace', function() {
|
|
var foo = document.querySelector('.foo');
|
|
assertComputed(foo, '4px', 'width');
|
|
});
|
|
|
|
test('imperative custom style', function() {
|
|
var cs = document.createElement('custom-style');
|
|
var style = document.createElement('style');
|
|
style.textContent = '.zonk { border: 13px solid tomato;}';
|
|
cs.appendChild(style);
|
|
var d = document.createElement('div');
|
|
d.classList.add('zonk');
|
|
document.body.appendChild(d);
|
|
document.body.appendChild(cs);
|
|
updateStyles();
|
|
if (window.ShadyDOM) {
|
|
assert.ok(style.textContent.match(':not'));
|
|
}
|
|
assertComputed(d, '13px');
|
|
document.body.removeChild(d);
|
|
document.body.removeChild(cs);
|
|
|
|
});
|
|
|
|
test('imperative custom style with include', function() {
|
|
var cs = document.createElement('custom-style');
|
|
var style = document.createElement('style');
|
|
style.setAttribute('include', 'shared-style2');
|
|
cs.appendChild(style);
|
|
var d = document.createElement('div');
|
|
d.classList.add('zazz');
|
|
document.body.appendChild(d);
|
|
document.body.appendChild(cs);
|
|
updateStyles();
|
|
assertComputed(d, '16px');
|
|
document.body.removeChild(d);
|
|
document.body.removeChild(cs);
|
|
});
|
|
|
|
test('imperative custom style with non-existent include', function() {
|
|
var s1 = document.createElement('custom-style');
|
|
var style = document.createElement('style');
|
|
s1.appendChild(style);
|
|
style.setAttribute('include', 'does-not-exist');
|
|
style.textContent = '.ziz { border: 14px solid tomato;}';
|
|
var d = document.createElement('div');
|
|
d.classList.add('ziz');
|
|
document.body.appendChild(d);
|
|
document.body.appendChild(s1);
|
|
updateStyles();
|
|
assertComputed(d, '14px');
|
|
document.body.removeChild(d);
|
|
document.body.removeChild(s1);
|
|
});
|
|
|
|
test('include style data applied before textContent', function() {
|
|
var d = document.createElement('div');
|
|
d.classList.add('zazz');
|
|
document.body.appendChild(d);
|
|
assertComputed(d, '20px');
|
|
document.body.removeChild(d);
|
|
});
|
|
|
|
test('variable name with assignment including var correctly applied', function() {
|
|
Polymer({
|
|
is: 'parent-variable-with-var'
|
|
});
|
|
Polymer({
|
|
is: 'child-variable-with-var'
|
|
});
|
|
Polymer({
|
|
is: 'child-of-child-with-var'
|
|
});
|
|
|
|
var d = document.querySelector('parent-variable-with-var');
|
|
var el = d.$.child.$.child;
|
|
assertComputed(el, '1px', 'margin-top');
|
|
assertComputed(el, '2px', 'margin-bottom');
|
|
assertComputed(el, '3px', 'padding-top');
|
|
assertComputed(el, '4px', 'padding-bottom');
|
|
assertComputed(el, '5px', 'padding-left');
|
|
assertComputed(el, '6px', 'padding-right');
|
|
assertComputed(el, '7px', 'margin-left');
|
|
assertComputed(el, '8px', 'margin-right');
|
|
assertComputed(el, 'rgb(255, 255, 0)', 'background-color');
|
|
assertComputed(el, '9px', 'bottom');
|
|
assertComputed(el, '10px', 'left');
|
|
assertComputed(el, '11px', 'right');
|
|
assertComputed(el, '12px', 'top');
|
|
|
|
// Avoid Edge bug with CSS Custom Properties and Fonts.
|
|
if (navigator.userAgent.match('Edge') && (!window.ShadyCSS || window.ShadyCSS.nativeCss)) {
|
|
return;
|
|
}
|
|
|
|
// Because FireFox and Chrome parse font-family differently...
|
|
var computed = getComputedStyle(el);
|
|
assert.equal(computed['font-family'].replace(/['"]+/g, ''), 'Varela font');
|
|
});
|
|
|
|
test('BEM-like CSS selectors under media queries', function() {
|
|
assertComputed(document.querySelector('.foo--bar'), '20px');
|
|
});
|
|
|
|
});
|
|
|
|
|
|
function assertComputed(element, value, property, pseudo) {
|
|
var computed = getComputedStyle(element, pseudo);
|
|
property = property || 'border-top-width';
|
|
assert.equal(computed[property], value, 'computed style incorrect for ' + property);
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|