0ac10982eaf4348fa72641e3b3524f0a0b6c05bf7f6c70750f7398dad4668134ee167b58e3d707f2daae80507a6b80a470b11181daa4820f88905034d08701 1.4 KB

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