From 855c928ea47c0dd667737fd24bacaf867b18fc21 Mon Sep 17 00:00:00 2001 From: Andrew Seier Date: Mon, 21 Oct 2024 21:25:13 -0700 Subject: [PATCH] Use non-registered symbols as weak map keys. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is now baseline as of 2023 so we ought to be able to use it. We use symbols to prevent internal abstractions from being leaked into code authored by integrators — for that, we just need an opaque token. But, because weak maps previously needed to be keyed with an _object_, we just created a dummy object as our key. Now, we can take the more modern approach of keying with a symbol. Closes #192. --- x-element.js | 58 ++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/x-element.js b/x-element.js index 9004540..c9cb247 100644 --- a/x-element.js +++ b/x-element.js @@ -1010,7 +1010,7 @@ export default class XElement extends HTMLElement { /** Internal implementation details for template engine. */ class TemplateEngine { - static #UNSET = Symbol('unset'); // Ensures a unique, initial comparison. + static #UNSET = Symbol(); // Ensures a unique, initial comparison. static #ATTRIBUTE_PREFIXES = { attribute: 'x-element-attribute-', boolean: 'x-element-boolean-', @@ -1027,8 +1027,8 @@ class TemplateEngine { static #interface = null; static #stateMap = new WeakMap(); // Maps nodes to internal state. static #analysisMap = new WeakMap(); // Maps strings to cached computations. - static #resultMap = new WeakMap(); // Maps references to results. - static #updaterMap = new WeakMap(); // Maps references to updaters. + static #resultMap = new WeakMap(); // Maps symbols to results. + static #updaterMap = new WeakMap(); // Maps symbols to updaters. /** * Declare HTML markup to be interpolated. @@ -1040,10 +1040,10 @@ class TemplateEngine { * @returns {any} */ static html(strings, ...values) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const result = TemplateEngine.#createResult('html', strings, values); - TemplateEngine.#resultMap.set(reference, result); - return reference; + TemplateEngine.#resultMap.set(symbol, result); + return symbol; } /** @@ -1056,10 +1056,10 @@ class TemplateEngine { * @returns {any} */ static svg(strings, ...values) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const result = TemplateEngine.#createResult('svg', strings, values); - TemplateEngine.#resultMap.set(reference, result); - return reference; + TemplateEngine.#resultMap.set(symbol, result); + return symbol; } /** @@ -1097,11 +1097,11 @@ class TemplateEngine { * @returns {any} */ static ifDefined(value) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const updater = (type, lastValue, details) => TemplateEngine.#ifDefined(type, value, lastValue, details); updater.value = value; - TemplateEngine.#updaterMap.set(reference, updater); - return reference; + TemplateEngine.#updaterMap.set(symbol, updater); + return symbol; } /** @@ -1115,11 +1115,11 @@ class TemplateEngine { * @returns {any} */ static nullish(value) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const updater = (type, lastValue, details) => TemplateEngine.#nullish(type, value, lastValue, details); updater.value = value; - TemplateEngine.#updaterMap.set(reference, updater); - return reference; + TemplateEngine.#updaterMap.set(symbol, updater); + return symbol; } /** @@ -1135,11 +1135,11 @@ class TemplateEngine { * @returns {any} */ static live(value) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const updater = (type, lastValue, details) => TemplateEngine.#live(type, value, lastValue, details); updater.value = value; - TemplateEngine.#updaterMap.set(reference, updater); - return reference; + TemplateEngine.#updaterMap.set(symbol, updater); + return symbol; } /** @@ -1153,11 +1153,11 @@ class TemplateEngine { * @returns {any} */ static unsafeHTML(value) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const updater = (type, lastValue, details) => TemplateEngine.#unsafeHTML(type, value, lastValue, details); updater.value = value; - TemplateEngine.#updaterMap.set(reference, updater); - return reference; + TemplateEngine.#updaterMap.set(symbol, updater); + return symbol; } /** @@ -1175,11 +1175,11 @@ class TemplateEngine { * @returns {any} */ static unsafeSVG(value) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const updater = (type, lastValue, details) => TemplateEngine.#unsafeSVG(type, value, lastValue, details); updater.value = value; - TemplateEngine.#updaterMap.set(reference, updater); - return reference; + TemplateEngine.#updaterMap.set(symbol, updater); + return symbol; } /** @@ -1260,12 +1260,12 @@ class TemplateEngine { } static #mapOrRepeat(value, identify, callback, name) { - const reference = TemplateEngine.#createReference(); + const symbol = Symbol(); const context = { identify, callback }; const updater = (type, lastValue, details) => TemplateEngine.#map(type, value, lastValue, details, context, name); updater.value = value; - TemplateEngine.#updaterMap.set(reference, updater); - return reference; + TemplateEngine.#updaterMap.set(symbol, updater); + return symbol; } static #exhaustString(string, state) { @@ -1756,10 +1756,6 @@ class TemplateEngine { } } - static #createReference() { - return Object.create(null); - } - static #setIfMissing(map, key, callback) { // Values set in this file are ALL truthy, so "get" is used (versus "has"). let value = map.get(key);