Skip to content

Commit 78bd936

Browse files
ota-meshimysticatea
authored andcommitted
Fix: ignore preformatted tokens in html-indent (fixes #653)(#659)
1 parent 0e51839 commit 78bd936

File tree

2 files changed

+151
-2
lines changed

2 files changed

+151
-2
lines changed

Diff for: lib/utils/indent-common.js

+31
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
258258
const options = parseOptions(context.options[0], context.options[1] || {}, defaultOptions)
259259
const sourceCode = context.getSourceCode()
260260
const offsets = new Map()
261+
const preformattedTokens = new Set()
261262

262263
/**
263264
* Set offset to the given tokens.
@@ -301,6 +302,29 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
301302
}
302303
}
303304

305+
/**
306+
* Sets preformatted tokens to the given element node.
307+
* @param {Node} node The node to set.
308+
* @returns {void}
309+
*/
310+
function setPreformattedTokens (node) {
311+
const endToken = (node.endTag && tokenStore.getFirstToken(node.endTag)) || tokenStore.getTokenAfter(node)
312+
313+
const option = {
314+
includeComments: true,
315+
filter: token => token != null && (
316+
token.type === 'HTMLText' ||
317+
token.type === 'HTMLTagOpen' ||
318+
token.type === 'HTMLEndTagOpen' ||
319+
token.type === 'HTMLComment'
320+
)
321+
}
322+
for (const token of tokenStore.getTokensBetween(node.startTag, endToken, option)) {
323+
preformattedTokens.add(token)
324+
}
325+
preformattedTokens.add(endToken)
326+
}
327+
304328
/**
305329
* Get the first and last tokens of the given node.
306330
* If the node is parenthesized, this gets the outermost parentheses.
@@ -782,6 +806,11 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
782806
}
783807
}
784808

809+
// It does not validate preformatted tokens.
810+
if (preformattedTokens.has(firstToken)) {
811+
return
812+
}
813+
785814
// Calculate the expected indents for comments.
786815
// It allows the same indent level with the previous line.
787816
const lastOffsetInfo = offsets.get(lastToken)
@@ -821,6 +850,8 @@ module.exports.defineVisitor = function create (context, tokenStore, defaultOpti
821850
if (node.name !== 'pre') {
822851
const childTokens = node.children.map(n => tokenStore.getFirstToken(n))
823852
setOffset(childTokens, 1, startTagToken)
853+
} else {
854+
setPreformattedTokens(node)
824855
}
825856
setOffset(endTagToken, 0, startTagToken)
826857
},

Diff for: tests/lib/rules/html-indent.js

+120-2
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,83 @@ tester.run('html-indent', rule, loadPatterns(
281281
</pre>
282282
</template>
283283
`
284+
},
285+
{
286+
filename: 'test.vue',
287+
code: unIndent`
288+
<template>
289+
<pre>
290+
<span>aaa</span>
291+
<span>bbb</span>
292+
<span>ccc</span>
293+
</pre>
294+
</template>
295+
`
296+
},
297+
{
298+
filename: 'test.vue',
299+
code: unIndent`
300+
<template>
301+
<pre>aaa
302+
bbb ccc
303+
ddd
304+
fff</pre>
305+
</template>
306+
`
307+
},
308+
{
309+
filename: 'test.vue',
310+
code: unIndent`
311+
<template>
312+
<pre><span>aaa</span>
313+
<span>bbb</span> <span>ccc</span>
314+
<span>ddd</span>
315+
<span>fff</span></pre>
316+
</template>
317+
`
318+
},
319+
{
320+
filename: 'test.vue',
321+
code: unIndent`
322+
<template>
323+
<div><pre>aaa
324+
bbb ccc
325+
ddd
326+
fff</pre></div>
327+
</template>
328+
`
329+
},
330+
{
331+
filename: 'test.vue',
332+
code: unIndent`
333+
<template>
334+
<pre>
335+
<!-- comment -->
336+
<!-- comment --> <!-- comment -->
337+
<!-- comment --></pre>
338+
</template>
339+
`
340+
},
341+
{
342+
filename: 'test.vue',
343+
code: unIndent`
344+
<template>
345+
<pre>
346+
<!-- comment --> text <span />
347+
<span /> <!-- comment --> text
348+
text <span /> <!-- comment -->
349+
</pre>
350+
<div>
351+
<input>
352+
</div>
353+
<pre>
354+
<!-- comment --> text <span /></pre>
355+
<pre>
356+
<span /> <!-- comment --> text</pre>
357+
<pre>
358+
text <span /> <!-- comment --></pre>
359+
</template>
360+
`
284361
}
285362
],
286363

@@ -564,13 +641,54 @@ tester.run('html-indent', rule, loadPatterns(
564641
aaa
565642
bbb
566643
ccc
567-
</pre>
644+
</pre>
568645
</template>
569646
`,
570647
errors: [
571648
{ message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 },
572649
{ message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 },
573-
{ message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 },
650+
{ message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 4 }
651+
]
652+
},
653+
{
654+
filename: 'test.vue',
655+
code: unIndent`
656+
<template>
657+
<pre
658+
:class="[
659+
'a',
660+
'b',
661+
'c'
662+
]"
663+
>
664+
aaa
665+
bbb
666+
ccc
667+
</pre>
668+
</template>
669+
`,
670+
output: unIndent`
671+
<template>
672+
<pre
673+
:class="[
674+
'a',
675+
'b',
676+
'c'
677+
]"
678+
>
679+
aaa
680+
bbb
681+
ccc
682+
</pre>
683+
</template>
684+
`,
685+
errors: [
686+
{ message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 2 },
687+
{ message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 3 },
688+
{ message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 4 },
689+
{ message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 5 },
690+
{ message: 'Expected indentation of 6 spaces but found 0 spaces.', line: 6 },
691+
{ message: 'Expected indentation of 4 spaces but found 0 spaces.', line: 7 },
574692
{ message: 'Expected indentation of 2 spaces but found 0 spaces.', line: 8 }
575693
]
576694
}

0 commit comments

Comments
 (0)