You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.2 KiB
139 lines
4.2 KiB
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; |
|
});
|
|
|