Mercurial > hg > digilib-old
comparison client/digitallibrary/baselib.js @ 237:786c27786281
new javascript code for digilib
author | robcast |
---|---|
date | Tue, 20 Jul 2004 09:57:24 +0200 |
parents | |
children | bc30dea2bb2e |
comparison
equal
deleted
inserted
replaced
236:35deb0f14913 | 237:786c27786281 |
---|---|
1 /* Copyright (C) 2003,2004 WTWG, Uni Bern and others | |
2 | |
3 This program is free software; you can redistribute it and/or | |
4 modify it under the terms of the GNU General Public License | |
5 as published by the Free Software Foundation; either version 2 | |
6 of the License, or (at your option) any later version. | |
7 | |
8 This program is distributed in the hope that it will be useful, | |
9 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 GNU General Public License for more details. | |
12 | |
13 You should have received a copy of the GNU General Public License | |
14 along with this program; if not, write to the Free Software | |
15 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | |
16 | |
17 Authors: ROC 03.06.2004 | |
18 first version by Christian Luginbuehl, 01.05.2003 | |
19 Changed for digiLib in Zope by DW 24.03.2004 | |
20 */ | |
21 | |
22 function getInt (n) { | |
23 // returns always an integer | |
24 n = parseInt (n); | |
25 if (isNaN (n)) | |
26 return 0; | |
27 return n; | |
28 } | |
29 | |
30 function defined(x) { | |
31 // returns if x is defined | |
32 return (typeof arguments[0] != "undefined"); | |
33 } | |
34 | |
35 // auxiliary function to crop senseless precision | |
36 function cropFloat(x) { | |
37 return parseInt(10000*x)/10000; | |
38 } | |
39 | |
40 // browser sniffer | |
41 var browserType = Object(); | |
42 browserType.doDHTML = false; | |
43 browserType.versIE = 0; | |
44 | |
45 if ((! document.cssonly && document.layers) || document.all || document.getElementById) { | |
46 var vers = navigator.appVersion.split('MSIE '); | |
47 vers = vers[vers.length - 1]; | |
48 browserType.versIE = getInt(vers); | |
49 browserType.isIE = navigator.userAgent.indexOf('MSIE') >= 0; | |
50 browserType.isMac = navigator.platform.indexOf('Mac') >= 0; | |
51 browserType.isWin = navigator.platform.indexOf('Win') >= 0; | |
52 browserType.isN4 = (navigator.userAgent.indexOf('Mozilla/4.') >= 0) && ! browserType.isIE; | |
53 browserType.isIEWin = browserType.versIE > 0 && browserType.isWin; | |
54 if (navigator.appVersion.indexOf('MSIE') < 0 || ! browserType.isMac || browserType.versIE >= 5) { | |
55 browserType.doDHTML = true; | |
56 browserType.isOpera = navigator.userAgent.indexOf(' Opera ') >= 0; | |
57 browserType.isKonq = navigator.userAgent.indexOf(' Konqueror') >= 0; | |
58 } | |
59 } | |
60 | |
61 // fixes for javascript < 1.2 | |
62 if (! Array.prototype.push) { | |
63 Array.prototype.push = function(val) { | |
64 this[this.length] = val; | |
65 return this.length; | |
66 } | |
67 Array.prototype.pop = function() { | |
68 var val = this[this.length-1]; | |
69 this.length -= 1; | |
70 return val; | |
71 } | |
72 } | |
73 | |
74 | |
75 /* ********************************************** | |
76 * geometry classes | |
77 * ******************************************** */ | |
78 | |
79 /* | |
80 * Size class | |
81 */ | |
82 function Size(w, h) { | |
83 this.width = parseFloat(w); | |
84 this.height = parseFloat(h); | |
85 return this; | |
86 } | |
87 | |
88 /* | |
89 * Position class | |
90 */ | |
91 function Position(x, y) { | |
92 this.x = parseFloat(x); | |
93 this.y = parseFloat(y); | |
94 return this; | |
95 } | |
96 | |
97 /* | |
98 * Rectangle class | |
99 */ | |
100 function Rectangle(x, y, w, h) { | |
101 this.x = parseFloat(x); | |
102 this.y = parseFloat(y); | |
103 this.width = parseFloat(w); | |
104 this.height = parseFloat(h); | |
105 return this; | |
106 } | |
107 Rectangle.prototype.copy = function() { | |
108 // returns a copy of this Rectangle | |
109 return new Rectangle(this.x, this.y, this.width, this.height); | |
110 } | |
111 Rectangle.prototype.getPosition = function() { | |
112 // returns the position of this Rectangle | |
113 return new Position(this.x, this.y); | |
114 } | |
115 Rectangle.prototype.getSize = function() { | |
116 // returns the size of this Rectangle | |
117 return new Size(this.width, this.height); | |
118 } | |
119 Rectangle.prototype.getArea = function() { | |
120 // returns the area of this Rectangle | |
121 return (this.width * this.height); | |
122 } | |
123 Rectangle.prototype.containsPosition = function(pos) { | |
124 // returns if the given Position lies in this Rectangle | |
125 return ((pos.x >= this.x)&&(pos.y >= this.y)&&(pos.x <= this.x+this.width)&&(pos.y <= this.y+this.width)); | |
126 } | |
127 Rectangle.prototype.intersect = function(rect) { | |
128 // returns the intersection of the given Rectangle and this one | |
129 var sec = rect.copy(); | |
130 if (sec.x < this.x) { | |
131 sec.width = sec.width - (this.x - sec.x); | |
132 sec.x = this.x; | |
133 } | |
134 if (sec.y < this.y) { | |
135 sec.height = sec.height - (this.y - sec.y); | |
136 sec.y = this.y; | |
137 } | |
138 if (sec.x + sec.width > this.x + this.width) { | |
139 sec.width = (this.x + this.width) - sec.x; | |
140 } | |
141 if (sec.y + sec.height > this.y + this.height) { | |
142 sec.height = (this.y + this.height) - sec.y; | |
143 } | |
144 return sec; | |
145 } | |
146 Rectangle.prototype.fit = function(rect) { | |
147 // returns a Rectangle that fits into this one (by moving first) | |
148 var sec = rect.copy(); | |
149 sec.x = Math.max(sec.x, this.x); | |
150 sec.x = Math.max(sec.x, this.x); | |
151 if (sec.x + sec.width > this.x + this.width) { | |
152 sec.x = this.x + this.width - sec.width; | |
153 } | |
154 if (sec.y + sec.height > this.y + this.height) { | |
155 sec.y = this.y + this.height - sec.height; | |
156 } | |
157 return sec.intersect(this); | |
158 } | |
159 | |
160 /* | |
161 * Transform class | |
162 * | |
163 * defines a class of affine transformations | |
164 */ | |
165 function Transform() { | |
166 this.m00 = 1.0; | |
167 this.m01 = 0.0; | |
168 this.m02 = 0.0; | |
169 this.m10 = 0.0; | |
170 this.m11 = 1.0; | |
171 this.m12 = 0.0; | |
172 this.m20 = 0.0; | |
173 this.m21 = 0.0; | |
174 this.m22 = 1.0; | |
175 return this; | |
176 } | |
177 Transform.prototype.concat = function(traf) { | |
178 // add Transform traf to this Transform | |
179 for (var i = 0; i < 3; i++) { | |
180 for (var j = 0; j < 3; j++) { | |
181 var c = 0.0; | |
182 for (var k = 0; k < 3; k++) { | |
183 c += traf["m"+i+k] * this["m"+k+j]; | |
184 } | |
185 this["m"+i+j] = c; | |
186 } | |
187 } | |
188 return this; | |
189 } | |
190 Transform.prototype.transform = function(rect) { | |
191 // returns transformed Rectangle or Position with this Transform applied | |
192 var x = this.m00 * rect.x + this.m01 * rect.y + this.m02; | |
193 var y = this.m10 * rect.x + this.m11 * rect.y + this.m12; | |
194 if (rect.width) { | |
195 var width = this.m00 * rect.width + this.m01 * rect.height; | |
196 var height = this.m10 * rect.width + this.m11 * rect.height; | |
197 return new Rectangle(x, y, width, height); | |
198 } | |
199 return new Position(x, y); | |
200 } | |
201 Transform.prototype.invtransform = function(pos) { | |
202 // returns transformed Position pos with the inverse of this Transform applied | |
203 var det = this.m00 * this.m11 - this.m01 * this.m10; | |
204 var x = (this.m11 * pos.x - this.m01 * pos.y - this.m11 * this.m02 + this.m01 * this.m12) / det; | |
205 var y = (- this.m10 * pos.x + this.m00 * pos.y + this.m10 * this.m02 - this.m00 * this.m12) / det; | |
206 return new Position(x, y); | |
207 } | |
208 function getRotation(angle, pos) { | |
209 // returns a Transform that is a rotation by angle degrees around [pos.x, pos.y] | |
210 var traf = new Transform(); | |
211 if (angle != 0) { | |
212 var t = 2.0 * Math.PI * parseFloat(angle) / 360.0; | |
213 traf.m00 = Math.cos(t); | |
214 traf.m01 = - Math.sin(t); | |
215 traf.m10 = Math.sin(t); | |
216 traf.m11 = Math.cos(t); | |
217 traf.m02 = pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t); | |
218 traf.m12 = pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t); | |
219 } | |
220 return traf; | |
221 } | |
222 function getTranslation(pos) { | |
223 // returns a Transform that is a translation by [pos.x, pos,y] | |
224 var traf = new Transform(); | |
225 traf.m02 = pos.x; | |
226 traf.m12 = pos.y; | |
227 return traf; | |
228 } | |
229 function getScale(size) { | |
230 // returns a Transform that is a scale by [size.width, size.height] | |
231 var traf = new Transform(); | |
232 traf.m00 = size.width; | |
233 traf.m11 = size.height; | |
234 return traf; | |
235 } | |
236 | |
237 | |
238 /* ********************************************** | |
239 * parameter routines | |
240 * ******************************************** */ | |
241 | |
242 var dlParams = new Object(); | |
243 | |
244 function newParameter(name, defaultValue, detail) { | |
245 // create a new parameter with a name and a default value | |
246 if (defined(dlParams[name])) { | |
247 alert("Fatal: An object with name '" + name + "' already exists - cannot recreate!"); | |
248 return false; | |
249 } else { | |
250 dlParams[name] = new Object(); | |
251 dlParams[name].defaultValue = defaultValue; | |
252 dlParams[name].hasValue = false; | |
253 dlParams[name].value = defaultValue; | |
254 dlParams[name].detail = detail; | |
255 return dlParams[name]; | |
256 } | |
257 } | |
258 | |
259 function getParameter(name) { | |
260 // returns the named parameter value or its default value | |
261 if (defined(dlParams[name])) { | |
262 if (dlParams[name].hasValue) { | |
263 return dlParams[name].value; | |
264 } else { | |
265 return dlParams[name].defaultValue; | |
266 } | |
267 } else { | |
268 return null; | |
269 } | |
270 } | |
271 | |
272 function setParameter(name, value) { | |
273 // sets parameter value | |
274 if (defined(dlParams[name])) { | |
275 dlParams[name].value = value; | |
276 dlParams[name].hasValue = true; | |
277 return true; | |
278 } | |
279 return false; | |
280 } | |
281 | |
282 function getAllParameters(detail) { | |
283 // returns a string of all parameters in query format | |
284 if (! detail) { | |
285 detail = 10; | |
286 } | |
287 var params = new Array(); | |
288 for ( param in dlParams ) { | |
289 if ((dlParams[param].detail <= detail)&&(dlParams[param].hasValue)) { | |
290 var val = getParameter(param); | |
291 if (val != "") { | |
292 params.push(param + "=" + val); | |
293 } | |
294 } | |
295 } | |
296 return params.join("&"); | |
297 } | |
298 | |
299 function parseParameters(query) { | |
300 // gets parameter values from query format string | |
301 var params = query.split("&"); | |
302 for (var i = 0; i < params.length; i++) { | |
303 var keyval = params[i].split("="); | |
304 if (keyval.length == 2) { | |
305 setParameter(keyval[0], keyval[1]); | |
306 } | |
307 } | |
308 } | |
309 | |
310 | |
311 /* ********************************************** | |
312 * HTML/DOM routines | |
313 * ******************************************** */ | |
314 | |
315 function getElement(tagid, quiet) { | |
316 // returns the element object with the id tagid | |
317 var e; | |
318 if (document.getElementById) { | |
319 e = document.getElementById(tagid); | |
320 } else if (document.all) { | |
321 alert("document.all!"); | |
322 e = document.all[tagid]; | |
323 } else if (document.layers) { | |
324 e = document.layers[tagid]; | |
325 } | |
326 if (e) { | |
327 return e; | |
328 } else { | |
329 if (! quiet) { | |
330 alert("unable to find element: "+tagid); | |
331 } | |
332 return null; | |
333 } | |
334 } | |
335 | |
336 function getElementPosition(elem) { | |
337 // returns a Position with the position of the element | |
338 var x = 0; | |
339 var y = 0; | |
340 if (defined(elem.offsetLeft)) { | |
341 var e = elem; | |
342 while (e) { | |
343 if (defined(e.clientLeft)) { | |
344 // special for IE | |
345 if (browserType.isMac) { | |
346 if (e.offsetParent.tagName == "BODY") { | |
347 // IE for Mac extraspecial | |
348 x += e.clientLeft; | |
349 y += e.clientTop; | |
350 break; | |
351 } | |
352 } else { | |
353 if ((e.tagName != "TABLE") && (e.tagName != "BODY")) { | |
354 x += e.clientLeft; | |
355 y += e.clientTop; | |
356 } | |
357 } | |
358 } | |
359 x += e.offsetLeft; | |
360 y += e.offsetTop; | |
361 e = e.offsetParent; | |
362 } | |
363 } else if (defined(elem.x)) { | |
364 x = elem.x; | |
365 y = elem.y; | |
366 } else if (defined(elem.pageX)) { | |
367 x = elem.pageX; | |
368 y = elem.pageY; | |
369 } else { | |
370 alert("unable to get position of "+elem+" (id:"+elem.id+")"); | |
371 } | |
372 return new Position(getInt(x), getInt(y)); | |
373 } | |
374 | |
375 function getElementSize(elem) { | |
376 // returns a Rectangle with the size of the element | |
377 var width = 0; | |
378 var height = 0; | |
379 if (defined(elem.offsetWidth)) { | |
380 width = elem.offsetWidth; | |
381 height = elem.offsetHeight; | |
382 } else if (defined(elem.width)) { | |
383 width = elem.width; | |
384 height = elem.height; | |
385 } else if (defined(elem.clip.width)) { | |
386 width = elem.clip.width; | |
387 height = elem.clip.height; | |
388 } else { | |
389 alert("unable to get size of "+elem+" (id:"+elem.id+")"); | |
390 } | |
391 return new Size(getInt(width), getInt(height)); | |
392 } | |
393 | |
394 function getElementRect(elem) { | |
395 // returns a Rectangle with the size and position of the element | |
396 var pos = getElementPosition(elem); | |
397 var size = getElementSize(elem); | |
398 return new Rectangle(pos.x, pos.y, size.width, size.height); | |
399 } | |
400 | |
401 | |
402 | |
403 function moveElement(elem, rect) { | |
404 // moves and sizes the element | |
405 if (elem.style) { | |
406 if (defined(rect.x)) { | |
407 elem.style.left = Math.round(rect.x) + "px"; | |
408 elem.style.top = Math.round(rect.y) + "px"; | |
409 } | |
410 if (defined(rect.width)) { | |
411 elem.style.width = Math.round(rect.width) + "px"; | |
412 elem.style.height = Math.round(rect.height) + "px"; | |
413 } | |
414 } else if (document.layers) { | |
415 if (defined(rect.x)) { | |
416 elem.pageX = getInt(rect.x); | |
417 elem.pageY = getInt(rect.y); | |
418 } | |
419 if (defined(rect.width)) { | |
420 elem.clip.width = getInt(rect.width); | |
421 elem.clip.height = getInt(rect.height); | |
422 } | |
423 } else { | |
424 alert("moveelement: no style nor layer property!"); | |
425 return false; | |
426 } | |
427 return true; | |
428 } | |
429 | |
430 function showElement(elem, show) { | |
431 // shows or hides the element | |
432 if (elem.style) { | |
433 if (show) { | |
434 elem.style.visibility = "visible"; | |
435 } else { | |
436 elem.style.visibility = "hidden"; | |
437 } | |
438 } else if (defined(elem.visibility)) { | |
439 if (show) { | |
440 elem.visibility = "show"; | |
441 } else { | |
442 elem.visibility = "hide"; | |
443 } | |
444 } else { | |
445 alert("showelement: no style nor layer property!"); | |
446 } | |
447 return true; | |
448 } | |
449 | |
450 function evtPosition(evt) { | |
451 // returns the on-screen Position of the Event | |
452 var x; | |
453 var y; | |
454 evt = (evt) ? evt : window.event; | |
455 if (!evt) { | |
456 alert("no event found! "+evt); | |
457 return; | |
458 } | |
459 if (defined(evt.pageX)) { | |
460 x = parseInt(evt.pageX); | |
461 y = parseInt(evt.pageY); | |
462 } else if (defined(evt.clientX)) { | |
463 x = parseInt(document.body.scrollLeft+evt.clientX); | |
464 y = parseInt(document.body.scrollTop+evt.clientY); | |
465 } else { | |
466 alert("evtPosition: don't know how to deal with "+evt); | |
467 } | |
468 return new Position(x, y); | |
469 } | |
470 | |
471 function registerMouseDown(elem, handler) { | |
472 // register a mouse down event handler on the indicated element | |
473 if (elem.addEventListener) { | |
474 elem.addEventListener("mousedown", handler, false); | |
475 } else { | |
476 if (elem.captureEvents) { | |
477 elem.captureEvents(Event.MOUSEDOWN); | |
478 } | |
479 elem.onmousedown = handler; | |
480 } | |
481 return true; | |
482 } | |
483 | |
484 function unregisterMouseDown(elem, handler) { | |
485 // unregister the mouse down event handler | |
486 if (elem.removeEventListener) { | |
487 elem.removeEventListener("mousedown", handler, false); | |
488 } else { | |
489 if (elem.releaseEvents) { | |
490 elem.releaseEvents(Event.MOUSEDOWN); | |
491 } | |
492 elem.onmousedown = null; | |
493 } | |
494 return true; | |
495 } | |
496 | |
497 function registerMouseMove(elem, handler) { | |
498 // register a mouse move event handler on the indicated element | |
499 if (elem.addEventListener) { | |
500 elem.addEventListener("mousemove", handler, false); | |
501 } else { | |
502 if (elem.captureEvents) { | |
503 elem.captureEvents(Event.MOUSEMOVE); | |
504 } | |
505 elem.onmousemove = handler; | |
506 } | |
507 return true; | |
508 } | |
509 | |
510 function unregisterMouseMove(elem, handler) { | |
511 // unregister the mouse move event handler | |
512 if (elem.removeEventListener) { | |
513 elem.removeEventListener("mousemove", handler, false); | |
514 } else { | |
515 if (elem.releaseEvents) { | |
516 elem.releaseEvents(Event.MOUSEMOVE); | |
517 } | |
518 elem.onmousemove = null; | |
519 } | |
520 return true; | |
521 } | |
522 | |
523 function registerKeyDown(handler) { | |
524 // register a key down handler | |
525 if ( document.addEventListener ) { | |
526 this.document.addEventListener('keypress', handler, false); | |
527 } else { | |
528 if (elem.captureEvents) { | |
529 elem.captureEvents(Event.MOUSEDOWN); | |
530 } | |
531 this.document.onkeypress = handler | |
532 } | |
533 return true; | |
534 } | |
535 | |
536 function getWinSize() { | |
537 // returns a Size with the current window size (mostly from www.quirksmode.org) | |
538 var wsize = new Size(100, 100); | |
539 if (defined(self.innerHeight)) { | |
540 // all except Explorer | |
541 wsize.width = self.innerWidth; | |
542 wsize.height = self.innerHeight; | |
543 } else if (document.documentElement && document.documentElement.clientHeight) { | |
544 // Explorer 6 Strict Mode | |
545 wsize.width = document.documentElement.clientWidth; | |
546 wsize.height = document.documentElement.clientHeight; | |
547 } else if (document.body) { | |
548 // other Explorers | |
549 wsize.width = document.body.clientWidth; | |
550 wsize.height = document.body.clientHeight; | |
551 } | |
552 return wsize; | |
553 } | |
554 | |
555 function openWin(url, title, params) { | |
556 // open browser window | |
557 var ow = window.open(url, title, params); | |
558 ow.focus(); | |
559 } |