Skip to content

Commit d77e073

Browse files
author
Steven Orvell
committed
Add support for styles with a shady-unscoped attribute
This is being added to 1.x and it's ported forward here so it can be used in hybrid mode.
1 parent 314bada commit d77e073

5 files changed

+175
-5
lines changed

lib/utils/style-gather.html

+23-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
const MODULE_STYLE_LINK_SELECTOR = 'link[rel=import][type~=css]';
1616
const INCLUDE_ATTR = 'include';
17+
const SHADY_UNSCOPED_ATTR = 'shady-unscoped';
18+
const unscopedStyleImportsMap = new WeakMap();
1719

1820
function importModule(moduleId) {
1921
const /** Polymer.DomModule */ PolymerDomModule = customElements.get('dom-module');
@@ -109,8 +111,14 @@
109111
cssText += this.cssFromModules(include);
110112
}
111113
e.parentNode.removeChild(e);
112-
cssText += baseURI ?
114+
const styleCss = baseURI ?
113115
Polymer.ResolveUrl.resolveCss(e.textContent, baseURI) : e.textContent;
116+
if (window.ShadyDOM && e.hasAttribute(SHADY_UNSCOPED_ATTR)) {
117+
e.textContent = styleCss;
118+
document.head.insertBefore(e, document.head.firstChild);
119+
} else {
120+
cssText += styleCss;
121+
}
114122
}
115123
return cssText;
116124
},
@@ -145,9 +153,20 @@
145153
// under the HTMLImports polyfill, there will be no 'body',
146154
// but the import pseudo-doc can be used directly.
147155
let container = importDoc.body ? importDoc.body : importDoc;
148-
cssText +=
149-
Polymer.ResolveUrl.resolveCss(container.textContent,
150-
importDoc.baseURI);
156+
const importCss = Polymer.ResolveUrl.resolveCss(container.textContent,
157+
importDoc.baseURI);
158+
// support the shady-unscoped promoting styles to main document
159+
if (window.ShadyDOM && p.hasAttribute(SHADY_UNSCOPED_ATTR)) {
160+
if (!unscopedStyleImportsMap.has(importDoc)) {
161+
unscopedStyleImportsMap.set(importDoc);
162+
const style = document.createElement('style');
163+
style.setAttribute(SHADY_UNSCOPED_ATTR, '');
164+
style.textContent = importCss;
165+
document.head.insertBefore(style, document.head.firstChild);
166+
}
167+
} else {
168+
cssText += importCss;
169+
}
151170
}
152171
}
153172
return cssText;

test/runner.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@
7373
'unit/mixin-utils.html',
7474
'unit/mixin-behaviors.html',
7575
'unit/render-status.html',
76-
'unit/dir.html'
76+
'unit/dir.html',
77+
'unit/shady-unscoped-style.html'
7778
];
7879

7980
// http://eddmann.com/posts/cartesian-product-in-javascript/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.import {
2+
border: 2px solid yellow;
3+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<dom-module id="global-shared1">
2+
<link rel="import" type="css" shady-unscoped href="shady-unscoped-style-import-css.html">
3+
<template>
4+
<style shady-unscoped>
5+
:root {
6+
--zug: margin: 10px;
7+
}
8+
9+
.happy {
10+
@apply --zug;
11+
border: 1px solid green;
12+
}
13+
</style>
14+
15+
<style>
16+
.normal {
17+
border: 3px solid orange;
18+
}
19+
</style>
20+
</template>
21+
</dom-module>
22+
23+
<dom-module id="global-shared2">
24+
<link rel="import" type="css" shady-unscoped href="shady-unscoped-style-import-css.html">
25+
</dom-module>
26+

test/unit/shady-unscoped-style.html

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<script src="../../../webcomponentsjs/webcomponents-lite.js"></script>
5+
<script src="../../../web-component-tester/browser.js"></script>
6+
<link rel="import" href="../../polymer.html">
7+
<link rel="import" href="shady-unscoped-style-import.html">
8+
</head>
9+
<body>
10+
11+
<custom-style>
12+
<style is="custom-style">
13+
html {
14+
--foo: {
15+
padding: 10px;
16+
}
17+
}
18+
</style>
19+
</custom-style>
20+
21+
<dom-module id="my-element">
22+
23+
<template>
24+
<style include="global-shared1 global-shared2">
25+
:host {
26+
display: block;
27+
}
28+
29+
.happy {
30+
@apply --foo;
31+
}
32+
</style>
33+
<div id="fromStyle" class="happy">Happy: green</div>
34+
<div id="fromImport" class="import">Happy: yellow</div>
35+
<div id="normal" class="normal">Happy: orange</div>
36+
</template>
37+
38+
<script>
39+
HTMLImports.whenReady(function() {
40+
Polymer({
41+
is: 'my-element'
42+
});
43+
});
44+
</script>
45+
46+
</dom-module>
47+
48+
<dom-module id="my-element2">
49+
50+
<template>
51+
<style include="global-shared1">
52+
:host {
53+
display: block;
54+
}
55+
56+
</style>
57+
<div id="fromStyle" class="happy">Happy: green</div>
58+
<div id="fromImport" class="import">Happy: yellow</div>
59+
<div id="normal" class="normal">Happy: orange</div>
60+
</template>
61+
62+
<script>
63+
HTMLImports.whenReady(function() {
64+
Polymer({ is: 'my-element2'});
65+
});
66+
</script>
67+
68+
</dom-module>
69+
70+
<my-element></my-element>
71+
<my-element2></my-element2>
72+
73+
<script>
74+
suite('shady-unscoped styles', function() {
75+
76+
function assertComputed(element, value, property, pseudo) {
77+
var computed = getComputedStyle(element, pseudo);
78+
property = property || 'border-top-width';
79+
if (Array.isArray(value)) {
80+
assert.oneOf(computed[property], value, 'computed style incorrect for ' + property);
81+
} else {
82+
assert.equal(computed[property], value, 'computed style incorrect for ' + property);
83+
}
84+
}
85+
86+
var el1 = document.querySelector('my-element');
87+
var el2 = document.querySelector('my-element2');
88+
89+
test('unscoped styles apply', function() {
90+
assertComputed(el1.$.fromStyle, '1px');
91+
assertComputed(el1.$.fromImport, '2px');
92+
assertComputed(el2.$.fromStyle, '1px');
93+
assertComputed(el2.$.fromImport, '2px');
94+
});
95+
96+
test('shared and @apply apply when used with unscoped styles', function() {
97+
assertComputed(el1.$.fromStyle, '10px', 'padding');
98+
assertComputed(el1.$.normal, '3px');
99+
assertComputed(el2.$.normal, '3px');
100+
})
101+
102+
test('unscoped styling de-duped in ShadyDOM', function() {
103+
if (!window.ShadyDOM) {
104+
this.skip();
105+
}
106+
assert.equal(document.head.querySelectorAll('style[shady-unscoped]').length, 2);
107+
});
108+
109+
test('@apply does not apply under ShadyDOM for shady-unscoped styles', function() {
110+
if (!window.ShadyDOM) {
111+
this.skip();
112+
}
113+
assertComputed(el1.$.fromStyle, '0px', 'margin');
114+
assertComputed(el2.$.fromStyle, '0px', 'margin');
115+
})
116+
117+
118+
});
119+
</script>
120+
</body>
121+
</html>

0 commit comments

Comments
 (0)