chromium/third_party/blink/web_tests/svg/carto.net/resources/scrollbar.js

/*
Scripts to create interactive scrollbars in SVG using ECMA script
Copyright (C) <2006>  <Andreas Neumann>
Version 0.9.1, 2006-10-30
[email protected]
http://www.carto.net/
http://www.carto.net/neumann/

Credits:

----

current version: 0.9.1

version history:
0.9 (2006-10-12)
initial version

0.9.1 (2006-10-30)
added .show(), .hide() and .remove() methods

-------


This ECMA script library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library (lesser_gpl.txt); if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

----

original document site: http://www.carto.net/papers/svg/gui/scrollbar/
Please contact the author in case you want to use code or ideas commercially.
If you use this code, please include this copyright header, the included full
LGPL 2.1 text and read the terms provided in the LGPL 2.1 license
(http://www.gnu.org/copyleft/lesser.txt)

-------------------------------

Please report bugs and send improvements to [email protected]
If you use this control, please link to the original (http://www.carto.net/papers/svg/gui/scrollbar/)
somewhere in the source-code-comment or the "about" of your project and give credits, thanks!

*/

function scrollbar(id,parentNode,x,y,width,height,startValue,endValue,initialHeightPerc,initialOffset,scrollStep,scrollButtonLocations,scrollbarStyles,scrollerStyles,triangleStyles,highlightStyles,functionToCall) {
    var nrArguments = 17;
    var createScrollbar = true;
    if (arguments.length == nrArguments) {
        //get constructor variables
        this.id = id;
        this.parentNode = parentNode;
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.startValue = startValue;
        this.endValue = endValue;
        this.initialHeightPerc = initialHeightPerc;
        this.initialOffset = initialOffset;
        this.scrollStep = scrollStep; //this value indicates how much the slider will scroll when the arrow buttons are pressed, values are in percentage
        this.scrollButtonLocations = scrollButtonLocations;
        if (this.scrollButtonLocations != "bottom_bottom" && this.scrollButtonLocations != "top_bottom" && this.scrollButtonLocations && "top_top" && this.scrollButtonLocations != "none_none") {
            createScrollbar = false;
            alert("Error: parameter 'scrollButtonLocations' can only be of the following values: 'bottom_bottom' || 'top_top' || 'top_bottom' || 'none_none'.");        
        }
        this.scrollbarStyles = scrollbarStyles;
        this.scrollerStyles = scrollerStyles;
        this.triangleStyles = triangleStyles;
        this.highlightStyles = highlightStyles;
        this.functionToCall = functionToCall;
        //additional properties to be used later
        this.horizOrVertical = "vertical"; //specifies wether scrollbar is horizontal or vertical
        this.cellHeight = this.width; //the height or width of the buttons on top or bottom of the scrollbar
        this.scrollStatus = false; //indicates whether scrolling is active
        this.buttonScrollActive = false; //indicates whether the scrollbutton is currently being pressed
        this.scrollbarScrollActive = false; //indicates whether the scrollbar is currently being pressed
    }
    else {
        createScrollbar = false;
        alert("Error ("+id+"): wrong nr of arguments! You have to pass over "+nrArguments+" parameters.");
    }
    if (createScrollbar) {
        //create scrollbar
        var result = this.testParent();
        if (result) {
            //timer stuff
            this.timer = new Timer(this); //a Timer instance for calling the functionToCall
            this.timerMs = 200; //a constant of this object that is used in conjunction with the timer - functionToCall is called after 200 ms
            this.createScrollbar();
        }
        else {
            alert("could not create or reference 'parentNode' of scrollbar with id '"+this.id+"'");
        }            
    }
    else {
        alert("Could not create scrollbar with id '"+id+"' due to errors in the constructor parameters");    
    }
}

//test if parent group exists or create a new group at the end of the file
scrollbar.prototype.testParent = function() {
    //test if of type object
    var nodeValid = false;
    this.parentGroup = document.createElementNS(svgNS,"g");
    if (typeof(this.parentNode) == "object") {
        if (this.parentNode.nodeName == "svg" || this.parentNode.nodeName == "g" || this.parentNode.nodeName == "svg:svg" || this.parentNode.nodeName == "svg:g") {
            this.parentNode.appendChild(this.parentGroup);
            nodeValid = true;
        }
    }
    else if (typeof(this.parentNode) == "string") { 
        //first test if button group exists
        if (!document.getElementById(this.parentNode)) {
            this.parentGroup.setAttributeNS(null,"id",this.parentNode);
            document.documentElement.appendChild(this.parentGroup);
            nodeValid = true;
           }
           else {
               document.getElementById(this.parentNode).appendChild(this.parentGroup);
               nodeValid = true;
           }
       }
       return nodeValid;
}

