From 7326f945579f4a601b1ab01c9a9edb1e621d3d88 Mon Sep 17 00:00:00 2001 From: Ray Guo <33137074+RayGuo-ergou@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:34:58 +1100 Subject: [PATCH 1/4] feat: allow pass in component prefix --- __tests__/formatter.test.ts | 34 ++++++++++++++++++++++++++++++++++ src/cli.ts | 14 ++++++++++++++ src/formatter.ts | 4 +++- src/main.ts | 1 + src/runtimeConfig.ts | 7 +++++++ 5 files changed, 59 insertions(+), 1 deletion(-) diff --git a/__tests__/formatter.test.ts b/__tests__/formatter.test.ts index bcee0005..30ec1af3 100644 --- a/__tests__/formatter.test.ts +++ b/__tests__/formatter.test.ts @@ -5612,6 +5612,40 @@ describe("formatter", () => { }); }); + test("Without component prefix declared, return syntax incorrect code", async () => { + const content = [ + "bar\">", + "", + ].join("\n"); + + const expected = [ + " bar\">", + "", + "", + ].join("\n"); + + await util.doubleFormatCheck(content, expected, { + componentPrefix: [], + }); + }); + + test("Component prefix option correct format", async () => { + const content = [ + "bar\">", + "", + ].join("\n"); + + const expected = [ + "bar\">", + "", + "", + ].join("\n"); + + await util.doubleFormatCheck(content, expected, { + componentPrefix: ['foo:'], + }); + }); + test("unmatched x-slot close tag", async () => { const content = [ "", diff --git a/src/cli.ts b/src/cli.ts index b17aa862..53bd8223 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -145,6 +145,20 @@ export default async function cli() { ); }, }) + .option("component-prefix", { + alias: "P", + type: "string", + description: + "Component prefixs use to preserve style in html attributes.", + default: "x-,livewire:", + nullable: true, + coerce(formats) { + // Make sure we support comma-separated syntax: --extra-liners head,body + return _.flatten( + _.flatten([formats]).map((format) => format.split(",")), + ); + }, + }) .option("no-multiple-empty-lines", { type: "boolean", description: "Merge multiple blank lines into a single blank line", diff --git a/src/formatter.ts b/src/formatter.ts index 08d77e83..b5c0aff1 100644 --- a/src/formatter.ts +++ b/src/formatter.ts @@ -1101,9 +1101,11 @@ export default class Formatter { } async preserveComponentAttribute(content: string) { + const prefixes = Array.isArray(this.options.componentPrefix) && this.options.componentPrefix.length > 0 ? this.options.componentPrefix : ["x-", "livewire:"]; + const regex = new RegExp(`(?<=<(${prefixes.join("|")})[^<]*?\\s):{1,2}(?)[\\w\-_.]*?=(["'])(?!=>)[^\\2]*?\\2(?=[^>]*?\/*?>)`, "gim") return _.replace( content, - /(?<=<(x-|livewire:)[^<]*?\s):{1,2}(?)[\w\-_.]*?=(["'])(?!=>)[^\2]*?\2(?=[^>]*?\/*?>)/gim, + regex, (match: any) => `${this.storeComponentAttribute(match)}`, ); } diff --git a/src/main.ts b/src/main.ts index b31dfc4e..ac179328 100644 --- a/src/main.ts +++ b/src/main.ts @@ -49,6 +49,7 @@ export type FormatterOption = { noSingleQuote?: boolean; noTrailingCommaPhp?: boolean; extraLiners?: string[]; + componentPrefix?: string[]; }; export type BladeFormatterOption = CLIOption & FormatterOption; diff --git a/src/runtimeConfig.ts b/src/runtimeConfig.ts index d5033a79..1bff9ea3 100644 --- a/src/runtimeConfig.ts +++ b/src/runtimeConfig.ts @@ -42,6 +42,7 @@ export interface RuntimeConfig { noSingleQuote?: boolean; noTrailingCommaPhp?: boolean; extraLiners?: string[]; + componentPrefix?: string[]; } const defaultConfigNames = [".bladeformatterrc.json", ".bladeformatterrc"]; @@ -123,6 +124,12 @@ export async function readRuntimeConfig( items: { type: "string" }, default: ["head", "body", "/html"], }, + componentPrefix: { + type: "array", + nullable: true, + items: { type: "string" }, + default: ["x-", "livewire:"], + }, }, additionalProperties: true, }; From b65cf5d5eb491e6bbfeef26cf24047c3763e0100 Mon Sep 17 00:00:00 2001 From: Ray Guo <33137074+RayGuo-ergou@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:15:49 +1100 Subject: [PATCH 2/4] docs: update readme --- README.md | 3 ++- src/cli.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ff5afcc9..75b21428 100755 --- a/README.md +++ b/README.md @@ -224,7 +224,8 @@ e.g. "noPhpSyntaxCheck": false, "noSingleQuote": false, "noTrailingCommaPhp": false, - "extraLiners": [] + "extraLiners": [], + "componentPrefix": ["x-", "livewire:"] } ``` diff --git a/src/cli.ts b/src/cli.ts index 53bd8223..2a8448e4 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -149,11 +149,11 @@ export default async function cli() { alias: "P", type: "string", description: - "Component prefixs use to preserve style in html attributes.", + "Component prefix use to preserve style in html attributes.", default: "x-,livewire:", nullable: true, coerce(formats) { - // Make sure we support comma-separated syntax: --extra-liners head,body + // Make sure we support comma-separated syntax: --component-prefix x-,livewire: return _.flatten( _.flatten([formats]).map((format) => format.split(",")), ); From e40fb137d9edf34bd9cbc90f5d56ad43657e7064 Mon Sep 17 00:00:00 2001 From: Ray Guo <33137074+RayGuo-ergou@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:23:34 +1100 Subject: [PATCH 3/4] teat: cli test for component prefix --- __tests__/cli.test.ts | 26 +++++++++++++++++++ .../componentPrefix/formatted.index.blade.php | 2 ++ .../componentPrefix/index.blade.php | 2 ++ 3 files changed, 30 insertions(+) create mode 100644 __tests__/fixtures/argumentTest/componentPrefix/formatted.index.blade.php create mode 100644 __tests__/fixtures/argumentTest/componentPrefix/index.blade.php diff --git a/__tests__/cli.test.ts b/__tests__/cli.test.ts index 0c67bcfe..27259cbc 100644 --- a/__tests__/cli.test.ts +++ b/__tests__/cli.test.ts @@ -1285,6 +1285,32 @@ describe("The blade formatter CLI", () => { expect(cmdResult).toEqual(formatted.toString("utf-8")); }); + test.concurrent("cli argument test (component prefix)", async () => { + const cmdResult = await cmd.execute(binPath, [ + "--component-prefix", + 'foo:', + path.resolve( + "__tests__", + "fixtures", + "argumentTest", + "componentPrefix", + "index.blade.php", + ), + ]); + + const formatted = fs.readFileSync( + path.resolve( + "__tests__", + "fixtures", + "argumentTest", + "componentPrefix", + "formatted.index.blade.php", + ), + ); + + expect(cmdResult).toEqual(formatted.toString("utf-8")); + }); + test.concurrent("runtime config test (trailing comma php)", async () => { const cmdResult = await cmd.execute(binPath, [ path.resolve( diff --git a/__tests__/fixtures/argumentTest/componentPrefix/formatted.index.blade.php b/__tests__/fixtures/argumentTest/componentPrefix/formatted.index.blade.php new file mode 100644 index 00000000..23f7c1a7 --- /dev/null +++ b/__tests__/fixtures/argumentTest/componentPrefix/formatted.index.blade.php @@ -0,0 +1,2 @@ + + diff --git a/__tests__/fixtures/argumentTest/componentPrefix/index.blade.php b/__tests__/fixtures/argumentTest/componentPrefix/index.blade.php new file mode 100644 index 00000000..23f7c1a7 --- /dev/null +++ b/__tests__/fixtures/argumentTest/componentPrefix/index.blade.php @@ -0,0 +1,2 @@ + + From a7efd174ffdf10079d8b5a0a555aac957a9d41ad Mon Sep 17 00:00:00 2001 From: Ray Guo <33137074+RayGuo-ergou@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:36:22 +1100 Subject: [PATCH 4/4] docs: update readme for component prefix --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 75b21428..b7a9cf3e 100755 --- a/README.md +++ b/README.md @@ -193,6 +193,7 @@ $ blade-formatter -c -d resources/**/*.blade.php --no-php-syntax-check Disable PHP syntax checking [boolean] [default: false] --no-trailing-comma-php If set to true, no trailing commas are printed for php expression. [boolean] [default: false] -p, --progress Print progress [boolean] [default: false] + -P, --component-prefix Specify custom prefixes for component names. This changes the format rules applied to custom components e.g. preserve style in attributes. [string] [default: "x-,livewire:"] --stdin Format code provided on [boolean] [default: false] --config Use this configuration, overriding .bladeformatterrc config options if present [string] [default: null] --ignore-path Specify path of ignore file [string] [default: null]