You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.2 KiB
JavaScript
140 lines
4.2 KiB
JavaScript
define([
|
|
"dojo/keys", // keys.ENTER keys.SPACE
|
|
"dojo/mouse",
|
|
"dojo/on",
|
|
"dojo/touch" // touch support for click is now there
|
|
], function(keys, mouse, on, touch){
|
|
|
|
// module:
|
|
// dijit/a11yclick
|
|
|
|
/*=====
|
|
return {
|
|
// summary:
|
|
// Custom press, release, and click synthetic events
|
|
// which trigger on a left mouse click, touch, or space/enter keyup.
|
|
|
|
click: function(node, listener){
|
|
// summary:
|
|
// Logical click operation for mouse, touch, or keyboard (space/enter key)
|
|
},
|
|
press: function(node, listener){
|
|
// summary:
|
|
// Mousedown (left button), touchstart, or keydown (space or enter) corresponding to logical click operation.
|
|
},
|
|
release: function(node, listener){
|
|
// summary:
|
|
// Mouseup (left button), touchend, or keyup (space or enter) corresponding to logical click operation.
|
|
},
|
|
move: function(node, listener){
|
|
// summary:
|
|
// Mouse cursor or a finger is dragged over the given node.
|
|
}
|
|
};
|
|
=====*/
|
|
|
|
function clickKey(/*Event*/ e){
|
|
// Test if this keyboard event should be tracked as the start (if keydown) or end (if keyup) of a click event.
|
|
// Only track for nodes marked to be tracked, and not for buttons or inputs,
|
|
// since buttons handle keyboard click natively, and text inputs should not
|
|
// prevent typing spaces or newlines.
|
|
if((e.keyCode === keys.ENTER || e.keyCode === keys.SPACE) && !/input|button|textarea/i.test(e.target.nodeName)){
|
|
|
|
// Test if a node or its ancestor has been marked with the dojoClick property to indicate special processing
|
|
for(var node = e.target; node; node = node.parentNode){
|
|
if(node.dojoClick){ return true; }
|
|
}
|
|
}
|
|
}
|
|
|
|
var lastKeyDownNode;
|
|
|
|
on(document, "keydown", function(e){
|
|
//console.log("a11yclick: 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();
|
|
}else{
|
|
lastKeyDownNode = null;
|
|
}
|
|
});
|
|
|
|
on(document, "keyup", function(e){
|
|
//console.log("a11yclick: 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,
|
|
ctrlKey: e.ctrlKey,
|
|
shiftKey: e.shiftKey,
|
|
metaKey: e.metaKey,
|
|
altKey: e.altKey,
|
|
_origType: e.type
|
|
});
|
|
}
|
|
});
|
|
|
|
// I want to return a hash of the synthetic events, but for backwards compatibility the main return value
|
|
// needs to be the click event. Change for 2.0.
|
|
|
|
var click = function(node, listener){
|
|
// Set flag on node so that keydown/keyup above emits click event.
|
|
// Also enables fast click processing from dojo/touch.
|
|
node.dojoClick = true;
|
|
|
|
return on(node, "click", listener);
|
|
};
|
|
click.click = click; // forward compatibility with 2.0
|
|
|
|
click.press = function(node, listener){
|
|
var touchListener = on(node, touch.press, function(evt){
|
|
if(evt.type == "mousedown" && !mouse.isLeft(evt)){
|
|
// Ignore right click
|
|
return;
|
|
}
|
|
listener(evt);
|
|
}), keyListener = on(node, "keydown", function(evt){
|
|
if(evt.keyCode === keys.ENTER || evt.keyCode === keys.SPACE){
|
|
listener(evt);
|
|
}
|
|
});
|
|
return {
|
|
remove: function(){
|
|
touchListener.remove();
|
|
keyListener.remove();
|
|
}
|
|
};
|
|
};
|
|
|
|
click.release = function(node, listener){
|
|
var touchListener = on(node, touch.release, function(evt){
|
|
if(evt.type == "mouseup" && !mouse.isLeft(evt)){
|
|
// Ignore right click
|
|
return;
|
|
}
|
|
listener(evt);
|
|
}), keyListener = on(node, "keyup", function(evt){
|
|
if(evt.keyCode === keys.ENTER || evt.keyCode === keys.SPACE){
|
|
listener(evt);
|
|
}
|
|
});
|
|
return {
|
|
remove: function(){
|
|
touchListener.remove();
|
|
keyListener.remove();
|
|
}
|
|
};
|
|
};
|
|
|
|
click.move = touch.move; // just for convenience
|
|
|
|
return click;
|
|
});
|