release: WRNexusJS 0.5.10
This commit is contained in:
@@ -153,18 +153,95 @@ function findOpeningTagEnd(value) {
|
||||
|
||||
function parseAttributes(value) {
|
||||
const attributes = [];
|
||||
let index = 0;
|
||||
|
||||
const pattern = /[^\s"'=<>`]+(?:\s*=\s*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^\s"'=<>`]+))?/g;
|
||||
while (index < value.length) {
|
||||
while (index < value.length && /\s/.test(value[index])) index += 1;
|
||||
if (index >= value.length) break;
|
||||
|
||||
let match;
|
||||
const start = index;
|
||||
while (index < value.length && !/[\s=]/.test(value[index])) index += 1;
|
||||
while (index < value.length && /\s/.test(value[index])) index += 1;
|
||||
|
||||
while ((match = pattern.exec(value)) !== null) {
|
||||
attributes.push(match[0].trim());
|
||||
if (value[index] === "=") {
|
||||
index += 1;
|
||||
while (index < value.length && /\s/.test(value[index])) index += 1;
|
||||
|
||||
const quote = value[index];
|
||||
if (quote === '"' || quote === "'") {
|
||||
index += 1;
|
||||
let escaped = false;
|
||||
while (index < value.length) {
|
||||
const character = value[index++];
|
||||
if (escaped) escaped = false;
|
||||
else if (character === "\\") escaped = true;
|
||||
else if (character === quote) break;
|
||||
}
|
||||
} else if (value[index] === "{") {
|
||||
let depth = 0;
|
||||
let expressionQuote = null;
|
||||
let escaped = false;
|
||||
while (index < value.length) {
|
||||
const character = value[index++];
|
||||
if (expressionQuote !== null) {
|
||||
if (escaped) escaped = false;
|
||||
else if (character === "\\") escaped = true;
|
||||
else if (character === expressionQuote) expressionQuote = null;
|
||||
continue;
|
||||
}
|
||||
if (character === '"' || character === "'" || character === "`") {
|
||||
expressionQuote = character;
|
||||
} else if (character === "{") {
|
||||
depth += 1;
|
||||
} else if (character === "}" && --depth === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (index < value.length && !/\s/.test(value[index])) index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
const attribute = value.slice(start, index).trim();
|
||||
if (attribute) attributes.push(attribute);
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
function parseStructuredAttribute(attribute) {
|
||||
const match = /^([^\s=]+)\s*=\s*\{([\s\S]*)\}$/.exec(attribute);
|
||||
if (!match) return null;
|
||||
|
||||
const expression = match[2].trim();
|
||||
if (!expression.startsWith("[") && !expression.startsWith("{")) return null;
|
||||
|
||||
try {
|
||||
return {
|
||||
name: match[1],
|
||||
value: JSON.parse(expression),
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function formatAttribute(attribute, indentation, unit) {
|
||||
const structured = parseStructuredAttribute(attribute);
|
||||
if (!structured) return [`${indentation}${attribute}`];
|
||||
|
||||
const jsonLines = JSON.stringify(structured.value, null, unit).split("\n");
|
||||
if (jsonLines.length === 1) {
|
||||
return [`${indentation}${structured.name}={${jsonLines[0]}}`];
|
||||
}
|
||||
|
||||
return [
|
||||
`${indentation}${structured.name}={${jsonLines[0]}`,
|
||||
...jsonLines.slice(1, -1).map((line) => `${indentation}${line}`),
|
||||
`${indentation}${jsonLines.at(-1)}}`,
|
||||
];
|
||||
}
|
||||
|
||||
function escapeRegExp(value) {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
@@ -257,7 +334,7 @@ function formatOpeningTag(value, unit, depth, printWidth = 100, multilineAttribu
|
||||
|
||||
const lines = [
|
||||
`${baseIndent}<${parsed.tagName}`,
|
||||
...parsed.attributes.map((attribute) => `${childIndent}${attribute}`),
|
||||
...parsed.attributes.flatMap((attribute) => formatAttribute(attribute, childIndent, unit)),
|
||||
];
|
||||
|
||||
if (parsed.selfClosing) {
|
||||
@@ -328,7 +405,7 @@ function countLeadingClosingBraces(value) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if (value[index] !== "}") {
|
||||
if (value[index] !== "}" && value[index] !== "]") {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -399,6 +476,10 @@ function countStructuralBraces(value) {
|
||||
openings += 1;
|
||||
} else if (character === "}") {
|
||||
closings += 1;
|
||||
} else if (character === "[") {
|
||||
openings += 1;
|
||||
} else if (character === "]") {
|
||||
closings += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,6 +538,27 @@ function expandInlineControlBlocks(lines) {
|
||||
});
|
||||
}
|
||||
|
||||
function expandStructuredStateDeclarations(lines, unit) {
|
||||
return lines.flatMap((line) => {
|
||||
const match = /^(\s*state\s+[A-Za-z_$][\w$]*\s*=\s*)([\\[{][\s\S]*)$/.exec(line);
|
||||
if (!match) return [line];
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(match[2].trim());
|
||||
const jsonLines = JSON.stringify(parsed, null, unit).split("\n");
|
||||
if (jsonLines.length === 1) return [`${match[1]}${jsonLines[0]}`];
|
||||
|
||||
const leading = match[1].match(/^\s*/)?.[0] ?? "";
|
||||
return [
|
||||
`${match[1]}${jsonLines[0]}`,
|
||||
...jsonLines.slice(1).map((jsonLine) => `${leading}${jsonLine}`),
|
||||
];
|
||||
} catch {
|
||||
return [line];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function formatWrn(source, options = {}) {
|
||||
const unit = options.insertSpaces === false ? "\t" : " ".repeat(options.tabSize ?? 4);
|
||||
|
||||
@@ -469,7 +571,10 @@ function formatWrn(source, options = {}) {
|
||||
let controlDepth = 0;
|
||||
let index = 0;
|
||||
|
||||
const inputLines = expandInlineControlBlocks(source.replace(/\r\n/g, "\n").split("\n"));
|
||||
const sourceLines = source.replace(/\r\n/g, "\n").split("\n");
|
||||
const inputLines = expandInlineControlBlocks(
|
||||
expandStructuredStateDeclarations(sourceLines, unit),
|
||||
);
|
||||
|
||||
const output = [];
|
||||
|
||||
@@ -587,6 +692,7 @@ function formatWrn(source, options = {}) {
|
||||
module.exports = {
|
||||
countStructuralBraces,
|
||||
formatOpeningTag,
|
||||
formatAttribute,
|
||||
formatWrn,
|
||||
parseAttributes,
|
||||
parseOpeningTag,
|
||||
|
||||
Reference in New Issue
Block a user