Skip to content

Commit

Permalink
Transform ::slotted() to ::content
Browse files Browse the repository at this point in the history
Provides forward compatibility with Polymer 2.x and ShadowDOM v1

Fixes #3976
  • Loading branch information
dfreedm committed Sep 22, 2016
1 parent 18d0af6 commit 541fdfb
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
30 changes: 25 additions & 5 deletions src/lib/style-transformer.html
Expand Up @@ -97,6 +97,18 @@
var styles = element._styles;
var cssText = '';
var cssBuildType = element.__cssBuild;
var passthrough = settings.useNativeShadow || cssBuildType === 'shady';
var cb = callback;
if (passthrough) {
var self = this;
//
cb = function(rule) {
rule.selector = self._slottedToContent(rule.selector);
if (callback) {
callback(rule);
}
}
}
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
var rules = styleUtil.rulesForStyle(s);
// no need to shim selectors if settings.useNativeShadow, also
Expand All @@ -105,9 +117,9 @@
// When there is a targeted build it will not be called for static shimming,
// but when the property shim is used it is called and should opt out of
// static shimming work when a proper build exists.
cssText += (settings.useNativeShadow || cssBuildType === 'shady') ?
styleUtil.toCssText(rules, callback) :
this.css(rules, element.is, element.extends, callback,
cssText += (passthrough) ?
styleUtil.toCssText(rules, cb) :
this.css(rules, element.is, element.extends, cb,
element._scopeCssViaAttr) + '\n\n';
}
return cssText.trim();
Expand Down Expand Up @@ -176,6 +188,7 @@
var hostContext = false;
var self = this;
selector = selector.trim();
selector = this._slottedToContent(selector);
selector = selector.replace(CONTENT_START, HOST + ' $1');
selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
if (!stop) {
Expand Down Expand Up @@ -237,7 +250,7 @@
_transformHostSelector: function(selector, hostScope) {
var m = selector.match(HOST_PAREN);
var paren = m && m[2].trim() || '';
if (paren) {
if (paren) {
if (!paren[0].match(SIMPLE_SELECTOR_PREFIX)) {
// paren starts with a type selector
var typeSelector = paren.split(SIMPLE_SELECTOR_PREFIX)[0];
Expand All @@ -257,7 +270,7 @@
});
}
// if no paren, do a straight :host replacement.
// TODO(sorvell): this should not strictly be necessary but
// TODO(sorvell): this should not strictly be necessary but
// it's needed to maintain support for `:host[foo]` type selectors
// which have been improperly used under Shady DOM. This should be
// deprecated.
Expand Down Expand Up @@ -287,6 +300,12 @@
this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);
},

// For forward compatibility with ShadowDOM v1 and Polymer 2.x,
// replace ::slotted(${inner}) with ::content > ${inner}
_slottedToContent: function(cssText) {
return cssText.replace(SLOTTED_PAREN, CONTENT + '> $1');
},

SCOPE_NAME: 'style-scope'
};

Expand All @@ -313,6 +332,7 @@
var CLASS = 'class';
var CONTENT_START = new RegExp('^(' + CONTENT + ')');
var SELECTOR_NO_MATCH = 'should_not_match';
var SLOTTED_PAREN = /(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;

// exports
return api;
Expand Down
25 changes: 24 additions & 1 deletion test/unit/styling-scoped-elements.html
Expand Up @@ -606,4 +606,27 @@
<script>
Polymer({is: 'x-content'});
</script>
</dom-module>
</dom-module>

<dom-module id="x-slotted">
<template>
<style>
::slotted(.auto-content) {
border: 2px solid orange;
}
.bar, ::slotted(.complex-child) {
border: 6px solid navy;
}
#container ::slotted(*) {
border: 8px solid green;
}
</style>
<slot></slot>
<div id="container">
<slot name="container"></slot>
</div>
</template>
<script>
Polymer({is: 'x-slotted'});
</script>
</dom-module>
33 changes: 33 additions & 0 deletions test/unit/styling-scoped.html
Expand Up @@ -161,6 +161,39 @@
assertComputed(d1, '6px');
});

test('auto ::slotted selector', function() {
var x = document.createElement('x-slotted');
var d1 = document.createElement('div');
d1.classList.add('auto-content');
d1.textContent = 'auto-content';
document.body.appendChild(x);
Polymer.dom(x).appendChild(d1);
Polymer.dom.flush();
assertComputed(d1, '2px');
});

test('::slotted + child in complex selector', function() {
var x = document.createElement('x-slotted');
var d1 = document.createElement('div');
d1.classList.add('complex-child');
d1.textContent = 'complex-child';
document.body.appendChild(x);
Polymer.dom(x).appendChild(d1);
Polymer.dom.flush();
assertComputed(d1, '6px');
});

test('::slotted + named slot', function() {
var x = document.createElement('x-slotted');
var d1 = document.createElement('div');
d1.setAttribute('slot', 'container')
d1.textContent = 'named slot child';
document.body.appendChild(x);
Polymer.dom(x).appendChild(d1);
Polymer.dom.flush();
assertComputed(d1, '8px');
});

test('::shadow selectors', function() {
assertComputed(styled.$.child.$.shadow, '7px');
});
Expand Down

0 comments on commit 541fdfb

Please sign in to comment.