jails-js 6.1.0 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -797,15 +797,8 @@ const Component = ({ name, module, dependencies, node, templates: templates2, si
797
797
  }
798
798
  },
799
799
  dataset(target, name2) {
800
- let el;
801
- let key;
802
- if (name2) {
803
- el = target;
804
- key = name2;
805
- } else {
806
- el = node;
807
- key = target;
808
- }
800
+ const el = name2 ? target : node;
801
+ const key = name2 ? name2 : target;
809
802
  const value = el.dataset[key];
810
803
  if (value === "true") return true;
811
804
  if (value === "false") return false;
@@ -820,6 +813,38 @@ const Component = ({ name, module, dependencies, node, templates: templates2, si
820
813
  }
821
814
  return value;
822
815
  },
816
+ attributes(target) {
817
+ let callbacks = [];
818
+ const elm = target || node;
819
+ const observer = new MutationObserver((mutationsList) => {
820
+ for (const mutation of mutationsList) {
821
+ if (mutation.type === "attributes") {
822
+ const attributeName = mutation.attributeName;
823
+ callbacks.forEach((item) => {
824
+ if (item.name == attributeName) {
825
+ item.callback(
826
+ attributeName,
827
+ elm.getAttribute(attributeName)
828
+ );
829
+ }
830
+ });
831
+ }
832
+ }
833
+ });
834
+ observer.observe(node, { attributes: true });
835
+ node.addEventListener(":unmount", () => {
836
+ callbacks = null;
837
+ observer.disconnect();
838
+ });
839
+ return {
840
+ onchange(name2, callback) {
841
+ callbacks.push({ name: name2, callback });
842
+ },
843
+ disconnect(callback) {
844
+ callbacks = callbacks.filter((item) => item.callback !== callback);
845
+ }
846
+ };
847
+ },
823
848
  /**
824
849
  * @Events
825
850
  */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/index.ts","../node_modules/idiomorph/dist/idiomorph.esm.js","../src/utils/pubsub.ts","../src/component.ts","../src/element.ts","../src/template-system.ts","../src/index.ts"],"sourcesContent":["\nconst textarea = document.createElement('textarea')\n\nexport const g = {\n\tscope: {}\n}\n\nexport const decodeHTML = (text) => {\n\ttextarea.innerHTML = text\n\treturn textarea.value\n}\n\nexport const rAF = (fn) => {\n\tif (requestAnimationFrame)\n\t\treturn requestAnimationFrame(fn)\n\telse\n\t\treturn setTimeout(fn, 1000 / 60)\n}\n\nexport const uuid = () => {\n\treturn Math.random().toString(36).substring(2, 9)\n}\n\nexport const dup = (o) => {\n\treturn JSON.parse(JSON.stringify(o))\n}\n\nexport const safe = (execute, val) => {\n\ttry{\n\t\treturn execute()\n\t}catch(err){\n\t\treturn val || ''\n\t}\n}\n","/**\n * @typedef {object} ConfigHead\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} [style]\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {function(Element): boolean} [shouldPreserve]\n * @property {function(Element): boolean} [shouldReAppend]\n * @property {function(Element): boolean} [shouldRemove]\n * @property {function(Element, {added: Node[], kept: Element[], removed: Element[]}): void} [afterHeadMorphed]\n */\n\n/**\n * @typedef {object} ConfigCallbacks\n *\n * @property {function(Node): boolean} [beforeNodeAdded]\n * @property {function(Node): void} [afterNodeAdded]\n * @property {function(Element, Node): boolean} [beforeNodeMorphed]\n * @property {function(Element, Node): void} [afterNodeMorphed]\n * @property {function(Element): boolean} [beforeNodeRemoved]\n * @property {function(Element): void} [afterNodeRemoved]\n * @property {function(string, Element, \"update\" | \"remove\"): boolean} [beforeAttributeUpdated]\n */\n\n/**\n * @typedef {object} Config\n *\n * @property {'outerHTML' | 'innerHTML'} [morphStyle]\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacks} [callbacks]\n * @property {ConfigHead} [head]\n */\n\n/**\n * @typedef {function} NoOp\n *\n * @returns {void}\n */\n\n/**\n * @typedef {object} ConfigHeadInternal\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} style\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {(function(Element): boolean) | NoOp} shouldPreserve\n * @property {(function(Element): boolean) | NoOp} shouldReAppend\n * @property {(function(Element): boolean) | NoOp} shouldRemove\n * @property {(function(Element, {added: Node[], kept: Element[], removed: Element[]}): void) | NoOp} afterHeadMorphed\n */\n\n/**\n * @typedef {object} ConfigCallbacksInternal\n *\n * @property {(function(Node): boolean) | NoOp} beforeNodeAdded\n * @property {(function(Node): void) | NoOp} afterNodeAdded\n * @property {(function(Node, Node): boolean) | NoOp} beforeNodeMorphed\n * @property {(function(Node, Node): void) | NoOp} afterNodeMorphed\n * @property {(function(Node): boolean) | NoOp} beforeNodeRemoved\n * @property {(function(Node): void) | NoOp} afterNodeRemoved\n * @property {(function(string, Element, \"update\" | \"remove\"): boolean) | NoOp} beforeAttributeUpdated\n */\n\n/**\n * @typedef {object} ConfigInternal\n *\n * @property {'outerHTML' | 'innerHTML'} morphStyle\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacksInternal} callbacks\n * @property {ConfigHeadInternal} head\n */\n\n/**\n * @typedef {Object} IdSets\n * @property {Set<string>} persistentIds\n * @property {Map<Node, Set<string>>} idMap\n */\n\n/**\n * @typedef {Function} Morph\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {undefined | Node[]}\n */\n\n// base IIFE to define idiomorph\n/**\n *\n * @type {{defaults: ConfigInternal, morph: Morph}}\n */\nvar Idiomorph = (function () {\n \"use strict\";\n\n /**\n * @typedef {object} MorphContext\n *\n * @property {Element} target\n * @property {Element} newContent\n * @property {ConfigInternal} config\n * @property {ConfigInternal['morphStyle']} morphStyle\n * @property {ConfigInternal['ignoreActive']} ignoreActive\n * @property {ConfigInternal['ignoreActiveValue']} ignoreActiveValue\n * @property {ConfigInternal['restoreFocus']} restoreFocus\n * @property {Map<Node, Set<string>>} idMap\n * @property {Set<string>} persistentIds\n * @property {ConfigInternal['callbacks']} callbacks\n * @property {ConfigInternal['head']} head\n * @property {HTMLDivElement} pantry\n */\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n\n const noOp = () => {};\n /**\n * Default configuration values, updatable by users now\n * @type {ConfigInternal}\n */\n const defaults = {\n morphStyle: \"outerHTML\",\n callbacks: {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n },\n head: {\n style: \"merge\",\n shouldPreserve: (elt) => elt.getAttribute(\"im-preserve\") === \"true\",\n shouldReAppend: (elt) => elt.getAttribute(\"im-re-append\") === \"true\",\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n },\n restoreFocus: true,\n };\n\n /**\n * Core idiomorph function for morphing one DOM tree to another\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {Promise<Node[]> | Node[]}\n */\n function morph(oldNode, newContent, config = {}) {\n oldNode = normalizeElement(oldNode);\n const newNode = normalizeParent(newContent);\n const ctx = createMorphContext(oldNode, newNode, config);\n\n const morphedNodes = saveAndRestoreFocus(ctx, () => {\n return withHeadBlocking(\n ctx,\n oldNode,\n newNode,\n /** @param {MorphContext} ctx */ (ctx) => {\n if (ctx.morphStyle === \"innerHTML\") {\n morphChildren(ctx, oldNode, newNode);\n return Array.from(oldNode.childNodes);\n } else {\n return morphOuterHTML(ctx, oldNode, newNode);\n }\n },\n );\n });\n\n ctx.pantry.remove();\n return morphedNodes;\n }\n\n /**\n * Morph just the outerHTML of the oldNode to the newContent\n * We have to be careful because the oldNode could have siblings which need to be untouched\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @returns {Node[]}\n */\n function morphOuterHTML(ctx, oldNode, newNode) {\n const oldParent = normalizeParent(oldNode);\n\n // basis for calulating which nodes were morphed\n // since there may be unmorphed sibling nodes\n let childNodes = Array.from(oldParent.childNodes);\n const index = childNodes.indexOf(oldNode);\n // how many elements are to the right of the oldNode\n const rightMargin = childNodes.length - (index + 1);\n\n morphChildren(\n ctx,\n oldParent,\n newNode,\n // these two optional params are the secret sauce\n oldNode, // start point for iteration\n oldNode.nextSibling, // end point for iteration\n );\n\n // return just the morphed nodes\n childNodes = Array.from(oldParent.childNodes);\n return childNodes.slice(index, childNodes.length - rightMargin);\n }\n\n /**\n * @param {MorphContext} ctx\n * @param {Function} fn\n * @returns {Promise<Node[]> | Node[]}\n */\n function saveAndRestoreFocus(ctx, fn) {\n if (!ctx.config.restoreFocus) return fn();\n let activeElement =\n /** @type {HTMLInputElement|HTMLTextAreaElement|null} */ (\n document.activeElement\n );\n\n // don't bother if the active element is not an input or textarea\n if (\n !(\n activeElement instanceof HTMLInputElement ||\n activeElement instanceof HTMLTextAreaElement\n )\n ) {\n return fn();\n }\n\n const { id: activeElementId, selectionStart, selectionEnd } = activeElement;\n\n const results = fn();\n\n if (activeElementId && activeElementId !== document.activeElement?.id) {\n activeElement = ctx.target.querySelector(`#${activeElementId}`);\n activeElement?.focus();\n }\n if (activeElement && !activeElement.selectionEnd && selectionEnd) {\n activeElement.setSelectionRange(selectionStart, selectionEnd);\n }\n\n return results;\n }\n\n const morphChildren = (function () {\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm:\n * - for each node in the new content:\n * - search self and siblings for an id set match, falling back to a soft match\n * - if match found\n * - remove any nodes up to the match:\n * - pantry persistent nodes\n * - delete the rest\n * - morph the match\n * - elsif no match found, and node is persistent\n * - find its match by querying the old root (future) and pantry (past)\n * - move it and its children here\n * - morph it\n * - else\n * - create a new node from scratch as a last result\n *\n * @param {MorphContext} ctx the merge context\n * @param {Element} oldParent the old content that we are merging the new content into\n * @param {Element} newParent the parent element of the new content\n * @param {Node|null} [insertionPoint] the point in the DOM we start morphing at (defaults to first child)\n * @param {Node|null} [endPoint] the point in the DOM we stop morphing at (defaults to after last child)\n */\n function morphChildren(\n ctx,\n oldParent,\n newParent,\n insertionPoint = null,\n endPoint = null,\n ) {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // @ts-ignore we can pretend the DocumentFragment is an Element\n oldParent = oldParent.content;\n // @ts-ignore ditto\n newParent = newParent.content;\n }\n insertionPoint ||= oldParent.firstChild;\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint != endPoint) {\n const bestMatch = findBestMatch(\n ctx,\n newChild,\n insertionPoint,\n endPoint,\n );\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n removeNodesBetween(ctx, insertionPoint, bestMatch);\n }\n morphNode(bestMatch, newChild, ctx);\n insertionPoint = bestMatch.nextSibling;\n continue;\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) {\n // move it and all its children here and morph\n const movedChild = moveBeforeById(\n oldParent,\n newChild.id,\n insertionPoint,\n ctx,\n );\n morphNode(movedChild, newChild, ctx);\n insertionPoint = movedChild.nextSibling;\n continue;\n }\n\n // last resort: insert the new node from scratch\n const insertedNode = createNode(\n oldParent,\n newChild,\n insertionPoint,\n ctx,\n );\n // could be null if beforeNodeAdded prevented insertion\n if (insertedNode) {\n insertionPoint = insertedNode.nextSibling;\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint != endPoint) {\n const tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(ctx, tempNode);\n }\n }\n\n /**\n * This performs the action of inserting a new node while handling situations where the node contains\n * elements with persistent ids and possible state info we can still preserve by moving in and then morphing\n *\n * @param {Element} oldParent\n * @param {Node} newChild\n * @param {Node|null} insertionPoint\n * @param {MorphContext} ctx\n * @returns {Node|null}\n */\n function createNode(oldParent, newChild, insertionPoint, ctx) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;\n if (ctx.idMap.has(newChild)) {\n // node has children with ids with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n /** @type {Element} */ (newChild).tagName,\n );\n oldParent.insertBefore(newEmptyChild, insertionPoint);\n morphNode(newEmptyChild, newChild, ctx);\n ctx.callbacks.afterNodeAdded(newEmptyChild);\n return newEmptyChild;\n } else {\n // optimisation: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true); // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newClonedChild);\n return newClonedChild;\n }\n }\n\n //=============================================================================\n // Matching Functions\n //=============================================================================\n const findBestMatch = (function () {\n /**\n * Scans forward from the startPoint to the endPoint looking for a match\n * for the node. It looks for an id set match first, then a soft match.\n * We abort softmatching if we find two future soft matches, to reduce churn.\n * @param {Node} node\n * @param {MorphContext} ctx\n * @param {Node | null} startPoint\n * @param {Node | null} endPoint\n * @returns {Node | null}\n */\n function findBestMatch(ctx, node, startPoint, endPoint) {\n let softMatch = null;\n let nextSibling = node.nextSibling;\n let siblingSoftMatchCount = 0;\n\n let cursor = startPoint;\n while (cursor && cursor != endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n if (isIdSetMatch(ctx, cursor, node)) {\n return cursor; // found an id set match, we're done!\n }\n\n // we haven't yet saved a soft match fallback\n if (softMatch === null) {\n // the current soft match will hard match something else in the future, leave it\n if (!ctx.idMap.has(cursor)) {\n // save this as the fallback if we get through the loop without finding a hard match\n softMatch = cursor;\n }\n }\n }\n if (\n softMatch === null &&\n nextSibling &&\n isSoftMatch(cursor, nextSibling)\n ) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n softMatch = undefined;\n }\n }\n\n // if the current node contains active element, stop looking for better future matches,\n // because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus\n if (cursor.contains(document.activeElement)) break;\n\n cursor = cursor.nextSibling;\n }\n\n return softMatch || null;\n }\n\n /**\n *\n * @param {MorphContext} ctx\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isIdSetMatch(ctx, oldNode, newNode) {\n let oldSet = ctx.idMap.get(oldNode);\n let newSet = ctx.idMap.get(newNode);\n\n if (!newSet || !oldSet) return false;\n\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n *\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isSoftMatch(oldNode, newNode) {\n // ok to cast: if one is not element, `id` and `tagName` will be undefined and we'll just compare that.\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n return (\n oldElt.nodeType === newElt.nodeType &&\n oldElt.tagName === newElt.tagName &&\n // If oldElt has an `id` with possible state and it doesn't match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!oldElt.id || oldElt.id === newElt.id)\n );\n }\n\n return findBestMatch;\n })();\n\n //=============================================================================\n // DOM Manipulation Functions\n //=============================================================================\n\n /**\n * Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n * - Persistent nodes will be moved to the pantry for later reuse\n * - Other nodes will have their hooks called, and then are removed\n * @param {MorphContext} ctx\n * @param {Node} node\n */\n function removeNode(ctx, node) {\n // are we going to id set match this later?\n if (ctx.idMap.has(node)) {\n // skip callbacks and move to pantry\n moveBefore(ctx.pantry, node, null);\n } else {\n // remove for realsies\n if (ctx.callbacks.beforeNodeRemoved(node) === false) return;\n node.parentNode?.removeChild(node);\n ctx.callbacks.afterNodeRemoved(node);\n }\n }\n\n /**\n * Remove nodes between the start and end nodes\n * @param {MorphContext} ctx\n * @param {Node} startInclusive\n * @param {Node} endExclusive\n * @returns {Node|null}\n */\n function removeNodesBetween(ctx, startInclusive, endExclusive) {\n /** @type {Node | null} */\n let cursor = startInclusive;\n // remove nodes until the endExclusive node\n while (cursor && cursor !== endExclusive) {\n let tempNode = /** @type {Node} */ (cursor);\n cursor = cursor.nextSibling;\n removeNode(ctx, tempNode);\n }\n return cursor;\n }\n\n /**\n * Search for an element by id within the document and pantry, and move it using moveBefore.\n *\n * @param {Element} parentNode - The parent node to which the element will be moved.\n * @param {string} id - The ID of the element to be moved.\n * @param {Node | null} after - The reference node to insert the element before.\n * If `null`, the element is appended as the last child.\n * @param {MorphContext} ctx\n * @returns {Element} The found element\n */\n function moveBeforeById(parentNode, id, after, ctx) {\n const target =\n /** @type {Element} - will always be found */\n (\n ctx.target.querySelector(`#${id}`) ||\n ctx.pantry.querySelector(`#${id}`)\n );\n removeElementFromAncestorsIdMaps(target, ctx);\n moveBefore(parentNode, target, after);\n return target;\n }\n\n /**\n * Removes an element from its ancestors' id maps. This is needed when an element is moved from the\n * \"future\" via `moveBeforeId`. Otherwise, its erstwhile ancestors could be mistakenly moved to the\n * pantry rather than being deleted, preventing their removal hooks from being called.\n *\n * @param {Element} element - element to remove from its ancestors' id maps\n * @param {MorphContext} ctx\n */\n function removeElementFromAncestorsIdMaps(element, ctx) {\n const id = element.id;\n /** @ts-ignore - safe to loop in this way **/\n while ((element = element.parentNode)) {\n let idSet = ctx.idMap.get(element);\n if (idSet) {\n idSet.delete(id);\n if (!idSet.size) {\n ctx.idMap.delete(element);\n }\n }\n }\n }\n\n /**\n * Moves an element before another element within the same parent.\n * Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n * This is essentialy a forward-compat wrapper.\n *\n * @param {Element} parentNode - The parent node containing the after element.\n * @param {Node} element - The element to be moved.\n * @param {Node | null} after - The reference node to insert `element` before.\n * If `null`, `element` is appended as the last child.\n */\n function moveBefore(parentNode, element, after) {\n // @ts-ignore - use proposed moveBefore feature\n if (parentNode.moveBefore) {\n try {\n // @ts-ignore - use proposed moveBefore feature\n parentNode.moveBefore(element, after);\n } catch (e) {\n // fall back to insertBefore as some browsers may fail on moveBefore when trying to move Dom disconnected nodes to pantry\n parentNode.insertBefore(element, after);\n }\n } else {\n parentNode.insertBefore(element, after);\n }\n }\n\n return morphChildren;\n })();\n\n //=============================================================================\n // Single Node Morphing Code\n //=============================================================================\n const morphNode = (function () {\n /**\n * @param {Node} oldNode root node to merge content into\n * @param {Node} newContent new content to merge\n * @param {MorphContext} ctx the merge context\n * @returns {Node | null} the element that ended up in the DOM\n */\n function morphNode(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n return null;\n }\n\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) {\n return oldNode;\n }\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (\n oldNode instanceof HTMLHeadElement &&\n ctx.head.style !== \"morph\"\n ) {\n // ok to cast: if newContent wasn't also a <head>, it would've got caught in the `!isSoftMatch` branch above\n handleHeadElement(\n oldNode,\n /** @type {HTMLHeadElement} */ (newContent),\n ctx,\n );\n } else {\n morphAttributes(oldNode, newContent, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n // @ts-ignore newContent can be a node here because .firstChild will be null\n morphChildren(ctx, oldNode, newContent);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n\n /**\n * syncs the oldNode to the newNode, copying over all attributes and\n * inner element state from the newNode to the oldNode\n *\n * @param {Node} oldNode the node to copy attributes & state to\n * @param {Node} newNode the node to copy attributes & state from\n * @param {MorphContext} ctx the merge context\n */\n function morphAttributes(oldNode, newNode, ctx) {\n let type = newNode.nodeType;\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n const oldAttributes = oldElt.attributes;\n const newAttributes = newElt.attributes;\n for (const newAttribute of newAttributes) {\n if (ignoreAttribute(newAttribute.name, oldElt, \"update\", ctx)) {\n continue;\n }\n if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) {\n oldElt.setAttribute(newAttribute.name, newAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = oldAttributes.length - 1; 0 <= i; i--) {\n const oldAttribute = oldAttributes[i];\n\n // toAttributes is a live NamedNodeMap, so iteration+mutation is unsafe\n // e.g. custom element attribute callbacks can remove other attributes\n if (!oldAttribute) continue;\n\n if (!newElt.hasAttribute(oldAttribute.name)) {\n if (ignoreAttribute(oldAttribute.name, oldElt, \"remove\", ctx)) {\n continue;\n }\n oldElt.removeAttribute(oldAttribute.name);\n }\n }\n\n if (!ignoreValueOfActiveElement(oldElt, ctx)) {\n syncInputValue(oldElt, newElt, ctx);\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue;\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param {Element} oldElement the element to sync the input value to\n * @param {Element} newElement the element to sync the input value from\n * @param {MorphContext} ctx the merge context\n */\n function syncInputValue(oldElement, newElement, ctx) {\n if (\n oldElement instanceof HTMLInputElement &&\n newElement instanceof HTMLInputElement &&\n newElement.type !== \"file\"\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n\n // sync boolean attributes\n syncBooleanAttribute(oldElement, newElement, \"checked\", ctx);\n syncBooleanAttribute(oldElement, newElement, \"disabled\", ctx);\n\n if (!newElement.hasAttribute(\"value\")) {\n if (!ignoreAttribute(\"value\", oldElement, \"remove\", ctx)) {\n oldElement.value = \"\";\n oldElement.removeAttribute(\"value\");\n }\n } else if (oldValue !== newValue) {\n if (!ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n oldElement.setAttribute(\"value\", newValue);\n oldElement.value = newValue;\n }\n }\n // TODO: QUESTION(1cg): this used to only check `newElement` unlike the other branches -- why?\n // did I break something?\n } else if (\n oldElement instanceof HTMLOptionElement &&\n newElement instanceof HTMLOptionElement\n ) {\n syncBooleanAttribute(oldElement, newElement, \"selected\", ctx);\n } else if (\n oldElement instanceof HTMLTextAreaElement &&\n newElement instanceof HTMLTextAreaElement\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n if (ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n return;\n }\n if (newValue !== oldValue) {\n oldElement.value = newValue;\n }\n if (\n oldElement.firstChild &&\n oldElement.firstChild.nodeValue !== newValue\n ) {\n oldElement.firstChild.nodeValue = newValue;\n }\n }\n }\n\n /**\n * @param {Element} oldElement element to write the value to\n * @param {Element} newElement element to read the value from\n * @param {string} attributeName the attribute name\n * @param {MorphContext} ctx the merge context\n */\n function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n const newLiveValue = newElement[attributeName],\n // @ts-ignore ditto\n oldLiveValue = oldElement[attributeName];\n if (newLiveValue !== oldLiveValue) {\n const ignoreUpdate = ignoreAttribute(\n attributeName,\n oldElement,\n \"update\",\n ctx,\n );\n if (!ignoreUpdate) {\n // update attribute's associated DOM property\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n oldElement[attributeName] = newElement[attributeName];\n }\n if (newLiveValue) {\n if (!ignoreUpdate) {\n // https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML\n // this is the correct way to set a boolean attribute to \"true\"\n oldElement.setAttribute(attributeName, \"\");\n }\n } else {\n if (!ignoreAttribute(attributeName, oldElement, \"remove\", ctx)) {\n oldElement.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * @param {string} attr the attribute to be mutated\n * @param {Element} element the element that is going to be updated\n * @param {\"update\" | \"remove\"} updateType\n * @param {MorphContext} ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, element, updateType, ctx) {\n if (\n attr === \"value\" &&\n ctx.ignoreActiveValue &&\n element === document.activeElement\n ) {\n return true;\n }\n return (\n ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) ===\n false\n );\n }\n\n /**\n * @param {Node} possibleActiveElement\n * @param {MorphContext} ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return (\n !!ctx.ignoreActiveValue &&\n possibleActiveElement === document.activeElement &&\n possibleActiveElement !== document.body\n );\n }\n\n return morphNode;\n })();\n\n //=============================================================================\n // Head Management Functions\n //=============================================================================\n /**\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @param {function} callback\n * @returns {Node[] | Promise<Node[]>}\n */\n function withHeadBlocking(ctx, oldNode, newNode, callback) {\n if (ctx.head.block) {\n const oldHead = oldNode.querySelector(\"head\");\n const newHead = newNode.querySelector(\"head\");\n if (oldHead && newHead) {\n const promises = handleHeadElement(oldHead, newHead, ctx);\n // when head promises resolve, proceed ignoring the head tag\n return Promise.all(promises).then(() => {\n const newCtx = Object.assign(ctx, {\n head: {\n block: false,\n ignore: true,\n },\n });\n return callback(newCtx);\n });\n }\n }\n // just proceed if we not head blocking\n return callback(ctx);\n }\n\n /**\n * The HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n *\n * @param {Element} oldHead\n * @param {Element} newHead\n * @param {MorphContext} ctx\n * @returns {Promise<void>[]}\n */\n function handleHeadElement(oldHead, newHead, ctx) {\n let added = [];\n let removed = [];\n let preserved = [];\n let nodesToAppend = [];\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHead.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of oldHead.children) {\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (ctx.head.style === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n // TODO: This could theoretically be null, based on type\n let newElt = /** @type {ChildNode} */ (\n document.createRange().createContextualFragment(newNode.outerHTML)\n .firstChild\n );\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (\n (\"href\" in newElt && newElt.href) ||\n (\"src\" in newElt && newElt.src)\n ) {\n /** @type {(result?: any) => void} */ let resolve;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener(\"load\", function () {\n resolve();\n });\n promises.push(promise);\n }\n oldHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n oldHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(oldHead, {\n added: added,\n kept: preserved,\n removed: removed,\n });\n return promises;\n }\n\n //=============================================================================\n // Create Morph Context Functions\n //=============================================================================\n const createMorphContext = (function () {\n /**\n *\n * @param {Element} oldNode\n * @param {Element} newContent\n * @param {Config} config\n * @returns {MorphContext}\n */\n function createMorphContext(oldNode, newContent, config) {\n const { persistentIds, idMap } = createIdMaps(oldNode, newContent);\n\n const mergedConfig = mergeDefaults(config);\n const morphStyle = mergedConfig.morphStyle || \"outerHTML\";\n if (![\"innerHTML\", \"outerHTML\"].includes(morphStyle)) {\n throw `Do not understand how to morph style ${morphStyle}`;\n }\n\n return {\n target: oldNode,\n newContent: newContent,\n config: mergedConfig,\n morphStyle: morphStyle,\n ignoreActive: mergedConfig.ignoreActive,\n ignoreActiveValue: mergedConfig.ignoreActiveValue,\n restoreFocus: mergedConfig.restoreFocus,\n idMap: idMap,\n persistentIds: persistentIds,\n pantry: createPantry(),\n callbacks: mergedConfig.callbacks,\n head: mergedConfig.head,\n };\n }\n\n /**\n * Deep merges the config object and the Idiomorph.defaults object to\n * produce a final configuration object\n * @param {Config} config\n * @returns {ConfigInternal}\n */\n function mergeDefaults(config) {\n let finalConfig = Object.assign({}, defaults);\n\n // copy top level stuff into final config\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = Object.assign(\n {},\n defaults.callbacks,\n config.callbacks,\n );\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = Object.assign({}, defaults.head, config.head);\n\n return finalConfig;\n }\n\n /**\n * @returns {HTMLDivElement}\n */\n function createPantry() {\n const pantry = document.createElement(\"div\");\n pantry.hidden = true;\n document.body.insertAdjacentElement(\"afterend\", pantry);\n return pantry;\n }\n\n /**\n * Returns all elements with an ID contained within the root element and its descendants\n *\n * @param {Element} root\n * @returns {Element[]}\n */\n function findIdElements(root) {\n let elements = Array.from(root.querySelectorAll(\"[id]\"));\n if (root.id) {\n elements.push(root);\n }\n return elements;\n }\n\n /**\n * A bottom-up algorithm that populates a map of Element -> IdSet.\n * The idSet for a given element is the set of all IDs contained within its subtree.\n * As an optimzation, we filter these IDs through the given list of persistent IDs,\n * because we don't need to bother considering IDed elements that won't be in the new content.\n *\n * @param {Map<Node, Set<string>>} idMap\n * @param {Set<string>} persistentIds\n * @param {Element} root\n * @param {Element[]} elements\n */\n function populateIdMapWithTree(idMap, persistentIds, root, elements) {\n for (const elt of elements) {\n if (persistentIds.has(elt.id)) {\n /** @type {Element|null} */\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n\n if (current === root) break;\n current = current.parentElement;\n }\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {IdSets}\n */\n function createIdMaps(oldContent, newContent) {\n const oldIdElements = findIdElements(oldContent);\n const newIdElements = findIdElements(newContent);\n\n const persistentIds = createPersistentIds(oldIdElements, newIdElements);\n\n /** @type {Map<Node, Set<string>>} */\n let idMap = new Map();\n populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);\n\n /** @ts-ignore - if newContent is a duck-typed parent, pass its single child node as the root to halt upwards iteration */\n const newRoot = newContent.__idiomorphRoot || newContent;\n populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements);\n\n return { persistentIds, idMap };\n }\n\n /**\n * This function computes the set of ids that persist between the two contents excluding duplicates\n *\n * @param {Element[]} oldIdElements\n * @param {Element[]} newIdElements\n * @returns {Set<string>}\n */\n function createPersistentIds(oldIdElements, newIdElements) {\n let duplicateIds = new Set();\n\n /** @type {Map<string, string>} */\n let oldIdTagNameMap = new Map();\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id);\n } else {\n oldIdTagNameMap.set(id, tagName);\n }\n }\n\n let persistentIds = new Set();\n for (const { id, tagName } of newIdElements) {\n if (persistentIds.has(id)) {\n duplicateIds.add(id);\n } else if (oldIdTagNameMap.get(id) === tagName) {\n persistentIds.add(id);\n }\n // skip if tag types mismatch because its not possible to morph one tag into another\n }\n\n for (const id of duplicateIds) {\n persistentIds.delete(id);\n }\n return persistentIds;\n }\n\n return createMorphContext;\n })();\n\n //=============================================================================\n // HTML Normalization Functions\n //=============================================================================\n const { normalizeElement, normalizeParent } = (function () {\n /** @type {WeakSet<Node>} */\n const generatedByIdiomorph = new WeakSet();\n\n /**\n *\n * @param {Element | Document} content\n * @returns {Element}\n */\n function normalizeElement(content) {\n if (content instanceof Document) {\n return content.documentElement;\n } else {\n return content;\n }\n }\n\n /**\n *\n * @param {null | string | Node | HTMLCollection | Node[] | Document & {generatedByIdiomorph:boolean}} newContent\n * @returns {Element}\n */\n function normalizeParent(newContent) {\n if (newContent == null) {\n return document.createElement(\"div\"); // dummy parent element\n } else if (typeof newContent === \"string\") {\n return normalizeParent(parseContent(newContent));\n } else if (\n generatedByIdiomorph.has(/** @type {Element} */ (newContent))\n ) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return /** @type {Element} */ (newContent);\n } else if (newContent instanceof Node) {\n if (newContent.parentNode) {\n // we can't use the parent directly because newContent may have siblings\n // that we don't want in the morph, and reparenting might be expensive (TODO is it?),\n // so we create a duck-typed parent node instead.\n return createDuckTypedParent(newContent);\n } else {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement(\"div\");\n dummyParent.append(newContent);\n return dummyParent;\n }\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement(\"div\");\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n /**\n * Creates a fake duck-typed parent element to wrap a single node, without actually reparenting it.\n * \"If it walks like a duck, and quacks like a duck, then it must be a duck!\" -- James Whitcomb Riley (1849–1916)\n *\n * @param {Node} newContent\n * @returns {Element}\n */\n function createDuckTypedParent(newContent) {\n return /** @type {Element} */ (\n /** @type {unknown} */ ({\n childNodes: [newContent],\n /** @ts-ignore - cover your eyes for a minute, tsc */\n querySelectorAll: (s) => {\n /** @ts-ignore */\n const elements = newContent.querySelectorAll(s);\n /** @ts-ignore */\n return newContent.matches(s) ? [newContent, ...elements] : elements;\n },\n /** @ts-ignore */\n insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r),\n /** @ts-ignore */\n moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r),\n // for later use with populateIdMapWithTree to halt upwards iteration\n get __idiomorphRoot() {\n return newContent;\n },\n })\n );\n }\n\n /**\n *\n * @param {string} newContent\n * @returns {Node | null | DocumentFragment}\n */\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(\n /<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n \"\",\n );\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (\n contentWithSvgsRemoved.match(/<\\/html>/) ||\n contentWithSvgsRemoved.match(/<\\/head>/) ||\n contentWithSvgsRemoved.match(/<\\/body>/)\n ) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n generatedByIdiomorph.add(content);\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n generatedByIdiomorph.add(htmlElement);\n }\n return htmlElement;\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\n \"<body><template>\" + newContent + \"</template></body>\",\n \"text/html\",\n );\n let content = /** @type {HTMLTemplateElement} */ (\n responseDoc.body.querySelector(\"template\")\n ).content;\n generatedByIdiomorph.add(content);\n return content;\n }\n }\n\n return { normalizeElement, normalizeParent };\n })();\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults,\n };\n})();\n\nexport {Idiomorph};\n","\nconst topics: any = {}\nconst _async: any = {}\n\nexport const publish = (name, params) => {\n\t_async[name] = Object.assign({}, _async[name], params)\n\tif (topics[name])\n\t\ttopics[name].forEach(topic => topic(params))\n}\n\nexport const subscribe = (name, method) => {\n\ttopics[name] = topics[name] || []\n\ttopics[name].push(method)\n\tif (name in _async) {\n\t\tmethod(_async[name])\n\t}\n\treturn () => {\n\t\ttopics[name] = topics[name].filter( fn => fn != method )\n\t}\n}\n","import { safe, g, dup } from './utils'\nimport { Idiomorph } from 'idiomorph/dist/idiomorph.esm'\nimport { publish, subscribe } from './utils/pubsub'\n\nexport const Component = ({ name, module, dependencies, node, templates, signal, register }) => {\n\n\tlet tick\n\tlet preserve\t\t= []\n\n\tconst _model \t\t= module.model || {}\n\tconst initialState \t= (new Function( `return ${node.getAttribute('html-model') || '{}'}`))()\n\tconst tplid \t\t= node.getAttribute('tplid')\n\tconst scopeid \t\t= node.getAttribute('html-scopeid')\n\tconst tpl \t\t\t= templates[ tplid ]\n\tconst scope \t\t= g.scope[ scopeid ]\n\tconst model \t\t= dup(module?.model?.apply ? _model({ elm:node, initialState }) : _model)\n\tconst state \t\t= Object.assign({}, scope, model, initialState)\n\tconst view \t\t\t= module.view? module.view : (data) => data\n\n\tconst base = {\n\t\tname,\n\t\tmodel,\n\t\telm: node,\n\t\ttemplate: tpl.template,\n\t\tdependencies,\n\t\tpublish,\n\t\tsubscribe,\n\n\t\tmain(fn) {\n\t\t\tnode.addEventListener(':mount', fn)\n\t\t},\n\n\t\t/**\n\t\t * @State\n\t\t */\n\t\tstate : {\n\n\t\t\tprotected( list ) {\n\t\t\t\tif( list ) {\n\t\t\t\t\tpreserve = list\n\t\t\t\t} else {\n\t\t\t\t\treturn preserve\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tsave(data) {\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata( state )\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tset( data ) {\n\n\t\t\t\tif (!document.body.contains(node)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata(state)\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\n\t\t\t\tconst newstate = Object.assign({}, state, scope)\n\n\t\t\t\treturn new Promise((resolve) => {\n\t\t\t\t\trender(newstate, () => resolve(newstate))\n\t\t\t\t})\n\t\t\t},\n\n\t\t\tget() {\n\t\t\t\treturn Object.assign({}, state)\n\t\t\t}\n\t\t},\n\n\t\tdataset( target, name) {\n\n\t\t\tlet el\n\t\t\tlet key\n\n\t\t\tif( name ) {\n\t\t\t\tel = target\n\t\t\t\tkey = name\n\t\t\t}else {\n\t\t\t\tel = node\n\t\t\t\tkey = target\n\t\t\t}\n\n\t\t\tconst value = el.dataset[key]\n\n\t\t\tif (value === 'true') return true\n\t\t\tif (value === 'false') return false\n\t\t\tif (!isNaN(value) && value.trim() !== '') return Number(value)\n\n\t\t\ttry {\n\t\t\t\t// If it's not JSON, try parsing as JS expression\n\t\t\t\treturn new Function('return (' + value + ')')()\n\t\t\t} catch {}\n\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value)\n\t\t\t} catch {}\n\n\t\t\treturn value\n\t\t},\n\n\t\t/**\n\t\t * @Events\n\t\t */\n\t\ton( ev, selectorOrCallback, callback ) {\n\n\t\t\tif( callback ) {\n\t\t\t\tcallback.handler = (e) => {\n\t\t\t\t\tconst detail = e.detail || {}\n\t\t\t\t\tlet parent = e.target\n\t\t\t\t\twhile (parent) {\n\t\t\t\t\t\tif (parent.matches(selectorOrCallback)) {\n\t\t\t\t\t\t\te.delegateTarget = parent\n\t\t\t\t\t\t\tcallback.apply(node, [e].concat(detail.args))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parent === node) break\n\t\t\t\t\t\tparent = parent.parentNode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, callback.handler, {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: (ev == 'focus' || ev == 'blur' || ev == 'mouseenter' || ev == 'mouseleave')\n\t\t\t\t})\n\n\t\t\t} else {\n\t\t\t\tselectorOrCallback.handler = (e) => {\n\t\t\t\t\te.delegateTarget = node\n\t\t\t\t\tselectorOrCallback.apply(node, [e].concat(e.detail.args))\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, selectorOrCallback.handler, { signal })\n\t\t\t}\n\n\t\t},\n\n\t\toff( ev, callback ) {\n\t\t\tif( callback.handler ) {\n\t\t\t\tnode.removeEventListener(ev, callback.handler)\n\t\t\t}\n\t\t},\n\n\t\ttrigger(ev, selectorOrCallback, data) {\n\t\t\tif( selectorOrCallback.constructor === String ) {\n\t\t\t\tArray\n\t\t\t\t\t.from(node.querySelectorAll(selectorOrCallback))\n\t\t\t\t\t.forEach( children => {\n\t\t\t\t\t\tchildren.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }) )\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail:{ args: data } }))\n\t\t\t}\n\t\t},\n\n\t\temit(ev, data) {\n\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }))\n\t\t},\n\n\t\tunmount( fn ) {\n\t\t\tnode.addEventListener(':unmount', fn)\n\t\t},\n\n\t\tinnerHTML ( target, html_ ) {\n\t\t\tconst element = html_? target : node\n\t\t\tconst clone = element.cloneNode()\n\t\t\tconst html = html_? html_ : target\n\t\t\tclone.innerHTML = html\n\t\t\tIdiomorph.morph(element, clone)\n\t\t}\n\t}\n\n\tconst render = ( data, callback = (() => {}) ) => {\n\t\tclearTimeout( tick )\n\t\ttick = setTimeout(() => {\n\t\t\tconst html = tpl.render.call({...data, ...view(data)}, node, safe, g )\n\t\t\tIdiomorph.morph( node, html, IdiomorphOptions(node, register) )\n\t\t\tPromise.resolve().then(() => {\n\t\t\t\tnode.querySelectorAll('[tplid]')\n\t\t\t\t\t.forEach((element) => {\n\t\t\t\t\t\tconst child = register.get(element)\n\t\t\t\t\t\tif(!child) return\n\t\t\t\t\t\tchild.state.protected().forEach( key => delete data[key] )\n\t\t\t\t\t\tchild.state.set(data)\n\t\t\t\t\t})\n\t\t\t\tPromise.resolve().then(() => {\n\t\t\t\t\tg.scope = {}\n\t\t\t\t\tcallback()\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\trender( state )\n\tregister.set( node, base )\n\treturn module.default( base )\n}\n\nconst IdiomorphOptions = ( parent, register ) => ({\n\tcallbacks: {\n\t\tbeforeNodeMorphed( node ) {\n\t\t\tif( node.nodeType === 1 ) {\n\t\t\t\tif( 'html-static' in node.attributes ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif( register.get(node) && node !== parent ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n})\n","import { Component } from './component'\n\nconst register = new WeakMap()\n\nexport const Element = ({ component, templates, start }) => {\n\n\tconst { name, module, dependencies } = component\n\n\treturn class extends HTMLElement {\n\n\t\tconstructor() {\n\t\t\tsuper()\n\t\t}\n\n\t\tconnectedCallback() {\n\n\t\t\tthis.abortController = new AbortController()\n\n\t\t\tif( !this.getAttribute('tplid') ) {\n\t\t\t\tstart( this.parentNode )\n\t\t\t}\n\n\t\t\tconst rtrn = Component({\n\t\t\t\tnode:this,\n\t\t\t\tname,\n\t\t\t\tmodule,\n\t\t\t\tdependencies,\n\t\t\t\ttemplates,\n\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\tregister\n\t\t\t})\n\n\t\t\tif ( rtrn && rtrn.constructor === Promise ) {\n\t\t\t\trtrn.then(() => {\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t}\n\t\t}\n\n\t\tdisconnectedCallback() {\n\t\t\tthis.dispatchEvent( new CustomEvent(':unmount') )\n\t\t\tthis.abortController.abort()\n\t\t}\n\t}\n}\n","import { uuid, decodeHTML } from './utils'\n\nconst templates = {}\n\nconst config = {\n\ttags: ['{{', '}}']\n}\n\nexport const templateConfig = (newconfig) => {\n\tObject.assign( config, newconfig )\n}\n\nexport const template = ( target, { components }) => {\n\n\ttagElements( target, [...Object.keys( components ), '[html-if]', 'template'], components )\n\tconst clone = target.cloneNode( true )\n\n\ttransformTemplate( clone )\n\tremoveTemplateTagsRecursively( clone )\n\tsetTemplates( clone, components )\n\n\treturn templates\n}\n\nexport const compile = ( html ) => {\n\n\tconst parsedHtml = JSON.stringify( html )\n\n\treturn new Function('$element', 'safe', '$g',`\n\t\tvar $data = this;\n\t\twith( $data ){\n\t\t\tvar output=${parsedHtml\n\t\t\t\t.replace(/%%_=(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\"+safe(function(){return '+ decodeHTML(variable) +';})+\"'\n\t\t\t\t})\n\t\t\t\t.replace(/%%_(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\";' + decodeHTML(variable) +'\\noutput+=\"'\n\t\t\t\t})};return output;\n\t\t}\n\t`)\n}\n\nconst tagElements = ( target, keys, components ) => {\n\ttarget\n\t\t.querySelectorAll( keys.toString() )\n\t\t.forEach((node) => {\n\t\t\tconst name = node.localName\n\t\t\tif( name === 'template' ) {\n\t\t\t\treturn tagElements( node.content, keys, components )\n\t\t\t}\n\t\t\tif( node.getAttribute('html-if') && !node.id ) {\n\t\t\t\tnode.id = uuid()\n\t\t\t}\n\t\t\tif( name in components ) {\n\t\t\t\tnode.setAttribute('tplid', uuid())\n\t\t\t}\n\t\t})\n}\n\nconst transformAttributes = ( html ) => {\n\n\tconst regexTags = new RegExp(`\\\\${config.tags[0]}(.+?)\\\\${config.tags[1]}`, 'g')\n\n\treturn html\n\t\t.replace(/jails___scope-id/g, '%%_=$scopeid_%%')\n\t\t.replace(regexTags, '%%_=$1_%%')\n\t\t// Booleans\n\t\t// https://meiert.com/en/blog/boolean-attributes-of-html/\n\t\t.replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\\\"(.*?)\\\"/g, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`)\n\t\t// The rest\n\t\t.replace(/html-([^\\s]*?)=\\\"(.*?)\\\"/g, (all, key, value) => {\n\t\t\tif (key === 'key' || key === 'model' || key === 'scopeid' ) {\n\t\t\t\treturn all\n\t\t\t}\n\t\t\tif (value) {\n\t\t\t\tvalue = value.replace(/^{|}$/g, '')\n\t\t\t\treturn `${key}=\"%%_=safe(function(){ return ${value} })_%%\"`\n\t\t\t} else {\n\t\t\t\treturn all\n\t\t\t}\n\t\t})\n}\n\nconst transformTemplate = ( clone ) => {\n\n\tclone.querySelectorAll('template, [html-for], [html-if], [html-inner], [html-class]')\n\t\t.forEach(( element ) => {\n\n\t\t\tconst htmlFor \t= element.getAttribute('html-for')\n\t\t\tconst htmlIf \t= element.getAttribute('html-if')\n\t\t\tconst htmlInner = element.getAttribute('html-inner')\n\t\t\tconst htmlClass = element.getAttribute('html-class')\n\n\t\t\tif ( htmlFor ) {\n\n\t\t\t\telement.removeAttribute('html-for')\n\n\t\t\t\tconst split \t = htmlFor.match(/(.*)\\sin\\s(.*)/) || ''\n\t\t\t\tconst varname \t = split[1]\n\t\t\t\tconst object \t = split[2]\n\t\t\t\tconst objectname = object.split(/\\./).shift()\n\t\t\t\tconst open \t\t = document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${object} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${varname} = ${object}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${objectname}: ${objectname} }, { ${varname} :${varname}, $index: $index, $key: $key }); _%%`)\n\t\t\t\tconst close \t = document.createTextNode(`%%_ $index++; } })() _%%`)\n\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlIf) {\n\t\t\t\telement.removeAttribute('html-if')\n\t\t\t\tconst open = document.createTextNode(`%%_ if ( safe(function(){ return ${htmlIf} }) ){ _%%`)\n\t\t\t\tconst close = document.createTextNode(`%%_ } _%%`)\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlInner) {\n\t\t\t\telement.removeAttribute('html-inner')\n\t\t\t\telement.innerHTML = `%%_=${htmlInner}_%%`\n\t\t\t}\n\n\t\t\tif (htmlClass) {\n\t\t\t\telement.removeAttribute('html-class')\n\t\t\t\telement.className = (element.className + ` %%_=${htmlClass}_%%`).trim()\n\t\t\t}\n\n\t\t\tif( element.localName === 'template' ) {\n\t\t\t\ttransformTemplate(element.content)\n\t\t\t}\n\t\t})\n}\n\nconst setTemplates = ( clone, components ) => {\n\n\tArray.from(clone.querySelectorAll('[tplid]'))\n\t\t.reverse()\n\t\t.forEach((node) => {\n\n\t\t\tconst tplid = node.getAttribute('tplid')\n\t\t\tconst name = node.localName\n\t\t\tnode.setAttribute('html-scopeid', 'jails___scope-id')\n\n\t\t\tif( name in components && components[name].module.template ) {\n\t\t\t\tconst children = node.innerHTML\n\t\t\t\tconst html = components[name].module.template({ elm:node, children })\n\t\t\t\tnode.innerHTML = html\n\t\t\t}\n\n\t\t\tconst html = transformAttributes(node.outerHTML)\n\n\t\t\ttemplates[ tplid ] = {\n\t\t\t\ttemplate: html,\n\t\t\t\trender\t: compile(html)\n\t\t\t}\n\t\t})\n}\n\nconst removeTemplateTagsRecursively = (node) => {\n\n\t// Get all <template> elements within the node\n\tconst templates = node.querySelectorAll('template')\n\n\ttemplates.forEach((template) => {\n\n\t\tif( template.getAttribute('html-if') || template.getAttribute('html-inner') ) {\n\t\t\treturn\n\t\t}\n\n\t\t// Process any nested <template> tags within this <template> first\n\t\tremoveTemplateTagsRecursively(template.content)\n\n\t\t// Get the parent of the <template> tag\n\t\tconst parent = template.parentNode\n\n\t\tif (parent) {\n\t\t\t// Move all child nodes from the <template>'s content to its parent\n\t\t\tconst content = template.content\n\t\t\twhile (content.firstChild) {\n\t\t\t\tparent.insertBefore(content.firstChild, template)\n\t\t\t}\n\t\t\t// Remove the <template> tag itself\n\t\t\tparent.removeChild(template)\n\t\t}\n\t})\n}\n\nconst wrap = (open, node, close) => {\n\tnode.parentNode?.insertBefore(open, node)\n\tnode.parentNode?.insertBefore(close, node.nextSibling)\n}\n","\nimport { Element } from './element'\nimport { template, templateConfig as config } from './template-system'\n\nexport { publish, subscribe } from './utils/pubsub'\n\nexport const templateConfig = (options) => {\n\tconfig( options )\n}\n\nwindow.__jails__ = window.__jails__ || { components: {} }\n\nexport const register = ( name, module, dependencies ) => {\n\tconst { components } = window.__jails__\n\tcomponents[ name ] = { name, module, dependencies }\n}\n\nexport const start = ( target = document.body ) => {\n\n\tconst { components } = window.__jails__\n\tconst templates = template( target, { components } )\n\n\tObject\n\t\t.values( components )\n\t\t.forEach(({ name, module, dependencies }) => {\n\t\t\tif( !customElements.get(name) ) {\n\t\t\t\tcustomElements.define( name, Element({ component: { name, module, dependencies }, templates, start }))\n\t\t\t}\n\t})\n}\n\ndeclare global {\n\tinterface Window {\n\t __jails__?: {\n\t\tcomponents: Record<string, any>\n\t }\n\t}\n}\n"],"names":["config","ctx","morphChildren","findBestMatch","morphNode","createMorphContext","normalizeElement","normalizeParent","templates","register","name","Element","start","templateConfig","html","template"],"mappings":"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","x_google_ignoreList":[1]}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/index.ts","../node_modules/idiomorph/dist/idiomorph.esm.js","../src/utils/pubsub.ts","../src/component.ts","../src/element.ts","../src/template-system.ts","../src/index.ts"],"sourcesContent":["\nconst textarea = document.createElement('textarea')\n\nexport const g = {\n\tscope: {}\n}\n\nexport const decodeHTML = (text) => {\n\ttextarea.innerHTML = text\n\treturn textarea.value\n}\n\nexport const rAF = (fn) => {\n\tif (requestAnimationFrame)\n\t\treturn requestAnimationFrame(fn)\n\telse\n\t\treturn setTimeout(fn, 1000 / 60)\n}\n\nexport const uuid = () => {\n\treturn Math.random().toString(36).substring(2, 9)\n}\n\nexport const dup = (o) => {\n\treturn JSON.parse(JSON.stringify(o))\n}\n\nexport const safe = (execute, val) => {\n\ttry{\n\t\treturn execute()\n\t}catch(err){\n\t\treturn val || ''\n\t}\n}\n","/**\n * @typedef {object} ConfigHead\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} [style]\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {function(Element): boolean} [shouldPreserve]\n * @property {function(Element): boolean} [shouldReAppend]\n * @property {function(Element): boolean} [shouldRemove]\n * @property {function(Element, {added: Node[], kept: Element[], removed: Element[]}): void} [afterHeadMorphed]\n */\n\n/**\n * @typedef {object} ConfigCallbacks\n *\n * @property {function(Node): boolean} [beforeNodeAdded]\n * @property {function(Node): void} [afterNodeAdded]\n * @property {function(Element, Node): boolean} [beforeNodeMorphed]\n * @property {function(Element, Node): void} [afterNodeMorphed]\n * @property {function(Element): boolean} [beforeNodeRemoved]\n * @property {function(Element): void} [afterNodeRemoved]\n * @property {function(string, Element, \"update\" | \"remove\"): boolean} [beforeAttributeUpdated]\n */\n\n/**\n * @typedef {object} Config\n *\n * @property {'outerHTML' | 'innerHTML'} [morphStyle]\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacks} [callbacks]\n * @property {ConfigHead} [head]\n */\n\n/**\n * @typedef {function} NoOp\n *\n * @returns {void}\n */\n\n/**\n * @typedef {object} ConfigHeadInternal\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} style\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {(function(Element): boolean) | NoOp} shouldPreserve\n * @property {(function(Element): boolean) | NoOp} shouldReAppend\n * @property {(function(Element): boolean) | NoOp} shouldRemove\n * @property {(function(Element, {added: Node[], kept: Element[], removed: Element[]}): void) | NoOp} afterHeadMorphed\n */\n\n/**\n * @typedef {object} ConfigCallbacksInternal\n *\n * @property {(function(Node): boolean) | NoOp} beforeNodeAdded\n * @property {(function(Node): void) | NoOp} afterNodeAdded\n * @property {(function(Node, Node): boolean) | NoOp} beforeNodeMorphed\n * @property {(function(Node, Node): void) | NoOp} afterNodeMorphed\n * @property {(function(Node): boolean) | NoOp} beforeNodeRemoved\n * @property {(function(Node): void) | NoOp} afterNodeRemoved\n * @property {(function(string, Element, \"update\" | \"remove\"): boolean) | NoOp} beforeAttributeUpdated\n */\n\n/**\n * @typedef {object} ConfigInternal\n *\n * @property {'outerHTML' | 'innerHTML'} morphStyle\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacksInternal} callbacks\n * @property {ConfigHeadInternal} head\n */\n\n/**\n * @typedef {Object} IdSets\n * @property {Set<string>} persistentIds\n * @property {Map<Node, Set<string>>} idMap\n */\n\n/**\n * @typedef {Function} Morph\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {undefined | Node[]}\n */\n\n// base IIFE to define idiomorph\n/**\n *\n * @type {{defaults: ConfigInternal, morph: Morph}}\n */\nvar Idiomorph = (function () {\n \"use strict\";\n\n /**\n * @typedef {object} MorphContext\n *\n * @property {Element} target\n * @property {Element} newContent\n * @property {ConfigInternal} config\n * @property {ConfigInternal['morphStyle']} morphStyle\n * @property {ConfigInternal['ignoreActive']} ignoreActive\n * @property {ConfigInternal['ignoreActiveValue']} ignoreActiveValue\n * @property {ConfigInternal['restoreFocus']} restoreFocus\n * @property {Map<Node, Set<string>>} idMap\n * @property {Set<string>} persistentIds\n * @property {ConfigInternal['callbacks']} callbacks\n * @property {ConfigInternal['head']} head\n * @property {HTMLDivElement} pantry\n */\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n\n const noOp = () => {};\n /**\n * Default configuration values, updatable by users now\n * @type {ConfigInternal}\n */\n const defaults = {\n morphStyle: \"outerHTML\",\n callbacks: {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n },\n head: {\n style: \"merge\",\n shouldPreserve: (elt) => elt.getAttribute(\"im-preserve\") === \"true\",\n shouldReAppend: (elt) => elt.getAttribute(\"im-re-append\") === \"true\",\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n },\n restoreFocus: true,\n };\n\n /**\n * Core idiomorph function for morphing one DOM tree to another\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {Promise<Node[]> | Node[]}\n */\n function morph(oldNode, newContent, config = {}) {\n oldNode = normalizeElement(oldNode);\n const newNode = normalizeParent(newContent);\n const ctx = createMorphContext(oldNode, newNode, config);\n\n const morphedNodes = saveAndRestoreFocus(ctx, () => {\n return withHeadBlocking(\n ctx,\n oldNode,\n newNode,\n /** @param {MorphContext} ctx */ (ctx) => {\n if (ctx.morphStyle === \"innerHTML\") {\n morphChildren(ctx, oldNode, newNode);\n return Array.from(oldNode.childNodes);\n } else {\n return morphOuterHTML(ctx, oldNode, newNode);\n }\n },\n );\n });\n\n ctx.pantry.remove();\n return morphedNodes;\n }\n\n /**\n * Morph just the outerHTML of the oldNode to the newContent\n * We have to be careful because the oldNode could have siblings which need to be untouched\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @returns {Node[]}\n */\n function morphOuterHTML(ctx, oldNode, newNode) {\n const oldParent = normalizeParent(oldNode);\n\n // basis for calulating which nodes were morphed\n // since there may be unmorphed sibling nodes\n let childNodes = Array.from(oldParent.childNodes);\n const index = childNodes.indexOf(oldNode);\n // how many elements are to the right of the oldNode\n const rightMargin = childNodes.length - (index + 1);\n\n morphChildren(\n ctx,\n oldParent,\n newNode,\n // these two optional params are the secret sauce\n oldNode, // start point for iteration\n oldNode.nextSibling, // end point for iteration\n );\n\n // return just the morphed nodes\n childNodes = Array.from(oldParent.childNodes);\n return childNodes.slice(index, childNodes.length - rightMargin);\n }\n\n /**\n * @param {MorphContext} ctx\n * @param {Function} fn\n * @returns {Promise<Node[]> | Node[]}\n */\n function saveAndRestoreFocus(ctx, fn) {\n if (!ctx.config.restoreFocus) return fn();\n let activeElement =\n /** @type {HTMLInputElement|HTMLTextAreaElement|null} */ (\n document.activeElement\n );\n\n // don't bother if the active element is not an input or textarea\n if (\n !(\n activeElement instanceof HTMLInputElement ||\n activeElement instanceof HTMLTextAreaElement\n )\n ) {\n return fn();\n }\n\n const { id: activeElementId, selectionStart, selectionEnd } = activeElement;\n\n const results = fn();\n\n if (activeElementId && activeElementId !== document.activeElement?.id) {\n activeElement = ctx.target.querySelector(`#${activeElementId}`);\n activeElement?.focus();\n }\n if (activeElement && !activeElement.selectionEnd && selectionEnd) {\n activeElement.setSelectionRange(selectionStart, selectionEnd);\n }\n\n return results;\n }\n\n const morphChildren = (function () {\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm:\n * - for each node in the new content:\n * - search self and siblings for an id set match, falling back to a soft match\n * - if match found\n * - remove any nodes up to the match:\n * - pantry persistent nodes\n * - delete the rest\n * - morph the match\n * - elsif no match found, and node is persistent\n * - find its match by querying the old root (future) and pantry (past)\n * - move it and its children here\n * - morph it\n * - else\n * - create a new node from scratch as a last result\n *\n * @param {MorphContext} ctx the merge context\n * @param {Element} oldParent the old content that we are merging the new content into\n * @param {Element} newParent the parent element of the new content\n * @param {Node|null} [insertionPoint] the point in the DOM we start morphing at (defaults to first child)\n * @param {Node|null} [endPoint] the point in the DOM we stop morphing at (defaults to after last child)\n */\n function morphChildren(\n ctx,\n oldParent,\n newParent,\n insertionPoint = null,\n endPoint = null,\n ) {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // @ts-ignore we can pretend the DocumentFragment is an Element\n oldParent = oldParent.content;\n // @ts-ignore ditto\n newParent = newParent.content;\n }\n insertionPoint ||= oldParent.firstChild;\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint != endPoint) {\n const bestMatch = findBestMatch(\n ctx,\n newChild,\n insertionPoint,\n endPoint,\n );\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n removeNodesBetween(ctx, insertionPoint, bestMatch);\n }\n morphNode(bestMatch, newChild, ctx);\n insertionPoint = bestMatch.nextSibling;\n continue;\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) {\n // move it and all its children here and morph\n const movedChild = moveBeforeById(\n oldParent,\n newChild.id,\n insertionPoint,\n ctx,\n );\n morphNode(movedChild, newChild, ctx);\n insertionPoint = movedChild.nextSibling;\n continue;\n }\n\n // last resort: insert the new node from scratch\n const insertedNode = createNode(\n oldParent,\n newChild,\n insertionPoint,\n ctx,\n );\n // could be null if beforeNodeAdded prevented insertion\n if (insertedNode) {\n insertionPoint = insertedNode.nextSibling;\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint != endPoint) {\n const tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(ctx, tempNode);\n }\n }\n\n /**\n * This performs the action of inserting a new node while handling situations where the node contains\n * elements with persistent ids and possible state info we can still preserve by moving in and then morphing\n *\n * @param {Element} oldParent\n * @param {Node} newChild\n * @param {Node|null} insertionPoint\n * @param {MorphContext} ctx\n * @returns {Node|null}\n */\n function createNode(oldParent, newChild, insertionPoint, ctx) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;\n if (ctx.idMap.has(newChild)) {\n // node has children with ids with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n /** @type {Element} */ (newChild).tagName,\n );\n oldParent.insertBefore(newEmptyChild, insertionPoint);\n morphNode(newEmptyChild, newChild, ctx);\n ctx.callbacks.afterNodeAdded(newEmptyChild);\n return newEmptyChild;\n } else {\n // optimisation: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true); // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newClonedChild);\n return newClonedChild;\n }\n }\n\n //=============================================================================\n // Matching Functions\n //=============================================================================\n const findBestMatch = (function () {\n /**\n * Scans forward from the startPoint to the endPoint looking for a match\n * for the node. It looks for an id set match first, then a soft match.\n * We abort softmatching if we find two future soft matches, to reduce churn.\n * @param {Node} node\n * @param {MorphContext} ctx\n * @param {Node | null} startPoint\n * @param {Node | null} endPoint\n * @returns {Node | null}\n */\n function findBestMatch(ctx, node, startPoint, endPoint) {\n let softMatch = null;\n let nextSibling = node.nextSibling;\n let siblingSoftMatchCount = 0;\n\n let cursor = startPoint;\n while (cursor && cursor != endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n if (isIdSetMatch(ctx, cursor, node)) {\n return cursor; // found an id set match, we're done!\n }\n\n // we haven't yet saved a soft match fallback\n if (softMatch === null) {\n // the current soft match will hard match something else in the future, leave it\n if (!ctx.idMap.has(cursor)) {\n // save this as the fallback if we get through the loop without finding a hard match\n softMatch = cursor;\n }\n }\n }\n if (\n softMatch === null &&\n nextSibling &&\n isSoftMatch(cursor, nextSibling)\n ) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n softMatch = undefined;\n }\n }\n\n // if the current node contains active element, stop looking for better future matches,\n // because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus\n if (cursor.contains(document.activeElement)) break;\n\n cursor = cursor.nextSibling;\n }\n\n return softMatch || null;\n }\n\n /**\n *\n * @param {MorphContext} ctx\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isIdSetMatch(ctx, oldNode, newNode) {\n let oldSet = ctx.idMap.get(oldNode);\n let newSet = ctx.idMap.get(newNode);\n\n if (!newSet || !oldSet) return false;\n\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n *\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isSoftMatch(oldNode, newNode) {\n // ok to cast: if one is not element, `id` and `tagName` will be undefined and we'll just compare that.\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n return (\n oldElt.nodeType === newElt.nodeType &&\n oldElt.tagName === newElt.tagName &&\n // If oldElt has an `id` with possible state and it doesn't match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!oldElt.id || oldElt.id === newElt.id)\n );\n }\n\n return findBestMatch;\n })();\n\n //=============================================================================\n // DOM Manipulation Functions\n //=============================================================================\n\n /**\n * Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n * - Persistent nodes will be moved to the pantry for later reuse\n * - Other nodes will have their hooks called, and then are removed\n * @param {MorphContext} ctx\n * @param {Node} node\n */\n function removeNode(ctx, node) {\n // are we going to id set match this later?\n if (ctx.idMap.has(node)) {\n // skip callbacks and move to pantry\n moveBefore(ctx.pantry, node, null);\n } else {\n // remove for realsies\n if (ctx.callbacks.beforeNodeRemoved(node) === false) return;\n node.parentNode?.removeChild(node);\n ctx.callbacks.afterNodeRemoved(node);\n }\n }\n\n /**\n * Remove nodes between the start and end nodes\n * @param {MorphContext} ctx\n * @param {Node} startInclusive\n * @param {Node} endExclusive\n * @returns {Node|null}\n */\n function removeNodesBetween(ctx, startInclusive, endExclusive) {\n /** @type {Node | null} */\n let cursor = startInclusive;\n // remove nodes until the endExclusive node\n while (cursor && cursor !== endExclusive) {\n let tempNode = /** @type {Node} */ (cursor);\n cursor = cursor.nextSibling;\n removeNode(ctx, tempNode);\n }\n return cursor;\n }\n\n /**\n * Search for an element by id within the document and pantry, and move it using moveBefore.\n *\n * @param {Element} parentNode - The parent node to which the element will be moved.\n * @param {string} id - The ID of the element to be moved.\n * @param {Node | null} after - The reference node to insert the element before.\n * If `null`, the element is appended as the last child.\n * @param {MorphContext} ctx\n * @returns {Element} The found element\n */\n function moveBeforeById(parentNode, id, after, ctx) {\n const target =\n /** @type {Element} - will always be found */\n (\n ctx.target.querySelector(`#${id}`) ||\n ctx.pantry.querySelector(`#${id}`)\n );\n removeElementFromAncestorsIdMaps(target, ctx);\n moveBefore(parentNode, target, after);\n return target;\n }\n\n /**\n * Removes an element from its ancestors' id maps. This is needed when an element is moved from the\n * \"future\" via `moveBeforeId`. Otherwise, its erstwhile ancestors could be mistakenly moved to the\n * pantry rather than being deleted, preventing their removal hooks from being called.\n *\n * @param {Element} element - element to remove from its ancestors' id maps\n * @param {MorphContext} ctx\n */\n function removeElementFromAncestorsIdMaps(element, ctx) {\n const id = element.id;\n /** @ts-ignore - safe to loop in this way **/\n while ((element = element.parentNode)) {\n let idSet = ctx.idMap.get(element);\n if (idSet) {\n idSet.delete(id);\n if (!idSet.size) {\n ctx.idMap.delete(element);\n }\n }\n }\n }\n\n /**\n * Moves an element before another element within the same parent.\n * Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n * This is essentialy a forward-compat wrapper.\n *\n * @param {Element} parentNode - The parent node containing the after element.\n * @param {Node} element - The element to be moved.\n * @param {Node | null} after - The reference node to insert `element` before.\n * If `null`, `element` is appended as the last child.\n */\n function moveBefore(parentNode, element, after) {\n // @ts-ignore - use proposed moveBefore feature\n if (parentNode.moveBefore) {\n try {\n // @ts-ignore - use proposed moveBefore feature\n parentNode.moveBefore(element, after);\n } catch (e) {\n // fall back to insertBefore as some browsers may fail on moveBefore when trying to move Dom disconnected nodes to pantry\n parentNode.insertBefore(element, after);\n }\n } else {\n parentNode.insertBefore(element, after);\n }\n }\n\n return morphChildren;\n })();\n\n //=============================================================================\n // Single Node Morphing Code\n //=============================================================================\n const morphNode = (function () {\n /**\n * @param {Node} oldNode root node to merge content into\n * @param {Node} newContent new content to merge\n * @param {MorphContext} ctx the merge context\n * @returns {Node | null} the element that ended up in the DOM\n */\n function morphNode(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n return null;\n }\n\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) {\n return oldNode;\n }\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (\n oldNode instanceof HTMLHeadElement &&\n ctx.head.style !== \"morph\"\n ) {\n // ok to cast: if newContent wasn't also a <head>, it would've got caught in the `!isSoftMatch` branch above\n handleHeadElement(\n oldNode,\n /** @type {HTMLHeadElement} */ (newContent),\n ctx,\n );\n } else {\n morphAttributes(oldNode, newContent, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n // @ts-ignore newContent can be a node here because .firstChild will be null\n morphChildren(ctx, oldNode, newContent);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n\n /**\n * syncs the oldNode to the newNode, copying over all attributes and\n * inner element state from the newNode to the oldNode\n *\n * @param {Node} oldNode the node to copy attributes & state to\n * @param {Node} newNode the node to copy attributes & state from\n * @param {MorphContext} ctx the merge context\n */\n function morphAttributes(oldNode, newNode, ctx) {\n let type = newNode.nodeType;\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n const oldAttributes = oldElt.attributes;\n const newAttributes = newElt.attributes;\n for (const newAttribute of newAttributes) {\n if (ignoreAttribute(newAttribute.name, oldElt, \"update\", ctx)) {\n continue;\n }\n if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) {\n oldElt.setAttribute(newAttribute.name, newAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = oldAttributes.length - 1; 0 <= i; i--) {\n const oldAttribute = oldAttributes[i];\n\n // toAttributes is a live NamedNodeMap, so iteration+mutation is unsafe\n // e.g. custom element attribute callbacks can remove other attributes\n if (!oldAttribute) continue;\n\n if (!newElt.hasAttribute(oldAttribute.name)) {\n if (ignoreAttribute(oldAttribute.name, oldElt, \"remove\", ctx)) {\n continue;\n }\n oldElt.removeAttribute(oldAttribute.name);\n }\n }\n\n if (!ignoreValueOfActiveElement(oldElt, ctx)) {\n syncInputValue(oldElt, newElt, ctx);\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue;\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param {Element} oldElement the element to sync the input value to\n * @param {Element} newElement the element to sync the input value from\n * @param {MorphContext} ctx the merge context\n */\n function syncInputValue(oldElement, newElement, ctx) {\n if (\n oldElement instanceof HTMLInputElement &&\n newElement instanceof HTMLInputElement &&\n newElement.type !== \"file\"\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n\n // sync boolean attributes\n syncBooleanAttribute(oldElement, newElement, \"checked\", ctx);\n syncBooleanAttribute(oldElement, newElement, \"disabled\", ctx);\n\n if (!newElement.hasAttribute(\"value\")) {\n if (!ignoreAttribute(\"value\", oldElement, \"remove\", ctx)) {\n oldElement.value = \"\";\n oldElement.removeAttribute(\"value\");\n }\n } else if (oldValue !== newValue) {\n if (!ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n oldElement.setAttribute(\"value\", newValue);\n oldElement.value = newValue;\n }\n }\n // TODO: QUESTION(1cg): this used to only check `newElement` unlike the other branches -- why?\n // did I break something?\n } else if (\n oldElement instanceof HTMLOptionElement &&\n newElement instanceof HTMLOptionElement\n ) {\n syncBooleanAttribute(oldElement, newElement, \"selected\", ctx);\n } else if (\n oldElement instanceof HTMLTextAreaElement &&\n newElement instanceof HTMLTextAreaElement\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n if (ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n return;\n }\n if (newValue !== oldValue) {\n oldElement.value = newValue;\n }\n if (\n oldElement.firstChild &&\n oldElement.firstChild.nodeValue !== newValue\n ) {\n oldElement.firstChild.nodeValue = newValue;\n }\n }\n }\n\n /**\n * @param {Element} oldElement element to write the value to\n * @param {Element} newElement element to read the value from\n * @param {string} attributeName the attribute name\n * @param {MorphContext} ctx the merge context\n */\n function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n const newLiveValue = newElement[attributeName],\n // @ts-ignore ditto\n oldLiveValue = oldElement[attributeName];\n if (newLiveValue !== oldLiveValue) {\n const ignoreUpdate = ignoreAttribute(\n attributeName,\n oldElement,\n \"update\",\n ctx,\n );\n if (!ignoreUpdate) {\n // update attribute's associated DOM property\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n oldElement[attributeName] = newElement[attributeName];\n }\n if (newLiveValue) {\n if (!ignoreUpdate) {\n // https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML\n // this is the correct way to set a boolean attribute to \"true\"\n oldElement.setAttribute(attributeName, \"\");\n }\n } else {\n if (!ignoreAttribute(attributeName, oldElement, \"remove\", ctx)) {\n oldElement.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * @param {string} attr the attribute to be mutated\n * @param {Element} element the element that is going to be updated\n * @param {\"update\" | \"remove\"} updateType\n * @param {MorphContext} ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, element, updateType, ctx) {\n if (\n attr === \"value\" &&\n ctx.ignoreActiveValue &&\n element === document.activeElement\n ) {\n return true;\n }\n return (\n ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) ===\n false\n );\n }\n\n /**\n * @param {Node} possibleActiveElement\n * @param {MorphContext} ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return (\n !!ctx.ignoreActiveValue &&\n possibleActiveElement === document.activeElement &&\n possibleActiveElement !== document.body\n );\n }\n\n return morphNode;\n })();\n\n //=============================================================================\n // Head Management Functions\n //=============================================================================\n /**\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @param {function} callback\n * @returns {Node[] | Promise<Node[]>}\n */\n function withHeadBlocking(ctx, oldNode, newNode, callback) {\n if (ctx.head.block) {\n const oldHead = oldNode.querySelector(\"head\");\n const newHead = newNode.querySelector(\"head\");\n if (oldHead && newHead) {\n const promises = handleHeadElement(oldHead, newHead, ctx);\n // when head promises resolve, proceed ignoring the head tag\n return Promise.all(promises).then(() => {\n const newCtx = Object.assign(ctx, {\n head: {\n block: false,\n ignore: true,\n },\n });\n return callback(newCtx);\n });\n }\n }\n // just proceed if we not head blocking\n return callback(ctx);\n }\n\n /**\n * The HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n *\n * @param {Element} oldHead\n * @param {Element} newHead\n * @param {MorphContext} ctx\n * @returns {Promise<void>[]}\n */\n function handleHeadElement(oldHead, newHead, ctx) {\n let added = [];\n let removed = [];\n let preserved = [];\n let nodesToAppend = [];\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHead.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of oldHead.children) {\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (ctx.head.style === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n // TODO: This could theoretically be null, based on type\n let newElt = /** @type {ChildNode} */ (\n document.createRange().createContextualFragment(newNode.outerHTML)\n .firstChild\n );\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (\n (\"href\" in newElt && newElt.href) ||\n (\"src\" in newElt && newElt.src)\n ) {\n /** @type {(result?: any) => void} */ let resolve;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener(\"load\", function () {\n resolve();\n });\n promises.push(promise);\n }\n oldHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n oldHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(oldHead, {\n added: added,\n kept: preserved,\n removed: removed,\n });\n return promises;\n }\n\n //=============================================================================\n // Create Morph Context Functions\n //=============================================================================\n const createMorphContext = (function () {\n /**\n *\n * @param {Element} oldNode\n * @param {Element} newContent\n * @param {Config} config\n * @returns {MorphContext}\n */\n function createMorphContext(oldNode, newContent, config) {\n const { persistentIds, idMap } = createIdMaps(oldNode, newContent);\n\n const mergedConfig = mergeDefaults(config);\n const morphStyle = mergedConfig.morphStyle || \"outerHTML\";\n if (![\"innerHTML\", \"outerHTML\"].includes(morphStyle)) {\n throw `Do not understand how to morph style ${morphStyle}`;\n }\n\n return {\n target: oldNode,\n newContent: newContent,\n config: mergedConfig,\n morphStyle: morphStyle,\n ignoreActive: mergedConfig.ignoreActive,\n ignoreActiveValue: mergedConfig.ignoreActiveValue,\n restoreFocus: mergedConfig.restoreFocus,\n idMap: idMap,\n persistentIds: persistentIds,\n pantry: createPantry(),\n callbacks: mergedConfig.callbacks,\n head: mergedConfig.head,\n };\n }\n\n /**\n * Deep merges the config object and the Idiomorph.defaults object to\n * produce a final configuration object\n * @param {Config} config\n * @returns {ConfigInternal}\n */\n function mergeDefaults(config) {\n let finalConfig = Object.assign({}, defaults);\n\n // copy top level stuff into final config\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = Object.assign(\n {},\n defaults.callbacks,\n config.callbacks,\n );\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = Object.assign({}, defaults.head, config.head);\n\n return finalConfig;\n }\n\n /**\n * @returns {HTMLDivElement}\n */\n function createPantry() {\n const pantry = document.createElement(\"div\");\n pantry.hidden = true;\n document.body.insertAdjacentElement(\"afterend\", pantry);\n return pantry;\n }\n\n /**\n * Returns all elements with an ID contained within the root element and its descendants\n *\n * @param {Element} root\n * @returns {Element[]}\n */\n function findIdElements(root) {\n let elements = Array.from(root.querySelectorAll(\"[id]\"));\n if (root.id) {\n elements.push(root);\n }\n return elements;\n }\n\n /**\n * A bottom-up algorithm that populates a map of Element -> IdSet.\n * The idSet for a given element is the set of all IDs contained within its subtree.\n * As an optimzation, we filter these IDs through the given list of persistent IDs,\n * because we don't need to bother considering IDed elements that won't be in the new content.\n *\n * @param {Map<Node, Set<string>>} idMap\n * @param {Set<string>} persistentIds\n * @param {Element} root\n * @param {Element[]} elements\n */\n function populateIdMapWithTree(idMap, persistentIds, root, elements) {\n for (const elt of elements) {\n if (persistentIds.has(elt.id)) {\n /** @type {Element|null} */\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n\n if (current === root) break;\n current = current.parentElement;\n }\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {IdSets}\n */\n function createIdMaps(oldContent, newContent) {\n const oldIdElements = findIdElements(oldContent);\n const newIdElements = findIdElements(newContent);\n\n const persistentIds = createPersistentIds(oldIdElements, newIdElements);\n\n /** @type {Map<Node, Set<string>>} */\n let idMap = new Map();\n populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);\n\n /** @ts-ignore - if newContent is a duck-typed parent, pass its single child node as the root to halt upwards iteration */\n const newRoot = newContent.__idiomorphRoot || newContent;\n populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements);\n\n return { persistentIds, idMap };\n }\n\n /**\n * This function computes the set of ids that persist between the two contents excluding duplicates\n *\n * @param {Element[]} oldIdElements\n * @param {Element[]} newIdElements\n * @returns {Set<string>}\n */\n function createPersistentIds(oldIdElements, newIdElements) {\n let duplicateIds = new Set();\n\n /** @type {Map<string, string>} */\n let oldIdTagNameMap = new Map();\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id);\n } else {\n oldIdTagNameMap.set(id, tagName);\n }\n }\n\n let persistentIds = new Set();\n for (const { id, tagName } of newIdElements) {\n if (persistentIds.has(id)) {\n duplicateIds.add(id);\n } else if (oldIdTagNameMap.get(id) === tagName) {\n persistentIds.add(id);\n }\n // skip if tag types mismatch because its not possible to morph one tag into another\n }\n\n for (const id of duplicateIds) {\n persistentIds.delete(id);\n }\n return persistentIds;\n }\n\n return createMorphContext;\n })();\n\n //=============================================================================\n // HTML Normalization Functions\n //=============================================================================\n const { normalizeElement, normalizeParent } = (function () {\n /** @type {WeakSet<Node>} */\n const generatedByIdiomorph = new WeakSet();\n\n /**\n *\n * @param {Element | Document} content\n * @returns {Element}\n */\n function normalizeElement(content) {\n if (content instanceof Document) {\n return content.documentElement;\n } else {\n return content;\n }\n }\n\n /**\n *\n * @param {null | string | Node | HTMLCollection | Node[] | Document & {generatedByIdiomorph:boolean}} newContent\n * @returns {Element}\n */\n function normalizeParent(newContent) {\n if (newContent == null) {\n return document.createElement(\"div\"); // dummy parent element\n } else if (typeof newContent === \"string\") {\n return normalizeParent(parseContent(newContent));\n } else if (\n generatedByIdiomorph.has(/** @type {Element} */ (newContent))\n ) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return /** @type {Element} */ (newContent);\n } else if (newContent instanceof Node) {\n if (newContent.parentNode) {\n // we can't use the parent directly because newContent may have siblings\n // that we don't want in the morph, and reparenting might be expensive (TODO is it?),\n // so we create a duck-typed parent node instead.\n return createDuckTypedParent(newContent);\n } else {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement(\"div\");\n dummyParent.append(newContent);\n return dummyParent;\n }\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement(\"div\");\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n /**\n * Creates a fake duck-typed parent element to wrap a single node, without actually reparenting it.\n * \"If it walks like a duck, and quacks like a duck, then it must be a duck!\" -- James Whitcomb Riley (1849–1916)\n *\n * @param {Node} newContent\n * @returns {Element}\n */\n function createDuckTypedParent(newContent) {\n return /** @type {Element} */ (\n /** @type {unknown} */ ({\n childNodes: [newContent],\n /** @ts-ignore - cover your eyes for a minute, tsc */\n querySelectorAll: (s) => {\n /** @ts-ignore */\n const elements = newContent.querySelectorAll(s);\n /** @ts-ignore */\n return newContent.matches(s) ? [newContent, ...elements] : elements;\n },\n /** @ts-ignore */\n insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r),\n /** @ts-ignore */\n moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r),\n // for later use with populateIdMapWithTree to halt upwards iteration\n get __idiomorphRoot() {\n return newContent;\n },\n })\n );\n }\n\n /**\n *\n * @param {string} newContent\n * @returns {Node | null | DocumentFragment}\n */\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(\n /<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n \"\",\n );\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (\n contentWithSvgsRemoved.match(/<\\/html>/) ||\n contentWithSvgsRemoved.match(/<\\/head>/) ||\n contentWithSvgsRemoved.match(/<\\/body>/)\n ) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n generatedByIdiomorph.add(content);\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n generatedByIdiomorph.add(htmlElement);\n }\n return htmlElement;\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\n \"<body><template>\" + newContent + \"</template></body>\",\n \"text/html\",\n );\n let content = /** @type {HTMLTemplateElement} */ (\n responseDoc.body.querySelector(\"template\")\n ).content;\n generatedByIdiomorph.add(content);\n return content;\n }\n }\n\n return { normalizeElement, normalizeParent };\n })();\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults,\n };\n})();\n\nexport {Idiomorph};\n","\nconst topics: any = {}\nconst _async: any = {}\n\nexport const publish = (name, params) => {\n\t_async[name] = Object.assign({}, _async[name], params)\n\tif (topics[name])\n\t\ttopics[name].forEach(topic => topic(params))\n}\n\nexport const subscribe = (name, method) => {\n\ttopics[name] = topics[name] || []\n\ttopics[name].push(method)\n\tif (name in _async) {\n\t\tmethod(_async[name])\n\t}\n\treturn () => {\n\t\ttopics[name] = topics[name].filter( fn => fn != method )\n\t}\n}\n","import { safe, g, dup } from './utils'\nimport { Idiomorph } from 'idiomorph/dist/idiomorph.esm'\nimport { publish, subscribe } from './utils/pubsub'\n\nexport const Component = ({ name, module, dependencies, node, templates, signal, register }) => {\n\n\tlet tick\n\tlet preserve\t\t= []\n\n\tconst _model \t\t= module.model || {}\n\tconst initialState \t= (new Function( `return ${node.getAttribute('html-model') || '{}'}`))()\n\tconst tplid \t\t= node.getAttribute('tplid')\n\tconst scopeid \t\t= node.getAttribute('html-scopeid')\n\tconst tpl \t\t\t= templates[ tplid ]\n\tconst scope \t\t= g.scope[ scopeid ]\n\tconst model \t\t= dup(module?.model?.apply ? _model({ elm:node, initialState }) : _model)\n\tconst state \t\t= Object.assign({}, scope, model, initialState)\n\tconst view \t\t\t= module.view? module.view : (data) => data\n\n\tconst base = {\n\t\tname,\n\t\tmodel,\n\t\telm: node,\n\t\ttemplate: tpl.template,\n\t\tdependencies,\n\t\tpublish,\n\t\tsubscribe,\n\n\t\tmain(fn) {\n\t\t\tnode.addEventListener(':mount', fn)\n\t\t},\n\n\t\t/**\n\t\t * @State\n\t\t */\n\t\tstate : {\n\n\t\t\tprotected( list ) {\n\t\t\t\tif( list ) {\n\t\t\t\t\tpreserve = list\n\t\t\t\t} else {\n\t\t\t\t\treturn preserve\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tsave(data) {\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata( state )\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tset( data ) {\n\n\t\t\t\tif (!document.body.contains(node)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata(state)\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\n\t\t\t\tconst newstate = Object.assign({}, state, scope)\n\n\t\t\t\treturn new Promise((resolve) => {\n\t\t\t\t\trender(newstate, () => resolve(newstate))\n\t\t\t\t})\n\t\t\t},\n\n\t\t\tget() {\n\t\t\t\treturn Object.assign({}, state)\n\t\t\t}\n\t\t},\n\n\t\tdataset( target, name ) {\n\n\t\t\tconst el = name? target : node\n\t\t\tconst key = name? name : target\n\t\t\tconst value = el.dataset[key]\n\n\t\t\tif (value === 'true') return true\n\t\t\tif (value === 'false') return false\n\t\t\tif (!isNaN(value) && value.trim() !== '') return Number(value)\n\n\t\t\ttry {\n\t\t\t\treturn new Function('return (' + value + ')')()\n\t\t\t} catch {}\n\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value)\n\t\t\t} catch {}\n\n\t\t\treturn value\n\t\t},\n\n\t\tattributes( target ) {\n\n\t\t\tlet callbacks = []\n\t\t\tconst elm = target || node\n\n\t\t\tconst observer = new MutationObserver((mutationsList) => {\n\t\t\t\tfor (const mutation of mutationsList) {\n\t\t\t\t\tif (mutation.type === 'attributes') {\n\t\t\t\t\t\tconst attributeName = mutation.attributeName\n\t\t\t\t\t\tcallbacks.forEach((item) => {\n\t\t\t\t\t\t\tif (item.name == attributeName) {\n\t\t\t\t\t\t\t\titem.callback(\n\t\t\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\t\t\telm.getAttribute(attributeName)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tobserver.observe(node, { attributes: true })\n\n\t\t\tnode.addEventListener(':unmount', () => {\n\t\t\t\tcallbacks = null\n\t\t\t\tobserver.disconnect()\n\t\t\t})\n\n\t\t\treturn {\n\n\t\t\t\tonchange( name, callback ) {\n\t\t\t\t\tcallbacks.push({ name, callback })\n\t\t\t\t},\n\n\t\t\t\tdisconnect( callback ) {\n\t\t\t\t\tcallbacks = callbacks.filter((item) => item.callback !== callback)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @Events\n\t\t */\n\t\ton( ev, selectorOrCallback, callback ) {\n\n\t\t\tif( callback ) {\n\t\t\t\tcallback.handler = (e) => {\n\t\t\t\t\tconst detail = e.detail || {}\n\t\t\t\t\tlet parent = e.target\n\t\t\t\t\twhile (parent) {\n\t\t\t\t\t\tif (parent.matches(selectorOrCallback)) {\n\t\t\t\t\t\t\te.delegateTarget = parent\n\t\t\t\t\t\t\tcallback.apply(node, [e].concat(detail.args))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parent === node) break\n\t\t\t\t\t\tparent = parent.parentNode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, callback.handler, {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: (ev == 'focus' || ev == 'blur' || ev == 'mouseenter' || ev == 'mouseleave')\n\t\t\t\t})\n\n\t\t\t} else {\n\t\t\t\tselectorOrCallback.handler = (e) => {\n\t\t\t\t\te.delegateTarget = node\n\t\t\t\t\tselectorOrCallback.apply(node, [e].concat(e.detail.args))\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, selectorOrCallback.handler, { signal })\n\t\t\t}\n\n\t\t},\n\n\t\toff( ev, callback ) {\n\t\t\tif( callback.handler ) {\n\t\t\t\tnode.removeEventListener(ev, callback.handler)\n\t\t\t}\n\t\t},\n\n\t\ttrigger(ev, selectorOrCallback, data) {\n\t\t\tif( selectorOrCallback.constructor === String ) {\n\t\t\t\tArray\n\t\t\t\t\t.from(node.querySelectorAll(selectorOrCallback))\n\t\t\t\t\t.forEach( children => {\n\t\t\t\t\t\tchildren.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }) )\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail:{ args: data } }))\n\t\t\t}\n\t\t},\n\n\t\temit(ev, data) {\n\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }))\n\t\t},\n\n\t\tunmount( fn ) {\n\t\t\tnode.addEventListener(':unmount', fn)\n\t\t},\n\n\t\tinnerHTML ( target, html_ ) {\n\t\t\tconst element = html_? target : node\n\t\t\tconst clone = element.cloneNode()\n\t\t\tconst html = html_? html_ : target\n\t\t\tclone.innerHTML = html\n\t\t\tIdiomorph.morph(element, clone)\n\t\t}\n\t}\n\n\tconst render = ( data, callback = (() => {}) ) => {\n\t\tclearTimeout( tick )\n\t\ttick = setTimeout(() => {\n\t\t\tconst html = tpl.render.call({...data, ...view(data)}, node, safe, g )\n\t\t\tIdiomorph.morph( node, html, IdiomorphOptions(node, register) )\n\t\t\tPromise.resolve().then(() => {\n\t\t\t\tnode.querySelectorAll('[tplid]')\n\t\t\t\t\t.forEach((element) => {\n\t\t\t\t\t\tconst child = register.get(element)\n\t\t\t\t\t\tif(!child) return\n\t\t\t\t\t\tchild.state.protected().forEach( key => delete data[key] )\n\t\t\t\t\t\tchild.state.set(data)\n\t\t\t\t\t})\n\t\t\t\tPromise.resolve().then(() => {\n\t\t\t\t\tg.scope = {}\n\t\t\t\t\tcallback()\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\trender( state )\n\tregister.set( node, base )\n\treturn module.default( base )\n}\n\nconst IdiomorphOptions = ( parent, register ) => ({\n\tcallbacks: {\n\t\tbeforeNodeMorphed( node ) {\n\t\t\tif( node.nodeType === 1 ) {\n\t\t\t\tif( 'html-static' in node.attributes ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif( register.get(node) && node !== parent ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n})\n","import { Component } from './component'\n\nconst register = new WeakMap()\n\nexport const Element = ({ component, templates, start }) => {\n\n\tconst { name, module, dependencies } = component\n\n\treturn class extends HTMLElement {\n\n\t\tconstructor() {\n\t\t\tsuper()\n\t\t}\n\n\t\tconnectedCallback() {\n\n\t\t\tthis.abortController = new AbortController()\n\n\t\t\tif( !this.getAttribute('tplid') ) {\n\t\t\t\tstart( this.parentNode )\n\t\t\t}\n\n\t\t\tconst rtrn = Component({\n\t\t\t\tnode:this,\n\t\t\t\tname,\n\t\t\t\tmodule,\n\t\t\t\tdependencies,\n\t\t\t\ttemplates,\n\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\tregister\n\t\t\t})\n\n\t\t\tif ( rtrn && rtrn.constructor === Promise ) {\n\t\t\t\trtrn.then(() => {\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t}\n\t\t}\n\n\t\tdisconnectedCallback() {\n\t\t\tthis.dispatchEvent( new CustomEvent(':unmount') )\n\t\t\tthis.abortController.abort()\n\t\t}\n\t}\n}\n","import { uuid, decodeHTML } from './utils'\n\nconst templates = {}\n\nconst config = {\n\ttags: ['{{', '}}']\n}\n\nexport const templateConfig = (newconfig) => {\n\tObject.assign( config, newconfig )\n}\n\nexport const template = ( target, { components }) => {\n\n\ttagElements( target, [...Object.keys( components ), '[html-if]', 'template'], components )\n\tconst clone = target.cloneNode( true )\n\n\ttransformTemplate( clone )\n\tremoveTemplateTagsRecursively( clone )\n\tsetTemplates( clone, components )\n\n\treturn templates\n}\n\nexport const compile = ( html ) => {\n\n\tconst parsedHtml = JSON.stringify( html )\n\n\treturn new Function('$element', 'safe', '$g',`\n\t\tvar $data = this;\n\t\twith( $data ){\n\t\t\tvar output=${parsedHtml\n\t\t\t\t.replace(/%%_=(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\"+safe(function(){return '+ decodeHTML(variable) +';})+\"'\n\t\t\t\t})\n\t\t\t\t.replace(/%%_(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\";' + decodeHTML(variable) +'\\noutput+=\"'\n\t\t\t\t})};return output;\n\t\t}\n\t`)\n}\n\nconst tagElements = ( target, keys, components ) => {\n\ttarget\n\t\t.querySelectorAll( keys.toString() )\n\t\t.forEach((node) => {\n\t\t\tconst name = node.localName\n\t\t\tif( name === 'template' ) {\n\t\t\t\treturn tagElements( node.content, keys, components )\n\t\t\t}\n\t\t\tif( node.getAttribute('html-if') && !node.id ) {\n\t\t\t\tnode.id = uuid()\n\t\t\t}\n\t\t\tif( name in components ) {\n\t\t\t\tnode.setAttribute('tplid', uuid())\n\t\t\t}\n\t\t})\n}\n\nconst transformAttributes = ( html ) => {\n\n\tconst regexTags = new RegExp(`\\\\${config.tags[0]}(.+?)\\\\${config.tags[1]}`, 'g')\n\n\treturn html\n\t\t.replace(/jails___scope-id/g, '%%_=$scopeid_%%')\n\t\t.replace(regexTags, '%%_=$1_%%')\n\t\t// Booleans\n\t\t// https://meiert.com/en/blog/boolean-attributes-of-html/\n\t\t.replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\\\"(.*?)\\\"/g, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`)\n\t\t// The rest\n\t\t.replace(/html-([^\\s]*?)=\\\"(.*?)\\\"/g, (all, key, value) => {\n\t\t\tif (key === 'key' || key === 'model' || key === 'scopeid' ) {\n\t\t\t\treturn all\n\t\t\t}\n\t\t\tif (value) {\n\t\t\t\tvalue = value.replace(/^{|}$/g, '')\n\t\t\t\treturn `${key}=\"%%_=safe(function(){ return ${value} })_%%\"`\n\t\t\t} else {\n\t\t\t\treturn all\n\t\t\t}\n\t\t})\n}\n\nconst transformTemplate = ( clone ) => {\n\n\tclone.querySelectorAll('template, [html-for], [html-if], [html-inner], [html-class]')\n\t\t.forEach(( element ) => {\n\n\t\t\tconst htmlFor \t= element.getAttribute('html-for')\n\t\t\tconst htmlIf \t= element.getAttribute('html-if')\n\t\t\tconst htmlInner = element.getAttribute('html-inner')\n\t\t\tconst htmlClass = element.getAttribute('html-class')\n\n\t\t\tif ( htmlFor ) {\n\n\t\t\t\telement.removeAttribute('html-for')\n\n\t\t\t\tconst split \t = htmlFor.match(/(.*)\\sin\\s(.*)/) || ''\n\t\t\t\tconst varname \t = split[1]\n\t\t\t\tconst object \t = split[2]\n\t\t\t\tconst objectname = object.split(/\\./).shift()\n\t\t\t\tconst open \t\t = document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${object} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${varname} = ${object}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${objectname}: ${objectname} }, { ${varname} :${varname}, $index: $index, $key: $key }); _%%`)\n\t\t\t\tconst close \t = document.createTextNode(`%%_ $index++; } })() _%%`)\n\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlIf) {\n\t\t\t\telement.removeAttribute('html-if')\n\t\t\t\tconst open = document.createTextNode(`%%_ if ( safe(function(){ return ${htmlIf} }) ){ _%%`)\n\t\t\t\tconst close = document.createTextNode(`%%_ } _%%`)\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlInner) {\n\t\t\t\telement.removeAttribute('html-inner')\n\t\t\t\telement.innerHTML = `%%_=${htmlInner}_%%`\n\t\t\t}\n\n\t\t\tif (htmlClass) {\n\t\t\t\telement.removeAttribute('html-class')\n\t\t\t\telement.className = (element.className + ` %%_=${htmlClass}_%%`).trim()\n\t\t\t}\n\n\t\t\tif( element.localName === 'template' ) {\n\t\t\t\ttransformTemplate(element.content)\n\t\t\t}\n\t\t})\n}\n\nconst setTemplates = ( clone, components ) => {\n\n\tArray.from(clone.querySelectorAll('[tplid]'))\n\t\t.reverse()\n\t\t.forEach((node) => {\n\n\t\t\tconst tplid = node.getAttribute('tplid')\n\t\t\tconst name = node.localName\n\t\t\tnode.setAttribute('html-scopeid', 'jails___scope-id')\n\n\t\t\tif( name in components && components[name].module.template ) {\n\t\t\t\tconst children = node.innerHTML\n\t\t\t\tconst html = components[name].module.template({ elm:node, children })\n\t\t\t\tnode.innerHTML = html\n\t\t\t}\n\n\t\t\tconst html = transformAttributes(node.outerHTML)\n\n\t\t\ttemplates[ tplid ] = {\n\t\t\t\ttemplate: html,\n\t\t\t\trender\t: compile(html)\n\t\t\t}\n\t\t})\n}\n\nconst removeTemplateTagsRecursively = (node) => {\n\n\t// Get all <template> elements within the node\n\tconst templates = node.querySelectorAll('template')\n\n\ttemplates.forEach((template) => {\n\n\t\tif( template.getAttribute('html-if') || template.getAttribute('html-inner') ) {\n\t\t\treturn\n\t\t}\n\n\t\t// Process any nested <template> tags within this <template> first\n\t\tremoveTemplateTagsRecursively(template.content)\n\n\t\t// Get the parent of the <template> tag\n\t\tconst parent = template.parentNode\n\n\t\tif (parent) {\n\t\t\t// Move all child nodes from the <template>'s content to its parent\n\t\t\tconst content = template.content\n\t\t\twhile (content.firstChild) {\n\t\t\t\tparent.insertBefore(content.firstChild, template)\n\t\t\t}\n\t\t\t// Remove the <template> tag itself\n\t\t\tparent.removeChild(template)\n\t\t}\n\t})\n}\n\nconst wrap = (open, node, close) => {\n\tnode.parentNode?.insertBefore(open, node)\n\tnode.parentNode?.insertBefore(close, node.nextSibling)\n}\n","\nimport { Element } from './element'\nimport { template, templateConfig as config } from './template-system'\n\nexport { publish, subscribe } from './utils/pubsub'\n\nexport const templateConfig = (options) => {\n\tconfig( options )\n}\n\nwindow.__jails__ = window.__jails__ || { components: {} }\n\nexport const register = ( name, module, dependencies ) => {\n\tconst { components } = window.__jails__\n\tcomponents[ name ] = { name, module, dependencies }\n}\n\nexport const start = ( target = document.body ) => {\n\n\tconst { components } = window.__jails__\n\tconst templates = template( target, { components } )\n\n\tObject\n\t\t.values( components )\n\t\t.forEach(({ name, module, dependencies }) => {\n\t\t\tif( !customElements.get(name) ) {\n\t\t\t\tcustomElements.define( name, Element({ component: { name, module, dependencies }, templates, start }))\n\t\t\t}\n\t})\n}\n\ndeclare global {\n\tinterface Window {\n\t __jails__?: {\n\t\tcomponents: Record<string, any>\n\t }\n\t}\n}\n"],"names":["config","ctx","morphChildren","findBestMatch","morphNode","createMorphContext","normalizeElement","normalizeParent","templates","register","name","Element","start","templateConfig","html","template"],"mappings":"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","x_google_ignoreList":[1]}
package/dist/jails.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).jails={})}(this,(function(e){"use strict";var t=Object.defineProperty,n=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,i=(e,n,r)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,a=(e,t)=>{for(var a in t||(t={}))r.call(t,a)&&i(e,a,t[a]);if(n)for(var a of n(t))o.call(t,a)&&i(e,a,t[a]);return e};const l=document.createElement("textarea"),s={scope:{}},c=e=>(l.innerHTML=e,l.value),d=()=>Math.random().toString(36).substring(2,9),u=(e,t)=>{try{return e()}catch(n){return t||""}};var f=function(){const e=()=>{},t={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:e=>"true"===e.getAttribute("im-preserve"),shouldReAppend:e=>"true"===e.getAttribute("im-re-append"),shouldRemove:e,afterHeadMorphed:e},restoreFocus:!0};const n=function(){function e(e,t,n,o){if(!1===o.callbacks.beforeNodeAdded(t))return null;if(o.idMap.has(t)){const i=document.createElement(t.tagName);return e.insertBefore(i,n),r(i,t,o),o.callbacks.afterNodeAdded(i),i}{const r=document.importNode(t,!0);return e.insertBefore(r,n),o.callbacks.afterNodeAdded(r),r}}const t=function(){function e(e,t,n){let r=e.idMap.get(t),o=e.idMap.get(n);if(!o||!r)return!1;for(const i of r)if(o.has(i))return!0;return!1}function t(e,t){const n=e,r=t;return n.nodeType===r.nodeType&&n.tagName===r.tagName&&(!n.id||n.id===r.id)}return function(n,r,o,i){let a=null,l=r.nextSibling,s=0,c=o;for(;c&&c!=i;){if(t(c,r)){if(e(n,c,r))return c;null===a&&(n.idMap.has(c)||(a=c))}if(null===a&&l&&t(c,l)&&(s++,l=l.nextSibling,s>=2&&(a=void 0)),c.contains(document.activeElement))break;c=c.nextSibling}return a||null}}();function n(e,t){var n;if(e.idMap.has(t))a(e.pantry,t,null);else{if(!1===e.callbacks.beforeNodeRemoved(t))return;null==(n=t.parentNode)||n.removeChild(t),e.callbacks.afterNodeRemoved(t)}}function o(e,t,r){let o=t;for(;o&&o!==r;){let t=o;o=o.nextSibling,n(e,t)}return o}function i(e,t,n,r){const o=r.target.querySelector(`#${t}`)||r.pantry.querySelector(`#${t}`);return function(e,t){const n=e.id;for(;e=e.parentNode;){let r=t.idMap.get(e);r&&(r.delete(n),r.size||t.idMap.delete(e))}}(o,r),a(e,o,n),o}function a(e,t,n){if(e.moveBefore)try{e.moveBefore(t,n)}catch(r){e.insertBefore(t,n)}else e.insertBefore(t,n)}return function(a,l,s,c=null,d=null){l instanceof HTMLTemplateElement&&s instanceof HTMLTemplateElement&&(l=l.content,s=s.content),c||(c=l.firstChild);for(const n of s.childNodes){if(c&&c!=d){const e=t(a,n,c,d);if(e){e!==c&&o(a,c,e),r(e,n,a),c=e.nextSibling;continue}}if(n instanceof Element&&a.persistentIds.has(n.id)){const e=i(l,n.id,c,a);r(e,n,a),c=e.nextSibling;continue}const s=e(l,n,c,a);s&&(c=s.nextSibling)}for(;c&&c!=d;){const e=c;c=c.nextSibling,n(a,e)}}}(),r=function(){function e(e,n,r,o){const i=n[r];if(i!==e[r]){const a=t(r,e,"update",o);a||(e[r]=n[r]),i?a||e.setAttribute(r,""):t(r,e,"remove",o)||e.removeAttribute(r)}}function t(e,t,n,r){return!("value"!==e||!r.ignoreActiveValue||t!==document.activeElement)||!1===r.callbacks.beforeAttributeUpdated(e,t,n)}function r(e,t){return!!t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}return function(i,a,l){return l.ignoreActive&&i===document.activeElement?null:(!1===l.callbacks.beforeNodeMorphed(i,a)||(i instanceof HTMLHeadElement&&l.head.ignore||(i instanceof HTMLHeadElement&&"morph"!==l.head.style?o(i,a,l):(!function(n,o,i){let a=o.nodeType;if(1===a){const a=n,l=o,s=a.attributes,c=l.attributes;for(const e of c)t(e.name,a,"update",i)||a.getAttribute(e.name)!==e.value&&a.setAttribute(e.name,e.value);for(let e=s.length-1;0<=e;e--){const n=s[e];if(n&&!l.hasAttribute(n.name)){if(t(n.name,a,"remove",i))continue;a.removeAttribute(n.name)}}r(a,i)||function(n,r,o){if(n instanceof HTMLInputElement&&r instanceof HTMLInputElement&&"file"!==r.type){let i=r.value,a=n.value;e(n,r,"checked",o),e(n,r,"disabled",o),r.hasAttribute("value")?a!==i&&(t("value",n,"update",o)||(n.setAttribute("value",i),n.value=i)):t("value",n,"remove",o)||(n.value="",n.removeAttribute("value"))}else if(n instanceof HTMLOptionElement&&r instanceof HTMLOptionElement)e(n,r,"selected",o);else if(n instanceof HTMLTextAreaElement&&r instanceof HTMLTextAreaElement){let e=r.value,i=n.value;if(t("value",n,"update",o))return;e!==i&&(n.value=e),n.firstChild&&n.firstChild.nodeValue!==e&&(n.firstChild.nodeValue=e)}}(a,l,i)}8!==a&&3!==a||n.nodeValue!==o.nodeValue&&(n.nodeValue=o.nodeValue)}(i,a,l),r(i,l)||n(l,i,a))),l.callbacks.afterNodeMorphed(i,a)),i)}}();function o(e,t,n){let r=[],o=[],i=[],a=[],l=new Map;for(const c of t.children)l.set(c.outerHTML,c);for(const c of e.children){let e=l.has(c.outerHTML),t=n.head.shouldReAppend(c),r=n.head.shouldPreserve(c);e||r?t?o.push(c):(l.delete(c.outerHTML),i.push(c)):"append"===n.head.style?t&&(o.push(c),a.push(c)):!1!==n.head.shouldRemove(c)&&o.push(c)}a.push(...l.values());let s=[];for(const c of a){let t=document.createRange().createContextualFragment(c.outerHTML).firstChild;if(!1!==n.callbacks.beforeNodeAdded(t)){if("href"in t&&t.href||"src"in t&&t.src){let e,n=new Promise((function(t){e=t}));t.addEventListener("load",(function(){e()})),s.push(n)}e.appendChild(t),n.callbacks.afterNodeAdded(t),r.push(t)}}for(const c of o)!1!==n.callbacks.beforeNodeRemoved(c)&&(e.removeChild(c),n.callbacks.afterNodeRemoved(c));return n.head.afterHeadMorphed(e,{added:r,kept:i,removed:o}),s}const i=function(){function e(){const e=document.createElement("div");return e.hidden=!0,document.body.insertAdjacentElement("afterend",e),e}function n(e){let t=Array.from(e.querySelectorAll("[id]"));return e.id&&t.push(e),t}function r(e,t,n,r){for(const o of r)if(t.has(o.id)){let t=o;for(;t;){let r=e.get(t);if(null==r&&(r=new Set,e.set(t,r)),r.add(o.id),t===n)break;t=t.parentElement}}}return function(o,i,a){const{persistentIds:l,idMap:s}=function(e,t){const o=n(e),i=n(t),a=function(e,t){let n=new Set,r=new Map;for(const{id:i,tagName:a}of e)r.has(i)?n.add(i):r.set(i,a);let o=new Set;for(const{id:i,tagName:a}of t)o.has(i)?n.add(i):r.get(i)===a&&o.add(i);for(const i of n)o.delete(i);return o}(o,i);let l=new Map;r(l,a,e,o);const s=t.__idiomorphRoot||t;return r(l,a,s,i),{persistentIds:a,idMap:l}}(o,i),c=function(e){let n=Object.assign({},t);return Object.assign(n,e),n.callbacks=Object.assign({},t.callbacks,e.callbacks),n.head=Object.assign({},t.head,e.head),n}(a),d=c.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(d))throw`Do not understand how to morph style ${d}`;return{target:o,newContent:i,config:c,morphStyle:d,ignoreActive:c.ignoreActive,ignoreActiveValue:c.ignoreActiveValue,restoreFocus:c.restoreFocus,idMap:s,persistentIds:l,pantry:e(),callbacks:c.callbacks,head:c.head}}}(),{normalizeElement:a,normalizeParent:l}=function(){const e=new WeakSet;return{normalizeElement:function(e){return e instanceof Document?e.documentElement:e},normalizeParent:function t(n){if(null==n)return document.createElement("div");if("string"==typeof n)return t(function(t){let n=new DOMParser,r=t.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let o=n.parseFromString(t,"text/html");if(r.match(/<\/html>/))return e.add(o),o;{let t=o.firstChild;return t&&e.add(t),t}}{let r=n.parseFromString("<body><template>"+t+"</template></body>","text/html").body.querySelector("template").content;return e.add(r),r}}(n));if(e.has(n))return n;if(n instanceof Node){if(n.parentNode)return function(e){return{childNodes:[e],querySelectorAll:t=>{const n=e.querySelectorAll(t);return e.matches(t)?[e,...n]:n},insertBefore:(t,n)=>e.parentNode.insertBefore(t,n),moveBefore:(t,n)=>e.parentNode.moveBefore(t,n),get __idiomorphRoot(){return e}}}(n);{const e=document.createElement("div");return e.append(n),e}}{const e=document.createElement("div");for(const t of[...n])e.append(t);return e}}}}();return{morph:function(e,t,r={}){e=a(e);const s=l(t),c=i(e,s,r),d=function(e,t){var n;if(!e.config.restoreFocus)return t();let r=document.activeElement;if(!(r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement))return t();const{id:o,selectionStart:i,selectionEnd:a}=r,l=t();o&&o!==(null==(n=document.activeElement)?void 0:n.id)&&(r=e.target.querySelector(`#${o}`),null==r||r.focus());r&&!r.selectionEnd&&a&&r.setSelectionRange(i,a);return l}(c,(()=>function(e,t,n,r){if(e.head.block){const i=t.querySelector("head"),a=n.querySelector("head");if(i&&a){const t=o(i,a,e);return Promise.all(t).then((()=>{const t=Object.assign(e,{head:{block:!1,ignore:!0}});return r(t)}))}}return r(e)}(c,e,s,(t=>"innerHTML"===t.morphStyle?(n(t,e,s),Array.from(e.childNodes)):function(e,t,r){const o=l(t);let i=Array.from(o.childNodes);const a=i.indexOf(t),s=i.length-(a+1);return n(e,o,r,t,t.nextSibling),i=Array.from(o.childNodes),i.slice(a,i.length-s)}(t,e,s)))));return c.pantry.remove(),d},defaults:t}}();const m={},p={},h=(e,t)=>{p[e]=Object.assign({},p[e],t),m[e]&&m[e].forEach((e=>e(t)))},b=(e,t)=>(m[e]=m[e]||[],m[e].push(t),e in p&&t(p[e]),()=>{m[e]=m[e].filter((e=>e!=t))}),g=({name:e,module:t,dependencies:n,node:r,templates:o,signal:i,register:l})=>{var c;let d,m=[];const p=t.model||{},g=new Function(`return ${r.getAttribute("html-model")||"{}"}`)(),y=r.getAttribute("tplid"),A=r.getAttribute("html-scopeid"),E=o[y],N=s.scope[A],M=(_=(null==(c=null==t?void 0:t.model)?void 0:c.apply)?p({elm:r,initialState:g}):p,JSON.parse(JSON.stringify(_)));var _;const S=Object.assign({},N,M,g),T=t.view?t.view:e=>e,w={name:e,model:M,elm:r,template:E.template,dependencies:n,publish:h,subscribe:b,main(e){r.addEventListener(":mount",e)},state:{protected(e){if(!e)return m;m=e},save(e){e.constructor===Function?e(S):Object.assign(S,e)},set(e){if(!document.body.contains(r))return;e.constructor===Function?e(S):Object.assign(S,e);const t=Object.assign({},S,N);return new Promise((e=>{$(t,(()=>e(t)))}))},get:()=>Object.assign({},S)},dataset(e,t){let n,o;t?(n=e,o=t):(n=r,o=e);const i=n.dataset[o];if("true"===i)return!0;if("false"===i)return!1;if(!isNaN(i)&&""!==i.trim())return Number(i);try{return new Function("return ("+i+")")()}catch(a){}try{return JSON.parse(i)}catch(a){}return i},on(e,t,n){n?(n.handler=e=>{const o=e.detail||{};let i=e.target;for(;i&&(i.matches(t)&&(e.delegateTarget=i,n.apply(r,[e].concat(o.args))),i!==r);)i=i.parentNode},r.addEventListener(e,n.handler,{signal:i,capture:"focus"==e||"blur"==e||"mouseenter"==e||"mouseleave"==e})):(t.handler=e=>{e.delegateTarget=r,t.apply(r,[e].concat(e.detail.args))},r.addEventListener(e,t.handler,{signal:i}))},off(e,t){t.handler&&r.removeEventListener(e,t.handler)},trigger(e,t,n){t.constructor===String?Array.from(r.querySelectorAll(t)).forEach((t=>{t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:{args:n}}))})):r.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:{args:n}}))},emit(e,t){r.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:{args:t}}))},unmount(e){r.addEventListener(":unmount",e)},innerHTML(e,t){const n=t?e:r,o=n.cloneNode(),i=t||e;o.innerHTML=i,f.morph(n,o)}},$=(e,t=()=>{})=>{clearTimeout(d),d=setTimeout((()=>{const n=E.render.call(a(a({},e),T(e)),r,u,s);f.morph(r,n,v(r,l)),Promise.resolve().then((()=>{r.querySelectorAll("[tplid]").forEach((t=>{const n=l.get(t);n&&(n.state.protected().forEach((t=>delete e[t])),n.state.set(e))})),Promise.resolve().then((()=>{s.scope={},t()}))}))}))};return $(S),l.set(r,w),t.default(w)},v=(e,t)=>({callbacks:{beforeNodeMorphed(n){if(1===n.nodeType){if("html-static"in n.attributes)return!1;if(t.get(n)&&n!==e)return!1}}}}),y=new WeakMap,A=({component:e,templates:t,start:n})=>{const{name:r,module:o,dependencies:i}=e;return class extends HTMLElement{constructor(){super()}connectedCallback(){this.abortController=new AbortController,this.getAttribute("tplid")||n(this.parentNode);const e=g({node:this,name:r,module:o,dependencies:i,templates:t,signal:this.abortController.signal,register:y});e&&e.constructor===Promise?e.then((()=>{this.dispatchEvent(new CustomEvent(":mount"))})):this.dispatchEvent(new CustomEvent(":mount"))}disconnectedCallback(){this.dispatchEvent(new CustomEvent(":unmount")),this.abortController.abort()}}},E={},N={tags:["{{","}}"]},M=e=>{const t=JSON.stringify(e);return new Function("$element","safe","$g",`\n\t\tvar $data = this;\n\t\twith( $data ){\n\t\t\tvar output=${t.replace(/%%_=(.+?)_%%/g,(function(e,t){return'"+safe(function(){return '+c(t)+';})+"'})).replace(/%%_(.+?)_%%/g,(function(e,t){return'";'+c(t)+'\noutput+="'}))};return output;\n\t\t}\n\t`)},_=(e,t,n)=>{e.querySelectorAll(t.toString()).forEach((e=>{const r=e.localName;if("template"===r)return _(e.content,t,n);e.getAttribute("html-if")&&!e.id&&(e.id=d()),r in n&&e.setAttribute("tplid",d())}))},S=e=>{e.querySelectorAll("template, [html-for], [html-if], [html-inner], [html-class]").forEach((e=>{const t=e.getAttribute("html-for"),n=e.getAttribute("html-if"),r=e.getAttribute("html-inner"),o=e.getAttribute("html-class");if(t){e.removeAttribute("html-for");const n=t.match(/(.*)\sin\s(.*)/)||"",r=n[1],o=n[2],i=o.split(/\./).shift(),a=document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${o} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${r} = ${o}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${i}: ${i} }, { ${r} :${r}, $index: $index, $key: $key }); _%%`),l=document.createTextNode("%%_ $index++; } })() _%%");$(a,e,l)}if(n){e.removeAttribute("html-if");const t=document.createTextNode(`%%_ if ( safe(function(){ return ${n} }) ){ _%%`),r=document.createTextNode("%%_ } _%%");$(t,e,r)}r&&(e.removeAttribute("html-inner"),e.innerHTML=`%%_=${r}_%%`),o&&(e.removeAttribute("html-class"),e.className=(e.className+` %%_=${o}_%%`).trim()),"template"===e.localName&&S(e.content)}))},T=(e,t)=>{Array.from(e.querySelectorAll("[tplid]")).reverse().forEach((e=>{const n=e.getAttribute("tplid"),r=e.localName;if(e.setAttribute("html-scopeid","jails___scope-id"),r in t&&t[r].module.template){const n=e.innerHTML,o=t[r].module.template({elm:e,children:n});e.innerHTML=o}const o=(e=>{const t=new RegExp(`\\${N.tags[0]}(.+?)\\${N.tags[1]}`,"g");return e.replace(/jails___scope-id/g,"%%_=$scopeid_%%").replace(t,"%%_=$1_%%").replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\"(.*?)\"/g,"%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%").replace(/html-([^\s]*?)=\"(.*?)\"/g,((e,t,n)=>"key"===t||"model"===t||"scopeid"===t?e:n?`${t}="%%_=safe(function(){ return ${n=n.replace(/^{|}$/g,"")} })_%%"`:e))})(e.outerHTML);E[n]={template:o,render:M(o)}}))},w=e=>{e.querySelectorAll("template").forEach((e=>{if(e.getAttribute("html-if")||e.getAttribute("html-inner"))return;w(e.content);const t=e.parentNode;if(t){const n=e.content;for(;n.firstChild;)t.insertBefore(n.firstChild,e);t.removeChild(e)}}))},$=(e,t,n)=>{var r,o;null==(r=t.parentNode)||r.insertBefore(e,t),null==(o=t.parentNode)||o.insertBefore(n,t.nextSibling)};window.__jails__=window.__jails__||{components:{}};const k=(e=document.body)=>{const{components:t}=window.__jails__,n=((e,{components:t})=>{_(e,[...Object.keys(t),"[html-if]","template"],t);const n=e.cloneNode(!0);return S(n),w(n),T(n,t),E})(e,{components:t});Object.values(t).forEach((({name:e,module:t,dependencies:r})=>{customElements.get(e)||customElements.define(e,A({component:{name:e,module:t,dependencies:r},templates:n,start:k}))}))};e.publish=h,e.register=(e,t,n)=>{const{components:r}=window.__jails__;r[e]={name:e,module:t,dependencies:n}},e.start=k,e.subscribe=b,e.templateConfig=e=>{var t;t=e,Object.assign(N,t)},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).jails={})}(this,(function(e){"use strict";var t=Object.defineProperty,n=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable,i=(e,n,r)=>n in e?t(e,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[n]=r,a=(e,t)=>{for(var a in t||(t={}))r.call(t,a)&&i(e,a,t[a]);if(n)for(var a of n(t))o.call(t,a)&&i(e,a,t[a]);return e};const l=document.createElement("textarea"),s={scope:{}},c=e=>(l.innerHTML=e,l.value),u=()=>Math.random().toString(36).substring(2,9),d=(e,t)=>{try{return e()}catch(n){return t||""}};var f=function(){const e=()=>{},t={morphStyle:"outerHTML",callbacks:{beforeNodeAdded:e,afterNodeAdded:e,beforeNodeMorphed:e,afterNodeMorphed:e,beforeNodeRemoved:e,afterNodeRemoved:e,beforeAttributeUpdated:e},head:{style:"merge",shouldPreserve:e=>"true"===e.getAttribute("im-preserve"),shouldReAppend:e=>"true"===e.getAttribute("im-re-append"),shouldRemove:e,afterHeadMorphed:e},restoreFocus:!0};const n=function(){function e(e,t,n,o){if(!1===o.callbacks.beforeNodeAdded(t))return null;if(o.idMap.has(t)){const i=document.createElement(t.tagName);return e.insertBefore(i,n),r(i,t,o),o.callbacks.afterNodeAdded(i),i}{const r=document.importNode(t,!0);return e.insertBefore(r,n),o.callbacks.afterNodeAdded(r),r}}const t=function(){function e(e,t,n){let r=e.idMap.get(t),o=e.idMap.get(n);if(!o||!r)return!1;for(const i of r)if(o.has(i))return!0;return!1}function t(e,t){const n=e,r=t;return n.nodeType===r.nodeType&&n.tagName===r.tagName&&(!n.id||n.id===r.id)}return function(n,r,o,i){let a=null,l=r.nextSibling,s=0,c=o;for(;c&&c!=i;){if(t(c,r)){if(e(n,c,r))return c;null===a&&(n.idMap.has(c)||(a=c))}if(null===a&&l&&t(c,l)&&(s++,l=l.nextSibling,s>=2&&(a=void 0)),c.contains(document.activeElement))break;c=c.nextSibling}return a||null}}();function n(e,t){var n;if(e.idMap.has(t))a(e.pantry,t,null);else{if(!1===e.callbacks.beforeNodeRemoved(t))return;null==(n=t.parentNode)||n.removeChild(t),e.callbacks.afterNodeRemoved(t)}}function o(e,t,r){let o=t;for(;o&&o!==r;){let t=o;o=o.nextSibling,n(e,t)}return o}function i(e,t,n,r){const o=r.target.querySelector(`#${t}`)||r.pantry.querySelector(`#${t}`);return function(e,t){const n=e.id;for(;e=e.parentNode;){let r=t.idMap.get(e);r&&(r.delete(n),r.size||t.idMap.delete(e))}}(o,r),a(e,o,n),o}function a(e,t,n){if(e.moveBefore)try{e.moveBefore(t,n)}catch(r){e.insertBefore(t,n)}else e.insertBefore(t,n)}return function(a,l,s,c=null,u=null){l instanceof HTMLTemplateElement&&s instanceof HTMLTemplateElement&&(l=l.content,s=s.content),c||(c=l.firstChild);for(const n of s.childNodes){if(c&&c!=u){const e=t(a,n,c,u);if(e){e!==c&&o(a,c,e),r(e,n,a),c=e.nextSibling;continue}}if(n instanceof Element&&a.persistentIds.has(n.id)){const e=i(l,n.id,c,a);r(e,n,a),c=e.nextSibling;continue}const s=e(l,n,c,a);s&&(c=s.nextSibling)}for(;c&&c!=u;){const e=c;c=c.nextSibling,n(a,e)}}}(),r=function(){function e(e,n,r,o){const i=n[r];if(i!==e[r]){const a=t(r,e,"update",o);a||(e[r]=n[r]),i?a||e.setAttribute(r,""):t(r,e,"remove",o)||e.removeAttribute(r)}}function t(e,t,n,r){return!("value"!==e||!r.ignoreActiveValue||t!==document.activeElement)||!1===r.callbacks.beforeAttributeUpdated(e,t,n)}function r(e,t){return!!t.ignoreActiveValue&&e===document.activeElement&&e!==document.body}return function(i,a,l){return l.ignoreActive&&i===document.activeElement?null:(!1===l.callbacks.beforeNodeMorphed(i,a)||(i instanceof HTMLHeadElement&&l.head.ignore||(i instanceof HTMLHeadElement&&"morph"!==l.head.style?o(i,a,l):(!function(n,o,i){let a=o.nodeType;if(1===a){const a=n,l=o,s=a.attributes,c=l.attributes;for(const e of c)t(e.name,a,"update",i)||a.getAttribute(e.name)!==e.value&&a.setAttribute(e.name,e.value);for(let e=s.length-1;0<=e;e--){const n=s[e];if(n&&!l.hasAttribute(n.name)){if(t(n.name,a,"remove",i))continue;a.removeAttribute(n.name)}}r(a,i)||function(n,r,o){if(n instanceof HTMLInputElement&&r instanceof HTMLInputElement&&"file"!==r.type){let i=r.value,a=n.value;e(n,r,"checked",o),e(n,r,"disabled",o),r.hasAttribute("value")?a!==i&&(t("value",n,"update",o)||(n.setAttribute("value",i),n.value=i)):t("value",n,"remove",o)||(n.value="",n.removeAttribute("value"))}else if(n instanceof HTMLOptionElement&&r instanceof HTMLOptionElement)e(n,r,"selected",o);else if(n instanceof HTMLTextAreaElement&&r instanceof HTMLTextAreaElement){let e=r.value,i=n.value;if(t("value",n,"update",o))return;e!==i&&(n.value=e),n.firstChild&&n.firstChild.nodeValue!==e&&(n.firstChild.nodeValue=e)}}(a,l,i)}8!==a&&3!==a||n.nodeValue!==o.nodeValue&&(n.nodeValue=o.nodeValue)}(i,a,l),r(i,l)||n(l,i,a))),l.callbacks.afterNodeMorphed(i,a)),i)}}();function o(e,t,n){let r=[],o=[],i=[],a=[],l=new Map;for(const c of t.children)l.set(c.outerHTML,c);for(const c of e.children){let e=l.has(c.outerHTML),t=n.head.shouldReAppend(c),r=n.head.shouldPreserve(c);e||r?t?o.push(c):(l.delete(c.outerHTML),i.push(c)):"append"===n.head.style?t&&(o.push(c),a.push(c)):!1!==n.head.shouldRemove(c)&&o.push(c)}a.push(...l.values());let s=[];for(const c of a){let t=document.createRange().createContextualFragment(c.outerHTML).firstChild;if(!1!==n.callbacks.beforeNodeAdded(t)){if("href"in t&&t.href||"src"in t&&t.src){let e,n=new Promise((function(t){e=t}));t.addEventListener("load",(function(){e()})),s.push(n)}e.appendChild(t),n.callbacks.afterNodeAdded(t),r.push(t)}}for(const c of o)!1!==n.callbacks.beforeNodeRemoved(c)&&(e.removeChild(c),n.callbacks.afterNodeRemoved(c));return n.head.afterHeadMorphed(e,{added:r,kept:i,removed:o}),s}const i=function(){function e(){const e=document.createElement("div");return e.hidden=!0,document.body.insertAdjacentElement("afterend",e),e}function n(e){let t=Array.from(e.querySelectorAll("[id]"));return e.id&&t.push(e),t}function r(e,t,n,r){for(const o of r)if(t.has(o.id)){let t=o;for(;t;){let r=e.get(t);if(null==r&&(r=new Set,e.set(t,r)),r.add(o.id),t===n)break;t=t.parentElement}}}return function(o,i,a){const{persistentIds:l,idMap:s}=function(e,t){const o=n(e),i=n(t),a=function(e,t){let n=new Set,r=new Map;for(const{id:i,tagName:a}of e)r.has(i)?n.add(i):r.set(i,a);let o=new Set;for(const{id:i,tagName:a}of t)o.has(i)?n.add(i):r.get(i)===a&&o.add(i);for(const i of n)o.delete(i);return o}(o,i);let l=new Map;r(l,a,e,o);const s=t.__idiomorphRoot||t;return r(l,a,s,i),{persistentIds:a,idMap:l}}(o,i),c=function(e){let n=Object.assign({},t);return Object.assign(n,e),n.callbacks=Object.assign({},t.callbacks,e.callbacks),n.head=Object.assign({},t.head,e.head),n}(a),u=c.morphStyle||"outerHTML";if(!["innerHTML","outerHTML"].includes(u))throw`Do not understand how to morph style ${u}`;return{target:o,newContent:i,config:c,morphStyle:u,ignoreActive:c.ignoreActive,ignoreActiveValue:c.ignoreActiveValue,restoreFocus:c.restoreFocus,idMap:s,persistentIds:l,pantry:e(),callbacks:c.callbacks,head:c.head}}}(),{normalizeElement:a,normalizeParent:l}=function(){const e=new WeakSet;return{normalizeElement:function(e){return e instanceof Document?e.documentElement:e},normalizeParent:function t(n){if(null==n)return document.createElement("div");if("string"==typeof n)return t(function(t){let n=new DOMParser,r=t.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");if(r.match(/<\/html>/)||r.match(/<\/head>/)||r.match(/<\/body>/)){let o=n.parseFromString(t,"text/html");if(r.match(/<\/html>/))return e.add(o),o;{let t=o.firstChild;return t&&e.add(t),t}}{let r=n.parseFromString("<body><template>"+t+"</template></body>","text/html").body.querySelector("template").content;return e.add(r),r}}(n));if(e.has(n))return n;if(n instanceof Node){if(n.parentNode)return function(e){return{childNodes:[e],querySelectorAll:t=>{const n=e.querySelectorAll(t);return e.matches(t)?[e,...n]:n},insertBefore:(t,n)=>e.parentNode.insertBefore(t,n),moveBefore:(t,n)=>e.parentNode.moveBefore(t,n),get __idiomorphRoot(){return e}}}(n);{const e=document.createElement("div");return e.append(n),e}}{const e=document.createElement("div");for(const t of[...n])e.append(t);return e}}}}();return{morph:function(e,t,r={}){e=a(e);const s=l(t),c=i(e,s,r),u=function(e,t){var n;if(!e.config.restoreFocus)return t();let r=document.activeElement;if(!(r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement))return t();const{id:o,selectionStart:i,selectionEnd:a}=r,l=t();o&&o!==(null==(n=document.activeElement)?void 0:n.id)&&(r=e.target.querySelector(`#${o}`),null==r||r.focus());r&&!r.selectionEnd&&a&&r.setSelectionRange(i,a);return l}(c,(()=>function(e,t,n,r){if(e.head.block){const i=t.querySelector("head"),a=n.querySelector("head");if(i&&a){const t=o(i,a,e);return Promise.all(t).then((()=>{const t=Object.assign(e,{head:{block:!1,ignore:!0}});return r(t)}))}}return r(e)}(c,e,s,(t=>"innerHTML"===t.morphStyle?(n(t,e,s),Array.from(e.childNodes)):function(e,t,r){const o=l(t);let i=Array.from(o.childNodes);const a=i.indexOf(t),s=i.length-(a+1);return n(e,o,r,t,t.nextSibling),i=Array.from(o.childNodes),i.slice(a,i.length-s)}(t,e,s)))));return c.pantry.remove(),u},defaults:t}}();const m={},p={},h=(e,t)=>{p[e]=Object.assign({},p[e],t),m[e]&&m[e].forEach((e=>e(t)))},b=(e,t)=>(m[e]=m[e]||[],m[e].push(t),e in p&&t(p[e]),()=>{m[e]=m[e].filter((e=>e!=t))}),g=({name:e,module:t,dependencies:n,node:r,templates:o,signal:i,register:l})=>{var c;let u,m=[];const p=t.model||{},g=new Function(`return ${r.getAttribute("html-model")||"{}"}`)(),y=r.getAttribute("tplid"),A=r.getAttribute("html-scopeid"),E=o[y],N=s.scope[A],M=(_=(null==(c=null==t?void 0:t.model)?void 0:c.apply)?p({elm:r,initialState:g}):p,JSON.parse(JSON.stringify(_)));var _;const S=Object.assign({},N,M,g),T=t.view?t.view:e=>e,w={name:e,model:M,elm:r,template:E.template,dependencies:n,publish:h,subscribe:b,main(e){r.addEventListener(":mount",e)},state:{protected(e){if(!e)return m;m=e},save(e){e.constructor===Function?e(S):Object.assign(S,e)},set(e){if(!document.body.contains(r))return;e.constructor===Function?e(S):Object.assign(S,e);const t=Object.assign({},S,N);return new Promise((e=>{$(t,(()=>e(t)))}))},get:()=>Object.assign({},S)},dataset(e,t){const n=t||e,o=(t?e:r).dataset[n];if("true"===o)return!0;if("false"===o)return!1;if(!isNaN(o)&&""!==o.trim())return Number(o);try{return new Function("return ("+o+")")()}catch(i){}try{return JSON.parse(o)}catch(i){}return o},attributes(e){let t=[];const n=e||r,o=new MutationObserver((e=>{for(const r of e)if("attributes"===r.type){const e=r.attributeName;t.forEach((t=>{t.name==e&&t.callback(e,n.getAttribute(e))}))}}));return o.observe(r,{attributes:!0}),r.addEventListener(":unmount",(()=>{t=null,o.disconnect()})),{onchange(e,n){t.push({name:e,callback:n})},disconnect(e){t=t.filter((t=>t.callback!==e))}}},on(e,t,n){n?(n.handler=e=>{const o=e.detail||{};let i=e.target;for(;i&&(i.matches(t)&&(e.delegateTarget=i,n.apply(r,[e].concat(o.args))),i!==r);)i=i.parentNode},r.addEventListener(e,n.handler,{signal:i,capture:"focus"==e||"blur"==e||"mouseenter"==e||"mouseleave"==e})):(t.handler=e=>{e.delegateTarget=r,t.apply(r,[e].concat(e.detail.args))},r.addEventListener(e,t.handler,{signal:i}))},off(e,t){t.handler&&r.removeEventListener(e,t.handler)},trigger(e,t,n){t.constructor===String?Array.from(r.querySelectorAll(t)).forEach((t=>{t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:{args:n}}))})):r.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:{args:n}}))},emit(e,t){r.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:{args:t}}))},unmount(e){r.addEventListener(":unmount",e)},innerHTML(e,t){const n=t?e:r,o=n.cloneNode(),i=t||e;o.innerHTML=i,f.morph(n,o)}},$=(e,t=()=>{})=>{clearTimeout(u),u=setTimeout((()=>{const n=E.render.call(a(a({},e),T(e)),r,d,s);f.morph(r,n,v(r,l)),Promise.resolve().then((()=>{r.querySelectorAll("[tplid]").forEach((t=>{const n=l.get(t);n&&(n.state.protected().forEach((t=>delete e[t])),n.state.set(e))})),Promise.resolve().then((()=>{s.scope={},t()}))}))}))};return $(S),l.set(r,w),t.default(w)},v=(e,t)=>({callbacks:{beforeNodeMorphed(n){if(1===n.nodeType){if("html-static"in n.attributes)return!1;if(t.get(n)&&n!==e)return!1}}}}),y=new WeakMap,A=({component:e,templates:t,start:n})=>{const{name:r,module:o,dependencies:i}=e;return class extends HTMLElement{constructor(){super()}connectedCallback(){this.abortController=new AbortController,this.getAttribute("tplid")||n(this.parentNode);const e=g({node:this,name:r,module:o,dependencies:i,templates:t,signal:this.abortController.signal,register:y});e&&e.constructor===Promise?e.then((()=>{this.dispatchEvent(new CustomEvent(":mount"))})):this.dispatchEvent(new CustomEvent(":mount"))}disconnectedCallback(){this.dispatchEvent(new CustomEvent(":unmount")),this.abortController.abort()}}},E={},N={tags:["{{","}}"]},M=e=>{const t=JSON.stringify(e);return new Function("$element","safe","$g",`\n\t\tvar $data = this;\n\t\twith( $data ){\n\t\t\tvar output=${t.replace(/%%_=(.+?)_%%/g,(function(e,t){return'"+safe(function(){return '+c(t)+';})+"'})).replace(/%%_(.+?)_%%/g,(function(e,t){return'";'+c(t)+'\noutput+="'}))};return output;\n\t\t}\n\t`)},_=(e,t,n)=>{e.querySelectorAll(t.toString()).forEach((e=>{const r=e.localName;if("template"===r)return _(e.content,t,n);e.getAttribute("html-if")&&!e.id&&(e.id=u()),r in n&&e.setAttribute("tplid",u())}))},S=e=>{e.querySelectorAll("template, [html-for], [html-if], [html-inner], [html-class]").forEach((e=>{const t=e.getAttribute("html-for"),n=e.getAttribute("html-if"),r=e.getAttribute("html-inner"),o=e.getAttribute("html-class");if(t){e.removeAttribute("html-for");const n=t.match(/(.*)\sin\s(.*)/)||"",r=n[1],o=n[2],i=o.split(/\./).shift(),a=document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${o} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${r} = ${o}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${i}: ${i} }, { ${r} :${r}, $index: $index, $key: $key }); _%%`),l=document.createTextNode("%%_ $index++; } })() _%%");$(a,e,l)}if(n){e.removeAttribute("html-if");const t=document.createTextNode(`%%_ if ( safe(function(){ return ${n} }) ){ _%%`),r=document.createTextNode("%%_ } _%%");$(t,e,r)}r&&(e.removeAttribute("html-inner"),e.innerHTML=`%%_=${r}_%%`),o&&(e.removeAttribute("html-class"),e.className=(e.className+` %%_=${o}_%%`).trim()),"template"===e.localName&&S(e.content)}))},T=(e,t)=>{Array.from(e.querySelectorAll("[tplid]")).reverse().forEach((e=>{const n=e.getAttribute("tplid"),r=e.localName;if(e.setAttribute("html-scopeid","jails___scope-id"),r in t&&t[r].module.template){const n=e.innerHTML,o=t[r].module.template({elm:e,children:n});e.innerHTML=o}const o=(e=>{const t=new RegExp(`\\${N.tags[0]}(.+?)\\${N.tags[1]}`,"g");return e.replace(/jails___scope-id/g,"%%_=$scopeid_%%").replace(t,"%%_=$1_%%").replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\"(.*?)\"/g,"%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%").replace(/html-([^\s]*?)=\"(.*?)\"/g,((e,t,n)=>"key"===t||"model"===t||"scopeid"===t?e:n?`${t}="%%_=safe(function(){ return ${n=n.replace(/^{|}$/g,"")} })_%%"`:e))})(e.outerHTML);E[n]={template:o,render:M(o)}}))},w=e=>{e.querySelectorAll("template").forEach((e=>{if(e.getAttribute("html-if")||e.getAttribute("html-inner"))return;w(e.content);const t=e.parentNode;if(t){const n=e.content;for(;n.firstChild;)t.insertBefore(n.firstChild,e);t.removeChild(e)}}))},$=(e,t,n)=>{var r,o;null==(r=t.parentNode)||r.insertBefore(e,t),null==(o=t.parentNode)||o.insertBefore(n,t.nextSibling)};window.__jails__=window.__jails__||{components:{}};const k=(e=document.body)=>{const{components:t}=window.__jails__,n=((e,{components:t})=>{_(e,[...Object.keys(t),"[html-if]","template"],t);const n=e.cloneNode(!0);return S(n),w(n),T(n,t),E})(e,{components:t});Object.values(t).forEach((({name:e,module:t,dependencies:r})=>{customElements.get(e)||customElements.define(e,A({component:{name:e,module:t,dependencies:r},templates:n,start:k}))}))};e.publish=h,e.register=(e,t,n)=>{const{components:r}=window.__jails__;r[e]={name:e,module:t,dependencies:n}},e.start=k,e.subscribe=b,e.templateConfig=e=>{var t;t=e,Object.assign(N,t)},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}));
2
2
  //# sourceMappingURL=jails.js.map
package/dist/jails.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"jails.js","sources":["../src/utils/index.ts","../node_modules/idiomorph/dist/idiomorph.esm.js","../src/utils/pubsub.ts","../src/component.ts","../src/element.ts","../src/template-system.ts","../src/index.ts"],"sourcesContent":["\nconst textarea = document.createElement('textarea')\n\nexport const g = {\n\tscope: {}\n}\n\nexport const decodeHTML = (text) => {\n\ttextarea.innerHTML = text\n\treturn textarea.value\n}\n\nexport const rAF = (fn) => {\n\tif (requestAnimationFrame)\n\t\treturn requestAnimationFrame(fn)\n\telse\n\t\treturn setTimeout(fn, 1000 / 60)\n}\n\nexport const uuid = () => {\n\treturn Math.random().toString(36).substring(2, 9)\n}\n\nexport const dup = (o) => {\n\treturn JSON.parse(JSON.stringify(o))\n}\n\nexport const safe = (execute, val) => {\n\ttry{\n\t\treturn execute()\n\t}catch(err){\n\t\treturn val || ''\n\t}\n}\n","/**\n * @typedef {object} ConfigHead\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} [style]\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {function(Element): boolean} [shouldPreserve]\n * @property {function(Element): boolean} [shouldReAppend]\n * @property {function(Element): boolean} [shouldRemove]\n * @property {function(Element, {added: Node[], kept: Element[], removed: Element[]}): void} [afterHeadMorphed]\n */\n\n/**\n * @typedef {object} ConfigCallbacks\n *\n * @property {function(Node): boolean} [beforeNodeAdded]\n * @property {function(Node): void} [afterNodeAdded]\n * @property {function(Element, Node): boolean} [beforeNodeMorphed]\n * @property {function(Element, Node): void} [afterNodeMorphed]\n * @property {function(Element): boolean} [beforeNodeRemoved]\n * @property {function(Element): void} [afterNodeRemoved]\n * @property {function(string, Element, \"update\" | \"remove\"): boolean} [beforeAttributeUpdated]\n */\n\n/**\n * @typedef {object} Config\n *\n * @property {'outerHTML' | 'innerHTML'} [morphStyle]\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacks} [callbacks]\n * @property {ConfigHead} [head]\n */\n\n/**\n * @typedef {function} NoOp\n *\n * @returns {void}\n */\n\n/**\n * @typedef {object} ConfigHeadInternal\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} style\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {(function(Element): boolean) | NoOp} shouldPreserve\n * @property {(function(Element): boolean) | NoOp} shouldReAppend\n * @property {(function(Element): boolean) | NoOp} shouldRemove\n * @property {(function(Element, {added: Node[], kept: Element[], removed: Element[]}): void) | NoOp} afterHeadMorphed\n */\n\n/**\n * @typedef {object} ConfigCallbacksInternal\n *\n * @property {(function(Node): boolean) | NoOp} beforeNodeAdded\n * @property {(function(Node): void) | NoOp} afterNodeAdded\n * @property {(function(Node, Node): boolean) | NoOp} beforeNodeMorphed\n * @property {(function(Node, Node): void) | NoOp} afterNodeMorphed\n * @property {(function(Node): boolean) | NoOp} beforeNodeRemoved\n * @property {(function(Node): void) | NoOp} afterNodeRemoved\n * @property {(function(string, Element, \"update\" | \"remove\"): boolean) | NoOp} beforeAttributeUpdated\n */\n\n/**\n * @typedef {object} ConfigInternal\n *\n * @property {'outerHTML' | 'innerHTML'} morphStyle\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacksInternal} callbacks\n * @property {ConfigHeadInternal} head\n */\n\n/**\n * @typedef {Object} IdSets\n * @property {Set<string>} persistentIds\n * @property {Map<Node, Set<string>>} idMap\n */\n\n/**\n * @typedef {Function} Morph\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {undefined | Node[]}\n */\n\n// base IIFE to define idiomorph\n/**\n *\n * @type {{defaults: ConfigInternal, morph: Morph}}\n */\nvar Idiomorph = (function () {\n \"use strict\";\n\n /**\n * @typedef {object} MorphContext\n *\n * @property {Element} target\n * @property {Element} newContent\n * @property {ConfigInternal} config\n * @property {ConfigInternal['morphStyle']} morphStyle\n * @property {ConfigInternal['ignoreActive']} ignoreActive\n * @property {ConfigInternal['ignoreActiveValue']} ignoreActiveValue\n * @property {ConfigInternal['restoreFocus']} restoreFocus\n * @property {Map<Node, Set<string>>} idMap\n * @property {Set<string>} persistentIds\n * @property {ConfigInternal['callbacks']} callbacks\n * @property {ConfigInternal['head']} head\n * @property {HTMLDivElement} pantry\n */\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n\n const noOp = () => {};\n /**\n * Default configuration values, updatable by users now\n * @type {ConfigInternal}\n */\n const defaults = {\n morphStyle: \"outerHTML\",\n callbacks: {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n },\n head: {\n style: \"merge\",\n shouldPreserve: (elt) => elt.getAttribute(\"im-preserve\") === \"true\",\n shouldReAppend: (elt) => elt.getAttribute(\"im-re-append\") === \"true\",\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n },\n restoreFocus: true,\n };\n\n /**\n * Core idiomorph function for morphing one DOM tree to another\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {Promise<Node[]> | Node[]}\n */\n function morph(oldNode, newContent, config = {}) {\n oldNode = normalizeElement(oldNode);\n const newNode = normalizeParent(newContent);\n const ctx = createMorphContext(oldNode, newNode, config);\n\n const morphedNodes = saveAndRestoreFocus(ctx, () => {\n return withHeadBlocking(\n ctx,\n oldNode,\n newNode,\n /** @param {MorphContext} ctx */ (ctx) => {\n if (ctx.morphStyle === \"innerHTML\") {\n morphChildren(ctx, oldNode, newNode);\n return Array.from(oldNode.childNodes);\n } else {\n return morphOuterHTML(ctx, oldNode, newNode);\n }\n },\n );\n });\n\n ctx.pantry.remove();\n return morphedNodes;\n }\n\n /**\n * Morph just the outerHTML of the oldNode to the newContent\n * We have to be careful because the oldNode could have siblings which need to be untouched\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @returns {Node[]}\n */\n function morphOuterHTML(ctx, oldNode, newNode) {\n const oldParent = normalizeParent(oldNode);\n\n // basis for calulating which nodes were morphed\n // since there may be unmorphed sibling nodes\n let childNodes = Array.from(oldParent.childNodes);\n const index = childNodes.indexOf(oldNode);\n // how many elements are to the right of the oldNode\n const rightMargin = childNodes.length - (index + 1);\n\n morphChildren(\n ctx,\n oldParent,\n newNode,\n // these two optional params are the secret sauce\n oldNode, // start point for iteration\n oldNode.nextSibling, // end point for iteration\n );\n\n // return just the morphed nodes\n childNodes = Array.from(oldParent.childNodes);\n return childNodes.slice(index, childNodes.length - rightMargin);\n }\n\n /**\n * @param {MorphContext} ctx\n * @param {Function} fn\n * @returns {Promise<Node[]> | Node[]}\n */\n function saveAndRestoreFocus(ctx, fn) {\n if (!ctx.config.restoreFocus) return fn();\n let activeElement =\n /** @type {HTMLInputElement|HTMLTextAreaElement|null} */ (\n document.activeElement\n );\n\n // don't bother if the active element is not an input or textarea\n if (\n !(\n activeElement instanceof HTMLInputElement ||\n activeElement instanceof HTMLTextAreaElement\n )\n ) {\n return fn();\n }\n\n const { id: activeElementId, selectionStart, selectionEnd } = activeElement;\n\n const results = fn();\n\n if (activeElementId && activeElementId !== document.activeElement?.id) {\n activeElement = ctx.target.querySelector(`#${activeElementId}`);\n activeElement?.focus();\n }\n if (activeElement && !activeElement.selectionEnd && selectionEnd) {\n activeElement.setSelectionRange(selectionStart, selectionEnd);\n }\n\n return results;\n }\n\n const morphChildren = (function () {\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm:\n * - for each node in the new content:\n * - search self and siblings for an id set match, falling back to a soft match\n * - if match found\n * - remove any nodes up to the match:\n * - pantry persistent nodes\n * - delete the rest\n * - morph the match\n * - elsif no match found, and node is persistent\n * - find its match by querying the old root (future) and pantry (past)\n * - move it and its children here\n * - morph it\n * - else\n * - create a new node from scratch as a last result\n *\n * @param {MorphContext} ctx the merge context\n * @param {Element} oldParent the old content that we are merging the new content into\n * @param {Element} newParent the parent element of the new content\n * @param {Node|null} [insertionPoint] the point in the DOM we start morphing at (defaults to first child)\n * @param {Node|null} [endPoint] the point in the DOM we stop morphing at (defaults to after last child)\n */\n function morphChildren(\n ctx,\n oldParent,\n newParent,\n insertionPoint = null,\n endPoint = null,\n ) {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // @ts-ignore we can pretend the DocumentFragment is an Element\n oldParent = oldParent.content;\n // @ts-ignore ditto\n newParent = newParent.content;\n }\n insertionPoint ||= oldParent.firstChild;\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint != endPoint) {\n const bestMatch = findBestMatch(\n ctx,\n newChild,\n insertionPoint,\n endPoint,\n );\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n removeNodesBetween(ctx, insertionPoint, bestMatch);\n }\n morphNode(bestMatch, newChild, ctx);\n insertionPoint = bestMatch.nextSibling;\n continue;\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) {\n // move it and all its children here and morph\n const movedChild = moveBeforeById(\n oldParent,\n newChild.id,\n insertionPoint,\n ctx,\n );\n morphNode(movedChild, newChild, ctx);\n insertionPoint = movedChild.nextSibling;\n continue;\n }\n\n // last resort: insert the new node from scratch\n const insertedNode = createNode(\n oldParent,\n newChild,\n insertionPoint,\n ctx,\n );\n // could be null if beforeNodeAdded prevented insertion\n if (insertedNode) {\n insertionPoint = insertedNode.nextSibling;\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint != endPoint) {\n const tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(ctx, tempNode);\n }\n }\n\n /**\n * This performs the action of inserting a new node while handling situations where the node contains\n * elements with persistent ids and possible state info we can still preserve by moving in and then morphing\n *\n * @param {Element} oldParent\n * @param {Node} newChild\n * @param {Node|null} insertionPoint\n * @param {MorphContext} ctx\n * @returns {Node|null}\n */\n function createNode(oldParent, newChild, insertionPoint, ctx) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;\n if (ctx.idMap.has(newChild)) {\n // node has children with ids with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n /** @type {Element} */ (newChild).tagName,\n );\n oldParent.insertBefore(newEmptyChild, insertionPoint);\n morphNode(newEmptyChild, newChild, ctx);\n ctx.callbacks.afterNodeAdded(newEmptyChild);\n return newEmptyChild;\n } else {\n // optimisation: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true); // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newClonedChild);\n return newClonedChild;\n }\n }\n\n //=============================================================================\n // Matching Functions\n //=============================================================================\n const findBestMatch = (function () {\n /**\n * Scans forward from the startPoint to the endPoint looking for a match\n * for the node. It looks for an id set match first, then a soft match.\n * We abort softmatching if we find two future soft matches, to reduce churn.\n * @param {Node} node\n * @param {MorphContext} ctx\n * @param {Node | null} startPoint\n * @param {Node | null} endPoint\n * @returns {Node | null}\n */\n function findBestMatch(ctx, node, startPoint, endPoint) {\n let softMatch = null;\n let nextSibling = node.nextSibling;\n let siblingSoftMatchCount = 0;\n\n let cursor = startPoint;\n while (cursor && cursor != endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n if (isIdSetMatch(ctx, cursor, node)) {\n return cursor; // found an id set match, we're done!\n }\n\n // we haven't yet saved a soft match fallback\n if (softMatch === null) {\n // the current soft match will hard match something else in the future, leave it\n if (!ctx.idMap.has(cursor)) {\n // save this as the fallback if we get through the loop without finding a hard match\n softMatch = cursor;\n }\n }\n }\n if (\n softMatch === null &&\n nextSibling &&\n isSoftMatch(cursor, nextSibling)\n ) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n softMatch = undefined;\n }\n }\n\n // if the current node contains active element, stop looking for better future matches,\n // because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus\n if (cursor.contains(document.activeElement)) break;\n\n cursor = cursor.nextSibling;\n }\n\n return softMatch || null;\n }\n\n /**\n *\n * @param {MorphContext} ctx\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isIdSetMatch(ctx, oldNode, newNode) {\n let oldSet = ctx.idMap.get(oldNode);\n let newSet = ctx.idMap.get(newNode);\n\n if (!newSet || !oldSet) return false;\n\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n *\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isSoftMatch(oldNode, newNode) {\n // ok to cast: if one is not element, `id` and `tagName` will be undefined and we'll just compare that.\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n return (\n oldElt.nodeType === newElt.nodeType &&\n oldElt.tagName === newElt.tagName &&\n // If oldElt has an `id` with possible state and it doesn't match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!oldElt.id || oldElt.id === newElt.id)\n );\n }\n\n return findBestMatch;\n })();\n\n //=============================================================================\n // DOM Manipulation Functions\n //=============================================================================\n\n /**\n * Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n * - Persistent nodes will be moved to the pantry for later reuse\n * - Other nodes will have their hooks called, and then are removed\n * @param {MorphContext} ctx\n * @param {Node} node\n */\n function removeNode(ctx, node) {\n // are we going to id set match this later?\n if (ctx.idMap.has(node)) {\n // skip callbacks and move to pantry\n moveBefore(ctx.pantry, node, null);\n } else {\n // remove for realsies\n if (ctx.callbacks.beforeNodeRemoved(node) === false) return;\n node.parentNode?.removeChild(node);\n ctx.callbacks.afterNodeRemoved(node);\n }\n }\n\n /**\n * Remove nodes between the start and end nodes\n * @param {MorphContext} ctx\n * @param {Node} startInclusive\n * @param {Node} endExclusive\n * @returns {Node|null}\n */\n function removeNodesBetween(ctx, startInclusive, endExclusive) {\n /** @type {Node | null} */\n let cursor = startInclusive;\n // remove nodes until the endExclusive node\n while (cursor && cursor !== endExclusive) {\n let tempNode = /** @type {Node} */ (cursor);\n cursor = cursor.nextSibling;\n removeNode(ctx, tempNode);\n }\n return cursor;\n }\n\n /**\n * Search for an element by id within the document and pantry, and move it using moveBefore.\n *\n * @param {Element} parentNode - The parent node to which the element will be moved.\n * @param {string} id - The ID of the element to be moved.\n * @param {Node | null} after - The reference node to insert the element before.\n * If `null`, the element is appended as the last child.\n * @param {MorphContext} ctx\n * @returns {Element} The found element\n */\n function moveBeforeById(parentNode, id, after, ctx) {\n const target =\n /** @type {Element} - will always be found */\n (\n ctx.target.querySelector(`#${id}`) ||\n ctx.pantry.querySelector(`#${id}`)\n );\n removeElementFromAncestorsIdMaps(target, ctx);\n moveBefore(parentNode, target, after);\n return target;\n }\n\n /**\n * Removes an element from its ancestors' id maps. This is needed when an element is moved from the\n * \"future\" via `moveBeforeId`. Otherwise, its erstwhile ancestors could be mistakenly moved to the\n * pantry rather than being deleted, preventing their removal hooks from being called.\n *\n * @param {Element} element - element to remove from its ancestors' id maps\n * @param {MorphContext} ctx\n */\n function removeElementFromAncestorsIdMaps(element, ctx) {\n const id = element.id;\n /** @ts-ignore - safe to loop in this way **/\n while ((element = element.parentNode)) {\n let idSet = ctx.idMap.get(element);\n if (idSet) {\n idSet.delete(id);\n if (!idSet.size) {\n ctx.idMap.delete(element);\n }\n }\n }\n }\n\n /**\n * Moves an element before another element within the same parent.\n * Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n * This is essentialy a forward-compat wrapper.\n *\n * @param {Element} parentNode - The parent node containing the after element.\n * @param {Node} element - The element to be moved.\n * @param {Node | null} after - The reference node to insert `element` before.\n * If `null`, `element` is appended as the last child.\n */\n function moveBefore(parentNode, element, after) {\n // @ts-ignore - use proposed moveBefore feature\n if (parentNode.moveBefore) {\n try {\n // @ts-ignore - use proposed moveBefore feature\n parentNode.moveBefore(element, after);\n } catch (e) {\n // fall back to insertBefore as some browsers may fail on moveBefore when trying to move Dom disconnected nodes to pantry\n parentNode.insertBefore(element, after);\n }\n } else {\n parentNode.insertBefore(element, after);\n }\n }\n\n return morphChildren;\n })();\n\n //=============================================================================\n // Single Node Morphing Code\n //=============================================================================\n const morphNode = (function () {\n /**\n * @param {Node} oldNode root node to merge content into\n * @param {Node} newContent new content to merge\n * @param {MorphContext} ctx the merge context\n * @returns {Node | null} the element that ended up in the DOM\n */\n function morphNode(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n return null;\n }\n\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) {\n return oldNode;\n }\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (\n oldNode instanceof HTMLHeadElement &&\n ctx.head.style !== \"morph\"\n ) {\n // ok to cast: if newContent wasn't also a <head>, it would've got caught in the `!isSoftMatch` branch above\n handleHeadElement(\n oldNode,\n /** @type {HTMLHeadElement} */ (newContent),\n ctx,\n );\n } else {\n morphAttributes(oldNode, newContent, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n // @ts-ignore newContent can be a node here because .firstChild will be null\n morphChildren(ctx, oldNode, newContent);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n\n /**\n * syncs the oldNode to the newNode, copying over all attributes and\n * inner element state from the newNode to the oldNode\n *\n * @param {Node} oldNode the node to copy attributes & state to\n * @param {Node} newNode the node to copy attributes & state from\n * @param {MorphContext} ctx the merge context\n */\n function morphAttributes(oldNode, newNode, ctx) {\n let type = newNode.nodeType;\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n const oldAttributes = oldElt.attributes;\n const newAttributes = newElt.attributes;\n for (const newAttribute of newAttributes) {\n if (ignoreAttribute(newAttribute.name, oldElt, \"update\", ctx)) {\n continue;\n }\n if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) {\n oldElt.setAttribute(newAttribute.name, newAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = oldAttributes.length - 1; 0 <= i; i--) {\n const oldAttribute = oldAttributes[i];\n\n // toAttributes is a live NamedNodeMap, so iteration+mutation is unsafe\n // e.g. custom element attribute callbacks can remove other attributes\n if (!oldAttribute) continue;\n\n if (!newElt.hasAttribute(oldAttribute.name)) {\n if (ignoreAttribute(oldAttribute.name, oldElt, \"remove\", ctx)) {\n continue;\n }\n oldElt.removeAttribute(oldAttribute.name);\n }\n }\n\n if (!ignoreValueOfActiveElement(oldElt, ctx)) {\n syncInputValue(oldElt, newElt, ctx);\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue;\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param {Element} oldElement the element to sync the input value to\n * @param {Element} newElement the element to sync the input value from\n * @param {MorphContext} ctx the merge context\n */\n function syncInputValue(oldElement, newElement, ctx) {\n if (\n oldElement instanceof HTMLInputElement &&\n newElement instanceof HTMLInputElement &&\n newElement.type !== \"file\"\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n\n // sync boolean attributes\n syncBooleanAttribute(oldElement, newElement, \"checked\", ctx);\n syncBooleanAttribute(oldElement, newElement, \"disabled\", ctx);\n\n if (!newElement.hasAttribute(\"value\")) {\n if (!ignoreAttribute(\"value\", oldElement, \"remove\", ctx)) {\n oldElement.value = \"\";\n oldElement.removeAttribute(\"value\");\n }\n } else if (oldValue !== newValue) {\n if (!ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n oldElement.setAttribute(\"value\", newValue);\n oldElement.value = newValue;\n }\n }\n // TODO: QUESTION(1cg): this used to only check `newElement` unlike the other branches -- why?\n // did I break something?\n } else if (\n oldElement instanceof HTMLOptionElement &&\n newElement instanceof HTMLOptionElement\n ) {\n syncBooleanAttribute(oldElement, newElement, \"selected\", ctx);\n } else if (\n oldElement instanceof HTMLTextAreaElement &&\n newElement instanceof HTMLTextAreaElement\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n if (ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n return;\n }\n if (newValue !== oldValue) {\n oldElement.value = newValue;\n }\n if (\n oldElement.firstChild &&\n oldElement.firstChild.nodeValue !== newValue\n ) {\n oldElement.firstChild.nodeValue = newValue;\n }\n }\n }\n\n /**\n * @param {Element} oldElement element to write the value to\n * @param {Element} newElement element to read the value from\n * @param {string} attributeName the attribute name\n * @param {MorphContext} ctx the merge context\n */\n function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n const newLiveValue = newElement[attributeName],\n // @ts-ignore ditto\n oldLiveValue = oldElement[attributeName];\n if (newLiveValue !== oldLiveValue) {\n const ignoreUpdate = ignoreAttribute(\n attributeName,\n oldElement,\n \"update\",\n ctx,\n );\n if (!ignoreUpdate) {\n // update attribute's associated DOM property\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n oldElement[attributeName] = newElement[attributeName];\n }\n if (newLiveValue) {\n if (!ignoreUpdate) {\n // https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML\n // this is the correct way to set a boolean attribute to \"true\"\n oldElement.setAttribute(attributeName, \"\");\n }\n } else {\n if (!ignoreAttribute(attributeName, oldElement, \"remove\", ctx)) {\n oldElement.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * @param {string} attr the attribute to be mutated\n * @param {Element} element the element that is going to be updated\n * @param {\"update\" | \"remove\"} updateType\n * @param {MorphContext} ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, element, updateType, ctx) {\n if (\n attr === \"value\" &&\n ctx.ignoreActiveValue &&\n element === document.activeElement\n ) {\n return true;\n }\n return (\n ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) ===\n false\n );\n }\n\n /**\n * @param {Node} possibleActiveElement\n * @param {MorphContext} ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return (\n !!ctx.ignoreActiveValue &&\n possibleActiveElement === document.activeElement &&\n possibleActiveElement !== document.body\n );\n }\n\n return morphNode;\n })();\n\n //=============================================================================\n // Head Management Functions\n //=============================================================================\n /**\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @param {function} callback\n * @returns {Node[] | Promise<Node[]>}\n */\n function withHeadBlocking(ctx, oldNode, newNode, callback) {\n if (ctx.head.block) {\n const oldHead = oldNode.querySelector(\"head\");\n const newHead = newNode.querySelector(\"head\");\n if (oldHead && newHead) {\n const promises = handleHeadElement(oldHead, newHead, ctx);\n // when head promises resolve, proceed ignoring the head tag\n return Promise.all(promises).then(() => {\n const newCtx = Object.assign(ctx, {\n head: {\n block: false,\n ignore: true,\n },\n });\n return callback(newCtx);\n });\n }\n }\n // just proceed if we not head blocking\n return callback(ctx);\n }\n\n /**\n * The HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n *\n * @param {Element} oldHead\n * @param {Element} newHead\n * @param {MorphContext} ctx\n * @returns {Promise<void>[]}\n */\n function handleHeadElement(oldHead, newHead, ctx) {\n let added = [];\n let removed = [];\n let preserved = [];\n let nodesToAppend = [];\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHead.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of oldHead.children) {\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (ctx.head.style === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n // TODO: This could theoretically be null, based on type\n let newElt = /** @type {ChildNode} */ (\n document.createRange().createContextualFragment(newNode.outerHTML)\n .firstChild\n );\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (\n (\"href\" in newElt && newElt.href) ||\n (\"src\" in newElt && newElt.src)\n ) {\n /** @type {(result?: any) => void} */ let resolve;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener(\"load\", function () {\n resolve();\n });\n promises.push(promise);\n }\n oldHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n oldHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(oldHead, {\n added: added,\n kept: preserved,\n removed: removed,\n });\n return promises;\n }\n\n //=============================================================================\n // Create Morph Context Functions\n //=============================================================================\n const createMorphContext = (function () {\n /**\n *\n * @param {Element} oldNode\n * @param {Element} newContent\n * @param {Config} config\n * @returns {MorphContext}\n */\n function createMorphContext(oldNode, newContent, config) {\n const { persistentIds, idMap } = createIdMaps(oldNode, newContent);\n\n const mergedConfig = mergeDefaults(config);\n const morphStyle = mergedConfig.morphStyle || \"outerHTML\";\n if (![\"innerHTML\", \"outerHTML\"].includes(morphStyle)) {\n throw `Do not understand how to morph style ${morphStyle}`;\n }\n\n return {\n target: oldNode,\n newContent: newContent,\n config: mergedConfig,\n morphStyle: morphStyle,\n ignoreActive: mergedConfig.ignoreActive,\n ignoreActiveValue: mergedConfig.ignoreActiveValue,\n restoreFocus: mergedConfig.restoreFocus,\n idMap: idMap,\n persistentIds: persistentIds,\n pantry: createPantry(),\n callbacks: mergedConfig.callbacks,\n head: mergedConfig.head,\n };\n }\n\n /**\n * Deep merges the config object and the Idiomorph.defaults object to\n * produce a final configuration object\n * @param {Config} config\n * @returns {ConfigInternal}\n */\n function mergeDefaults(config) {\n let finalConfig = Object.assign({}, defaults);\n\n // copy top level stuff into final config\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = Object.assign(\n {},\n defaults.callbacks,\n config.callbacks,\n );\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = Object.assign({}, defaults.head, config.head);\n\n return finalConfig;\n }\n\n /**\n * @returns {HTMLDivElement}\n */\n function createPantry() {\n const pantry = document.createElement(\"div\");\n pantry.hidden = true;\n document.body.insertAdjacentElement(\"afterend\", pantry);\n return pantry;\n }\n\n /**\n * Returns all elements with an ID contained within the root element and its descendants\n *\n * @param {Element} root\n * @returns {Element[]}\n */\n function findIdElements(root) {\n let elements = Array.from(root.querySelectorAll(\"[id]\"));\n if (root.id) {\n elements.push(root);\n }\n return elements;\n }\n\n /**\n * A bottom-up algorithm that populates a map of Element -> IdSet.\n * The idSet for a given element is the set of all IDs contained within its subtree.\n * As an optimzation, we filter these IDs through the given list of persistent IDs,\n * because we don't need to bother considering IDed elements that won't be in the new content.\n *\n * @param {Map<Node, Set<string>>} idMap\n * @param {Set<string>} persistentIds\n * @param {Element} root\n * @param {Element[]} elements\n */\n function populateIdMapWithTree(idMap, persistentIds, root, elements) {\n for (const elt of elements) {\n if (persistentIds.has(elt.id)) {\n /** @type {Element|null} */\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n\n if (current === root) break;\n current = current.parentElement;\n }\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {IdSets}\n */\n function createIdMaps(oldContent, newContent) {\n const oldIdElements = findIdElements(oldContent);\n const newIdElements = findIdElements(newContent);\n\n const persistentIds = createPersistentIds(oldIdElements, newIdElements);\n\n /** @type {Map<Node, Set<string>>} */\n let idMap = new Map();\n populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);\n\n /** @ts-ignore - if newContent is a duck-typed parent, pass its single child node as the root to halt upwards iteration */\n const newRoot = newContent.__idiomorphRoot || newContent;\n populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements);\n\n return { persistentIds, idMap };\n }\n\n /**\n * This function computes the set of ids that persist between the two contents excluding duplicates\n *\n * @param {Element[]} oldIdElements\n * @param {Element[]} newIdElements\n * @returns {Set<string>}\n */\n function createPersistentIds(oldIdElements, newIdElements) {\n let duplicateIds = new Set();\n\n /** @type {Map<string, string>} */\n let oldIdTagNameMap = new Map();\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id);\n } else {\n oldIdTagNameMap.set(id, tagName);\n }\n }\n\n let persistentIds = new Set();\n for (const { id, tagName } of newIdElements) {\n if (persistentIds.has(id)) {\n duplicateIds.add(id);\n } else if (oldIdTagNameMap.get(id) === tagName) {\n persistentIds.add(id);\n }\n // skip if tag types mismatch because its not possible to morph one tag into another\n }\n\n for (const id of duplicateIds) {\n persistentIds.delete(id);\n }\n return persistentIds;\n }\n\n return createMorphContext;\n })();\n\n //=============================================================================\n // HTML Normalization Functions\n //=============================================================================\n const { normalizeElement, normalizeParent } = (function () {\n /** @type {WeakSet<Node>} */\n const generatedByIdiomorph = new WeakSet();\n\n /**\n *\n * @param {Element | Document} content\n * @returns {Element}\n */\n function normalizeElement(content) {\n if (content instanceof Document) {\n return content.documentElement;\n } else {\n return content;\n }\n }\n\n /**\n *\n * @param {null | string | Node | HTMLCollection | Node[] | Document & {generatedByIdiomorph:boolean}} newContent\n * @returns {Element}\n */\n function normalizeParent(newContent) {\n if (newContent == null) {\n return document.createElement(\"div\"); // dummy parent element\n } else if (typeof newContent === \"string\") {\n return normalizeParent(parseContent(newContent));\n } else if (\n generatedByIdiomorph.has(/** @type {Element} */ (newContent))\n ) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return /** @type {Element} */ (newContent);\n } else if (newContent instanceof Node) {\n if (newContent.parentNode) {\n // we can't use the parent directly because newContent may have siblings\n // that we don't want in the morph, and reparenting might be expensive (TODO is it?),\n // so we create a duck-typed parent node instead.\n return createDuckTypedParent(newContent);\n } else {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement(\"div\");\n dummyParent.append(newContent);\n return dummyParent;\n }\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement(\"div\");\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n /**\n * Creates a fake duck-typed parent element to wrap a single node, without actually reparenting it.\n * \"If it walks like a duck, and quacks like a duck, then it must be a duck!\" -- James Whitcomb Riley (1849–1916)\n *\n * @param {Node} newContent\n * @returns {Element}\n */\n function createDuckTypedParent(newContent) {\n return /** @type {Element} */ (\n /** @type {unknown} */ ({\n childNodes: [newContent],\n /** @ts-ignore - cover your eyes for a minute, tsc */\n querySelectorAll: (s) => {\n /** @ts-ignore */\n const elements = newContent.querySelectorAll(s);\n /** @ts-ignore */\n return newContent.matches(s) ? [newContent, ...elements] : elements;\n },\n /** @ts-ignore */\n insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r),\n /** @ts-ignore */\n moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r),\n // for later use with populateIdMapWithTree to halt upwards iteration\n get __idiomorphRoot() {\n return newContent;\n },\n })\n );\n }\n\n /**\n *\n * @param {string} newContent\n * @returns {Node | null | DocumentFragment}\n */\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(\n /<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n \"\",\n );\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (\n contentWithSvgsRemoved.match(/<\\/html>/) ||\n contentWithSvgsRemoved.match(/<\\/head>/) ||\n contentWithSvgsRemoved.match(/<\\/body>/)\n ) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n generatedByIdiomorph.add(content);\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n generatedByIdiomorph.add(htmlElement);\n }\n return htmlElement;\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\n \"<body><template>\" + newContent + \"</template></body>\",\n \"text/html\",\n );\n let content = /** @type {HTMLTemplateElement} */ (\n responseDoc.body.querySelector(\"template\")\n ).content;\n generatedByIdiomorph.add(content);\n return content;\n }\n }\n\n return { normalizeElement, normalizeParent };\n })();\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults,\n };\n})();\n\nexport {Idiomorph};\n","\nconst topics: any = {}\nconst _async: any = {}\n\nexport const publish = (name, params) => {\n\t_async[name] = Object.assign({}, _async[name], params)\n\tif (topics[name])\n\t\ttopics[name].forEach(topic => topic(params))\n}\n\nexport const subscribe = (name, method) => {\n\ttopics[name] = topics[name] || []\n\ttopics[name].push(method)\n\tif (name in _async) {\n\t\tmethod(_async[name])\n\t}\n\treturn () => {\n\t\ttopics[name] = topics[name].filter( fn => fn != method )\n\t}\n}\n","import { safe, g, dup } from './utils'\nimport { Idiomorph } from 'idiomorph/dist/idiomorph.esm'\nimport { publish, subscribe } from './utils/pubsub'\n\nexport const Component = ({ name, module, dependencies, node, templates, signal, register }) => {\n\n\tlet tick\n\tlet preserve\t\t= []\n\n\tconst _model \t\t= module.model || {}\n\tconst initialState \t= (new Function( `return ${node.getAttribute('html-model') || '{}'}`))()\n\tconst tplid \t\t= node.getAttribute('tplid')\n\tconst scopeid \t\t= node.getAttribute('html-scopeid')\n\tconst tpl \t\t\t= templates[ tplid ]\n\tconst scope \t\t= g.scope[ scopeid ]\n\tconst model \t\t= dup(module?.model?.apply ? _model({ elm:node, initialState }) : _model)\n\tconst state \t\t= Object.assign({}, scope, model, initialState)\n\tconst view \t\t\t= module.view? module.view : (data) => data\n\n\tconst base = {\n\t\tname,\n\t\tmodel,\n\t\telm: node,\n\t\ttemplate: tpl.template,\n\t\tdependencies,\n\t\tpublish,\n\t\tsubscribe,\n\n\t\tmain(fn) {\n\t\t\tnode.addEventListener(':mount', fn)\n\t\t},\n\n\t\t/**\n\t\t * @State\n\t\t */\n\t\tstate : {\n\n\t\t\tprotected( list ) {\n\t\t\t\tif( list ) {\n\t\t\t\t\tpreserve = list\n\t\t\t\t} else {\n\t\t\t\t\treturn preserve\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tsave(data) {\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata( state )\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tset( data ) {\n\n\t\t\t\tif (!document.body.contains(node)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata(state)\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\n\t\t\t\tconst newstate = Object.assign({}, state, scope)\n\n\t\t\t\treturn new Promise((resolve) => {\n\t\t\t\t\trender(newstate, () => resolve(newstate))\n\t\t\t\t})\n\t\t\t},\n\n\t\t\tget() {\n\t\t\t\treturn Object.assign({}, state)\n\t\t\t}\n\t\t},\n\n\t\tdataset( target, name) {\n\n\t\t\tlet el\n\t\t\tlet key\n\n\t\t\tif( name ) {\n\t\t\t\tel = target\n\t\t\t\tkey = name\n\t\t\t}else {\n\t\t\t\tel = node\n\t\t\t\tkey = target\n\t\t\t}\n\n\t\t\tconst value = el.dataset[key]\n\n\t\t\tif (value === 'true') return true\n\t\t\tif (value === 'false') return false\n\t\t\tif (!isNaN(value) && value.trim() !== '') return Number(value)\n\n\t\t\ttry {\n\t\t\t\t// If it's not JSON, try parsing as JS expression\n\t\t\t\treturn new Function('return (' + value + ')')()\n\t\t\t} catch {}\n\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value)\n\t\t\t} catch {}\n\n\t\t\treturn value\n\t\t},\n\n\t\t/**\n\t\t * @Events\n\t\t */\n\t\ton( ev, selectorOrCallback, callback ) {\n\n\t\t\tif( callback ) {\n\t\t\t\tcallback.handler = (e) => {\n\t\t\t\t\tconst detail = e.detail || {}\n\t\t\t\t\tlet parent = e.target\n\t\t\t\t\twhile (parent) {\n\t\t\t\t\t\tif (parent.matches(selectorOrCallback)) {\n\t\t\t\t\t\t\te.delegateTarget = parent\n\t\t\t\t\t\t\tcallback.apply(node, [e].concat(detail.args))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parent === node) break\n\t\t\t\t\t\tparent = parent.parentNode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, callback.handler, {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: (ev == 'focus' || ev == 'blur' || ev == 'mouseenter' || ev == 'mouseleave')\n\t\t\t\t})\n\n\t\t\t} else {\n\t\t\t\tselectorOrCallback.handler = (e) => {\n\t\t\t\t\te.delegateTarget = node\n\t\t\t\t\tselectorOrCallback.apply(node, [e].concat(e.detail.args))\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, selectorOrCallback.handler, { signal })\n\t\t\t}\n\n\t\t},\n\n\t\toff( ev, callback ) {\n\t\t\tif( callback.handler ) {\n\t\t\t\tnode.removeEventListener(ev, callback.handler)\n\t\t\t}\n\t\t},\n\n\t\ttrigger(ev, selectorOrCallback, data) {\n\t\t\tif( selectorOrCallback.constructor === String ) {\n\t\t\t\tArray\n\t\t\t\t\t.from(node.querySelectorAll(selectorOrCallback))\n\t\t\t\t\t.forEach( children => {\n\t\t\t\t\t\tchildren.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }) )\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail:{ args: data } }))\n\t\t\t}\n\t\t},\n\n\t\temit(ev, data) {\n\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }))\n\t\t},\n\n\t\tunmount( fn ) {\n\t\t\tnode.addEventListener(':unmount', fn)\n\t\t},\n\n\t\tinnerHTML ( target, html_ ) {\n\t\t\tconst element = html_? target : node\n\t\t\tconst clone = element.cloneNode()\n\t\t\tconst html = html_? html_ : target\n\t\t\tclone.innerHTML = html\n\t\t\tIdiomorph.morph(element, clone)\n\t\t}\n\t}\n\n\tconst render = ( data, callback = (() => {}) ) => {\n\t\tclearTimeout( tick )\n\t\ttick = setTimeout(() => {\n\t\t\tconst html = tpl.render.call({...data, ...view(data)}, node, safe, g )\n\t\t\tIdiomorph.morph( node, html, IdiomorphOptions(node, register) )\n\t\t\tPromise.resolve().then(() => {\n\t\t\t\tnode.querySelectorAll('[tplid]')\n\t\t\t\t\t.forEach((element) => {\n\t\t\t\t\t\tconst child = register.get(element)\n\t\t\t\t\t\tif(!child) return\n\t\t\t\t\t\tchild.state.protected().forEach( key => delete data[key] )\n\t\t\t\t\t\tchild.state.set(data)\n\t\t\t\t\t})\n\t\t\t\tPromise.resolve().then(() => {\n\t\t\t\t\tg.scope = {}\n\t\t\t\t\tcallback()\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\trender( state )\n\tregister.set( node, base )\n\treturn module.default( base )\n}\n\nconst IdiomorphOptions = ( parent, register ) => ({\n\tcallbacks: {\n\t\tbeforeNodeMorphed( node ) {\n\t\t\tif( node.nodeType === 1 ) {\n\t\t\t\tif( 'html-static' in node.attributes ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif( register.get(node) && node !== parent ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n})\n","import { Component } from './component'\n\nconst register = new WeakMap()\n\nexport const Element = ({ component, templates, start }) => {\n\n\tconst { name, module, dependencies } = component\n\n\treturn class extends HTMLElement {\n\n\t\tconstructor() {\n\t\t\tsuper()\n\t\t}\n\n\t\tconnectedCallback() {\n\n\t\t\tthis.abortController = new AbortController()\n\n\t\t\tif( !this.getAttribute('tplid') ) {\n\t\t\t\tstart( this.parentNode )\n\t\t\t}\n\n\t\t\tconst rtrn = Component({\n\t\t\t\tnode:this,\n\t\t\t\tname,\n\t\t\t\tmodule,\n\t\t\t\tdependencies,\n\t\t\t\ttemplates,\n\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\tregister\n\t\t\t})\n\n\t\t\tif ( rtrn && rtrn.constructor === Promise ) {\n\t\t\t\trtrn.then(() => {\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t}\n\t\t}\n\n\t\tdisconnectedCallback() {\n\t\t\tthis.dispatchEvent( new CustomEvent(':unmount') )\n\t\t\tthis.abortController.abort()\n\t\t}\n\t}\n}\n","import { uuid, decodeHTML } from './utils'\n\nconst templates = {}\n\nconst config = {\n\ttags: ['{{', '}}']\n}\n\nexport const templateConfig = (newconfig) => {\n\tObject.assign( config, newconfig )\n}\n\nexport const template = ( target, { components }) => {\n\n\ttagElements( target, [...Object.keys( components ), '[html-if]', 'template'], components )\n\tconst clone = target.cloneNode( true )\n\n\ttransformTemplate( clone )\n\tremoveTemplateTagsRecursively( clone )\n\tsetTemplates( clone, components )\n\n\treturn templates\n}\n\nexport const compile = ( html ) => {\n\n\tconst parsedHtml = JSON.stringify( html )\n\n\treturn new Function('$element', 'safe', '$g',`\n\t\tvar $data = this;\n\t\twith( $data ){\n\t\t\tvar output=${parsedHtml\n\t\t\t\t.replace(/%%_=(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\"+safe(function(){return '+ decodeHTML(variable) +';})+\"'\n\t\t\t\t})\n\t\t\t\t.replace(/%%_(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\";' + decodeHTML(variable) +'\\noutput+=\"'\n\t\t\t\t})};return output;\n\t\t}\n\t`)\n}\n\nconst tagElements = ( target, keys, components ) => {\n\ttarget\n\t\t.querySelectorAll( keys.toString() )\n\t\t.forEach((node) => {\n\t\t\tconst name = node.localName\n\t\t\tif( name === 'template' ) {\n\t\t\t\treturn tagElements( node.content, keys, components )\n\t\t\t}\n\t\t\tif( node.getAttribute('html-if') && !node.id ) {\n\t\t\t\tnode.id = uuid()\n\t\t\t}\n\t\t\tif( name in components ) {\n\t\t\t\tnode.setAttribute('tplid', uuid())\n\t\t\t}\n\t\t})\n}\n\nconst transformAttributes = ( html ) => {\n\n\tconst regexTags = new RegExp(`\\\\${config.tags[0]}(.+?)\\\\${config.tags[1]}`, 'g')\n\n\treturn html\n\t\t.replace(/jails___scope-id/g, '%%_=$scopeid_%%')\n\t\t.replace(regexTags, '%%_=$1_%%')\n\t\t// Booleans\n\t\t// https://meiert.com/en/blog/boolean-attributes-of-html/\n\t\t.replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\\\"(.*?)\\\"/g, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`)\n\t\t// The rest\n\t\t.replace(/html-([^\\s]*?)=\\\"(.*?)\\\"/g, (all, key, value) => {\n\t\t\tif (key === 'key' || key === 'model' || key === 'scopeid' ) {\n\t\t\t\treturn all\n\t\t\t}\n\t\t\tif (value) {\n\t\t\t\tvalue = value.replace(/^{|}$/g, '')\n\t\t\t\treturn `${key}=\"%%_=safe(function(){ return ${value} })_%%\"`\n\t\t\t} else {\n\t\t\t\treturn all\n\t\t\t}\n\t\t})\n}\n\nconst transformTemplate = ( clone ) => {\n\n\tclone.querySelectorAll('template, [html-for], [html-if], [html-inner], [html-class]')\n\t\t.forEach(( element ) => {\n\n\t\t\tconst htmlFor \t= element.getAttribute('html-for')\n\t\t\tconst htmlIf \t= element.getAttribute('html-if')\n\t\t\tconst htmlInner = element.getAttribute('html-inner')\n\t\t\tconst htmlClass = element.getAttribute('html-class')\n\n\t\t\tif ( htmlFor ) {\n\n\t\t\t\telement.removeAttribute('html-for')\n\n\t\t\t\tconst split \t = htmlFor.match(/(.*)\\sin\\s(.*)/) || ''\n\t\t\t\tconst varname \t = split[1]\n\t\t\t\tconst object \t = split[2]\n\t\t\t\tconst objectname = object.split(/\\./).shift()\n\t\t\t\tconst open \t\t = document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${object} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${varname} = ${object}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${objectname}: ${objectname} }, { ${varname} :${varname}, $index: $index, $key: $key }); _%%`)\n\t\t\t\tconst close \t = document.createTextNode(`%%_ $index++; } })() _%%`)\n\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlIf) {\n\t\t\t\telement.removeAttribute('html-if')\n\t\t\t\tconst open = document.createTextNode(`%%_ if ( safe(function(){ return ${htmlIf} }) ){ _%%`)\n\t\t\t\tconst close = document.createTextNode(`%%_ } _%%`)\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlInner) {\n\t\t\t\telement.removeAttribute('html-inner')\n\t\t\t\telement.innerHTML = `%%_=${htmlInner}_%%`\n\t\t\t}\n\n\t\t\tif (htmlClass) {\n\t\t\t\telement.removeAttribute('html-class')\n\t\t\t\telement.className = (element.className + ` %%_=${htmlClass}_%%`).trim()\n\t\t\t}\n\n\t\t\tif( element.localName === 'template' ) {\n\t\t\t\ttransformTemplate(element.content)\n\t\t\t}\n\t\t})\n}\n\nconst setTemplates = ( clone, components ) => {\n\n\tArray.from(clone.querySelectorAll('[tplid]'))\n\t\t.reverse()\n\t\t.forEach((node) => {\n\n\t\t\tconst tplid = node.getAttribute('tplid')\n\t\t\tconst name = node.localName\n\t\t\tnode.setAttribute('html-scopeid', 'jails___scope-id')\n\n\t\t\tif( name in components && components[name].module.template ) {\n\t\t\t\tconst children = node.innerHTML\n\t\t\t\tconst html = components[name].module.template({ elm:node, children })\n\t\t\t\tnode.innerHTML = html\n\t\t\t}\n\n\t\t\tconst html = transformAttributes(node.outerHTML)\n\n\t\t\ttemplates[ tplid ] = {\n\t\t\t\ttemplate: html,\n\t\t\t\trender\t: compile(html)\n\t\t\t}\n\t\t})\n}\n\nconst removeTemplateTagsRecursively = (node) => {\n\n\t// Get all <template> elements within the node\n\tconst templates = node.querySelectorAll('template')\n\n\ttemplates.forEach((template) => {\n\n\t\tif( template.getAttribute('html-if') || template.getAttribute('html-inner') ) {\n\t\t\treturn\n\t\t}\n\n\t\t// Process any nested <template> tags within this <template> first\n\t\tremoveTemplateTagsRecursively(template.content)\n\n\t\t// Get the parent of the <template> tag\n\t\tconst parent = template.parentNode\n\n\t\tif (parent) {\n\t\t\t// Move all child nodes from the <template>'s content to its parent\n\t\t\tconst content = template.content\n\t\t\twhile (content.firstChild) {\n\t\t\t\tparent.insertBefore(content.firstChild, template)\n\t\t\t}\n\t\t\t// Remove the <template> tag itself\n\t\t\tparent.removeChild(template)\n\t\t}\n\t})\n}\n\nconst wrap = (open, node, close) => {\n\tnode.parentNode?.insertBefore(open, node)\n\tnode.parentNode?.insertBefore(close, node.nextSibling)\n}\n","\nimport { Element } from './element'\nimport { template, templateConfig as config } from './template-system'\n\nexport { publish, subscribe } from './utils/pubsub'\n\nexport const templateConfig = (options) => {\n\tconfig( options )\n}\n\nwindow.__jails__ = window.__jails__ || { components: {} }\n\nexport const register = ( name, module, dependencies ) => {\n\tconst { components } = window.__jails__\n\tcomponents[ name ] = { name, module, dependencies }\n}\n\nexport const start = ( target = document.body ) => {\n\n\tconst { components } = window.__jails__\n\tconst templates = template( target, { components } )\n\n\tObject\n\t\t.values( components )\n\t\t.forEach(({ name, module, dependencies }) => {\n\t\t\tif( !customElements.get(name) ) {\n\t\t\t\tcustomElements.define( name, Element({ component: { name, module, dependencies }, templates, start }))\n\t\t\t}\n\t})\n}\n\ndeclare global {\n\tinterface Window {\n\t __jails__?: {\n\t\tcomponents: Record<string, any>\n\t }\n\t}\n}\n"],"names":["textarea","document","createElement","g","scope","decodeHTML","text","innerHTML","value","uuid","Math","random","toString","substring","safe","execute","val","err","Idiomorph","noOp","defaults","morphStyle","callbacks","beforeNodeAdded","afterNodeAdded","beforeNodeMorphed","afterNodeMorphed","beforeNodeRemoved","afterNodeRemoved","beforeAttributeUpdated","head","style","shouldPreserve","elt","getAttribute","shouldReAppend","shouldRemove","afterHeadMorphed","restoreFocus","morphChildren","createNode","oldParent","newChild","insertionPoint","ctx","idMap","has","newEmptyChild","tagName","insertBefore","morphNode","newClonedChild","importNode","findBestMatch","isIdSetMatch","oldNode","newNode","oldSet","get","newSet","id","isSoftMatch","oldElt","newElt","nodeType","node","startPoint","endPoint","softMatch","nextSibling","siblingSoftMatchCount","cursor","contains","activeElement","removeNode","moveBefore","pantry","_a","parentNode","removeChild","removeNodesBetween","startInclusive","endExclusive","tempNode","moveBeforeById","after","target","querySelector","element","idSet","delete","size","removeElementFromAncestorsIdMaps","e","newParent","HTMLTemplateElement","content","firstChild","childNodes","bestMatch","Element","persistentIds","movedChild","insertedNode","syncBooleanAttribute","oldElement","newElement","attributeName","newLiveValue","ignoreUpdate","ignoreAttribute","setAttribute","removeAttribute","attr","updateType","ignoreActiveValue","ignoreValueOfActiveElement","possibleActiveElement","body","newContent","ignoreActive","HTMLHeadElement","ignore","handleHeadElement","type","oldAttributes","attributes","newAttributes","newAttribute","name","i","length","oldAttribute","hasAttribute","HTMLInputElement","newValue","oldValue","HTMLOptionElement","HTMLTextAreaElement","nodeValue","syncInputValue","morphAttributes","oldHead","newHead","added","removed","preserved","nodesToAppend","srcToNewHeadNodes","Map","newHeadChild","children","set","outerHTML","currentHeadElt","inNewContent","isReAppended","isPreserved","push","values","promises","createRange","createContextualFragment","href","src","resolve","promise","Promise","_resolve","addEventListener","appendChild","removedElement","kept","createMorphContext","createPantry","hidden","insertAdjacentElement","findIdElements","root","elements","Array","from","querySelectorAll","populateIdMapWithTree","current","Set","add","parentElement","config","oldContent","oldIdElements","newIdElements","duplicateIds","oldIdTagNameMap","createPersistentIds","newRoot","__idiomorphRoot","createIdMaps","mergedConfig","finalConfig","Object","assign","mergeDefaults","includes","normalizeElement","normalizeParent","generatedByIdiomorph","WeakSet","Document","documentElement","parser","DOMParser","contentWithSvgsRemoved","replace","match","parseFromString","htmlElement","parseContent","Node","s","matches","n","r","createDuckTypedParent","dummyParent","append","morph","morphedNodes","fn","activeElementId","selectionStart","selectionEnd","results","focus","setSelectionRange","saveAndRestoreFocus","callback","block","all","then","newCtx","withHeadBlocking","index","indexOf","rightMargin","slice","morphOuterHTML","remove","topics","_async","publish","params","forEach","topic","subscribe","method","filter","Component","module","dependencies","templates","signal","register","tick","preserve","_model","model","initialState","Function","tplid","scopeid","tpl","o","apply","elm","JSON","parse","stringify","state","view","data","base","template","main","protected","list","save","constructor","newstate","render","dataset","el","key","isNaN","trim","Number","on","ev","selectorOrCallback","handler","detail","parent","delegateTarget","concat","args","capture","off","removeEventListener","trigger","String","dispatchEvent","CustomEvent","bubbles","emit","unmount","html_","clone","cloneNode","html","clearTimeout","setTimeout","call","__spreadValues","IdiomorphOptions","child","default","WeakMap","component","start","HTMLElement","super","connectedCallback","this","abortController","AbortController","rtrn","disconnectedCallback","abort","tags","compile","parsedHtml","_","variable","tagElements","keys","components","localName","transformTemplate","htmlFor","htmlIf","htmlInner","htmlClass","split","varname","object","objectname","shift","open","createTextNode","close","wrap","className","setTemplates","reverse","regexTags","RegExp","transformAttributes","removeTemplateTagsRecursively","_b","window","__jails__","customElements","define","options","newconfig"],"mappings":"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","x_google_ignoreList":[1]}
1
+ {"version":3,"file":"jails.js","sources":["../src/utils/index.ts","../node_modules/idiomorph/dist/idiomorph.esm.js","../src/utils/pubsub.ts","../src/component.ts","../src/element.ts","../src/template-system.ts","../src/index.ts"],"sourcesContent":["\nconst textarea = document.createElement('textarea')\n\nexport const g = {\n\tscope: {}\n}\n\nexport const decodeHTML = (text) => {\n\ttextarea.innerHTML = text\n\treturn textarea.value\n}\n\nexport const rAF = (fn) => {\n\tif (requestAnimationFrame)\n\t\treturn requestAnimationFrame(fn)\n\telse\n\t\treturn setTimeout(fn, 1000 / 60)\n}\n\nexport const uuid = () => {\n\treturn Math.random().toString(36).substring(2, 9)\n}\n\nexport const dup = (o) => {\n\treturn JSON.parse(JSON.stringify(o))\n}\n\nexport const safe = (execute, val) => {\n\ttry{\n\t\treturn execute()\n\t}catch(err){\n\t\treturn val || ''\n\t}\n}\n","/**\n * @typedef {object} ConfigHead\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} [style]\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {function(Element): boolean} [shouldPreserve]\n * @property {function(Element): boolean} [shouldReAppend]\n * @property {function(Element): boolean} [shouldRemove]\n * @property {function(Element, {added: Node[], kept: Element[], removed: Element[]}): void} [afterHeadMorphed]\n */\n\n/**\n * @typedef {object} ConfigCallbacks\n *\n * @property {function(Node): boolean} [beforeNodeAdded]\n * @property {function(Node): void} [afterNodeAdded]\n * @property {function(Element, Node): boolean} [beforeNodeMorphed]\n * @property {function(Element, Node): void} [afterNodeMorphed]\n * @property {function(Element): boolean} [beforeNodeRemoved]\n * @property {function(Element): void} [afterNodeRemoved]\n * @property {function(string, Element, \"update\" | \"remove\"): boolean} [beforeAttributeUpdated]\n */\n\n/**\n * @typedef {object} Config\n *\n * @property {'outerHTML' | 'innerHTML'} [morphStyle]\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacks} [callbacks]\n * @property {ConfigHead} [head]\n */\n\n/**\n * @typedef {function} NoOp\n *\n * @returns {void}\n */\n\n/**\n * @typedef {object} ConfigHeadInternal\n *\n * @property {'merge' | 'append' | 'morph' | 'none'} style\n * @property {boolean} [block]\n * @property {boolean} [ignore]\n * @property {(function(Element): boolean) | NoOp} shouldPreserve\n * @property {(function(Element): boolean) | NoOp} shouldReAppend\n * @property {(function(Element): boolean) | NoOp} shouldRemove\n * @property {(function(Element, {added: Node[], kept: Element[], removed: Element[]}): void) | NoOp} afterHeadMorphed\n */\n\n/**\n * @typedef {object} ConfigCallbacksInternal\n *\n * @property {(function(Node): boolean) | NoOp} beforeNodeAdded\n * @property {(function(Node): void) | NoOp} afterNodeAdded\n * @property {(function(Node, Node): boolean) | NoOp} beforeNodeMorphed\n * @property {(function(Node, Node): void) | NoOp} afterNodeMorphed\n * @property {(function(Node): boolean) | NoOp} beforeNodeRemoved\n * @property {(function(Node): void) | NoOp} afterNodeRemoved\n * @property {(function(string, Element, \"update\" | \"remove\"): boolean) | NoOp} beforeAttributeUpdated\n */\n\n/**\n * @typedef {object} ConfigInternal\n *\n * @property {'outerHTML' | 'innerHTML'} morphStyle\n * @property {boolean} [ignoreActive]\n * @property {boolean} [ignoreActiveValue]\n * @property {boolean} [restoreFocus]\n * @property {ConfigCallbacksInternal} callbacks\n * @property {ConfigHeadInternal} head\n */\n\n/**\n * @typedef {Object} IdSets\n * @property {Set<string>} persistentIds\n * @property {Map<Node, Set<string>>} idMap\n */\n\n/**\n * @typedef {Function} Morph\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {undefined | Node[]}\n */\n\n// base IIFE to define idiomorph\n/**\n *\n * @type {{defaults: ConfigInternal, morph: Morph}}\n */\nvar Idiomorph = (function () {\n \"use strict\";\n\n /**\n * @typedef {object} MorphContext\n *\n * @property {Element} target\n * @property {Element} newContent\n * @property {ConfigInternal} config\n * @property {ConfigInternal['morphStyle']} morphStyle\n * @property {ConfigInternal['ignoreActive']} ignoreActive\n * @property {ConfigInternal['ignoreActiveValue']} ignoreActiveValue\n * @property {ConfigInternal['restoreFocus']} restoreFocus\n * @property {Map<Node, Set<string>>} idMap\n * @property {Set<string>} persistentIds\n * @property {ConfigInternal['callbacks']} callbacks\n * @property {ConfigInternal['head']} head\n * @property {HTMLDivElement} pantry\n */\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n\n const noOp = () => {};\n /**\n * Default configuration values, updatable by users now\n * @type {ConfigInternal}\n */\n const defaults = {\n morphStyle: \"outerHTML\",\n callbacks: {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n },\n head: {\n style: \"merge\",\n shouldPreserve: (elt) => elt.getAttribute(\"im-preserve\") === \"true\",\n shouldReAppend: (elt) => elt.getAttribute(\"im-re-append\") === \"true\",\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n },\n restoreFocus: true,\n };\n\n /**\n * Core idiomorph function for morphing one DOM tree to another\n *\n * @param {Element | Document} oldNode\n * @param {Element | Node | HTMLCollection | Node[] | string | null} newContent\n * @param {Config} [config]\n * @returns {Promise<Node[]> | Node[]}\n */\n function morph(oldNode, newContent, config = {}) {\n oldNode = normalizeElement(oldNode);\n const newNode = normalizeParent(newContent);\n const ctx = createMorphContext(oldNode, newNode, config);\n\n const morphedNodes = saveAndRestoreFocus(ctx, () => {\n return withHeadBlocking(\n ctx,\n oldNode,\n newNode,\n /** @param {MorphContext} ctx */ (ctx) => {\n if (ctx.morphStyle === \"innerHTML\") {\n morphChildren(ctx, oldNode, newNode);\n return Array.from(oldNode.childNodes);\n } else {\n return morphOuterHTML(ctx, oldNode, newNode);\n }\n },\n );\n });\n\n ctx.pantry.remove();\n return morphedNodes;\n }\n\n /**\n * Morph just the outerHTML of the oldNode to the newContent\n * We have to be careful because the oldNode could have siblings which need to be untouched\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @returns {Node[]}\n */\n function morphOuterHTML(ctx, oldNode, newNode) {\n const oldParent = normalizeParent(oldNode);\n\n // basis for calulating which nodes were morphed\n // since there may be unmorphed sibling nodes\n let childNodes = Array.from(oldParent.childNodes);\n const index = childNodes.indexOf(oldNode);\n // how many elements are to the right of the oldNode\n const rightMargin = childNodes.length - (index + 1);\n\n morphChildren(\n ctx,\n oldParent,\n newNode,\n // these two optional params are the secret sauce\n oldNode, // start point for iteration\n oldNode.nextSibling, // end point for iteration\n );\n\n // return just the morphed nodes\n childNodes = Array.from(oldParent.childNodes);\n return childNodes.slice(index, childNodes.length - rightMargin);\n }\n\n /**\n * @param {MorphContext} ctx\n * @param {Function} fn\n * @returns {Promise<Node[]> | Node[]}\n */\n function saveAndRestoreFocus(ctx, fn) {\n if (!ctx.config.restoreFocus) return fn();\n let activeElement =\n /** @type {HTMLInputElement|HTMLTextAreaElement|null} */ (\n document.activeElement\n );\n\n // don't bother if the active element is not an input or textarea\n if (\n !(\n activeElement instanceof HTMLInputElement ||\n activeElement instanceof HTMLTextAreaElement\n )\n ) {\n return fn();\n }\n\n const { id: activeElementId, selectionStart, selectionEnd } = activeElement;\n\n const results = fn();\n\n if (activeElementId && activeElementId !== document.activeElement?.id) {\n activeElement = ctx.target.querySelector(`#${activeElementId}`);\n activeElement?.focus();\n }\n if (activeElement && !activeElement.selectionEnd && selectionEnd) {\n activeElement.setSelectionRange(selectionStart, selectionEnd);\n }\n\n return results;\n }\n\n const morphChildren = (function () {\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm:\n * - for each node in the new content:\n * - search self and siblings for an id set match, falling back to a soft match\n * - if match found\n * - remove any nodes up to the match:\n * - pantry persistent nodes\n * - delete the rest\n * - morph the match\n * - elsif no match found, and node is persistent\n * - find its match by querying the old root (future) and pantry (past)\n * - move it and its children here\n * - morph it\n * - else\n * - create a new node from scratch as a last result\n *\n * @param {MorphContext} ctx the merge context\n * @param {Element} oldParent the old content that we are merging the new content into\n * @param {Element} newParent the parent element of the new content\n * @param {Node|null} [insertionPoint] the point in the DOM we start morphing at (defaults to first child)\n * @param {Node|null} [endPoint] the point in the DOM we stop morphing at (defaults to after last child)\n */\n function morphChildren(\n ctx,\n oldParent,\n newParent,\n insertionPoint = null,\n endPoint = null,\n ) {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // @ts-ignore we can pretend the DocumentFragment is an Element\n oldParent = oldParent.content;\n // @ts-ignore ditto\n newParent = newParent.content;\n }\n insertionPoint ||= oldParent.firstChild;\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint != endPoint) {\n const bestMatch = findBestMatch(\n ctx,\n newChild,\n insertionPoint,\n endPoint,\n );\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n removeNodesBetween(ctx, insertionPoint, bestMatch);\n }\n morphNode(bestMatch, newChild, ctx);\n insertionPoint = bestMatch.nextSibling;\n continue;\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctx.persistentIds.has(newChild.id)) {\n // move it and all its children here and morph\n const movedChild = moveBeforeById(\n oldParent,\n newChild.id,\n insertionPoint,\n ctx,\n );\n morphNode(movedChild, newChild, ctx);\n insertionPoint = movedChild.nextSibling;\n continue;\n }\n\n // last resort: insert the new node from scratch\n const insertedNode = createNode(\n oldParent,\n newChild,\n insertionPoint,\n ctx,\n );\n // could be null if beforeNodeAdded prevented insertion\n if (insertedNode) {\n insertionPoint = insertedNode.nextSibling;\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint != endPoint) {\n const tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(ctx, tempNode);\n }\n }\n\n /**\n * This performs the action of inserting a new node while handling situations where the node contains\n * elements with persistent ids and possible state info we can still preserve by moving in and then morphing\n *\n * @param {Element} oldParent\n * @param {Node} newChild\n * @param {Node|null} insertionPoint\n * @param {MorphContext} ctx\n * @returns {Node|null}\n */\n function createNode(oldParent, newChild, insertionPoint, ctx) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;\n if (ctx.idMap.has(newChild)) {\n // node has children with ids with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n /** @type {Element} */ (newChild).tagName,\n );\n oldParent.insertBefore(newEmptyChild, insertionPoint);\n morphNode(newEmptyChild, newChild, ctx);\n ctx.callbacks.afterNodeAdded(newEmptyChild);\n return newEmptyChild;\n } else {\n // optimisation: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true); // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newClonedChild);\n return newClonedChild;\n }\n }\n\n //=============================================================================\n // Matching Functions\n //=============================================================================\n const findBestMatch = (function () {\n /**\n * Scans forward from the startPoint to the endPoint looking for a match\n * for the node. It looks for an id set match first, then a soft match.\n * We abort softmatching if we find two future soft matches, to reduce churn.\n * @param {Node} node\n * @param {MorphContext} ctx\n * @param {Node | null} startPoint\n * @param {Node | null} endPoint\n * @returns {Node | null}\n */\n function findBestMatch(ctx, node, startPoint, endPoint) {\n let softMatch = null;\n let nextSibling = node.nextSibling;\n let siblingSoftMatchCount = 0;\n\n let cursor = startPoint;\n while (cursor && cursor != endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n if (isIdSetMatch(ctx, cursor, node)) {\n return cursor; // found an id set match, we're done!\n }\n\n // we haven't yet saved a soft match fallback\n if (softMatch === null) {\n // the current soft match will hard match something else in the future, leave it\n if (!ctx.idMap.has(cursor)) {\n // save this as the fallback if we get through the loop without finding a hard match\n softMatch = cursor;\n }\n }\n }\n if (\n softMatch === null &&\n nextSibling &&\n isSoftMatch(cursor, nextSibling)\n ) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n softMatch = undefined;\n }\n }\n\n // if the current node contains active element, stop looking for better future matches,\n // because if one is found, this node will be moved to the pantry, reparenting it and thus losing focus\n if (cursor.contains(document.activeElement)) break;\n\n cursor = cursor.nextSibling;\n }\n\n return softMatch || null;\n }\n\n /**\n *\n * @param {MorphContext} ctx\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isIdSetMatch(ctx, oldNode, newNode) {\n let oldSet = ctx.idMap.get(oldNode);\n let newSet = ctx.idMap.get(newNode);\n\n if (!newSet || !oldSet) return false;\n\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n *\n * @param {Node} oldNode\n * @param {Node} newNode\n * @returns {boolean}\n */\n function isSoftMatch(oldNode, newNode) {\n // ok to cast: if one is not element, `id` and `tagName` will be undefined and we'll just compare that.\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n return (\n oldElt.nodeType === newElt.nodeType &&\n oldElt.tagName === newElt.tagName &&\n // If oldElt has an `id` with possible state and it doesn't match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!oldElt.id || oldElt.id === newElt.id)\n );\n }\n\n return findBestMatch;\n })();\n\n //=============================================================================\n // DOM Manipulation Functions\n //=============================================================================\n\n /**\n * Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n * - Persistent nodes will be moved to the pantry for later reuse\n * - Other nodes will have their hooks called, and then are removed\n * @param {MorphContext} ctx\n * @param {Node} node\n */\n function removeNode(ctx, node) {\n // are we going to id set match this later?\n if (ctx.idMap.has(node)) {\n // skip callbacks and move to pantry\n moveBefore(ctx.pantry, node, null);\n } else {\n // remove for realsies\n if (ctx.callbacks.beforeNodeRemoved(node) === false) return;\n node.parentNode?.removeChild(node);\n ctx.callbacks.afterNodeRemoved(node);\n }\n }\n\n /**\n * Remove nodes between the start and end nodes\n * @param {MorphContext} ctx\n * @param {Node} startInclusive\n * @param {Node} endExclusive\n * @returns {Node|null}\n */\n function removeNodesBetween(ctx, startInclusive, endExclusive) {\n /** @type {Node | null} */\n let cursor = startInclusive;\n // remove nodes until the endExclusive node\n while (cursor && cursor !== endExclusive) {\n let tempNode = /** @type {Node} */ (cursor);\n cursor = cursor.nextSibling;\n removeNode(ctx, tempNode);\n }\n return cursor;\n }\n\n /**\n * Search for an element by id within the document and pantry, and move it using moveBefore.\n *\n * @param {Element} parentNode - The parent node to which the element will be moved.\n * @param {string} id - The ID of the element to be moved.\n * @param {Node | null} after - The reference node to insert the element before.\n * If `null`, the element is appended as the last child.\n * @param {MorphContext} ctx\n * @returns {Element} The found element\n */\n function moveBeforeById(parentNode, id, after, ctx) {\n const target =\n /** @type {Element} - will always be found */\n (\n ctx.target.querySelector(`#${id}`) ||\n ctx.pantry.querySelector(`#${id}`)\n );\n removeElementFromAncestorsIdMaps(target, ctx);\n moveBefore(parentNode, target, after);\n return target;\n }\n\n /**\n * Removes an element from its ancestors' id maps. This is needed when an element is moved from the\n * \"future\" via `moveBeforeId`. Otherwise, its erstwhile ancestors could be mistakenly moved to the\n * pantry rather than being deleted, preventing their removal hooks from being called.\n *\n * @param {Element} element - element to remove from its ancestors' id maps\n * @param {MorphContext} ctx\n */\n function removeElementFromAncestorsIdMaps(element, ctx) {\n const id = element.id;\n /** @ts-ignore - safe to loop in this way **/\n while ((element = element.parentNode)) {\n let idSet = ctx.idMap.get(element);\n if (idSet) {\n idSet.delete(id);\n if (!idSet.size) {\n ctx.idMap.delete(element);\n }\n }\n }\n }\n\n /**\n * Moves an element before another element within the same parent.\n * Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n * This is essentialy a forward-compat wrapper.\n *\n * @param {Element} parentNode - The parent node containing the after element.\n * @param {Node} element - The element to be moved.\n * @param {Node | null} after - The reference node to insert `element` before.\n * If `null`, `element` is appended as the last child.\n */\n function moveBefore(parentNode, element, after) {\n // @ts-ignore - use proposed moveBefore feature\n if (parentNode.moveBefore) {\n try {\n // @ts-ignore - use proposed moveBefore feature\n parentNode.moveBefore(element, after);\n } catch (e) {\n // fall back to insertBefore as some browsers may fail on moveBefore when trying to move Dom disconnected nodes to pantry\n parentNode.insertBefore(element, after);\n }\n } else {\n parentNode.insertBefore(element, after);\n }\n }\n\n return morphChildren;\n })();\n\n //=============================================================================\n // Single Node Morphing Code\n //=============================================================================\n const morphNode = (function () {\n /**\n * @param {Node} oldNode root node to merge content into\n * @param {Node} newContent new content to merge\n * @param {MorphContext} ctx the merge context\n * @returns {Node | null} the element that ended up in the DOM\n */\n function morphNode(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) {\n // don't morph focused element\n return null;\n }\n\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) {\n return oldNode;\n }\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {\n // ignore the head element\n } else if (\n oldNode instanceof HTMLHeadElement &&\n ctx.head.style !== \"morph\"\n ) {\n // ok to cast: if newContent wasn't also a <head>, it would've got caught in the `!isSoftMatch` branch above\n handleHeadElement(\n oldNode,\n /** @type {HTMLHeadElement} */ (newContent),\n ctx,\n );\n } else {\n morphAttributes(oldNode, newContent, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n // @ts-ignore newContent can be a node here because .firstChild will be null\n morphChildren(ctx, oldNode, newContent);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n\n /**\n * syncs the oldNode to the newNode, copying over all attributes and\n * inner element state from the newNode to the oldNode\n *\n * @param {Node} oldNode the node to copy attributes & state to\n * @param {Node} newNode the node to copy attributes & state from\n * @param {MorphContext} ctx the merge context\n */\n function morphAttributes(oldNode, newNode, ctx) {\n let type = newNode.nodeType;\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = /** @type {Element} */ (oldNode);\n const newElt = /** @type {Element} */ (newNode);\n\n const oldAttributes = oldElt.attributes;\n const newAttributes = newElt.attributes;\n for (const newAttribute of newAttributes) {\n if (ignoreAttribute(newAttribute.name, oldElt, \"update\", ctx)) {\n continue;\n }\n if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) {\n oldElt.setAttribute(newAttribute.name, newAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = oldAttributes.length - 1; 0 <= i; i--) {\n const oldAttribute = oldAttributes[i];\n\n // toAttributes is a live NamedNodeMap, so iteration+mutation is unsafe\n // e.g. custom element attribute callbacks can remove other attributes\n if (!oldAttribute) continue;\n\n if (!newElt.hasAttribute(oldAttribute.name)) {\n if (ignoreAttribute(oldAttribute.name, oldElt, \"remove\", ctx)) {\n continue;\n }\n oldElt.removeAttribute(oldAttribute.name);\n }\n }\n\n if (!ignoreValueOfActiveElement(oldElt, ctx)) {\n syncInputValue(oldElt, newElt, ctx);\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue;\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param {Element} oldElement the element to sync the input value to\n * @param {Element} newElement the element to sync the input value from\n * @param {MorphContext} ctx the merge context\n */\n function syncInputValue(oldElement, newElement, ctx) {\n if (\n oldElement instanceof HTMLInputElement &&\n newElement instanceof HTMLInputElement &&\n newElement.type !== \"file\"\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n\n // sync boolean attributes\n syncBooleanAttribute(oldElement, newElement, \"checked\", ctx);\n syncBooleanAttribute(oldElement, newElement, \"disabled\", ctx);\n\n if (!newElement.hasAttribute(\"value\")) {\n if (!ignoreAttribute(\"value\", oldElement, \"remove\", ctx)) {\n oldElement.value = \"\";\n oldElement.removeAttribute(\"value\");\n }\n } else if (oldValue !== newValue) {\n if (!ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n oldElement.setAttribute(\"value\", newValue);\n oldElement.value = newValue;\n }\n }\n // TODO: QUESTION(1cg): this used to only check `newElement` unlike the other branches -- why?\n // did I break something?\n } else if (\n oldElement instanceof HTMLOptionElement &&\n newElement instanceof HTMLOptionElement\n ) {\n syncBooleanAttribute(oldElement, newElement, \"selected\", ctx);\n } else if (\n oldElement instanceof HTMLTextAreaElement &&\n newElement instanceof HTMLTextAreaElement\n ) {\n let newValue = newElement.value;\n let oldValue = oldElement.value;\n if (ignoreAttribute(\"value\", oldElement, \"update\", ctx)) {\n return;\n }\n if (newValue !== oldValue) {\n oldElement.value = newValue;\n }\n if (\n oldElement.firstChild &&\n oldElement.firstChild.nodeValue !== newValue\n ) {\n oldElement.firstChild.nodeValue = newValue;\n }\n }\n }\n\n /**\n * @param {Element} oldElement element to write the value to\n * @param {Element} newElement element to read the value from\n * @param {string} attributeName the attribute name\n * @param {MorphContext} ctx the merge context\n */\n function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n const newLiveValue = newElement[attributeName],\n // @ts-ignore ditto\n oldLiveValue = oldElement[attributeName];\n if (newLiveValue !== oldLiveValue) {\n const ignoreUpdate = ignoreAttribute(\n attributeName,\n oldElement,\n \"update\",\n ctx,\n );\n if (!ignoreUpdate) {\n // update attribute's associated DOM property\n // @ts-ignore this function is only used on boolean attrs that are reflected as dom properties\n oldElement[attributeName] = newElement[attributeName];\n }\n if (newLiveValue) {\n if (!ignoreUpdate) {\n // https://developer.mozilla.org/en-US/docs/Glossary/Boolean/HTML\n // this is the correct way to set a boolean attribute to \"true\"\n oldElement.setAttribute(attributeName, \"\");\n }\n } else {\n if (!ignoreAttribute(attributeName, oldElement, \"remove\", ctx)) {\n oldElement.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * @param {string} attr the attribute to be mutated\n * @param {Element} element the element that is going to be updated\n * @param {\"update\" | \"remove\"} updateType\n * @param {MorphContext} ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, element, updateType, ctx) {\n if (\n attr === \"value\" &&\n ctx.ignoreActiveValue &&\n element === document.activeElement\n ) {\n return true;\n }\n return (\n ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) ===\n false\n );\n }\n\n /**\n * @param {Node} possibleActiveElement\n * @param {MorphContext} ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return (\n !!ctx.ignoreActiveValue &&\n possibleActiveElement === document.activeElement &&\n possibleActiveElement !== document.body\n );\n }\n\n return morphNode;\n })();\n\n //=============================================================================\n // Head Management Functions\n //=============================================================================\n /**\n * @param {MorphContext} ctx\n * @param {Element} oldNode\n * @param {Element} newNode\n * @param {function} callback\n * @returns {Node[] | Promise<Node[]>}\n */\n function withHeadBlocking(ctx, oldNode, newNode, callback) {\n if (ctx.head.block) {\n const oldHead = oldNode.querySelector(\"head\");\n const newHead = newNode.querySelector(\"head\");\n if (oldHead && newHead) {\n const promises = handleHeadElement(oldHead, newHead, ctx);\n // when head promises resolve, proceed ignoring the head tag\n return Promise.all(promises).then(() => {\n const newCtx = Object.assign(ctx, {\n head: {\n block: false,\n ignore: true,\n },\n });\n return callback(newCtx);\n });\n }\n }\n // just proceed if we not head blocking\n return callback(ctx);\n }\n\n /**\n * The HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n *\n * @param {Element} oldHead\n * @param {Element} newHead\n * @param {MorphContext} ctx\n * @returns {Promise<void>[]}\n */\n function handleHeadElement(oldHead, newHead, ctx) {\n let added = [];\n let removed = [];\n let preserved = [];\n let nodesToAppend = [];\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHead.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of oldHead.children) {\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (ctx.head.style === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n // TODO: This could theoretically be null, based on type\n let newElt = /** @type {ChildNode} */ (\n document.createRange().createContextualFragment(newNode.outerHTML)\n .firstChild\n );\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (\n (\"href\" in newElt && newElt.href) ||\n (\"src\" in newElt && newElt.src)\n ) {\n /** @type {(result?: any) => void} */ let resolve;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener(\"load\", function () {\n resolve();\n });\n promises.push(promise);\n }\n oldHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n oldHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(oldHead, {\n added: added,\n kept: preserved,\n removed: removed,\n });\n return promises;\n }\n\n //=============================================================================\n // Create Morph Context Functions\n //=============================================================================\n const createMorphContext = (function () {\n /**\n *\n * @param {Element} oldNode\n * @param {Element} newContent\n * @param {Config} config\n * @returns {MorphContext}\n */\n function createMorphContext(oldNode, newContent, config) {\n const { persistentIds, idMap } = createIdMaps(oldNode, newContent);\n\n const mergedConfig = mergeDefaults(config);\n const morphStyle = mergedConfig.morphStyle || \"outerHTML\";\n if (![\"innerHTML\", \"outerHTML\"].includes(morphStyle)) {\n throw `Do not understand how to morph style ${morphStyle}`;\n }\n\n return {\n target: oldNode,\n newContent: newContent,\n config: mergedConfig,\n morphStyle: morphStyle,\n ignoreActive: mergedConfig.ignoreActive,\n ignoreActiveValue: mergedConfig.ignoreActiveValue,\n restoreFocus: mergedConfig.restoreFocus,\n idMap: idMap,\n persistentIds: persistentIds,\n pantry: createPantry(),\n callbacks: mergedConfig.callbacks,\n head: mergedConfig.head,\n };\n }\n\n /**\n * Deep merges the config object and the Idiomorph.defaults object to\n * produce a final configuration object\n * @param {Config} config\n * @returns {ConfigInternal}\n */\n function mergeDefaults(config) {\n let finalConfig = Object.assign({}, defaults);\n\n // copy top level stuff into final config\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = Object.assign(\n {},\n defaults.callbacks,\n config.callbacks,\n );\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = Object.assign({}, defaults.head, config.head);\n\n return finalConfig;\n }\n\n /**\n * @returns {HTMLDivElement}\n */\n function createPantry() {\n const pantry = document.createElement(\"div\");\n pantry.hidden = true;\n document.body.insertAdjacentElement(\"afterend\", pantry);\n return pantry;\n }\n\n /**\n * Returns all elements with an ID contained within the root element and its descendants\n *\n * @param {Element} root\n * @returns {Element[]}\n */\n function findIdElements(root) {\n let elements = Array.from(root.querySelectorAll(\"[id]\"));\n if (root.id) {\n elements.push(root);\n }\n return elements;\n }\n\n /**\n * A bottom-up algorithm that populates a map of Element -> IdSet.\n * The idSet for a given element is the set of all IDs contained within its subtree.\n * As an optimzation, we filter these IDs through the given list of persistent IDs,\n * because we don't need to bother considering IDed elements that won't be in the new content.\n *\n * @param {Map<Node, Set<string>>} idMap\n * @param {Set<string>} persistentIds\n * @param {Element} root\n * @param {Element[]} elements\n */\n function populateIdMapWithTree(idMap, persistentIds, root, elements) {\n for (const elt of elements) {\n if (persistentIds.has(elt.id)) {\n /** @type {Element|null} */\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n\n if (current === root) break;\n current = current.parentElement;\n }\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {IdSets}\n */\n function createIdMaps(oldContent, newContent) {\n const oldIdElements = findIdElements(oldContent);\n const newIdElements = findIdElements(newContent);\n\n const persistentIds = createPersistentIds(oldIdElements, newIdElements);\n\n /** @type {Map<Node, Set<string>>} */\n let idMap = new Map();\n populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);\n\n /** @ts-ignore - if newContent is a duck-typed parent, pass its single child node as the root to halt upwards iteration */\n const newRoot = newContent.__idiomorphRoot || newContent;\n populateIdMapWithTree(idMap, persistentIds, newRoot, newIdElements);\n\n return { persistentIds, idMap };\n }\n\n /**\n * This function computes the set of ids that persist between the two contents excluding duplicates\n *\n * @param {Element[]} oldIdElements\n * @param {Element[]} newIdElements\n * @returns {Set<string>}\n */\n function createPersistentIds(oldIdElements, newIdElements) {\n let duplicateIds = new Set();\n\n /** @type {Map<string, string>} */\n let oldIdTagNameMap = new Map();\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id);\n } else {\n oldIdTagNameMap.set(id, tagName);\n }\n }\n\n let persistentIds = new Set();\n for (const { id, tagName } of newIdElements) {\n if (persistentIds.has(id)) {\n duplicateIds.add(id);\n } else if (oldIdTagNameMap.get(id) === tagName) {\n persistentIds.add(id);\n }\n // skip if tag types mismatch because its not possible to morph one tag into another\n }\n\n for (const id of duplicateIds) {\n persistentIds.delete(id);\n }\n return persistentIds;\n }\n\n return createMorphContext;\n })();\n\n //=============================================================================\n // HTML Normalization Functions\n //=============================================================================\n const { normalizeElement, normalizeParent } = (function () {\n /** @type {WeakSet<Node>} */\n const generatedByIdiomorph = new WeakSet();\n\n /**\n *\n * @param {Element | Document} content\n * @returns {Element}\n */\n function normalizeElement(content) {\n if (content instanceof Document) {\n return content.documentElement;\n } else {\n return content;\n }\n }\n\n /**\n *\n * @param {null | string | Node | HTMLCollection | Node[] | Document & {generatedByIdiomorph:boolean}} newContent\n * @returns {Element}\n */\n function normalizeParent(newContent) {\n if (newContent == null) {\n return document.createElement(\"div\"); // dummy parent element\n } else if (typeof newContent === \"string\") {\n return normalizeParent(parseContent(newContent));\n } else if (\n generatedByIdiomorph.has(/** @type {Element} */ (newContent))\n ) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return /** @type {Element} */ (newContent);\n } else if (newContent instanceof Node) {\n if (newContent.parentNode) {\n // we can't use the parent directly because newContent may have siblings\n // that we don't want in the morph, and reparenting might be expensive (TODO is it?),\n // so we create a duck-typed parent node instead.\n return createDuckTypedParent(newContent);\n } else {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement(\"div\");\n dummyParent.append(newContent);\n return dummyParent;\n }\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement(\"div\");\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n /**\n * Creates a fake duck-typed parent element to wrap a single node, without actually reparenting it.\n * \"If it walks like a duck, and quacks like a duck, then it must be a duck!\" -- James Whitcomb Riley (1849–1916)\n *\n * @param {Node} newContent\n * @returns {Element}\n */\n function createDuckTypedParent(newContent) {\n return /** @type {Element} */ (\n /** @type {unknown} */ ({\n childNodes: [newContent],\n /** @ts-ignore - cover your eyes for a minute, tsc */\n querySelectorAll: (s) => {\n /** @ts-ignore */\n const elements = newContent.querySelectorAll(s);\n /** @ts-ignore */\n return newContent.matches(s) ? [newContent, ...elements] : elements;\n },\n /** @ts-ignore */\n insertBefore: (n, r) => newContent.parentNode.insertBefore(n, r),\n /** @ts-ignore */\n moveBefore: (n, r) => newContent.parentNode.moveBefore(n, r),\n // for later use with populateIdMapWithTree to halt upwards iteration\n get __idiomorphRoot() {\n return newContent;\n },\n })\n );\n }\n\n /**\n *\n * @param {string} newContent\n * @returns {Node | null | DocumentFragment}\n */\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(\n /<svg(\\s[^>]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n \"\",\n );\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (\n contentWithSvgsRemoved.match(/<\\/html>/) ||\n contentWithSvgsRemoved.match(/<\\/head>/) ||\n contentWithSvgsRemoved.match(/<\\/body>/)\n ) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n generatedByIdiomorph.add(content);\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n generatedByIdiomorph.add(htmlElement);\n }\n return htmlElement;\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\n \"<body><template>\" + newContent + \"</template></body>\",\n \"text/html\",\n );\n let content = /** @type {HTMLTemplateElement} */ (\n responseDoc.body.querySelector(\"template\")\n ).content;\n generatedByIdiomorph.add(content);\n return content;\n }\n }\n\n return { normalizeElement, normalizeParent };\n })();\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults,\n };\n})();\n\nexport {Idiomorph};\n","\nconst topics: any = {}\nconst _async: any = {}\n\nexport const publish = (name, params) => {\n\t_async[name] = Object.assign({}, _async[name], params)\n\tif (topics[name])\n\t\ttopics[name].forEach(topic => topic(params))\n}\n\nexport const subscribe = (name, method) => {\n\ttopics[name] = topics[name] || []\n\ttopics[name].push(method)\n\tif (name in _async) {\n\t\tmethod(_async[name])\n\t}\n\treturn () => {\n\t\ttopics[name] = topics[name].filter( fn => fn != method )\n\t}\n}\n","import { safe, g, dup } from './utils'\nimport { Idiomorph } from 'idiomorph/dist/idiomorph.esm'\nimport { publish, subscribe } from './utils/pubsub'\n\nexport const Component = ({ name, module, dependencies, node, templates, signal, register }) => {\n\n\tlet tick\n\tlet preserve\t\t= []\n\n\tconst _model \t\t= module.model || {}\n\tconst initialState \t= (new Function( `return ${node.getAttribute('html-model') || '{}'}`))()\n\tconst tplid \t\t= node.getAttribute('tplid')\n\tconst scopeid \t\t= node.getAttribute('html-scopeid')\n\tconst tpl \t\t\t= templates[ tplid ]\n\tconst scope \t\t= g.scope[ scopeid ]\n\tconst model \t\t= dup(module?.model?.apply ? _model({ elm:node, initialState }) : _model)\n\tconst state \t\t= Object.assign({}, scope, model, initialState)\n\tconst view \t\t\t= module.view? module.view : (data) => data\n\n\tconst base = {\n\t\tname,\n\t\tmodel,\n\t\telm: node,\n\t\ttemplate: tpl.template,\n\t\tdependencies,\n\t\tpublish,\n\t\tsubscribe,\n\n\t\tmain(fn) {\n\t\t\tnode.addEventListener(':mount', fn)\n\t\t},\n\n\t\t/**\n\t\t * @State\n\t\t */\n\t\tstate : {\n\n\t\t\tprotected( list ) {\n\t\t\t\tif( list ) {\n\t\t\t\t\tpreserve = list\n\t\t\t\t} else {\n\t\t\t\t\treturn preserve\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tsave(data) {\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata( state )\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tset( data ) {\n\n\t\t\t\tif (!document.body.contains(node)) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif( data.constructor === Function ) {\n\t\t\t\t\tdata(state)\n\t\t\t\t} else {\n\t\t\t\t\tObject.assign(state, data)\n\t\t\t\t}\n\n\t\t\t\tconst newstate = Object.assign({}, state, scope)\n\n\t\t\t\treturn new Promise((resolve) => {\n\t\t\t\t\trender(newstate, () => resolve(newstate))\n\t\t\t\t})\n\t\t\t},\n\n\t\t\tget() {\n\t\t\t\treturn Object.assign({}, state)\n\t\t\t}\n\t\t},\n\n\t\tdataset( target, name ) {\n\n\t\t\tconst el = name? target : node\n\t\t\tconst key = name? name : target\n\t\t\tconst value = el.dataset[key]\n\n\t\t\tif (value === 'true') return true\n\t\t\tif (value === 'false') return false\n\t\t\tif (!isNaN(value) && value.trim() !== '') return Number(value)\n\n\t\t\ttry {\n\t\t\t\treturn new Function('return (' + value + ')')()\n\t\t\t} catch {}\n\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(value)\n\t\t\t} catch {}\n\n\t\t\treturn value\n\t\t},\n\n\t\tattributes( target ) {\n\n\t\t\tlet callbacks = []\n\t\t\tconst elm = target || node\n\n\t\t\tconst observer = new MutationObserver((mutationsList) => {\n\t\t\t\tfor (const mutation of mutationsList) {\n\t\t\t\t\tif (mutation.type === 'attributes') {\n\t\t\t\t\t\tconst attributeName = mutation.attributeName\n\t\t\t\t\t\tcallbacks.forEach((item) => {\n\t\t\t\t\t\t\tif (item.name == attributeName) {\n\t\t\t\t\t\t\t\titem.callback(\n\t\t\t\t\t\t\t\t\tattributeName,\n\t\t\t\t\t\t\t\t\telm.getAttribute(attributeName)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tobserver.observe(node, { attributes: true })\n\n\t\t\tnode.addEventListener(':unmount', () => {\n\t\t\t\tcallbacks = null\n\t\t\t\tobserver.disconnect()\n\t\t\t})\n\n\t\t\treturn {\n\n\t\t\t\tonchange( name, callback ) {\n\t\t\t\t\tcallbacks.push({ name, callback })\n\t\t\t\t},\n\n\t\t\t\tdisconnect( callback ) {\n\t\t\t\t\tcallbacks = callbacks.filter((item) => item.callback !== callback)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * @Events\n\t\t */\n\t\ton( ev, selectorOrCallback, callback ) {\n\n\t\t\tif( callback ) {\n\t\t\t\tcallback.handler = (e) => {\n\t\t\t\t\tconst detail = e.detail || {}\n\t\t\t\t\tlet parent = e.target\n\t\t\t\t\twhile (parent) {\n\t\t\t\t\t\tif (parent.matches(selectorOrCallback)) {\n\t\t\t\t\t\t\te.delegateTarget = parent\n\t\t\t\t\t\t\tcallback.apply(node, [e].concat(detail.args))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (parent === node) break\n\t\t\t\t\t\tparent = parent.parentNode\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, callback.handler, {\n\t\t\t\t\tsignal,\n\t\t\t\t\tcapture: (ev == 'focus' || ev == 'blur' || ev == 'mouseenter' || ev == 'mouseleave')\n\t\t\t\t})\n\n\t\t\t} else {\n\t\t\t\tselectorOrCallback.handler = (e) => {\n\t\t\t\t\te.delegateTarget = node\n\t\t\t\t\tselectorOrCallback.apply(node, [e].concat(e.detail.args))\n\t\t\t\t}\n\t\t\t\tnode.addEventListener(ev, selectorOrCallback.handler, { signal })\n\t\t\t}\n\n\t\t},\n\n\t\toff( ev, callback ) {\n\t\t\tif( callback.handler ) {\n\t\t\t\tnode.removeEventListener(ev, callback.handler)\n\t\t\t}\n\t\t},\n\n\t\ttrigger(ev, selectorOrCallback, data) {\n\t\t\tif( selectorOrCallback.constructor === String ) {\n\t\t\t\tArray\n\t\t\t\t\t.from(node.querySelectorAll(selectorOrCallback))\n\t\t\t\t\t.forEach( children => {\n\t\t\t\t\t\tchildren.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }) )\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail:{ args: data } }))\n\t\t\t}\n\t\t},\n\n\t\temit(ev, data) {\n\t\t\tnode.dispatchEvent(new CustomEvent(ev, { bubbles: true, detail: { args: data } }))\n\t\t},\n\n\t\tunmount( fn ) {\n\t\t\tnode.addEventListener(':unmount', fn)\n\t\t},\n\n\t\tinnerHTML ( target, html_ ) {\n\t\t\tconst element = html_? target : node\n\t\t\tconst clone = element.cloneNode()\n\t\t\tconst html = html_? html_ : target\n\t\t\tclone.innerHTML = html\n\t\t\tIdiomorph.morph(element, clone)\n\t\t}\n\t}\n\n\tconst render = ( data, callback = (() => {}) ) => {\n\t\tclearTimeout( tick )\n\t\ttick = setTimeout(() => {\n\t\t\tconst html = tpl.render.call({...data, ...view(data)}, node, safe, g )\n\t\t\tIdiomorph.morph( node, html, IdiomorphOptions(node, register) )\n\t\t\tPromise.resolve().then(() => {\n\t\t\t\tnode.querySelectorAll('[tplid]')\n\t\t\t\t\t.forEach((element) => {\n\t\t\t\t\t\tconst child = register.get(element)\n\t\t\t\t\t\tif(!child) return\n\t\t\t\t\t\tchild.state.protected().forEach( key => delete data[key] )\n\t\t\t\t\t\tchild.state.set(data)\n\t\t\t\t\t})\n\t\t\t\tPromise.resolve().then(() => {\n\t\t\t\t\tg.scope = {}\n\t\t\t\t\tcallback()\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t}\n\n\trender( state )\n\tregister.set( node, base )\n\treturn module.default( base )\n}\n\nconst IdiomorphOptions = ( parent, register ) => ({\n\tcallbacks: {\n\t\tbeforeNodeMorphed( node ) {\n\t\t\tif( node.nodeType === 1 ) {\n\t\t\t\tif( 'html-static' in node.attributes ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif( register.get(node) && node !== parent ) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n})\n","import { Component } from './component'\n\nconst register = new WeakMap()\n\nexport const Element = ({ component, templates, start }) => {\n\n\tconst { name, module, dependencies } = component\n\n\treturn class extends HTMLElement {\n\n\t\tconstructor() {\n\t\t\tsuper()\n\t\t}\n\n\t\tconnectedCallback() {\n\n\t\t\tthis.abortController = new AbortController()\n\n\t\t\tif( !this.getAttribute('tplid') ) {\n\t\t\t\tstart( this.parentNode )\n\t\t\t}\n\n\t\t\tconst rtrn = Component({\n\t\t\t\tnode:this,\n\t\t\t\tname,\n\t\t\t\tmodule,\n\t\t\t\tdependencies,\n\t\t\t\ttemplates,\n\t\t\t\tsignal: this.abortController.signal,\n\t\t\t\tregister\n\t\t\t})\n\n\t\t\tif ( rtrn && rtrn.constructor === Promise ) {\n\t\t\t\trtrn.then(() => {\n\t\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tthis.dispatchEvent( new CustomEvent(':mount') )\n\t\t\t}\n\t\t}\n\n\t\tdisconnectedCallback() {\n\t\t\tthis.dispatchEvent( new CustomEvent(':unmount') )\n\t\t\tthis.abortController.abort()\n\t\t}\n\t}\n}\n","import { uuid, decodeHTML } from './utils'\n\nconst templates = {}\n\nconst config = {\n\ttags: ['{{', '}}']\n}\n\nexport const templateConfig = (newconfig) => {\n\tObject.assign( config, newconfig )\n}\n\nexport const template = ( target, { components }) => {\n\n\ttagElements( target, [...Object.keys( components ), '[html-if]', 'template'], components )\n\tconst clone = target.cloneNode( true )\n\n\ttransformTemplate( clone )\n\tremoveTemplateTagsRecursively( clone )\n\tsetTemplates( clone, components )\n\n\treturn templates\n}\n\nexport const compile = ( html ) => {\n\n\tconst parsedHtml = JSON.stringify( html )\n\n\treturn new Function('$element', 'safe', '$g',`\n\t\tvar $data = this;\n\t\twith( $data ){\n\t\t\tvar output=${parsedHtml\n\t\t\t\t.replace(/%%_=(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\"+safe(function(){return '+ decodeHTML(variable) +';})+\"'\n\t\t\t\t})\n\t\t\t\t.replace(/%%_(.+?)_%%/g, function(_, variable){\n\t\t\t\t\treturn '\";' + decodeHTML(variable) +'\\noutput+=\"'\n\t\t\t\t})};return output;\n\t\t}\n\t`)\n}\n\nconst tagElements = ( target, keys, components ) => {\n\ttarget\n\t\t.querySelectorAll( keys.toString() )\n\t\t.forEach((node) => {\n\t\t\tconst name = node.localName\n\t\t\tif( name === 'template' ) {\n\t\t\t\treturn tagElements( node.content, keys, components )\n\t\t\t}\n\t\t\tif( node.getAttribute('html-if') && !node.id ) {\n\t\t\t\tnode.id = uuid()\n\t\t\t}\n\t\t\tif( name in components ) {\n\t\t\t\tnode.setAttribute('tplid', uuid())\n\t\t\t}\n\t\t})\n}\n\nconst transformAttributes = ( html ) => {\n\n\tconst regexTags = new RegExp(`\\\\${config.tags[0]}(.+?)\\\\${config.tags[1]}`, 'g')\n\n\treturn html\n\t\t.replace(/jails___scope-id/g, '%%_=$scopeid_%%')\n\t\t.replace(regexTags, '%%_=$1_%%')\n\t\t// Booleans\n\t\t// https://meiert.com/en/blog/boolean-attributes-of-html/\n\t\t.replace(/html-(allowfullscreen|async|autofocus|autoplay|checked|controls|default|defer|disabled|formnovalidate|inert|ismap|itemscope|loop|multiple|muted|nomodule|novalidate|open|playsinline|readonly|required|reversed|selected)=\\\"(.*?)\\\"/g, `%%_if(safe(function(){ return $2 })){_%%$1%%_}_%%`)\n\t\t// The rest\n\t\t.replace(/html-([^\\s]*?)=\\\"(.*?)\\\"/g, (all, key, value) => {\n\t\t\tif (key === 'key' || key === 'model' || key === 'scopeid' ) {\n\t\t\t\treturn all\n\t\t\t}\n\t\t\tif (value) {\n\t\t\t\tvalue = value.replace(/^{|}$/g, '')\n\t\t\t\treturn `${key}=\"%%_=safe(function(){ return ${value} })_%%\"`\n\t\t\t} else {\n\t\t\t\treturn all\n\t\t\t}\n\t\t})\n}\n\nconst transformTemplate = ( clone ) => {\n\n\tclone.querySelectorAll('template, [html-for], [html-if], [html-inner], [html-class]')\n\t\t.forEach(( element ) => {\n\n\t\t\tconst htmlFor \t= element.getAttribute('html-for')\n\t\t\tconst htmlIf \t= element.getAttribute('html-if')\n\t\t\tconst htmlInner = element.getAttribute('html-inner')\n\t\t\tconst htmlClass = element.getAttribute('html-class')\n\n\t\t\tif ( htmlFor ) {\n\n\t\t\t\telement.removeAttribute('html-for')\n\n\t\t\t\tconst split \t = htmlFor.match(/(.*)\\sin\\s(.*)/) || ''\n\t\t\t\tconst varname \t = split[1]\n\t\t\t\tconst object \t = split[2]\n\t\t\t\tconst objectname = object.split(/\\./).shift()\n\t\t\t\tconst open \t\t = document.createTextNode(`%%_ ;(function(){ var $index = 0; for(var $key in safe(function(){ return ${object} }) ){ var $scopeid = Math.random().toString(36).substring(2, 9); var ${varname} = ${object}[$key]; $g.scope[$scopeid] = Object.assign({}, { ${objectname}: ${objectname} }, { ${varname} :${varname}, $index: $index, $key: $key }); _%%`)\n\t\t\t\tconst close \t = document.createTextNode(`%%_ $index++; } })() _%%`)\n\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlIf) {\n\t\t\t\telement.removeAttribute('html-if')\n\t\t\t\tconst open = document.createTextNode(`%%_ if ( safe(function(){ return ${htmlIf} }) ){ _%%`)\n\t\t\t\tconst close = document.createTextNode(`%%_ } _%%`)\n\t\t\t\twrap(open, element, close)\n\t\t\t}\n\n\t\t\tif (htmlInner) {\n\t\t\t\telement.removeAttribute('html-inner')\n\t\t\t\telement.innerHTML = `%%_=${htmlInner}_%%`\n\t\t\t}\n\n\t\t\tif (htmlClass) {\n\t\t\t\telement.removeAttribute('html-class')\n\t\t\t\telement.className = (element.className + ` %%_=${htmlClass}_%%`).trim()\n\t\t\t}\n\n\t\t\tif( element.localName === 'template' ) {\n\t\t\t\ttransformTemplate(element.content)\n\t\t\t}\n\t\t})\n}\n\nconst setTemplates = ( clone, components ) => {\n\n\tArray.from(clone.querySelectorAll('[tplid]'))\n\t\t.reverse()\n\t\t.forEach((node) => {\n\n\t\t\tconst tplid = node.getAttribute('tplid')\n\t\t\tconst name = node.localName\n\t\t\tnode.setAttribute('html-scopeid', 'jails___scope-id')\n\n\t\t\tif( name in components && components[name].module.template ) {\n\t\t\t\tconst children = node.innerHTML\n\t\t\t\tconst html = components[name].module.template({ elm:node, children })\n\t\t\t\tnode.innerHTML = html\n\t\t\t}\n\n\t\t\tconst html = transformAttributes(node.outerHTML)\n\n\t\t\ttemplates[ tplid ] = {\n\t\t\t\ttemplate: html,\n\t\t\t\trender\t: compile(html)\n\t\t\t}\n\t\t})\n}\n\nconst removeTemplateTagsRecursively = (node) => {\n\n\t// Get all <template> elements within the node\n\tconst templates = node.querySelectorAll('template')\n\n\ttemplates.forEach((template) => {\n\n\t\tif( template.getAttribute('html-if') || template.getAttribute('html-inner') ) {\n\t\t\treturn\n\t\t}\n\n\t\t// Process any nested <template> tags within this <template> first\n\t\tremoveTemplateTagsRecursively(template.content)\n\n\t\t// Get the parent of the <template> tag\n\t\tconst parent = template.parentNode\n\n\t\tif (parent) {\n\t\t\t// Move all child nodes from the <template>'s content to its parent\n\t\t\tconst content = template.content\n\t\t\twhile (content.firstChild) {\n\t\t\t\tparent.insertBefore(content.firstChild, template)\n\t\t\t}\n\t\t\t// Remove the <template> tag itself\n\t\t\tparent.removeChild(template)\n\t\t}\n\t})\n}\n\nconst wrap = (open, node, close) => {\n\tnode.parentNode?.insertBefore(open, node)\n\tnode.parentNode?.insertBefore(close, node.nextSibling)\n}\n","\nimport { Element } from './element'\nimport { template, templateConfig as config } from './template-system'\n\nexport { publish, subscribe } from './utils/pubsub'\n\nexport const templateConfig = (options) => {\n\tconfig( options )\n}\n\nwindow.__jails__ = window.__jails__ || { components: {} }\n\nexport const register = ( name, module, dependencies ) => {\n\tconst { components } = window.__jails__\n\tcomponents[ name ] = { name, module, dependencies }\n}\n\nexport const start = ( target = document.body ) => {\n\n\tconst { components } = window.__jails__\n\tconst templates = template( target, { components } )\n\n\tObject\n\t\t.values( components )\n\t\t.forEach(({ name, module, dependencies }) => {\n\t\t\tif( !customElements.get(name) ) {\n\t\t\t\tcustomElements.define( name, Element({ component: { name, module, dependencies }, templates, start }))\n\t\t\t}\n\t})\n}\n\ndeclare global {\n\tinterface Window {\n\t __jails__?: {\n\t\tcomponents: Record<string, any>\n\t }\n\t}\n}\n"],"names":["textarea","document","createElement","g","scope","decodeHTML","text","innerHTML","value","uuid","Math","random","toString","substring","safe","execute","val","err","Idiomorph","noOp","defaults","morphStyle","callbacks","beforeNodeAdded","afterNodeAdded","beforeNodeMorphed","afterNodeMorphed","beforeNodeRemoved","afterNodeRemoved","beforeAttributeUpdated","head","style","shouldPreserve","elt","getAttribute","shouldReAppend","shouldRemove","afterHeadMorphed","restoreFocus","morphChildren","createNode","oldParent","newChild","insertionPoint","ctx","idMap","has","newEmptyChild","tagName","insertBefore","morphNode","newClonedChild","importNode","findBestMatch","isIdSetMatch","oldNode","newNode","oldSet","get","newSet","id","isSoftMatch","oldElt","newElt","nodeType","node","startPoint","endPoint","softMatch","nextSibling","siblingSoftMatchCount","cursor","contains","activeElement","removeNode","moveBefore","pantry","_a","parentNode","removeChild","removeNodesBetween","startInclusive","endExclusive","tempNode","moveBeforeById","after","target","querySelector","element","idSet","delete","size","removeElementFromAncestorsIdMaps","e","newParent","HTMLTemplateElement","content","firstChild","childNodes","bestMatch","Element","persistentIds","movedChild","insertedNode","syncBooleanAttribute","oldElement","newElement","attributeName","newLiveValue","ignoreUpdate","ignoreAttribute","setAttribute","removeAttribute","attr","updateType","ignoreActiveValue","ignoreValueOfActiveElement","possibleActiveElement","body","newContent","ignoreActive","HTMLHeadElement","ignore","handleHeadElement","type","oldAttributes","attributes","newAttributes","newAttribute","name","i","length","oldAttribute","hasAttribute","HTMLInputElement","newValue","oldValue","HTMLOptionElement","HTMLTextAreaElement","nodeValue","syncInputValue","morphAttributes","oldHead","newHead","added","removed","preserved","nodesToAppend","srcToNewHeadNodes","Map","newHeadChild","children","set","outerHTML","currentHeadElt","inNewContent","isReAppended","isPreserved","push","values","promises","createRange","createContextualFragment","href","src","resolve","promise","Promise","_resolve","addEventListener","appendChild","removedElement","kept","createMorphContext","createPantry","hidden","insertAdjacentElement","findIdElements","root","elements","Array","from","querySelectorAll","populateIdMapWithTree","current","Set","add","parentElement","config","oldContent","oldIdElements","newIdElements","duplicateIds","oldIdTagNameMap","createPersistentIds","newRoot","__idiomorphRoot","createIdMaps","mergedConfig","finalConfig","Object","assign","mergeDefaults","includes","normalizeElement","normalizeParent","generatedByIdiomorph","WeakSet","Document","documentElement","parser","DOMParser","contentWithSvgsRemoved","replace","match","parseFromString","htmlElement","parseContent","Node","s","matches","n","r","createDuckTypedParent","dummyParent","append","morph","morphedNodes","fn","activeElementId","selectionStart","selectionEnd","results","focus","setSelectionRange","saveAndRestoreFocus","callback","block","all","then","newCtx","withHeadBlocking","index","indexOf","rightMargin","slice","morphOuterHTML","remove","topics","_async","publish","params","forEach","topic","subscribe","method","filter","Component","module","dependencies","templates","signal","register","tick","preserve","_model","model","initialState","Function","tplid","scopeid","tpl","o","apply","elm","JSON","parse","stringify","state","view","data","base","template","main","protected","list","save","constructor","newstate","render","dataset","key","isNaN","trim","Number","observer","MutationObserver","mutationsList","mutation","item","observe","disconnect","onchange","on","ev","selectorOrCallback","handler","detail","parent","delegateTarget","concat","args","capture","off","removeEventListener","trigger","String","dispatchEvent","CustomEvent","bubbles","emit","unmount","html_","clone","cloneNode","html","clearTimeout","setTimeout","call","__spreadValues","IdiomorphOptions","child","default","WeakMap","component","start","HTMLElement","super","connectedCallback","this","abortController","AbortController","rtrn","disconnectedCallback","abort","tags","compile","parsedHtml","_","variable","tagElements","keys","components","localName","transformTemplate","htmlFor","htmlIf","htmlInner","htmlClass","split","varname","object","objectname","shift","open","createTextNode","close","wrap","className","setTemplates","reverse","regexTags","RegExp","transformAttributes","removeTemplateTagsRecursively","_b","window","__jails__","customElements","define","options","newconfig"],"mappings":"0jBACM,MAAAA,EAAWC,SAASC,cAAc,YAE3BC,EAAI,CAChBC,MAAO,CAAA,GAGKC,EAAcC,IAC1BN,EAASO,UAAYD,EACdN,EAASQ,OAUJC,EAAO,IACZC,KAAKC,SAASC,SAAS,IAAIC,UAAU,EAAG,GAOnCC,EAAO,CAACC,EAASC,KAC1B,IACF,OAAOD,UACDE,GACN,OAAOD,GAAO,EAAA,GCiEhB,IAAIE,EAAa,WAwBf,MAAMC,EAAO,OAKPC,EAAW,CACfC,WAAY,YACZC,UAAW,CACTC,gBAAiBJ,EACjBK,eAAgBL,EAChBM,kBAAmBN,EACnBO,iBAAkBP,EAClBQ,kBAAmBR,EACnBS,iBAAkBT,EAClBU,uBAAwBV,GAE1BW,KAAM,CACJC,MAAO,QACPC,eAAiBC,GAA4C,SAApCA,EAAIC,aAAa,eAC1CC,eAAiBF,GAA6C,SAArCA,EAAIC,aAAa,gBAC1CE,aAAcjB,EACdkB,iBAAkBlB,GAEpBmB,cAAc,GAyGhB,MAAMC,EAA6B,WAgHjC,SAASC,EAAWC,EAAWC,EAAUC,EAAgBC,GACvD,IAAgD,IAA5CA,EAAItB,UAAUC,gBAAgBmB,GAA4B,OAAA,KAC9D,GAAIE,EAAIC,MAAMC,IAAIJ,GAAW,CAE3B,MAAMK,EAAgB9C,SAASC,cACLwC,EAAUM,SAK7B,OAHGP,EAAAQ,aAAaF,EAAeJ,GAC5BO,EAAAH,EAAeL,EAAUE,GAC/BA,EAAAtB,UAAUE,eAAeuB,GACtBA,CACf,CAAa,CAEL,MAAMI,EAAiBlD,SAASmD,WAAWV,GAAU,GAG9C,OAFGD,EAAAQ,aAAaE,EAAgBR,GACnCC,EAAAtB,UAAUE,eAAe2B,GACtBA,CACf,CACA,CAKI,MAAME,EAA6B,WAoExB,SAAAC,EAAaV,EAAKW,EAASC,GAClC,IAAIC,EAASb,EAAIC,MAAMa,IAAIH,GACvBI,EAASf,EAAIC,MAAMa,IAAIF,GAE3B,IAAKG,IAAWF,EAAe,OAAA,EAE/B,IAAA,MAAWG,KAAMH,EAKX,GAAAE,EAAOb,IAAIc,GACN,OAAA,EAGJ,OAAA,CACf,CAQe,SAAAC,EAAYN,EAASC,GAEtB,MAAAM,EAAA,EACAC,EAAA,EAEN,OACED,EAAOE,WAAaD,EAAOC,UAC3BF,EAAOd,UAAYe,EAAOf,WAIxBc,EAAOF,IAAME,EAAOF,KAAOG,EAAOH,GAE9C,CAEaP,OAhGP,SAAuBT,EAAKqB,EAAMC,EAAYC,GAC5C,IAAIC,EAAY,KACZC,EAAcJ,EAAKI,YACnBC,EAAwB,EAExBC,EAASL,EACN,KAAAK,GAAUA,GAAUJ,GAAU,CAE/B,GAAAN,EAAYU,EAAQN,GAAO,CAC7B,GAAIX,EAAaV,EAAK2B,EAAQN,GACrB,OAAAM,EAIS,OAAdH,IAEGxB,EAAIC,MAAMC,IAAIyB,KAELH,EAAAG,GAG5B,CAqBU,GAnBgB,OAAdH,GACAC,GACAR,EAAYU,EAAQF,KAIpBC,IACAD,EAAcA,EAAYA,YAKtBC,GAAyB,IACfF,OAAA,IAMZG,EAAOC,SAASvE,SAASwE,eAAgB,MAE7CF,EAASA,EAAOF,WAC1B,CAEQ,OAAOD,GAAa,IAC5B,CAiDA,CA5GuC,GAyH1B,SAAAM,EAAW9B,EAAKqB,SAEvB,GAAIrB,EAAIC,MAAMC,IAAImB,GAELU,EAAA/B,EAAIgC,OAAQX,EAAM,UACxB,CAEL,IAA8C,IAA1CrB,EAAItB,UAAUK,kBAAkBsC,GAAiB,OACrD,OAAKY,EAAAZ,EAAAa,eAAYC,YAAYd,GACzBrB,EAAAtB,UAAUM,iBAAiBqC,EACvC,CACA,CASa,SAAAe,EAAmBpC,EAAKqC,EAAgBC,GAE/C,IAAIX,EAASU,EAEN,KAAAV,GAAUA,IAAWW,GAAc,CACpC,IAAAC,EAAA,EACJZ,EAASA,EAAOF,YAChBK,EAAW9B,EAAKuC,EACxB,CACa,OAAAZ,CACb,CAYI,SAASa,EAAeN,EAAYlB,EAAIyB,EAAOzC,GACvC,MAAA0C,EAGF1C,EAAI0C,OAAOC,cAAc,IAAI3B,MAC3BhB,EAAIgC,OAAOW,cAAc,IAAI3B,KAI5B,OAWA,SAAiC4B,EAAS5C,GACjD,MAAMgB,EAAK4B,EAAQ5B,GAEX,KAAA4B,EAAUA,EAAQV,YAAa,CACrC,IAAIW,EAAQ7C,EAAIC,MAAMa,IAAI8B,GACtBC,IACFA,EAAMC,OAAO9B,GACR6B,EAAME,MACL/C,EAAAC,MAAM6C,OAAOF,GAG7B,CACA,CAzBMI,CAAiCN,EAAQ1C,GAC9B+B,EAAAG,EAAYQ,EAAQD,GACxBC,CACb,CAkCa,SAAAX,EAAWG,EAAYU,EAASH,GAEvC,GAAIP,EAAWH,WACT,IAESG,EAAAH,WAAWa,EAASH,EAChC,OAAQQ,GAEIf,EAAA7B,aAAauC,EAASH,EAC3C,MAEmBP,EAAA7B,aAAauC,EAASH,EAEzC,CAEW9C,OA1UP,SACEK,EACAH,EACAqD,EACAnD,EAAiB,KACjBwB,EAAW,MAIT1B,aAAqBsD,qBACrBD,aAAqBC,sBAGrBtD,EAAYA,EAAUuD,QAEtBF,EAAYA,EAAUE,SAExBrD,IAAAA,EAAmBF,EAAUwD,YAGlB,IAAA,MAAAvD,KAAYoD,EAAUI,WAAY,CAEvC,GAAAvD,GAAkBA,GAAkBwB,EAAU,CAChD,MAAMgC,EAAY9C,EAChBT,EACAF,EACAC,EACAwB,GAEF,GAAIgC,EAAW,CAETA,IAAcxD,GACGqC,EAAApC,EAAKD,EAAgBwD,GAEhCjD,EAAAiD,EAAWzD,EAAUE,GAC/BD,EAAiBwD,EAAU9B,YAC3B,QACZ,CACA,CAGQ,GAAI3B,aAAoB0D,SAAWxD,EAAIyD,cAAcvD,IAAIJ,EAASkB,IAAK,CAErE,MAAM0C,EAAalB,EACjB3C,EACAC,EAASkB,GACTjB,EACAC,GAEQM,EAAAoD,EAAY5D,EAAUE,GAChCD,EAAiB2D,EAAWjC,YAC5B,QACV,CAGQ,MAAMkC,EAAe/D,EACnBC,EACAC,EACAC,EACAC,GAGE2D,IACF5D,EAAiB4D,EAAalC,YAExC,CAGa,KAAA1B,GAAkBA,GAAkBwB,GAAU,CACnD,MAAMgB,EAAWxC,EACjBA,EAAiBA,EAAe0B,YAChCK,EAAW9B,EAAKuC,EACxB,CACA,CAkQA,CAtWqC,GA2W7BjC,EAAyB,WAoK7B,SAASsD,EAAqBC,EAAYC,EAAYC,EAAe/D,GAEnE,MAAMgE,EAAeF,EAAWC,GAGhC,GAAIC,IADaH,EAAWE,GACO,CACjC,MAAME,EAAeC,EACnBH,EACAF,EACA,SACA7D,GAEGiE,IAGQJ,EAAAE,GAAiBD,EAAWC,IAErCC,EACGC,GAGQJ,EAAAM,aAAaJ,EAAe,IAGpCG,EAAgBH,EAAeF,EAAY,SAAU7D,IACxD6D,EAAWO,gBAAgBL,EAGvC,CACA,CASI,SAASG,EAAgBG,EAAMzB,EAAS0B,EAAYtE,GAClD,QACW,UAATqE,IACArE,EAAIuE,mBACJ3B,IAAYvF,SAASwE,iBAMrB,IADA7B,EAAItB,UAAUO,uBAAuBoF,EAAMzB,EAAS0B,EAG5D,CAOa,SAAAE,EAA2BC,EAAuBzE,GAEvD,QAAEA,EAAIuE,mBACNE,IAA0BpH,SAASwE,eACnC4C,IAA0BpH,SAASqH,IAE3C,CAEWpE,OA9NEA,SAAUK,EAASgE,EAAY3E,GACtC,OAAIA,EAAI4E,cAAgBjE,IAAYtD,SAASwE,cAEpC,OAGoD,IAAzD7B,EAAItB,UAAUG,kBAAkB8B,EAASgE,KAIzChE,aAAmBkE,iBAAmB7E,EAAId,KAAK4F,SAGjDnE,aAAmBkE,iBACA,UAAnB7E,EAAId,KAAKC,MAGT4F,EACEpE,EACgCgE,EAChC3E,KAqBG,SAAgBW,EAASC,EAASZ,GACzC,IAAIgF,EAAOpE,EAAQQ,SAInB,GAAa,IAAT4D,EAA+B,CAC3B,MAAA9D,EAAA,EACAC,EAAA,EAEA8D,EAAgB/D,EAAOgE,WACvBC,EAAgBhE,EAAO+D,WAC7B,IAAA,MAAWE,KAAgBD,EACrBjB,EAAgBkB,EAAaC,KAAMnE,EAAQ,SAAUlB,IAGrDkB,EAAO5B,aAAa8F,EAAaC,QAAUD,EAAaxH,OAC1DsD,EAAOiD,aAAaiB,EAAaC,KAAMD,EAAaxH,OAIxD,IAAA,IAAS0H,EAAIL,EAAcM,OAAS,EAAG,GAAKD,EAAGA,IAAK,CAC5C,MAAAE,EAAeP,EAAcK,GAInC,GAAKE,IAEArE,EAAOsE,aAAaD,EAAaH,MAAO,CAC3C,GAAInB,EAAgBsB,EAAaH,KAAMnE,EAAQ,SAAUlB,GACvD,SAEKkB,EAAAkD,gBAAgBoB,EAAaH,KAChD,CACA,CAEab,EAA2BtD,EAAQlB,IAuBnC,SAAe6D,EAAYC,EAAY9D,GAC9C,GACE6D,aAAsB6B,kBACtB5B,aAAsB4B,kBACF,SAApB5B,EAAWkB,KACX,CACA,IAAIW,EAAW7B,EAAWlG,MACtBgI,EAAW/B,EAAWjG,MAGLgG,EAAAC,EAAYC,EAAY,UAAW9D,GACnC4D,EAAAC,EAAYC,EAAY,WAAY9D,GAEpD8D,EAAW2B,aAAa,SAKlBG,IAAaD,IACjBzB,EAAgB,QAASL,EAAY,SAAU7D,KACvC6D,EAAAM,aAAa,QAASwB,GACjC9B,EAAWjG,MAAQ+H,IAPhBzB,EAAgB,QAASL,EAAY,SAAU7D,KAClD6D,EAAWjG,MAAQ,GACnBiG,EAAWO,gBAAgB,SAUvC,MACQ,GAAAP,aAAsBgC,mBACtB/B,aAAsB+B,kBAEDjC,EAAAC,EAAYC,EAAY,WAAY9D,QAEzD,GAAA6D,aAAsBiC,qBACtBhC,aAAsBgC,oBACtB,CACA,IAAIH,EAAW7B,EAAWlG,MACtBgI,EAAW/B,EAAWjG,MAC1B,GAAIsG,EAAgB,QAASL,EAAY,SAAU7D,GACjD,OAEE2F,IAAaC,IACf/B,EAAWjG,MAAQ+H,GAGnB9B,EAAWR,YACXQ,EAAWR,WAAW0C,YAAcJ,IAEpC9B,EAAWR,WAAW0C,UAAYJ,EAE5C,CACA,CAxEyBK,CAAA9E,EAAQC,EAAQnB,EAEzC,CAGmB,IAATgF,GAAqC,IAATA,GAC1BrE,EAAQoF,YAAcnF,EAAQmF,YAChCpF,EAAQoF,UAAYnF,EAAQmF,UAGtC,CAhEwBE,CAAAtF,EAASgE,EAAY3E,GAChCwE,EAA2B7D,EAASX,IAEzBL,EAAAK,EAAKW,EAASgE,KAG5B3E,EAAAtB,UAAUI,iBAAiB6B,EAASgE,IAtB/BhE,EAwBf,CAgMA,CAtOiC,GAgRtB,SAAAoE,EAAkBmB,EAASC,EAASnG,GAC3C,IAAIoG,EAAQ,GACRC,EAAU,GACVC,EAAY,GACZC,EAAgB,GAGhBC,MAAwBC,IACjB,IAAA,MAAAC,KAAgBP,EAAQQ,SACfH,EAAAI,IAAIF,EAAaG,UAAWH,GAIrC,IAAA,MAAAI,KAAkBZ,EAAQS,SAAU,CAE7C,IAAII,EAAeP,EAAkBtG,IAAI4G,EAAeD,WACpDG,EAAehH,EAAId,KAAKK,eAAeuH,GACvCG,EAAcjH,EAAId,KAAKE,eAAe0H,GACtCC,GAAgBE,EACdD,EAEFX,EAAQa,KAAKJ,IAIKN,EAAA1D,OAAOgE,EAAeD,WACxCP,EAAUY,KAAKJ,IAGM,WAAnB9G,EAAId,KAAKC,MAGP6H,IACFX,EAAQa,KAAKJ,GACbP,EAAcW,KAAKJ,KAIyB,IAA1C9G,EAAId,KAAKM,aAAasH,IACxBT,EAAQa,KAAKJ,EAIzB,CAIIP,EAAcW,QAAQV,EAAkBW,UAExC,IAAIC,EAAW,GACf,IAAA,MAAWxG,KAAW2F,EAAe,CAE/B,IAAApF,EACF9D,SAASgK,cAAcC,yBAAyB1G,EAAQiG,WACrD,WAEL,IAA8C,IAA1C7G,EAAItB,UAAUC,gBAAgBwC,GAAmB,CACnD,GACG,SAAUA,GAAUA,EAAOoG,MAC3B,QAASpG,GAAUA,EAAOqG,IAC3B,CAC0C,IAAAC,EACtCC,EAAU,IAAIC,SAAQ,SAAUC,GACxBH,EAAAG,CACtB,IACiBzG,EAAA0G,iBAAiB,QAAQ,WACrBJ,GACrB,IACUL,EAASF,KAAKQ,EACxB,CACQxB,EAAQ4B,YAAY3G,GAChBnB,EAAAtB,UAAUE,eAAeuC,GAC7BiF,EAAMc,KAAK/F,EACnB,CACA,CAII,IAAA,MAAW4G,KAAkB1B,GAC6B,IAApDrG,EAAItB,UAAUK,kBAAkBgJ,KAClC7B,EAAQ/D,YAAY4F,GAChB/H,EAAAtB,UAAUM,iBAAiB+I,IAS5B,OALH/H,EAAAd,KAAKO,iBAAiByG,EAAS,CACjCE,QACA4B,KAAM1B,EACND,YAEKe,CACX,CAKE,MAAMa,EAAkC,WA6DtC,SAASC,IACD,MAAAlG,EAAS3E,SAASC,cAAc,OAG/B,OAFP0E,EAAOmG,QAAS,EACP9K,SAAAqH,KAAK0D,sBAAsB,WAAYpG,GACzCA,CACb,CAQI,SAASqG,EAAeC,GACtB,IAAIC,EAAWC,MAAMC,KAAKH,EAAKI,iBAAiB,SAIzC,OAHHJ,EAAKtH,IACPuH,EAASrB,KAAKoB,GAETC,CACb,CAaI,SAASI,EAAsB1I,EAAOwD,EAAe6E,EAAMC,GACzD,IAAA,MAAWlJ,KAAOkJ,EAChB,GAAI9E,EAAcvD,IAAIb,EAAI2B,IAAK,CAE7B,IAAI4H,EAAUvJ,EAGd,KAAOuJ,GAAS,CACV,IAAA/F,EAAQ5C,EAAMa,IAAI8H,GAQtB,GANa,MAAT/F,IACFA,MAAYgG,IACN5I,EAAA2G,IAAIgC,EAAS/F,IAEfA,EAAAiG,IAAIzJ,EAAI2B,IAEV4H,IAAYN,EAAM,MACtBM,EAAUA,EAAQG,aAC9B,CACA,CAEA,CAiEWd,OA3KEA,SAAmBtH,EAASgE,EAAYqE,GAC/C,MAAMvF,cAAEA,EAAexD,MAAAA,GAqHhB,SAAagJ,EAAYtE,GAC1B,MAAAuE,EAAgBb,EAAeY,GAC/BE,EAAgBd,EAAe1D,GAE/BlB,EAoBC,SAAoByF,EAAeC,GACtC,IAAAC,MAAmBP,IAGnBQ,MAAsB5C,IAC1B,IAAA,MAAWzF,GAAEA,EAAAZ,QAAIA,KAAa8I,EACxBG,EAAgBnJ,IAAIc,GACtBoI,EAAaN,IAAI9H,GAEDqI,EAAAzC,IAAI5F,EAAIZ,GAIxB,IAAAqD,MAAoBoF,IACxB,IAAA,MAAW7H,GAAEA,EAAAZ,QAAIA,KAAa+I,EACxB1F,EAAcvD,IAAIc,GACpBoI,EAAaN,IAAI9H,GACRqI,EAAgBvI,IAAIE,KAAQZ,GACrCqD,EAAcqF,IAAI9H,GAKtB,IAAA,MAAWA,KAAMoI,EACf3F,EAAcX,OAAO9B,GAEhB,OAAAyC,CACb,CA/C4B6F,CAAoBJ,EAAeC,GAGrD,IAAAlJ,MAAYwG,IACMkC,EAAA1I,EAAOwD,EAAewF,EAAYC,GAGlD,MAAAK,EAAU5E,EAAW6E,iBAAmB7E,EAGvC,OAFegE,EAAA1I,EAAOwD,EAAe8F,EAASJ,GAE9C,CAAE1F,gBAAexD,QAC9B,CApIuCwJ,CAAa9I,EAASgE,GAEjD+E,EA4BR,SAAuBV,GACrB,IAAIW,EAAcC,OAAOC,OAAO,CAAA,EAAIrL,GAe7B,OAZAoL,OAAAC,OAAOF,EAAaX,GAG3BW,EAAYjL,UAAYkL,OAAOC,OAC7B,CAAE,EACFrL,EAASE,UACTsK,EAAOtK,WAIGiL,EAAAzK,KAAO0K,OAAOC,OAAO,CAAE,EAAErL,EAASU,KAAM8J,EAAO9J,MAEpDyK,CACb,CA7C2BG,CAAcd,GAC7BvK,EAAaiL,EAAajL,YAAc,YAC9C,IAAK,CAAC,YAAa,aAAasL,SAAStL,GACvC,KAAM,wCAAwCA,IAGzC,MAAA,CACLiE,OAAQ/B,EACRgE,aACAqE,OAAQU,EACRjL,aACAmG,aAAc8E,EAAa9E,aAC3BL,kBAAmBmF,EAAanF,kBAChC7E,aAAcgK,EAAahK,aAC3BO,QACAwD,gBACAzB,OAAQkG,IACRxJ,UAAWgL,EAAahL,UACxBQ,KAAMwK,EAAaxK,KAE3B,CAqJA,CApL0C,IAyLlC8K,iBAAEA,EAAAC,gBAAkBA,GAAiC,WAEnD,MAAAC,MAA2BC,QAmIjC,MAAO,CAAEH,iBA5HT,SAA0B5G,GACxB,OAAIA,aAAmBgH,SACdhH,EAAQiH,gBAERjH,CAEf,EAsH+B6G,gBA/G3B,SAASA,EAAgBtF,GACvB,GAAkB,MAAdA,EACK,OAAAtH,SAASC,cAAc,OACtC,GAAuC,iBAAfqH,EACTsF,OAAAA,EAgEX,SAAsBtF,GAChB,IAAA2F,EAAS,IAAIC,UAGbC,EAAyB7F,EAAW8F,QACtC,uCACA,IAKA,GAAAD,EAAuBE,MAAM,aAC7BF,EAAuBE,MAAM,aAC7BF,EAAuBE,MAAM,YAC7B,CACA,IAAItH,EAAUkH,EAAOK,gBAAgBhG,EAAY,aAE7C,GAAA6F,EAAuBE,MAAM,YAExB,OADPR,EAAqBpB,IAAI1F,GAClBA,EACF,CAEL,IAAIwH,EAAcxH,EAAQC,WAInB,OAHHuH,GACFV,EAAqBpB,IAAI8B,GAEpBA,CACjB,CACA,CAAa,CAGL,IAIIxH,EAJckH,EAAOK,gBACvB,mBAAqBhG,EAAa,qBAClC,aAGYD,KAAK/B,cAAc,YAC/B,QAEK,OADPuH,EAAqBpB,IAAI1F,GAClBA,CACf,CACA,CAzG+ByH,CAAalG,OAEpCuF,EAAqBhK,IAA4ByE,GAGjD,OAAA,EACR,GAAiBA,aAAsBmG,KAAM,CACrC,GAAInG,EAAWzC,WAIb,OAyBN,SAA+ByC,GAC7B,MAAA,CAEIrB,WAAY,CAACqB,GAEb+D,iBAAmBqC,IAEX,MAAAxC,EAAW5D,EAAW+D,iBAAiBqC,GAEtC,OAAApG,EAAWqG,QAAQD,GAAK,CAACpG,KAAe4D,GAAYA,CAAA,EAG7DlI,aAAc,CAAC4K,EAAGC,IAAMvG,EAAWzC,WAAW7B,aAAa4K,EAAGC,GAE9DnJ,WAAY,CAACkJ,EAAGC,IAAMvG,EAAWzC,WAAWH,WAAWkJ,EAAGC,GAE1D,mBAAI1B,GACK,OAAA7E,CACR,EAGX,CA9CiBwG,CAAsBxG,GACxB,CAEC,MAAAyG,EAAc/N,SAASC,cAAc,OAEpC,OADP8N,EAAYC,OAAO1G,GACZyG,CACjB,CACA,CAAa,CAGC,MAAAA,EAAc/N,SAASC,cAAc,OAC3C,IAAA,MAAW+B,IAAO,IAAIsF,GACpByG,EAAYC,OAAOhM,GAEd,OAAA+L,CACf,CACA,EAiFA,CAtI6D,GA2IpD,MAAA,CACLE,MA9nCF,SAAe3K,EAASgE,EAAYqE,EAAS,CAAA,GAC3CrI,EAAUqJ,EAAiBrJ,GACrB,MAAAC,EAAUqJ,EAAgBtF,GAC1B3E,EAAMiI,EAAmBtH,EAASC,EAASoI,GAE3CuC,EAyDC,SAAoBvL,EAAKwL,SAChC,IAAKxL,EAAIgJ,OAAOtJ,oBAAqB8L,IACjC,IAAA3J,EAEAxE,SAAS,cAIb,KAEIwE,aAAyB6D,kBACzB7D,aAAyBiE,qBAG3B,OAAO0F,IAGT,MAAQxK,GAAIyK,EAAiBC,eAAAA,EAAAC,aAAgBA,GAAiB9J,EAExD+J,EAAUJ,IAEZC,GAAmBA,KAAoB,OAAAxJ,EAAS5E,SAAAwE,wBAAeb,MACjEa,EAAgB7B,EAAI0C,OAAOC,cAAc,IAAI8I,KAC9B,MAAA5J,GAAAA,EAAAgK,SAEbhK,IAAkBA,EAAc8J,cAAgBA,GACpC9J,EAAAiK,kBAAkBJ,EAAgBC,GAG3C,OAAAC,CACX,CAvFyBG,CAAoB/L,GAAK,IAsrBhD,SAA0BA,EAAKW,EAASC,EAASoL,GAC3C,GAAAhM,EAAId,KAAK+M,MAAO,CACZ,MAAA/F,EAAUvF,EAAQgC,cAAc,QAChCwD,EAAUvF,EAAQ+B,cAAc,QACtC,GAAIuD,GAAWC,EAAS,CACtB,MAAMiB,EAAWrC,EAAkBmB,EAASC,EAASnG,GAErD,OAAO2H,QAAQuE,IAAI9E,GAAU+E,MAAK,KAC1B,MAAAC,EAASxC,OAAOC,OAAO7J,EAAK,CAChCd,KAAM,CACJ+M,OAAO,EACPnH,QAAQ,KAGZ,OAAOkH,EAASI,EAAM,GAEhC,CACA,CAEI,OAAOJ,EAAShM,EACpB,CAzsBaqM,CACLrM,EACAW,EACAC,GACkCZ,GACT,cAAnBA,EAAIvB,YACQuB,EAAAA,EAAKW,EAASC,GACrB4H,MAAMC,KAAK9H,EAAQ2C,aAoB3B,SAAetD,EAAKW,EAASC,GAC9B,MAAAf,EAAYoK,EAAgBtJ,GAIlC,IAAI2C,EAAakF,MAAMC,KAAK5I,EAAUyD,YAChC,MAAAgJ,EAAQhJ,EAAWiJ,QAAQ5L,GAE3B6L,EAAclJ,EAAWiC,QAAU+G,EAAQ,GAajD,OAXA3M,EACEK,EACAH,EACAe,EAEAD,EACAA,EAAQc,aAIG6B,EAAAkF,MAAMC,KAAK5I,EAAUyD,YAC3BA,EAAWmJ,MAAMH,EAAOhJ,EAAWiC,OAASiH,EACvD,CAxCmBE,CAAe1M,EAAKW,EAASC,OAOrC,OADPZ,EAAIgC,OAAO2K,SACJpB,CACX,EAwmCI/M,WAEJ,CA3rCiB,GC/FjB,MAAMoO,EAAc,CAAC,EACfC,EAAc,CAAC,EAERC,EAAU,CAACzH,EAAM0H,KACtBF,EAAAxH,GAAQuE,OAAOC,OAAO,CAAA,EAAIgD,EAAOxH,GAAO0H,GAC3CH,EAAOvH,IACVuH,EAAOvH,GAAM2H,SAAiBC,GAAAA,EAAMF,IAAO,EAGhCG,EAAY,CAAC7H,EAAM8H,KAC/BP,EAAOvH,GAAQuH,EAAOvH,IAAS,GACxBuH,EAAAvH,GAAM6B,KAAKiG,GACd9H,KAAQwH,GACJM,EAAAN,EAAOxH,IAER,KACCuH,EAAAvH,GAAQuH,EAAOvH,GAAM+H,QAAQ5B,GAAMA,GAAM2B,GAAO,GCb5CE,EAAY,EAAGhI,OAAMiI,OAAAA,EAAQC,eAAclM,OAAMmM,UAAAA,EAAWC,SAAQC,SAAAA,YAE5E,IAAAC,EACAC,EAAY,GAEV,MAAAC,EAAWP,EAAOQ,OAAS,CAAC,EAC5BC,EAAiB,IAAIC,SAAU,UAAU3M,EAAK/B,aAAa,eAAiB,OAA3D,GACjB2O,EAAU5M,EAAK/B,aAAa,SAC5B4O,EAAY7M,EAAK/B,aAAa,gBAC9B6O,EAASX,EAAWS,GACpBzQ,EAAUD,EAAEC,MAAO0Q,GACnBJ,GHQaM,GGRE,OAAAnM,EAAA,MAAAqL,OAAA,EAAAA,EAAQQ,YAAR,EAAA7L,EAAeoM,OAAQR,EAAO,CAAES,IAAIjN,EAAM0M,iBAAkBF,EHS1EU,KAAKC,MAAMD,KAAKE,UAAUL,KADf,IAACA,EGPnB,MAAMM,EAAU9E,OAAOC,OAAO,CAAI,EAAArM,EAAOsQ,EAAOC,GAC1CY,EAAUrB,EAAOqB,KAAMrB,EAAOqB,KAAQC,GAASA,EAE/CC,EAAO,CACZxJ,OACAyI,QACAQ,IAAKjN,EACLyN,SAAUX,EAAIW,SACdvB,eACAT,UACAI,YAEA,IAAA6B,CAAKvD,GACCnK,EAAAwG,iBAAiB,SAAU2D,EACjC,EAKAkD,MAAQ,CAEP,SAAAM,CAAWC,GACV,IAAIA,EAGI,OAAArB,EAFIA,EAAAqB,CAIb,EAEA,IAAAC,CAAKN,GACAA,EAAKO,cAAgBnB,SACxBY,EAAMF,GAEC9E,OAAAC,OAAO6E,EAAOE,EAEvB,EAEA,GAAAhI,CAAKgI,GAEJ,IAAKvR,SAASqH,KAAK9C,SAASP,GAC3B,OAEGuN,EAAKO,cAAgBnB,SACxBY,EAAKF,GAEE9E,OAAAC,OAAO6E,EAAOE,GAGtB,MAAMQ,EAAWxF,OAAOC,OAAO,CAAA,EAAI6E,EAAOlR,GAEnC,OAAA,IAAImK,SAASF,IACnB4H,EAAOD,GAAU,IAAM3H,EAAQ2H,IAAS,GAE1C,EAEAtO,IAAM,IACE8I,OAAOC,OAAO,CAAC,EAAG6E,IAI3B,OAAAY,CAAS5M,EAAQ2C,GAEV,MACAkK,EAAMlK,GAAa3C,EACnB9E,GAFKyH,EAAM3C,EAASrB,GAETiO,QAAQC,GAErB,GAAU,SAAV3R,EAAyB,OAAA,EACzB,GAAU,UAAVA,EAA0B,OAAA,EAC1B,IAAC4R,MAAM5R,IAA2B,KAAjBA,EAAM6R,OAAsB,OAAAC,OAAO9R,GAEpD,IACH,OAAO,IAAIoQ,SAAS,WAAapQ,EAAQ,IAAlC,EAAuC,CACvC,MAAAqF,GAAA,CAEJ,IACI,OAAAsL,KAAKC,MAAM5Q,EAAK,CAChB,MAAAqF,GAAA,CAED,OAAArF,CACR,EAEA,UAAAsH,CAAYxC,GAEX,IAAIhE,EAAY,GAChB,MAAM4P,EAAM5L,GAAUrB,EAEhBsO,EAAW,IAAIC,kBAAkBC,IACtC,IAAA,MAAWC,KAAYD,EAClB,GAAkB,eAAlBC,EAAS9K,KAAuB,CACnC,MAAMjB,EAAgB+L,EAAS/L,cACrBrF,EAAAsO,SAAS+C,IACdA,EAAK1K,MAAQtB,GACXgM,EAAA/D,SACJjI,EACAuK,EAAIhP,aAAayE,GAClB,GAED,CACF,IAWK,OAPP4L,EAASK,QAAQ3O,EAAM,CAAE6D,YAAY,IAEhC7D,EAAAwG,iBAAiB,YAAY,KACrBnJ,EAAA,KACZiR,EAASM,YAAW,IAGd,CAEN,QAAAC,CAAU7K,EAAM2G,GACftN,EAAUwI,KAAK,CAAE7B,KAAAA,EAAM2G,YACxB,EAEA,UAAAiE,CAAYjE,GACXtN,EAAYA,EAAU0O,QAAQ2C,GAASA,EAAK/D,WAAaA,GAAQ,EAGpE,EAKA,EAAAmE,CAAIC,EAAIC,EAAoBrE,GAEvBA,GACMA,EAAAsE,QAAWrN,IACb,MAAAsN,EAAStN,EAAEsN,QAAU,CAAC,EAC5B,IAAIC,EAASvN,EAAEP,OACf,KAAO8N,IACFA,EAAOxF,QAAQqF,KAClBpN,EAAEwN,eAAiBD,EACVxE,EAAAqC,MAAMhN,EAAM,CAAC4B,GAAGyN,OAAOH,EAAOI,QAEpCH,IAAWnP,IACfmP,EAASA,EAAOtO,UAAA,EAGbb,EAAAwG,iBAAiBuI,EAAIpE,EAASsE,QAAS,CAC3C7C,SACAmD,QAAgB,SAANR,GAAuB,QAANA,GAAsB,cAANA,GAA4B,cAANA,MAI/CC,EAAAC,QAAWrN,IAC7BA,EAAEwN,eAAiBpP,EACAgP,EAAAhC,MAAMhN,EAAM,CAAC4B,GAAGyN,OAAOzN,EAAEsN,OAAOI,MAAK,EAEzDtP,EAAKwG,iBAAiBuI,EAAIC,EAAmBC,QAAS,CAAE7C,WAG1D,EAEA,GAAAoD,CAAKT,EAAIpE,GACJA,EAASsE,SACPjP,EAAAyP,oBAAoBV,EAAIpE,EAASsE,QAExC,EAEA,OAAAS,CAAQX,EAAIC,EAAoBzB,GAC3ByB,EAAmBlB,cAAgB6B,OAEpCxI,MAAAC,KAAKpH,EAAKqH,iBAAiB2H,IAC3BrD,SAAqBrG,IACrBA,EAASsK,cAAc,IAAIC,YAAYd,EAAI,CAAEe,SAAS,EAAMZ,OAAQ,CAAEI,KAAM/B,KAAU,IAGxFvN,EAAK4P,cAAc,IAAIC,YAAYd,EAAI,CAAEe,SAAS,EAAMZ,OAAO,CAAEI,KAAM/B,KAEzE,EAEA,IAAAwC,CAAKhB,EAAIxB,GACRvN,EAAK4P,cAAc,IAAIC,YAAYd,EAAI,CAAEe,SAAS,EAAMZ,OAAQ,CAAEI,KAAM/B,KACzE,EAEA,OAAAyC,CAAS7F,GACHnK,EAAAwG,iBAAiB,WAAY2D,EACnC,EAEA,SAAA7N,CAAY+E,EAAQ4O,GACb,MAAA1O,EAAU0O,EAAO5O,EAASrB,EAC1BkQ,EAAQ3O,EAAQ4O,YAChBC,EAAOH,GAAe5O,EAC5B6O,EAAM5T,UAAY8T,EACRnT,EAAAgN,MAAM1I,EAAS2O,EAAK,GAI1BlC,EAAS,CAAET,EAAM5C,EAAY,UAClC0F,aAAc/D,GACdA,EAAOgE,YAAW,KACX,MAAAF,EAAOtD,EAAIkB,OAAOuC,KAAKC,EAAAA,EAAA,CAAA,EAAIjD,GAASD,EAAKC,IAAQvN,EAAMnD,EAAMX,GACnEe,EAAUgN,MAAOjK,EAAMoQ,EAAMK,EAAiBzQ,EAAMqM,IAC5C/F,QAAAF,UAAU0E,MAAK,KACtB9K,EAAKqH,iBAAiB,WACpBsE,SAASpK,IACH,MAAAmP,EAAQrE,EAAS5M,IAAI8B,GACvBmP,IACEA,EAAArD,MAAMM,YAAYhC,mBAAuB4B,EAAKW,KAC9CwC,EAAArD,MAAM9H,IAAIgI,GAAI,IAEdjH,QAAAF,UAAU0E,MAAK,KACtB5O,EAAEC,MAAQ,CAAC,EACFwO,GAAA,GACT,GACD,GACD,EAKKsB,OAFP+B,EAAQX,GACChB,EAAA9G,IAAKvF,EAAMwN,GACbvB,EAAO0E,QAASnD,EAAK,EAGvBiD,EAAmB,CAAEtB,EAAQ9C,KAAe,CACjDhP,UAAW,CACV,iBAAAG,CAAmBwC,GACd,GAAkB,IAAlBA,EAAKD,SAAiB,CACrB,GAAA,gBAAiBC,EAAK6D,WAClB,OAAA,EAER,GAAIwI,EAAS5M,IAAIO,IAASA,IAASmP,EAC3B,OAAA,CACR,CACD,KC/OG9C,MAAeuE,QAERzO,EAAU,EAAG0O,YAAW1E,UAAAA,EAAW2E,MAAAA,MAE/C,MAAM9M,KAAEA,EAAMiI,OAAAA,EAAAA,aAAQC,GAAiB2E,EAEvC,OAAO,cAAcE,YAEpB,WAAAjD,GACOkD,OAAA,CAGP,iBAAAC,GAEMC,KAAAC,gBAAkB,IAAIC,gBAEtBF,KAAKjT,aAAa,UACtB6S,EAAOI,KAAKrQ,YAGb,MAAMwQ,EAAOrF,EAAU,CACtBhM,KAAKkR,KACLlN,OACAiI,OAAAA,EACAC,eACAC,UAAAA,EACAC,OAAQ8E,KAAKC,gBAAgB/E,OAC7BC,SAAAA,IAGIgF,GAAQA,EAAKvD,cAAgBxH,QACjC+K,EAAKvG,MAAK,KACToG,KAAKtB,cAAe,IAAIC,YAAY,UAAU,IAG/CqB,KAAKtB,cAAe,IAAIC,YAAY,UACrC,CAGD,oBAAAyB,GACCJ,KAAKtB,cAAe,IAAIC,YAAY,aACpCqB,KAAKC,gBAAgBI,OAAM,EAE7B,EC3CKpF,EAAa,CAAC,EAEdxE,EAAS,CACd6J,KAAM,CAAC,KAAM,OAmBDC,EAAYrB,IAElB,MAAAsB,EAAaxE,KAAKE,UAAWgD,GAEnC,OAAO,IAAIzD,SAAS,WAAY,OAAQ,KAAK,iEAG9B+E,EACXtI,QAAQ,iBAAiB,SAASuI,EAAGC,GAC9B,MAAA,4BAA6BxV,EAAWwV,GAAW,OAC1D,IACAxI,QAAQ,gBAAgB,SAASuI,EAAGC,GAC7B,MAAA,KAAOxV,EAAWwV,GAAW,aAAA,gCAGvC,EAGIC,EAAc,CAAExQ,EAAQyQ,EAAMC,KACnC1Q,EACEgG,iBAAkByK,EAAKnV,YACvBgP,SAAS3L,IACT,MAAMgE,EAAOhE,EAAKgS,UAClB,GAAa,aAAThO,EACH,OAAO6N,EAAa7R,EAAK+B,QAAS+P,EAAMC,GAErC/R,EAAK/B,aAAa,aAAe+B,EAAKL,KACzCK,EAAKL,GAAKnD,KAEPwH,KAAQ+N,GACN/R,EAAA8C,aAAa,QAAStG,IAAM,GAElC,EA2BGyV,EAAsB/B,IAE3BA,EAAM7I,iBAAiB,+DACrBsE,SAAUpK,IAEJ,MAAA2Q,EAAW3Q,EAAQtD,aAAa,YAChCkU,EAAU5Q,EAAQtD,aAAa,WAC/BmU,EAAY7Q,EAAQtD,aAAa,cACjCoU,EAAY9Q,EAAQtD,aAAa,cAEvC,GAAKiU,EAAU,CAEd3Q,EAAQwB,gBAAgB,YAExB,MAAMuP,EAAUJ,EAAQ7I,MAAM,mBAAqB,GAC7CkJ,EAAYD,EAAM,GAClBE,EAAWF,EAAM,GACjBG,EAAaD,EAAOF,MAAM,MAAMI,QAChCC,EAAU3W,SAAS4W,eAAe,6EAA6EJ,0EAA+ED,OAAaC,qDAA0DC,MAAeA,UAAmBF,MAAYA,yCACnTM,EAAU7W,SAAS4W,eAAe,4BAEnCE,EAAAH,EAAMpR,EAASsR,EAAK,CAG1B,GAAIV,EAAQ,CACX5Q,EAAQwB,gBAAgB,WACxB,MAAM4P,EAAO3W,SAAS4W,eAAe,oCAAoCT,eACnEU,EAAQ7W,SAAS4W,eAAe,cACjCE,EAAAH,EAAMpR,EAASsR,EAAK,CAGtBT,IACH7Q,EAAQwB,gBAAgB,cAChBxB,EAAAjF,UAAY,OAAO8V,QAGxBC,IACH9Q,EAAQwB,gBAAgB,cACxBxB,EAAQwR,WAAaxR,EAAQwR,UAAY,QAAQV,QAAgBjE,QAGxC,aAAtB7M,EAAQyQ,WACXC,EAAkB1Q,EAAQQ,QAAO,GAElC,EAGGiR,EAAe,CAAE9C,EAAO6B,KAEvB5K,MAAAC,KAAK8I,EAAM7I,iBAAiB,YAChC4L,UACAtH,SAAS3L,IAEH,MAAA4M,EAAQ5M,EAAK/B,aAAa,SAC1B+F,EAAQhE,EAAKgS,UAGnB,GAFKhS,EAAA8C,aAAa,eAAgB,oBAE9BkB,KAAQ+N,GAAcA,EAAW/N,GAAMiI,OAAOwB,SAAW,CAC5D,MAAMnI,EAAWtF,EAAK1D,UAChB8T,EAAO2B,EAAW/N,GAAMiI,OAAOwB,SAAS,CAAER,IAAIjN,EAAMsF,aAC1DtF,EAAK1D,UAAY8T,CAAA,CAGZ,MAAAA,EAvFmB,CAAEA,IAE7B,MAAM8C,EAAY,IAAIC,OAAO,KAAKxL,EAAO6J,KAAK,YAAY7J,EAAO6J,KAAK,KAAM,KAE5E,OAAOpB,EACLhH,QAAQ,oBAAqB,mBAC7BA,QAAQ8J,EAAW,aAGnB9J,QAAQ,uOAAwO,qDAEhPA,QAAQ,6BAA6B,CAACyB,EAAKqD,EAAK3R,IACpC,QAAR2R,GAAyB,UAARA,GAA2B,YAARA,EAChCrD,EAEJtO,EAEI,GAAG2R,kCADF3R,EAAAA,EAAM6M,QAAQ,SAAU,aAGzByB,GAER,EAkEauI,CAAoBpT,EAAKwF,WAEtC2G,EAAWS,GAAU,CACpBa,SAAU2C,EACVpC,OAASyD,EAAQrB,GAClB,GACA,EAGGiD,EAAiCrT,IAGpBA,EAAKqH,iBAAiB,YAE9BsE,SAAS8B,IAElB,GAAIA,EAASxP,aAAa,YAAcwP,EAASxP,aAAa,cAC7D,OAIDoV,EAA8B5F,EAAS1L,SAGvC,MAAMoN,EAAS1B,EAAS5M,WAExB,GAAIsO,EAAQ,CAEX,MAAMpN,EAAU0L,EAAS1L,QACzB,KAAOA,EAAQC,YACPmN,EAAAnQ,aAAa+C,EAAQC,WAAYyL,GAGzC0B,EAAOrO,YAAY2M,EAAQ,IAE5B,EAGIqF,EAAO,CAACH,EAAM3S,EAAM6S,aACpB,OAAAjS,EAAAZ,EAAAa,aAAYD,EAAA5B,aAAa2T,EAAM3S,GACpC,OAAAsT,EAAAtT,EAAKa,aAALyS,EAAiBtU,aAAa6T,EAAO7S,EAAKI,YAAA,EChL3CmT,OAAOC,UAAYD,OAAOC,WAAa,CAAEzB,WAAY,CAAA,GAExC,MAKAjB,EAAQ,CAAEzP,EAASrF,SAASqH,QAElC,MAAA0O,WAAEA,GAAewB,OAAOC,UACxBrH,EDRiB,EAAE9K,GAAU0Q,iBAEtBF,EAAAxQ,EAAQ,IAAIkH,OAAOuJ,KAAMC,GAAc,YAAa,YAAaA,GACxE,MAAA7B,EAAQ7O,EAAO8O,WAAW,GAMzB,OAJP8B,EAAmB/B,GACnBmD,EAA+BnD,GAC/B8C,EAAc9C,EAAO6B,GAEd5F,CAAA,ECDWsB,CAAUpM,EAAQ,CAAE0Q,eAGpCxJ,OAAAzC,OAAQiM,GACRpG,SAAQ,EAAG3H,OAAMiI,OAAAA,EAAQC,mBACpBuH,eAAehU,IAAIuE,IACvByP,eAAeC,OAAQ1P,EAAM7B,EAAQ,CAAE0O,UAAW,CAAE7M,OAAMiI,OAAAA,EAAQC,gBAAgBC,UAAAA,EAAW2E,UAAQ,GAEvG,yBAhBsB,CAAE9M,EAAMiI,EAAQC,KACjC,MAAA6F,WAAEA,GAAewB,OAAOC,UAC9BzB,EAAY/N,GAAS,CAAEA,OAAMiI,OAAAA,EAAQC,eAAa,2CARpByH,IDED,IAACC,ICDtBD,EDEDpL,OAAAC,OAAQb,EAAQiM,ECFP","x_google_ignoreList":[1]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jails-js",
3
- "version": "6.1.0",
3
+ "version": "6.2.0",
4
4
  "description": "Jails - Elegant and Minimalistic Javascript Application Library",
5
5
  "types": "types.d.ts",
6
6
  "module": "./dist/index.js",
package/src/component.ts CHANGED
@@ -74,19 +74,10 @@ export const Component = ({ name, module, dependencies, node, templates, signal,
74
74
  }
75
75
  },
76
76
 
77
- dataset( target, name) {
78
-
79
- let el
80
- let key
81
-
82
- if( name ) {
83
- el = target
84
- key = name
85
- }else {
86
- el = node
87
- key = target
88
- }
77
+ dataset( target, name ) {
89
78
 
79
+ const el = name? target : node
80
+ const key = name? name : target
90
81
  const value = el.dataset[key]
91
82
 
92
83
  if (value === 'true') return true
@@ -94,7 +85,6 @@ export const Component = ({ name, module, dependencies, node, templates, signal,
94
85
  if (!isNaN(value) && value.trim() !== '') return Number(value)
95
86
 
96
87
  try {
97
- // If it's not JSON, try parsing as JS expression
98
88
  return new Function('return (' + value + ')')()
99
89
  } catch {}
100
90
 
@@ -105,6 +95,46 @@ export const Component = ({ name, module, dependencies, node, templates, signal,
105
95
  return value
106
96
  },
107
97
 
98
+ attributes( target ) {
99
+
100
+ let callbacks = []
101
+ const elm = target || node
102
+
103
+ const observer = new MutationObserver((mutationsList) => {
104
+ for (const mutation of mutationsList) {
105
+ if (mutation.type === 'attributes') {
106
+ const attributeName = mutation.attributeName
107
+ callbacks.forEach((item) => {
108
+ if (item.name == attributeName) {
109
+ item.callback(
110
+ attributeName,
111
+ elm.getAttribute(attributeName)
112
+ )
113
+ }
114
+ })
115
+ }
116
+ }
117
+ })
118
+
119
+ observer.observe(node, { attributes: true })
120
+
121
+ node.addEventListener(':unmount', () => {
122
+ callbacks = null
123
+ observer.disconnect()
124
+ })
125
+
126
+ return {
127
+
128
+ onchange( name, callback ) {
129
+ callbacks.push({ name, callback })
130
+ },
131
+
132
+ disconnect( callback ) {
133
+ callbacks = callbacks.filter((item) => item.callback !== callback)
134
+ }
135
+ }
136
+ },
137
+
108
138
  /**
109
139
  * @Events
110
140
  */