Skip to content

Commit

Permalink
Merge pull request #3951 from Polymer/html-selector
Browse files Browse the repository at this point in the history
Support more expressive `:root` and `html` selectors
  • Loading branch information
Steve Orvell authored Sep 26, 2016
2 parents 1a01896 + 63433c8 commit 03989ac
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 12 deletions.
20 changes: 13 additions & 7 deletions src/lib/style-properties.html
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,13 @@
return {properties: props, key: o};
},

_rootSelector: /:root|:host\s*>\s*\*/,

_checkRoot: function(hostScope, selector) {
return Boolean(selector.match(this._rootSelector)) ||
(hostScope === 'html' && selector.indexOf('html') > -1);
},

whenHostOrRootRule: function(scope, rule, style, callback) {
if (!rule.propertyInfo) {
self.decorateRule(rule);
Expand All @@ -296,22 +303,18 @@
styleTransformer._calcHostScope(scope.is, scope.extends) :
'html';
var parsedSelector = rule.parsedSelector;
var isRoot = parsedSelector === ':root';
var isHost = parsedSelector.indexOf(':host') === 0;
var isRoot = this._checkRoot(hostScope, parsedSelector);
var isHost = !isRoot && parsedSelector.indexOf(':host') === 0;
// build info is either in scope (when scope is an element) or in the style
// when scope is the default scope; note: this allows default scope to have
// mixed mode built and unbuilt styles.
var cssBuild = scope.__cssBuild || style.__cssBuild;
if (cssBuild === 'shady') {
// :root -> x-foo > *.x-foo for elements and html for custom-style
isRoot = parsedSelector === (hostScope + ' > *.' + hostScope) || parsedSelector.indexOf('html') !== -1;
isRoot = parsedSelector === (hostScope + ' > *.' + hostScope) || parsedSelector.indexOf('html') > -1;
// :host -> x-foo for elements, but sub-rules have .x-foo in them
isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0;
}
if (cssBuild === 'shadow') {
isRoot = parsedSelector === ':host > *' || parsedSelector === 'html';
isHost = isHost && !isRoot;
}
if (!isRoot && !isHost) {
return;
}
Expand All @@ -331,6 +334,9 @@
// parsedSelector fallback for 'shady' css build
selectorToMatch = rule.transformedSelector || rule.parsedSelector;
}
if (isRoot && hostScope === 'html') {
selectorToMatch = rule.transformedSelector || rule.parsedSelector;
}
callback({
selector: selectorToMatch,
isHost: isHost,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/style-transformer.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
var self = this;
cb = function(rule) {
rule.selector = self._slottedToContent(rule.selector);
rule.selector = rule.selector.replace(ROOT, ':host > *');
if (callback) {
callback(rule);
}
Expand Down Expand Up @@ -189,6 +190,7 @@
var self = this;
selector = selector.trim();
selector = this._slottedToContent(selector);
selector = selector.replace(ROOT, ':host > *');
selector = selector.replace(CONTENT_START, HOST + ' $1');
selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
if (!stop) {
Expand Down Expand Up @@ -289,9 +291,7 @@
},

normalizeRootSelector: function(rule) {
if (rule.selector === ROOT) {
rule.selector = 'html';
}
rule.selector = rule.selector.replace(ROOT, 'html');
},

_transformDocumentSelector: function(selector) {
Expand Down
65 changes: 65 additions & 0 deletions test/unit/custom-style.html
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@
}
}
</style>

<style is="custom-style">
:root[foo="bar"] {
--foo: 10px dotted red;
}
html {
--html: 10px dotted yellow;
}
html[foo="bar"] {
--html-foo: 10px dotted green;
}
</style>
</head>
<body>
<div class="italic">italic</div>
Expand Down Expand Up @@ -283,6 +295,25 @@
</template>
</dom-module>

<dom-module id="x-top-selectors">
<template>
<style>
#foo {
border: var(--foo);
}
#html {
border: var(--html);
}
#htmlFoo {
border: var(--html-foo);
}
</style>
<div id="foo"></div>
<div id="html"></div>
<div id="htmlFoo"></div>
</template>
</dom-module>

