event.js
Summary
DOM Event related methods.
Project Homepage: http://mozile.mozdev.org
Version: 0.8
$Id: overview-summary-event.js.html,v 1.9 2006/08/23 23:30:17 jameso Exp $
Author: James A. Overton
mozile.require("mozile.dom");
mozile.require("mozile.edit");
mozile.provide("mozile.event.*");
mozile.event = new Object();
mozile.event.prototype = new mozile.Module;
mozile.event.mousedown = false;
mozile.event.normalize = function(event) {
if(!event) return event;
if(typeof(event.target) == "undefined") event.target = event.srcElement;
if(typeof(event.charCode) == "undefined") event.charCode = event.keyCode;
return event;
}
mozile.event.addListener = function(doc, type, listener, useCapture) {
if(!listener) listener = mozile.event.handle;
if(doc.addEventListener) doc.addEventListener(type, listener, useCapture);
else if(doc.attachEvent) doc.attachEvent("on" + type, listener);
else mozile.debug.inform("mozile.event.addListener", "No known event method available");
}
mozile.event.listen = function() {
var events = ["mousedown", "mousemove", "mouseup", "click", "dblclick", "keydown", "keyup", "keypress"];
for(var i=0; i < events.length; i++) {
mozile.event.addListener(document, events[i]);
}
}
mozile.event.dispatch = function(element, type, keyCode, charCode, ctrlKey, altKey, shiftKey, metaKey) {
if(element.fireEvent) element.fireEvent("on"+type);
else if(element.dispatchEvent) {
var event;
if(type.indexOf("click") > -1 || type.indexOf("mouse") > -1) {
event = document.createEvent("MouseEvent");
event.initMouseEvent(type, true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 1, null);
}
else if(type.indexOf("key") > -1) {
if(!ctrlKey) ctrlKey = false;
if(!altKey) altKey = false;
if(!shiftKey) shiftKey = false;
if(!metaKey) metaKey = false;
event = document.createEvent("KeyEvent");
event.initKeyEvent(type, true, true, document.defaultView, ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode);
}
else {
event = document.createEvent("Events");
event.initEvent(type, true, true);
}
element.dispatchEvent(event);
}
}
mozile.event.cancel = function(event) {
if(!event) return;
if(event.stopPropagation) event.stopPropagation();
event.cancelBubble = true;
if(event.preventDefault) event.preventDefault();
}
mozile.event.handle = function(event) {
try {
switch(event.type) {
case "mousemove":
return mozile.event.handleMouseMove(event);
case "mouseup":
case "click":
case "dblclick":
mozile.event.mousedown = false;
}
event = mozile.event.normalize(event);
mozile.event.findTarget(event);
if(!event.node) return true;
event.container = mozile.edit.getContainer(event.node);
event.editable = Boolean(event.container);
var state = mozile.edit.handleEvent(event);
if(state) return mozile.event.handled(event, state);
if(mozile.gui) mozile.gui.update(event);
if(!mozile.edit.editable) return true;
var priorStatus = mozile.edit.status;
mozile.edit.setStatus(event.editable);
if(!event.editable) return true;
mozile.event.storeSelection(event);
if(!priorStatus) mozile.event.fixFocus(event);
var node = event.node;
while(event.node) {
if(!event.rng) event.rng = mozile.edit.lookupRNG(event.node);
if(event.rng) {
state = event.rng.handleEvent(event);
if(state) return mozile.event.handled(event, state);
}
if(event.node == event.container) break;
else event.node = event.node.parentNode;
}
event.node = node;
state = mozile.edit.handleDefault(event);
if(state) return mozile.event.handled(event, state);
if(!mozile.event.cancelKeyEvent(event)) return false;
if(!mozile.event.cancelHyperlink(event)) return false;
} catch(e) { mozile.debug.inform("mozile.event.handle", mozile.dumpError(e)); }
return true;
}
mozile.event.handled = function(event, state) {
mozile.edit.done(state);
if(state.changesMade) {
if(mozile.gui) mozile.gui.update(event, state.changesMade);
}
if(state.cancel) {
mozile.event.cancel(event);
return false;
}
else return true;
}
mozile.event.handleMouseMove = function(event) {
if(!mozile.browser.isMozilla) return true;
if(!mozile.event.mousedown) return true;
var selection = mozile.dom.selection.get();
if(!selection) return true;
if(selection.focusNode != event.rangeParent ||
selection.focusOffset != event.rangeOffset) {
selection.extend(event.rangeParent, event.rangeOffset);
}
return true;
}
mozile.event.findTarget = function(event) {
event.selection = mozile.dom.selection.get();
if(!event.selection || event.selection.rangeCount < 1) return;
event.range = event.selection.getRangeAt(0);
if(!event.range) return;
event.node = event.range.commonAncestorContainer;
}
mozile.event.storeSelection = function(event) {
mozile.dom.selection.last = {
anchorNode: event.selection.anchorNode,
anchorOffset: event.selection.anchorOffset,
focusNode: event.selection.focusNode,
focusOffset: event.selection.focusOffset,
isCollapsed: event.selection.isCollapsed
};
}
mozile.event.fixFocus = function(event) {
if(!mozile.browser.isMozilla) return;
if(!mozile.useDesignMode) return;
if(event.type != "mousedown") return;
var newEvent = document.createEvent("MouseEvent");
newEvent.initMouseEvent("mousedown", true, true, event.view, 1, event.screenX, event.screenY, event.clientX, event.clientY, false, false, false, false, 1, event.relatedTarget);
event.target.dispatchEvent(newEvent);
}
mozile.event.cancelKeyEvent = function(event) {
if(!event || !event.keyCode) return true;
switch(event.keyCode) {
case 8:
case 9:
case 46:
mozile.event.cancel(event);
return false;
}
return true;
}
mozile.event.cancelHyperlink = function(event) {
if(!mozile.browser.isMozilla) return true;
if(mozile.useDesignMode) return true;
switch(event.type) {
case "mousedown":
case "click":
case "dblclick":
case "mouseup":
break;
default: return true;
}
var node = event.explicitOriginalTarget;
var container = mozile.edit.getContainer(node);
if(container) {
while(node) {
if(node.localName && node.localName.toLowerCase() == "a") {
if(event.selection && event.rangeParent &&
event.rangeOffset != undefined) {
if(event.type == "mousedown") {
event.selection.collapse(event.rangeParent, event.rangeOffset);
mozile.event.mousedown = true;
}
else mozile.event.mousedown = false;
if(event.type == "dblclick") {
mozile.event.selectWord(event.rangeParent, event.rangeOffset);
}
}
mozile.event.cancel(event);
return false;
}
if(node == container) break;
node = node.parentNode;
}
}
return true;
}
mozile.event.selectWord = function(node, offset) {
if(!node || offset == undefined) return;
var selection = mozile.dom.selection.get();
if(node.nodeType != mozile.dom.TEXT_NODE) {
selection.collapse(node, offset);
}
else {
var match = /\s/;
var data = node.data;
if(offset == data.length) return;
var startOffset = offset - 2;
while(startOffset >= 0) {
if(data.charAt(startOffset).match(match)) {
startOffset++;
break;
}
else startOffset--;
}
if(startOffset < 0) startOffset = 0;
var endOffset = offset + 1;
while(endOffset <= data.length) {
if(data.charAt(endOffset).match(match)) break;
else endOffset++;
}
if(endOffset > data.length) endOffset = data.length;
selection.collapse(node, startOffset);
selection.extend(node, endOffset);
}
}
mozile.event.listen();
Documentation generated by
JSDoc on Wed Aug 23 18:45:51 2006