decorators.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. var clazz = (function () {
  2. var creatingPrototype = {};
  3. var methods = function (object) {
  4. var methods = {};
  5. var proto = object.__proto__;
  6. while (proto !== Object.prototype) {
  7. for (var methodName in proto) {
  8. if (!methods[methodName] && typeof(proto[methodName]) === "function") {
  9. methods[methodName] = proto[methodName];
  10. }
  11. }
  12. proto = proto.__proto__;
  13. }
  14. return methods;
  15. }
  16. var decorateWith = function (decorator) {
  17. var decoratorMethods = methods(decorator);
  18. for (var methodName in decoratorMethods) {
  19. var decoratorMethod = decoratorMethods[methodName];
  20. if (typeof(decoratorMethod) === "function" && !(methodName === "construct" || methodName.name === "onDelegateAttached" || methodName === "decorateWith")) {
  21. this[methodName] = (function (prototype, methodName, method, decorator) {
  22. return function () {
  23. var delegate = this;
  24. try {
  25. decorator.decorated = function () {
  26. return prototype.apply(delegate, arguments);
  27. }
  28. return method.apply(decorator, arguments);
  29. } finally {
  30. delete decorator.decorated;
  31. }
  32. };
  33. })(this[methodName], methodName, decoratorMethod, decorator);
  34. this[methodName].displayName = methodName + "#decorator";
  35. }
  36. }
  37. if (decorator.onDelegateAttached) {
  38. decorator.onDelegateAttached(this);
  39. }
  40. decorator.delegate = this;
  41. return this;
  42. };
  43. return function (SuperClass, methods) {
  44. var constructor = function (arg) {
  45. if (arg === creatingPrototype) {
  46. return;
  47. }
  48. if (this.construct) {
  49. this.construct.apply(this, arguments);
  50. }
  51. };
  52. constructor.prototype = SuperClass !== Object ? new SuperClass(creatingPrototype) : new SuperClass;
  53. for (var methodName in methods) {
  54. constructor.prototype[methodName] = (function (prototype, methodName, method) {
  55. return function () {
  56. var currentSuper = this.super;
  57. try {
  58. this.super = prototype;
  59. return method.apply(this, arguments);
  60. } finally {
  61. this.super = currentSuper;
  62. }
  63. };
  64. })(constructor.prototype[methodName], methodName, methods[methodName]);
  65. constructor.prototype[methodName].displayName = methodName;
  66. }
  67. if (!constructor.prototype.decorateWith) {
  68. constructor.prototype.decorateWith = decorateWith;
  69. }
  70. return constructor;
  71. }
  72. })();