UNPKG

lit-html

Version:

HTML template literals in JavaScript

77 lines 3.25 kB
/** * @license * Copyright (c) 2018 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 { directive, NodePart, reparentNodes } from '../lit-html.js'; const partCaches = new WeakMap(); /** * Efficiently switches between two templates based on the given condition. The * rendered content is cached, and re-used when switching conditions. Templates * are evaluated lazily, so the passed values must be functions. * * While this directive can render any regular part, it makes the most sense * when used with TemplateResult since most other values are dirty checked * already. * * Example: * * let checked = false; * * html` * when(checked, () => html`Checkmark is checked`, () => html`Checkmark is not * checked`); * ` * * @param condition the condition to test truthiness against * @param trueValue the value to render given a true condition * @param falseValue the value to render given a false condition */ export const when = (condition, trueValue, falseValue) => directive((parentPart) => { let cache = partCaches.get(parentPart); // Create a new cache if this is the first render if (cache === undefined) { // Cache consists of two parts, one for each condition, and a // docment fragment which we cache the nodes of the condition that's // not currently rendered. cache = { truePart: new NodePart(parentPart.templateFactory), falsePart: new NodePart(parentPart.templateFactory), cacheContainer: document.createDocumentFragment(), }; partCaches.set(parentPart, cache); cache.truePart.appendIntoPart(parentPart); cache.falsePart.appendIntoPart(parentPart); } // Based on the condition, select which part to render and which value // to set on that part. const nextPart = condition ? cache.truePart : cache.falsePart; const nextValue = condition ? trueValue() : falseValue(); // If we switched condition, swap nodes to/from the cache. if (!!condition !== cache.prevCondition) { // Get the part which was rendered for the opposite condition. This // should be added to the cache. const prevPart = condition ? cache.falsePart : cache.truePart; // If the next part was rendered, take it from the cache if (nextPart.value) { parentPart.startNode.parentNode.appendChild(cache.cacheContainer); } // If the prev part was rendered, move it to the cache if (prevPart.value) { reparentNodes(cache.cacheContainer, prevPart.startNode, prevPart.endNode.nextSibling); } } // Set the next part's value nextPart.setValue(nextValue); nextPart.commit(); cache.prevCondition = !!condition; }); //# sourceMappingURL=when.js.map