Skip to content

Commit 883aa5c

Browse files
committed
Fix for mixins declaration with space before colon.
Allow any space character or even `{` and `}` (before and after capturing pattern correspondingly) as pattern boundaries instead of new lines only. In minified sources there might be no space, semicolon or line start, so we need to account that as well.
1 parent 6ed836f commit 883aa5c

File tree

3 files changed

+83
-29
lines changed

3 files changed

+83
-29
lines changed

src/lib/css-parse.html

+9-9
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
n = {start: i+1, parent: p, previous: previous};
4444
p.rules.push(n);
4545
break;
46-
case this.CLOSE_BRACE:
46+
case this.CLOSE_BRACE:
4747
//console.groupEnd(n.start);
4848
n.end = i+1;
4949
n = n.parent || root;
@@ -84,9 +84,9 @@
8484
if (r$) {
8585
for (var i=0, l=r$.length, r; (i<l) && (r=r$[i]); i++) {
8686
this._parseCss(r, text);
87-
}
87+
}
8888
}
89-
return node;
89+
return node;
9090
},
9191

9292
// stringify parsed css.
@@ -99,10 +99,10 @@
9999
if (r$ && (preserveProperties || !this._hasMixinRules(r$))) {
100100
for (var i=0, l=r$.length, r; (i<l) && (r=r$[i]); i++) {
101101
cssText = this.stringify(r, preserveProperties, cssText);
102-
}
102+
}
103103
} else {
104-
cssText = preserveProperties ? node.cssText :
105-
this.removeCustomProps(node.cssText);
104+
cssText = preserveProperties ? node.cssText :
105+
this.removeCustomProps(node.cssText);
106106
cssText = cssText.trim();
107107
if (cssText) {
108108
cssText = ' ' + cssText + '\n';
@@ -138,7 +138,7 @@
138138
},
139139

140140
removeCustomPropApply: function(cssText) {
141-
return cssText
141+
return cssText
142142
.replace(this._rx.mixinApply, '')
143143
.replace(this._rx.varApply, '');
144144
},
@@ -158,7 +158,7 @@
158158
comments: /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
159159
port: /@import[^;]*;/gim,
160160
customProp: /(?:^|[\s;])--[^;{]*?:[^{};]*?(?:[;\n]|$)/gim,
161-
mixinProp: /(?:^|[\s;])--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim,
161+
mixinProp: /(?:^|[\s;])?--[^;{]*?:[^{;]*?{[^}]*?}(?:[;\n]|$)?/gim,
162162
mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim,
163163
varApply: /[^;:]*?:[^;]*var[^;]*(?:[;\n]|$)?/gim,
164164
keyframesRule: /^@[^\s]*keyframes/,
@@ -171,7 +171,7 @@
171171
};
172172

173173

174-
// exports
174+
// exports
175175
return api;
176176

177177
})();

src/lib/style-properties.html

