init
This commit is contained in:
commit
53e7c46749
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules/
|
||||
dist/
|
1
.npmrc
Normal file
1
.npmrc
Normal file
|
@ -0,0 +1 @@
|
|||
@nulo:registry=https://gitea.nulo.in/api/packages/nulo/npm/
|
81
html.ts
Normal file
81
html.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Inspirado en https://gitea.nulo.in/Nulo/html.lua/src/commit/cb7e35dcca0e45b397baf628f5e1a162a2269638/html.lua
|
||||
|
||||
interface VirtualElement {
|
||||
__element_type: string;
|
||||
things: Thing[];
|
||||
}
|
||||
interface RawHtml {
|
||||
__raw: string;
|
||||
}
|
||||
interface Attributes {
|
||||
[key: string]: string | number;
|
||||
}
|
||||
type Thing = VirtualElement | RawHtml | Attributes | string;
|
||||
type Renderable = VirtualElement | RawHtml | string;
|
||||
|
||||
export const basicElement =
|
||||
(__element_type: string) =>
|
||||
(...things: Thing[]): VirtualElement => ({ __element_type, things });
|
||||
export const raw = (html: string): RawHtml => ({ __raw: html });
|
||||
|
||||
export const doctype = basicElement("!doctype html");
|
||||
export const head = basicElement("head");
|
||||
export const body = basicElement("body");
|
||||
export const meta = basicElement("meta");
|
||||
export const title = basicElement("title");
|
||||
export const link = basicElement("link");
|
||||
export const metaUtf8 = meta({ charset: "utf-8" });
|
||||
export const h1 = basicElement("h1");
|
||||
export const h2 = basicElement("h2");
|
||||
export const h3 = basicElement("h3");
|
||||
export const h4 = basicElement("h4");
|
||||
export const h5 = basicElement("h5");
|
||||
export const h6 = basicElement("h6");
|
||||
export const p = basicElement("p");
|
||||
export const ul = basicElement("ul");
|
||||
export const ol = basicElement("ol");
|
||||
export const li = basicElement("li");
|
||||
export const a = basicElement("a");
|
||||
export const img = basicElement("img");
|
||||
export const span = basicElement("span");
|
||||
export const picture = basicElement("picture");
|
||||
export const source = basicElement("source");
|
||||
export const figure = basicElement("figure");
|
||||
export const figcaption = basicElement("figcaption");
|
||||
export const article = basicElement("article");
|
||||
export const nav = basicElement("nav");
|
||||
export const main = basicElement("main");
|
||||
|
||||
// TODO: actually escape
|
||||
const escapeHTML = (string: string) => string;
|
||||
export const render = (...elements: Renderable[]): string => {
|
||||
if (elements.length > 1) return elements.map((e) => render(e)).join("");
|
||||
if (typeof elements[0] == "string") return escapeHTML(elements[0]);
|
||||
if ("__raw" in elements[0]) return elements[0].__raw;
|
||||
const { __element_type, things } = elements[0];
|
||||
|
||||
const attributes = things.filter(
|
||||
(t) =>
|
||||
!(typeof t == "string") && !("__element_type" in t) && !("__raw" in t)
|
||||
);
|
||||
const children = things.filter(
|
||||
(t) =>
|
||||
typeof t == "string" ||
|
||||
("__element_type" in t && "things" in t) ||
|
||||
"__raw" in t
|
||||
) as Renderable[];
|
||||
const selfClosing =
|
||||
["meta", "img", "source", "link", "br"].includes(__element_type) ||
|
||||
__element_type.startsWith("!"); // doctype
|
||||
|
||||
// TODO: escape attribute values
|
||||
return `<${__element_type}${attributes.length ? " " : ""}${attributes
|
||||
.flatMap((t) =>
|
||||
Object.entries(t).map(([name, value]) => `${name}="${value}"`)
|
||||
)
|
||||
.join("")}${
|
||||
selfClosing
|
||||
? ">"
|
||||
: `>${children.map((c) => render(c)).join("")}</${__element_type}>`
|
||||
}`;
|
||||
};
|
18
package.json
Normal file
18
package.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "@nulo/html.js",
|
||||
"version": "0.0.2",
|
||||
"description": "",
|
||||
"main": "dist/html.js",
|
||||
"files": [
|
||||
"dist/**.js",
|
||||
"dist/**.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"prepublish": "tsc"
|
||||
},
|
||||
"author": "Nulo <git@nulo.in>",
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.11.17",
|
||||
"typescript": "^4.9.4"
|
||||
}
|
||||
}
|
21
pnpm-lock.yaml
Normal file
21
pnpm-lock.yaml
Normal file
|
@ -0,0 +1,21 @@
|
|||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@types/node': ^18.11.17
|
||||
typescript: ^4.9.4
|
||||
|
||||
devDependencies:
|
||||
'@types/node': 18.11.17
|
||||
typescript: 4.9.4
|
||||
|
||||
packages:
|
||||
|
||||
/@types/node/18.11.17:
|
||||
resolution: {integrity: sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==}
|
||||
dev: true
|
||||
|
||||
/typescript/4.9.4:
|
||||
resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
11
tsconfig.json
Normal file
11
tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"target": "es2022",
|
||||
"module": "es2022",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"strict": true,
|
||||
"outDir": "dist/"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue