Initial check-in
[dygraphs.git] / mochikit_v14 / doc / rst / MochiKit / Signal.rst
1 .. title:: MochiKit.Signal - Simple universal event handling
2 .. |---| unicode:: U+2014  .. em dash, trimming surrounding whitespace
3    :trim:
4
5 Name
6 ====
7
8 MochiKit.Signal - Simple universal event handling
9
10
11 Synopsis
12 ========
13
14 Signal for DOM events::
15
16     // DOM events are also signals. Connect freely! The functions will be
17     // called with the custom event as a parameter.
18
19     // calls myClicked.apply(getElement('myID'), [event])
20     connect('myID', 'onclick', myClicked);
21
22     // calls wasClicked.apply(myObject, [event])
23     connect('myID', 'onclick', myObject, wasClicked);
24
25     // calls myObject.wasClicked(event)
26     connect('myID', 'onclick', myObject, 'wasClicked');
27
28     // the event is normalized, no more e = e || window.event!
29     myObject.wasClicked = function(e) {
30         var crossBrowserCoordinates = e.mouse().page;
31         // e.mouse().page is a MochiKit.Style.Coordinates object
32     }
33
34
35 Signal for non-DOM events::
36
37     // otherObject.gotFlash() will be called when 'flash' signalled.
38     connect(myObject, 'flash', otherObject, 'gotFlash');
39
40     // gotBang.apply(otherObject, [...]) will be called when 'bang' signalled.
41     // You can access otherObject from within gotBang as 'this'.
42     connect(myObject, 'bang', otherObject, gotBang);
43
44     // myFunc.apply(myObject, [...]) will be called when 'flash' signalled.
45     // You can access myObject from within myFunc as 'this'.
46     var ident = connect(myObject, 'flash', myFunc);
47
48     // You may disconnect with the return value from connect
49     disconnect(ident);
50
51     // Signal can take parameters. These will be passed along to the
52     // connected functions.
53     signal(myObject, 'flash');
54     signal(myObject, 'bang', 'BANG!');
55
56
57 Description
58 ===========
59
60 Event handling was never so easy!
61
62 This module takes care of all the hard work |---| figuring out which
63 event model to use, trying to retrieve the event object, and handling
64 your own internal events, as well as cleanup when the page is unloaded
65 to clean up IE's nasty memory leakage.
66
67 This event system is largely based on Qt's signal/slot system. Read
68 more on how that is handled and also how it is used in model/view
69 programming at: http://doc.trolltech.com/
70
71
72 Dependencies
73 ============
74
75 - :mochiref:`MochiKit.Base`
76 - :mochiref:`MochiKit.DOM`
77
78
79 Overview
80 ========
81
82 Using Signal for DOM Events
83 ---------------------------
84
85 When using MochiKit.Signal, do not use the browser's native event
86 API. That means, no ``onclick="blah"``, no
87 ``elem.addEventListener(...)``, and certainly no
88 ``elem.attachEvent(...)``. This also means that
89 :mochiref:`MochiKit.DOM.addToCallStack` and
90 :mochiref:`MochiKit.DOM.addLoadEvent` should not be used in
91 combination with this module.
92
93 Signals for DOM objects are named with the ``'on'`` prefix, e.g.:
94 ``'onclick'``, ``'onkeyup'``, etc.
95
96 When the signal fires, your slot will be called with one parameter,
97 the custom event object.
98
99
100 Custom Event Objects for DOM events
101 -----------------------------------
102
103 Signals triggered by DOM events are called with a custom event object
104 as a parameter. The custom event object presents a consistent view of
105 the event across all supported platforms and browsers, and provides
106 many conveniences not available even in a correct W3C implementation.
107
108 See the `DOM Custom Event Object Reference`_ for a detailed API
109 description of this object.
110
111 If you find that you're accessing the native event for any reason,
112 create a `new ticket`_ and we'll look into normalizing the behavior
113 you're looking for.
114
115 .. _`new ticket`: http://trac.mochikit.com/newticket
116 .. _`Safari bug 6595`: http://bugs.webkit.org/show_bug.cgi?id=6595
117 .. _`Safari bug 7790`: http://bugs.webkit.org/show_bug.cgi?id=7790
118 .. _`Safari bug 8707`: http://bugs.webkit.org/show_bug.cgi?id=8707
119 .. _`stopPropagation()`: http://developer.mozilla.org/en/docs/DOM:event.stopPropagation
120 .. _`preventDefault()`: http://developer.mozilla.org/en/docs/DOM:event.preventDefault
121
122
123 Memory Usage
124 ------------
125
126 Any object that has connected slots (via :mochiref:`connect()`) is
127 referenced by the Signal mechanism until it is disconnected via
128 :mochiref:`disconnect()` or :mochiref:`disconnectAll()`.
129
130 Signal does not leak. It registers an ``'onunload'`` event that
131 disconnects all objects on the page when the browser leaves the
132 page. However, memory usage will grow during the page view for every
133 connection made until it is disconnected. Even if the DOM object is
134 removed from the document, it will still be referenced by Signal until
135 it is explicitly disconnected.
136
137 In order to conserve memory during the page view,
138 :mochiref:`disconnectAll()` any DOM elements that are about to be
139 removed from the document.
140
141
142 Synthesized Events
143 ------------------
144
145 Certain events supported by MochiKit are not generated natively by all
146 browsers. MochiKit can synthesize these events even for non-supporting
147 browsers, however, by watching for related events and triggering the
148 appropriate signals at the right times.
149
150 These events include:
151
152 ``onmouseenter``
153
154     Similar to ``'onmouseover'``, but does not "bubble" up to parent
155     nodes. Such bubbling is often a cause of confusion. On an
156     ``'onmouseenter'`` event, you can be certain that the mouse has
157     left the node attached to the event.
158
159     *Availability:*
160         Available in MochiKit 1.4+
161
162 ``onmouseleave``
163
164     Similar to ``'onmouseout'``, but does not "bubble" up to parent
165     nodes. This is the analog to ``'onmouseenter'``.
166
167     *Availability:*
168         Available in MochiKit 1.4+
169
170
171 Using Signal for non-DOM objects
172 --------------------------------
173
174 Signals are triggered with the :mochiref:`signal(src, 'signal', ...)`
175 function. Additional parameters passed to this are passed onto the
176 connected slots. Explicit signals are not required for DOM events.
177
178 Slots that are connected to a signal are called in the following
179 manner when that signal is signalled:
180
181 -   If the slot was a single function, then it is called with ``this``
182     set to the object originating the signal with whatever parameters
183     it was signalled with.
184
185 -   If the slot was an object and a function, then it is called with
186     ``this`` set to the object, and with whatever parameters it was
187     signalled with.
188
189 -   If the slot was an object and a string, then ``object[string]`` is
190     called with the parameters to the signal.
191
192
193 API Reference
194 =============
195
196
197 Signal API Reference
198 --------------------
199
200 :mochidef:`connect(src, signal, dest[, func])`:
201
202     Connects a signal to a slot, and return a unique identifier that
203     can be used to disconnect that signal.
204
205     ``src`` is the object that has the signal. You may pass in a
206     string, in which case, it is interpreted as an id for an HTML
207     element.
208
209     ``signal`` is a string that represents a signal name. If 'src' is
210     an HTML Element, ``window``, or the ``document``, then it can be
211     one of the 'on-XYZ' events. You must include the 'on' prefix, and
212     it must be all lower-case.
213
214     ``dest`` and ``func`` describe the slot, or the action to take
215     when the signal is triggered.
216
217         -   If ``dest`` is an object and ``func`` is a string, then
218             ``dest[func].apply(dest, [...])`` will be called when the
219             signal is signalled.
220
221         -   If ``dest`` is an object and ``func`` is a function, then
222             ``func.apply(dest, [...])`` will be called when the signal
223             is signalled.
224
225         -   If ``func`` is undefined and ``dest`` is a function, then
226             ``dest.apply(src, [...])`` will be called when the signal is
227             signalled.
228
229     No other combinations are allowed and will raise an exception.
230
231     The return value can be passed to :mochiref:`disconnect` to
232     disconnect the signal.
233
234     In MochiKit 1.4+, if ``src`` is an object that has a ``__connect__``
235     method, then ``src.__connect__(ident, signal, objOrFunc, funcOrStr)``
236     will be called. This method may be used to disconnect the signal.
237     DOM objects can not implement this feature.
238     
239     *Availability*:
240         Available in MochiKit 1.3.1+
241
242
243 :mochidef:`disconnect(ident)`:
244
245     To disconnect a signal, pass its ident returned by
246     :mochiref:`connect()`.  This is similar to how the browser's
247     ``setTimeout`` and ``clearTimeout`` works.
248
249     *Availability*:
250         Available in MochiKit 1.3.1+
251
252
253 :mochidef:`disconnectAll(src[, signal, ...])`:
254
255     ``disconnectAll(src)`` removes all signals from src.
256
257     ``disconnectAll(src, 'onmousedown', 'mySignal')`` will remove all
258     ``'onmousedown'`` and ``'mySignal'`` signals from src.
259
260     *Availability*:
261         Available in MochiKit 1.3.1+
262
263
264 :mochidef:`disconnectAllTo(dest[, func])`:
265
266     ``disconnectAllTo(dest)`` removes all signals connected to dest.
267
268     ``disconnectAllTo(dest, func)`` will remove all
269     signals connected to dest using func. 
270
271     *Availability*:
272         Available in MochiKit 1.4+
273
274
275 :mochidef:`signal(src, signal, ...)`:
276
277     This will signal a signal, passing whatever additional parameters
278     on to the connected slots. ``src`` and ``signal`` are the same as
279     for :mochiref:`connect()`.
280
281     *Availability*:
282         Available in MochiKit 1.3.1+
283
284
285 DOM Custom Event Object Reference
286 ---------------------------------
287
288 :mochidef:`event()`:
289
290     The native event produced by the browser. You should not need to
291     use this.
292
293     *Availability*:
294         Available in MochiKit 1.3.1+
295
296
297 :mochidef:`src()`:
298
299     The element that this signal is connected to.
300
301     *Availability*:
302         Available in MochiKit 1.3.1+
303
304
305 :mochidef:`type()`:
306
307     The event type (``'click'``, ``'mouseover'``, ``'keypress'``,
308     etc.) as a string. Does not include the ``'on'`` prefix.
309
310     *Availability*:
311         Available in MochiKit 1.3.1+
312
313
314 :mochidef:`target()`:
315
316     The element that triggered the event. This may be a child of
317     :mochiref:`src()`.
318
319     *Availability*:
320         Available in MochiKit 1.3.1+
321
322
323 :mochidef:`modifier()`:
324
325     Returns ``{shift, ctrl, meta, alt, any}``, where each property is
326     ``true`` if its respective modifier key was pressed, ``false``
327     otherwise. ``any`` is ``true`` if any modifier is pressed,
328     ``false`` otherwise.
329
330     *Availability*:
331         Available in MochiKit 1.3.1+
332
333
334 :mochidef:`stopPropagation()`:
335
336     Works like W3C's `stopPropagation()`_.
337
338     *Availability*:
339         Available in MochiKit 1.3.1+
340
341
342 :mochidef:`preventDefault()`:
343
344     Works like W3C's `preventDefault()`_.
345
346     *Availability*:
347         Available in MochiKit 1.3.1+
348
349
350 :mochidef:`stop()`:
351
352     Shortcut that calls ``stopPropagation()`` and
353     ``preventDefault()``.
354
355     *Availability*:
356         Available in MochiKit 1.3.1+
357
358
359 :mochidef:`key()`:
360
361     Returns ``{code, string}``.
362
363     Use ``'onkeydown'`` and ``'onkeyup'`` handlers to detect control
364     characters such as ``'KEY_F1'``. Use the ``'onkeypress'``
365     handler to detect "printable" characters, such as ``'é'``.
366
367     When a user presses F1, in ``'onkeydown'`` and ``'onkeyup'`` this
368     method returns ``{code: 122, string: 'KEY_F1'}``. In
369     ``'onkeypress'``, it returns ``{code: 0, string: ''}``.
370
371     If a user presses Shift+2 on a US keyboard, this method returns
372     ``{code: 50, string: 'KEY_2'}`` in ``'onkeydown'`` and
373     ``'onkeyup'``.  In ``'onkeypress'``, it returns ``{code: 64,
374     string: '@'}``.
375
376     See ``_specialKeys`` in the source code for a comprehensive list
377     of control characters.
378
379     *Availability*:
380         Available in MochiKit 1.3.1+
381
382
383 :mochidef:`mouse()`:
384
385     Properties for ``'onmouse*'``, ``'onclick'``, ``'ondblclick'``,
386     and ``'oncontextmenu'``:
387
388         -   ``page`` is a :mochiref:`MochiKit.Style.Coordinates` object
389             that represents the cursor position relative to the HTML
390             document.  Equivalent to ``pageX`` and ``pageY`` in
391             Safari, Mozilla, and Opera.
392
393         -   ``client`` is a :mochiref:`MochiKit.Style.Coordinates`
394             object that represents the cursor position relative to the
395             visible portion of the HTML document. Equivalent to
396             ``clientX`` and ``clientY`` on all browsers. Current versions of
397             Safari incorrectly return clientX as relative to the canvas
398             instead of relative to the viewport (`Safari Bug 8707`_).
399
400     Properties for ``'onmouseup'``, ``'onmousedown'``, ``'onclick'``,
401     and ``'ondblclick'``:
402
403         -   ``mouse().button`` returns ``{left, right, middle}`` where
404             each property is ``true`` if the mouse button was pressed,
405             ``false`` otherwise.
406
407     Known browser bugs:
408
409         -   Current versions of Safari won't signal ``'ondblclick'``
410             when attached via ``connect()`` (`Safari Bug 7790`_).
411             
412         -   In Safari < 2.0.4, calling ``preventDefault()`` or ``stop()`` 
413             in ``'onclick'`` events signalled from ``<a>`` tags does not 
414             prevent the browser from following those links.
415
416         -   Mac browsers don't report right-click consistently. Firefox
417             signals the slot and sets ``modifier().ctrl`` to true,
418             Opera signals the slot and sets ``modifier().meta`` to
419             ``true``, and Safari doesn't signal the slot at all
420             (`Safari Bug 6595`_).
421
422             To find a right-click in Safari, Firefox, and IE, you can
423             connect an element to ``'oncontextmenu'``. This doesn't
424             work in Opera.
425
426     *Availability*:
427         Available in MochiKit 1.3.1+
428
429
430 :mochidef:`relatedTarget()`:
431
432     Returns the document element that the mouse has moved to. This is
433     generated for ``'onmouseover'`` and ``'onmouseout'`` events.
434
435     *Availability*:
436         Available in MochiKit 1.3.1+
437
438
439 :mochidef:`confirmUnload(msg)`:
440
441     In browsers that support the ``'onbeforeunload'`` event (IE and
442     Firefox), calling this in the event handler will show a dialog box
443     that allows the user to confirm or cancel the navigation away from
444     the page.
445
446     *Availability*:
447         Available in MochiKit 1.4+
448
449
450 Authors
451 =======
452
453 -   Jonathan Gardner <jgardner@jonathangardner.net>
454 -   Beau Hartshorne <beau@hartshornesoftware.com>
455 -   Bob Ippolito <bob@redivi.com>
456
457
458 Copyright
459 =========
460
461 Copyright 2006 Jonathan Gardner <jgardner@jonathangardner.net>, Beau
462 Hartshorne <beau@hartshornesoftware.com>, and Bob Ippolito
463 <bob@redivi.com>.  This program is dual-licensed free software; you
464 can redistribute it and/or modify it under the terms of the `MIT
465 License`_ or the `Academic Free License v2.1`_.
466
467 .. _`MIT License`: http://www.opensource.org/licenses/mit-license.php
468 .. _`Academic Free License v2.1`: http://www.opensource.org/licenses/afl-2.1.php