lit-html
Advanced tools
Comparing version 0.11.3 to 0.11.4
@@ -19,2 +19,6 @@ # Change Log | ||
## [0.11.4] - 2018-09-17 | ||
### Fixed | ||
* Fixed issues with `shady-render` introduced in 0.11.3 ([#504](https://github.com/Polymer/lit-html/issues/504) and [#505](https://github.com/Polymer/lit-html/issues/505). | ||
## [0.11.3] - 2018-09-13 | ||
@@ -21,0 +25,0 @@ ### Changed |
@@ -35,4 +35,4 @@ /** | ||
const walker = document.createTreeWalker(content, walkerNodeFilter, null, false); | ||
let partIndex = 0; | ||
let part = parts[0]; | ||
let partIndex = nextActiveIndexInTemplateParts(parts); | ||
let part = parts[partIndex]; | ||
let nodeIndex = -1; | ||
@@ -65,3 +65,5 @@ let removeCount = 0; | ||
part.index = currentRemovingNode !== null ? -1 : part.index - removeCount; | ||
part = parts[++partIndex]; | ||
// go to the next active part. | ||
partIndex = nextActiveIndexInTemplateParts(parts, partIndex); | ||
part = parts[partIndex]; | ||
} | ||
@@ -72,3 +74,3 @@ } | ||
const countNodes = (node) => { | ||
let count = 1; | ||
let count = (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) ? 0 : 1; | ||
const walker = document.createTreeWalker(node, walkerNodeFilter, null, false); | ||
@@ -110,4 +112,4 @@ while (walker.nextNode()) { | ||
if (walkerNode === refNode) { | ||
insertCount = countNodes(node); | ||
refNode.parentNode.insertBefore(node, refNode); | ||
insertCount = countNodes(node); | ||
} | ||
@@ -114,0 +116,0 @@ while (partIndex !== -1 && parts[partIndex].index === walkerIndex) { |
@@ -89,45 +89,67 @@ /** | ||
*/ | ||
const styleTemplatesForScope = (fragment, template, scopeName) => { | ||
const prepareTemplateStyles = (renderedDOM, template, scopeName) => { | ||
shadyRenderSet.add(scopeName); | ||
// Move styles out of rendered DOM and store. | ||
const styles = fragment.querySelectorAll('style'); | ||
const styleFragment = document.createDocumentFragment(); | ||
const styles = renderedDOM.querySelectorAll('style'); | ||
// If there are no styles, there's no work to do. | ||
if (styles.length === 0) { | ||
return; | ||
} | ||
const condensedStyle = document.createElement('style'); | ||
// Collect styles into a single style. This helps us make sure ShadyCSS | ||
// manipulations will not prevent us from being able to fix up template | ||
// part indices. | ||
// NOTE: collecting styles is inefficient for browsers but ShadyCSS | ||
// currently does this anyway. When it does not, this should be changed. | ||
for (let i = 0; i < styles.length; i++) { | ||
styleFragment.appendChild(styles[i]); | ||
const style = styles[i]; | ||
style.parentNode.removeChild(style); | ||
condensedStyle.textContent += style.textContent; | ||
} | ||
// Remove styles from nested templates in this scope. | ||
removeStylesFromLitTemplates(scopeName); | ||
// And then put them into the "root" template passed in as `template`. | ||
insertNodeIntoTemplate(template, styleFragment, template.element.content.firstChild); | ||
// And then put the condensed style into the "root" template passed in as | ||
// `template`. | ||
insertNodeIntoTemplate(template, condensedStyle, template.element.content.firstChild); | ||
// Note, it's important that ShadyCSS gets the template that `lit-html` | ||
// will actually render so that it can update the style inside when | ||
// needed. | ||
// needed (e.g. @apply native Shadow DOM case). | ||
window.ShadyCSS.prepareTemplateStyles(template.element, scopeName); | ||
// When using native Shadow DOM, replace the style in the rendered | ||
// fragment. | ||
if (window.ShadyCSS.nativeShadow) { | ||
// When in native Shadow DOM, re-add styling to rendered content using | ||
// the style ShadyCSS produced. | ||
const style = template.element.content.querySelector('style'); | ||
if (style !== null) { | ||
fragment.insertBefore(style.cloneNode(true), fragment.firstChild); | ||
} | ||
renderedDOM.insertBefore(style.cloneNode(true), renderedDOM.firstChild); | ||
} | ||
else { | ||
// When not in native Shadow DOM, at this point ShadyCSS will have | ||
// removed the style from the lit template and parts will be broken as a | ||
// result. To fix this, we put back the style node ShadyCSS removed | ||
// and then tell lit to remove that node from the template. | ||
// NOTE, ShadyCSS creates its own style so we can safely add/remove | ||
// `condensedStyle` here. | ||
template.element.content.insertBefore(condensedStyle, template.element.content.firstChild); | ||
const removes = new Set(); | ||
removes.add(condensedStyle); | ||
removeNodesFromTemplate(template, removes); | ||
} | ||
}; | ||
export function render(result, container, scopeName) { | ||
const shouldScope = container instanceof ShadowRoot && compatibleShadyCSSVersion; | ||
const hasScoped = shadyRenderSet.has(scopeName); | ||
// Call `styleElement` to update element if it's already been processed. | ||
// This ensures the template is up to date before stamping the template | ||
// into the shadowRoot *or* updates the shadowRoot if we've already stamped | ||
// and are just updating the template. | ||
if (shouldScope && hasScoped) { | ||
window.ShadyCSS.styleElement(container.host); | ||
} | ||
const hasRendered = parts.has(container); | ||
litRender(result, container, shadyTemplateFactory(scopeName)); | ||
// When rendering a TemplateResult, scope the template with ShadyCSS | ||
if (shouldScope && !hasScoped && result instanceof TemplateResult) { | ||
const part = parts.get(container); | ||
const instance = part.value; | ||
styleTemplatesForScope(container, instance.template, scopeName); | ||
if (container instanceof ShadowRoot && compatibleShadyCSSVersion && | ||
result instanceof TemplateResult) { | ||
// Scope the element template one time only for this scope. | ||
if (!shadyRenderSet.has(scopeName)) { | ||
const part = parts.get(container); | ||
const instance = part.value; | ||
prepareTemplateStyles(container, instance.template, scopeName); | ||
} | ||
// Update styling if this is the initial render to this container. | ||
if (!hasRendered) { | ||
window.ShadyCSS.styleElement(container.host); | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=shady-render.js.map |
{ | ||
"name": "lit-html", | ||
"version": "0.11.3", | ||
"version": "0.11.4", | ||
"description": "HTML template literals in JavaScript", | ||
@@ -5,0 +5,0 @@ "license": "BSD-3-Clause", |
@@ -41,4 +41,4 @@ /** | ||
document.createTreeWalker(content, walkerNodeFilter, null as any, false); | ||
let partIndex = 0; | ||
let part = parts[0]; | ||
let partIndex = nextActiveIndexInTemplateParts(parts); | ||
let part = parts[partIndex]; | ||
let nodeIndex = -1; | ||
@@ -71,3 +71,5 @@ let removeCount = 0; | ||
part.index = currentRemovingNode !== null ? -1 : part.index - removeCount; | ||
part = parts[++partIndex]; | ||
// go to the next active part. | ||
partIndex = nextActiveIndexInTemplateParts(parts, partIndex); | ||
part = parts[partIndex]; | ||
} | ||
@@ -79,3 +81,3 @@ } | ||
const countNodes = (node: Node) => { | ||
let count = 1; | ||
let count = (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) ? 0 : 1; | ||
const walker = | ||
@@ -123,4 +125,4 @@ document.createTreeWalker(node, walkerNodeFilter, null as any, false); | ||
if (walkerNode === refNode) { | ||
insertCount = countNodes(node); | ||
refNode.parentNode!.insertBefore(node, refNode); | ||
insertCount = countNodes(node); | ||
} | ||
@@ -127,0 +129,0 @@ while (partIndex !== -1 && parts[partIndex].index === walkerIndex) { |
@@ -110,27 +110,49 @@ /** | ||
*/ | ||
const styleTemplatesForScope = | ||
(fragment: DocumentFragment, template: Template, scopeName: string) => { | ||
const prepareTemplateStyles = | ||
(renderedDOM: DocumentFragment, template: Template, scopeName: string) => { | ||
shadyRenderSet.add(scopeName); | ||
// Move styles out of rendered DOM and store. | ||
const styles = fragment.querySelectorAll('style'); | ||
const styleFragment = document.createDocumentFragment(); | ||
const styles = renderedDOM.querySelectorAll('style'); | ||
// If there are no styles, there's no work to do. | ||
if (styles.length === 0) { | ||
return; | ||
} | ||
const condensedStyle = document.createElement('style'); | ||
// Collect styles into a single style. This helps us make sure ShadyCSS | ||
// manipulations will not prevent us from being able to fix up template | ||
// part indices. | ||
// NOTE: collecting styles is inefficient for browsers but ShadyCSS | ||
// currently does this anyway. When it does not, this should be changed. | ||
for (let i = 0; i < styles.length; i++) { | ||
styleFragment.appendChild(styles[i]); | ||
const style = styles[i]; | ||
style.parentNode!.removeChild(style); | ||
condensedStyle.textContent! += style.textContent; | ||
} | ||
// Remove styles from nested templates in this scope. | ||
removeStylesFromLitTemplates(scopeName); | ||
// And then put them into the "root" template passed in as `template`. | ||
// And then put the condensed style into the "root" template passed in as | ||
// `template`. | ||
insertNodeIntoTemplate( | ||
template, styleFragment, template.element.content.firstChild); | ||
template, condensedStyle, template.element.content.firstChild); | ||
// Note, it's important that ShadyCSS gets the template that `lit-html` | ||
// will actually render so that it can update the style inside when | ||
// needed. | ||
// needed (e.g. @apply native Shadow DOM case). | ||
window.ShadyCSS.prepareTemplateStyles(template.element, scopeName); | ||
// When using native Shadow DOM, replace the style in the rendered | ||
// fragment. | ||
if (window.ShadyCSS.nativeShadow) { | ||
const style = template.element.content.querySelector('style'); | ||
if (style !== null) { | ||
fragment.insertBefore(style.cloneNode(true), fragment.firstChild); | ||
} | ||
// When in native Shadow DOM, re-add styling to rendered content using | ||
// the style ShadyCSS produced. | ||
const style = template.element.content.querySelector('style')!; | ||
renderedDOM.insertBefore(style.cloneNode(true), renderedDOM.firstChild); | ||
} else { | ||
// When not in native Shadow DOM, at this point ShadyCSS will have | ||
// removed the style from the lit template and parts will be broken as a | ||
// result. To fix this, we put back the style node ShadyCSS removed | ||
// and then tell lit to remove that node from the template. | ||
// NOTE, ShadyCSS creates its own style so we can safely add/remove | ||
// `condensedStyle` here. | ||
template.element.content.insertBefore( | ||
condensedStyle, template.element.content.firstChild); | ||
const removes = new Set(); | ||
removes.add(condensedStyle); | ||
removeNodesFromTemplate(template, removes); | ||
} | ||
@@ -143,20 +165,19 @@ }; | ||
scopeName: string) { | ||
const shouldScope = | ||
container instanceof ShadowRoot && compatibleShadyCSSVersion; | ||
const hasScoped = shadyRenderSet.has(scopeName); | ||
// Call `styleElement` to update element if it's already been processed. | ||
// This ensures the template is up to date before stamping the template | ||
// into the shadowRoot *or* updates the shadowRoot if we've already stamped | ||
// and are just updating the template. | ||
if (shouldScope && hasScoped) { | ||
window.ShadyCSS.styleElement((container as ShadowRoot).host); | ||
} | ||
const hasRendered = parts.has(container); | ||
litRender(result, container, shadyTemplateFactory(scopeName)); | ||
// When rendering a TemplateResult, scope the template with ShadyCSS | ||
if (shouldScope && !hasScoped && result instanceof TemplateResult) { | ||
const part = parts.get(container)!; | ||
const instance = part.value as TemplateInstance; | ||
styleTemplatesForScope( | ||
(container as ShadowRoot), instance.template, scopeName); | ||
if (container instanceof ShadowRoot && compatibleShadyCSSVersion && | ||
result instanceof TemplateResult) { | ||
// Scope the element template one time only for this scope. | ||
if (!shadyRenderSet.has(scopeName)) { | ||
const part = parts.get(container)!; | ||
const instance = part.value as TemplateInstance; | ||
prepareTemplateStyles( | ||
(container as ShadowRoot), instance.template, scopeName); | ||
} | ||
// Update styling if this is the initial render to this container. | ||
if (!hasRendered) { | ||
window.ShadyCSS.styleElement((container as ShadowRoot).host); | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
335845
4840