-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackbone.mixture.js
93 lines (87 loc) · 3.42 KB
/
backbone.mixture.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['backbone', 'underscore'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('backbone'), require('underscore'));
} else {
root.Backbone.Mixture = factory(root.Backbone, root._);
}
})(this, function factory(Backbone, _) {
function noop() {}
var assign = _.assign || _.extend;
var Mixture = function () {};
Mixture.extend = Backbone.Model.extend;
Mixture.VERSION = '0.0.2';
Mixture.implement = function (implementation, statics) {
if (!implementation.id) {
implementation = assign({id: _.uniqueId('mixture')}, implementation);
}
return this.extend(implementation, statics);
};
Mixture.mixin = Backbone.View.mixin = Backbone.Model.mixin = Backbone.Collection.mixin = Backbone.Router.mixin = mixin;
function interceptBefore(object, methodName, fn) {
var method = object[methodName] || noop;
if (!_.isFunction(fn)) {
return (object[methodName] = method);
}
return (object[methodName] = function () {
if (fn.apply(this, arguments) !== false) {
return method.apply(this, arguments);
}
});
}
function interceptAfter(object, methodName, fn) {
var method = object[methodName] || noop;
if (!_.isFunction(fn)) {
return (object[methodName] = method);
}
return (object[methodName] = function () {
var ret = method.apply(this, arguments);
fn.apply(this, arguments);
return ret;
});
}
function mixin() {
return _.reduce(_.flatten(arguments), function (cls, mixture) {
var proto = cls.prototype;
var mixins = proto.__mixins__ = proto.__mixins__ || {};
var toOmit = ['constructor', 'id', 'beforeHooks', 'afterHooks', 'mixins'];
var implementation = _.isFunction(mixture) ? mixture.prototype || new mixture() : mixture;
if (!_.isObject(implementation)) {
return cls;
}
var mixinId = implementation.id;
if (mixinId && mixins[mixinId]) {
return cls;
}
if (implementation.mixins) {
cls = mixin.apply(cls, implementation.mixins);
}
var beforeHooks = implementation.beforeHooks;
var afterHooks = implementation.afterHooks;
if (_.isObject(beforeHooks)) {
_.each(beforeHooks, function (from, to) {
if (to === Number(to)) {
to = from;
}
interceptBefore(proto, to, implementation[from]);
toOmit.push(from);
});
}
if (_.isObject(afterHooks)) {
_.each(afterHooks, function (from, to) {
if (to === Number(to)) {
to = from;
}
interceptAfter(proto, to, implementation[from]);
toOmit.push(from);
});
}
assign(proto, _.omit(implementation, toOmit));
assign(cls, _.omit(mixture, ['extend', 'implement', 'mixin', 'VERSION', '__super__']));
mixins[mixinId] = mixture;
return cls;
}, this);
}
return Mixture;
});