Skip to content

Commit 7d6e6a7

Browse files
author
Steven Orvell
committed
Fixes #1900: adds basic support for host-context(...)
1 parent 9dd38f6 commit 7d6e6a7

File tree

3 files changed

+52
-8
lines changed

3 files changed

+52
-8
lines changed

src/lib/style-transformer.html

+26-7
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
3737
* ::shadow, /deep/: processed simimlar to ::content
3838
39-
* :host-context(...): NOT SUPPORTED
39+
* :host-context(...): scopeName..., ... scopeName
4040
4141
*/
4242
var api = {
@@ -156,28 +156,42 @@
156156

157157
_transformComplexSelector: function(selector, scope, hostScope) {
158158
var stop = false;
159+
var hostContext = false;
159160
var self = this;
160161
selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
161162
if (!stop) {
162163
var o = self._transformCompoundSelector(s, c, scope, hostScope);
163-
if (o.stop) {
164-
stop = true;
165-
}
164+
stop = stop || o.stop;
165+
hostContext = hostContext || o.hostContext;
166166
c = o.combinator;
167167
s = o.value;
168168
} else {
169169
s = s.replace(SCOPE_JUMP, ' ');
170170
}
171171
return c + s;
172172
});
173+
if (hostContext) {
174+
selector = selector.replace(CONTEXT_MARKER_MATCH,
175+
function(m, pre, paren, post) {
176+
return pre + paren + ' ' + hostScope + post +
177+
COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;
178+
});
179+
}
173180
return selector;
174181
},
175182

176183
_transformCompoundSelector: function(selector, combinator, scope, hostScope) {
177184
// replace :host with host scoping class
178185
var jumpIndex = selector.search(SCOPE_JUMP);
179-
if (selector.indexOf(HOST) >=0) {
180-
// :host(...)
186+
var hostContext = false;
187+
if (selector.indexOf(HOST_CONTEXT) >=0) {
188+
// :host-context(...) -> ##...##
189+
selector = selector.replace(HOST_CONTEXT_PAREN, function(m, host, paren) {
190+
hostContext = true;
191+
return CONTEXT_MARKER + paren + CONTEXT_MARKER;
192+
});
193+
} else if (selector.indexOf(HOST) >=0) {
194+
// :host(...) -> scopeName...
181195
selector = selector.replace(HOST_PAREN, function(m, host, paren) {
182196
return hostScope + paren;
183197
});
@@ -199,7 +213,8 @@
199213
selector = selector.replace(SCOPE_JUMP, ' ');
200214
stop = true;
201215
}
202-
return {value: selector, combinator: combinator, stop: stop};
216+
return {value: selector, combinator: combinator, stop: stop,
217+
hostContext: hostContext};
203218
},
204219

205220
_transformSimpleSelector: function(selector, scope) {
@@ -243,6 +258,10 @@
243258
// :host(:not([selected]), more general support requires
244259
// parsing which seems like overkill
245260
var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
261+
var HOST_CONTEXT = ':host-context';
262+
var HOST_CONTEXT_PAREN = /(\:host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
263+
var CONTEXT_MARKER = '##';
264+
var CONTEXT_MARKER_MATCH = /(.*)##(.*)##(.*)/;
246265
var CONTENT = '::content';
247266
var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
248267
var CSS_CLASS_PREFIX = '.';

test/unit/styling-scoped-elements.html

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
<dom-module id="x-gchild">
2+
<style>
3+
:host-context(.wide) #target {
4+
border: 10px solid orange;
5+
}
6+
</style>
7+
<template>
8+
<div id="target">x-gchild</div>
9+
</template>
10+
</dom-module>
11+
<script>
12+
Polymer({
13+
is: 'x-gchild'
14+
});
15+
</script>
16+
117
<dom-module id="x-child">
218
<template>
319
<div id="simple">simple</div>
@@ -6,6 +22,8 @@
622
<div id="media">media</div>
723
<div id="shadow" class="shadowTarget">shadowTarget</div>
824
<div id="deep" class="deepTarget">deepTarget</div>
25+
<x-gchild id="gchild1"></x-gchild>
26+
<x-gchild id="gchild2" class="wide"></x-gchild>
927
</template>
1028
</dom-module>
1129
<script>

test/unit/styling-scoped.html

+8-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@
6464

6565
});
6666

67+
test(':host-context(...)', function() {
68+
assertComputed(styled.$.child.$.gchild1.$.target, '0px');
69+
assertComputed(styled.$.child.$.gchild2.$.target, '10px');
70+
assertComputed(styledWide.$.child.$.gchild1.$.target, '10px');
71+
assertComputed(styledWide.$.child.$.gchild2.$.target, '10px');
72+
});
73+
6774
test('scoped selectors, simple and complex', function() {
6875
assertComputed(styled.$.simple, '3px');
6976
assertComputed(styled.$.complex1, '4px');
@@ -192,7 +199,7 @@
192199

193200
test('styles shimmed in registration order', function() {
194201
var s$ = document.head.querySelectorAll('style[scope]');
195-
var expected = ['x-child2', 'x-styled', 'x-button', 'x-dynamic-scope'];
202+
var expected = ['x-gchild', 'x-child2', 'x-styled', 'x-button', 'x-dynamic-scope'];
196203
var actual = [];
197204
for (var i=0; i<s$.length; i++) {
198205
actual.push(s$[i].getAttribute('scope'));

0 commit comments

Comments
 (0)