diff --git a/lib/rules/no-raw-text.js b/lib/rules/no-raw-text.js
index 378bdbf8..f34333c0 100644
--- a/lib/rules/no-raw-text.js
+++ b/lib/rules/no-raw-text.js
@@ -7,6 +7,48 @@ const { parse, AST } = require('vue-eslint-parser')
const { defineTemplateBodyVisitor } = require('../utils/index')
const hasOnlyLineBreak = value => /^[\r\n\t\f\v]+$/.test(value.replace(/ /g, ''))
+const INNER_START_OFFSET = ''.length
+
+function calculateLoc (node, base = null) {
+ return !base
+ ? node.loc
+ : {
+ start: {
+ line: base.loc.start.line,
+ column: base.loc.start.column + (node.loc.start.column - INNER_START_OFFSET)
+ },
+ end: {
+ line: base.loc.end.line,
+ column: base.loc.end.column + (node.loc.end.column - INNER_START_OFFSET)
+ }
+ }
+}
+
+function checkVExpressionContainerText (context, node, baseNode = null) {
+ if (!node.expression) { return }
+
+ if (node.expression.type === 'Literal') {
+ const literalNode = node.expression
+ const loc = calculateLoc(literalNode, baseNode)
+ context.report({
+ loc,
+ message: `raw text '${literalNode.value}' is used`
+ })
+ } else if (node.expression.type === 'ConditionalExpression') {
+ const targets = [node.expression.consequent, node.expression.alternate]
+ targets.forEach(target => {
+ if (target.type === 'Literal') {
+ const loc = calculateLoc(target, baseNode)
+ context.report({
+ loc,
+ message: `raw text '${target.value}' is used`
+ })
+ }
+ })
+ } else if ((node.parent && node.parent.type === 'VAttribute' && node.parent.directive) &&
+ (node.parent.key && node.parent.key.type === 'VDirectiveKey')) {
+ }
+}
function checkRawText (context, value, loc) {
if (typeof value !== 'string' || hasOnlyLineBreak(value)) { return }
@@ -52,6 +94,10 @@ function getComponentTemplateNode (value) {
function create (context) {
return defineTemplateBodyVisitor(context, { // template block
+ VExpressionContainer (node) {
+ checkVExpressionContainerText(context, node)
+ },
+
VText (node) {
checkRawText(context, node.value, node.loc)
}
@@ -65,6 +111,8 @@ function create (context) {
enterNode (node) {
if (node.type === 'VText') {
checkRawText(context, node.value, valueNode.loc)
+ } else if (node.type === 'VExpressionContainer') {
+ checkVExpressionContainerText(context, node, valueNode)
}
},
leaveNode () {}
diff --git a/tests/lib/rules/no-raw-text.js b/tests/lib/rules/no-raw-text.js
index 45028344..4de1cdbb 100644
--- a/tests/lib/rules/no-raw-text.js
+++ b/tests/lib/rules/no-raw-text.js
@@ -25,6 +25,12 @@ tester.run('no-raw-text', rule, {
{{ $t('click') }}{{ $t('here') }}{{ $t('terminal') }} {{ hello }} {{ 'hello' }} {{ ok ? 'hello' : 'world' }}
{{ "hello" }}
' + const Component = { + template + } + `, + errors: [{ + message: `raw text 'hello' is used`, line: 2, column: 30 + }] + }, { + // javascript expression specify string literal to `template` variable in mustache + code: ` + const template = '{{ ok ? "hello" : "world" }}
' + const Component = { + template + } + `, + errors: [{ + message: `raw text 'hello' is used`, line: 2, column: 35 + }, { + message: `raw text 'world' is used`, line: 2, column: 45 + }] }, { // directly specify string literal to JSX with `render` code: `