//create scrollbar geometry
scrollbar.prototype.createScrollbar = function() {
    //first determine if vertical of horizontal
    if (this.width > this.height) {
        this.horizOrVertical = "horizontal";
        this.cellHeight = this.height;
    }
    this.triangleFourth = Math.round(this.cellHeight / 4); //this is used to construct the triangles for the buttons

    if (this.scrollButtonLocations != "none_none") {
        this.scrollUpperRect = document.createElementNS(svgNS,"rect");
        this.scrollLowerRect = document.createElementNS(svgNS,"rect");
        this.scrollUpperTriangle = document.createElementNS(svgNS,"path");
        this.scrollLowerTriangle = document.createElementNS(svgNS,"path");
    }
 
    if (this.horizOrVertical == "vertical")  {
        this.scrollUpperRectX = this.x;
        this.scrollLowerRectX = this.x;
        switch (this.scrollButtonLocations)  {
            case "top_top":
                this.scrollbarX = this.x;
                this.scrollbarY = this.y + (2 * this.cellHeight);
                this.scrollbarWidth = this.width;
                this.scrollbarHeight = this.height - (2 * this.cellHeight);
                 this.scrollUpperRectY = this.y;
                 this.scrollLowerRectY = this.y + this.cellHeight;
                break;
            case "bottom_bottom":
                this.scrollbarX = this.x;
                this.scrollbarY = this.y;
                this.scrollbarWidth = this.width;
                this.scrollbarHeight = this.height - (2 * this.cellHeight);
                 this.scrollUpperRectY = this.y + this.height - (2 * this.cellHeight);
                 this.scrollLowerRectY = this.y + this.height - this.cellHeight;
                break;
            case "top_bottom":
                this.scrollbarX = this.x;
                this.scrollbarY = this.y + this.cellHeight;
                this.scrollbarWidth = this.width;
                this.scrollbarHeight = this.height - (2 * this.cellHeight);
                 this.scrollUpperRectY = this.y;
                 this.scrollLowerRectY = this.y + this.height - this.cellHeight;
                break;
            default:
                this.scrollbarX = this.x;
                this.scrollbarY = this.y;
                this.scrollbarWidth = this.width;
                this.scrollbarHeight = this.height;
                break;                
        }
        var myUpperTriPath = "M"+(this.scrollUpperRectX + this.cellHeight * 0.5)+" "+(this.scrollUpperRectY + this.triangleFourth)+" L"+(this.scrollUpperRectX + 3 * this.triangleFourth)+" "+(this.scrollUpperRectY + 3 * this.triangleFourth)+" L"+(this.scrollUpperRectX + this.triangleFourth)+" "+(this.scrollUpperRectY + 3 * this.triangleFourth)+" Z";
        var myLowerTriPath = "M"+(this.scrollLowerRectX + this.cellHeight * 0.5)+" "+(this.scrollLowerRectY + 3 * this.triangleFourth)+" L"+(this.scrollLowerRectX + this.triangleFourth)+" "+(this.scrollLowerRectY + this.triangleFourth)+" L"+(this.scrollLowerRectX + this.triangleFourth * 3)+" "+(this.scrollLowerRectY + this.triangleFourth)+" Z";
    }

    if (this.horizOrVertical == "horizontal")  {
        this.scrollUpperRectY = this.y;
        this.scrollLowerRectY = this.y;
        switch (this.scrollButtonLocations)  {
            case "top_top":
                this.scrollbarX = this.x + (2 * this.cellHeight);
                this.scrollbarY = this.y;
                this.scrollbarWidth = this.width - (2 * this.cellHeight);
                this.scrollbarHeight = this.height;
                this.scrollUpperRectX = this.x;
                 this.scrollLowerRectX = this.x + this.cellHeight;
                break;
            case "bottom_bottom":
                this.scrollbarX = this.x;
                this.scrollbarY = this.y;
                this.scrollbarWidth = this.width - (2 * this.cellHeight);
                this.scrollbarHeight = this.height;
                 this.scrollUpperRectX = this.x + this.width - (2 * this.cellHeight);
                 this.scrollLowerRectX = this.x + this.width - this.cellHeight;
                break;
            case "top_bottom":
                this.scrollbarX = this.x + this.cellHeight;
                this.scrollbarY = this.y;
                this.scrollbarWidth = this.width - (2 * this.cellHeight);
                this.scrollbarHeight = this.height;
                 this.scrollUpperRectX = this.x;
                 this.scrollLowerRectX = this.x + this.width - this.cellHeight;
                break;
            default:
                this.scrollbarX = this.x;
                this.scrollbarY = this.y;
                this.scrollbarWidth = this.width;
                this.scrollbarHeight = this.height;
                break;                
        }
        var myUpperTriPath = "M"+(this.scrollUpperRectX + this.triangleFourth)+" "+(this.scrollUpperRectY + this.triangleFourth * 2)+" L"+(this.scrollUpperRectX + 3 * this.triangleFourth)+" "+(this.scrollUpperRectY + this.triangleFourth)+" L"+(this.scrollUpperRectX + 3 * this.triangleFourth)+" "+(this.scrollUpperRectY + 3 * this.triangleFourth)+" Z";
        var myLowerTriPath = "M"+(this.scrollLowerRectX + this.triangleFourth * 3)+" "+(this.scrollLowerRectY + 2 * this.triangleFourth)+" L"+(this.scrollLowerRectX + this.triangleFourth)+" "+(this.scrollLowerRectY + this.triangleFourth * 3)+" L"+(this.scrollLowerRectX + this.triangleFourth)+" "+(this.scrollLowerRectY + this.triangleFourth)+" Z";
    }

    this.scrollbar = document.createElementNS(svgNS,"rect");
    this.scrollbar.setAttributeNS(null,"x",this.scrollbarX);
    this.scrollbar.setAttributeNS(null,"y",this.scrollbarY);
    this.scrollbar.setAttributeNS(null,"width",this.scrollbarWidth);
    this.scrollbar.setAttributeNS(null,"height",this.scrollbarHeight);
    this.scrollbar.setAttributeNS(null,"id","scrollbar_"+this.id);
    for (var attrib in this.scrollbarStyles) {
        this.scrollbar.setAttributeNS(null,attrib,this.scrollbarStyles[attrib]);
    }
    this.scrollbar.addEventListener("mousedown",this,false);
    this.parentGroup.appendChild(this.scrollbar);
    //now create scroller
    this.scroller = document.createElementNS(svgNS,"rect");
    if (this.horizOrVertical == "vertical")  {
        this.scroller.setAttributeNS(null,"x",this.scrollbarX);
        this.scrollerY = this.scrollbarY + (this.scrollbarHeight - this.scrollbarHeight * this.initialHeightPerc)  * this.initialOffset;
        this.scroller.setAttributeNS(null,"y",this.scrollerY);
        this.scroller.setAttributeNS(null,"width",this.scrollbarWidth);
        this.scrollerHeight = this.scrollbarHeight * this.initialHeightPerc;
        this.scroller.setAttributeNS(null,"height",this.scrollerHeight);
    }
    if (this.horizOrVertical == "horizontal")  {
        this.scrollerX = this.scrollbarX + (this.scrollbarWidth - this.scrollbarWidth * this.initialHeightPerc)  * this.initialOffset;
        this.scroller.setAttributeNS(null,"x",this.scrollerX);
        this.scroller.setAttributeNS(null,"y",this.scrollbarY);
        this.scrollerWidth = this.scrollbarWidth * this.initialHeightPerc;
        this.scroller.setAttributeNS(null,"width",this.scrollerWidth);
        this.scroller.setAttributeNS(null,"height",this.scrollbarHeight);
    }
    for (var attrib in this.scrollerStyles) {
        this.scroller.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
    }
    //need to add events here
    this.scroller.setAttributeNS(null,"id","scroller_"+this.id);
    this.scroller.addEventListener("mousedown",this,false);
    this.parentGroup.appendChild(this.scroller);
    //append rects and triangles
    if (this.scrollButtonLocations != "none_none") {
        //upper rect
        for (var attrib in this.scrollerStyles) {
            this.scrollUpperRect.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
        }
        this.scrollUpperRect.setAttributeNS(null,"x",this.scrollUpperRectX);
        this.scrollUpperRect.setAttributeNS(null,"y",this.scrollUpperRectY);
        this.scrollUpperRect.setAttributeNS(null,"width",this.cellHeight);
        this.scrollUpperRect.setAttributeNS(null,"height",this.cellHeight);
        this.scrollUpperRect.addEventListener("mousedown", this, false);
        this.scrollUpperRect.setAttributeNS(null,"id","scrollUpperRect_"+this.id);
        this.parentGroup.appendChild(this.scrollUpperRect);
        //lower rect
        for (var attrib in this.scrollerStyles) {
            this.scrollLowerRect.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
        }
        this.scrollLowerRect.setAttributeNS(null,"x",this.scrollLowerRectX);
        this.scrollLowerRect.setAttributeNS(null,"y",this.scrollLowerRectY);
        this.scrollLowerRect.setAttributeNS(null,"width",this.cellHeight);
        this.scrollLowerRect.setAttributeNS(null,"height",this.cellHeight);
        this.scrollLowerRect.addEventListener("mousedown", this, false);
        this.scrollLowerRect.setAttributeNS(null,"id","scrollLowerRect_"+this.id);
        this.parentGroup.appendChild(this.scrollLowerRect);
        //upper triangle
        this.scrollUpperTriangle.setAttributeNS(null,"d",myUpperTriPath);
        this.scrollUpperTriangle.setAttributeNS(null,"pointer-events","none");
        for (var attrib in this.triangleStyles) {
            this.scrollUpperTriangle.setAttributeNS(null,attrib,this.triangleStyles[attrib]);
        }
        this.parentGroup.appendChild(this.scrollUpperTriangle);
        //lower triangle
        this.scrollLowerTriangle.setAttributeNS(null,"d",myLowerTriPath);
        this.scrollLowerTriangle.setAttributeNS(null,"pointer-events","none");
        for (var attrib in this.triangleStyles) {
            this.scrollLowerTriangle.setAttributeNS(null,attrib,this.triangleStyles[attrib]);
        }
        this.parentGroup.appendChild(this.scrollLowerTriangle);
    }
 }
 
 scrollbar.prototype.handleEvent = function(evt) {
    var el = evt.target;
    var callerId = el.getAttributeNS(null,"id");
    if (evt.type == "mousedown") {
        if (callerId == "scroller_"+this.id) {
            //case the mouse went down on scroller
            this.scroll(evt);
        }
        if (callerId == "scrollLowerRect_"+this.id || callerId == "scrollUpperRect_"+this.id) {
            //this part is for scrolling per button
            this.buttonScrollActive = true;
            this.scrollDir = "down";
            this.currentScrollButton = evt.target;
            this.currentScrollTriangle = this.scrollLowerTriangle;
            if (callerId == "scrollUpperRect_"+this.id) {
                this.scrollDir = "up";
                this.currentScrollTriangle = this.scrollUpperTriangle;
            }
            document.documentElement.addEventListener("mouseup",this,false);
            //change appearance of button
            for (var attrib in this.scrollerStyles) {
                this.currentScrollButton.removeAttributeNS(null,attrib);
            }
            for (var attrib in this.highlightStyles) {
                this.currentScrollButton.setAttributeNS(null,attrib,this.highlightStyles[attrib]);
            }
            //change appearance of triangle
            for (var attrib in this.triangleStyles) {
                this.currentScrollTriangle.removeAttributeNS(null,attrib);
            }
            for (var attrib in this.scrollerStyles) {
                this.currentScrollTriangle.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
            }
            this.scrollPercent(this.scrollDir,this.scrollStep);
            this.timer.setTimeout("scrollPerButton",400);
        }
        if (callerId == "scrollbar_"+this.id) {
            //this part is for scrolling when mouse is down on scrollbar
            var coords = myMapApp.calcCoord(evt,this.scrollbar);
            this.scrollbarScrollActive = true;
            this.scrollDir = "down";
            if (this.horizOrVertical == "vertical") {
                if (coords.y < this.scrollerY) {
                    this.scrollDir = "up";
                }
            }
            if (this.horizOrVertical == "horizontal") {
                if (coords.x < this.scrollerX) {
                    this.scrollDir = "up";
                }
            }
            document.documentElement.addEventListener("mouseup",this,false);
            //change styling
            for (var attrib in this.scrollerStyles) {
                this.scroller.removeAttributeNS(null,attrib);
            }
            for (var attrib in this.highlightStyles) {
                this.scroller.setAttributeNS(null,attrib,this.highlightStyles[attrib]);
            }
            this.scrollPercent(this.scrollDir,this.scrollStep*10);
            this.timer.setTimeout("scrollPerScrollbar",400);
        }
    }
    if (evt.type == "mousemove" && this.scrollStatus) {
        //this is for scrolling per scroller
        this.scroll(evt);
    }
    if (evt.type == "mouseup") {
        //this is for finishing the different scroll modi
        if (this.scrollStatus) {
            //finishing scroll per scroller
            this.scroll(evt);
        }
        if (this.buttonScrollActive) {
            //finishing scroll per button
            this.buttonScrollActive = false;
            document.documentElement.removeEventListener("mouseup",this,false);
            //change appearance of button
            for (var attrib in this.highlightStyles) {
                this.currentScrollButton.removeAttributeNS(null,attrib);
            }
            for (var attrib in this.scrollerStyles) {
                this.currentScrollButton.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
            }
            //change appearance of triangle
            for (var attrib in this.scrollerStyles) {
                this.currentScrollTriangle.removeAttributeNS(null,attrib);
            }
            for (var attrib in this.triangleStyles) {
                this.currentScrollTriangle.setAttributeNS(null,attrib,this.triangleStyles[attrib]);
            }
            this.currentScrollButton = undefined;
            this.currentScrollTriangle = undefined;
        }
        if (this.scrollbarScrollActive) {
            //finishing scroll per scrollbar
            this.scrollbarScrollActive = false;
            document.documentElement.removeEventListener("mouseup",this,false);        
            //change styling
            for (var attrib in this.highlightStyles) {
                this.scroller.removeAttributeNS(null,attrib);
            }
            for (var attrib in this.scrollerStyles) {
                this.scroller.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
            }
        }
    }
}

