main.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. var prefix = 'sd',
  2. Directive = require('./directive'),
  3. Directives = require('./directives'),
  4. selector = Object.keys(Directives).map(function (d) {
  5. return '[' + prefix + '-' + d + ']'
  6. }).join()
  7. function Seed (opts) {
  8. var self = this,
  9. root = this.el = document.getElementById(opts.id),
  10. els = root.querySelectorAll(selector)
  11. self.bindings = {}
  12. self.scope = {}
  13. // process nodes for directives
  14. ;[].forEach.call(els, this.compileNode.bind(this))
  15. this.compileNode(root)
  16. // initialize all variables by invoking setters
  17. for (var key in self.bindings) {
  18. self.scope[key] = opts.scope[key]
  19. }
  20. }
  21. Seed.prototype.compileNode = function (node) {
  22. var self = this
  23. cloneAttributes(node.attributes).forEach(function (attr) {
  24. var directive = Directive.parse(attr, prefix)
  25. if (directive) {
  26. self.bind(node, directive)
  27. }
  28. })
  29. }
  30. Seed.prototype.bind = function (node, directive) {
  31. directive.el = node
  32. node.removeAttribute(directive.attr.name)
  33. var key = directive.key,
  34. binding = this.bindings[key] || this.createBinding(key)
  35. // add directive to this binding
  36. binding.directives.push(directive)
  37. // invoke bind hook if exists
  38. if (directive.bind) {
  39. directive.bind(node, binding.value)
  40. }
  41. }
  42. Seed.prototype.createBinding = function (key) {
  43. var binding = {
  44. value: undefined,
  45. directives: []
  46. }
  47. this.bindings[key] = binding
  48. // bind accessor triggers to scope
  49. Object.defineProperty(this.scope, key, {
  50. get: function () {
  51. return binding.value
  52. },
  53. set: function (value) {
  54. binding.value = value
  55. binding.directives.forEach(function (directive) {
  56. directive.update(value)
  57. })
  58. }
  59. })
  60. return binding
  61. }
  62. Seed.prototype.dump = function () {
  63. var data = {}
  64. for (var key in this._bindings) {
  65. data[key] = this._bindings[key].value
  66. }
  67. return data
  68. }
  69. Seed.prototype.destroy = function () {
  70. for (var key in this._bindings) {
  71. this._bindings[key].directives.forEach(unbind)
  72. }
  73. this.el.parentNode.remove(this.el)
  74. function unbind (directive) {
  75. if (directive.unbind) {
  76. directive.unbind()
  77. }
  78. }
  79. }
  80. // clone attributes so they don't change
  81. function cloneAttributes (attributes) {
  82. return [].map.call(attributes, function (attr) {
  83. return {
  84. name: attr.name,
  85. value: attr.value
  86. }
  87. })
  88. }
  89. module.exports = {
  90. create: function (opts) {
  91. return new Seed(opts)
  92. },
  93. directive: function () {
  94. // create dir
  95. },
  96. filter: function () {
  97. // create filter
  98. }
  99. }