123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- define("dojo/aspect", [], function(){
- "use strict";
- var nextId = 0;
- function advise(dispatcher, type, advice, receiveArguments){
- var previous = dispatcher[type];
- var around = type == "around";
- var signal;
- if(around){
- var advised = advice(function(){
- return previous.advice(this, arguments);
- });
- signal = {
- remove: function(){
- if(advised){
- advised = dispatcher = advice = null;
- }
- },
- advice: function(target, args){
- return advised ?
- advised.apply(target, args) :
- previous.advice(target, args);
- }
- };
- }else{
-
- signal = {
- remove: function(){
- if(signal.advice){
- var previous = signal.previous;
- var next = signal.next;
- if(!next && !previous){
- delete dispatcher[type];
- }else{
- if(previous){
- previous.next = next;
- }else{
- dispatcher[type] = next;
- }
- if(next){
- next.previous = previous;
- }
- }
-
- dispatcher = advice = signal.advice = null;
- }
- },
- id: nextId++,
- advice: advice,
- receiveArguments: receiveArguments
- };
- }
- if(previous && !around){
- if(type == "after"){
-
-
- while(previous.next && (previous = previous.next)){}
- previous.next = signal;
- signal.previous = previous;
- }else if(type == "before"){
-
- dispatcher[type] = signal;
- signal.next = previous;
- previous.previous = signal;
- }
- }else{
-
- dispatcher[type] = signal;
- }
- return signal;
- }
- function aspect(type){
- return function(target, methodName, advice, receiveArguments){
- var existing = target[methodName], dispatcher;
- if(!existing || existing.target != target){
-
- target[methodName] = dispatcher = function(){
- var executionId = nextId;
-
- var args = arguments;
- var before = dispatcher.before;
- while(before){
- args = before.advice.apply(this, args) || args;
- before = before.next;
- }
-
- if(dispatcher.around){
- var results = dispatcher.around.advice(this, args);
- }
-
- var after = dispatcher.after;
- while(after && after.id < executionId){
- results = after.receiveArguments ? after.advice.apply(this, args) || results :
- after.advice.call(this, results);
- after = after.next;
- }
- return results;
- };
- if(existing){
- dispatcher.around = {advice: function(target, args){
- return existing.apply(target, args);
- }};
- }
- dispatcher.target = target;
- }
- var results = advise((dispatcher || existing), type, advice, receiveArguments);
- advice = null;
- return results;
- };
- }
- return {
- before: aspect("before"),
- around: aspect("around"),
- after: aspect("after")
- };
- });
|