diff --git a/cjs/utils.js b/cjs/utils.js index 6a12b07..2b2c47c 100644 --- a/cjs/utils.js +++ b/cjs/utils.js @@ -77,7 +77,13 @@ const parse = (template, expectedLength, svg) => { case name[0] === '.': const lower = name.slice(1).toLowerCase(); updates.push(lower === 'dataset' ? - (value => (pre + keys(value).map(data, value).join(''))) : + (value => ( + pre + + keys(value) + .filter(key => value[key] != null) + .map(data, value) + .join('') + )) : (value => { let result = pre; // null, undefined, and false are not shown at all diff --git a/es.js b/es.js index 1598b4b..e7cfd20 100644 --- a/es.js +++ b/es.js @@ -1 +1 @@ -self.uhtml=function(e){"use strict";const{replace:t}="",n=/[&<>'"]/g,r={"&":"&","<":"<",">":">","'":"'",'"':"""},s=e=>r[e],c=e=>t.call(e,n,s);const a=/([^\s\\>"'=]+)\s*=\s*(['"]?)$/,o=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,i=/<[a-z][^>]+$/i,u=/>[^<>]*$/,l=/<([a-z]+[a-z0-9:._-]*)([^>]*?)(\/>)/gi,$=/\s+$/,p=(e,t)=>0o.test(t)?e:`<${t}${n.replace($,"")}>`;const{isArray:g}=Array,{toString:h}=Function,{keys:b}=Object,m=(e=>{let t;return n=>{t!==n&&(t=n,"function"==typeof n?n(e):n.current=e)}})(null),w="isµ"+Date.now(),k=new RegExp(`(\x3c!--${w}(\\d+)--\x3e|\\s*${w}(\\d+)=('|")([^\\4]+?)\\4)`,"g"),d=(e,t,n)=>` ${e}=${t}${c(n)}${t}`,y=e=>{switch(typeof e){case"string":return c(e);case"boolean":case"number":return String(e);case"object":switch(!0){case g(e):return e.map(y).join("");case e instanceof x:return e.toString()}break;case"function":return y(e())}return null==e?"":c(String(e))};class x extends String{}const j=(e,t,n)=>{const r=((e,t,n)=>{const r=[],{length:s}=e;for(let n=1;n`${t}${n-1}=${s||'"'}${r}${s?"":'"'}`)):`${s}\x3c!--${t}${n-1}--\x3e`)}r.push(e[s-1]);const c=r.join("").trim();return n?c:c.replace(l,f)})(e,w,n),s=[];let c=0,o=null;for(;o=k.exec(r);){const e=r.slice(c,o.index);if(c=o.index+o[0].length,o[2])s.push((t=>e+y(t)));else{let t=o[5];const n=o[4];switch(!0){case"aria"===t:s.push((t=>e+b(t).map(S,t).join("")));break;case"ref"===t:s.push((t=>(m(t),e)));break;case"?"===t[0]:const r=t.slice(1).toLowerCase();s.push((t=>{let n=e;return t&&(n+=` ${r}`),n}));break;case"."===t[0]:const c=t.slice(1).toLowerCase();s.push("dataset"===c?t=>e+b(t).map(v,t).join(""):t=>{let r=e;return null!=t&&!1!==t&&(r+=!0===t?` ${c}`:d(c,n,t)),r});break;case"@"===t[0]:t="on"+t.slice(1);case"o"===t[0]&&"n"===t[1]:s.push((r=>{let s=e;switch(typeof r){case"object":if(!(t in r))break;if("function"!=typeof(r=r[t]))break;case"function":if(r.toString===h)break;case"string":s+=d(t,n,r)}return s}));break;default:s.push((r=>{let s=e;return null!=r&&(s+=d(t,n,r)),s}))}}}const{length:i}=s;if(i!==t)throw new Error(`invalid template ${e}`);if(i){const e=s[i-1],t=r.slice(c);s[i-1]=n=>e(n)+t}else s.push((()=>r));return s};function S(e){const t=c(this[e]);return"role"===e?` role="${t}"`:` aria-${e.toLowerCase()}="${t}"`}function v(e){return` data-${t=e,t.replace(/(([A-Z0-9])([A-Z0-9][a-z]))|(([a-z])([A-Z]))/g,"$2$5-$3$6").toLowerCase()}="${c(this[e])}"`;var t}const z=(A=new WeakMap,{get:e=>A.get(e),set:(e,t)=>(A.set(e,t),t)});var A;const C=e=>{const t=(t,...n)=>{const{length:r}=n,s=z.get(t)||z.set(t,j(t,r,e));return new x(r?n.map(E,s).join(""):s[0]())};return t.node=t,t.for=()=>t,t},L=C(!1),Z=C(!0);function E(e,t){return this[t](e)}return e.Hole=x,e.html=L,e.render=(e,t)=>{const n=("function"==typeof t?t():t).toString();return"function"==typeof e?e(n):(e.write(n),e)},e.svg=Z,e}({}); +self.uhtml=function(e){"use strict";const{replace:t}="",n=/[&<>'"]/g,r={"&":"&","<":"<",">":">","'":"'",'"':"""},s=e=>r[e],c=e=>t.call(e,n,s);const a=/([^\s\\>"'=]+)\s*=\s*(['"]?)$/,o=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,i=/<[a-z][^>]+$/i,u=/>[^<>]*$/,l=/<([a-z]+[a-z0-9:._-]*)([^>]*?)(\/>)/gi,$=/\s+$/,p=(e,t)=>0o.test(t)?e:`<${t}${n.replace($,"")}>`;const{isArray:g}=Array,{toString:h}=Function,{keys:b}=Object,m=(e=>{let t;return n=>{t!==n&&(t=n,"function"==typeof n?n(e):n.current=e)}})(null),w="isµ"+Date.now(),k=new RegExp(`(\x3c!--${w}(\\d+)--\x3e|\\s*${w}(\\d+)=('|")([^\\4]+?)\\4)`,"g"),d=(e,t,n)=>` ${e}=${t}${c(n)}${t}`,y=e=>{switch(typeof e){case"string":return c(e);case"boolean":case"number":return String(e);case"object":switch(!0){case g(e):return e.map(y).join("");case e instanceof x:return e.toString()}break;case"function":return y(e())}return null==e?"":c(String(e))};class x extends String{}const j=(e,t,n)=>{const r=((e,t,n)=>{const r=[],{length:s}=e;for(let n=1;n`${t}${n-1}=${s||'"'}${r}${s?"":'"'}`)):`${s}\x3c!--${t}${n-1}--\x3e`)}r.push(e[s-1]);const c=r.join("").trim();return n?c:c.replace(l,f)})(e,w,n),s=[];let c=0,o=null;for(;o=k.exec(r);){const e=r.slice(c,o.index);if(c=o.index+o[0].length,o[2])s.push((t=>e+y(t)));else{let t=o[5];const n=o[4];switch(!0){case"aria"===t:s.push((t=>e+b(t).map(S,t).join("")));break;case"ref"===t:s.push((t=>(m(t),e)));break;case"?"===t[0]:const r=t.slice(1).toLowerCase();s.push((t=>{let n=e;return t&&(n+=` ${r}`),n}));break;case"."===t[0]:const c=t.slice(1).toLowerCase();s.push("dataset"===c?t=>e+b(t).filter((e=>null!=t[e])).map(v,t).join(""):t=>{let r=e;return null!=t&&!1!==t&&(r+=!0===t?` ${c}`:d(c,n,t)),r});break;case"@"===t[0]:t="on"+t.slice(1);case"o"===t[0]&&"n"===t[1]:s.push((r=>{let s=e;switch(typeof r){case"object":if(!(t in r))break;if("function"!=typeof(r=r[t]))break;case"function":if(r.toString===h)break;case"string":s+=d(t,n,r)}return s}));break;default:s.push((r=>{let s=e;return null!=r&&(s+=d(t,n,r)),s}))}}}const{length:i}=s;if(i!==t)throw new Error(`invalid template ${e}`);if(i){const e=s[i-1],t=r.slice(c);s[i-1]=n=>e(n)+t}else s.push((()=>r));return s};function S(e){const t=c(this[e]);return"role"===e?` role="${t}"`:` aria-${e.toLowerCase()}="${t}"`}function v(e){return` data-${t=e,t.replace(/(([A-Z0-9])([A-Z0-9][a-z]))|(([a-z])([A-Z]))/g,"$2$5-$3$6").toLowerCase()}="${c(this[e])}"`;var t}const z=(A=new WeakMap,{get:e=>A.get(e),set:(e,t)=>(A.set(e,t),t)});var A;const C=e=>{const t=(t,...n)=>{const{length:r}=n,s=z.get(t)||z.set(t,j(t,r,e));return new x(r?n.map(E,s).join(""):s[0]())};return t.node=t,t.for=()=>t,t},L=C(!1),Z=C(!0);function E(e,t){return this[t](e)}return e.Hole=x,e.html=L,e.render=(e,t)=>{const n=("function"==typeof t?t():t).toString();return"function"==typeof e?e(n):(e.write(n),e)},e.svg=Z,e}({}); diff --git a/esm/utils.js b/esm/utils.js index 1f2e31f..bd3a69f 100644 --- a/esm/utils.js +++ b/esm/utils.js @@ -75,7 +75,13 @@ export const parse = (template, expectedLength, svg) => { case name[0] === '.': const lower = name.slice(1).toLowerCase(); updates.push(lower === 'dataset' ? - (value => (pre + keys(value).map(data, value).join(''))) : + (value => ( + pre + + keys(value) + .filter(key => value[key] != null) + .map(data, value) + .join('') + )) : (value => { let result = pre; // null, undefined, and false are not shown at all diff --git a/index.js b/index.js index 907e054..9bddf1a 100644 --- a/index.js +++ b/index.js @@ -178,7 +178,13 @@ self.uhtml = (function (exports) { case name[0] === '.': const lower = name.slice(1).toLowerCase(); updates.push(lower === 'dataset' ? - (value => (pre + keys(value).map(data, value).join(''))) : + (value => ( + pre + + keys(value) + .filter(key => value[key] != null) + .map(data, value) + .join('') + )) : (value => { let result = pre; // null, undefined, and false are not shown at all diff --git a/test/index.js b/test/index.js index 4c4ce4a..7f8ded3 100644 --- a/test/index.js +++ b/test/index.js @@ -94,6 +94,11 @@ assert( `is a html test` ); +assert( + render(String, html`is a html test`), + `is a html test` +); + assert( render(String, html`is a html test`), ``