@eeue56/coed
Version:
Write HTML in pure TS
1,176 lines (1,175 loc) • 37.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.class_ = class_;
exports.style_ = style_;
exports.none = none;
exports.attribute = attribute;
exports.booleanAttribute = booleanAttribute;
exports.on = on;
exports.onInput = onInput;
exports.text = text;
exports.node = node;
exports.voidNode = voidNode;
exports.nodeNS = nodeNS;
exports.voidNodeNS = voidNodeNS;
exports.render = render;
exports.flatRender = flatRender;
exports.fromString = fromString;
exports.hydrate = hydrate;
exports.hydrateNode = hydrateNode;
exports.buildTree = buildTree;
exports.triggerEvent = triggerEvent;
exports.map = map;
exports.program = program;
exports.a = a;
exports.abbr = abbr;
exports.address = address;
exports.area = area;
exports.article = article;
exports.aside = aside;
exports.audio = audio;
exports.b = b;
exports.base = base;
exports.bdi = bdi;
exports.bdo = bdo;
exports.blockquote = blockquote;
exports.body = body;
exports.br = br;
exports.button = button;
exports.canvas = canvas;
exports.caption = caption;
exports.cite = cite;
exports.code = code;
exports.col = col;
exports.colgroup = colgroup;
exports.data = data;
exports.datalist = datalist;
exports.dd = dd;
exports.del = del;
exports.details = details;
exports.dfn = dfn;
exports.dialog = dialog;
exports.div = div;
exports.dl = dl;
exports.dt = dt;
exports.em = em;
exports.embed = embed;
exports.fieldset = fieldset;
exports.figure = figure;
exports.footer = footer;
exports.form = form;
exports.h1 = h1;
exports.h2 = h2;
exports.h3 = h3;
exports.h4 = h4;
exports.h5 = h5;
exports.h6 = h6;
exports.head = head;
exports.header = header;
exports.hgroup = hgroup;
exports.hr = hr;
exports.html = html;
exports.i = i;
exports.iframe = iframe;
exports.img = img;
exports.input = input;
exports.ins = ins;
exports.kbd = kbd;
exports.keygen = keygen;
exports.label = label;
exports.legend = legend;
exports.li = li;
exports.link = link;
exports.main = main;
exports.map_ = map_;
exports.mark = mark;
exports.menu = menu;
exports.menuitem = menuitem;
exports.meta = meta;
exports.meter = meter;
exports.nav = nav;
exports.noscript = noscript;
exports.object = object;
exports.ol = ol;
exports.optgroup = optgroup;
exports.option = option;
exports.output = output;
exports.p = p;
exports.param = param;
exports.pre = pre;
exports.progress = progress;
exports.q = q;
exports.rb = rb;
exports.rp = rp;
exports.rt = rt;
exports.rtc = rtc;
exports.ruby = ruby;
exports.s = s;
exports.samp = samp;
exports.script = script;
exports.section = section;
exports.select = select;
exports.small = small;
exports.source = source;
exports.span = span;
exports.strong = strong;
exports.style = style;
exports.sub = sub;
exports.summary = summary;
exports.sup = sup;
exports.table = table;
exports.tbody = tbody;
exports.td = td;
exports.template = template;
exports.textarea = textarea;
exports.tfoot = tfoot;
exports.th = th;
exports.thead = thead;
exports.time = time;
exports.title = title;
exports.tr = tr;
exports.track = track;
exports.u = u;
exports.ul = ul;
exports.var_ = var_;
exports.video = video;
exports.wbr = wbr;
const ts_core_1 = require("@eeue56/ts-core");
/**
Creates a class attribute - classes are combined by the html creator, so you can use it like:
```
html.div([ ], [ class_("one"), class_("two") ], [ ])
```
*/
function class_(str) {
return {
kind: "string",
key: "class",
value: str,
};
}
/**
Creates a style attribute - styles are combined by the html creator, so you can use it like:
```
html.div([ ], [ style_("color", "red"), style_("background-color", "blue") ], [ ])
```
*/
function style_(key, value) {
return {
kind: "style",
key: key,
value: value,
};
}
/**
An empty attribute - filtered by the html creator on creation. This is useful if you have a tenary
operator, e.g:
```
html.div([ ], [ somethingTruthy ? none() : class_("something") ], [ ])
```
*/
function none() {
return {
kind: "none",
};
}
/**
Create an attribute with a given key and value. This is set via `setAttribute` at runtime.
*/
function attribute(key, value) {
if (key === "style")
return style_(value.split(":")[0], value.split(":")[1]);
return {
kind: "string",
key: key,
value: value,
};
}
/**
Create an attribute with a given key and value. This is set via `setAttribute` at runtime.
*/
function booleanAttribute(key, value) {
return {
kind: "boolean",
key: key,
value: value,
};
}
/**
Creates an event handler for passing to a html node
*/
function on(name, tagger, stopPropagation = true, preventDefault = true) {
return {
name: name,
tagger: (event) => {
if (stopPropagation) {
event.stopPropagation();
}
if (preventDefault) {
event.preventDefault();
}
return tagger(event);
},
};
}
/**
Special-cased input handler
*/
function onInput(tagger) {
return {
name: "input",
tagger: (event) => {
event.stopPropagation();
event.preventDefault();
if (event.target && "value" in event.target) {
return tagger(event.target.value);
}
return tagger("");
},
};
}
/**
Creates a text node
*/
function text(str) {
return {
kind: "text",
text: str,
};
}
/**
Creates a html node with a given tag name, any events, any attributes and any children.
*/
function node(tag, events, attributes, children) {
return {
kind: "regular",
tag: tag,
events: events,
attributes: combineAttributes(attributes),
children: children,
_eventListeners: [],
};
}
/**
Creates a void html node with a given tag name, any events, any attributes.
*/
function voidNode(tag, events, attributes) {
return {
kind: "void",
tag: tag,
events: events,
attributes: combineAttributes(attributes),
_eventListeners: [],
};
}
/**
Creates a void html node with a given tag name, any events, any attributes.
*/
function nodeNS(tag, namespace, events, attributes, children) {
const namespaceXmlns = {
kind: "string",
key: "xmlns",
value: namespace,
};
attributes.push(namespaceXmlns);
return {
kind: "ns-regular",
tag: tag,
namespace,
events: events,
attributes: combineAttributes(attributes),
children: children,
_eventListeners: [],
};
}
/**
Creates a void html node with a given tag name, any events, any attributes.
*/
function voidNodeNS(tag, namespace, events, attributes) {
const namespaceXmlns = {
kind: "string",
key: "xmlns",
value: namespace,
};
attributes.push(namespaceXmlns);
return {
kind: "ns-void",
tag: tag,
namespace,
events: events,
attributes: combineAttributes(attributes),
_eventListeners: [],
};
}
function combineAttributes(attributes) {
const knownStringAttributes = {};
const knownStyleAttributes = [];
const otherAttributes = [];
// group attribute values
attributes.forEach((attribute) => {
switch (attribute.kind) {
case "string":
if (!knownStringAttributes[attribute.key]) {
knownStringAttributes[attribute.key] = [];
}
knownStringAttributes[attribute.key].push(attribute);
break;
case "style":
knownStyleAttributes.push(attribute);
break;
default:
otherAttributes.push(attribute);
}
});
const combinedAttributes = otherAttributes.filter((attribute) => attribute.kind !== "none");
// actually combine attributes together
Object.keys(knownStringAttributes).map((key) => {
combinedAttributes.push(knownStringAttributes[key].reduce((acc, currentValue) => {
if (key === "class") {
acc.value += " " + currentValue.value;
}
return acc;
}));
});
if (knownStyleAttributes.length > 0) {
// actually combine attributes together
combinedAttributes.push(knownStyleAttributes.reduce((acc, currentValue) => {
if (typeof acc.value === "undefined")
acc.value = "";
acc.value +=
currentValue.key + ":" + currentValue.value + ";";
return acc;
}, attribute("style", "")));
}
return combinedAttributes;
}
function renderAttribute(attribute) {
switch (attribute.kind) {
case "string":
if (attribute.value.indexOf('"') > 0) {
return `${attribute.key}='${attribute.value}'`;
}
return `${attribute.key}="${attribute.value}"`;
case "number":
return `${attribute.key}=${attribute.value}`;
case "style":
return "";
case "boolean":
return attribute.value ? `${attribute.key}="${attribute.key}"` : "";
case "none":
return "";
}
}
/**
* Renders a HtmlNode tree as a string.
*/
function render(node, depth = 0) {
const whitespace = " ".repeat(depth * 4);
switch (node.kind) {
case "text":
return whitespace + node.text;
case "void":
case "regular":
case "ns-void":
case "ns-regular": {
const renderedAttributes = node.attributes
.map(renderAttribute)
.join(" ");
const attributes = (renderedAttributes.length > 0 ? " " : "") + renderedAttributes;
switch (node.kind) {
case "void":
case "ns-void":
return whitespace + `<${node.tag}${attributes}>`;
case "regular":
case "ns-regular": {
if (node.children.length > 0) {
return (whitespace +
`<${node.tag}${attributes}>
${node.children.map((child) => render(child, depth + 1)).join("\n")}
${whitespace}</${node.tag}>`);
}
return (whitespace + `<${node.tag}${attributes}></${node.tag}>`);
}
}
}
case "html-string": {
return node.content;
}
}
}
/**
* Render a node without whitespace
*/
function flatRender(node) {
switch (node.kind) {
case "text":
return node.text;
case "void":
case "regular":
case "ns-void":
case "ns-regular": {
const attributes = (node.attributes.length > 0 ? " " : "") +
node.attributes.map(renderAttribute).join(" ");
switch (node.kind) {
case "void":
case "ns-void":
return `<${node.tag}${attributes}>`;
case "regular":
case "ns-regular": {
if (node.children.length > 0) {
return `<${node.tag}${attributes}>${node.children
.map((child) => flatRender(child))
.join("")}</${node.tag}>`;
}
return `<${node.tag}${attributes}></${node.tag}>`;
}
}
}
case "html-string": {
return node.content;
}
}
}
/**
* Create a HtmlStringNode from a html string - and create a DOM element using it
* @param string a string of html
*/
function fromString(string) {
return { kind: "html-string", content: string };
}
/**
Hydrates a root from a given program. Program must have root set as the string "hydration"
**/
function hydrate(program, root) {
program.program.root = root;
const node = program.program.view(program.program.initialModel);
if (node.kind === "text")
return;
if (root.children.length === 0) {
console.error("This root has no children. Did you correctly server-side render content?");
console.error(`Your html should look like <div id="root">{your content}</div>`);
console.error("The root node should have exactly one child, which is your generated html.");
}
hydrateNode(node, program.send, root.children[0]);
}
/**
Attaches event listeners to nodes
*/
function hydrateNode(node, listener, root) {
switch (node.kind) {
case "text": {
return;
}
case "void":
case "regular": {
node.events.forEach((event) => {
const listenerFunction = (data) => {
listener(event.tagger(data));
};
root.addEventListener(event.name, listenerFunction, {
once: true,
});
node._eventListeners.push({
event: event,
listener: listenerFunction,
});
});
}
}
if (node.kind === "regular") {
let i = 0;
for (const child of node.children) {
if (child.kind === "text")
continue;
const newRoot = root.children[i];
hydrateNode(child, listener, newRoot);
i++;
}
}
}
/**
* Builds a HTMLElement tree from a HtmlNode tree, with event triggers being sent to the runner via the listener
* This function should not be needed by most usage.
*/
function buildTree(listener, node) {
switch (node.kind) {
case "text":
return document.createTextNode(node.text);
case "void":
case "regular":
case "ns-void":
case "ns-regular": {
let element;
if (node.kind === "ns-regular" || node.kind === "ns-void") {
element = document.createElementNS(node.namespace, node.tag);
}
else {
element = document.createElement(node.tag);
}
node.attributes.forEach((attribute) => {
setAttributeOnElement(element, attribute);
});
node.events.forEach((event) => {
const listenerFunction = (data) => {
listener(event.tagger(data));
};
element.addEventListener(event.name, listenerFunction, {
once: true,
});
node._eventListeners.push({
event: event,
listener: listenerFunction,
});
});
if (node.kind === "regular" || node.kind === "ns-regular") {
const children = node.children.map((child) => buildTree(listener, child));
children.forEach((child) => {
element.appendChild(child);
});
}
return element;
}
case "html-string": {
const parser = new DOMParser();
const parsed = parser.parseFromString(node.content, "text/html");
if (!parsed.body.firstElementChild)
return document.createTextNode("Failed to parse");
return parsed.body.firstElementChild;
}
}
}
/**
* Triggers the event by name, passing it the payload provided.
* This function is useful for testing but not much else
*/
function triggerEvent(eventName, payload, node) {
payload = Object.assign({ stopPropagation: () => undefined, preventDefault: () => undefined }, payload);
switch (node.kind) {
case "text": {
return ts_core_1.Maybe.Nothing();
}
case "void":
case "regular":
case "ns-void":
case "ns-regular": {
const events = node.events.filter((event) => event.name === eventName);
if (events.length > 0) {
return ts_core_1.Maybe.Just(events[0].tagger(payload));
}
else {
return ts_core_1.Maybe.Nothing();
}
}
case "html-string": {
return ts_core_1.Maybe.Nothing();
}
}
}
/**
Converts a `HtmlNode` of type `A` to a `HtmlNode` of type `B`, including children.
*/
function map(tagger, tree) {
switch (tree.kind) {
case "text": {
return tree;
}
case "void":
case "ns-void": {
return voidNode(tree.tag, tree.events.map((event) => {
return on(event.name, (data) => tagger(event.tagger(data)));
}), tree.attributes);
}
case "regular":
case "ns-regular": {
return node(tree.tag, tree.events.map((event) => {
return on(event.name, (data) => tagger(event.tagger(data)));
}), tree.attributes, tree.children.map((child) => {
return map(tagger, child);
}));
}
case "html-string": {
return tree;
}
}
}
function isProperty(tag, key) {
switch (tag) {
case "INPUT":
return (key === "checked" ||
key === "indeterminate" ||
key === "value" ||
key === "readonly" ||
key === "disabled");
case "OPTION":
return key === "selected" || key === "disabled";
case "TEXTAREA":
return key === "value" || key === "readonly" || key === "disabled";
case "SELECT":
return key === "value" || key === "disabled";
case "BUTTON":
case "OPTGROUP":
return key === "disabled";
}
return false;
}
function setAttributeOnElement(element, attribute) {
switch (attribute.kind) {
case "string":
case "number": {
if (isProperty(element.tagName, attribute.key)) {
element[attribute.key] = attribute.value;
return true;
}
else {
element.setAttribute(attribute.key, attribute.value);
return true;
}
}
case "style": {
element.removeAttribute("style");
const styles = attribute.value.split(";");
for (var i = 0; i < styles.length; i++) {
const styleName = styles[i].split(":")[0];
const styleValue = styles[i].split(":")[1];
element.style[styleName] = styleValue;
}
return true;
}
case "boolean": {
if (attribute.value) {
if (isProperty(element.tagName, attribute.key)) {
element[attribute.key] = attribute.value;
return true;
}
element.setAttribute(attribute.key, attribute.key);
}
else {
if (element.getAttribute(attribute.key) === attribute.key) {
element.removeAttribute(attribute.key);
}
}
return true;
}
case "none":
return true;
}
}
function patchFacts(previousTree, nextTree, elements) {
switch (nextTree.kind) {
case "void":
case "regular":
case "ns-void":
case "ns-regular": {
// remove previous attributes that no longer exist on the next dom version
if (previousTree.kind === nextTree.kind) {
const nextAttributes = [];
for (const attr of nextTree.attributes) {
if (attr.kind != "none") {
nextAttributes.push(attr.key);
}
}
for (const attribute of previousTree.attributes) {
if (attribute.kind !== "none" &&
nextAttributes.indexOf(attribute.key) === -1) {
elements.removeAttribute(attribute.key);
}
}
}
nextTree.attributes.forEach((attribute) => {
setAttributeOnElement(elements, attribute);
});
return true;
}
case "text": {
return true;
}
case "html-string": {
return true;
}
}
}
function patchEvents(listener, previousTree, nextTree, elements) {
switch (nextTree.kind) {
case "void":
case "regular":
case "ns-void":
case "ns-regular":
previousTree._eventListeners.forEach((eventListeners) => {
elements.removeEventListener(eventListeners.event.name, eventListeners.listener);
});
nextTree.events.forEach((event) => {
const listenerFunction = (data) => {
listener(event.tagger(data));
};
elements.addEventListener(event.name, listenerFunction, {
once: true,
});
nextTree._eventListeners.push({
event: event,
listener: listenerFunction,
});
});
return true;
case "text":
case "html-string":
return true;
}
}
function patch(listener, currentTree, nextTree, elements) {
var _a, _b;
if (currentTree.kind != nextTree.kind) {
elements.replaceWith(buildTree(listener, nextTree));
return nextTree;
}
switch (currentTree.kind) {
case "text": {
nextTree = nextTree;
elements = elements;
if (currentTree.text == nextTree.text) {
return currentTree;
}
else {
elements.replaceWith(document.createTextNode(nextTree.text));
return nextTree;
}
}
case "void":
case "ns-void": {
currentTree = currentTree;
nextTree = nextTree;
if (currentTree.tag != nextTree.tag) {
elements.replaceWith(buildTree(listener, nextTree));
return nextTree;
}
else {
patchFacts(currentTree, nextTree, elements);
patchEvents(listener, currentTree, nextTree, elements);
}
return nextTree;
}
case "regular":
case "ns-regular": {
currentTree = currentTree;
nextTree = nextTree;
const currentTreeId = (_a = currentTree.attributes.filter((x) => x.kind === "string" && x.key === "id")[0]) === null || _a === void 0 ? void 0 : _a.value;
const nextTreeId = (_b = nextTree.attributes.filter((x) => x.kind === "string" && x.key === "id")[0]) === null || _b === void 0 ? void 0 : _b.value;
if (currentTree.tag !== nextTree.tag ||
currentTreeId !== nextTreeId) {
elements.replaceWith(buildTree(listener, nextTree));
return nextTree;
}
else {
patchFacts(currentTree, nextTree, elements);
patchEvents(listener, currentTree, nextTree, elements);
const htmlElements = elements;
for (var i = 0; i < nextTree.children.length; i++) {
const currentChild = currentTree.children[i];
const nextChild = nextTree.children[i];
const node = htmlElements.childNodes[i];
if (typeof node === "undefined") {
htmlElements.appendChild(buildTree(listener, nextChild));
continue;
}
switch (node.nodeType) {
case Node.ELEMENT_NODE:
const element = node;
patch(listener, currentChild, nextChild, element);
break;
case Node.TEXT_NODE:
const text = node;
patch(listener, currentChild, nextChild, text);
break;
}
}
for (var i = htmlElements.childNodes.length - 1; i > nextTree.children.length - 1; i--) {
const node = htmlElements.childNodes[i];
htmlElements.removeChild(node);
}
}
return nextTree;
}
case "html-string": {
currentTree = currentTree;
nextTree = nextTree;
if (currentTree.content === nextTree.content) {
return currentTree;
}
elements.replaceWith(buildTree(listener, nextTree));
return nextTree;
}
}
}
/**
* Takes in a program, sets it up and runs it as a main loop
*/
function program(program) {
let model = program.initialModel;
let previousView = program.view(program.initialModel);
let currentTree = null;
const listener = async (msg) => {
if (currentTree === null) {
currentTree = buildTree(listener, previousView);
if (program.root !== "hydration") {
while (program.root.firstChild) {
program.root.removeChild(program.root.firstChild);
}
program.root.appendChild(currentTree);
}
}
model = await program.update(msg, model, listener);
const nextView = program.view(model);
patch(listener, previousView, nextView, currentTree);
previousView = nextView;
if (program.postRender) {
program.postRender(model);
}
};
if (program.root !== "hydration") {
currentTree = buildTree(listener, previousView);
program.root.appendChild(currentTree);
}
return {
program: program,
send: listener,
};
}
// tags
function a(events, attributes, children) {
return node("a", events, attributes, children);
}
function abbr(events, attributes, children) {
return node("abbr", events, attributes, children);
}
function address(events, attributes, children) {
return node("address", events, attributes, children);
}
function area(events, attributes) {
return voidNode("area", events, attributes);
}
function article(events, attributes, children) {
return node("article", events, attributes, children);
}
function aside(events, attributes, children) {
return node("aside", events, attributes, children);
}
function audio(events, attributes, children) {
return node("audio", events, attributes, children);
}
function b(events, attributes, children) {
return node("b", events, attributes, children);
}
function base(events, attributes) {
return voidNode("base", events, attributes);
}
function bdi(events, attributes, children) {
return node("bdi", events, attributes, children);
}
function bdo(events, attributes, children) {
return node("bdo", events, attributes, children);
}
function blockquote(events, attributes, children) {
return node("blockquote", events, attributes, children);
}
function body(events, attributes, children) {
return node("body", events, attributes, children);
}
function br(events, attributes) {
return voidNode("br", events, attributes);
}
function button(events, attributes, children) {
return node("button", events, attributes, children);
}
function canvas(events, attributes, children) {
return node("canvas", events, attributes, children);
}
function caption(events, attributes, children) {
return node("caption", events, attributes, children);
}
function cite(events, attributes, children) {
return node("cite", events, attributes, children);
}
function code(events, attributes, children) {
return node("code", events, attributes, children);
}
function col(events, attributes) {
return voidNode("col", events, attributes);
}
function colgroup(events, attributes, children) {
return node("colgroup", events, attributes, children);
}
function data(events, attributes, children) {
return node("data", events, attributes, children);
}
function datalist(events, attributes, children) {
return node("datalist", events, attributes, children);
}
function dd(events, attributes, children) {
return node("dd", events, attributes, children);
}
function del(events, attributes, children) {
return node("del", events, attributes, children);
}
function details(events, attributes, children) {
return node("details", events, attributes, children);
}
function dfn(events, attributes, children) {
return node("dfn", events, attributes, children);
}
function dialog(events, attributes, children) {
return node("dialog", events, attributes, children);
}
function div(events, attributes, children) {
return node("div", events, attributes, children);
}
function dl(events, attributes, children) {
return node("dl", events, attributes, children);
}
function dt(events, attributes, children) {
return node("dt", events, attributes, children);
}
function em(events, attributes, children) {
return node("em", events, attributes, children);
}
function embed(events, attributes) {
return voidNode("embed", events, attributes);
}
function fieldset(events, attributes, children) {
return node("fieldset", events, attributes, children);
}
function figure(events, attributes, children) {
return node("figure", events, attributes, children);
}
function footer(events, attributes, children) {
return node("footer", events, attributes, children);
}
function form(events, attributes, children) {
return node("form", events, attributes, children);
}
function h1(events, attributes, children) {
return node("h1", events, attributes, children);
}
function h2(events, attributes, children) {
return node("h2", events, attributes, children);
}
function h3(events, attributes, children) {
return node("h3", events, attributes, children);
}
function h4(events, attributes, children) {
return node("h4", events, attributes, children);
}
function h5(events, attributes, children) {
return node("h5", events, attributes, children);
}
function h6(events, attributes, children) {
return node("h6", events, attributes, children);
}
function head(events, attributes, children) {
return node("head", events, attributes, children);
}
function header(events, attributes, children) {
return node("header", events, attributes, children);
}
function hgroup(events, attributes, children) {
return node("hgroup", events, attributes, children);
}
function hr(events, attributes) {
return voidNode("hr", events, attributes);
}
function html(events, attributes, children) {
return node("html", events, attributes, children);
}
function i(events, attributes, children) {
return node("i", events, attributes, children);
}
function iframe(events, attributes, children) {
return node("iframe", events, attributes, children);
}
function img(events, attributes) {
return voidNode("img", events, attributes);
}
function input(events, attributes) {
return voidNode("input", events, attributes);
}
function ins(events, attributes, children) {
return node("ins", events, attributes, children);
}
function kbd(events, attributes, children) {
return node("kbd", events, attributes, children);
}
function keygen(events, attributes, children) {
return node("keygen", events, attributes, children);
}
function label(events, attributes, children) {
return node("label", events, attributes, children);
}
function legend(events, attributes, children) {
return node("legend", events, attributes, children);
}
function li(events, attributes, children) {
return node("li", events, attributes, children);
}
function link(events, attributes) {
return voidNode("link", events, attributes);
}
function main(events, attributes, children) {
return node("main", events, attributes, children);
}
function map_(events, attributes, children) {
return node("map", events, attributes, children);
}
function mark(events, attributes, children) {
return node("mark", events, attributes, children);
}
function menu(events, attributes, children) {
return node("menu", events, attributes, children);
}
function menuitem(events, attributes, children) {
return node("menuitem", events, attributes, children);
}
function meta(events, attributes) {
return voidNode("meta", events, attributes);
}
function meter(events, attributes, children) {
return node("meter", events, attributes, children);
}
function nav(events, attributes, children) {
return node("nav", events, attributes, children);
}
function noscript(events, attributes, children) {
return node("noscript", events, attributes, children);
}
function object(events, attributes, children) {
return node("object", events, attributes, children);
}
function ol(events, attributes, children) {
return node("ol", events, attributes, children);
}
function optgroup(events, attributes, children) {
return node("optgroup", events, attributes, children);
}
function option(events, attributes, children) {
return node("option", events, attributes, children);
}
function output(events, attributes, children) {
return node("output", events, attributes, children);
}
function p(events, attributes, children) {
return node("p", events, attributes, children);
}
function param(events, attributes) {
return voidNode("param", events, attributes);
}
function pre(events, attributes, children) {
return node("pre", events, attributes, children);
}
function progress(events, attributes, children) {
return node("progress", events, attributes, children);
}
function q(events, attributes, children) {
return node("q", events, attributes, children);
}
function rb(events, attributes, children) {
return node("rb", events, attributes, children);
}
function rp(events, attributes, children) {
return node("rp", events, attributes, children);
}
function rt(events, attributes, children) {
return node("rt", events, attributes, children);
}
function rtc(events, attributes, children) {
return node("rtc", events, attributes, children);
}
function ruby(events, attributes, children) {
return node("ruby", events, attributes, children);
}
function s(events, attributes, children) {
return node("s", events, attributes, children);
}
function samp(events, attributes, children) {
return node("samp", events, attributes, children);
}
function script(events, attributes, children) {
return node("script", events, attributes, children);
}
function section(events, attributes, children) {
return node("section", events, attributes, children);
}
function select(events, attributes, children) {
return node("select", events, attributes, children);
}
function small(events, attributes, children) {
return node("small", events, attributes, children);
}
function source(events, attributes) {
return voidNode("source", events, attributes);
}
function span(events, attributes, children) {
return node("span", events, attributes, children);
}
function strong(events, attributes, children) {
return node("strong", events, attributes, children);
}
function style(events, attributes, children) {
return node("style", events, attributes, children);
}
function sub(events, attributes, children) {
return node("sub", events, attributes, children);
}
function summary(events, attributes, children) {
return node("summary", events, attributes, children);
}
function sup(events, attributes, children) {
return node("sup", events, attributes, children);
}
function table(events, attributes, children) {
return node("table", events, attributes, children);
}
function tbody(events, attributes, children) {
return node("tbody", events, attributes, children);
}
function td(events, attributes, children) {
return node("td", events, attributes, children);
}
function template(events, attributes, children) {
return node("template", events, attributes, children);
}
function textarea(events, attributes, children) {
return node("textarea", events, attributes, children);
}
function tfoot(events, attributes, children) {
return node("tfoot", events, attributes, children);
}
function th(events, attributes, children) {
return node("th", events, attributes, children);
}
function thead(events, attributes, children) {
return node("thead", events, attributes, children);
}
function time(events, attributes, children) {
return node("time", events, attributes, children);
}
function title(events, attributes, children) {
return node("title", events, attributes, children);
}
function tr(events, attributes, children) {
return node("tr", events, attributes, children);
}
function track(events, attributes) {
return voidNode("track", events, attributes);
}
function u(events, attributes, children) {
return node("u", events, attributes, children);
}
function ul(events, attributes, children) {
return node("ul", events, attributes, children);
}
function var_(events, attributes, children) {
return node("var", events, attributes, children);
}
function video(events, attributes, children) {
return node("video", events, attributes, children);
}
function wbr(events, attributes) {
return voidNode("wbr", events, attributes);
}