Skip to content

Commit 84f37b8

Browse files
committed
🐛 bug(rule): fix cannot detect raw text of template syntax expression
closes #23
1 parent 801043c commit 84f37b8

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

lib/rules/no-raw-text.js

+48
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,48 @@ const { parse, AST } = require('vue-eslint-parser')
77
const { defineTemplateBodyVisitor } = require('../utils/index')
88

99
const hasOnlyLineBreak = value => /^[\r\n\t\f\v]+$/.test(value.replace(/ /g, ''))
10+
const INNER_START_OFFSET = '<template>'.length
11+
12+
function calculateLoc (node, base = null) {
13+
return !base
14+
? node.loc
15+
: {
16+
start: {
17+
line: base.loc.start.line,
18+
column: base.loc.start.column + (node.loc.start.column - INNER_START_OFFSET)
19+
},
20+
end: {
21+
line: base.loc.end.line,
22+
column: base.loc.end.column + (node.loc.end.column - INNER_START_OFFSET)
23+
}
24+
}
25+
}
26+
27+
function checkVExpressionContainerText (context, node, baseNode = null) {
28+
if (!node.expression) { return }
29+
30+
if (node.expression.type === 'Literal') {
31+
const literalNode = node.expression
32+
const loc = calculateLoc(literalNode, baseNode)
33+
context.report({
34+
loc,
35+
message: `raw text '${literalNode.value}' is used`
36+
})
37+
} else if (node.expression.type === 'ConditionalExpression') {
38+
const targets = [node.expression.consequent, node.expression.alternate]
39+
targets.forEach(target => {
40+
if (target.type === 'Literal') {
41+
const loc = calculateLoc(target, baseNode)
42+
context.report({
43+
loc,
44+
message: `raw text '${target.value}' is used`
45+
})
46+
}
47+
})
48+
} else if ((node.parent && node.parent.type === 'VAttribute' && node.parent.directive) &&
49+
(node.parent.key && node.parent.key.type === 'VDirectiveKey')) {
50+
}
51+
}
1052

1153
function checkRawText (context, value, loc) {
1254
if (typeof value !== 'string' || hasOnlyLineBreak(value)) { return }
@@ -52,6 +94,10 @@ function getComponentTemplateNode (value) {
5294

5395
function create (context) {
5496
return defineTemplateBodyVisitor(context, { // template block
97+
VExpressionContainer (node) {
98+
checkVExpressionContainerText(context, node)
99+
},
100+
55101
VText (node) {
56102
checkRawText(context, node.value, node.loc)
57103
}
@@ -65,6 +111,8 @@ function create (context) {
65111
enterNode (node) {
66112
if (node.type === 'VText') {
67113
checkRawText(context, node.value, valueNode.loc)
114+
} else if (node.type === 'VExpressionContainer') {
115+
checkVExpressionContainerText(context, node, valueNode)
68116
}
69117
},
70118
leaveNode () {}

tests/lib/rules/no-raw-text.js

+62
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ tester.run('no-raw-text', rule, {
2525
<p class="inner">{{ $t('click') }}<a href="/foo">{{ $t('here') }}</a>{{ $t('terminal') }}</p>
2626
</div>
2727
</template>`
28+
}, {
29+
code: `
30+
<template>
31+
<p>{{ hello }}</p>
32+
</template>
33+
`
2834
}, {
2935
filename: 'test.vue',
3036
code: `
@@ -85,6 +91,38 @@ tester.run('no-raw-text', rule, {
8591
}, {
8692
message: `raw text '!' is used`, line: 5
8793
}]
94+
}, {
95+
// directly specify string literal in mustache
96+
code: `
97+
<template>
98+
<p>{{ 'hello' }}</p>
99+
</template>
100+
`,
101+
errors: [{
102+
message: `raw text 'hello' is used`, line: 3
103+
}]
104+
}, {
105+
// javascript expression specify string literal in mustache
106+
code: `
107+
<template>
108+
<p>{{ ok ? 'hello' : 'world' }}</p>
109+
</template>
110+
`,
111+
errors: [{
112+
message: `raw text 'hello' is used`, line: 3
113+
}, {
114+
message: `raw text 'world' is used`, line: 3
115+
}]
116+
}, {
117+
// directly specify string literal in v-text
118+
code: `
119+
<template>
120+
<p v-text="'hello'"></p>
121+
</template>
122+
`,
123+
errors: [{
124+
message: `raw text 'hello' is used`, line: 3
125+
}]
88126
}, {
89127
// directly specify string literal to `template` component option at export default object
90128
code: `
@@ -116,6 +154,30 @@ tester.run('no-raw-text', rule, {
116154
errors: [{
117155
message: `raw text 'hello' is used`, line: 2
118156
}]
157+
}, {
158+
// directly specify string literal to `template` variable
159+
code: `
160+
const template = '<p>{{ "hello" }}</p>'
161+
const Component = {
162+
template
163+
}
164+
`,
165+
errors: [{
166+
message: `raw text 'hello' is used`, line: 2, column: 30
167+
}]
168+
}, {
169+
// javascript expression specify string literal to `template` variable in mustache
170+
code: `
171+
const template = '<p>{{ ok ? "hello" : "world" }}</p>'
172+
const Component = {
173+
template
174+
}
175+
`,
176+
errors: [{
177+
message: `raw text 'hello' is used`, line: 2, column: 35
178+
}, {
179+
message: `raw text 'world' is used`, line: 2, column: 45
180+
}]
119181
}, {
120182
// directly specify string literal to JSX with `render`
121183
code: `

0 commit comments

Comments
 (0)