Annotation of zogiLib/js/js_lib.js, revision 1.1

1.1     ! casties     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 3.5.2004
        !            18:   first version by Christian Luginbuehl, 01.05.2003
        !            19:   Changed for digiLib in Zope by DW 24.03.2004
        !            20: */
        !            21: 
        !            22: // fixes for javascript < 1.2
        !            23: if (! Array.prototype.push) {
        !            24:     Array.prototype.push = function(val) {
        !            25:    this[this.length] = val;
        !            26:    return this.length;
        !            27:     }
        !            28:     Array.prototype.pop = function() {
        !            29:    var val = this[this.length-1];
        !            30:    this.length -= 1;
        !            31:    return val;
        !            32:     }
        !            33: }
        !            34: 
        !            35: // auxiliary function to crop senseless precision
        !            36: function cropFloat(x) {
        !            37:     return parseInt(10000*x)/10000;
        !            38: }
        !            39: 
        !            40: 
        !            41: /* **********************************************
        !            42:  *     geometry classes
        !            43:  * ******************************************** */
        !            44: 
        !            45: /*
        !            46:  * Size class
        !            47:  */
        !            48: function Size(w, h) {
        !            49:     this.width = parseFloat(w);
        !            50:     this.height = parseFloat(h);
        !            51:     return this;
        !            52: }
        !            53: 
        !            54: /*
        !            55:  * Position class
        !            56:  */
        !            57: function Position(x, y) {
        !            58:     this.x = parseFloat(x);
        !            59:     this.y = parseFloat(y);
        !            60:     return this;
        !            61: }
        !            62: 
        !            63: /*
        !            64:  * Rectangle class
        !            65:  */
        !            66: function Rectangle(x, y, w, h) {
        !            67:     this.x = parseFloat(x);
        !            68:     this.y = parseFloat(y);
        !            69:     this.width = parseFloat(w);
        !            70:     this.height = parseFloat(h);
        !            71:     return this;
        !            72: }
        !            73: Rectangle.prototype.copy = function() {
        !            74:     // returns a copy of this Rectangle
        !            75:     return new Rectangle(this.x, this.y, this.width, this.height);
        !            76: }
        !            77: Rectangle.prototype.containsPosition = function(pos) {
        !            78:     // returns if the given Position lies in this Rectangle
        !            79:     return ((pos.x >= this.x)&&(pos.y >= this.y)&&(pos.x <= this.x+this.width)&&(pos.y <= this.y+this.width));
        !            80: }
        !            81: Rectangle.prototype.intersect = function(rect) {
        !            82:     // returns the intersection of the given Rectangle and this one
        !            83:     var sec = rect.copy();
        !            84:     if (sec.x < this.x) {
        !            85:    sec.width = sec.width - (this.x - sec.x);
        !            86:    sec.x = this.x;
        !            87:     }
        !            88:     if (sec.y < this.y) {
        !            89:    sec.height = sec.height - (this.y - sec.y);
        !            90:    sec.y = this.y;
        !            91:     }
        !            92:     if (sec.x + sec.width > this.x + this.width) {
        !            93:    sec.width = (this.x + this.width) - sec.x;
        !            94:     }
        !            95:     if (sec.y + sec.height > this.y + this.height) {
        !            96:    sec.height = (this.y + this.height) - sec.y;
        !            97:     }
        !            98:     return sec;
        !            99: }
        !           100: Rectangle.prototype.fit = function(rect) {
        !           101:     // returns a Rectangle that fits into this one (by moving first)
        !           102:     var sec = rect.copy();
        !           103:     sec.x = Math.max(sec.x, this.x);
        !           104:     sec.x = Math.max(sec.x, this.x);
        !           105:     if (sec.x + sec.width > this.x + this.width) {
        !           106:    sec.x = this.x + this.width - sec.width;
        !           107:     }
        !           108:     if (sec.y + sec.height > this.y + this.height) {
        !           109:    sec.y = this.y + this.height - sec.height;
        !           110:     }
        !           111:     return sec.intersect(this);
        !           112: }
        !           113: 
        !           114: /*
        !           115:  * Transform class
        !           116:  *
        !           117:  * defines a class of affine transformations
        !           118:  */
        !           119: function Transform() {
        !           120:     this.m00 = 1.0;
        !           121:     this.m01 = 0.0;
        !           122:     this.m02 = 0.0;
        !           123:     this.m10 = 0.0;
        !           124:     this.m11 = 1.0;
        !           125:     this.m12 = 0.0;
        !           126:     this.m20 = 0.0;
        !           127:     this.m21 = 0.0;
        !           128:     this.m22 = 1.0;
        !           129:     return this;
        !           130: }
        !           131: Transform.prototype.concat = function(traf) {
        !           132:     // add Transform traf to this Transform
        !           133:     for (var i = 0; i < 3; i++) {
        !           134:    for (var j = 0; j < 3; j++) {
        !           135:        var c = 0.0;
        !           136:        for (var k = 0; k < 3; k++) {
        !           137:        c += traf["m"+i+k] * this["m"+k+j];
        !           138:        }
        !           139:        this["m"+i+j] = c;
        !           140:    }
        !           141:     }
        !           142:     return this;
        !           143: }
        !           144: Transform.prototype.transform = function(pos) {
        !           145:     // returns transformed Position pos with this Transform applied
        !           146:     var x = this.m00 * pos.x + this.m01 * pos.y + this.m02;
        !           147:     var y = this.m10 * pos.x + this.m11 * pos.y + this.m12;
        !           148:     return new Position(x, y);
        !           149: }
        !           150: Transform.prototype.invtransform = function(pos) {
        !           151:     // returns transformed Position pos with the inverse of this Transform applied
        !           152:     var det = this.m00 * this.m11 - this.m01 * this.m10;
        !           153:     var x = (this.m11 * pos.x - this.m01 * pos.y - this.m11 * this.m02 + this.m01 * this.m12) / det;
        !           154:     var y = (- this.m10 * pos.x + this.m00 * pos.y + this.m10 * this.m02 - this.m00 * this.m12) / det;
        !           155:     return new Position(x, y);
        !           156: }
        !           157: function getRotation(angle, pos) {
        !           158:     // returns a Transform that is a rotation by angle degrees around [pos.x, pos.y]
        !           159:     var traf = new Transform();
        !           160:     if (angle != 0) {
        !           161:    var t = 2.0 * Math.PI * parseFloat(angle) / 360.0;
        !           162:    traf.m00 = Math.cos(t);
        !           163:    traf.m01 = - Math.sin(t);
        !           164:    traf.m10 = Math.sin(t);
        !           165:    traf.m11 = Math.cos(t);
        !           166:    traf.m02 = pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t);
        !           167:    traf.m12 = pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t);
        !           168:     }
        !           169:     return traf;
        !           170: }
        !           171: function getTranslation(pos) {
        !           172:     // returns a Transform that is a translation by [pos.x, pos,y]
        !           173:     var traf = new Transform();
        !           174:     traf.m02 = pos.x;
        !           175:     traf.m12 = pos.y;
        !           176:     return traf;
        !           177: }
        !           178: function getScale(size) {
        !           179:     // returns a Transform that is a scale by [size.width, size.height]
        !           180:     var traf = new Transform();
        !           181:     traf.m00 = size.width;
        !           182:     traf.m11 = size.height;
        !           183:     return traf;
        !           184: }
        !           185: 
        !           186: 
        !           187: /* **********************************************
        !           188:  *     parameter routines
        !           189:  * ******************************************** */
        !           190: 
        !           191: var dlParams = new Object();
        !           192: 
        !           193: function newParameter(name, defaultValue, detail) {
        !           194:     // create a new parameter with a name and a default value
        !           195:     if (dlParams[name]) {
        !           196:    alert("Fatal: An object with name '" + name + "' already exists - cannot recreate!");
        !           197:    return false;
        !           198:     } else {
        !           199:    dlParams[name] = new Object();
        !           200:    dlParams[name].defaultValue = defaultValue;
        !           201:    dlParams[name].hasValue = false;
        !           202:    dlParams[name].value = defaultValue;
        !           203:    dlParams[name].detail = detail;
        !           204:    return dlParams[name];
        !           205:     }
        !           206: }
        !           207: 
        !           208: function getParameter(name) {
        !           209:     // returns the named parameter value or its default value
        !           210:     if (dlParams[name]) {
        !           211:    if (dlParams[name].hasValue) {
        !           212:        return dlParams[name].value;
        !           213:    } else {
        !           214:        return dlParams[name].defaultValue;
        !           215:    }
        !           216:     } else {
        !           217:    return undefined;
        !           218:     }
        !           219: }
        !           220: 
        !           221: function setParameter(name, value) {
        !           222:     // sets parameter value
        !           223:     if (dlParams[name]) {
        !           224:    dlParams[name].value = value;
        !           225:    dlParams[name].hasValue = true;
        !           226:    return true;
        !           227:     }
        !           228:     return false;
        !           229: }
        !           230: 
        !           231: function getAllParameters(detail) {
        !           232:     // returns a string of all parameters in query format
        !           233:     var params = new Array();
        !           234:     for ( param in dlParams ) {
        !           235:    if ((dlParams[param].detail <= detail)&&(dlParams[param].hasValue)) {
        !           236:        var val = getParameter(param);
        !           237:        if (val != "") {
        !           238:        params.push(param + "=" + val);
        !           239:        }
        !           240:    }
        !           241:     }
        !           242:     return params.join("&");
        !           243: }
        !           244: 
        !           245: function parseParameters(query) {
        !           246:     // gets parameter values from query format string
        !           247:     var params = query.split("&");
        !           248:     for (var i = 0; i < params.length; i++) {
        !           249:    var keyval = params[i].split("=");
        !           250:    if (keyval.length == 2) {
        !           251:        setParameter(keyval[0], keyval[1]);
        !           252:    }
        !           253:     }
        !           254: }
        !           255: 
        !           256: 
        !           257: /* **********************************************
        !           258:  *     HTML/DOM routines
        !           259:  * ******************************************** */
        !           260: 
        !           261: function getElement(tagid) {
        !           262:     // returns the element object with the id tagid
        !           263:     if (document.getElementById) {
        !           264:    return document.getElementById(tagid);
        !           265:     } else if (document.all) {
        !           266:    alert("document.all!");
        !           267:    return document.all[tagid];
        !           268:     } else {
        !           269:    var s = "";
        !           270:    for (var e in document.layers) {
        !           271:        s += "'" + e + "', ";
        !           272:    }
        !           273:    alert("no document.all! "+tagid+" = "+s);
        !           274:    return document[tagid];
        !           275:     }
        !           276: }    
        !           277: 
        !           278: function getElementSize(tagid) {
        !           279:     // returns a Rectangle with the size and position of the named element
        !           280:     var x = 0;
        !           281:     var y = 0;
        !           282:     var width = 0;
        !           283:     var height = 0;
        !           284:     var elem = getElement(tagid);
        !           285:     if (elem.left) {
        !           286:    alert("elem.left!");
        !           287:    x = elem.left;
        !           288:    y = elem.top;
        !           289:    width = elem.width;
        !           290:    height = elem.height;
        !           291:     } else {
        !           292:    if (elem.clientLeft) {
        !           293:        // spass mit IE
        !           294:        x = elem.clientLeft;
        !           295:        y = elem.clientTop;
        !           296:    } else {
        !           297:        var e = elem;
        !           298:        while (e) {
        !           299:        x += e.offsetLeft;
        !           300:        y += e.offsetTop;
        !           301:        e = e.offsetParent;
        !           302:        }
        !           303:    }
        !           304:    width = elem.offsetWidth;
        !           305:    height = elem.offsetHeight;
        !           306:     }
        !           307:     return new Rectangle(x, y, width, height);
        !           308: }
        !           309: 
        !           310: function moveElement(tagid, pos) {
        !           311:     // moves the named element to the indicated position
        !           312:     var elem = getElement(tagid);
        !           313:     if (elem.style) {
        !           314:    elem.style.left = pos.x + "px";
        !           315:    elem.style.top = pos.y + "px";
        !           316:     } else {
        !           317:    alert("moveelement: no style property!");
        !           318:    elem.left = pos.x;
        !           319:    elem.top = pos.y;
        !           320:     }
        !           321:     return true;
        !           322: }
        !           323: 
        !           324: function showElement(tagid, show) {
        !           325:     // shows or hides the named element
        !           326:     var elem = getElement(tagid);
        !           327:     if (elem.style) {
        !           328:    if (show) {
        !           329:        elem.style.visibility = "visible";
        !           330:    } else {
        !           331:        elem.style.visibility = "hidden";
        !           332:    }
        !           333:     } else {
        !           334:    alert("showelement: no style property!");
        !           335:     }
        !           336:     return true;
        !           337: }
        !           338: 
        !           339: function evtPosition(evt) {
        !           340:     // returns the on-screen Position of the Event 
        !           341:     var x;
        !           342:     var y;
        !           343:     if (document.all) {
        !           344:    x = parseInt(document.body.scrollLeft+event.clientX);
        !           345:    y = parseInt(document.body.scrollLeft+event.clientY);
        !           346:     } else {
        !           347:    x = parseInt(evt.pageX);
        !           348:    y = parseInt(evt.pageY);
        !           349:     }
        !           350:     return new Position(x, y);
        !           351: }
        !           352: 
        !           353: function registerMouseDown(tagid, handler) {
        !           354:     // register a mouse down event handler on the indicated element
        !           355:     if ( document.all ) {
        !           356:    document.all[tagid].onmousedown = handler;
        !           357:     } else if (document.getElementById) {
        !           358:    document.getElementById(tagid).addEventListener("mousedown", handler, true);
        !           359:     } else {
        !           360:    document[tagid].captureEvents(Event.MOUSEDOWN);
        !           361:    document[tagid].onmousedown = handler;
        !           362:     }
        !           363:     return true;
        !           364: }
        !           365: 
        !           366: function unregisterMouseDown(tagid, handler) {
        !           367:     // unregister the mouse down event handler
        !           368:     if ( document.all ) {
        !           369:    document.all[tagid].onmousedown = null;
        !           370:     } else if (document.getElementById) {
        !           371:    document.getElementById(tagid).removeEventListener("mousedown", handler, true);
        !           372:     } else {
        !           373:    document[tagid].releaseEvents(Event.MOUSEDOWN);
        !           374:     }
        !           375:     return true;
        !           376: }
        !           377: 
        !           378: function registerMouseMove(tagid, handler) {
        !           379:     // register a mouse move event handler on the indicated element
        !           380:     if ( document.all ) {
        !           381:    document.all[tagid].onmousemove = handler;
        !           382:     } else if (document.getElementById) {
        !           383:    document.getElementById(tagid).addEventListener("mousemove", handler, true);
        !           384:     } else {
        !           385:    document[tagid].captureEvents(Event.MOUSEMOVE);
        !           386:    document[tagid].onmousemove = handler;
        !           387:     }
        !           388:     return true;
        !           389: }
        !           390: 
        !           391: function unregisterMouseMove(tagid, handler) {
        !           392:     // unregister the mouse move event handler
        !           393:     if ( document.all ) {
        !           394:    document.all[tagid].onmousemove = null;
        !           395:     } else if (document.getElementById) {
        !           396:    document.getElementById(tagid).removeEventListener("mousemove", handler, true);
        !           397:     } else {
        !           398:    document[tagid].releaseEvents(Event.MOUSEMOVE);
        !           399:     }
        !           400:     return true;
        !           401: }
        !           402: 
        !           403: function registerKeyDown(handler) {
        !           404:     // register a key down handler
        !           405:     if ( document.all ) {
        !           406:    this.document.onkeypress = handler
        !           407:     } else if ( typeof(document.addEventListener) == "function" ) {
        !           408:    this.document.addEventListener('keypress', handler, true);
        !           409:     } else {
        !           410:    window.captureEvents(Event.KEYDOWN);
        !           411:    window.onkeydown = handler;
        !           412:     }
        !           413:     return true;
        !           414: }
        !           415: 
        !           416: function getWinSize() {
        !           417:     // returns a Size with the current window size (from www.quirksmode.org)
        !           418:     var wsize = new Size(100, 100);
        !           419:     if (self.innerHeight)  {
        !           420:    // all except Explorer
        !           421:    wsize.width = self.innerWidth;
        !           422:    wsize.height = self.innerHeight;
        !           423:     } else if (document.documentElement && document.documentElement.clientHeight) {
        !           424:    // Explorer 6 Strict Mode
        !           425:    wsize.width = document.documentElement.clientWidth;
        !           426:    wsize.height = document.documentElement.clientHeight;
        !           427:     } else if (document.body) {
        !           428:    // other Explorers
        !           429:    wsize.width = document.body.clientWidth;
        !           430:    wsize.height = document.body.clientHeight;
        !           431:     }
        !           432:     return wsize;
        !           433: }
        !           434: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>