1 |
|
2 |
|
3 | const validDivisionCharRE = /[\w).+\-_$\]]/
|
4 |
|
5 | export function parseFilters (exp: string): string {
|
6 | let inSingle = false
|
7 | let inDouble = false
|
8 | let inTemplateString = false
|
9 | let inRegex = false
|
10 | let curly = 0
|
11 | let square = 0
|
12 | let paren = 0
|
13 | let lastFilterIndex = 0
|
14 | let c, prev, i, expression, filters
|
15 |
|
16 | for (i = 0; i < exp.length; i++) {
|
17 | prev = c
|
18 | c = exp.charCodeAt(i)
|
19 | if (inSingle) {
|
20 | if (c === 0x27 && prev !== 0x5C) inSingle = false
|
21 | } else if (inDouble) {
|
22 | if (c === 0x22 && prev !== 0x5C) inDouble = false
|
23 | } else if (inTemplateString) {
|
24 | if (c === 0x60 && prev !== 0x5C) inTemplateString = false
|
25 | } else if (inRegex) {
|
26 | if (c === 0x2f && prev !== 0x5C) inRegex = false
|
27 | } else if (
|
28 | c === 0x7C &&
|
29 | exp.charCodeAt(i + 1) !== 0x7C &&
|
30 | exp.charCodeAt(i - 1) !== 0x7C &&
|
31 | !curly && !square && !paren
|
32 | ) {
|
33 | if (expression === undefined) {
|
34 |
|
35 | lastFilterIndex = i + 1
|
36 | expression = exp.slice(0, i).trim()
|
37 | } else {
|
38 | pushFilter()
|
39 | }
|
40 | } else {
|
41 | switch (c) {
|
42 | case 0x22: inDouble = true; break
|
43 | case 0x27: inSingle = true; break
|
44 | case 0x60: inTemplateString = true; break
|
45 | case 0x28: paren++; break
|
46 | case 0x29: paren--; break
|
47 | case 0x5B: square++; break
|
48 | case 0x5D: square--; break
|
49 | case 0x7B: curly++; break
|
50 | case 0x7D: curly--; break
|
51 | }
|
52 | if (c === 0x2f) {
|
53 | let j = i - 1
|
54 | let p
|
55 |
|
56 | for (; j >= 0; j--) {
|
57 | p = exp.charAt(j)
|
58 | if (p !== ' ') break
|
59 | }
|
60 | if (!p || !validDivisionCharRE.test(p)) {
|
61 | inRegex = true
|
62 | }
|
63 | }
|
64 | }
|
65 | }
|
66 |
|
67 | if (expression === undefined) {
|
68 | expression = exp.slice(0, i).trim()
|
69 | } else if (lastFilterIndex !== 0) {
|
70 | pushFilter()
|
71 | }
|
72 |
|
73 | function pushFilter () {
|
74 | (filters || (filters = [])).push(exp.slice(lastFilterIndex, i).trim())
|
75 | lastFilterIndex = i + 1
|
76 | }
|
77 |
|
78 | if (filters) {
|
79 | for (i = 0; i < filters.length; i++) {
|
80 | expression = wrapFilter(expression, filters[i])
|
81 | }
|
82 | }
|
83 |
|
84 | return expression
|
85 | }
|
86 |
|
87 | function wrapFilter (exp: string, filter: string): string {
|
88 | const i = filter.indexOf('(')
|
89 | if (i < 0) {
|
90 |
|
91 | return `_f("${filter}")(${exp})`
|
92 | } else {
|
93 | const name = filter.slice(0, i)
|
94 | const args = filter.slice(i + 1)
|
95 | return `_f("${name}")(${exp}${args !== ')' ? ',' + args : args}`
|
96 | }
|
97 | }
|