From adf0adde987a368298e135c23ce307efbc38d888 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Wed, 16 Aug 2023 15:18:47 -0300 Subject: html: move parseAttributes from replacer into html lib It also always returns an html.Attributes object, instead of a key/value mapping (which would be provided to html.attributes). --- src/util/html.js | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ src/util/replacer.js | 68 ++++------------------------------------------------ 2 files changed, 69 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/util/html.js b/src/util/html.js index 19a7d126..712a0a68 100644 --- a/src/util/html.js +++ b/src/util/html.js @@ -424,6 +424,10 @@ export function attributes(attributes) { return new Attributes(attributes); } +export function parseAttributes(string) { + return Attributes.parse(string); +} + export class Attributes { #attributes = Object.create(null); @@ -496,6 +500,66 @@ export class Attributes { .replaceAll('"', '"') .replaceAll("'", '''); } + + static parse(string) { + const attributes = Object.create(null); + + const skipWhitespace = i => { + if (!/\s/.test(string[i])) { + return i; + } + + const match = string.slice(i).match(/[^\s]/); + if (match) { + return i + match.index; + } + + return string.length; + }; + + for (let i = 0; i < string.length; ) { + i = skipWhitespace(i); + const aStart = i; + const aEnd = i + string.slice(i).match(/[\s=]|$/).index; + const attribute = string.slice(aStart, aEnd); + i = skipWhitespace(aEnd); + if (string[i] === '=') { + i = skipWhitespace(i + 1); + let end, endOffset; + if (string[i] === '"' || string[i] === "'") { + end = string[i]; + endOffset = 1; + i++; + } else { + end = '\\s'; + endOffset = 0; + } + const vStart = i; + const vEnd = i + string.slice(i).match(new RegExp(`${end}|$`)).index; + const value = string.slice(vStart, vEnd); + i = vEnd + endOffset; + attributes[attribute] = value; + } else { + attributes[attribute] = attribute; + } + } + + return ( + Reflect.construct(this, [ + Object.fromEntries( + Object.entries(attributes) + .map(([key, val]) => [ + key, + (val === 'true' + ? true + : val === 'false' + ? false + : val === key + ? true + : val), + ])), + ])); + } } export function resolve(tagOrTemplate) { diff --git a/src/util/replacer.js b/src/util/replacer.js index e1d81319..ac23bf46 100644 --- a/src/util/replacer.js +++ b/src/util/replacer.js @@ -276,64 +276,6 @@ function parseNodes(input, i, stopAt, textOnly) { return nodes; } -function parseAttributes(string) { - const attributes = Object.create(null); - - const skipWhitespace = i => { - if (!/\s/.test(string[i])) { - return i; - } - - const match = string.slice(i).match(/[^\s]/); - if (match) { - return i + match.index; - } - - return string.length; - }; - - for (let i = 0; i < string.length; ) { - i = skipWhitespace(i); - const aStart = i; - const aEnd = i + string.slice(i).match(/[\s=]|$/).index; - const attribute = string.slice(aStart, aEnd); - i = skipWhitespace(aEnd); - if (string[i] === '=') { - i = skipWhitespace(i + 1); - let end, endOffset; - if (string[i] === '"' || string[i] === "'") { - end = string[i]; - endOffset = 1; - i++; - } else { - end = '\\s'; - endOffset = 0; - } - const vStart = i; - const vEnd = i + string.slice(i).match(new RegExp(`${end}|$`)).index; - const value = string.slice(vStart, vEnd); - i = vEnd + endOffset; - attributes[attribute] = value; - } else { - attributes[attribute] = attribute; - } - } - - return ( - Object.fromEntries( - Object.entries(attributes) - .map(([key, val]) => [ - key, - val === 'true' - ? true - : val === 'false' - ? false - : val === key - ? true - : val, - ]))); -} - export function postprocessImages(inputNodes) { const outputNodes = []; @@ -356,9 +298,9 @@ export function postprocessImages(inputNodes) { parseFrom = match.index + match[0].length; const imageNode = {type: 'image'}; - const attributes = parseAttributes(match[1]); + const attributes = html.parseAttributes(match[1]); - imageNode.src = attributes.src; + imageNode.src = attributes.get('src'); if (previousText.endsWith('\n')) { atStartOfLine = true; @@ -393,9 +335,9 @@ export function postprocessImages(inputNodes) { return false; })(); - if (attributes.link) imageNode.link = attributes.link; - if (attributes.width) imageNode.width = parseInt(attributes.width); - if (attributes.height) imageNode.height = parseInt(attributes.height); + if (attributes.get('link')) imageNode.link = attributes.get('link'); + if (attributes.get('width')) imageNode.width = parseInt(attributes.get('width')); + if (attributes.get('height')) imageNode.height = parseInt(attributes.get('height')); outputNodes.push(imageNode); -- cgit 1.3.0-6-gf8a5