Skip to content

Commit 6953041

Browse files
committed
See #108. Implement proxy.advise for base object proxies, port connection facets to use proxy.advise where appropriate
1 parent 4ac04c9 commit 6953041

25 files changed

+743
-763
lines changed

aop.js

+64-73
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ define(function(require) {
6767
// Simple advice
6868
//
6969

70-
function addSingleAdvice(addAdviceFunc, advices, proxy, advice, options, wire) {
70+
function addSingleAdvice(addAdviceFunc, proxy, advice, options, wire, advices) {
7171

72-
function handleAopConnection(srcObject, srcMethod, adviceHandler) {
73-
checkAdvisable(srcObject, srcMethod);
74-
advices.push(addAdviceFunc(srcObject, srcMethod, adviceHandler));
72+
function handleAopConnection(srcProxy, srcMethod, adviceHandler) {
73+
checkAdvisable(srcProxy.target, srcMethod);
74+
advices.push(addAdviceFunc(srcProxy, srcMethod, adviceHandler));
7575
}
7676

7777
return connection.parse(proxy, advice, options, wire, handleAopConnection);
@@ -84,30 +84,38 @@ define(function(require) {
8484
}
8585

8686
function makeSingleAdviceAdd(adviceType) {
87-
return function (source, sourceMethod, advice) {
88-
return meld[adviceType](source, sourceMethod, advice);
87+
return function (srcProxy, sourceMethod, advice) {
88+
var aspect = {};
89+
aspect[adviceType] = advice;
90+
return srcProxy.advise(sourceMethod, aspect);
8991
};
9092
}
9193

92-
function addAfterFulfillingAdvice(source, sourceMethod, advice) {
93-
return meld.afterReturning(source, sourceMethod, function(promise) {
94-
return when(promise, advice);
94+
function addAfterFulfillingAdvice(srcProxy, sourceMethod, advice) {
95+
return srcProxy.advise(sourceMethod, {
96+
afterReturning: function(promise) {
97+
return when(promise, advice);
98+
}
9599
});
96100
}
97101

98-
function addAfterRejectingAdvice(source, sourceMethod, advice) {
99-
return meld.afterReturning(source, sourceMethod, function(promise) {
100-
return when(promise, null, advice);
102+
function addAfterRejectingAdvice(srcProxy, sourceMethod, advice) {
103+
return srcProxy.advise(sourceMethod, {
104+
afterReturning: function(promise) {
105+
return when(promise, null, advice);
106+
}
101107
});
102108
}
103109

104-
function addAfterPromiseAdvice(source, sourceMethod, advice) {
105-
return meld.after(source, sourceMethod, function(promise) {
106-
return when(promise, advice, advice);
110+
function addAfterPromiseAdvice(srcProxy, sourceMethod, advice) {
111+
return srcProxy.advise(sourceMethod, {
112+
after: function(promise) {
113+
return when(promise, advice, advice);
114+
}
107115
});
108116
}
109117

110-
function makeAdviceFacet(addAdviceFunc, advices) {
118+
function makeAdviceFacet(advices, addAdviceFunc) {
111119
return function(resolver, facet, wire) {
112120
var advice, target, advicesToAdd, promises;
113121

@@ -116,8 +124,8 @@ define(function(require) {
116124
promises = [];
117125

118126
for(advice in advicesToAdd) {
119-
promises.push(addSingleAdvice(addAdviceFunc, advices,
120-
target, advice, advicesToAdd[advice], wire));
127+
promises.push(addSingleAdvice(addAdviceFunc,
128+
target, advice, advicesToAdd[advice], wire, advices));
121129
}
122130

123131
resolver.resolve(when.all(promises));
@@ -128,28 +136,28 @@ define(function(require) {
128136
// Aspect Weaving
129137
//
130138

131-
function applyAspectCombined(target, aspect, wire, add) {
139+
function applyAspectCombined(targetProxy, aspect, wire, aspects) {
132140
return when(wire.resolveRef(aspect), function (aspect) {
133141
var pointcut = aspect.pointcut;
134142

135143
if (pointcut) {
136-
add(target, pointcut, aspect);
144+
aspects.push(targetProxy.advise(pointcut, aspect));
137145
}
138146

139-
return target;
147+
return targetProxy;
140148
});
141149
}
142150

143-
function applyAspectSeparate(target, aspect, wire, add) {
151+
function applyAspectSeparate(targetProxy, aspect, wire, aspects) {
144152
var pointcut, advice;
145153

146154
pointcut = aspect.pointcut;
147155
advice = aspect.advice;
148156

149157
function applyAdvice(pointcut) {
150158
return when(wire.resolveRef(advice), function (aspect) {
151-
add(target, pointcut, aspect);
152-
return target;
159+
aspects.push(targetProxy.advise(pointcut, aspect));
160+
return targetProxy;
153161
});
154162
}
155163

@@ -158,24 +166,23 @@ define(function(require) {
158166
: applyAdvice(pointcut);
159167
}
160168

161-
function weave(resolver, proxy, wire, options, add) {
169+
function weave(proxy, wire, options, wovenAspects) {
162170
// TODO: Refactor weaving to use proxy.invoke
163171

164172
var target, path, aspects, applyAdvice;
165173

166174
aspects = options.aspects;
167175
path = proxy.path;
168176

169-
if (!aspects || path === undef) {
170-
resolver.resolve();
177+
if (path === undef) {
171178
return;
172179
}
173180

174181
target = proxy.target;
175182
applyAdvice = applyAspectCombined;
176183

177184
// Reduce will preserve order of aspects being applied
178-
resolver.resolve(when.reduce(aspects, function(target, aspect) {
185+
return when.reduce(aspects, function(proxy, aspect) {
179186
var aspectPath;
180187

181188
if (aspect.advice) {
@@ -186,10 +193,10 @@ define(function(require) {
186193
}
187194

188195
return typeof aspectPath === 'string' && aspectPath !== path
189-
? applyAdvice(target, aspect, wire, add)
190-
: target;
196+
? applyAdvice(proxy, aspect, wire, wovenAspects)
197+
: proxy;
191198

192-
}, target));
199+
}, proxy);
193200
}
194201

195202
/**
@@ -199,67 +206,51 @@ define(function(require) {
199206
*/
200207
return function(options) {
201208

202-
// Track aspects so they can be removed when the context is destroyed
203-
var woven, plugin, i, len, adviceType;
204-
205-
woven = [];
206-
207-
/**
208-
* Function to add an aspect and remember it in the current context
209-
* so that it can be removed when the context is destroyed.
210-
* @param target
211-
* @param pointcut
212-
* @param aspect
213-
*/
214-
function add(target, pointcut, aspect) {
215-
woven.push(meld.add(target, pointcut, aspect));
216-
}
217-
218-
function makeFacet(step, callback) {
219-
var facet = {};
209+
var plugin, aspects, makeAdvice;
220210

221-
facet[step] = function(resolver, proxy, wire) {
222-
callback(resolver, proxy, wire);
223-
};
224-
225-
return facet;
226-
}
211+
aspects = [];
212+
makeAdvice = makeAdviceFacet.bind(null, aspects);
227213

228-
// Plugin
229214
plugin = {
230215
context: {
231216
destroy: function(resolver) {
232-
woven.forEach(function(aspect) {
233-
aspect.remove();
234-
});
217+
connection.removeAll(aspects);
235218
resolver.resolve();
236219
}
237220
},
238221
facets: {
239222
decorate: makeFacet('configure:after', decorateFacet),
240-
afterFulfilling: makeFacet(adviceStep, makeAdviceFacet(addAfterFulfillingAdvice, woven)),
241-
afterRejecting: makeFacet(adviceStep, makeAdviceFacet(addAfterRejectingAdvice, woven)),
242-
after: makeFacet(adviceStep, makeAdviceFacet(addAfterPromiseAdvice, woven))
223+
afterFulfilling: makeFacet(adviceStep, makeAdvice(addAfterFulfillingAdvice)),
224+
afterRejecting: makeFacet(adviceStep, makeAdvice(addAfterRejectingAdvice)),
225+
after: makeFacet(adviceStep, makeAdvice(addAfterPromiseAdvice))
243226
}
244227
};
245228

246229
if(options.aspects) {
247230
plugin.create = function(resolver, proxy, wire) {
248-
weave(resolver, proxy, wire, options, add);
231+
var woven = weave(proxy, wire, options, aspects);
232+
resolver.resolve(woven);
249233
};
250234
}
251235

252236
// Add all regular single advice facets
253-
for(i = 0, len = adviceTypes.length; i<len; i++) {
254-
adviceType = adviceTypes[i];
255-
plugin.facets[adviceType] = makeFacet(adviceStep, makeAdviceFacet(makeSingleAdviceAdd(adviceType), woven));
256-
}
237+
adviceTypes.forEach(function(adviceType) {
238+
plugin.facets[adviceType] = makeFacet(adviceStep,
239+
makeAdvice(makeSingleAdviceAdd(adviceType)));
240+
});
257241

258242
return plugin;
259-
};
243+
244+
function makeFacet(step, callback) {
245+
var facet = {};
246+
247+
facet[step] = function(resolver, proxy, wire) {
248+
callback(resolver, proxy, wire);
249+
};
250+
251+
return facet;
252+
}
253+
254+
};
260255
});
261-
})(typeof define == 'function'
262-
// use define for AMD if available
263-
? define
264-
: function(factory) { module.exports = factory(require); }
265-
);
256+
}(typeof define == 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));

connect.js

+19-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @license MIT License (c) copyright B Cavalier & J Hann */
1+
/** @license MIT License (c) copyright 2011-2013 original author or authors */
22

33
/**
44
* wire/connect plugin
@@ -38,41 +38,43 @@
3838
*
3939
* Licensed under the MIT License at:
4040
* http://www.opensource.org/licenses/mit-license.php
41+
*
42+
* @author Brian Cavalier
43+
* @author John Hann
4144
*/
4245

43-
(function(define) {
44-
define(['when', 'meld', './lib/functional', './lib/connection'],
45-
function(when, meld, functional, connection) {
46+
(function(define) { 'use strict';
47+
define(function(require) {
4648

47-
return function eventsPlugin(/* options */) {
49+
var all, connection;
4850

49-
var connectHandles = [];
51+
all = require('when').all;
52+
connection = require('./lib/connection');
5053

51-
function handleConnection(instance, methodName, handler) {
52-
connectHandles.push(meld.on(instance, methodName, handler));
53-
}
54+
return function connectPlugin(/* options */) {
55+
56+
var connections = [];
5457

55-
function doConnect(proxy, connect, options, wire) {
56-
return connection.parse(proxy, connect, options, wire, handleConnection);
58+
function makeConnection(sourceProxy, methodName, handler) {
59+
connections.push(sourceProxy.advise(methodName, { on: handler }));
5760
}
5861

5962
function connectFacet(wire, facet) {
6063
var promises, connects;
6164

6265
connects = facet.options;
6366
promises = Object.keys(connects).map(function(key) {
64-
return doConnect(facet, key, connects[key], wire);
67+
return connection.parse(
68+
facet, key, connects[key], wire, makeConnection);
6569
});
6670

67-
return when.all(promises);
71+
return all(promises);
6872
}
6973

7074
return {
7175
context: {
7276
destroy: function(resolver) {
73-
connectHandles.forEach(function(handle) {
74-
handle.remove();
75-
});
77+
connection.removeAll(connections);
7678
resolver.resolve();
7779
}
7880
},
@@ -88,12 +90,5 @@ function(when, meld, functional, connection) {
8890
};
8991
};
9092
});
91-
})(typeof define == 'function'
92-
? define
93-
: function(deps, factory) {
94-
module.exports = factory.apply(this, deps.map(function(x) {
95-
return require(x);
96-
}));
97-
}
98-
);
93+
}(typeof define == 'function' && define.amd ? define : function(factory) { module.exports = factory(require); }));
9994

dojo/events.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/** @license MIT License (c) copyright B Cavalier & J Hann */
1+
/** @license MIT License (c) copyright 2011-2013 original author or authors */
22

33
/**
44
* wire/dojo/events plugin
@@ -7,22 +7,25 @@
77
* This implementation uses dojo.connect and dojo.disconnect to do
88
* the work of connecting and disconnecting event handlers.
99
*
10-
* wire is part of the cujo.js family of libraries (http://cujojs.com/)
10+
* wire is part of the cujoJS family of libraries (http://cujojs.com/)
1111
*
1212
* Licensed under the MIT License at:
1313
* http://www.opensource.org/licenses/mit-license.php
14+
*
15+
* @author Brian Cavalier
16+
* @author John Hann
1417
*/
1518

1619
define(['when', '../lib/connection', 'dojo', 'dojo/_base/event'],
1720
function(when, connection, events) {
1821

1922
return {
20-
wire$plugin: function eventsPlugin(/*, options*/) {
23+
wire$plugin: function dojoEventsPlugin(/*, options*/) {
2124

2225
var connectHandles = [];
2326

24-
function handleConnection(source, eventName, handler) {
25-
connectHandles.push(events.connect(source, eventName, handler));
27+
function handleConnection(sourceProxy, eventName, handler) {
28+
connectHandles.push(events.connect(sourceProxy.target, eventName, handler));
2629
}
2730

2831
function connect(source, connect, options, wire) {

0 commit comments

Comments
 (0)