text-parser.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. var openChar = '{',
  2. endChar = '}',
  3. ESCAPE_RE = /[-.*+?^${}()|[\]\/\\]/g,
  4. BINDING_RE = buildInterpolationRegex(),
  5. // lazy require
  6. Directive
  7. function buildInterpolationRegex () {
  8. var open = escapeRegex(openChar),
  9. end = escapeRegex(endChar)
  10. return new RegExp(open + open + open + '?(.+?)' + end + '?' + end + end)
  11. }
  12. function escapeRegex (str) {
  13. return str.replace(ESCAPE_RE, '\\$&')
  14. }
  15. function setDelimiters (delimiters) {
  16. exports.delimiters = delimiters
  17. openChar = delimiters[0]
  18. endChar = delimiters[1]
  19. BINDING_RE = buildInterpolationRegex()
  20. }
  21. /**
  22. * Parse a piece of text, return an array of tokens
  23. * token types:
  24. * 1. plain string
  25. * 2. object with key = binding key
  26. * 3. object with key & html = true
  27. */
  28. function parse (text) {
  29. if (!BINDING_RE.test(text)) return null
  30. var m, i, token, match, tokens = []
  31. /* jshint boss: true */
  32. while (m = text.match(BINDING_RE)) {
  33. i = m.index
  34. if (i > 0) tokens.push(text.slice(0, i))
  35. token = { key: m[1].trim() }
  36. match = m[0]
  37. token.html =
  38. match.charAt(2) === openChar &&
  39. match.charAt(match.length - 3) === endChar
  40. tokens.push(token)
  41. text = text.slice(i + m[0].length)
  42. }
  43. if (text.length) tokens.push(text)
  44. return tokens
  45. }
  46. /**
  47. * Parse an attribute value with possible interpolation tags
  48. * return a Directive-friendly expression
  49. *
  50. * e.g. a {{b}} c => "a " + b + " c"
  51. */
  52. function parseAttr (attr) {
  53. Directive = Directive || require('./directive')
  54. var tokens = parse(attr)
  55. if (!tokens) return null
  56. if (tokens.length === 1) return tokens[0].key
  57. var res = [], token
  58. for (var i = 0, l = tokens.length; i < l; i++) {
  59. token = tokens[i]
  60. res.push(
  61. token.key
  62. ? inlineFilters(token.key)
  63. : ('"' + token + '"')
  64. )
  65. }
  66. return res.join('+')
  67. }
  68. /**
  69. * Inlines any possible filters in a binding
  70. * so that we can combine everything into a huge expression
  71. */
  72. function inlineFilters (key) {
  73. if (key.indexOf('|') > -1) {
  74. var dirs = Directive.parse(key),
  75. dir = dirs && dirs[0]
  76. if (dir && dir.filters) {
  77. key = Directive.inlineFilters(
  78. dir.key,
  79. dir.filters
  80. )
  81. }
  82. }
  83. return '(' + key + ')'
  84. }
  85. exports.parse = parse
  86. exports.parseAttr = parseAttr
  87. exports.setDelimiters = setDelimiters
  88. exports.delimiters = [openChar, endChar]