mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-01 20:34:20 +01:00
249 lines
8.2 KiB
JavaScript
249 lines
8.2 KiB
JavaScript
|
/*
|
||
|
DynAPI Distribution
|
||
|
DynKeyEvent Extensions
|
||
|
|
||
|
The DynAPI Distribution is distributed under the terms of the GNU LGPL license.
|
||
|
|
||
|
Requirements:
|
||
|
dynapi.api
|
||
|
*/
|
||
|
function DynKeyEvent(type,src) {
|
||
|
this.DynEvent = DynEvent;
|
||
|
this.DynEvent(type,src);
|
||
|
this.charKey=null;
|
||
|
};
|
||
|
var p=dynapi.setPrototype('DynKeyEvent','DynEvent');
|
||
|
p.getKey=function() {
|
||
|
return this.charKey;
|
||
|
};
|
||
|
DynKeyEvent._keyEventListener=function(e) {
|
||
|
var dynobj=this._dynobj;
|
||
|
if(!dynobj)
|
||
|
return true;
|
||
|
var dyndoc=dynobj.doc._dynobj;
|
||
|
if(!dyndoc) return true;
|
||
|
if(!e) var e=dyndoc.frame.event;
|
||
|
|
||
|
var evt=new DynKeyEvent(e.type,dynobj);
|
||
|
evt.which=(e.keyCode)?e.keyCode:e.which;
|
||
|
var key=String.fromCharCode(evt.which).toLowerCase();
|
||
|
if((key>='a'&&key<='z')||(key>='0'&&key<='9')) evt.charKey=key;
|
||
|
evt.spaceKey=(evt.which==32);
|
||
|
evt.enterKey=(evt.which==13);
|
||
|
evt.tabKey=(evt.which==9||evt.which==65289);
|
||
|
evt.leftKey=(evt.which==37||evt.which==52||evt.which==100||evt.which==65460);
|
||
|
evt.rightKey=(evt.which==39||evt.which==54||evt.which==102||evt.which==65462);
|
||
|
evt.upKey=(evt.which==38||evt.which==56||evt.which==104||evt.which==65464);
|
||
|
evt.downKey=(evt.which==40||evt.which==50||evt.which==98||evt.which==65458);
|
||
|
evt.altKey=(e.modifiers)?false:(e.altKey||e.altLeft||evt.which==18||evt.which==57388);
|
||
|
evt.ctrlKey=(e.modifiers)?(e.modifiers&Event.CONTROL_MASK):(e.ctrlKey||e.ctrlLeft||evt.which==17||evt.which==57391);
|
||
|
evt.shiftKey=(e.modifiers)?(e.modifiers&Event.SHIFT_MASK):(e.shiftKey||e.shiftLeft||evt.which==16||evt.which==57390);
|
||
|
|
||
|
dynobj.invokeEvent(evt.type,evt);
|
||
|
if(evt.defaultValue==false) {
|
||
|
if(e.cancelBubble) e.cancelBubble=true;
|
||
|
if(e.stopPropagation) e.stopPropagation();
|
||
|
}
|
||
|
return evt.defaultValue;
|
||
|
};
|
||
|
|
||
|
TabManager={};
|
||
|
TabManager._c=0; // Current tab manager index.
|
||
|
TabManager._all=[];
|
||
|
TabManager._active=false;
|
||
|
TabManager._activeTimeout=function() { // Prevent duplcate keydown events in NS4.
|
||
|
TabManager._active=true;
|
||
|
setTimeout('TabManager._active=false;',25);
|
||
|
};
|
||
|
TabManager._getForm=null;
|
||
|
TabManager.getForm=function(p) { // Prevent default tab focus in Mozilla.
|
||
|
if(TabManager._getForm) return;
|
||
|
TabManager._getForm=p;
|
||
|
var html='<form name="__frm" onsubmit="return false;"><input name="__tab" size=1></form>';
|
||
|
return p.addChild(new DynLayer(html),'__lyr');
|
||
|
};
|
||
|
TabManager._grabFocus=function() {
|
||
|
var form=TabManager._getForm.__lyr;
|
||
|
setTimeout(form+'.doc.forms.__frm.__tab.focus();',0);
|
||
|
};
|
||
|
TabManager._el={};
|
||
|
TabManager._el.onkeydown=function(e) {
|
||
|
if(TabManager._getForm) { // User must have inserted TabManager form.
|
||
|
if(TabManager._active) return;
|
||
|
TabManager._activeTimeout();
|
||
|
}
|
||
|
var i1,o1,l1,i2,o2,l2;
|
||
|
var nextKey=(e.tabKey||e.rightKey);
|
||
|
var prevKey=((e.shiftKey&&e.tabKey)||e.leftKey);
|
||
|
var submitKey=(e.enterKey||e.spaceKey);
|
||
|
i1=TabManager._c; o1=TabManager._all[i1]; l1=TabManager._all.length;
|
||
|
i2=o1._tabGroup._c; o2=o1._tabGroup._all[i2]; l2=o1._tabGroup._all.length;
|
||
|
if(nextKey||prevKey) { // Cycle group.
|
||
|
if(o2._hasFocusEvents) o2.setFocus(false,o2._focusBubble);
|
||
|
else o2.invokeEvent('blur');
|
||
|
if(prevKey) i2=(i2==0)?l2-1:i2-1;
|
||
|
else i2=(i2==l2-1)?0:i2+1;
|
||
|
o2=o1._tabGroup._all[i2]; o1._tabGroup._c=i2;
|
||
|
if(o2._hasFocusEvents) o2.setFocus(true,o2._focusBubble);
|
||
|
else o2.invokeEvent('focus');
|
||
|
}
|
||
|
else if(e.upKey||e.downKey) { // Cycle manager.
|
||
|
if(o2._hasFocusEvents) o2.setFocus(false,o2._focusBubble);
|
||
|
else o2.invokeEvent('blur');
|
||
|
if(e.upKey) i1=(i1==0)?l1-1:i1-1;
|
||
|
else i1=(i1==l1-1)?0:i1+1;
|
||
|
o1=TabManager._all[i1]; TabManager._c=i1;
|
||
|
i2=o1._tabGroup._c;
|
||
|
o2=o1._tabGroup._all[i2];
|
||
|
if(o2._hasFocusEvents) o2.setFocus(true,o2._focusBubble);
|
||
|
else o2.invokeEvent('focus');
|
||
|
} else if(submitKey) {
|
||
|
o2.invokeEvent('submit');
|
||
|
}
|
||
|
e.preventDefault();
|
||
|
if(TabManager._getForm) TabManager._grabFocus();
|
||
|
};
|
||
|
DynElement.prototype.createTabManager=function() {
|
||
|
var p=this, c=p.children; if(!c) return;
|
||
|
var args=(arguments.length)?arguments:c;
|
||
|
var l=args.length, s; if(!l) return;
|
||
|
if(p._tabGroup) delete p._tabGroup;
|
||
|
p._tabGroup={ _c:0, _all:[] };
|
||
|
for(var i=0;i<l;i++) {
|
||
|
c=args[i];
|
||
|
p._tabGroup._all[i]=c;
|
||
|
c._hasTabManager=true;
|
||
|
if(!c._submitFn) {
|
||
|
s=c.id.replace(/-/g,'.')+'()'; // Element id callback.
|
||
|
c._submitFn=s;
|
||
|
}
|
||
|
}
|
||
|
l=TabManager._all.length; TabManager._all[l]=p;
|
||
|
if(l==0) dynapi.onLoad(function() {
|
||
|
dynapi.document.addEventListener(TabManager._el);
|
||
|
});
|
||
|
};
|
||
|
DynElement.prototype.updateTabManager=function() {
|
||
|
var tm=TabManager, all=tm._all[TabManager._c]; if(!all) return;
|
||
|
var old=all._tabGroup; if(!old||old._all[old._c]==this) return;
|
||
|
var p=this.parent, l;
|
||
|
var tg=(p&&p._tabGroup)?p._tabGroup:null; if(!tg) return;
|
||
|
l=tg._all.length;
|
||
|
for(var i=0;i<l;i++) if(tg._all[i]==this) { tg._c=i; break; }
|
||
|
l=tm._all.length;
|
||
|
for(var i=0;i<l;i++) if(tm._all[i]==p) { tm._c=i; break; }
|
||
|
};
|
||
|
DynElement.prototype.addTabListeners=function(el) {
|
||
|
if(el&&this._tabGroup) {
|
||
|
var a=this._tabGroup._all;
|
||
|
for(var i in a) a[i].addEventListener(el);
|
||
|
}
|
||
|
};
|
||
|
DynElement.prototype.addSubmitFn=function(fn) {
|
||
|
if(fn) this._submitFn=fn;
|
||
|
};
|
||
|
DynElement.prototype.callSubmitFn=function() {
|
||
|
var f=this._submitFn;
|
||
|
if(typeof(f)=='function') f();
|
||
|
else if(typeof(f)=='string') eval(f);
|
||
|
};
|
||
|
|
||
|
DynElement.prototype.captureKeyEvents=function() {
|
||
|
// This impossibilitates Inheritance... changing to the same aproach as captureMouseEvents
|
||
|
//var elm=(this.getClassName()=='DynLayer')?this.elm:this.doc;
|
||
|
var elm;
|
||
|
|
||
|
if (this.getKeyEventElement) elm = this.getKeyEventElement();
|
||
|
else elm=(this.getClassName()=='DynDocument')?this.doc:this.elm;
|
||
|
|
||
|
//if(!elm||this._hasKeyEvents) return true;
|
||
|
if (!elm) return true;
|
||
|
if(elm.addEventListener) {
|
||
|
elm.addEventListener("keydown",DynKeyEvent._keyEventListener,false);
|
||
|
elm.addEventListener("keypress",DynKeyEvent._keyEventListener,false);
|
||
|
elm.addEventListener("keyup",DynKeyEvent._keyEventListener,false);
|
||
|
elm.addEventListener("blur",DynKeyEvent._keyEventListener,false);
|
||
|
elm.addEventListener("focus",DynKeyEvent._keyEventListener,false);
|
||
|
}
|
||
|
else {
|
||
|
if(elm.captureEvents)
|
||
|
elm.captureEvents(Event.KEYPRESS|Event.KEYDOWN|Event.KEYUP);
|
||
|
elm.onblur=elm.onfocus=elm.onkeydown=elm.onkeypress=elm.onkeyup=DynKeyEvent._keyEventListener;
|
||
|
}
|
||
|
this._hasKeyEvents=true;
|
||
|
return false;
|
||
|
};
|
||
|
DynElement.prototype.releaseKeyEvents=function() {
|
||
|
var elm=(this.getClassName()=='DynLayer')?this.elm:this.doc;
|
||
|
if(!elm||!this._hasKeyEvents) return true;
|
||
|
if(elm.removeEventListener) {
|
||
|
elm.removeEventListener("keydown",DynKeyEvent._keyEventListener,false);
|
||
|
elm.removeEventListener("keypress",DynKeyEvent._keyEventListener,false);
|
||
|
elm.removeEventListener("keyup",DynKeyEvent._keyEventListener,false);
|
||
|
}
|
||
|
else {
|
||
|
if(elm.releaseEvents)
|
||
|
elm.releaseEvents(Event.KEYPRESS|Event.KEYDOWN|Event.KEYUP);
|
||
|
elm.onkeydown=elm.onkeypress=elm.onkeyup=null;
|
||
|
}
|
||
|
this._hasKeyEvents=false;
|
||
|
return false;
|
||
|
};
|
||
|
|
||
|
DynDocument.prototype.captureHotKey = function(key,fn){
|
||
|
var klst=((key+'').toLowerCase()).split('+');
|
||
|
klst.sort();
|
||
|
key=klst.join('+');
|
||
|
if(!this._hotKeys){
|
||
|
this._hotKeys={};
|
||
|
this._keyDn={};
|
||
|
this._keyLst='';
|
||
|
this.captureKeyEvents();
|
||
|
this.addEventListener({
|
||
|
onkeydown:function(e){
|
||
|
var k = e.which;
|
||
|
var o = e.getSource();
|
||
|
// to-do: add opera v7 key code (57xxx), e.g 57388
|
||
|
if (k==13) k="enter";
|
||
|
else if(k==27) k="esc";
|
||
|
else if(k==45) k="insert";
|
||
|
else if(k==46) k="delete";
|
||
|
else if(k==36) k="home";
|
||
|
else if(k==35) k="end";
|
||
|
else if(k==33) k="pgup";
|
||
|
else if(k==34) k="pgdn";
|
||
|
else if(k==38) k="up";
|
||
|
else if(k==40) k="down";
|
||
|
else if(k==37) k="left";
|
||
|
else if(k==39) k="right";
|
||
|
else if(e.altKey && !o._keyDn['alt']) k="alt";
|
||
|
else if(e.ctrlKey && !o._keyDn['ctrl']) k="ctrl";
|
||
|
else if(e.shiftKey && !o._keyDn['shift']) k="shift";
|
||
|
else k=(String.fromCharCode(k)).toLowerCase();
|
||
|
if(!o._keyDn[k]) {
|
||
|
// store new key in keyDn array
|
||
|
o._keyLst+=(((o._keyLst)? '+':'')+k); // build key list
|
||
|
var ar=o._keyLst.split('+');
|
||
|
ar.sort();
|
||
|
o._keyLst=ar.join('+');
|
||
|
o._keyDn[k]=true;
|
||
|
}
|
||
|
k=o._hotKeys[o._keyLst];
|
||
|
if(k){
|
||
|
o._keyLst='';o._keyDn={};
|
||
|
if(typeof(k)=='string') return eval(k); else return k();
|
||
|
}
|
||
|
},
|
||
|
onkeyup:function(e){
|
||
|
var o=e.getSource();
|
||
|
o._keyLst='';o._keyDn={};
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
this._hotKeys[key]=fn;
|
||
|
};
|
||
|
DynDocument.prototype.releaseHotKey = function(key){
|
||
|
if(this._hotKeys) delete this._hotKeys[key];
|
||
|
};
|
||
|
|