diff --git a/__tests__/formatter.test.js b/__tests__/formatter.test.js index 80f6ec54..c789dda9 100644 --- a/__tests__/formatter.test.js +++ b/__tests__/formatter.test.js @@ -1445,4 +1445,26 @@ describe('formatter', () => { assert.equal(result, expected); }); }); + + test('should format inline function directives in scripts', async () => { + const content = [ + ``, + ].join('\n'); + + const expected = [ + ``, + ``, + ].join('\n'); + + return new BladeFormatter().format(content).then((result) => { + assert.equal(result, expected); + }); + }); }); diff --git a/src/formatter.js b/src/formatter.js index bda4beaf..db58d62f 100644 --- a/src/formatter.js +++ b/src/formatter.js @@ -9,6 +9,7 @@ import { phpKeywordStartTokens, phpKeywordEndTokens, indentStartAndEndTokens, + inlineFunctionTokens, } from './indent'; import * as util from './util'; import * as vsctm from './vsctm'; @@ -119,10 +120,23 @@ export default class Formatter { content, /(.*?)<\/script>/gis, (_match, p1, p2) => { - if (new RegExp(indentStartTokens.join('|'), 'gmi').test(p2) === false) { + const targetTokens = [...indentStartTokens, ...inlineFunctionTokens]; + if (new RegExp(targetTokens.join('|'), 'gmi').test(p2) === false) { return `${p2}`; } + const inlineFunctionDirectives = inlineFunctionTokens.join('|'); + const inlineFunctionRegex = new RegExp( + // eslint-disable-next-line max-len + `(?!\\/\\*.*?\\*\\/)(${inlineFunctionDirectives})(\\s*?)\\(((?:[^)(]+|\\((?:[^)(]+|\\([^)(]*\\))*\\))*)\\)`, + 'gmi', + ); + + // eslint-disable-next-line no-param-reassign + p2 = _.replace(p2, inlineFunctionRegex, (match) => { + return this.storeBladeDirective(util.formatRawStringAsPhp(match)); + }); + const directives = _.chain(indentStartTokens) .without('@switch', '@forelse') .map((x) => _.replace(x, /@/, '')) @@ -312,6 +326,10 @@ export default class Formatter { return content; } + if (this.isInline(content)) { + return `${spaces}${content}`; + } + const leftIndentAmount = detectIndent(spaces).amount; const indentLevel = leftIndentAmount / this.indentSize; const prefix = this.indentCharacter.repeat( @@ -338,14 +356,18 @@ export default class Formatter { .join('\n'); } - indentBladeDirectiveBlock(spaces, content) { - if (_.isEmpty(spaces)) { + indentBladeDirectiveBlock(prefix, content) { + if (_.isEmpty(prefix)) { return content; } - const leftIndentAmount = detectIndent(spaces).amount; + if (this.isInline(content)) { + return `${prefix}${content}`; + } + + const leftIndentAmount = detectIndent(prefix).amount; const indentLevel = leftIndentAmount / this.indentSize; - const prefix = this.indentCharacter.repeat( + const prefixSpaces = this.indentCharacter.repeat( indentLevel < 0 ? 0 : indentLevel * this.indentSize, ); const prefixForEnd = this.indentCharacter.repeat( @@ -360,7 +382,7 @@ export default class Formatter { return prefixForEnd + line; } - return prefix + line; + return prefixSpaces + line; }) .value() .join('\n'); diff --git a/src/indent.js b/src/indent.js index 49769ef0..77f946bf 100644 --- a/src/indent.js +++ b/src/indent.js @@ -95,6 +95,8 @@ export const phpKeywordEndTokens = [ '@break', ]; +export const inlineFunctionTokens = ['@json']; + export function hasStartAndEndToken(tokenizeLineResult, originalLine) { return ( _.filter(tokenizeLineResult.tokens, (tokenStruct) => {