Skip to content

Commit

Permalink
fix: non-native type script tag throws an error if it contains direct…
Browse files Browse the repository at this point in the history
…ive (#725)
  • Loading branch information
shufo authored Oct 1, 2022
1 parent b87787b commit cbdf6d1
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 8 deletions.
58 changes: 58 additions & 0 deletions __tests__/formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4619,4 +4619,62 @@ describe('formatter', () => {

await util.doubleFormatCheck(content, expected);
});

test('it should not throws error if non-native script type ontains directive', async () => {
const content = [
`<script type="text/template">`,
`@if(true)`,
` <div class="true"></div>`,
`@else`,
` <div class="false"></div>`,
`@endif`,
`</script>`,
`<script id="data" type="application/json">`,
`{"org": 10, "items":["one","two"]}`,
`</script>`,
`<script id="data" type="application/json">`,
` <?php echo json_encode($users); ?>`,
`</script>`,
`<script id="data" type="application/json">`,
` @json($users)`,
`</script>`,
`<script id="data" type="text/template">`,
` <div>`,
` @if ($users)`,
` <p>@json($users)</p>`,
` @endif`,
` </div>`,
`</script>`,
].join('\n');

const expected = [
`<script type="text/template">`,
`@if(true)`,
` <div class="true"></div>`,
`@else`,
` <div class="false"></div>`,
`@endif`,
`</script>`,
`<script id="data" type="application/json">`,
`{"org": 10, "items":["one","two"]}`,
`</script>`,
`<script id="data" type="application/json">`,
` <?php echo json_encode($users); ?>`,
`</script>`,
`<script id="data" type="application/json">`,
` @json($users)`,
`</script>`,
`<script id="data" type="text/template">`,
` <div>`,
` @if ($users)`,
` <p>@json($users)</p>`,
` @endif`,
` </div>`,
`</script>`,
``,
].join('\n');

await util.doubleFormatCheck(content, expected);
await expect(new BladeFormatter().format(content)).resolves.not.toThrow("Can't format blade");
});
});
40 changes: 32 additions & 8 deletions src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export default class Formatter {

result: any;

nonnativeScripts: Array<string>;

scripts: any;

xData: any;
Expand Down Expand Up @@ -137,6 +139,7 @@ export default class Formatter {
this.bladeComments = [];
this.bladeBraces = [];
this.rawBladeBraces = [];
this.nonnativeScripts = [];
this.scripts = [];
this.htmlAttributes = [];
this.xData = [];
Expand All @@ -157,6 +160,7 @@ export default class Formatter {
formatContent(content: any) {
return new Promise((resolve) => resolve(content))
.then((target) => this.preserveIgnoredLines(target))
.then((target) => this.preserveNonnativeScripts(target))
.then((target) => this.preserveCurlyBraceForJS(target))
.then((target) => this.preserveRawPhpTags(target))
.then((target) => this.preserveEscapedBladeDirective(target))
Expand Down Expand Up @@ -207,6 +211,7 @@ export default class Formatter {
.then((target) => this.restoreEscapedBladeDirective(target))
.then((target) => this.restoreRawPhpTags(target))
.then((target) => this.restoreCurlyBraceForJS(target))
.then((target) => this.restoreNonnativeScripts(target))
.then((target) => this.restoreIgnoredLines(target))
.then((formattedResult) => util.checkResult(formattedResult));
}
Expand Down Expand Up @@ -765,6 +770,14 @@ export default class Formatter {
return _.replace(content, /<\?php(.*?)\?>/gms, (match: any) => this.storeRawPhpTags(match));
}

async preserveNonnativeScripts(content: string) {
return _.replace(
content,
/<script[^>]*?type=(["'])(?!text\/javascript)[^\1]*?\1[^>]*?>.*?<\/script>/gis,
(match: string) => this.storeNonnativeScripts(match),
);
}

async preserveScripts(content: any) {
return _.replace(content, /<script.*?>.*?<\/script>/gis, (match: any) => this.storeScripts(match));
}
Expand Down Expand Up @@ -905,6 +918,11 @@ export default class Formatter {
return this.getRawPhpTagPlaceholder(index);
}

storeNonnativeScripts(value: string) {
const index = this.nonnativeScripts.push(value) - 1;
return this.getNonnativeScriptPlaceholder(index.toString());
}

storeScripts(value: any) {
const index = this.scripts.push(value) - 1;
return this.getScriptPlaceholder(index);
Expand Down Expand Up @@ -1020,6 +1038,10 @@ export default class Formatter {
return _.replace('___raw_php_tag_#___', '#', replace);
}

getNonnativeScriptPlaceholder(replace: string) {
return _.replace('<blade ___non_native_scripts_#___ />', '#', replace);
}

getScriptPlaceholder(replace: any) {
return _.replace('<blade ___scripts_#___ />', '#', replace);
}
Expand Down Expand Up @@ -1693,6 +1715,16 @@ export default class Formatter {
);
}

restoreNonnativeScripts(content: string) {
return _.replace(
content,
new RegExp(`${this.getNonnativeScriptPlaceholder('(\\d+)')}`, 'gmi'),
(_match: any, p1: number) => {
return `${this.nonnativeScripts[p1]}`;
},
);
}

restoreScripts(content: any) {
return new Promise((resolve) => resolve(content)).then((res) =>
_.replace(
Expand All @@ -1702,14 +1734,6 @@ export default class Formatter {
(_match: any, p1: number) => {
const script = this.scripts[p1];

// do nothing if type of script tag is not JS
const scriptTagAttrs = script.match(/<script[^>]*?type=(["'])(.*?)\1/);
const typeIsNotJavaScript = scriptTagAttrs && scriptTagAttrs[2] !== 'text/javascript';

if (typeIsNotJavaScript) {
return script;
}

const placeholder = this.getScriptPlaceholder(p1);
const matchedLine = content.match(new RegExp(`^(.*?)${placeholder}`, 'gmi')) ?? [''];
const indent = detectIndent(matchedLine[0]);
Expand Down

0 comments on commit cbdf6d1

Please sign in to comment.