@syndicate-lang/html2
Advanced tools
Comparing version 0.35.9 to 0.35.10
@@ -59,4 +59,22 @@ import * as __SYNDICATE__ from '@syndicate-lang/core'; | ||
} | ||
function nodeInserter(n) { | ||
return (vs, node) => { | ||
class NodeInserter { | ||
constructor(variablePartIndex) { | ||
this.variablePartIndex = variablePartIndex; | ||
} | ||
reset(state, node) { | ||
var _a, _b; | ||
if ('nodeCount' in state) { | ||
const previouslyInsertedNodes = state.nodeCount; | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(makePlaceholder(), node); | ||
for (let n = 0; n < previouslyInsertedNodes; n++) { | ||
const nextNode = node.nextSibling; | ||
(_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(node); | ||
if (nextNode === null) | ||
break; | ||
node = nextNode; | ||
} | ||
} | ||
state.nodeCount = 0; | ||
} | ||
act(state, vs, node) { | ||
var _a; | ||
@@ -96,25 +114,73 @@ function walk(f) { | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(newNode, node); | ||
state.nodeCount++; | ||
} | ||
} | ||
walk(vs[n]); | ||
walk(vs[this.variablePartIndex]); | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node); | ||
}; | ||
} | ||
} | ||
function attributesInserter(n) { | ||
return (vs, node) => { | ||
class AttributesInserter { | ||
constructor(variablePartIndex) { | ||
this.variablePartIndex = variablePartIndex; | ||
} | ||
reset(state, node) { | ||
var _a; | ||
const attrNames = ((_a = state.attrNames) !== null && _a !== void 0 ? _a : []); | ||
attrNames.forEach(n => node.removeAttribute(n)); | ||
state.attrNames = []; | ||
} | ||
act(state, vs, node) { | ||
const e = document.createElement('template'); | ||
const n = this.variablePartIndex; | ||
e.innerHTML = `<x-dummy ${renderFragment(vs[n], false).join('')}></x-dummy>`; | ||
Array.from(e.content.firstElementChild.attributes).forEach(a => node.setAttribute(a.name, a.value)); | ||
}; | ||
Array.from(e.content.firstElementChild.attributes).forEach(a => { | ||
state.attrNames.push(a.name); | ||
node.setAttribute(a.name, a.value); | ||
}); | ||
} | ||
} | ||
function attributeValueInserter(attrName, constantParts, placeholders) { | ||
return (vs, node) => { | ||
const pieces = [constantParts[0]]; | ||
placeholders.forEach((n, i) => { | ||
class AttributeValueInserter { | ||
constructor(attrName, constantParts, placeholders) { | ||
this.attrName = attrName; | ||
this.constantParts = constantParts; | ||
this.placeholders = placeholders; | ||
} | ||
reset(_state, _node) { } | ||
act(_state, vs, node) { | ||
const pieces = [this.constantParts[0]]; | ||
this.placeholders.forEach((n, i) => { | ||
pieces.push(...renderFragment(vs[n], false)); | ||
pieces.push(constantParts[i + 1]); | ||
pieces.push(this.constantParts[i + 1]); | ||
}); | ||
node.setAttribute(attrName, pieces.join('')); | ||
}; | ||
node.setAttribute(this.attrName, pieces.join('')); | ||
} | ||
} | ||
class CompoundAction { | ||
constructor(actions) { | ||
this.actions = actions; | ||
} | ||
reset(states, n) { | ||
this.actions.forEach((a, i) => { | ||
var _a; | ||
const state = (_a = states[i]) !== null && _a !== void 0 ? _a : (states[i] = {}); | ||
a.reset(state, n); | ||
}); | ||
} | ||
act(states, vs, n) { | ||
this.actions.forEach((a, i) => { | ||
var _a; | ||
const state = (_a = states[i]) !== null && _a !== void 0 ? _a : (states[i] = {}); | ||
a.act(state, vs, n); | ||
}); | ||
} | ||
} | ||
class HtmlFragmentInstance { | ||
constructor(container) { | ||
this.container = container; | ||
this.state = {}; | ||
} | ||
} | ||
function makePlaceholder() { | ||
return document.createElement('x-placeholder'); | ||
} | ||
class HtmlFragmentBuilder { | ||
@@ -139,4 +205,3 @@ constructor(constantParts) { | ||
if (i > 0) { | ||
const placeholder = document.createElement('x-placeholder'); | ||
(_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(placeholder, n); | ||
(_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(makePlaceholder(), n); | ||
} | ||
@@ -149,6 +214,6 @@ (_b = n.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(document.createTextNode(c), n); | ||
const currentPath = path.slice(); | ||
currentPath[currentPath.length - 1] = i * 2 + 1; | ||
currentPath[currentPath.length - 1] += i * 2 + 1; | ||
this.placeholderActions.push({ | ||
path: currentPath, | ||
action: nodeInserter(n), | ||
action: new NodeInserter(n), | ||
}); | ||
@@ -169,3 +234,3 @@ }); | ||
const n = parseInt(nameIsPlaceholder[1], 10); | ||
actions.push(attributesInserter(n)); | ||
actions.push(new AttributesInserter(n)); | ||
} | ||
@@ -175,3 +240,3 @@ else { | ||
if (constantParts.length !== 1) { | ||
actions.push(attributeValueInserter(attrName, constantParts, placeholders)); | ||
actions.push(new AttributeValueInserter(attrName, constantParts, placeholders)); | ||
} | ||
@@ -183,3 +248,3 @@ } | ||
path: path.slice(), | ||
action: (vs, n) => actions.forEach(a => a(vs, n)), | ||
action: actions.length === 1 ? actions[0] : new CompoundAction(actions), | ||
}); | ||
@@ -218,8 +283,17 @@ } | ||
clone() { | ||
return Array.from(this.template.cloneNode(true).content.childNodes); | ||
return new HtmlFragmentInstance(Array.from(this.template.cloneNode(true).content.childNodes)); | ||
} | ||
update(template, variableParts) { | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
action(variableParts, followPath(template, path)); | ||
var _a; | ||
var _b, _c; | ||
const state = (_a = (_b = template.state)[_c = path.map(n => '' + n).join('.')]) !== null && _a !== void 0 ? _a : (_b[_c] = {}); | ||
action.reset(state, followPath(template.container, path)); | ||
}); | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
var _a; | ||
var _b, _c; | ||
const state = (_a = (_b = template.state)[_c = path.map(n => '' + n).join('.')]) !== null && _a !== void 0 ? _a : (_b[_c] = {}); | ||
action.act(state, variableParts, followPath(template.container, path)); | ||
}); | ||
} | ||
@@ -231,3 +305,3 @@ } | ||
function template() { | ||
let container = null; | ||
let instance = null; | ||
return (constantParts, ...variableParts) => { | ||
@@ -239,7 +313,7 @@ let b = templateCache.get(constantParts); | ||
} | ||
if (container === null) { | ||
container = b.clone(); | ||
if (instance === null) { | ||
instance = b.clone(); | ||
} | ||
b.update(container, variableParts); | ||
return container; | ||
b.update(instance, variableParts); | ||
return instance.container; | ||
}; | ||
@@ -246,0 +320,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import*as e from"@syndicate-lang/core";import{randomId as t,Dataspace as n,Turn as r}from"@syndicate-lang/core";const a=t(8,!0),s=new RegExp(`x-${a}-(\\d+)-${a}-x`),o=new RegExp(`x-${a}-(\\d+)-${a}-x`,"g");function i(e){let t=null,n=0;const r=[],a=[];for(;null!==(t=o.exec(e));)r.push(e.substring(n,t.index)),a.push(parseInt(t[1],10)),n=o.lastIndex;return r.push(e.substring(n)),{constantParts:r,placeholders:a}}function l(e,t){const n=[];return function e(r){if(Array.isArray(r))r.forEach(e);else switch(typeof r){case"string":n.push(t?r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):r);break;case"number":n.push(""+r);break;default:throw new Error("Cannot render Node in attribute context")}}(e),n}function c(e){return(t,n)=>{var r;!function e(t){var r;if(Array.isArray(t))t.forEach(e);else{let e;switch(typeof t){case"string":e=document.createTextNode(t);break;case"number":e=document.createTextNode(""+t);break;case"object":if(null!==t&&"nodeType"in t){e=t;break}default:{let n;try{n=""+t}catch(e){n=t.toString()}e=document.createTextNode(`<ERROR: invalid HtmlFragment: ${n}>`);break}}null===(r=n.parentNode)||void 0===r||r.insertBefore(e,n)}}(t[e]),null===(r=n.parentNode)||void 0===r||r.removeChild(n)}}function u(e){return(t,n)=>{const r=document.createElement("template");r.innerHTML=`<x-dummy ${l(t[e],!1).join("")}></x-dummy>`,Array.from(r.content.firstElementChild.attributes).forEach((e=>n.setAttribute(e.name,e.value)))}}function h(e,t,n){return(r,a)=>{const s=[t[0]];n.forEach(((e,n)=>{s.push(...l(r[e],!1)),s.push(t[n+1])})),a.setAttribute(e,s.join(""))}}class d{constructor(e){this.template=document.createElement("template"),this.placeholderActions=[];const t=[];e.raw.forEach(((e,n)=>{n>0&&t.push(`x-${a}-${n-1}-${a}-x`),t.push(e)})),this.template.innerHTML=t.join(""),this.indexPlaceholders()}indexTextNode(e,t){var n,r;const{constantParts:a,placeholders:s}=i(null!==(n=e.textContent)&&void 0!==n?n:"");a.forEach(((t,n)=>{var r,a;if(n>0){const t=document.createElement("x-placeholder");null===(r=e.parentNode)||void 0===r||r.insertBefore(t,e)}null===(a=e.parentNode)||void 0===a||a.insertBefore(document.createTextNode(t),e)}));const o=e.nextSibling;return null===(r=e.parentNode)||void 0===r||r.removeChild(e),s.forEach(((e,n)=>{const r=t.slice();r[r.length-1]=2*n+1,this.placeholderActions.push({path:r,action:c(e)})})),t[t.length-1]+=a.length+s.length,o}indexElement(e,t){const n=[];for(let t=0;t<e.attributes.length;t++){const r=e.attributes[t],a=r.name,o=a.match(s);if(null!==o){e.removeAttributeNode(r),t--;const a=parseInt(o[1],10);n.push(u(a))}else{const{constantParts:e,placeholders:t}=i(r.value);1!==e.length&&n.push(h(a,e,t))}}n.length&&this.placeholderActions.push({path:t.slice(),action:(e,t)=>n.forEach((n=>n(e,t)))})}indexPlaceholders(){const e=[],t=n=>{e.push(0);let r=n.firstChild;for(;null!==r;){const n=r;switch(n.nodeType){case Node.TEXT_NODE:r=this.indexTextNode(n,e);break;case Node.ELEMENT_NODE:{const a=n;this.indexElement(a,e),t(a),r=a.nextSibling,e[e.length-1]++;break}default:r=n.nextSibling,e[e.length-1]++}}e.pop()};t(this.template.content)}clone(){return Array.from(this.template.cloneNode(!0).content.childNodes)}update(e,t){this.placeholderActions.forEach((({path:n,action:r})=>{r(t,function(e,t){let n=e[t[0]];for(let e=1;e<t.length;e++)n=n.childNodes[t[e]];return n}(e,n))}))}}const p=new WeakMap;function v(){let e=null;return(t,...n)=>{let r=p.get(t);return void 0===r&&(r=new d(t),p.set(t,r)),null===e&&(e=r.clone()),r.update(e,n),e}}const f=e.Record.makeConstructor()(Symbol.for("LocationHash"),["hash"]);function m(t=n.local){!function(t){e.Dataspace._spawn((()=>{e.Turn.activeFacet.actor.name="LocationHashTracker",(t=>{const n=e.Turn.active.field("/","hashValue"),a=()=>{var e=decodeURIComponent(window.location.hash);e.length&&"#"===e[0]&&(e=e.slice(1)),n.value=e||"/"},s=r.activeFacet,o=()=>s.turn(a);window.addEventListener("hashchange",o),e.Turn.activeFacet.onStop((()=>{window.removeEventListener("hashchange",o)})),a(),e.Turn.active.assertDataflow((()=>({target:t(),assertion:f(n.value)}))),e.Turn.active.assertDataflow((()=>({target:t(),assertion:e.Observe({pattern:e.QuasiValue.finish(e.QuasiValue.ctor(f,e.QuasiValue.bind(e.QuasiValue._))),observer:e.Turn.ref({message:e=>{if(Array.isArray(e)){if("string"!=typeof e[0])return;const t=e[0];window.location.hash=t}}})})})))})((()=>t))}))}(t)}class g{get node(){return this._node}constructor(t,n){let a;this._node=null,this.callbacks=new Map,a="object"==typeof n?E(t,n):"function"==typeof t?t:()=>[t],this.facet=r.activeFacet;const s=this.facet.actor.atExit((()=>this.node.remove()));e.Turn.activeFacet.onStop((()=>{this.node.remove(),s()}));const o=v();e.Turn.active._dataflow((()=>{const e=a(o);if(1!==e.length)throw new Error("@syndicate-lang/html2: Expected exactly one node from template");if(null===this._node)this._node=e[0];else if(this._node!==e[0])throw new Error("@syndicate-lang/html2: Node generator is not stable")}))}get _nodeAsParent(){return this._node&&"querySelector"in this._node?this._node:null}get parent(){return this.node.parentNode}set parent(e){this.setParent(e)}setParent(e,t=document){return"string"==typeof e&&(e=t.querySelector(e)),this.node.parentNode!==e&&(null===e?this.node.remove():e.appendChild(this.node)),this}querySelector(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelector(e);return r?new(null!=t?t:g)(r):null}querySelectorAll(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelectorAll(e),a=[];return r&&r.forEach((e=>a.push(new(null!=t?t:g)(e)))),a}on(e,t){return this.addEventListener(e,t),this}once(e,t){return this.addEventListener(e,t,{once:!0}),this}off(e,t){return this.removeEventListener(e,t),this}addEventListener(e,t,n){if(null===t)return;let r=this.callbacks.get(e);if(void 0===r)r=new Map,this.callbacks.set(e,r);else if(r.has(t))return;const a={wrapped:"function"==typeof t?e=>this.facet.turn((()=>t(e))):e=>this.facet.turn((()=>t.handleEvent(e))),options:n};r.set(t,a),this.node.addEventListener(e,a.wrapped,n)}dispatchEvent(e){return this.node.dispatchEvent(e)}removeEventListener(e,t,n){if(null===t)return;const r=this.callbacks.get(e);if(void 0===r)return;const a=r.get(t);void 0!==a&&(this.node.removeEventListener(e,a.wrapped,n),r.delete(t),0===r.size&&this.callbacks.delete(e))}}class b extends g{constructor(t,n,r){super(t,n);const a="string"==typeof n?n:"string"==typeof r?r:"change",s=e.Turn.active.field("","value");this._value=s;const o=e.Turn.active.field(NaN,"valueAsNumber");this._valueAsNumber=o,"value"in this.node&&(this.on(a,(()=>this.readValues())),this.readValues(),e.Turn.active._dataflow((()=>{this.valueAsNumber=this._valueAsNumber.value})),e.Turn.active._dataflow((()=>{this.value=this._value.value})))}readValues(){var e,t;const n=this.node;this.suppressCycleWarning(),this._value.value=null!==(e=n.value)&&void 0!==e?e:"",this._valueAsNumber.value=null!==(t=n.valueAsNumber)&&void 0!==t?t:NaN}get value(){return this._value.value}set value(e){this.node.value=e,this._value.value=e}get valueAsNumber(){return this._valueAsNumber.value}set valueAsNumber(e){this.node.value=Number.isNaN(e)?"":""+e,this._valueAsNumber.value=e}suppressCycleWarning(){this._value.suppressCycleWarning(),this._valueAsNumber.suppressCycleWarning()}}function E(e,t){const n="string"==typeof e?document.querySelector(e):e;if(null===n)throw new Error("Cannot find template: "+e);const r=`return t => t\`${n.innerHTML.trim().split("`").join("\\`")}\``,a=Object.entries(t),s=a.map((e=>e[0])),o=a.map((e=>e[1]));return new Function(...s,r)(...o)}export{f as LocationHash,b as ValueWidget,g as Widget,m as boot,v as template,E as templateGenerator}; | ||
import*as e from"@syndicate-lang/core";import{randomId as t,Dataspace as n,Turn as r}from"@syndicate-lang/core";const a=t(8,!0),s=new RegExp(`x-${a}-(\\d+)-${a}-x`),o=new RegExp(`x-${a}-(\\d+)-${a}-x`,"g");function i(e){let t=null,n=0;const r=[],a=[];for(;null!==(t=o.exec(e));)r.push(e.substring(n,t.index)),a.push(parseInt(t[1],10)),n=o.lastIndex;return r.push(e.substring(n)),{constantParts:r,placeholders:a}}function l(e,t){const n=[];return function e(r){if(Array.isArray(r))r.forEach(e);else switch(typeof r){case"string":n.push(t?r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):r);break;case"number":n.push(""+r);break;default:throw new Error("Cannot render Node in attribute context")}}(e),n}function c(e,t){let n=e[t[0]];for(let e=1;e<t.length;e++)n=n.childNodes[t[e]];return n}class u{constructor(e){this.variablePartIndex=e}reset(e,t){var n,r;if("nodeCount"in e){const a=e.nodeCount;null===(n=t.parentNode)||void 0===n||n.insertBefore(f(),t);for(let e=0;e<a;e++){const e=t.nextSibling;if(null===(r=t.parentNode)||void 0===r||r.removeChild(t),null===e)break;t=e}}e.nodeCount=0}act(e,t,n){var r;!function t(r){var a;if(Array.isArray(r))r.forEach(t);else{let t;switch(typeof r){case"string":t=document.createTextNode(r);break;case"number":t=document.createTextNode(""+r);break;case"object":if(null!==r&&"nodeType"in r){t=r;break}default:{let e;try{e=""+r}catch(t){e=r.toString()}t=document.createTextNode(`<ERROR: invalid HtmlFragment: ${e}>`);break}}null===(a=n.parentNode)||void 0===a||a.insertBefore(t,n),e.nodeCount++}}(t[this.variablePartIndex]),null===(r=n.parentNode)||void 0===r||r.removeChild(n)}}class h{constructor(e){this.variablePartIndex=e}reset(e,t){var n;(null!==(n=e.attrNames)&&void 0!==n?n:[]).forEach((e=>t.removeAttribute(e))),e.attrNames=[]}act(e,t,n){const r=document.createElement("template"),a=this.variablePartIndex;r.innerHTML=`<x-dummy ${l(t[a],!1).join("")}></x-dummy>`,Array.from(r.content.firstElementChild.attributes).forEach((t=>{e.attrNames.push(t.name),n.setAttribute(t.name,t.value)}))}}class d{constructor(e,t,n){this.attrName=e,this.constantParts=t,this.placeholders=n}reset(e,t){}act(e,t,n){const r=[this.constantParts[0]];this.placeholders.forEach(((e,n)=>{r.push(...l(t[e],!1)),r.push(this.constantParts[n+1])})),n.setAttribute(this.attrName,r.join(""))}}class v{constructor(e){this.actions=e}reset(e,t){this.actions.forEach(((n,r)=>{var a;const s=null!==(a=e[r])&&void 0!==a?a:e[r]={};n.reset(s,t)}))}act(e,t,n){this.actions.forEach(((r,a)=>{var s;const o=null!==(s=e[a])&&void 0!==s?s:e[a]={};r.act(o,t,n)}))}}class p{constructor(e){this.container=e,this.state={}}}function f(){return document.createElement("x-placeholder")}class m{constructor(e){this.template=document.createElement("template"),this.placeholderActions=[];const t=[];e.raw.forEach(((e,n)=>{n>0&&t.push(`x-${a}-${n-1}-${a}-x`),t.push(e)})),this.template.innerHTML=t.join(""),this.indexPlaceholders()}indexTextNode(e,t){var n,r;const{constantParts:a,placeholders:s}=i(null!==(n=e.textContent)&&void 0!==n?n:"");a.forEach(((t,n)=>{var r,a;n>0&&(null===(r=e.parentNode)||void 0===r||r.insertBefore(f(),e)),null===(a=e.parentNode)||void 0===a||a.insertBefore(document.createTextNode(t),e)}));const o=e.nextSibling;return null===(r=e.parentNode)||void 0===r||r.removeChild(e),s.forEach(((e,n)=>{const r=t.slice();r[r.length-1]+=2*n+1,this.placeholderActions.push({path:r,action:new u(e)})})),t[t.length-1]+=a.length+s.length,o}indexElement(e,t){const n=[];for(let t=0;t<e.attributes.length;t++){const r=e.attributes[t],a=r.name,o=a.match(s);if(null!==o){e.removeAttributeNode(r),t--;const a=parseInt(o[1],10);n.push(new h(a))}else{const{constantParts:e,placeholders:t}=i(r.value);1!==e.length&&n.push(new d(a,e,t))}}n.length&&this.placeholderActions.push({path:t.slice(),action:1===n.length?n[0]:new v(n)})}indexPlaceholders(){const e=[],t=n=>{e.push(0);let r=n.firstChild;for(;null!==r;){const n=r;switch(n.nodeType){case Node.TEXT_NODE:r=this.indexTextNode(n,e);break;case Node.ELEMENT_NODE:{const a=n;this.indexElement(a,e),t(a),r=a.nextSibling,e[e.length-1]++;break}default:r=n.nextSibling,e[e.length-1]++}}e.pop()};t(this.template.content)}clone(){return new p(Array.from(this.template.cloneNode(!0).content.childNodes))}update(e,t){this.placeholderActions.forEach((({path:t,action:n})=>{var r,a,s;const o=null!==(r=(a=e.state)[s=t.map((e=>""+e)).join(".")])&&void 0!==r?r:a[s]={};n.reset(o,c(e.container,t))})),this.placeholderActions.forEach((({path:n,action:r})=>{var a,s,o;const i=null!==(a=(s=e.state)[o=n.map((e=>""+e)).join(".")])&&void 0!==a?a:s[o]={};r.act(i,t,c(e.container,n))}))}}const g=new WeakMap;function b(){let e=null;return(t,...n)=>{let r=g.get(t);return void 0===r&&(r=new m(t),g.set(t,r)),null===e&&(e=r.clone()),r.update(e,n),e.container}}const N=e.Record.makeConstructor()(Symbol.for("LocationHash"),["hash"]);function E(t=n.local){!function(t){e.Dataspace._spawn((()=>{e.Turn.activeFacet.actor.name="LocationHashTracker",(t=>{const n=e.Turn.active.field("/","hashValue"),a=()=>{var e=decodeURIComponent(window.location.hash);e.length&&"#"===e[0]&&(e=e.slice(1)),n.value=e||"/"},s=r.activeFacet,o=()=>s.turn(a);window.addEventListener("hashchange",o),e.Turn.activeFacet.onStop((()=>{window.removeEventListener("hashchange",o)})),a(),e.Turn.active.assertDataflow((()=>({target:t(),assertion:N(n.value)}))),e.Turn.active.assertDataflow((()=>({target:t(),assertion:e.Observe({pattern:e.QuasiValue.finish(e.QuasiValue.ctor(N,e.QuasiValue.bind(e.QuasiValue._))),observer:e.Turn.ref({message:e=>{if(Array.isArray(e)){if("string"!=typeof e[0])return;const t=e[0];window.location.hash=t}}})})})))})((()=>t))}))}(t)}class w{get node(){return this._node}constructor(t,n){let a;this._node=null,this.callbacks=new Map,a="object"==typeof n?y(t,n):"function"==typeof t?t:()=>[t],this.facet=r.activeFacet;const s=this.facet.actor.atExit((()=>this.node.remove()));e.Turn.activeFacet.onStop((()=>{this.node.remove(),s()}));const o=b();e.Turn.active._dataflow((()=>{const e=a(o);if(1!==e.length)throw new Error("@syndicate-lang/html2: Expected exactly one node from template");if(null===this._node)this._node=e[0];else if(this._node!==e[0])throw new Error("@syndicate-lang/html2: Node generator is not stable")}))}get _nodeAsParent(){return this._node&&"querySelector"in this._node?this._node:null}get parent(){return this.node.parentNode}set parent(e){this.setParent(e)}setParent(e,t=document){return"string"==typeof e&&(e=t.querySelector(e)),this.node.parentNode!==e&&(null===e?this.node.remove():e.appendChild(this.node)),this}querySelector(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelector(e);return r?new(null!=t?t:w)(r):null}querySelectorAll(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelectorAll(e),a=[];return r&&r.forEach((e=>a.push(new(null!=t?t:w)(e)))),a}on(e,t){return this.addEventListener(e,t),this}once(e,t){return this.addEventListener(e,t,{once:!0}),this}off(e,t){return this.removeEventListener(e,t),this}addEventListener(e,t,n){if(null===t)return;let r=this.callbacks.get(e);if(void 0===r)r=new Map,this.callbacks.set(e,r);else if(r.has(t))return;const a={wrapped:"function"==typeof t?e=>this.facet.turn((()=>t(e))):e=>this.facet.turn((()=>t.handleEvent(e))),options:n};r.set(t,a),this.node.addEventListener(e,a.wrapped,n)}dispatchEvent(e){return this.node.dispatchEvent(e)}removeEventListener(e,t,n){if(null===t)return;const r=this.callbacks.get(e);if(void 0===r)return;const a=r.get(t);void 0!==a&&(this.node.removeEventListener(e,a.wrapped,n),r.delete(t),0===r.size&&this.callbacks.delete(e))}}class x extends w{constructor(t,n,r){super(t,n);const a="string"==typeof n?n:"string"==typeof r?r:"change",s=e.Turn.active.field("","value");this._value=s;const o=e.Turn.active.field(NaN,"valueAsNumber");this._valueAsNumber=o,"value"in this.node&&(this.on(a,(()=>this.readValues())),this.readValues(),e.Turn.active._dataflow((()=>{this.valueAsNumber=this._valueAsNumber.value})),e.Turn.active._dataflow((()=>{this.value=this._value.value})))}readValues(){var e,t;const n=this.node;this.suppressCycleWarning(),this._value.value=null!==(e=n.value)&&void 0!==e?e:"",this._valueAsNumber.value=null!==(t=n.valueAsNumber)&&void 0!==t?t:NaN}get value(){return this._value.value}set value(e){this.node.value=e,this._value.value=e}get valueAsNumber(){return this._valueAsNumber.value}set valueAsNumber(e){this.node.value=Number.isNaN(e)?"":""+e,this._valueAsNumber.value=e}suppressCycleWarning(){this._value.suppressCycleWarning(),this._valueAsNumber.suppressCycleWarning()}}function y(e,t){const n="string"==typeof e?document.querySelector(e):e;if(null===n)throw new Error("Cannot find template: "+e);const r=`return t => t\`${n.innerHTML.trim().split("`").join("\\`")}\``,a=Object.entries(t),s=a.map((e=>e[0])),o=a.map((e=>e[1]));return new Function(...s,r)(...o)}export{N as LocationHash,x as ValueWidget,w as Widget,E as boot,b as template,y as templateGenerator}; | ||
//# sourceMappingURL=syndicate-html2.es6.min.js.map |
@@ -82,4 +82,22 @@ (function (global, factory) { | ||
} | ||
function nodeInserter(n) { | ||
return (vs, node) => { | ||
class NodeInserter { | ||
constructor(variablePartIndex) { | ||
this.variablePartIndex = variablePartIndex; | ||
} | ||
reset(state, node) { | ||
var _a, _b; | ||
if ('nodeCount' in state) { | ||
const previouslyInsertedNodes = state.nodeCount; | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(makePlaceholder(), node); | ||
for (let n = 0; n < previouslyInsertedNodes; n++) { | ||
const nextNode = node.nextSibling; | ||
(_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(node); | ||
if (nextNode === null) | ||
break; | ||
node = nextNode; | ||
} | ||
} | ||
state.nodeCount = 0; | ||
} | ||
act(state, vs, node) { | ||
var _a; | ||
@@ -119,25 +137,73 @@ function walk(f) { | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(newNode, node); | ||
state.nodeCount++; | ||
} | ||
} | ||
walk(vs[n]); | ||
walk(vs[this.variablePartIndex]); | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node); | ||
}; | ||
} | ||
} | ||
function attributesInserter(n) { | ||
return (vs, node) => { | ||
class AttributesInserter { | ||
constructor(variablePartIndex) { | ||
this.variablePartIndex = variablePartIndex; | ||
} | ||
reset(state, node) { | ||
var _a; | ||
const attrNames = ((_a = state.attrNames) !== null && _a !== void 0 ? _a : []); | ||
attrNames.forEach(n => node.removeAttribute(n)); | ||
state.attrNames = []; | ||
} | ||
act(state, vs, node) { | ||
const e = document.createElement('template'); | ||
const n = this.variablePartIndex; | ||
e.innerHTML = `<x-dummy ${renderFragment(vs[n], false).join('')}></x-dummy>`; | ||
Array.from(e.content.firstElementChild.attributes).forEach(a => node.setAttribute(a.name, a.value)); | ||
}; | ||
Array.from(e.content.firstElementChild.attributes).forEach(a => { | ||
state.attrNames.push(a.name); | ||
node.setAttribute(a.name, a.value); | ||
}); | ||
} | ||
} | ||
function attributeValueInserter(attrName, constantParts, placeholders) { | ||
return (vs, node) => { | ||
const pieces = [constantParts[0]]; | ||
placeholders.forEach((n, i) => { | ||
class AttributeValueInserter { | ||
constructor(attrName, constantParts, placeholders) { | ||
this.attrName = attrName; | ||
this.constantParts = constantParts; | ||
this.placeholders = placeholders; | ||
} | ||
reset(_state, _node) { } | ||
act(_state, vs, node) { | ||
const pieces = [this.constantParts[0]]; | ||
this.placeholders.forEach((n, i) => { | ||
pieces.push(...renderFragment(vs[n], false)); | ||
pieces.push(constantParts[i + 1]); | ||
pieces.push(this.constantParts[i + 1]); | ||
}); | ||
node.setAttribute(attrName, pieces.join('')); | ||
}; | ||
node.setAttribute(this.attrName, pieces.join('')); | ||
} | ||
} | ||
class CompoundAction { | ||
constructor(actions) { | ||
this.actions = actions; | ||
} | ||
reset(states, n) { | ||
this.actions.forEach((a, i) => { | ||
var _a; | ||
const state = (_a = states[i]) !== null && _a !== void 0 ? _a : (states[i] = {}); | ||
a.reset(state, n); | ||
}); | ||
} | ||
act(states, vs, n) { | ||
this.actions.forEach((a, i) => { | ||
var _a; | ||
const state = (_a = states[i]) !== null && _a !== void 0 ? _a : (states[i] = {}); | ||
a.act(state, vs, n); | ||
}); | ||
} | ||
} | ||
class HtmlFragmentInstance { | ||
constructor(container) { | ||
this.container = container; | ||
this.state = {}; | ||
} | ||
} | ||
function makePlaceholder() { | ||
return document.createElement('x-placeholder'); | ||
} | ||
class HtmlFragmentBuilder { | ||
@@ -162,4 +228,3 @@ constructor(constantParts) { | ||
if (i > 0) { | ||
const placeholder = document.createElement('x-placeholder'); | ||
(_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(placeholder, n); | ||
(_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(makePlaceholder(), n); | ||
} | ||
@@ -172,6 +237,6 @@ (_b = n.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(document.createTextNode(c), n); | ||
const currentPath = path.slice(); | ||
currentPath[currentPath.length - 1] = i * 2 + 1; | ||
currentPath[currentPath.length - 1] += i * 2 + 1; | ||
this.placeholderActions.push({ | ||
path: currentPath, | ||
action: nodeInserter(n), | ||
action: new NodeInserter(n), | ||
}); | ||
@@ -192,3 +257,3 @@ }); | ||
const n = parseInt(nameIsPlaceholder[1], 10); | ||
actions.push(attributesInserter(n)); | ||
actions.push(new AttributesInserter(n)); | ||
} | ||
@@ -198,3 +263,3 @@ else { | ||
if (constantParts.length !== 1) { | ||
actions.push(attributeValueInserter(attrName, constantParts, placeholders)); | ||
actions.push(new AttributeValueInserter(attrName, constantParts, placeholders)); | ||
} | ||
@@ -206,3 +271,3 @@ } | ||
path: path.slice(), | ||
action: (vs, n) => actions.forEach(a => a(vs, n)), | ||
action: actions.length === 1 ? actions[0] : new CompoundAction(actions), | ||
}); | ||
@@ -241,8 +306,17 @@ } | ||
clone() { | ||
return Array.from(this.template.cloneNode(true).content.childNodes); | ||
return new HtmlFragmentInstance(Array.from(this.template.cloneNode(true).content.childNodes)); | ||
} | ||
update(template, variableParts) { | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
action(variableParts, followPath(template, path)); | ||
var _a; | ||
var _b, _c; | ||
const state = (_a = (_b = template.state)[_c = path.map(n => '' + n).join('.')]) !== null && _a !== void 0 ? _a : (_b[_c] = {}); | ||
action.reset(state, followPath(template.container, path)); | ||
}); | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
var _a; | ||
var _b, _c; | ||
const state = (_a = (_b = template.state)[_c = path.map(n => '' + n).join('.')]) !== null && _a !== void 0 ? _a : (_b[_c] = {}); | ||
action.act(state, variableParts, followPath(template.container, path)); | ||
}); | ||
} | ||
@@ -254,3 +328,3 @@ } | ||
function template() { | ||
let container = null; | ||
let instance = null; | ||
return (constantParts, ...variableParts) => { | ||
@@ -262,7 +336,7 @@ let b = templateCache.get(constantParts); | ||
} | ||
if (container === null) { | ||
container = b.clone(); | ||
if (instance === null) { | ||
instance = b.clone(); | ||
} | ||
b.update(container, variableParts); | ||
return container; | ||
b.update(instance, variableParts); | ||
return instance.container; | ||
}; | ||
@@ -269,0 +343,0 @@ } |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@syndicate-lang/core")):"function"==typeof define&&define.amd?define(["exports","@syndicate-lang/core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SyndicateHtml2={},e.Syndicate)}(this,(function(e,t){"use strict";function n(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var r=n(t);const a=t.randomId(8,!0),o=new RegExp(`x-${a}-(\\d+)-${a}-x`),s=new RegExp(`x-${a}-(\\d+)-${a}-x`,"g");function i(e){let t=null,n=0;const r=[],a=[];for(;null!==(t=s.exec(e));)r.push(e.substring(n,t.index)),a.push(parseInt(t[1],10)),n=s.lastIndex;return r.push(e.substring(n)),{constantParts:r,placeholders:a}}function l(e,t){const n=[];return function e(r){if(Array.isArray(r))r.forEach(e);else switch(typeof r){case"string":n.push(t?r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):r);break;case"number":n.push(""+r);break;default:throw new Error("Cannot render Node in attribute context")}}(e),n}function c(e){return(t,n)=>{var r;!function e(t){var r;if(Array.isArray(t))t.forEach(e);else{let e;switch(typeof t){case"string":e=document.createTextNode(t);break;case"number":e=document.createTextNode(""+t);break;case"object":if(null!==t&&"nodeType"in t){e=t;break}default:{let n;try{n=""+t}catch(e){n=t.toString()}e=document.createTextNode(`<ERROR: invalid HtmlFragment: ${n}>`);break}}null===(r=n.parentNode)||void 0===r||r.insertBefore(e,n)}}(t[e]),null===(r=n.parentNode)||void 0===r||r.removeChild(n)}}function u(e){return(t,n)=>{const r=document.createElement("template");r.innerHTML=`<x-dummy ${l(t[e],!1).join("")}></x-dummy>`,Array.from(r.content.firstElementChild.attributes).forEach((e=>n.setAttribute(e.name,e.value)))}}function d(e,t,n){return(r,a)=>{const o=[t[0]];n.forEach(((e,n)=>{o.push(...l(r[e],!1)),o.push(t[n+1])})),a.setAttribute(e,o.join(""))}}class h{constructor(e){this.template=document.createElement("template"),this.placeholderActions=[];const t=[];e.raw.forEach(((e,n)=>{n>0&&t.push(`x-${a}-${n-1}-${a}-x`),t.push(e)})),this.template.innerHTML=t.join(""),this.indexPlaceholders()}indexTextNode(e,t){var n,r;const{constantParts:a,placeholders:o}=i(null!==(n=e.textContent)&&void 0!==n?n:"");a.forEach(((t,n)=>{var r,a;if(n>0){const t=document.createElement("x-placeholder");null===(r=e.parentNode)||void 0===r||r.insertBefore(t,e)}null===(a=e.parentNode)||void 0===a||a.insertBefore(document.createTextNode(t),e)}));const s=e.nextSibling;return null===(r=e.parentNode)||void 0===r||r.removeChild(e),o.forEach(((e,n)=>{const r=t.slice();r[r.length-1]=2*n+1,this.placeholderActions.push({path:r,action:c(e)})})),t[t.length-1]+=a.length+o.length,s}indexElement(e,t){const n=[];for(let t=0;t<e.attributes.length;t++){const r=e.attributes[t],a=r.name,s=a.match(o);if(null!==s){e.removeAttributeNode(r),t--;const a=parseInt(s[1],10);n.push(u(a))}else{const{constantParts:e,placeholders:t}=i(r.value);1!==e.length&&n.push(d(a,e,t))}}n.length&&this.placeholderActions.push({path:t.slice(),action:(e,t)=>n.forEach((n=>n(e,t)))})}indexPlaceholders(){const e=[],t=n=>{e.push(0);let r=n.firstChild;for(;null!==r;){const n=r;switch(n.nodeType){case Node.TEXT_NODE:r=this.indexTextNode(n,e);break;case Node.ELEMENT_NODE:{const a=n;this.indexElement(a,e),t(a),r=a.nextSibling,e[e.length-1]++;break}default:r=n.nextSibling,e[e.length-1]++}}e.pop()};t(this.template.content)}clone(){return Array.from(this.template.cloneNode(!0).content.childNodes)}update(e,t){this.placeholderActions.forEach((({path:n,action:r})=>{r(t,function(e,t){let n=e[t[0]];for(let e=1;e<t.length;e++)n=n.childNodes[t[e]];return n}(e,n))}))}}const p=new WeakMap;function f(){let e=null;return(t,...n)=>{let r=p.get(t);return void 0===r&&(r=new h(t),p.set(t,r)),null===e&&(e=r.clone()),r.update(e,n),e}}const v=r.Record.makeConstructor()(Symbol.for("LocationHash"),["hash"]);class m{get node(){return this._node}constructor(e,n){let a;this._node=null,this.callbacks=new Map,a="object"==typeof n?g(e,n):"function"==typeof e?e:()=>[e],this.facet=t.Turn.activeFacet;const o=this.facet.actor.atExit((()=>this.node.remove()));r.Turn.activeFacet.onStop((()=>{this.node.remove(),o()}));const s=f();r.Turn.active._dataflow((()=>{const e=a(s);if(1!==e.length)throw new Error("@syndicate-lang/html2: Expected exactly one node from template");if(null===this._node)this._node=e[0];else if(this._node!==e[0])throw new Error("@syndicate-lang/html2: Node generator is not stable")}))}get _nodeAsParent(){return this._node&&"querySelector"in this._node?this._node:null}get parent(){return this.node.parentNode}set parent(e){this.setParent(e)}setParent(e,t=document){return"string"==typeof e&&(e=t.querySelector(e)),this.node.parentNode!==e&&(null===e?this.node.remove():e.appendChild(this.node)),this}querySelector(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelector(e);return r?new(null!=t?t:m)(r):null}querySelectorAll(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelectorAll(e),a=[];return r&&r.forEach((e=>a.push(new(null!=t?t:m)(e)))),a}on(e,t){return this.addEventListener(e,t),this}once(e,t){return this.addEventListener(e,t,{once:!0}),this}off(e,t){return this.removeEventListener(e,t),this}addEventListener(e,t,n){if(null===t)return;let r=this.callbacks.get(e);if(void 0===r)r=new Map,this.callbacks.set(e,r);else if(r.has(t))return;const a={wrapped:"function"==typeof t?e=>this.facet.turn((()=>t(e))):e=>this.facet.turn((()=>t.handleEvent(e))),options:n};r.set(t,a),this.node.addEventListener(e,a.wrapped,n)}dispatchEvent(e){return this.node.dispatchEvent(e)}removeEventListener(e,t,n){if(null===t)return;const r=this.callbacks.get(e);if(void 0===r)return;const a=r.get(t);void 0!==a&&(this.node.removeEventListener(e,a.wrapped,n),r.delete(t),0===r.size&&this.callbacks.delete(e))}}function g(e,t){const n="string"==typeof e?document.querySelector(e):e;if(null===n)throw new Error("Cannot find template: "+e);const r=`return t => t\`${n.innerHTML.trim().split("`").join("\\`")}\``,a=Object.entries(t),o=a.map((e=>e[0])),s=a.map((e=>e[1]));return new Function(...o,r)(...s)}e.LocationHash=v,e.ValueWidget=class extends m{constructor(e,t,n){super(e,t);const a="string"==typeof t?t:"string"==typeof n?n:"change",o=r.Turn.active.field("","value");this._value=o;const s=r.Turn.active.field(NaN,"valueAsNumber");this._valueAsNumber=s,"value"in this.node&&(this.on(a,(()=>this.readValues())),this.readValues(),r.Turn.active._dataflow((()=>{this.valueAsNumber=this._valueAsNumber.value})),r.Turn.active._dataflow((()=>{this.value=this._value.value})))}readValues(){var e,t;const n=this.node;this.suppressCycleWarning(),this._value.value=null!==(e=n.value)&&void 0!==e?e:"",this._valueAsNumber.value=null!==(t=n.valueAsNumber)&&void 0!==t?t:NaN}get value(){return this._value.value}set value(e){this.node.value=e,this._value.value=e}get valueAsNumber(){return this._valueAsNumber.value}set valueAsNumber(e){this.node.value=Number.isNaN(e)?"":""+e,this._valueAsNumber.value=e}suppressCycleWarning(){this._value.suppressCycleWarning(),this._valueAsNumber.suppressCycleWarning()}},e.Widget=m,e.boot=function(e=t.Dataspace.local){!function(e){r.Dataspace._spawn((()=>{r.Turn.activeFacet.actor.name="LocationHashTracker",(e=>{const n=r.Turn.active.field("/","hashValue"),a=()=>{var e=decodeURIComponent(window.location.hash);e.length&&"#"===e[0]&&(e=e.slice(1)),n.value=e||"/"},o=t.Turn.activeFacet,s=()=>o.turn(a);window.addEventListener("hashchange",s),r.Turn.activeFacet.onStop((()=>{window.removeEventListener("hashchange",s)})),a(),r.Turn.active.assertDataflow((()=>({target:e(),assertion:v(n.value)}))),r.Turn.active.assertDataflow((()=>({target:e(),assertion:r.Observe({pattern:r.QuasiValue.finish(r.QuasiValue.ctor(v,r.QuasiValue.bind(r.QuasiValue._))),observer:r.Turn.ref({message:e=>{if(Array.isArray(e)){if("string"!=typeof e[0])return;const t=e[0];window.location.hash=t}}})})})))})((()=>e))}))}(e)},e.template=f,e.templateGenerator=g,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@syndicate-lang/core")):"function"==typeof define&&define.amd?define(["exports","@syndicate-lang/core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SyndicateHtml2={},e.Syndicate)}(this,(function(e,t){"use strict";function n(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var r=n(t);const a=t.randomId(8,!0),s=new RegExp(`x-${a}-(\\d+)-${a}-x`),o=new RegExp(`x-${a}-(\\d+)-${a}-x`,"g");function i(e){let t=null,n=0;const r=[],a=[];for(;null!==(t=o.exec(e));)r.push(e.substring(n,t.index)),a.push(parseInt(t[1],10)),n=o.lastIndex;return r.push(e.substring(n)),{constantParts:r,placeholders:a}}function l(e,t){const n=[];return function e(r){if(Array.isArray(r))r.forEach(e);else switch(typeof r){case"string":n.push(t?r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'"):r);break;case"number":n.push(""+r);break;default:throw new Error("Cannot render Node in attribute context")}}(e),n}function c(e,t){let n=e[t[0]];for(let e=1;e<t.length;e++)n=n.childNodes[t[e]];return n}class u{constructor(e){this.variablePartIndex=e}reset(e,t){var n,r;if("nodeCount"in e){const a=e.nodeCount;null===(n=t.parentNode)||void 0===n||n.insertBefore(f(),t);for(let e=0;e<a;e++){const e=t.nextSibling;if(null===(r=t.parentNode)||void 0===r||r.removeChild(t),null===e)break;t=e}}e.nodeCount=0}act(e,t,n){var r;!function t(r){var a;if(Array.isArray(r))r.forEach(t);else{let t;switch(typeof r){case"string":t=document.createTextNode(r);break;case"number":t=document.createTextNode(""+r);break;case"object":if(null!==r&&"nodeType"in r){t=r;break}default:{let e;try{e=""+r}catch(t){e=r.toString()}t=document.createTextNode(`<ERROR: invalid HtmlFragment: ${e}>`);break}}null===(a=n.parentNode)||void 0===a||a.insertBefore(t,n),e.nodeCount++}}(t[this.variablePartIndex]),null===(r=n.parentNode)||void 0===r||r.removeChild(n)}}class d{constructor(e){this.variablePartIndex=e}reset(e,t){var n;(null!==(n=e.attrNames)&&void 0!==n?n:[]).forEach((e=>t.removeAttribute(e))),e.attrNames=[]}act(e,t,n){const r=document.createElement("template"),a=this.variablePartIndex;r.innerHTML=`<x-dummy ${l(t[a],!1).join("")}></x-dummy>`,Array.from(r.content.firstElementChild.attributes).forEach((t=>{e.attrNames.push(t.name),n.setAttribute(t.name,t.value)}))}}class h{constructor(e,t,n){this.attrName=e,this.constantParts=t,this.placeholders=n}reset(e,t){}act(e,t,n){const r=[this.constantParts[0]];this.placeholders.forEach(((e,n)=>{r.push(...l(t[e],!1)),r.push(this.constantParts[n+1])})),n.setAttribute(this.attrName,r.join(""))}}class p{constructor(e){this.actions=e}reset(e,t){this.actions.forEach(((n,r)=>{var a;const s=null!==(a=e[r])&&void 0!==a?a:e[r]={};n.reset(s,t)}))}act(e,t,n){this.actions.forEach(((r,a)=>{var s;const o=null!==(s=e[a])&&void 0!==s?s:e[a]={};r.act(o,t,n)}))}}class v{constructor(e){this.container=e,this.state={}}}function f(){return document.createElement("x-placeholder")}class m{constructor(e){this.template=document.createElement("template"),this.placeholderActions=[];const t=[];e.raw.forEach(((e,n)=>{n>0&&t.push(`x-${a}-${n-1}-${a}-x`),t.push(e)})),this.template.innerHTML=t.join(""),this.indexPlaceholders()}indexTextNode(e,t){var n,r;const{constantParts:a,placeholders:s}=i(null!==(n=e.textContent)&&void 0!==n?n:"");a.forEach(((t,n)=>{var r,a;n>0&&(null===(r=e.parentNode)||void 0===r||r.insertBefore(f(),e)),null===(a=e.parentNode)||void 0===a||a.insertBefore(document.createTextNode(t),e)}));const o=e.nextSibling;return null===(r=e.parentNode)||void 0===r||r.removeChild(e),s.forEach(((e,n)=>{const r=t.slice();r[r.length-1]+=2*n+1,this.placeholderActions.push({path:r,action:new u(e)})})),t[t.length-1]+=a.length+s.length,o}indexElement(e,t){const n=[];for(let t=0;t<e.attributes.length;t++){const r=e.attributes[t],a=r.name,o=a.match(s);if(null!==o){e.removeAttributeNode(r),t--;const a=parseInt(o[1],10);n.push(new d(a))}else{const{constantParts:e,placeholders:t}=i(r.value);1!==e.length&&n.push(new h(a,e,t))}}n.length&&this.placeholderActions.push({path:t.slice(),action:1===n.length?n[0]:new p(n)})}indexPlaceholders(){const e=[],t=n=>{e.push(0);let r=n.firstChild;for(;null!==r;){const n=r;switch(n.nodeType){case Node.TEXT_NODE:r=this.indexTextNode(n,e);break;case Node.ELEMENT_NODE:{const a=n;this.indexElement(a,e),t(a),r=a.nextSibling,e[e.length-1]++;break}default:r=n.nextSibling,e[e.length-1]++}}e.pop()};t(this.template.content)}clone(){return new v(Array.from(this.template.cloneNode(!0).content.childNodes))}update(e,t){this.placeholderActions.forEach((({path:t,action:n})=>{var r,a,s;const o=null!==(r=(a=e.state)[s=t.map((e=>""+e)).join(".")])&&void 0!==r?r:a[s]={};n.reset(o,c(e.container,t))})),this.placeholderActions.forEach((({path:n,action:r})=>{var a,s,o;const i=null!==(a=(s=e.state)[o=n.map((e=>""+e)).join(".")])&&void 0!==a?a:s[o]={};r.act(i,t,c(e.container,n))}))}}const g=new WeakMap;function b(){let e=null;return(t,...n)=>{let r=g.get(t);return void 0===r&&(r=new m(t),g.set(t,r)),null===e&&(e=r.clone()),r.update(e,n),e.container}}const y=r.Record.makeConstructor()(Symbol.for("LocationHash"),["hash"]);class N{get node(){return this._node}constructor(e,n){let a;this._node=null,this.callbacks=new Map,a="object"==typeof n?E(e,n):"function"==typeof e?e:()=>[e],this.facet=t.Turn.activeFacet;const s=this.facet.actor.atExit((()=>this.node.remove()));r.Turn.activeFacet.onStop((()=>{this.node.remove(),s()}));const o=b();r.Turn.active._dataflow((()=>{const e=a(o);if(1!==e.length)throw new Error("@syndicate-lang/html2: Expected exactly one node from template");if(null===this._node)this._node=e[0];else if(this._node!==e[0])throw new Error("@syndicate-lang/html2: Node generator is not stable")}))}get _nodeAsParent(){return this._node&&"querySelector"in this._node?this._node:null}get parent(){return this.node.parentNode}set parent(e){this.setParent(e)}setParent(e,t=document){return"string"==typeof e&&(e=t.querySelector(e)),this.node.parentNode!==e&&(null===e?this.node.remove():e.appendChild(this.node)),this}querySelector(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelector(e);return r?new(null!=t?t:N)(r):null}querySelectorAll(e,t){var n;const r=null===(n=this._nodeAsParent)||void 0===n?void 0:n.querySelectorAll(e),a=[];return r&&r.forEach((e=>a.push(new(null!=t?t:N)(e)))),a}on(e,t){return this.addEventListener(e,t),this}once(e,t){return this.addEventListener(e,t,{once:!0}),this}off(e,t){return this.removeEventListener(e,t),this}addEventListener(e,t,n){if(null===t)return;let r=this.callbacks.get(e);if(void 0===r)r=new Map,this.callbacks.set(e,r);else if(r.has(t))return;const a={wrapped:"function"==typeof t?e=>this.facet.turn((()=>t(e))):e=>this.facet.turn((()=>t.handleEvent(e))),options:n};r.set(t,a),this.node.addEventListener(e,a.wrapped,n)}dispatchEvent(e){return this.node.dispatchEvent(e)}removeEventListener(e,t,n){if(null===t)return;const r=this.callbacks.get(e);if(void 0===r)return;const a=r.get(t);void 0!==a&&(this.node.removeEventListener(e,a.wrapped,n),r.delete(t),0===r.size&&this.callbacks.delete(e))}}function E(e,t){const n="string"==typeof e?document.querySelector(e):e;if(null===n)throw new Error("Cannot find template: "+e);const r=`return t => t\`${n.innerHTML.trim().split("`").join("\\`")}\``,a=Object.entries(t),s=a.map((e=>e[0])),o=a.map((e=>e[1]));return new Function(...s,r)(...o)}e.LocationHash=y,e.ValueWidget=class extends N{constructor(e,t,n){super(e,t);const a="string"==typeof t?t:"string"==typeof n?n:"change",s=r.Turn.active.field("","value");this._value=s;const o=r.Turn.active.field(NaN,"valueAsNumber");this._valueAsNumber=o,"value"in this.node&&(this.on(a,(()=>this.readValues())),this.readValues(),r.Turn.active._dataflow((()=>{this.valueAsNumber=this._valueAsNumber.value})),r.Turn.active._dataflow((()=>{this.value=this._value.value})))}readValues(){var e,t;const n=this.node;this.suppressCycleWarning(),this._value.value=null!==(e=n.value)&&void 0!==e?e:"",this._valueAsNumber.value=null!==(t=n.valueAsNumber)&&void 0!==t?t:NaN}get value(){return this._value.value}set value(e){this.node.value=e,this._value.value=e}get valueAsNumber(){return this._valueAsNumber.value}set valueAsNumber(e){this.node.value=Number.isNaN(e)?"":""+e,this._valueAsNumber.value=e}suppressCycleWarning(){this._value.suppressCycleWarning(),this._valueAsNumber.suppressCycleWarning()}},e.Widget=N,e.boot=function(e=t.Dataspace.local){!function(e){r.Dataspace._spawn((()=>{r.Turn.activeFacet.actor.name="LocationHashTracker",(e=>{const n=r.Turn.active.field("/","hashValue"),a=()=>{var e=decodeURIComponent(window.location.hash);e.length&&"#"===e[0]&&(e=e.slice(1)),n.value=e||"/"},s=t.Turn.activeFacet,o=()=>s.turn(a);window.addEventListener("hashchange",o),r.Turn.activeFacet.onStop((()=>{window.removeEventListener("hashchange",o)})),a(),r.Turn.active.assertDataflow((()=>({target:e(),assertion:y(n.value)}))),r.Turn.active.assertDataflow((()=>({target:e(),assertion:r.Observe({pattern:r.QuasiValue.finish(r.QuasiValue.ctor(y,r.QuasiValue.bind(r.QuasiValue._))),observer:r.Turn.ref({message:e=>{if(Array.isArray(e)){if("string"!=typeof e[0])return;const t=e[0];window.location.hash=t}}})})})))})((()=>e))}))}(e)},e.template=b,e.templateGenerator=E,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=syndicate-html2.min.js.map |
export declare function escape(s: string): string; | ||
export type HtmlFragment = string | number | Node | Array<HtmlFragment>; | ||
type PlaceholderAction = (variableParts: HtmlFragment[], node: Node) => void; | ||
type PlaceholderState = { | ||
[key: string]: any; | ||
}; | ||
interface PlaceholderAction { | ||
reset(state: PlaceholderState, node: Node): void; | ||
act(state: PlaceholderState, variableParts: HtmlFragment[], node: Node): void; | ||
} | ||
export declare class HtmlFragmentInstance { | ||
container: ChildNode[]; | ||
state: { | ||
[path: string]: PlaceholderState; | ||
}; | ||
constructor(container: ChildNode[]); | ||
} | ||
export declare class HtmlFragmentBuilder { | ||
@@ -14,4 +27,4 @@ template: HTMLTemplateElement; | ||
private indexPlaceholders; | ||
clone(): ChildNode[]; | ||
update(template: ChildNode[], variableParts: Array<HtmlFragment>): void; | ||
clone(): HtmlFragmentInstance; | ||
update(template: HtmlFragmentInstance, variableParts: Array<HtmlFragment>): void; | ||
} | ||
@@ -18,0 +31,0 @@ export type HtmlTemplater = (constantParts: TemplateStringsArray, ...variableParts: Array<HtmlFragment>) => ChildNode[]; |
132
lib/html.js
@@ -58,4 +58,22 @@ /// SPDX-License-Identifier: GPL-3.0-or-later | ||
} | ||
function nodeInserter(n) { | ||
return (vs, node) => { | ||
class NodeInserter { | ||
constructor(variablePartIndex) { | ||
this.variablePartIndex = variablePartIndex; | ||
} | ||
reset(state, node) { | ||
var _a, _b; | ||
if ('nodeCount' in state) { | ||
const previouslyInsertedNodes = state.nodeCount; | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(makePlaceholder(), node); | ||
for (let n = 0; n < previouslyInsertedNodes; n++) { | ||
const nextNode = node.nextSibling; | ||
(_b = node.parentNode) === null || _b === void 0 ? void 0 : _b.removeChild(node); | ||
if (nextNode === null) | ||
break; | ||
node = nextNode; | ||
} | ||
} | ||
state.nodeCount = 0; | ||
} | ||
act(state, vs, node) { | ||
var _a; | ||
@@ -95,25 +113,73 @@ function walk(f) { | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(newNode, node); | ||
state.nodeCount++; | ||
} | ||
} | ||
walk(vs[n]); | ||
walk(vs[this.variablePartIndex]); | ||
(_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(node); | ||
}; | ||
} | ||
} | ||
function attributesInserter(n) { | ||
return (vs, node) => { | ||
class AttributesInserter { | ||
constructor(variablePartIndex) { | ||
this.variablePartIndex = variablePartIndex; | ||
} | ||
reset(state, node) { | ||
var _a; | ||
const attrNames = ((_a = state.attrNames) !== null && _a !== void 0 ? _a : []); | ||
attrNames.forEach(n => node.removeAttribute(n)); | ||
state.attrNames = []; | ||
} | ||
act(state, vs, node) { | ||
const e = document.createElement('template'); | ||
const n = this.variablePartIndex; | ||
e.innerHTML = `<x-dummy ${renderFragment(vs[n], false).join('')}></x-dummy>`; | ||
Array.from(e.content.firstElementChild.attributes).forEach(a => node.setAttribute(a.name, a.value)); | ||
}; | ||
Array.from(e.content.firstElementChild.attributes).forEach(a => { | ||
state.attrNames.push(a.name); | ||
node.setAttribute(a.name, a.value); | ||
}); | ||
} | ||
} | ||
function attributeValueInserter(attrName, constantParts, placeholders) { | ||
return (vs, node) => { | ||
const pieces = [constantParts[0]]; | ||
placeholders.forEach((n, i) => { | ||
class AttributeValueInserter { | ||
constructor(attrName, constantParts, placeholders) { | ||
this.attrName = attrName; | ||
this.constantParts = constantParts; | ||
this.placeholders = placeholders; | ||
} | ||
reset(_state, _node) { } | ||
act(_state, vs, node) { | ||
const pieces = [this.constantParts[0]]; | ||
this.placeholders.forEach((n, i) => { | ||
pieces.push(...renderFragment(vs[n], false)); | ||
pieces.push(constantParts[i + 1]); | ||
pieces.push(this.constantParts[i + 1]); | ||
}); | ||
node.setAttribute(attrName, pieces.join('')); | ||
}; | ||
node.setAttribute(this.attrName, pieces.join('')); | ||
} | ||
} | ||
class CompoundAction { | ||
constructor(actions) { | ||
this.actions = actions; | ||
} | ||
reset(states, n) { | ||
this.actions.forEach((a, i) => { | ||
var _a; | ||
const state = (_a = states[i]) !== null && _a !== void 0 ? _a : (states[i] = {}); | ||
a.reset(state, n); | ||
}); | ||
} | ||
act(states, vs, n) { | ||
this.actions.forEach((a, i) => { | ||
var _a; | ||
const state = (_a = states[i]) !== null && _a !== void 0 ? _a : (states[i] = {}); | ||
a.act(state, vs, n); | ||
}); | ||
} | ||
} | ||
export class HtmlFragmentInstance { | ||
constructor(container) { | ||
this.container = container; | ||
this.state = {}; | ||
} | ||
} | ||
function makePlaceholder() { | ||
return document.createElement('x-placeholder'); | ||
} | ||
export class HtmlFragmentBuilder { | ||
@@ -138,4 +204,3 @@ constructor(constantParts) { | ||
if (i > 0) { | ||
const placeholder = document.createElement('x-placeholder'); | ||
(_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(placeholder, n); | ||
(_a = n.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(makePlaceholder(), n); | ||
} | ||
@@ -148,6 +213,6 @@ (_b = n.parentNode) === null || _b === void 0 ? void 0 : _b.insertBefore(document.createTextNode(c), n); | ||
const currentPath = path.slice(); | ||
currentPath[currentPath.length - 1] = i * 2 + 1; | ||
currentPath[currentPath.length - 1] += i * 2 + 1; | ||
this.placeholderActions.push({ | ||
path: currentPath, | ||
action: nodeInserter(n), | ||
action: new NodeInserter(n), | ||
}); | ||
@@ -168,3 +233,3 @@ }); | ||
const n = parseInt(nameIsPlaceholder[1], 10); | ||
actions.push(attributesInserter(n)); | ||
actions.push(new AttributesInserter(n)); | ||
} | ||
@@ -174,3 +239,3 @@ else { | ||
if (constantParts.length !== 1) { | ||
actions.push(attributeValueInserter(attrName, constantParts, placeholders)); | ||
actions.push(new AttributeValueInserter(attrName, constantParts, placeholders)); | ||
} | ||
@@ -182,3 +247,3 @@ } | ||
path: path.slice(), | ||
action: (vs, n) => actions.forEach(a => a(vs, n)), | ||
action: actions.length === 1 ? actions[0] : new CompoundAction(actions), | ||
}); | ||
@@ -217,8 +282,17 @@ } | ||
clone() { | ||
return Array.from(this.template.cloneNode(true).content.childNodes); | ||
return new HtmlFragmentInstance(Array.from(this.template.cloneNode(true).content.childNodes)); | ||
} | ||
update(template, variableParts) { | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
action(variableParts, followPath(template, path)); | ||
var _a; | ||
var _b, _c; | ||
const state = (_a = (_b = template.state)[_c = path.map(n => '' + n).join('.')]) !== null && _a !== void 0 ? _a : (_b[_c] = {}); | ||
action.reset(state, followPath(template.container, path)); | ||
}); | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
var _a; | ||
var _b, _c; | ||
const state = (_a = (_b = template.state)[_c = path.map(n => '' + n).join('.')]) !== null && _a !== void 0 ? _a : (_b[_c] = {}); | ||
action.act(state, variableParts, followPath(template.container, path)); | ||
}); | ||
} | ||
@@ -230,3 +304,3 @@ } | ||
export function template() { | ||
let container = null; | ||
let instance = null; | ||
return (constantParts, ...variableParts) => { | ||
@@ -238,9 +312,9 @@ let b = templateCache.get(constantParts); | ||
} | ||
if (container === null) { | ||
container = b.clone(); | ||
if (instance === null) { | ||
instance = b.clone(); | ||
} | ||
b.update(container, variableParts); | ||
return container; | ||
b.update(instance, variableParts); | ||
return instance.container; | ||
}; | ||
} | ||
//# sourceMappingURL=html.js.map |
{ | ||
"name": "@syndicate-lang/html2", | ||
"version": "0.35.9", | ||
"version": "0.35.10", | ||
"description": "DOM/HTML UI for Syndicate/JS", | ||
@@ -25,12 +25,14 @@ "homepage": "https://github.com/syndicate-lang/syndicate-js/tree/main/packages/html2", | ||
"clean": "rm -rf lib/ dist/ index.js index.js.map", | ||
"veryclean": "yarn run clean && rm -rf node_modules" | ||
"veryclean": "yarn run clean && rm -rf node_modules", | ||
"test": "../../node_modules/.bin/jest", | ||
"test:watch": "yarn test --watch" | ||
}, | ||
"dependencies": { | ||
"@syndicate-lang/core": "^0.34.8" | ||
"@syndicate-lang/core": "^0.34.9" | ||
}, | ||
"devDependencies": { | ||
"@syndicate-lang/ts-plugin": "^0.36.8", | ||
"@syndicate-lang/tsc": "^0.36.8" | ||
"@syndicate-lang/ts-plugin": "^0.36.9", | ||
"@syndicate-lang/tsc": "^0.36.9" | ||
}, | ||
"gitHead": "8fcea8362c55687e1dca6d839a9202006439e593" | ||
"gitHead": "078c34632bc519f8c00e4aa79e91168509b2506a" | ||
} |
146
src/html.ts
@@ -61,6 +61,27 @@ /// SPDX-License-Identifier: GPL-3.0-or-later | ||
type PlaceholderAction = (variableParts: HtmlFragment[], node: Node) => void; | ||
type PlaceholderState = { [key: string]: any }; | ||
function nodeInserter(n: number): PlaceholderAction { | ||
return (vs, node) => { | ||
interface PlaceholderAction { | ||
reset(state: PlaceholderState, node: Node): void; | ||
act(state: PlaceholderState, variableParts: HtmlFragment[], node: Node): void; | ||
} | ||
class NodeInserter implements PlaceholderAction { | ||
constructor(public variablePartIndex: number) {} | ||
reset(state: PlaceholderState, node: Node) { | ||
if ('nodeCount' in state) { | ||
const previouslyInsertedNodes = state.nodeCount as number; | ||
node.parentNode?.insertBefore(makePlaceholder(), node); | ||
for (let n = 0; n < previouslyInsertedNodes; n++) { | ||
const nextNode = node.nextSibling; | ||
node.parentNode?.removeChild(node); | ||
if (nextNode === null) break; | ||
node = nextNode; | ||
} | ||
} | ||
state.nodeCount = 0; | ||
} | ||
act(state: PlaceholderState, vs: HtmlFragment[], node: Node): void { | ||
function walk(f: HtmlFragment) { | ||
@@ -92,33 +113,78 @@ if (Array.isArray(f)) { | ||
node.parentNode?.insertBefore(newNode, node); | ||
state.nodeCount++; | ||
} | ||
} | ||
walk(vs[n]); | ||
walk(vs[this.variablePartIndex]); | ||
node.parentNode?.removeChild(node); | ||
}; | ||
} | ||
} | ||
function attributesInserter(n: number): PlaceholderAction { | ||
return (vs, node) => { | ||
class AttributesInserter implements PlaceholderAction { | ||
constructor(public variablePartIndex: number) {} | ||
reset(state: PlaceholderState, node: Node): void { | ||
const attrNames: string[] = (state.attrNames ?? []); | ||
attrNames.forEach(n => (node as Element).removeAttribute(n)); | ||
state.attrNames = []; | ||
} | ||
act(state: PlaceholderState, vs: HtmlFragment[], node: Node): void { | ||
const e = document.createElement('template'); | ||
const n = this.variablePartIndex; | ||
e.innerHTML = `<x-dummy ${renderFragment(vs[n], false).join('')}></x-dummy>`; | ||
Array.from(e.content.firstElementChild!.attributes).forEach(a => | ||
(node as Element).setAttribute(a.name, a.value)); | ||
}; | ||
Array.from(e.content.firstElementChild!.attributes).forEach(a => { | ||
state.attrNames.push(a.name); | ||
(node as Element).setAttribute(a.name, a.value); | ||
}); | ||
} | ||
} | ||
function attributeValueInserter( | ||
attrName: string, | ||
constantParts: string[], | ||
placeholders: number[], | ||
): PlaceholderAction { | ||
return (vs, node) => { | ||
const pieces = [constantParts[0]]; | ||
placeholders.forEach((n, i) => { | ||
class AttributeValueInserter implements PlaceholderAction { | ||
constructor( | ||
public attrName: string, | ||
public constantParts: string[], | ||
public placeholders: number[], | ||
) {} | ||
reset(_state: PlaceholderState, _node: Node): void {} | ||
act(_state: PlaceholderState, vs: HtmlFragment[], node: Node): void { | ||
const pieces = [this.constantParts[0]]; | ||
this.placeholders.forEach((n, i) => { | ||
pieces.push(...renderFragment(vs[n], false)); | ||
pieces.push(constantParts[i + 1]); | ||
pieces.push(this.constantParts[i + 1]); | ||
}); | ||
(node as Element).setAttribute(attrName, pieces.join('')); | ||
}; | ||
(node as Element).setAttribute(this.attrName, pieces.join('')); | ||
} | ||
} | ||
class CompoundAction implements PlaceholderAction { | ||
constructor(public actions: PlaceholderAction[]) {} | ||
reset(states: PlaceholderState, n: Node) { | ||
this.actions.forEach((a, i) => { | ||
const state = states[i] ??= {}; | ||
a.reset(state, n); | ||
}); | ||
} | ||
act(states: PlaceholderState, vs: HtmlFragment[], n: Node) { | ||
this.actions.forEach((a, i) => { | ||
const state = states[i] ??= {}; | ||
a.act(state, vs, n); | ||
}); | ||
} | ||
} | ||
export class HtmlFragmentInstance { | ||
state: { [path: string]: PlaceholderState } = {}; | ||
constructor( | ||
public container: ChildNode[], | ||
) {} | ||
} | ||
function makePlaceholder(): Element { | ||
return document.createElement('x-placeholder'); | ||
} | ||
export class HtmlFragmentBuilder { | ||
@@ -143,4 +209,3 @@ template: HTMLTemplateElement = document.createElement('template'); | ||
if (i > 0) { | ||
const placeholder = document.createElement('x-placeholder'); | ||
n.parentNode?.insertBefore(placeholder, n); | ||
n.parentNode?.insertBefore(makePlaceholder(), n); | ||
} | ||
@@ -153,6 +218,6 @@ n.parentNode?.insertBefore(document.createTextNode(c), n); | ||
const currentPath = path.slice(); | ||
currentPath[currentPath.length - 1] = i * 2 + 1; | ||
currentPath[currentPath.length - 1] += i * 2 + 1; | ||
this.placeholderActions.push({ | ||
path: currentPath, | ||
action: nodeInserter(n), | ||
action: new NodeInserter(n), | ||
}); | ||
@@ -174,3 +239,3 @@ }); | ||
const n = parseInt(nameIsPlaceholder[1], 10); | ||
actions.push(attributesInserter(n)); | ||
actions.push(new AttributesInserter(n)); | ||
} else { | ||
@@ -180,3 +245,3 @@ const { constantParts, placeholders } = | ||
if (constantParts.length !== 1) { | ||
actions.push(attributeValueInserter( | ||
actions.push(new AttributeValueInserter( | ||
attrName, | ||
@@ -191,3 +256,3 @@ constantParts, | ||
path: path.slice(), | ||
action: (vs, n) => actions.forEach(a => a(vs, n)), | ||
action: actions.length === 1 ? actions[0] : new CompoundAction(actions), | ||
}); | ||
@@ -227,11 +292,16 @@ } | ||
clone(): ChildNode[] { | ||
return Array.from( | ||
(this.template.cloneNode(true) as HTMLTemplateElement).content.childNodes); | ||
clone(): HtmlFragmentInstance { | ||
return new HtmlFragmentInstance(Array.from( | ||
(this.template.cloneNode(true) as HTMLTemplateElement).content.childNodes)); | ||
} | ||
update(template: ChildNode[], variableParts: Array<HtmlFragment>) { | ||
update(template: HtmlFragmentInstance, variableParts: Array<HtmlFragment>) { | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
action(variableParts, followPath(template, path)); | ||
const state = template.state[path.map(n => '' + n).join('.')] ??= {}; | ||
action.reset(state, followPath(template.container, path)); | ||
}); | ||
this.placeholderActions.forEach(({ path, action }) => { | ||
const state = template.state[path.map(n => '' + n).join('.')] ??= {}; | ||
action.act(state, variableParts, followPath(template.container, path)); | ||
}); | ||
} | ||
@@ -249,3 +319,3 @@ } | ||
export function template(): HtmlTemplater { | ||
let container: ChildNode[] | null = null; | ||
let instance: HtmlFragmentInstance | null = null; | ||
return (constantParts, ... variableParts) => { | ||
@@ -257,8 +327,8 @@ let b = templateCache.get(constantParts); | ||
} | ||
if (container === null) { | ||
container = b.clone(); | ||
if (instance === null) { | ||
instance = b.clone(); | ||
} | ||
b.update(container, variableParts); | ||
return container; | ||
b.update(instance, variableParts); | ||
return instance.container; | ||
}; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
325650
24
2485
Updated@syndicate-lang/core@^0.34.9