Fixes #3326. Changes inspired by #3276 and #3344

This commit is contained in:
Steven Orvell 2016-02-04 17:55:52 -08:00
parent 9968266e74
commit b5ba9a8219
6 changed files with 71 additions and 30 deletions

View File

@ -88,17 +88,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
// but not production, so strip out {...}
cssText = cssText.replace(this.rx.BRACKETED, '')
.replace(this.rx.VAR_ASSIGN, '');
var parts = cssText.split(';');
for (var i=0, p; i<parts.length; i++) {
p = parts[i];
if (p.match(this.rx.MIXIN_MATCH) ||
p.match(this.rx.VAR_MATCH) ||
this.rx.ANIMATION_MATCH.test(p) ||
styleUtil.isKeyframesSelector(rule)) {
customCssText += p + ';\n';
}
}
return customCssText;
return cssText;
},
collectPropertiesInCssText: function(cssText, props) {
@ -369,7 +359,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var parts = selector.split(',');
for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {
parts[i] = p.match(hostRx) ?
p.replace(hostSelector, hostSelector + scope) :
p.replace(hostSelector, scope) :
scope + ' ' + p;
}
rule.selector = parts.join(',');

View File

@ -42,8 +42,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}
if (this._template) {
this._styles = this._collectStyles();
// calculate shimmed styles (we must always do this as it
// stores shimmed style data in the css rules for later use)
var cssText = styleTransformer.elementStyles(this);
if (cssText) {
// do we really need to output shimmed styles
var needsStatic = this._needsStaticStyles(this._styles);
cssText = needsStatic ? cssText : '';
// under shady dom we always output a shimmed style (which may be
// empty) so that other dynamic stylesheets can always be placed
// after the element's main stylesheet.
// This helps ensure element styles are always in registration order.
if (needsStatic || !nativeShadow) {
var style = styleUtil.applyCss(cssText, this.is,
nativeShadow ? this._template.content : null);
// keep track of style when in document scope (polyfill) so we can

View File

@ -26,6 +26,22 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
Polymer.Base._addFeature({
// Skip applying CSS if there are some mixins or variables used
// since styles with mixins and variables will be added on later stages anyway,
// and will include styles applied here, no need to do this twice
_needsStaticStyles: function(styles) {
var needsStatic;
for (var i=0, l=styles.length, css; i < l; i++) {
css = styles[i].textContent;
needsStatic = needsStatic || Boolean(css);
if (css.match(propertyUtils.rx.MIXIN_MATCH) ||
css.match(propertyUtils.rx.VAR_MATCH)) {
return false;
}
}
return needsStatic;
},
_prepStyleProperties: function() {
// note: an element should produce an x-scope stylesheet
// if it has any _stylePropertyNames

View File

@ -795,10 +795,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
// skip for now, until #3326 is fixed
test.skip('custom style class overrides css variable', function() {
test('custom style class overrides css variable', function() {
var d = document.createElement('x-variable-override');
d.classList.add('variable-override');
document.body.appendChild(d);
CustomElements.takeRecords();
assertComputed(d, '10px');
});

View File

@ -199,13 +199,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
test('styles shimmed in registration order', function() {
var s$ = document.head.querySelectorAll('style[scope]');
var expected = ['x-order', 'x-child2', 'x-styled', 'x-styled-0', 'x-button', 'x-dynamic-scope'];
var actual = [];
for (var i=0; i<s$.length; i++) {
actual.push(s$[i].getAttribute('scope'));
var regList = Polymer.telemetry.registrations.map(function(reg) {
return reg.is;
});
function regIndex(styleScope) {
for (var i=0; (r=regList[i]); i++) {
if (styleScope.match(new RegExp(r + '\\-?\\d*$'))) {
return i;
}
}
}
var s$ = document.head.querySelectorAll('style[scope]');
for (var i=0, scope, n=0, o=0; i<s$.length; i++) {
scope = s$[i].getAttribute('scope');
n = regIndex(scope);
assert.isTrue(n >= o, 'style not in registration order: ' + scope);
o = n;
}
assert.deepEqual(actual, expected);
});
});
}

View File

@ -249,17 +249,23 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
test('styles shimmed in registration order', function() {
var s$ = document.head.querySelectorAll('style[scope]');
var expected = ['x-keyframes', 'x-keyframes-1', 'x-keyframes-0', 'x-gchild', 'x-child2',
'x-styled', 'x-button', 'x-mixed-case', 'x-mixed-case-button',
'x-dynamic-scope', 'x-dynamic-template', 'x-dynamic-svg',
'x-specificity', 'x-overriding', 'x-overriding-0',
'x-specificity-parent-0', 'x-specificity-nested-0'];
var actual = [];
for (var i=0; i<s$.length; i++) {
actual.push(s$[i].getAttribute('scope'));
var regList = Polymer.telemetry.registrations.map(function(reg) {
return reg.is;
});
function regIndex(styleScope) {
for (var i=0; (r=regList[i]); i++) {
if (styleScope.match(new RegExp(r + '\\-?\\d*$'))) {
return i;
}
}
}
var s$ = document.head.querySelectorAll('style[scope]');
for (var i=0, scope, n=0, o=0; i<s$.length; i++) {
scope = s$[i].getAttribute('scope');
n = regIndex(scope);
assert.isTrue(n >= o, 'style not in registration order: ' + scope);
o = n;
}
assert.deepEqual(actual, expected);
});
test('svg elements properly scoped', function() {
@ -306,6 +312,15 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
test('specificity of ::content > :not(template) selector', function() {
assertComputed(document.querySelector('[is=x-specificity-nested]'), '10px');
});
test('overwriting mixin properties', function() {
var root = document.querySelector('x-overriding');
assertComputed(root.querySelector('.red'), '1px');
assertComputed(root.querySelector('.green'), '2px');
assertComputed(root.querySelector('.red-2'), '1px');
assertComputed(root.querySelector('.blue'), '3px');
});
});
test('svg classes are dynamically scoped correctly', function() {