Changeset 12144

Show
Ignore:
Timestamp:
01/23/08 07:49:57 (12 months ago)
Author:
becky
Message:

fixes #4411, #5134 refs # 5133, #4025. Focus now goes to the first focusable item when a dialog or tooltip dialog is opened. If there is no focusable item, focus remains on the dialog or tooltip dialog container.

Location:
dijit/trunk
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • dijit/trunk/Dialog.js

    r12068 r12144  
    136136                duration: 400, 
    137137 
     138                // _firstFocusItem: DomNode 
     139                //              The pointer to the first focusable node in the dialog 
     140                _firstFocusItem:null, 
     141                 
    138142                // _lastFocusItem: DomNode 
    139143                //              The pointer to which node has focus prior to our dialog 
     
    149153                        this.connect(this, "onExecute", "hide"); 
    150154                        this.connect(this, "onCancel", "hide"); 
    151                         this._modalconnects = [];        
     155                        this._modalconnects = []; 
    152156                }, 
    153157 
     
    172176                                "class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ") 
    173177                        }); 
     178                         
     179                        // find and store focusable Items 
     180                        if (!this.firstFocusItem){ 
     181                                var focusItem = dijit.getFirstInTabbingOrder(this.domNode); 
     182                                this._firstFocusItem = focusItem ? focusItem : this.domNode; 
     183                                focusItem = dijit.getLastInTabbingOrder(this.domNode); 
     184                                this._lastFocusItem = focusItem ? focusItem : this._firstFocusItem; 
     185                        } 
    174186 
    175187                        var node = this.domNode; 
     
    228240                }, 
    229241 
    230                 _findLastFocus: function(/*Event*/ evt){ 
    231                         // summary:  called from onblur of dialog container to determine the last focusable item 
    232                         this._lastFocused = evt.target; 
    233                 }, 
    234  
    235                 _cycleFocus: function(/*Event*/ evt){ 
    236                         // summary: when tabEnd receives focus, advance focus around to titleBar 
    237  
    238                         // on first focus to tabEnd, store the last focused item in dialog 
    239                         if(!this._lastFocusItem){ 
    240                                 this._lastFocusItem = this._lastFocused; 
    241                         } 
    242                         this.titleBar.focus(); 
    243                 }, 
    244  
    245242                _onKey: function(/*Event*/ evt){ 
    246243                        // summary: handles the keyboard events for accessibility reasons 
    247244                        if(evt.keyCode){ 
    248245                                var node = evt.target; 
    249                                 // see if we are shift-tabbing from titleBar 
    250                                 if(node == this.titleBar && evt.shiftKey && evt.keyCode == dojo.keys.TAB){ 
    251                                         if(this._lastFocusItem){ 
    252                                                 this._lastFocusItem.focus(); // send focus to last item in dialog if known 
     246                                var singleFocusItem = (this._firstFocusItem == this._lastFocusItem); 
     247                                // see if we are shift-tabbing from first focusable item on dialog 
     248                                if(node == this._firstFocusItem && evt.shiftKey && evt.keyCode == dojo.keys.TAB){ 
     249                                        if(!singleFocusItem){ 
     250                                                dijit.focus(this._lastFocusItem); // send focus to last item in dialog 
     251                                        } 
     252                                        dojo.stopEvent(evt); 
     253                                }else if(node == this._lastFocusItem && evt.keyCode == dojo.keys.TAB && !evt.shiftKey){ 
     254                                        if (!singleFocusItem){ 
     255                                                dijit.focus(this._firstFocusItem); // send focus to first item in dialog 
    253256                                        } 
    254257                                        dojo.stopEvent(evt); 
     
    271274                                        }else if (!dojo.isOpera){ 
    272275                                                try{ 
    273                                                         this.titleBar.focus(); 
     276                                                        this._firstFocusItem.focus(); 
    274277                                                }catch(e){/*squelch*/} 
    275278                                        } 
     
    296299                        this._modalconnects.push(dojo.connect(document.documentElement, "onkeypress", this, "_onKey")); 
    297300 
    298                         // IE doesn't bubble onblur events - use ondeactivate instead 
    299                         var ev = typeof(document.ondeactivate) == "object" ? "ondeactivate" : "onblur"; 
    300                         this._modalconnects.push(dojo.connect(this.containerNode, ev, this, "_findLastFocus")); 
    301  
    302301                        dojo.style(this.domNode, "opacity", 0); 
    303302                        this.domNode.style.display="block"; 
     
    313312                        // set timeout to allow the browser to render dialog 
    314313                        setTimeout(dojo.hitch(this, function(){ 
    315                                 dijit.focus(this.titleBar); 
     314                                dijit.focus(this._firstFocusItem); 
    316315                        }), 50); 
    317316                }, 
     
    372371                title: "", 
    373372 
     373                // _firstFocusItem: DomNode 
     374                //              The pointer to the first focusable node in the dialog 
     375                _firstFocusItem:null, 
     376                 
    374377                // _lastFocusItem: DomNode 
    375378                //              The domNode that had focus before we took it. 
     
    382385                        this.inherited("postCreate",arguments); 
    383386                        this.connect(this.containerNode, "onkeypress", "_onKey"); 
    384  
    385                         // IE doesn't bubble onblur events - use ondeactivate instead 
    386                         var ev = typeof(document.ondeactivate) == "object" ? "ondeactivate" : "onblur"; 
    387                         this.connect(this.containerNode, ev, "_findLastFocus"); 
    388387                        this.containerNode.title=this.title; 
    389388                }, 
     
    396395                onOpen: function(/*Object*/ pos){ 
    397396                        // summary: called when dialog is displayed 
     397                         
     398                        // first time we show the dialog, there's some initialization stuff to do                        
     399                        if(!this._alreadyInitialized){ 
     400                                this._setup(); 
     401                                this._alreadyInitialized=true; 
     402                        } 
     403                         
    398404                        this.orient(this.domNode,pos.aroundCorner, pos.corner); 
    399405                        this._loadCheck(); // lazy load trigger 
    400                         this.containerNode.focus(); 
     406                        dijit.focus(this._firstFocusItem); 
     407                }, 
     408                 
     409                _setup: function(){ 
     410                        // find and store focusable Items 
     411                        var focusItem = dijit.getFirstInTabbingOrder(this.containerNode); 
     412                        this._firstFocusItem = focusItem ? focusItem : this.containerNode; 
     413                        focusItem = dijit.getLastInTabbingOrder(this.containerNode); 
     414                        this._lastFocusItem = focusItem ? focusItem : this._firstFocusItem; 
    401415                }, 
    402416 
    403417                _onKey: function(/*Event*/ evt){ 
    404418                        // summary: keep keyboard focus in dialog; close dialog on escape key 
     419                        var node = evt.target; 
     420                        var singleFocusItem = (this._firstFocusItem == this._lastFocusItem); 
    405421                        if(evt.keyCode == dojo.keys.ESCAPE){ 
    406422                                this.onCancel(); 
    407                         }else if(evt.target == this.containerNode && evt.shiftKey && evt.keyCode == dojo.keys.TAB){ 
    408                                 if (this._lastFocusItem){ 
    409                                         this._lastFocusItem.focus(); 
     423                        }else if(node == this._firstFocusItem && evt.shiftKey && evt.keyCode == dojo.keys.TAB){ 
     424                                if(!singleFocusItem){ 
     425                                        dijit.focus(this._lastFocusItem); // send focus to last item in dialog 
     426                                } 
     427                                dojo.stopEvent(evt); 
     428                        }else if(node == this._lastFocusItem && evt.keyCode == dojo.keys.TAB && !evt.shiftKey){ 
     429                                if(!singleFocusItem){ 
     430                                        dijit.focus(this._firstFocusItem); // send focus to first item in dialog 
    410431                                } 
    411432                                dojo.stopEvent(evt); 
     
    415436                                evt.stopPropagation(); 
    416437                        } 
    417                 }, 
    418  
    419                 _findLastFocus: function(/*Event*/ evt){ 
    420                         // summary: called from onblur of dialog container to determine the last focusable item 
    421                         this._lastFocused = evt.target; 
    422                 }, 
    423  
    424                 _cycleFocus: function(/*Event*/ evt){ 
    425                         // summary: when tabEnd receives focus, advance focus around to containerNode 
    426  
    427                         // on first focus to tabEnd, store the last focused item in dialog 
    428                         if(!this._lastFocusItem){ 
    429                                 this._lastFocusItem = this._lastFocused; 
    430                         } 
    431                         this.containerNode.focus(); 
    432438                } 
    433439        }        
  • dijit/trunk/layout/templates/TooltipDialog.html

    r10527 r12144  
    11<div class="dijitTooltipDialog" > 
    22        <div class="dijitTooltipContainer"> 
    3                 <div class ="dijitTooltipContents dijitTooltipFocusNode" dojoAttachPoint="containerNode" tabindex="0" waiRole="dialog"></div> 
     3                <div class ="dijitTooltipContents dijitTooltipFocusNode" dojoAttachPoint="containerNode" tabindex="-1" waiRole="dialog"></div> 
    44        </div> 
    5         <span dojoAttachPoint="tabEnd" tabindex="0" dojoAttachEvent="focus:_cycleFocus"></span> 
    65        <div class="dijitTooltipConnector" ></div> 
    76</div> 
  • dijit/trunk/templates/Dialog.html

    r11737 r12144  
    1 <div class="dijitDialog"> 
    2         <div dojoAttachPoint="titleBar" class="dijitDialogTitleBar" tabindex="0" waiRole="dialog"> 
    3         <span dojoAttachPoint="titleNode" class="dijitDialogTitle">${title}</span> 
     1<div class="dijitDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title"> 
     2        <div dojoAttachPoint="titleBar" class="dijitDialogTitleBar"> 
     3        <span dojoAttachPoint="titleNode" class="dijitDialogTitle" id="${id}_title">${title}</span> 
    44        <span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="onclick: onCancel"> 
    55                <span dojoAttachPoint="closeText" class="closeText">x</span> 
     
    77        </div> 
    88                <div dojoAttachPoint="containerNode" class="dijitDialogPaneContent"></div> 
    9         <span dojoAttachPoint="tabEnd" dojoAttachEvent="onfocus:_cycleFocus" tabindex="0"></span> 
    109</div> 
  • dijit/trunk/tests/test_Dialog.html

    r11722 r12144  
    162162<div dojoType="dijit.form.DropDownButton"> 
    163163        <span>Test slowloading HREF Tooltip Dialog</span> 
    164         <div dojoType="dijit.TooltipDialog" href="layout/getResponse.php?delay=500&messId=2"> 
     164        <div dojoType="dijit.TooltipDialog" href="layout/getResponse.php?delay=500&messId=2" title="tooltip dialog with no focusable items"> 
    165165        </div> 
    166166</div> |