Skip to content

Commit 984304c

Browse files
author
Evan You
committed
allow config custom interpolation delimiters
1 parent f3af959 commit 984304c

File tree

3 files changed

+110
-24
lines changed

3 files changed

+110
-24
lines changed

src/config.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
module.exports = {
1+
var TextParser = require('./text-parser')
22

3+
module.exports = {
34
prefix : 'v',
45
debug : false,
56
silent : false,
67
enterClass : 'v-enter',
78
leaveClass : 'v-leave',
89
interpolate : true
10+
}
911

10-
}
12+
Object.defineProperty(module.exports, 'delimiters', {
13+
get: function () {
14+
return TextParser.delimiters
15+
},
16+
set: function (delimiters) {
17+
TextParser.setDelimiters(delimiters)
18+
}
19+
})

src/text-parser.js

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,31 @@
1-
var BINDING_RE = /{{{?(.+?)}?}}/
1+
var openChar = '{',
2+
endChar = '}',
3+
ESCAPE_RE = /[-.*+?^${}()|[\]\/\\]/g,
4+
BINDING_RE = buildInterpolationRegex()
25

3-
/**
6+
function buildInterpolationRegex () {
7+
var open = escapeRegex(openChar),
8+
end = escapeRegex(endChar)
9+
return new RegExp(open + open + open + '?(.+?)' + end + '?' + end + end)
10+
}
11+
12+
function escapeRegex (str) {
13+
return str.replace(ESCAPE_RE, '\\$&')
14+
}
15+
16+
function setDelimiters (delimiters) {
17+
exports.delimiters = delimiters
18+
openChar = delimiters[0]
19+
endChar = delimiters[1]
20+
BINDING_RE = buildInterpolationRegex()
21+
}
22+
23+
/**
424
* Parse a piece of text, return an array of tokens
25+
* token types:
26+
* 1. plain string
27+
* 2. object with key = binding key
28+
* 3. object with key & html = true
529
*/
630
function parse (text) {
731
if (!BINDING_RE.test(text)) return null
@@ -13,8 +37,8 @@ function parse (text) {
1337
token = { key: m[1].trim() }
1438
match = m[0]
1539
token.html =
16-
match.charAt(2) === '{' &&
17-
match.charAt(match.length - 3) === '}'
40+
match.charAt(2) === openChar &&
41+
match.charAt(match.length - 3) === endChar
1842
tokens.push(token)
1943
text = text.slice(i + m[0].length)
2044
}
@@ -25,6 +49,8 @@ function parse (text) {
2549
/**
2650
* Parse an attribute value with possible interpolation tags
2751
* return a Directive-friendly expression
52+
*
53+
* e.g. a {{b}} c => "a " + b + " c"
2854
*/
2955
function parseAttr (attr) {
3056
var tokens = parse(attr)
@@ -42,5 +68,7 @@ function parseAttr (attr) {
4268
return res.join('+')
4369
}
4470

45-
exports.parse = parse
46-
exports.parseAttr = parseAttr
71+
exports.parse = parse
72+
exports.parseAttr = parseAttr
73+
exports.setDelimiters = setDelimiters
74+
exports.delimiters = [openChar, endChar]

test/unit/specs/api.js

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,6 @@ describe('API', function () {
77
describe('config()', function () {
88

99
var config = require('vue/src/config')
10-
11-
it('should work when changing prefix', function () {
12-
var testId = 'config-1'
13-
Vue.config({
14-
prefix: 'test'
15-
})
16-
mock(testId, '<span test-text="test"></span>')
17-
new Vue({
18-
el: '#' + testId,
19-
data: { test: testId }
20-
})
21-
assert.strictEqual(document.querySelector('#' + testId + ' span').innerHTML, testId)
22-
})
2310

2411
it('should get', function () {
2512
assert.strictEqual(Vue.config('debug'), false)
@@ -30,10 +17,72 @@ describe('API', function () {
3017
assert.strictEqual(config.test, 1)
3118
})
3219

33-
after(function () {
34-
Vue.config({
35-
prefix: 'v'
20+
describe('changing prefix', function () {
21+
22+
before(function () {
23+
Vue.config({ prefix: 'test' })
24+
})
25+
26+
after(function () {
27+
Vue.config({ prefix: 'v' })
28+
})
29+
30+
it('should work', function () {
31+
var v = new Vue({
32+
template: '<span test-text="test"></span>',
33+
data: { test: 'helllllo' }
34+
})
35+
assert.strictEqual(v.$el.innerHTML, '<span>' + v.test + '</span>')
36+
})
37+
38+
})
39+
40+
describe('changing interpolation delimiters', function () {
41+
42+
before(function () {
43+
Vue.config({ delimiters: ['[', ']'] })
44+
})
45+
46+
after(function () {
47+
Vue.config({ delimiters: ['{', '}'] })
48+
})
49+
50+
it('should work', function () {
51+
var v = new Vue({
52+
template: '<span>[[text]]</span><div>[[[html]]]</div>',
53+
data: {
54+
text: 'hello!!!',
55+
html: '<span><a>some raw html</a></span>'
56+
}
57+
})
58+
59+
assert.strictEqual(v.$el.querySelector('span').innerHTML, v.text)
60+
assert.strictEqual(v.$el.querySelector('div').innerHTML, v.html + '<!--v-html-->')
61+
})
62+
63+
})
64+
65+
describe('skipping interpolation', function () {
66+
67+
before(function () {
68+
Vue.config({ interpolate: false })
3669
})
70+
71+
after(function () {
72+
Vue.config({ interpolate: true })
73+
})
74+
75+
it('should work', function () {
76+
var raw = '<span class="{{text}}">{{text}}</span>'
77+
var v = new Vue({
78+
template: raw,
79+
data: {
80+
text: 'hello!!!'
81+
}
82+
})
83+
assert.strictEqual(v.$el.innerHTML, raw)
84+
})
85+
3786
})
3887

3988
})

0 commit comments

Comments
 (0)