Skip to content

Commit

Permalink
optimise / fix types
Browse files Browse the repository at this point in the history
  • Loading branch information
dbushell committed Sep 25, 2024
1 parent 3de28f1 commit 3804620
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 25 deletions.
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dbushell/hyperless",
"version": "0.7.0",
"version": "0.8.0",
"exports": {
".": "./mod.ts"
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dbushell/hyperless",
"version": "0.7.0",
"version": "0.8.0",
"repository": {
"type": "git",
"url": "git+https://github.com/dbushell/hyperless.git"
Expand Down
42 changes: 19 additions & 23 deletions src/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,65 +22,63 @@ type STATE =
/**
* Return a map of HTML attributes
* @param attributes HTML tag to parse
* @returns {Map} Key/value attributes map
* @returns Attributes map
*/
export const parseAttributes = (attributes: string): Map<string, string> => {
export const parseAttributes = (attributes: string): AttributeMap => {
const map: AttributeMap = new AttributeMap();

let state: STATE = 'BEFORE_NAME';
let name = '';
let value = '';

parseLoop: for (let i = 0; i < attributes.length; i++) {
for (let i = 0; i < attributes.length; i++) {
const char = attributes[i];
// Handle case where closing HTML tag is included to avoid error
if (state === 'BEFORE_NAME' || state === 'NAME' || state === 'UNQUOTED') {
if (char === '/' || char === '>') {
break;
}
}
switch (state) {
case 'BEFORE_NAME':
if (char === '/' || char === '>') {
break parseLoop;
}
if (ASCII_WHITESPACE.has(char)) {
continue;
}
if (INVALID_ATTRIBUTE_NAME.has(char)) {
} else if (INVALID_ATTRIBUTE_NAME.has(char)) {
throw new Error(`Invalid attribute name at character ${i}`);
}
name = char;
value = '';
state = 'NAME';
continue;
case 'NAME':
if (char === '/' || char === '>') {
break parseLoop;
if (char === '=') {
state = 'BEFORE_VALUE';
} else if (ASCII_WHITESPACE.has(char)) {
state = 'AFTER_NAME';
} else if (char === '=') {
state = 'BEFORE_VALUE';
} else if (INVALID_ATTRIBUTE_NAME.has(char)) {
throw new Error(`invalid name at ${i}`);
} else {
name += char;
}
continue;
case 'AFTER_NAME':
if (ASCII_WHITESPACE.has(char)) {
continue;
} else if (char === '=') {
if (char === '=') {
state = 'BEFORE_VALUE';
} else {
// Found empty attribute
} else if (ASCII_WHITESPACE.has(char) === false) {
// End of empty attribute
map.set(name, '');
// Rewind state to match new name
i--;
state = 'BEFORE_NAME';
}
continue;
case 'BEFORE_VALUE':
if (ASCII_WHITESPACE.has(char)) {
continue;
} else if (char === "'") {
if (char === "'") {
state = 'SINGLE_QUOTED';
} else if (char === '"') {
state = 'DOUBLE_QUOTED';
} else if (ASCII_WHITESPACE.has(char)) {
continue;
} else if (INVALID_ATTRIBUTE_VALUE.has(char)) {
throw new Error(`Invalid unquoted attribute value at character ${i}`);
} else {
Expand All @@ -107,9 +105,7 @@ export const parseAttributes = (attributes: string): Map<string, string> => {
}
continue;
case 'UNQUOTED':
if (char === '/' || char === '>') {
break parseLoop;
} else if (ASCII_WHITESPACE.has(char)) {
if (ASCII_WHITESPACE.has(char)) {
// End of unquoted attribute
map.set(name, value);
state = 'BEFORE_NAME';
Expand Down

0 comments on commit 3804620

Please sign in to comment.