UNPKG

@eeue56/coed

Version:
1,054 lines (1,053 loc) 36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.em = exports.dt = exports.dl = exports.div = exports.dialog = exports.dfn = exports.details = exports.del = exports.dd = exports.datalist = exports.data = exports.colgroup = exports.col = exports.code = exports.cite = exports.caption = exports.canvas = exports.button = exports.br = exports.body = exports.blockquote = exports.bdo = exports.bdi = exports.base = exports.b = exports.audio = exports.aside = exports.article = exports.area = exports.address = exports.abbr = exports.a = exports.program = exports.map = exports.triggerEvent = exports.buildTree = exports.hydrateNode = exports.hydrate = exports.flatRender = exports.render = exports.voidNode = exports.node = exports.text = exports.onInput = exports.on = exports.booleanAttribute = exports.attribute = exports.none = exports.style_ = exports.class_ = void 0; exports.rtc = exports.rt = exports.rp = exports.rb = exports.q = exports.progress = exports.pre = exports.param = exports.p = exports.output = exports.option = exports.optgroup = exports.ol = exports.object = exports.noscript = exports.nav = exports.meter = exports.meta = exports.menuitem = exports.menu = exports.mark = exports.map_ = exports.main = exports.link = exports.li = exports.legend = exports.label = exports.keygen = exports.kbd = exports.ins = exports.input = exports.img = exports.iframe = exports.i = exports.html = exports.hr = exports.hgroup = exports.header = exports.head = exports.h6 = exports.h5 = exports.h4 = exports.h3 = exports.h2 = exports.h1 = exports.form = exports.footer = exports.figure = exports.fieldset = exports.embed = void 0; exports.wbr = exports.video = exports.var_ = exports.ul = exports.u = exports.track = exports.tr = exports.title = exports.time = exports.thead = exports.th = exports.tfoot = exports.textarea = exports.template = exports.td = exports.tbody = exports.table = exports.sup = exports.summary = exports.sub = exports.style = exports.strong = exports.span = exports.source = exports.small = exports.select = exports.section = exports.script = exports.samp = exports.s = exports.ruby = void 0; 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, }; } exports.class_ = class_; /** 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, }; } exports.style_ = style_; /** 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", }; } exports.none = 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, }; } exports.attribute = attribute; /** 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, }; } exports.booleanAttribute = booleanAttribute; /** 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); }, }; } exports.on = on; /** Special-cased input handler */ function onInput(tagger) { return { name: "input", tagger: (event) => { event.stopPropagation(); event.preventDefault(); return tagger(event.target.value); }, }; } exports.onInput = onInput; /** Creates a text node */ function text(str) { return { kind: "text", text: str, }; } exports.text = text; /** 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: [], }; } exports.node = node; /** 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: [], }; } exports.voidNode = voidNode; 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": const renderedAttributes = node.attributes .map(renderAttribute) .join(" "); const attributes = (renderedAttributes.length > 0 ? " " : "") + renderedAttributes; switch (node.kind) { case "void": return whitespace + `<${node.tag}${attributes}>`; case "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}>`); } } } } exports.render = render; /** Render a node without whitespace */ function flatRender(node) { switch (node.kind) { case "text": return node.text; case "void": case "regular": const attributes = (node.attributes.length > 0 ? " " : "") + node.attributes.map(renderAttribute).join(" "); switch (node.kind) { case "void": return `<${node.tag}${attributes}>`; case "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}>`; } } } } exports.flatRender = flatRender; /** 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]); } exports.hydrate = hydrate; /** 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++; } } } exports.hydrateNode = hydrateNode; /** 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": { const 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") { const children = node.children.map((child) => buildTree(listener, child)); children.forEach((child) => { element.appendChild(child); }); } return element; } } } exports.buildTree = buildTree; /** 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": 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(); } } } exports.triggerEvent = triggerEvent; /** 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": return voidNode(tree.tag, tree.events.map((event) => { return on(event.name, (data) => tagger(event.tagger(data))); }), tree.attributes); case "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); })); } } exports.map = map; 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": { // 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; } case "text": return; } } function patchEvents(listener, previousTree, nextTree, elements) { switch (nextTree.kind) { case "void": case "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; case "text": return; } } 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": { 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": 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; } } /** 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 = (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 = program.update(msg, model, listener); const nextView = program.view(model); patch(listener, previousView, nextView, currentTree); previousView = nextView; }; if (program.root !== "hydration") { currentTree = buildTree(listener, previousView); program.root.appendChild(currentTree); } return { program: program, send: listener, }; } exports.program = program; // tags function a(events, attributes, children) { return node("a", events, attributes, children); } exports.a = a; function abbr(events, attributes, children) { return node("abbr", events, attributes, children); } exports.abbr = abbr; function address(events, attributes, children) { return node("address", events, attributes, children); } exports.address = address; function area(events, attributes) { return voidNode("area", events, attributes); } exports.area = area; function article(events, attributes, children) { return node("article", events, attributes, children); } exports.article = article; function aside(events, attributes, children) { return node("aside", events, attributes, children); } exports.aside = aside; function audio(events, attributes, children) { return node("audio", events, attributes, children); } exports.audio = audio; function b(events, attributes, children) { return node("b", events, attributes, children); } exports.b = b; function base(events, attributes) { return voidNode("base", events, attributes); } exports.base = base; function bdi(events, attributes, children) { return node("bdi", events, attributes, children); } exports.bdi = bdi; function bdo(events, attributes, children) { return node("bdo", events, attributes, children); } exports.bdo = bdo; function blockquote(events, attributes, children) { return node("blockquote", events, attributes, children); } exports.blockquote = blockquote; function body(events, attributes, children) { return node("body", events, attributes, children); } exports.body = body; function br(events, attributes) { return voidNode("br", events, attributes); } exports.br = br; function button(events, attributes, children) { return node("button", events, attributes, children); } exports.button = button; function canvas(events, attributes, children) { return node("canvas", events, attributes, children); } exports.canvas = canvas; function caption(events, attributes, children) { return node("caption", events, attributes, children); } exports.caption = caption; function cite(events, attributes, children) { return node("cite", events, attributes, children); } exports.cite = cite; function code(events, attributes, children) { return node("code", events, attributes, children); } exports.code = code; function col(events, attributes) { return voidNode("col", events, attributes); } exports.col = col; function colgroup(events, attributes, children) { return node("colgroup", events, attributes, children); } exports.colgroup = colgroup; function data(events, attributes, children) { return node("data", events, attributes, children); } exports.data = data; function datalist(events, attributes, children) { return node("datalist", events, attributes, children); } exports.datalist = datalist; function dd(events, attributes, children) { return node("dd", events, attributes, children); } exports.dd = dd; function del(events, attributes, children) { return node("del", events, attributes, children); } exports.del = del; function details(events, attributes, children) { return node("details", events, attributes, children); } exports.details = details; function dfn(events, attributes, children) { return node("dfn", events, attributes, children); } exports.dfn = dfn; function dialog(events, attributes, children) { return node("dialog", events, attributes, children); } exports.dialog = dialog; function div(events, attributes, children) { return node("div", events, attributes, children); } exports.div = div; function dl(events, attributes, children) { return node("dl", events, attributes, children); } exports.dl = dl; function dt(events, attributes, children) { return node("dt", events, attributes, children); } exports.dt = dt; function em(events, attributes, children) { return node("em", events, attributes, children); } exports.em = em; function embed(events, attributes) { return voidNode("embed", events, attributes); } exports.embed = embed; function fieldset(events, attributes, children) { return node("fieldset", events, attributes, children); } exports.fieldset = fieldset; function figure(events, attributes, children) { return node("figure", events, attributes, children); } exports.figure = figure; function footer(events, attributes, children) { return node("footer", events, attributes, children); } exports.footer = footer; function form(events, attributes, children) { return node("form", events, attributes, children); } exports.form = form; function h1(events, attributes, children) { return node("h1", events, attributes, children); } exports.h1 = h1; function h2(events, attributes, children) { return node("h2", events, attributes, children); } exports.h2 = h2; function h3(events, attributes, children) { return node("h3", events, attributes, children); } exports.h3 = h3; function h4(events, attributes, children) { return node("h4", events, attributes, children); } exports.h4 = h4; function h5(events, attributes, children) { return node("h5", events, attributes, children); } exports.h5 = h5; function h6(events, attributes, children) { return node("h6", events, attributes, children); } exports.h6 = h6; function head(events, attributes, children) { return node("head", events, attributes, children); } exports.head = head; function header(events, attributes, children) { return node("header", events, attributes, children); } exports.header = header; function hgroup(events, attributes, children) { return node("hgroup", events, attributes, children); } exports.hgroup = hgroup; function hr(events, attributes) { return voidNode("hr", events, attributes); } exports.hr = hr; function html(events, attributes, children) { return node("html", events, attributes, children); } exports.html = html; function i(events, attributes, children) { return node("i", events, attributes, children); } exports.i = i; function iframe(events, attributes, children) { return node("iframe", events, attributes, children); } exports.iframe = iframe; function img(events, attributes) { return voidNode("img", events, attributes); } exports.img = img; function input(events, attributes) { return voidNode("input", events, attributes); } exports.input = input; function ins(events, attributes, children) { return node("ins", events, attributes, children); } exports.ins = ins; function kbd(events, attributes, children) { return node("kbd", events, attributes, children); } exports.kbd = kbd; function keygen(events, attributes, children) { return node("keygen", events, attributes, children); } exports.keygen = keygen; function label(events, attributes, children) { return node("label", events, attributes, children); } exports.label = label; function legend(events, attributes, children) { return node("legend", events, attributes, children); } exports.legend = legend; function li(events, attributes, children) { return node("li", events, attributes, children); } exports.li = li; function link(events, attributes) { return voidNode("link", events, attributes); } exports.link = link; function main(events, attributes, children) { return node("main", events, attributes, children); } exports.main = main; function map_(events, attributes, children) { return node("map", events, attributes, children); } exports.map_ = map_; function mark(events, attributes, children) { return node("mark", events, attributes, children); } exports.mark = mark; function menu(events, attributes, children) { return node("menu", events, attributes, children); } exports.menu = menu; function menuitem(events, attributes, children) { return node("menuitem", events, attributes, children); } exports.menuitem = menuitem; function meta(events, attributes) { return voidNode("meta", events, attributes); } exports.meta = meta; function meter(events, attributes, children) { return node("meter", events, attributes, children); } exports.meter = meter; function nav(events, attributes, children) { return node("nav", events, attributes, children); } exports.nav = nav; function noscript(events, attributes, children) { return node("noscript", events, attributes, children); } exports.noscript = noscript; function object(events, attributes, children) { return node("object", events, attributes, children); } exports.object = object; function ol(events, attributes, children) { return node("ol", events, attributes, children); } exports.ol = ol; function optgroup(events, attributes, children) { return node("optgroup", events, attributes, children); } exports.optgroup = optgroup; function option(events, attributes, children) { return node("option", events, attributes, children); } exports.option = option; function output(events, attributes, children) { return node("output", events, attributes, children); } exports.output = output; function p(events, attributes, children) { return node("p", events, attributes, children); } exports.p = p; function param(events, attributes) { return voidNode("param", events, attributes); } exports.param = param; function pre(events, attributes, children) { return node("pre", events, attributes, children); } exports.pre = pre; function progress(events, attributes, children) { return node("progress", events, attributes, children); } exports.progress = progress; function q(events, attributes, children) { return node("q", events, attributes, children); } exports.q = q; function rb(events, attributes, children) { return node("rb", events, attributes, children); } exports.rb = rb; function rp(events, attributes, children) { return node("rp", events, attributes, children); } exports.rp = rp; function rt(events, attributes, children) { return node("rt", events, attributes, children); } exports.rt = rt; function rtc(events, attributes, children) { return node("rtc", events, attributes, children); } exports.rtc = rtc; function ruby(events, attributes, children) { return node("ruby", events, attributes, children); } exports.ruby = ruby; function s(events, attributes, children) { return node("s", events, attributes, children); } exports.s = s; function samp(events, attributes, children) { return node("samp", events, attributes, children); } exports.samp = samp; function script(events, attributes, children) { return node("script", events, attributes, children); } exports.script = script; function section(events, attributes, children) { return node("section", events, attributes, children); } exports.section = section; function select(events, attributes, children) { return node("select", events, attributes, children); } exports.select = select; function small(events, attributes, children) { return node("small", events, attributes, children); } exports.small = small; function source(events, attributes) { return voidNode("source", events, attributes); } exports.source = source; function span(events, attributes, children) { return node("span", events, attributes, children); } exports.span = span; function strong(events, attributes, children) { return node("strong", events, attributes, children); } exports.strong = strong; function style(events, attributes, children) { return node("style", events, attributes, children); } exports.style = style; function sub(events, attributes, children) { return node("sub", events, attributes, children); } exports.sub = sub; function summary(events, attributes, children) { return node("summary", events, attributes, children); } exports.summary = summary; function sup(events, attributes, children) { return node("sup", events, attributes, children); } exports.sup = sup; function table(events, attributes, children) { return node("table", events, attributes, children); } exports.table = table; function tbody(events, attributes, children) { return node("tbody", events, attributes, children); } exports.tbody = tbody; function td(events, attributes, children) { return node("td", events, attributes, children); } exports.td = td; function template(events, attributes, children) { return node("template", events, attributes, children); } exports.template = template; function textarea(events, attributes, children) { return node("textarea", events, attributes, children); } exports.textarea = textarea; function tfoot(events, attributes, children) { return node("tfoot", events, attributes, children); } exports.tfoot = tfoot; function th(events, attributes, children) { return node("th", events, attributes, children); } exports.th = th; function thead(events, attributes, children) { return node("thead", events, attributes, children); } exports.thead = thead; function time(events, attributes, children) { return node("time", events, attributes, children); } exports.time = time; function title(events, attributes, children) { return node("title", events, attributes, children); } exports.title = title; function tr(events, attributes, children) { return node("tr", events, attributes, children); } exports.tr = tr; function track(events, attributes) { return voidNode("track", events, attributes); } exports.track = track; function u(events, attributes, children) { return node("u", events, attributes, children); } exports.u = u; function ul(events, attributes, children) { return node("ul", events, attributes, children); } exports.ul = ul; function var_(events, attributes, children) { return node("var", events, attributes, children); } exports.var_ = var_; function video(events, attributes, children) { return node("video", events, attributes, children); } exports.video = video; function wbr(events, attributes) { return voidNode("wbr", events, attributes); } exports.wbr = wbr;