release: WRNexusJS 0.2.32
This commit is contained in:
+163
-45
@@ -19,24 +19,35 @@ const VOID_ELEMENTS = new Set([
|
||||
|
||||
function findOpeningTagEnd(value) {
|
||||
let quote = null;
|
||||
let escaped = false;
|
||||
|
||||
for (let index = 0; index < value.length; index += 1) {
|
||||
const char = value[index];
|
||||
const character = value[index];
|
||||
|
||||
if (quote !== null) {
|
||||
if (char === quote && value[index - 1] !== "\\") {
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (character === "\\") {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (character === quote) {
|
||||
quote = null;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === '"' || char === "'") {
|
||||
quote = char;
|
||||
if (character === '"' || character === "'") {
|
||||
quote = character;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (char === ">") {
|
||||
if (character === ">") {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@@ -46,7 +57,8 @@ function findOpeningTagEnd(value) {
|
||||
|
||||
function parseAttributes(value) {
|
||||
const attributes = [];
|
||||
const pattern = /[^\s"'=<>`]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'=<>`]+))?/g;
|
||||
|
||||
const pattern = /[^\s"'=<>`]+(?:\s*=\s*(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|[^\s"'=<>`]+))?/g;
|
||||
|
||||
let match;
|
||||
|
||||
@@ -65,17 +77,21 @@ function parseOpeningTag(value) {
|
||||
}
|
||||
|
||||
const openingPart = value.slice(0, endIndex + 1);
|
||||
|
||||
const remainder = value.slice(endIndex + 1).trim();
|
||||
|
||||
const match = /^<([A-Za-z][\w:-]*)([\s\S]*?)(\/?)>$/.exec(openingPart);
|
||||
const match = /^<([A-Za-z][\w$:.-]*)([\s\S]*?)(\/?)>$/.exec(openingPart);
|
||||
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tagName = match[1];
|
||||
|
||||
const attributes = parseAttributes(match[2].trim());
|
||||
|
||||
const selfClosing = match[3] === "/";
|
||||
|
||||
const inlineClosing = remainder === `</${tagName}>`;
|
||||
|
||||
return {
|
||||
@@ -98,7 +114,9 @@ function formatOpeningTag(value, unit, depth, printWidth = 100) {
|
||||
}
|
||||
|
||||
const baseIndent = unit.repeat(depth);
|
||||
|
||||
const attributeIndent = unit.repeat(depth + 1);
|
||||
|
||||
const normalizedSingleLine = value.replace(/\s+/g, " ").trim();
|
||||
|
||||
const shouldBreak =
|
||||
@@ -159,42 +177,144 @@ function isMultilineOpeningTagStart(value) {
|
||||
}
|
||||
|
||||
function isClosingTag(value) {
|
||||
return /^<\/[A-Za-z][\w:-]*\s*>/.test(value);
|
||||
return /^<\/[A-Za-z][\w$:.-]*\s*>/.test(value);
|
||||
}
|
||||
|
||||
function isInlineElement(value) {
|
||||
return /^<([A-Za-z][\w:-]*)\b[^>]*>[\s\S]*<\/\1\s*>$/.test(value);
|
||||
return /^<([A-Za-z][\w$:.-]*)\b[^>]*>[\s\S]*<\/\1\s*>$/.test(value);
|
||||
}
|
||||
|
||||
function isWrnBlockClosing(value) {
|
||||
return value === "}" || value.startsWith("} ");
|
||||
}
|
||||
function countLeadingClosingBraces(value) {
|
||||
let index = 0;
|
||||
let count = 0;
|
||||
|
||||
function isWrnBlockOpening(value) {
|
||||
if (!value.endsWith("{")) {
|
||||
return false;
|
||||
while (index < value.length) {
|
||||
while (index < value.length && /\s/.test(value[index])) {
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if (value[index] !== "}") {
|
||||
break;
|
||||
}
|
||||
|
||||
count += 1;
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return !value.startsWith("{");
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count braces outside strings and HTML comments.
|
||||
*
|
||||
* This supports WRN blocks, function bodies, lifecycle hooks,
|
||||
* watcher bodies and multiline JavaScript object literals.
|
||||
*/
|
||||
function countStructuralBraces(value) {
|
||||
let openings = 0;
|
||||
let closings = 0;
|
||||
|
||||
let quote = null;
|
||||
let escaped = false;
|
||||
let htmlComment = false;
|
||||
|
||||
for (let index = 0; index < value.length; index += 1) {
|
||||
if (!quote && !htmlComment && value.startsWith("<!--", index)) {
|
||||
htmlComment = true;
|
||||
index += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (htmlComment && value.startsWith("-->", index)) {
|
||||
htmlComment = false;
|
||||
index += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (htmlComment) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const character = value[index];
|
||||
|
||||
if (quote !== null) {
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (character === "\\") {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (character === quote) {
|
||||
quote = null;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (character === '"' || character === "'" || character === "`") {
|
||||
quote = character;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (character === "{") {
|
||||
openings += 1;
|
||||
} else if (character === "}") {
|
||||
closings += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
openings,
|
||||
closings,
|
||||
};
|
||||
}
|
||||
|
||||
function collectOpeningTag(inputLines, startIndex) {
|
||||
const collected = [inputLines[startIndex].trim()];
|
||||
|
||||
let index = startIndex;
|
||||
|
||||
while (index + 1 < inputLines.length) {
|
||||
const joined = collected.join(" ");
|
||||
|
||||
if (findOpeningTagEnd(joined) !== -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
index += 1;
|
||||
collected.push(inputLines[index].trim());
|
||||
}
|
||||
|
||||
return {
|
||||
value: collected.join(" "),
|
||||
endIndex: index,
|
||||
};
|
||||
}
|
||||
|
||||
function formatWrn(source, options = {}) {
|
||||
const unit = options.insertSpaces === false ? "\t" : " ".repeat(options.tabSize || 4);
|
||||
|
||||
const printWidth = options.printWidth || 100;
|
||||
|
||||
const inputLines = source.replace(/\r\n/g, "\n").split("\n");
|
||||
|
||||
const output = [];
|
||||
|
||||
let wrnDepth = 0;
|
||||
let codeDepth = 0;
|
||||
let htmlDepth = 0;
|
||||
let index = 0;
|
||||
let previousWasBlank = false;
|
||||
|
||||
while (index < inputLines.length) {
|
||||
const originalLine = inputLines[index];
|
||||
const trimmed = originalLine.trim();
|
||||
|
||||
if (trimmed === "") {
|
||||
let value = originalLine.trim();
|
||||
|
||||
if (value === "") {
|
||||
if (!previousWasBlank && output.length > 0) {
|
||||
output.push("");
|
||||
}
|
||||
@@ -206,43 +326,31 @@ function formatWrn(source, options = {}) {
|
||||
|
||||
previousWasBlank = false;
|
||||
|
||||
let value = trimmed;
|
||||
|
||||
if (isMultilineOpeningTagStart(value)) {
|
||||
const collected = [value];
|
||||
let cursor = index + 1;
|
||||
const collected = collectOpeningTag(inputLines, index);
|
||||
|
||||
while (cursor < inputLines.length) {
|
||||
const nextPart = inputLines[cursor].trim();
|
||||
collected.push(nextPart);
|
||||
|
||||
const joined = collected.join(" ");
|
||||
|
||||
if (findOpeningTagEnd(joined) !== -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
cursor += 1;
|
||||
}
|
||||
|
||||
value = collected.join(" ");
|
||||
index = cursor;
|
||||
value = collected.value;
|
||||
index = collected.endIndex;
|
||||
}
|
||||
|
||||
if (isWrnBlockClosing(value)) {
|
||||
wrnDepth = Math.max(0, wrnDepth - 1);
|
||||
}
|
||||
const leadingClosingBraces = countLeadingClosingBraces(value);
|
||||
|
||||
const lineCodeDepth = Math.max(0, codeDepth - leadingClosingBraces);
|
||||
|
||||
let lineHtmlDepth = htmlDepth;
|
||||
|
||||
if (isClosingTag(value)) {
|
||||
htmlDepth = Math.max(0, htmlDepth - 1);
|
||||
lineHtmlDepth = Math.max(0, htmlDepth - 1);
|
||||
}
|
||||
|
||||
const depth = wrnDepth + htmlDepth;
|
||||
const depth = lineCodeDepth + lineHtmlDepth;
|
||||
|
||||
if (
|
||||
value.startsWith("<") &&
|
||||
!value.startsWith("</") &&
|
||||
!value.startsWith("<!--") &&
|
||||
!value.startsWith("<!") &&
|
||||
!value.startsWith("<?") &&
|
||||
!isInlineElement(value)
|
||||
) {
|
||||
const formattedTag = formatOpeningTag(value, unit, depth, printWidth);
|
||||
@@ -256,10 +364,17 @@ function formatWrn(source, options = {}) {
|
||||
output.push(`${unit.repeat(depth)}${value}`);
|
||||
}
|
||||
|
||||
if (isWrnBlockOpening(value)) {
|
||||
wrnDepth += 1;
|
||||
if (isClosingTag(value)) {
|
||||
htmlDepth = lineHtmlDepth;
|
||||
}
|
||||
|
||||
const braces = countStructuralBraces(value);
|
||||
|
||||
codeDepth = Math.max(
|
||||
0,
|
||||
lineCodeDepth + braces.openings - Math.max(0, braces.closings - leadingClosingBraces),
|
||||
);
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
@@ -271,6 +386,9 @@ function formatWrn(source, options = {}) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
countStructuralBraces,
|
||||
formatOpeningTag,
|
||||
formatWrn,
|
||||
parseAttributes,
|
||||
parseOpeningTag,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user