diff --git a/src/lib/style-transformer.html b/src/lib/style-transformer.html index 74adf086f4..aa5a557222 100644 --- a/src/lib/style-transformer.html +++ b/src/lib/style-transformer.html @@ -206,12 +206,7 @@ if (selector.indexOf(HOST_CONTEXT) >=0) { hostContext = true; } else if (selector.indexOf(HOST) >=0) { - // :host(...) -> scopeName... - selector = selector.replace(HOST_PAREN, function(m, host, paren) { - return (m.indexOf(hostScope) === -1 ? hostScope : '') + paren; - }); - // now normal :host - selector = selector.replace(HOST, hostScope); + selector = this._transformHostSelector(selector, hostScope); // replace other selectors with scoping class } else if (jumpIndex !== 0) { selector = scope ? this._transformSimpleSelector(selector, scope) : @@ -238,6 +233,30 @@ return p$.join(PSEUDO_PREFIX); }, + // :host(...) -> scopeName... + _transformHostSelector: function(selector, hostScope) { + var m = HOST_PAREN.exec(selector); + HOST_PAREN.lastIndex = 0; + var paren = m && m[2].trim(); + if (paren) { + var selectorKind = /[[.:#*]/; + if (!paren[0].match(selectorKind)) { + var typeSelector = paren.split(selectorKind)[0]; + if (typeSelector === hostScope) { + hostScope = ''; + } else { + return SELECTOR_NO_MATCH; + } + } + return selector.replace(HOST_PAREN, function(m, host, paren) { + return hostScope + paren; + }); + } else { + // now normal :host + return selector.replace(HOST, hostScope); + } + }, + documentRule: function(rule) { // reset selector in case this is redone. rule.selector = rule.parsedSelector; @@ -283,6 +302,7 @@ var PSEUDO_PREFIX = ':'; var CLASS = 'class'; var CONTENT_START = new RegExp('^(' + CONTENT + ')'); + var SELECTOR_NO_MATCH = 'should_not_match'; // exports return api; diff --git a/test/unit/styling-scoped-elements.html b/test/unit/styling-scoped-elements.html index 0b291139a2..dd6c279f5c 100644 --- a/test/unit/styling-scoped-elements.html +++ b/test/unit/styling-scoped-elements.html @@ -554,6 +554,10 @@ display: block; border: 4px solid orange; } + + :host(.x-shared1) { + padding: 8px; + }; diff --git a/test/unit/styling-scoped.html b/test/unit/styling-scoped.html index 298aba5a95..32264cd494 100644 --- a/test/unit/styling-scoped.html +++ b/test/unit/styling-scoped.html @@ -410,6 +410,14 @@ assertComputed(s2, '4px'); }); + test(':host with superset of element tag selector does not leak', function() { + var t = document.createElement('div'); + t.textContent = 'host leak test'; + t.classList.add('x-shared1'); + document.body.appendChild(t); + assertComputed(t, '0px', 'padding'); + }); + });