Requires

Provides

Class.Mixin.js

Classes that can be mixed in and out in runtime.

License:
MIT-style license.
  1. 22
  2. 23
  3. 24
  4. 25
  5. 26
  6. 27
  7. 28
  8. 29
  9. 30
  10. 31
  11. 32
  12. 33
  13. 34
  14. 35
  15. 36
  16. 37
  17. 38
  18. 39
  19. 40
  20. 41
  21. 42
  22. 43
  23. 44
  24. 45
  25. 46
  26. 47
  27. 48
  28. 49
  29. 50
  30. 51
  31. 52
  32. 53
  33. 54
  34. 55
  35. 56
  36. 57
  37. 58
  38. 59
  39. 60
  40. 61
  41. 62
  42. 63
  43. 64
  44. 65
  45. 66
  46. 67
  47. 68
  48. 69
  49. 70
  50. 71
  51. 72
  52. 73
  53. 74
  54. 75
  55. 76
  56. 77
  57. 78
  58. 79
  59. 80
  60. 81
  61. 82
  62. 83
  63. 84
Class.mixin = function(instance, klass) { var proto = klass.prototype; Object.each(proto, function(value, name) { if (typeof value !== 'function') return; switch (name) { case "parent": case "initialize": case "uninitialize": case "$constructor": return; } value = value.$origin; var origin = instance[name], parent, wrap if (origin) { if (origin.$mixes) return origin.$mixes.push(value); parent = origin.$owner; wrap = origin; origin = origin.$origin; } var wrapper = instance[name] = function() { var stack = wrapper.$stack; if (!stack) stack = wrapper.$stack = wrapper.$mixes.clone() var mix = stack.pop(); wrapper.$owner = {parent: mix ? instance.$constructor : parent} if (!mix) mix = origin; if (!mix) return; var caller = this.caller, current = this.$caller; this.caller = current; this.$caller = wrapper; var result = (mix || origin).apply(this, arguments); this.$caller = current; this.caller = caller; delete wrapper.$stack; return result; }.extend({$mixes: [value], $origin: origin, $name: name}); }); if (instance.setOptions && proto.options) instance.setOptions(proto.options) //undoeable now :( if (proto.initialize) { var parent = instance.parent; instance.parent = function(){}; proto.initialize.call(instance, instance); instance.parent = parent; } } Class.unmix = function(instance, klass) { var proto = klass.prototype; Object.each(proto, function(value, key) { if (typeof value !== 'function') return; var remixed = instance[key] if (remixed && remixed.$mixes) { if (remixed.$origin) instance[key] = remixed.$origin; else delete instance[key]; } }) if (proto.uninitialize) { var parent = instance.parent; instance.parent = function(){}; proto.uninitialize.call(instance, instance); instance.parent = parent; } } Class.implement('mixin', function(klass) { Class.mixin(this, klass) }) Class.implement('unmix', function(klass) { Class.unmix(this, klass) })