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

Commit

Permalink
Browse files Browse the repository at this point in the history
also, shimmed styles that include polyfill specific comments can now contain :host to refer to the host element.
  • Loading branch information
sorvell committed Oct 14, 2013
1 parent ca89c64 commit 6db75b5
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 39 deletions.
78 changes: 53 additions & 25 deletions src/ShadowCSS.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ var ShadowCSS = {
// Shim styles for a given root associated with a name and extendsName
// 1. cache root styles by name
// 2. optionally tag root nodes with scope name
// 3. shim polyfill directives /* @polyfill */
// 3. shim polyfill directives /* @polyfill */ and /* @polyfill-rule */
// 4. shim @host and scoping
shimStyling: function(root, name, extendsName) {
// use caching to make working with styles nodes easier and to facilitate
Expand All @@ -151,10 +151,11 @@ var ShadowCSS = {
if (this.strictStyling) {
this.applyScopeToContent(root, name);
}
this.shimPolyfillDirectives(def.rootStyles, name);
// insert @polyfill and @polyfill-rule rules into style elements
// scoping process takes care of shimming these
this.insertPolyfillDirectives(def.rootStyles);
this.insertPolyfillRules(def.rootStyles);
var cssText = this.stylesToShimmedCssText(def.scopeStyles, name);
// note: it's critical that polyfill-rules are not shimmed.
cssText += '\n\n' + this.extractPolyfillRules(def.scopeStyles, name);
// provide shimmedStyle for user extensibility
def.shimmedStyle = cssTextToStyle(cssText);
if (root) {
Expand Down Expand Up @@ -205,49 +206,61 @@ var ShadowCSS = {
*
* For example, we convert this rule:
*
* (comment start) @polyfill @host g-menu-item (comment end)
* shadow::-webkit-distributed(g-menu-item) {
* (comment start) @polyfill :host menu-item (comment end)
* shadow::-webkit-distributed(menu-item) {
*
* to this:
*
* scopeName g-menu-item {
* scopeName menu-item {
*
**/
shimPolyfillDirectives: function(styles, name) {
insertPolyfillDirectives: function(styles, name) {
if (styles) {
Array.prototype.forEach.call(styles, function(s) {
s.textContent = this.convertPolyfillDirectives(s.textContent, name);
s.textContent = this.insertPolyfillDirectivesInCssText(s.textContent);
}, this);
}
},
convertPolyfillDirectives: function(cssText, name) {
var r = '', l = 0, matches, selector;
insertPolyfillDirectivesInCssText: function(cssText, name) {
var r = '', l = 0, matches;
while (matches = cssPolyfillCommentRe.exec(cssText)) {
r += cssText.substring(l, matches.index);
// remove end comment delimiter (*/)
selector = matches[1].slice(0, -2).replace(hostRe, name);
r += this.scopeSelector(selector, name) + '{';
r += matches[1].slice(0, -2) + '{';
l = cssPolyfillCommentRe.lastIndex;
}
r += cssText.substring(l, cssText.length);
return r;
},
extractPolyfillRules: function(styles, name) {
/*
* Process styles to add rules which will only apply under the polyfill
*
* For example, we convert this rule:
*
* (comment start) @polyfill-rule :host menu-item {
* ... } (comment end)
*
* to this:
*
* scopeName menu-item {...}
*
**/
insertPolyfillRules: function(styles, name) {
if (styles) {
var cssText = '';
Array.prototype.forEach.call(styles, function(s) {
cssText += this.extractPolyfillRulesFromCssText(s.textContent, name) +
'\n\n';
s.textContent = this.insertPolyfillRulesInCssText(s.textContent);
}, this);
}
return cssText;
},
extractPolyfillRulesFromCssText: function(cssText, name) {
var r = '', l = 0, matches, selector;
insertPolyfillRulesInCssText: function(cssText, name) {
var r = '', l = 0, matches;
while (matches = cssPolyfillRuleCommentRe.exec(cssText)) {
rule = matches[1].slice(0, -1).replace(hostRe, name);
r += rule + '\n\n';
r += cssText.substring(l, matches.index);
// remove end comment delimiter (*/)
r += matches[1].slice(0, -1);
l = cssPolyfillCommentRe.lastIndex;
}
r += cssText.substring(l, cssText.length);
return r;
},
// apply @host and scope shimming
Expand Down Expand Up @@ -325,6 +338,7 @@ var ShadowCSS = {
},
convertScopedStyles: function(styles, name) {
var cssText = stylesToCssText(styles).replace(hostRuleRe, '');
cssText = this.insertPolyfillHostInCssText(cssText);
cssText = this.convertPseudos(cssText);
var rules = cssToRules(cssText);
cssText = this.scopeRules(rules, name);
Expand Down Expand Up @@ -368,9 +382,19 @@ var ShadowCSS = {
var re = new RegExp('^' + matchScope + selectorReSuffix, 'm');
return !selector.match(re);
},
insertPolyfillHostInCssText: function(selector) {
return selector.replace(hostRe, polyfillHost).replace(colonHostRe,
polyfillHost);
},
// scope via name and [is=name]
applySimpleSelectorScope: function(selector, name) {
return name + ' ' + selector + ', ' + '[is=' + name + '] ' + selector;
var ancestor = name + ' ', is = '[is=' + name + '] ';
if (selector.match(polyfillHostRe)) {
return selector.replace(polyfillHostRe, ancestor) + ', ' +
selector.replace(polyfillHostRe, is);
} else {
return ancestor + selector + ', ' + is + selector;
}
},
// return a selector with [name] suffix on each simple selector
// e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]
Expand All @@ -381,7 +405,8 @@ var ShadowCSS = {
splits.forEach(function(sep) {
var parts = scoped.split(sep);
scoped = parts.map(function(p) {
var t = p.trim();
// remove :host since it should be unnecessary
var t = p.trim().replace(polyfillHostRe, '');
if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {
p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3')
}
Expand Down Expand Up @@ -411,7 +436,10 @@ var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,
cssPolyfillRuleCommentRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
cssPseudoRe = /::(x-[^\s{,(]*)/gim,
selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
hostRe = /@host/gim;
hostRe = /@host/gim,
colonHostRe = /\:host/gim,
polyfillHost = '-host',
polyfillHostRe = /-host/gim;

function stylesToCssText(styles, preserveComments) {
var cssText = '';
Expand Down
32 changes: 22 additions & 10 deletions test/html/styling/polyfill-directive.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
-->
<html>
<head>
<title>Psuedo scoped styling</title>
<title>polyfill directive</title>
<script src="../../../platform.js" shadow></script>
<script src="register.js"></script>
<script src="../../../../tools/test/htmltest.js"></script>
Expand All @@ -16,8 +16,12 @@
<x-foo>
<div>Green?</div>
</x-foo>

<x-bar>
<div>Green?</div>
</x-bar>

<template id="x-foo"">
<template id="x-foo">
<style>
@host {
* {
Expand All @@ -26,31 +30,39 @@
}
}

/*@polyfill @host > div */
/*@polyfill :host > div */
::-webkit-distributed(*) {
background: green;
}

/*@polyfill @host > div */
/*@polyfill :host > div */
::-webkit-distributed(*) {
color: red;
}

</style>
<content></content>
</template>



<script>
XFoo = register('x-foo', '', HTMLElement.prototype);
XBar = register('x-bar', 'x-foo', HTMLElement.prototype);

function test(selector) {
var n = document.querySelector(selector);
nDiv = n.firstElementChild;
chai.assert.equal(getComputedStyle(nDiv).backgroundColor,
'rgb(0, 128, 0)', '@polyfill styles are applied');
chai.assert.equal(getComputedStyle(nDiv).color,
'rgb(255, 0, 0)', '@polyfill styles are applied');
}

document.addEventListener('WebComponentsReady', function() {
setTimeout(function() {
var foo = document.querySelector('x-foo');
fooDiv = foo.firstElementChild;
chai.assert.equal(getComputedStyle(fooDiv).backgroundColor,
'rgb(0, 128, 0)', '@polyfill styles are applied');
chai.assert.equal(getComputedStyle(fooDiv).color,
'rgb(255, 0, 0)', '@polyfill styles are applied');
test('x-foo');
test('x-bar');
done();
});
});
Expand Down
7 changes: 3 additions & 4 deletions test/html/styling/polyfill-rule.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
-->
<html>
<head>
<title>Psuedo scoped styling</title>
<title>polyfill rule</title>
<script src="../../../platform.js" shadow></script>
<script src="register.js"></script>
<script src="../../../../tools/test/htmltest.js"></script>
Expand All @@ -17,12 +17,11 @@
<div class="zonk">red?</div>
</x-foo>

<template id="x-foo"">
<template id="x-foo">
<style>
/* @polyfill-rule .zonk {
/* @polyfill-rule :host > .zonk {
background: red;
} */

</style>
<content></content>
</template>
Expand Down

0 comments on commit 6db75b5

Please sign in to comment.