diff --git a/src/ShadowCSS.js b/src/ShadowCSS.js index e975434..8851e07 100644 --- a/src/ShadowCSS.js +++ b/src/ShadowCSS.js @@ -156,6 +156,8 @@ var ShadowCSS = { this.insertPolyfillDirectives(def.rootStyles); this.insertPolyfillRules(def.rootStyles); var cssText = this.stylesToShimmedCssText(def.scopeStyles, name); + // note: we only need to do rootStyles since these are unscoped. + cssText += this.extractPolyfillUnscopedRules(def.rootStyles); // provide shimmedStyle for user extensibility def.shimmedStyle = cssTextToStyle(cssText); if (root) { @@ -263,6 +265,37 @@ var ShadowCSS = { r += cssText.substring(l, cssText.length); return r; }, + /* + * Process styles to add rules which will only apply under the polyfill + * and do not process via CSSOM. (CSSOM is destructive to rules on rare + * occasions, e.g. -webkit-calc on Safari.) + * For example, we convert this rule: + * + * (comment start) @polyfill-unscoped-rule menu-item { + * ... } (comment end) + * + * to this: + * + * menu-item {...} + * + **/ + extractPolyfillUnscopedRules: function(styles) { + var cssText = ''; + if (styles) { + Array.prototype.forEach.call(styles, function(s) { + cssText += this.extractPolyfillUnscopedRulesFromCssText( + s.textContent) + '\n\n'; + }, this); + } + return cssText; + }, + extractPolyfillUnscopedRulesFromCssText: function(cssText) { + var r = '', l = 0, matches; + while (matches = cssPolyfillUnscopedRuleCommentRe.exec(cssText)) { + r += matches[1].slice(0, -1) + '\n\n'; + } + return r; + }, // apply @host and scope shimming stylesToShimmedCssText: function(styles, name) { return this.shimAtHost(styles, name) + this.shimScoping(styles, name); @@ -434,6 +467,7 @@ var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim, cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim, cssPolyfillCommentRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim, cssPolyfillRuleCommentRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim, + cssPolyfillUnscopedRuleCommentRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim, cssPseudoRe = /::(x-[^\s{,(]*)/gim, selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$', hostRe = /@host/gim, diff --git a/test/html/styling/polyfill-rule.html b/test/html/styling/polyfill-rule.html index d04e2ec..a66d2a1 100644 --- a/test/html/styling/polyfill-rule.html +++ b/test/html/styling/polyfill-rule.html @@ -16,12 +16,17 @@
red?
- +
unscoped
@@ -30,13 +35,16 @@ XFoo = register('x-foo', '', HTMLElement.prototype); document.addEventListener('WebComponentsReady', function() { - setTimeout(function() { + //setTimeout(function() { var foo = document.querySelector('x-foo'); fooDiv = foo.firstElementChild; chai.assert.equal(getComputedStyle(fooDiv).backgroundColor, 'rgb(255, 0, 0)', '@polyfill styles are applied'); + var unscoped = document.querySelector('.unscoped'); + chai.assert.equal(getComputedStyle(unscoped).backgroundColor, + 'rgb(0, 0, 0)', '@polyfill-unscoped-rule styles are applied'); done(); - }); + //}); });