Skip to content
This repository was archived by the owner on Mar 13, 2018. It is now read-only.

Commit ebaaa0c

Browse files
committed
shim :host(.foo) bar { …}; simplify replacements
1 parent 750690d commit ebaaa0c

2 files changed

Lines changed: 46 additions & 50 deletions

File tree

src/ShadowCSS.js

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,10 @@ var ShadowCSS = {
237237
}
238238
},
239239
insertPolyfillDirectivesInCssText: function(cssText, name) {
240-
var r = '', l = 0, matches;
241-
while (matches = cssPolyfillCommentRe.exec(cssText)) {
242-
r += cssText.substring(l, matches.index);
243-
// remove end comment delimiter (*/)
244-
r += matches[1].slice(0, -2) + '{';
245-
l = cssPolyfillCommentRe.lastIndex;
246-
}
247-
r += cssText.substring(l, cssText.length);
248-
return r;
240+
return cssText.replace(cssPolyfillCommentRe, function(match, p1) {
241+
// remove end comment delimiter and add block start
242+
return p1.slice(0, -2) + '{';
243+
});
249244
},
250245
/*
251246
* Process styles to add rules which will only apply under the polyfill
@@ -268,15 +263,10 @@ var ShadowCSS = {
268263
}
269264
},
270265
insertPolyfillRulesInCssText: function(cssText, name) {
271-
var r = '', l = 0, matches;
272-
while (matches = cssPolyfillRuleCommentRe.exec(cssText)) {
273-
r += cssText.substring(l, matches.index);
274-
// remove end comment delimiter (*/)
275-
r += matches[1].slice(0, -1);
276-
l = cssPolyfillCommentRe.lastIndex;
277-
}
278-
r += cssText.substring(l, cssText.length);
279-
return r;
266+
return cssText.replace(cssPolyfillRuleCommentRe, function(match, p1) {
267+
// remove end comment delimiter
268+
return p1.slice(0, -1);
269+
});
280270
},
281271
/*
282272
* Process styles to add rules which will only apply under the polyfill
@@ -303,7 +293,7 @@ var ShadowCSS = {
303293
return cssText;
304294
},
305295
extractPolyfillUnscopedRulesFromCssText: function(cssText) {
306-
var r = '', l = 0, matches;
296+
var r = '', matches;
307297
while (matches = cssPolyfillUnscopedRuleCommentRe.exec(cssText)) {
308298
r += matches[1].slice(0, -1) + '\n\n';
309299
}
@@ -321,25 +311,19 @@ var ShadowCSS = {
321311
}
322312
},
323313
convertAtHostStyles: function(styles, name) {
324-
var cssText = stylesToCssText(styles);
325-
var r = '', l=0, matches;
326-
while (matches = hostRuleRe.exec(cssText)) {
327-
r += cssText.substring(l, matches.index);
328-
r += this.scopeHostCss(matches[1], name);
329-
l = hostRuleRe.lastIndex;
330-
}
331-
r += cssText.substring(l, cssText.length);
332-
var re = new RegExp('^' + name + selectorReSuffix, 'm');
333-
var cssText = rulesToCss(this.findAtHostRules(cssToRules(r),
334-
re));
314+
var cssText = stylesToCssText(styles), self = this;
315+
cssText = cssText.replace(hostRuleRe, function(m, p1) {
316+
return self.scopeHostCss(p1, name);
317+
});
318+
cssText = rulesToCss(this.findAtHostRules(cssToRules(cssText),
319+
new RegExp('^' + name + selectorReSuffix, 'm')));
335320
return cssText;
336321
},
337322
scopeHostCss: function(cssText, name) {
338-
var r = '', matches;
339-
while (matches = selectorRe.exec(cssText)) {
340-
r += this.scopeHostSelector(matches[1], name) +' ' + matches[2] + '\n\t';
341-
}
342-
return r;
323+
var self = this;
324+
return cssText.replace(selectorRe, function(m, p1, p2) {
325+
return self.scopeHostSelector(p1, name) + ' ' + p2 + '\n\t';
326+
});
343327
},
344328
// supports scopig by name and [is=name] syntax
345329
scopeHostSelector: function(selector, name) {
@@ -398,14 +382,22 @@ var ShadowCSS = {
398382
convertParts: function(cssText) {
399383
return cssText.replace(cssPartRe, ' [part=$1]');
400384
},
385+
/*
386+
* convert a rule like :host(.foo) > .bar { }
387+
*
388+
* to
389+
*
390+
* scopeName.foo > .bar, .foo scopeName > .bar { }
391+
* TODO(sorvell): file bug since native impl does not do the former yet.
392+
* http://jsbin.com/OganOCI/2/edit
393+
*/
401394
convertColonHost: function(cssText) {
402-
/*
403-
var is = '[is=' + name + ']';
404-
var r = name + '$1$2, $1 ' + name + '$2, ' +
405-
is + '$1$2, $1' + is + '$2 ';
406-
*/
407-
var r = '$1$2$3, $2 $1$3';
408-
return cssText.replace(cssColonHostRe, r);
395+
// p1 = :host, p2 = contents of (), p3 rest of rule
396+
return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) {
397+
return p2 ? polyfillHostNoCombinator + p2 + p3 + ', '
398+
+ p2 + ' ' + p1 + p3 :
399+
p1 + p3;
400+
});
409401
},
410402
// change a selector like 'div' to 'name div'
411403
scopeRules: function(cssRules, name) {
@@ -448,12 +440,14 @@ var ShadowCSS = {
448440
},
449441
// scope via name and [is=name]
450442
applySimpleSelectorScope: function(selector, name) {
451-
var ancestor = name + ' ', is = '[is=' + name + '] ';
443+
var is = '[is=' + name + ']';
452444
if (selector.match(polyfillHostRe)) {
453-
return selector.replace(polyfillHostRe, ancestor) + ', ' +
454-
selector.replace(polyfillHostRe, is);
445+
selector = selector.replace(polyfillHostNoCombinator, name) + ', ' +
446+
selector.replace(polyfillHostNoCombinator, is);
447+
return selector.replace(polyfillHostRe, name + ' ') + ', ' +
448+
selector.replace(polyfillHostRe, is + ' ');
455449
} else {
456-
return ancestor + selector + ', ' + is + selector;
450+
return name + ' ' + selector + ', ' + is + ' ' + selector;
457451
}
458452
},
459453
// return a selector with [name] suffix on each simple selector
@@ -503,6 +497,8 @@ var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,
503497
hostRe = /@host/gim,
504498
colonHostRe = /\:host/gim,
505499
polyfillHost = '-host',
500+
/* host name without combinator */
501+
polyfillHostNoCombinator = '-host-no-combinator',
506502
polyfillHostRe = /-host/gim;
507503

508504
function stylesToCssText(styles, preserveComments) {

test/html/styling/colon-host.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,16 @@ <h4>Expected: 20px padding</h4>
142142
':host styles matching * are applied (backgroundColor)');
143143

144144
var foo2 = document.querySelector('x-foo.foo');
145-
//chai.assert.equal(getComputedStyle(foo2).backgroundColor, 'rgb(0, 0, 0)',
146-
// ':host styles are conditionally applied (backgroundColor)');
145+
chai.assert.equal(getComputedStyle(foo2).backgroundColor, 'rgb(0, 0, 0)',
146+
':host styles are conditionally applied (backgroundColor)');
147147

148148
var scope = document.querySelector('x-scope');
149149
chai.assert.equal(getComputedStyle(scope).backgroundColor, 'rgb(255, 0, 0)',
150150
':host styles matching :scope are applied (backgroundColor)');
151151

152152
var scope2 = document.querySelector('x-scope.foo');
153-
//chai.assert.equal(getComputedStyle(scope2).backgroundColor, 'rgb(0, 0, 0)',
154-
// ':host styles matching :scope are conditionally applied (backgroundColor)');
153+
chai.assert.equal(getComputedStyle(scope2).backgroundColor, 'rgb(0, 0, 0)',
154+
':host styles matching :scope are conditionally applied (backgroundColor)');
155155

156156
var bar = document.querySelector('x-bar');
157157
var barStyle = getComputedStyle(bar);

0 commit comments

Comments
 (0)