@tko/binding.template
Advanced tools
+3
-3
@@ -1,6 +0,6 @@ | ||
| // @tko/binding.template 🥊 4.0.0 ESM | ||
| // @tko/binding.template 🥊 4.0.1 ESM | ||
| "use strict"; | ||
| import { unwrap, peek } from "@tko/observable"; | ||
| import { nativeTemplateEngine } from "./nativeTemplateEngine"; | ||
| import { TemplateBindingHandler } from "./templating"; | ||
| import { nativeTemplateEngine } from "./nativeTemplateEngine.js"; | ||
| import { TemplateBindingHandler } from "./templating.js"; | ||
| export class TemplateForEachBindingHandler extends TemplateBindingHandler { | ||
@@ -7,0 +7,0 @@ get value() { |
+7
-7
@@ -1,9 +0,9 @@ | ||
| // @tko/binding.template 🥊 4.0.0 ESM | ||
| // @tko/binding.template 🥊 4.0.1 ESM | ||
| "use strict"; | ||
| import { TemplateForEachBindingHandler } from "./foreach"; | ||
| import { TemplateBindingHandler } from "./templating"; | ||
| import { TemplateForEachBindingHandler } from "./foreach.js"; | ||
| import { TemplateBindingHandler } from "./templating.js"; | ||
| export const bindings = { foreach: TemplateForEachBindingHandler, template: TemplateBindingHandler }; | ||
| export * from "./nativeTemplateEngine"; | ||
| export * from "./templateEngine"; | ||
| export * from "./templating"; | ||
| export * from "./templateSources"; | ||
| export * from "./nativeTemplateEngine.js"; | ||
| export * from "./templateEngine.js"; | ||
| export * from "./templating.js"; | ||
| export * from "./templateSources.js"; |
+7
-7
@@ -1,9 +0,9 @@ | ||
| // @tko/binding.template 🥊 4.0.0 MJS | ||
| // @tko/binding.template 🥊 4.0.1 MJS | ||
| "use strict"; | ||
| import { TemplateForEachBindingHandler } from "./foreach"; | ||
| import { TemplateBindingHandler } from "./templating"; | ||
| import { TemplateForEachBindingHandler } from "./foreach.js"; | ||
| import { TemplateBindingHandler } from "./templating.js"; | ||
| export const bindings = { foreach: TemplateForEachBindingHandler, template: TemplateBindingHandler }; | ||
| export * from "./nativeTemplateEngine"; | ||
| export * from "./templateEngine"; | ||
| export * from "./templating"; | ||
| export * from "./templateSources"; | ||
| export * from "./nativeTemplateEngine.js"; | ||
| export * from "./templateEngine.js"; | ||
| export * from "./templating.js"; | ||
| export * from "./templateSources.js"; |
@@ -1,6 +0,6 @@ | ||
| // @tko/binding.template 🥊 4.0.0 ESM | ||
| // @tko/binding.template 🥊 4.0.1 ESM | ||
| "use strict"; | ||
| import { makeArray, parseHtmlFragment } from "@tko/utils"; | ||
| import { templateEngine } from "./templateEngine"; | ||
| import { setTemplateEngine } from "./templating"; | ||
| import { templateEngine } from "./templateEngine.js"; | ||
| import { setTemplateEngine } from "./templating.js"; | ||
| export function nativeTemplateEngine() { | ||
@@ -7,0 +7,0 @@ } |
| { | ||
| "version": 3, | ||
| "sources": ["../src/nativeTemplateEngine.ts"], | ||
| "sourcesContent": ["import { makeArray, parseHtmlFragment } from '@tko/utils'\nimport { templateEngine, TemplateOptions } from './templateEngine'\nimport { setTemplateEngine } from './templating'\nimport type { TemplateSource } from './templateSources'\nimport type { BindingContext } from '@tko/bind'\n\nexport function nativeTemplateEngine() {}\n\nnativeTemplateEngine.prototype = new templateEngine()\nnativeTemplateEngine.prototype.constructor = nativeTemplateEngine\nnativeTemplateEngine.prototype.renderTemplateSource = function (\n templateSource: TemplateSource,\n bindingContext: BindingContext<any>,\n options: TemplateOptions<any>,\n templateDocument?: Document\n): Node[] {\n const templateNodes = templateSource.nodes ? templateSource.nodes() : null\n\n if (templateNodes) {\n return makeArray(templateNodes.cloneNode(true).childNodes)\n } else {\n const templateText = templateSource.text()\n return parseHtmlFragment(templateText, templateDocument)\n }\n}\n\nnativeTemplateEngine.instance = new nativeTemplateEngine()\nsetTemplateEngine(nativeTemplateEngine.instance)\n"], | ||
| "mappings": ";;AAAA,SAAS,WAAW,yBAAyB;AAC7C,SAAS,sBAAuC;AAChD,SAAS,yBAAyB;AAI3B,gBAAS,uBAAuB;AAAC;AAExC,qBAAqB,YAAY,IAAI,eAAe;AACpD,qBAAqB,UAAU,cAAc;AAC7C,qBAAqB,UAAU,uBAAuB,SACpD,gBACA,gBACA,SACA,kBACQ;AACR,QAAM,gBAAgB,eAAe,QAAQ,eAAe,MAAM,IAAI;AAEtE,MAAI,eAAe;AACjB,WAAO,UAAU,cAAc,UAAU,IAAI,EAAE,UAAU;AAAA,EAC3D,OAAO;AACL,UAAM,eAAe,eAAe,KAAK;AACzC,WAAO,kBAAkB,cAAc,gBAAgB;AAAA,EACzD;AACF;AAEA,qBAAqB,WAAW,IAAI,qBAAqB;AACzD,kBAAkB,qBAAqB,QAAQ;", | ||
| "sourcesContent": ["import { makeArray, parseHtmlFragment } from '@tko/utils'\nimport { templateEngine, type TemplateOptions } from './templateEngine'\nimport { setTemplateEngine } from './templating'\nimport type { TemplateSource } from './templateSources'\nimport type { BindingContext } from '@tko/bind'\n\nexport function nativeTemplateEngine() {}\n\nnativeTemplateEngine.prototype = new templateEngine()\nnativeTemplateEngine.prototype.constructor = nativeTemplateEngine\nnativeTemplateEngine.prototype.renderTemplateSource = function (\n templateSource: TemplateSource,\n bindingContext: BindingContext<any>,\n options: TemplateOptions<any>,\n templateDocument?: Document\n): Node[] {\n const templateNodes = templateSource.nodes ? templateSource.nodes() : null\n\n if (templateNodes) {\n return makeArray(templateNodes.cloneNode(true).childNodes)\n } else {\n const templateText = templateSource.text()\n return parseHtmlFragment(templateText, templateDocument)\n }\n}\n\nnativeTemplateEngine.instance = new nativeTemplateEngine()\nsetTemplateEngine(nativeTemplateEngine.instance)\n"], | ||
| "mappings": ";;AAAA,SAAS,WAAW,yBAAyB;AAC7C,SAAS,sBAA4C;AACrD,SAAS,yBAAyB;AAI3B,gBAAS,uBAAuB;AAAC;AAExC,qBAAqB,YAAY,IAAI,eAAe;AACpD,qBAAqB,UAAU,cAAc;AAC7C,qBAAqB,UAAU,uBAAuB,SACpD,gBACA,gBACA,SACA,kBACQ;AACR,QAAM,gBAAgB,eAAe,QAAQ,eAAe,MAAM,IAAI;AAEtE,MAAI,eAAe;AACjB,WAAO,UAAU,cAAc,UAAU,IAAI,EAAE,UAAU;AAAA,EAC3D,OAAO;AACL,UAAM,eAAe,eAAe,KAAK;AACzC,WAAO,kBAAkB,cAAc,gBAAgB;AAAA,EACzD;AACF;AAEA,qBAAqB,WAAW,IAAI,qBAAqB;AACzD,kBAAkB,qBAAqB,QAAQ;", | ||
| "names": [] | ||
| } |
@@ -1,5 +0,5 @@ | ||
| // @tko/binding.template 🥊 4.0.0 ESM | ||
| // @tko/binding.template 🥊 4.0.1 ESM | ||
| "use strict"; | ||
| import { extend, options } from "@tko/utils"; | ||
| import { domElement, anonymousTemplate } from "./templateSources"; | ||
| import { domElement, anonymousTemplate } from "./templateSources.js"; | ||
| export function templateEngine() { | ||
@@ -6,0 +6,0 @@ } |
@@ -1,2 +0,2 @@ | ||
| // @tko/binding.template 🥊 4.0.0 ESM | ||
| // @tko/binding.template 🥊 4.0.1 ESM | ||
| "use strict"; | ||
@@ -14,2 +14,4 @@ import { tagNameLower as tagNameLowerFn, setHtml, domData, parseHtmlForTemplateNodes } from "@tko/utils"; | ||
| export class domElement { | ||
| domElement; | ||
| templateType; | ||
| constructor(element) { | ||
@@ -16,0 +18,0 @@ this.domElement = element; |
| { | ||
| "version": 3, | ||
| "sources": ["../src/templateSources.ts"], | ||
| "sourcesContent": ["// A template source represents a read/write way of accessing a template. This is to eliminate the need for template loading/saving\n// logic to be duplicated in every template engine (and means they can all work with anonymous templates, etc.)\n//\n// Two are provided by default:\n// 1. ko.templateSources.domElement - reads/writes the text content of an arbitrary DOM element\n// 2. ko.templateSources.anonymousElement - uses ko.utils.domData to read/write text *associated* with the DOM element, but\n// without reading/writing the actual element text content, since it will be overwritten\n// with the rendered template output.\n// You can implement your own template source if you want to fetch/store templates somewhere other than in DOM elements.\n// Template sources need to have the following functions:\n// text() \t\t\t- returns the template text from your storage location\n// text(value)\t\t- writes the supplied template text to your storage location\n// data(key)\t\t\t- reads values stored using data(key, value) - see below\n// data(key, value)\t- associates \"value\" with this template and the key \"key\". Is used to store information like \"isRewritten\".\n//\n// Optionally, template sources can also have the following functions:\n// nodes() - returns a DOM element containing the nodes of this template, where available\n// nodes(value) - writes the given DOM element to your storage location\n// If a DOM element is available for a given template source, template engines are encouraged to use it in preference over text()\n// for improved speed. However, all templateSources must supply text() even if they don't supply nodes().\n//\n// Once you've implemented a templateSource, make your template engine use it by subclassing whatever template engine you were\n// using and overriding \"makeTemplateSource\" to return an instance of your custom template source.\n\nimport { tagNameLower as tagNameLowerFn, setHtml, domData, parseHtmlForTemplateNodes } from '@tko/utils'\n\n// ---- ko.templateSources.domElement -----\n\n// template types\nconst templateScript = 1,\n templateTextArea = 2,\n templateTemplate = 3,\n templateElement = 4,\n templateAnonymous = 5\n\nexport interface TemplateSource {\n text(): string\n text(valueToWrite: string): void\n text(valueToWrite?: string): string | void\n\n data(key: string): any\n data<T>(key: string): T\n data<T>(key: string, valueToWrite: T): void\n\n nodes(): Node\n nodes(valueToWrite: Node): undefined\n nodes(valueToWrite?: any): Node | undefined\n}\n\nconst dataDomDataPrefix = domData.nextKey() + '_'\nconst templatesDomDataKey = domData.nextKey()\nfunction getTemplateDomData(element) {\n return domData.get(element, templatesDomDataKey) || {}\n}\nfunction setTemplateDomData(element, data) {\n domData.set(element, templatesDomDataKey, data)\n}\n\nexport class domElement implements TemplateSource {\n protected domElement: Element | Comment\n protected templateType: number\n\n constructor(element: Element | Comment) {\n this.domElement = element\n\n if (element.nodeType === Node.COMMENT_NODE) {\n this.templateType = templateElement\n } else {\n const tagNameLower = tagNameLowerFn(this.domElement as Element)\n this.templateType =\n tagNameLower === 'script'\n ? templateScript\n : tagNameLower === 'textarea'\n ? templateTextArea\n : // For browsers with proper <template> element support, where the .content property gives a document fragment\n tagNameLower == 'template'\n && (element as HTMLTemplateElement).content\n && (element as HTMLTemplateElement).content.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ? templateTemplate\n : templateElement\n }\n }\n\n text(): string\n text(valueToWrite: string): void\n text(valueToWrite?: string): string | void {\n const elemContentsProperty =\n this.templateType === templateScript ? 'text' : this.templateType === templateTextArea ? 'value' : 'innerHTML'\n\n if (arguments.length == 0) {\n return this.domElement[elemContentsProperty]\n } else {\n if (elemContentsProperty === 'innerHTML') {\n setHtml(this.domElement, valueToWrite!)\n } else {\n this.domElement[elemContentsProperty] = valueToWrite\n }\n }\n }\n\n data<T = any>(key: string, valueToWrite?: T): T | void {\n if (arguments.length === 1) {\n return domData.get(this.domElement, dataDomDataPrefix + key)\n } else {\n domData.set(this.domElement, dataDomDataPrefix + key, valueToWrite)\n }\n }\n\n nodes(): Node\n nodes(valueToWrite: Node): undefined\n nodes(valueToWrite?: any): Node | undefined {\n const element = this.domElement\n if (arguments.length == 0) {\n const templateData = getTemplateDomData(element)\n let nodes =\n templateData.containerData\n || (this.templateType === templateTemplate\n ? (element as HTMLTemplateElement).content\n : this.templateType === templateElement\n ? element\n : undefined)\n if (!nodes || templateData.alwaysCheckText) {\n // If the template is associated with an element that stores the template as text,\n // parse and cache the nodes whenever there's new text content available. This allows\n // the user to update the template content by updating the text of template node.\n const text = this.text()\n if (text) {\n nodes = parseHtmlForTemplateNodes(text, element.ownerDocument)\n this.text('') // clear the text from the node\n setTemplateDomData(element, { containerData: nodes, alwaysCheckText: true })\n }\n }\n return nodes\n } else {\n setTemplateDomData(element, { containerData: valueToWrite })\n }\n return undefined\n }\n}\n\n// ---- ko.templateSources.anonymousTemplate -----\n// Anonymous templates are normally saved/retrieved as DOM nodes through \"nodes\".\n// For compatibility, you can also read \"text\"; it will be serialized from the nodes on demand.\n// Writing to \"text\" is still supported, but then the template data will not be available as DOM nodes.\nexport class anonymousTemplate extends domElement {\n constructor(element: Element | Comment) {\n super(element)\n //The old prototype construct uses an empty-constructor from domElement, so templateType and element was 'undefined'.\n //With the new templateType = templateAnonymous (5) we achieve the same behavior in the \"nodes\" Method\n this.templateType = templateAnonymous\n }\n\n override text(): string\n override text(valueToWrite: string): void\n override text(valueToWrite?: string): string | void {\n if (arguments.length == 0) {\n const templateData = getTemplateDomData(this.domElement)\n if (templateData.textData === undefined && templateData.containerData) {\n templateData.textData = templateData.containerData.innerHTML\n }\n return templateData.textData\n } else {\n setTemplateDomData(this.domElement, { textData: valueToWrite })\n }\n }\n}\n"], | ||
| "mappings": ";;AAwBA,SAAS,gBAAgB,gBAAgB,SAAS,SAAS,iCAAiC;AAK5F,MAAM,iBAAiB,GACrB,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,oBAAoB;AAgBtB,MAAM,oBAAoB,QAAQ,QAAQ,IAAI;AAC9C,MAAM,sBAAsB,QAAQ,QAAQ;AAC5C,SAAS,mBAAmB,SAAS;AACnC,SAAO,QAAQ,IAAI,SAAS,mBAAmB,KAAK,CAAC;AACvD;AACA,SAAS,mBAAmB,SAAS,MAAM;AACzC,UAAQ,IAAI,SAAS,qBAAqB,IAAI;AAChD;AAEO,aAAM,WAAqC;AAAA,EAIhD,YAAY,SAA4B;AACtC,SAAK,aAAa;AAElB,QAAI,QAAQ,aAAa,KAAK,cAAc;AAC1C,WAAK,eAAe;AAAA,IACtB,OAAO;AACL,YAAM,eAAe,eAAe,KAAK,UAAqB;AAC9D,WAAK,eACH,iBAAiB,WACb,iBACA,iBAAiB,aACf;AAAA;AAAA,QAEA,gBAAgB,cACV,QAAgC,WAChC,QAAgC,QAAQ,aAAa,KAAK,yBAC9D,mBACA;AAAA;AAAA,IACZ;AAAA,EACF;AAAA,EAIA,KAAK,cAAsC;AACzC,UAAM,uBACJ,KAAK,iBAAiB,iBAAiB,SAAS,KAAK,iBAAiB,mBAAmB,UAAU;AAErG,QAAI,UAAU,UAAU,GAAG;AACzB,aAAO,KAAK,WAAW,oBAAoB;AAAA,IAC7C,OAAO;AACL,UAAI,yBAAyB,aAAa;AACxC,gBAAQ,KAAK,YAAY,YAAa;AAAA,MACxC,OAAO;AACL,aAAK,WAAW,oBAAoB,IAAI;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAAc,KAAa,cAA4B;AACrD,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,QAAQ,IAAI,KAAK,YAAY,oBAAoB,GAAG;AAAA,IAC7D,OAAO;AACL,cAAQ,IAAI,KAAK,YAAY,oBAAoB,KAAK,YAAY;AAAA,IACpE;AAAA,EACF;AAAA,EAIA,MAAM,cAAsC;AAC1C,UAAM,UAAU,KAAK;AACrB,QAAI,UAAU,UAAU,GAAG;AACzB,YAAM,eAAe,mBAAmB,OAAO;AAC/C,UAAI,QACF,aAAa,kBACT,KAAK,iBAAiB,mBACrB,QAAgC,UACjC,KAAK,iBAAiB,kBACpB,UACA;AACR,UAAI,CAAC,SAAS,aAAa,iBAAiB;AAI1C,cAAM,OAAO,KAAK,KAAK;AACvB,YAAI,MAAM;AACR,kBAAQ,0BAA0B,MAAM,QAAQ,aAAa;AAC7D,eAAK,KAAK,EAAE;AACZ,6BAAmB,SAAS,EAAE,eAAe,OAAO,iBAAiB,KAAK,CAAC;AAAA,QAC7E;AAAA,MACF;AACA,aAAO;AAAA,IACT,OAAO;AACL,yBAAmB,SAAS,EAAE,eAAe,aAAa,CAAC;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AACF;AAMO,aAAM,0BAA0B,WAAW;AAAA,EAChD,YAAY,SAA4B;AACtC,UAAM,OAAO;AAGb,SAAK,eAAe;AAAA,EACtB;AAAA,EAIS,KAAK,cAAsC;AAClD,QAAI,UAAU,UAAU,GAAG;AACzB,YAAM,eAAe,mBAAmB,KAAK,UAAU;AACvD,UAAI,aAAa,aAAa,UAAa,aAAa,eAAe;AACrE,qBAAa,WAAW,aAAa,cAAc;AAAA,MACrD;AACA,aAAO,aAAa;AAAA,IACtB,OAAO;AACL,yBAAmB,KAAK,YAAY,EAAE,UAAU,aAAa,CAAC;AAAA,IAChE;AAAA,EACF;AACF;", | ||
| "sourcesContent": ["// A template source represents a read/write way of accessing a template. This is to eliminate the need for template loading/saving\n// logic to be duplicated in every template engine (and means they can all work with anonymous templates, etc.)\n//\n// Two are provided by default:\n// 1. ko.templateSources.domElement - reads/writes the text content of an arbitrary DOM element\n// 2. ko.templateSources.anonymousElement - uses ko.utils.domData to read/write text *associated* with the DOM element, but\n// without reading/writing the actual element text content, since it will be overwritten\n// with the rendered template output.\n// You can implement your own template source if you want to fetch/store templates somewhere other than in DOM elements.\n// Template sources need to have the following functions:\n// text() \t\t\t- returns the template text from your storage location\n// text(value)\t\t- writes the supplied template text to your storage location\n// data(key)\t\t\t- reads values stored using data(key, value) - see below\n// data(key, value)\t- associates \"value\" with this template and the key \"key\". Is used to store information like \"isRewritten\".\n//\n// Optionally, template sources can also have the following functions:\n// nodes() - returns a DOM element containing the nodes of this template, where available\n// nodes(value) - writes the given DOM element to your storage location\n// If a DOM element is available for a given template source, template engines are encouraged to use it in preference over text()\n// for improved speed. However, all templateSources must supply text() even if they don't supply nodes().\n//\n// Once you've implemented a templateSource, make your template engine use it by subclassing whatever template engine you were\n// using and overriding \"makeTemplateSource\" to return an instance of your custom template source.\n\nimport { tagNameLower as tagNameLowerFn, setHtml, domData, parseHtmlForTemplateNodes } from '@tko/utils'\n\n// ---- ko.templateSources.domElement -----\n\n// template types\nconst templateScript = 1,\n templateTextArea = 2,\n templateTemplate = 3,\n templateElement = 4,\n templateAnonymous = 5\n\nexport interface TemplateSource {\n text(): string\n text(valueToWrite: string): void\n text(valueToWrite?: string): string | void\n\n data(key: string): any\n data<T>(key: string): T\n data<T>(key: string, valueToWrite: T): void\n\n nodes(): Node\n nodes(valueToWrite: Node): undefined\n nodes(valueToWrite?: any): Node | undefined\n}\n\nconst dataDomDataPrefix = domData.nextKey() + '_'\nconst templatesDomDataKey = domData.nextKey()\nfunction getTemplateDomData(element) {\n return domData.get(element, templatesDomDataKey) || {}\n}\nfunction setTemplateDomData(element, data) {\n domData.set(element, templatesDomDataKey, data)\n}\n\nexport class domElement implements TemplateSource {\n protected domElement: Element | Comment\n protected templateType: number\n\n constructor(element: Element | Comment) {\n this.domElement = element\n\n if (element.nodeType === Node.COMMENT_NODE) {\n this.templateType = templateElement\n } else {\n const tagNameLower = tagNameLowerFn(this.domElement as Element)\n this.templateType =\n tagNameLower === 'script'\n ? templateScript\n : tagNameLower === 'textarea'\n ? templateTextArea\n : // For browsers with proper <template> element support, where the .content property gives a document fragment\n tagNameLower == 'template' &&\n (element as HTMLTemplateElement).content &&\n (element as HTMLTemplateElement).content.nodeType === Node.DOCUMENT_FRAGMENT_NODE\n ? templateTemplate\n : templateElement\n }\n }\n\n text(): string\n text(valueToWrite: string): void\n text(valueToWrite?: string): string | void {\n const elemContentsProperty =\n this.templateType === templateScript ? 'text' : this.templateType === templateTextArea ? 'value' : 'innerHTML'\n\n if (arguments.length == 0) {\n return this.domElement[elemContentsProperty]\n } else {\n if (elemContentsProperty === 'innerHTML') {\n setHtml(this.domElement, valueToWrite!)\n } else {\n this.domElement[elemContentsProperty] = valueToWrite\n }\n }\n }\n\n data<T = any>(key: string, valueToWrite?: T): T | void {\n if (arguments.length === 1) {\n return domData.get(this.domElement, dataDomDataPrefix + key)\n } else {\n domData.set(this.domElement, dataDomDataPrefix + key, valueToWrite)\n }\n }\n\n nodes(): Node\n nodes(valueToWrite: Node): undefined\n nodes(valueToWrite?: any): Node | undefined {\n const element = this.domElement\n if (arguments.length == 0) {\n const templateData = getTemplateDomData(element)\n let nodes =\n templateData.containerData ||\n (this.templateType === templateTemplate\n ? (element as HTMLTemplateElement).content\n : this.templateType === templateElement\n ? element\n : undefined)\n if (!nodes || templateData.alwaysCheckText) {\n // If the template is associated with an element that stores the template as text,\n // parse and cache the nodes whenever there's new text content available. This allows\n // the user to update the template content by updating the text of template node.\n const text = this.text()\n if (text) {\n nodes = parseHtmlForTemplateNodes(text, element.ownerDocument)\n this.text('') // clear the text from the node\n setTemplateDomData(element, { containerData: nodes, alwaysCheckText: true })\n }\n }\n return nodes\n } else {\n setTemplateDomData(element, { containerData: valueToWrite })\n }\n return undefined\n }\n}\n\n// ---- ko.templateSources.anonymousTemplate -----\n// Anonymous templates are normally saved/retrieved as DOM nodes through \"nodes\".\n// For compatibility, you can also read \"text\"; it will be serialized from the nodes on demand.\n// Writing to \"text\" is still supported, but then the template data will not be available as DOM nodes.\nexport class anonymousTemplate extends domElement {\n constructor(element: Element | Comment) {\n super(element)\n //The old prototype construct uses an empty-constructor from domElement, so templateType and element was 'undefined'.\n //With the new templateType = templateAnonymous (5) we achieve the same behavior in the \"nodes\" Method\n this.templateType = templateAnonymous\n }\n\n override text(): string\n override text(valueToWrite: string): void\n override text(valueToWrite?: string): string | void {\n if (arguments.length == 0) {\n const templateData = getTemplateDomData(this.domElement)\n if (templateData.textData === undefined && templateData.containerData) {\n templateData.textData = templateData.containerData.innerHTML\n }\n return templateData.textData\n } else {\n setTemplateDomData(this.domElement, { textData: valueToWrite })\n }\n }\n}\n"], | ||
| "mappings": ";;AAwBA,SAAS,gBAAgB,gBAAgB,SAAS,SAAS,iCAAiC;AAK5F,MAAM,iBAAiB,GACrB,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,oBAAoB;AAgBtB,MAAM,oBAAoB,QAAQ,QAAQ,IAAI;AAC9C,MAAM,sBAAsB,QAAQ,QAAQ;AAC5C,SAAS,mBAAmB,SAAS;AACnC,SAAO,QAAQ,IAAI,SAAS,mBAAmB,KAAK,CAAC;AACvD;AACA,SAAS,mBAAmB,SAAS,MAAM;AACzC,UAAQ,IAAI,SAAS,qBAAqB,IAAI;AAChD;AAEO,aAAM,WAAqC;AAAA,EACtC;AAAA,EACA;AAAA,EAEV,YAAY,SAA4B;AACtC,SAAK,aAAa;AAElB,QAAI,QAAQ,aAAa,KAAK,cAAc;AAC1C,WAAK,eAAe;AAAA,IACtB,OAAO;AACL,YAAM,eAAe,eAAe,KAAK,UAAqB;AAC9D,WAAK,eACH,iBAAiB,WACb,iBACA,iBAAiB,aACf;AAAA;AAAA,QAEA,gBAAgB,cACb,QAAgC,WAChC,QAAgC,QAAQ,aAAa,KAAK,yBAC3D,mBACA;AAAA;AAAA,IACZ;AAAA,EACF;AAAA,EAIA,KAAK,cAAsC;AACzC,UAAM,uBACJ,KAAK,iBAAiB,iBAAiB,SAAS,KAAK,iBAAiB,mBAAmB,UAAU;AAErG,QAAI,UAAU,UAAU,GAAG;AACzB,aAAO,KAAK,WAAW,oBAAoB;AAAA,IAC7C,OAAO;AACL,UAAI,yBAAyB,aAAa;AACxC,gBAAQ,KAAK,YAAY,YAAa;AAAA,MACxC,OAAO;AACL,aAAK,WAAW,oBAAoB,IAAI;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAAc,KAAa,cAA4B;AACrD,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,QAAQ,IAAI,KAAK,YAAY,oBAAoB,GAAG;AAAA,IAC7D,OAAO;AACL,cAAQ,IAAI,KAAK,YAAY,oBAAoB,KAAK,YAAY;AAAA,IACpE;AAAA,EACF;AAAA,EAIA,MAAM,cAAsC;AAC1C,UAAM,UAAU,KAAK;AACrB,QAAI,UAAU,UAAU,GAAG;AACzB,YAAM,eAAe,mBAAmB,OAAO;AAC/C,UAAI,QACF,aAAa,kBACZ,KAAK,iBAAiB,mBAClB,QAAgC,UACjC,KAAK,iBAAiB,kBACpB,UACA;AACR,UAAI,CAAC,SAAS,aAAa,iBAAiB;AAI1C,cAAM,OAAO,KAAK,KAAK;AACvB,YAAI,MAAM;AACR,kBAAQ,0BAA0B,MAAM,QAAQ,aAAa;AAC7D,eAAK,KAAK,EAAE;AACZ,6BAAmB,SAAS,EAAE,eAAe,OAAO,iBAAiB,KAAK,CAAC;AAAA,QAC7E;AAAA,MACF;AACA,aAAO;AAAA,IACT,OAAO;AACL,yBAAmB,SAAS,EAAE,eAAe,aAAa,CAAC;AAAA,IAC7D;AACA,WAAO;AAAA,EACT;AACF;AAMO,aAAM,0BAA0B,WAAW;AAAA,EAChD,YAAY,SAA4B;AACtC,UAAM,OAAO;AAGb,SAAK,eAAe;AAAA,EACtB;AAAA,EAIS,KAAK,cAAsC;AAClD,QAAI,UAAU,UAAU,GAAG;AACzB,YAAM,eAAe,mBAAmB,KAAK,UAAU;AACvD,UAAI,aAAa,aAAa,UAAa,aAAa,eAAe;AACrE,qBAAa,WAAW,aAAa,cAAc;AAAA,MACrD;AACA,aAAO,aAAa;AAAA,IACtB,OAAO;AACL,yBAAmB,KAAK,YAAY,EAAE,UAAU,aAAa,CAAC;AAAA,IAChE;AAAA,EACF;AACF;", | ||
| "names": [] | ||
| } |
@@ -1,2 +0,2 @@ | ||
| // @tko/binding.template 🥊 4.0.0 ESM | ||
| // @tko/binding.template 🥊 4.0.1 ESM | ||
| "use strict"; | ||
@@ -23,4 +23,4 @@ import { | ||
| import { isObservable, dependencyDetection, unwrap, observable, isObservableArray } from "@tko/observable"; | ||
| import { templateEngine } from "./templateEngine"; | ||
| import { anonymousTemplate as AnonymousTemplate } from "./templateSources"; | ||
| import { templateEngine } from "./templateEngine.js"; | ||
| import { anonymousTemplate as AnonymousTemplate } from "./templateSources.js"; | ||
| let _templateEngine; | ||
@@ -27,0 +27,0 @@ const cleanContainerDomDataKey = domData.nextKey(); |
| { | ||
| "version": 3, | ||
| "sources": ["../src/templating.ts"], | ||
| "sourcesContent": ["import {\n virtualElements,\n fixUpContinuousNodeArray,\n replaceDomNodes,\n memoization,\n domNodeIsAttachedToDocument,\n moveCleanedNodesToContainerElement,\n arrayFilter,\n domData,\n options as koOptions\n} from '@tko/utils'\n\nimport {\n applyBindings,\n setDomNodeChildrenFromArrayMapping,\n AsyncBindingHandler,\n bindingEvent,\n bindingContext as BindingContextConstructor\n} from '@tko/bind'\n\nimport { computed } from '@tko/computed'\n\nimport type { Computed } from '@tko/computed'\n\nimport type { BindingContext } from '@tko/bind'\n\nimport { isObservable, dependencyDetection, unwrap, observable, isObservableArray } from '@tko/observable'\n\nimport { templateEngine } from './templateEngine'\n\nimport type { TemplateEngine, TemplateOptions } from './templateEngine'\n\nimport { anonymousTemplate as AnonymousTemplate } from './templateSources'\n\nlet _templateEngine: TemplateEngine\nconst cleanContainerDomDataKey = domData.nextKey()\n\nexport function setTemplateEngine(tEngine: TemplateEngine | undefined): void {\n if (tEngine !== undefined && !(tEngine instanceof templateEngine)) {\n // TODO: ko.templateEngine to appropriate name\n throw new Error('templateEngine must inherit from ko.templateEngine')\n }\n _templateEngine = tEngine!\n}\n\nfunction invokeForEachNodeInContinuousRange(firstNode, lastNode, action) {\n let node\n let nextInQueue = firstNode\n const firstOutOfRangeNode = virtualElements.nextSibling(lastNode)\n while (nextInQueue && (node = nextInQueue) !== firstOutOfRangeNode) {\n nextInQueue = virtualElements.nextSibling(node)\n action(node, nextInQueue)\n }\n}\n\nfunction activateBindingsOnContinuousNodeArray(\n continuousNodeArray,\n bindingContext: BindingContext,\n afterBindingCallback\n) {\n // To be used on any nodes that have been rendered by a template and have been inserted into some parent element\n // Walks through continuousNodeArray (which *must* be continuous, i.e., an uninterrupted sequence of sibling nodes, because\n // the algorithm for walking them relies on this), and for each top-level item in the virtual-element sense,\n // (1) Does a regular \"applyBindings\" to associate bindingContext with this node and to activate any non-memoized bindings\n // (2) Unmemoizes any memos in the DOM subtree (e.g., to activate bindings that had been memoized during template rewriting)\n\n if (continuousNodeArray.length) {\n let firstNode = continuousNodeArray[0]\n let lastNode = continuousNodeArray[continuousNodeArray.length - 1]\n const parentNode = firstNode.parentNode\n const provider = koOptions.bindingProviderInstance\n const preprocessNode = provider.preprocessNode\n\n if (preprocessNode) {\n invokeForEachNodeInContinuousRange(firstNode, lastNode, function (node, nextNodeInRange) {\n const nodePreviousSibling = node.previousSibling\n const newNodes = preprocessNode.call(provider, node)\n if (newNodes) {\n if (node === firstNode) {\n firstNode = newNodes[0] || nextNodeInRange\n }\n if (node === lastNode) {\n lastNode = newNodes[newNodes.length - 1] || nodePreviousSibling\n }\n }\n })\n\n // Because preprocessNode can change the nodes, including the first and last nodes, update continuousNodeArray to match.\n // We need the full set, including inner nodes, because the unmemoize step might remove the first node (and so the real\n // first node needs to be in the array).\n continuousNodeArray.length = 0\n if (!firstNode) {\n // preprocessNode might have removed all the nodes, in which case there's nothing left to do\n return\n }\n if (firstNode === lastNode) {\n continuousNodeArray.push(firstNode)\n } else {\n continuousNodeArray.push(firstNode, lastNode)\n fixUpContinuousNodeArray(continuousNodeArray, parentNode)\n }\n }\n\n // Need to applyBindings *before* unmemoziation, because unmemoization might introduce extra nodes (that we don't want to re-bind)\n // whereas a regular applyBindings won't introduce new memoized nodes\n invokeForEachNodeInContinuousRange(firstNode, lastNode, function (node) {\n if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.COMMENT_NODE) {\n applyBindings(bindingContext, node).then(afterBindingCallback)\n }\n })\n invokeForEachNodeInContinuousRange(firstNode, lastNode, function (node) {\n if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.COMMENT_NODE) {\n memoization.unmemoizeDomNodeAndDescendants(node, [bindingContext])\n }\n })\n\n // Make sure any changes done by applyBindings or unmemoize are reflected in the array\n fixUpContinuousNodeArray(continuousNodeArray, parentNode)\n }\n}\n\nfunction getFirstNodeFromPossibleArray(nodeOrNodeArray) {\n return nodeOrNodeArray.nodeType ? nodeOrNodeArray : nodeOrNodeArray.length > 0 ? nodeOrNodeArray[0] : null\n}\n\nfunction executeTemplate(targetNodeOrNodeArray, renderMode, template, bindingContext, options, afterBindingCallback) {\n options = options || {}\n const firstTargetNode = targetNodeOrNodeArray && getFirstNodeFromPossibleArray(targetNodeOrNodeArray)\n const templateDocument = (firstTargetNode || template || {}).ownerDocument\n const templateEngineToUse = options.templateEngine || _templateEngine\n const renderedNodesArray = templateEngineToUse.renderTemplate(template, bindingContext, options, templateDocument)\n\n // Loosely check result is an array of DOM nodes\n if (\n typeof renderedNodesArray.length !== 'number'\n || (renderedNodesArray.length > 0 && typeof renderedNodesArray[0].nodeType !== 'number')\n ) {\n throw new Error('Template engine must return an array of DOM nodes')\n }\n\n let haveAddedNodesToParent = false\n switch (renderMode) {\n case 'replaceChildren':\n virtualElements.setDomNodeChildren(targetNodeOrNodeArray, renderedNodesArray)\n haveAddedNodesToParent = true\n break\n case 'replaceNode':\n replaceDomNodes(targetNodeOrNodeArray, renderedNodesArray)\n haveAddedNodesToParent = true\n break\n case 'ignoreTargetNode':\n break\n default:\n throw new Error('Unknown renderMode: ' + renderMode)\n }\n\n if (haveAddedNodesToParent) {\n activateBindingsOnContinuousNodeArray(renderedNodesArray, bindingContext, afterBindingCallback)\n if (options.afterRender) {\n dependencyDetection.ignore(options.afterRender, null, [renderedNodesArray, bindingContext['$data']])\n }\n if (renderMode === 'replaceChildren') {\n bindingEvent.notify(targetNodeOrNodeArray, bindingEvent.childrenComplete)\n }\n }\n\n return renderedNodesArray\n}\n\nfunction resolveTemplateName(template, data, context) {\n // The template can be specified as:\n if (isObservable(template)) {\n // 1. An observable, with string value\n return template()\n } else if (typeof template === 'function') {\n // 2. A function of (data, context) returning a string\n return template(data, context)\n } else {\n // 3. A string\n return template\n }\n}\n\nexport type RenderModeEnum = 'replaceChildren' | 'replaceNode' | 'ignoreTargetNode'\n\nexport function renderTemplate<T = any>(\n template: string | Node | (() => string | Node),\n dataOrBindingContext: T | BindingContext<T> | null | undefined,\n options: TemplateOptions<T> | null | undefined,\n targetNodeOrNodeArray: Node | Node[],\n renderMode?: RenderModeEnum,\n afterBindingCallback?\n): Computed<void> | string {\n options = options || {}\n if ((options.templateEngine || _templateEngine) === undefined) {\n throw new Error('Set a template engine before calling renderTemplate')\n }\n renderMode = renderMode || 'replaceChildren'\n\n if (targetNodeOrNodeArray) {\n let firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray)\n\n const whenToDispose = function () {\n return !firstTargetNode || !domNodeIsAttachedToDocument(firstTargetNode)\n } // Passive disposal (on next evaluation)\n const activelyDisposeWhenNodeIsRemoved =\n firstTargetNode && renderMode === 'replaceNode' ? firstTargetNode.parentNode : firstTargetNode\n\n return computed(\n // So the DOM is automatically updated when any dependency changes\n function () {\n // Ensure we've got a proper binding context to work with\n const bindingContext =\n dataOrBindingContext && dataOrBindingContext instanceof BindingContextConstructor\n ? dataOrBindingContext\n : new BindingContextConstructor(dataOrBindingContext, undefined, undefined, undefined, {\n exportDependencies: true\n })\n\n const templateName = resolveTemplateName(template, bindingContext.$data, bindingContext)\n const renderedNodesArray = executeTemplate(\n targetNodeOrNodeArray,\n renderMode,\n templateName,\n bindingContext,\n options,\n afterBindingCallback\n )\n\n if (renderMode === 'replaceNode') {\n targetNodeOrNodeArray = renderedNodesArray\n firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray)\n }\n },\n null,\n { disposeWhen: whenToDispose, disposeWhenNodeIsRemoved: activelyDisposeWhenNodeIsRemoved }\n )\n } else {\n // We don't yet have a DOM node to evaluate, so use a memo and render the template later when there is a DOM node\n return memoization.memoize(function (domNode) {\n renderTemplate(template, dataOrBindingContext, options, domNode, 'replaceNode')\n })\n }\n}\n\nexport default function renderTemplateForEach(\n template,\n arrayOrObservableArray,\n options,\n targetNode,\n parentBindingContext,\n afterBindingCallback\n) {\n // Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then\n // activateBindingsCallback for added items, we can store the binding context in the former to use in the latter.\n let arrayItemContext\n\n // This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode\n function executeTemplateForArrayItem(arrayValue, index) {\n // Support selecting template as a function of the data being rendered\n if (options.as) {\n if (koOptions.createChildContextWithAs) {\n arrayItemContext = parentBindingContext.createChildContext(arrayValue, options.as, context => {\n context.$index = index\n })\n } else {\n arrayItemContext = parentBindingContext.extend({ [options.as]: arrayValue, $index: index })\n }\n } else {\n arrayItemContext = parentBindingContext.createChildContext(arrayValue, options.as, context => {\n context.$index = index\n })\n }\n\n const templateName = resolveTemplateName(template, arrayValue, arrayItemContext)\n return executeTemplate(\n targetNode,\n 'ignoreTargetNode',\n templateName,\n arrayItemContext,\n options,\n afterBindingCallback\n )\n }\n\n // This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode\n const activateBindingsCallback = function (arrayValue, addedNodesArray /*, index */) {\n activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext, afterBindingCallback)\n if (options.afterRender) {\n options.afterRender(addedNodesArray, arrayValue)\n }\n\n // release the \"cache\" variable, so that it can be collected by\n // the GC when its value isn't used from within the bindings anymore.\n arrayItemContext = null\n }\n\n // Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function).\n // If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping.\n function localSetDomNodeChildrenFromArrayMapping(newArray, changeList?) {\n dependencyDetection.ignore(setDomNodeChildrenFromArrayMapping, null, [\n targetNode,\n newArray,\n executeTemplateForArrayItem,\n options,\n activateBindingsCallback,\n changeList\n ])\n bindingEvent.notify(targetNode, bindingEvent.childrenComplete)\n }\n\n const shouldHideDestroyed =\n options.includeDestroyed === false || (koOptions.foreachHidesDestroyed && !options.includeDestroyed)\n if (!shouldHideDestroyed && !options.beforeRemove && isObservableArray(arrayOrObservableArray)) {\n localSetDomNodeChildrenFromArrayMapping(arrayOrObservableArray.peek())\n const subscription = arrayOrObservableArray.subscribe(\n function (changeList) {\n localSetDomNodeChildrenFromArrayMapping(arrayOrObservableArray(), changeList)\n },\n null,\n 'arrayChange'\n )\n subscription.disposeWhenNodeIsRemoved(targetNode)\n return subscription\n } else {\n return computed(\n function () {\n let unwrappedArray = unwrap(arrayOrObservableArray) || []\n const unwrappedIsIterable = Symbol.iterator in unwrappedArray\n if (!unwrappedIsIterable) {\n unwrappedArray = [unwrappedArray]\n }\n if (shouldHideDestroyed) {\n // Filter out any entries marked as destroyed\n unwrappedArray = arrayFilter(unwrappedArray, function (item) {\n return item === undefined || item === null || !unwrap(item._destroy)\n })\n }\n localSetDomNodeChildrenFromArrayMapping(unwrappedArray)\n },\n null,\n { disposeWhenNodeIsRemoved: targetNode }\n )\n }\n}\n\nconst templateComputedDomDataKey = domData.nextKey()\n\nexport class TemplateBindingHandler extends AsyncBindingHandler {\n constructor(params) {\n super(params)\n const element = this.$element\n const bindingValue = unwrap(this.value)\n\n // Expose 'conditional' for `else` chaining.\n domData.set(element, 'conditional', { elseChainSatisfied: observable(true) })\n\n // Support anonymous templates\n if (typeof bindingValue === 'string' || bindingValue.name) {\n this.bindNamedTemplate()\n } else if ('nodes' in bindingValue) {\n this.bindNodeTemplate(bindingValue.nodes || [])\n } else {\n this.bindAnonymousTemplate()\n }\n }\n\n bindNamedTemplate() {\n // It's a named template - clear the element\n virtualElements.emptyNode(this.$element)\n }\n\n // We've been given an array of DOM nodes. Save them as the template source.\n // There is no known use case for the node array being an observable array (if the output\n // varies, put that behavior *into* your template - that's what templates are for), and\n // the implementation would be a mess, so assert that it's not observable.\n bindNodeTemplate(nodes) {\n if (isObservable(nodes)) {\n throw new Error('The \"nodes\" option must be a plain, non-observable array.')\n }\n\n // If the nodes are already attached to a KO-generated container, we reuse that container without moving the\n // elements to a new one (we check only the first node, as the nodes are always moved together)\n let container = nodes[0] && nodes[0].parentNode\n if (!container || !domData.get(container, cleanContainerDomDataKey)) {\n container = moveCleanedNodesToContainerElement(nodes)\n domData.set(container, cleanContainerDomDataKey, true)\n }\n\n new AnonymousTemplate(this.$element).nodes(container)\n }\n\n bindAnonymousTemplate() {\n // It's an anonymous template - store the element contents, then clear the element\n const templateNodes = virtualElements.childNodes(this.$element)\n if (templateNodes.length === 0) {\n throw new Error('Anonymous template defined, but no template content was provided.')\n }\n const container = moveCleanedNodesToContainerElement(templateNodes) // This also removes the nodes from their current parent\n new AnonymousTemplate(this.$element).nodes(container)\n }\n\n onValueChange() {\n const element = this.$element\n const bindingContext = this.$context\n const value = this.value\n let options = unwrap(value)\n let shouldDisplay = true\n let templateComputed: string | Computed<any> | null = null\n const elseChainSatisfied = domData.get(element, 'conditional').elseChainSatisfied\n let templateName\n\n if (typeof options === 'string') {\n templateName = value\n options = {}\n } else {\n templateName = options.name\n\n // Support \"if\"/\"ifnot\" conditions\n if ('if' in options) {\n shouldDisplay = unwrap(options.if)\n }\n\n if (shouldDisplay && 'ifnot' in options) {\n shouldDisplay = !unwrap(options.ifnot)\n }\n }\n\n if ('foreach' in options) {\n // Render once for each data point (treating data set as empty if shouldDisplay==false)\n const dataArray = (shouldDisplay && options.foreach) || []\n templateComputed = renderTemplateForEach(\n templateName || element,\n dataArray,\n options,\n element,\n bindingContext,\n this.completeBinding\n )\n\n elseChainSatisfied((unwrap(dataArray) || []).length !== 0)\n } else if (shouldDisplay) {\n // Render once for this single data point (or use the viewModel if no data was provided)\n const innerBindingContext =\n 'data' in options\n ? bindingContext.createStaticChildContext(options.data, options.as) // Given an explicit 'data' value, we create a child binding context for it\n : bindingContext // Given no explicit 'data' value, we retain the same binding context\n templateComputed = renderTemplate(\n templateName || element,\n innerBindingContext,\n options,\n element,\n undefined,\n this.completeBinding\n )\n elseChainSatisfied(true)\n } else {\n virtualElements.emptyNode(element)\n elseChainSatisfied(false)\n }\n\n // It only makes sense to have a single template computed per element (otherwise which one should have its output displayed?)\n this.disposeOldComputedAndStoreNewOne(element, templateComputed)\n }\n\n disposeOldComputedAndStoreNewOne(element, newComputed) {\n const oldComputed = domData.get(element, templateComputedDomDataKey)\n if (oldComputed && typeof oldComputed.dispose === 'function') {\n oldComputed.dispose()\n }\n domData.set(\n element,\n templateComputedDomDataKey,\n newComputed && (!newComputed.isActive || newComputed.isActive()) ? newComputed : undefined\n )\n }\n\n override get controlsDescendants() {\n return true\n }\n static override get allowVirtualElements() {\n return true\n }\n}\n"], | ||
| "mappings": "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", | ||
| "sourcesContent": ["import {\n virtualElements,\n fixUpContinuousNodeArray,\n replaceDomNodes,\n memoization,\n domNodeIsAttachedToDocument,\n moveCleanedNodesToContainerElement,\n arrayFilter,\n domData,\n options as koOptions\n} from '@tko/utils'\n\nimport {\n applyBindings,\n setDomNodeChildrenFromArrayMapping,\n AsyncBindingHandler,\n bindingEvent,\n bindingContext as BindingContextConstructor\n} from '@tko/bind'\n\nimport { computed } from '@tko/computed'\n\nimport type { Computed } from '@tko/computed'\n\nimport type { BindingContext } from '@tko/bind'\n\nimport { isObservable, dependencyDetection, unwrap, observable, isObservableArray } from '@tko/observable'\n\nimport { templateEngine } from './templateEngine'\n\nimport type { TemplateEngine, TemplateOptions } from './templateEngine'\n\nimport { anonymousTemplate as AnonymousTemplate } from './templateSources'\n\nlet _templateEngine: TemplateEngine\nconst cleanContainerDomDataKey = domData.nextKey()\n\nexport function setTemplateEngine(tEngine: TemplateEngine | undefined): void {\n if (tEngine !== undefined && !(tEngine instanceof templateEngine)) {\n // TODO: ko.templateEngine to appropriate name\n throw new Error('templateEngine must inherit from ko.templateEngine')\n }\n _templateEngine = tEngine!\n}\n\nfunction invokeForEachNodeInContinuousRange(firstNode, lastNode, action) {\n let node\n let nextInQueue = firstNode\n const firstOutOfRangeNode = virtualElements.nextSibling(lastNode)\n while (nextInQueue && (node = nextInQueue) !== firstOutOfRangeNode) {\n nextInQueue = virtualElements.nextSibling(node)\n action(node, nextInQueue)\n }\n}\n\nfunction activateBindingsOnContinuousNodeArray(\n continuousNodeArray,\n bindingContext: BindingContext,\n afterBindingCallback\n) {\n // To be used on any nodes that have been rendered by a template and have been inserted into some parent element\n // Walks through continuousNodeArray (which *must* be continuous, i.e., an uninterrupted sequence of sibling nodes, because\n // the algorithm for walking them relies on this), and for each top-level item in the virtual-element sense,\n // (1) Does a regular \"applyBindings\" to associate bindingContext with this node and to activate any non-memoized bindings\n // (2) Unmemoizes any memos in the DOM subtree (e.g., to activate bindings that had been memoized during template rewriting)\n\n if (continuousNodeArray.length) {\n let firstNode = continuousNodeArray[0]\n let lastNode = continuousNodeArray[continuousNodeArray.length - 1]\n const parentNode = firstNode.parentNode\n const provider = koOptions.bindingProviderInstance\n const preprocessNode = provider.preprocessNode\n\n if (preprocessNode) {\n invokeForEachNodeInContinuousRange(firstNode, lastNode, function (node, nextNodeInRange) {\n const nodePreviousSibling = node.previousSibling\n const newNodes = preprocessNode.call(provider, node)\n if (newNodes) {\n if (node === firstNode) {\n firstNode = newNodes[0] || nextNodeInRange\n }\n if (node === lastNode) {\n lastNode = newNodes[newNodes.length - 1] || nodePreviousSibling\n }\n }\n })\n\n // Because preprocessNode can change the nodes, including the first and last nodes, update continuousNodeArray to match.\n // We need the full set, including inner nodes, because the unmemoize step might remove the first node (and so the real\n // first node needs to be in the array).\n continuousNodeArray.length = 0\n if (!firstNode) {\n // preprocessNode might have removed all the nodes, in which case there's nothing left to do\n return\n }\n if (firstNode === lastNode) {\n continuousNodeArray.push(firstNode)\n } else {\n continuousNodeArray.push(firstNode, lastNode)\n fixUpContinuousNodeArray(continuousNodeArray, parentNode)\n }\n }\n\n // Need to applyBindings *before* unmemoziation, because unmemoization might introduce extra nodes (that we don't want to re-bind)\n // whereas a regular applyBindings won't introduce new memoized nodes\n invokeForEachNodeInContinuousRange(firstNode, lastNode, function (node) {\n if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.COMMENT_NODE) {\n applyBindings(bindingContext, node).then(afterBindingCallback)\n }\n })\n invokeForEachNodeInContinuousRange(firstNode, lastNode, function (node) {\n if (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.COMMENT_NODE) {\n memoization.unmemoizeDomNodeAndDescendants(node, [bindingContext])\n }\n })\n\n // Make sure any changes done by applyBindings or unmemoize are reflected in the array\n fixUpContinuousNodeArray(continuousNodeArray, parentNode)\n }\n}\n\nfunction getFirstNodeFromPossibleArray(nodeOrNodeArray) {\n return nodeOrNodeArray.nodeType ? nodeOrNodeArray : nodeOrNodeArray.length > 0 ? nodeOrNodeArray[0] : null\n}\n\nfunction executeTemplate(targetNodeOrNodeArray, renderMode, template, bindingContext, options, afterBindingCallback) {\n options = options || {}\n const firstTargetNode = targetNodeOrNodeArray && getFirstNodeFromPossibleArray(targetNodeOrNodeArray)\n const templateDocument = (firstTargetNode || template || {}).ownerDocument\n const templateEngineToUse = options.templateEngine || _templateEngine\n const renderedNodesArray = templateEngineToUse.renderTemplate(template, bindingContext, options, templateDocument)\n\n // Loosely check result is an array of DOM nodes\n if (\n typeof renderedNodesArray.length !== 'number' ||\n (renderedNodesArray.length > 0 && typeof renderedNodesArray[0].nodeType !== 'number')\n ) {\n throw new Error('Template engine must return an array of DOM nodes')\n }\n\n let haveAddedNodesToParent = false\n switch (renderMode) {\n case 'replaceChildren':\n virtualElements.setDomNodeChildren(targetNodeOrNodeArray, renderedNodesArray)\n haveAddedNodesToParent = true\n break\n case 'replaceNode':\n replaceDomNodes(targetNodeOrNodeArray, renderedNodesArray)\n haveAddedNodesToParent = true\n break\n case 'ignoreTargetNode':\n break\n default:\n throw new Error('Unknown renderMode: ' + renderMode)\n }\n\n if (haveAddedNodesToParent) {\n activateBindingsOnContinuousNodeArray(renderedNodesArray, bindingContext, afterBindingCallback)\n if (options.afterRender) {\n dependencyDetection.ignore(options.afterRender, null, [renderedNodesArray, bindingContext['$data']])\n }\n if (renderMode === 'replaceChildren') {\n bindingEvent.notify(targetNodeOrNodeArray, bindingEvent.childrenComplete)\n }\n }\n\n return renderedNodesArray\n}\n\nfunction resolveTemplateName(template, data, context) {\n // The template can be specified as:\n if (isObservable(template)) {\n // 1. An observable, with string value\n return template()\n } else if (typeof template === 'function') {\n // 2. A function of (data, context) returning a string\n return template(data, context)\n } else {\n // 3. A string\n return template\n }\n}\n\nexport type RenderModeEnum = 'replaceChildren' | 'replaceNode' | 'ignoreTargetNode'\n\nexport function renderTemplate<T = any>(\n template: string | Node | (() => string | Node),\n dataOrBindingContext: T | BindingContext<T> | null | undefined,\n options: TemplateOptions<T> | null | undefined,\n targetNodeOrNodeArray: Node | Node[],\n renderMode?: RenderModeEnum,\n afterBindingCallback?\n): Computed<void> | string {\n options = options || {}\n if ((options.templateEngine || _templateEngine) === undefined) {\n throw new Error('Set a template engine before calling renderTemplate')\n }\n renderMode = renderMode || 'replaceChildren'\n\n if (targetNodeOrNodeArray) {\n let firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray)\n\n const whenToDispose = function () {\n return !firstTargetNode || !domNodeIsAttachedToDocument(firstTargetNode)\n } // Passive disposal (on next evaluation)\n const activelyDisposeWhenNodeIsRemoved =\n firstTargetNode && renderMode === 'replaceNode' ? firstTargetNode.parentNode : firstTargetNode\n\n return computed(\n // So the DOM is automatically updated when any dependency changes\n function () {\n // Ensure we've got a proper binding context to work with\n const bindingContext =\n dataOrBindingContext && dataOrBindingContext instanceof BindingContextConstructor\n ? dataOrBindingContext\n : new BindingContextConstructor(dataOrBindingContext, undefined, undefined, undefined, {\n exportDependencies: true\n })\n\n const templateName = resolveTemplateName(template, bindingContext.$data, bindingContext)\n const renderedNodesArray = executeTemplate(\n targetNodeOrNodeArray,\n renderMode,\n templateName,\n bindingContext,\n options,\n afterBindingCallback\n )\n\n if (renderMode === 'replaceNode') {\n targetNodeOrNodeArray = renderedNodesArray\n firstTargetNode = getFirstNodeFromPossibleArray(targetNodeOrNodeArray)\n }\n },\n null,\n { disposeWhen: whenToDispose, disposeWhenNodeIsRemoved: activelyDisposeWhenNodeIsRemoved }\n )\n } else {\n // We don't yet have a DOM node to evaluate, so use a memo and render the template later when there is a DOM node\n return memoization.memoize(function (domNode) {\n renderTemplate(template, dataOrBindingContext, options, domNode, 'replaceNode')\n })\n }\n}\n\nexport default function renderTemplateForEach(\n template,\n arrayOrObservableArray,\n options,\n targetNode,\n parentBindingContext,\n afterBindingCallback\n) {\n // Since setDomNodeChildrenFromArrayMapping always calls executeTemplateForArrayItem and then\n // activateBindingsCallback for added items, we can store the binding context in the former to use in the latter.\n let arrayItemContext\n\n // This will be called by setDomNodeChildrenFromArrayMapping to get the nodes to add to targetNode\n function executeTemplateForArrayItem(arrayValue, index) {\n // Support selecting template as a function of the data being rendered\n if (options.as) {\n if (koOptions.createChildContextWithAs) {\n arrayItemContext = parentBindingContext.createChildContext(arrayValue, options.as, context => {\n context.$index = index\n })\n } else {\n arrayItemContext = parentBindingContext.extend({ [options.as]: arrayValue, $index: index })\n }\n } else {\n arrayItemContext = parentBindingContext.createChildContext(arrayValue, options.as, context => {\n context.$index = index\n })\n }\n\n const templateName = resolveTemplateName(template, arrayValue, arrayItemContext)\n return executeTemplate(\n targetNode,\n 'ignoreTargetNode',\n templateName,\n arrayItemContext,\n options,\n afterBindingCallback\n )\n }\n\n // This will be called whenever setDomNodeChildrenFromArrayMapping has added nodes to targetNode\n const activateBindingsCallback = function (arrayValue, addedNodesArray /*, index */) {\n activateBindingsOnContinuousNodeArray(addedNodesArray, arrayItemContext, afterBindingCallback)\n if (options.afterRender) {\n options.afterRender(addedNodesArray, arrayValue)\n }\n\n // release the \"cache\" variable, so that it can be collected by\n // the GC when its value isn't used from within the bindings anymore.\n arrayItemContext = null\n }\n\n // Call setDomNodeChildrenFromArrayMapping, ignoring any observables unwrapped within (most likely from a callback function).\n // If the array items are observables, though, they will be unwrapped in executeTemplateForArrayItem and managed within setDomNodeChildrenFromArrayMapping.\n function localSetDomNodeChildrenFromArrayMapping(newArray, changeList?) {\n dependencyDetection.ignore(setDomNodeChildrenFromArrayMapping, null, [\n targetNode,\n newArray,\n executeTemplateForArrayItem,\n options,\n activateBindingsCallback,\n changeList\n ])\n bindingEvent.notify(targetNode, bindingEvent.childrenComplete)\n }\n\n const shouldHideDestroyed =\n options.includeDestroyed === false || (koOptions.foreachHidesDestroyed && !options.includeDestroyed)\n if (!shouldHideDestroyed && !options.beforeRemove && isObservableArray(arrayOrObservableArray)) {\n localSetDomNodeChildrenFromArrayMapping(arrayOrObservableArray.peek())\n const subscription = arrayOrObservableArray.subscribe(\n function (changeList) {\n localSetDomNodeChildrenFromArrayMapping(arrayOrObservableArray(), changeList)\n },\n null,\n 'arrayChange'\n )\n subscription.disposeWhenNodeIsRemoved(targetNode)\n return subscription\n } else {\n return computed(\n function () {\n let unwrappedArray = unwrap(arrayOrObservableArray) || []\n const unwrappedIsIterable = Symbol.iterator in unwrappedArray\n if (!unwrappedIsIterable) {\n unwrappedArray = [unwrappedArray]\n }\n if (shouldHideDestroyed) {\n // Filter out any entries marked as destroyed\n unwrappedArray = arrayFilter(unwrappedArray, function (item) {\n return item === undefined || item === null || !unwrap(item._destroy)\n })\n }\n localSetDomNodeChildrenFromArrayMapping(unwrappedArray)\n },\n null,\n { disposeWhenNodeIsRemoved: targetNode }\n )\n }\n}\n\nconst templateComputedDomDataKey = domData.nextKey()\n\nexport class TemplateBindingHandler extends AsyncBindingHandler {\n constructor(params) {\n super(params)\n const element = this.$element\n const bindingValue = unwrap(this.value)\n\n // Expose 'conditional' for `else` chaining.\n domData.set(element, 'conditional', { elseChainSatisfied: observable(true) })\n\n // Support anonymous templates\n if (typeof bindingValue === 'string' || bindingValue.name) {\n this.bindNamedTemplate()\n } else if ('nodes' in bindingValue) {\n this.bindNodeTemplate(bindingValue.nodes || [])\n } else {\n this.bindAnonymousTemplate()\n }\n }\n\n bindNamedTemplate() {\n // It's a named template - clear the element\n virtualElements.emptyNode(this.$element)\n }\n\n // We've been given an array of DOM nodes. Save them as the template source.\n // There is no known use case for the node array being an observable array (if the output\n // varies, put that behavior *into* your template - that's what templates are for), and\n // the implementation would be a mess, so assert that it's not observable.\n bindNodeTemplate(nodes) {\n if (isObservable(nodes)) {\n throw new Error('The \"nodes\" option must be a plain, non-observable array.')\n }\n\n // If the nodes are already attached to a KO-generated container, we reuse that container without moving the\n // elements to a new one (we check only the first node, as the nodes are always moved together)\n let container = nodes[0] && nodes[0].parentNode\n if (!container || !domData.get(container, cleanContainerDomDataKey)) {\n container = moveCleanedNodesToContainerElement(nodes)\n domData.set(container, cleanContainerDomDataKey, true)\n }\n\n new AnonymousTemplate(this.$element).nodes(container)\n }\n\n bindAnonymousTemplate() {\n // It's an anonymous template - store the element contents, then clear the element\n const templateNodes = virtualElements.childNodes(this.$element)\n if (templateNodes.length === 0) {\n throw new Error('Anonymous template defined, but no template content was provided.')\n }\n const container = moveCleanedNodesToContainerElement(templateNodes) // This also removes the nodes from their current parent\n new AnonymousTemplate(this.$element).nodes(container)\n }\n\n onValueChange() {\n const element = this.$element\n const bindingContext = this.$context\n const value = this.value\n let options = unwrap(value)\n let shouldDisplay = true\n let templateComputed: string | Computed<any> | null = null\n const elseChainSatisfied = domData.get(element, 'conditional').elseChainSatisfied\n let templateName\n\n if (typeof options === 'string') {\n templateName = value\n options = {}\n } else {\n templateName = options.name\n\n // Support \"if\"/\"ifnot\" conditions\n if ('if' in options) {\n shouldDisplay = unwrap(options.if)\n }\n\n if (shouldDisplay && 'ifnot' in options) {\n shouldDisplay = !unwrap(options.ifnot)\n }\n }\n\n if ('foreach' in options) {\n // Render once for each data point (treating data set as empty if shouldDisplay==false)\n const dataArray = (shouldDisplay && options.foreach) || []\n templateComputed = renderTemplateForEach(\n templateName || element,\n dataArray,\n options,\n element,\n bindingContext,\n this.completeBinding\n )\n\n elseChainSatisfied((unwrap(dataArray) || []).length !== 0)\n } else if (shouldDisplay) {\n // Render once for this single data point (or use the viewModel if no data was provided)\n const innerBindingContext =\n 'data' in options\n ? bindingContext.createStaticChildContext(options.data, options.as) // Given an explicit 'data' value, we create a child binding context for it\n : bindingContext // Given no explicit 'data' value, we retain the same binding context\n templateComputed = renderTemplate(\n templateName || element,\n innerBindingContext,\n options,\n element,\n undefined,\n this.completeBinding\n )\n elseChainSatisfied(true)\n } else {\n virtualElements.emptyNode(element)\n elseChainSatisfied(false)\n }\n\n // It only makes sense to have a single template computed per element (otherwise which one should have its output displayed?)\n this.disposeOldComputedAndStoreNewOne(element, templateComputed)\n }\n\n disposeOldComputedAndStoreNewOne(element, newComputed) {\n const oldComputed = domData.get(element, templateComputedDomDataKey)\n if (oldComputed && typeof oldComputed.dispose === 'function') {\n oldComputed.dispose()\n }\n domData.set(\n element,\n templateComputedDomDataKey,\n newComputed && (!newComputed.isActive || newComputed.isActive()) ? newComputed : undefined\n )\n }\n\n override get controlsDescendants() {\n return true\n }\n static override get allowVirtualElements() {\n return true\n }\n}\n"], | ||
| "mappings": "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", | ||
| "names": [] | ||
| } |
+12
-16
| { | ||
| "version": "4.0.0", | ||
| "version": "4.0.1", | ||
| "name": "@tko/binding.template", | ||
| "description": "TKO Template bindings", | ||
| "module": "dist/binding.template.js", | ||
| "module": "dist/index.js", | ||
| "files": [ | ||
| "dist/", | ||
| "helpers/" | ||
| "dist/" | ||
| ], | ||
@@ -26,15 +25,10 @@ "repository": { | ||
| "dependencies": { | ||
| "@tko/bind": "^4.0.0", | ||
| "@tko/computed": "^4.0.0", | ||
| "@tko/observable": "^4.0.0", | ||
| "@tko/utils": "^4.0.0", | ||
| "@tko/bind": "^4.0.1", | ||
| "@tko/computed": "^4.0.1", | ||
| "@tko/observable": "^4.0.1", | ||
| "@tko/utils": "^4.0.1", | ||
| "tslib": "^2.2.0" | ||
| }, | ||
| "karma": { | ||
| "frameworks": [ | ||
| "jasmine" | ||
| ] | ||
| }, | ||
| "peerDependencies": { | ||
| "@tko/binding.if": "^4.0.0" | ||
| "@tko/binding.if": "^4.0.1" | ||
| }, | ||
@@ -51,5 +45,7 @@ "licenses": [ | ||
| "import": "./dist/index.js" | ||
| }, | ||
| "./helpers/*": "./helpers/*" | ||
| } | ||
| }, | ||
| "scripts": { | ||
| "build": "bun ../../tools/build.ts" | ||
| } | ||
| } |
| import { extend, arrayPushAll, parseHtmlFragment } from '@tko/utils' | ||
| import { renderTemplate, anonymousTemplate, templateEngine } from '../dist' | ||
| import type { BindingContext } from '@tko/bind' | ||
| export function dummyTemplateEngine(templates?) { | ||
| const inMemoryTemplates = templates || {} | ||
| const inMemoryTemplateData = {} | ||
| function dummyTemplateSource(id) { | ||
| this.id = id | ||
| } | ||
| dummyTemplateSource.prototype = { | ||
| text: function (val) { | ||
| if (arguments.length >= 1) inMemoryTemplates[this.id] = val | ||
| return inMemoryTemplates[this.id] | ||
| }, | ||
| data: function (key, val) { | ||
| if (arguments.length >= 2) { | ||
| inMemoryTemplateData[this.id] = inMemoryTemplateData[this.id] || {} | ||
| inMemoryTemplateData[this.id][key] = val | ||
| } | ||
| return (inMemoryTemplateData[this.id] || {})[key] | ||
| } | ||
| } | ||
| this.makeTemplateSource = function (template) { | ||
| if (typeof template == 'string') | ||
| return new dummyTemplateSource(template) // Named template comes from the in-memory collection | ||
| else if (template.nodeType === Node.ELEMENT_NODE || template.nodeType === Node.COMMENT_NODE) | ||
| return new anonymousTemplate(template) // Anonymous template | ||
| } | ||
| this.renderTemplateSource = function (templateSource, bindingContext: BindingContext, rt_options, templateDocument) { | ||
| let data = bindingContext['$data'] | ||
| if (data && typeof data.get_value === 'function') { | ||
| // For cases when data is an Identifier/Expression. | ||
| data = data.get_value(data, bindingContext) | ||
| } | ||
| templateDocument = templateDocument || document | ||
| rt_options = rt_options || {} | ||
| let templateText = templateSource.text() | ||
| if (typeof templateText == 'function') templateText = templateText(data, rt_options) | ||
| templateText = rt_options.showParams ? templateText + ', data=' + data + ', options=' + rt_options : templateText | ||
| // var templateOptions = options.templateOptions; // Have templateOptions in scope to support [js:templateOptions.foo] syntax | ||
| let result | ||
| data = data || {} | ||
| // Builders (e.g. rollup) mangle `data` to e.g. `data$$1`. | ||
| // This workaround works as long as nomangle$data doesn't | ||
| // appear anywhere not in tests. | ||
| const nomangle$data: any = data | ||
| ;(window as any).__prevent_tree_shaking__ = nomangle$data | ||
| delete (window as any).__prevent_tree_shaking__ | ||
| rt_options.templateRenderingVariablesInScope = rt_options.templateRenderingVariablesInScope || {} | ||
| extend(data, rt_options.templateRenderingVariablesInScope) | ||
| // Dummy [renderTemplate:...] syntax | ||
| result = templateText.replace(/\[renderTemplate\:(.*?)\]/g, function (match, templateName) { | ||
| return renderTemplate(templateName, data, rt_options) | ||
| }) | ||
| const evalHandler = function (match, script) { | ||
| try { | ||
| const evalResult = eval(script) | ||
| return evalResult === null || evalResult === undefined ? '' : evalResult.toString() | ||
| } catch (ex: any) { | ||
| throw new Error('Error evaluating script: [js: ' + script + ']\n\nException: ' + ex.toString()) | ||
| } | ||
| } | ||
| // Dummy [[js:...]] syntax (in case you need to use square brackets inside the expression) | ||
| result = result.replace(/\[\[js\:([\s\S]*?)\]\]/g, evalHandler) | ||
| // Dummy [js:...] syntax | ||
| result = result.replace(/\[js\:([\s\S]*?)\]/g, evalHandler) | ||
| /*with (bindingContext) { | ||
| with (data || {}) { | ||
| with (options.templateRenderingVariablesInScope || {}) { | ||
| } | ||
| } | ||
| }*/ | ||
| // Use same HTML parsing code as real template engine so as to trigger same combination of IE weirdnesses | ||
| // Also ensure resulting nodelist is an array to mimic what the default templating engine does, so we see the effects of not being able to remove dead memo comment nodes. | ||
| return arrayPushAll([], parseHtmlFragment(result, templateDocument)) | ||
| } | ||
| this.rewriteTemplate = function (template, rewriterCallback, templateDocument) { | ||
| // Only rewrite if the template isn't a function (can't rewrite those) | ||
| const templateSource = this.makeTemplateSource(template, templateDocument) | ||
| if (typeof templateSource.text() != 'function') | ||
| return templateEngine.prototype.rewriteTemplate.call(this, template, rewriterCallback, templateDocument) | ||
| } | ||
| this.createJavaScriptEvaluatorBlock = function (script) { | ||
| return '[js:' + script + ']' | ||
| } | ||
| } | ||
| dummyTemplateEngine.prototype = new templateEngine() |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
136481
-68.78%17
-5.56%1073
-75.29%Updated
Updated
Updated
Updated