blob: 0f8bdb3a3fc78fd5d9145a52294cce11bf8a5e89 [file] [log] [blame]
/*
Copyright (c) 2004-2005, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.event.browser");
dojo.require("dojo.event");
dojo_ie_clobber = new function(){
this.clobberNodes = [];
function nukeProp(node, prop){
// try{ node.removeAttribute(prop); }catch(e){ /* squelch */ }
try{ node[prop] = null; }catch(e){ /* squelch */ }
try{ delete node[prop]; }catch(e){ /* squelch */ }
// FIXME: JotLive needs this, but I'm not sure if it's too slow or not
try{ node.removeAttribute(prop); }catch(e){ /* squelch */ }
}
this.clobber = function(nodeRef){
var na;
var tna;
if(nodeRef){
tna = nodeRef.getElementsByTagName("*");
na = [nodeRef];
for(var x=0; x<tna.length; x++){
// if we're gonna be clobbering the thing, at least make sure
// we aren't trying to do it twice
if(tna[x]["__doClobber__"]){
na.push(tna[x]);
}
}
}else{
try{ window.onload = null; }catch(e){}
na = (this.clobberNodes.length) ? this.clobberNodes : document.all;
}
tna = null;
var basis = {};
for(var i = na.length-1; i>=0; i=i-1){
var el = na[i];
if(el["__clobberAttrs__"]){
for(var j=0; j<el.__clobberAttrs__.length; j++){
nukeProp(el, el.__clobberAttrs__[j]);
}
nukeProp(el, "__clobberAttrs__");
nukeProp(el, "__doClobber__");
}
}
na = null;
}
}
if(dojo.render.html.ie){
window.onunload = function(){
dojo_ie_clobber.clobber();
try{
if((dojo["widget"])&&(dojo.widget["manager"])){
dojo.widget.manager.destroyAll();
}
}catch(e){}
try{ window.onload = null; }catch(e){}
try{ window.onunload = null; }catch(e){}
dojo_ie_clobber.clobberNodes = [];
// CollectGarbage();
}
}
dojo.event.browser = new function(){
var clobberIdx = 0;
this.clean = function(node){
if(dojo.render.html.ie){
dojo_ie_clobber.clobber(node);
}
}
this.addClobberNode = function(node){
if(!node["__doClobber__"]){
node.__doClobber__ = true;
dojo_ie_clobber.clobberNodes.push(node);
// this might not be the most efficient thing to do, but it's
// much less error prone than other approaches which were
// previously tried and failed
node.__clobberAttrs__ = [];
}
}
this.addClobberNodeAttrs = function(node, props){
this.addClobberNode(node);
for(var x=0; x<props.length; x++){
node.__clobberAttrs__.push(props[x]);
}
}
this.removeListener = function(node, evtName, fp, capture){
if(!capture){ var capture = false; }
evtName = evtName.toLowerCase();
if(evtName.substr(0,2)=="on"){ evtName = evtName.substr(2); }
// FIXME: this is mostly a punt, we aren't actually doing anything on IE
if(node.removeEventListener){
node.removeEventListener(evtName, fp, capture);
}
}
this.addListener = function(node, evtName, fp, capture, dontFix){
if(!node){ return; } // FIXME: log and/or bail?
if(!capture){ var capture = false; }
evtName = evtName.toLowerCase();
if(evtName.substr(0,2)!="on"){ evtName = "on"+evtName; }
if(!dontFix){
// build yet another closure around fp in order to inject fixEvent
// around the resulting event
var newfp = function(evt){
if(!evt){ evt = window.event; }
var ret = fp(dojo.event.browser.fixEvent(evt));
if(capture){
dojo.event.browser.stopEvent(evt);
}
return ret;
}
}else{
newfp = fp;
}
if(node.addEventListener){
node.addEventListener(evtName.substr(2), newfp, capture);
return newfp;
}else{
if(typeof node[evtName] == "function" ){
var oldEvt = node[evtName];
node[evtName] = function(e){
oldEvt(e);
return newfp(e);
}
}else{
node[evtName]=newfp;
}
if(dojo.render.html.ie){
this.addClobberNodeAttrs(node, [evtName]);
}
return newfp;
}
}
this.isEvent = function(obj){
// FIXME: event detection hack ... could test for additional attributes
// if necessary
return (typeof obj != "undefined")&&(typeof Event != "undefined")&&(obj.eventPhase);
// Event does not support instanceof in Opera, otherwise:
//return (typeof Event != "undefined")&&(obj instanceof Event);
}
this.currentEvent = null;
this.callListener = function(listener, curTarget){
if(typeof listener != 'function'){
dojo.raise("listener not a function: " + listener);
}
dojo.event.browser.currentEvent.currentTarget = curTarget;
return listener.call(curTarget, dojo.event.browser.currentEvent);
}
this.stopPropagation = function(){
dojo.event.browser.currentEvent.cancelBubble = true;
}
this.preventDefault = function(){
dojo.event.browser.currentEvent.returnValue = false;
}
this.keys = {
KEY_BACKSPACE: 8,
KEY_TAB: 9,
KEY_ENTER: 13,
KEY_SHIFT: 16,
KEY_CTRL: 17,
KEY_ALT: 18,
KEY_PAUSE: 19,
KEY_CAPS_LOCK: 20,
KEY_ESCAPE: 27,
KEY_SPACE: 32,
KEY_PAGE_UP: 33,
KEY_PAGE_DOWN: 34,
KEY_END: 35,
KEY_HOME: 36,
KEY_LEFT_ARROW: 37,
KEY_UP_ARROW: 38,
KEY_RIGHT_ARROW: 39,
KEY_DOWN_ARROW: 40,
KEY_INSERT: 45,
KEY_DELETE: 46,
KEY_LEFT_WINDOW: 91,
KEY_RIGHT_WINDOW: 92,
KEY_SELECT: 93,
KEY_F1: 112,
KEY_F2: 113,
KEY_F3: 114,
KEY_F4: 115,
KEY_F5: 116,
KEY_F6: 117,
KEY_F7: 118,
KEY_F8: 119,
KEY_F9: 120,
KEY_F10: 121,
KEY_F11: 122,
KEY_F12: 123,
KEY_NUM_LOCK: 144,
KEY_SCROLL_LOCK: 145
};
// reverse lookup
this.revKeys = [];
for(var key in this.keys){
this.revKeys[this.keys[key]] = key;
}
this.fixEvent = function(evt){
if((!evt)&&(window["event"])){
var evt = window.event;
}
if((evt["type"])&&(evt["type"].indexOf("key") == 0)){ // key events
evt.keys = this.revKeys;
// FIXME: how can we eliminate this iteration?
for(var key in this.keys) {
evt[key] = this.keys[key];
}
if((dojo.render.html.ie)&&(evt["type"] == "keypress")){
evt.charCode = evt.keyCode;
}
}
if(dojo.render.html.ie){
if(!evt.target){ evt.target = evt.srcElement; }
if(!evt.currentTarget){ evt.currentTarget = evt.srcElement; }
if(!evt.layerX){ evt.layerX = evt.offsetX; }
if(!evt.layerY){ evt.layerY = evt.offsetY; }
// mouseover
if(evt.fromElement){ evt.relatedTarget = evt.fromElement; }
// mouseout
if(evt.toElement){ evt.relatedTarget = evt.toElement; }
this.currentEvent = evt;
evt.callListener = this.callListener;
evt.stopPropagation = this.stopPropagation;
evt.preventDefault = this.preventDefault;
}
return evt;
}
this.stopEvent = function(ev) {
if(window.event){
ev.returnValue = false;
ev.cancelBubble = true;
}else{
ev.preventDefault();
ev.stopPropagation();
}
}
}