Skip to content

Commit

Permalink
fix: 🐛 unbalanced x-slot tag behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
shufo committed Aug 21, 2023
1 parent 2cb7315 commit 04c823f
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 2 deletions.
49 changes: 49 additions & 0 deletions __tests__/fixtures/snapshots/unmatched_xslot_close_tag.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
------------------------------------options----------------------------------------
{
"wrapAttributes": "force-expand-multiline",
"wrapAttributesMinAttrs": 1
}
------------------------------------content----------------------------------------
<x-alert>
<x-slot:title name="f>oo"
value="bar">
Foo bar
</x-slot>
<x-slot name="foo">
Foo bar
</x-slot:title>
<x-slot:title>
Foo bar
</x-slot:title>
<x-slot:foo>
Foo bar
<x-slot:bar>
Foo bar
</x-slot>
Foo bar
</x-slot>
</x-alert>
------------------------------------expected----------------------------------------
<x-alert>
<x-slot:title
name="f>oo"
value="bar"
>
Foo bar
</x-slot>
<x-slot
name="foo"
>
Foo bar
</x-slot:title>
<x-slot:title>
Foo bar
</x-slot:title>
<x-slot:foo>
Foo bar
<x-slot:bar>
Foo bar
</x-slot>
Foo bar
</x-slot>
</x-alert>
48 changes: 48 additions & 0 deletions __tests__/formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5240,4 +5240,52 @@ describe('formatter', () => {
extraLiners: [],
});
});

test('unmatched x-slot close tag', async () => {
const content = [
`<x-alert>`,
` <x-slot:title name="f>oo"`,
`value="bar">`,
` Foo bar`,
` </x-slot>`,
` <x-slot name="foo">`,
` Foo bar`,
` </x-slot:title>`,
` <x-slot:title>`,
` Foo bar`,
` </x-slot:title>`,
` <x-slot:foo>`,
` Foo bar`,
` <x-slot:bar>`,
` Foo bar`,
` </x-slot>`,
` Foo bar`,
` </x-slot>`,
` </x-alert>`,
].join('\n');

const expected = [
`<x-alert>`,
` <x-slot:title name="f>oo" value="bar">`,
` Foo bar`,
` </x-slot>`,
` <x-slot name="foo">`,
` Foo bar`,
` </x-slot:title>`,
` <x-slot:title>`,
` Foo bar`,
` </x-slot:title>`,
` <x-slot:foo>`,
` Foo bar`,
` <x-slot:bar>`,
` Foo bar`,
` </x-slot>`,
` Foo bar`,
` </x-slot>`,
`</x-alert>`,
``,
].join('\n');

await util.doubleFormatCheck(content, expected);
});
});
30 changes: 28 additions & 2 deletions src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ export default class Formatter {

scripts: any;

xData: any;
xData: Array<string>;

xInit: any;
xInit: Array<string>;

xSlot: Array<string>;

htmlTags: Array<string>;

Expand Down Expand Up @@ -171,6 +173,7 @@ export default class Formatter {
this.directivesInScript = [];
this.unbalancedDirectives = [];
this.escapedBladeDirectives = [];
this.xSlot = [];
this.result = [];
this.diffs = [];
this.defaultPhpFormatOption = { noPhpSyntaxCheck: this.options.noPhpSyntaxCheck, printWidth: this.wrapLineLength };
Expand Down Expand Up @@ -209,10 +212,12 @@ export default class Formatter {
.then((target) => this.sortHtmlAttributes(target))
.then((target) => this.preservePhpBlock(target))
.then((target) => this.preserveHtmlAttributes(target))
.then((target) => this.preserveXslot(target))
.then((target) => this.preserveHtmlTags(target))
.then((target) => this.formatAsHtml(target))
.then((target) => this.formatAsBlade(target))
.then((target) => this.restoreHtmlTags(target))
.then((target) => this.restoreXslot(target))
.then((target) => this.restoreHtmlAttributes(target))
.then((target) => this.restorePhpBlock(target))
.then((target) => this.restoreShorthandBinding(target))
Expand Down Expand Up @@ -771,6 +776,12 @@ export default class Formatter {
return _.replace(content, /@@\w*/gim, (match: string) => this.storeEscapedBladeDirective(match));
}

async preserveXslot(content: string) {
return _.replace(content, /(?<=<\/?)(x-slot:[\w_\\-]+)(?=(?:[^>]*?[^?])?>)/gm, (match: string) =>
this.storeXslot(match),
);
}

async preserveBladeComment(content: any) {
return _.replace(content, /\{\{--(.*?)--\}\}/gs, (match: string) => this.storeBladeComment(match));
}
Expand Down Expand Up @@ -972,6 +983,10 @@ export default class Formatter {
return this.getEscapedBladeDirectivePlaceholder((this.escapedBladeDirectives.push(value) - 1).toString());
}

storeXslot(value: string) {
return this.getXslotPlaceholder((this.xSlot.push(value) - 1).toString());
}

storeBladeComment(value: any) {
return this.getBladeCommentPlaceholder(this.bladeComments.push(value) - 1);
}
Expand Down Expand Up @@ -1122,6 +1137,10 @@ export default class Formatter {
return _.replace('___escaped_directive_#___', '#', replace);
}

getXslotPlaceholder(replace: string) {
return _.replace('x-slot --___#___--', '#', replace);
}

getBladeCommentPlaceholder(replace: any) {
return _.replace('___blade_comment_#___', '#', replace);
}
Expand Down Expand Up @@ -1664,6 +1683,13 @@ export default class Formatter {
);
}

restoreXslot(content: string) {
return _.replace(content, /x-slot\s*--___(\d+)___--/gms, (_match: string, p1: number) => this.xSlot[p1]).replace(
/(?<=<x-slot:[\w\_\-]*)\s+(?=\/?>)/gm,
(_match: string) => '',
);
}

restorePhpComment(content: string) {
return _.replace(
content,
Expand Down
1 change: 1 addition & 0 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ const escapeTags = [
'@customdirective',
'@elsecustomdirective',
'@endcustomdirective',
'x-slot --___\\d+___--',
];

export function checkResult(formatted: any) {
Expand Down

0 comments on commit 04c823f

Please sign in to comment.