~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to gis/dhis-gis-geostat/mfbase/ext/source/util/Observable.js

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Ext JS Library 2.2
 
3
 * Copyright(c) 2006-2008, Ext JS, LLC.
 
4
 * licensing@extjs.com
 
5
 * 
 
6
 * http://extjs.com/license
 
7
 */
 
8
 
 
9
/**
 
10
 * @class Ext.util.Observable
 
11
 * Abstract base class that provides a common interface for publishing events. Subclasses are expected to
 
12
 * to have a property "events" with all the events defined.<br>
 
13
 * For example:
 
14
 * <pre><code>
 
15
 Employee = function(name){
 
16
    this.name = name;
 
17
    this.addEvents({
 
18
        "fired" : true,
 
19
        "quit" : true
 
20
    });
 
21
 }
 
22
 Ext.extend(Employee, Ext.util.Observable);
 
23
</code></pre>
 
24
 */
 
25
Ext.util.Observable = function(){
 
26
    /**
 
27
     * @cfg {Object} listeners A config object containing one or more event handlers to be added to this
 
28
     * object during initialization.  This should be a valid listeners config object as specified in the
 
29
     * {@link #addListener} example for attaching multiple handlers at once.
 
30
     */
 
31
    if(this.listeners){
 
32
        this.on(this.listeners);
 
33
        delete this.listeners;
 
34
    }
 
35
};
 
