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