UNPKG

1.46 kBJavaScriptView Raw
1/* @flow */
2
3import { cached } from 'shared/util'
4import { parseFilters } from './filter-parser'
5
6const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g
7const regexEscapeRE = /[-.*+?^${}()|[\]\/\\]/g
8
9const buildRegex = cached(delimiters => {
10 const open = delimiters[0].replace(regexEscapeRE, '\\$&')
11 const close = delimiters[1].replace(regexEscapeRE, '\\$&')
12 return new RegExp(open + '((?:.|\\n)+?)' + close, 'g')
13})
14
15type TextParseResult = {
16 expression: string,
17 tokens: Array<string | { '@binding': string }>
18}
19
20export function parseText (
21 text: string,
22 delimiters?: [string, string]
23): TextParseResult | void {
24 const tagRE = delimiters ? buildRegex(delimiters) : defaultTagRE
25 if (!tagRE.test(text)) {
26 return
27 }
28 const tokens = []
29 const rawTokens = []
30 let lastIndex = tagRE.lastIndex = 0
31 let match, index, tokenValue
32 while ((match = tagRE.exec(text))) {
33 index = match.index
34 // push text token
35 if (index > lastIndex) {
36 rawTokens.push(tokenValue = text.slice(lastIndex, index))
37 tokens.push(JSON.stringify(tokenValue))
38 }
39 // tag token
40 const exp = parseFilters(match[1].trim())
41 tokens.push(`_s(${exp})`)
42 rawTokens.push({ '@binding': exp })
43 lastIndex = index + match[0].length
44 }
45 if (lastIndex < text.length) {
46 rawTokens.push(tokenValue = text.slice(lastIndex))
47 tokens.push(JSON.stringify(tokenValue))
48 }
49 return {
50 expression: tokens.join('+'),
51 tokens: rawTokens
52 }
53}