directive.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. var Directives = require('./directives'),
  2. Filters = require('./filters')
  3. var KEY_RE = /^[^\|]+/,
  4. FILTERS_RE = /\|[^\|]+/g
  5. function Directive (def, attr, arg, key) {
  6. if (typeof def === 'function') {
  7. this._update = def
  8. } else {
  9. for (var prop in def) {
  10. if (prop === 'update') {
  11. this['_update'] = def.update
  12. continue
  13. }
  14. this[prop] = def[prop]
  15. }
  16. }
  17. this.attr = attr
  18. this.arg = arg
  19. this.key = key
  20. var filters = attr.value.match(FILTERS_RE)
  21. if (filters) {
  22. this.filters = filters.map(function (filter) {
  23. // TODO test performance against regex
  24. var tokens = filter.replace('|', '').trim().split(/\s+/)
  25. return {
  26. apply: Filters[tokens[0]],
  27. args: tokens.length > 1 ? tokens.slice(1) : null
  28. }
  29. })
  30. }
  31. }
  32. Directive.prototype.update = function (value) {
  33. // apply filters
  34. if (this.filters) {
  35. value = this.applyFilters(value)
  36. }
  37. this._update(value)
  38. }
  39. Directive.prototype.applyFilters = function (value) {
  40. var filtered = value
  41. this.filters.forEach(function (filter) {
  42. filtered = filter.apply(filtered, filter.args)
  43. })
  44. return filtered
  45. }
  46. module.exports = {
  47. // make sure the directive and value is valid
  48. parse: function (attr, prefix) {
  49. if (attr.name.indexOf(prefix) === -1) return null
  50. var noprefix = attr.name.slice(prefix.length + 1),
  51. argIndex = noprefix.indexOf('-'),
  52. arg = argIndex === -1
  53. ? null
  54. : noprefix.slice(argIndex + 1),
  55. name = arg
  56. ? noprefix.slice(0, argIndex)
  57. : noprefix,
  58. def = Directives[name]
  59. var key = attr.value.match(KEY_RE)
  60. return def && key
  61. ? new Directive(def, attr, arg, key[0].trim())
  62. : null
  63. }
  64. }