36
Ext.util.Observable.prototype = {
 
37
    /**
 
38
     * Fires the specified event with the passed parameters (minus the event name).
 
39
     * @param {String} eventName
 
40
     * @param {Object...} args Variable number of parameters are passed to handlers
 
41
     * @return {Boolean} returns false if any of the handlers return false otherwise it returns true
 
42
     */
 
43
    fireEvent : function(){
 
44
        if(this.eventsSuspended !== true){
 
45
            var ce = this.events[arguments[0].toLowerCase()];
 
46
            if(typeof ce == "object"){
 
47
                return ce.fire.apply(ce, Array.prototype.slice.call(arguments, 1));
 
48
            }
 
49
        }
 
50
        return true;
 
51
    },
 
52
 
 
53
    // private
 
54
    filterOptRe : /^(?:scope|delay|buffer|single)$/,
 
55
 
 
56
    /**
 
57
     * Appends an event handler to this component
 
58
     * @param {String}   eventName The type of event to listen for
 
59
     * @param {Function} handler The method the event invokes
 
60
     * @param {Object}   scope (optional) The scope in which to execute the handler
 
61
     * function. The handler function's "this" context.
 
62
     * @param {Object}   options (optional) An object containing handler configuration
 
63
     * properties. This may contain any of the following properties:<ul>
 
64
     * <li><b>scope</b> : Object<p class="sub-desc">The scope in which to execute the handler function. The handler function's "this" context.</p></li>
 
65
     * <li><b>delay</b> : Number<p class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</p></li>
 
66
     * <li><b>single</b> : Boolean<p class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</p></li>
 
67
     * <li><b>buffer</b> : Number<p class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
 
68
     * by the specified number of milliseconds. If the event fires again within that time, the original
 
69
     * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</p></li>
 
70
     * </ul><br>
 
71
     * <p>
 
72
     * <b>Combining Options</b><br>
 
73
     * Using the options argument, it is possible to combine different types of listeners:<br>
 
74
     * <br>
 
75
     * A normalized, delayed, one-time listener that auto stops the event and passes a custom argument (forumId)
 
76
     * <pre><code>
 
77
el.on('click', this.onClick, this, {
 
78
    single: true,
 
79
    delay: 100,
 
80
    forumId: 4
 
81
});</code></pre>
 
82
     * <p>
 
83
     * <b>Attaching multiple handlers in 1 call</b><br>
 
84
      * The method also allows for a single argument to be passed which is a config object containing properties
 
85
     * which specify multiple handlers.
 
86
     * <p>
 
87
     * <pre><code>
 
88
foo.on({
 
89
    'click' : {
 
90
        fn: this.onClick,
 
91
        scope: this,
 
92
        delay: 100
 
93
    },
 
94
    'mouseover' : {
 
95
        fn: this.onMouseOver,
 
96
        scope: this
 
97
    },
 
98
    'mouseout' : {
 
99
        fn: this.onMouseOut,
 
100
        scope: this
 
101
    }
 
102
});</code></pre>
 
103
     * <p>
 
104
     * Or a shorthand syntax:<br>
 
105
     * <pre><code>
 
106
foo.on({
 
107
    'click' : this.onClick,
 
108
    'mouseover' : this.onMouseOver,
 
109
    'mouseout' : this.onMouseOut,
 
110
     scope: this
 
111
});</code></pre>
 
112
     */
 
113
    addListener : function(eventName, fn, scope, o){
 
114
        if(typeof eventName == "object"){
 
115
            o = eventName;
 
116
            for(var e in o){
 
117
                if(this.filterOptRe.test(e)){
 
118
                    continue;
 
119
                }
 
120
                if(typeof o[e] == "function"){
 
121
                    // shared options
 
122
                    this.addListener(e, o[e], o.scope,  o);
 
123
                }else{
 
124
                    // individual options
 
125
                    this.addListener(e, o[e].fn, o[e].scope, o[e]);
 
126
                }
 
127
            }
 
128
            return;
 
129
        }
 
130
        o = (!o || typeof o == "boolean") ? {} : o;
 
131
        eventName = eventName.toLowerCase();
 
132
        var ce = this.events[eventName] || true;
 
133
        if(typeof ce == "boolean"){
 
134
            ce = new Ext.util.Event(this, eventName);
 
135
            this.events[eventName] = ce;
 
136
        }
 
137
        ce.addListener(fn, scope, o);
 
138
    },
 
139
 
 
140
    /**
 
141
     * Removes a listener
 
142
     * @param {String}   eventName     The type of event to listen for
 
143
     * @param {Function} handler        The handler to remove
 
144
     * @param {Object}   scope  (optional) The scope (this object) for the handler
 
145
     */
 
146
    removeListener : function(eventName, fn, scope){
 
147
        var ce = this.events[eventName.toLowerCase()];
 
148
        if(typeof ce == "object"){
 
149
            ce.removeListener(fn, scope);
 
150
        }
 
151
    },
 
152
 
 
153
    /**
 
154
     * Removes all listeners for this object
 
155
     */
 
156
    purgeListeners : function(){
 
157
        for(var evt in this.events){
 
158
            if(typeof this.events[evt] == "object"){
 
159
                 this.events[evt].clearListeners();
 
160
            }
 
161
        }
 
162
    },
 
163
 
 
164
    /**
 
165
     * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
 
166
     * @param {Object} o The Observable whose events this object is to relay.
 
167
     * @param {Array} events Array of event names to relay.
 
168
     */
 
169
    relayEvents : function(o, events){
 
170
        var createHandler = function(ename){
 
171
            return function(){
 
172
                return this.fireEvent.apply(this, Ext.combine(ename, Array.prototype.slice.call(arguments, 0)));
 
173
            };
 
174
        };
 
175
        for(var i = 0, len = events.length; i < len; i++){
 
176
            var ename = events[i];
 
177
            if(!this.events[ename]){ this.events[ename] = true; };
 
178
            o.on(ename, createHandler(ename), this);
 
179
        }
 
180
    },
 
181
 
 
182
    /**
 
183
     * Used to define events on this Observable
 
184
     * @param {Object} object The object with the events defined
 
185
     */
 
186
    addEvents : function(o){
 
187
        if(!this.events){
 
188
            this.events = {};
 
189
        }
 
190
        if(typeof o == 'string'){
 
191
            for(var i = 0, a = arguments, v; v = a[i]; i++){
 
192
                if(!this.events[a[i]]){
 
193
                    this.events[a[i]] = true;
 
194
                }
 
195
            }
 
196
        }else{
 
197
            Ext.applyIf(this.events, o);
 
198
        }
 
199
    },
 
200
 
 
201
    /**
 
202
     * Checks to see if this object has any listeners for a specified event
 
203
     * @param {String} eventName The name of the event to check for
 
204
     * @return {Boolean} True if the event is being listened for, else false
 
205
     */
 
206
    hasListener : function(eventName){
 
207
        var e = this.events[eventName];
 
208
        return typeof e == "object" && e.listeners.length > 0;
 
209
    },
 
210
 
 
211
    /**
 
212
     * Suspend the firing of all events. (see {@link #resumeEvents})
 
213
     */
 
214
    suspendEvents : function(){
 
215
        this.eventsSuspended = true;
 
216
    },
 
217
 
 
218
    /**
 
219
     * Resume firing events. (see {@link #suspendEvents})
 
220
     */
 
221
    resumeEvents : function(){
 
222
        this.eventsSuspended = false;
 
223
    },
 
224
 
 
225
    // these are considered experimental
 
226
    // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
 
227
    // private
 
228
    getMethodEvent : function(method){
 
229
        if(!this.methodEvents){
 
230
            this.methodEvents = {};
 
231
        }
 
232
        var e = this.methodEvents[method];
 
233
        if(!e){
 
234
            e = {};
 
235
            this.methodEvents[method] = e;
 
236
 
 
237
            e.originalFn = this[method];
 
238
            e.methodName = method;
 
239
            e.before = [];
 
240
            e.after = [];
 
241
 
 
242
 
 
243
            var returnValue, v, cancel;
 
244
            var obj = this;
 
245
 
 
246
            var makeCall = function(fn, scope, args){
 
247
                if((v = fn.apply(scope || obj, args)) !== undefined){
 
248
                    if(typeof v === 'object'){
 
249
                        if(v.returnValue !== undefined){
 
250
                            returnValue = v.returnValue;
 
251
                        }else{
 
252
                            returnValue = v;
 
253
                        }
 
254
                        if(v.cancel === true){
 
255
                            cancel = true;
 
256
                        }
 
257
                    }else if(v === false){
 
258
                        cancel = true;
 
259
                    }else {
 
260
                        returnValue = v;
 
261
                    }
 
262
                }
 
263
            }
 
264
 
 
265
            this[method] = function(){
 
266
                returnValue = v = undefined; cancel = false;
 
267
                var args = Array.prototype.slice.call(arguments, 0);
 
268
                for(var i = 0, len = e.before.length; i < len; i++){
 
269
                    makeCall(e.before[i].fn, e.before[i].scope, args);
 
270
                    if(cancel){
 
271
                        return returnValue;
 
272
                    }
 
273
                }
 
274
 
 
275
                if((v = e.originalFn.apply(obj, args)) !== undefined){
 
276
                    returnValue = v;
 
277
                }
 
278
 
 
279
                for(var i = 0, len = e.after.length; i < len; i++){
 
280
                    makeCall(e.after[i].fn, e.after[i].scope, args);
 
281
                    if(cancel){
 
282
                        return returnValue;
 
283
                    }
 
284
                }
 
285
                return returnValue;
 
286
            };
 
287
        }
 
288
        return e;
 
289
    },
 
290
 
 
291
    // adds an "interceptor" called before the original method
 
292
    beforeMethod : function(method, fn, scope){
 
293
        var e = this.getMethodEvent(method);
 
294
        e.before.push({fn: fn, scope: scope});
 
295
    },
 
296
 
 
297
    // adds a "sequence" called after the original method
 
298
    afterMethod : function(method, fn, scope){
 
299
        var e = this.getMethodEvent(method);
 
300
        e.after.push({fn: fn, scope: scope});
 
301
    },
 
302
 
 
303
    removeMethodListener : function(method, fn, scope){
 
304
        var e = this.getMethodEvent(method);
 
305
        for(var i = 0, len = e.before.length; i < len; i++){
 
306
            if(e.before[i].fn == fn && e.before[i].scope == scope){
 
307
                e.before.splice(i, 1);
 
308
                return;
 
309
            }
 
310
        }
 
311
        for(var i = 0, len = e.after.length; i < len; i++){
 
312
            if(e.after[i].fn == fn && e.after[i].scope == scope){
 
313
                e.after.splice(i, 1);
 
314
                return;
 
315
            }
 
316
        }
 
317
    }
 
318
};
 
319
/**
 
320
 * Appends an event handler to this element (shorthand for addListener)
 
321
 * @param {String}   eventName     The type of event to listen for
 
322
 * @param {Function} handler        The method the event invokes
 
323
 * @param {Object}   scope (optional) The scope in which to execute the handler
 
324
 * function. The handler function's "this" context.
 
325
 * @param {Object}   options  (optional)
 
326
 * @method
 
327
 */
 
328
Ext.util.Observable.prototype.on = Ext.util.Observable.prototype.addListener;
 
329
/**
 
330
 * Removes a listener (shorthand for removeListener)
 
331
 * @param {String}   eventName     The type of event to listen for
 
332
 * @param {Function} handler        The handler to remove
 
333
 * @param {Object}   scope  (optional) The scope (this object) for the handler
 
334
 * @method
 
335
 */
 
336
Ext.util.Observable.prototype.un = Ext.util.Observable.prototype.removeListener;
 
337
 
 
338
/**
 
339
 * Starts capture on the specified Observable. All events will be passed
 
340
 * to the supplied function with the event name + standard signature of the event
 
341
 * <b>before</b> the event is fired. If the supplied function returns false,
 
342
 * the event will not fire.
 
343
 * @param {Observable} o The Observable to capture
 
344
 * @param {Function} fn The function to call
 
345
 * @param {Object} scope (optional) The scope (this object) for the fn
 
346
 * @static
 
347
 */
 
