/
delegate-attributes.js
103 lines (85 loc) · 2.45 KB
/
delegate-attributes.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
94
95
96
97
98
99
100
101
102
103
var propsExtender = require('./assign-properties');
var eventsExtender = require('./events');
function assignDelegateTo(obj, delegate) {
Object.defineProperty(obj, '_delegate_obj', {
value: delegate,
configurable: false,
writable: false
});
obj.listenTo(delegate, 'all', obj.trigger);
}
function getterFor(obj, key) {
Object.defineProperty(obj, key, {
enumerable: true,
get: function() {
return this._delegate_obj.get(key);
}
});
}
function setterAndGetterFor(obj, key) {
Object.defineProperty(obj, key, {
enumerable: true,
get: function() {
return this._delegate_obj.get(key);
},
set: function(val) {
return this._delegate_obj.set(key, val);
}
});
}
var delegateExtend = propsExtender.extend(eventsExtender).extend({
transformConstructor: function(Constructor) {
return function Class() {
var ret = Constructor.apply(this, arguments);
var delegate = this.delegate.apply(this, arguments);
if (delegate) {
/*eslint guard-for-in: 0 */
assignDelegateTo(this, delegate);
var valApplier = this.delegate_readOnly ? getterFor : setterAndGetterFor;
for (var key in delegate.constructor._attributes) {
valApplier(this, key);
}
}
return ret;
};
},
beforeExtend: function(opts) {
// set default value
if (!('delegate_readOnly' in opts.protoProps)) {
opts.protoProps.delegate_readOnly = true;
}
},
afterExtend: function(opts) {
var get = opts.child.prototype.get;
var set;
if (!opts.protoProps.delegate_readOnly) {
set = opts.child.prototype.set;
}
if (get) {
opts.child.prototype.get = function(key) {
var delegate = this._delegate_obj;
if (delegate && key in delegate.constructor._attributes) {
return delegate.get.apply(delegate, arguments);
} else {
return get.apply(this, arguments);
}
};
} else {
opts.child.prototype.get = function() {
var delegate = this._delegate_obj;
return delegate.get.apply(delegate, arguments);
};
}
if (set) {
opts.child.prototype.set = function(key) {
var delegate = this._delegate_obj;
if (delegate && key in delegate.constructor._attributes) {
return delegate.set.apply(delegate, arguments);
} else {
set.call(this, arguments);
}
};
}
}
});
module.exports = delegateExtend;