<script>
HTMLImports.whenReady(function() {
Polymer({
Expand All @@ -304,6 +335,9 @@
Polymer({
is: 'x-blue-bold-text'
});
Polymer({
is: 'x-top-selectors'
});
})
</script>

Expand Down Expand Up @@ -532,6 +566,37 @@
assertComputed(el, '2px');
}
);

suite('top-level selectors', function() {
var el;
function activateSelectors() {
document.documentElement.setAttribute('foo', 'bar');
CustomElements.takeRecords();
Polymer.updateStyles();
}
suiteSetup(function() {
el = document.createElement('x-top-selectors');
document.body.appendChild(el);
});
teardown(function() {
document.documentElement.removeAttribute('foo');
CustomElements.takeRecords();
Polymer.updateStyles();
});
test(':root...', function() {
assertComputed(el.$.foo, '0px');
activateSelectors();
assertComputed(el.$.foo, '10px');
});
test('html', function() {
assertComputed(el.$.html, '10px');
});
test('html...', function() {
assertComputed(el.$.htmlFoo, '0px');
activateSelectors();
assertComputed(el.$.htmlFoo, '10px');
});
});
});


Expand Down
37 changes: 35 additions & 2 deletions test/unit/styling-cross-scope-var.html
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,32 @@
</script>
</dom-module>

<dom-module id="root-styles">
<template>
<style>
:root {
--root-border: 2px solid black;
}
:host > * {
--host-star-border: 10px solid orange;
}
#root {
border: var(--root-border);
}
#host {
border: var(--host-star-border);
}
</style>
<div id="root"></div>
<div id="host"></div>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({is: 'root-styles'});
});
</script>
</dom-module>

<script>
suite('scoped-styling-var', function() {

Expand Down Expand Up @@ -1073,8 +1099,6 @@
assertComputed(x.$.child, '6px');
});



test('styles update based on root customStyle changes', function() {
assertComputed(styled.$.dynamic, '0px');
Polymer.StyleDefaults.customStyle['--dynamic'] = '4px solid navy';
Expand Down Expand Up @@ -1234,6 +1258,7 @@
e.updateStyles();
assertComputed(e, 'rgb(255, 0, 0)', null, 'background-color');
});

test('updateStyles removes the correct number of style properties', function() {
if (!Polymer.Settings.useNativeCSSProperties) {
this.skip();
Expand Down Expand Up @@ -1274,6 +1299,14 @@
CustomElements.takeRecords();
assertComputed(e.$.child, '5px');
});

test(':root and :host > * rules apply to all shadowroot children', function() {
var e = document.createElement('root-styles');
document.body.appendChild(e);
CustomElements.takeRecords();
assertComputed(e.$.root, '2px');
assertComputed(e.$.host, '10px');
});
});

</script>
Expand Down
23 changes: 23 additions & 0 deletions test/unit/styling-scoped-elements.html
Original file line number Diff line number Diff line change
Expand Up @@ -630,3 +630,26 @@
Polymer({is: 'x-slotted'});
</script>
</dom-module>

<dom-module id="root-styles">
<template>
<style>
:root {
color: rgb(123, 123, 123);
--root-padding: 10px;
}
:host > * {
border: 2px solid black;
--host-margin: 10px;
}
#child {
padding: var(--root-padding);
margin: var(--host-margin);
}
</style>
<div id="child">Child</div>
</template>
<script>
Polymer({is: 'root-styles'});
</script>
</dom-module>
10 changes: 10 additions & 0 deletions test/unit/styling-scoped.html
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,16 @@
assertComputed(e.$.bar3, '6px');
});

test('ShadowRoot-wide selectors', function() {
var e = document.createElement('root-styles');
document.body.appendChild(e);
CustomElements.takeRecords();
// :root
assertComputed(e.$.child, 'rgb(123, 123, 123)', 'color');
// :host > *
assertComputed(e.$.child, '2px');
});

suite('scoped-styling-shady-only', function() {

suiteSetup(function() {
Expand Down

0 comments on commit 03989ac

Please sign in to comment.