[Dojo-checkins] becky - r17832 - in dijit/trunk: . form form/templates tests tests/form tests/form/robot tests/robot
dojo-checkins-admin at dojotoolkit.org
dojo-checkins-admin at dojotoolkit.org
Wed Jun 10 10:29:30 EDT 2009
Author: becky
Date: Wed Jun 10 07:29:13 2009
New Revision: 17832
Modified:
dijit/trunk/_Widget.js
dijit/trunk/form/Button.js
dijit/trunk/form/templates/Button.html
dijit/trunk/form/templates/ComboButton.html
dijit/trunk/tests/_Widget-ondijitclick.html
dijit/trunk/tests/form/robot/Button_a11y.html
dijit/trunk/tests/form/test_Button.html
dijit/trunk/tests/robot/_Widget-ondijitclick_a11y.html
Log:
fixes #8879, #8946, #8951, #8978, #8979, #9304, #9156 rework of ondijitclick event handler. Perform action only on keyup of enter or space. Track object that receives keydown and only invoke action on keyup when target matches the keydown object. Do not use ondijitclick for elements that already have onclick support for enter and space key press (button, links) or when that onclick event will bubble up to a parent element. Thus, changed button and combobutton templates to use onclick rather than ondijitclick. No longer need special case for submit and reset buttons in button.js _onButtonClick(). Updated button_a11y.html test file to include test of submit and reset buttons. Updated widget-ondijitclick.html to again include space and enter key testing. !strict
Modified: dijit/trunk/_Widget.js
==============================================================================
--- dijit/trunk/_Widget.js (original)
+++ dijit/trunk/_Widget.js Wed Jun 10 07:29:13 2009
@@ -4,6 +4,9 @@
dojo.require( "dijit._base" );
//>>excludeEnd("dijitBaseExclude");
+
+// This code is to assist deferring dojo.connect() calls in widgets (connecting to events on the widgets'
+// DOM nodes) until someone actually needs to monitor that event.
dojo.connect(dojo, "_connect",
function(/*Widget*/ widget, /*String*/ event){
if(widget && dojo.isFunction(widget._onConnect)){
@@ -13,6 +16,25 @@
dijit._connectOnUseEventHandler = function(/*Event*/ event){};
+//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
+dijit._lastKeyDownNode = null;
+if(dojo.isIE){
+ dojo.doc.attachEvent('onkeydown', function(evt){
+ //console.log("keypress on IE");
+ dijit._lastKeyDownNode = evt.srcElement;
+ });
+}else{
+ dojo.doc.addEventListener('keydown', function(evt){
+ //console.log("keydown, non-IE", evt.target);
+ dijit._lastKeyDownNode = evt.target;
+ }, true);
+}
+
(function(){
var _attrReg = {};
@@ -880,9 +902,7 @@
// Provide widget-specific analog to dojo.connect, except with the
// implicit use of this widget as the target object.
// This version of connect also provides a special "ondijitclick"
- // event which triggers on a click or space-up, enter-down in IE
- // or enter press in FF (since often can't cancel enter onkeydown
- // in FF)
+ // event which triggers on a click or space or enter keyup
// returns:
// A handle that can be passed to `disconnect` in order to disconnect before
// the widget is destroyed.
@@ -901,32 +921,31 @@
var handles =[];
if(event == "ondijitclick"){
// add key based click activation for unsupported nodes.
- if(!this.nodesWithKeyClick[obj.nodeName]){
+ // do all processing onkey up to prevent spurious clicks
+ // for details see comments at top of this file where _lastKeyDownNode is defined
+ if(!this.nodesWithKeyClick[obj.tagName.toLowerCase()]){
var m = d.hitch(this, method);
handles.push(
dc(obj, "onkeydown", this, function(e){
- if(!d.isFF && e.keyCode == d.keys.ENTER &&
+ //console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
+ if((e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
- return m(e);
- }else if(e.keyCode == d.keys.SPACE){
- // stop space down as it causes IE to scroll
- // the browser window
- d.stopEvent(e);
+ // needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
+ dijit._lastKeyDownNode = e.target;
+ d.stopEvent(e); // stop event to prevent scrolling on space key in IE
}
}),
dc(obj, "onkeyup", this, function(e){
- if(e.keyCode == d.keys.SPACE &&
- !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
+ //console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", dijit._lastKeyDownNode, ", equality is ", (e.target === dijit._lastKeyDownNode));
+ if( (e.keyCode == d.keys.ENTER || e.keyCode == d.keys.SPACE) &&
+ e.target === dijit._lastKeyDownNode &&
+ !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){
+ //need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
+ dijit._lastKeyDownNode = null;
+ return m(e);
+ }
})
);
- if(d.isFF){
- handles.push(
- dc(obj, "onkeypress", this, function(e){
- if(e.keyCode == d.keys.ENTER &&
- !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){ return m(e); }
- })
- );
- }
}
event = "onclick";
}
Modified: dijit/trunk/form/Button.js
==============================================================================
--- dijit/trunk/form/Button.js (original)
+++ dijit/trunk/form/Button.js Wed Jun 10 07:29:13 2009
@@ -66,10 +66,6 @@
_onButtonClick: function(/*Event*/ e){
// summary:
// Handler when the user activates the button portion.
- // If is activated via a keystroke, stop the event unless is submit or reset.
- if(e.type!='click' && !(this.type=="submit" || this.type=="reset")){
- dojo.stopEvent(e);
- }
if(this._onClick(e) === false){ // returning nothing is same as true
e.preventDefault(); // needed for checkbox
}else if(this.type=="submit" && !this.focusNode.form){ // see if a nonform widget needs to be signalled
Modified: dijit/trunk/form/templates/Button.html
==============================================================================
--- dijit/trunk/form/templates/Button.html (original)
+++ dijit/trunk/form/templates/Button.html Wed Jun 10 07:29:13 2009
@@ -1,5 +1,5 @@
<span class="dijit dijitReset dijitLeft dijitInline"
- dojoAttachEvent="ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse"
+ dojoAttachEvent="onclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse"
><span class="dijitReset dijitRight dijitInline"
><span class="dijitReset dijitInline dijitButtonNode"
><button class="dijitReset dijitStretch dijitButtonContents"
Modified: dijit/trunk/form/templates/ComboButton.html
==============================================================================
--- dijit/trunk/form/templates/ComboButton.html (original)
+++ dijit/trunk/form/templates/ComboButton.html Wed Jun 10 07:29:13 2009
@@ -2,7 +2,7 @@
cellspacing='0' cellpadding='0' waiRole="presentation"
><tbody waiRole="presentation"><tr waiRole="presentation"
><td class="dijitReset dijitStretch dijitButtonNode"><button class="dijitReset dijitButtonContents"
- dojoAttachEvent="ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" dojoAttachPoint="titleNode"
+ dojoAttachEvent="onclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" dojoAttachPoint="titleNode"
waiRole="button" waiState="labelledby-${id}_label"
><div class="dijitReset dijitInline" dojoAttachPoint="iconNode" waiRole="presentation"></div
><div class="dijitReset dijitInline dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode" waiRole="presentation"></div
Modified: dijit/trunk/tests/_Widget-ondijitclick.html
==============================================================================
--- dijit/trunk/tests/_Widget-ondijitclick.html (original)
+++ dijit/trunk/tests/_Widget-ondijitclick.html Wed Jun 10 07:29:13 2009
@@ -68,5 +68,10 @@
onClick="console.log('onclick on third'); window.spuriousOnDijitClick = true;">
clicking the button above shouldn't cause my ondijitclick handler to fire
</div>
+ <br>
+ <div id="fourth" dojoType="dijit.WidgetWithOndijitclick" tabIndex=0 style="margin-top: 0px;"
+ onClick='alert("make sure can close this alert via keyboard");'>
+ Manual Test: Click me using space or enter to launch a JavaScript alert() from element using ondijitclick
+ </div>
</body>
</html>
Modified: dijit/trunk/tests/form/robot/Button_a11y.html
==============================================================================
--- dijit/trunk/tests/form/robot/Button_a11y.html (original)
+++ dijit/trunk/tests/form/robot/Button_a11y.html Wed Jun 10 07:29:13 2009
@@ -21,6 +21,20 @@
dojo.addOnLoad(function(){
doh.robot.initRobot('../test_Button.html');
+ var submitCount = 0, resetCount = 0;
+
+
+ doh.register("setup", function(){
+ doh.robot.sequence(function(){
+ dojo.connect(dijit.byId("testForm"), "onSubmit", function(){
+ submitCount++;
+ }),
+ dojo.connect(dijit.byId("testForm"), "onReset", function(){
+ resetCount++;
+ })
+ });
+ });
+
doh.register("dijit.form.Button", [
{
name: "enabled",
@@ -350,6 +364,56 @@
}
}
]);
+
+ dojo.forEach(["SPACE", "ENTER"], function(key){
+ doh.register("Invoke Submit and Reset Buttons by " + key, [
+ {
+ name: "click Submit",
+ timeout: 5000,
+ runTest: function(){
+ var d = new doh.Deferred();
+ submitCount = 0;
+ doh.robot.sequence(function(){
+ dijit.byId("bSubmit").focus();
+ });
+ doh.robot.keyPress(dojo.keys[key], 500, {});
+
+ doh.robot.sequence(d.getTestCallback(function(){
+ doh.is(1, submitCount, (key + ": # of times submit invoked " + submitCount));
+ }), 500);
+
+ return d;
+ }
+ },
+
+ {
+ name: "click Reset",
+ timeout: 7000,
+ runTest: function(){
+ var d = new doh.Deferred();
+ resetCount = 0;
+ dijit.byId("testName").value = "";
+
+
+ doh.robot.sequence(function(){
+ dijit.byId("testName").focus();
+ },500);
+ doh.robot.typeKeys("test", 500, 2000);
+
+ doh.robot.sequence(function(){
+ dijit.byId("bReset").focus();
+ },500);
+ doh.robot.keyPress(dojo.keys[key], 500, {});
+
+ doh.robot.sequence(d.getTestCallback(function(){
+ doh.is(1, resetCount, (key + ": reset should be invoked 1 time. actual count = " + resetCount));
+ doh.is("",dijit.byId("testName").value, "Name field has been reset");
+ }), 1000);
+ return d;
+ }
+ }
+ ]);
+ });
doh.run();
});
Modified: dijit/trunk/tests/form/test_Button.html
==============================================================================
--- dijit/trunk/tests/form/test_Button.html (original)
+++ dijit/trunk/tests/form/test_Button.html Wed Jun 10 07:29:13 2009
@@ -34,6 +34,8 @@
dojo.require("dijit.Menu");
dojo.require("dijit.Tooltip");
dojo.require("dijit.form.Button");
+ dojo.require("dijit.form.Form");
+ dojo.require("dijit.form.TextBox");
dojo.require("dojo.parser");
</script>
</head>
@@ -45,8 +47,8 @@
</p>
<p class="box">
<button id="button" onclick="console.log('clicked native button');"><button></button>
- <input id="input" type="button" value="<input type='button'>">
- <button id="1465" dojoType="dijit.form.Button" onClick='console.log("clicked simple")' iconClass="plusIcon" value="Create">
+ <input id="input" type="button" value="<input type='button'>" onclick="console.log('clicked native input button');">
+ <button id="1465" dojoType="dijit.form.Button" onClick='console.log("clicked simple");' iconClass="plusIcon" value="Create">
Create
</button>
<span dojoType="dijit.Tooltip" connectId="1465">tooltip on button</span>
@@ -317,6 +319,24 @@
</script>
<button id="createButton" onclick="createButton();">create dropdown button</button>
<button id="destroyButton" onclick="destroyButton();">destroy dropdown button</button>
-
+
+ <h3>Submit and Reset Buttons</h3>
+ <div>Testing that submit and reset buttons work properly. OnSubmit and OnReset handlers
+ for the form just output to the console.
+ </div>
+ <form dojoType="dijit.form.Form" id="testForm" name="testForm"
+ encType="multipart/form-data" action="../formAction.html" method="" >
+ <script type="dojo/method" event="onReset">
+ console.log("testForm onReset invoked");
+ </script>
+ <script type="dojo/method" event="onSubmit">
+ console.log("testForm onSubmit invoked - not really submitting");
+ return false;
+ </script>
+ <label for="testName">Name: </label><input dojoType="dijit.form.TextBox" id="testName" name="testName" value=""><br>
+ <button dojoType="dijit.form.Button" type="submit" id="bSubmit">Submit</button>
+ <button dojoType="dijit.form.Button" type="reset" id="bReset">Reset</button>
+ </form>
+
</body>
</html>
Modified: dijit/trunk/tests/robot/_Widget-ondijitclick_a11y.html
==============================================================================
--- dijit/trunk/tests/robot/_Widget-ondijitclick_a11y.html (original)
+++ dijit/trunk/tests/robot/_Widget-ondijitclick_a11y.html Wed Jun 10 07:29:13 2009
@@ -37,7 +37,7 @@
// Test ondijitclick on a <div> which refocuses onto a native <button> node.
// Make sure that the <button> doesn't get a spurious click event.
- dojo.forEach(["SPACE" /*** commented out until #8946 and #8978 are fixed , "ENTER" ***/ ], function(key){
+ dojo.forEach(["SPACE", "ENTER"], function(key){
doh.register("ondijitclick by " + key, [
{
@@ -100,7 +100,7 @@
// Test ondijitclick on a <div> which refocuses onto a native <textarea> node.
// Tests that the keyboard event gets supressed so it doesn't modify the focused node.
- dojo.forEach(["SPACE", /*** commented out until #8979 is fixed , "ENTER" ***/ ], function(key){
+ dojo.forEach(["SPACE","ENTER"], function(key){
doh.register("focus to textarea by " + key, [
{
More information about the Dojo-checkins
mailing list