Skip to content

Commit 3dec9a6

Browse files
committed
ready
1 parent c2ef854 commit 3dec9a6

7 files changed

Lines changed: 17 additions & 50 deletions

File tree

*htm.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# HTM (Hyperscript Tagged Markup)
22

3+
<img src="https://i.imgur.com/09ih11e.jpg" align="center" width="715">
4+
35
`htm` is an implementation of JSX-like syntax in plain JavaScript, using [Tagged Template Literals].
46
It lets your build apps using Preact/React/etc directly in the browser.
57
JSX can be converted to `htm` with only a few tiny modifications.
@@ -25,6 +27,7 @@ Here's some ergonomic features you get for free that aren't present in JSX:
2527
- HTML's self-closing tags: `<img src=${url}>`
2628
- Optional end-tags: `<section><h1>this is the whole template!`
2729
- Convenient implicit end-tags: `<${Footer}>footer content<//>`
30+
- Support for HTML comments: `<div><!-- don't delete this! --></div>`
2831

2932
## Project Status
3033

dist-preact.mjs

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

dist-preact.umd.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
var e={},t=document.createElement("template"),r=/(\$_h\[\d+\])/g;function n(e,t){return t.toUpperCase()}function a(e,t){var n=e.match(r),a=JSON.stringify(e);if(null!=n){if(n[0]===e)return e;a=a.replace(r,'"'+t+"$1"+t+'"').replace(/"[+,]"/g,""),","===t&&(a="["+a+"]")}return a}export default function(r){return function(i){return(e[i]||(e[i]=function(e){for(var r=e[0],i=1;i<e.length;)r+="$_h["+i+"]"+e[i++];return t.innerHTML=r.replace(/<(\/?)(\$_h\[\d+\])/g,"<$1c c@=$2").replace(/<([\w:-]+)(\s.*?)?\/>/gi,"<$1$2></$1>").trim(),Function("h","$_h","return "+function e(t){if(1!==t.nodeType)return 3===t.nodeType&&t.data?a(t.data,","):"null";for(var r='"'+t.localName+'"',i="{",u="",c="}",l=0;l<t.attributes.length;l++){var o=t.attributes[l],f=o.name,h=o.value;"c@"!=f?f.match(/^\.\.\./)?(c="})",i="Object.assign("+i+"},"+f.substring(3)+",{",u=""):(i+=u+'"'+f.replace(/:(\w)/g,n)+'":'+(!h||a(h,"+")),u=","):r=h}i="h("+r+","+(i+c);for(var g=t.firstChild;g;)i+=","+e(g),g=g.nextSibling;return i+")"}((t.content||t).firstChild))}(i)))(r,arguments)}};
1+
var e={},t=document.createElement("template"),r=/(\$_h\[\d+\])/g;function n(e,t){return t.toUpperCase()}function a(e,t){var n=e.match(r),a=JSON.stringify(e);if(null!=n){if(n[0]===e)return e;a=a.replace(r,'"'+t+"$1"+t+'"').replace(/"[+,]"/g,""),","===t&&(a="["+a+"]")}return a}export default function(r){return(e[r]||(e[r]=function(e){for(var r=e[0],i=1;i<e.length;)r+="$_h["+i+"]"+e[i++];return t.innerHTML=r.replace(/<(\/?)(\$_h\[\d+\])/g,"<$1c c@=$2").replace(/<([\w:-]+)(\s.*?)?\/>/gi,"<$1$2></$1>").trim(),Function("h","$_h","return "+function e(t){if(1!==t.nodeType)return 3===t.nodeType&&t.data?a(t.data,","):"null";for(var r='"'+t.localName+'"',i="{",u="",c="}",l=0;l<t.attributes.length;l++){var o=t.attributes[l],f=o.name,s=o.value;"c@"!=f?"..."!==f.substring(0,3)?(i+=u+'"'+f.replace(/:(\w)/g,n)+'":'+(!s||a(s,"+")),u=","):(c="})",i="Object.assign("+i+"},"+f.substring(3)+",{",u=""):r=s}i="h("+r+","+i+c;for(var g=t.firstChild;g;)i+=","+e(g),g=g.nextSibling;return i+")"}((t.content||t).firstChild))}(r)))(this,arguments)};

dist.umd.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-preact.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ export function render(tree, parent) {
77
preactRender(tree, parent, parent.firstElementChild);
88
}
99

10-
export const html = htm(h);
10+
export const html = htm.bind(h);

src.js

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,24 @@
1-
// import { h, Component, render as preactRender } from 'preact';
2-
3-
// const CACHE = new Map();
41
const CACHE = {};
52

6-
const tn = document.createElement('template');
3+
const TEMPLATE = document.createElement('template');
74

85
const reg = /(\$_h\[\d+\])/g;
96

