main.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. var config = require('./config'),
  2. ViewModel = require('./viewmodel'),
  3. directives = require('./directives'),
  4. filters = require('./filters'),
  5. utils = require('./utils')
  6. /**
  7. * Set config options
  8. */
  9. ViewModel.config = function (opts, val) {
  10. if (typeof opts === 'string') {
  11. if (val === undefined) {
  12. return config[opts]
  13. } else {
  14. config[opts] = val
  15. }
  16. } else {
  17. utils.extend(config, opts)
  18. }
  19. return this
  20. }
  21. /**
  22. * Allows user to register/retrieve a directive definition
  23. */
  24. ViewModel.directive = function (id, fn) {
  25. if (!fn) return directives[id]
  26. directives[id] = fn
  27. return this
  28. }
  29. /**
  30. * Allows user to register/retrieve a filter function
  31. */
  32. ViewModel.filter = function (id, fn) {
  33. if (!fn) return filters[id]
  34. filters[id] = fn
  35. return this
  36. }
  37. /**
  38. * Allows user to register/retrieve a ViewModel constructor
  39. */
  40. ViewModel.component = function (id, Ctor) {
  41. if (!Ctor) return utils.components[id]
  42. utils.components[id] = utils.toConstructor(Ctor)
  43. return this
  44. }
  45. /**
  46. * Allows user to register/retrieve a template partial
  47. */
  48. ViewModel.partial = function (id, partial) {
  49. if (!partial) return utils.partials[id]
  50. utils.partials[id] = utils.toFragment(partial)
  51. return this
  52. }
  53. /**
  54. * Allows user to register/retrieve a transition definition object
  55. */
  56. ViewModel.transition = function (id, transition) {
  57. if (!transition) return utils.transitions[id]
  58. utils.transitions[id] = transition
  59. return this
  60. }
  61. ViewModel.extend = extend
  62. ViewModel.nextTick = utils.nextTick
  63. /**
  64. * Expose the main ViewModel class
  65. * and add extend method
  66. */
  67. function extend (options) {
  68. var ParentVM = this
  69. // inherit options
  70. options = inheritOptions(options, ParentVM.options, true)
  71. utils.processOptions(options)
  72. var ExtendedVM = function (opts, asParent) {
  73. if (!asParent) {
  74. opts = inheritOptions(opts, options, true)
  75. }
  76. ParentVM.call(this, opts, true)
  77. }
  78. // inherit prototype props
  79. var proto = ExtendedVM.prototype = Object.create(ParentVM.prototype)
  80. utils.defProtected(proto, 'constructor', ExtendedVM)
  81. // copy prototype props
  82. var methods = options.methods
  83. if (methods) {
  84. for (var key in methods) {
  85. if (
  86. !(key in ViewModel.prototype) &&
  87. typeof methods[key] === 'function'
  88. ) {
  89. proto[key] = methods[key]
  90. }
  91. }
  92. }
  93. // allow extended VM to be further extended
  94. ExtendedVM.extend = extend
  95. ExtendedVM.super = ParentVM
  96. ExtendedVM.options = options
  97. return ExtendedVM
  98. }
  99. /**
  100. * Inherit options
  101. *
  102. * For options such as `data`, `vms`, `directives`, 'partials',
  103. * they should be further extended. However extending should only
  104. * be done at top level.
  105. *
  106. * `proto` is an exception because it's handled directly on the
  107. * prototype.
  108. *
  109. * `el` is an exception because it's not allowed as an
  110. * extension option, but only as an instance option.
  111. */
  112. function inheritOptions (child, parent, topLevel) {
  113. child = child || utils.hash()
  114. if (!parent) return child
  115. for (var key in parent) {
  116. if (key === 'el' || key === 'methods') continue
  117. var val = child[key],
  118. parentVal = parent[key],
  119. type = utils.typeOf(val)
  120. if (topLevel && type === 'Function' && parentVal) {
  121. // merge hook functions into an array
  122. child[key] = [val]
  123. if (Array.isArray(parentVal)) {
  124. child[key] = child[key].concat(parentVal)
  125. } else {
  126. child[key].push(parentVal)
  127. }
  128. } else if (topLevel && type === 'Object') {
  129. // merge toplevel object options
  130. inheritOptions(val, parentVal)
  131. } else if (val === undefined) {
  132. // inherit if child doesn't override
  133. child[key] = parentVal
  134. }
  135. }
  136. return child
  137. }
  138. module.exports = ViewModel