scrollbar.prototype.scroll = function(evt) {
    var coords = myMapApp.calcCoord(evt,this.scrollbar);
    if (evt.type == "mousedown") {
        document.documentElement.addEventListener("mousemove",this,false);
        document.documentElement.addEventListener("mouseup",this,false);
        this.scrollStatus = true;
        this.panCoords = coords;
        this.fireFunction("scrollStart");
        //change styling
        for (var attrib in this.scrollerStyles) {
            this.scroller.removeAttributeNS(null,attrib);
        }
        for (var attrib in this.highlightStyles) {
            this.scroller.setAttributeNS(null,attrib,this.highlightStyles[attrib]);
        }
    }
    if (evt.type == "mousemove") {
        var diffX = coords.x - this.panCoords.x;
        var diffY = coords.y - this.panCoords.y;
        var scrollerDiff = false;
        if (this.horizOrVertical == "vertical") {
            var scrollerOrigY = this.scrollerY;
            this.scrollerY += diffY;
            if (this.scrollerY < this.scrollbarY) {
                this.scrollerY = this.scrollbarY;
            }
            if ((this.scrollerY + this.scrollerHeight) > (this.scrollbarY + this.scrollbarHeight)) {
                this.scrollerY = this.scrollbarY + this.scrollbarHeight - this.scrollerHeight;
            }
            this.scroller.setAttributeNS(null,"y",this.scrollerY);
            if (scrollerOrigY != this.scrollerY) {
                scrollerDiff = true;
            }
        }
        if (this.horizOrVertical == "horizontal") {
            var scrollerOrigX = this.scrollerX;
            this.scrollerX += diffX;
            if (this.scrollerX < this.scrollbarX) {
                this.scrollerX = this.scrollbarX;
            }
            if ((this.scrollerX + this.scrollerWidth) > (this.scrollbarX + this.scrollbarWidth)) {
                this.scrollerX = this.scrollbarX + this.scrollbarWidth - this.scrollerWidth;
            }
            this.scroller.setAttributeNS(null,"x",this.scrollerX);
            if (scrollerOrigX != this.scrollerX) {
                scrollerDiff = true;
            }
        }
        if (scrollerDiff) {
            this.fireFunction("scrollChange");
        }
        this.panCoords = coords;
    }
    if (evt.type == "mouseup") {
        this.scrollStatus = false;
        document.documentElement.removeEventListener("mousemove",this,false);
        document.documentElement.removeEventListener("mouseup",this,false);
        //change styling
        for (var attrib in this.highlightStyles) {
            this.scroller.removeAttributeNS(null,attrib);
        }
        for (var attrib in this.scrollerStyles) {
            this.scroller.setAttributeNS(null,attrib,this.scrollerStyles[attrib]);
        }
        this.fireFunction("scrollEnd");
    }
}