+17-17
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@
133133
var self = this;
134134
var fn = function(all, prefix, value, fallback) {
135135
var propertyValue = (self.valueForProperty(props[value], props) ||
136-
(props[fallback] ?
137-
self.valueForProperty(props[fallback], props) :
136+
(props[fallback] ?
137+
self.valueForProperty(props[fallback], props) :
138138
fallback));
139139
return prefix + (propertyValue || '');
140140
};
@@ -160,7 +160,7 @@
160160
}
161161
p = pp.join(':');
162162
}
163-
parts[i] = (p && p.lastIndexOf(';') === p.length - 1) ?
163+
parts[i] = (p && p.lastIndexOf(';') === p.length - 1) ?
164164
// strip trailing ;
165165
p.slice(0, -1) :
166166
p || '';
@@ -188,7 +188,7 @@
188188
// generates a unique key for these matches
189189
var o = [], i = 0;
190190
styleUtil.forRulesInStyles(styles, function(rule) {
191-
// TODO(sorvell): we could trim the set of rules at declaration
191+
// TODO(sorvell): we could trim the set of rules at declaration
192192
// time to only include ones that have properties
193193
if (!rule.propertyInfo) {
194194
self.decorateRule(rule);
@@ -212,7 +212,7 @@
212212
// collect any custom properties into `props`.
213213
scopePropertiesFromStyles: function(styles) {
214214
if (!styles._scopeStyleProperties) {
215-
styles._scopeStyleProperties =
215+
styles._scopeStyleProperties =
216216
this.selectedPropertiesFromStyles(styles, this.SCOPE_SELECTORS);
217217
}
218218
return styles._scopeStyleProperties;
@@ -225,7 +225,7 @@
225225
// :host(...) and then matching these against self.
226226
hostPropertiesFromStyles: function(styles) {
227227
if (!styles._hostStyleProperties) {
228-
styles._hostStyleProperties =
228+
styles._hostStyleProperties =
229229
this.selectedPropertiesFromStyles(styles, this.HOST_SELECTORS);
230230
}
231231
return styles._hostStyleProperties;
@@ -251,15 +251,15 @@
251251
var self = this;
252252
var hostSelector = styleTransformer
253253
._calcHostScope(element.is, element.extends);
254-
var rxHostSelector = element.extends ?
255-
'\\' + hostSelector.slice(0, -1) + '\\]' :
254+
var rxHostSelector = element.extends ?
255+
'\\' + hostSelector.slice(0, -1) + '\\]' :
256256
hostSelector;
257-
var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector +
257+
var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector +
258258
this.rx.HOST_SUFFIX);
259259
return styleTransformer.elementStyles(element, function(rule) {
260260
self.applyProperties(rule, properties);
261261
if (rule.cssText && !nativeShadow) {
262-
self._scopeSelector(rule, hostRx, hostSelector,
262+
self._scopeSelector(rule, hostRx, hostSelector,
263263
element._scopeCssViaAttr, scopeSelector);
264264
}
265265
});
@@ -271,8 +271,8 @@
271271
_scopeSelector: function(rule, hostRx, hostSelector, viaAttr, scopeId) {
272272
rule.transformedSelector = rule.transformedSelector || rule.selector;
273273
var selector = rule.transformedSelector;
274-
var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' +
275-
scopeId + ']' :
274+
var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' +
275+
scopeId + ']' :
276276
'.' + scopeId;
277277
var parts = selector.split(',');
278278
for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {
@@ -299,8 +299,8 @@
299299

300300
applyElementStyle: function(element, properties, selector, style) {
301301
// calculate cssText to apply
302-
var cssText = style ? style.textContent || '' :
303-
this.transformStyles(element, properties, selector);
302+
var cssText = style ? style.textContent || '' :
303+
this.transformStyles(element, properties, selector);
304304
// if shady and we have a cached style that is not style, decrement
305305
var s = element._customStyle;
306306
if (s && !nativeShadow && (s !== style)) {
@@ -320,7 +320,7 @@
320320
} else if (cssText) {
321321
// apply css after the scope style of the element to help with
322322
// style predence rules.
323-
style = styleUtil.applyCss(cssText, selector,
323+
style = styleUtil.applyCss(cssText, selector,
324324
nativeShadow ? element.root : null, element._scopeStyle);
325325
}
326326
}
@@ -350,8 +350,8 @@
350350
},
351351

352352
rx: {
353-
VAR_ASSIGN: /(?:^|[;\n]\s*)(--[\w-]*?):\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\n])|$)/gi,
354-
MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i,
353+
VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,
354+
MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i,
355355
// note, this supports:
356356
// var(--a)
357357
// var(--a, --b)

test/unit/custom-style.html

+57-3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@
4747
};
4848
}
4949

50+
:root {
51+
--red-text : {
52+
color : red;
53+
};
54+
}
55+
56+
:root{--blue-text:{color:#0000ff};--dummy-mixin:{};--bold-text:{font-weight:700}}
57+
5058

5159
:root {
5260

@@ -69,7 +77,7 @@
6977
}
7078

7179
x-foo {
72-
80+
7381
--primary: 10px;
7482
}
7583

@@ -108,7 +116,7 @@
108116

109117
<style is="custom-style" include="shared-style2">
110118
.zazz {
111-
border: 20px solid blue;
119+
border: 20px solid blue;
112120
}
113121
</style>
114122
</head>
@@ -126,6 +134,10 @@
126134

127135
<x-foo></x-foo>
128136

137+
<x-red-text></x-red-text>
138+
139+
<x-blue-bold-text></x-blue-bold-text>
140+
129141
<br><br>
130142
<div id="after"></div>
131143

@@ -180,12 +192,32 @@
180192
</template>
181193
</dom-module>
182194

195+
<dom-module id="x-red-text">
196+
<style>
197+
:host {
198+
@apply(--red-text);
199+
}
200+
</style>
201+
<template>
202+
x-red-text
203+
</template>
204+
</dom-module>
205+
206+
<dom-module id="x-blue-bold-text">
207+
<style>
208+
:host {@apply(--blue-text);@apply(--bold-text);}
209+
</style>
210+
<template>
211+
x-blue-bold-text
212+
</template>
213+
</dom-module>
214+
183215
<script>
184216

185217
suite('custom-style', function() {
186218

187219
suiteSetup(function() {
188-
220+
189221
Polymer({
190222
is: 'x-baz'
191223
});
@@ -198,6 +230,14 @@
198230
is: 'x-foo'
199231
});
200232

233+
Polymer({
234+
is: 'x-red-text'
235+
});
236+
237+
Polymer({
238+
is: 'x-blue-bold-text'
239+
});
240+
201241
xBar = document.querySelector('x-bar');
202242
xFoo = document.querySelector('x-foo');
203243

@@ -227,6 +267,20 @@
227267
assert.property(props, '--bag');
228268
});
229269

270+
test('custom properties with space before semicolon', function() {
271+
var red = document.querySelector('x-red-text');
272+
assertComputed(red, 'rgb(255, 0, 0)', 'color');
273+
});
274+
275+
test('custom properties in minified css', function() {
276+
var blue = document.querySelector('x-blue-bold-text');
277+
assertComputed(blue, 'rgb(0, 0, 255)', 'color');
278+
279+
var computed = getComputedStyle(blue);
280+
// Firefox returns `700`, while Chrome returns original `bold`
281+
assert.ok(computed.fontWeight == '700' || computed.fontWeight == 'bold', 'computed style incorrect for fontWeight');
282+
});
283+
230284
test('custom-styles apply normal and property values to main document', function() {
231285
var bag = document.querySelector('.bag');
232286
var italic = document.querySelector('.italic');

0 commit comments

Comments
 (0)