@simonbuchan/html
Advanced tools
Comparing version 0.9.0 to 0.9.1
@@ -1,1 +0,1 @@ | ||
"use strict";function e(e,t){const n=[];let o=t;for(;e!==o;){let e=0;if(!o)throw new Error("Could not find target from root");const t=o.parentNode;for(;null!==(o=o.previousSibling);)++e;n.unshift(e),o=t}return n}function t(e,t){for(const n of t)e=e.childNodes[n];return e}const n="⚡";function o(t,o){const r=t.createElement("template");r.innerHTML=o.join(n);const{content:s}=r,l=t.createNodeIterator(s,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),a=[];let i=l.nextNode();for(;i;){const t=l.nextNode();switch(i.nodeType){case Node.TEXT_NODE:{let t,o=i;for(;0<=(t=o.data.indexOf(n));){const n=o;o=o.splitText(t+1);const r=t?n.splitText(t):n;t=0;let l={type:"node",path:e(s,r)};a.push(l)}break}case Node.ELEMENT_NODE:{const t=i;for(const o of t.attributes)o.value===n&&a.push({type:"attr-value",path:e(s,t),name:o.name});break}}i=t}if(a.length!==o.length-1)throw new Error(`Could not find all replacements in template: ${o.join(n)}`);return{element:r,content:s,slots:a}}function r(e,n,o){const r=e.importNode(n.content,!0),s=[],i=[],c=[];for(let e=0;e!==n.slots.length;e++){const o=n.slots[e],l=t(r,o.path);switch(o.type){default:throw new Error(`Unhandled type for template slot: ${JSON.stringify(o)}`);case"node":const e={type:"node",startAfter:l.previousSibling,endBefore:l.nextSibling};s.push(e),i.push(e);break;case"attr-value":const t={type:"attr-value",element:l,name:o.name};s.push(t),c.push(t)}}for(let t=0;t!==n.slots.length;t++){const n=s[t],r=o[t];switch(n.type){case"node":l(e,n,r);break;case"attr-value":a(n,r)}}return{fragment:r,slots:s,nodeSlots:i,attrValueSlots:c}}function s(e,t){const n=[];if(e)for(let o=e;(o=o.nextSibling)&&o!==t;)n.push(o);else for(let e=t;e=e.previousSibling;)n.unshift(e);return n}function l(e,t,n){const o=s(t.startAfter,t.endBefore);if("string"==typeof n){let r=o.find(e=>e.nodeType===Node.TEXT_NODE);r?r.data=n:(r=e.createTextNode(n),t.endBefore.before(r));for(const e of o)e!==r&&e.remove()}else if(null!=n&&!1!==n){o.includes(n)||t.endBefore.before(n);for(const e of o)e!==n&&e.remove()}else for(const e of o)e.remove()}function a(e,t){"string"==typeof t?e.element.setAttribute(e.name,t):null!=t&&!1!==t?(console.warn("Cannot assign non-string value to attribute slot %O: %O",name,t),e.element.removeAttribute(e.name)):e.element.removeAttribute(e.name)}function i(e,t,n){switch(t.type){case"node":l(e,t,n);break;case"attr-value":a(t,n)}}const c=new Map;function f(e,...t){let n=c.get(e);n||(n=o(document,e),c.set(e,n));const{fragment:s}=r(document,n,t);return s}function u(e,...t){let s=c.get(e);if(s||(s=o(document,e),c.set(e,s)),1!==s.content.childElementCount)throw new Error(`html.element template should have a single top-level element: ${e.join(n)}`);const{fragment:l}=r(document,s,t);return l.firstElementChild}function d(e,...t){let n=c.get(e);n||(n=o(document,e),c.set(e,n));const{fragment:l,slots:a,attrValueSlots:f,nodeSlots:u}=r(document,n,t);return{fragment:l,node:l.firstChild,element:l.firstElementChild,slots:a.map(e=>({update(t){i(document,e,t)}})),attrSlots:f.map(({element:e,name:t})=>({element:e,name:t,remove(){e.removeAttribute(t)},set(n){e.setAttribute(t,n)}})),childSlots:u.map(({startAfter:e,endBefore:t})=>{return{nodes:()=>s(e,t),range:n,clear(){n().deleteContents()},prepend(...n){e?e.after(...n):t.parentNode.prepend(...n)},append(...e){t.before(...e)},replace(...e){n().deleteContents(),t.before(...e)}};function n(){const n=document.createRange();return e?n.setStartAfter(e):n.setStart(t.parentNode,0),n.setEndBefore(t),n}})}}f.el=u,f.element=u,f.instance=d,module.exports=f; | ||
"use strict";function e(e,t){const n=[];let o=t;for(;e!==o;){let e=0;if(!o)throw new Error("Could not find target from root");const t=o.parentNode;for(;null!==(o=o.previousSibling);)++e;n.unshift(e),o=t}return n}function t(e,t){for(const n of t)e=e.childNodes[n];return e}function n(t,n){const o=t.createElement("template");o.innerHTML=n.join("⚡");const{content:r}=o,l=t.createNodeIterator(r,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s=[];let a=l.nextNode();for(;a;){const t=l.nextNode();switch(a.nodeType){case Node.TEXT_NODE:{let t,n=a;for(;0<=(t=n.data.indexOf("⚡"));){const o=n;n=n.splitText(t+1);const l=t?o.splitText(t):o;t=0;let a={type:"node",path:e(r,l)};s.push(a)}break}case Node.ELEMENT_NODE:{const t=a;for(const n of t.attributes)"⚡"===n.value&&s.push({type:"attr-value",path:e(r,t),name:n.name});break}}a=t}if(s.length!==n.length-1)throw new Error(`Could not find all replacements in template: ${n.join("⚡")}`);return{element:o,content:r,slots:s}}function o(e,n,o){const r=e.importNode(n.content,!0),a=[],i=[],c=[];for(let e=0;e!==n.slots.length;e++){const o=n.slots[e],l=t(r,o.path);switch(o.type){default:throw new Error(`Unhandled type for template slot: ${JSON.stringify(o)}`);case"node":const e={type:"node",startAfter:l.previousSibling,endBefore:l.nextSibling};a.push(e),i.push(e);break;case"attr-value":const t={type:"attr-value",element:l,name:o.name};a.push(t),c.push(t)}}for(let t=0;t!==n.slots.length;t++){const n=a[t],r=o[t];switch(n.type){case"node":l(e,n,r);break;case"attr-value":s(n,r)}}return{fragment:r,slots:a,nodeSlots:i,attrValueSlots:c}}function r(e,t){const n=[];if(e)for(let o=e;(o=o.nextSibling)&&o!==t;)n.push(o);else for(let e=t;e=e.previousSibling;)n.unshift(e);return n}function l(e,t,n){const o=r(t.startAfter,t.endBefore);if("string"==typeof n){let r=o.find((e=>e.nodeType===Node.TEXT_NODE));r?r.data=n:(r=e.createTextNode(n),t.endBefore.before(r));for(const e of o)e!==r&&e.remove()}else if(null!=n&&!1!==n){o.includes(n)||t.endBefore.before(n);for(const e of o)e!==n&&e.remove()}else for(const e of o)e.remove()}function s(e,t){"string"==typeof t?e.element.setAttribute(e.name,t):null!=t&&!1!==t?(console.warn("Cannot assign non-string value to attribute slot %O: %O",name,t),e.element.removeAttribute(e.name)):e.element.removeAttribute(e.name)}const a=Symbol("template");function i(e,...t){var r;const l=null!==(r=e[a])&&void 0!==r?r:e[a]=n(document,e),{fragment:s}=o(document,l,t);return s}function c(e,...t){var r;const l=null!==(r=e[a])&&void 0!==r?r:e[a]=n(document,e);if(1!==l.content.childElementCount)throw new Error(`html.element template should have a single top-level element: ${e.join("⚡")}`);const{fragment:s}=o(document,l,t);return s.firstElementChild}i.el=c,i.element=c,i.instance=function(e,...t){var i;const c=null!==(i=e[a])&&void 0!==i?i:e[a]=n(document,e),{fragment:u,slots:f,attrValueSlots:d,nodeSlots:m}=o(document,c,t);return{fragment:u,node:u.firstChild,element:u.firstElementChild,slots:f.map((e=>({update(t){!function(e,t,n){switch(t.type){case"node":l(e,t,n);break;case"attr-value":s(t,n)}}(document,e,t)}}))),attrSlots:d.map((({element:e,name:t})=>({element:e,name:t,remove(){e.removeAttribute(t)},set(n){e.setAttribute(t,n)}}))),childSlots:m.map((({startAfter:e,endBefore:t})=>{return{nodes:()=>r(e,t),range:n,clear(){n().deleteContents()},prepend(...n){e?e.after(...n):t.parentNode.prepend(...n)},append(...e){t.before(...e)},replace(...e){n().deleteContents(),t.before(...e)}};function n(){const n=document.createRange();return e?n.setStartAfter(e):n.setStart(t.parentNode,0),n.setEndBefore(t),n}}))}},module.exports=i; |
@@ -1,12 +0,7 @@ | ||
// Stolen from hyper-html! Should work fine for now as it | ||
// just needs to not be in the template, not the content. | ||
import { replacement, createTemplate, createTemplateInstance, updateSlot, collectChildNodes, } from './template'; | ||
const templates = new Map(); | ||
import { collectChildNodes, createTemplate, createTemplateInstance, replacement, updateSlot, } from "./template"; | ||
const templateSymbol = Symbol("template"); | ||
/** Create some HTML content from a template string. */ | ||
export default function html(strings, ...args) { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
var _a; | ||
const template = (_a = strings[templateSymbol]) !== null && _a !== void 0 ? _a : (strings[templateSymbol] = createTemplate(document, strings)); | ||
const { fragment } = createTemplateInstance(document, template, args); | ||
@@ -19,7 +14,4 @@ return fragment; | ||
function htmlElement(strings, ...args) { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
var _a; | ||
const template = (_a = strings[templateSymbol]) !== null && _a !== void 0 ? _a : (strings[templateSymbol] = createTemplate(document, strings)); | ||
if (template.content.childElementCount !== 1) { | ||
@@ -34,7 +26,4 @@ throw new Error(`html.element template should have a single top-level element: ${strings.join(replacement)}`); | ||
function htmlInstance(strings, ...args) { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
var _a; | ||
const template = (_a = strings[templateSymbol]) !== null && _a !== void 0 ? _a : (strings[templateSymbol] = createTemplate(document, strings)); | ||
const { fragment, slots, attrValueSlots, nodeSlots } = createTemplateInstance(document, template, args); | ||
@@ -41,0 +30,0 @@ return { |
import { nodeFromPath, pathToNode } from './paths'; | ||
// Stolen from hyper-html! Should work fine for now as it | ||
// just needs to not be in the template, not the content. | ||
export const replacement = '⚡'; | ||
@@ -3,0 +5,0 @@ export function createTemplate(document, strings) { |
@@ -1,7 +0,12 @@ | ||
import { TemplateArgument } from './template'; | ||
import { Template, TemplateArgument } from "./template"; | ||
declare const templateSymbol: unique symbol; | ||
export { TemplateArgument }; | ||
declare global { | ||
interface TemplateStringsArray { | ||
[templateSymbol]?: Template; | ||
} | ||
} | ||
/** Create some HTML content from a template string. */ | ||
export default function html(strings: TemplateStringsArray, ...args: TemplateArgument[]): DocumentFragment; | ||
/** Create some HTML content from a template string. */ | ||
export default namespace html { | ||
declare function html(strings: TemplateStringsArray, ...args: TemplateArgument[]): DocumentFragment; | ||
declare namespace html { | ||
var el: typeof htmlElement; | ||
@@ -11,5 +16,6 @@ var element: typeof htmlElement; | ||
} | ||
export default html; | ||
/** Create an HTML element from a template string. */ | ||
declare function htmlElement(strings: TemplateStringsArray, ...args: TemplateArgument[]): Element; | ||
interface Instance { | ||
export interface Instance { | ||
fragment: DocumentFragment; | ||
@@ -22,6 +28,6 @@ node: Node | null; | ||
} | ||
interface Slot { | ||
export interface Slot { | ||
update(arg: TemplateArgument): void; | ||
} | ||
interface ChildSlot { | ||
export interface ChildSlot { | ||
nodes(): ChildNode[]; | ||
@@ -34,3 +40,3 @@ range(): Range; | ||
} | ||
interface AttrSlot { | ||
export interface AttrSlot { | ||
element: Element; | ||
@@ -37,0 +43,0 @@ name: string; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// Stolen from hyper-html! Should work fine for now as it | ||
// just needs to not be in the template, not the content. | ||
const template_1 = require("./template"); | ||
const templates = new Map(); | ||
const templateSymbol = Symbol("template"); | ||
/** Create some HTML content from a template string. */ | ||
function html(strings, ...args) { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = template_1.createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
const { fragment } = template_1.createTemplateInstance(document, template, args); | ||
var _a; | ||
const template = (_a = strings[templateSymbol]) !== null && _a !== void 0 ? _a : (strings[templateSymbol] = (0, template_1.createTemplate)(document, strings)); | ||
const { fragment } = (0, template_1.createTemplateInstance)(document, template, args); | ||
return fragment; | ||
@@ -22,11 +17,8 @@ } | ||
function htmlElement(strings, ...args) { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = template_1.createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
var _a; | ||
const template = (_a = strings[templateSymbol]) !== null && _a !== void 0 ? _a : (strings[templateSymbol] = (0, template_1.createTemplate)(document, strings)); | ||
if (template.content.childElementCount !== 1) { | ||
throw new Error(`html.element template should have a single top-level element: ${strings.join(template_1.replacement)}`); | ||
} | ||
const { fragment } = template_1.createTemplateInstance(document, template, args); | ||
const { fragment } = (0, template_1.createTemplateInstance)(document, template, args); | ||
return fragment.firstElementChild; | ||
@@ -37,8 +29,5 @@ } | ||
function htmlInstance(strings, ...args) { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = template_1.createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
const { fragment, slots, attrValueSlots, nodeSlots } = template_1.createTemplateInstance(document, template, args); | ||
var _a; | ||
const template = (_a = strings[templateSymbol]) !== null && _a !== void 0 ? _a : (strings[templateSymbol] = (0, template_1.createTemplate)(document, strings)); | ||
const { fragment, slots, attrValueSlots, nodeSlots } = (0, template_1.createTemplateInstance)(document, template, args); | ||
return { | ||
@@ -50,3 +39,3 @@ fragment, | ||
update(arg) { | ||
template_1.updateSlot(document, slot, arg); | ||
(0, template_1.updateSlot)(document, slot, arg); | ||
}, | ||
@@ -67,3 +56,3 @@ })), | ||
nodes() { | ||
return template_1.collectChildNodes(startAfter, endBefore); | ||
return (0, template_1.collectChildNodes)(startAfter, endBefore); | ||
}, | ||
@@ -70,0 +59,0 @@ range, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.nodeFromPath = exports.pathToNode = void 0; | ||
/** | ||
@@ -4,0 +5,0 @@ * Return the array of child indexes from a root to a target node. |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.updateSlot = exports.updateAttrValueSlot = exports.updateNodeSlot = exports.collectChildNodes = exports.createTemplateInstance = exports.createTemplate = exports.replacement = void 0; | ||
const paths_1 = require("./paths"); | ||
// Stolen from hyper-html! Should work fine for now as it | ||
// just needs to not be in the template, not the content. | ||
exports.replacement = '⚡'; | ||
@@ -34,3 +37,3 @@ function createTemplate(document, strings) { | ||
type: 'node', | ||
path: paths_1.pathToNode(content, split), | ||
path: (0, paths_1.pathToNode)(content, split), | ||
}; | ||
@@ -48,3 +51,3 @@ lastSlot = slot; | ||
type: 'attr-value', | ||
path: paths_1.pathToNode(content, element), | ||
path: (0, paths_1.pathToNode)(content, element), | ||
name: attr.name, | ||
@@ -73,3 +76,3 @@ }); | ||
const templateSlot = template.slots[i]; | ||
const node = paths_1.nodeFromPath(fragment, templateSlot.path); | ||
const node = (0, paths_1.nodeFromPath)(fragment, templateSlot.path); | ||
switch (templateSlot.type) { | ||
@@ -76,0 +79,0 @@ default: |
{ | ||
"name": "@simonbuchan/html", | ||
"license": "MIT", | ||
"version": "0.9.0", | ||
"version": "0.9.1", | ||
"main": "lib/html.js", | ||
@@ -26,6 +26,6 @@ "module": "lib-esm/html.js", | ||
"devDependencies": { | ||
"rollup": "^1.1.2", | ||
"rollup-plugin-terser": "^4.0.2", | ||
"typescript": "~3.2.4" | ||
"rollup": "2", | ||
"rollup-plugin-terser": "7", | ||
"typescript": "4.4" | ||
} | ||
} |
@@ -0,0 +0,0 @@ # Yet Another HTML tagged string template library |
@@ -0,0 +0,0 @@ import { terser } from 'rollup-plugin-terser'; |
@@ -1,24 +0,24 @@ | ||
// Stolen from hyper-html! Should work fine for now as it | ||
// just needs to not be in the template, not the content. | ||
import { | ||
replacement, | ||
collectChildNodes, | ||
createTemplate, | ||
TemplateArgument, | ||
createTemplateInstance, | ||
replacement, | ||
Template, | ||
updateSlot, updateAttrValueSlot, collectChildNodes, | ||
} from './template'; | ||
TemplateArgument, | ||
updateSlot, | ||
} from "./template"; | ||
const templates = new Map<TemplateStringsArray, Template>(); | ||
const templateSymbol = Symbol("template"); | ||
export { TemplateArgument }; | ||
declare global { | ||
interface TemplateStringsArray { | ||
[templateSymbol]?: Template; | ||
} | ||
} | ||
/** Create some HTML content from a template string. */ | ||
export default function html(strings: TemplateStringsArray, ...args: TemplateArgument[]): DocumentFragment { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
const template = strings[templateSymbol] ??= createTemplate(document, strings); | ||
const { fragment } = createTemplateInstance(document, template, args); | ||
@@ -32,7 +32,3 @@ return fragment; | ||
function htmlElement(strings: TemplateStringsArray, ...args: TemplateArgument[]): Element { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
const template = strings[templateSymbol] ??= createTemplate(document, strings); | ||
@@ -48,3 +44,3 @@ if (template.content.childElementCount !== 1) { | ||
interface Instance { | ||
export interface Instance { | ||
fragment: DocumentFragment; | ||
@@ -58,7 +54,7 @@ node: Node | null; | ||
interface Slot { | ||
export interface Slot { | ||
update(arg: TemplateArgument): void; | ||
} | ||
interface ChildSlot { | ||
export interface ChildSlot { | ||
nodes(): ChildNode[]; | ||
@@ -72,3 +68,3 @@ range(): Range; | ||
interface AttrSlot { | ||
export interface AttrSlot { | ||
element: Element; | ||
@@ -84,7 +80,3 @@ name: string; | ||
function htmlInstance(strings: TemplateStringsArray, ...args: TemplateArgument[]): Instance { | ||
let template = templates.get(strings); | ||
if (!template) { | ||
template = createTemplate(document, strings); | ||
templates.set(strings, template); | ||
} | ||
const template = strings[templateSymbol] ??= createTemplate(document, strings); | ||
@@ -91,0 +83,0 @@ const { fragment, slots, attrValueSlots, nodeSlots } = createTemplateInstance(document, template, args); |
@@ -0,0 +0,0 @@ export type NodePath = number[]; |
import { nodeFromPath, NodePath, pathToNode } from './paths'; | ||
// Stolen from hyper-html! Should work fine for now as it | ||
// just needs to not be in the template, not the content. | ||
export const replacement = '⚡'; | ||
@@ -4,0 +6,0 @@ |
{ | ||
"compilerOptions": { | ||
"moduleResolution": "node", | ||
"module": "es2015", | ||
"target": "es2018", | ||
"moduleResolution": "Node", | ||
"module": "ES2015", | ||
"target": "ES2018", | ||
"strict": true, | ||
"outDir": "lib-esm", | ||
"sourceMap": true | ||
"sourceMap": true, | ||
"lib": [ | ||
"ES2018", | ||
"DOM", | ||
"DOM.Iterable", | ||
], | ||
"types": [], | ||
}, | ||
@@ -13,2 +19,2 @@ "include": [ | ||
] | ||
} | ||
} |
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
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
79161
1141