scrollbar.prototype.scrollPercent = function(direction,increment) {
    var currentValues = this.getValue();
    if (direction == "up") {
        increment = increment * -1;
    }
    var newPercent = currentValues.perc + increment;
    if (newPercent < 0) {
        newPercent = 0;
    }
    if (newPercent > 1) {
        newPercent = 1;
    }
    this.scrollToPercent(newPercent);
}

scrollbar.prototype.scrollToPercent = function(percValue) {
    if (percValue >= 0 && percValue <= 1) {
        if (this.horizOrVertical == "vertical") {
            var newY = this.scrollbarY + (this.scrollbarHeight - this.scrollerHeight) * percValue;
            this.scrollerY = newY;
            this.scroller.setAttributeNS(null,"y",newY);
        }
        if (this.horizOrVertical == "horizontal") {
            var newX = this.scrollbarX + (this.scrollbarWidth - this.scrollerWidth) * percValue;
            this.scrollerX = newX;
            this.scroller.setAttributeNS(null,"x",newX);
        }
        this.fireFunction("scrolledStep");
    }
    else {
        alert("error in method '.scrollToPercent()' of scrollbar with id '"+this.id+"'. Value out of range. Value needs to be in range 0 <= value <= 1.");
    }
}

scrollbar.prototype.scrollPerButton = function() {
    if (this.buttonScrollActive) {
            this.scrollPercent(this.scrollDir,this.scrollStep);
            this.timer.setTimeout("scrollPerButton",150);
    }
}

