Skip to content

Instantly share code, notes, and snippets.

@nykula
Last active May 13, 2020 00:10
Show Gist options
  • Save nykula/0575494162a547100b5432938330ebe8 to your computer and use it in GitHub Desktop.
Save nykula/0575494162a547100b5432938330ebe8 to your computer and use it in GitHub Desktop.
#!/usr/bin/qjs
// Initial hyperscript test cases, framework-independent.
// ./h.test.js|tee h.test~|diff -u h.test -&&echo ok h.test||echo fail h.test
// 0BSD / public domain. 2020 Denys Nykula <nykula@ukr.net>
// TODO h("p", h("hr")), h("p", h("hr"), "2020"), h("p", "2020", h("hr"))
// TODO h('a[href=#][title="hyper script"]')
function h(s, a, c) {
if (!c && a && ("" + a === a || 0 in a)) (c = a), (a = {});
(a = a || {}), (c = c || []);
if ("" + s !== s) return s(a, c);
var k = "";
var t = "div";
var r = /^(\w+)|^\.(\w+)|^#(\w+)|^\[(\w+)=(\w+)\]|^(\s*>\s*|$)/;
var xs = [];
for (var m; (m = r.exec(s)); s = s.slice(m.index + m[0].length))
if (m[1]) t = m[1];
else if (m[2]) k = (k ? k + " " : "") + m[2];
else if (m[3] && !a.id) a.id = m[3];
else if (m[4]) a[m[4]] = m[5];
else if (m[6] || m[6] == "") {
a.className = k + (a.className ? " " + a.className : "");
xs.push([t, a, c]), (a = {}), (k = ""), (t = "div");
if (m[6] == "") break;
}
for (var x; (x = xs.pop()) && xs.length; ) xs[xs.length - 1][2] = [x];
return x;
}
var render = (x) => x;
var t = (...x) => console.log(JSON.stringify(x));
t("creates div with text", render(h("div", "Hyperscript")));
t("creates div with text[1]", render(h("div", ["Hyperscript"])));
t("creates div with text[3]", render(h("div", ["Hyper", " ", "script"])));
t(
"creates a with href and text",
render(h("a", { href: "about:blank" }, "Home"))
);
t(
"creates div explicitly with classes",
[1, 0].map((big) => render(h("div.hr" + (big ? ".big" : ""))))
);
t(
"creates div implicitly with classes",
[1, 0].map((big) => render(h(".hr" + (big ? ".big" : ""))))
);
t(
"creates nested tree",
render(
h("#wrap > header>.container", [
h(".brand", null, [
h("div.title", { className: "punch" }, [
h("a", { href: "#" }, [
h("h1", "Initial hyperscript test cases."),
h("p.sub", "Framework-independent!"),
]),
]),
]),
h("nav"),
])
)
);
t(
"allows array child",
render(
h("article", [
h("h1", "Jackdaws love my big sphinx of quartz?"),
[
"Zing, vext cwm fly jabs Kurd qoph.",
"Foo bar baz qux!",
"Prating jokers quizzically vexed me with fibs.",
].map((p) => h("p", p)),
h("p.more", [h("a", { href: "#" }, "Read more")]),
])
)
);
function TodoV(props) {
return h(".todo", [
h("label.inner", [
h("input.done", {
checked: props.done ? "checked" : "",
type: "checkbox",
}),
" ",
h("span.text", props.text),
]),
]);
}
function TodoAdd() {
return h("form#todoadd[method=POST]", [
h("input.todoaddtext", {
placeholder: "Create a todo",
title: "Todo text",
type: "text",
}),
h("button", { type: "submit" }, "Submit"),
]);
}
class TodosV {
static fetch() {
return {
todos: [
{ done: true, text: "Wake up" },
{ done: false, text: "Drink coffee" },
{ done: true, text: "Take shower" },
],
};
}
static render(props) {
return h(".todos", [h(TodoAdd), props.todos.map((x) => h(TodoV, x))]);
}
}
// How do you pass props from server to client in Crank instead? Tell me pls :D
t("renders todos", render(h(TodosV.render, TodosV.fetch())));
// Also, how do you return them without render, when headers.accept says json?
t("doesn't render todos", TodosV.fetch());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment