Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / svg / carto.net / resources / slider.js
blobce3d83f0dbd0d210d976064f0041e55222ee1be0
1 /*
2 Scripts to create interactive sliders in SVG using ECMA script
3 Copyright (C) <2006>  <Andreas Neumann>
4 Version 1.0, 2006-08-04
5 neumann@karto.baug.ethz.ch
6 http://www.carto.net/
7 http://www.carto.net/neumann/
9 Credits:
10 * Kevin Lindsey for ideas how to implement such a slider
12 ----
14 Documentation: http://www.carto.net/papers/svg/gui/slider/
16 ----
18 current version: 1.0.
20 version history:
21 0.99 (not documented, somewhere around 2001)
23 1.0 (2006-08-04)
24 changed constructor parameters (added id, parentNode), removed parameter sliderGroupId, added documentation, added method .moveTo()
26 -------
28 This ECMA script library is free software; you can redistribute it and/or
29 modify it under the terms of the GNU Lesser General Public
30 License as published by the Free Software Foundation; either
31 version 2.1 of the License, or (at your option) any later version.
33 This library is distributed in the hope that it will be useful,
34 but WITHOUT ANY WARRANTY; without even the implied warranty of
35 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
36 Lesser General Public License for more details.
38 You should have received a copy of the GNU Lesser General Public
39 License along with this library (lesser_gpl.txt); if not, write to the Free Software
40 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
42 ----
44 original document site: http://www.carto.net/papers/svg/gui/slider/
45 Please contact the author in case you want to use code or ideas commercially.
46 If you use this code, please include this copyright header, the included full
47 LGPL 2.1 text and read the terms provided in the LGPL 2.1 license
48 (http://www.gnu.org/copyleft/lesser.txt)
50 -------------------------------
52 Please report bugs and send improvements to neumann@karto.baug.ethz.ch
53 If you use this control, please link to the original (http://www.carto.net/papers/svg/gui/slider/)
54 somewhere in the source-code-comment or the "about" of your project and give credits, thanks!
58 //slider properties
59 function slider(id,parentNode,x1,y1,value1,x2,y2,value2,startVal,sliderStyles,invisSliderWidth,sliderSymb,functionToCall,mouseMoveBool) {
60     var nrArguments = 14;
61     var createSlider= true;
62     if (arguments.length == nrArguments) {    
63         this.id = id; //an internal id, this id is not used in the SVG Dom tree
64         this.parentNode = parentNode; //the parentNode, string or nodeReference
65         this.x1 = x1; //the start point x of the slider
66         this.y1 = y1; //the start point y of the slider
67         this.value1 = value1; //the value at the start point, min slider value
68         this.x2 = x2; //the end point x of the slider 
69         this.y2 = y2; //the end point y of the slider
70         this.value2 = value2; //the value at the end point, max slider value
71         this.startVal = startVal; //the initial value of the slider
72         this.value = startVal; //the current value of the slider
73         this.sliderStyles = sliderStyles; //the color of the slider line
74         this.invisSliderWidth = invisSliderWidth; //the width of invisible part of the slider
75         this.sliderSymb = sliderSymb; //the id for the movable symbol to be placed on the slider line 
76         this.functionToCall = functionToCall; //the callback function
77         this.mouseMoveBool = mouseMoveBool; //boolean value to indicate if the slider gives immediate feedback or not
78         this.length = toPolarDist((this.x2 - this.x1),(this.y2 - this.y1));
79         this.direction = toPolarDir((this.x2 - this.x1),(this.y2 - this.y1));
80         this.invisSliderLine = null;
81         this.slideStatus = 0;
82     }
83     else {
84         createSlider = false;
85         alert("Error in slider ("+id+") constructor: wrong nr of arguments! You have to pass over "+nrArguments+" parameters.");
86     }
87     if (createSlider) {
88         this.createSlider();
89     }
90     else {
91         alert("Could not create slider with id '"+id+"' due to errors in the constructor parameters");        
92     }
95 //create slider
96 slider.prototype.createSlider = function() {
97     var result = this.testParent();
98     if (result) {
99         this.invisSliderLine = document.createElementNS(svgNS,"line");
100         this.invisSliderLine.setAttributeNS(null,"x1",this.x1);
101         this.invisSliderLine.setAttributeNS(null,"y1",this.y1);
102         this.invisSliderLine.setAttributeNS(null,"x2",this.x2);
103         this.invisSliderLine.setAttributeNS(null,"y2",this.y2);
104         this.invisSliderLine.setAttributeNS(null,"stroke","black");
105         this.invisSliderLine.setAttributeNS(null,"stroke-width",this.invisSliderWidth);
106         //note that due to bugs in Opera9 and Firefox I can't use pointer-events here
107         this.invisSliderLine.setAttributeNS(null,"stroke-opacity","0");
108         this.invisSliderLine.setAttributeNS(null,"fill-opacity","0");
109         this.invisSliderLine.setAttributeNS(null,"stroke-linecap","square");
110         this.invisSliderLine.addEventListener("mousedown",this,false);
111         this.parentGroup.appendChild(this.invisSliderLine);
112         this.visSliderLine = document.createElementNS(svgNS,"line");
113         this.visSliderLine.setAttributeNS(null,"x1",this.x1);
114         this.visSliderLine.setAttributeNS(null,"y1",this.y1);
115         this.visSliderLine.setAttributeNS(null,"x2",this.x2);
116         this.visSliderLine.setAttributeNS(null,"y2",this.y2);
117         for (var attrib in this.sliderStyles) {
118             this.visSliderLine.setAttributeNS(null,attrib,this.sliderStyles[attrib]);
119         }
120         this.visSliderLine.setAttributeNS(null,"pointer-events","none");
121         this.parentGroup.appendChild(this.visSliderLine);
122         this.sliderSymbol = document.createElementNS(svgNS,"use");
123         this.sliderSymbol.setAttributeNS(xlinkNS,"xlink:href","#"+this.sliderSymb);
124         var myStartDistance = this.length - ((this.value2 - this.startVal) / (this.value2 - this.value1)) * this.length;
125         var myPosX = this.x1 + toRectX(this.direction,myStartDistance);
126         var myPosY = this.y1 + toRectY(this.direction,myStartDistance);
127         var myTransformString = "translate("+myPosX+","+myPosY+") rotate(" + Math.round(this.direction / Math.PI * 180) + ")";
128         this.sliderSymbol.setAttributeNS(null,"transform",myTransformString);
129         this.sliderSymbol.setAttributeNS(null,"pointer-events","none");
130         this.parentGroup.appendChild(this.sliderSymbol);
131     }
132     else {
133         alert("could not create or reference 'parentNode' of slider with id '"+this.id+"'");            
134     }
137 //test if parent group exists
138 slider.prototype.testParent = function() {
139     //test if of type object
140     var nodeValid = false;
141     if (typeof(this.parentNode) == "object") {
142         if (this.parentNode.nodeName == "svg" || this.parentNode.nodeName == "g" || this.parentNode.nodeName == "svg:svg" || this.parentNode.nodeName == "svg:g") {
143             this.parentGroup = this.parentNode;
144             nodeValid = true;
145         }
146     }
147     else if (typeof(this.parentNode) == "string") { 
148         //first test if button group exists
149         if (!document.getElementById(this.parentNode)) {
150             this.parentGroup = document.createElementNS(svgNS,"g");
151             this.parentGroup.setAttributeNS(null,"id",this.parentNode);
152             document.documentElement.appendChild(this.parentGroup);
153             nodeValid = true;
154            }
155            else {
156                this.parentGroup = document.getElementById(this.parentNode);
157                nodeValid = true;
158            }
159        }
160        return nodeValid;
163 //remove all slider elements
164 slider.prototype.removeSlider = function() {
165     this.parentGroup.removeChild(this.sliderSymbol);
166     this.parentGroup.removeChild(this.visSliderLine);
167     this.parentGroup.removeChild(this.invisSliderLine);
170 //handle events
171 slider.prototype.handleEvent = function(evt) {
172     this.drag(evt);
175 //drag slider
176 slider.prototype.drag = function(evt) {
177     if (evt.type == "mousedown" || (evt.type == "mousemove" && this.slideStatus == 1)) {
178         //get coordinate in slider coordinate system
179         var coordPoint = myMapApp.calcCoord(evt,this.invisSliderLine);
180         //draw normal line for first vertex
181         var ax = this.x2 - this.x1;
182         var ay = this.y2 - this.y1;
183         //normal vector 1
184         var px1 = parseFloat(this.x1) + ay * -1;
185         var py1 = parseFloat(this.y1) + ax;
186         //normal vector 2
187         var px2 = parseFloat(this.x2) + ay * -1;
188         var py2 = parseFloat(this.y2) + ax;
189                 
190         if (leftOfTest(coordPoint.x,coordPoint.y,this.x1,this.y1,px1,py1) == 0 && leftOfTest(coordPoint.x,coordPoint.y,this.x2,this.y2,px2,py2) == 1) {
191             if (evt.type == "mousedown" && (evt.detail == 1 || evt.detail == 0)) {
192                 this.slideStatus = 1;
193                 document.documentElement.addEventListener("mousemove",this,false);
194                 document.documentElement.addEventListener("mouseup",this,false);
195             }
196             myNewPos = intersect2lines(this.x1,this.y1,this.x2,this.y2,coordPoint.x,coordPoint.y,coordPoint.x + ay * -1,coordPoint.y + ax);
197             var myPercentage = toPolarDist(myNewPos['x'] - this.x1,myNewPos['y'] - this.y1) / this.length;
198             this.value = this.value1 + myPercentage * (this.value2 - this.value1);
199         }
200         else {
201             var myNewPos = new Array();
202             if (leftOfTest(coordPoint.x,coordPoint.y,this.x1,this.y1,px1,py1) == 0 && leftOfTest(coordPoint.x,coordPoint.y,this.x2,this.y2,px2,py2) == 0) {
203                 //more than max
204                 this.value = this.value2;
205                 myNewPos['x'] = this.x2;
206                 myNewPos['y'] = this.y2;
207             }
208             if (leftOfTest(coordPoint.x,coordPoint.y,this.x1,this.y1,px1,py1) == 1 && leftOfTest(coordPoint.x,coordPoint.y,this.x2,this.y2,px2,py2) == 1) {
209                 //less than min
210                 this.value = this.value1;
211                 myNewPos['x'] = this.x1;
212                 myNewPos['y'] = this.y1;
213             }
214         }
215         var myTransformString = "translate("+myNewPos['x']+","+myNewPos['y']+") rotate(" + Math.round(this.direction / Math.PI * 180) + ")";
216         this.sliderSymbol.setAttributeNS(null,"transform",myTransformString);
217         this.fireFunction();
218     }
219     if (evt.type == "mouseup" && (evt.detail == 1 || evt.detail == 0)) {
220         if (this.slideStatus == 1) {
221             this.slideStatus = 2;
222             document.documentElement.removeEventListener("mousemove",this,false);
223             document.documentElement.removeEventListener("mouseup",this,false);
224             this.fireFunction();
225         }
226         this.slideStatus = 0;
227     }
230 //this code is executed, after the slider is released
231 //you can use switch/if to detect which slider was used (use this.id) for that
232 slider.prototype.fireFunction = function() {
233     if (this.slideStatus == 1 && this.mouseMoveBool == true) {
234         if (typeof(this.functionToCall) == "function") {
235             this.functionToCall("change",this.id,this.value);
236         }
237         if (typeof(this.functionToCall) == "object") {
238             this.functionToCall.getSliderVal("change",this.id,this.value);
239         }
240         if (typeof(this.functionToCall) == undefined) {
241             return;
242         }
243     }
244     if (this.slideStatus == 2) {
245         if (typeof(this.functionToCall) == "function") {
246             this.functionToCall("release",this.id,this.value);
247         }
248         if (typeof(this.functionToCall) == "object") {
249             this.functionToCall.getSliderVal("release",this.id,this.value);
250         }
251         if (typeof(this.functionToCall) == undefined) {
252             return;
253         }
254     }
257 slider.prototype.getValue = function() {
258     return this.value;
261 //this is to set the value from other scripts
262 slider.prototype.setValue = function(value,fireFunction) {
263     this.value = value;
264     var myPercAlLine = (this.value - this.value1) / (this.value2 - this.value1);
265     var myPosX = this.x1 + toRectX(this.direction,this.length * myPercAlLine);
266     var myPosY = this.y1 + toRectY(this.direction,this.length * myPercAlLine);
267     var myTransformString = "translate("+myPosX+","+myPosY+") rotate(" + Math.round(this.direction / Math.PI * 180) + ")";
268     this.sliderSymbol.setAttributeNS(null,"transform",myTransformString);
269     if (fireFunction) {
270         //temporary set slideStatus
271         this.slideStatus = 2;
272         this.fireFunction();
273         this.slideStatus = 0;
274     }
277 slider.prototype.moveTo = function(x1,y1,x2,y2) {
278     this.x1 = x1;
279     this.y1 = y1;
280     this.x2 = x2;
281     this.y2 = y2;
282     this.invisSliderLine.setAttributeNS(null,"x1",this.x1);
283     this.invisSliderLine.setAttributeNS(null,"y1",this.y1);
284     this.invisSliderLine.setAttributeNS(null,"x2",this.x2);
285     this.invisSliderLine.setAttributeNS(null,"y2",this.y2);
286     this.visSliderLine.setAttributeNS(null,"x1",this.x1);
287     this.visSliderLine.setAttributeNS(null,"y1",this.y1);
288     this.visSliderLine.setAttributeNS(null,"x2",this.x2);
289     this.visSliderLine.setAttributeNS(null,"y2",this.y2);
290     //reset direction and length of the slider
291     this.length = toPolarDist((this.x2 - this.x1),(this.y2 - this.y1));
292     this.direction = toPolarDir((this.x2 - this.x1),(this.y2 - this.y1));
293     //reset the value to correctly reposition element
294     this.setValue(this.getValue(),false);