~ubuntu-branches/ubuntu/natty/ntop/natty

« back to all changes in this revision

Viewing changes to html/MochiKit/Signal.js

  • Committer: Bazaar Package Importer
  • Author(s): Ludovico Cavedon, Jordan Metzmeier, Ludovico Cavedon
  • Date: 2010-12-15 20:06:19 UTC
  • mfrom: (5.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101215200619-0ojz3iak95ihibun
Tags: 3:4.0.3+dfsg1-1
[ Jordan Metzmeier ]
* New upstream release (Closes: #522042)
* Move data files to /usr/share/ntop (Closes: #595450).
* Package architecture independent data in a separate ntop-data package.
* Use debhelper 7.
* Update Standards-Version to 3.9.1.
* Depend on python-mako.
* Do not include ntop.txt in binary packages as it is a copy of the man
  page.
* Do not include NEWS, as it is outdated.
* Switch to package source version 3.0 (quilt).
* Add password creation to debconf
* Changed init script to fix localization problems (thanks to Alejandro
  Varas <alej0varas@gmail.com>, LP: #257466)
* Remove manual update-rc.d calls from postrm and postinst. debhelper adds
  this for us.
* Add pre-depends on adduser for postinst script.
* Fix errors in the manpages: fix-manpage-errors.patch.
* Added fixes for matching active interfaces.
* Added a watch file.

[ Ludovico Cavedon ]
* Remove direct changes to upstream tree, and move them into specific patch
  files:
  - fix-manpage-errors.patch: fix typos in ntop.8.
  - dot-path.patch: fix path of /usr/bin/dot executable
* Add patches:
  - reduce-autogen-purged-files.patch: prevent agutogen.sh from reamoving
  too many files during cleanup.
  - Add build-without-ntop-darwin.patch, to fix compilation without
  ntop_darwin.c.
* No longer add faq.html, as it is not distributed in the upstream tarball.
* Use ${source:Version} in control file. Have ntop-data recommend
  ntop.
* Rename dirs to ntop.dirs and keep only empty directories that need
  to be created.
* Remove var/lib from ntop.install file, as it is empty (keeping it in
  ntop.dirs).
* Update po files.
* Breaks and Replaces instead of Conflitcs for ntop-data.
* Use a longer package description.
* Remove useless configure options from debian/rules.
* Move private shared libraries libraries in /usr/lib/ntop.
* Add change-plugin-dir.patch for adjusting plugin directory.
* Remove development files.
* Use system library for MochiKit.js.
* Rewrite DEP5 copyright file.
* Repackage upstream tarball in order to remove non-DFSG-compliant code. Add
  get-orig-source.sh script and get-orig-source target in debian/rules.
* Add explanation to README.Debian why geolocation is no longer working.
* Add avoid-copy-maxmind-db.patch to prevent copying of Geo*.dat
  files.
* Remove old unused patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***
2
2
 
3
 
MochiKit.Signal 1.3.1
 
3
MochiKit.Signal 1.4.2
4
4
 
5
5
See <http://mochikit.com/> for documentation, downloads, license, etc.
6
6
 
8
8
 
9
9
***/
10
10
 
11
 
if (typeof(dojo) != 'undefined') {
12
 
    dojo.provide('MochiKit.Signal');
13
 
    dojo.require('MochiKit.Base');
14
 
    dojo.require('MochiKit.DOM');
15
 
}
16
 
if (typeof(JSAN) != 'undefined') {
17
 
    JSAN.use('MochiKit.Base', []);
18
 
    JSAN.use('MochiKit.DOM', []);
19
 
}
20
 
 
21
 
try {
22
 
    if (typeof(MochiKit.Base) == 'undefined') {
23
 
        throw '';
24
 
    }
25
 
} catch (e) {
26
 
    throw 'MochiKit.Signal depends on MochiKit.Base!';
27
 
}
28
 
 
29
 
try {
30
 
    if (typeof(MochiKit.DOM) == 'undefined') {
31
 
        throw '';
32
 
    }
33
 
} catch (e) {
34
 
    throw 'MochiKit.Signal depends on MochiKit.DOM!';
35
 
}
36
 
 
37
 
if (typeof(MochiKit.Signal) == 'undefined') {
38
 
    MochiKit.Signal = {};
39
 
}
 
11
MochiKit.Base._deps('Signal', ['Base', 'DOM', 'Style']);
40
12
 
41
13
MochiKit.Signal.NAME = 'MochiKit.Signal';
42
 
MochiKit.Signal.VERSION = '1.3.1';
 
14
MochiKit.Signal.VERSION = '1.4.2';
43
15
 
44
16
MochiKit.Signal._observers = [];
45
17
 
 
18
/** @id MochiKit.Signal.Event */
46
19
MochiKit.Signal.Event = function (src, e) {
47
20
    this._event = e || window.event;
48
21
    this._src = src;
50
23
 
51
24
MochiKit.Base.update(MochiKit.Signal.Event.prototype, {
52
25
 
53
 
    __repr__: function() {
 
26
    __repr__: function () {
54
27
        var repr = MochiKit.Base.repr;
55
28
        var str = '{event(): ' + repr(this.event()) +
56
 
            ', src(): ' + repr(this.src()) + 
 
29
            ', src(): ' + repr(this.src()) +
57
30
            ', type(): ' + repr(this.type()) +
58
 
            ', target(): ' + repr(this.target()) +
59
 
            ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) +
 
31
            ', target(): ' + repr(this.target());
 
32
 
 
33
        if (this.type() &&
 
34
            this.type().indexOf('key') === 0 ||
 
35
            this.type().indexOf('mouse') === 0 ||
 
36
            this.type().indexOf('click') != -1 ||
 
37
            this.type() == 'contextmenu') {
 
38
            str += ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) +
60
39
            ', ctrl: ' + repr(this.modifier().ctrl) +
61
40
            ', meta: ' + repr(this.modifier().meta) +
62
 
            ', shift: ' + repr(this.modifier().shift) + 
 
41
            ', shift: ' + repr(this.modifier().shift) +
63
42
            ', any: ' + repr(this.modifier().any) + '}';
64
 
        
 
43
        }
 
44
 
65
45
        if (this.type() && this.type().indexOf('key') === 0) {
66
46
            str += ', key(): {code: ' + repr(this.key().code) +
67
47
                ', string: ' + repr(this.key().string) + '}';
75
55
            str += ', mouse(): {page: ' + repr(this.mouse().page) +
76
56
                ', client: ' + repr(this.mouse().client);
77
57
 
78
 
            if (this.type() != 'mousemove') {
 
58
            if (this.type() != 'mousemove' && this.type() != 'mousewheel') {
79
59
                str += ', button: {left: ' + repr(this.mouse().button.left) +
80
60
                    ', middle: ' + repr(this.mouse().button.middle) +
81
 
                    ', right: ' + repr(this.mouse().button.right) + '}}';
82
 
            } else {
83
 
                str += '}';
84
 
            }
 
61
                    ', right: ' + repr(this.mouse().button.right) + '}';
 
62
            }
 
63
            if (this.type() == 'mousewheel') {
 
64
                str += ', wheel: ' + repr(this.mouse().wheel);
 
65
            }
 
66
            str += '}';
85
67
        }
86
 
        if (this.type() == 'mouseover' || this.type() == 'mouseout') {
 
68
        if (this.type() == 'mouseover' || this.type() == 'mouseout' || 
 
69
            this.type() == 'mouseenter' || this.type() == 'mouseleave') {
87
70
            str += ', relatedTarget(): ' + repr(this.relatedTarget());
88
71
        }
89
72
        str += '}';
90
73
        return str;
91
74
    },
92
75
 
 
76
     /** @id MochiKit.Signal.Event.prototype.toString */
93
77
    toString: function () {
94
78
        return this.__repr__();
95
79
    },
96
80
 
 
81
    /** @id MochiKit.Signal.Event.prototype.src */
97
82
    src: function () {
98
83
        return this._src;
99
84
    },
100
85
 
 
86
    /** @id MochiKit.Signal.Event.prototype.event  */
101
87
    event: function () {
102
88
        return this._event;
103
89
    },
104
90
 
 
91
    /** @id MochiKit.Signal.Event.prototype.type */
105
92
    type: function () {
106
 
        return this._event.type || undefined;
 
93
        if (this._event.type === "DOMMouseScroll") {
 
94
            return "mousewheel";
 
95
        } else {
 
96
            return this._event.type || undefined;
 
97
        }
107
98
    },
108
99
 
 
100
    /** @id MochiKit.Signal.Event.prototype.target */
109
101
    target: function () {
110
102
        return this._event.target || this._event.srcElement;
111
103
    },
112
104
 
 
105
    _relatedTarget: null,
 
106
    /** @id MochiKit.Signal.Event.prototype.relatedTarget */
113
107
    relatedTarget: function () {
114
 
        if (this.type() == 'mouseover') {
115
 
            return (this._event.relatedTarget ||
 
108
        if (this._relatedTarget !== null) {
 
109
            return this._relatedTarget;
 
110
        }
 
111
 
 
112
        var elem = null;
 
113
        if (this.type() == 'mouseover' || this.type() == 'mouseenter') {
 
114
            elem = (this._event.relatedTarget ||
116
115
                this._event.fromElement);
117
 
        } else if (this.type() == 'mouseout') {
118
 
            return (this._event.relatedTarget ||
 
116
        } else if (this.type() == 'mouseout' || this.type() == 'mouseleave') {
 
117
            elem = (this._event.relatedTarget ||
119
118
                this._event.toElement);
120
119
        }
121
 
        // throw new Error("relatedTarget only available for 'mouseover' and 'mouseout'");
 
120
        try {
 
121
            if (elem !== null && elem.nodeType !== null) {
 
122
                this._relatedTarget = elem;
 
123
                return elem;
 
124
            }
 
125
        } catch (ignore) {
 
126
            // Firefox 3 throws a permission denied error when accessing
 
127
            // any property on XUL elements (e.g. scrollbars)...
 
128
        }
 
129
 
122
130
        return undefined;
123
131
    },
124
132
 
 
133
    _modifier: null,
 
134
    /** @id MochiKit.Signal.Event.prototype.modifier */
125
135
    modifier: function () {
 
136
        if (this._modifier !== null) {
 
137
            return this._modifier;
 
138
        }
126
139
        var m = {};
127
140
        m.alt = this._event.altKey;
128
141
        m.ctrl = this._event.ctrlKey;
129
142
        m.meta = this._event.metaKey || false; // IE and Opera punt here
130
143
        m.shift = this._event.shiftKey;
131
144
        m.any = m.alt || m.ctrl || m.shift || m.meta;
 
145
        this._modifier = m;
132
146
        return m;
133
147
    },
134
148
 
 
149
    _key: null,
 
150
    /** @id MochiKit.Signal.Event.prototype.key */
135
151
    key: function () {
 
152
        if (this._key !== null) {
 
153
            return this._key;
 
154
        }
136
155
        var k = {};
137
156
        if (this.type() && this.type().indexOf('key') === 0) {
138
157
 
139
158
            /*
140
159
 
141
 
                        If you're looking for a special key, look for it in keydown or
 
160
                If you're looking for a special key, look for it in keydown or
142
161
                keyup, but never keypress. If you're looking for a Unicode
143
162
                chracter, look for it with keypress, but never keyup or
144
163
                keydown.
145
 
        
146
 
                        Notes:
147
 
        
148
 
                        FF key event behavior:
149
 
                        key     event   charCode    keyCode
150
 
                        DOWN    ku,kd   0           40
151
 
                        DOWN    kp      0           40
152
 
                        ESC     ku,kd   0           27
153
 
                        ESC     kp      0           27
154
 
                        a       ku,kd   0           65
155
 
                        a       kp      97          0
156
 
                        shift+a ku,kd   0           65
157
 
                        shift+a kp      65          0
158
 
                        1       ku,kd   0           49
159
 
                        1       kp      49          0
160
 
                        shift+1 ku,kd   0           0
161
 
                        shift+1 kp      33          0
162
 
        
163
 
                        IE key event behavior:
164
 
                        (IE doesn't fire keypress events for special keys.)
165
 
                        key     event   keyCode
166
 
                        DOWN    ku,kd   40
167
 
                        DOWN    kp      undefined
168
 
                        ESC     ku,kd   27
169
 
                        ESC     kp      27
170
 
                        a       ku,kd   65
171
 
                        a       kp      97
172
 
                        shift+a ku,kd   65
173
 
                        shift+a kp      65
174
 
                        1       ku,kd   49
175
 
                        1       kp      49
176
 
                        shift+1 ku,kd   49
177
 
                        shift+1 kp      33
178
 
 
179
 
                        Safari key event behavior:
180
 
                        (Safari sets charCode and keyCode to something crazy for
181
 
                        special keys.)
182
 
                        key     event   charCode    keyCode
183
 
                        DOWN    ku,kd   63233       40
184
 
                        DOWN    kp      63233       63233
185
 
                        ESC     ku,kd   27          27
186
 
                        ESC     kp      27          27
187
 
                        a       ku,kd   97          65
188
 
                        a       kp      97          97
189
 
                        shift+a ku,kd   65          65
190
 
                        shift+a kp      65          65
191
 
                        1       ku,kd   49          49
192
 
                        1       kp      49          49
193
 
                        shift+1 ku,kd   33          49
194
 
                        shift+1 kp      33          33
 
164
 
 
165
                Notes:
 
166
 
 
167
                FF key event behavior:
 
168
                key     event   charCode    keyCode
 
169
                DOWN    ku,kd   0           40
 
170
                DOWN    kp      0           40
 
171
                ESC     ku,kd   0           27
 
172
                ESC     kp      0           27
 
173
                a       ku,kd   0           65
 
174
                a       kp      97          0
 
175
                shift+a ku,kd   0           65
 
176
                shift+a kp      65          0
 
177
                1       ku,kd   0           49
 
178
                1       kp      49          0
 
179
                shift+1 ku,kd   0           0
 
180
                shift+1 kp      33          0
 
181
 
 
182
                IE key event behavior:
 
183
                (IE doesn't fire keypress events for special keys.)
 
184
                key     event   keyCode
 
185
                DOWN    ku,kd   40
 
186
                DOWN    kp      undefined
 
187
                ESC     ku,kd   27
 
188
                ESC     kp      27
 
189
                a       ku,kd   65
 
190
                a       kp      97
 
191
                shift+a ku,kd   65
 
192
                shift+a kp      65
 
193
                1       ku,kd   49
 
194
                1       kp      49
 
195
                shift+1 ku,kd   49
 
196
                shift+1 kp      33
 
197
 
 
198
                Safari key event behavior:
 
199
                (Safari sets charCode and keyCode to something crazy for
 
200
                special keys.)
 
201
                key     event   charCode    keyCode
 
202
                DOWN    ku,kd   63233       40
 
203
                DOWN    kp      63233       63233
 
204
                ESC     ku,kd   27          27
 
205
                ESC     kp      27          27
 
206
                a       ku,kd   97          65
 
207
                a       kp      97          97
 
208
                shift+a ku,kd   65          65
 
209
                shift+a kp      65          65
 
210
                1       ku,kd   49          49
 
211
                1       kp      49          49
 
212
                shift+1 ku,kd   33          49
 
213
                shift+1 kp      33          33
195
214
 
196
215
            */
197
216
 
200
219
                k.code = this._event.keyCode;
201
220
                k.string = (MochiKit.Signal._specialKeys[k.code] ||
202
221
                    'KEY_UNKNOWN');
 
222
                this._key = k;
203
223
                return k;
204
 
        
 
224
 
205
225
            /* look for characters here */
206
226
            } else if (this.type() == 'keypress') {
207
 
            
 
227
 
208
228
                /*
209
 
            
 
229
 
210
230
                    Special key behavior:
211
 
                
 
231
 
212
232
                    IE: does not fire keypress events for special keys
213
233
                    FF: sets charCode to 0, and sets the correct keyCode
214
234
                    Safari: sets keyCode and charCode to something stupid
215
 
            
 
235
 
216
236
                */
217
 
            
 
237
 
218
238
                k.code = 0;
219
239
                k.string = '';
220
 
                        
221
 
                if (typeof(this._event.charCode) != 'undefined' && 
 
240
 
 
241
                if (typeof(this._event.charCode) != 'undefined' &&
222
242
                    this._event.charCode !== 0 &&
223
243
                    !MochiKit.Signal._specialMacKeys[this._event.charCode]) {
224
244
                    k.code = this._event.charCode;
225
245
                    k.string = String.fromCharCode(k.code);
226
 
                } else if (this._event.keyCode && 
 
246
                } else if (this._event.keyCode &&
227
247
                    typeof(this._event.charCode) == 'undefined') { // IE
228
248
                    k.code = this._event.keyCode;
229
249
                    k.string = String.fromCharCode(k.code);
230
250
                }
231
 
            
 
251
 
 
252
                this._key = k;
232
253
                return k;
233
254
            }
234
255
        }
235
 
        // throw new Error('This is not a key event');
236
256
        return undefined;
237
257
    },
238
258
 
 
259
    _mouse: null,
 
260
    /** @id MochiKit.Signal.Event.prototype.mouse */
239
261
    mouse: function () {
 
262
        if (this._mouse !== null) {
 
263
            return this._mouse;
 
264
        }
 
265
 
240
266
        var m = {};
241
267
        var e = this._event;
242
 
        
 
268
 
243
269
        if (this.type() && (
244
270
            this.type().indexOf('mouse') === 0 ||
245
271
            this.type().indexOf('click') != -1 ||
246
272
            this.type() == 'contextmenu')) {
247
 
            
248
 
            m.client = new MochiKit.DOM.Coordinates(0, 0);
 
273
 
 
274
            m.client = new MochiKit.Style.Coordinates(0, 0);
249
275
            if (e.clientX || e.clientY) {
250
276
                m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX;
251
277
                m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY;
252
278
            }
253
279
 
254
 
            m.page = new MochiKit.DOM.Coordinates(0, 0);
 
280
            m.page = new MochiKit.Style.Coordinates(0, 0);
255
281
            if (e.pageX || e.pageY) {
256
282
                m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
257
283
                m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
258
284
            } else {
259
285
                /*
260
 
            
261
 
                                IE keeps the document offset in:
262
 
                                        document.documentElement.clientTop ||
263
 
                                        document.body.clientTop
264
 
                                
265
 
                                and:
266
 
                                        document.documentElement.clientLeft ||
267
 
                                        document.body.clientLeft
268
 
 
269
 
                    see:
270
 
                                http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
271
 
 
272
 
                                The offset is (2,2) in standards mode and (0,0) in quirks 
273
 
                                mode.
274
 
                                
 
286
 
 
287
                    The IE shortcut can be off by two. We fix it. See:
 
288
                    http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
 
289
 
 
290
                    This is similar to the method used in
 
291
                    MochiKit.Style.getElementPosition().
 
292
 
275
293
                */
276
 
            
277
294
                var de = MochiKit.DOM._document.documentElement;
278
295
                var b = MochiKit.DOM._document.body;
279
 
            
 
296
 
280
297
                m.page.x = e.clientX +
281
 
                    (de.scrollLeft || b.scrollLeft) - 
282
 
                    (de.clientLeft || b.clientLeft);
283
 
            
 
298
                    (de.scrollLeft || b.scrollLeft) -
 
299
                    (de.clientLeft || 0);
 
300
 
284
301
                m.page.y = e.clientY +
285
 
                    (de.scrollTop || b.scrollTop) - 
286
 
                    (de.clientTop || b.clientTop);
287
 
            
 
302
                    (de.scrollTop || b.scrollTop) -
 
303
                    (de.clientTop || 0);
 
304
 
288
305
            }
289
 
            if (this.type() != 'mousemove') {
 
306
            if (this.type() != 'mousemove' && this.type() != 'mousewheel') {
290
307
                m.button = {};
291
308
                m.button.left = false;
292
309
                m.button.right = false;
299
316
                    m.button.right = (e.which == 3);
300
317
 
301
318
                    /*
302
 
                
303
 
                                        Mac browsers and right click:
304
 
                                        
305
 
                                                - Safari doesn't fire any click events on a right
306
 
                                                  click:
307
 
                                                  http://bugzilla.opendarwin.org/show_bug.cgi?id=6595
308
 
                                                  
309
 
                                                - Firefox fires the event, and sets ctrlKey = true
310
 
                                                  
311
 
                                                - Opera fires the event, and sets metaKey = true
312
 
                                        
313
 
                                        oncontextmenu is fired on right clicks between 
314
 
                                        browsers and across platforms.
315
 
                                        
 
319
 
 
320
                        Mac browsers and right click:
 
321
 
 
322
                            - Safari doesn't fire any click events on a right
 
323
                              click:
 
324
                              http://bugs.webkit.org/show_bug.cgi?id=6595
 
325
 
 
326
                            - Firefox fires the event, and sets ctrlKey = true
 
327
 
 
328
                            - Opera fires the event, and sets metaKey = true
 
329
 
 
330
                        oncontextmenu is fired on right clicks between
 
331
                        browsers and across platforms.
 
332
 
316
333
                    */
317
 
                
 
334
 
318
335
                } else {
319
336
                    m.button.left = !!(e.button & 1);
320
337
                    m.button.right = !!(e.button & 2);
321
338
                    m.button.middle = !!(e.button & 4);
322
339
                }
323
340
            }
 
341
            if (this.type() == 'mousewheel') {
 
342
                m.wheel = new MochiKit.Style.Coordinates(0, 0);
 
343
                if (e.wheelDeltaX || e.wheelDeltaY) {
 
344
                    m.wheel.x = e.wheelDeltaX / -40 || 0;
 
345
                    m.wheel.y = e.wheelDeltaY / -40 || 0;
 
346
                } else if (e.wheelDelta) {
 
347
                    m.wheel.y = e.wheelDelta / -40;
 
348
                } else {
 
349
                    m.wheel.y = e.detail || 0;
 
350
                }
 
351
            }
 
352
            this._mouse = m;
324
353
            return m;
325
354
        }
326
 
        // throw new Error('This is not a mouse event');
327
355
        return undefined;
328
356
    },
329
357
 
 
358
    /** @id MochiKit.Signal.Event.prototype.stop */
330
359
    stop: function () {
331
360
        this.stopPropagation();
332
361
        this.preventDefault();
333
362
    },
334
363
 
 
364
    /** @id MochiKit.Signal.Event.prototype.stopPropagation */
335
365
    stopPropagation: function () {
336
366
        if (this._event.stopPropagation) {
337
367
            this._event.stopPropagation();
340
370
        }
341
371
    },
342
372
 
 
373
    /** @id MochiKit.Signal.Event.prototype.preventDefault */
343
374
    preventDefault: function () {
344
375
        if (this._event.preventDefault) {
345
376
            this._event.preventDefault();
346
 
        } else {
 
377
        } else if (this._confirmUnload === null) {
347
378
            this._event.returnValue = false;
348
379
        }
 
380
    },
 
381
 
 
382
    _confirmUnload: null,
 
383
 
 
384
    /** @id MochiKit.Signal.Event.prototype.confirmUnload */
 
385
    confirmUnload: function (msg) {
 
386
        if (this.type() == 'beforeunload') {
 
387
            this._confirmUnload = msg;
 
388
            this._event.returnValue = msg;
 
389
        }
349
390
    }
350
 
 
351
391
});
352
392
 
353
393
/* Safari sets keyCode to these special values onkeypress. */
367
407
};
368
408
 
369
409
/* for KEY_F1 - KEY_F12 */
370
 
for (i = 63236; i <= 63242; i++) {
371
 
    MochiKit.Signal._specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1); // no F0
372
 
}
 
410
(function () {
 
411
    var _specialMacKeys = MochiKit.Signal._specialMacKeys;
 
412
    for (i = 63236; i <= 63242; i++) {
 
413
        // no F0
 
414
        _specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1);
 
415
    }
 
416
})();
373
417
 
374
418
/* Standard keyboard key codes. */
375
419
MochiKit.Signal._specialKeys = {
392
436
    38: 'KEY_ARROW_UP',
393
437
    39: 'KEY_ARROW_RIGHT',
394
438
    40: 'KEY_ARROW_DOWN',
395
 
    44: 'KEY_PRINT_SCREEN', 
 
439
    44: 'KEY_PRINT_SCREEN',
396
440
    45: 'KEY_INSERT',
397
441
    46: 'KEY_DELETE',
398
442
    59: 'KEY_SEMICOLON', // weird, for Safari and IE only
399
 
    91: 'KEY_WINDOWS_LEFT', 
400
 
    92: 'KEY_WINDOWS_RIGHT', 
401
 
    93: 'KEY_SELECT', 
 
443
    91: 'KEY_WINDOWS_LEFT',
 
444
    92: 'KEY_WINDOWS_RIGHT',
 
445
    93: 'KEY_SELECT',
402
446
    106: 'KEY_NUM_PAD_ASTERISK',
403
447
    107: 'KEY_NUM_PAD_PLUS_SIGN',
404
448
    109: 'KEY_NUM_PAD_HYPHEN-MINUS',
420
464
    // undefined: 'KEY_UNKNOWN'
421
465
};
422
466
 
423
 
/* for KEY_0 - KEY_9 */
424
 
for (var i = 48; i <= 57; i++) {
425
 
    MochiKit.Signal._specialKeys[i] = 'KEY_' + (i - 48);
426
 
}
427
 
 
428
 
/* for KEY_A - KEY_Z */
429
 
for (i = 65; i <= 90; i++) {
430
 
    MochiKit.Signal._specialKeys[i] = 'KEY_' + String.fromCharCode(i);
431
 
}
432
 
 
433
 
/* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
434
 
for (i = 96; i <= 105; i++) {
435
 
    MochiKit.Signal._specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
436
 
}
437
 
 
438
 
/* for KEY_F1 - KEY_F12 */
439
 
for (i = 112; i <= 123; i++) {
440
 
    MochiKit.Signal._specialKeys[i] = 'KEY_F' + (i - 112 + 1); // no F0
441
 
}
 
467
(function () {
 
468
    /* for KEY_0 - KEY_9 */
 
469
    var _specialKeys = MochiKit.Signal._specialKeys;
 
470
    for (var i = 48; i <= 57; i++) {
 
471
        _specialKeys[i] = 'KEY_' + (i - 48);
 
472
    }
 
473
 
 
474
    /* for KEY_A - KEY_Z */
 
475
    for (i = 65; i <= 90; i++) {
 
476
        _specialKeys[i] = 'KEY_' + String.fromCharCode(i);
 
477
    }
 
478
 
 
479
    /* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
 
480
    for (i = 96; i <= 105; i++) {
 
481
        _specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
 
482
    }
 
483
 
 
484
    /* for KEY_F1 - KEY_F12 */
 
485
    for (i = 112; i <= 123; i++) {
 
486
        // no F0
 
487
        _specialKeys[i] = 'KEY_F' + (i - 112 + 1);
 
488
    }
 
489
})();
 
490
 
 
491
/* Internal object to keep track of created signals. */
 
492
MochiKit.Signal.Ident = function (ident) {
 
493
    this.source = ident.source;
 
494
    this.signal = ident.signal;
 
495
    this.listener = ident.listener;
 
496
    this.isDOM = ident.isDOM;
 
497
    this.objOrFunc = ident.objOrFunc;
 
498
    this.funcOrStr = ident.funcOrStr;
 
499
    this.connected = ident.connected;
 
500
};
 
501
 
 
502
MochiKit.Signal.Ident.prototype = {};
442
503
 
443
504
MochiKit.Base.update(MochiKit.Signal, {
444
505
 
453
514
    _unloadCache: function () {
454
515
        var self = MochiKit.Signal;
455
516
        var observers = self._observers;
456
 
        
 
517
 
457
518
        for (var i = 0; i < observers.length; i++) {
458
 
            self._disconnect(observers[i]);
459
 
        }
460
 
        
461
 
        delete self._observers;
462
 
        
463
 
        try {
464
 
            window.onload = undefined;
465
 
        } catch(e) {
466
 
            // pass
467
 
        }
468
 
 
469
 
        try {
470
 
            window.onunload = undefined;
471
 
        } catch(e) {
472
 
            // pass
 
519
            if (observers[i].signal !== 'onload' && observers[i].signal !== 'onunload') {
 
520
                self._disconnect(observers[i]);
 
521
            }
473
522
        }
474
523
    },
475
524
 
476
 
    _listener: function (src, func, obj, isDOM) {
477
 
        var E = MochiKit.Signal.Event;
 
525
    _listener: function (src, sig, func, obj, isDOM) {
 
526
        var self = MochiKit.Signal;
 
527
        var E = self.Event;
478
528
        if (!isDOM) {
479
 
            return MochiKit.Base.bind(func, obj);
480
 
        } 
 
529
            /* We don't want to re-bind already bound methods */
 
530
            if (typeof(func.im_self) == 'undefined') {
 
531
                return MochiKit.Base.bindLate(func, obj);
 
532
            } else {
 
533
                return func;
 
534
            }
 
535
        }
481
536
        obj = obj || src;
482
537
        if (typeof(func) == "string") {
483
 
            return function (nativeEvent) {
484
 
                obj[func].apply(obj, [new E(src, nativeEvent)]);
485
 
            };
 
538
            if (sig === 'onload' || sig === 'onunload') {
 
539
                return function (nativeEvent) {
 
540
                    obj[func].apply(obj, [new E(src, nativeEvent)]);
 
541
                    
 
542
                    var ident = new MochiKit.Signal.Ident({
 
543
                        source: src, signal: sig, objOrFunc: obj, funcOrStr: func});
 
544
                    
 
545
                    MochiKit.Signal._disconnect(ident);
 
546
                };
 
547
            } else {
 
548
                return function (nativeEvent) {
 
549
                    obj[func].apply(obj, [new E(src, nativeEvent)]);
 
550
                };
 
551
            }
486
552
        } else {
487
 
            return function (nativeEvent) {
488
 
                func.apply(obj, [new E(src, nativeEvent)]);
489
 
            };
490
 
        }
491
 
    },
492
 
    
493
 
    connect: function (src, sig, objOrFunc/* optional */, funcOrStr) {
494
 
        src = MochiKit.DOM.getElement(src);
495
 
        var self = MochiKit.Signal;
496
 
        
497
 
        if (typeof(sig) != 'string') {
498
 
            throw new Error("'sig' must be a string");
499
 
        }
500
 
        
 
553
            if (sig === 'onload' || sig === 'onunload') {
 
554
                return function (nativeEvent) {
 
555
                    func.apply(obj, [new E(src, nativeEvent)]);
 
556
                    
 
557
                    var ident = new MochiKit.Signal.Ident({
 
558
                        source: src, signal: sig, objOrFunc: func});
 
559
                    
 
560
                    MochiKit.Signal._disconnect(ident);
 
561
                };
 
562
            } else {
 
563
                return function (nativeEvent) {
 
564
                    func.apply(obj, [new E(src, nativeEvent)]);
 
565
                };
 
566
            }
 
567
        }
 
568
    },
 
569
 
 
570
    _browserAlreadyHasMouseEnterAndLeave: function () {
 
571
        return /MSIE/.test(navigator.userAgent);
 
572
    },
 
573
 
 
574
    _browserLacksMouseWheelEvent: function () {
 
575
        return /Gecko\//.test(navigator.userAgent);
 
576
    },
 
577
 
 
578
    _mouseEnterListener: function (src, sig, func, obj) {
 
579
        var E = MochiKit.Signal.Event;
 
580
        return function (nativeEvent) {
 
581
            var e = new E(src, nativeEvent);
 
582
            try {
 
583
                e.relatedTarget().nodeName;
 
584
            } catch (err) {
 
585
                /* probably hit a permission denied error; possibly one of
 
586
                 * firefox's screwy anonymous DIVs inside an input element.
 
587
                 * Allow this event to propogate up.
 
588
                 */
 
589
                return;
 
590
            }
 
591
            e.stop();
 
592
            if (MochiKit.DOM.isChildNode(e.relatedTarget(), src)) {
 
593
                /* We've moved between our node and a child. Ignore. */
 
594
                return;
 
595
            }
 
596
            e.type = function () { return sig; };
 
597
            if (typeof(func) == "string") {
 
598
                return obj[func].apply(obj, [e]);
 
599
            } else {
 
600
                return func.apply(obj, [e]);
 
601
            }
 
602
        };
 
603
    },
 
604
 
 
605
    _getDestPair: function (objOrFunc, funcOrStr) {
501
606
        var obj = null;
502
607
        var func = null;
503
608
        if (typeof(funcOrStr) != 'undefined') {
515
620
        } else {
516
621
            func = objOrFunc;
517
622
        }
 
623
        return [obj, func];
 
624
    },
 
625
 
 
626
    /** @id MochiKit.Signal.connect */
 
627
    connect: function (src, sig, objOrFunc/* optional */, funcOrStr) {
 
628
        src = MochiKit.DOM.getElement(src);
 
629
        var self = MochiKit.Signal;
 
630
 
 
631
        if (typeof(sig) != 'string') {
 
632
            throw new Error("'sig' must be a string");
 
633
        }
 
634
 
 
635
        var destPair = self._getDestPair(objOrFunc, funcOrStr);
 
636
        var obj = destPair[0];
 
637
        var func = destPair[1];
518
638
        if (typeof(obj) == 'undefined' || obj === null) {
519
639
            obj = src;
520
640
        }
521
 
        
 
641
 
522
642
        var isDOM = !!(src.addEventListener || src.attachEvent);
523
 
        var listener = self._listener(src, func, obj, isDOM);
524
 
        
 
643
        if (isDOM && (sig === "onmouseenter" || sig === "onmouseleave")
 
644
                  && !self._browserAlreadyHasMouseEnterAndLeave()) {
 
645
            var listener = self._mouseEnterListener(src, sig.substr(2), func, obj);
 
646
            if (sig === "onmouseenter") {
 
647
                sig = "onmouseover";
 
648
            } else {
 
649
                sig = "onmouseout";
 
650
            }
 
651
        } else if (isDOM && sig == "onmousewheel" && self._browserLacksMouseWheelEvent()) {
 
652
            var listener = self._listener(src, sig, func, obj, isDOM);
 
653
            sig = "onDOMMouseScroll";
 
654
        } else {
 
655
            var listener = self._listener(src, sig, func, obj, isDOM);
 
656
        }
 
657
 
525
658
        if (src.addEventListener) {
526
659
            src.addEventListener(sig.substr(2), listener, false);
527
660
        } else if (src.attachEvent) {
528
661
            src.attachEvent(sig, listener); // useCapture unsupported
529
662
        }
530
663
 
531
 
        var ident = [src, sig, listener, isDOM, objOrFunc, funcOrStr];
 
664
        var ident = new MochiKit.Signal.Ident({
 
665
            source: src, 
 
666
            signal: sig, 
 
667
            listener: listener, 
 
668
            isDOM: isDOM, 
 
669
            objOrFunc: objOrFunc, 
 
670
            funcOrStr: funcOrStr, 
 
671
            connected: true
 
672
        });
532
673
        self._observers.push(ident);
533
 
        
534
 
       
 
674
 
 
675
        if (!isDOM && typeof(src.__connect__) == 'function') {
 
676
            var args = MochiKit.Base.extend([ident], arguments, 1);
 
677
            src.__connect__.apply(src, args);
 
678
        }
 
679
 
535
680
        return ident;
536
681
    },
537
 
    
 
682
 
538
683
    _disconnect: function (ident) {
 
684
        // already disconnected
 
685
        if (!ident.connected) {
 
686
            return;
 
687
        }
 
688
        ident.connected = false;
 
689
        var src = ident.source;
 
690
        var sig = ident.signal;
 
691
        var listener = ident.listener;
539
692
        // check isDOM
540
 
        if (!ident[3]) { return; }
541
 
        var src = ident[0];
542
 
        var sig = ident[1];
543
 
        var listener = ident[2];
 
693
        if (!ident.isDOM) {
 
694
            if (typeof(src.__disconnect__) == 'function') {
 
695
                src.__disconnect__(ident, sig, ident.objOrFunc, ident.funcOrStr);
 
696
            }
 
697
            return;
 
698
        }
544
699
        if (src.removeEventListener) {
545
700
            src.removeEventListener(sig.substr(2), listener, false);
546
701
        } else if (src.detachEvent) {
549
704
            throw new Error("'src' must be a DOM element");
550
705
        }
551
706
    },
552
 
    
 
707
 
 
708
     /** @id MochiKit.Signal.disconnect */
553
709
    disconnect: function (ident) {
554
710
        var self = MochiKit.Signal;
555
711
        var observers = self._observers;
562
718
            var func = arguments[3];
563
719
            for (var i = observers.length - 1; i >= 0; i--) {
564
720
                var o = observers[i];
565
 
                if (o[0] === src && o[1] === sig && o[4] === obj && o[5] === func) {
 
721
                if (o.source === src && o.signal === sig && o.objOrFunc === obj && o.funcOrStr === func) {
566
722
                    self._disconnect(o);
567
 
                    observers.splice(i, 1);
 
723
                    if (!self._lock) {
 
724
                        observers.splice(i, 1);
 
725
                    } else {
 
726
                        self._dirty = true;
 
727
                    }
568
728
                    return true;
569
729
                }
570
730
            }
572
732
            var idx = m.findIdentical(observers, ident);
573
733
            if (idx >= 0) {
574
734
                self._disconnect(ident);
575
 
                observers.splice(idx, 1);
 
735
                if (!self._lock) {
 
736
                    observers.splice(idx, 1);
 
737
                } else {
 
738
                    self._dirty = true;
 
739
                }
576
740
                return true;
577
741
            }
578
742
        }
579
743
        return false;
580
744
    },
581
 
    
582
 
    disconnectAll: function(src/* optional */, sig) {
 
745
 
 
746
    /** @id MochiKit.Signal.disconnectAllTo */
 
747
    disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) {
 
748
        var self = MochiKit.Signal;
 
749
        var observers = self._observers;
 
750
        var disconnect = self._disconnect;
 
751
        var locked = self._lock;
 
752
        var dirty = self._dirty;
 
753
        if (typeof(funcOrStr) === 'undefined') {
 
754
            funcOrStr = null;
 
755
        }
 
756
        for (var i = observers.length - 1; i >= 0; i--) {
 
757
            var ident = observers[i];
 
758
            if (ident.objOrFunc === objOrFunc &&
 
759
                    (funcOrStr === null || ident.funcOrStr === funcOrStr)) {
 
760
                disconnect(ident);
 
761
                if (locked) {
 
762
                    dirty = true;
 
763
                } else {
 
764
                    observers.splice(i, 1);
 
765
                }
 
766
            }
 
767
        }
 
768
        self._dirty = dirty;
 
769
    },
 
770
 
 
771
    /** @id MochiKit.Signal.disconnectAll */
 
772
    disconnectAll: function (src/* optional */, sig) {
583
773
        src = MochiKit.DOM.getElement(src);
584
774
        var m = MochiKit.Base;
585
775
        var signals = m.flattenArguments(m.extend(null, arguments, 1));
586
776
        var self = MochiKit.Signal;
587
777
        var disconnect = self._disconnect;
588
778
        var observers = self._observers;
 
779
        var i, ident;
 
780
        var locked = self._lock;
 
781
        var dirty = self._dirty;
589
782
        if (signals.length === 0) {
590
783
            // disconnect all
591
 
            for (var i = observers.length - 1; i >= 0; i--) {
592
 
                var ident = observers[i];
593
 
                if (ident[0] === src) {
 
784
            for (i = observers.length - 1; i >= 0; i--) {
 
785
                ident = observers[i];
 
786
                if (ident.source === src) {
594
787
                    disconnect(ident);
595
 
                    observers.splice(i, 1);
 
788
                    if (!locked) {
 
789
                        observers.splice(i, 1);
 
790
                    } else {
 
791
                        dirty = true;
 
792
                    }
596
793
                }
597
794
            }
598
795
        } else {
599
796
            var sigs = {};
600
 
            for (var i = 0; i < signals.length; i++) {
 
797
            for (i = 0; i < signals.length; i++) {
601
798
                sigs[signals[i]] = true;
602
799
            }
603
 
            for (var i = observers.length - 1; i >= 0; i--) {
604
 
                var ident = observers[i];
605
 
                if (ident[0] === src && ident[1] in sigs) {
 
800
            for (i = observers.length - 1; i >= 0; i--) {
 
801
                ident = observers[i];
 
802
                if (ident.source === src && ident.signal in sigs) {
606
803
                    disconnect(ident);
607
 
                    observers.splice(i, 1);
 
804
                    if (!locked) {
 
805
                        observers.splice(i, 1);
 
806
                    } else {
 
807
                        dirty = true;
 
808
                    }
608
809
                }
609
810
            }
610
811
        }
611
 
        
 
812
        self._dirty = dirty;
612
813
    },
613
814
 
 
815
    /** @id MochiKit.Signal.signal */
614
816
    signal: function (src, sig) {
615
 
        var observers = MochiKit.Signal._observers;
 
817
        var self = MochiKit.Signal;
 
818
        var observers = self._observers;
616
819
        src = MochiKit.DOM.getElement(src);
617
820
        var args = MochiKit.Base.extend(null, arguments, 2);
618
821
        var errors = [];
 
822
        self._lock = true;
619
823
        for (var i = 0; i < observers.length; i++) {
620
824
            var ident = observers[i];
621
 
            if (ident[0] === src && ident[1] === sig) {
 
825
            if (ident.source === src && ident.signal === sig &&
 
826
                    ident.connected) {
622
827
                try {
623
 
                    ident[2].apply(src, args);
 
828
                    ident.listener.apply(src, args);
624
829
                } catch (e) {
625
830
                    errors.push(e);
626
831
                }
627
832
            }
628
833
        }
 
834
        self._lock = false;
 
835
        if (self._dirty) {
 
836
            self._dirty = false;
 
837
            for (var i = observers.length - 1; i >= 0; i--) {
 
838
                if (!observers[i].connected) {
 
839
                    observers.splice(i, 1);
 
840
                }
 
841
            }
 
842
        }
629
843
        if (errors.length == 1) {
630
844
            throw errors[0];
631
845
        } else if (errors.length > 1) {
643
857
    'connect',
644
858
    'disconnect',
645
859
    'signal',
646
 
    'disconnectAll'
 
860
    'disconnectAll',
 
861
    'disconnectAllTo'
647
862
];
648
863
 
649
864
MochiKit.Signal.__new__ = function (win) {
650
865
    var m = MochiKit.Base;
651
866
    this._document = document;
652
867
    this._window = win;
 
868
    this._lock = false;
 
869
    this._dirty = false;
653
870
 
654
871
    try {
655
872
        this.connect(window, 'onunload', this._unloadCache);
670
887
//
671
888
// XXX: Internet Explorer blows
672
889
//
673
 
if (!MochiKit.__compat__) {
 
890
if (MochiKit.__export__) {
674
891
    connect = MochiKit.Signal.connect;
675
892
    disconnect = MochiKit.Signal.disconnect;
676
893
    disconnectAll = MochiKit.Signal.disconnectAll;