Skip to content

Commit

Permalink
Support more expressive :root and html selectors
Browse files Browse the repository at this point in the history
Selectors like `:root[dir="rtl"]` and `html.foo` are now supported

Support `html` selector for `custom-style`

Fixes #3902
Fixes #3924
  • Loading branch information
dfreedm committed Sep 13, 2016
1 parent ff6e884 commit 2a8f21a
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 5 deletions.
20 changes: 15 additions & 5 deletions src/lib/style-properties.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
self.decorateRule(rule);
// mark in-order position of ast rule in styles block, used for cache key
rule.index = ruleIndex++;
self.whenHostOrRootRule(scope, rule, style, function(info) {
self.whenHostOrRootRule(scope, rule, style, false, function(info) {
// we can't cache styles with :host and :root props in @media rules
if (rule.parent.type === styleUtil.ruleTypes.MEDIA_RULE) {
scope.__notStyleScopeCacheable = true;
Expand Down Expand Up @@ -285,18 +285,25 @@
return {properties: props, key: o};
},

whenHostOrRootRule: function(scope, rule, style, callback) {
whenHostOrRootRule: function(scope, rule, style, runtime, callback) {
if (!rule.propertyInfo) {
self.decorateRule(rule);
}
if (!rule.propertyInfo.properties) {
return;
}
var checkRoot = function(hostScope, selector) {
if (runtime) {
return selector.indexOf(':root') === 0 || (hostScope === 'html' && parsedSelector.indexOf('html') === 0);
} else {
return selector === ':root' || selector === 'html';
}
};
var hostScope = scope.is ?
styleTransformer._calcHostScope(scope.is, scope.extends) :
'html';
var parsedSelector = rule.parsedSelector;
var isRoot = parsedSelector === ':root';
var isRoot = checkRoot(hostScope, parsedSelector);
var isHost = 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
Expand All @@ -309,7 +316,7 @@
isHost = !isRoot && parsedSelector.indexOf(hostScope) === 0;
}
if (cssBuild === 'shadow') {
isRoot = parsedSelector === ':host > *' || parsedSelector === 'html';
isRoot = parsedSelector === ':host > *' || checkRoot(hostScope, parsedSelector);
isHost = isHost && !isRoot;
}
if (!isRoot && !isHost) {
Expand All @@ -331,6 +338,9 @@
// parsedSelector fallback for 'shady' css build
selectorToMatch = rule.transformedSelector || rule.parsedSelector;
}
if (isRoot && runtime && hostScope === 'html') {
selectorToMatch = rule.transformedSelector || rule.parsedSelector;
}
callback({
selector: selectorToMatch,
isHost: isHost,
Expand All @@ -343,7 +353,7 @@
// note: active rules excludes non-matching @media rules
styleUtil.forActiveRulesInStyles(scope._styles, function(rule, style) {
// if scope is StyleDefaults, use _element for matchesSelector
self.whenHostOrRootRule(scope, rule, style, function(info) {
self.whenHostOrRootRule(scope, rule, style, true, function(info) {
var element = scope._element || scope;
if (matchesSelector.call(element, info.selector)) {
if (info.isHost) {
Expand Down
63 changes: 63 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,35 @@
assertComputed(el, '2px');
}
);

suite('top-level selectors', function() {
var el;
function activateSelectors() {
document.documentElement.setAttribute('foo', 'bar');
Polymer.updateStyles();
}
suiteSetup(function() {
el = document.createElement('x-top-selectors');
document.body.appendChild(el);
});
teardown(function() {
document.documentElement.removeAttribute('foo');
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

0 comments on commit 2a8f21a

Please sign in to comment.