import { render, nothing } from '../lit-html.js'; import { directive, Directive } from '../directive.js'; import { isTemplateResult, getCommittedValue, setCommittedValue, insertPart, clearPart, isCompiledTemplateResult } from '../directive-helpers.js'; /** * @license * Copyright 2017 Google LLC * SPDX-License-Identifier: BSD-3-Clause */ /** * The template strings array contents are not compatible between the two * template result types as the compiled template contains a prepared string; * only use the returned template strings array as a cache key. */ const getStringsFromTemplateResult = (result) => isCompiledTemplateResult(result) ? result['_$litType$'].h : result.strings; class CacheDirective extends Directive { constructor(partInfo) { super(partInfo); this._templateCache = new WeakMap(); } render(v) { // Return an array of the value to induce lit-html to create a ChildPart // for the value that we can move into the cache. return [v]; } update(containerPart, [v]) { const _valueKey = isTemplateResult(this._value) ? getStringsFromTemplateResult(this._value) : null; const vKey = isTemplateResult(v) ? getStringsFromTemplateResult(v) : null; // If the previous value is a TemplateResult and the new value is not, // or is a different Template as the previous value, move the child part // into the cache. if (_valueKey !== null && (vKey === null || _valueKey !== vKey)) { // This is always an array because we return [v] in render() const partValue = getCommittedValue(containerPart); const childPart = partValue.pop(); let cachedContainerPart = this._templateCache.get(_valueKey); if (cachedContainerPart === undefined) { const fragment = document.createDocumentFragment(); cachedContainerPart = render(nothing, fragment); cachedContainerPart.setConnected(false); this._templateCache.set(_valueKey, cachedContainerPart); } // Move into cache setCommittedValue(cachedContainerPart, [childPart]); insertPart(cachedContainerPart, undefined, childPart); } // If the new value is a TemplateResult and the previous value is not, // or is a different Template as the previous value, restore the child // part from the cache. if (vKey !== null) { if (_valueKey === null || _valueKey !== vKey) { const cachedContainerPart = this._templateCache.get(vKey); if (cachedContainerPart !== undefined) { // Move the cached part back into the container part value const partValue = getCommittedValue(cachedContainerPart); const cachedPart = partValue.pop(); // Move cached part back into DOM clearPart(containerPart); insertPart(containerPart, undefined, cachedPart); setCommittedValue(containerPart, [cachedPart]); } } // Because vKey is non null, v must be a TemplateResult. this._value = v; } else { this._value = undefined; } return this.render(v); } } /** * Enables fast switching between multiple templates by caching the DOM nodes * and TemplateInstances produced by the templates. * * Example: * * ```js * let checked = false; * * html` * ${cache(checked ? html`input is checked` : html`input is not checked`)} * ` * ``` */ const cache = directive(CacheDirective); export { cache }; //# sourceMappingURL=cache.js.map