10-
// export function render(tree, parent) {
11-
// preactRender(tree, parent, parent.firstElementChild);
12-
// }
13-
14-
// export { h, Component };
15-
16-
export default function htm(h) {
17-
return function (statics) {
18-
const tpl = CACHE[statics] || (CACHE[statics] = build(statics));
19-
// eslint-disable-next-line prefer-rest-params
20-
return tpl(h, arguments);
21-
};
7+
export default function html(statics) {
8+
const tpl = CACHE[statics] || (CACHE[statics] = build(statics));
9+
// eslint-disable-next-line prefer-rest-params
10+
return tpl(this, arguments);
2211
}
2312

24-
// export function html(statics) {
25-
// const tpl = CACHE[statics] || (CACHE[statics] = build(statics));
26-
// // return tpl(holes, h);
27-
// // eslint-disable-next-line prefer-rest-params
28-
// return tpl(h, arguments);
29-
// }
3013

3114
/** Create a template function given strings from a tagged template literal. */
3215
function build(statics) {
3316
let str = statics[0], i = 1;
3417
while (i < statics.length) {
3518
str += '$_h[' + i + ']' + statics[i++];
3619
}
37-
// let str = '', i = 0;
38-
// while (i < statics.length) {
39-
// // if (i !== 0) str += `$_h[${i - 1}]`;
40-
// if (i !== 0) str += `$_h[${i}]`;
41-
// str += statics[i++];
42-
// }
43-
44-
// tn.innerHTML = str.replace(/<(\$_h\[\d+\])/g, '<c c@=$1').replace(/<\/\$_h\[\d+\]/g, '</c').replace(/<([a-z0-9:@-]+)(\s.*?)?\/>/gi, '<$1$2></$1>').trim();
45-
// tn.innerHTML = str.replace(/<(\/?)(\$_h\[\d+\])/g, '<$1c c@=$2').replace(/<([a-z0-9:@-]+)(\s.*?)?\/>/gi, '<$1$2></$1>').trim();
46-
// tn.innerHTML = str.replace(/<(\/?)(\$_h\[\d+\])/g, '<$1c c@=$2').replace(/<([\w-]+)(\s.*?)?\/>/gi, '<$1$2></$1>').replace(RegExp(str.match(/\n\s*/)[0]));
47-
// tn.innerHTML = str.replace(/<(\/?)(\$_h\[\d+\])/g, '<$1c c@=$2').replace(/\/>/g, '></c>').trim();
48-
// tn.innerHTML = str.replace(/<(\/?)(\$_h\[\d+\])((\s.*?)?\/>)?/g, (s, slash, name, closing) => (slash ? '' : `<c c@=${name}${closing}${closing?`</${name}>`:''}`) + (slash || closing ? `</${name}>` : '')).trim();
49-
tn.innerHTML = str.replace(/<(\/?)(\$_h\[\d+\])/g, '<$1c c@=$2').replace(/<([\w:-]+)(\s.*?)?\/>/gi, '<$1$2></$1>').trim();
50-
return Function('h', '$_h', 'return ' + walk((tn.content || tn).firstChild));
51-
// const dom = new DOMParser().parseFromString(str.replace(/<(\$_h\[\d+\])/g, '<c@ c@=$1').replace(/<\/\$_h\[\d+\]/g, '</c@').replace(/<([a-z0-9:@-]+)(\s.*?)?\/>/gi, '<$1$2></$1>').trim(), 'text/html').body.firstChild;
52-
// return Function('h', '$_h', 'return ' + walk(dom));
20+
TEMPLATE.innerHTML = str.replace(/<(\/?)(\$_h\[\d+\])/g, '<$1c c@=$2').replace(/<([\w:-]+)(\s.*?)?\/>/gi, '<$1$2></$1>').trim();
21+
return Function('h', '$_h', 'return ' + walk((TEMPLATE.content || TEMPLATE).firstChild));
5322
}
5423

5524
/** Traverse a DOM tree and serialize it to hyperscript function calls */
@@ -58,28 +27,23 @@ function walk(n) {
5827
if (n.nodeType === 3 && n.data) return field(n.data, ',');
5928
return 'null';
6029
}
61-
// let str = 'h(' + (n.getAttribute('c@') || `"${n.localName}"`) + ',', val, name;
6230
let nodeName = `"${n.localName}"`, str = '{', sub='', end='}';
6331
for (let i=0; i<n.attributes.length; i++) {
6432
let { name, value } = n.attributes[i];
6533
if (name=='c@') {
6634
nodeName = value;
6735
continue;
6836
}
69-
if (name.match(/^\.\.\./)) {
37+
if (name.substring(0,3)==='...') {
7038
end = '})';
7139
str = 'Object.assign(' + str + '},' + name.substring(3) + ',{';
7240
sub = '';
7341
continue;
7442
}
75-
// if (str) str += ',';
76-
// if (sub) str += ',';
7743
str += `${sub}"${name.replace(/:(\w)/g, upper)}":${value ? field(value, '+') : true}`;
7844
sub = ',';
7945
}
80-
str = 'h(' + nodeName + ',' + (str + end);
81-
// str = 'h(' + nodeName + ',' + (str ? (start + str + end) : 'null');
82-
// str += val === undefined ? 'null' : '}';
46+
str = 'h(' + nodeName + ',' + str + end;
8347
let child = n.firstChild;
8448
while (child) {
8549
str += ',' + walk(child);

0 commit comments

Comments
 (0)