comparison src/de/mpg/mpiwg/itgroup/digilib/icons/greyskin/baselib.js @ 1:83c58ea33792

first release (continued)
author dwinter
date Mon, 03 Jan 2011 09:11:25 +0100
parents
children
comparison
equal deleted inserted replaced
0:6829553d2378 1:83c58ea33792
1 /* Copyright (C) 2003-2006 IT-Group MPIWG, 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:
18 Christian Luginbuehl, 01.05.2003 (first version)
19 DW 24.03.2004 (Changed for digiLib in Zope)
20 Robert Casties, 2.11.2004 (almost complete rewrite)
21 Martin Raspe, 12.12.2005 (changes for Digilib NG)
22 Robert Casties, 3.9.2009
23 */
24
25 // was: function base_init() {
26 baseLibVersion = "2.011";
27 browserType = getBrowserType();
28
29 sliders = {};
30 activeSlider = null;
31
32 function getInt(n) {
33 // returns always an integer
34 n = parseInt(n);
35 return (isNaN(n)) ? 0 : n;
36 }
37
38 function defined(x) {
39 // returns if x is defined
40 return (typeof arguments[0] != "undefined");
41 }
42
43 function cropFloat(x) {
44 // auxiliary function to crop senseless precision
45 return parseInt(10000 * x) / 10000;
46 }
47
48 function getBrowserType() {
49 // browser sniffer
50 var bt = Object();
51 bt.doDHTML = false;
52 bt.versIE = 0;
53
54 if ((! document.cssonly && document.layers) || document.all || document.getElementById) {
55 var vers = navigator.appVersion.split('MSIE ');
56 vers = vers[vers.length - 1];
57 bt.versIE = getInt(vers);
58 bt.isIE = navigator.userAgent.indexOf('MSIE') >= 0;
59 bt.isMac = navigator.platform.indexOf('Mac') >= 0;
60 bt.isWin = navigator.platform.indexOf('Win') >= 0;
61 bt.isN4 = (navigator.userAgent.indexOf('Mozilla/4.') >= 0) && ! bt.isIE;
62 bt.isIEWin = bt.versIE > 0 && bt.isWin;
63 if (navigator.appVersion.indexOf('MSIE') < 0 || ! bt.isMac || bt.versIE >= 5) {
64 bt.doDHTML = true;
65 bt.isOpera = navigator.userAgent.indexOf(' Opera ') >= 0;
66 bt.isKonq = navigator.userAgent.indexOf(' Konqueror') >= 0;
67 }
68 }
69 return bt;
70 }
71
72 // fixes for javascript < 1.2
73 if (! Array.prototype.push) {
74 Array.prototype.push = function(val) {
75 this[this.length] = val;
76 return this.length;
77 }
78 Array.prototype.pop = function() {
79 var val = this[this.length-1];
80 this.length -= 1;
81 return val;
82 }
83 }
84
85
86 /* **********************************************
87 * geometry classes
88 * ******************************************** */
89
90 /*
91 * Size class
92 */
93 function Size(w, h) {
94 this.width = parseFloat(w);
95 this.height = parseFloat(h);
96 return this;
97 }
98 Size.prototype.toString = function() {
99 return this.width + "x" + this.height;
100 }
101 Size.prototype.equals = function(other) {
102 return (this.width == other.width
103 && this.height == other.height)
104 }
105
106 /*
107 * Position class
108 */
109 function Position(x, y) {
110 this.x = parseFloat(x);
111 this.y = parseFloat(y);
112 return this;
113 }
114 Position.prototype.toString = function() {
115 return this.x + "," + this.y;
116 }
117 Position.prototype.equals = function(other) {
118 return (this.x == other.x
119 && this.y == other.y)
120 }
121 /*
122 * Rectangle class
123 */
124 function Rectangle(x, y, w, h) {
125 if (typeof x == "object") {
126 // assume x and y are Position
127 this.x = x.x;
128 this.y = x.y;
129 this.width = y.x - x.x;
130 this.height = y.y - x.y;
131 return this;
132 }
133 this.x = parseFloat(x);
134 this.y = parseFloat(y);
135 this.width = parseFloat(w);
136 this.height = parseFloat(h);
137 return this;
138 }
139 Rectangle.prototype.toString = function() {
140 return this.width+"x"+this.height+"@"+this.x+","+this.y;
141 }
142 Rectangle.prototype.copy = function() {
143 // returns a copy of this Rectangle
144 return new Rectangle(this.x, this.y, this.width, this.height);
145 }
146 Rectangle.prototype.getPosition = function() {
147 // returns the position of this Rectangle
148 return new Position(this.x, this.y);
149 }
150 Rectangle.prototype.getPt1 = Rectangle.prototype.getPosition;
151 // returns the upper left corner position
152
153 Rectangle.prototype.getPt2 = function() {
154 // returns the lower right corner position of this Rectangle
155 return new Position(this.x + this.width, this.y + this.height);
156 }
157 Rectangle.prototype.setPt1 = function(pos) {
158 // sets the upper left corner to position pos
159 this.x = pos.x;
160 this.y = pos.y;
161 return this;
162 }
163 Rectangle.prototype.setPt2 = function(pos) {
164 // sets the lower right corner to position pos
165 this.width = pos.x - this.x;
166 this.height = pos.y - this.y;
167 return this;
168 }
169 Rectangle.prototype.getCenter = function() {
170 // returns the center position of this Rectangle
171 return new Position(this.x + this.width / 2, this.y + this.height / 2);
172 }
173 Rectangle.prototype.setCenter = function(pos) {
174 // moves this Rectangle's center to position pos
175 this.x = pos.x - this.width / 2;
176 this.y = pos.y - this.height / 2;
177 return this;
178 }
179 Rectangle.prototype.getSize = function() {
180 // returns the size of this Rectangle
181 return new Size(this.width, this.height);
182 }
183 Rectangle.prototype.equals = function(other) {
184 // equal props
185 return (this.getPosition().equals(other.getPosition())
186 && this.getSize().equals(other.getSize())
187 );
188 }
189 Rectangle.prototype.getArea = function() {
190 // returns the area of this Rectangle
191 return (this.width * this.height);
192 }
193 Rectangle.prototype.normalize = function() {
194 // eliminates negative width and height
195 var p = this.getPt2();
196 this.x = Math.min(this.x, p.x);
197 this.y = Math.min(this.y, p.y);
198 this.width = Math.abs(this.width);
199 this.height = Math.abs(this.height);
200 return this;
201 }
202 Rectangle.prototype.containsPosition = function(pos) {
203 // returns if Position "pos" lies inside of this rectangle
204 return ((pos.x >= this.x)
205 && (pos.y >= this.y)
206 && (pos.x <= this.x + this.width)
207 && (pos.y <= this.y + this.width)
208 );
209 }
210 Rectangle.prototype.containsRect = function(rect) {
211 // returns if rectangle "rect" is contained in this rectangle
212 return (this.containsPosition(rect.getPt1())
213 && this.containsPosition(rect.getPt2()));
214 }
215 Rectangle.prototype.stayInside = function(rect) {
216 // changes this rectangle's x/y values so it stays inside of rectangle rect
217 // keeping the proportions
218 if (this.x < rect.x) this.x = rect.x;
219 if (this.y < rect.y) this.y = rect.y;
220 if (this.x + this.width > rect.x + rect.width)
221 this.x = rect.x + rect.width - this.width;
222 if (this.y + this.height > rect.y + rect.height)
223 this.y = rect.y + rect.height - this.height;
224 return this;
225 }
226 Rectangle.prototype.clipTo = function(rect) {
227 // clips this rectangle so it stays inside of rectangle rect
228 var p1 = rect.getPt1();
229 var p2 = rect.getPt2();
230 var this2 = this.getPt2();
231 this.setPt1(new Position(Math.max(this.x, p1.x), Math.max(this.y, p1.y)));
232 this.setPt2(new Position(Math.min(this2.x, p2.x), Math.min(this2.y, p2.y)));
233 return this;
234 }
235 Rectangle.prototype.intersect = function(rect) {
236 // returns the intersection of the given Rectangle and this one
237 // FIX ME: not really, it should return null if there is no overlap
238 var sec = rect.copy();
239 if (sec.x < this.x) {
240 sec.width = sec.width - (this.x - sec.x);
241 sec.x = this.x;
242 }
243 if (sec.y < this.y) {
244 sec.height = sec.height - (this.y - sec.y);
245 sec.y = this.y;
246 }
247 if (sec.x + sec.width > this.x + this.width) {
248 sec.width = (this.x + this.width) - sec.x;
249 }
250 if (sec.y + sec.height > this.y + this.height) {
251 sec.height = (this.y + this.height) - sec.y;
252 }
253 return sec;
254 }
255 Rectangle.prototype.fit = function(rect) {
256 // returns a Rectangle that fits into this one (by moving first)
257 var sec = rect.copy();
258 sec.x = Math.max(sec.x, this.x);
259 sec.y = Math.max(sec.y, this.x);
260 if (sec.x + sec.width > this.x + this.width) {
261 sec.x = this.x + this.width - sec.width;
262 }
263 if (sec.y + sec.height > this.y + this.height) {
264 sec.y = this.y + this.height - sec.height;
265 }
266 return sec.intersect(this);
267 }
268
269 /*
270 * Transform class
271 *
272 * defines a class of affine transformations
273 */
274 function Transform() {
275 this.m00 = 1.0;
276 this.m01 = 0.0;
277 this.m02 = 0.0;
278 this.m10 = 0.0;
279 this.m11 = 1.0;
280 this.m12 = 0.0;
281 this.m20 = 0.0;
282 this.m21 = 0.0;
283 this.m22 = 1.0;
284 return this;
285 }
286 Transform.prototype.concat = function(traf) {
287 // add Transform traf to this Transform
288 for (var i = 0; i < 3; i++) {
289 for (var j = 0; j < 3; j++) {
290 var c = 0.0;
291 for (var k = 0; k < 3; k++) {
292 c += traf["m"+i+k] * this["m"+k+j];
293 }
294 this["m"+i+j] = c;
295 }
296 }
297 return this;
298 }
299 Transform.prototype.transform = function(rect) {
300 // returns transformed Rectangle or Position with this Transform applied
301 var x = this.m00 * rect.x + this.m01 * rect.y + this.m02;
302 var y = this.m10 * rect.x + this.m11 * rect.y + this.m12;
303 if (rect.width) {
304 // transform the other corner points
305 var pt2 = rect.getPt2();
306 var x2 = this.m00 * pt2.x + this.m01 * pt2.y + this.m02;
307 var y2 = this.m10 * pt2.x + this.m11 * pt2.y + this.m12;
308 var width = x2 - x;
309 var height = y2 - y;
310 return new Rectangle(x, y, width, height);
311 }
312 return new Position(x, y);
313 }
314 Transform.prototype.invtransform = function(rect) {
315 // returns transformed Rectangle or Position with the inverse of this Transform applied
316 var det = this.m00 * this.m11 - this.m01 * this.m10;
317 var x = (this.m11 * rect.x - this.m01 * rect.y - this.m11 * this.m02 + this.m01 * this.m12) / det;
318 var y = (- this.m10 * rect.x + this.m00 * rect.y + this.m10 * this.m02 - this.m00 * this.m12) / det;
319 if (rect.width) {
320 /* transforming width and height like points seems to be wrong
321 var width = (this.m11 * rect.width - this.m01 * rect.height - this.m11 * this.m02 + this.m01 * this.m12) / det;
322 var height = (- this.m10 * rect.width + this.m00 * rect.height + this.m10 * this.m02 - this.m00 * this.m12) / det;
323 */
324 // transform the other corner points
325 var pt2 = rect.getPt2();
326 var x2 = (this.m11 * pt2.x - this.m01 * pt2.y - this.m11 * this.m02 + this.m01 * this.m12) / det;
327 var y2 = (- this.m10 * pt2.x + this.m00 * pt2.y + this.m10 * this.m02 - this.m00 * this.m12) / det;
328 var width = x2 - x;
329 var height = y2 - y;
330 return new Rectangle(x, y, width, height);
331 }
332 return new Position(x, y);
333 }
334 function getRotation(angle, pos) {
335 // returns a Transform that is a rotation by angle degrees around [pos.x, pos.y]
336 var traf = new Transform();
337 if (angle != 0) {
338 var t = 2.0 * Math.PI * parseFloat(angle) / 360.0;
339 traf.m00 = Math.cos(t);
340 traf.m01 = - Math.sin(t);
341 traf.m10 = Math.sin(t);
342 traf.m11 = Math.cos(t);
343 traf.m02 = pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t);
344 traf.m12 = pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t);
345 }
346 return traf;
347 }
348 Transform.prototype.getRotation = getRotation;
349 function getTranslation(pos) {
350 // returns a Transform that is a translation by [pos.x, pos,y]
351 var traf = new Transform();
352 traf.m02 = pos.x;
353 traf.m12 = pos.y;
354 return traf;
355 }
356 Transform.prototype.getTranslation = getTranslation;
357 function getScale(size) {
358 // returns a Transform that is a scale by [size.width, size.height]
359 var traf = new Transform();
360 traf.m00 = size.width;
361 traf.m11 = size.height;
362 return traf;
363 }
364 Transform.prototype.getScale = getScale;
365
366
367 /*
368 * parameters class
369 */
370
371 function Parameters() {
372 this.params = new Object();
373 this.PARAM_ALL = 65535;
374 return this;
375 }
376 Parameters.prototype.define = function(name, defaultValue, detail) {
377 // create a new parameter with a name and a default value
378 if (!this.params[name]) this.params[name] = new Object();
379 this.params[name].defaultValue = defaultValue;
380 this.params[name].hasValue = false;
381 this.params[name].value = defaultValue;
382 this.params[name].detail = detail;
383 return this.params[name];
384 }
385 Parameters.prototype.reset = function(name) {
386 // resets the given parameter to its default value
387 if (!this.params[name]) {
388 alert("Could not reset non-existing parameter '" + name + "'");
389 return false;
390 }
391 this.params[name].hasValue = false;
392 this.params[name].value = this.params[name].defaultValue;
393 return this.params[name];
394 }
395 Parameters.prototype.resetAll = function() {
396 // resets all parameters to their default values
397 for (var p in this.params) {
398 this.reset(p);
399 }
400 return true;
401 }
402 Parameters.prototype.remove = function(name) {
403 if (!defined(this.params[name])) return false;
404 delete this.params[name];
405 return true;
406 }
407 Parameters.prototype.get = function(name) {
408 // returns the named parameter value or its default value
409 if (!defined(this.params[name])) return null;
410 return this.params[name].hasValue ? this.params[name].value : this.params[name].defaultValue;
411 }
412 Parameters.prototype.set = function(name, value, relative) {
413 // sets parameter value (relative values with +/- if relative=true)
414 if (!defined(this.params[name])) return null;
415 var p = this.params[name];
416 if (relative && value.slice) {
417 // value is a string -- check if it starts with +/-
418 var sign = value.slice(0, 1);
419 if (sign == '+') {
420 p.value = parseFloat(p.value) + parseFloat(value.slice(1));
421 } else if (sign == '-') {
422 p.value = parseFloat(p.value) - parseFloat(value.slice(1));
423 } else {
424 p.value = value;
425 }
426 } else {
427 p.value = value;
428 }
429 p.hasValue = true;
430 return p.value;
431 }
432 Parameters.prototype.isSet = function(name) {
433 // returns if the parameter's value has been set
434 if (!defined(this.params[name])) return null;
435 return this.params[name].hasValue;
436 }
437 Parameters.prototype.getAll = function(detail) {
438 // returns a string of all parameters in query format
439 if (!detail) detail = this.PARAM_ALL;
440 var pa = new Array();
441 for (p in this.params) {
442 if (((this.params[p].detail & detail) > 0)
443 && (this.params[p].hasValue)) {
444 var val = this.params[p].value;
445 if (val != "") {
446 pa.push(p + "=" + val);
447 }
448 }
449 }
450 return pa.join("&");
451 }
452 Parameters.prototype.parse = function(query) {
453 // gets parameter values from query format string
454 var pa = query.split("&");
455 for (var i = 0; i < pa.length; i++) {
456 var keyval = pa[i].split("=");
457 if (keyval.length == 2) {
458 this.set(keyval[0], keyval[1]);
459 }
460 }
461 }
462
463 /*
464 * Flags class
465 *
466 * Flags are (hash-) collections of unique strings.
467 */
468 function Flags() {
469 this.flags = new Object();
470 return this;
471 }
472 Flags.prototype.define = function(name, detail) {
473 // create a new flag with a name and detail level
474 this.flags[name] = new Object();
475 this.flags[name].set = false;
476 this.flags[name].detail = detail;
477 return this.flags[name];
478 }
479 Flags.prototype.get = function(name) {
480 return (this.flags[name]) ? this.flags[name].set : false;
481 }
482 Flags.prototype.set = function(name, value) {
483 if (!defined(value)) value = true;
484 if (!this.flags[name]) this.flags[name] = new Object;
485 this.flags[name].set = value;
486 }
487 Flags.prototype.reset = function(name) {
488 if (!this.flags[name]) this.flags[name] = new Object;
489 this.flags[name].set = false;
490 }
491 Flags.prototype.toggle = function(name) {
492 if (!this.flags[name]) this.flags[name] = new Object;
493 this.flags[name].set = !this.flags[name].set;
494 }
495 Flags.prototype.resetAll = function() {
496 for (var f in this.flags) {
497 this.flags[f].set = false;
498 }
499 }
500 Flags.prototype.parse = function(query, sep) {
501 // sets the flags from the string query
502 if (!sep) sep = ",";
503 var fa = query.split(sep);
504 for (var i = 0; i < fa.length ; i++) {
505 var f = fa[i];
506 if (f != "") {
507 this.set(f);
508 }
509 }
510 }
511 Flags.prototype.getAll = function(detail, sep) {
512 // returns a string of all flags in query format
513 if (!detail) detail = 255;
514 if (!sep) sep = ",";
515 var fa = new Array();
516 for (f in this.flags) {
517 if (this.flags[f].set) {
518 // if the flag has a detail level it must match
519 // otherwise we assume detail=128
520 if (this.flags[f].detail) {
521 if ((this.flags[f].detail & detail) > 0) {
522 fa.push(f);
523 }
524 } else {
525 if ((detail & 128) > 0) {
526 fa.push(f);
527 }
528 }
529 }
530 }
531 return fa.join(sep);
532 }
533
534
535 /* **********************************************
536 * HTML/DOM routines
537 * ******************************************** */
538
539 function getElement(tagid, quiet) {
540 // returns the element object with the id tagid
541 var e;
542 if (document.getElementById) {
543 e = document.getElementById(tagid);
544 } else if (document.all) {
545 alert("document.all!");
546 e = document.all[tagid];
547 } else if (document.layers) {
548 e = document.layers[tagid];
549 }
550 if (e) {
551 return e;
552 } else {
553 if (! quiet) {
554 alert("unable to find element: "+tagid);
555 }
556 return null;
557 }
558 }
559
560 function getElementPosition(elem) {
561 // returns a Position with the position of the element
562 var x = 0;
563 var y = 0;
564 if (defined(elem.offsetLeft)) {
565 var e = elem;
566 while (e) {
567 if (browserType.isIE) {
568 if (browserType.isMac) {
569 if (e.offsetParent.tagName == "BODY") {
570 // IE for Mac extraspecial
571 x += e.clientLeft;
572 y += e.clientTop;
573 break;
574 }
575 } else {
576 if ((e.tagName != "TABLE") && (e.tagName != "BODY")) {
577 x += e.clientLeft;
578 y += e.clientTop;
579 }
580 }
581 }
582 x += e.offsetLeft;
583 y += e.offsetTop;
584 e = e.offsetParent;
585 }
586 } else if (defined(elem.x)) {
587 // use .x for other (which?)
588 x = elem.x;
589 y = elem.y;
590 } else if (defined(elem.pageX)) {
591 // use pageX for N4
592 x = elem.pageX;
593 y = elem.pageY;
594 } else {
595 alert("unable to get position of " + elem + " (id:" + elem.id + ")");
596 }
597 return new Position(getInt(x), getInt(y));
598 }
599
600 function getElementSize(elem) {
601 // returns a Rectangle with the size of the element
602 var width = 0;
603 var height = 0;
604 if (defined(elem.offsetWidth)) {
605 width = elem.offsetWidth;
606 height = elem.offsetHeight;
607 } else if (defined(elem.width)) {
608 width = elem.width;
609 height = elem.height;
610 } else if (defined(elem.clip.width)) {
611 width = elem.clip.width;
612 height = elem.clip.height;
613 } else {
614 alert("unable to get size of " + elem + " (id:" + elem.id + ")");
615 }
616 return new Size(getInt(width), getInt(height));
617 }
618
619 function getElementRect(elem) {
620 // returns a Rectangle with the size and position of the element
621 // FIX ME: what about borders?
622 var pos = getElementPosition(elem);
623 var size = getElementSize(elem);
624 return new Rectangle(pos.x, pos.y, size.width, size.height);
625 }
626
627 function moveElement(elem, rect) {
628 // moves and sizes the element
629 if (elem.style) {
630 if (defined(rect.x)) {
631 elem.style.left = Math.round(rect.x) + "px";
632 elem.style.top = Math.round(rect.y) + "px";
633 }
634 if (defined(rect.width)) {
635 elem.style.width = Math.round(rect.width) + "px";
636 elem.style.height = Math.round(rect.height) + "px";
637 }
638 } else if (document.layers) {
639 if (defined(rect.x)) {
640 elem.pageX = getInt(rect.x);
641 elem.pageY = getInt(rect.y);
642 }
643 if (defined(rect.width)) {
644 elem.clip.width = getInt(rect.width);
645 elem.clip.height = getInt(rect.height);
646 }
647 } else {
648 alert("moveElement(): element has no style or layer property!");
649 return false;
650 }
651 return true;
652 }
653
654 function showElement(elem, show) {
655 // shows or hides the element
656 if (elem.style)
657 elem.style.visibility = show ? "visible" : "hidden";
658 else if (defined(elem.visibility))
659 elem.visibility = show ? "show" : "hide";
660 else
661 alert("showElement(): element has no style or layer property!");
662 return true;
663 }
664
665 function evtPosition(evt) {
666 // returns the on-screen Position of the Event
667 var x;
668 var y;
669 evt = (evt) ? evt : window.event;
670 if (!evt) {
671 alert("no event found! " + evt);
672 return;
673 }
674 if (defined(evt.pageX)) {
675 x = parseInt(evt.pageX);
676 y = parseInt(evt.pageY);
677 } else if (defined(evt.clientX)) {
678 x = parseInt(document.body.scrollLeft + evt.clientX);
679 y = parseInt(document.body.scrollTop + evt.clientY);
680 } else {
681 alert("evtPosition(): don't know how to deal with " + evt);
682 }
683 return new Position(x, y);
684 }
685
686 function registerEvent(type, elem, handler) {
687 // register the given event handler on the indicated element
688 if (elem.addEventListener) {
689 elem.addEventListener(type, handler, false); // bubble
690 }
691 else if (elem.attachEvent) {
692 elem.attachEvent("on" + type, handler);
693 }
694 else if (elem.captureEvents) {
695 if (Event) {
696 t = type.toUpperCase();
697 elem.captureEvents(Event[t]);
698 elem[ "on" + type ] = handler;
699 }
700 }
701 else {
702 alert("Could not register event of type " + type);
703 return false;
704 }
705 return true;
706 }
707
708 function unregisterEvent(type, elem, handler) {
709 // unregister the given event handler from the indicated element
710 if (elem.removeEventListener) {
711 elem.removeEventListener(type, handler, false);
712 }
713 else if (elem.detachEvent) {
714 elem.detachEvent("on" + type, handler);
715 }
716 else if (elem.releaseEvents) {
717 if (Event) {
718 t = type.toUpperCase();
719 elem.releaseEvents(Event[t]);
720 elem[ "on" + type ] = null;
721 }
722 }
723 else {
724 alert("Could not register event of type " + type);
725 return false;
726 }
727 return true;
728 }
729
730 function registerEventById(type, id, handler) {
731 registerEvent(type, getElement(id), handler);
732 }
733
734 function unregisterEventById(type, id, handler) {
735 unregisterEvent(type, getElement(id), handler);
736 }
737
738 function stopEvent(e) {
739 if (!e) var e = window.event;
740 e.cancelBubble = true;
741 if (e.stopPropagation) e.stopPropagation();
742 return false;
743 }
744
745 function getEventSrc(e) {
746 if (e.target) return e.target;
747 if (e.srcElement) return e.srcElement;
748 }
749
750 // old registerXXYY API for compatibility
751 function registerMouseDown(elem, handler) {
752 return registerEvent("mousedown", elem, handler);
753 }
754 function unregisterMouseDown(elem, handler) {
755 return unregisterEvent("mousedown", elem, handler);
756 }
757 function registerMouseMove(elem, handler) {
758 return registerEvent("mousemove", elem, handler);
759 }
760 function unregisterMouseMove(elem, handler) {
761 return unregisterEvent("mousemove", elem, handler);
762 }
763 function registerKeyDown(handler) {
764 return registerEvent("keypress", elem, handler);
765 }
766
767
768 function getWinSize() {
769 // returns a Size with the current window size (mostly from www.quirksmode.org)
770 var wsize = new Size(100, 100);
771 if (defined(self.innerHeight)) {
772 // all except Explorer
773 if ((self.innerWidth == 0)||(self.innerHeight == 0)) {
774 // Safari 1.2 (and other) bug
775 if (parent) {
776 wsize.height = parent.innerHeight;
777 wsize.width = parent.innerWidth;
778 }
779 } else {
780 wsize.width = self.innerWidth;
781 wsize.height = self.innerHeight;
782 }
783 } else if (document.documentElement && document.documentElement.clientHeight) {
784 // Explorer 6 Strict Mode
785 wsize.width = document.documentElement.clientWidth;
786 wsize.height = document.documentElement.clientHeight;
787 } else if (document.body) {
788 // other Explorers
789 wsize.width = document.body.clientWidth;
790 wsize.height = document.body.clientHeight;
791 }
792 return wsize;
793 }
794
795 function getWinRect() {
796 var size = getWinSize();
797 return new Rectangle(0, 0, size.width, size.height);
798 }
799
800 function openWin(url, name, params) {
801 // open browser window
802 var ow = window.open(url, name, params);
803 ow.focus();
804 }
805
806 /* **********************************************
807 * cookie class
808 * ******************************************** */
809
810 function Cookie() {
811 return this.read();
812 }
813
814 Cookie.prototype.read = function() {
815 var s = document.cookie;
816 var lines = s.split("; "); // semicolon and space for all browsers?
817 for (var i in lines) {
818 var line = lines[i];
819 var sep = line.indexOf("=");
820 if (sep != -1) this.add(
821 line.substr(0, sep),
822 line.substr(sep + 1)
823 );
824 }
825 return this;
826 }
827
828 Cookie.prototype.store = function() {
829 var lines = new Array();
830 for (var i in this) {
831 var item = this[i];
832 if (typeof(item) == typeof(lines)) // Array
833 lines.push(i + "=" + item.join(","));
834 else if (typeof(item) != "function") // single item
835 lines.push(i + "=" + item);
836 }
837 // var s = lines.join(";")
838 for (line in lines) document.cookie = lines[line];
839 return this;
840 }
841
842 Cookie.prototype.add = function(key, value) {
843 value = value.toString();
844 if (value.indexOf(",") == -1)
845 this[key] = value; // single value
846 else
847 this[key] = value.split(","); // list of values
848 return this[key];
849 }
850
851 Cookie.prototype.get = function(key) {
852 return this[key];
853 }
854
855 Cookie.prototype.addbool = function(key, value) {
856 this[key] = Boolean(value).toString();
857 return this[key];
858 }
859
860 Cookie.prototype.getbool = function(key) {
861 var val = this[key];
862 return (val > "") && (val != "0") && (val != "false");
863 }
864
865 Cookie.prototype.remove = function(key) {
866 delete this[key];
867 }
868
869 function Slider(id, valMin, valMax, valStart, stepSize, onChange) {
870 // a (horizontal) slider widget
871 this.id = id;
872 this.elem = getElement(id);
873 this.slider = getElement(id + "-slider"); // the slider handle
874 this.input = getElement(id + "-input", 1); // optional input field
875 this.bar = getElement(id + "-bar"); // the slider bar
876 this.barRect = getElementRect(this.bar);
877 this.sliderRect = getElementRect(this.slider);
878 this.xMin = this.barRect.x;
879 this.xMax = this.xMin + this.barRect.width;
880 this.xDiff = this.xMax - this.xMin;
881 this.Y = this.barRect.getCenter().y; // middle axis of bar
882 this.valMin = valMin;
883 this.valMax = valMax;
884 this.valDiff = Math.abs(valMax - valMin);
885 this.valStart = valStart;
886 this.value = valStart;
887 this.stepSize = stepSize;
888 this.valueLabel = getElement(id + "-value", 1);
889 this.valMinLabel = getElement(id + "-valmin", 1);
890 this.valMaxLabel = getElement(id + "-valmax", 1);
891 this.onChange = onChange ? onChange : function() {};
892 this.update();
893 this.activate();
894 sliders[id + '-slider'] = this; // make a handle to the object
895 return this;
896 }
897
898 Slider.prototype.show = function(show) {
899 showElement(this.elem, show);
900 this.activate();
901 }
902
903 Slider.prototype.activate = function() {
904 this.setupEvents();
905 }
906
907 Slider.prototype.deactivate = function() {
908 unregisterEvent("mousedown", this.slider, this.onDragStart);
909 }
910
911 Slider.prototype.reset = function() {
912 this.setValue(this.startVal);
913 }
914
915 Slider.prototype.setValue = function(newVal) {
916 // sets slider to new value and updates
917 this.value = newVal;
918 this.update();
919 }
920
921 Slider.prototype.calcValue = function() {
922 // calculates value from slider position
923 var xSlider = this.sliderRect.getCenter().x - this.xMin;
924 this.value = xSlider * this.valDiff / this.xDiff;
925 return this.value;
926 }
927
928 Slider.prototype.update = function() {
929 // updates slider position to new value
930 var xSlider = this.value * this.xDiff / this.valDiff;
931 moveElement(this.slider, this.sliderRect.setCenter(
932 new Position(xSlider + this.xMin, this.Y)));
933 var strVal = this.value.toString();
934 if (this.valueLabel) this.valueLabel.innerHTML = strVal;
935 if (this.input) this.input.value = strVal;
936 }
937
938 Slider.prototype.setupEvents = function() {
939 // installs all event callbacks
940 registerEvent("mousedown", this.slider, this.onDragStart);
941 }
942
943 Slider.prototype.onDragStart = function(evt) {
944 var slider = sliders[this.id];
945 activeSlider = slider;
946 unregisterEvent("mousedown", slider.slider, slider.onDragStart);
947 registerEvent("mousemove", document, slider.onDrag);
948 registerEvent("mouseup", document, slider.onDragEnd);
949 slider.startPos = evtPosition(evt);
950 slider.startX = slider.sliderRect.getCenter().x;
951 return stopEvent(evt);
952 }
953
954 Slider.prototype.onDrag = function(evt) {
955 var slider = activeSlider;
956 var pos = evtPosition(evt);
957 var currX = slider.slider
958 var newX = pos.x - slider.startPos + slider.startX;
959 if (newX < slider.xMin) newX = slider.xMin;
960 if (newX > slider.xMax) newX = slider.xMax;
961 moveElement(slider.slider, slider.sliderRect.setCenter(
962 new Position(newX, slider.Y)));
963 return stopEvent(evt);
964 }
965
966 Slider.prototype.onDragEnd = function(evt) {
967 var slider = activeSlider;
968 unregisterEvent("mousemove", document, slider.onDrag);
969 unregisterEvent("mouseup", document, slider.onDragEnd);
970 slider.onChange(slider.calcValue());
971 activeSlider = null;
972 return stopEvent(evt);
973 }
974
975 Slider.prototype.onInputChange = function() {
976 var slider = activeSlider;
977 slider.onChange(s.value);
978 }
979
980 // :tabSize=4:indentSize=4:noTabs=true:
981