diff options
author | Andrew Dolgov <[email protected]> | 2013-03-18 10:26:24 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2013-03-18 10:26:26 +0400 |
commit | f0cfe83e3725f9a3928da97a6e3085e79cb25309 (patch) | |
tree | 4b0af188defaa807c7bc6ff3a101b41c9166c463 /lib/dijit/a11yclick.js.uncompressed.js | |
parent | 9a2885da170ffd64358b99194095851a2d09c1b6 (diff) |
upgrade dojo to 1.8.3 (refs #570)
Diffstat (limited to 'lib/dijit/a11yclick.js.uncompressed.js')
-rw-r--r-- | lib/dijit/a11yclick.js.uncompressed.js | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/dijit/a11yclick.js.uncompressed.js b/lib/dijit/a11yclick.js.uncompressed.js new file mode 100644 index 000000000..ed92308dd --- /dev/null +++ b/lib/dijit/a11yclick.js.uncompressed.js @@ -0,0 +1,131 @@ +define("dijit/a11yclick", [ + "dojo/on", + "dojo/_base/array", // array.forEach + "dojo/keys", // keys.ENTER keys.SPACE + "dojo/_base/declare", // declare + "dojo/has", // has("dom-addeventlistener") + "dojo/_base/unload", // unload.addOnWindowUnload + "dojo/_base/window" // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent +], function(on, array, keys, declare, has, unload, win){ + + // module: + // dijit/a11yclick + + // Keep track of where the last keydown event was, to help avoid generating + // spurious ondijitclick events when: + // 1. focus is on a <button> or <a> + // 2. user presses then releases the ENTER key + // 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler + // 4. onkeyup event fires, causing the ondijitclick handler to fire + var lastKeyDownNode = null; + if(has("dom-addeventlistener")){ + win.doc.addEventListener('keydown', function(evt){ + lastKeyDownNode = evt.target; + }, true); + }else{ + // Fallback path for IE6-8 + (function(){ + var keydownCallback = function(evt){ + lastKeyDownNode = evt.srcElement; + }; + win.doc.attachEvent('onkeydown', keydownCallback); + unload.addOnWindowUnload(function(){ + win.doc.detachEvent('onkeydown', keydownCallback); + }); + })(); + } + + function clickKey(/*Event*/ e){ + return (e.keyCode === keys.ENTER || e.keyCode === keys.SPACE) && + !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey; + } + + return function(node, listener){ + // summary: + // Custom a11yclick (a.k.a. ondijitclick) event + // which triggers on a mouse click, touch, or space/enter keyup. + + if(/input|button/i.test(node.nodeName)){ + // pass through, the browser already generates click event on SPACE/ENTER key + return on(node, "click", listener); + }else{ + // Don't fire the click event unless both the keydown and keyup occur on this node. + // Avoids problems where focus shifted to this node or away from the node on keydown, + // either causing this node to process a stray keyup event, or causing another node + // to get a stray keyup event. + + var handles = [ + on(node, "keydown", function(e){ + //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode)); + if(clickKey(e)){ + // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work + lastKeyDownNode = e.target; + + // Prevent viewport scrolling on space key in IE<9. + // (Reproducible on test_Button.html on any of the first dijit/form/Button examples) + e.preventDefault(); + } + }), + + on(node, "keyup", function(e){ + //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode)); + if(clickKey(e) && e.target == lastKeyDownNode){ // === breaks greasemonkey + //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert + lastKeyDownNode = null; + on.emit(e.target, "click", { + cancelable: true, + bubbles: true + }); + } + }), + + on(node, "click", function(e){ + // catch mouse clicks, plus the on.emit() calls from above and below + listener.call(this, e); + }) + ]; + + if(has("touch")){ + // touchstart-->touchend will automatically generate a click event, but there are problems + // on iOS after focus has been programatically shifted (#14604, #14918), so setup a failsafe + // if click doesn't fire naturally. + + var clickTimer; + handles.push( + on(node, "touchend", function(e){ + var target = e.target; + clickTimer = setTimeout(function(){ + clickTimer = null; + on.emit(target, "click", { + cancelable: true, + bubbles: true + }); + }, 600); + }), + on(node, "click", function(e){ + // If browser generates a click naturally, clear the timer to fire a synthetic click event + if(clickTimer){ + clearTimeout(clickTimer); + } + }) + // TODO: if the touchstart and touchend were <100ms apart, and then there's another touchstart + // event <300ms after the touchend event, then clear the synthetic click timer, because user + // is doing a zoom. Alternately monitor screen.deviceXDPI (or something similar) to see if + // zoom level has changed. + ); + } + + return { + remove: function(){ + array.forEach(handles, function(h){ h.remove(); }); + if(clickTimer){ + clearTimeout(clickTimer); + clickTimer = null; + } + } + }; + } + }; + + return ret; +}); |