]>
git.wh0rd.org - tt-rss.git/blob - lib/dojo/_base/connect.js.uncompressed.js
1 define("dojo/_base/connect", ["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(kernel
, on
, hub
, aspect
, eventModule
, mouse
, has
, lang
){
5 // This module defines the dojo.connect API.
6 // This modules also provides keyboard event handling helpers.
7 // This module exports an extension event for emulating Firefox's keypress handling.
8 // However, this extension event exists primarily for backwards compatibility and
9 // is not recommended. WebKit and IE uses an alternate keypress handling (only
10 // firing for printable characters, to distinguish from keydown events), and most
11 // consider the WebKit/IE behavior more desirable.
12 has
.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
13 var testKeyEvent
= {charCode
: 0};
15 testKeyEvent
= document
.createEvent("KeyboardEvent");
16 (testKeyEvent
.initKeyboardEvent
|| testKeyEvent
.initKeyEvent
).call(testKeyEvent
, "keypress", true, true, null, false, false, false, false, 9, 3);
18 return testKeyEvent
.charCode
== 0 && !has("opera");
21 function connect_(obj
, event
, context
, method
, dontFix
){
22 method
= lang
.hitch(context
, method
);
23 if(!obj
|| !(obj
.addEventListener
|| obj
.attachEvent
)){
24 // it is a not a DOM node and we are using the dojo.connect style of treating a
25 // method like an event, must go right to aspect
26 return aspect
.after(obj
|| kernel
.global
, event
, method
, true);
28 if(typeof event
== "string" && event
.substring(0, 2) == "on"){
29 event
= event
.substring(2);
36 // dojo.connect has special handling for these event types
48 return on(obj
, event
, method
, dontFix
);
67 var evtCopyKey
= has("mac") ? "metaKey" : "ctrlKey";
70 var _synthesizeEvent = function(evt
, props
){
71 var faux
= lang
.mixin({}, evt
, props
);
73 // FIXME: would prefer to use lang.hitch: lang.hitch(evt, evt.preventDefault);
74 // but it throws an error when preventDefault is invoked on Safari
75 // does Event.preventDefault not support "apply" on Safari?
76 faux
.preventDefault = function(){ evt
.preventDefault(); };
77 faux
.stopPropagation = function(){ evt
.stopPropagation(); };
80 function setKeyChar(evt
){
81 evt
.keyChar
= evt
.charCode
? String
.fromCharCode(evt
.charCode
) : '';
82 evt
.charOrCode
= evt
.keyChar
|| evt
.keyCode
;
85 if(has("events-keypress-typed")){
86 // this emulates Firefox's keypress behavior where every keydown can correspond to a keypress
87 var _trySetKeyCode = function(e
, code
){
89 // squelch errors when keyCode is read-only
90 // (e.g. if keyCode is ctrl or shift)
91 return (e
.keyCode
= code
);
96 keypress = function(object
, listener
){
97 var keydownSignal
= on(object
, "keydown", function(evt
){
100 // These are Windows Virtual Key Codes
101 // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
102 var unprintable
= (k
!=13 || (has("ie") >= 9 && !has("quirks"))) && k
!=32 && (k
!=27||!has("ie")) && (k
<48||k
>90) && (k
<96||k
>111) && (k
<186||k
>192) && (k
<219||k
>222) && k
!=229;
103 // synthesize keypress for most unprintables and CTRL-keys
104 if(unprintable
||evt
.ctrlKey
){
105 var c
= unprintable
? 0 : k
;
108 return listener
.call(evt
.currentTarget
, evt
); // IE will post CTRL-BREAK, CTRL-ENTER as keypress natively
109 }else if(c
>95 && c
<106){
110 c
-= 48; // map CTRL-[numpad 0-9] to ASCII
111 }else if((!evt
.shiftKey
)&&(c
>=65&&c
<=90)){
112 c
+= 32; // map CTRL-[A-Z] to lowercase
114 c
= _punctMap
[c
] || c
; // map other problematic CTRL combinations to ASCII
117 // simulate a keypress event
118 var faux
= _synthesizeEvent(evt
, {type
: 'keypress', faux
: true, charCode
: c
});
119 listener
.call(evt
.currentTarget
, faux
);
121 _trySetKeyCode(evt
, faux
.keyCode
);
125 var keypressSignal
= on(object
, "keypress", function(evt
){
126 var c
= evt
.charCode
;
128 evt
= _synthesizeEvent(evt
, {charCode
: c
, faux
: true});
129 return listener
.call(this, evt
);
133 keydownSignal
.remove();
134 keypressSignal
.remove();
140 keypress = function(object
, listener
){
141 return on(object
, "keypress", function(evt
){
144 c
=99; // Mozilla maps CTRL-BREAK to CTRL-c
146 // can't trap some keys at all, like INSERT and DELETE
147 // there is no differentiating info between DELETE and ".", or INSERT and "-"
148 c
= c
<32 && !evt
.shiftKey
? 0 : c
;
149 if(evt
.ctrlKey
&& !evt
.shiftKey
&& c
>=65 && c
<=90){
150 // lowercase CTRL-[A-Z] keys
153 return listener
.call(this, _synthesizeEvent(evt
, { charCode
: c
}));
157 keypress = function(object
, listener
){
158 return on(object
, "keypress", function(evt
){
160 return listener
.call(this, evt
);
169 connect:function(obj
, event
, context
, method
, dontFix
){
170 // normalize arguments
171 var a
=arguments
, args
=[], i
=0;
172 // if a[0] is a String, obj was omitted
173 args
.push(typeof a
[0] == "string" ? null : a
[i
++], a
[i
++]);
174 // if the arg-after-next is a String or Function, context was NOT omitted
176 args
.push(typeof a1
== "string" || typeof a1
== "function" ? a
[i
++] : null, a
[i
++]);
177 // absorb any additional arguments
178 for(var l
=a
.length
; i
<l
; i
++){ args
.push(a
[i
]); }
179 return connect_
.apply(this, args
);
182 disconnect:function(handle
){
188 subscribe:function(topic
, context
, method
){
189 return hub
.subscribe(topic
, lang
.hitch(context
, method
));
192 publish:function(topic
, args
){
193 return hub
.publish
.apply(hub
, [topic
].concat(args
));
196 connectPublisher:function(topic
, obj
, event
){
197 var pf = function(){ connect
.publish(topic
, arguments
); };
198 return event
? connect
.connect(obj
, event
, pf
) : connect
.connect(obj
, pf
); //Handle
201 isCopyKey: function(e
){
202 return e
[evtCopyKey
]; // Boolean
205 connect
.unsubscribe
= connect
.disconnect
;
207 1 && lang
.mixin(kernel
, connect
);
211 dojo.connect = function(obj, event, context, method, dontFix){
213 // `dojo.connect` is the core event handling and delegation method in
214 // Dojo. It allows one function to "listen in" on the execution of
215 // any other, triggering the second whenever the first is called. Many
216 // listeners may be attached to a function, and source functions may
217 // be either regular function calls or DOM events.
220 // Connects listeners to actions, so that after event fires, a
221 // listener is called with the same arguments passed to the original
224 // Since `dojo.connect` allows the source of events to be either a
225 // "regular" JavaScript function or a DOM event, it provides a uniform
226 // interface for listening to all the types of events that an
227 // application is likely to deal with though a single, unified
228 // interface. DOM programmers may want to think of it as
229 // "addEventListener for everything and anything".
231 // When setting up a connection, the `event` parameter must be a
232 // string that is the name of the method/event to be listened for. If
233 // `obj` is null, `kernel.global` is assumed, meaning that connections
234 // to global methods are supported but also that you may inadvertently
235 // connect to a global by passing an incorrect object name or invalid
238 // `dojo.connect` generally is forgiving. If you pass the name of a
239 // function or method that does not yet exist on `obj`, connect will
240 // not fail, but will instead set up a stub method. Similarly, null
241 // arguments may simply be omitted such that fewer than 4 arguments
242 // may be required to set up a connection See the examples for details.
244 // The return value is a handle that is needed to
245 // remove this connection with `dojo.disconnect`.
248 // The source object for the event function.
249 // Defaults to `kernel.global` if null.
250 // If obj is a DOM node, the connection is delegated
251 // to the DOM event manager (unless dontFix is true).
254 // String name of the event function in obj.
255 // I.e. identifies a property `obj[event]`.
257 // context: Object|null
258 // The object that method will receive as "this".
260 // If context is null and method is a function, then method
261 // inherits the context of event.
263 // If method is a string then context must be the source
264 // object object for method (context[method]). If context is null,
265 // kernel.global is used.
267 // method: String|Function:
268 // A function reference, or name of a function in context.
269 // The function identified by method fires after event does.
270 // method receives the same arguments as the event.
271 // See context argument comments for information on method's scope.
274 // If obj is a DOM node, set dontFix to true to prevent delegation
275 // of this connection to the DOM event manager.
278 // When obj.onchange(), do ui.update():
279 // | dojo.connect(obj, "onchange", ui, "update");
280 // | dojo.connect(obj, "onchange", ui, ui.update); // same
283 // Using return value for disconnect:
284 // | var link = dojo.connect(obj, "onchange", ui, "update");
286 // | dojo.disconnect(link);
289 // When onglobalevent executes, watcher.handler is invoked:
290 // | dojo.connect(null, "onglobalevent", watcher, "handler");
293 // When ob.onCustomEvent executes, customEventHandler is invoked:
294 // | dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
295 // | dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
298 // When ob.onCustomEvent executes, customEventHandler is invoked
299 // with the same scope (this):
300 // | dojo.connect(ob, "onCustomEvent", null, customEventHandler);
301 // | dojo.connect(ob, "onCustomEvent", customEventHandler); // same
304 // When globalEvent executes, globalHandler is invoked
305 // with the same scope (this):
306 // | dojo.connect(null, "globalEvent", null, globalHandler);
307 // | dojo.connect("globalEvent", globalHandler); // same
312 dojo.disconnect = function(handle){
314 // Remove a link created by dojo.connect.
316 // Removes the connection between event and the method referenced by handle.
318 // the return value of the dojo.connect call that created the connection.
323 dojo.subscribe = function(topic, context, method){
325 // Attach a listener to a named topic. The listener function is invoked whenever the
326 // named topic is published (see: dojo.publish).
327 // Returns a handle which is needed to unsubscribe this listener.
329 // The topic to which to subscribe.
330 // context: Object|null:
331 // Scope in which method will be invoked, or null for default scope.
332 // method: String|Function:
333 // The name of a function in context, or a function reference. This is the function that
334 // is invoked when topic is published.
336 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
337 // | dojo.publish("alerts", [ "read this", "hello world" ]);
342 dojo.unsubscribe = function(handle){
344 // Remove a topic listener.
346 // The handle returned from a call to subscribe.
348 // | var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
350 // | dojo.unsubscribe(alerter);
355 dojo.publish = function(topic, args){
357 // Invoke all listener method subscribed to topic.
359 // The name of the topic to publish.
361 // An array of arguments. The arguments will be applied
362 // to each topic subscriber (as first class parameters, via apply).
364 // | dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
365 // | dojo.publish("alerts", [ "read this", "hello world" ]);
370 dojo.connectPublisher = function(topic, obj, event){
372 // Ensure that every time obj.event() is called, a message is published
373 // on the topic. Returns a handle which can be passed to
374 // dojo.disconnect() to disable subsequent automatic publication on
377 // The name of the topic to publish.
379 // The source object for the event function. Defaults to kernel.global
382 // The name of the event function in obj.
383 // I.e. identifies a property obj[event].
385 // | dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
390 dojo.isCopyKey = function(e){
392 // Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
394 // Event object to examine