348
Ext.util.Observable.capture = function(o, fn, scope){
 
349
    o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
 
350
};
 
351
 
 
352
/**
 
353
 * Removes <b>all</b> added captures from the Observable.
 
354
 * @param {Observable} o The Observable to release
 
355
 * @static
 
356
 */
 
357
Ext.util.Observable.releaseCapture = function(o){
 
358
    o.fireEvent = Ext.util.Observable.prototype.fireEvent;
 
359
};
 
360
 
 
361
(function(){
 
362
 
 
363
    var createBuffered = function(h, o, scope){
 
364
        var task = new Ext.util.DelayedTask();
 
365
        return function(){
 
366
            task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
 
367
        };
 
368
    };
 
369
 
 
370
    var createSingle = function(h, e, fn, scope){
 
371
        return function(){
 
372
            e.removeListener(fn, scope);
 
373
            return h.apply(scope, arguments);
 
374
        };
 
375
    };
 
376
 
 
377
    var createDelayed = function(h, o, scope){
 
378
        return function(){
 
379
            var args = Array.prototype.slice.call(arguments, 0);
 
380
            setTimeout(function(){
 
381
                h.apply(scope, args);
 
382
            }, o.delay || 10);
 
383
        };
 
384
    };
 
385
 
 
386
    Ext.util.Event = function(obj, name){
 
387
        this.name = name;
 
388
        this.obj = obj;
 
389
        this.listeners = [];
 
390
    };
 
391
 
 
392
    Ext.util.Event.prototype = {
 
393
        addListener : function(fn, scope, options){
 
394
            scope = scope || this.obj;
 
395
            if(!this.isListening(fn, scope)){
 
396
                var l = this.createListener(fn, scope, options);
 
397
                if(!this.firing){
 
398
                    this.listeners.push(l);
 
399
                }else{ // if we are currently firing this event, don't disturb the listener loop
 
400
                    this.listeners = this.listeners.slice(0);
 
401
                    this.listeners.push(l);
 
402
                }
 
403
            }
 
404
        },
 
405
 
 
406
        createListener : function(fn, scope, o){
 
407
            o = o || {};
 
408
            scope = scope || this.obj;
 
409
            var l = {fn: fn, scope: scope, options: o};
 
410
            var h = fn;
 
411
            if(o.delay){
 
412
                h = createDelayed(h, o, scope);
 
413
            }
 
414
            if(o.single){
 
415
                h = createSingle(h, this, fn, scope);
 
416
            }
 
417
            if(o.buffer){
 
418
                h = createBuffered(h, o, scope);
 
419
            }
 
420
            l.fireFn = h;
 
421
            return l;
 
422
        },
 
423
 
 
424
        findListener : function(fn, scope){
 
425
            scope = scope || this.obj;
 
426
            var ls = this.listeners;
 
427
            for(var i = 0, len = ls.length; i < len; i++){
 
428
                var l = ls[i];
 
429
                if(l.fn == fn && l.scope == scope){
 
430
                    return i;
 
431
                }
 
432
            }
 
433
            return -1;
 
434
        },
 
435
 
 
436
        isListening : function(fn, scope){
 
437
            return this.findListener(fn, scope) != -1;
 
438
        },
 
439
 
 
440
        removeListener : function(fn, scope){
 
441
            var index;
 
442
            if((index = this.findListener(fn, scope)) != -1){
 
443
                if(!this.firing){
 
444
                    this.listeners.splice(index, 1);
 
445
                }else{
 
446
                    this.listeners = this.listeners.slice(0);
 
447
                    this.listeners.splice(index, 1);
 
448
                }
 
449
                return true;
 
450
            }
 
451
            return false;
 
452
        },
 
453
 
 
454
        clearListeners : function(){
 
455
            this.listeners = [];
 
456
        },
 
457
 
 
458
        fire : function(){
 
459
            var ls = this.listeners, scope, len = ls.length;
 
460
            if(len > 0){
 
461
                this.firing = true;
 
462
                var args = Array.prototype.slice.call(arguments, 0);
 
463
                for(var i = 0; i < len; i++){
 
464
                    var l = ls[i];
 
465
                    if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
 
466
                        this.firing = false;
 
467
                        return false;
 
468
                    }
 
469
                }
 
470
                this.firing = false;
 
471
            }
 
472
            return true;
 
473
        }
 
474
    };
 
475
})();
 
 
b'\\ No newline at end of file'