html-to-ivi
Advanced tools
Comparing version 0.0.1 to 0.0.2
@@ -5,43 +5,126 @@ "use strict"; | ||
const prettier = require("prettier"); | ||
function extractElementAttributes(attrs) { | ||
const result = {}; | ||
let items = 0; | ||
for (const key of Object.keys(attrs)) { | ||
if (key.startsWith("on")) { | ||
continue; | ||
const escape_1 = require("./escape"); | ||
const ElementFlags = { | ||
input: 1 /* Input */, | ||
textarea: 2 /* TextArea */, | ||
}; | ||
const AttributesToProps = { | ||
class: null, | ||
style: null, | ||
autofocus: null, | ||
"accept-charset": "acceptCharset", | ||
"for": "htmlFor", | ||
}; | ||
const InputAttributesToProps = Object.assign({}, AttributesToProps, { type: null, checked: null, value: null }); | ||
const InputTypes = { | ||
button: "Button", | ||
checkbox: "Checkbox", | ||
color: "Color", | ||
date: "Date", | ||
datetime: "Datetime", | ||
"datetime-local": "DatetimeLocal", | ||
email: "Email", | ||
file: "File", | ||
hidden: "Hidden", | ||
image: "Image", | ||
month: "Month", | ||
number: "Number", | ||
password: "Password", | ||
radio: "Radio", | ||
range: "Range", | ||
reset: "Reset", | ||
search: "Search", | ||
submit: "Submit", | ||
tel: "Tel", | ||
text: "Text", | ||
time: "Time", | ||
url: "Url", | ||
week: "Week", | ||
}; | ||
function extractFlags(node) { | ||
const flags = ElementFlags[node.tag]; | ||
if (flags === undefined) { | ||
return 0; | ||
} | ||
return flags; | ||
} | ||
function extractAttributes(flags, node) { | ||
const attrs = node.attrs; | ||
if (attrs) { | ||
let attrsToProps = AttributesToProps; | ||
if ((flags & 1 /* Input */) !== 0) { | ||
attrsToProps = InputAttributesToProps; | ||
} | ||
switch (key) { | ||
case "class": | ||
case "style": | ||
break; | ||
case "accept-charset": | ||
result["acceptCharset"] = attrs[key]; | ||
break; | ||
case "for": | ||
result["htmlFor"] = attrs[key]; | ||
break; | ||
default: | ||
result[key] = attrs[key]; | ||
const result = {}; | ||
let items = 0; | ||
for (const key of Object.keys(attrs)) { | ||
// Ignore events. | ||
if (key.startsWith("on")) { | ||
continue; | ||
} | ||
let v = attrsToProps[key]; | ||
if (v !== null) { | ||
if (v === undefined) { | ||
v = attrs[key]; | ||
} | ||
result[key] = v === "" ? true : v; | ||
items++; | ||
} | ||
} | ||
if (items > 0) { | ||
return result; | ||
} | ||
} | ||
if (items > 0) { | ||
return result; | ||
return null; | ||
} | ||
function extractStyle(node) { | ||
if (node.attrs && node.attrs.style) { | ||
const style = node.attrs.style; | ||
const result = {}; | ||
let items = 0; | ||
for (const kv of style.split(";")) { | ||
const [key, value] = kv.split(":"); | ||
if (value !== undefined) { | ||
result[key.trim()] = value.trim(); | ||
items++; | ||
} | ||
} | ||
if (items > 0) { | ||
return result; | ||
} | ||
} | ||
return null; | ||
} | ||
function extractElementStyles(styles) { | ||
const result = {}; | ||
let items = 0; | ||
for (const kv of styles.split(";")) { | ||
const [key, value] = kv.split(":"); | ||
if (value !== undefined) { | ||
result[key.trim()] = value.trim(); | ||
items++; | ||
function extractClassName(node) { | ||
const attrs = node.attrs; | ||
if (attrs && attrs.class) { | ||
return attrs.class; | ||
} | ||
return ""; | ||
} | ||
function extractInputType(node) { | ||
const attrs = node.attrs; | ||
if (attrs && attrs.type) { | ||
const t = InputTypes[attrs.type]; | ||
if (t !== undefined) { | ||
return t; | ||
} | ||
} | ||
if (items > 0) { | ||
return result; | ||
return "Text"; | ||
} | ||
const DefaultInputValues = { value: "", checked: false }; | ||
function extractInputValues(node) { | ||
const attrs = node.attrs; | ||
if (attrs) { | ||
let value = ""; | ||
let checked = false; | ||
if (attrs.value) { | ||
value = attrs.value; | ||
} | ||
if (attrs.checked) { | ||
checked = true; | ||
} | ||
return { value, checked }; | ||
} | ||
return null; | ||
return DefaultInputValues; | ||
} | ||
@@ -51,3 +134,9 @@ function attrsToString(attrs) { | ||
for (const key of Object.keys(attrs)) { | ||
result += `"${key}":"${attrs[key]}",`; | ||
const v = attrs[key]; | ||
if (v === true) { | ||
result += `"${key}":true,`; | ||
} | ||
else { | ||
result += `"${key}":"${v}",`; | ||
} | ||
} | ||
@@ -67,9 +156,9 @@ return result; | ||
} | ||
function extractChildren(nodes, options) { | ||
function extractChildren(content, options) { | ||
let result = ""; | ||
for (const n of nodes) { | ||
for (const n of content) { | ||
if (typeof n === "string") { | ||
if (n) { | ||
if (!options.trim || !isWhitespace(n)) { | ||
result += `"${n.replace(/\n/g, "\\n")}",`; | ||
result += `"${escape_1.escapeText(n)}",`; | ||
} | ||
@@ -85,33 +174,50 @@ } | ||
function printNode(node, options) { | ||
let result = `h.${node.tag}`; | ||
if (node.attrs) { | ||
if (node.attrs.class) { | ||
result += `("${node.attrs.class}")`; | ||
let result = ""; | ||
const tag = node.tag; | ||
const flags = extractFlags(node); | ||
const className = extractClassName(node); | ||
const attrs = extractAttributes(flags, node); | ||
const style = extractStyle(node); | ||
const content = node.content; | ||
if ((flags & 1 /* Input */) === 0) { | ||
result += `h.${tag}`; | ||
} | ||
else { | ||
result += `h.input${extractInputType(node)}`; | ||
} | ||
result += className ? `("${className}")` : `()`; | ||
if (style) { | ||
result += `.style({${stylesToString(style)}})`; | ||
} | ||
if ((flags & 1 /* Input */) !== 0) { | ||
const inputValues = extractInputValues(node); | ||
if (inputValues.value) { | ||
result += `.value("${escape_1.escapeText(inputValues.value)}")`; | ||
} | ||
else { | ||
result += `()`; | ||
if (inputValues.checked) { | ||
result += `.checked(true)`; | ||
} | ||
if (node.attrs.style) { | ||
const styles = extractElementStyles(node.attrs.style); | ||
if (styles !== null) { | ||
result += `.style({${stylesToString(styles)}})`; | ||
} | ||
} | ||
const attrs = extractElementAttributes(node.attrs); | ||
if (attrs !== null) { | ||
if (attrs) { | ||
result += `.props({${attrsToString(attrs)}})`; | ||
} | ||
} | ||
else { | ||
result += `()`; | ||
} | ||
if (node.content) { | ||
const children = extractChildren(node.content, options); | ||
if (children) { | ||
result += `.children(${children})`; | ||
if (content) { | ||
if ((flags & 2 /* TextArea */) !== 0) { | ||
if (content.length > 0) { | ||
const value = content[0]; | ||
if (typeof value === "string" && value) { | ||
result += `.value("${escape_1.escapeText(value.trim())}")`; | ||
} | ||
} | ||
} | ||
else { | ||
const children = extractChildren(content, options); | ||
if (children) { | ||
result += `.children(${children})`; | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
function htmlToIvi(html, options) { | ||
function htmlToIvi(html, options = { componentName: "Component", trim: true }) { | ||
const nodes = parser(html); | ||
@@ -118,0 +224,0 @@ if (nodes.length > 0) { |
{ | ||
"name": "html-to-ivi", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Converts HTML to ivi Virtual DOM.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
12125
7
345