Skip to content

Commit 997240a

Browse files
author
Steven Orvell
committed
Fixes #3739: correctly shim :host(.element-name) as element-name.element-name.
Also converts `:host(not-element-name)` to a non-matching selector.
1 parent 06bc9db commit 997240a

3 files changed

Lines changed: 38 additions & 6 deletions

File tree

‎src/lib/style-transformer.html‎

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,7 @@
206206
if (selector.indexOf(HOST_CONTEXT) >=0) {
207207
hostContext = true;
208208
} else if (selector.indexOf(HOST) >=0) {
209-
// :host(...) -> scopeName...
210-
selector = selector.replace(HOST_PAREN, function(m, host, paren) {
211-
return (m.indexOf(hostScope) === -1 ? hostScope : '') + paren;
212-
});
213-
// now normal :host
214-
selector = selector.replace(HOST, hostScope);
209+
selector = this._transformHostSelector(selector, hostScope);
215210
// replace other selectors with scoping class
216211
} else if (jumpIndex !== 0) {
217212
selector = scope ? this._transformSimpleSelector(selector, scope) :
@@ -238,6 +233,30 @@
238233
return p$.join(PSEUDO_PREFIX);
239234
},
240235

236+
// :host(...) -> scopeName...
237+
_transformHostSelector: function(selector, hostScope) {
238+
var m = HOST_PAREN.exec(selector);
239+
HOST_PAREN.lastIndex = 0;
240+
var paren = m && m[2].trim();
241+
if (paren) {
242+
var selectorKind = /[[.:#*]/;
243+
if (!paren[0].match(selectorKind)) {
244+
var typeSelector = paren.split(selectorKind)[0];
245+
if (typeSelector === hostScope) {
246+
hostScope = '';
247+
} else {
248+
return SELECTOR_NO_MATCH;
249+
}
250+
}
251+
return selector.replace(HOST_PAREN, function(m, host, paren) {
252+
return hostScope + paren;
253+
});
254+
} else {
255+
// now normal :host
256+
return selector.replace(HOST, hostScope);
257+
}
258+
},
259+
241260
documentRule: function(rule) {
242261
// reset selector in case this is redone.
243262
rule.selector = rule.parsedSelector;
@@ -283,6 +302,7 @@
283302
var PSEUDO_PREFIX = ':';
284303
var CLASS = 'class';
285304
var CONTENT_START = new RegExp('^(' + CONTENT + ')');
305+
var SELECTOR_NO_MATCH = 'should_not_match';
286306

287307
// exports
288308
return api;

‎test/unit/styling-scoped-elements.html‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,10 @@
554554
display: block;
555555
border: 4px solid orange;
556556
}
557+
558+
:host(.x-shared1) {
559+
padding: 8px;
560+
};
557561
</style>
558562
</template>
559563
</dom-module>

‎test/unit/styling-scoped.html‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,14 @@
410410
assertComputed(s2, '4px');
411411
});
412412

413+
test(':host with superset of element tag selector does not leak', function() {
414+
var t = document.createElement('div');
415+
t.textContent = 'host leak test';
416+
t.classList.add('x-shared1');
417+
document.body.appendChild(t);
418+
assertComputed(t, '0px', 'padding');
419+
});
420+
413421
});
414422

415423
</script>

0 commit comments

Comments
 (0)