blob: 9a4120485ffcf4b7cd07c3201128b19c591d7596 [file] [log] [blame]
/*
Copyright (c) 2004-2009, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dojox.grid._FocusManager"]){
dojo._hasResource["dojox.grid._FocusManager"]=true;
dojo.provide("dojox.grid._FocusManager");
dojo.require("dojox.grid.util");
dojo.declare("dojox.grid._FocusManager",null,{constructor:function(_1){
this.grid=_1;
this.cell=null;
this.rowIndex=-1;
this._connects=[];
this.headerMenu=this.grid.headerMenu;
this._connects.push(dojo.connect(this.grid.domNode,"onfocus",this,"doFocus"));
this._connects.push(dojo.connect(this.grid.domNode,"onblur",this,"doBlur"));
this._connects.push(dojo.connect(this.grid.domNode,"oncontextmenu",this,"doContextMenu"));
this._connects.push(dojo.connect(this.grid.lastFocusNode,"onfocus",this,"doLastNodeFocus"));
this._connects.push(dojo.connect(this.grid.lastFocusNode,"onblur",this,"doLastNodeBlur"));
this._connects.push(dojo.connect(this.grid,"_onFetchComplete",this,"_delayedCellFocus"));
this._connects.push(dojo.connect(this.grid,"postrender",this,"_delayedHeaderFocus"));
},destroy:function(){
dojo.forEach(this._connects,dojo.disconnect);
delete this.grid;
delete this.cell;
},_colHeadNode:null,_colHeadFocusIdx:null,_contextMenuBindNode:null,tabbingOut:false,focusClass:"dojoxGridCellFocus",focusView:null,initFocusView:function(){
this.focusView=this.grid.views.getFirstScrollingView()||this.focusView;
this._initColumnHeaders();
},isFocusCell:function(_2,_3){
return (this.cell==_2)&&(this.rowIndex==_3);
},isLastFocusCell:function(){
if(this.cell){
return (this.rowIndex==this.grid.rowCount-1)&&(this.cell.index==this.grid.layout.cellCount-1);
}
return false;
},isFirstFocusCell:function(){
if(this.cell){
return (this.rowIndex===0)&&(this.cell.index===0);
}
return false;
},isNoFocusCell:function(){
return (this.rowIndex<0)||!this.cell;
},isNavHeader:function(){
return (!!this._colHeadNode);
},getHeaderIndex:function(){
if(this._colHeadNode){
return dojo.indexOf(this._findHeaderCells(),this._colHeadNode);
}else{
return -1;
}
},_focusifyCellNode:function(_4){
var n=this.cell&&this.cell.getNode(this.rowIndex);
if(n){
dojo.toggleClass(n,this.focusClass,_4);
if(_4){
var sl=this.scrollIntoView();
try{
if(!this.grid.edit.isEditing()){
dojox.grid.util.fire(n,"focus");
if(sl){
this.cell.view.scrollboxNode.scrollLeft=sl;
}
}
}
catch(e){
}
}
}
},_delayedCellFocus:function(){
if(this.isNavHeader()||!this.grid._focused){
return;
}
var n=this.cell&&this.cell.getNode(this.rowIndex);
if(n){
try{
if(!this.grid.edit.isEditing()){
dojo.toggleClass(n,this.focusClass,true);
this.blurHeader();
dojox.grid.util.fire(n,"focus");
}
}
catch(e){
}
}
},_delayedHeaderFocus:function(){
if(this.isNavHeader()){
this.focusHeader();
this.grid.domNode.focus();
}
},_initColumnHeaders:function(){
var _5=this._findHeaderCells();
for(var i=0;i<_5.length;i++){
this._connects.push(dojo.connect(_5[i],"onfocus",this,"doColHeaderFocus"));
this._connects.push(dojo.connect(_5[i],"onblur",this,"doColHeaderBlur"));
}
},_findHeaderCells:function(){
var _6=dojo.query("th",this.grid.viewsHeaderNode);
var _7=[];
for(var i=0;i<_6.length;i++){
var _8=_6[i];
var _9=dojo.hasAttr(_8,"tabIndex");
var _a=dojo.attr(_8,"tabIndex");
if(_9&&_a<0){
_7.push(_8);
}
}
return _7;
},_setActiveColHeader:function(_b,_c,_d){
dojo.attr(this.grid.domNode,"aria-activedescendant",_b.id);
if(_d!=null&&_d>=0&&_d!=_c){
dojo.toggleClass(this._findHeaderCells()[_d],this.focusClass,false);
}
dojo.toggleClass(_b,this.focusClass,true);
this._colHeadNode=_b;
this._colHeadFocusIdx=_c;
this._scrollHeader(this._colHeadFocusIdx);
},scrollIntoView:function(){
var _e=(this.cell?this._scrollInfo(this.cell):null);
if(!_e||!_e.s){
return null;
}
var rt=this.grid.scroller.findScrollTop(this.rowIndex);
if(_e.n&&_e.sr){
if(_e.n.offsetLeft+_e.n.offsetWidth>_e.sr.l+_e.sr.w){
_e.s.scrollLeft=_e.n.offsetLeft+_e.n.offsetWidth-_e.sr.w;
}else{
if(_e.n.offsetLeft<_e.sr.l){
_e.s.scrollLeft=_e.n.offsetLeft;
}
}
}
if(_e.r&&_e.sr){
if(rt+_e.r.offsetHeight>_e.sr.t+_e.sr.h){
this.grid.setScrollTop(rt+_e.r.offsetHeight-_e.sr.h);
}else{
if(rt<_e.sr.t){
this.grid.setScrollTop(rt);
}
}
}
return _e.s.scrollLeft;
},_scrollInfo:function(_f,_10){
if(_f){
var cl=_f,sbn=cl.view.scrollboxNode,_11={w:sbn.clientWidth,l:sbn.scrollLeft,t:sbn.scrollTop,h:sbn.clientHeight},rn=cl.view.getRowNode(this.rowIndex);
return {c:cl,s:sbn,sr:_11,n:(_10?_10:_f.getNode(this.rowIndex)),r:rn};
}
return null;
},_scrollHeader:function(_12){
var _13=null;
if(this._colHeadNode){
var _14=this.grid.getCell(_12);
_13=this._scrollInfo(_14,_14.getNode(0));
}
if(_13&&_13.s&&_13.sr&&_13.n){
var _15=_13.sr.l+_13.sr.w;
if(_13.n.offsetLeft+_13.n.offsetWidth>_15){
_13.s.scrollLeft=_13.n.offsetLeft+_13.n.offsetWidth-_13.sr.w;
}else{
if(_13.n.offsetLeft<_13.sr.l){
_13.s.scrollLeft=_13.n.offsetLeft;
}else{
if(dojo.isIE<=7&&_14&&_14.view.headerNode){
_14.view.headerNode.scrollLeft=_13.s.scrollLeft;
}
}
}
}
},_isHeaderHidden:function(){
var _16=this.focusView;
if(!_16){
for(var i=0,_17;(_17=this.grid.views.views[i]);i++){
if(_17.headerNode){
_16=_17;
break;
}
}
}
return (_16&&dojo.getComputedStyle(_16.headerNode).display=="none");
},colSizeAdjust:function(e,_18,_19){
var _1a=this._findHeaderCells();
var _1b=this.focusView;
if(!_1b){
for(var i=0,_1c;(_1c=this.grid.views.views[i]);i++){
if(_1c.header.tableMap.map){
_1b=_1c;
break;
}
}
}
var _1d=_1a[_18];
if(!_1b||(_18==_1a.length-1&&_18===0)){
return;
}
_1b.content.baseDecorateEvent(e);
e.cellNode=_1d;
e.cellIndex=_1b.content.getCellNodeIndex(e.cellNode);
e.cell=(e.cellIndex>=0?this.grid.getCell(e.cellIndex):null);
if(_1b.header.canResize(e)){
var _1e={l:_19};
var _1f=_1b.header.colResizeSetup(e,false);
_1b.header.doResizeColumn(_1f,null,_1e);
_1b.update();
}
},styleRow:function(_20){
return;
},setFocusIndex:function(_21,_22){
this.setFocusCell(this.grid.getCell(_22),_21);
},setFocusCell:function(_23,_24){
if(_23&&!this.isFocusCell(_23,_24)){
this.tabbingOut=false;
if(this._colHeadNode){
this.blurHeader();
}
this._colHeadNode=this._colHeadFocusIdx=null;
this.focusGridView();
this._focusifyCellNode(false);
this.cell=_23;
this.rowIndex=_24;
this._focusifyCellNode(true);
}
if(dojo.isOpera){
setTimeout(dojo.hitch(this.grid,"onCellFocus",this.cell,this.rowIndex),1);
}else{
this.grid.onCellFocus(this.cell,this.rowIndex);
}
},next:function(){
if(this.cell){
var row=this.rowIndex,col=this.cell.index+1,cc=this.grid.layout.cellCount-1,rc=this.grid.rowCount-1;
if(col>cc){
col=0;
row++;
}
if(row>rc){
col=cc;
row=rc;
}
if(this.grid.edit.isEditing()){
var _25=this.grid.getCell(col);
if(!this.isLastFocusCell()&&!_25.editable){
this.cell=_25;
this.rowIndex=row;
this.next();
return;
}
}
this.setFocusIndex(row,col);
}
},previous:function(){
if(this.cell){
var row=(this.rowIndex||0),col=(this.cell.index||0)-1;
if(col<0){
col=this.grid.layout.cellCount-1;
row--;
}
if(row<0){
row=0;
col=0;
}
if(this.grid.edit.isEditing()){
var _26=this.grid.getCell(col);
if(!this.isFirstFocusCell()&&!_26.editable){
this.cell=_26;
this.rowIndex=row;
this.previous();
return;
}
}
this.setFocusIndex(row,col);
}
},move:function(_27,_28){
var _29=_28<0?-1:1;
if(this.isNavHeader()){
var _2a=this._findHeaderCells();
var _2b=currentIdx=dojo.indexOf(_2a,this._colHeadNode);
currentIdx+=_28;
while(currentIdx>=0&&currentIdx<_2a.length&&_2a[currentIdx].style.display=="none"){
currentIdx+=_29;
}
if((currentIdx>=0)&&(currentIdx<_2a.length)){
this._setActiveColHeader(_2a[currentIdx],currentIdx,_2b);
}
}else{
if(this.cell){
var sc=this.grid.scroller,r=this.rowIndex,rc=this.grid.rowCount-1,row=Math.min(rc,Math.max(0,r+_27));
if(_27){
if(_27>0){
if(row>sc.getLastPageRow(sc.page)){
this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r));
}
}else{
if(_27<0){
if(row<=sc.getPageRow(sc.page)){
this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row));
}
}
}
}
var cc=this.grid.layout.cellCount-1,i=this.cell.index,col=Math.min(cc,Math.max(0,i+_28));
var _2c=this.grid.getCell(col);
while(col>=0&&col<cc&&_2c&&_2c.hidden===true){
col+=_29;
_2c=this.grid.getCell(col);
}
if(!_2c||_2c.hidden===true){
col=i;
}
this.setFocusIndex(row,col);
if(_27){
this.grid.updateRow(r);
}
}
}
},previousKey:function(e){
if(this.grid.edit.isEditing()){
dojo.stopEvent(e);
this.previous();
}else{
if(!this.isNavHeader()&&!this._isHeaderHidden()){
this.grid.domNode.focus();
dojo.stopEvent(e);
}else{
this.tabOut(this.grid.domNode);
if(this._colHeadFocusIdx!=null){
dojo.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx],this.focusClass,false);
this._colHeadFocusIdx=null;
}
this._focusifyCellNode(false);
}
}
},nextKey:function(e){
var _2d=(this.grid.rowCount===0);
if(e.target===this.grid.domNode&&this._colHeadFocusIdx==null){
this.focusHeader();
dojo.stopEvent(e);
}else{
if(this.isNavHeader()){
this.blurHeader();
if(!this.findAndFocusGridCell()){
this.tabOut(this.grid.lastFocusNode);
}
this._colHeadNode=this._colHeadFocusIdx=null;
}else{
if(this.grid.edit.isEditing()){
dojo.stopEvent(e);
this.next();
}else{
this.tabOut(this.grid.lastFocusNode);
}
}
}
},tabOut:function(_2e){
this.tabbingOut=true;
_2e.focus();
},focusGridView:function(){
dojox.grid.util.fire(this.focusView,"focus");
},focusGrid:function(_2f){
this.focusGridView();
this._focusifyCellNode(true);
},findAndFocusGridCell:function(){
var _30=true;
var _31=(this.grid.rowCount===0);
if(this.isNoFocusCell()&&!_31){
var _32=0;
var _33=this.grid.getCell(_32);
if(_33.hidden){
_32=this.isNavHeader()?this._colHeadFocusIdx:0;
}
this.setFocusIndex(0,_32);
}else{
if(this.cell&&!_31){
if(this.focusView&&!this.focusView.rowNodes[this.rowIndex]){
this.grid.scrollToRow(this.rowIndex);
}
this.focusGrid();
}else{
_30=false;
}
}
this._colHeadNode=this._colHeadFocusIdx=null;
return _30;
},focusHeader:function(){
var _34=this._findHeaderCells();
var _35=this._colHeadFocusIdx;
if(this._isHeaderHidden()){
this.findAndFocusGridCell();
}else{
if(!this._colHeadFocusIdx){
if(this.isNoFocusCell()){
this._colHeadFocusIdx=0;
}else{
this._colHeadFocusIdx=this.cell.index;
}
}
}
this._colHeadNode=_34[this._colHeadFocusIdx];
while(this._colHeadNode&&this._colHeadFocusIdx>=0&&this._colHeadFocusIdx<_34.length&&this._colHeadNode.style.display=="none"){
this._colHeadFocusIdx++;
this._colHeadNode=_34[this._colHeadFocusIdx];
}
if(this._colHeadNode&&this._colHeadNode.style.display!="none"){
if(this.headerMenu&&this._contextMenuBindNode!=this.grid.domNode){
this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode);
this.headerMenu.bindDomNode(this.grid.domNode);
this._contextMenuBindNode=this.grid.domNode;
}
this._setActiveColHeader(this._colHeadNode,this._colHeadFocusIdx,_35);
this._scrollHeader(this._colHeadFocusIdx);
this._focusifyCellNode(false);
}else{
this.findAndFocusGridCell();
}
},blurHeader:function(){
dojo.removeClass(this._colHeadNode,this.focusClass);
dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
if(this.headerMenu&&this._contextMenuBindNode==this.grid.domNode){
var _36=this.grid.viewsHeaderNode;
this.headerMenu.unBindDomNode(this.grid.domNode);
this.headerMenu.bindDomNode(_36);
this._contextMenuBindNode=_36;
}
},doFocus:function(e){
if(e&&e.target!=e.currentTarget){
dojo.stopEvent(e);
return;
}
if(!this.tabbingOut){
this.focusHeader();
}
this.tabbingOut=false;
dojo.stopEvent(e);
},doBlur:function(e){
dojo.stopEvent(e);
},doContextMenu:function(e){
if(!this.headerMenu){
dojo.stopEvent(e);
}
},doLastNodeFocus:function(e){
if(this.tabbingOut){
this._focusifyCellNode(false);
}else{
if(this.grid.rowCount>0){
if(this.isNoFocusCell()){
this.setFocusIndex(0,0);
}
this._focusifyCellNode(true);
}else{
this.focusHeader();
}
}
this.tabbingOut=false;
dojo.stopEvent(e);
},doLastNodeBlur:function(e){
dojo.stopEvent(e);
},doColHeaderFocus:function(e){
this._setActiveColHeader(e.target,dojo.attr(e.target,"idx"),this._colHeadFocusIdx);
this._scrollHeader(this.getHeaderIndex());
dojo.stopEvent(e);
},doColHeaderBlur:function(e){
dojo.toggleClass(e.target,this.focusClass,false);
}});
}