aboutsummaryrefslogtreecommitdiff
path: root/catapult/third_party/polymer/components/shadycss/tests/scoping.html
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/third_party/polymer/components/shadycss/tests/scoping.html')
-rw-r--r--catapult/third_party/polymer/components/shadycss/tests/scoping.html1058
1 files changed, 1058 insertions, 0 deletions
diff --git a/catapult/third_party/polymer/components/shadycss/tests/scoping.html b/catapult/third_party/polymer/components/shadycss/tests/scoping.html
new file mode 100644
index 00000000..eaab8e04
--- /dev/null
+++ b/catapult/third_party/polymer/components/shadycss/tests/scoping.html
@@ -0,0 +1,1058 @@
+<!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="./test-flags.js"></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="../scoping-shim.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>
+
+ <custom-style>
+ <style>
+ div#priority {
+ border: 1px solid black;
+ }
+ </style>
+ </custom-style>
+</head>
+<body>
+
+<template id="x-gchild">
+ <style>
+ </style>
+ <div id="target">x-gchild</div>
+</template>
+
+<template id="x-child">
+ <div id="simple">simple</div>
+ <div id="complex1" class="scoped">complex1</div>
+ <div id="complex2" selected>complex2</div>
+ <div id="media">media</div>
+ <div id="shadow" class="shadowTarget">shadowTarget</div>
+ <div id="deep" class="deepTarget">deepTarget</div>
+ <x-gchild id="gchild1"></x-gchild>
+ <x-gchild id="gchild2" class="wide"></x-gchild>
+</template>
+
+<template id="x-child2">
+ <style>
+ :host(.wide) #target{
+ border: none;
+ }
+ </style>
+ <div id="target">x-child2</div>
+</template>
+
+<template id="x-scope-class">
+ <div id="scope">Trivial</div>
+</template>
+
+<template id="x-scoped">
+ <style>
+ :host {
+ display: block;
+ border: 1px solid orange;
+ --keyframes100: 100px;
+ }
+
+ :host(.wide) {
+ border-width: 2px;
+ }
+
+ :host(.wide)::after {
+ content: '-content-';
+ };
+
+ #keyframes2.special {
+ --keyframes100: 200px;
+ }
+
+ #simple {
+ border: 3px solid orange;
+ }
+
+ .scoped, [selected] {
+ border: 4px solid pink;
+ }
+
+ @media(max-width: 10000px) {
+ .media {
+ border: 5px solid brown;
+ }
+ }
+
+ .container ::slotted(*) {
+ border: 6px solid navy;
+ }
+
+ #priority {
+ border: 9px solid orange;
+ }
+
+ .container1 > ::slotted([slot=content1]) {
+ border: 13px solid navy;
+ }
+
+ .container2 > ::slotted([slot=content2]) {
+ border: 14px solid navy;
+ }
+
+ .computed {
+ border: 15px solid orange;
+ }
+
+ .computeda {
+ border: 20px solid orange;
+ }
+
+ #child {
+ border: 16px solid tomato;
+ display: block;
+ }
+
+ svg {
+ margin-top: 20px;
+ }
+
+ #circle {
+ fill: seagreen;
+ stroke-width: 1px;
+ stroke: tomato;
+ }
+ </style>
+ <slot name="blank"></slot>
+ <div id="simple">simple</div>
+ <div id="complex1" class="scoped">complex1</div>
+ <div id="complex2" selected>complex2</div>
+ <div id="media" class="media">media</div>
+ <div class="container1">
+ <slot name="content1"></slot>
+ </div>
+ <div class="container2">
+ <slot name="content2"></slot>
+ </div>
+ <div class="container">
+ <slot></slot>
+ </div>
+ <x-child id="child"></x-child>
+ <div id="priority">priority</div>
+ <x-child2 class="wide" id="child2"></x-child2>
+ <div id="computed">Computed</div>
+ <svg height="25" width="25">
+ <circle id="circle" cx="12" cy="12" r="10"></circle>
+ </svg>
+ <x-scope-class id="scopeClass"></x-scope-class>
+ <x-keyframes id="keyframes"></x-keyframes>
+ <x-keyframes id="keyframes2"></x-keyframes>
+</template>
+
+<template id="x-slotted">
+ <style>
+ ::slotted(.auto-content) {
+ border: 2px solid orange;
+ }
+ .bar, ::slotted(.complex-child) {
+ border: 6px solid navy;
+ }
+ #container ::slotted(*) {
+ border: 8px solid green;
+ }
+ </style>
+ <slot></slot>
+ <div id="container">
+ <slot name="container"></slot>
+ </div>
+</template>
+
+<template id="dynamic">
+ <div class="added">
+ Added
+ <div class="sub-added">
+ Sub-added
+ </div>
+ </div>
+ </div>
+</template>
+
+<template id="x-dynamic-scope">
+ <style>
+ .added {
+ border: 17px solid beige;
+ }
+ .sub-added {
+ border: 18px solid #fafafa;
+ }
+ </style>
+ <div id="container"></div>
+</template>
+
+<template id="x-keyframes">
+ <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>
+
+<template id="x-attr-selector">
+ <style>
+ #foo1 ~ #bar1 {
+ border: 2px solid red;
+ }
+
+ #foo1 ~ #bar1 ~ #foo2[attr~=foo2] ~ #bar2[attr~=bar2] {
+ border: 4px solid red;
+ }
+
+ #foo1 ~ #bar1 ~ #foo2[attr~=foo2] ~ #bar2[attr~=bar2] ~ #foo3[attr~=foo3][a~=a] ~ #bar3[attr~=bar3][a~=a] {
+ border: 6px solid red;
+ }
+ </style>
+ <div id="foo1"></div>
+ <div id="bar1">bar1</div>
+ <div id="foo2" attr="foo2"></div>
+ <div id="bar2" attr="bar2">bar2</div>
+ <div id="foo3" attr="foo3" a="a"></div>
+ <div id="bar3" attr="bar3" a="a">bar3</div>
+</template>
+
+<template id="x-adjacent-sibling">
+ <style>
+ div {
+ border: 20px solid black;
+ }
+ #foo2 + #foo1 {
+ border: 2px solid black;
+ }
+ #foo1 + #foo2 {
+ border: 4px solid black;
+ }
+ #foo2 + #foo3 {
+ border: 6px solid black;
+ }
+ </style>
+ <div id="foo1"></div>
+ <div id="foo2"></div>
+ <div id="foo3"></div>
+</template>
+
+<template id="svg">
+ <svg class="svg" viewBox="0 0 24 24">
+ <circle id="circle" r="12" cx="12" cy="12" />
+ </svg>
+</template>
+
+<template id="x-dynamic-svg">
+ <style>
+ .svg {
+ height: 24px;
+ width: 24px;
+ }
+ #circle {
+ fill: red;
+ fill-opacity: 0.5;
+ }
+ </style>
+ <div id="container"></div>
+</template>
+
+<template id="x-specificity">
+ <style>
+ :host {
+ border-top: 1px solid red;
+ }
+ :host(.bar) {
+ border-top: 2px solid red;
+ }
+ </style>
+ <slot></slot>
+</template>
+
+<template id="self-test">
+ <style>
+ :host {
+ --border: 10px solid rgb(123, 123, 123);
+ }
+
+ a {
+ border: var(--border);
+ }
+ </style>
+ <a>I should be red.</a>
+</template>
+
+<template id="nth-plus-one">
+ <style>
+ .foo.bar {
+ color: rgb(255, 0, 0);
+ }
+ div:nth-child(n+1) {
+ color: rgb(0, 255, 0);
+ }
+ </style>
+ <div>1</div>
+ <div class="foo bar">2</div>
+</template>
+
+<template id="shady-unscoped">
+ <style shady-unscoped>
+ .unscoped {
+ color: rgb(255, 0, 0);
+ }
+ </style>
+ <div class="unscoped"></div>
+</template>
+
+<template id="shady-unscoped-2">
+ <style shady-unscoped>
+ .unscoped {
+ color: rgb(255, 0, 0);
+ }
+ </style>
+ <span class="unscoped"></span>
+</template>
+
+<template id="unscoped-apply-user">
+ <style>
+ div {
+ @apply --unscoped-foo;
+ }
+ </style>
+ <div></div>
+</template>
+
+<template id="unscoped-apply">
+ <style shady-unscoped>
+ html, :host > * {
+ --unscoped-foo: {border: 10px solid black};
+ }
+ </style>
+ <unscoped-apply-user></unscoped-apply-user>
+</template>
+
+<template id="any-selector">
+ <style>
+ :-webkit-any(div, span) {
+ color: rgb(123, 123, 123);
+ }
+ :-moz-any(div, span) {
+ color: rgb(123, 123, 123);
+ }
+ </style>
+ <div>a</div>
+ <span>b</span>
+</template>
+
+<template id="scoped-keyframes">
+ <style>
+ :host {
+ --time: 0.1s;
+ }
+
+ div {
+ /* prefix for older chrome and safari */
+ -webkit-animation-duration: var(--time);
+ animation-duration: var(--time);
+ -webkit-animation-fill-mode: forwards;
+ animation-fill-mode: forwards;
+ border: 0px solid black;
+ }
+
+ :host([animate]) div {
+ /* prefix for older chrome and safari */
+ -webkit-animation-name: border-grow;
+ animation-name: border-grow;
+ }
+
+ /* prefix for older chrome and safari */
+ @-webkit-keyframes border {}
+ @-webkit-keyframes border-grow {
+ to {
+ border-top-width: 10px;
+ }
+ }
+ @keyframes border {}
+ @keyframes border-grow {
+ to {
+ border-top-width: 10px;
+ }
+ }
+ </style>
+
+ <div id="target">Hello world</div>
+</template>
+
+<template id="nested-templates">
+ <style>
+ * {
+ opacity: 0.5;
+ }
+ </style>
+ <div id="a"></div>
+ <template id="t1">
+ <div id="b">
+ <div id="c">
+ <template id="t2">
+ <div id="d"></div>
+ </template>
+ </div>
+ </div>
+ </template>
+ <svg>
+ <template id="t3">
+ <g id="g">
+ <circle id="circle"></circle>
+ </g>
+ </template>
+ </svg>
+</template>
+
+<template id="bad-mixin">
+ <style>
+ :host(.nomatch) {
+ --div-border: {
+ border: 2px solid black;
+ }
+ }
+ div {
+ @apply --div-border;
+ }
+ </style>
+ <div></div>
+</template>
+
+<template id="x-parent-skip">
+ <style>
+ :host {
+ --foo: 10px solid black;
+ }
+ </style>
+ <x-skip></x-skip>
+</template>
+
+<template id="x-skip">
+ <x-child-skip></x-child-skip>
+</template>
+
+<template id="x-child-skip">
+ <style>
+ div {
+ border: var(--foo);
+ }
+ </style>
+ <div></div>
+</template>
+
+<script>
+(function() {
+ function assertComputed(element, value, property, pseudo) {
+ var computed = getComputedStyle(element, pseudo);
+ property = property || 'border-top-width';
+ if (Array.isArray(value)) {
+ assert.oneOf(computed[property], value, 'computed style incorrect for ' + property);
+ } else {
+ assert.equal(computed[property], value, 'computed style incorrect for ' + property);
+ }
+ }
+
+ function findNode(desc) {
+ var parts = desc.split('.');
+ var root = document;
+ var node;
+ for (var i=0, p; i < parts.length; i++) {
+ p = parts[i];
+ if (p == '$') {
+ root = node.shadowRoot;
+ } else {
+ node = root.querySelector('#' + p);
+ }
+ }
+ return node;
+ }
+
+ function flush() {
+ if (window.ShadyDOM) {
+ window.ShadyDOM.flush();
+ }
+ window.ShadyCSS.ScopingShim.flush();
+ }
+
+ suite('scoped-styling', function() {
+
+ suiteSetup(function() {
+ makeElement('x-gchild');
+ makeElement('x-child', function() {
+ this.classList.add('nug');
+ });
+ makeElement('x-child2');
+ makeElement('x-scope-class');
+ makeElement('x-scoped');
+ makeElement('x-slotted');
+ (function() {
+ var dynamic = document.querySelector('template#dynamic');
+
+ makeElement('x-dynamic-scope',
+ function() {
+ // simulate 3rd party action by using normal dom to add to element.
+ var dom = document.importNode(dynamic.content, true);
+ this.shadowRoot.querySelector('#container').appendChild(dom);
+ });
+ })();
+ makeElement('x-keyframes');
+ makeElement('x-attr-selector');
+ (function() {
+ var template = document.querySelector('template#svg');
+
+ makeElement('x-dynamic-svg', function() {
+ var dom = document.importNode(template.content, true);
+ this.shadowRoot.querySelector('#container').appendChild(dom);
+ });
+ })();
+ makeElement('x-specificity');
+ makeElement('nested-templates');
+ });
+
+ var el;
+ setup(function() {
+ el = document.createElement('x-scoped');
+ el.id = 'el';
+ document.body.appendChild(el);
+ flush();
+ });
+
+ teardown(function() {
+ document.body.removeChild(el);
+ });
+
+ test(':host', function() {
+ assertComputed(el, '1px');
+ assertComputed(el, ['', 'none'], 'content', '::after');
+ });
+
+ test(':host(...)', function() {
+ var el2 = document.createElement('x-scoped');
+ el2.classList.add('wide');
+ document.body.appendChild(el2);
+ flush();
+ assertComputed(el2, '2px');
+ assertComputed(el2, ['"-content-"', '-content-'], 'content', '::after');
+ document.body.removeChild(el2);
+ });
+
+ test('scoped selectors, simple and complex', function() {
+ assertComputed(findNode('el.$.simple'), '3px');
+ assertComputed(findNode('el.$.complex1'), '4px');
+ assertComputed(findNode('el.$.complex2'), '4px');
+ });
+
+ test('media query scoped selectors', function() {
+ assertComputed(findNode('el.$.media'), '5px');
+ });
+
+ test('upper bound encapsulation', function() {
+ var d = document.createElement('div');
+ d.classList.add('scoped');
+ document.body.appendChild(d);
+ assertComputed(d, '0px');
+ document.body.removeChild(d);
+ });
+
+ test('lower bound encapsulation', function() {
+ assertComputed(findNode('el.$.child.$.simple'), '0px');
+ assertComputed(findNode('el.$.child.$.complex1'), '0px');
+ assertComputed(findNode('el.$.child.$.complex2'), '0px');
+ assertComputed(findNode('el.$.child.$.media'), '0px');
+ });
+
+ test('nested templates', function() {
+ var el = document.createElement('nested-templates');
+ document.body.appendChild(el);
+ // Append nested template content. Note the <template> in <svg> is not
+ // an HTML template with .content at this point; it is just an unknown
+ // SVGElement so we don't have to stamp it
+ var t1 = el.shadowRoot.querySelector('#t1');
+ el.shadowRoot.appendChild(t1.content.cloneNode(true));
+ var t2 = el.shadowRoot.querySelector('#t2');
+ el.shadowRoot.appendChild(t2.content.cloneNode(true));
+ // Everything should now have 'opacity: 0.5'
+ var els = Array.from(el.shadowRoot.querySelectorAll('[id]'));
+ assert.deepEqual(els.map(e => e.getAttribute('id')), ['a', 't1', 't3', 'g', 'circle', 'b', 'c', 't2', 'd']);
+ els.forEach(e => {
+ assert.equal(getComputedStyle(e).opacity, '0.5', `Element with id "${e.id}" does not have the correct opacity`);
+ });
+ document.body.removeChild(el);
+ });
+
+ });
+
+ suite('slotted', function() {
+
+ test('::slotted selectors', function() {
+ var el = document.createElement('x-scoped');
+ document.body.appendChild(el);
+ var content1 = document.createElement('div');
+ content1.slot = 'content1';
+ var content2 = document.createElement('div');
+ content2.slot = 'content2';
+ var content = document.createElement('div');
+ content.className = 'content';
+ el.appendChild(content1);
+ el.appendChild(content2);
+ el.appendChild(content);
+ flush();
+
+ assertComputed(content, '6px');
+ assertComputed(content1, '13px');
+ assertComputed(content2, '14px');
+ document.body.removeChild(el);
+ });
+
+ test('auto ::slotted selector', function() {
+ var x = document.createElement('x-slotted');
+ var d1 = document.createElement('div');
+ d1.classList.add('auto-content');
+ d1.textContent = 'auto-content';
+ document.body.appendChild(x);
+ x.appendChild(d1);
+ flush();
+ assertComputed(d1, '2px');
+ document.body.removeChild(x);
+ });
+
+ test('::slotted + child in complex selector', function() {
+ var x = document.createElement('x-slotted');
+ var d1 = document.createElement('div');
+ d1.classList.add('complex-child');
+ d1.textContent = 'complex-child';
+ document.body.appendChild(x);
+ x.appendChild(d1);
+ flush();
+ assertComputed(d1, '6px');
+ document.body.removeChild(x);
+ });
+
+ test('::slotted + named slot', function() {
+ var x = document.createElement('x-slotted');
+ var d1 = document.createElement('div');
+ d1.setAttribute('slot', 'container')
+ d1.textContent = 'named slot child';
+ document.body.appendChild(x);
+ x.appendChild(d1);
+ flush();
+ assertComputed(d1, '8px');
+ document.body.removeChild(x);
+ });
+
+ });
+
+ suite('dynamic changes', function() {
+
+ test('elements dynamically added/removed from root', function() {
+ var el = document.createElement('x-scoped');
+ document.body.appendChild(el);
+ flush();
+ var d = document.createElement('div');
+ d.classList.add('scoped');
+ d.textContent = 'Dynamically... Scoped!';
+ el.shadowRoot.appendChild(d);
+ flush();
+ assertComputed(d, '4px');
+ document.body.appendChild(d);
+ flush();
+ assert.notInclude(d.getAttribute('style-scoped') || '', el.is, 'scoping attribute not removed when added to other root');
+ assert.notInclude(d.className, el.is, 'scoping class not removed when added to other root');
+ el.shadowRoot.appendChild(d);
+ flush();
+ assertComputed(d, '4px');
+ el.shadowRoot.removeChild(d);
+ flush();
+ assert.notInclude(d.getAttribute('style-scoped') || '', el.is, 'scoping attribute not removed when removed from root');
+ assert.notInclude(d.className, el.is, 'scoping class not removed when removed from root');
+ el.shadowRoot.appendChild(d);
+ flush();
+ assertComputed(d, '4px');
+ document.body.removeChild(el);
+ });
+
+ test('elements dynamically added/removed from host', function() {
+ var el = document.createElement('x-scoped');
+ document.body.appendChild(el);
+ var d = document.createElement('div');
+ d.classList.add('scoped');
+ d.slot = 'blank';
+ d.textContent = 'Dynamically... unScoped!';
+ el.appendChild(d);
+ flush();
+ assertComputed(d, '0px');
+ el.removeChild(d);
+ flush();
+ assert.notInclude(d.getAttribute('style-scoped') || '', el.is, 'scoping attribute not removed when added to other root');
+ assert.notInclude(d.className, el.is, 'scoping class not removed when added to other root');
+ el.appendChild(d);
+ flush();
+ assertComputed(d, '0px');
+ el.removeChild(d);
+ flush();
+ assert.notInclude(d.getAttribute('style-scoped') || '', el.is, 'scoping attribute not removed when removed from root');
+ assert.notInclude(d.className, el.is, 'scoping class not removed when removed from root');
+ el.appendChild(d);
+ flush();
+ assertComputed(d, '0px');
+ document.body.removeChild(el);
+ });
+
+ test('element subtree added via dom api', function() {
+ var el = document.createElement('x-dynamic-scope');
+ document.body.appendChild(el);
+ flush();
+ var container = el.shadowRoot.querySelector('#container');
+ var a = container.querySelector('.added');
+ assertComputed(a, '17px');
+ var b = container.querySelector('.sub-added');
+ assertComputed(b, '18px');
+ document.body.removeChild(el);
+ });
+
+ test('changes to class attribute', function() {
+ var el = document.createElement('x-scoped');
+ el.id = 'el'
+ document.body.appendChild(el);
+ flush();
+ var d = findNode('el.$.computed');
+ assertComputed(d, '0px');
+ d.setAttribute('class', 'computed');
+ assertComputed(d, '15px');
+ d.setAttribute('class', '', 'empty class attr does not remove class');
+ assertComputed(d, '0px');
+ d.setAttribute('class', 'computed ', 'class attr with space does not apply');
+ assertComputed(d, '15px');
+ document.body.removeChild(el);
+ });
+
+ });
+
+ suite('misc', function() {
+
+ var el;
+ setup(function() {
+ el = document.createElement('x-scoped');
+ el.id = 'el';
+ document.body.appendChild(el);
+ flush();
+ });
+
+ teardown(function() {
+ document.body.removeChild(el);
+ });
+
+ test('keyframes change scope', function(done) {
+ var xKeyframes = findNode('el.$.keyframes');
+ // Edge 16 does not support CSS Custom Properties in keyframes
+ if (window.ShadyCSS.nativeCss && navigator.userAgent.match(/Edge/)) {
+ this.skip();
+ }
+ var onAnimationEnd = function() {
+ xKeyframes.removeEventListener('animationend', onAnimationEnd);
+ xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
+ assertComputed(xKeyframes, '100px', 'left');
+
+ xKeyframes = findNode('el.$.keyframes2');
+
+ onAnimationEnd = function() {
+ xKeyframes.removeEventListener('animationend', onAnimationEnd);
+ xKeyframes.removeEventListener('webkitAnimationEnd', onAnimationEnd);
+ assertComputed(xKeyframes, '200px', 'left');
+ done();
+ };
+
+ xKeyframes.addEventListener('animationend', onAnimationEnd);
+ xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);
+
+ xKeyframes.classList.add('special');
+ xKeyframes.setAttribute('animated', '');
+ window.ShadyCSS.ScopingShim.styleElement(xKeyframes);
+ };
+ xKeyframes.addEventListener('animationend', onAnimationEnd);
+ xKeyframes.addEventListener('webkitAnimationEnd', onAnimationEnd);
+ xKeyframes.setAttribute('animated', '');
+ assertComputed(xKeyframes, '0px', 'left');
+ });
+
+ test('keyframe names are transformed correctly', function(done) {
+ makeElement('scoped-keyframes');
+ var e = document.createElement('scoped-keyframes');
+ document.body.appendChild(e);
+ flush();
+ var target = e.shadowRoot.querySelector('#target');
+ var onAnimationEnd = function() {
+ assertComputed(target, '10px');
+ target.removeEventListener('animationend', onAnimationEnd);
+ target.removeEventListener('webkitAnimationEnd', onAnimationEnd);
+ document.body.removeChild(e);
+ done();
+ };
+ target.addEventListener('animationend', onAnimationEnd);
+ target.addEventListener('webkitAnimationEnd', onAnimationEnd);
+ e.setAttribute('animate', '');
+ assertComputed(target, '0px');
+ });
+
+ test('attribute inclusive selector and general sibling selectors', function() {
+ var x = document.createElement('x-attr-selector');
+ x.id = 'x';
+ document.body.appendChild(x);
+ flush();
+ assertComputed(findNode('x.$.bar1'), '2px');
+ assertComputed(findNode('x.$.bar2'), '4px');
+ assertComputed(findNode('x.$.bar3'), '6px');
+ document.body.removeChild(x);
+ });
+
+ test('adjacent sibling selectors', function() {
+ makeElement('x-adjacent-sibling');
+ var x = document.createElement('x-adjacent-sibling');
+ x.id = 'x';
+ document.body.appendChild(x);
+ flush();
+ assertComputed(findNode('x.$.foo1'), '20px');
+ assertComputed(findNode('x.$.foo2'), '4px');
+ assertComputed(findNode('x.$.foo3'), '6px');
+ document.body.removeChild(x);
+ })
+
+ test('svg classes are dynamically scoped correctly', function() {
+ var x = document.createElement('x-dynamic-svg');
+ x.id = 'x';
+ document.body.appendChild(x);
+ flush();
+ var container = findNode('x.$.container');
+ var svg = container.querySelector('.svg');
+ var computed = getComputedStyle(svg);
+ assert.equal(computed.height, '24px');
+ assert.equal(computed.width, '24px');
+ var circle = container.querySelector('#circle');
+ computed = getComputedStyle(circle);
+ assert.equal(computed['fill-opacity'], '0.5');
+ document.body.removeChild(x);
+ });
+
+ test(':host selectors always lowest priority', function() {
+ var priority = findNode('el.$.priority');
+ assertComputed(priority, '9px');
+ el.setAttribute('class', 'wide');
+ assertComputed(priority, '9px');
+ });
+
+ test('svg elements properly scoped', function() {
+ if (window.ShadyCSS.nativeShadow) {
+ this.skip();
+ }
+ var circle = findNode('el.$.circle');
+ var classes = (circle.getAttribute('class') || '').split(/\s+/);
+ assert.include(classes, 'x-scoped');
+ assert.include(classes, 'style-scope');
+ assert.notInclude(classes, 'null');
+ assertComputed(circle, '1px', 'strokeWidth');
+ });
+
+ test('set attribute class has style scoping selectors', function() {
+ if (window.ShadyCSS.nativeShadow) {
+ this.skip();
+ }
+ var s = findNode('el.$.scopeClass');
+ var scope = findNode('el.$.scopeClass.$.scope');
+ assert.isTrue(s.classList.contains('style-scope'));
+ assert.isTrue(s.classList.contains('x-scoped'));
+ s.setAttribute('class', 'foo');
+ assert.isTrue(s.classList.contains('foo'));
+ assert.isTrue(s.classList.contains('style-scope'));
+ assert.isTrue(s.classList.contains('x-scoped'));
+ //
+ assert.isTrue(scope.classList.contains('style-scope'));
+ assert.isTrue(scope.classList.contains('x-scope-class'));
+ scope.setAttribute('class', 'foo');
+ assert.isTrue(scope.classList.contains('foo'));
+ assert.isTrue(scope.classList.contains('style-scope'));
+ assert.isTrue(scope.classList.contains('x-scope-class'));
+ });
+
+ test('specificity of :host selector with class', function() {
+ var e1 = document.createElement('x-specificity');
+ document.body.appendChild(e1);
+ flush();
+ assertComputed(e1, '1px');
+ document.body.removeChild(e1);
+ var e2 = document.createElement('x-specificity');
+ e2.setAttribute('class', 'bar');
+ document.body.appendChild(e2);
+ flush();
+ assertComputed(e2, '2px');
+ document.body.removeChild(e2);
+ });
+
+ test('self-use is supported', function() {
+ makeElement('self-test');
+ var e = document.createElement('self-test');
+ document.body.appendChild(e);
+ flush();
+ assertComputed(e.shadowRoot.querySelector('a'), '10px');
+ document.body.removeChild(e);
+ });
+
+ test('nth-child selectors work correctly with plusses', function() {
+ makeElement('nth-plus-one');
+ var e = document.createElement('nth-plus-one');
+ document.body.appendChild(e);
+ flush();
+ assertComputed(e.shadowRoot.querySelector('.foo'), 'rgb(255, 0, 0)', 'color');
+ document.body.removeChild(e);
+ });
+
+ test(':-webkit-any and :-moz-any selectors are supported', function() {
+ if (navigator.userAgent.match(/Trident|Edge/)) {
+ this.skip();
+ }
+ makeElement('any-selector');
+ var e = document.createElement('any-selector');
+ document.body.appendChild(e);
+ flush();
+ assertComputed(e.shadowRoot.querySelector('div'), 'rgb(123, 123, 123)', 'color');
+ assertComputed(e.shadowRoot.querySelector('span'), 'rgb(123, 123, 123)', 'color');
+ document.body.removeChild(e);
+ });
+
+ test(':host() sets mixin definitions correctly', function() {
+ makeElement('bad-mixin');
+ var e = document.createElement('bad-mixin');
+ document.body.appendChild(e);
+ flush();
+ assertComputed(e.shadowRoot.querySelector('div'), '0px');
+ document.body.removeChild(e);
+ });
+
+ test('trees with elements missing styles render correctly', function() {
+ makeElement('x-parent-skip');
+ makeElement('x-skip');
+ makeElement('x-child-skip');
+ const p = document.createElement('x-parent-skip');
+ document.body.appendChild(p);
+ flush();
+ const inner = p.shadowRoot.querySelector('x-skip').shadowRoot.querySelector('x-child-skip').shadowRoot.querySelector('div');
+ assertComputed(inner, '10px');
+ document.body.removeChild(p);
+ });
+
+ test('trees with elements missing templates render correctly', function() {
+ makeElement('no-shadow');
+ const p = document.createElement('x-parent-skip');
+ const n = document.createElement('no-shadow');
+ const c = document.createElement('x-child-skip');
+ document.body.appendChild(p);
+ p.shadowRoot.appendChild(n);
+ n.shadowRoot.appendChild(c);
+ flush();
+ const inner = c.shadowRoot.querySelector('div');
+ assertComputed(inner, '10px');
+ document.body.removeChild(p);
+ })
+
+ });
+
+ suite('unscoping', function() {
+ suiteSetup(function() {
+ makeElement('shady-unscoped');
+ });
+ test('styles with "shady-unscoped" attr work in Shady and Shadow', function() {
+ var el = document.createElement('shady-unscoped');
+ document.body.appendChild(el);
+ flush();
+ var div = el.shadowRoot.querySelector('div');
+ assertComputed(div, 'rgb(255, 0, 0)', 'color');
+ document.body.removeChild(el);
+ });
+ test('styles with "shady-unscoped" attr deduplicate', function(){
+ if (window.ShadyCSS.nativeShadow) {
+ this.skip();
+ }
+ makeElement('shady-unscoped-2');
+ var el1 = document.createElement('shady-unscoped');
+ var el2 = document.createElement('shady-unscoped-2');
+ document.body.appendChild(el1);
+ document.body.appendChild(el2);
+ flush();
+ assert.equal(document.querySelectorAll('style[shady-unscoped]').length, 1);
+ document.body.removeChild(el1);
+ document.body.removeChild(el2);
+ });
+ test('@apply does not work in shady-unscoped', function() {
+ makeElement('unscoped-apply-user');
+ makeElement('unscoped-apply');
+ var el = document.createElement('unscoped-apply');
+ document.body.appendChild(el);
+ flush();
+ var inner = el.shadowRoot.querySelector('unscoped-apply-user');
+ var target = inner.shadowRoot.querySelector('div');
+ assertComputed(target, '0px');
+ document.body.removeChild(el);
+ });
+ });
+
+})();
+</script>
+</body>
+</html>