New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scope styles even if the rendered value is not a TemplateResult. #910
Changes from 2 commits
822b15f
434aa5f
6e254e1
755fdc5
72c11e8
9e1efa2
da77ffd
da77bbd
2150067
4b8d150
5d71c23
bf1373b
68094d4
572c103
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
* Do not remove this comment; it keeps typedoc from misplacing the module | ||
* docs. | ||
*/ | ||
import {html} from '../lit-html.js'; | ||
import {removeNodes} from './dom.js'; | ||
import {insertNodeIntoTemplate, removeNodesFromTemplate} from './modify-template.js'; | ||
import {RenderOptions} from './render-options.js'; | ||
|
@@ -248,7 +249,7 @@ export const render = | |
const hasRendered = parts.has(container); | ||
const needsScoping = compatibleShadyCSSVersion && | ||
container.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */ && | ||
!!(container as ShadowRoot).host && result instanceof TemplateResult; | ||
!!(container as ShadowRoot).host; | ||
// Handle first render to a scope specially... | ||
const firstScopeRender = needsScoping && !shadyRenderSet.has(scopeName); | ||
// On first scope render, render into a fragment; this cannot be a single | ||
|
@@ -272,12 +273,18 @@ export const render = | |
if (firstScopeRender) { | ||
const part = parts.get(renderContainer)!; | ||
parts.delete(renderContainer); | ||
if (part.value instanceof TemplateInstance) { | ||
prepareTemplateStyles( | ||
renderContainer as DocumentFragment, | ||
part.value.template, | ||
scopeName); | ||
} | ||
// ShadyCSS might have style sheets (e.g. from `prepareAdoptedCssText`) | ||
// that should apply to `renderContainer` even if the rendered value is | ||
// not a TemplateInstance. However, it will only insert scoped styles | ||
// into the document if `prepareTemplateStyles` has already been called | ||
// for the given scope name. `prepareTemplateStyles` requires a | ||
// template element (and the local wrapper requires a Template), so we | ||
// create an empty one here to satisfy it. | ||
const template = part.value instanceof TemplateInstance ? | ||
part.value.template : | ||
new Template(html``, document.createElement('template')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's this part for? Add a comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added, let me know what you think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really going to work? I get the feeling that this isn't going to work with the original use-case of rendering There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the gist is that the styling we are about in this case was sent to ShadyCSS via So it seems like all we need to do in this case is ensure that (1) styles are removed from any lit template for the scope (would there be any if no TemplateResult is being rendered?, (2) ensure that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ok, I added another test specifically for this case.
AFAICT, the current setup seems to be that all styles in the first render are scoped and any styles that appear later aren't. So I think that even styles inserted into NodeParts of a top-level TemplateInstance were collected / scoped / removed from their rendered position on the first render. Am I correct in thinking that (local)
I was avoiding this because it seemed difficult to pry apart the Template editing parts of (local) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made |
||
prepareTemplateStyles( | ||
renderContainer as DocumentFragment, template, scopeName); | ||
removeNodes(container, container.firstChild); | ||
container.appendChild(renderContainer); | ||
parts.set(container, part); | ||
|
@@ -286,7 +293,7 @@ export const render = | |
// initial render to this container. | ||
// This is needed whenever dynamic changes are made so it would be | ||
// safest to do every render; however, this would regress performance | ||
// so we leave it up to the user to call `ShadyCSSS.styleElement` | ||
// so we leave it up to the user to call `ShadyCSS.styleElement` | ||
// for dynamic changes. | ||
if (!hasRendered && needsScoping) { | ||
window.ShadyCSS!.styleElement((container as ShadowRoot).host); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* @license | ||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/ | ||
|
||
import {renderShadowRoot} from '../test-utils/shadow-root.js'; | ||
|
||
const assert = chai.assert; | ||
|
||
suite('shady-render scoping shim', () => { | ||
test('scoped styles are applied for non-TemplateResult values', function() { | ||
if (typeof window.ShadyDOM === 'undefined' || !window.ShadyDOM.inUse) { | ||
this.skip(); | ||
return; | ||
} | ||
if (typeof window.ShadyCSS === 'undefined' || | ||
window.ShadyCSS.nativeShadow || | ||
window.ShadyCSS.ScopingShim === undefined) { | ||
this.skip(); | ||
return; | ||
} | ||
const container = document.createElement('scope-1'); | ||
window.ShadyCSS.ScopingShim.prepareAdoptedCssText( | ||
[':host { border-top: 2px solid black; }'], 'scope-1'); | ||
document.body.appendChild(container); | ||
renderShadowRoot(undefined, container); | ||
assert.equal( | ||
getComputedStyle(container).getPropertyValue('border-top-width').trim(), | ||
'2px'); | ||
document.body.removeChild(container); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!doctype html> | ||
<html> | ||
<head> | ||
<script> | ||
if (location.search.match('shadydom')) { | ||
window.ShadyDOM = {force: true}; | ||
} | ||
if (location.search.match('shimcssproperties')) { | ||
window.ShadyCSS = {shimcssproperties: true}; | ||
} | ||
</script> | ||
<script src="../node_modules/mocha/mocha.js"></script> | ||
<script src="../node_modules/chai/chai.js"></script> | ||
<script src="../node_modules/wct-mocha/wct-mocha.js"></script> | ||
<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script> | ||
<script src="../node_modules/@webcomponents/shadycss/scoping-shim.min.js"></script> | ||
</head> | ||
<body> | ||
<script type="module" src="./lib/shady-render-scoping-shim_test.js"></script> | ||
</body> | ||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update this comment since we're not creating an empty template here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.