]>
git.wh0rd.org - tt-rss.git/blob - lib/dijit/a11yclick.js.uncompressed.js
1 define("dijit/a11yclick", [
3 "dojo/_base/array", // array.forEach
4 "dojo/keys", // keys.ENTER keys.SPACE
5 "dojo/_base/declare", // declare
6 "dojo/has", // has("dom-addeventlistener")
7 "dojo/_base/unload", // unload.addOnWindowUnload
8 "dojo/_base/window" // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent
9 ], function(on
, array
, keys
, declare
, has
, unload
, win
){
14 // Keep track of where the last keydown event was, to help avoid generating
15 // spurious ondijitclick events when:
16 // 1. focus is on a <button> or <a>
17 // 2. user presses then releases the ENTER key
18 // 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler
19 // 4. onkeyup event fires, causing the ondijitclick handler to fire
20 var lastKeyDownNode
= null;
21 if(has("dom-addeventlistener")){
22 win
.doc
.addEventListener('keydown', function(evt
){
23 lastKeyDownNode
= evt
.target
;
26 // Fallback path for IE6-8
28 var keydownCallback = function(evt
){
29 lastKeyDownNode
= evt
.srcElement
;
31 win
.doc
.attachEvent('onkeydown', keydownCallback
);
32 unload
.addOnWindowUnload(function(){
33 win
.doc
.detachEvent('onkeydown', keydownCallback
);
38 function clickKey(/*Event*/ e
){
39 return (e
.keyCode
=== keys
.ENTER
|| e
.keyCode
=== keys
.SPACE
) &&
40 !e
.ctrlKey
&& !e
.shiftKey
&& !e
.altKey
&& !e
.metaKey
;
43 return function(node
, listener
){
45 // Custom a11yclick (a.k.a. ondijitclick) event
46 // which triggers on a mouse click, touch, or space/enter keyup.
48 if(/input|button/i.test(node
.nodeName
)){
49 // pass through, the browser already generates click event on SPACE/ENTER key
50 return on(node
, "click", listener
);
52 // Don't fire the click event unless both the keydown and keyup occur on this node.
53 // Avoids problems where focus shifted to this node or away from the node on keydown,
54 // either causing this node to process a stray keyup event, or causing another node
55 // to get a stray keyup event.
58 on(node
, "keydown", function(e
){
59 //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
61 // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
62 lastKeyDownNode
= e
.target
;
64 // Prevent viewport scrolling on space key in IE<9.
65 // (Reproducible on test_Button.html on any of the first dijit/form/Button examples)
70 on(node
, "keyup", function(e
){
71 //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
72 if(clickKey(e
) && e
.target
== lastKeyDownNode
){ // === breaks greasemonkey
73 //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
74 lastKeyDownNode
= null;
75 on
.emit(e
.target
, "click", {
82 on(node
, "click", function(e
){
83 // catch mouse clicks, plus the on.emit() calls from above and below
84 listener
.call(this, e
);
89 // touchstart-->touchend will automatically generate a click event, but there are problems
90 // on iOS after focus has been programatically shifted (#14604, #14918), so setup a failsafe
91 // if click doesn't fire naturally.
95 on(node
, "touchend", function(e
){
96 var target
= e
.target
;
97 clickTimer
= setTimeout(function(){
99 on
.emit(target
, "click", {
105 on(node
, "click", function(e
){
106 // If browser generates a click naturally, clear the timer to fire a synthetic click event
108 clearTimeout(clickTimer
);
111 // TODO: if the touchstart and touchend were <100ms apart, and then there's another touchstart
112 // event <300ms after the touchend event, then clear the synthetic click timer, because user
113 // is doing a zoom. Alternately monitor screen.deviceXDPI (or something similar) to see if
114 // zoom level has changed.
120 array
.forEach(handles
, function(h
){ h
.remove(); });
122 clearTimeout(clickTimer
);