Skip to content

Commit fea64b9

Browse files
committed
Translate :root to :host > * for element styles
Support `:host > *` as root rules for CSS Custom Properties Fixes #3991
1 parent a49b366 commit fea64b9

5 files changed

+73
-8
lines changed

src/lib/style-properties.html

+4-6
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,10 @@
285285
return {properties: props, key: o};
286286
},
287287

288+
_rootSelector: /(?:^:root)|(?::host\s*>\s*\*)/,
289+
288290
_checkRoot: function(hostScope, selector) {
289-
return selector.indexOf(':root') === 0 ||
291+
return Boolean(selector.match(this._rootSelector)) ||
290292
(hostScope === 'html' && selector.indexOf('html') === 0);
291293
},
292294

@@ -302,7 +304,7 @@
302304
'html';
303305
var parsedSelector = rule.parsedSelector;
304306
var isRoot = this._checkRoot(hostScope, parsedSelector);
305-
var isHost = parsedSelector.indexOf(':host') === 0;
307+
var isHost = !isRoot && parsedSelector.indexOf(':host') === 0;
306308
// build info is either in scope (when scope is an element) or in the style
307309
// when scope is the default scope; note: this allows default scope to have
308310
// mixed mode built and unbuilt styles.
@@ -313,10 +315,6 @@
313315
// :host -> x-foo for elements, but sub-rules have .x-foo in them
314316
isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0;
315317
}
316-
if (cssBuild === 'shadow') {
317-
isRoot = parsedSelector === ':host > *' || this._checkRoot(hostScope, parsedSelector);
318-
isHost = isHost && !isRoot;
319-
}
320318
if (!isRoot && !isHost) {
321319
return;
322320
}

src/lib/style-transformer.html

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
var self = this;
105105
cb = function(rule) {
106106
rule.selector = self._slottedToContent(rule.selector);
107+
rule.selector = rule.selector.replace(ROOT, ':host > *');
107108
if (callback) {
108109
callback(rule);
109110
}
@@ -189,6 +190,7 @@
189190
var self = this;
190191
selector = selector.trim();
191192
selector = this._slottedToContent(selector);
193+
selector = selector.replace(ROOT, ':host > *');
192194
selector = selector.replace(CONTENT_START, HOST + ' $1');
193195
selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
194196
if (!stop) {

test/unit/styling-cross-scope-var.html

+35-2
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,32 @@
831831
</script>
832832
</dom-module>
833833

834+
<dom-module id="root-styles">
835+
<template>
836+
<style>
837+
:root {
838+
--root-border: 2px solid black;
839+
}
840+
:host > * {
841+
--host-star-border: 10px solid orange;
842+
}
843+
#root {
844+
border: var(--root-border);
845+
}
846+
#host {
847+
border: var(--host-star-border);
848+
}
849+
</style>
850+
<div id="root"></div>
851+
<div id="host"></div>
852+
</template>
853+
<script>
854+
HTMLImports.whenReady(function() {
855+
Polymer({is: 'root-styles'});
856+
});
857+
</script>
858+
</dom-module>
859+
834860
<script>
835861
suite('scoped-styling-var', function() {
836862

@@ -1073,8 +1099,6 @@
10731099
assertComputed(x.$.child, '6px');
10741100
});
10751101

1076-
1077-
10781102
test('styles update based on root customStyle changes', function() {
10791103
assertComputed(styled.$.dynamic, '0px');
10801104
Polymer.StyleDefaults.customStyle['--dynamic'] = '4px solid navy';
@@ -1234,6 +1258,7 @@
12341258
e.updateStyles();
12351259
assertComputed(e, 'rgb(255, 0, 0)', null, 'background-color');
12361260
});
1261+
12371262
test('updateStyles removes the correct number of style properties', function() {
12381263
if (!Polymer.Settings.useNativeCSSProperties) {
12391264
this.skip();
@@ -1274,6 +1299,14 @@
12741299
CustomElements.takeRecords();
12751300
assertComputed(e.$.child, '5px');
12761301
});
1302+
1303+
test(':root and :host > * rules apply to all shadowroot children', function() {
1304+
var e = document.createElement('root-styles');
1305+
document.body.appendChild(e);
1306+
CustomElements.takeRecords();
1307+
assertComputed(e.$.root, '2px');
1308+
assertComputed(e.$.host, '10px');
1309+
});
12771310
});
12781311

12791312
</script>

test/unit/styling-scoped-elements.html

+23
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,26 @@
630630
Polymer({is: 'x-slotted'});
631631
</script>
632632
</dom-module>
633+
634+
<dom-module id="root-styles">
635+
<template>
636+
<style>
637+
:root {
638+
color: rgb(123, 123, 123);
639+
--root-padding: 10px;
640+
}
641+
:host > * {
642+
border: 2px solid black;
643+
--host-margin: 10px;
644+
}
645+
#child {
646+
padding: var(--root-padding);
647+
margin: var(--host-margin);
648+
}
649+
</style>
650+
<div id="child">Child</div>
651+
</template>
652+
<script>
653+
Polymer({is: 'root-styles'});
654+
</script>
655+
</dom-module>

test/unit/styling-scoped.html

+9
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,15 @@
329329
assertComputed(e.$.bar3, '6px');
330330
});
331331

332+
test('ShadowRoot-wide selectors', function() {
333+
var e = document.createElement('root-styles');
334+
document.body.appendChild(e);
335+
// :root
336+
assertComputed(e.$.child, 'rgb(123, 123, 123)', 'color');
337+
// :host > *
338+
assertComputed(e.$.child, '2px');
339+
});
340+
332341
suite('scoped-styling-shady-only', function() {
333342

334343
suiteSetup(function() {

0 commit comments

Comments
 (0)