From 819652eb9f37166744a3bcb7628696a0ea0f6e90 Mon Sep 17 00:00:00 2001 From: Steven Orvell Date: Thu, 19 Oct 2017 12:56:30 -0700 Subject: [PATCH] Allow style elements to be separate in the element template. Previously Polymer collapsed any included shared styles into 1 style element. This prevents the browser from recognizing shared style elements as similar and optimizing them. With this change, we no longer collapse styles. Note, included styles are still currently collapsed by ShadyCSS but the polyfill will likely not do this in the future. --- lib/mixins/dir-mixin.html | 4 +- lib/mixins/element-mixin.html | 55 +++++++--- lib/utils/style-gather.html | 192 ++++++++++++++++++++++++++++------ test/runner.html | 3 +- test/unit/multi-style.html | 115 ++++++++++++++++++++ 5 files changed, 315 insertions(+), 54 deletions(-) create mode 100644 test/unit/multi-style.html diff --git a/lib/mixins/dir-mixin.html b/lib/mixins/dir-mixin.html index 8773d83faa..075da5f581 100644 --- a/lib/mixins/dir-mixin.html +++ b/lib/mixins/dir-mixin.html @@ -104,8 +104,8 @@ * @override * @suppress {missingProperties} Interfaces in closure do not inherit statics, but classes do */ - static _processStyleText(is, template, baseURI) { - let cssText = super._processStyleText(is, template, baseURI); + static _processStyleText(cssText, baseURI) { + cssText = super._processStyleText(cssText, baseURI); cssText = this._replaceDirInCssText(cssText); return cssText; } diff --git a/lib/mixins/element-mixin.html b/lib/mixins/element-mixin.html index 2ed3e29b0d..842aacad21 100644 --- a/lib/mixins/element-mixin.html +++ b/lib/mixins/element-mixin.html @@ -399,6 +399,37 @@ } } + /** + * Process all style elements in the element template. Styles with the + * `include` attribute are processed such that any styles in + * the associated "style modules" are included in the element template. + * @param {PolymerElementConstructor} klass Element class + * @param {!HTMLTemplateElement} template Template to process + * @param {string} is Name of element + * @param {string} ext Name of native element + * @param {string} baseURI Base URI for element + * @private + */ + function processElementStyles(klass, template, is, ext, baseURI) { + const styles = Polymer.StyleGather.stylesFromModuleImports(is).concat( + Polymer.StyleGather.stylesFromTemplate(template)); + let templateStyles = template.content.querySelectorAll('style'); + let lastStyle = templateStyles[templateStyles.length-1]; + for (let i=0; i < styles.length; i++) { + let s = styles[i]; + // if the style is not in this template, it's been "included" and + // we put a clone of it in the template. + if (s.getRootNode() != template.content) { + s = s.cloneNode(true); + template.content.insertBefore(s, lastStyle); + } + s.textContent = klass._processStyleText(s.textContent, baseURI); + } + if (window.ShadyCSS) { + window.ShadyCSS.prepareTemplate(template, is, ext); + } + } + /** * @polymer * @mixinClass @@ -578,17 +609,15 @@ } /** - * Gather style text for the template + * Gather style text for a style element in the template. * - * @param {string} is Tag name for this element - * @param {!HTMLTemplateElement} template Template to process + * @param {string} cssText Text containing styling to process * @param {string} baseURI Base URI to rebase CSS paths against - * @return {string} The combined CSS text + * @return {string} The processed CSS text * @protected */ - static _processStyleText(is, template, baseURI) { - return Polymer.StyleGather.cssFromModuleImports(is) + - Polymer.StyleGather.cssFromTemplate(template, baseURI); + static _processStyleText(cssText, baseURI) { + return Polymer.ResolveUrl.resolveCss(cssText, baseURI); } /** @@ -607,16 +636,8 @@ template.__polymerFinalized = true; const importPath = this.importPath; const baseURI = importPath ? Polymer.ResolveUrl.resolveUrl(importPath) : ''; - // support `include="module-name"` - let cssText = this._processStyleText(is, template, baseURI); - if (cssText) { - let style = document.createElement('style'); - style.textContent = cssText; - template.content.insertBefore(style, template.content.firstChild); - } - if (window.ShadyCSS) { - window.ShadyCSS.prepareTemplate(template, is, ext); - } + // e.g. support `include="module-name"`, and ShadyCSS + processElementStyles(this, template, is, ext, baseURI); this.prototype._bindTemplate(template); } } diff --git a/lib/utils/style-gather.html b/lib/utils/style-gather.html index 8e9f61c65a..62694530e0 100644 --- a/lib/utils/style-gather.html +++ b/lib/utils/style-gather.html @@ -39,15 +39,154 @@ const StyleGather = { /** + * Returns a list of + + + + + + + + + + + + + + + + + + + \ No newline at end of file