scrollbar.prototype.scrollPerScrollbar = function() {
    if (this.scrollbarScrollActive) {
            this.scrollPercent(this.scrollDir,this.scrollStep*5);
            this.timer.setTimeout("scrollPerScrollbar",150);
    }
}

scrollbar.prototype.scrollToValue = function(value) {
    if ((value >= this.startValue && value <= this.endValue) || (value <= this.startValue && value >= this.endValue)) {
        var percValue = value/(this.endValue - this.startValue);
        this.scrollToPercent(percValue);
    }
    else {
        alert("Error in scrollbar with id '"+this.id+"': the provided value '"+value+"' is out of range. The valid range is between '"+this.startValue+"' and '"+this.endValue+"'");
    }
}

scrollbar.prototype.getValue = function() {
    var perc;
    if (this.horizOrVertical == "vertical") {
        perc = (this.scrollerY - this.scrollbarY) / (this.scrollbarHeight - this.scrollerHeight);
    }
    if (this.horizOrVertical == "horizontal") {
        perc = (this.scrollerX - this.scrollbarX) / (this.scrollbarWidth - this.scrollerWidth);
    }
    var abs = this.startValue + (this.endValue - this.startValue) * perc;
    return {"abs":abs,"perc":perc};
}

scrollbar.prototype.fireFunction = function(changeType) {
    var values = this.getValue();
    if (typeof(this.functionToCall) == "function") {
        this.functionToCall(this.id,changeType,values.abs,values.perc);
    }
    if (typeof(this.functionToCall) == "object") {
        this.functionToCall.scrollbarChanged(this.id,changeType,values.abs,values.perc);
    }
    if (typeof(this.functionToCall) == undefined) {
        return;
    }
}

scrollbar.prototype.hide = function() {
    this.parentGroup.setAttributeNS(null,"display","none");
}

scrollbar.prototype.show = function() {
    this.parentGroup.setAttributeNS(null,"display","inherit");
}

scrollbar.prototype.remove = function() {
    this.parentGroup.parentNode.removeChild(this.parentGroup);
}