/[cvs]/nfo/js/com.cross-browser.cbe/cbe_event.js
ViewVC logotype

Contents of /nfo/js/com.cross-browser.cbe/cbe_event.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Fri Apr 18 16:14:42 2003 UTC (21 years, 2 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
File MIME type: application/javascript
rest of main cbe include files (currently not required)

1 /* cbe_event.js $Revision: 0.15 $
2 * CBE v4.19, Cross-Browser DHTML API from Cross-Browser.com
3 * Copyright (c) 2002 Michael Foster (mike@cross-browser.com)
4 * Distributed under the terms of the GNU LGPL from gnu.org
5 */
6 function cbeELReg(eventType, eventListener, eventCapture, listenerObject) { // event listener registration object constructor
7 this.type = eventType; this.listener = eventListener; this.capture = eventCapture; this.obj = listenerObject;
8 }
9 function CrossBrowserEvent(e) { // Object constructor
10 // from DOM2 Interface Event
11 this.type = "";
12 this.target = null;
13 this.currentTarget = null;
14 this.eventPhase = 0;
15 this.bubbles = true;
16 this.cancelable = true;
17 this.timeStamp = 0;
18 this.AT_TARGET = 1; this.BUBBLING_PHASE = 2; this.CAPTURING_PHASE = 3; // eventPhase masks
19 // from DOM2 Interface MouseEvent : UIEvent
20 this.screenX = 0;
21 this.screenY = 0;
22 this.clientX = 0;
23 this.clientY = 0;
24 this.ctrlKey = false;
25 this.shiftKey = false;
26 this.altKey = false;
27 this.metaKey = false;
28 this.button = 3; // 3 == undefined
29 this.relatedTarget = null;
30 this.LEFT = 0; this.MIDDLE = 1; this.RIGHT = 2; // button masks
31 // from IE4 Object Model
32 this.keyCode = 0;
33 this.offsetX = 0;
34 this.offsetY = 0;
35 // from NN4 Object Model
36 this.pageX = 0;
37 this.pageY = 0;
38 // CBE
39 this.stopPropagationFlag = false;
40 this.preventDefaultFlag = false;
41 this.cbeTarget = window.cbe;
42 this.cbeCurrentTarget = window.cbe;
43
44 if (!e) return;
45
46 if (e.type) { this.type = e.type; }
47 if (e.target) { this.target = e.target; }
48 else if (e.srcElement) { this.target = e.srcElement; }
49 if (e.currentTarget) { this.currentTarget = e.currentTarget; }
50 else if (e.toElement) { this.currentTarget = e.toElement; }
51 if (e.eventPhase) { this.eventPhase = e.eventPhase; }
52 if (e.bubbles) { this.bubbles = e.bubbles; }
53 if (e.cancelable) { this.cancelable = e.cancelable; }
54 if (e.timeStamp) { this.timeStamp = e.timeStamp; }
55
56 if (e.screenX) { this.screenX = e.screenX; }
57 if (e.screenY) { this.screenY = e.screenY; }
58 if (is.opera5or6) { this.clientX = e.clientX - document.cbe.scrollLeft(); }
59 else if (e.clientX) { this.clientX = e.clientX; }
60 else if (e.pageX) { this.clientX = e.pageX - document.cbe.scrollLeft(); }
61 if (is.opera5or6) { this.clientY = e.clientY - document.cbe.scrollLeft(); }
62 else if (e.clientY) { this.clientY = e.clientY; }
63 else if (e.pageY) { this.clientY = e.pageY - document.cbe.scrollLeft(); }
64 if (is.opera5or6) { this.ctrlKey = e.type=='mousemove' ? e.shiftKey : e.ctrlKey; }
65 else if (_def(e.ctrlKey)) { this.ctrlKey = e.ctrlKey; }
66 else if (_def(e.modifiers) && window.Event) { this.ctrlKey = (e.modifiers & window.Event.CONTROL_MASK) != 0; }
67 if (is.opera5or6) { this.shiftKey = e.type=='mousemove' ? e.ctrlKey : e.shiftKey; }
68 else if (_def(e.shiftKey)) { this.shiftKey = e.shiftKey; }
69 else if (_def(e.modifiers) && window.Event) { this.shiftKey = (e.modifiers & Event.SHIFT_MASK) != 0; }
70 if (e.altKey) { this.altKey = e.altKey; }
71 else if (_def(e.modifiers) && window.Event) { this.altKey = (e.modifiers & Event.ALT_MASK) != 0; }
72 if (e.metaKey) { this.metaKey = e.metaKey; }
73
74 // button (?)
75 if (is.ie) {
76 if (this.type.indexOf('mouse') != -1) {
77 if (e.button == 1) this.button = this.LEFT;
78 else if (e.button == 4) this.button = this.MIDDLE;
79 else if (e.button == 2) this.button = this.RIGHT;
80 }
81 else if (this.type == 'click') this.button = this.LEFT;
82 else this.button = 4; // non-mouse event
83 }
84 else if (_def(e.button)) { // standard
85 if (this.type.indexOf('mouse') != -1) { this.button = e.button; if (this.button < 0 || this.button > 2) {this.button = 3;} }
86 else if (this.type == 'click') this.button = this.LEFT;
87 else this.button = 4; // non-mouse event
88 }
89 else if (_def(e.which)) {
90 if (document.layers) { // nn4
91 if (this.type.indexOf('mouse') != -1) { this.button = e.which - 1; if (this.button < 0 || this.button > 2) {this.button = 3;} }
92 else if (this.type == 'click') this.button = this.LEFT;
93 else this.button = 4; // non-mouse event
94 }
95 else { // opera5or6
96 if ((e.type == 'click' && e.which == 0) || ((e.type == 'mousedown' || e.type == 'mouseup') && e.which == 1)) {this.button = this.LEFT;}
97 }
98 }
99
100 if (e.relatedTarget) { this.relatedTarget = e.relatedTarget; }
101 else if (e.fromElement) { this.relatedTarget = e.fromElement; } // ? may need to be toElement in some cases ?
102 if (_def(e.which)) { this.keyCode = e.which; }
103 else if (_def(e.keyCode)) { this.keyCode = e.keyCode; }
104 var calcOfs = false;
105 if (_def(e.layerX,e.layerY)) { this.offsetX = e.layerX; this.offsetY = e.layerY; }
106 else calcOfs = true; // calculate it below
107 if (is.opera5or6) { this.pageX = e.clientX; this.pageY = e.clientY; }
108 else if (_def(e.pageX,e.pageY)) { this.pageX = e.pageX; this.pageY = e.pageY; }
109 else {
110 this.pageX = this.clientX + document.cbe.scrollLeft();
111 this.pageY = this.clientY + document.cbe.scrollTop();
112 }
113
114 // Find the CBE event target
115 if (document.layers) {
116 this.cbeTarget = cbeGetNodeFromPoint(this.pageX, this.pageY);
117 // NN4 note: mouseout works only if mouseover and mouseout are both added to the same object
118 if (this.type == 'mouseover') cbeMOT = this.cbeTarget;
119 else if (this.type == 'mouseout') this.cbeTarget = cbeMOT || document.cbe;
120 }
121 else { var target = this.target; while (!target.cbe) {target = cbeGetParentElement(target);} this.cbeTarget = target.cbe; }
122 this.cbeCurrentTarget = this.cbeTarget;
123 if (calcOfs) { this.offsetX = this.pageX - this.cbeTarget.pageX(); this.offsetY = this.pageY - this.cbeTarget.pageY(); }
124 }
125
126 CrossBrowserElement.prototype.addEventListener = function(eventType, eventListener, useCapture, listenerObject) {
127 if (!useCapture) useCapture = false;
128 eventType = eventType.toLowerCase();
129 if (
130 (eventType.indexOf('mouse') != -1)
131 || eventType == 'click'
132 || (eventType.indexOf('key') != -1)
133 /* || (eventType.indexOf('resize') != -1 && !is.nav4 && !is.opera)
134 || (eventType.indexOf('scroll') != -1 && !is.nav && !is.opera) */
135 ) {
136 var add=true;
137 for (var i=0; i < this.listeners.length; ++i) { if (eventType == this.listeners[i].type) {add=false; break;} }
138 if (add) {
139 cbeNativeAddEventListener(this.ele, eventType, cbePropagateEvent, false);
140 }
141 this.listeners[this.listeners.length] = new cbeELReg(eventType, eventListener, useCapture, listenerObject);
142 return;
143 }
144 switch(eventType) {
145 case 'slidestart': this.onslidestart = eventListener; return;
146 case 'slide': this.onslide = eventListener; return;
147 case 'slideend': this.onslideend = eventListener; return;
148 case 'dragstart': this.ondragstart = eventListener; return;
149 case 'drag':
150 this.ondragCapture = useCapture;
151 this.ondrag = eventListener;
152 this.addEventListener('mousedown', cbeDragStartEvent, useCapture);
153 return;
154 case 'dragend': this.ondragend = eventListener; return;
155 case 'dragresize': if (window.cbeUtilJsLoaded) cbeAddDragResizeListener(this); return;
156 case 'scroll':
157 if (is.nav || is.opera) {
158 window.cbeOldScrollTop = cbePageYOffset();
159 window.cbeOnScrollListener = eventListener;
160 cbeScrollEvent();
161 return;
162 }
163 break;
164 case 'resize':
165 if (is.nav4 || is.opera) {
166 window.cbeOldWidth = cbeInnerWidth();
167 window.cbeOldHeight = cbeInnerHeight();
168 window.cbeOnResizeListener = eventListener;
169 cbeResizeEvent();
170 return;
171 }
172 break;
173 } // end switch
174 cbeNativeAddEventListener(this.ele, eventType, eventListener, useCapture);
175 }
176 function cbeNativeAddEventListener(ele, eventType, eventListener, useCapture) {
177 if (!useCapture) useCapture = false;
178 eventType = eventType.toLowerCase();
179 var eh = "ele.on" + eventType + "=eventListener";
180 if (ele.addEventListener) {
181 ele.addEventListener(eventType, eventListener, useCapture);
182 }
183 else if (ele.captureEvents) {
184 // if (useCapture || (eventType.indexOf('mousemove')!=-1)) // ???
185 ele.captureEvents(eval("Event." + eventType.toUpperCase()));
186 eval(eh);
187 }
188 else { eval(eh); }
189 }
190 function cbeNativeRemoveEventListener(ele, eventType, eventListener, useCapture) {
191 if (!useCapture) useCapture = false;
192 eventType = eventType.toLowerCase();
193 var eh = "ele.on" + eventType + "=null";
194 if (ele.removeEventListener) {
195 ele.removeEventListener(eventType, eventListener, useCapture);
196 }
197 else if (ele.releaseEvents) {
198 // if (useCapture || (eventType.indexOf('mousemove')!=-1)) // ???
199 ele.releaseEvents(eval("Event." + eventType.toUpperCase()));
200 eval(eh);
201 }
202 else { eval(eh); }
203 }
204 CrossBrowserElement.prototype.removeEventListener = function(eventType, eventListener, useCapture) {
205 eventType = eventType.toLowerCase();
206 if (!useCapture) useCapture = false;
207 if ((eventType.indexOf('mouse') != -1) || eventType == 'click' || (eventType.indexOf('key') != -1)) {
208 var i;
209 for (i = 0; i < this.listeners.length; ++i) {
210 if (this.listeners[i].type == eventType && this.listeners[i].listener == eventListener && this.listeners[i].capture == useCapture) {
211 if (this.listeners.splice) this.listeners.splice(i, 1);
212 else this.listeners[i].type = "*";
213 break;
214 }
215 }
216 var remove=true;
217 for (i = 0; i < this.listeners.length; ++i) { if (eventType == this.listeners[i].type) { remove = false; break; } }
218 if (remove) cbeNativeRemoveEventListener(this.ele, eventType, cbePropagateEvent, false);
219 return;
220 }
221 switch(eventType) {
222 case 'slidestart': this.onslidestart = null; return;
223 case 'slide': this.onslide = null; return;
224 case 'slideend': this.onslideend = null; return;
225 case 'dragstart': this.ondragstart = null; return;
226 case 'drag':
227 this.removeEventListener('mousedown', cbeDragStartEvent, this.ondragCapture);
228 this.ondrag = null;
229 return;
230 case 'dragend': this.ondragend = null; return;
231 case 'dragresize': if (window.cbeUtilJsLoaded) cbeRemoveDragResizeListener(this); return;
232 case 'scroll':
233 if (is.nav || is.opera) {
234 window.cbeOnScrollListener = null;
235 return;
236 }
237 break;
238 case 'resize':
239 if (is.nav4 || is.opera) {
240 window.cbeOnResizeListener = null;
241 return;
242 }
243 break;
244 } // end switch
245 cbeNativeRemoveEventListener(this.ele, eventType, eventListener, useCapture);
246 }
247 CrossBrowserEvent.prototype.stopPropagation = function() { this.stopPropagationFlag = true; }
248 CrossBrowserEvent.prototype.preventDefault = function() { this.preventDefaultFlag = true; }
249 CrossBrowserElement.prototype.dispatchEvent= function(e) {
250 var dispatch;
251 e.cbeCurrentTarget = this;
252 for (var i=0; i < this.listeners.length; ++i) {
253 dispatch = false;
254 if (e.type == this.listeners[i].type) {
255 if (e.eventPhase == e.CAPTURING_PHASE) {
256 if (this.listeners[i].capture) dispatch = true;
257 }
258 else if (!this.listeners[i].capture) dispatch = true;
259 }
260 if (dispatch) {
261 if (this.listeners[i].obj) cbeEval(this.listeners[i].obj, this.listeners[i].listener, e);
262 else cbeEval(this.listeners[i].listener, e);
263 }
264 }
265 }
266 function cbePropagateEvent(evt) {
267 var i=0, e=null, a=new Array();
268 if (evt) e = new CrossBrowserEvent(evt);
269 else if (window.event) e = new CrossBrowserEvent(window.event);
270 else return;
271 // Create an array of EventTargets, following the parent chain up (does not include cbeTarget)
272 var node = e.cbeTarget.parentNode;
273 while(node) {
274 a[i++] = node;
275 node = node.parentNode;
276 }
277 // The capturing phase
278 e.eventPhase = e.CAPTURING_PHASE;
279 for (i = a.length-1; i>=0; --i) {
280 a[i].dispatchEvent(e);
281 if (e.stopPropagationFlag) break;
282 }
283 // The at-target phase
284 if (!e.stopPropagationFlag) {
285 e.eventPhase = e.AT_TARGET;
286 e.cbeTarget.dispatchEvent(e);
287 // The bubbling phase
288 if (!e.stopPropagationFlag && e.bubbles) {
289 e.eventPhase = e.BUBBLING_PHASE;
290 for (i = 0; i < a.length; ++i) {
291 a[i].dispatchEvent(e);
292 if (e.stopPropagationFlag) break;
293 }
294 }
295 }
296 // Don't allow native bubbling
297 if (is.ie) window.event.cancelBubble = true;
298 else if (is.gecko) evt.stopPropagation();
299 // Allow listener to cancel default action
300 if (e.cancelable && e.preventDefaultFlag) {
301 if (is.gecko || is.opera) evt.preventDefault();
302 return false;
303 }
304 else return true;
305 }
306 function cbeGetNodeFromPoint(x, y) {
307 var hn /* highNode */, hz=0 /* highZ */, cn /* currentNode */, cz /* currentZ */;
308 hn = document.cbe;
309 while (hn.firstChild && hz >= 0) {
310 hz = -1;
311 cn = hn.firstChild;
312 while (cn) {
313 if (cn.contains(x, y)) {
314 cz = cn.zIndex();
315 if (cz >= hz) {
316 hn = cn;
317 hz = cz;
318 }
319 }
320 cn = cn.nextSibling;
321 }
322 }
323 return hn;
324 }
325 function cbeScrollEvent() {
326 if (!window.cbeOnScrollListener) { return; }
327 if (cbePageYOffset() != window.cbeOldScrollTop) {
328 cbeEval(window.cbeOnScrollListener);
329 window.cbeOldScrollTop = cbePageYOffset();
330 }
331 setTimeout("cbeScrollEvent()", 250);
332 }
333 function cbeResizeEvent() {
334 if (!window.cbeOnResizeListener) { return; }
335 var dw = window.cbeOldWidth - cbeInnerWidth();
336 var dh = window.cbeOldHeight - cbeInnerHeight();
337 if (dw != 0 || dh != 0) {
338 if (window.cbeOnResizeListener) cbeEval(window.cbeOnResizeListener, dw, dh);
339 window.cbeOldWidth = cbeInnerWidth();
340 window.cbeOldHeight = cbeInnerHeight();
341 }
342 setTimeout("cbeResizeEvent()", 250);
343 }
344 function cbeDefaultResizeListener() {
345 if (is.opera) location.replace(location.href);
346 else history.go(0);
347 }
348 var cbeDragObj, cbeDragTarget, cbeDragPhase;
349 function cbeDragStartEvent(e) {
350 if (is.opera) { var tn = e.target.tagName.toLowerCase(); if (tn == 'a') return; }
351 else if (is.nav4) { if (e.target.href) return; }
352 cbeDragObj = e.cbeCurrentTarget;
353 cbeDragTarget = e.cbeTarget;
354 if (cbeDragTarget.id == cbeDragObj.id) cbeDragPhase = e.AT_TARGET;
355 else if (cbeDragObj.ondragCapture) cbeDragPhase = e.CAPTURING_PHASE;
356 else cbeDragPhase = e.BUBBLING_PHASE;
357 if (cbeDragObj) {
358 if (cbeDragObj.ondragstart) { e.type = 'dragstart'; cbeEval(cbeDragObj.ondragstart, e); e.type = 'mousedown'; }
359 cbeDragObj.x = e.pageX;
360 cbeDragObj.y = e.pageY;
361 document.cbe.addEventListener('mousemove', cbeDragEvent, cbeDragObj.ondragCapture);
362 document.cbe.addEventListener('mouseup', cbeDragEndEvent, false);
363 }
364 e.stopPropagation();
365 e.preventDefault();
366 }
367 function cbeDragEndEvent(e) {
368 document.cbe.removeEventListener('mousemove', cbeDragEvent, cbeDragObj.ondragCapture);
369 document.cbe.removeEventListener('mouseup', cbeDragEndEvent, false);
370 if (cbeDragObj.ondragend) {
371 e.type = 'dragend';
372 e.cbeCurrentTarget = cbeDragObj;
373 e.cbeTarget = cbeDragTarget;
374 cbeEval(cbeDragObj.ondragend, e);
375 e.type = 'mouseup';
376 }
377 //e.stopPropagation();
378 e.preventDefault();
379 }
380 function cbeDragEvent(e) {
381 if (cbeDragObj) {
382 e.dx = e.pageX - cbeDragObj.x;
383 e.dy = e.pageY - cbeDragObj.y;
384 cbeDragObj.x = e.pageX;
385 cbeDragObj.y = e.pageY;
386 e.type = 'drag';
387 e.cbeTarget = cbeDragTarget;
388 e.cbeCurrentTarget = cbeDragObj;
389 e.eventPhase = cbeDragPhase;
390 if (cbeDragObj.ondrag) cbeEval(cbeDragObj.ondrag, e);
391 else cbeDragObj.moveBy(e.dx,e.dy);
392 e.type = 'mousemove';
393 }
394 //e.stopPropagation();
395 e.preventDefault();
396 }
397 var cbeEventPhase = new Array('', 'AT_TARGET', 'BUBBLING_PHASE', 'CAPTURING_PHASE');
398 var cbeButton = new Array('LEFT', 'MIDDLE', 'RIGHT', 'undefined', 'non-mouse event');
399 CrossBrowserElement.prototype.ondragstart = null;
400 CrossBrowserElement.prototype.ondrag = null;
401 CrossBrowserElement.prototype.ondragend = null;
402 var cbeEventJsLoaded = true;
403 // End cbe_event.js

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed