Mercurial > hg > LGMap
comparison geotemco/platin.js @ 0:57bde4830927
first commit
author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
---|---|
date | Tue, 24 Mar 2015 11:37:17 +0100 |
parents | |
children | 0330b2138c87 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:57bde4830927 |
---|---|
1 (function($){ | |
2 | |
3 var jQuery = $; | |
4 /* | |
5 * basic.js | |
6 * | |
7 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
8 * | |
9 * This library is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public | |
11 * License as published by the Free Software Foundation; either | |
12 * version 3 of the License, or (at your option) any later version. | |
13 * | |
14 * This library is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with this library; if not, write to the Free Software | |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
22 * MA 02110-1301 USA | |
23 */ | |
24 | |
25 /** | |
26 * basic code which is included first for the minified version | |
27 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
28 * @release 1.0 | |
29 * @release date: 2012-07-27 | |
30 * @version date: 2012-07-27 | |
31 */ | |
32 | |
33 var arrayIndex = function(array, obj) { | |
34 if (Array.indexOf) { | |
35 return array.indexOf(obj); | |
36 } | |
37 for (var i = 0; i < array.length; i++) { | |
38 if (array[i] == obj) { | |
39 return i; | |
40 } | |
41 } | |
42 return -1; | |
43 } | |
44 var GeoTemCoMinifier_urlPrefix; | |
45 for (var i = 0; i < document.getElementsByTagName("script").length; i++) { | |
46 var script = document.getElementsByTagName("script")[i]; | |
47 var index = script.src.indexOf("platin.js"); | |
48 if (index == -1) { | |
49 index = script.src.indexOf("platin-min.js"); | |
50 } | |
51 if (index != -1) { | |
52 GeoTemCoMinifier_urlPrefix = script.src.substring(0, index); | |
53 break; | |
54 } | |
55 } | |
56 // Copyright 2006 Google Inc. | |
57 // | |
58 // Licensed under the Apache License, Version 2.0 (the "License"); | |
59 // you may not use this file except in compliance with the License. | |
60 // You may obtain a copy of the License at | |
61 // | |
62 // http://www.apache.org/licenses/LICENSE-2.0 | |
63 // | |
64 // Unless required by applicable law or agreed to in writing, software | |
65 // distributed under the License is distributed on an "AS IS" BASIS, | |
66 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
67 // See the License for the specific language governing permissions and | |
68 // limitations under the License. | |
69 | |
70 | |
71 // Known Issues: | |
72 // | |
73 // * Patterns are not implemented. | |
74 // * Radial gradient are not implemented. The VML version of these look very | |
75 // different from the canvas one. | |
76 // * Clipping paths are not implemented. | |
77 // * Coordsize. The width and height attribute have higher priority than the | |
78 // width and height style values which isn't correct. | |
79 // * Painting mode isn't implemented. | |
80 // * Canvas width/height should is using content-box by default. IE in | |
81 // Quirks mode will draw the canvas using border-box. Either change your | |
82 // doctype to HTML5 | |
83 // (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) | |
84 // or use Box Sizing Behavior from WebFX | |
85 // (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) | |
86 // * Non uniform scaling does not correctly scale strokes. | |
87 // * Optimize. There is always room for speed improvements. | |
88 | |
89 // Only add this code if we do not already have a canvas implementation | |
90 if (!document.createElement('canvas').getContext) { | |
91 | |
92 (function() { | |
93 | |
94 // alias some functions to make (compiled) code shorter | |
95 var m = Math; | |
96 var mr = m.round; | |
97 var ms = m.sin; | |
98 var mc = m.cos; | |
99 var abs = m.abs; | |
100 var sqrt = m.sqrt; | |
101 | |
102 // this is used for sub pixel precision | |
103 var Z = 10; | |
104 var Z2 = Z / 2; | |
105 | |
106 /** | |
107 * This funtion is assigned to the <canvas> elements as element.getContext(). | |
108 * @this {HTMLElement} | |
109 * @return {CanvasRenderingContext2D_} | |
110 */ | |
111 function getContext() { | |
112 return this.context_ || | |
113 (this.context_ = new CanvasRenderingContext2D_(this)); | |
114 } | |
115 | |
116 var slice = Array.prototype.slice; | |
117 | |
118 /** | |
119 * Binds a function to an object. The returned function will always use the | |
120 * passed in {@code obj} as {@code this}. | |
121 * | |
122 * Example: | |
123 * | |
124 * g = bind(f, obj, a, b) | |
125 * g(c, d) // will do f.call(obj, a, b, c, d) | |
126 * | |
127 * @param {Function} f The function to bind the object to | |
128 * @param {Object} obj The object that should act as this when the function | |
129 * is called | |
130 * @param {*} var_args Rest arguments that will be used as the initial | |
131 * arguments when the function is called | |
132 * @return {Function} A new function that has bound this | |
133 */ | |
134 function bind(f, obj, var_args) { | |
135 var a = slice.call(arguments, 2); | |
136 return function() { | |
137 return f.apply(obj, a.concat(slice.call(arguments))); | |
138 }; | |
139 } | |
140 | |
141 var G_vmlCanvasManager_ = { | |
142 init: function(opt_doc) { | |
143 if (/MSIE/.test(navigator.userAgent) && !window.opera) { | |
144 var doc = opt_doc || document; | |
145 // Create a dummy element so that IE will allow canvas elements to be | |
146 // recognized. | |
147 doc.createElement('canvas'); | |
148 doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); | |
149 } | |
150 }, | |
151 | |
152 init_: function(doc) { | |
153 // create xmlns | |
154 if (!doc.namespaces['g_vml_']) { | |
155 doc.namespaces.add('g_vml_', 'urn:schemas-microsoft-com:vml', | |
156 '#default#VML'); | |
157 | |
158 } | |
159 if (!doc.namespaces['g_o_']) { | |
160 doc.namespaces.add('g_o_', 'urn:schemas-microsoft-com:office:office', | |
161 '#default#VML'); | |
162 } | |
163 | |
164 // Setup default CSS. Only add one style sheet per document | |
165 if (!doc.styleSheets['ex_canvas_']) { | |
166 var ss = doc.createStyleSheet(); | |
167 ss.owningElement.id = 'ex_canvas_'; | |
168 ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + | |
169 // default size is 300x150 in Gecko and Opera | |
170 'text-align:left;width:300px;height:150px}' + | |
171 'g_vml_\\:*{behavior:url(#default#VML)}' + | |
172 'g_o_\\:*{behavior:url(#default#VML)}'; | |
173 | |
174 } | |
175 | |
176 // find all canvas elements | |
177 var els = doc.getElementsByTagName('canvas'); | |
178 for (var i = 0; i < els.length; i++) { | |
179 this.initElement(els[i]); | |
180 } | |
181 }, | |
182 | |
183 /** | |
184 * Public initializes a canvas element so that it can be used as canvas | |
185 * element from now on. This is called automatically before the page is | |
186 * loaded but if you are creating elements using createElement you need to | |
187 * make sure this is called on the element. | |
188 * @param {HTMLElement} el The canvas element to initialize. | |
189 * @return {HTMLElement} the element that was created. | |
190 */ | |
191 initElement: function(el) { | |
192 if (!el.getContext) { | |
193 | |
194 el.getContext = getContext; | |
195 | |
196 // Remove fallback content. There is no way to hide text nodes so we | |
197 // just remove all childNodes. We could hide all elements and remove | |
198 // text nodes but who really cares about the fallback content. | |
199 el.innerHTML = ''; | |
200 | |
201 // do not use inline function because that will leak memory | |
202 el.attachEvent('onpropertychange', onPropertyChange); | |
203 el.attachEvent('onresize', onResize); | |
204 | |
205 var attrs = el.attributes; | |
206 if (attrs.width && attrs.width.specified) { | |
207 // TODO: use runtimeStyle and coordsize | |
208 // el.getContext().setWidth_(attrs.width.nodeValue); | |
209 el.style.width = attrs.width.nodeValue + 'px'; | |
210 } else { | |
211 el.width = el.clientWidth; | |
212 } | |
213 if (attrs.height && attrs.height.specified) { | |
214 // TODO: use runtimeStyle and coordsize | |
215 // el.getContext().setHeight_(attrs.height.nodeValue); | |
216 el.style.height = attrs.height.nodeValue + 'px'; | |
217 } else { | |
218 el.height = el.clientHeight; | |
219 } | |
220 //el.getContext().setCoordsize_() | |
221 } | |
222 return el; | |
223 } | |
224 }; | |
225 | |
226 function onPropertyChange(e) { | |
227 var el = e.srcElement; | |
228 | |
229 switch (e.propertyName) { | |
230 case 'width': | |
231 el.style.width = el.attributes.width.nodeValue + 'px'; | |
232 el.getContext().clearRect(); | |
233 break; | |
234 case 'height': | |
235 el.style.height = el.attributes.height.nodeValue + 'px'; | |
236 el.getContext().clearRect(); | |
237 break; | |
238 } | |
239 } | |
240 | |
241 function onResize(e) { | |
242 var el = e.srcElement; | |
243 if (el.firstChild) { | |
244 el.firstChild.style.width = el.clientWidth + 'px'; | |
245 el.firstChild.style.height = el.clientHeight + 'px'; | |
246 } | |
247 } | |
248 | |
249 G_vmlCanvasManager_.init(); | |
250 | |
251 // precompute "00" to "FF" | |
252 var dec2hex = []; | |
253 for (var i = 0; i < 16; i++) { | |
254 for (var j = 0; j < 16; j++) { | |
255 dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); | |
256 } | |
257 } | |
258 | |
259 function createMatrixIdentity() { | |
260 return [ | |
261 [1, 0, 0], | |
262 [0, 1, 0], | |
263 [0, 0, 1] | |
264 ]; | |
265 } | |
266 | |
267 function matrixMultiply(m1, m2) { | |
268 var result = createMatrixIdentity(); | |
269 | |
270 for (var x = 0; x < 3; x++) { | |
271 for (var y = 0; y < 3; y++) { | |
272 var sum = 0; | |
273 | |
274 for (var z = 0; z < 3; z++) { | |
275 sum += m1[x][z] * m2[z][y]; | |
276 } | |
277 | |
278 result[x][y] = sum; | |
279 } | |
280 } | |
281 return result; | |
282 } | |
283 | |
284 function copyState(o1, o2) { | |
285 o2.fillStyle = o1.fillStyle; | |
286 o2.lineCap = o1.lineCap; | |
287 o2.lineJoin = o1.lineJoin; | |
288 o2.lineWidth = o1.lineWidth; | |
289 o2.miterLimit = o1.miterLimit; | |
290 o2.shadowBlur = o1.shadowBlur; | |
291 o2.shadowColor = o1.shadowColor; | |
292 o2.shadowOffsetX = o1.shadowOffsetX; | |
293 o2.shadowOffsetY = o1.shadowOffsetY; | |
294 o2.strokeStyle = o1.strokeStyle; | |
295 o2.globalAlpha = o1.globalAlpha; | |
296 o2.arcScaleX_ = o1.arcScaleX_; | |
297 o2.arcScaleY_ = o1.arcScaleY_; | |
298 o2.lineScale_ = o1.lineScale_; | |
299 } | |
300 | |
301 function processStyle(styleString) { | |
302 var str, alpha = 1; | |
303 | |
304 styleString = String(styleString); | |
305 if (styleString.substring(0, 3) == 'rgb') { | |
306 var start = styleString.indexOf('(', 3); | |
307 var end = styleString.indexOf(')', start + 1); | |
308 var guts = styleString.substring(start + 1, end).split(','); | |
309 | |
310 str = '#'; | |
311 for (var i = 0; i < 3; i++) { | |
312 str += dec2hex[Number(guts[i])]; | |
313 } | |
314 | |
315 if (guts.length == 4 && styleString.substr(3, 1) == 'a') { | |
316 alpha = guts[3]; | |
317 } | |
318 } else { | |
319 str = styleString; | |
320 } | |
321 | |
322 return {color: str, alpha: alpha}; | |
323 } | |
324 | |
325 function processLineCap(lineCap) { | |
326 switch (lineCap) { | |
327 case 'butt': | |
328 return 'flat'; | |
329 case 'round': | |
330 return 'round'; | |
331 case 'square': | |
332 default: | |
333 return 'square'; | |
334 } | |
335 } | |
336 | |
337 /** | |
338 * This class implements CanvasRenderingContext2D interface as described by | |
339 * the WHATWG. | |
340 * @param {HTMLElement} surfaceElement The element that the 2D context should | |
341 * be associated with | |
342 */ | |
343 function CanvasRenderingContext2D_(surfaceElement) { | |
344 this.m_ = createMatrixIdentity(); | |
345 | |
346 this.mStack_ = []; | |
347 this.aStack_ = []; | |
348 this.currentPath_ = []; | |
349 | |
350 // Canvas context properties | |
351 this.strokeStyle = '#000'; | |
352 this.fillStyle = '#000'; | |
353 | |
354 this.lineWidth = 1; | |
355 this.lineJoin = 'miter'; | |
356 this.lineCap = 'butt'; | |
357 this.miterLimit = Z * 1; | |
358 this.globalAlpha = 1; | |
359 this.canvas = surfaceElement; | |
360 | |
361 var el = surfaceElement.ownerDocument.createElement('div'); | |
362 el.style.width = surfaceElement.clientWidth + 'px'; | |
363 el.style.height = surfaceElement.clientHeight + 'px'; | |
364 el.style.overflow = 'hidden'; | |
365 el.style.position = 'absolute'; | |
366 surfaceElement.appendChild(el); | |
367 | |
368 this.element_ = el; | |
369 this.arcScaleX_ = 1; | |
370 this.arcScaleY_ = 1; | |
371 this.lineScale_ = 1; | |
372 } | |
373 | |
374 var contextPrototype = CanvasRenderingContext2D_.prototype; | |
375 contextPrototype.clearRect = function() { | |
376 this.element_.innerHTML = ''; | |
377 }; | |
378 | |
379 contextPrototype.beginPath = function() { | |
380 // TODO: Branch current matrix so that save/restore has no effect | |
381 // as per safari docs. | |
382 this.currentPath_ = []; | |
383 }; | |
384 | |
385 contextPrototype.moveTo = function(aX, aY) { | |
386 var p = this.getCoords_(aX, aY); | |
387 this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); | |
388 this.currentX_ = p.x; | |
389 this.currentY_ = p.y; | |
390 }; | |
391 | |
392 contextPrototype.lineTo = function(aX, aY) { | |
393 var p = this.getCoords_(aX, aY); | |
394 this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); | |
395 | |
396 this.currentX_ = p.x; | |
397 this.currentY_ = p.y; | |
398 }; | |
399 | |
400 contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, | |
401 aCP2x, aCP2y, | |
402 aX, aY) { | |
403 var p = this.getCoords_(aX, aY); | |
404 var cp1 = this.getCoords_(aCP1x, aCP1y); | |
405 var cp2 = this.getCoords_(aCP2x, aCP2y); | |
406 bezierCurveTo(this, cp1, cp2, p); | |
407 }; | |
408 | |
409 // Helper function that takes the already fixed cordinates. | |
410 function bezierCurveTo(self, cp1, cp2, p) { | |
411 self.currentPath_.push({ | |
412 type: 'bezierCurveTo', | |
413 cp1x: cp1.x, | |
414 cp1y: cp1.y, | |
415 cp2x: cp2.x, | |
416 cp2y: cp2.y, | |
417 x: p.x, | |
418 y: p.y | |
419 }); | |
420 self.currentX_ = p.x; | |
421 self.currentY_ = p.y; | |
422 } | |
423 | |
424 contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { | |
425 // the following is lifted almost directly from | |
426 // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes | |
427 | |
428 var cp = this.getCoords_(aCPx, aCPy); | |
429 var p = this.getCoords_(aX, aY); | |
430 | |
431 var cp1 = { | |
432 x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), | |
433 y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) | |
434 }; | |
435 var cp2 = { | |
436 x: cp1.x + (p.x - this.currentX_) / 3.0, | |
437 y: cp1.y + (p.y - this.currentY_) / 3.0 | |
438 }; | |
439 | |
440 bezierCurveTo(this, cp1, cp2, p); | |
441 }; | |
442 | |
443 contextPrototype.arc = function(aX, aY, aRadius, | |
444 aStartAngle, aEndAngle, aClockwise) { | |
445 aRadius *= Z; | |
446 var arcType = aClockwise ? 'at' : 'wa'; | |
447 | |
448 var xStart = aX + mc(aStartAngle) * aRadius - Z2; | |
449 var yStart = aY + ms(aStartAngle) * aRadius - Z2; | |
450 | |
451 var xEnd = aX + mc(aEndAngle) * aRadius - Z2; | |
452 var yEnd = aY + ms(aEndAngle) * aRadius - Z2; | |
453 | |
454 // IE won't render arches drawn counter clockwise if xStart == xEnd. | |
455 if (xStart == xEnd && !aClockwise) { | |
456 xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something | |
457 // that can be represented in binary | |
458 } | |
459 | |
460 var p = this.getCoords_(aX, aY); | |
461 var pStart = this.getCoords_(xStart, yStart); | |
462 var pEnd = this.getCoords_(xEnd, yEnd); | |
463 | |
464 this.currentPath_.push({type: arcType, | |
465 x: p.x, | |
466 y: p.y, | |
467 radius: aRadius, | |
468 xStart: pStart.x, | |
469 yStart: pStart.y, | |
470 xEnd: pEnd.x, | |
471 yEnd: pEnd.y}); | |
472 | |
473 }; | |
474 | |
475 contextPrototype.rect = function(aX, aY, aWidth, aHeight) { | |
476 this.moveTo(aX, aY); | |
477 this.lineTo(aX + aWidth, aY); | |
478 this.lineTo(aX + aWidth, aY + aHeight); | |
479 this.lineTo(aX, aY + aHeight); | |
480 this.closePath(); | |
481 }; | |
482 | |
483 contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { | |
484 var oldPath = this.currentPath_; | |
485 this.beginPath(); | |
486 | |
487 this.moveTo(aX, aY); | |
488 this.lineTo(aX + aWidth, aY); | |
489 this.lineTo(aX + aWidth, aY + aHeight); | |
490 this.lineTo(aX, aY + aHeight); | |
491 this.closePath(); | |
492 this.stroke(); | |
493 | |
494 this.currentPath_ = oldPath; | |
495 }; | |
496 | |
497 contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { | |
498 var oldPath = this.currentPath_; | |
499 this.beginPath(); | |
500 | |
501 this.moveTo(aX, aY); | |
502 this.lineTo(aX + aWidth, aY); | |
503 this.lineTo(aX + aWidth, aY + aHeight); | |
504 this.lineTo(aX, aY + aHeight); | |
505 this.closePath(); | |
506 this.fill(); | |
507 | |
508 this.currentPath_ = oldPath; | |
509 }; | |
510 | |
511 contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { | |
512 var gradient = new CanvasGradient_('gradient'); | |
513 gradient.x0_ = aX0; | |
514 gradient.y0_ = aY0; | |
515 gradient.x1_ = aX1; | |
516 gradient.y1_ = aY1; | |
517 return gradient; | |
518 }; | |
519 | |
520 contextPrototype.createRadialGradient = function(aX0, aY0, aR0, | |
521 aX1, aY1, aR1) { | |
522 var gradient = new CanvasGradient_('gradientradial'); | |
523 gradient.x0_ = aX0; | |
524 gradient.y0_ = aY0; | |
525 gradient.r0_ = aR0; | |
526 gradient.x1_ = aX1; | |
527 gradient.y1_ = aY1; | |
528 gradient.r1_ = aR1; | |
529 return gradient; | |
530 }; | |
531 | |
532 contextPrototype.drawImage = function(image, var_args) { | |
533 var dx, dy, dw, dh, sx, sy, sw, sh; | |
534 | |
535 // to find the original width we overide the width and height | |
536 var oldRuntimeWidth = image.runtimeStyle.width; | |
537 var oldRuntimeHeight = image.runtimeStyle.height; | |
538 image.runtimeStyle.width = 'auto'; | |
539 image.runtimeStyle.height = 'auto'; | |
540 | |
541 // get the original size | |
542 var w = image.width; | |
543 var h = image.height; | |
544 | |
545 // and remove overides | |
546 image.runtimeStyle.width = oldRuntimeWidth; | |
547 image.runtimeStyle.height = oldRuntimeHeight; | |
548 | |
549 if (arguments.length == 3) { | |
550 dx = arguments[1]; | |
551 dy = arguments[2]; | |
552 sx = sy = 0; | |
553 sw = dw = w; | |
554 sh = dh = h; | |
555 } else if (arguments.length == 5) { | |
556 dx = arguments[1]; | |
557 dy = arguments[2]; | |
558 dw = arguments[3]; | |
559 dh = arguments[4]; | |
560 sx = sy = 0; | |
561 sw = w; | |
562 sh = h; | |
563 } else if (arguments.length == 9) { | |
564 sx = arguments[1]; | |
565 sy = arguments[2]; | |
566 sw = arguments[3]; | |
567 sh = arguments[4]; | |
568 dx = arguments[5]; | |
569 dy = arguments[6]; | |
570 dw = arguments[7]; | |
571 dh = arguments[8]; | |
572 } else { | |
573 throw Error('Invalid number of arguments'); | |
574 } | |
575 | |
576 var d = this.getCoords_(dx, dy); | |
577 | |
578 var w2 = sw / 2; | |
579 var h2 = sh / 2; | |
580 | |
581 var vmlStr = []; | |
582 | |
583 var W = 10; | |
584 var H = 10; | |
585 | |
586 // For some reason that I've now forgotten, using divs didn't work | |
587 vmlStr.push(' <g_vml_:group', | |
588 ' coordsize="', Z * W, ',', Z * H, '"', | |
589 ' coordorigin="0,0"' , | |
590 ' style="width:', W, 'px;height:', H, 'px;position:absolute;'); | |
591 | |
592 // If filters are necessary (rotation exists), create them | |
593 // filters are bog-slow, so only create them if abbsolutely necessary | |
594 // The following check doesn't account for skews (which don't exist | |
595 // in the canvas spec (yet) anyway. | |
596 | |
597 if (this.m_[0][0] != 1 || this.m_[0][1]) { | |
598 var filter = []; | |
599 | |
600 // Note the 12/21 reversal | |
601 filter.push('M11=', this.m_[0][0], ',', | |
602 'M12=', this.m_[1][0], ',', | |
603 'M21=', this.m_[0][1], ',', | |
604 'M22=', this.m_[1][1], ',', | |
605 'Dx=', mr(d.x / Z), ',', | |
606 'Dy=', mr(d.y / Z), ''); | |
607 | |
608 // Bounding box calculation (need to minimize displayed area so that | |
609 // filters don't waste time on unused pixels. | |
610 var max = d; | |
611 var c2 = this.getCoords_(dx + dw, dy); | |
612 var c3 = this.getCoords_(dx, dy + dh); | |
613 var c4 = this.getCoords_(dx + dw, dy + dh); | |
614 | |
615 max.x = m.max(max.x, c2.x, c3.x, c4.x); | |
616 max.y = m.max(max.y, c2.y, c3.y, c4.y); | |
617 | |
618 vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z), | |
619 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(', | |
620 filter.join(''), ", sizingmethod='clip');") | |
621 } else { | |
622 vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;'); | |
623 } | |
624 | |
625 vmlStr.push(' ">' , | |
626 '<g_vml_:image src="', image.src, '"', | |
627 ' style="width:', Z * dw, 'px;', | |
628 ' height:', Z * dh, 'px;"', | |
629 ' cropleft="', sx / w, '"', | |
630 ' croptop="', sy / h, '"', | |
631 ' cropright="', (w - sx - sw) / w, '"', | |
632 ' cropbottom="', (h - sy - sh) / h, '"', | |
633 ' />', | |
634 '</g_vml_:group>'); | |
635 | |
636 this.element_.insertAdjacentHTML('BeforeEnd', | |
637 vmlStr.join('')); | |
638 }; | |
639 | |
640 contextPrototype.stroke = function(aFill) { | |
641 var lineStr = []; | |
642 var lineOpen = false; | |
643 var a = processStyle(aFill ? this.fillStyle : this.strokeStyle); | |
644 var color = a.color; | |
645 var opacity = a.alpha * this.globalAlpha; | |
646 | |
647 var W = 10; | |
648 var H = 10; | |
649 | |
650 lineStr.push('<g_vml_:shape', | |
651 ' filled="', !!aFill, '"', | |
652 ' style="position:absolute;width:', W, 'px;height:', H, 'px;"', | |
653 ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"', | |
654 ' stroked="', !aFill, '"', | |
655 ' path="'); | |
656 | |
657 var newSeq = false; | |
658 var min = {x: null, y: null}; | |
659 var max = {x: null, y: null}; | |
660 | |
661 for (var i = 0; i < this.currentPath_.length; i++) { | |
662 var p = this.currentPath_[i]; | |
663 var c; | |
664 | |
665 switch (p.type) { | |
666 case 'moveTo': | |
667 c = p; | |
668 lineStr.push(' m ', mr(p.x), ',', mr(p.y)); | |
669 break; | |
670 case 'lineTo': | |
671 lineStr.push(' l ', mr(p.x), ',', mr(p.y)); | |
672 break; | |
673 case 'close': | |
674 lineStr.push(' x '); | |
675 p = null; | |
676 break; | |
677 case 'bezierCurveTo': | |
678 lineStr.push(' c ', | |
679 mr(p.cp1x), ',', mr(p.cp1y), ',', | |
680 mr(p.cp2x), ',', mr(p.cp2y), ',', | |
681 mr(p.x), ',', mr(p.y)); | |
682 break; | |
683 case 'at': | |
684 case 'wa': | |
685 lineStr.push(' ', p.type, ' ', | |
686 mr(p.x - this.arcScaleX_ * p.radius), ',', | |
687 mr(p.y - this.arcScaleY_ * p.radius), ' ', | |
688 mr(p.x + this.arcScaleX_ * p.radius), ',', | |
689 mr(p.y + this.arcScaleY_ * p.radius), ' ', | |
690 mr(p.xStart), ',', mr(p.yStart), ' ', | |
691 mr(p.xEnd), ',', mr(p.yEnd)); | |
692 break; | |
693 } | |
694 | |
695 | |
696 // TODO: Following is broken for curves due to | |
697 // move to proper paths. | |
698 | |
699 // Figure out dimensions so we can do gradient fills | |
700 // properly | |
701 if (p) { | |
702 if (min.x == null || p.x < min.x) { | |
703 min.x = p.x; | |
704 } | |
705 if (max.x == null || p.x > max.x) { | |
706 max.x = p.x; | |
707 } | |
708 if (min.y == null || p.y < min.y) { | |
709 min.y = p.y; | |
710 } | |
711 if (max.y == null || p.y > max.y) { | |
712 max.y = p.y; | |
713 } | |
714 } | |
715 } | |
716 lineStr.push(' ">'); | |
717 | |
718 if (!aFill) { | |
719 var lineWidth = this.lineScale_ * this.lineWidth; | |
720 | |
721 // VML cannot correctly render a line if the width is less than 1px. | |
722 // In that case, we dilute the color to make the line look thinner. | |
723 if (lineWidth < 1) { | |
724 opacity *= lineWidth; | |
725 } | |
726 | |
727 lineStr.push( | |
728 '<g_vml_:stroke', | |
729 ' opacity="', opacity, '"', | |
730 ' joinstyle="', this.lineJoin, '"', | |
731 ' miterlimit="', this.miterLimit, '"', | |
732 ' endcap="', processLineCap(this.lineCap), '"', | |
733 ' weight="', lineWidth, 'px"', | |
734 ' color="', color, '" />' | |
735 ); | |
736 } else if (typeof this.fillStyle == 'object') { | |
737 var fillStyle = this.fillStyle; | |
738 var angle = 0; | |
739 var focus = {x: 0, y: 0}; | |
740 | |
741 // additional offset | |
742 var shift = 0; | |
743 // scale factor for offset | |
744 var expansion = 1; | |
745 | |
746 if (fillStyle.type_ == 'gradient') { | |
747 var x0 = fillStyle.x0_ / this.arcScaleX_; | |
748 var y0 = fillStyle.y0_ / this.arcScaleY_; | |
749 var x1 = fillStyle.x1_ / this.arcScaleX_; | |
750 var y1 = fillStyle.y1_ / this.arcScaleY_; | |
751 var p0 = this.getCoords_(x0, y0); | |
752 var p1 = this.getCoords_(x1, y1); | |
753 var dx = p1.x - p0.x; | |
754 var dy = p1.y - p0.y; | |
755 angle = Math.atan2(dx, dy) * 180 / Math.PI; | |
756 | |
757 // The angle should be a non-negative number. | |
758 if (angle < 0) { | |
759 angle += 360; | |
760 } | |
761 | |
762 // Very small angles produce an unexpected result because they are | |
763 // converted to a scientific notation string. | |
764 if (angle < 1e-6) { | |
765 angle = 0; | |
766 } | |
767 } else { | |
768 var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); | |
769 var width = max.x - min.x; | |
770 var height = max.y - min.y; | |
771 focus = { | |
772 x: (p0.x - min.x) / width, | |
773 y: (p0.y - min.y) / height | |
774 }; | |
775 | |
776 width /= this.arcScaleX_ * Z; | |
777 height /= this.arcScaleY_ * Z; | |
778 var dimension = m.max(width, height); | |
779 shift = 2 * fillStyle.r0_ / dimension; | |
780 expansion = 2 * fillStyle.r1_ / dimension - shift; | |
781 } | |
782 | |
783 // We need to sort the color stops in ascending order by offset, | |
784 // otherwise IE won't interpret it correctly. | |
785 var stops = fillStyle.colors_; | |
786 stops.sort(function(cs1, cs2) { | |
787 return cs1.offset - cs2.offset; | |
788 }); | |
789 | |
790 var length = stops.length; | |
791 var color1 = stops[0].color; | |
792 var color2 = stops[length - 1].color; | |
793 var opacity1 = stops[0].alpha * this.globalAlpha; | |
794 var opacity2 = stops[length - 1].alpha * this.globalAlpha; | |
795 | |
796 var colors = []; | |
797 for (var i = 0; i < length; i++) { | |
798 var stop = stops[i]; | |
799 colors.push(stop.offset * expansion + shift + ' ' + stop.color); | |
800 } | |
801 | |
802 // When colors attribute is used, the meanings of opacity and o:opacity2 | |
803 // are reversed. | |
804 lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"', | |
805 ' method="none" focus="100%"', | |
806 ' color="', color1, '"', | |
807 ' color2="', color2, '"', | |
808 ' colors="', colors.join(','), '"', | |
809 ' opacity="', opacity2, '"', | |
810 ' g_o_:opacity2="', opacity1, '"', | |
811 ' angle="', angle, '"', | |
812 ' focusposition="', focus.x, ',', focus.y, '" />'); | |
813 } else { | |
814 lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, | |
815 '" />'); | |
816 } | |
817 | |
818 lineStr.push('</g_vml_:shape>'); | |
819 | |
820 this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); | |
821 }; | |
822 | |
823 contextPrototype.fill = function() { | |
824 this.stroke(true); | |
825 } | |
826 | |
827 contextPrototype.closePath = function() { | |
828 this.currentPath_.push({type: 'close'}); | |
829 }; | |
830 | |
831 /** | |
832 * @private | |
833 */ | |
834 contextPrototype.getCoords_ = function(aX, aY) { | |
835 var m = this.m_; | |
836 return { | |
837 x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, | |
838 y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 | |
839 } | |
840 }; | |
841 | |
842 contextPrototype.save = function() { | |
843 var o = {}; | |
844 copyState(this, o); | |
845 this.aStack_.push(o); | |
846 this.mStack_.push(this.m_); | |
847 this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); | |
848 }; | |
849 | |
850 contextPrototype.restore = function() { | |
851 copyState(this.aStack_.pop(), this); | |
852 this.m_ = this.mStack_.pop(); | |
853 }; | |
854 | |
855 function matrixIsFinite(m) { | |
856 for (var j = 0; j < 3; j++) { | |
857 for (var k = 0; k < 2; k++) { | |
858 if (!isFinite(m[j][k]) || isNaN(m[j][k])) { | |
859 return false; | |
860 } | |
861 } | |
862 } | |
863 return true; | |
864 } | |
865 | |
866 function setM(ctx, m, updateLineScale) { | |
867 if (!matrixIsFinite(m)) { | |
868 return; | |
869 } | |
870 ctx.m_ = m; | |
871 | |
872 if (updateLineScale) { | |
873 // Get the line scale. | |
874 // Determinant of this.m_ means how much the area is enlarged by the | |
875 // transformation. So its square root can be used as a scale factor | |
876 // for width. | |
877 var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; | |
878 ctx.lineScale_ = sqrt(abs(det)); | |
879 } | |
880 } | |
881 | |
882 contextPrototype.translate = function(aX, aY) { | |
883 var m1 = [ | |
884 [1, 0, 0], | |
885 [0, 1, 0], | |
886 [aX, aY, 1] | |
887 ]; | |
888 | |
889 setM(this, matrixMultiply(m1, this.m_), false); | |
890 }; | |
891 | |
892 contextPrototype.rotate = function(aRot) { | |
893 var c = mc(aRot); | |
894 var s = ms(aRot); | |
895 | |
896 var m1 = [ | |
897 [c, s, 0], | |
898 [-s, c, 0], | |
899 [0, 0, 1] | |
900 ]; | |
901 | |
902 setM(this, matrixMultiply(m1, this.m_), false); | |
903 }; | |
904 | |
905 contextPrototype.scale = function(aX, aY) { | |
906 this.arcScaleX_ *= aX; | |
907 this.arcScaleY_ *= aY; | |
908 var m1 = [ | |
909 [aX, 0, 0], | |
910 [0, aY, 0], | |
911 [0, 0, 1] | |
912 ]; | |
913 | |
914 setM(this, matrixMultiply(m1, this.m_), true); | |
915 }; | |
916 | |
917 contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { | |
918 var m1 = [ | |
919 [m11, m12, 0], | |
920 [m21, m22, 0], | |
921 [dx, dy, 1] | |
922 ]; | |
923 | |
924 setM(this, matrixMultiply(m1, this.m_), true); | |
925 }; | |
926 | |
927 contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { | |
928 var m = [ | |
929 [m11, m12, 0], | |
930 [m21, m22, 0], | |
931 [dx, dy, 1] | |
932 ]; | |
933 | |
934 setM(this, m, true); | |
935 }; | |
936 | |
937 /******** STUBS ********/ | |
938 contextPrototype.clip = function() { | |
939 // TODO: Implement | |
940 }; | |
941 | |
942 contextPrototype.arcTo = function() { | |
943 // TODO: Implement | |
944 }; | |
945 | |
946 contextPrototype.createPattern = function() { | |
947 return new CanvasPattern_; | |
948 }; | |
949 | |
950 // Gradient / Pattern Stubs | |
951 function CanvasGradient_(aType) { | |
952 this.type_ = aType; | |
953 this.x0_ = 0; | |
954 this.y0_ = 0; | |
955 this.r0_ = 0; | |
956 this.x1_ = 0; | |
957 this.y1_ = 0; | |
958 this.r1_ = 0; | |
959 this.colors_ = []; | |
960 } | |
961 | |
962 CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { | |
963 aColor = processStyle(aColor); | |
964 this.colors_.push({offset: aOffset, | |
965 color: aColor.color, | |
966 alpha: aColor.alpha}); | |
967 }; | |
968 | |
969 function CanvasPattern_() {} | |
970 | |
971 // set up externs | |
972 G_vmlCanvasManager = G_vmlCanvasManager_; | |
973 CanvasRenderingContext2D = CanvasRenderingContext2D_; | |
974 CanvasGradient = CanvasGradient_; | |
975 CanvasPattern = CanvasPattern_; | |
976 | |
977 })(); | |
978 | |
979 } // if | |
980 /*----------------------------------------------------------------------------\ | |
981 | Range Class | | |
982 |-----------------------------------------------------------------------------| | |
983 | Created by Erik Arvidsson | | |
984 | (http://webfx.eae.net/contact.html#erik) | | |
985 | For WebFX (http://webfx.eae.net/) | | |
986 |-----------------------------------------------------------------------------| | |
987 | Used to model the data used when working with sliders, scrollbars and | | |
988 | progress bars. Based on the ideas of the javax.swing.BoundedRangeModel | | |
989 | interface defined by Sun for Java; http://java.sun.com/products/jfc/ | | |
990 | swingdoc-api-1.0.3/com/sun/java/swing/BoundedRangeModel.html | | |
991 |-----------------------------------------------------------------------------| | |
992 | Copyright (c) 2002, 2005, 2006 Erik Arvidsson | | |
993 |-----------------------------------------------------------------------------| | |
994 | Licensed under the Apache License, Version 2.0 (the "License"); you may not | | |
995 | use this file except in compliance with the License. You may obtain a copy | | |
996 | of the License at http://www.apache.org/licenses/LICENSE-2.0 | | |
997 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |
998 | Unless required by applicable law or agreed to in writing, software | | |
999 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | | |
1000 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | | |
1001 | License for the specific language governing permissions and limitations | | |
1002 | under the License. | | |
1003 |-----------------------------------------------------------------------------| | |
1004 | 2002-10-14 | Original version released | | |
1005 | 2005-10-27 | Use Math.round instead of Math.floor | | |
1006 | 2006-05-28 | Changed license to Apache Software License 2.0. | | |
1007 |-----------------------------------------------------------------------------| | |
1008 | Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 | | |
1009 \----------------------------------------------------------------------------*/ | |
1010 | |
1011 | |
1012 function Range() { | |
1013 this._value = 0; | |
1014 this._minimum = 0; | |
1015 this._maximum = 100; | |
1016 this._extent = 0; | |
1017 | |
1018 this._isChanging = false; | |
1019 } | |
1020 | |
1021 Range.prototype.setValue = function (value) { | |
1022 value = Math.round(parseFloat(value)); | |
1023 if (isNaN(value)) return; | |
1024 if (this._value != value) { | |
1025 if (value + this._extent > this._maximum) | |
1026 this._value = this._maximum - this._extent; | |
1027 else if (value < this._minimum) | |
1028 this._value = this._minimum; | |
1029 else | |
1030 this._value = value; | |
1031 if (!this._isChanging && typeof this.onchange == "function") | |
1032 this.onchange(); | |
1033 } | |
1034 }; | |
1035 | |
1036 Range.prototype.getValue = function () { | |
1037 return this._value; | |
1038 }; | |
1039 | |
1040 Range.prototype.setExtent = function (extent) { | |
1041 if (this._extent != extent) { | |
1042 if (extent < 0) | |
1043 this._extent = 0; | |
1044 else if (this._value + extent > this._maximum) | |
1045 this._extent = this._maximum - this._value; | |
1046 else | |
1047 this._extent = extent; | |
1048 if (!this._isChanging && typeof this.onchange == "function") | |
1049 this.onchange(); | |
1050 } | |
1051 }; | |
1052 | |
1053 Range.prototype.getExtent = function () { | |
1054 return this._extent; | |
1055 }; | |
1056 | |
1057 Range.prototype.setMinimum = function (minimum) { | |
1058 if (this._minimum != minimum) { | |
1059 var oldIsChanging = this._isChanging; | |
1060 this._isChanging = true; | |
1061 | |
1062 this._minimum = minimum; | |
1063 | |
1064 if (minimum > this._value) | |
1065 this.setValue(minimum); | |
1066 if (minimum > this._maximum) { | |
1067 this._extent = 0; | |
1068 this.setMaximum(minimum); | |
1069 this.setValue(minimum) | |
1070 } | |
1071 if (minimum + this._extent > this._maximum) | |
1072 this._extent = this._maximum - this._minimum; | |
1073 | |
1074 this._isChanging = oldIsChanging; | |
1075 if (!this._isChanging && typeof this.onchange == "function") | |
1076 this.onchange(); | |
1077 } | |
1078 }; | |
1079 | |
1080 Range.prototype.getMinimum = function () { | |
1081 return this._minimum; | |
1082 }; | |
1083 | |
1084 Range.prototype.setMaximum = function (maximum) { | |
1085 if (this._maximum != maximum) { | |
1086 var oldIsChanging = this._isChanging; | |
1087 this._isChanging = true; | |
1088 | |
1089 this._maximum = maximum; | |
1090 | |
1091 if (maximum < this._value) | |
1092 this.setValue(maximum - this._extent); | |
1093 if (maximum < this._minimum) { | |
1094 this._extent = 0; | |
1095 this.setMinimum(maximum); | |
1096 this.setValue(this._maximum); | |
1097 } | |
1098 if (maximum < this._minimum + this._extent) | |
1099 this._extent = this._maximum - this._minimum; | |
1100 if (maximum < this._value + this._extent) | |
1101 this._extent = this._maximum - this._value; | |
1102 | |
1103 this._isChanging = oldIsChanging; | |
1104 if (!this._isChanging && typeof this.onchange == "function") | |
1105 this.onchange(); | |
1106 } | |
1107 }; | |
1108 | |
1109 Range.prototype.getMaximum = function () { | |
1110 return this._maximum; | |
1111 }; | |
1112 /*----------------------------------------------------------------------------\ | |
1113 | Slider 1.02 | | |
1114 |-----------------------------------------------------------------------------| | |
1115 | Created by Erik Arvidsson | | |
1116 | (http://webfx.eae.net/contact.html#erik) | | |
1117 | For WebFX (http://webfx.eae.net/) | | |
1118 |-----------------------------------------------------------------------------| | |
1119 | A slider control that degrades to an input control for non supported | | |
1120 | browsers. | | |
1121 |-----------------------------------------------------------------------------| | |
1122 | Copyright (c) 2002, 2003, 2006 Erik Arvidsson | | |
1123 |-----------------------------------------------------------------------------| | |
1124 | Licensed under the Apache License, Version 2.0 (the "License"); you may not | | |
1125 | use this file except in compliance with the License. You may obtain a copy | | |
1126 | of the License at http://www.apache.org/licenses/LICENSE-2.0 | | |
1127 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |
1128 | Unless required by applicable law or agreed to in writing, software | | |
1129 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | | |
1130 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | | |
1131 | License for the specific language governing permissions and limitations | | |
1132 | under the License. | | |
1133 |-----------------------------------------------------------------------------| | |
1134 | Dependencies: timer.js - an OO abstraction of timers | | |
1135 | range.js - provides the data model for the slider | | |
1136 | winclassic.css or any other css file describing the look | | |
1137 |-----------------------------------------------------------------------------| | |
1138 | 2002-10-14 | Original version released | | |
1139 | 2003-03-27 | Added a test in the constructor for missing oElement arg | | |
1140 | 2003-11-27 | Only use mousewheel when focused | | |
1141 | 2006-05-28 | Changed license to Apache Software License 2.0. | | |
1142 |-----------------------------------------------------------------------------| | |
1143 | Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 | | |
1144 \----------------------------------------------------------------------------*/ | |
1145 | |
1146 Slider.isSupported = typeof document.createElement != "undefined" && | |
1147 typeof document.documentElement != "undefined" && | |
1148 typeof document.documentElement.offsetWidth == "number"; | |
1149 | |
1150 | |
1151 function Slider(oElement, oInput, sOrientation) { | |
1152 if (!oElement) return; | |
1153 this._orientation = sOrientation || "horizontal"; | |
1154 this._range = new Range(); | |
1155 this._range.setExtent(0); | |
1156 this._blockIncrement = 10; | |
1157 this._unitIncrement = 1; | |
1158 this._timer = new Timer(100); | |
1159 | |
1160 | |
1161 if (Slider.isSupported && oElement) { | |
1162 | |
1163 this.document = oElement.ownerDocument || oElement.document; | |
1164 | |
1165 this.element = oElement; | |
1166 this.element.slider = this; | |
1167 this.element.unselectable = "on"; | |
1168 | |
1169 // add class name tag to class name | |
1170 this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className; | |
1171 | |
1172 // create line | |
1173 this.line = this.document.createElement("DIV"); | |
1174 this.line.className = "line"; | |
1175 this.line.unselectable = "on"; | |
1176 this.line.appendChild(this.document.createElement("DIV")); | |
1177 this.element.appendChild(this.line); | |
1178 | |
1179 // create handle | |
1180 this.handle = this.document.createElement("DIV"); | |
1181 this.handle.className = "handle"; | |
1182 this.handle.unselectable = "on"; | |
1183 this.handle.appendChild(this.document.createElement("DIV")); | |
1184 this.handle.firstChild.appendChild( | |
1185 this.document.createTextNode(String.fromCharCode(160))); | |
1186 this.element.appendChild(this.handle); | |
1187 } | |
1188 | |
1189 this.input = oInput; | |
1190 | |
1191 // events | |
1192 var oThis = this; | |
1193 this._range.onchange = function () { | |
1194 oThis.recalculate(); | |
1195 if (typeof oThis.onchange == "function") | |
1196 oThis.onchange(); | |
1197 }; | |
1198 | |
1199 if (Slider.isSupported && oElement) { | |
1200 this.element.onfocus = Slider.eventHandlers.onfocus; | |
1201 this.element.onblur = Slider.eventHandlers.onblur; | |
1202 this.element.onmousedown = Slider.eventHandlers.onmousedown; | |
1203 this.element.onmouseover = Slider.eventHandlers.onmouseover; | |
1204 this.element.onmouseout = Slider.eventHandlers.onmouseout; | |
1205 this.element.onkeydown = Slider.eventHandlers.onkeydown; | |
1206 this.element.onkeypress = Slider.eventHandlers.onkeypress; | |
1207 this.element.onmousewheel = Slider.eventHandlers.onmousewheel; | |
1208 this.handle.onselectstart = | |
1209 this.element.onselectstart = function () { return false; }; | |
1210 | |
1211 this._timer.ontimer = function () { | |
1212 oThis.ontimer(); | |
1213 }; | |
1214 | |
1215 // extra recalculate for ie | |
1216 window.setTimeout(function() { | |
1217 oThis.recalculate(); | |
1218 }, 1); | |
1219 } | |
1220 else { | |
1221 this.input.onchange = function (e) { | |
1222 oThis.setValue(oThis.input.value); | |
1223 }; | |
1224 } | |
1225 } | |
1226 | |
1227 Slider.eventHandlers = { | |
1228 | |
1229 // helpers to make events a bit easier | |
1230 getEvent: function (e, el) { | |
1231 if (!e) { | |
1232 if (el) | |
1233 e = el.document.parentWindow.event; | |
1234 else | |
1235 e = window.event; | |
1236 } | |
1237 if (!e.srcElement) { | |
1238 var el = e.target; | |
1239 while (el != null && el.nodeType != 1) | |
1240 el = el.parentNode; | |
1241 e.srcElement = el; | |
1242 } | |
1243 if (typeof e.offsetX == "undefined") { | |
1244 e.offsetX = e.layerX; | |
1245 e.offsetY = e.layerY; | |
1246 } | |
1247 | |
1248 return e; | |
1249 }, | |
1250 | |
1251 getDocument: function (e) { | |
1252 if (e.target) | |
1253 return e.target.ownerDocument; | |
1254 return e.srcElement.document; | |
1255 }, | |
1256 | |
1257 getSlider: function (e) { | |
1258 var el = e.target || e.srcElement; | |
1259 while (el != null && el.slider == null) { | |
1260 el = el.parentNode; | |
1261 } | |
1262 if (el) | |
1263 return el.slider; | |
1264 return null; | |
1265 }, | |
1266 | |
1267 getLine: function (e) { | |
1268 var el = e.target || e.srcElement; | |
1269 while (el != null && el.className != "line") { | |
1270 el = el.parentNode; | |
1271 } | |
1272 return el; | |
1273 }, | |
1274 | |
1275 getHandle: function (e) { | |
1276 var el = e.target || e.srcElement; | |
1277 var re = /handle/; | |
1278 while (el != null && !re.test(el.className)) { | |
1279 el = el.parentNode; | |
1280 } | |
1281 return el; | |
1282 }, | |
1283 // end helpers | |
1284 | |
1285 onfocus: function (e) { | |
1286 var s = this.slider; | |
1287 s._focused = true; | |
1288 s.handle.className = "handle hover"; | |
1289 }, | |
1290 | |
1291 onblur: function (e) { | |
1292 var s = this.slider | |
1293 s._focused = false; | |
1294 s.handle.className = "handle"; | |
1295 }, | |
1296 | |
1297 onmouseover: function (e) { | |
1298 e = Slider.eventHandlers.getEvent(e, this); | |
1299 var s = this.slider; | |
1300 if (e.srcElement == s.handle) | |
1301 s.handle.className = "handle hover"; | |
1302 }, | |
1303 | |
1304 onmouseout: function (e) { | |
1305 e = Slider.eventHandlers.getEvent(e, this); | |
1306 var s = this.slider; | |
1307 if (e.srcElement == s.handle && !s._focused) | |
1308 s.handle.className = "handle"; | |
1309 }, | |
1310 | |
1311 onmousedown: function (e) { | |
1312 e = Slider.eventHandlers.getEvent(e, this); | |
1313 var s = this.slider; | |
1314 if (s.element.focus) | |
1315 s.element.focus(); | |
1316 | |
1317 Slider._currentInstance = s; | |
1318 var doc = s.document; | |
1319 | |
1320 if (doc.addEventListener) { | |
1321 doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true); | |
1322 doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true); | |
1323 } | |
1324 else if (doc.attachEvent) { | |
1325 doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove); | |
1326 doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup); | |
1327 doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup); | |
1328 s.element.setCapture(); | |
1329 } | |
1330 | |
1331 if (Slider.eventHandlers.getHandle(e)) { // start drag | |
1332 Slider._sliderDragData = { | |
1333 screenX: e.screenX, | |
1334 screenY: e.screenY, | |
1335 dx: e.screenX - s.handle.offsetLeft, | |
1336 dy: e.screenY - s.handle.offsetTop, | |
1337 startValue: s.getValue(), | |
1338 slider: s | |
1339 }; | |
1340 } | |
1341 else { | |
1342 return; | |
1343 var lineEl = Slider.eventHandlers.getLine(e); | |
1344 s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0); | |
1345 s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0); | |
1346 s._increasing = null; | |
1347 s.ontimer(); | |
1348 } | |
1349 }, | |
1350 | |
1351 onmousemove: function (e) { | |
1352 e = Slider.eventHandlers.getEvent(e, this); | |
1353 | |
1354 if (Slider._sliderDragData) { // drag | |
1355 var s = Slider._sliderDragData.slider; | |
1356 | |
1357 var boundSize = s.getMaximum() - s.getMinimum(); | |
1358 var size, pos, reset; | |
1359 | |
1360 if (s._orientation == "horizontal") { | |
1361 size = s.element.offsetWidth - s.handle.offsetWidth; | |
1362 pos = e.screenX - Slider._sliderDragData.dx; | |
1363 reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100; | |
1364 } | |
1365 else { | |
1366 size = s.element.offsetHeight - s.handle.offsetHeight; | |
1367 pos = s.element.offsetHeight - s.handle.offsetHeight - | |
1368 (e.screenY - Slider._sliderDragData.dy); | |
1369 reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100; | |
1370 } | |
1371 s.setValue(reset ? Slider._sliderDragData.startValue : | |
1372 s.getMinimum() + boundSize * pos / size); | |
1373 return false; | |
1374 } | |
1375 else { | |
1376 return; | |
1377 var s = Slider._currentInstance; | |
1378 if (s != null) { | |
1379 var lineEl = Slider.eventHandlers.getLine(e); | |
1380 s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0); | |
1381 s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0); | |
1382 } | |
1383 } | |
1384 | |
1385 }, | |
1386 | |
1387 onmouseup: function (e) { | |
1388 e = Slider.eventHandlers.getEvent(e, this); | |
1389 var s = Slider._currentInstance; | |
1390 var doc = s.document; | |
1391 if (doc.removeEventListener) { | |
1392 doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true); | |
1393 doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true); | |
1394 } | |
1395 else if (doc.detachEvent) { | |
1396 doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove); | |
1397 doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup); | |
1398 doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup); | |
1399 s.element.releaseCapture(); | |
1400 } | |
1401 | |
1402 if (Slider._sliderDragData) { // end drag | |
1403 Slider._sliderDragData = null; | |
1404 } | |
1405 else { | |
1406 return; | |
1407 s._timer.stop(); | |
1408 s._increasing = null; | |
1409 } | |
1410 Slider._currentInstance = null; | |
1411 }, | |
1412 | |
1413 onkeydown: function (e) { | |
1414 return; | |
1415 e = Slider.eventHandlers.getEvent(e, this); | |
1416 //var s = Slider.eventHandlers.getSlider(e); | |
1417 var s = this.slider; | |
1418 var kc = e.keyCode; | |
1419 switch (kc) { | |
1420 case 33: // page up | |
1421 s.setValue(s.getValue() + s.getBlockIncrement()); | |
1422 break; | |
1423 case 34: // page down | |
1424 s.setValue(s.getValue() - s.getBlockIncrement()); | |
1425 break; | |
1426 case 35: // end | |
1427 s.setValue(s.getOrientation() == "horizontal" ? | |
1428 s.getMaximum() : | |
1429 s.getMinimum()); | |
1430 break; | |
1431 case 36: // home | |
1432 s.setValue(s.getOrientation() == "horizontal" ? | |
1433 s.getMinimum() : | |
1434 s.getMaximum()); | |
1435 break; | |
1436 case 38: // up | |
1437 case 39: // right | |
1438 s.setValue(s.getValue() + s.getUnitIncrement()); | |
1439 break; | |
1440 | |
1441 case 37: // left | |
1442 case 40: // down | |
1443 s.setValue(s.getValue() - s.getUnitIncrement()); | |
1444 break; | |
1445 } | |
1446 | |
1447 if (kc >= 33 && kc <= 40) { | |
1448 return false; | |
1449 } | |
1450 }, | |
1451 | |
1452 onkeypress: function (e) { | |
1453 return; | |
1454 e = Slider.eventHandlers.getEvent(e, this); | |
1455 var kc = e.keyCode; | |
1456 if (kc >= 33 && kc <= 40) { | |
1457 return false; | |
1458 } | |
1459 }, | |
1460 | |
1461 onmousewheel: function (e) { | |
1462 return; | |
1463 e = Slider.eventHandlers.getEvent(e, this); | |
1464 var s = this.slider; | |
1465 if (s._focused) { | |
1466 s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement()); | |
1467 // windows inverts this on horizontal sliders. That does not | |
1468 // make sense to me | |
1469 return false; | |
1470 } | |
1471 } | |
1472 }; | |
1473 | |
1474 | |
1475 | |
1476 Slider.prototype.classNameTag = "dynamic-slider-control", | |
1477 | |
1478 Slider.prototype.setValue = function (v) { | |
1479 this._range.setValue(v); | |
1480 this.input.value = this.getValue(); | |
1481 }; | |
1482 | |
1483 Slider.prototype.getValue = function () { | |
1484 return this._range.getValue(); | |
1485 }; | |
1486 | |
1487 Slider.prototype.setMinimum = function (v) { | |
1488 this._range.setMinimum(v); | |
1489 this.input.value = this.getValue(); | |
1490 }; | |
1491 | |
1492 Slider.prototype.getMinimum = function () { | |
1493 return this._range.getMinimum(); | |
1494 }; | |
1495 | |
1496 Slider.prototype.setMaximum = function (v) { | |
1497 this._range.setMaximum(v); | |
1498 this.input.value = this.getValue(); | |
1499 }; | |
1500 | |
1501 Slider.prototype.getMaximum = function () { | |
1502 return this._range.getMaximum(); | |
1503 }; | |
1504 | |
1505 Slider.prototype.setUnitIncrement = function (v) { | |
1506 this._unitIncrement = v; | |
1507 }; | |
1508 | |
1509 Slider.prototype.getUnitIncrement = function () { | |
1510 return this._unitIncrement; | |
1511 }; | |
1512 | |
1513 Slider.prototype.setBlockIncrement = function (v) { | |
1514 this._blockIncrement = v; | |
1515 }; | |
1516 | |
1517 Slider.prototype.getBlockIncrement = function () { | |
1518 return this._blockIncrement; | |
1519 }; | |
1520 | |
1521 Slider.prototype.getOrientation = function () { | |
1522 return this._orientation; | |
1523 }; | |
1524 | |
1525 Slider.prototype.setOrientation = function (sOrientation) { | |
1526 if (sOrientation != this._orientation) { | |
1527 if (Slider.isSupported && this.element) { | |
1528 // add class name tag to class name | |
1529 this.element.className = this.element.className.replace(this._orientation, | |
1530 sOrientation); | |
1531 } | |
1532 this._orientation = sOrientation; | |
1533 this.recalculate(); | |
1534 | |
1535 } | |
1536 }; | |
1537 | |
1538 Slider.prototype.recalculate = function() { | |
1539 if (!Slider.isSupported || !this.element) return; | |
1540 | |
1541 var w = this.element.offsetWidth; | |
1542 var h = this.element.offsetHeight; | |
1543 var hw = this.handle.offsetWidth; | |
1544 var hh = this.handle.offsetHeight; | |
1545 var lw = this.line.offsetWidth; | |
1546 var lh = this.line.offsetHeight; | |
1547 | |
1548 // this assumes a border-box layout | |
1549 | |
1550 if (this._orientation == "horizontal") { | |
1551 this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) / | |
1552 (this.getMaximum() - this.getMinimum()) + "px"; | |
1553 this.handle.style.top = (h - hh) / 2 + "px"; | |
1554 | |
1555 this.line.style.top = (h - lh) / 2 + "px"; | |
1556 this.line.style.left = hw / 2 + "px"; | |
1557 //this.line.style.right = hw / 2 + "px"; | |
1558 this.line.style.width = Math.max(0, w - hw - 2)+ "px"; | |
1559 this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px"; | |
1560 } | |
1561 else { | |
1562 this.handle.style.left = (w - hw) / 2 + "px"; | |
1563 this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) / | |
1564 (this.getMaximum() - this.getMinimum()) + "px"; | |
1565 | |
1566 this.line.style.left = (w - lw) / 2 + "px"; | |
1567 this.line.style.top = hh / 2 + "px"; | |
1568 this.line.style.height = Math.max(0, h - hh - 2) + "px"; //hard coded border width | |
1569 //this.line.style.bottom = hh / 2 + "px"; | |
1570 this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px"; //hard coded border width | |
1571 } | |
1572 }; | |
1573 | |
1574 Slider.prototype.ontimer = function () { | |
1575 var hw = this.handle.offsetWidth; | |
1576 var hh = this.handle.offsetHeight; | |
1577 var hl = this.handle.offsetLeft; | |
1578 var ht = this.handle.offsetTop; | |
1579 | |
1580 if (this._orientation == "horizontal") { | |
1581 if (this._mouseX > hl + hw && | |
1582 (this._increasing == null || this._increasing)) { | |
1583 this.setValue(this.getValue() + this.getBlockIncrement()); | |
1584 this._increasing = true; | |
1585 } | |
1586 else if (this._mouseX < hl && | |
1587 (this._increasing == null || !this._increasing)) { | |
1588 this.setValue(this.getValue() - this.getBlockIncrement()); | |
1589 this._increasing = false; | |
1590 } | |
1591 } | |
1592 else { | |
1593 if (this._mouseY > ht + hh && | |
1594 (this._increasing == null || !this._increasing)) { | |
1595 this.setValue(this.getValue() - this.getBlockIncrement()); | |
1596 this._increasing = false; | |
1597 } | |
1598 else if (this._mouseY < ht && | |
1599 (this._increasing == null || this._increasing)) { | |
1600 this.setValue(this.getValue() + this.getBlockIncrement()); | |
1601 this._increasing = true; | |
1602 } | |
1603 } | |
1604 | |
1605 this._timer.start(); | |
1606 }; | |
1607 /*----------------------------------------------------------------------------\ | |
1608 | Timer Class | | |
1609 |-----------------------------------------------------------------------------| | |
1610 | Created by Erik Arvidsson | | |
1611 | (http://webfx.eae.net/contact.html#erik) | | |
1612 | For WebFX (http://webfx.eae.net/) | | |
1613 |-----------------------------------------------------------------------------| | |
1614 | Object Oriented Encapsulation of setTimeout fires ontimer when the timer | | |
1615 | is triggered. Does not work in IE 5.00 | | |
1616 |-----------------------------------------------------------------------------| | |
1617 | Copyright (c) 2002, 2006 Erik Arvidsson | | |
1618 |-----------------------------------------------------------------------------| | |
1619 | Licensed under the Apache License, Version 2.0 (the "License"); you may not | | |
1620 | use this file except in compliance with the License. You may obtain a copy | | |
1621 | of the License at http://www.apache.org/licenses/LICENSE-2.0 | | |
1622 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | | |
1623 | Unless required by applicable law or agreed to in writing, software | | |
1624 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | | |
1625 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | | |
1626 | License for the specific language governing permissions and limitations | | |
1627 | under the License. | | |
1628 |-----------------------------------------------------------------------------| | |
1629 | 2002-10-14 | Original version released | | |
1630 | 2006-05-28 | Changed license to Apache Software License 2.0. | | |
1631 |-----------------------------------------------------------------------------| | |
1632 | Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 | | |
1633 \----------------------------------------------------------------------------*/ | |
1634 | |
1635 function Timer(nPauseTime) { | |
1636 this._pauseTime = typeof nPauseTime == "undefined" ? 1000 : nPauseTime; | |
1637 this._timer = null; | |
1638 this._isStarted = false; | |
1639 } | |
1640 | |
1641 Timer.prototype.start = function () { | |
1642 if (this.isStarted()) | |
1643 this.stop(); | |
1644 var oThis = this; | |
1645 this._timer = window.setTimeout(function () { | |
1646 if (typeof oThis.ontimer == "function") | |
1647 oThis.ontimer(); | |
1648 }, this._pauseTime); | |
1649 this._isStarted = false; | |
1650 }; | |
1651 | |
1652 Timer.prototype.stop = function () { | |
1653 if (this._timer != null) | |
1654 window.clearTimeout(this._timer); | |
1655 this._isStarted = false; | |
1656 }; | |
1657 | |
1658 Timer.prototype.isStarted = function () { | |
1659 return this._isStarted; | |
1660 }; | |
1661 | |
1662 Timer.prototype.getPauseTime = function () { | |
1663 return this._pauseTime; | |
1664 }; | |
1665 | |
1666 Timer.prototype.setPauseTime = function (nPauseTime) { | |
1667 this._pauseTime = nPauseTime; | |
1668 }; | |
1669 /* | |
1670 | |
1671 OpenLayers.js -- OpenLayers Map Viewer Library | |
1672 | |
1673 Copyright (c) 2006-2013 by OpenLayers Contributors | |
1674 Published under the 2-clause BSD license. | |
1675 See http://openlayers.org/dev/license.txt for the full text of the license, and http://openlayers.org/dev/authors.txt for full list of contributors. | |
1676 | |
1677 Includes compressed code under the following licenses: | |
1678 | |
1679 (For uncompressed versions of the code used, please see the | |
1680 OpenLayers Github repository: <https://github.com/openlayers/openlayers>) | |
1681 | |
1682 */ | |
1683 | |
1684 /** | |
1685 * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/> | |
1686 * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com) | |
1687 * | |
1688 * Licensed under the Apache License, Version 2.0 (the "License"); | |
1689 * you may not use this file except in compliance with the License. | |
1690 * You may obtain a copy of the License at | |
1691 * http://www.apache.org/licenses/LICENSE-2.0 | |
1692 */ | |
1693 | |
1694 /** | |
1695 * OpenLayers.Util.pagePosition is based on Yahoo's getXY method, which is | |
1696 * Copyright (c) 2006, Yahoo! Inc. | |
1697 * All rights reserved. | |
1698 * | |
1699 * Redistribution and use of this software in source and binary forms, with or | |
1700 * without modification, are permitted provided that the following conditions | |
1701 * are met: | |
1702 * | |
1703 * * Redistributions of source code must retain the above copyright notice, | |
1704 * this list of conditions and the following disclaimer. | |
1705 * | |
1706 * * Redistributions in binary form must reproduce the above copyright notice, | |
1707 * this list of conditions and the following disclaimer in the documentation | |
1708 * and/or other materials provided with the distribution. | |
1709 * | |
1710 * * Neither the name of Yahoo! Inc. nor the names of its contributors may be | |
1711 * used to endorse or promote products derived from this software without | |
1712 * specific prior written permission of Yahoo! Inc. | |
1713 * | |
1714 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
1715 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
1716 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
1717 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
1718 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
1719 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
1720 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
1721 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
1722 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
1723 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
1724 * POSSIBILITY OF SUCH DAMAGE. | |
1725 */ | |
1726 var OpenLayers={VERSION_NUMBER:"Release 2.13.1",singleFile:!0,_getScriptLocation:function(){for(var a=/(^|(.*?\/))(OpenLayers[^\/]*?\.js)(\?|$)/,b=document.getElementsByTagName("script"),c,d="",e=0,f=b.length;e<f;e++)if(c=b[e].getAttribute("src"))if(c=c.match(a)){d=c[1];break}return function(){return d}}(),ImgPath:""};OpenLayers.Class=function(){var a=arguments.length,b=arguments[0],c=arguments[a-1],d="function"==typeof c.initialize?c.initialize:function(){b.prototype.initialize.apply(this,arguments)};1<a?(a=[d,b].concat(Array.prototype.slice.call(arguments).slice(1,a-1),c),OpenLayers.inherit.apply(null,a)):d.prototype=c;return d}; | |
1727 OpenLayers.inherit=function(a,b){var c=function(){};c.prototype=b.prototype;a.prototype=new c;var d,e,c=2;for(d=arguments.length;c<d;c++)e=arguments[c],"function"===typeof e&&(e=e.prototype),OpenLayers.Util.extend(a.prototype,e)};OpenLayers.Util=OpenLayers.Util||{};OpenLayers.Util.extend=function(a,b){a=a||{};if(b){for(var c in b){var d=b[c];void 0!==d&&(a[c]=d)}"function"==typeof window.Event&&b instanceof window.Event||(!b.hasOwnProperty||!b.hasOwnProperty("toString"))||(a.toString=b.toString)}return a};OpenLayers.String={startsWith:function(a,b){return 0==a.indexOf(b)},contains:function(a,b){return-1!=a.indexOf(b)},trim:function(a){return a.replace(/^\s\s*/,"").replace(/\s\s*$/,"")},camelize:function(a){a=a.split("-");for(var b=a[0],c=1,d=a.length;c<d;c++)var e=a[c],b=b+(e.charAt(0).toUpperCase()+e.substring(1));return b},format:function(a,b,c){b||(b=window);return a.replace(OpenLayers.String.tokenRegEx,function(a,e){for(var f,g=e.split(/\.+/),h=0;h<g.length;h++){0==h&&(f=b);if(void 0===f)break; | |
1728 f=f[g[h]]}"function"==typeof f&&(f=c?f.apply(null,c):f());return"undefined"==typeof f?"undefined":f})},tokenRegEx:/\$\{([\w.]+?)\}/g,numberRegEx:/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/,isNumeric:function(a){return OpenLayers.String.numberRegEx.test(a)},numericIf:function(a,b){var c=a;!0===b&&(null!=a&&a.replace)&&(a=a.replace(/^\s*|\s*$/g,""));return OpenLayers.String.isNumeric(a)?parseFloat(a):c}}; | |
1729 OpenLayers.Number={decimalSeparator:".",thousandsSeparator:",",limitSigDigs:function(a,b){var c=0;0<b&&(c=parseFloat(a.toPrecision(b)));return c},format:function(a,b,c,d){b="undefined"!=typeof b?b:0;c="undefined"!=typeof c?c:OpenLayers.Number.thousandsSeparator;d="undefined"!=typeof d?d:OpenLayers.Number.decimalSeparator;null!=b&&(a=parseFloat(a.toFixed(b)));var e=a.toString().split(".");1==e.length&&null==b&&(b=0);a=e[0];if(c)for(var f=/(-?[0-9]+)([0-9]{3})/;f.test(a);)a=a.replace(f,"$1"+c+"$2"); | |
1730 0==b?b=a:(c=1<e.length?e[1]:"0",null!=b&&(c+=Array(b-c.length+1).join("0")),b=a+d+c);return b},zeroPad:function(a,b,c){for(a=a.toString(c||10);a.length<b;)a="0"+a;return a}}; | |
1731 OpenLayers.Function={bind:function(a,b){var c=Array.prototype.slice.apply(arguments,[2]);return function(){var d=c.concat(Array.prototype.slice.apply(arguments,[0]));return a.apply(b,d)}},bindAsEventListener:function(a,b){return function(c){return a.call(b,c||window.event)}},False:function(){return!1},True:function(){return!0},Void:function(){}}; | |
1732 OpenLayers.Array={filter:function(a,b,c){var d=[];if(Array.prototype.filter)d=a.filter(b,c);else{var e=a.length;if("function"!=typeof b)throw new TypeError;for(var f=0;f<e;f++)if(f in a){var g=a[f];b.call(c,g,f,a)&&d.push(g)}}return d}};OpenLayers.Bounds=OpenLayers.Class({left:null,bottom:null,right:null,top:null,centerLonLat:null,initialize:function(a,b,c,d){OpenLayers.Util.isArray(a)&&(d=a[3],c=a[2],b=a[1],a=a[0]);null!=a&&(this.left=OpenLayers.Util.toFloat(a));null!=b&&(this.bottom=OpenLayers.Util.toFloat(b));null!=c&&(this.right=OpenLayers.Util.toFloat(c));null!=d&&(this.top=OpenLayers.Util.toFloat(d))},clone:function(){return new OpenLayers.Bounds(this.left,this.bottom,this.right,this.top)},equals:function(a){var b=!1;null!= | |
1733 a&&(b=this.left==a.left&&this.right==a.right&&this.top==a.top&&this.bottom==a.bottom);return b},toString:function(){return[this.left,this.bottom,this.right,this.top].join()},toArray:function(a){return!0===a?[this.bottom,this.left,this.top,this.right]:[this.left,this.bottom,this.right,this.top]},toBBOX:function(a,b){null==a&&(a=6);var c=Math.pow(10,a),d=Math.round(this.left*c)/c,e=Math.round(this.bottom*c)/c,f=Math.round(this.right*c)/c,c=Math.round(this.top*c)/c;return!0===b?e+","+d+","+c+","+f:d+ | |
1734 ","+e+","+f+","+c},toGeometry:function(){return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(this.left,this.bottom),new OpenLayers.Geometry.Point(this.right,this.bottom),new OpenLayers.Geometry.Point(this.right,this.top),new OpenLayers.Geometry.Point(this.left,this.top)])])},getWidth:function(){return this.right-this.left},getHeight:function(){return this.top-this.bottom},getSize:function(){return new OpenLayers.Size(this.getWidth(),this.getHeight())}, | |
1735 getCenterPixel:function(){return new OpenLayers.Pixel((this.left+this.right)/2,(this.bottom+this.top)/2)},getCenterLonLat:function(){this.centerLonLat||(this.centerLonLat=new OpenLayers.LonLat((this.left+this.right)/2,(this.bottom+this.top)/2));return this.centerLonLat},scale:function(a,b){null==b&&(b=this.getCenterLonLat());var c,d;"OpenLayers.LonLat"==b.CLASS_NAME?(c=b.lon,d=b.lat):(c=b.x,d=b.y);return new OpenLayers.Bounds((this.left-c)*a+c,(this.bottom-d)*a+d,(this.right-c)*a+c,(this.top-d)*a+ | |
1736 d)},add:function(a,b){if(null==a||null==b)throw new TypeError("Bounds.add cannot receive null values");return new OpenLayers.Bounds(this.left+a,this.bottom+b,this.right+a,this.top+b)},extend:function(a){if(a)switch(a.CLASS_NAME){case "OpenLayers.LonLat":this.extendXY(a.lon,a.lat);break;case "OpenLayers.Geometry.Point":this.extendXY(a.x,a.y);break;case "OpenLayers.Bounds":this.centerLonLat=null;if(null==this.left||a.left<this.left)this.left=a.left;if(null==this.bottom||a.bottom<this.bottom)this.bottom= | |
1737 a.bottom;if(null==this.right||a.right>this.right)this.right=a.right;if(null==this.top||a.top>this.top)this.top=a.top}},extendXY:function(a,b){this.centerLonLat=null;if(null==this.left||a<this.left)this.left=a;if(null==this.bottom||b<this.bottom)this.bottom=b;if(null==this.right||a>this.right)this.right=a;if(null==this.top||b>this.top)this.top=b},containsLonLat:function(a,b){"boolean"===typeof b&&(b={inclusive:b});b=b||{};var c=this.contains(a.lon,a.lat,b.inclusive),d=b.worldBounds;d&&!c&&(c=d.getWidth(), | |
1738 d=Math.round((a.lon-(d.left+d.right)/2)/c),c=this.containsLonLat({lon:a.lon-d*c,lat:a.lat},{inclusive:b.inclusive}));return c},containsPixel:function(a,b){return this.contains(a.x,a.y,b)},contains:function(a,b,c){null==c&&(c=!0);if(null==a||null==b)return!1;a=OpenLayers.Util.toFloat(a);b=OpenLayers.Util.toFloat(b);var d=!1;return d=c?a>=this.left&&a<=this.right&&b>=this.bottom&&b<=this.top:a>this.left&&a<this.right&&b>this.bottom&&b<this.top},intersectsBounds:function(a,b){"boolean"===typeof b&&(b= | |
1739 {inclusive:b});b=b||{};if(b.worldBounds){var c=this.wrapDateLine(b.worldBounds);a=a.wrapDateLine(b.worldBounds)}else c=this;null==b.inclusive&&(b.inclusive=!0);var d=!1,e=c.left==a.right||c.right==a.left||c.top==a.bottom||c.bottom==a.top;if(b.inclusive||!e)var d=a.top>=c.bottom&&a.top<=c.top||c.top>a.bottom&&c.top<a.top,e=a.left>=c.left&&a.left<=c.right||c.left>=a.left&&c.left<=a.right,f=a.right>=c.left&&a.right<=c.right||c.right>=a.left&&c.right<=a.right,d=(a.bottom>=c.bottom&&a.bottom<=c.top||c.bottom>= | |
1740 a.bottom&&c.bottom<=a.top||d)&&(e||f);if(b.worldBounds&&!d){var g=b.worldBounds,e=g.getWidth(),f=!g.containsBounds(c),g=!g.containsBounds(a);f&&!g?(a=a.add(-e,0),d=c.intersectsBounds(a,{inclusive:b.inclusive})):g&&!f&&(c=c.add(-e,0),d=a.intersectsBounds(c,{inclusive:b.inclusive}))}return d},containsBounds:function(a,b,c){null==b&&(b=!1);null==c&&(c=!0);var d=this.contains(a.left,a.bottom,c),e=this.contains(a.right,a.bottom,c),f=this.contains(a.left,a.top,c);a=this.contains(a.right,a.top,c);return b? | |
1741 d||e||f||a:d&&e&&f&&a},determineQuadrant:function(a){var b="",c=this.getCenterLonLat(),b=b+(a.lat<c.lat?"b":"t");return b+=a.lon<c.lon?"l":"r"},transform:function(a,b){this.centerLonLat=null;var c=OpenLayers.Projection.transform({x:this.left,y:this.bottom},a,b),d=OpenLayers.Projection.transform({x:this.right,y:this.bottom},a,b),e=OpenLayers.Projection.transform({x:this.left,y:this.top},a,b),f=OpenLayers.Projection.transform({x:this.right,y:this.top},a,b);this.left=Math.min(c.x,e.x);this.bottom=Math.min(c.y, | |
1742 d.y);this.right=Math.max(d.x,f.x);this.top=Math.max(e.y,f.y);return this},wrapDateLine:function(a,b){b=b||{};var c=b.leftTolerance||0,d=b.rightTolerance||0,e=this.clone();if(a){for(var f=a.getWidth();e.left<a.left&&e.right-d<=a.left;)e=e.add(f,0);for(;e.left+c>=a.right&&e.right>a.right;)e=e.add(-f,0);c=e.left+c;c<a.right&&(c>a.left&&e.right-d>a.right)&&(e=e.add(-f,0))}return e},CLASS_NAME:"OpenLayers.Bounds"}); | |
1743 OpenLayers.Bounds.fromString=function(a,b){var c=a.split(",");return OpenLayers.Bounds.fromArray(c,b)};OpenLayers.Bounds.fromArray=function(a,b){return!0===b?new OpenLayers.Bounds(a[1],a[0],a[3],a[2]):new OpenLayers.Bounds(a[0],a[1],a[2],a[3])};OpenLayers.Bounds.fromSize=function(a){return new OpenLayers.Bounds(0,a.h,a.w,0)};OpenLayers.Bounds.oppositeQuadrant=function(a){var b;b=""+("t"==a.charAt(0)?"b":"t");return b+="l"==a.charAt(1)?"r":"l"};OpenLayers.Element={visible:function(a){return"none"!=OpenLayers.Util.getElement(a).style.display},toggle:function(){for(var a=0,b=arguments.length;a<b;a++){var c=OpenLayers.Util.getElement(arguments[a]),d=OpenLayers.Element.visible(c)?"none":"";c.style.display=d}},remove:function(a){a=OpenLayers.Util.getElement(a);a.parentNode.removeChild(a)},getHeight:function(a){a=OpenLayers.Util.getElement(a);return a.offsetHeight},hasClass:function(a,b){var c=a.className;return!!c&&RegExp("(^|\\s)"+b+"(\\s|$)").test(c)}, | |
1744 addClass:function(a,b){OpenLayers.Element.hasClass(a,b)||(a.className+=(a.className?" ":"")+b);return a},removeClass:function(a,b){var c=a.className;c&&(a.className=OpenLayers.String.trim(c.replace(RegExp("(^|\\s+)"+b+"(\\s+|$)")," ")));return a},toggleClass:function(a,b){OpenLayers.Element.hasClass(a,b)?OpenLayers.Element.removeClass(a,b):OpenLayers.Element.addClass(a,b);return a},getStyle:function(a,b){a=OpenLayers.Util.getElement(a);var c=null;if(a&&a.style){c=a.style[OpenLayers.String.camelize(b)]; | |
1745 c||(document.defaultView&&document.defaultView.getComputedStyle?c=(c=document.defaultView.getComputedStyle(a,null))?c.getPropertyValue(b):null:a.currentStyle&&(c=a.currentStyle[OpenLayers.String.camelize(b)]));var d=["left","top","right","bottom"];window.opera&&(-1!=OpenLayers.Util.indexOf(d,b)&&"static"==OpenLayers.Element.getStyle(a,"position"))&&(c="auto")}return"auto"==c?null:c}};OpenLayers.LonLat=OpenLayers.Class({lon:0,lat:0,initialize:function(a,b){OpenLayers.Util.isArray(a)&&(b=a[1],a=a[0]);this.lon=OpenLayers.Util.toFloat(a);this.lat=OpenLayers.Util.toFloat(b)},toString:function(){return"lon="+this.lon+",lat="+this.lat},toShortString:function(){return this.lon+", "+this.lat},clone:function(){return new OpenLayers.LonLat(this.lon,this.lat)},add:function(a,b){if(null==a||null==b)throw new TypeError("LonLat.add cannot receive null values");return new OpenLayers.LonLat(this.lon+ | |
1746 OpenLayers.Util.toFloat(a),this.lat+OpenLayers.Util.toFloat(b))},equals:function(a){var b=!1;null!=a&&(b=this.lon==a.lon&&this.lat==a.lat||isNaN(this.lon)&&isNaN(this.lat)&&isNaN(a.lon)&&isNaN(a.lat));return b},transform:function(a,b){var c=OpenLayers.Projection.transform({x:this.lon,y:this.lat},a,b);this.lon=c.x;this.lat=c.y;return this},wrapDateLine:function(a){var b=this.clone();if(a){for(;b.lon<a.left;)b.lon+=a.getWidth();for(;b.lon>a.right;)b.lon-=a.getWidth()}return b},CLASS_NAME:"OpenLayers.LonLat"}); | |
1747 OpenLayers.LonLat.fromString=function(a){a=a.split(",");return new OpenLayers.LonLat(a[0],a[1])};OpenLayers.LonLat.fromArray=function(a){var b=OpenLayers.Util.isArray(a);return new OpenLayers.LonLat(b&&a[0],b&&a[1])};OpenLayers.Pixel=OpenLayers.Class({x:0,y:0,initialize:function(a,b){this.x=parseFloat(a);this.y=parseFloat(b)},toString:function(){return"x="+this.x+",y="+this.y},clone:function(){return new OpenLayers.Pixel(this.x,this.y)},equals:function(a){var b=!1;null!=a&&(b=this.x==a.x&&this.y==a.y||isNaN(this.x)&&isNaN(this.y)&&isNaN(a.x)&&isNaN(a.y));return b},distanceTo:function(a){return Math.sqrt(Math.pow(this.x-a.x,2)+Math.pow(this.y-a.y,2))},add:function(a,b){if(null==a||null==b)throw new TypeError("Pixel.add cannot receive null values"); | |
1748 return new OpenLayers.Pixel(this.x+a,this.y+b)},offset:function(a){var b=this.clone();a&&(b=this.add(a.x,a.y));return b},CLASS_NAME:"OpenLayers.Pixel"});OpenLayers.Size=OpenLayers.Class({w:0,h:0,initialize:function(a,b){this.w=parseFloat(a);this.h=parseFloat(b)},toString:function(){return"w="+this.w+",h="+this.h},clone:function(){return new OpenLayers.Size(this.w,this.h)},equals:function(a){var b=!1;null!=a&&(b=this.w==a.w&&this.h==a.h||isNaN(this.w)&&isNaN(this.h)&&isNaN(a.w)&&isNaN(a.h));return b},CLASS_NAME:"OpenLayers.Size"});OpenLayers.Console={log:function(){},debug:function(){},info:function(){},warn:function(){},error:function(){},userError:function(a){alert(a)},assert:function(){},dir:function(){},dirxml:function(){},trace:function(){},group:function(){},groupEnd:function(){},time:function(){},timeEnd:function(){},profile:function(){},profileEnd:function(){},count:function(){},CLASS_NAME:"OpenLayers.Console"}; | |
1749 (function(){for(var a=document.getElementsByTagName("script"),b=0,c=a.length;b<c;++b)if(-1!=a[b].src.indexOf("firebug.js")&&console){OpenLayers.Util.extend(OpenLayers.Console,console);break}})();OpenLayers.Lang={code:null,defaultCode:"en",getCode:function(){OpenLayers.Lang.code||OpenLayers.Lang.setCode();return OpenLayers.Lang.code},setCode:function(a){var b;a||(a="msie"==OpenLayers.BROWSER_NAME?navigator.userLanguage:navigator.language);a=a.split("-");a[0]=a[0].toLowerCase();"object"==typeof OpenLayers.Lang[a[0]]&&(b=a[0]);if(a[1]){var c=a[0]+"-"+a[1].toUpperCase();"object"==typeof OpenLayers.Lang[c]&&(b=c)}b||(OpenLayers.Console.warn("Failed to find OpenLayers.Lang."+a.join("-")+" dictionary, falling back to default language"), | |
1750 b=OpenLayers.Lang.defaultCode);OpenLayers.Lang.code=b},translate:function(a,b){var c=OpenLayers.Lang[OpenLayers.Lang.getCode()];(c=c&&c[a])||(c=a);b&&(c=OpenLayers.String.format(c,b));return c}};OpenLayers.i18n=OpenLayers.Lang.translate;OpenLayers.Util=OpenLayers.Util||{};OpenLayers.Util.getElement=function(){for(var a=[],b=0,c=arguments.length;b<c;b++){var d=arguments[b];"string"==typeof d&&(d=document.getElementById(d));if(1==arguments.length)return d;a.push(d)}return a};OpenLayers.Util.isElement=function(a){return!(!a||1!==a.nodeType)};OpenLayers.Util.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)};OpenLayers.Util.removeItem=function(a,b){for(var c=a.length-1;0<=c;c--)a[c]==b&&a.splice(c,1);return a}; | |
1751 OpenLayers.Util.indexOf=function(a,b){if("function"==typeof a.indexOf)return a.indexOf(b);for(var c=0,d=a.length;c<d;c++)if(a[c]==b)return c;return-1};OpenLayers.Util.dotless=/\./g; | |
1752 OpenLayers.Util.modifyDOMElement=function(a,b,c,d,e,f,g,h){b&&(a.id=b.replace(OpenLayers.Util.dotless,"_"));c&&(a.style.left=c.x+"px",a.style.top=c.y+"px");d&&(a.style.width=d.w+"px",a.style.height=d.h+"px");e&&(a.style.position=e);f&&(a.style.border=f);g&&(a.style.overflow=g);0<=parseFloat(h)&&1>parseFloat(h)?(a.style.filter="alpha(opacity="+100*h+")",a.style.opacity=h):1==parseFloat(h)&&(a.style.filter="",a.style.opacity="")}; | |
1753 OpenLayers.Util.createDiv=function(a,b,c,d,e,f,g,h){var k=document.createElement("div");d&&(k.style.backgroundImage="url("+d+")");a||(a=OpenLayers.Util.createUniqueID("OpenLayersDiv"));e||(e="absolute");OpenLayers.Util.modifyDOMElement(k,a,b,c,e,f,g,h);return k}; | |
1754 OpenLayers.Util.createImage=function(a,b,c,d,e,f,g,h){var k=document.createElement("img");a||(a=OpenLayers.Util.createUniqueID("OpenLayersDiv"));e||(e="relative");OpenLayers.Util.modifyDOMElement(k,a,b,c,e,f,null,g);h&&(k.style.display="none",b=function(){k.style.display="";OpenLayers.Event.stopObservingElement(k)},OpenLayers.Event.observe(k,"load",b),OpenLayers.Event.observe(k,"error",b));k.style.alt=a;k.galleryImg="no";d&&(k.src=d);return k};OpenLayers.IMAGE_RELOAD_ATTEMPTS=0; | |
1755 OpenLayers.Util.alphaHackNeeded=null;OpenLayers.Util.alphaHack=function(){if(null==OpenLayers.Util.alphaHackNeeded){var a=navigator.appVersion.split("MSIE"),a=parseFloat(a[1]),b=!1;try{b=!!document.body.filters}catch(c){}OpenLayers.Util.alphaHackNeeded=b&&5.5<=a&&7>a}return OpenLayers.Util.alphaHackNeeded}; | |
1756 OpenLayers.Util.modifyAlphaImageDiv=function(a,b,c,d,e,f,g,h,k){OpenLayers.Util.modifyDOMElement(a,b,c,d,f,null,null,k);b=a.childNodes[0];e&&(b.src=e);OpenLayers.Util.modifyDOMElement(b,a.id+"_innerImage",null,d,"relative",g);OpenLayers.Util.alphaHack()&&("none"!=a.style.display&&(a.style.display="inline-block"),null==h&&(h="scale"),a.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+b.src+"', sizingMethod='"+h+"')",0<=parseFloat(a.style.opacity)&&1>parseFloat(a.style.opacity)&& | |
1757 (a.style.filter+=" alpha(opacity="+100*a.style.opacity+")"),b.style.filter="alpha(opacity=0)")};OpenLayers.Util.createAlphaImageDiv=function(a,b,c,d,e,f,g,h,k){var l=OpenLayers.Util.createDiv();k=OpenLayers.Util.createImage(null,null,null,null,null,null,null,k);k.className="olAlphaImg";l.appendChild(k);OpenLayers.Util.modifyAlphaImageDiv(l,a,b,c,d,e,f,g,h);return l};OpenLayers.Util.upperCaseObject=function(a){var b={},c;for(c in a)b[c.toUpperCase()]=a[c];return b}; | |
1758 OpenLayers.Util.applyDefaults=function(a,b){a=a||{};var c="function"==typeof window.Event&&b instanceof window.Event,d;for(d in b)if(void 0===a[d]||!c&&b.hasOwnProperty&&b.hasOwnProperty(d)&&!a.hasOwnProperty(d))a[d]=b[d];!c&&(b&&b.hasOwnProperty&&b.hasOwnProperty("toString")&&!a.hasOwnProperty("toString"))&&(a.toString=b.toString);return a}; | |
1759 OpenLayers.Util.getParameterString=function(a){var b=[],c;for(c in a){var d=a[c];if(null!=d&&"function"!=typeof d){if("object"==typeof d&&d.constructor==Array){for(var e=[],f,g=0,h=d.length;g<h;g++)f=d[g],e.push(encodeURIComponent(null===f||void 0===f?"":f));d=e.join(",")}else d=encodeURIComponent(d);b.push(encodeURIComponent(c)+"="+d)}}return b.join("&")};OpenLayers.Util.urlAppend=function(a,b){var c=a;if(b)var d=(a+" ").split(/[?&]/),c=c+(" "===d.pop()?b:d.length?"&"+b:"?"+b);return c}; | |
1760 OpenLayers.Util.getImagesLocation=function(){return OpenLayers.ImgPath||OpenLayers._getScriptLocation()+"img/"};OpenLayers.Util.getImageLocation=function(a){return OpenLayers.Util.getImagesLocation()+a};OpenLayers.Util.Try=function(){for(var a=null,b=0,c=arguments.length;b<c;b++){var d=arguments[b];try{a=d();break}catch(e){}}return a}; | |
1761 OpenLayers.Util.getXmlNodeValue=function(a){var b=null;OpenLayers.Util.Try(function(){b=a.text;b||(b=a.textContent);b||(b=a.firstChild.nodeValue)},function(){b=a.textContent});return b};OpenLayers.Util.mouseLeft=function(a,b){for(var c=a.relatedTarget?a.relatedTarget:a.toElement;c!=b&&null!=c;)c=c.parentNode;return c!=b};OpenLayers.Util.DEFAULT_PRECISION=14;OpenLayers.Util.toFloat=function(a,b){null==b&&(b=OpenLayers.Util.DEFAULT_PRECISION);"number"!==typeof a&&(a=parseFloat(a));return 0===b?a:parseFloat(a.toPrecision(b))}; | |
1762 OpenLayers.Util.rad=function(a){return a*Math.PI/180};OpenLayers.Util.deg=function(a){return 180*a/Math.PI};OpenLayers.Util.VincentyConstants={a:6378137,b:6356752.3142,f:1/298.257223563}; | |
1763 OpenLayers.Util.distVincenty=function(a,b){for(var c=OpenLayers.Util.VincentyConstants,d=c.a,e=c.b,c=c.f,f=OpenLayers.Util.rad(b.lon-a.lon),g=Math.atan((1-c)*Math.tan(OpenLayers.Util.rad(a.lat))),h=Math.atan((1-c)*Math.tan(OpenLayers.Util.rad(b.lat))),k=Math.sin(g),g=Math.cos(g),l=Math.sin(h),h=Math.cos(h),m=f,n=2*Math.PI,p=20;1E-12<Math.abs(m-n)&&0<--p;){var q=Math.sin(m),r=Math.cos(m),s=Math.sqrt(h*q*h*q+(g*l-k*h*r)*(g*l-k*h*r));if(0==s)return 0;var r=k*l+g*h*r,t=Math.atan2(s,r),u=Math.asin(g*h* | |
1764 q/s),v=Math.cos(u)*Math.cos(u),q=r-2*k*l/v,w=c/16*v*(4+c*(4-3*v)),n=m,m=f+(1-w)*c*Math.sin(u)*(t+w*s*(q+w*r*(-1+2*q*q)))}if(0==p)return NaN;d=v*(d*d-e*e)/(e*e);c=d/1024*(256+d*(-128+d*(74-47*d)));return(e*(1+d/16384*(4096+d*(-768+d*(320-175*d))))*(t-c*s*(q+c/4*(r*(-1+2*q*q)-c/6*q*(-3+4*s*s)*(-3+4*q*q))))).toFixed(3)/1E3}; | |
1765 OpenLayers.Util.destinationVincenty=function(a,b,c){var d=OpenLayers.Util,e=d.VincentyConstants,f=e.a,g=e.b,h=e.f,e=a.lon;a=a.lat;var k=d.rad(b);b=Math.sin(k);k=Math.cos(k);a=(1-h)*Math.tan(d.rad(a));var l=1/Math.sqrt(1+a*a),m=a*l,n=Math.atan2(a,k);a=l*b;for(var p=1-a*a,f=p*(f*f-g*g)/(g*g),q=1+f/16384*(4096+f*(-768+f*(320-175*f))),r=f/1024*(256+f*(-128+f*(74-47*f))),f=c/(g*q),s=2*Math.PI;1E-12<Math.abs(f-s);)var t=Math.cos(2*n+f),u=Math.sin(f),v=Math.cos(f),w=r*u*(t+r/4*(v*(-1+2*t*t)-r/6*t*(-3+4* | |
1766 u*u)*(-3+4*t*t))),s=f,f=c/(g*q)+w;c=m*u-l*v*k;g=Math.atan2(m*v+l*u*k,(1-h)*Math.sqrt(a*a+c*c));b=Math.atan2(u*b,l*v-m*u*k);k=h/16*p*(4+h*(4-3*p));t=b-(1-k)*h*a*(f+k*u*(t+k*v*(-1+2*t*t)));Math.atan2(a,-c);return new OpenLayers.LonLat(e+d.deg(t),d.deg(g))}; | |
1767 OpenLayers.Util.getParameters=function(a,b){b=b||{};a=null===a||void 0===a?window.location.href:a;var c="";if(OpenLayers.String.contains(a,"?"))var d=a.indexOf("?")+1,c=OpenLayers.String.contains(a,"#")?a.indexOf("#"):a.length,c=a.substring(d,c);for(var d={},c=c.split(/[&;]/),e=0,f=c.length;e<f;++e){var g=c[e].split("=");if(g[0]){var h=g[0];try{h=decodeURIComponent(h)}catch(k){h=unescape(h)}g=(g[1]||"").replace(/\+/g," ");try{g=decodeURIComponent(g)}catch(l){g=unescape(g)}!1!==b.splitArgs&&(g=g.split(",")); | |
1768 1==g.length&&(g=g[0]);d[h]=g}}return d};OpenLayers.Util.lastSeqID=0;OpenLayers.Util.createUniqueID=function(a){a=null==a?"id_":a.replace(OpenLayers.Util.dotless,"_");OpenLayers.Util.lastSeqID+=1;return a+OpenLayers.Util.lastSeqID};OpenLayers.INCHES_PER_UNIT={inches:1,ft:12,mi:63360,m:39.37,km:39370,dd:4374754,yd:36};OpenLayers.INCHES_PER_UNIT["in"]=OpenLayers.INCHES_PER_UNIT.inches;OpenLayers.INCHES_PER_UNIT.degrees=OpenLayers.INCHES_PER_UNIT.dd;OpenLayers.INCHES_PER_UNIT.nmi=1852*OpenLayers.INCHES_PER_UNIT.m; | |
1769 OpenLayers.METERS_PER_INCH=0.0254000508001016; | |
1770 OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{Inch:OpenLayers.INCHES_PER_UNIT.inches,Meter:1/OpenLayers.METERS_PER_INCH,Foot:0.3048006096012192/OpenLayers.METERS_PER_INCH,IFoot:0.3048/OpenLayers.METERS_PER_INCH,ClarkeFoot:0.3047972651151/OpenLayers.METERS_PER_INCH,SearsFoot:0.30479947153867626/OpenLayers.METERS_PER_INCH,GoldCoastFoot:0.3047997101815088/OpenLayers.METERS_PER_INCH,IInch:0.0254/OpenLayers.METERS_PER_INCH,MicroInch:2.54E-5/OpenLayers.METERS_PER_INCH,Mil:2.54E-8/OpenLayers.METERS_PER_INCH, | |
1771 Centimeter:0.01/OpenLayers.METERS_PER_INCH,Kilometer:1E3/OpenLayers.METERS_PER_INCH,Yard:0.9144018288036576/OpenLayers.METERS_PER_INCH,SearsYard:0.914398414616029/OpenLayers.METERS_PER_INCH,IndianYard:0.9143985307444408/OpenLayers.METERS_PER_INCH,IndianYd37:0.91439523/OpenLayers.METERS_PER_INCH,IndianYd62:0.9143988/OpenLayers.METERS_PER_INCH,IndianYd75:0.9143985/OpenLayers.METERS_PER_INCH,IndianFoot:0.30479951/OpenLayers.METERS_PER_INCH,IndianFt37:0.30479841/OpenLayers.METERS_PER_INCH,IndianFt62:0.3047996/ | |
1772 OpenLayers.METERS_PER_INCH,IndianFt75:0.3047995/OpenLayers.METERS_PER_INCH,Mile:1609.3472186944373/OpenLayers.METERS_PER_INCH,IYard:0.9144/OpenLayers.METERS_PER_INCH,IMile:1609.344/OpenLayers.METERS_PER_INCH,NautM:1852/OpenLayers.METERS_PER_INCH,"Lat-66":110943.31648893273/OpenLayers.METERS_PER_INCH,"Lat-83":110946.25736872235/OpenLayers.METERS_PER_INCH,Decimeter:0.1/OpenLayers.METERS_PER_INCH,Millimeter:0.001/OpenLayers.METERS_PER_INCH,Dekameter:10/OpenLayers.METERS_PER_INCH,Decameter:10/OpenLayers.METERS_PER_INCH, | |
1773 Hectometer:100/OpenLayers.METERS_PER_INCH,GermanMeter:1.0000135965/OpenLayers.METERS_PER_INCH,CaGrid:0.999738/OpenLayers.METERS_PER_INCH,ClarkeChain:20.1166194976/OpenLayers.METERS_PER_INCH,GunterChain:20.11684023368047/OpenLayers.METERS_PER_INCH,BenoitChain:20.116782494375872/OpenLayers.METERS_PER_INCH,SearsChain:20.11676512155/OpenLayers.METERS_PER_INCH,ClarkeLink:0.201166194976/OpenLayers.METERS_PER_INCH,GunterLink:0.2011684023368047/OpenLayers.METERS_PER_INCH,BenoitLink:0.20116782494375873/OpenLayers.METERS_PER_INCH, | |
1774 SearsLink:0.2011676512155/OpenLayers.METERS_PER_INCH,Rod:5.02921005842012/OpenLayers.METERS_PER_INCH,IntnlChain:20.1168/OpenLayers.METERS_PER_INCH,IntnlLink:0.201168/OpenLayers.METERS_PER_INCH,Perch:5.02921005842012/OpenLayers.METERS_PER_INCH,Pole:5.02921005842012/OpenLayers.METERS_PER_INCH,Furlong:201.1684023368046/OpenLayers.METERS_PER_INCH,Rood:3.778266898/OpenLayers.METERS_PER_INCH,CapeFoot:0.3047972615/OpenLayers.METERS_PER_INCH,Brealey:375/OpenLayers.METERS_PER_INCH,ModAmFt:0.304812252984506/ | |
1775 OpenLayers.METERS_PER_INCH,Fathom:1.8288/OpenLayers.METERS_PER_INCH,"NautM-UK":1853.184/OpenLayers.METERS_PER_INCH,"50kilometers":5E4/OpenLayers.METERS_PER_INCH,"150kilometers":15E4/OpenLayers.METERS_PER_INCH}); | |
1776 OpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT,{mm:OpenLayers.INCHES_PER_UNIT.Meter/1E3,cm:OpenLayers.INCHES_PER_UNIT.Meter/100,dm:100*OpenLayers.INCHES_PER_UNIT.Meter,km:1E3*OpenLayers.INCHES_PER_UNIT.Meter,kmi:OpenLayers.INCHES_PER_UNIT.nmi,fath:OpenLayers.INCHES_PER_UNIT.Fathom,ch:OpenLayers.INCHES_PER_UNIT.IntnlChain,link:OpenLayers.INCHES_PER_UNIT.IntnlLink,"us-in":OpenLayers.INCHES_PER_UNIT.inches,"us-ft":OpenLayers.INCHES_PER_UNIT.Foot,"us-yd":OpenLayers.INCHES_PER_UNIT.Yard,"us-ch":OpenLayers.INCHES_PER_UNIT.GunterChain, | |
1777 "us-mi":OpenLayers.INCHES_PER_UNIT.Mile,"ind-yd":OpenLayers.INCHES_PER_UNIT.IndianYd37,"ind-ft":OpenLayers.INCHES_PER_UNIT.IndianFt37,"ind-ch":20.11669506/OpenLayers.METERS_PER_INCH});OpenLayers.DOTS_PER_INCH=72;OpenLayers.Util.normalizeScale=function(a){return 1<a?1/a:a};OpenLayers.Util.getResolutionFromScale=function(a,b){var c;a&&(null==b&&(b="degrees"),c=1/(OpenLayers.Util.normalizeScale(a)*OpenLayers.INCHES_PER_UNIT[b]*OpenLayers.DOTS_PER_INCH));return c}; | |
1778 OpenLayers.Util.getScaleFromResolution=function(a,b){null==b&&(b="degrees");return a*OpenLayers.INCHES_PER_UNIT[b]*OpenLayers.DOTS_PER_INCH}; | |
1779 OpenLayers.Util.pagePosition=function(a){var b=[0,0],c=OpenLayers.Util.getViewportElement();if(!a||a==window||a==c)return b;var d=OpenLayers.IS_GECKO&&document.getBoxObjectFor&&"absolute"==OpenLayers.Element.getStyle(a,"position")&&(""==a.style.top||""==a.style.left),e=null;if(a.getBoundingClientRect)a=a.getBoundingClientRect(),e=window.pageYOffset||c.scrollTop,b[0]=a.left+(window.pageXOffset||c.scrollLeft),b[1]=a.top+e;else if(document.getBoxObjectFor&&!d)a=document.getBoxObjectFor(a),c=document.getBoxObjectFor(c), | |
1780 b[0]=a.screenX-c.screenX,b[1]=a.screenY-c.screenY;else{b[0]=a.offsetLeft;b[1]=a.offsetTop;e=a.offsetParent;if(e!=a)for(;e;)b[0]+=e.offsetLeft,b[1]+=e.offsetTop,e=e.offsetParent;c=OpenLayers.BROWSER_NAME;if("opera"==c||"safari"==c&&"absolute"==OpenLayers.Element.getStyle(a,"position"))b[1]-=document.body.offsetTop;for(e=a.offsetParent;e&&e!=document.body;){b[0]-=e.scrollLeft;if("opera"!=c||"TR"!=e.tagName)b[1]-=e.scrollTop;e=e.offsetParent}}return b}; | |
1781 OpenLayers.Util.getViewportElement=function(){var a=arguments.callee.viewportElement;void 0==a&&(a="msie"==OpenLayers.BROWSER_NAME&&"CSS1Compat"!=document.compatMode?document.body:document.documentElement,arguments.callee.viewportElement=a);return a}; | |
1782 OpenLayers.Util.isEquivalentUrl=function(a,b,c){c=c||{};OpenLayers.Util.applyDefaults(c,{ignoreCase:!0,ignorePort80:!0,ignoreHash:!0,splitArgs:!1});a=OpenLayers.Util.createUrlObject(a,c);b=OpenLayers.Util.createUrlObject(b,c);for(var d in a)if("args"!==d&&a[d]!=b[d])return!1;for(d in a.args){if(a.args[d]!=b.args[d])return!1;delete b.args[d]}for(d in b.args)return!1;return!0}; | |
1783 OpenLayers.Util.createUrlObject=function(a,b){b=b||{};if(!/^\w+:\/\//.test(a)){var c=window.location,d=c.port?":"+c.port:"",d=c.protocol+"//"+c.host.split(":").shift()+d;0===a.indexOf("/")?a=d+a:(c=c.pathname.split("/"),c.pop(),a=d+c.join("/")+"/"+a)}b.ignoreCase&&(a=a.toLowerCase());c=document.createElement("a");c.href=a;d={};d.host=c.host.split(":").shift();d.protocol=c.protocol;d.port=b.ignorePort80?"80"==c.port||"0"==c.port?"":c.port:""==c.port||"0"==c.port?"80":c.port;d.hash=b.ignoreHash||"#"=== | |
1784 c.hash?"":c.hash;var e=c.search;e||(e=a.indexOf("?"),e=-1!=e?a.substr(e):"");d.args=OpenLayers.Util.getParameters(e,{splitArgs:b.splitArgs});d.pathname="/"==c.pathname.charAt(0)?c.pathname:"/"+c.pathname;return d};OpenLayers.Util.removeTail=function(a){var b=null,b=a.indexOf("?"),c=a.indexOf("#");return b=-1==b?-1!=c?a.substr(0,c):a:-1!=c?a.substr(0,Math.min(b,c)):a.substr(0,b)};OpenLayers.IS_GECKO=function(){var a=navigator.userAgent.toLowerCase();return-1==a.indexOf("webkit")&&-1!=a.indexOf("gecko")}(); | |
1785 OpenLayers.CANVAS_SUPPORTED=function(){var a=document.createElement("canvas");return!(!a.getContext||!a.getContext("2d"))}();OpenLayers.BROWSER_NAME=function(){var a="",b=navigator.userAgent.toLowerCase();-1!=b.indexOf("opera")?a="opera":-1!=b.indexOf("msie")?a="msie":-1!=b.indexOf("safari")?a="safari":-1!=b.indexOf("mozilla")&&(a=-1!=b.indexOf("firefox")?"firefox":"mozilla");return a}();OpenLayers.Util.getBrowserName=function(){return OpenLayers.BROWSER_NAME}; | |
1786 OpenLayers.Util.getRenderedDimensions=function(a,b,c){var d,e,f=document.createElement("div");f.style.visibility="hidden";for(var g=c&&c.containerElement?c.containerElement:document.body,h=!1,k=null,l=g;l&&"body"!=l.tagName.toLowerCase();){var m=OpenLayers.Element.getStyle(l,"position");if("absolute"==m){h=!0;break}else if(m&&"static"!=m)break;l=l.parentNode}!h||0!==g.clientHeight&&0!==g.clientWidth||(k=document.createElement("div"),k.style.visibility="hidden",k.style.position="absolute",k.style.overflow= | |
1787 "visible",k.style.width=document.body.clientWidth+"px",k.style.height=document.body.clientHeight+"px",k.appendChild(f));f.style.position="absolute";b&&(b.w?(d=b.w,f.style.width=d+"px"):b.h&&(e=b.h,f.style.height=e+"px"));c&&c.displayClass&&(f.className=c.displayClass);b=document.createElement("div");b.innerHTML=a;b.style.overflow="visible";if(b.childNodes)for(a=0,c=b.childNodes.length;a<c;a++)b.childNodes[a].style&&(b.childNodes[a].style.overflow="visible");f.appendChild(b);k?g.appendChild(k):g.appendChild(f); | |
1788 d||(d=parseInt(b.scrollWidth),f.style.width=d+"px");e||(e=parseInt(b.scrollHeight));f.removeChild(b);k?(k.removeChild(f),g.removeChild(k)):g.removeChild(f);return new OpenLayers.Size(d,e)}; | |
1789 OpenLayers.Util.getScrollbarWidth=function(){var a=OpenLayers.Util._scrollbarWidth;if(null==a){var b=null,c=null,b=a=0,b=document.createElement("div");b.style.position="absolute";b.style.top="-1000px";b.style.left="-1000px";b.style.width="100px";b.style.height="50px";b.style.overflow="hidden";c=document.createElement("div");c.style.width="100%";c.style.height="200px";b.appendChild(c);document.body.appendChild(b);a=c.offsetWidth;b.style.overflow="scroll";b=c.offsetWidth;document.body.removeChild(document.body.lastChild); | |
1790 OpenLayers.Util._scrollbarWidth=a-b;a=OpenLayers.Util._scrollbarWidth}return a}; | |
1791 OpenLayers.Util.getFormattedLonLat=function(a,b,c){c||(c="dms");a=(a+540)%360-180;var d=Math.abs(a),e=Math.floor(d),f=d=(d-e)/(1/60),d=Math.floor(d),f=Math.round(10*((f-d)/(1/60))),f=f/10;60<=f&&(f-=60,d+=1,60<=d&&(d-=60,e+=1));10>e&&(e="0"+e);e+="\u00b0";0<=c.indexOf("dm")&&(10>d&&(d="0"+d),e+=d+"'",0<=c.indexOf("dms")&&(10>f&&(f="0"+f),e+=f+'"'));return e="lon"==b?e+(0>a?OpenLayers.i18n("W"):OpenLayers.i18n("E")):e+(0>a?OpenLayers.i18n("S"):OpenLayers.i18n("N"))};OpenLayers.Format=OpenLayers.Class({options:null,externalProjection:null,internalProjection:null,data:null,keepData:!1,initialize:function(a){OpenLayers.Util.extend(this,a);this.options=a},destroy:function(){},read:function(a){throw Error("Read not implemented.");},write:function(a){throw Error("Write not implemented.");},CLASS_NAME:"OpenLayers.Format"});OpenLayers.Format.CSWGetRecords=function(a){a=OpenLayers.Util.applyDefaults(a,OpenLayers.Format.CSWGetRecords.DEFAULTS);var b=OpenLayers.Format.CSWGetRecords["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported CSWGetRecords version: "+a.version;return new b(a)};OpenLayers.Format.CSWGetRecords.DEFAULTS={version:"2.0.2"};OpenLayers.Control=OpenLayers.Class({id:null,map:null,div:null,type:null,allowSelection:!1,displayClass:"",title:"",autoActivate:!1,active:null,handlerOptions:null,handler:null,eventListeners:null,events:null,initialize:function(a){this.displayClass=this.CLASS_NAME.replace("OpenLayers.","ol").replace(/\./g,"");OpenLayers.Util.extend(this,a);this.events=new OpenLayers.Events(this);if(this.eventListeners instanceof Object)this.events.on(this.eventListeners);null==this.id&&(this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+ | |
1792 "_"))},destroy:function(){this.events&&(this.eventListeners&&this.events.un(this.eventListeners),this.events.destroy(),this.events=null);this.eventListeners=null;this.handler&&(this.handler.destroy(),this.handler=null);if(this.handlers){for(var a in this.handlers)this.handlers.hasOwnProperty(a)&&"function"==typeof this.handlers[a].destroy&&this.handlers[a].destroy();this.handlers=null}this.map&&(this.map.removeControl(this),this.map=null);this.div=null},setMap:function(a){this.map=a;this.handler&& | |
1793 this.handler.setMap(a)},draw:function(a){null==this.div&&(this.div=OpenLayers.Util.createDiv(this.id),this.div.className=this.displayClass,this.allowSelection||(this.div.className+=" olControlNoSelect",this.div.setAttribute("unselectable","on",0),this.div.onselectstart=OpenLayers.Function.False),""!=this.title&&(this.div.title=this.title));null!=a&&(this.position=a.clone());this.moveTo(this.position);return this.div},moveTo:function(a){null!=a&&null!=this.div&&(this.div.style.left=a.x+"px",this.div.style.top= | |
1794 a.y+"px")},activate:function(){if(this.active)return!1;this.handler&&this.handler.activate();this.active=!0;this.map&&OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active");this.events.triggerEvent("activate");return!0},deactivate:function(){return this.active?(this.handler&&this.handler.deactivate(),this.active=!1,this.map&&OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass.replace(/ /g,"")+"Active"),this.events.triggerEvent("deactivate"), | |
1795 !0):!1},CLASS_NAME:"OpenLayers.Control"});OpenLayers.Control.TYPE_BUTTON=1;OpenLayers.Control.TYPE_TOGGLE=2;OpenLayers.Control.TYPE_TOOL=3;OpenLayers.Event={observers:!1,KEY_SPACE:32,KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,element:function(a){return a.target||a.srcElement},isSingleTouch:function(a){return a.touches&&1==a.touches.length},isMultiTouch:function(a){return a.touches&&1<a.touches.length},isLeftClick:function(a){return a.which&&1==a.which||a.button&&1==a.button},isRightClick:function(a){return a.which&&3==a.which||a.button&&2==a.button},stop:function(a, | |
1796 b){b||OpenLayers.Event.preventDefault(a);a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},findElement:function(a,b){for(var c=OpenLayers.Event.element(a);c.parentNode&&(!c.tagName||c.tagName.toUpperCase()!=b.toUpperCase());)c=c.parentNode;return c},observe:function(a,b,c,d){a=OpenLayers.Util.getElement(a);d=d||!1;"keypress"==b&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||a.attachEvent)&&(b="keydown"); | |
1797 this.observers||(this.observers={});if(!a._eventCacheID){var e="eventCacheID_";a.id&&(e=a.id+"_"+e);a._eventCacheID=OpenLayers.Util.createUniqueID(e)}e=a._eventCacheID;this.observers[e]||(this.observers[e]=[]);this.observers[e].push({element:a,name:b,observer:c,useCapture:d});a.addEventListener?a.addEventListener(b,c,d):a.attachEvent&&a.attachEvent("on"+b,c)},stopObservingElement:function(a){a=OpenLayers.Util.getElement(a)._eventCacheID;this._removeElementObservers(OpenLayers.Event.observers[a])}, | |
1798 _removeElementObservers:function(a){if(a)for(var b=a.length-1;0<=b;b--){var c=a[b];OpenLayers.Event.stopObserving.apply(this,[c.element,c.name,c.observer,c.useCapture])}},stopObserving:function(a,b,c,d){d=d||!1;a=OpenLayers.Util.getElement(a);var e=a._eventCacheID;"keypress"==b&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||a.detachEvent)&&(b="keydown");var f=!1,g=OpenLayers.Event.observers[e];if(g)for(var h=0;!f&&h<g.length;){var k=g[h];if(k.name==b&&k.observer==c&&k.useCapture==d){g.splice(h, | |
1799 1);0==g.length&&delete OpenLayers.Event.observers[e];f=!0;break}h++}f&&(a.removeEventListener?a.removeEventListener(b,c,d):a&&a.detachEvent&&a.detachEvent("on"+b,c));return f},unloadCache:function(){if(OpenLayers.Event&&OpenLayers.Event.observers){for(var a in OpenLayers.Event.observers)OpenLayers.Event._removeElementObservers.apply(this,[OpenLayers.Event.observers[a]]);OpenLayers.Event.observers=!1}},CLASS_NAME:"OpenLayers.Event"}; | |
1800 OpenLayers.Event.observe(window,"unload",OpenLayers.Event.unloadCache,!1); | |
1801 OpenLayers.Events=OpenLayers.Class({BROWSER_EVENTS:"mouseover mouseout mousedown mouseup mousemove click dblclick rightclick dblrightclick resize focus blur touchstart touchmove touchend keydown".split(" "),listeners:null,object:null,element:null,eventHandler:null,fallThrough:null,includeXY:!1,extensions:null,extensionCount:null,clearMouseListener:null,initialize:function(a,b,c,d,e){OpenLayers.Util.extend(this,e);this.object=a;this.fallThrough=d;this.listeners={};this.extensions={};this.extensionCount= | |
1802 {};this._msTouches=[];null!=b&&this.attachToElement(b)},destroy:function(){for(var a in this.extensions)"boolean"!==typeof this.extensions[a]&&this.extensions[a].destroy();this.extensions=null;this.element&&(OpenLayers.Event.stopObservingElement(this.element),this.element.hasScrollEvent&&OpenLayers.Event.stopObserving(window,"scroll",this.clearMouseListener));this.eventHandler=this.fallThrough=this.object=this.listeners=this.element=null},addEventType:function(a){},attachToElement:function(a){this.element? | |
1803 OpenLayers.Event.stopObservingElement(this.element):(this.eventHandler=OpenLayers.Function.bindAsEventListener(this.handleBrowserEvent,this),this.clearMouseListener=OpenLayers.Function.bind(this.clearMouseCache,this));this.element=a;for(var b=!!window.navigator.msMaxTouchPoints,c,d=0,e=this.BROWSER_EVENTS.length;d<e;d++)c=this.BROWSER_EVENTS[d],OpenLayers.Event.observe(a,c,this.eventHandler),b&&0===c.indexOf("touch")&&this.addMsTouchListener(a,c,this.eventHandler);OpenLayers.Event.observe(a,"dragstart", | |
1804 OpenLayers.Event.stop)},on:function(a){for(var b in a)"scope"!=b&&a.hasOwnProperty(b)&&this.register(b,a.scope,a[b])},register:function(a,b,c,d){a in OpenLayers.Events&&!this.extensions[a]&&(this.extensions[a]=new OpenLayers.Events[a](this));if(null!=c){null==b&&(b=this.object);var e=this.listeners[a];e||(e=[],this.listeners[a]=e,this.extensionCount[a]=0);b={obj:b,func:c};d?(e.splice(this.extensionCount[a],0,b),"object"===typeof d&&d.extension&&this.extensionCount[a]++):e.push(b)}},registerPriority:function(a, | |
1805 b,c){this.register(a,b,c,!0)},un:function(a){for(var b in a)"scope"!=b&&a.hasOwnProperty(b)&&this.unregister(b,a.scope,a[b])},unregister:function(a,b,c){null==b&&(b=this.object);a=this.listeners[a];if(null!=a)for(var d=0,e=a.length;d<e;d++)if(a[d].obj==b&&a[d].func==c){a.splice(d,1);break}},remove:function(a){null!=this.listeners[a]&&(this.listeners[a]=[])},triggerEvent:function(a,b){var c=this.listeners[a];if(c&&0!=c.length){null==b&&(b={});b.object=this.object;b.element=this.element;b.type||(b.type= | |
1806 a);for(var c=c.slice(),d,e=0,f=c.length;e<f&&(d=c[e],d=d.func.apply(d.obj,[b]),void 0==d||!1!=d);e++);this.fallThrough||OpenLayers.Event.stop(b,!0);return d}},handleBrowserEvent:function(a){var b=a.type,c=this.listeners[b];if(c&&0!=c.length){if((c=a.touches)&&c[0]){for(var d=0,e=0,f=c.length,g,h=0;h<f;++h)g=this.getTouchClientXY(c[h]),d+=g.clientX,e+=g.clientY;a.clientX=d/f;a.clientY=e/f}this.includeXY&&(a.xy=this.getMousePosition(a));this.triggerEvent(b,a)}},getTouchClientXY:function(a){var b=window.olMockWin|| | |
1807 window,c=b.pageXOffset,b=b.pageYOffset,d=a.clientX,e=a.clientY;if(0===a.pageY&&Math.floor(e)>Math.floor(a.pageY)||0===a.pageX&&Math.floor(d)>Math.floor(a.pageX))d-=c,e-=b;else if(e<a.pageY-b||d<a.pageX-c)d=a.pageX-c,e=a.pageY-b;a.olClientX=d;a.olClientY=e;return{clientX:d,clientY:e}},clearMouseCache:function(){this.element.scrolls=null;this.element.lefttop=null;this.element.offsets=null},getMousePosition:function(a){this.includeXY?this.element.hasScrollEvent||(OpenLayers.Event.observe(window,"scroll", | |
1808 this.clearMouseListener),this.element.hasScrollEvent=!0):this.clearMouseCache();if(!this.element.scrolls){var b=OpenLayers.Util.getViewportElement();this.element.scrolls=[window.pageXOffset||b.scrollLeft,window.pageYOffset||b.scrollTop]}this.element.lefttop||(this.element.lefttop=[document.documentElement.clientLeft||0,document.documentElement.clientTop||0]);this.element.offsets||(this.element.offsets=OpenLayers.Util.pagePosition(this.element));return new OpenLayers.Pixel(a.clientX+this.element.scrolls[0]- | |
1809 this.element.offsets[0]-this.element.lefttop[0],a.clientY+this.element.scrolls[1]-this.element.offsets[1]-this.element.lefttop[1])},addMsTouchListener:function(a,b,c){function d(a){c(OpenLayers.Util.applyDefaults({stopPropagation:function(){for(var a=e.length-1;0<=a;--a)e[a].stopPropagation()},preventDefault:function(){for(var a=e.length-1;0<=a;--a)e[a].preventDefault()},type:b},a))}var e=this._msTouches;switch(b){case "touchstart":return this.addMsTouchListenerStart(a,b,d);case "touchend":return this.addMsTouchListenerEnd(a, | |
1810 b,d);case "touchmove":return this.addMsTouchListenerMove(a,b,d);default:throw"Unknown touch event type";}},addMsTouchListenerStart:function(a,b,c){var d=this._msTouches;OpenLayers.Event.observe(a,"MSPointerDown",function(a){for(var b=!1,g=0,h=d.length;g<h;++g)if(d[g].pointerId==a.pointerId){b=!0;break}b||d.push(a);a.touches=d.slice();c(a)});OpenLayers.Event.observe(a,"MSPointerUp",function(a){for(var b=0,c=d.length;b<c;++b)if(d[b].pointerId==a.pointerId){d.splice(b,1);break}})},addMsTouchListenerMove:function(a, | |
1811 b,c){var d=this._msTouches;OpenLayers.Event.observe(a,"MSPointerMove",function(a){if(a.pointerType!=a.MSPOINTER_TYPE_MOUSE||0!=a.buttons)if(1!=d.length||d[0].pageX!=a.pageX||d[0].pageY!=a.pageY){for(var b=0,g=d.length;b<g;++b)if(d[b].pointerId==a.pointerId){d[b]=a;break}a.touches=d.slice();c(a)}})},addMsTouchListenerEnd:function(a,b,c){var d=this._msTouches;OpenLayers.Event.observe(a,"MSPointerUp",function(a){for(var b=0,g=d.length;b<g;++b)if(d[b].pointerId==a.pointerId){d.splice(b,1);break}a.touches= | |
1812 d.slice();c(a)})},CLASS_NAME:"OpenLayers.Events"});OpenLayers.Events.buttonclick=OpenLayers.Class({target:null,events:"mousedown mouseup click dblclick touchstart touchmove touchend keydown".split(" "),startRegEx:/^mousedown|touchstart$/,cancelRegEx:/^touchmove$/,completeRegEx:/^mouseup|touchend$/,initialize:function(a){this.target=a;for(a=this.events.length-1;0<=a;--a)this.target.register(this.events[a],this,this.buttonClick,{extension:!0})},destroy:function(){for(var a=this.events.length-1;0<=a;--a)this.target.unregister(this.events[a],this,this.buttonClick); | |
1813 delete this.target},getPressedButton:function(a){var b=3,c;do{if(OpenLayers.Element.hasClass(a,"olButton")){c=a;break}a=a.parentNode}while(0<--b&&a);return c},ignore:function(a){var b=3,c=!1;do{if("a"===a.nodeName.toLowerCase()){c=!0;break}a=a.parentNode}while(0<--b&&a);return c},buttonClick:function(a){var b=!0,c=OpenLayers.Event.element(a);if(c&&(OpenLayers.Event.isLeftClick(a)||!~a.type.indexOf("mouse")))if(c=this.getPressedButton(c)){if("keydown"===a.type)switch(a.keyCode){case OpenLayers.Event.KEY_RETURN:case OpenLayers.Event.KEY_SPACE:this.target.triggerEvent("buttonclick", | |
1814 {buttonElement:c}),OpenLayers.Event.stop(a),b=!1}else if(this.startEvt){if(this.completeRegEx.test(a.type)){var b=OpenLayers.Util.pagePosition(c),d=OpenLayers.Util.getViewportElement(),e=window.pageYOffset||d.scrollTop;b[0]-=window.pageXOffset||d.scrollLeft;b[1]-=e;this.target.triggerEvent("buttonclick",{buttonElement:c,buttonXY:{x:this.startEvt.clientX-b[0],y:this.startEvt.clientY-b[1]}})}this.cancelRegEx.test(a.type)&&delete this.startEvt;OpenLayers.Event.stop(a);b=!1}this.startRegEx.test(a.type)&& | |
1815 (this.startEvt=a,OpenLayers.Event.stop(a),b=!1)}else b=!this.ignore(OpenLayers.Event.element(a)),delete this.startEvt;return b}});OpenLayers.Util=OpenLayers.Util||{}; | |
1816 OpenLayers.Util.vendorPrefix=function(){function a(a){return a?a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}).replace(/^ms-/,"-ms-"):null}function b(a,b){if(void 0===g[b]){var c,e=0,f=d.length,p="undefined"!==typeof a.cssText;for(g[b]=null;e<f;e++)if((c=d[e])?(p||(c=c.toLowerCase()),c=c+b.charAt(0).toUpperCase()+b.slice(1)):c=b,void 0!==a[c]){g[b]=c;break}}return g[b]}function c(a){return b(e,a)}var d=["","O","ms","Moz","Webkit"],e=document.createElement("div").style,f={},g={};return{css:function(b){if(void 0=== | |
1817 f[b]){var d=b.replace(/(-[\s\S])/g,function(a){return a.charAt(1).toUpperCase()}),d=c(d);f[b]=a(d)}return f[b]},js:b,style:c,cssCache:f,jsCache:g}}();OpenLayers.Animation=function(a){var b=OpenLayers.Util.vendorPrefix.js(a,"requestAnimationFrame"),c=!!b,d=function(){var c=a[b]||function(b,c){a.setTimeout(b,16)};return function(b,d){c.apply(a,[b,d])}}(),e=0,f={};return{isNative:c,requestFrame:d,start:function(a,b,c){b=0<b?b:Number.POSITIVE_INFINITY;var l=++e,m=+new Date;f[l]=function(){f[l]&&+new Date-m<=b?(a(),f[l]&&d(f[l],c)):delete f[l]};d(f[l],c);return l},stop:function(a){delete f[a]}}}(window);OpenLayers.Tween=OpenLayers.Class({easing:null,begin:null,finish:null,duration:null,callbacks:null,time:null,minFrameRate:null,startTime:null,animationId:null,playing:!1,initialize:function(a){this.easing=a?a:OpenLayers.Easing.Expo.easeOut},start:function(a,b,c,d){this.playing=!0;this.begin=a;this.finish=b;this.duration=c;this.callbacks=d.callbacks;this.minFrameRate=d.minFrameRate||30;this.time=0;this.startTime=(new Date).getTime();OpenLayers.Animation.stop(this.animationId);this.animationId=null; | |
1818 this.callbacks&&this.callbacks.start&&this.callbacks.start.call(this,this.begin);this.animationId=OpenLayers.Animation.start(OpenLayers.Function.bind(this.play,this))},stop:function(){this.playing&&(this.callbacks&&this.callbacks.done&&this.callbacks.done.call(this,this.finish),OpenLayers.Animation.stop(this.animationId),this.animationId=null,this.playing=!1)},play:function(){var a={},b;for(b in this.begin){var c=this.begin[b],d=this.finish[b];if(null==c||null==d||isNaN(c)||isNaN(d))throw new TypeError("invalid value for Tween"); | |
1819 a[b]=this.easing.apply(this,[this.time,c,d-c,this.duration])}this.time++;this.callbacks&&this.callbacks.eachStep&&((new Date).getTime()-this.startTime)/this.time<=1E3/this.minFrameRate&&this.callbacks.eachStep.call(this,a);this.time>this.duration&&this.stop()},CLASS_NAME:"OpenLayers.Tween"});OpenLayers.Easing={CLASS_NAME:"OpenLayers.Easing"};OpenLayers.Easing.Linear={easeIn:function(a,b,c,d){return c*a/d+b},easeOut:function(a,b,c,d){return c*a/d+b},easeInOut:function(a,b,c,d){return c*a/d+b},CLASS_NAME:"OpenLayers.Easing.Linear"}; | |
1820 OpenLayers.Easing.Expo={easeIn:function(a,b,c,d){return 0==a?b:c*Math.pow(2,10*(a/d-1))+b},easeOut:function(a,b,c,d){return a==d?b+c:c*(-Math.pow(2,-10*a/d)+1)+b},easeInOut:function(a,b,c,d){return 0==a?b:a==d?b+c:1>(a/=d/2)?c/2*Math.pow(2,10*(a-1))+b:c/2*(-Math.pow(2,-10*--a)+2)+b},CLASS_NAME:"OpenLayers.Easing.Expo"}; | |
1821 OpenLayers.Easing.Quad={easeIn:function(a,b,c,d){return c*(a/=d)*a+b},easeOut:function(a,b,c,d){return-c*(a/=d)*(a-2)+b},easeInOut:function(a,b,c,d){return 1>(a/=d/2)?c/2*a*a+b:-c/2*(--a*(a-2)-1)+b},CLASS_NAME:"OpenLayers.Easing.Quad"};OpenLayers.Projection=OpenLayers.Class({proj:null,projCode:null,titleRegEx:/\+title=[^\+]*/,initialize:function(a,b){OpenLayers.Util.extend(this,b);this.projCode=a;"object"==typeof Proj4js&&(this.proj=new Proj4js.Proj(a))},getCode:function(){return this.proj?this.proj.srsCode:this.projCode},getUnits:function(){return this.proj?this.proj.units:null},toString:function(){return this.getCode()},equals:function(a){var b=!1;a&&(a instanceof OpenLayers.Projection||(a=new OpenLayers.Projection(a)),"object"== | |
1822 typeof Proj4js&&this.proj.defData&&a.proj.defData?b=this.proj.defData.replace(this.titleRegEx,"")==a.proj.defData.replace(this.titleRegEx,""):a.getCode&&(b=this.getCode(),a=a.getCode(),b=b==a||!!OpenLayers.Projection.transforms[b]&&OpenLayers.Projection.transforms[b][a]===OpenLayers.Projection.nullTransform));return b},destroy:function(){delete this.proj;delete this.projCode},CLASS_NAME:"OpenLayers.Projection"});OpenLayers.Projection.transforms={}; | |
1823 OpenLayers.Projection.defaults={"EPSG:4326":{units:"degrees",maxExtent:[-180,-90,180,90],yx:!0},"CRS:84":{units:"degrees",maxExtent:[-180,-90,180,90]},"EPSG:900913":{units:"m",maxExtent:[-2.003750834E7,-2.003750834E7,2.003750834E7,2.003750834E7]}}; | |
1824 OpenLayers.Projection.addTransform=function(a,b,c){if(c===OpenLayers.Projection.nullTransform){var d=OpenLayers.Projection.defaults[a];d&&!OpenLayers.Projection.defaults[b]&&(OpenLayers.Projection.defaults[b]=d)}OpenLayers.Projection.transforms[a]||(OpenLayers.Projection.transforms[a]={});OpenLayers.Projection.transforms[a][b]=c}; | |
1825 OpenLayers.Projection.transform=function(a,b,c){if(b&&c)if(b instanceof OpenLayers.Projection||(b=new OpenLayers.Projection(b)),c instanceof OpenLayers.Projection||(c=new OpenLayers.Projection(c)),b.proj&&c.proj)a=Proj4js.transform(b.proj,c.proj,a);else{b=b.getCode();c=c.getCode();var d=OpenLayers.Projection.transforms;if(d[b]&&d[b][c])d[b][c](a)}return a};OpenLayers.Projection.nullTransform=function(a){return a}; | |
1826 (function(){function a(a){a.x=180*a.x/d;a.y=180/Math.PI*(2*Math.atan(Math.exp(a.y/d*Math.PI))-Math.PI/2);return a}function b(a){a.x=a.x*d/180;var b=Math.log(Math.tan((90+a.y)*Math.PI/360))/Math.PI*d;a.y=Math.max(-2.003750834E7,Math.min(b,2.003750834E7));return a}function c(c,d){var e=OpenLayers.Projection.addTransform,f=OpenLayers.Projection.nullTransform,g,p,q,r,s;g=0;for(p=d.length;g<p;++g)for(q=d[g],e(c,q,b),e(q,c,a),s=g+1;s<p;++s)r=d[s],e(q,r,f),e(r,q,f)}var d=2.003750834E7,e=["EPSG:900913","EPSG:3857", | |
1827 "EPSG:102113","EPSG:102100"],f=["CRS:84","urn:ogc:def:crs:EPSG:6.6:4326","EPSG:4326"],g;for(g=e.length-1;0<=g;--g)c(e[g],f);for(g=f.length-1;0<=g;--g)c(f[g],e)})();OpenLayers.Map=OpenLayers.Class({Z_INDEX_BASE:{BaseLayer:100,Overlay:325,Feature:725,Popup:750,Control:1E3},id:null,fractionalZoom:!1,events:null,allOverlays:!1,div:null,dragging:!1,size:null,viewPortDiv:null,layerContainerOrigin:null,layerContainerDiv:null,layers:null,controls:null,popups:null,baseLayer:null,center:null,resolution:null,zoom:0,panRatio:1.5,options:null,tileSize:null,projection:"EPSG:4326",units:null,resolutions:null,maxResolution:null,minResolution:null,maxScale:null,minScale:null, | |
1828 maxExtent:null,minExtent:null,restrictedExtent:null,numZoomLevels:16,theme:null,displayProjection:null,fallThrough:!1,autoUpdateSize:!0,eventListeners:null,panTween:null,panMethod:OpenLayers.Easing.Expo.easeOut,panDuration:50,zoomTween:null,zoomMethod:OpenLayers.Easing.Quad.easeOut,zoomDuration:20,paddingForPopups:null,layerContainerOriginPx:null,minPx:null,maxPx:null,initialize:function(a,b){1===arguments.length&&"object"===typeof a&&(a=(b=a)&&b.div);this.tileSize=new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH, | |
1829 OpenLayers.Map.TILE_HEIGHT);this.paddingForPopups=new OpenLayers.Bounds(15,15,15,15);this.theme=OpenLayers._getScriptLocation()+"theme/default/style.css";this.options=OpenLayers.Util.extend({},b);OpenLayers.Util.extend(this,b);OpenLayers.Util.applyDefaults(this,OpenLayers.Projection.defaults[this.projection instanceof OpenLayers.Projection?this.projection.projCode:this.projection]);!this.maxExtent||this.maxExtent instanceof OpenLayers.Bounds||(this.maxExtent=new OpenLayers.Bounds(this.maxExtent)); | |
1830 !this.minExtent||this.minExtent instanceof OpenLayers.Bounds||(this.minExtent=new OpenLayers.Bounds(this.minExtent));!this.restrictedExtent||this.restrictedExtent instanceof OpenLayers.Bounds||(this.restrictedExtent=new OpenLayers.Bounds(this.restrictedExtent));!this.center||this.center instanceof OpenLayers.LonLat||(this.center=new OpenLayers.LonLat(this.center));this.layers=[];this.id=OpenLayers.Util.createUniqueID("OpenLayers.Map_");this.div=OpenLayers.Util.getElement(a);this.div||(this.div=document.createElement("div"), | |
1831 this.div.style.height="1px",this.div.style.width="1px");OpenLayers.Element.addClass(this.div,"olMap");var c=this.id+"_OpenLayers_ViewPort";this.viewPortDiv=OpenLayers.Util.createDiv(c,null,null,null,"relative",null,"hidden");this.viewPortDiv.style.width="100%";this.viewPortDiv.style.height="100%";this.viewPortDiv.className="olMapViewport";this.div.appendChild(this.viewPortDiv);this.events=new OpenLayers.Events(this,this.viewPortDiv,null,this.fallThrough,{includeXY:!0});OpenLayers.TileManager&&null!== | |
1832 this.tileManager&&(this.tileManager instanceof OpenLayers.TileManager||(this.tileManager=new OpenLayers.TileManager(this.tileManager)),this.tileManager.addMap(this));c=this.id+"_OpenLayers_Container";this.layerContainerDiv=OpenLayers.Util.createDiv(c);this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE.Popup-1;this.layerContainerOriginPx={x:0,y:0};this.applyTransform();this.viewPortDiv.appendChild(this.layerContainerDiv);this.updateSize();if(this.eventListeners instanceof Object)this.events.on(this.eventListeners); | |
1833 !0===this.autoUpdateSize&&(this.updateSizeDestroy=OpenLayers.Function.bind(this.updateSize,this),OpenLayers.Event.observe(window,"resize",this.updateSizeDestroy));if(this.theme){for(var c=!0,d=document.getElementsByTagName("link"),e=0,f=d.length;e<f;++e)if(OpenLayers.Util.isEquivalentUrl(d.item(e).href,this.theme)){c=!1;break}c&&(c=document.createElement("link"),c.setAttribute("rel","stylesheet"),c.setAttribute("type","text/css"),c.setAttribute("href",this.theme),document.getElementsByTagName("head")[0].appendChild(c))}null== | |
1834 this.controls&&(this.controls=[],null!=OpenLayers.Control&&(OpenLayers.Control.Navigation?this.controls.push(new OpenLayers.Control.Navigation):OpenLayers.Control.TouchNavigation&&this.controls.push(new OpenLayers.Control.TouchNavigation),OpenLayers.Control.Zoom?this.controls.push(new OpenLayers.Control.Zoom):OpenLayers.Control.PanZoom&&this.controls.push(new OpenLayers.Control.PanZoom),OpenLayers.Control.ArgParser&&this.controls.push(new OpenLayers.Control.ArgParser),OpenLayers.Control.Attribution&& | |
1835 this.controls.push(new OpenLayers.Control.Attribution)));e=0;for(f=this.controls.length;e<f;e++)this.addControlToMap(this.controls[e]);this.popups=[];this.unloadDestroy=OpenLayers.Function.bind(this.destroy,this);OpenLayers.Event.observe(window,"unload",this.unloadDestroy);b&&b.layers&&(delete this.center,delete this.zoom,this.addLayers(b.layers),b.center&&!this.getCenter()&&this.setCenter(b.center,b.zoom));this.panMethod&&(this.panTween=new OpenLayers.Tween(this.panMethod));this.zoomMethod&&this.applyTransform.transform&& | |
1836 (this.zoomTween=new OpenLayers.Tween(this.zoomMethod))},getViewport:function(){return this.viewPortDiv},render:function(a){this.div=OpenLayers.Util.getElement(a);OpenLayers.Element.addClass(this.div,"olMap");this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);this.div.appendChild(this.viewPortDiv);this.updateSize()},unloadDestroy:null,updateSizeDestroy:null,destroy:function(){if(!this.unloadDestroy)return!1;this.panTween&&(this.panTween.stop(),this.panTween=null);this.zoomTween&&(this.zoomTween.stop(), | |
1837 this.zoomTween=null);OpenLayers.Event.stopObserving(window,"unload",this.unloadDestroy);this.unloadDestroy=null;this.updateSizeDestroy&&OpenLayers.Event.stopObserving(window,"resize",this.updateSizeDestroy);this.paddingForPopups=null;if(null!=this.controls){for(var a=this.controls.length-1;0<=a;--a)this.controls[a].destroy();this.controls=null}if(null!=this.layers){for(a=this.layers.length-1;0<=a;--a)this.layers[a].destroy(!1);this.layers=null}this.viewPortDiv&&this.viewPortDiv.parentNode&&this.viewPortDiv.parentNode.removeChild(this.viewPortDiv); | |
1838 this.viewPortDiv=null;this.tileManager&&(this.tileManager.removeMap(this),this.tileManager=null);this.eventListeners&&(this.events.un(this.eventListeners),this.eventListeners=null);this.events.destroy();this.options=this.events=null},setOptions:function(a){var b=this.minPx&&a.restrictedExtent!=this.restrictedExtent;OpenLayers.Util.extend(this,a);b&&this.moveTo(this.getCachedCenter(),this.zoom,{forceZoomChange:!0})},getTileSize:function(){return this.tileSize},getBy:function(a,b,c){var d="function"== | |
1839 typeof c.test;return OpenLayers.Array.filter(this[a],function(a){return a[b]==c||d&&c.test(a[b])})},getLayersBy:function(a,b){return this.getBy("layers",a,b)},getLayersByName:function(a){return this.getLayersBy("name",a)},getLayersByClass:function(a){return this.getLayersBy("CLASS_NAME",a)},getControlsBy:function(a,b){return this.getBy("controls",a,b)},getControlsByClass:function(a){return this.getControlsBy("CLASS_NAME",a)},getLayer:function(a){for(var b=null,c=0,d=this.layers.length;c<d;c++){var e= | |
1840 this.layers[c];if(e.id==a){b=e;break}}return b},setLayerZIndex:function(a,b){a.setZIndex(this.Z_INDEX_BASE[a.isBaseLayer?"BaseLayer":"Overlay"]+5*b)},resetLayersZIndex:function(){for(var a=0,b=this.layers.length;a<b;a++)this.setLayerZIndex(this.layers[a],a)},addLayer:function(a){for(var b=0,c=this.layers.length;b<c;b++)if(this.layers[b]==a)return!1;if(!1===this.events.triggerEvent("preaddlayer",{layer:a}))return!1;this.allOverlays&&(a.isBaseLayer=!1);a.div.className="olLayerDiv";a.div.style.overflow= | |
1841 "";this.setLayerZIndex(a,this.layers.length);a.isFixed?this.viewPortDiv.appendChild(a.div):this.layerContainerDiv.appendChild(a.div);this.layers.push(a);a.setMap(this);a.isBaseLayer||this.allOverlays&&!this.baseLayer?null==this.baseLayer?this.setBaseLayer(a):a.setVisibility(!1):a.redraw();this.events.triggerEvent("addlayer",{layer:a});a.events.triggerEvent("added",{map:this,layer:a});a.afterAdd();return!0},addLayers:function(a){for(var b=0,c=a.length;b<c;b++)this.addLayer(a[b])},removeLayer:function(a, | |
1842 b){if(!1!==this.events.triggerEvent("preremovelayer",{layer:a})){null==b&&(b=!0);a.isFixed?this.viewPortDiv.removeChild(a.div):this.layerContainerDiv.removeChild(a.div);OpenLayers.Util.removeItem(this.layers,a);a.removeMap(this);a.map=null;if(this.baseLayer==a&&(this.baseLayer=null,b))for(var c=0,d=this.layers.length;c<d;c++){var e=this.layers[c];if(e.isBaseLayer||this.allOverlays){this.setBaseLayer(e);break}}this.resetLayersZIndex();this.events.triggerEvent("removelayer",{layer:a});a.events.triggerEvent("removed", | |
1843 {map:this,layer:a})}},getNumLayers:function(){return this.layers.length},getLayerIndex:function(a){return OpenLayers.Util.indexOf(this.layers,a)},setLayerIndex:function(a,b){var c=this.getLayerIndex(a);0>b?b=0:b>this.layers.length&&(b=this.layers.length);if(c!=b){this.layers.splice(c,1);this.layers.splice(b,0,a);for(var c=0,d=this.layers.length;c<d;c++)this.setLayerZIndex(this.layers[c],c);this.events.triggerEvent("changelayer",{layer:a,property:"order"});this.allOverlays&&(0===b?this.setBaseLayer(a): | |
1844 this.baseLayer!==this.layers[0]&&this.setBaseLayer(this.layers[0]))}},raiseLayer:function(a,b){var c=this.getLayerIndex(a)+b;this.setLayerIndex(a,c)},setBaseLayer:function(a){if(a!=this.baseLayer&&-1!=OpenLayers.Util.indexOf(this.layers,a)){var b=this.getCachedCenter(),c=OpenLayers.Util.getResolutionFromScale(this.getScale(),a.units);null==this.baseLayer||this.allOverlays||this.baseLayer.setVisibility(!1);this.baseLayer=a;if(!this.allOverlays||this.baseLayer.visibility)this.baseLayer.setVisibility(!0), | |
1845 !1===this.baseLayer.inRange&&this.baseLayer.redraw();null!=b&&(a=this.getZoomForResolution(c||this.resolution,!0),this.setCenter(b,a,!1,!0));this.events.triggerEvent("changebaselayer",{layer:this.baseLayer})}},addControl:function(a,b){this.controls.push(a);this.addControlToMap(a,b)},addControls:function(a,b){for(var c=1===arguments.length?[]:b,d=0,e=a.length;d<e;d++)this.addControl(a[d],c[d]?c[d]:null)},addControlToMap:function(a,b){a.outsideViewport=null!=a.div;this.displayProjection&&!a.displayProjection&& | |
1846 (a.displayProjection=this.displayProjection);a.setMap(this);var c=a.draw(b);c&&!a.outsideViewport&&(c.style.zIndex=this.Z_INDEX_BASE.Control+this.controls.length,this.viewPortDiv.appendChild(c));a.autoActivate&&a.activate()},getControl:function(a){for(var b=null,c=0,d=this.controls.length;c<d;c++){var e=this.controls[c];if(e.id==a){b=e;break}}return b},removeControl:function(a){a&&a==this.getControl(a.id)&&(a.div&&a.div.parentNode==this.viewPortDiv&&this.viewPortDiv.removeChild(a.div),OpenLayers.Util.removeItem(this.controls, | |
1847 a))},addPopup:function(a,b){if(b)for(var c=this.popups.length-1;0<=c;--c)this.removePopup(this.popups[c]);a.map=this;this.popups.push(a);if(c=a.draw())c.style.zIndex=this.Z_INDEX_BASE.Popup+this.popups.length,this.layerContainerDiv.appendChild(c)},removePopup:function(a){OpenLayers.Util.removeItem(this.popups,a);if(a.div)try{this.layerContainerDiv.removeChild(a.div)}catch(b){}a.map=null},getSize:function(){var a=null;null!=this.size&&(a=this.size.clone());return a},updateSize:function(){var a=this.getCurrentSize(); | |
1848 if(a&&!isNaN(a.h)&&!isNaN(a.w)){this.events.clearMouseCache();var b=this.getSize();null==b&&(this.size=b=a);if(!a.equals(b)){this.size=a;a=0;for(b=this.layers.length;a<b;a++)this.layers[a].onMapResize();a=this.getCachedCenter();null!=this.baseLayer&&null!=a&&(b=this.getZoom(),this.zoom=null,this.setCenter(a,b))}}this.events.triggerEvent("updatesize")},getCurrentSize:function(){var a=new OpenLayers.Size(this.div.clientWidth,this.div.clientHeight);if(0==a.w&&0==a.h||isNaN(a.w)&&isNaN(a.h))a.w=this.div.offsetWidth, | |
1849 a.h=this.div.offsetHeight;if(0==a.w&&0==a.h||isNaN(a.w)&&isNaN(a.h))a.w=parseInt(this.div.style.width),a.h=parseInt(this.div.style.height);return a},calculateBounds:function(a,b){var c=null;null==a&&(a=this.getCachedCenter());null==b&&(b=this.getResolution());if(null!=a&&null!=b)var c=this.size.w*b/2,d=this.size.h*b/2,c=new OpenLayers.Bounds(a.lon-c,a.lat-d,a.lon+c,a.lat+d);return c},getCenter:function(){var a=null,b=this.getCachedCenter();b&&(a=b.clone());return a},getCachedCenter:function(){!this.center&& | |
1850 this.size&&(this.center=this.getLonLatFromViewPortPx({x:this.size.w/2,y:this.size.h/2}));return this.center},getZoom:function(){return this.zoom},pan:function(a,b,c){c=OpenLayers.Util.applyDefaults(c,{animate:!0,dragging:!1});if(c.dragging)0==a&&0==b||this.moveByPx(a,b);else{var d=this.getViewPortPxFromLonLat(this.getCachedCenter());a=d.add(a,b);if(this.dragging||!a.equals(d))d=this.getLonLatFromViewPortPx(a),c.animate?this.panTo(d):(this.moveTo(d),this.dragging&&(this.dragging=!1,this.events.triggerEvent("moveend")))}}, | |
1851 panTo:function(a){if(this.panTween&&this.getExtent().scale(this.panRatio).containsLonLat(a)){var b=this.getCachedCenter();if(!a.equals(b)){var b=this.getPixelFromLonLat(b),c=this.getPixelFromLonLat(a),d=0,e=0;this.panTween.start({x:0,y:0},{x:c.x-b.x,y:c.y-b.y},this.panDuration,{callbacks:{eachStep:OpenLayers.Function.bind(function(a){this.moveByPx(a.x-d,a.y-e);d=Math.round(a.x);e=Math.round(a.y)},this),done:OpenLayers.Function.bind(function(b){this.moveTo(a);this.dragging=!1;this.events.triggerEvent("moveend")}, | |
1852 this)}})}}else this.setCenter(a)},setCenter:function(a,b,c,d){this.panTween&&this.panTween.stop();this.zoomTween&&this.zoomTween.stop();this.moveTo(a,b,{dragging:c,forceZoomChange:d})},moveByPx:function(a,b){var c=this.size.w/2,d=this.size.h/2,e=c+a,f=d+b,g=this.baseLayer.wrapDateLine,h=0,k=0;this.restrictedExtent&&(h=c,k=d,g=!1);a=g||e<=this.maxPx.x-h&&e>=this.minPx.x+h?Math.round(a):0;b=f<=this.maxPx.y-k&&f>=this.minPx.y+k?Math.round(b):0;if(a||b){this.dragging||(this.dragging=!0,this.events.triggerEvent("movestart")); | |
1853 this.center=null;a&&(this.layerContainerOriginPx.x-=a,this.minPx.x-=a,this.maxPx.x-=a);b&&(this.layerContainerOriginPx.y-=b,this.minPx.y-=b,this.maxPx.y-=b);this.applyTransform();d=0;for(e=this.layers.length;d<e;++d)c=this.layers[d],c.visibility&&(c===this.baseLayer||c.inRange)&&(c.moveByPx(a,b),c.events.triggerEvent("move"));this.events.triggerEvent("move")}},adjustZoom:function(a){if(this.baseLayer&&this.baseLayer.wrapDateLine){var b=this.baseLayer.resolutions,c=this.getMaxExtent().getWidth()/this.size.w; | |
1854 if(this.getResolutionForZoom(a)>c)if(this.fractionalZoom)a=this.getZoomForResolution(c);else for(var d=a|0,e=b.length;d<e;++d)if(b[d]<=c){a=d;break}}return a},getMinZoom:function(){return this.adjustZoom(0)},moveTo:function(a,b,c){null==a||a instanceof OpenLayers.LonLat||(a=new OpenLayers.LonLat(a));c||(c={});null!=b&&(b=parseFloat(b),this.fractionalZoom||(b=Math.round(b)));var d=b;b=this.adjustZoom(b);b!==d&&(a=this.getCenter());var d=c.dragging||this.dragging,e=c.forceZoomChange;this.getCachedCenter()|| | |
1855 this.isValidLonLat(a)||(a=this.maxExtent.getCenterLonLat(),this.center=a.clone());if(null!=this.restrictedExtent){null==a&&(a=this.center);null==b&&(b=this.getZoom());var f=this.getResolutionForZoom(b),f=this.calculateBounds(a,f);if(!this.restrictedExtent.containsBounds(f)){var g=this.restrictedExtent.getCenterLonLat();f.getWidth()>this.restrictedExtent.getWidth()?a=new OpenLayers.LonLat(g.lon,a.lat):f.left<this.restrictedExtent.left?a=a.add(this.restrictedExtent.left-f.left,0):f.right>this.restrictedExtent.right&& | |
1856 (a=a.add(this.restrictedExtent.right-f.right,0));f.getHeight()>this.restrictedExtent.getHeight()?a=new OpenLayers.LonLat(a.lon,g.lat):f.bottom<this.restrictedExtent.bottom?a=a.add(0,this.restrictedExtent.bottom-f.bottom):f.top>this.restrictedExtent.top&&(a=a.add(0,this.restrictedExtent.top-f.top))}}e=e||this.isValidZoomLevel(b)&&b!=this.getZoom();f=this.isValidLonLat(a)&&!a.equals(this.center);if(e||f||d){d||this.events.triggerEvent("movestart",{zoomChanged:e});f&&(!e&&this.center&&this.centerLayerContainer(a), | |
1857 this.center=a.clone());a=e?this.getResolutionForZoom(b):this.getResolution();if(e||null==this.layerContainerOrigin){this.layerContainerOrigin=this.getCachedCenter();this.layerContainerOriginPx.x=0;this.layerContainerOriginPx.y=0;this.applyTransform();var f=this.getMaxExtent({restricted:!0}),h=f.getCenterLonLat(),g=this.center.lon-h.lon,h=h.lat-this.center.lat,k=Math.round(f.getWidth()/a),l=Math.round(f.getHeight()/a);this.minPx={x:(this.size.w-k)/2-g/a,y:(this.size.h-l)/2-h/a};this.maxPx={x:this.minPx.x+ | |
1858 Math.round(f.getWidth()/a),y:this.minPx.y+Math.round(f.getHeight()/a)}}e&&(this.zoom=b,this.resolution=a);a=this.getExtent();this.baseLayer.visibility&&(this.baseLayer.moveTo(a,e,c.dragging),c.dragging||this.baseLayer.events.triggerEvent("moveend",{zoomChanged:e}));a=this.baseLayer.getExtent();for(b=this.layers.length-1;0<=b;--b)f=this.layers[b],f===this.baseLayer||f.isBaseLayer||(g=f.calculateInRange(),f.inRange!=g&&((f.inRange=g)||f.display(!1),this.events.triggerEvent("changelayer",{layer:f,property:"visibility"})), | |
1859 g&&f.visibility&&(f.moveTo(a,e,c.dragging),c.dragging||f.events.triggerEvent("moveend",{zoomChanged:e})));this.events.triggerEvent("move");d||this.events.triggerEvent("moveend");if(e){b=0;for(c=this.popups.length;b<c;b++)this.popups[b].updatePosition();this.events.triggerEvent("zoomend")}}},centerLayerContainer:function(a){var b=this.getViewPortPxFromLonLat(this.layerContainerOrigin),c=this.getViewPortPxFromLonLat(a);if(null!=b&&null!=c){var d=this.layerContainerOriginPx.x;a=this.layerContainerOriginPx.y; | |
1860 var e=Math.round(b.x-c.x),b=Math.round(b.y-c.y);this.applyTransform(this.layerContainerOriginPx.x=e,this.layerContainerOriginPx.y=b);d-=e;a-=b;this.minPx.x-=d;this.maxPx.x-=d;this.minPx.y-=a;this.maxPx.y-=a}},isValidZoomLevel:function(a){return null!=a&&0<=a&&a<this.getNumZoomLevels()},isValidLonLat:function(a){var b=!1;null!=a&&(b=this.getMaxExtent(),b=b.containsLonLat(a,{worldBounds:this.baseLayer.wrapDateLine&&b}));return b},getProjection:function(){var a=this.getProjectionObject();return a?a.getCode(): | |
1861 null},getProjectionObject:function(){var a=null;null!=this.baseLayer&&(a=this.baseLayer.projection);return a},getMaxResolution:function(){var a=null;null!=this.baseLayer&&(a=this.baseLayer.maxResolution);return a},getMaxExtent:function(a){var b=null;a&&a.restricted&&this.restrictedExtent?b=this.restrictedExtent:null!=this.baseLayer&&(b=this.baseLayer.maxExtent);return b},getNumZoomLevels:function(){var a=null;null!=this.baseLayer&&(a=this.baseLayer.numZoomLevels);return a},getExtent:function(){var a= | |
1862 null;null!=this.baseLayer&&(a=this.baseLayer.getExtent());return a},getResolution:function(){var a=null;null!=this.baseLayer?a=this.baseLayer.getResolution():!0===this.allOverlays&&0<this.layers.length&&(a=this.layers[0].getResolution());return a},getUnits:function(){var a=null;null!=this.baseLayer&&(a=this.baseLayer.units);return a},getScale:function(){var a=null;null!=this.baseLayer&&(a=this.getResolution(),a=OpenLayers.Util.getScaleFromResolution(a,this.baseLayer.units));return a},getZoomForExtent:function(a, | |
1863 b){var c=null;null!=this.baseLayer&&(c=this.baseLayer.getZoomForExtent(a,b));return c},getResolutionForZoom:function(a){var b=null;this.baseLayer&&(b=this.baseLayer.getResolutionForZoom(a));return b},getZoomForResolution:function(a,b){var c=null;null!=this.baseLayer&&(c=this.baseLayer.getZoomForResolution(a,b));return c},zoomTo:function(a,b){var c=this;if(c.isValidZoomLevel(a))if(c.baseLayer.wrapDateLine&&(a=c.adjustZoom(a)),c.zoomTween){var d=c.getResolution(),e=c.getResolutionForZoom(a),f={scale:1}, | |
1864 d={scale:d/e};c.zoomTween.playing&&c.zoomTween.duration<3*c.zoomDuration?c.zoomTween.finish={scale:c.zoomTween.finish.scale*d.scale}:(b||(e=c.getSize(),b={x:e.w/2,y:e.h/2}),c.zoomTween.start(f,d,c.zoomDuration,{minFrameRate:50,callbacks:{eachStep:function(a){var d=c.layerContainerOriginPx;a=a.scale;c.applyTransform(d.x+((a-1)*(d.x-b.x)|0),d.y+((a-1)*(d.y-b.y)|0),a)},done:function(a){c.applyTransform();a=c.getResolution()/a.scale;var d=c.getZoomForResolution(a,!0);c.moveTo(c.getZoomTargetCenter(b, | |
1865 a),d,!0)}}}))}else f=b?c.getZoomTargetCenter(b,c.getResolutionForZoom(a)):null,c.setCenter(f,a)},zoomIn:function(){this.zoomTo(this.getZoom()+1)},zoomOut:function(){this.zoomTo(this.getZoom()-1)},zoomToExtent:function(a,b){a instanceof OpenLayers.Bounds||(a=new OpenLayers.Bounds(a));var c=a.getCenterLonLat();if(this.baseLayer.wrapDateLine){c=this.getMaxExtent();for(a=a.clone();a.right<a.left;)a.right+=c.getWidth();c=a.getCenterLonLat().wrapDateLine(c)}this.setCenter(c,this.getZoomForExtent(a,b))}, | |
1866 zoomToMaxExtent:function(a){a=this.getMaxExtent({restricted:a?a.restricted:!0});this.zoomToExtent(a)},zoomToScale:function(a,b){var c=OpenLayers.Util.getResolutionFromScale(a,this.baseLayer.units),d=this.size.w*c/2,c=this.size.h*c/2,e=this.getCachedCenter(),d=new OpenLayers.Bounds(e.lon-d,e.lat-c,e.lon+d,e.lat+c);this.zoomToExtent(d,b)},getLonLatFromViewPortPx:function(a){var b=null;null!=this.baseLayer&&(b=this.baseLayer.getLonLatFromViewPortPx(a));return b},getViewPortPxFromLonLat:function(a){var b= | |
1867 null;null!=this.baseLayer&&(b=this.baseLayer.getViewPortPxFromLonLat(a));return b},getZoomTargetCenter:function(a,b){var c=null,d=this.getSize(),e=d.w/2-a.x,d=a.y-d.h/2,f=this.getLonLatFromPixel(a);f&&(c=new OpenLayers.LonLat(f.lon+e*b,f.lat+d*b));return c},getLonLatFromPixel:function(a){return this.getLonLatFromViewPortPx(a)},getPixelFromLonLat:function(a){a=this.getViewPortPxFromLonLat(a);a.x=Math.round(a.x);a.y=Math.round(a.y);return a},getGeodesicPixelSize:function(a){var b=a?this.getLonLatFromPixel(a): | |
1868 this.getCachedCenter()||new OpenLayers.LonLat(0,0),c=this.getResolution();a=b.add(-c/2,0);var d=b.add(c/2,0),e=b.add(0,-c/2),b=b.add(0,c/2),c=new OpenLayers.Projection("EPSG:4326"),f=this.getProjectionObject()||c;f.equals(c)||(a.transform(f,c),d.transform(f,c),e.transform(f,c),b.transform(f,c));return new OpenLayers.Size(OpenLayers.Util.distVincenty(a,d),OpenLayers.Util.distVincenty(e,b))},getViewPortPxFromLayerPx:function(a){var b=null;null!=a&&(b=a.add(this.layerContainerOriginPx.x,this.layerContainerOriginPx.y)); | |
1869 return b},getLayerPxFromViewPortPx:function(a){var b=null;null!=a&&(b=a.add(-this.layerContainerOriginPx.x,-this.layerContainerOriginPx.y),isNaN(b.x)||isNaN(b.y))&&(b=null);return b},getLonLatFromLayerPx:function(a){a=this.getViewPortPxFromLayerPx(a);return this.getLonLatFromViewPortPx(a)},getLayerPxFromLonLat:function(a){a=this.getPixelFromLonLat(a);return this.getLayerPxFromViewPortPx(a)},applyTransform:function(a,b,c){c=c||1;var d=this.layerContainerOriginPx,e=1!==c;a=a||d.x;b=b||d.y;var f=this.layerContainerDiv.style, | |
1870 g=this.applyTransform.transform,h=this.applyTransform.template;if(void 0===g&&(g=OpenLayers.Util.vendorPrefix.style("transform"),this.applyTransform.transform=g)){var k=OpenLayers.Element.getStyle(this.viewPortDiv,OpenLayers.Util.vendorPrefix.css("transform"));k&&"none"===k||(h=["translate3d(",",0) ","scale3d(",",1)"],f[g]=[h[0],"0,0",h[1]].join(""));h&&~f[g].indexOf(h[0])||(h=["translate(",") ","scale(",")"]);this.applyTransform.template=h}null===g||"translate3d("!==h[0]&&!0!==e?(f.left=a+"px",f.top= | |
1871 b+"px",null!==g&&(f[g]="")):(!0===e&&"translate("===h[0]&&(a-=d.x,b-=d.y,f.left=d.x+"px",f.top=d.y+"px"),f[g]=[h[0],a,"px,",b,"px",h[1],h[2],c,",",c,h[3]].join(""))},CLASS_NAME:"OpenLayers.Map"});OpenLayers.Map.TILE_WIDTH=256;OpenLayers.Map.TILE_HEIGHT=256;OpenLayers.Handler=OpenLayers.Class({id:null,control:null,map:null,keyMask:null,active:!1,evt:null,touch:!1,initialize:function(a,b,c){OpenLayers.Util.extend(this,c);this.control=a;this.callbacks=b;(a=this.map||a.map)&&this.setMap(a);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_")},setMap:function(a){this.map=a},checkModifiers:function(a){return null==this.keyMask?!0:((a.shiftKey?OpenLayers.Handler.MOD_SHIFT:0)|(a.ctrlKey?OpenLayers.Handler.MOD_CTRL:0)|(a.altKey?OpenLayers.Handler.MOD_ALT: | |
1872 0)|(a.metaKey?OpenLayers.Handler.MOD_META:0))==this.keyMask},activate:function(){if(this.active)return!1;for(var a=OpenLayers.Events.prototype.BROWSER_EVENTS,b=0,c=a.length;b<c;b++)this[a[b]]&&this.register(a[b],this[a[b]]);return this.active=!0},deactivate:function(){if(!this.active)return!1;for(var a=OpenLayers.Events.prototype.BROWSER_EVENTS,b=0,c=a.length;b<c;b++)this[a[b]]&&this.unregister(a[b],this[a[b]]);this.active=this.touch=!1;return!0},startTouch:function(){if(!this.touch){this.touch=!0; | |
1873 for(var a="mousedown mouseup mousemove click dblclick mouseout".split(" "),b=0,c=a.length;b<c;b++)this[a[b]]&&this.unregister(a[b],this[a[b]])}},callback:function(a,b){a&&this.callbacks[a]&&this.callbacks[a].apply(this.control,b)},register:function(a,b){this.map.events.registerPriority(a,this,b);this.map.events.registerPriority(a,this,this.setEvent)},unregister:function(a,b){this.map.events.unregister(a,this,b);this.map.events.unregister(a,this,this.setEvent)},setEvent:function(a){this.evt=a;return!0}, | |
1874 destroy:function(){this.deactivate();this.control=this.map=null},CLASS_NAME:"OpenLayers.Handler"});OpenLayers.Handler.MOD_NONE=0;OpenLayers.Handler.MOD_SHIFT=1;OpenLayers.Handler.MOD_CTRL=2;OpenLayers.Handler.MOD_ALT=4;OpenLayers.Handler.MOD_META=8;OpenLayers.Handler.Click=OpenLayers.Class(OpenLayers.Handler,{delay:300,single:!0,"double":!1,pixelTolerance:0,dblclickTolerance:13,stopSingle:!1,stopDouble:!1,timerId:null,down:null,last:null,first:null,rightclickTimerId:null,touchstart:function(a){this.startTouch();this.down=this.getEventInfo(a);this.last=this.getEventInfo(a);return!0},touchmove:function(a){this.last=this.getEventInfo(a);return!0},touchend:function(a){this.down&&(a.xy=this.last.xy,a.lastTouches=this.last.touches,this.handleSingle(a), | |
1875 this.down=null);return!0},mousedown:function(a){this.down=this.getEventInfo(a);this.last=this.getEventInfo(a);return!0},mouseup:function(a){var b=!0;this.checkModifiers(a)&&(this.control.handleRightClicks&&OpenLayers.Event.isRightClick(a))&&(b=this.rightclick(a));return b},rightclick:function(a){if(this.passesTolerance(a)){if(null!=this.rightclickTimerId)return this.clearTimer(),this.callback("dblrightclick",[a]),!this.stopDouble;a=this["double"]?OpenLayers.Util.extend({},a):this.callback("rightclick", | |
1876 [a]);a=OpenLayers.Function.bind(this.delayedRightCall,this,a);this.rightclickTimerId=window.setTimeout(a,this.delay)}return!this.stopSingle},delayedRightCall:function(a){this.rightclickTimerId=null;a&&this.callback("rightclick",[a])},click:function(a){this.last||(this.last=this.getEventInfo(a));this.handleSingle(a);return!this.stopSingle},dblclick:function(a){this.handleDouble(a);return!this.stopDouble},handleDouble:function(a){this.passesDblclickTolerance(a)&&(this["double"]&&this.callback("dblclick", | |
1877 [a]),this.clearTimer())},handleSingle:function(a){this.passesTolerance(a)&&(null!=this.timerId?(this.last.touches&&1===this.last.touches.length&&(this["double"]&&OpenLayers.Event.preventDefault(a),this.handleDouble(a)),this.last.touches&&2===this.last.touches.length||this.clearTimer()):(this.first=this.getEventInfo(a),a=this.single?OpenLayers.Util.extend({},a):null,this.queuePotentialClick(a)))},queuePotentialClick:function(a){this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall, | |
1878 this,a),this.delay)},passesTolerance:function(a){var b=!0;if(null!=this.pixelTolerance&&this.down&&this.down.xy&&(b=this.pixelTolerance>=this.down.xy.distanceTo(a.xy))&&this.touch&&this.down.touches.length===this.last.touches.length){a=0;for(var c=this.down.touches.length;a<c;++a)if(this.getTouchDistance(this.down.touches[a],this.last.touches[a])>this.pixelTolerance){b=!1;break}}return b},getTouchDistance:function(a,b){return Math.sqrt(Math.pow(a.clientX-b.clientX,2)+Math.pow(a.clientY-b.clientY, | |
1879 2))},passesDblclickTolerance:function(a){a=!0;this.down&&this.first&&(a=this.down.xy.distanceTo(this.first.xy)<=this.dblclickTolerance);return a},clearTimer:function(){null!=this.timerId&&(window.clearTimeout(this.timerId),this.timerId=null);null!=this.rightclickTimerId&&(window.clearTimeout(this.rightclickTimerId),this.rightclickTimerId=null)},delayedCall:function(a){this.timerId=null;a&&this.callback("click",[a])},getEventInfo:function(a){var b;if(a.touches){var c=a.touches.length;b=Array(c);for(var d, | |
1880 e=0;e<c;e++)d=a.touches[e],b[e]={clientX:d.olClientX,clientY:d.olClientY}}return{xy:a.xy,touches:b}},deactivate:function(){var a=!1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.clearTimer(),this.last=this.first=this.down=null,a=!0);return a},CLASS_NAME:"OpenLayers.Handler.Click"});OpenLayers.Handler.Drag=OpenLayers.Class(OpenLayers.Handler,{started:!1,stopDown:!0,dragging:!1,last:null,start:null,lastMoveEvt:null,oldOnselectstart:null,interval:0,timeoutId:null,documentDrag:!1,documentEvents:null,initialize:function(a,b,c){OpenLayers.Handler.prototype.initialize.apply(this,arguments);if(!0===this.documentDrag){var d=this;this._docMove=function(a){d.mousemove({xy:{x:a.clientX,y:a.clientY},element:document})};this._docUp=function(a){d.mouseup({xy:{x:a.clientX,y:a.clientY}})}}}, | |
1881 dragstart:function(a){var b=!0;this.dragging=!1;this.checkModifiers(a)&&(OpenLayers.Event.isLeftClick(a)||OpenLayers.Event.isSingleTouch(a))?(this.started=!0,this.last=this.start=a.xy,OpenLayers.Element.addClass(this.map.viewPortDiv,"olDragDown"),this.down(a),this.callback("down",[a.xy]),OpenLayers.Event.preventDefault(a),this.oldOnselectstart||(this.oldOnselectstart=document.onselectstart?document.onselectstart:OpenLayers.Function.True),document.onselectstart=OpenLayers.Function.False,b=!this.stopDown): | |
1882 (this.started=!1,this.last=this.start=null);return b},dragmove:function(a){this.lastMoveEvt=a;!this.started||(this.timeoutId||a.xy.x==this.last.x&&a.xy.y==this.last.y)||(!0===this.documentDrag&&this.documentEvents&&(a.element===document?(this.adjustXY(a),this.setEvent(a)):this.removeDocumentEvents()),0<this.interval&&(this.timeoutId=setTimeout(OpenLayers.Function.bind(this.removeTimeout,this),this.interval)),this.dragging=!0,this.move(a),this.callback("move",[a.xy]),this.oldOnselectstart||(this.oldOnselectstart= | |
1883 document.onselectstart,document.onselectstart=OpenLayers.Function.False),this.last=a.xy);return!0},dragend:function(a){if(this.started){!0===this.documentDrag&&this.documentEvents&&(this.adjustXY(a),this.removeDocumentEvents());var b=this.start!=this.last;this.dragging=this.started=!1;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.up(a);this.callback("up",[a.xy]);b&&this.callback("done",[a.xy]);document.onselectstart=this.oldOnselectstart}return!0},down:function(a){},move:function(a){}, | |
1884 up:function(a){},out:function(a){},mousedown:function(a){return this.dragstart(a)},touchstart:function(a){this.startTouch();return this.dragstart(a)},mousemove:function(a){return this.dragmove(a)},touchmove:function(a){return this.dragmove(a)},removeTimeout:function(){this.timeoutId=null;this.dragging&&this.mousemove(this.lastMoveEvt)},mouseup:function(a){return this.dragend(a)},touchend:function(a){a.xy=this.last;return this.dragend(a)},mouseout:function(a){if(this.started&&OpenLayers.Util.mouseLeft(a, | |
1885 this.map.viewPortDiv))if(!0===this.documentDrag)this.addDocumentEvents();else{var b=this.start!=this.last;this.dragging=this.started=!1;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown");this.out(a);this.callback("out",[]);b&&this.callback("done",[a.xy]);document.onselectstart&&(document.onselectstart=this.oldOnselectstart)}return!0},click:function(a){return this.start==this.last},activate:function(){var a=!1;OpenLayers.Handler.prototype.activate.apply(this,arguments)&&(this.dragging= | |
1886 !1,a=!0);return a},deactivate:function(){var a=!1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.dragging=this.started=!1,this.last=this.start=null,a=!0,OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDragDown"));return a},adjustXY:function(a){var b=OpenLayers.Util.pagePosition(this.map.viewPortDiv);a.xy.x-=b[0];a.xy.y-=b[1]},addDocumentEvents:function(){OpenLayers.Element.addClass(document.body,"olDragDown");this.documentEvents=!0;OpenLayers.Event.observe(document,"mousemove", | |
1887 this._docMove);OpenLayers.Event.observe(document,"mouseup",this._docUp)},removeDocumentEvents:function(){OpenLayers.Element.removeClass(document.body,"olDragDown");this.documentEvents=!1;OpenLayers.Event.stopObserving(document,"mousemove",this._docMove);OpenLayers.Event.stopObserving(document,"mouseup",this._docUp)},CLASS_NAME:"OpenLayers.Handler.Drag"});OpenLayers.Control.OverviewMap=OpenLayers.Class(OpenLayers.Control,{element:null,ovmap:null,size:{w:180,h:90},layers:null,minRectSize:15,minRectDisplayClass:"RectReplacement",minRatio:8,maxRatio:32,mapOptions:null,autoPan:!1,handlers:null,resolutionFactor:1,maximized:!1,maximizeTitle:"",minimizeTitle:"",initialize:function(a){this.layers=[];this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,[a])},destroy:function(){this.mapDiv&&(this.handlers.click&&this.handlers.click.destroy(), | |
1888 this.handlers.drag&&this.handlers.drag.destroy(),this.ovmap&&this.ovmap.viewPortDiv.removeChild(this.extentRectangle),this.extentRectangle=null,this.rectEvents&&(this.rectEvents.destroy(),this.rectEvents=null),this.ovmap&&(this.ovmap.destroy(),this.ovmap=null),this.element.removeChild(this.mapDiv),this.mapDiv=null,this.div.removeChild(this.element),this.element=null,this.maximizeDiv&&(this.div.removeChild(this.maximizeDiv),this.maximizeDiv=null),this.minimizeDiv&&(this.div.removeChild(this.minimizeDiv), | |
1889 this.minimizeDiv=null),this.map.events.un({buttonclick:this.onButtonClick,moveend:this.update,changebaselayer:this.baseLayerDraw,scope:this}),OpenLayers.Control.prototype.destroy.apply(this,arguments))},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(0===this.layers.length)if(this.map.baseLayer)this.layers=[this.map.baseLayer.clone()];else return this.map.events.register("changebaselayer",this,this.baseLayerDraw),this.div;this.element=document.createElement("div");this.element.className= | |
1890 this.displayClass+"Element";this.element.style.display="none";this.mapDiv=document.createElement("div");this.mapDiv.style.width=this.size.w+"px";this.mapDiv.style.height=this.size.h+"px";this.mapDiv.style.position="relative";this.mapDiv.style.overflow="hidden";this.mapDiv.id=OpenLayers.Util.createUniqueID("overviewMap");this.extentRectangle=document.createElement("div");this.extentRectangle.style.position="absolute";this.extentRectangle.style.zIndex=1E3;this.extentRectangle.className=this.displayClass+ | |
1891 "ExtentRectangle";this.element.appendChild(this.mapDiv);this.div.appendChild(this.element);if(this.outsideViewport)this.element.style.display="";else{this.div.className+=" "+this.displayClass+"Container";var a=OpenLayers.Util.getImageLocation("layer-switcher-maximize.png");this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv(this.displayClass+"MaximizeButton",null,null,a,"absolute");this.maximizeDiv.style.display="none";this.maximizeDiv.className=this.displayClass+"MaximizeButton olButton";this.maximizeTitle&& | |
1892 (this.maximizeDiv.title=this.maximizeTitle);this.div.appendChild(this.maximizeDiv);a=OpenLayers.Util.getImageLocation("layer-switcher-minimize.png");this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_minimizeDiv",null,null,a,"absolute");this.minimizeDiv.style.display="none";this.minimizeDiv.className=this.displayClass+"MinimizeButton olButton";this.minimizeTitle&&(this.minimizeDiv.title=this.minimizeTitle);this.div.appendChild(this.minimizeDiv);this.minimizeControl()}this.map.getExtent()&& | |
1893 this.update();this.map.events.on({buttonclick:this.onButtonClick,moveend:this.update,scope:this});this.maximized&&this.maximizeControl();return this.div},baseLayerDraw:function(){this.draw();this.map.events.unregister("changebaselayer",this,this.baseLayerDraw)},rectDrag:function(a){var b=this.handlers.drag.last.x-a.x,c=this.handlers.drag.last.y-a.y;if(0!=b||0!=c){var d=this.rectPxBounds.top,e=this.rectPxBounds.left;a=Math.abs(this.rectPxBounds.getHeight());var f=this.rectPxBounds.getWidth(),c=Math.max(0, | |
1894 d-c),c=Math.min(c,this.ovmap.size.h-this.hComp-a),b=Math.max(0,e-b),b=Math.min(b,this.ovmap.size.w-this.wComp-f);this.setRectPxBounds(new OpenLayers.Bounds(b,c+a,b+f,c))}},mapDivClick:function(a){var b=this.rectPxBounds.getCenterPixel(),c=a.xy.x-b.x,d=a.xy.y-b.y,e=this.rectPxBounds.top,f=this.rectPxBounds.left;a=Math.abs(this.rectPxBounds.getHeight());b=this.rectPxBounds.getWidth();d=Math.max(0,e+d);d=Math.min(d,this.ovmap.size.h-a);c=Math.max(0,f+c);c=Math.min(c,this.ovmap.size.w-b);this.setRectPxBounds(new OpenLayers.Bounds(c, | |
1895 d+a,c+b,d));this.updateMapToRect()},onButtonClick:function(a){a.buttonElement===this.minimizeDiv?this.minimizeControl():a.buttonElement===this.maximizeDiv&&this.maximizeControl()},maximizeControl:function(a){this.element.style.display="";this.showToggle(!1);null!=a&&OpenLayers.Event.stop(a)},minimizeControl:function(a){this.element.style.display="none";this.showToggle(!0);null!=a&&OpenLayers.Event.stop(a)},showToggle:function(a){this.maximizeDiv&&(this.maximizeDiv.style.display=a?"":"none");this.minimizeDiv&& | |
1896 (this.minimizeDiv.style.display=a?"none":"")},update:function(){null==this.ovmap&&this.createMap();!this.autoPan&&this.isSuitableOverview()||this.updateOverview();this.updateRectToMap()},isSuitableOverview:function(){var a=this.map.getExtent(),b=this.map.getMaxExtent(),a=new OpenLayers.Bounds(Math.max(a.left,b.left),Math.max(a.bottom,b.bottom),Math.min(a.right,b.right),Math.min(a.top,b.top));this.ovmap.getProjection()!=this.map.getProjection()&&(a=a.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject())); | |
1897 b=this.ovmap.getResolution()/this.map.getResolution();return b>this.minRatio&&b<=this.maxRatio&&this.ovmap.getExtent().containsBounds(a)},updateOverview:function(){var a=this.map.getResolution(),b=this.ovmap.getResolution(),c=b/a;c>this.maxRatio?b=this.minRatio*a:c<=this.minRatio&&(b=this.maxRatio*a);this.ovmap.getProjection()!=this.map.getProjection()?(a=this.map.center.clone(),a.transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject())):a=this.map.center;this.ovmap.setCenter(a, | |
1898 this.ovmap.getZoomForResolution(b*this.resolutionFactor));this.updateRectToMap()},createMap:function(){var a=OpenLayers.Util.extend({controls:[],maxResolution:"auto",fallThrough:!1},this.mapOptions);this.ovmap=new OpenLayers.Map(this.mapDiv,a);this.ovmap.viewPortDiv.appendChild(this.extentRectangle);OpenLayers.Event.stopObserving(window,"unload",this.ovmap.unloadDestroy);this.ovmap.addLayers(this.layers);this.ovmap.zoomToMaxExtent();this.wComp=(this.wComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle, | |
1899 "border-left-width"))+parseInt(OpenLayers.Element.getStyle(this.extentRectangle,"border-right-width")))?this.wComp:2;this.hComp=(this.hComp=parseInt(OpenLayers.Element.getStyle(this.extentRectangle,"border-top-width"))+parseInt(OpenLayers.Element.getStyle(this.extentRectangle,"border-bottom-width")))?this.hComp:2;this.handlers.drag=new OpenLayers.Handler.Drag(this,{move:this.rectDrag,done:this.updateMapToRect},{map:this.ovmap});this.handlers.click=new OpenLayers.Handler.Click(this,{click:this.mapDivClick}, | |
1900 {single:!0,"double":!1,stopSingle:!0,stopDouble:!0,pixelTolerance:1,map:this.ovmap});this.handlers.click.activate();this.rectEvents=new OpenLayers.Events(this,this.extentRectangle,null,!0);this.rectEvents.register("mouseover",this,function(a){this.handlers.drag.active||this.map.dragging||this.handlers.drag.activate()});this.rectEvents.register("mouseout",this,function(a){this.handlers.drag.dragging||this.handlers.drag.deactivate()});if(this.ovmap.getProjection()!=this.map.getProjection()){var a=this.map.getProjectionObject().getUnits()|| | |
1901 this.map.units||this.map.baseLayer.units,b=this.ovmap.getProjectionObject().getUnits()||this.ovmap.units||this.ovmap.baseLayer.units;this.resolutionFactor=a&&b?OpenLayers.INCHES_PER_UNIT[a]/OpenLayers.INCHES_PER_UNIT[b]:1}},updateRectToMap:function(){var a;a=this.ovmap.getProjection()!=this.map.getProjection()?this.map.getExtent().transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject()):this.map.getExtent();(a=this.getRectBoundsFromMapBounds(a))&&this.setRectPxBounds(a)},updateMapToRect:function(){var a= | |
1902 this.getMapBoundsFromRectBounds(this.rectPxBounds);this.ovmap.getProjection()!=this.map.getProjection()&&(a=a.transform(this.ovmap.getProjectionObject(),this.map.getProjectionObject()));this.map.panTo(a.getCenterLonLat())},setRectPxBounds:function(a){var b=Math.max(a.top,0),c=Math.max(a.left,0),d=Math.min(a.top+Math.abs(a.getHeight()),this.ovmap.size.h-this.hComp);a=Math.min(a.left+a.getWidth(),this.ovmap.size.w-this.wComp);var e=Math.max(a-c,0),f=Math.max(d-b,0);e<this.minRectSize||f<this.minRectSize? | |
1903 (this.extentRectangle.className=this.displayClass+this.minRectDisplayClass,e=c+e/2-this.minRectSize/2,this.extentRectangle.style.top=Math.round(b+f/2-this.minRectSize/2)+"px",this.extentRectangle.style.left=Math.round(e)+"px",this.extentRectangle.style.height=this.minRectSize+"px",this.extentRectangle.style.width=this.minRectSize+"px"):(this.extentRectangle.className=this.displayClass+"ExtentRectangle",this.extentRectangle.style.top=Math.round(b)+"px",this.extentRectangle.style.left=Math.round(c)+ | |
1904 "px",this.extentRectangle.style.height=Math.round(f)+"px",this.extentRectangle.style.width=Math.round(e)+"px");this.rectPxBounds=new OpenLayers.Bounds(Math.round(c),Math.round(d),Math.round(a),Math.round(b))},getRectBoundsFromMapBounds:function(a){var b=this.getOverviewPxFromLonLat({lon:a.left,lat:a.bottom});a=this.getOverviewPxFromLonLat({lon:a.right,lat:a.top});var c=null;b&&a&&(c=new OpenLayers.Bounds(b.x,b.y,a.x,a.y));return c},getMapBoundsFromRectBounds:function(a){var b=this.getLonLatFromOverviewPx({x:a.left, | |
1905 y:a.bottom});a=this.getLonLatFromOverviewPx({x:a.right,y:a.top});return new OpenLayers.Bounds(b.lon,b.lat,a.lon,a.lat)},getLonLatFromOverviewPx:function(a){var b=this.ovmap.size,c=this.ovmap.getResolution(),d=this.ovmap.getExtent().getCenterLonLat();return{lon:d.lon+(a.x-b.w/2)*c,lat:d.lat-(a.y-b.h/2)*c}},getOverviewPxFromLonLat:function(a){var b=this.ovmap.getResolution(),c=this.ovmap.getExtent();if(c)return{x:Math.round(1/b*(a.lon-c.left)),y:Math.round(1/b*(c.top-a.lat))}},CLASS_NAME:"OpenLayers.Control.OverviewMap"});OpenLayers.Layer=OpenLayers.Class({id:null,name:null,div:null,opacity:1,alwaysInRange:null,RESOLUTION_PROPERTIES:"scales resolutions maxScale minScale maxResolution minResolution numZoomLevels maxZoomLevel".split(" "),events:null,map:null,isBaseLayer:!1,alpha:!1,displayInLayerSwitcher:!0,visibility:!0,attribution:null,inRange:!1,imageSize:null,options:null,eventListeners:null,gutter:0,projection:null,units:null,scales:null,resolutions:null,maxExtent:null,minExtent:null,maxResolution:null,minResolution:null, | |
1906 numZoomLevels:null,minScale:null,maxScale:null,displayOutsideMaxExtent:!1,wrapDateLine:!1,metadata:null,initialize:function(a,b){this.metadata={};b=OpenLayers.Util.extend({},b);null!=this.alwaysInRange&&(b.alwaysInRange=this.alwaysInRange);this.addOptions(b);this.name=a;if(null==this.id&&(this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_"),this.div=OpenLayers.Util.createDiv(this.id),this.div.style.width="100%",this.div.style.height="100%",this.div.dir="ltr",this.events=new OpenLayers.Events(this, | |
1907 this.div),this.eventListeners instanceof Object))this.events.on(this.eventListeners)},destroy:function(a){null==a&&(a=!0);null!=this.map&&this.map.removeLayer(this,a);this.options=this.div=this.name=this.map=this.projection=null;this.events&&(this.eventListeners&&this.events.un(this.eventListeners),this.events.destroy());this.events=this.eventListeners=null},clone:function(a){null==a&&(a=new OpenLayers.Layer(this.name,this.getOptions()));OpenLayers.Util.applyDefaults(a,this);a.map=null;return a}, | |
1908 getOptions:function(){var a={},b;for(b in this.options)a[b]=this[b];return a},setName:function(a){a!=this.name&&(this.name=a,null!=this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"name"}))},addOptions:function(a,b){null==this.options&&(this.options={});a&&("string"==typeof a.projection&&(a.projection=new OpenLayers.Projection(a.projection)),a.projection&&OpenLayers.Util.applyDefaults(a,OpenLayers.Projection.defaults[a.projection.getCode()]),!a.maxExtent||a.maxExtent instanceof | |
1909 OpenLayers.Bounds||(a.maxExtent=new OpenLayers.Bounds(a.maxExtent)),!a.minExtent||a.minExtent instanceof OpenLayers.Bounds||(a.minExtent=new OpenLayers.Bounds(a.minExtent)));OpenLayers.Util.extend(this.options,a);OpenLayers.Util.extend(this,a);this.projection&&this.projection.getUnits()&&(this.units=this.projection.getUnits());if(this.map){var c=this.map.getResolution(),d=this.RESOLUTION_PROPERTIES.concat(["projection","units","minExtent","maxExtent"]),e;for(e in a)if(a.hasOwnProperty(e)&&0<=OpenLayers.Util.indexOf(d, | |
1910 e)){this.initResolutions();b&&this.map.baseLayer===this&&(this.map.setCenter(this.map.getCenter(),this.map.getZoomForResolution(c),!1,!0),this.map.events.triggerEvent("changebaselayer",{layer:this}));break}}},onMapResize:function(){},redraw:function(){var a=!1;if(this.map){this.inRange=this.calculateInRange();var b=this.getExtent();b&&(this.inRange&&this.visibility)&&(this.moveTo(b,!0,!1),this.events.triggerEvent("moveend",{zoomChanged:!0}),a=!0)}return a},moveTo:function(a,b,c){a=this.visibility; | |
1911 this.isBaseLayer||(a=a&&this.inRange);this.display(a)},moveByPx:function(a,b){},setMap:function(a){null==this.map&&(this.map=a,this.maxExtent=this.maxExtent||this.map.maxExtent,this.minExtent=this.minExtent||this.map.minExtent,this.projection=this.projection||this.map.projection,"string"==typeof this.projection&&(this.projection=new OpenLayers.Projection(this.projection)),this.units=this.projection.getUnits()||this.units||this.map.units,this.initResolutions(),this.isBaseLayer||(this.inRange=this.calculateInRange(), | |
1912 this.div.style.display=this.visibility&&this.inRange?"":"none"),this.setTileSize())},afterAdd:function(){},removeMap:function(a){},getImageSize:function(a){return this.imageSize||this.tileSize},setTileSize:function(a){this.tileSize=a=a?a:this.tileSize?this.tileSize:this.map.getTileSize();this.gutter&&(this.imageSize=new OpenLayers.Size(a.w+2*this.gutter,a.h+2*this.gutter))},getVisibility:function(){return this.visibility},setVisibility:function(a){a!=this.visibility&&(this.visibility=a,this.display(a), | |
1913 this.redraw(),null!=this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"visibility"}),this.events.triggerEvent("visibilitychanged"))},display:function(a){a!=("none"!=this.div.style.display)&&(this.div.style.display=a&&this.calculateInRange()?"block":"none")},calculateInRange:function(){var a=!1;this.alwaysInRange?a=!0:this.map&&(a=this.map.getResolution(),a=a>=this.minResolution&&a<=this.maxResolution);return a},setIsBaseLayer:function(a){a!=this.isBaseLayer&&(this.isBaseLayer= | |
1914 a,null!=this.map&&this.map.events.triggerEvent("changebaselayer",{layer:this}))},initResolutions:function(){var a,b,c,d={},e=!0;a=0;for(b=this.RESOLUTION_PROPERTIES.length;a<b;a++)c=this.RESOLUTION_PROPERTIES[a],d[c]=this.options[c],e&&this.options[c]&&(e=!1);null==this.options.alwaysInRange&&(this.alwaysInRange=e);null==d.resolutions&&(d.resolutions=this.resolutionsFromScales(d.scales));null==d.resolutions&&(d.resolutions=this.calculateResolutions(d));if(null==d.resolutions){a=0;for(b=this.RESOLUTION_PROPERTIES.length;a< | |
1915 b;a++)c=this.RESOLUTION_PROPERTIES[a],d[c]=null!=this.options[c]?this.options[c]:this.map[c];null==d.resolutions&&(d.resolutions=this.resolutionsFromScales(d.scales));null==d.resolutions&&(d.resolutions=this.calculateResolutions(d))}var f;this.options.maxResolution&&"auto"!==this.options.maxResolution&&(f=this.options.maxResolution);this.options.minScale&&(f=OpenLayers.Util.getResolutionFromScale(this.options.minScale,this.units));var g;this.options.minResolution&&"auto"!==this.options.minResolution&& | |
1916 (g=this.options.minResolution);this.options.maxScale&&(g=OpenLayers.Util.getResolutionFromScale(this.options.maxScale,this.units));d.resolutions&&(d.resolutions.sort(function(a,b){return b-a}),f||(f=d.resolutions[0]),g||(g=d.resolutions[d.resolutions.length-1]));if(this.resolutions=d.resolutions){b=this.resolutions.length;this.scales=Array(b);for(a=0;a<b;a++)this.scales[a]=OpenLayers.Util.getScaleFromResolution(this.resolutions[a],this.units);this.numZoomLevels=b}if(this.minResolution=g)this.maxScale= | |
1917 OpenLayers.Util.getScaleFromResolution(g,this.units);if(this.maxResolution=f)this.minScale=OpenLayers.Util.getScaleFromResolution(f,this.units)},resolutionsFromScales:function(a){if(null!=a){var b,c,d;d=a.length;b=Array(d);for(c=0;c<d;c++)b[c]=OpenLayers.Util.getResolutionFromScale(a[c],this.units);return b}},calculateResolutions:function(a){var b,c,d=a.maxResolution;null!=a.minScale?d=OpenLayers.Util.getResolutionFromScale(a.minScale,this.units):"auto"==d&&null!=this.maxExtent&&(b=this.map.getSize(), | |
1918 c=this.maxExtent.getWidth()/b.w,b=this.maxExtent.getHeight()/b.h,d=Math.max(c,b));c=a.minResolution;null!=a.maxScale?c=OpenLayers.Util.getResolutionFromScale(a.maxScale,this.units):"auto"==a.minResolution&&null!=this.minExtent&&(b=this.map.getSize(),c=this.minExtent.getWidth()/b.w,b=this.minExtent.getHeight()/b.h,c=Math.max(c,b));"number"!==typeof d&&("number"!==typeof c&&null!=this.maxExtent)&&(d=this.map.getTileSize(),d=Math.max(this.maxExtent.getWidth()/d.w,this.maxExtent.getHeight()/d.h));b=a.maxZoomLevel; | |
1919 a=a.numZoomLevels;"number"===typeof c&&"number"===typeof d&&void 0===a?a=Math.floor(Math.log(d/c)/Math.log(2))+1:void 0===a&&null!=b&&(a=b+1);if(!("number"!==typeof a||0>=a||"number"!==typeof d&&"number"!==typeof c)){b=Array(a);var e=2;"number"==typeof c&&"number"==typeof d&&(e=Math.pow(d/c,1/(a-1)));var f;if("number"===typeof d)for(f=0;f<a;f++)b[f]=d/Math.pow(e,f);else for(f=0;f<a;f++)b[a-1-f]=c*Math.pow(e,f);return b}},getResolution:function(){var a=this.map.getZoom();return this.getResolutionForZoom(a)}, | |
1920 getExtent:function(){return this.map.calculateBounds()},getZoomForExtent:function(a,b){var c=this.map.getSize(),c=Math.max(a.getWidth()/c.w,a.getHeight()/c.h);return this.getZoomForResolution(c,b)},getDataExtent:function(){},getResolutionForZoom:function(a){a=Math.max(0,Math.min(a,this.resolutions.length-1));if(this.map.fractionalZoom){var b=Math.floor(a),c=Math.ceil(a);a=this.resolutions[b]-(a-b)*(this.resolutions[b]-this.resolutions[c])}else a=this.resolutions[Math.round(a)];return a},getZoomForResolution:function(a, | |
1921 b){var c,d;if(this.map.fractionalZoom){var e=0,f=this.resolutions[e],g=this.resolutions[this.resolutions.length-1],h;c=0;for(d=this.resolutions.length;c<d;++c)if(h=this.resolutions[c],h>=a&&(f=h,e=c),h<=a){g=h;break}c=f-g;c=0<c?e+(f-a)/c:e}else{f=Number.POSITIVE_INFINITY;c=0;for(d=this.resolutions.length;c<d;c++)if(b){e=Math.abs(this.resolutions[c]-a);if(e>f)break;f=e}else if(this.resolutions[c]<a)break;c=Math.max(0,c-1)}return c},getLonLatFromViewPortPx:function(a){var b=null,c=this.map;if(null!= | |
1922 a&&c.minPx){var b=c.getResolution(),d=c.getMaxExtent({restricted:!0}),b=new OpenLayers.LonLat((a.x-c.minPx.x)*b+d.left,(c.minPx.y-a.y)*b+d.top);this.wrapDateLine&&(b=b.wrapDateLine(this.maxExtent))}return b},getViewPortPxFromLonLat:function(a,b){var c=null;null!=a&&(b=b||this.map.getResolution(),c=this.map.calculateBounds(null,b),c=new OpenLayers.Pixel(1/b*(a.lon-c.left),1/b*(c.top-a.lat)));return c},setOpacity:function(a){if(a!=this.opacity){this.opacity=a;for(var b=this.div.childNodes,c=0,d=b.length;c< | |
1923 d;++c){var e=b[c].firstChild||b[c],f=b[c].lastChild;f&&"iframe"===f.nodeName.toLowerCase()&&(e=f.parentNode);OpenLayers.Util.modifyDOMElement(e,null,null,null,null,null,null,a)}null!=this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"})}},getZIndex:function(){return this.div.style.zIndex},setZIndex:function(a){this.div.style.zIndex=a},adjustBounds:function(a){if(this.gutter){var b=this.gutter*this.map.getResolution();a=new OpenLayers.Bounds(a.left-b,a.bottom-b,a.right+ | |
1924 b,a.top+b)}this.wrapDateLine&&(b={rightTolerance:this.getResolution(),leftTolerance:this.getResolution()},a=a.wrapDateLine(this.maxExtent,b));return a},CLASS_NAME:"OpenLayers.Layer"});OpenLayers.Layer.SphericalMercator={getExtent:function(){var a=null;return a=this.sphericalMercator?this.map.calculateBounds():OpenLayers.Layer.FixedZoomLevels.prototype.getExtent.apply(this)},getLonLatFromViewPortPx:function(a){return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this,arguments)},getViewPortPxFromLonLat:function(a){return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this,arguments)},initMercatorParameters:function(){this.RESOLUTIONS=[];for(var a=0;a<=this.MAX_ZOOM_LEVEL;++a)this.RESOLUTIONS[a]= | |
1925 156543.03390625/Math.pow(2,a);this.units="m";this.projection=this.projection||"EPSG:900913"},forwardMercator:function(){var a=new OpenLayers.Projection("EPSG:4326"),b=new OpenLayers.Projection("EPSG:900913");return function(c,d){var e=OpenLayers.Projection.transform({x:c,y:d},a,b);return new OpenLayers.LonLat(e.x,e.y)}}(),inverseMercator:function(){var a=new OpenLayers.Projection("EPSG:4326"),b=new OpenLayers.Projection("EPSG:900913");return function(c,d){var e=OpenLayers.Projection.transform({x:c, | |
1926 y:d},b,a);return new OpenLayers.LonLat(e.x,e.y)}}()};OpenLayers.Layer.EventPane=OpenLayers.Class(OpenLayers.Layer,{smoothDragPan:!0,isBaseLayer:!0,isFixed:!0,pane:null,mapObject:null,initialize:function(a,b){OpenLayers.Layer.prototype.initialize.apply(this,arguments);null==this.pane&&(this.pane=OpenLayers.Util.createDiv(this.div.id+"_EventPane"))},destroy:function(){this.pane=this.mapObject=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments)},setMap:function(a){OpenLayers.Layer.prototype.setMap.apply(this,arguments);this.pane.style.zIndex= | |
1927 parseInt(this.div.style.zIndex)+1;this.pane.style.display=this.div.style.display;this.pane.style.width="100%";this.pane.style.height="100%";"msie"==OpenLayers.BROWSER_NAME&&(this.pane.style.background="url("+OpenLayers.Util.getImageLocation("blank.gif")+")");this.isFixed?this.map.viewPortDiv.appendChild(this.pane):this.map.layerContainerDiv.appendChild(this.pane);this.loadMapObject();null==this.mapObject&&this.loadWarningMessage()},removeMap:function(a){this.pane&&this.pane.parentNode&&this.pane.parentNode.removeChild(this.pane); | |
1928 OpenLayers.Layer.prototype.removeMap.apply(this,arguments)},loadWarningMessage:function(){this.div.style.backgroundColor="darkblue";var a=this.map.getSize(),b=Math.min(a.w,300),c=Math.min(a.h,200),b=new OpenLayers.Size(b,c),a=(new OpenLayers.Pixel(a.w/2,a.h/2)).add(-b.w/2,-b.h/2),a=OpenLayers.Util.createDiv(this.name+"_warning",a,b,null,null,null,"auto");a.style.padding="7px";a.style.backgroundColor="yellow";a.innerHTML=this.getWarningHTML();this.div.appendChild(a)},getWarningHTML:function(){return""}, | |
1929 display:function(a){OpenLayers.Layer.prototype.display.apply(this,arguments);this.pane.style.display=this.div.style.display},setZIndex:function(a){OpenLayers.Layer.prototype.setZIndex.apply(this,arguments);this.pane.style.zIndex=parseInt(this.div.style.zIndex)+1},moveByPx:function(a,b){OpenLayers.Layer.prototype.moveByPx.apply(this,arguments);this.dragPanMapObject?this.dragPanMapObject(a,-b):this.moveTo(this.map.getCachedCenter())},moveTo:function(a,b,c){OpenLayers.Layer.prototype.moveTo.apply(this, | |
1930 arguments);if(null!=this.mapObject){var d=this.map.getCenter(),e=this.map.getZoom();if(null!=d){var f=this.getMapObjectCenter(),f=this.getOLLonLatFromMapObjectLonLat(f),g=this.getMapObjectZoom(),g=this.getOLZoomFromMapObjectZoom(g);d.equals(f)&&e==g||(!b&&f&&this.dragPanMapObject&&this.smoothDragPan?(e=this.map.getViewPortPxFromLonLat(f),d=this.map.getViewPortPxFromLonLat(d),this.dragPanMapObject(d.x-e.x,e.y-d.y)):(d=this.getMapObjectLonLatFromOLLonLat(d),e=this.getMapObjectZoomFromOLZoom(e),this.setMapObjectCenter(d, | |
1931 e,c)))}}},getLonLatFromViewPortPx:function(a){var b=null;null!=this.mapObject&&null!=this.getMapObjectCenter()&&(a=this.getMapObjectPixelFromOLPixel(a),a=this.getMapObjectLonLatFromMapObjectPixel(a),b=this.getOLLonLatFromMapObjectLonLat(a));return b},getViewPortPxFromLonLat:function(a){var b=null;null!=this.mapObject&&null!=this.getMapObjectCenter()&&(a=this.getMapObjectLonLatFromOLLonLat(a),a=this.getMapObjectPixelFromMapObjectLonLat(a),b=this.getOLPixelFromMapObjectPixel(a));return b},getOLLonLatFromMapObjectLonLat:function(a){var b= | |
1932 null;null!=a&&(b=this.getLongitudeFromMapObjectLonLat(a),a=this.getLatitudeFromMapObjectLonLat(a),b=new OpenLayers.LonLat(b,a));return b},getMapObjectLonLatFromOLLonLat:function(a){var b=null;null!=a&&(b=this.getMapObjectLonLatFromLonLat(a.lon,a.lat));return b},getOLPixelFromMapObjectPixel:function(a){var b=null;null!=a&&(b=this.getXFromMapObjectPixel(a),a=this.getYFromMapObjectPixel(a),b=new OpenLayers.Pixel(b,a));return b},getMapObjectPixelFromOLPixel:function(a){var b=null;null!=a&&(b=this.getMapObjectPixelFromXY(a.x, | |
1933 a.y));return b},CLASS_NAME:"OpenLayers.Layer.EventPane"});OpenLayers.Layer.FixedZoomLevels=OpenLayers.Class({initialize:function(){},initResolutions:function(){for(var a=["minZoomLevel","maxZoomLevel","numZoomLevels"],b=0,c=a.length;b<c;b++){var d=a[b];this[d]=null!=this.options[d]?this.options[d]:this.map[d]}if(null==this.minZoomLevel||this.minZoomLevel<this.MIN_ZOOM_LEVEL)this.minZoomLevel=this.MIN_ZOOM_LEVEL;a=this.MAX_ZOOM_LEVEL-this.minZoomLevel+1;b=null==this.options.numZoomLevels&&null!=this.options.maxZoomLevel||null==this.numZoomLevels&&null!=this.maxZoomLevel? | |
1934 this.maxZoomLevel-this.minZoomLevel+1:this.numZoomLevels;this.numZoomLevels=null!=b?Math.min(b,a):a;this.maxZoomLevel=this.minZoomLevel+this.numZoomLevels-1;if(null!=this.RESOLUTIONS){a=0;this.resolutions=[];for(b=this.minZoomLevel;b<=this.maxZoomLevel;b++)this.resolutions[a++]=this.RESOLUTIONS[b];this.maxResolution=this.resolutions[0];this.minResolution=this.resolutions[this.resolutions.length-1]}},getResolution:function(){if(null!=this.resolutions)return OpenLayers.Layer.prototype.getResolution.apply(this, | |
1935 arguments);var a=null,b=this.map.getSize(),c=this.getExtent();null!=b&&null!=c&&(a=Math.max(c.getWidth()/b.w,c.getHeight()/b.h));return a},getExtent:function(){var a=this.map.getSize(),b=this.getLonLatFromViewPortPx({x:0,y:0}),a=this.getLonLatFromViewPortPx({x:a.w,y:a.h});return null!=b&&null!=a?new OpenLayers.Bounds(b.lon,a.lat,a.lon,b.lat):null},getZoomForResolution:function(a){if(null!=this.resolutions)return OpenLayers.Layer.prototype.getZoomForResolution.apply(this,arguments);var b=OpenLayers.Layer.prototype.getExtent.apply(this, | |
1936 []);return this.getZoomForExtent(b)},getOLZoomFromMapObjectZoom:function(a){var b=null;null!=a&&(b=a-this.minZoomLevel,this.map.baseLayer!==this&&(b=this.map.baseLayer.getZoomForResolution(this.getResolutionForZoom(b))));return b},getMapObjectZoomFromOLZoom:function(a){var b=null;null!=a&&(b=a+this.minZoomLevel,this.map.baseLayer!==this&&(b=this.getZoomForResolution(this.map.baseLayer.getResolutionForZoom(b))));return b},CLASS_NAME:"OpenLayers.Layer.FixedZoomLevels"});OpenLayers.Layer.Google=OpenLayers.Class(OpenLayers.Layer.EventPane,OpenLayers.Layer.FixedZoomLevels,{MIN_ZOOM_LEVEL:0,MAX_ZOOM_LEVEL:21,RESOLUTIONS:[1.40625,0.703125,0.3515625,0.17578125,0.087890625,0.0439453125,0.02197265625,0.010986328125,0.0054931640625,0.00274658203125,0.001373291015625,6.866455078125E-4,3.4332275390625E-4,1.71661376953125E-4,8.58306884765625E-5,4.291534423828125E-5,2.145767211914062E-5,1.072883605957031E-5,5.36441802978515E-6,2.68220901489257E-6,1.341104507446289E-6,6.705522537231445E-7], | |
1937 type:null,wrapDateLine:!0,sphericalMercator:!1,version:null,initialize:function(a,b){b=b||{};b.version||(b.version="function"===typeof GMap2?"2":"3");var c=OpenLayers.Layer.Google["v"+b.version.replace(/\./g,"_")];if(c)OpenLayers.Util.applyDefaults(b,c);else throw"Unsupported Google Maps API version: "+b.version;OpenLayers.Util.applyDefaults(b,c.DEFAULTS);b.maxExtent&&(b.maxExtent=b.maxExtent.clone());OpenLayers.Layer.EventPane.prototype.initialize.apply(this,[a,b]);OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this, | |
1938 [a,b]);this.sphericalMercator&&(OpenLayers.Util.extend(this,OpenLayers.Layer.SphericalMercator),this.initMercatorParameters())},clone:function(){return new OpenLayers.Layer.Google(this.name,this.getOptions())},setVisibility:function(a){var b=null==this.opacity?1:this.opacity;OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this,arguments);this.setOpacity(b)},display:function(a){this._dragging||this.setGMapVisibility(a);OpenLayers.Layer.EventPane.prototype.display.apply(this,arguments)},moveTo:function(a, | |
1939 b,c){this._dragging=c;OpenLayers.Layer.EventPane.prototype.moveTo.apply(this,arguments);delete this._dragging},setOpacity:function(a){a!==this.opacity&&(null!=this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"opacity"}),this.opacity=a);if(this.getVisibility()){var b=this.getMapContainer();OpenLayers.Util.modifyDOMElement(b,null,null,null,null,null,null,a)}},destroy:function(){if(this.map){this.setGMapVisibility(!1);var a=OpenLayers.Layer.Google.cache[this.map.id];a&&1>=a.count&& | |
1940 this.removeGMapElements()}OpenLayers.Layer.EventPane.prototype.destroy.apply(this,arguments)},removeGMapElements:function(){var a=OpenLayers.Layer.Google.cache[this.map.id];if(a){var b=this.mapObject&&this.getMapContainer();b&&b.parentNode&&b.parentNode.removeChild(b);(b=a.termsOfUse)&&b.parentNode&&b.parentNode.removeChild(b);(a=a.poweredBy)&&a.parentNode&&a.parentNode.removeChild(a);this.mapObject&&(window.google&&google.maps&&google.maps.event&&google.maps.event.clearListeners)&&google.maps.event.clearListeners(this.mapObject, | |
1941 "tilesloaded")}},removeMap:function(a){this.visibility&&this.mapObject&&this.setGMapVisibility(!1);var b=OpenLayers.Layer.Google.cache[a.id];b&&(1>=b.count?(this.removeGMapElements(),delete OpenLayers.Layer.Google.cache[a.id]):--b.count);delete this.termsOfUse;delete this.poweredBy;delete this.mapObject;delete this.dragObject;OpenLayers.Layer.EventPane.prototype.removeMap.apply(this,arguments)},getOLBoundsFromMapObjectBounds:function(a){var b=null;null!=a&&(b=a.getSouthWest(),a=a.getNorthEast(),this.sphericalMercator? | |
1942 (b=this.forwardMercator(b.lng(),b.lat()),a=this.forwardMercator(a.lng(),a.lat())):(b=new OpenLayers.LonLat(b.lng(),b.lat()),a=new OpenLayers.LonLat(a.lng(),a.lat())),b=new OpenLayers.Bounds(b.lon,b.lat,a.lon,a.lat));return b},getWarningHTML:function(){return OpenLayers.i18n("googleWarning")},getMapObjectCenter:function(){return this.mapObject.getCenter()},getMapObjectZoom:function(){return this.mapObject.getZoom()},getLongitudeFromMapObjectLonLat:function(a){return this.sphericalMercator?this.forwardMercator(a.lng(), | |
1943 a.lat()).lon:a.lng()},getLatitudeFromMapObjectLonLat:function(a){return this.sphericalMercator?this.forwardMercator(a.lng(),a.lat()).lat:a.lat()},getXFromMapObjectPixel:function(a){return a.x},getYFromMapObjectPixel:function(a){return a.y},CLASS_NAME:"OpenLayers.Layer.Google"});OpenLayers.Layer.Google.cache={}; | |
1944 OpenLayers.Layer.Google.v2={termsOfUse:null,poweredBy:null,dragObject:null,loadMapObject:function(){this.type||(this.type=G_NORMAL_MAP);var a,b,c,d=OpenLayers.Layer.Google.cache[this.map.id];if(d)a=d.mapObject,b=d.termsOfUse,c=d.poweredBy,++d.count;else{var d=this.map.viewPortDiv,e=document.createElement("div");e.id=this.map.id+"_GMap2Container";e.style.position="absolute";e.style.width="100%";e.style.height="100%";d.appendChild(e);try{a=new GMap2(e),b=e.lastChild,d.appendChild(b),b.style.zIndex= | |
1945 "1100",b.style.right="",b.style.bottom="",b.className="olLayerGoogleCopyright",c=e.lastChild,d.appendChild(c),c.style.zIndex="1100",c.style.right="",c.style.bottom="",c.className="olLayerGooglePoweredBy gmnoprint"}catch(f){throw f;}OpenLayers.Layer.Google.cache[this.map.id]={mapObject:a,termsOfUse:b,poweredBy:c,count:1}}this.mapObject=a;this.termsOfUse=b;this.poweredBy=c;-1===OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),this.type)&&this.mapObject.addMapType(this.type);"function"==typeof a.getDragObject? | |
1946 this.dragObject=a.getDragObject():this.dragPanMapObject=null;!1===this.isBaseLayer&&this.setGMapVisibility("none"!==this.div.style.display)},onMapResize:function(){if(this.visibility&&this.mapObject.isLoaded())this.mapObject.checkResize();else{if(!this._resized)var a=this,b=GEvent.addListener(this.mapObject,"load",function(){GEvent.removeListener(b);delete a._resized;a.mapObject.checkResize();a.moveTo(a.map.getCenter(),a.map.getZoom())});this._resized=!0}},setGMapVisibility:function(a){var b=OpenLayers.Layer.Google.cache[this.map.id]; | |
1947 if(b){var c=this.mapObject.getContainer();!0===a?(this.mapObject.setMapType(this.type),c.style.display="",this.termsOfUse.style.left="",this.termsOfUse.style.display="",this.poweredBy.style.display="",b.displayed=this.id):(b.displayed===this.id&&delete b.displayed,b.displayed||(c.style.display="none",this.termsOfUse.style.display="none",this.termsOfUse.style.left="-9999px",this.poweredBy.style.display="none"))}},getMapContainer:function(){return this.mapObject.getContainer()},getMapObjectBoundsFromOLBounds:function(a){var b= | |
1948 null;null!=a&&(b=this.sphericalMercator?this.inverseMercator(a.bottom,a.left):new OpenLayers.LonLat(a.bottom,a.left),a=this.sphericalMercator?this.inverseMercator(a.top,a.right):new OpenLayers.LonLat(a.top,a.right),b=new GLatLngBounds(new GLatLng(b.lat,b.lon),new GLatLng(a.lat,a.lon)));return b},setMapObjectCenter:function(a,b){this.mapObject.setCenter(a,b)},dragPanMapObject:function(a,b){this.dragObject.moveBy(new GSize(-a,b))},getMapObjectLonLatFromMapObjectPixel:function(a){return this.mapObject.fromContainerPixelToLatLng(a)}, | |
1949 getMapObjectPixelFromMapObjectLonLat:function(a){return this.mapObject.fromLatLngToContainerPixel(a)},getMapObjectZoomFromMapObjectBounds:function(a){return this.mapObject.getBoundsZoomLevel(a)},getMapObjectLonLatFromLonLat:function(a,b){var c;this.sphericalMercator?(c=this.inverseMercator(a,b),c=new GLatLng(c.lat,c.lon)):c=new GLatLng(b,a);return c},getMapObjectPixelFromXY:function(a,b){return new GPoint(a,b)}};OpenLayers.Format.XML=OpenLayers.Class(OpenLayers.Format,{namespaces:null,namespaceAlias:null,defaultPrefix:null,readers:{},writers:{},xmldom:null,initialize:function(a){window.ActiveXObject&&(this.xmldom=new ActiveXObject("Microsoft.XMLDOM"));OpenLayers.Format.prototype.initialize.apply(this,[a]);this.namespaces=OpenLayers.Util.extend({},this.namespaces);this.namespaceAlias={};for(var b in this.namespaces)this.namespaceAlias[this.namespaces[b]]=b},destroy:function(){this.xmldom=null;OpenLayers.Format.prototype.destroy.apply(this, | |
1950 arguments)},setNamespace:function(a,b){this.namespaces[a]=b;this.namespaceAlias[b]=a},read:function(a){var b=a.indexOf("<");0<b&&(a=a.substring(b));b=OpenLayers.Util.Try(OpenLayers.Function.bind(function(){var b;b=window.ActiveXObject&&!this.xmldom?new ActiveXObject("Microsoft.XMLDOM"):this.xmldom;b.loadXML(a);return b},this),function(){return(new DOMParser).parseFromString(a,"text/xml")},function(){var b=new XMLHttpRequest;b.open("GET","data:text/xml;charset=utf-8,"+encodeURIComponent(a),!1);b.overrideMimeType&& | |
1951 b.overrideMimeType("text/xml");b.send(null);return b.responseXML});this.keepData&&(this.data=b);return b},write:function(a){if(this.xmldom)a=a.xml;else{var b=new XMLSerializer;if(1==a.nodeType){var c=document.implementation.createDocument("","",null);c.importNode&&(a=c.importNode(a,!0));c.appendChild(a);a=b.serializeToString(c)}else a=b.serializeToString(a)}return a},createElementNS:function(a,b){return this.xmldom?"string"==typeof a?this.xmldom.createNode(1,b,a):this.xmldom.createNode(1,b,""):document.createElementNS(a, | |
1952 b)},createDocumentFragment:function(){return this.xmldom?this.xmldom.createDocumentFragment():document.createDocumentFragment()},createTextNode:function(a){"string"!==typeof a&&(a=String(a));return this.xmldom?this.xmldom.createTextNode(a):document.createTextNode(a)},getElementsByTagNameNS:function(a,b,c){var d=[];if(a.getElementsByTagNameNS)d=a.getElementsByTagNameNS(b,c);else{a=a.getElementsByTagName("*");for(var e,f,g=0,h=a.length;g<h;++g)if(e=a[g],f=e.prefix?e.prefix+":"+c:c,"*"==c||f==e.nodeName)"*"!= | |
1953 b&&b!=e.namespaceURI||d.push(e)}return d},getAttributeNodeNS:function(a,b,c){var d=null;if(a.getAttributeNodeNS)d=a.getAttributeNodeNS(b,c);else{a=a.attributes;for(var e,f,g=0,h=a.length;g<h;++g)if(e=a[g],e.namespaceURI==b&&(f=e.prefix?e.prefix+":"+c:c,f==e.nodeName)){d=e;break}}return d},getAttributeNS:function(a,b,c){var d="";if(a.getAttributeNS)d=a.getAttributeNS(b,c)||"";else if(a=this.getAttributeNodeNS(a,b,c))d=a.nodeValue;return d},getChildValue:function(a,b){var c=b||"";if(a)for(var d=a.firstChild;d;d= | |
1954 d.nextSibling)switch(d.nodeType){case 3:case 4:c+=d.nodeValue}return c},isSimpleContent:function(a){var b=!0;for(a=a.firstChild;a;a=a.nextSibling)if(1===a.nodeType){b=!1;break}return b},contentType:function(a){var b=!1,c=!1,d=OpenLayers.Format.XML.CONTENT_TYPE.EMPTY;for(a=a.firstChild;a;a=a.nextSibling){switch(a.nodeType){case 1:c=!0;break;case 8:break;default:b=!0}if(c&&b)break}if(c&&b)d=OpenLayers.Format.XML.CONTENT_TYPE.MIXED;else{if(c)return OpenLayers.Format.XML.CONTENT_TYPE.COMPLEX;if(b)return OpenLayers.Format.XML.CONTENT_TYPE.SIMPLE}return d}, | |
1955 hasAttributeNS:function(a,b,c){var d=!1;return d=a.hasAttributeNS?a.hasAttributeNS(b,c):!!this.getAttributeNodeNS(a,b,c)},setAttributeNS:function(a,b,c,d){if(a.setAttributeNS)a.setAttributeNS(b,c,d);else if(this.xmldom)b?(b=a.ownerDocument.createNode(2,c,b),b.nodeValue=d,a.setAttributeNode(b)):a.setAttribute(c,d);else throw"setAttributeNS not implemented";},createElementNSPlus:function(a,b){b=b||{};var c=b.uri||this.namespaces[b.prefix];c||(c=a.indexOf(":"),c=this.namespaces[a.substring(0,c)]);c|| | |
1956 (c=this.namespaces[this.defaultPrefix]);c=this.createElementNS(c,a);b.attributes&&this.setAttributes(c,b.attributes);var d=b.value;null!=d&&c.appendChild(this.createTextNode(d));return c},setAttributes:function(a,b){var c,d,e;for(e in b)null!=b[e]&&b[e].toString&&(c=b[e].toString(),d=this.namespaces[e.substring(0,e.indexOf(":"))]||null,this.setAttributeNS(a,d,e,c))},readNode:function(a,b){b||(b={});var c=this.readers[a.namespaceURI?this.namespaceAlias[a.namespaceURI]:this.defaultPrefix];if(c){var d= | |
1957 a.localName||a.nodeName.split(":").pop();(c=c[d]||c["*"])&&c.apply(this,[a,b])}return b},readChildNodes:function(a,b){b||(b={});for(var c=a.childNodes,d,e=0,f=c.length;e<f;++e)d=c[e],1==d.nodeType&&this.readNode(d,b);return b},writeNode:function(a,b,c){var d,e=a.indexOf(":");0<e?(d=a.substring(0,e),a=a.substring(e+1)):d=c?this.namespaceAlias[c.namespaceURI]:this.defaultPrefix;b=this.writers[d][a].apply(this,[b]);c&&c.appendChild(b);return b},getChildEl:function(a,b,c){return a&&this.getThisOrNextEl(a.firstChild, | |
1958 b,c)},getNextEl:function(a,b,c){return a&&this.getThisOrNextEl(a.nextSibling,b,c)},getThisOrNextEl:function(a,b,c){a:for(;a;a=a.nextSibling)switch(a.nodeType){case 1:if(!(b&&b!==(a.localName||a.nodeName.split(":").pop())||c&&c!==a.namespaceURI))break a;a=null;break a;case 3:if(/^\s*$/.test(a.nodeValue))break;case 4:case 6:case 12:case 10:case 11:a=null;break a}return a||null},lookupNamespaceURI:function(a,b){var c=null;if(a)if(a.lookupNamespaceURI)c=a.lookupNamespaceURI(b);else a:switch(a.nodeType){case 1:if(null!== | |
1959 a.namespaceURI&&a.prefix===b){c=a.namespaceURI;break a}if(c=a.attributes.length)for(var d,e=0;e<c;++e)if(d=a.attributes[e],"xmlns"===d.prefix&&d.name==="xmlns:"+b){c=d.value||null;break a}else if("xmlns"===d.name&&null===b){c=d.value||null;break a}c=this.lookupNamespaceURI(a.parentNode,b);break a;case 2:c=this.lookupNamespaceURI(a.ownerElement,b);break a;case 9:c=this.lookupNamespaceURI(a.documentElement,b);break a;case 6:case 12:case 10:case 11:break a;default:c=this.lookupNamespaceURI(a.parentNode, | |
1960 b)}return c},getXMLDoc:function(){OpenLayers.Format.XML.document||this.xmldom||(document.implementation&&document.implementation.createDocument?OpenLayers.Format.XML.document=document.implementation.createDocument("","",null):!this.xmldom&&window.ActiveXObject&&(this.xmldom=new ActiveXObject("Microsoft.XMLDOM")));return OpenLayers.Format.XML.document||this.xmldom},CLASS_NAME:"OpenLayers.Format.XML"});OpenLayers.Format.XML.CONTENT_TYPE={EMPTY:0,SIMPLE:1,COMPLEX:2,MIXED:3}; | |
1961 OpenLayers.Format.XML.lookupNamespaceURI=OpenLayers.Function.bind(OpenLayers.Format.XML.prototype.lookupNamespaceURI,OpenLayers.Format.XML.prototype);OpenLayers.Format.XML.document=null;OpenLayers.Format.WFST=function(a){a=OpenLayers.Util.applyDefaults(a,OpenLayers.Format.WFST.DEFAULTS);var b=OpenLayers.Format.WFST["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported WFST version: "+a.version;return new b(a)};OpenLayers.Format.WFST.DEFAULTS={version:"1.0.0"};OpenLayers.Feature=OpenLayers.Class({layer:null,id:null,lonlat:null,data:null,marker:null,popupClass:null,popup:null,initialize:function(a,b,c){this.layer=a;this.lonlat=b;this.data=null!=c?c:{};this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_")},destroy:function(){null!=this.layer&&null!=this.layer.map&&null!=this.popup&&this.layer.map.removePopup(this.popup);null!=this.layer&&null!=this.marker&&this.layer.removeMarker(this.marker);this.data=this.lonlat=this.id=this.layer=null;null!=this.marker&& | |
1962 (this.destroyMarker(this.marker),this.marker=null);null!=this.popup&&(this.destroyPopup(this.popup),this.popup=null)},onScreen:function(){var a=!1;null!=this.layer&&null!=this.layer.map&&(a=this.layer.map.getExtent().containsLonLat(this.lonlat));return a},createMarker:function(){null!=this.lonlat&&(this.marker=new OpenLayers.Marker(this.lonlat,this.data.icon));return this.marker},destroyMarker:function(){this.marker.destroy()},createPopup:function(a){null!=this.lonlat&&(this.popup||(this.popup=new (this.popupClass? | |
1963 this.popupClass:OpenLayers.Popup.Anchored)(this.id+"_popup",this.lonlat,this.data.popupSize,this.data.popupContentHTML,this.marker?this.marker.icon:null,a)),null!=this.data.overflow&&(this.popup.contentDiv.style.overflow=this.data.overflow),this.popup.feature=this);return this.popup},destroyPopup:function(){this.popup&&(this.popup.feature=null,this.popup.destroy(),this.popup=null)},CLASS_NAME:"OpenLayers.Feature"});OpenLayers.State={UNKNOWN:"Unknown",INSERT:"Insert",UPDATE:"Update",DELETE:"Delete"}; | |
1964 OpenLayers.Feature.Vector=OpenLayers.Class(OpenLayers.Feature,{fid:null,geometry:null,attributes:null,bounds:null,state:null,style:null,url:null,renderIntent:"default",modified:null,initialize:function(a,b,c){OpenLayers.Feature.prototype.initialize.apply(this,[null,null,b]);this.lonlat=null;this.geometry=a?a:null;this.state=null;this.attributes={};b&&(this.attributes=OpenLayers.Util.extend(this.attributes,b));this.style=c?c:null},destroy:function(){this.layer&&(this.layer.removeFeatures(this),this.layer= | |
1965 null);this.modified=this.geometry=null;OpenLayers.Feature.prototype.destroy.apply(this,arguments)},clone:function(){return new OpenLayers.Feature.Vector(this.geometry?this.geometry.clone():null,this.attributes,this.style)},onScreen:function(a){var b=!1;this.layer&&this.layer.map&&(b=this.layer.map.getExtent(),a?(a=this.geometry.getBounds(),b=b.intersectsBounds(a)):b=b.toGeometry().intersects(this.geometry));return b},getVisibility:function(){return!(this.style&&"none"==this.style.display||!this.layer|| | |
1966 this.layer&&this.layer.styleMap&&"none"==this.layer.styleMap.createSymbolizer(this,this.renderIntent).display||this.layer&&!this.layer.getVisibility())},createMarker:function(){return null},destroyMarker:function(){},createPopup:function(){return null},atPoint:function(a,b,c){var d=!1;this.geometry&&(d=this.geometry.atPoint(a,b,c));return d},destroyPopup:function(){},move:function(a){if(this.layer&&this.geometry.move){a="OpenLayers.LonLat"==a.CLASS_NAME?this.layer.getViewPortPxFromLonLat(a):a;var b= | |
1967 this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat()),c=this.layer.map.getResolution();this.geometry.move(c*(a.x-b.x),c*(b.y-a.y));this.layer.drawFeature(this);return b}},toState:function(a){if(a==OpenLayers.State.UPDATE)switch(this.state){case OpenLayers.State.UNKNOWN:case OpenLayers.State.DELETE:this.state=a}else if(a==OpenLayers.State.INSERT)switch(this.state){case OpenLayers.State.UNKNOWN:break;default:this.state=a}else if(a==OpenLayers.State.DELETE)switch(this.state){case OpenLayers.State.UNKNOWN:case OpenLayers.State.UPDATE:this.state= | |
1968 a}else a==OpenLayers.State.UNKNOWN&&(this.state=a)},CLASS_NAME:"OpenLayers.Feature.Vector"}); | |
1969 OpenLayers.Feature.Vector.style={"default":{fillColor:"#ee9900",fillOpacity:0.4,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#ee9900",strokeOpacity:1,strokeWidth:1,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit",fontColor:"#000000",labelAlign:"cm",labelOutlineColor:"white",labelOutlineWidth:3},select:{fillColor:"blue",fillOpacity:0.4, | |
1970 hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"blue",strokeOpacity:1,strokeWidth:2,strokeLinecap:"round",strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"pointer",fontColor:"#000000",labelAlign:"cm",labelOutlineColor:"white",labelOutlineWidth:3},temporary:{fillColor:"#66cccc",fillOpacity:0.2,hoverFillColor:"white",hoverFillOpacity:0.8,strokeColor:"#66cccc",strokeOpacity:1, | |
1971 strokeLinecap:"round",strokeWidth:2,strokeDashstyle:"solid",hoverStrokeColor:"red",hoverStrokeOpacity:1,hoverStrokeWidth:0.2,pointRadius:6,hoverPointRadius:1,hoverPointUnit:"%",pointerEvents:"visiblePainted",cursor:"inherit",fontColor:"#000000",labelAlign:"cm",labelOutlineColor:"white",labelOutlineWidth:3},"delete":{display:"none"}};OpenLayers.Style=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:!1,rules:null,context:null,defaultStyle:null,defaultsPerSymbolizer:!1,propertyStyles:null,initialize:function(a,b){OpenLayers.Util.extend(this,b);this.rules=[];b&&b.rules&&this.addRules(b.rules);this.setDefaultStyle(a||OpenLayers.Feature.Vector.style["default"]);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_")},destroy:function(){for(var a=0,b=this.rules.length;a<b;a++)this.rules[a].destroy(), | |
1972 this.rules[a]=null;this.defaultStyle=this.rules=null},createSymbolizer:function(a){for(var b=this.defaultsPerSymbolizer?{}:this.createLiterals(OpenLayers.Util.extend({},this.defaultStyle),a),c=this.rules,d,e=[],f=!1,g=0,h=c.length;g<h;g++)d=c[g],d.evaluate(a)&&(d instanceof OpenLayers.Rule&&d.elseFilter?e.push(d):(f=!0,this.applySymbolizer(d,b,a)));if(!1==f&&0<e.length)for(f=!0,g=0,h=e.length;g<h;g++)this.applySymbolizer(e[g],b,a);0<c.length&&!1==f&&(b.display="none");null!=b.label&&"string"!==typeof b.label&& | |
1973 (b.label=String(b.label));return b},applySymbolizer:function(a,b,c){var d=c.geometry?this.getSymbolizerPrefix(c.geometry):OpenLayers.Style.SYMBOLIZER_PREFIXES[0];a=a.symbolizer[d]||a.symbolizer;!0===this.defaultsPerSymbolizer&&(d=this.defaultStyle,OpenLayers.Util.applyDefaults(a,{pointRadius:d.pointRadius}),!0!==a.stroke&&!0!==a.graphic||OpenLayers.Util.applyDefaults(a,{strokeWidth:d.strokeWidth,strokeColor:d.strokeColor,strokeOpacity:d.strokeOpacity,strokeDashstyle:d.strokeDashstyle,strokeLinecap:d.strokeLinecap}), | |
1974 !0!==a.fill&&!0!==a.graphic||OpenLayers.Util.applyDefaults(a,{fillColor:d.fillColor,fillOpacity:d.fillOpacity}),!0===a.graphic&&OpenLayers.Util.applyDefaults(a,{pointRadius:this.defaultStyle.pointRadius,externalGraphic:this.defaultStyle.externalGraphic,graphicName:this.defaultStyle.graphicName,graphicOpacity:this.defaultStyle.graphicOpacity,graphicWidth:this.defaultStyle.graphicWidth,graphicHeight:this.defaultStyle.graphicHeight,graphicXOffset:this.defaultStyle.graphicXOffset,graphicYOffset:this.defaultStyle.graphicYOffset})); | |
1975 return this.createLiterals(OpenLayers.Util.extend(b,a),c)},createLiterals:function(a,b){var c=OpenLayers.Util.extend({},b.attributes||b.data);OpenLayers.Util.extend(c,this.context);for(var d in this.propertyStyles)a[d]=OpenLayers.Style.createLiteral(a[d],c,b,d);return a},findPropertyStyles:function(){var a={};this.addPropertyStyles(a,this.defaultStyle);for(var b=this.rules,c,d,e=0,f=b.length;e<f;e++){c=b[e].symbolizer;for(var g in c)if(d=c[g],"object"==typeof d)this.addPropertyStyles(a,d);else{this.addPropertyStyles(a, | |
1976 c);break}}return a},addPropertyStyles:function(a,b){var c,d;for(d in b)c=b[d],"string"==typeof c&&c.match(/\$\{\w+\}/)&&(a[d]=!0);return a},addRules:function(a){Array.prototype.push.apply(this.rules,a);this.propertyStyles=this.findPropertyStyles()},setDefaultStyle:function(a){this.defaultStyle=a;this.propertyStyles=this.findPropertyStyles()},getSymbolizerPrefix:function(a){for(var b=OpenLayers.Style.SYMBOLIZER_PREFIXES,c=0,d=b.length;c<d;c++)if(-1!=a.CLASS_NAME.indexOf(b[c]))return b[c]},clone:function(){var a= | |
1977 OpenLayers.Util.extend({},this);if(this.rules){a.rules=[];for(var b=0,c=this.rules.length;b<c;++b)a.rules.push(this.rules[b].clone())}a.context=this.context&&OpenLayers.Util.extend({},this.context);b=OpenLayers.Util.extend({},this.defaultStyle);return new OpenLayers.Style(b,a)},CLASS_NAME:"OpenLayers.Style"});OpenLayers.Style.createLiteral=function(a,b,c,d){"string"==typeof a&&-1!=a.indexOf("${")&&(a=OpenLayers.String.format(a,b,[c,d]),a=isNaN(a)||!a?a:parseFloat(a));return a}; | |
1978 OpenLayers.Style.SYMBOLIZER_PREFIXES=["Point","Line","Polygon","Text","Raster"];OpenLayers.Filter=OpenLayers.Class({initialize:function(a){OpenLayers.Util.extend(this,a)},destroy:function(){},evaluate:function(a){return!0},clone:function(){return null},toString:function(){return OpenLayers.Format&&OpenLayers.Format.CQL?OpenLayers.Format.CQL.prototype.write(this):Object.prototype.toString.call(this)},CLASS_NAME:"OpenLayers.Filter"});OpenLayers.Filter.Spatial=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,distance:null,distanceUnits:null,evaluate:function(a){var b=!1;switch(this.type){case OpenLayers.Filter.Spatial.BBOX:case OpenLayers.Filter.Spatial.INTERSECTS:if(a.geometry){var c=this.value;"OpenLayers.Bounds"==this.value.CLASS_NAME&&(c=this.value.toGeometry());a.geometry.intersects(c)&&(b=!0)}break;default:throw Error("evaluate is not implemented for this filter type.");}return b},clone:function(){var a= | |
1979 OpenLayers.Util.applyDefaults({value:this.value&&this.value.clone&&this.value.clone()},this);return new OpenLayers.Filter.Spatial(a)},CLASS_NAME:"OpenLayers.Filter.Spatial"});OpenLayers.Filter.Spatial.BBOX="BBOX";OpenLayers.Filter.Spatial.INTERSECTS="INTERSECTS";OpenLayers.Filter.Spatial.DWITHIN="DWITHIN";OpenLayers.Filter.Spatial.WITHIN="WITHIN";OpenLayers.Filter.Spatial.CONTAINS="CONTAINS";OpenLayers.Filter.FeatureId=OpenLayers.Class(OpenLayers.Filter,{fids:null,type:"FID",initialize:function(a){this.fids=[];OpenLayers.Filter.prototype.initialize.apply(this,[a])},evaluate:function(a){for(var b=0,c=this.fids.length;b<c;b++)if((a.fid||a.id)==this.fids[b])return!0;return!1},clone:function(){var a=new OpenLayers.Filter.FeatureId;OpenLayers.Util.extend(a,this);a.fids=this.fids.slice();return a},CLASS_NAME:"OpenLayers.Filter.FeatureId"});OpenLayers.Format.WFST.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs",gml:"http://www.opengis.net/gml",ogc:"http://www.opengis.net/ogc",ows:"http://www.opengis.net/ows"},defaultPrefix:"wfs",version:null,schemaLocations:null,srsName:null,extractAttributes:!0,xy:!0,stateName:null,initialize:function(a){this.stateName={};this.stateName[OpenLayers.State.INSERT]="wfs:Insert";this.stateName[OpenLayers.State.UPDATE]= | |
1980 "wfs:Update";this.stateName[OpenLayers.State.DELETE]="wfs:Delete";OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},getSrsName:function(a,b){var c=b&&b.srsName;c||(c=a&&a.layer?a.layer.projection.getCode():this.srsName);return c},read:function(a,b){b=b||{};OpenLayers.Util.applyDefaults(b,{output:"features"});"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var c={};a&&this.readNode(a,c,!0);c.features&&"features"===b.output&& | |
1981 (c=c.features);return c},readers:{wfs:{FeatureCollection:function(a,b){b.features=[];this.readChildNodes(a,b)}}},write:function(a,b){var c=this.writeNode("wfs:Transaction",{features:a,options:b}),d=this.schemaLocationAttr();d&&this.setAttributeNS(c,this.namespaces.xsi,"xsi:schemaLocation",d);return OpenLayers.Format.XML.prototype.write.apply(this,[c])},writers:{wfs:{GetFeature:function(a){var b=this.createElementNSPlus("wfs:GetFeature",{attributes:{service:"WFS",version:this.version,handle:a&&a.handle, | |
1982 outputFormat:a&&a.outputFormat,maxFeatures:a&&a.maxFeatures,"xsi:schemaLocation":this.schemaLocationAttr(a)}});if("string"==typeof this.featureType)this.writeNode("Query",a,b);else for(var c=0,d=this.featureType.length;c<d;c++)a.featureType=this.featureType[c],this.writeNode("Query",a,b);return b},Transaction:function(a){a=a||{};var b=a.options||{},c=this.createElementNSPlus("wfs:Transaction",{attributes:{service:"WFS",version:this.version,handle:b.handle}}),d,e=a.features;if(e){!0===b.multi&&OpenLayers.Util.extend(this.geometryTypes, | |
1983 {"OpenLayers.Geometry.Point":"MultiPoint","OpenLayers.Geometry.LineString":!0===this.multiCurve?"MultiCurve":"MultiLineString","OpenLayers.Geometry.Polygon":!0===this.multiSurface?"MultiSurface":"MultiPolygon"});var f,g;a=0;for(d=e.length;a<d;++a)g=e[a],(f=this.stateName[g.state])&&this.writeNode(f,{feature:g,options:b},c);!0===b.multi&&this.setGeometryTypes()}if(b.nativeElements)for(a=0,d=b.nativeElements.length;a<d;++a)this.writeNode("wfs:Native",b.nativeElements[a],c);return c},Native:function(a){return this.createElementNSPlus("wfs:Native", | |
1984 {attributes:{vendorId:a.vendorId,safeToIgnore:a.safeToIgnore},value:a.value})},Insert:function(a){var b=a.feature;a=a.options;a=this.createElementNSPlus("wfs:Insert",{attributes:{handle:a&&a.handle}});this.srsName=this.getSrsName(b);this.writeNode("feature:_typeName",b,a);return a},Update:function(a){var b=a.feature;a=a.options;a=this.createElementNSPlus("wfs:Update",{attributes:{handle:a&&a.handle,typeName:(this.featureNS?this.featurePrefix+":":"")+this.featureType}});this.featureNS&&a.setAttribute("xmlns:"+ | |
1985 this.featurePrefix,this.featureNS);var c=b.modified;null===this.geometryName||c&&void 0===c.geometry||(this.srsName=this.getSrsName(b),this.writeNode("Property",{name:this.geometryName,value:b.geometry},a));for(var d in b.attributes)void 0===b.attributes[d]||c&&c.attributes&&(!c.attributes||void 0===c.attributes[d])||this.writeNode("Property",{name:d,value:b.attributes[d]},a);this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[b.fid]}),a);return a},Property:function(a){var b=this.createElementNSPlus("wfs:Property"); | |
1986 this.writeNode("Name",a.name,b);null!==a.value&&this.writeNode("Value",a.value,b);return b},Name:function(a){return this.createElementNSPlus("wfs:Name",{value:a})},Value:function(a){var b;a instanceof OpenLayers.Geometry?(b=this.createElementNSPlus("wfs:Value"),a=this.writeNode("feature:_geometry",a).firstChild,b.appendChild(a)):b=this.createElementNSPlus("wfs:Value",{value:a});return b},Delete:function(a){var b=a.feature;a=a.options;a=this.createElementNSPlus("wfs:Delete",{attributes:{handle:a&& | |
1987 a.handle,typeName:(this.featureNS?this.featurePrefix+":":"")+this.featureType}});this.featureNS&&a.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);this.writeNode("ogc:Filter",new OpenLayers.Filter.FeatureId({fids:[b.fid]}),a);return a}}},schemaLocationAttr:function(a){a=OpenLayers.Util.extend({featurePrefix:this.featurePrefix,schema:this.schema},a);var b=OpenLayers.Util.extend({},this.schemaLocations);a.schema&&(b[a.featurePrefix]=a.schema);a=[];var c,d;for(d in b)(c=this.namespaces[d])&& | |
1988 a.push(c+" "+b[d]);return a.join(" ")||void 0},setFilterProperty:function(a){if(a.filters)for(var b=0,c=a.filters.length;b<c;++b)OpenLayers.Format.WFST.v1.prototype.setFilterProperty.call(this,a.filters[b]);else a instanceof OpenLayers.Filter.Spatial&&!a.property&&(a.property=this.geometryName)},CLASS_NAME:"OpenLayers.Format.WFST.v1"});OpenLayers.Format.OGCExceptionReport=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ogc:"http://www.opengis.net/ogc"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},defaultPrefix:"ogc",read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b={exceptionReport:null};a.documentElement&&(this.readChildNodes(a,b),null===b.exceptionReport&&(b=(new OpenLayers.Format.OWSCommon).read(a)));return b},readers:{ogc:{ServiceExceptionReport:function(a, | |
1989 b){b.exceptionReport={exceptions:[]};this.readChildNodes(a,b.exceptionReport)},ServiceException:function(a,b){var c={code:a.getAttribute("code"),locator:a.getAttribute("locator"),text:this.getChildValue(a)};b.exceptions.push(c)}}},CLASS_NAME:"OpenLayers.Format.OGCExceptionReport"});OpenLayers.Format.XML.VersionedOGC=OpenLayers.Class(OpenLayers.Format.XML,{defaultVersion:null,version:null,profile:null,allowFallback:!1,name:null,stringifyOutput:!1,parser:null,initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a]);a=this.CLASS_NAME;this.name=a.substring(a.lastIndexOf(".")+1)},getVersion:function(a,b){var c;a?(c=this.version,c||(c=a.getAttribute("version"),c||(c=this.defaultVersion))):c=b&&b.version||this.version||this.defaultVersion;return c},getParser:function(a){a= | |
1990 a||this.defaultVersion;var b=this.profile?"_"+this.profile:"";if(!this.parser||this.parser.VERSION!=a){var c=OpenLayers.Format[this.name]["v"+a.replace(/\./g,"_")+b];if(!c&&(""!==b&&this.allowFallback&&(b="",c=OpenLayers.Format[this.name]["v"+a.replace(/\./g,"_")]),!c))throw"Can't find a "+this.name+" parser for version "+a+b;this.parser=new c(this.options)}return this.parser},write:function(a,b){var c=this.getVersion(null,b);this.parser=this.getParser(c);c=this.parser.write(a,b);return!1===this.stringifyOutput? | |
1991 c:OpenLayers.Format.XML.prototype.write.apply(this,[c])},read:function(a,b){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var c=this.getVersion(a.documentElement);this.parser=this.getParser(c);var d=this.parser.read(a,b),e=this.parser.errorProperty||null;null!==e&&void 0===d[e]&&(e=new OpenLayers.Format.OGCExceptionReport,d.error=e.read(a));d.version=c;return d},CLASS_NAME:"OpenLayers.Format.XML.VersionedOGC"});OpenLayers.Filter.Logical=OpenLayers.Class(OpenLayers.Filter,{filters:null,type:null,initialize:function(a){this.filters=[];OpenLayers.Filter.prototype.initialize.apply(this,[a])},destroy:function(){this.filters=null;OpenLayers.Filter.prototype.destroy.apply(this)},evaluate:function(a){var b,c;switch(this.type){case OpenLayers.Filter.Logical.AND:b=0;for(c=this.filters.length;b<c;b++)if(!1==this.filters[b].evaluate(a))return!1;return!0;case OpenLayers.Filter.Logical.OR:b=0;for(c=this.filters.length;b< | |
1992 c;b++)if(!0==this.filters[b].evaluate(a))return!0;return!1;case OpenLayers.Filter.Logical.NOT:return!this.filters[0].evaluate(a)}},clone:function(){for(var a=[],b=0,c=this.filters.length;b<c;++b)a.push(this.filters[b].clone());return new OpenLayers.Filter.Logical({type:this.type,filters:a})},CLASS_NAME:"OpenLayers.Filter.Logical"});OpenLayers.Filter.Logical.AND="&&";OpenLayers.Filter.Logical.OR="||";OpenLayers.Filter.Logical.NOT="!";OpenLayers.Filter.Comparison=OpenLayers.Class(OpenLayers.Filter,{type:null,property:null,value:null,matchCase:!0,lowerBoundary:null,upperBoundary:null,initialize:function(a){OpenLayers.Filter.prototype.initialize.apply(this,[a]);this.type===OpenLayers.Filter.Comparison.LIKE&&void 0===a.matchCase&&(this.matchCase=null)},evaluate:function(a){a instanceof OpenLayers.Feature.Vector&&(a=a.attributes);var b=!1;a=a[this.property];switch(this.type){case OpenLayers.Filter.Comparison.EQUAL_TO:b=this.value; | |
1993 b=this.matchCase||"string"!=typeof a||"string"!=typeof b?a==b:a.toUpperCase()==b.toUpperCase();break;case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:b=this.value;b=this.matchCase||"string"!=typeof a||"string"!=typeof b?a!=b:a.toUpperCase()!=b.toUpperCase();break;case OpenLayers.Filter.Comparison.LESS_THAN:b=a<this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN:b=a>this.value;break;case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:b=a<=this.value;break;case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:b= | |
1994 a>=this.value;break;case OpenLayers.Filter.Comparison.BETWEEN:b=a>=this.lowerBoundary&&a<=this.upperBoundary;break;case OpenLayers.Filter.Comparison.LIKE:b=RegExp(this.value,"gi").test(a);break;case OpenLayers.Filter.Comparison.IS_NULL:b=null===a}return b},value2regex:function(a,b,c){if("."==a)throw Error("'.' is an unsupported wildCard character for OpenLayers.Filter.Comparison");a=a?a:"*";b=b?b:".";this.value=this.value.replace(RegExp("\\"+(c?c:"!")+"(.|$)","g"),"\\$1");this.value=this.value.replace(RegExp("\\"+ | |
1995 b,"g"),".");this.value=this.value.replace(RegExp("\\"+a,"g"),".*");this.value=this.value.replace(RegExp("\\\\.\\*","g"),"\\"+a);return this.value=this.value.replace(RegExp("\\\\\\.","g"),"\\"+b)},regex2value:function(){var a=this.value,a=a.replace(/!/g,"!!"),a=a.replace(/(\\)?\\\./g,function(a,c){return c?a:"!."}),a=a.replace(/(\\)?\\\*/g,function(a,c){return c?a:"!*"}),a=a.replace(/\\\\/g,"\\");return a=a.replace(/\.\*/g,"*")},clone:function(){return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison, | |
1996 this)},CLASS_NAME:"OpenLayers.Filter.Comparison"});OpenLayers.Filter.Comparison.EQUAL_TO="==";OpenLayers.Filter.Comparison.NOT_EQUAL_TO="!=";OpenLayers.Filter.Comparison.LESS_THAN="<";OpenLayers.Filter.Comparison.GREATER_THAN=">";OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO="<=";OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO=">=";OpenLayers.Filter.Comparison.BETWEEN="..";OpenLayers.Filter.Comparison.LIKE="~";OpenLayers.Filter.Comparison.IS_NULL="NULL";OpenLayers.Format.Filter=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.0.0",CLASS_NAME:"OpenLayers.Format.Filter"});OpenLayers.Filter.Function=OpenLayers.Class(OpenLayers.Filter,{name:null,params:null,CLASS_NAME:"OpenLayers.Filter.Function"});OpenLayers.Date={dateRegEx:/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))|Z)?$/,toISOString:function(){return"toISOString"in Date.prototype?function(a){return a.toISOString()}:function(a){return isNaN(a.getTime())?"Invalid Date":a.getUTCFullYear()+"-"+OpenLayers.Number.zeroPad(a.getUTCMonth()+1,2)+"-"+OpenLayers.Number.zeroPad(a.getUTCDate(),2)+"T"+OpenLayers.Number.zeroPad(a.getUTCHours(),2)+":"+OpenLayers.Number.zeroPad(a.getUTCMinutes(), | |
1997 2)+":"+OpenLayers.Number.zeroPad(a.getUTCSeconds(),2)+"."+OpenLayers.Number.zeroPad(a.getUTCMilliseconds(),3)+"Z"}}(),parse:function(a){var b;if((a=a.match(this.dateRegEx))&&(a[1]||a[7])){b=parseInt(a[1],10)||0;var c=parseInt(a[2],10)-1||0,d=parseInt(a[3],10)||1;b=new Date(Date.UTC(b,c,d));if(c=a[7]){var d=parseInt(a[4],10),e=parseInt(a[5],10),f=parseFloat(a[6]),g=f|0,f=Math.round(1E3*(f-g));b.setUTCHours(d,e,g,f);"Z"!==c&&(c=parseInt(c,10),a=parseInt(a[8],10)||0,a=-1E3*(60*60*c+60*a),b=new Date(b.getTime()+ | |
1998 a))}}else b=new Date("invalid");return b}};OpenLayers.Format.Filter.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"ogc",schemaLocation:null,initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},read:function(a){var b={};this.readers.ogc.Filter.apply(this,[a,b]);return b.filter},readers:{ogc:{_expression:function(a){for(var b="",c=a.firstChild;c;c= | |
1999 c.nextSibling)switch(c.nodeType){case 1:a=this.readNode(c);a.property?b+="${"+a.property+"}":void 0!==a.value&&(b+=a.value);break;case 3:case 4:b+=c.nodeValue}return b},Filter:function(a,b){var c={fids:[],filters:[]};this.readChildNodes(a,c);0<c.fids.length?b.filter=new OpenLayers.Filter.FeatureId({fids:c.fids}):0<c.filters.length&&(b.filter=c.filters[0])},FeatureId:function(a,b){var c=a.getAttribute("fid");c&&b.fids.push(c)},And:function(a,b){var c=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND}); | |
2000 this.readChildNodes(a,c);b.filters.push(c)},Or:function(a,b){var c=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.OR});this.readChildNodes(a,c);b.filters.push(c)},Not:function(a,b){var c=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.NOT});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsLessThan:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsGreaterThan:function(a, | |
2001 b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsLessThanOrEqualTo:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsGreaterThanOrEqualTo:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO});this.readChildNodes(a,c);b.filters.push(c)}, | |
2002 PropertyIsBetween:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.BETWEEN});this.readChildNodes(a,c);b.filters.push(c)},Literal:function(a,b){b.value=OpenLayers.String.numericIf(this.getChildValue(a),!0)},PropertyName:function(a,b){b.property=this.getChildValue(a)},LowerBoundary:function(a,b){b.lowerBoundary=OpenLayers.String.numericIf(this.readers.ogc._expression.call(this,a),!0)},UpperBoundary:function(a,b){b.upperBoundary=OpenLayers.String.numericIf(this.readers.ogc._expression.call(this, | |
2003 a),!0)},Intersects:function(a,b){this.readSpatial(a,b,OpenLayers.Filter.Spatial.INTERSECTS)},Within:function(a,b){this.readSpatial(a,b,OpenLayers.Filter.Spatial.WITHIN)},Contains:function(a,b){this.readSpatial(a,b,OpenLayers.Filter.Spatial.CONTAINS)},DWithin:function(a,b){this.readSpatial(a,b,OpenLayers.Filter.Spatial.DWITHIN)},Distance:function(a,b){b.distance=parseInt(this.getChildValue(a));b.distanceUnits=a.getAttribute("units")},Function:function(a,b){},PropertyIsNull:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.IS_NULL}); | |
2004 this.readChildNodes(a,c);b.filters.push(c)}}},readSpatial:function(a,b,c){c=new OpenLayers.Filter.Spatial({type:c});this.readChildNodes(a,c);c.value=c.components[0];delete c.components;b.filters.push(c)},encodeLiteral:function(a){a instanceof Date&&(a=OpenLayers.Date.toISOString(a));return a},writeOgcExpression:function(a,b){a instanceof OpenLayers.Filter.Function?this.writeNode("Function",a,b):this.writeNode("Literal",a,b);return b},write:function(a){return this.writers.ogc.Filter.apply(this,[a])}, | |
2005 writers:{ogc:{Filter:function(a){var b=this.createElementNSPlus("ogc:Filter");this.writeNode(this.getFilterType(a),a,b);return b},_featureIds:function(a){for(var b=this.createDocumentFragment(),c=0,d=a.fids.length;c<d;++c)this.writeNode("ogc:FeatureId",a.fids[c],b);return b},FeatureId:function(a){return this.createElementNSPlus("ogc:FeatureId",{attributes:{fid:a}})},And:function(a){for(var b=this.createElementNSPlus("ogc:And"),c,d=0,e=a.filters.length;d<e;++d)c=a.filters[d],this.writeNode(this.getFilterType(c), | |
2006 c,b);return b},Or:function(a){for(var b=this.createElementNSPlus("ogc:Or"),c,d=0,e=a.filters.length;d<e;++d)c=a.filters[d],this.writeNode(this.getFilterType(c),c,b);return b},Not:function(a){var b=this.createElementNSPlus("ogc:Not");a=a.filters[0];this.writeNode(this.getFilterType(a),a,b);return b},PropertyIsLessThan:function(a){var b=this.createElementNSPlus("ogc:PropertyIsLessThan");this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsGreaterThan:function(a){var b= | |
2007 this.createElementNSPlus("ogc:PropertyIsGreaterThan");this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsLessThanOrEqualTo:function(a){var b=this.createElementNSPlus("ogc:PropertyIsLessThanOrEqualTo");this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsGreaterThanOrEqualTo:function(a){var b=this.createElementNSPlus("ogc:PropertyIsGreaterThanOrEqualTo");this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b); | |
2008 return b},PropertyIsBetween:function(a){var b=this.createElementNSPlus("ogc:PropertyIsBetween");this.writeNode("PropertyName",a,b);this.writeNode("LowerBoundary",a,b);this.writeNode("UpperBoundary",a,b);return b},PropertyName:function(a){return this.createElementNSPlus("ogc:PropertyName",{value:a.property})},Literal:function(a){return this.createElementNSPlus("ogc:Literal",{value:(this.encodeLiteral||OpenLayers.Format.Filter.v1.prototype.encodeLiteral)(a)})},LowerBoundary:function(a){var b=this.createElementNSPlus("ogc:LowerBoundary"); | |
2009 this.writeOgcExpression(a.lowerBoundary,b);return b},UpperBoundary:function(a){var b=this.createElementNSPlus("ogc:UpperBoundary");this.writeNode("Literal",a.upperBoundary,b);return b},INTERSECTS:function(a){return this.writeSpatial(a,"Intersects")},WITHIN:function(a){return this.writeSpatial(a,"Within")},CONTAINS:function(a){return this.writeSpatial(a,"Contains")},DWITHIN:function(a){var b=this.writeSpatial(a,"DWithin");this.writeNode("Distance",a,b);return b},Distance:function(a){return this.createElementNSPlus("ogc:Distance", | |
2010 {attributes:{units:a.distanceUnits},value:a.distance})},Function:function(a){var b=this.createElementNSPlus("ogc:Function",{attributes:{name:a.name}});a=a.params;for(var c=0,d=a.length;c<d;c++)this.writeOgcExpression(a[c],b);return b},PropertyIsNull:function(a){var b=this.createElementNSPlus("ogc:PropertyIsNull");this.writeNode("PropertyName",a,b);return b}}},getFilterType:function(a){var b=this.filterMap[a.type];if(!b)throw"Filter writing not supported for rule type: "+a.type;return b},filterMap:{"&&":"And", | |
2011 "||":"Or","!":"Not","==":"PropertyIsEqualTo","!=":"PropertyIsNotEqualTo","<":"PropertyIsLessThan",">":"PropertyIsGreaterThan","<=":"PropertyIsLessThanOrEqualTo",">=":"PropertyIsGreaterThanOrEqualTo","..":"PropertyIsBetween","~":"PropertyIsLike",NULL:"PropertyIsNull",BBOX:"BBOX",DWITHIN:"DWITHIN",WITHIN:"WITHIN",CONTAINS:"CONTAINS",INTERSECTS:"INTERSECTS",FID:"_featureIds"},CLASS_NAME:"OpenLayers.Format.Filter.v1"});OpenLayers.Geometry=OpenLayers.Class({id:null,parent:null,bounds:null,initialize:function(){this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_")},destroy:function(){this.bounds=this.id=null},clone:function(){return new OpenLayers.Geometry},setBounds:function(a){a&&(this.bounds=a.clone())},clearBounds:function(){this.bounds=null;this.parent&&this.parent.clearBounds()},extendBounds:function(a){this.getBounds()?this.bounds.extend(a):this.setBounds(a)},getBounds:function(){null==this.bounds&&this.calculateBounds(); | |
2012 return this.bounds},calculateBounds:function(){},distanceTo:function(a,b){},getVertices:function(a){},atPoint:function(a,b,c){var d=!1;null!=this.getBounds()&&null!=a&&(b=null!=b?b:0,c=null!=c?c:0,d=(new OpenLayers.Bounds(this.bounds.left-b,this.bounds.bottom-c,this.bounds.right+b,this.bounds.top+c)).containsLonLat(a));return d},getLength:function(){return 0},getArea:function(){return 0},getCentroid:function(){return null},toString:function(){return OpenLayers.Format&&OpenLayers.Format.WKT?OpenLayers.Format.WKT.prototype.write(new OpenLayers.Feature.Vector(this)): | |
2013 Object.prototype.toString.call(this)},CLASS_NAME:"OpenLayers.Geometry"});OpenLayers.Geometry.fromWKT=function(a){var b;if(OpenLayers.Format&&OpenLayers.Format.WKT){var c=OpenLayers.Geometry.fromWKT.format;c||(c=new OpenLayers.Format.WKT,OpenLayers.Geometry.fromWKT.format=c);a=c.read(a);if(a instanceof OpenLayers.Feature.Vector)b=a.geometry;else if(OpenLayers.Util.isArray(a)){b=a.length;for(var c=Array(b),d=0;d<b;++d)c[d]=a[d].geometry;b=new OpenLayers.Geometry.Collection(c)}}return b}; | |
2014 OpenLayers.Geometry.segmentsIntersect=function(a,b,c){var d=c&&c.point;c=c&&c.tolerance;var e=!1,f=a.x1-b.x1,g=a.y1-b.y1,h=a.x2-a.x1,k=a.y2-a.y1,l=b.y2-b.y1,m=b.x2-b.x1,n=l*h-m*k,l=m*g-l*f,g=h*g-k*f;0==n?0==l&&0==g&&(e=!0):(f=l/n,n=g/n,0<=f&&(1>=f&&0<=n&&1>=n)&&(d?(h=a.x1+f*h,n=a.y1+f*k,e=new OpenLayers.Geometry.Point(h,n)):e=!0));if(c)if(e){if(d)a:for(a=[a,b],b=0;2>b;++b)for(f=a[b],k=1;3>k;++k)if(h=f["x"+k],n=f["y"+k],d=Math.sqrt(Math.pow(h-e.x,2)+Math.pow(n-e.y,2)),d<c){e.x=h;e.y=n;break a}}else a:for(a= | |
2015 [a,b],b=0;2>b;++b)for(h=a[b],n=a[(b+1)%2],k=1;3>k;++k)if(f={x:h["x"+k],y:h["y"+k]},g=OpenLayers.Geometry.distanceToSegment(f,n),g.distance<c){e=d?new OpenLayers.Geometry.Point(f.x,f.y):!0;break a}return e};OpenLayers.Geometry.distanceToSegment=function(a,b){var c=OpenLayers.Geometry.distanceSquaredToSegment(a,b);c.distance=Math.sqrt(c.distance);return c}; | |
2016 OpenLayers.Geometry.distanceSquaredToSegment=function(a,b){var c=a.x,d=a.y,e=b.x1,f=b.y1,g=b.x2,h=b.y2,k=g-e,l=h-f,m=(k*(c-e)+l*(d-f))/(Math.pow(k,2)+Math.pow(l,2));0>=m||(1<=m?(e=g,f=h):(e+=m*k,f+=m*l));return{distance:Math.pow(e-c,2)+Math.pow(f-d,2),x:e,y:f,along:m}};OpenLayers.Geometry.Point=OpenLayers.Class(OpenLayers.Geometry,{x:null,y:null,initialize:function(a,b){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.x=parseFloat(a);this.y=parseFloat(b)},clone:function(a){null==a&&(a=new OpenLayers.Geometry.Point(this.x,this.y));OpenLayers.Util.applyDefaults(a,this);return a},calculateBounds:function(){this.bounds=new OpenLayers.Bounds(this.x,this.y,this.x,this.y)},distanceTo:function(a,b){var c=!(b&&!1===b.edge)&&b&&b.details,d,e,f,g,h;a instanceof | |
2017 OpenLayers.Geometry.Point?(e=this.x,f=this.y,g=a.x,h=a.y,d=Math.sqrt(Math.pow(e-g,2)+Math.pow(f-h,2)),d=c?{x0:e,y0:f,x1:g,y1:h,distance:d}:d):(d=a.distanceTo(this,b),c&&(d={x0:d.x1,y0:d.y1,x1:d.x0,y1:d.y0,distance:d.distance}));return d},equals:function(a){var b=!1;null!=a&&(b=this.x==a.x&&this.y==a.y||isNaN(this.x)&&isNaN(this.y)&&isNaN(a.x)&&isNaN(a.y));return b},toShortString:function(){return this.x+", "+this.y},move:function(a,b){this.x+=a;this.y+=b;this.clearBounds()},rotate:function(a,b){a*= | |
2018 Math.PI/180;var c=this.distanceTo(b),d=a+Math.atan2(this.y-b.y,this.x-b.x);this.x=b.x+c*Math.cos(d);this.y=b.y+c*Math.sin(d);this.clearBounds()},getCentroid:function(){return new OpenLayers.Geometry.Point(this.x,this.y)},resize:function(a,b,c){this.x=b.x+a*(void 0==c?1:c)*(this.x-b.x);this.y=b.y+a*(this.y-b.y);this.clearBounds();return this},intersects:function(a){var b=!1;return b="OpenLayers.Geometry.Point"==a.CLASS_NAME?this.equals(a):a.intersects(this)},transform:function(a,b){a&&b&&(OpenLayers.Projection.transform(this, | |
2019 a,b),this.bounds=null);return this},getVertices:function(a){return[this]},CLASS_NAME:"OpenLayers.Geometry.Point"});OpenLayers.Geometry.Collection=OpenLayers.Class(OpenLayers.Geometry,{components:null,componentTypes:null,initialize:function(a){OpenLayers.Geometry.prototype.initialize.apply(this,arguments);this.components=[];null!=a&&this.addComponents(a)},destroy:function(){this.components.length=0;this.components=null;OpenLayers.Geometry.prototype.destroy.apply(this,arguments)},clone:function(){for(var a=eval("new "+this.CLASS_NAME+"()"),b=0,c=this.components.length;b<c;b++)a.addComponent(this.components[b].clone()); | |
2020 OpenLayers.Util.applyDefaults(a,this);return a},getComponentsString:function(){for(var a=[],b=0,c=this.components.length;b<c;b++)a.push(this.components[b].toShortString());return a.join(",")},calculateBounds:function(){this.bounds=null;var a=new OpenLayers.Bounds,b=this.components;if(b)for(var c=0,d=b.length;c<d;c++)a.extend(b[c].getBounds());null!=a.left&&(null!=a.bottom&&null!=a.right&&null!=a.top)&&this.setBounds(a)},addComponents:function(a){OpenLayers.Util.isArray(a)||(a=[a]);for(var b=0,c=a.length;b< | |
2021 c;b++)this.addComponent(a[b])},addComponent:function(a,b){var c=!1;if(a&&(null==this.componentTypes||-1<OpenLayers.Util.indexOf(this.componentTypes,a.CLASS_NAME))){if(null!=b&&b<this.components.length){var c=this.components.slice(0,b),d=this.components.slice(b,this.components.length);c.push(a);this.components=c.concat(d)}else this.components.push(a);a.parent=this;this.clearBounds();c=!0}return c},removeComponents:function(a){var b=!1;OpenLayers.Util.isArray(a)||(a=[a]);for(var c=a.length-1;0<=c;--c)b= | |
2022 this.removeComponent(a[c])||b;return b},removeComponent:function(a){OpenLayers.Util.removeItem(this.components,a);this.clearBounds();return!0},getLength:function(){for(var a=0,b=0,c=this.components.length;b<c;b++)a+=this.components[b].getLength();return a},getArea:function(){for(var a=0,b=0,c=this.components.length;b<c;b++)a+=this.components[b].getArea();return a},getGeodesicArea:function(a){for(var b=0,c=0,d=this.components.length;c<d;c++)b+=this.components[c].getGeodesicArea(a);return b},getCentroid:function(a){if(!a)return this.components.length&& | |
2023 this.components[0].getCentroid();a=this.components.length;if(!a)return!1;for(var b=[],c=[],d=0,e=Number.MAX_VALUE,f,g=0;g<a;++g){f=this.components[g];var h=f.getArea();f=f.getCentroid(!0);isNaN(h)||(isNaN(f.x)||isNaN(f.y))||(b.push(h),d+=h,e=h<e&&0<h?h:e,c.push(f))}a=b.length;if(0===d){for(g=0;g<a;++g)b[g]=1;d=b.length}else{for(g=0;g<a;++g)b[g]/=e;d/=e}for(var k=e=0,g=0;g<a;++g)f=c[g],h=b[g],e+=f.x*h,k+=f.y*h;return new OpenLayers.Geometry.Point(e/d,k/d)},getGeodesicLength:function(a){for(var b=0, | |
2024 c=0,d=this.components.length;c<d;c++)b+=this.components[c].getGeodesicLength(a);return b},move:function(a,b){for(var c=0,d=this.components.length;c<d;c++)this.components[c].move(a,b)},rotate:function(a,b){for(var c=0,d=this.components.length;c<d;++c)this.components[c].rotate(a,b)},resize:function(a,b,c){for(var d=0;d<this.components.length;++d)this.components[d].resize(a,b,c);return this},distanceTo:function(a,b){for(var c=!(b&&!1===b.edge)&&b&&b.details,d,e,f,g=Number.POSITIVE_INFINITY,h=0,k=this.components.length;h< | |
2025 k&&!(d=this.components[h].distanceTo(a,b),f=c?d.distance:d,f<g&&(g=f,e=d,0==g));++h);return e},equals:function(a){var b=!0;if(a&&a.CLASS_NAME&&this.CLASS_NAME==a.CLASS_NAME)if(OpenLayers.Util.isArray(a.components)&&a.components.length==this.components.length)for(var c=0,d=this.components.length;c<d;++c){if(!this.components[c].equals(a.components[c])){b=!1;break}}else b=!1;else b=!1;return b},transform:function(a,b){if(a&&b){for(var c=0,d=this.components.length;c<d;c++)this.components[c].transform(a, | |
2026 b);this.bounds=null}return this},intersects:function(a){for(var b=!1,c=0,d=this.components.length;c<d&&!(b=a.intersects(this.components[c]));++c);return b},getVertices:function(a){for(var b=[],c=0,d=this.components.length;c<d;++c)Array.prototype.push.apply(b,this.components[c].getVertices(a));return b},CLASS_NAME:"OpenLayers.Geometry.Collection"});OpenLayers.Geometry.MultiPoint=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Point"],addPoint:function(a,b){this.addComponent(a,b)},removePoint:function(a){this.removeComponent(a)},CLASS_NAME:"OpenLayers.Geometry.MultiPoint"});OpenLayers.Geometry.Curve=OpenLayers.Class(OpenLayers.Geometry.MultiPoint,{componentTypes:["OpenLayers.Geometry.Point"],getLength:function(){var a=0;if(this.components&&1<this.components.length)for(var b=1,c=this.components.length;b<c;b++)a+=this.components[b-1].distanceTo(this.components[b]);return a},getGeodesicLength:function(a){var b=this;if(a){var c=new OpenLayers.Projection("EPSG:4326");c.equals(a)||(b=this.clone().transform(a,c))}a=0;if(b.components&&1<b.components.length)for(var d,e=1,f=b.components.length;e< | |
2027 f;e++)c=b.components[e-1],d=b.components[e],a+=OpenLayers.Util.distVincenty({lon:c.x,lat:c.y},{lon:d.x,lat:d.y});return 1E3*a},CLASS_NAME:"OpenLayers.Geometry.Curve"});OpenLayers.Geometry.LineString=OpenLayers.Class(OpenLayers.Geometry.Curve,{removeComponent:function(a){var b=this.components&&2<this.components.length;b&&OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,arguments);return b},intersects:function(a){var b=!1,c=a.CLASS_NAME;if("OpenLayers.Geometry.LineString"==c||"OpenLayers.Geometry.LinearRing"==c||"OpenLayers.Geometry.Point"==c){var d=this.getSortedSegments();a="OpenLayers.Geometry.Point"==c?[{x1:a.x,y1:a.y,x2:a.x,y2:a.y}]:a.getSortedSegments(); | |
2028 var e,f,g,h,k,l,m,n=0,p=d.length;a:for(;n<p;++n){c=d[n];e=c.x1;f=c.x2;g=c.y1;h=c.y2;var q=0,r=a.length;for(;q<r;++q){k=a[q];if(k.x1>f)break;if(!(k.x2<e||(l=k.y1,m=k.y2,Math.min(l,m)>Math.max(g,h)||Math.max(l,m)<Math.min(g,h)||!OpenLayers.Geometry.segmentsIntersect(c,k)))){b=!0;break a}}}}else b=a.intersects(this);return b},getSortedSegments:function(){for(var a=this.components.length-1,b=Array(a),c,d,e=0;e<a;++e)c=this.components[e],d=this.components[e+1],b[e]=c.x<d.x?{x1:c.x,y1:c.y,x2:d.x,y2:d.y}: | |
2029 {x1:d.x,y1:d.y,x2:c.x,y2:c.y};return b.sort(function(a,b){return a.x1-b.x1})},splitWithSegment:function(a,b){for(var c=!(b&&!1===b.edge),d=b&&b.tolerance,e=[],f=this.getVertices(),g=[],h=[],k=!1,l,m,n,p={point:!0,tolerance:d},q=null,r=0,s=f.length-2;r<=s;++r)if(d=f[r],g.push(d.clone()),l=f[r+1],m={x1:d.x,y1:d.y,x2:l.x,y2:l.y},m=OpenLayers.Geometry.segmentsIntersect(a,m,p),m instanceof OpenLayers.Geometry.Point&&((n=m.x===a.x1&&m.y===a.y1||m.x===a.x2&&m.y===a.y2||m.equals(d)||m.equals(l)?!0:!1)||c))m.equals(h[h.length- | |
2030 1])||h.push(m.clone()),0===r&&m.equals(d)||m.equals(l)||(k=!0,m.equals(d)||g.push(m),e.push(new OpenLayers.Geometry.LineString(g)),g=[m.clone()]);k&&(g.push(l.clone()),e.push(new OpenLayers.Geometry.LineString(g)));if(0<h.length)var t=a.x1<a.x2?1:-1,u=a.y1<a.y2?1:-1,q={lines:e,points:h.sort(function(a,b){return t*a.x-t*b.x||u*a.y-u*b.y})};return q},split:function(a,b){var c=null,d=b&&b.mutual,e,f,g,h;if(a instanceof OpenLayers.Geometry.LineString){var k=this.getVertices(),l,m,n,p,q,r=[];g=[];for(var s= | |
2031 0,t=k.length-2;s<=t;++s){l=k[s];m=k[s+1];n={x1:l.x,y1:l.y,x2:m.x,y2:m.y};h=h||[a];d&&r.push(l.clone());for(var u=0;u<h.length;++u)if(p=h[u].splitWithSegment(n,b))if(q=p.lines,0<q.length&&(q.unshift(u,1),Array.prototype.splice.apply(h,q),u+=q.length-2),d)for(var v=0,w=p.points.length;v<w;++v)q=p.points[v],q.equals(l)||(r.push(q),g.push(new OpenLayers.Geometry.LineString(r)),r=q.equals(m)?[]:[q.clone()])}d&&(0<g.length&&0<r.length)&&(r.push(m.clone()),g.push(new OpenLayers.Geometry.LineString(r)))}else c= | |
2032 a.splitWith(this,b);h&&1<h.length?f=!0:h=[];g&&1<g.length?e=!0:g=[];if(f||e)c=d?[g,h]:h;return c},splitWith:function(a,b){return a.split(this,b)},getVertices:function(a){return!0===a?[this.components[0],this.components[this.components.length-1]]:!1===a?this.components.slice(1,this.components.length-1):this.components.slice()},distanceTo:function(a,b){var c=!(b&&!1===b.edge)&&b&&b.details,d,e={},f=Number.POSITIVE_INFINITY;if(a instanceof OpenLayers.Geometry.Point){for(var g=this.getSortedSegments(), | |
2033 h=a.x,k=a.y,l,m=0,n=g.length;m<n;++m)if(l=g[m],d=OpenLayers.Geometry.distanceToSegment(a,l),d.distance<f){if(f=d.distance,e=d,0===f)break}else if(l.x2>h&&(k>l.y1&&k<l.y2||k<l.y1&&k>l.y2))break;e=c?{distance:e.distance,x0:e.x,y0:e.y,x1:h,y1:k}:e.distance}else if(a instanceof OpenLayers.Geometry.LineString){var g=this.getSortedSegments(),h=a.getSortedSegments(),p,q,r=h.length,s={point:!0},m=0,n=g.length;a:for(;m<n;++m){k=g[m];l=k.x1;q=k.y1;for(var t=0;t<r;++t)if(d=h[t],p=OpenLayers.Geometry.segmentsIntersect(k, | |
2034 d,s)){f=0;e={distance:0,x0:p.x,y0:p.y,x1:p.x,y1:p.y};break a}else d=OpenLayers.Geometry.distanceToSegment({x:l,y:q},d),d.distance<f&&(f=d.distance,e={distance:f,x0:l,y0:q,x1:d.x,y1:d.y})}c||(e=e.distance);0!==f&&k&&(d=a.distanceTo(new OpenLayers.Geometry.Point(k.x2,k.y2),b),m=c?d.distance:d,m<f&&(e=c?{distance:f,x0:d.x1,y0:d.y1,x1:d.x0,y1:d.y0}:m))}else e=a.distanceTo(this,b),c&&(e={distance:e.distance,x0:e.x1,y0:e.y1,x1:e.x0,y1:e.y0});return e},simplify:function(a){if(this&&null!==this){var b=this.getVertices(); | |
2035 if(3>b.length)return this;var c=function(a,b,d,k){for(var l=0,m=0,n=b,p;n<d;n++){p=a[b];var q=a[d],r=a[n],r=Math.abs(0.5*(p.x*q.y+q.x*r.y+r.x*p.y-q.x*p.y-r.x*q.y-p.x*r.y));p=Math.sqrt(Math.pow(p.x-q.x,2)+Math.pow(p.y-q.y,2));p=2*(r/p);p>l&&(l=p,m=n)}l>k&&m!=b&&(e.push(m),c(a,b,m,k),c(a,m,d,k))},d=b.length-1,e=[];e.push(0);for(e.push(d);b[0].equals(b[d]);)d--,e.push(d);c(b,0,d,a);a=[];e.sort(function(a,b){return a-b});for(d=0;d<e.length;d++)a.push(b[e[d]]);return new OpenLayers.Geometry.LineString(a)}return this}, | |
2036 CLASS_NAME:"OpenLayers.Geometry.LineString"});OpenLayers.Geometry.MultiLineString=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LineString"],split:function(a,b){for(var c=null,d=b&&b.mutual,e,f,g,h,k=[],l=[a],m=0,n=this.components.length;m<n;++m){f=this.components[m];g=!1;for(var p=0;p<l.length;++p)if(e=f.split(l[p],b)){if(d){g=e[0];for(var q=0,r=g.length;q<r;++q)0===q&&k.length?k[k.length-1].addComponent(g[q]):k.push(new OpenLayers.Geometry.MultiLineString([g[q]]));g=!0;e=e[1]}if(e.length){e.unshift(p, | |
2037 1);Array.prototype.splice.apply(l,e);break}}g||(k.length?k[k.length-1].addComponent(f.clone()):k=[new OpenLayers.Geometry.MultiLineString(f.clone())])}k&&1<k.length?g=!0:k=[];l&&1<l.length?h=!0:l=[];if(g||h)c=d?[k,l]:l;return c},splitWith:function(a,b){var c=null,d=b&&b.mutual,e,f,g,h,k,l;if(a instanceof OpenLayers.Geometry.LineString){l=[];k=[a];for(var m=0,n=this.components.length;m<n;++m){g=!1;f=this.components[m];for(var p=0;p<k.length;++p)if(e=k[p].split(f,b)){d&&(g=e[0],g.length&&(g.unshift(p, | |
2038 1),Array.prototype.splice.apply(k,g),p+=g.length-2),e=e[1],0===e.length&&(e=[f.clone()]));g=0;for(var q=e.length;g<q;++g)0===g&&l.length?l[l.length-1].addComponent(e[g]):l.push(new OpenLayers.Geometry.MultiLineString([e[g]]));g=!0}g||(l.length?l[l.length-1].addComponent(f.clone()):l=[new OpenLayers.Geometry.MultiLineString([f.clone()])])}}else c=a.split(this);k&&1<k.length?h=!0:k=[];l&&1<l.length?g=!0:l=[];if(h||g)c=d?[k,l]:l;return c},CLASS_NAME:"OpenLayers.Geometry.MultiLineString"});OpenLayers.Geometry.LinearRing=OpenLayers.Class(OpenLayers.Geometry.LineString,{componentTypes:["OpenLayers.Geometry.Point"],addComponent:function(a,b){var c=!1,d=this.components.pop();null==b&&a.equals(d)||(c=OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,arguments));OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[this.components[0]]);return c},removeComponent:function(a){var b=this.components&&3<this.components.length;b&&(this.components.pop(),OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this, | |
2039 arguments),OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,[this.components[0]]));return b},move:function(a,b){for(var c=0,d=this.components.length;c<d-1;c++)this.components[c].move(a,b)},rotate:function(a,b){for(var c=0,d=this.components.length;c<d-1;++c)this.components[c].rotate(a,b)},resize:function(a,b,c){for(var d=0,e=this.components.length;d<e-1;++d)this.components[d].resize(a,b,c);return this},transform:function(a,b){if(a&&b){for(var c=0,d=this.components.length;c<d-1;c++)this.components[c].transform(a, | |
2040 b);this.bounds=null}return this},getCentroid:function(){if(this.components){var a=this.components.length;if(0<a&&2>=a)return this.components[0].clone();if(2<a){var b=0,c=0,d=this.components[0].x,e=this.components[0].y,f=-1*this.getArea();if(0!=f){for(var g=0;g<a-1;g++)var h=this.components[g],k=this.components[g+1],b=b+(h.x+k.x-2*d)*((h.x-d)*(k.y-e)-(k.x-d)*(h.y-e)),c=c+(h.y+k.y-2*e)*((h.x-d)*(k.y-e)-(k.x-d)*(h.y-e));b=d+b/(6*f);a=e+c/(6*f)}else{for(g=0;g<a-1;g++)b+=this.components[g].x,c+=this.components[g].y; | |
2041 b/=a-1;a=c/(a-1)}return new OpenLayers.Geometry.Point(b,a)}return null}},getArea:function(){var a=0;if(this.components&&2<this.components.length){for(var b=a=0,c=this.components.length;b<c-1;b++)var d=this.components[b],e=this.components[b+1],a=a+(d.x+e.x)*(e.y-d.y);a=-a/2}return a},getGeodesicArea:function(a){var b=this;if(a){var c=new OpenLayers.Projection("EPSG:4326");c.equals(a)||(b=this.clone().transform(a,c))}a=0;c=b.components&&b.components.length;if(2<c){for(var d,e,f=0;f<c-1;f++)d=b.components[f], | |
2042 e=b.components[f+1],a+=OpenLayers.Util.rad(e.x-d.x)*(2+Math.sin(OpenLayers.Util.rad(d.y))+Math.sin(OpenLayers.Util.rad(e.y)));a=40680631590769*a/2}return a},containsPoint:function(a){var b=OpenLayers.Number.limitSigDigs,c=b(a.x,14);a=b(a.y,14);for(var d=this.components.length-1,e,f,g,h,k,l=0,m=0;m<d;++m)if(e=this.components[m],g=b(e.x,14),e=b(e.y,14),f=this.components[m+1],h=b(f.x,14),f=b(f.y,14),e==f){if(a==e&&(g<=h&&c>=g&&c<=h||g>=h&&c<=g&&c>=h)){l=-1;break}}else{k=b((a-f)*((h-g)/(f-e))+h,14);if(k== | |
2043 c&&(e<f&&a>=e&&a<=f||e>f&&a<=e&&a>=f)){l=-1;break}k<=c||g!=h&&(k<Math.min(g,h)||k>Math.max(g,h))||(e<f&&a>=e&&a<f||e>f&&a<e&&a>=f)&&++l}return-1==l?1:!!(l&1)},intersects:function(a){var b=!1;if("OpenLayers.Geometry.Point"==a.CLASS_NAME)b=this.containsPoint(a);else if("OpenLayers.Geometry.LineString"==a.CLASS_NAME)b=a.intersects(this);else if("OpenLayers.Geometry.LinearRing"==a.CLASS_NAME)b=OpenLayers.Geometry.LineString.prototype.intersects.apply(this,[a]);else for(var c=0,d=a.components.length;c< | |
2044 d&&!(b=a.components[c].intersects(this));++c);return b},getVertices:function(a){return!0===a?[]:this.components.slice(0,this.components.length-1)},CLASS_NAME:"OpenLayers.Geometry.LinearRing"});OpenLayers.Geometry.Polygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.LinearRing"],getArea:function(){var a=0;if(this.components&&0<this.components.length)for(var a=a+Math.abs(this.components[0].getArea()),b=1,c=this.components.length;b<c;b++)a-=Math.abs(this.components[b].getArea());return a},getGeodesicArea:function(a){var b=0;if(this.components&&0<this.components.length)for(var b=b+Math.abs(this.components[0].getGeodesicArea(a)),c=1,d=this.components.length;c< | |
2045 d;c++)b-=Math.abs(this.components[c].getGeodesicArea(a));return b},containsPoint:function(a){var b=this.components.length,c=!1;if(0<b&&(c=this.components[0].containsPoint(a),1!==c&&c&&1<b))for(var d,e=1;e<b;++e)if(d=this.components[e].containsPoint(a)){c=1===d?1:!1;break}return c},intersects:function(a){var b=!1,c,d;if("OpenLayers.Geometry.Point"==a.CLASS_NAME)b=this.containsPoint(a);else if("OpenLayers.Geometry.LineString"==a.CLASS_NAME||"OpenLayers.Geometry.LinearRing"==a.CLASS_NAME){c=0;for(d= | |
2046 this.components.length;c<d&&!(b=a.intersects(this.components[c]));++c);if(!b)for(c=0,d=a.components.length;c<d&&!(b=this.containsPoint(a.components[c]));++c);}else for(c=0,d=a.components.length;c<d&&!(b=this.intersects(a.components[c]));++c);if(!b&&"OpenLayers.Geometry.Polygon"==a.CLASS_NAME){var e=this.components[0];c=0;for(d=e.components.length;c<d&&!(b=a.containsPoint(e.components[c]));++c);}return b},distanceTo:function(a,b){return b&&!1===b.edge&&this.intersects(a)?0:OpenLayers.Geometry.Collection.prototype.distanceTo.apply(this, | |
2047 [a,b])},CLASS_NAME:"OpenLayers.Geometry.Polygon"});OpenLayers.Geometry.Polygon.createRegularPolygon=function(a,b,c,d){var e=Math.PI*(1/c-0.5);d&&(e+=d/180*Math.PI);for(var f,g=[],h=0;h<c;++h)f=e+2*h*Math.PI/c,d=a.x+b*Math.cos(f),f=a.y+b*Math.sin(f),g.push(new OpenLayers.Geometry.Point(d,f));a=new OpenLayers.Geometry.LinearRing(g);return new OpenLayers.Geometry.Polygon([a])};OpenLayers.Geometry.MultiPolygon=OpenLayers.Class(OpenLayers.Geometry.Collection,{componentTypes:["OpenLayers.Geometry.Polygon"],CLASS_NAME:"OpenLayers.Geometry.MultiPolygon"});OpenLayers.Format.GML=OpenLayers.Class(OpenLayers.Format.XML,{featureNS:"http://mapserver.gis.umn.edu/mapserver",featurePrefix:"feature",featureName:"featureMember",layerName:"features",geometryName:"geometry",collectionName:"FeatureCollection",gmlns:"http://www.opengis.net/gml",extractAttributes:!0,xy:!0,initialize:function(a){this.regExes={trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g};OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},read:function(a){"string"== | |
2048 typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a=this.getElementsByTagNameNS(a.documentElement,this.gmlns,this.featureName);for(var b=[],c=0;c<a.length;c++){var d=this.parseFeature(a[c]);d&&b.push(d)}return b},parseFeature:function(a){for(var b="MultiPolygon Polygon MultiLineString LineString MultiPoint Point Envelope".split(" "),c,d,e,f=0;f<b.length;++f)if(c=b[f],d=this.getElementsByTagNameNS(a,this.gmlns,c),0<d.length){if(e=this.parseGeometry[c.toLowerCase()])e=e.apply(this, | |
2049 [d[0]]),this.internalProjection&&this.externalProjection&&e.transform(this.externalProjection,this.internalProjection);else throw new TypeError("Unsupported geometry type: "+c);break}var g;c=this.getElementsByTagNameNS(a,this.gmlns,"Box");for(f=0;f<c.length;++f)b=c[f],d=this.parseGeometry.box.apply(this,[b]),b=b.parentNode,"boundedBy"===(b.localName||b.nodeName.split(":").pop())?g=d:e=d.toGeometry();var h;this.extractAttributes&&(h=this.parseAttributes(a));h=new OpenLayers.Feature.Vector(e,h);h.bounds= | |
2050 g;h.gml={featureType:a.firstChild.nodeName.split(":")[1],featureNS:a.firstChild.namespaceURI,featureNSPrefix:a.firstChild.prefix};a=a.firstChild;for(var k;a&&(1!=a.nodeType||!(k=a.getAttribute("fid")||a.getAttribute("id")));)a=a.nextSibling;h.fid=k;return h},parseGeometry:{point:function(a){var b,c;c=[];b=this.getElementsByTagNameNS(a,this.gmlns,"pos");0<b.length&&(c=b[0].firstChild.nodeValue,c=c.replace(this.regExes.trimSpace,""),c=c.split(this.regExes.splitSpace));0==c.length&&(b=this.getElementsByTagNameNS(a, | |
2051 this.gmlns,"coordinates"),0<b.length&&(c=b[0].firstChild.nodeValue,c=c.replace(this.regExes.removeSpace,""),c=c.split(",")));0==c.length&&(b=this.getElementsByTagNameNS(a,this.gmlns,"coord"),0<b.length&&(a=this.getElementsByTagNameNS(b[0],this.gmlns,"X"),b=this.getElementsByTagNameNS(b[0],this.gmlns,"Y"),0<a.length&&0<b.length&&(c=[a[0].firstChild.nodeValue,b[0].firstChild.nodeValue])));2==c.length&&(c[2]=null);return this.xy?new OpenLayers.Geometry.Point(c[0],c[1],c[2]):new OpenLayers.Geometry.Point(c[1], | |
2052 c[0],c[2])},multipoint:function(a){a=this.getElementsByTagNameNS(a,this.gmlns,"Point");var b=[];if(0<a.length)for(var c,d=0;d<a.length;++d)(c=this.parseGeometry.point.apply(this,[a[d]]))&&b.push(c);return new OpenLayers.Geometry.MultiPoint(b)},linestring:function(a,b){var c,d;d=[];var e=[];c=this.getElementsByTagNameNS(a,this.gmlns,"posList");if(0<c.length){d=this.getChildValue(c[0]);d=d.replace(this.regExes.trimSpace,"");d=d.split(this.regExes.splitSpace);var f=parseInt(c[0].getAttribute("dimension")), | |
2053 g,h,k;for(c=0;c<d.length/f;++c)g=c*f,h=d[g],k=d[g+1],g=2==f?null:d[g+2],this.xy?e.push(new OpenLayers.Geometry.Point(h,k,g)):e.push(new OpenLayers.Geometry.Point(k,h,g))}if(0==d.length&&(c=this.getElementsByTagNameNS(a,this.gmlns,"coordinates"),0<c.length))for(d=this.getChildValue(c[0]),d=d.replace(this.regExes.trimSpace,""),d=d.replace(this.regExes.trimComma,","),f=d.split(this.regExes.splitSpace),c=0;c<f.length;++c)d=f[c].split(","),2==d.length&&(d[2]=null),this.xy?e.push(new OpenLayers.Geometry.Point(d[0], | |
2054 d[1],d[2])):e.push(new OpenLayers.Geometry.Point(d[1],d[0],d[2]));d=null;0!=e.length&&(d=b?new OpenLayers.Geometry.LinearRing(e):new OpenLayers.Geometry.LineString(e));return d},multilinestring:function(a){a=this.getElementsByTagNameNS(a,this.gmlns,"LineString");var b=[];if(0<a.length)for(var c,d=0;d<a.length;++d)(c=this.parseGeometry.linestring.apply(this,[a[d]]))&&b.push(c);return new OpenLayers.Geometry.MultiLineString(b)},polygon:function(a){a=this.getElementsByTagNameNS(a,this.gmlns,"LinearRing"); | |
2055 var b=[];if(0<a.length)for(var c,d=0;d<a.length;++d)(c=this.parseGeometry.linestring.apply(this,[a[d],!0]))&&b.push(c);return new OpenLayers.Geometry.Polygon(b)},multipolygon:function(a){a=this.getElementsByTagNameNS(a,this.gmlns,"Polygon");var b=[];if(0<a.length)for(var c,d=0;d<a.length;++d)(c=this.parseGeometry.polygon.apply(this,[a[d]]))&&b.push(c);return new OpenLayers.Geometry.MultiPolygon(b)},envelope:function(a){var b=[],c,d,e=this.getElementsByTagNameNS(a,this.gmlns,"lowerCorner");if(0<e.length){c= | |
2056 [];0<e.length&&(c=e[0].firstChild.nodeValue,c=c.replace(this.regExes.trimSpace,""),c=c.split(this.regExes.splitSpace));2==c.length&&(c[2]=null);var f=this.xy?new OpenLayers.Geometry.Point(c[0],c[1],c[2]):new OpenLayers.Geometry.Point(c[1],c[0],c[2])}a=this.getElementsByTagNameNS(a,this.gmlns,"upperCorner");if(0<a.length){c=[];0<a.length&&(c=a[0].firstChild.nodeValue,c=c.replace(this.regExes.trimSpace,""),c=c.split(this.regExes.splitSpace));2==c.length&&(c[2]=null);var g=this.xy?new OpenLayers.Geometry.Point(c[0], | |
2057 c[1],c[2]):new OpenLayers.Geometry.Point(c[1],c[0],c[2])}f&&g&&(b.push(new OpenLayers.Geometry.Point(f.x,f.y)),b.push(new OpenLayers.Geometry.Point(g.x,f.y)),b.push(new OpenLayers.Geometry.Point(g.x,g.y)),b.push(new OpenLayers.Geometry.Point(f.x,g.y)),b.push(new OpenLayers.Geometry.Point(f.x,f.y)),b=new OpenLayers.Geometry.LinearRing(b),d=new OpenLayers.Geometry.Polygon([b]));return d},box:function(a){var b=this.getElementsByTagNameNS(a,this.gmlns,"coordinates"),c=a=null;0<b.length&&(b=b[0].firstChild.nodeValue, | |
2058 b=b.split(" "),2==b.length&&(a=b[0].split(","),c=b[1].split(",")));if(null!==a&&null!==c)return new OpenLayers.Bounds(parseFloat(a[0]),parseFloat(a[1]),parseFloat(c[0]),parseFloat(c[1]))}},parseAttributes:function(a){var b={};a=a.firstChild;for(var c,d,e;a;){if(1==a.nodeType){a=a.childNodes;for(c=0;c<a.length;++c)if(d=a[c],1==d.nodeType)if(e=d.childNodes,1==e.length){if(e=e[0],3==e.nodeType||4==e.nodeType)d=d.prefix?d.nodeName.split(":")[1]:d.nodeName,e=e.nodeValue.replace(this.regExes.trimSpace, | |
2059 ""),b[d]=e}else b[d.nodeName.split(":").pop()]=null;break}a=a.nextSibling}return b},write:function(a){OpenLayers.Util.isArray(a)||(a=[a]);for(var b=this.createElementNS("http://www.opengis.net/wfs","wfs:"+this.collectionName),c=0;c<a.length;c++)b.appendChild(this.createFeatureXML(a[c]));return OpenLayers.Format.XML.prototype.write.apply(this,[b])},createFeatureXML:function(a){var b=this.buildGeometryNode(a.geometry),c=this.createElementNS(this.featureNS,this.featurePrefix+":"+this.geometryName);c.appendChild(b); | |
2060 var b=this.createElementNS(this.gmlns,"gml:"+this.featureName),d=this.createElementNS(this.featureNS,this.featurePrefix+":"+this.layerName);d.setAttribute("fid",a.fid||a.id);d.appendChild(c);for(var e in a.attributes){var c=this.createTextNode(a.attributes[e]),f=e.substring(e.lastIndexOf(":")+1),f=this.createElementNS(this.featureNS,this.featurePrefix+":"+f);f.appendChild(c);d.appendChild(f)}b.appendChild(d);return b},buildGeometryNode:function(a){this.externalProjection&&this.internalProjection&& | |
2061 (a=a.clone(),a.transform(this.internalProjection,this.externalProjection));var b=a.CLASS_NAME,b=b.substring(b.lastIndexOf(".")+1);return this.buildGeometry[b.toLowerCase()].apply(this,[a])},buildGeometry:{point:function(a){var b=this.createElementNS(this.gmlns,"gml:Point");b.appendChild(this.buildCoordinatesNode(a));return b},multipoint:function(a){var b=this.createElementNS(this.gmlns,"gml:MultiPoint");a=a.components;for(var c,d,e=0;e<a.length;e++)c=this.createElementNS(this.gmlns,"gml:pointMember"), | |
2062 d=this.buildGeometry.point.apply(this,[a[e]]),c.appendChild(d),b.appendChild(c);return b},linestring:function(a){var b=this.createElementNS(this.gmlns,"gml:LineString");b.appendChild(this.buildCoordinatesNode(a));return b},multilinestring:function(a){var b=this.createElementNS(this.gmlns,"gml:MultiLineString");a=a.components;for(var c,d,e=0;e<a.length;++e)c=this.createElementNS(this.gmlns,"gml:lineStringMember"),d=this.buildGeometry.linestring.apply(this,[a[e]]),c.appendChild(d),b.appendChild(c); | |
2063 return b},linearring:function(a){var b=this.createElementNS(this.gmlns,"gml:LinearRing");b.appendChild(this.buildCoordinatesNode(a));return b},polygon:function(a){var b=this.createElementNS(this.gmlns,"gml:Polygon");a=a.components;for(var c,d,e=0;e<a.length;++e)c=0==e?"outerBoundaryIs":"innerBoundaryIs",c=this.createElementNS(this.gmlns,"gml:"+c),d=this.buildGeometry.linearring.apply(this,[a[e]]),c.appendChild(d),b.appendChild(c);return b},multipolygon:function(a){var b=this.createElementNS(this.gmlns, | |
2064 "gml:MultiPolygon");a=a.components;for(var c,d,e=0;e<a.length;++e)c=this.createElementNS(this.gmlns,"gml:polygonMember"),d=this.buildGeometry.polygon.apply(this,[a[e]]),c.appendChild(d),b.appendChild(c);return b},bounds:function(a){var b=this.createElementNS(this.gmlns,"gml:Box");b.appendChild(this.buildCoordinatesNode(a));return b}},buildCoordinatesNode:function(a){var b=this.createElementNS(this.gmlns,"gml:coordinates");b.setAttribute("decimal",".");b.setAttribute("cs",",");b.setAttribute("ts", | |
2065 " ");var c=[];if(a instanceof OpenLayers.Bounds)c.push(a.left+","+a.bottom),c.push(a.right+","+a.top);else{a=a.components?a.components:[a];for(var d=0;d<a.length;d++)c.push(a[d].x+","+a[d].y)}c=this.createTextNode(c.join(" "));b.appendChild(c);return b},CLASS_NAME:"OpenLayers.Format.GML"});OpenLayers.Format.GML||(OpenLayers.Format.GML={}); | |
2066 OpenLayers.Format.GML.Base=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",wfs:"http://www.opengis.net/wfs"},defaultPrefix:"gml",schemaLocation:null,featureType:null,featureNS:null,geometryName:"geometry",extractAttributes:!0,srsName:null,xy:!0,geometryTypes:null,singleFeatureType:null,regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g,featureMember:/^(.*:)?featureMembers?$/}, | |
2067 initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a]);this.setGeometryTypes();a&&a.featureNS&&this.setNamespace("feature",a.featureNS);this.singleFeatureType=!a||"string"===typeof a.featureType},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b=[];this.readNode(a,{features:b},!0);if(0==b.length){var c=this.getElementsByTagNameNS(a,this.namespaces.gml,"featureMember");if(c.length){a= | |
2068 0;for(var d=c.length;a<d;++a)this.readNode(c[a],{features:b},!0)}else c=this.getElementsByTagNameNS(a,this.namespaces.gml,"featureMembers"),c.length&&this.readNode(c[0],{features:b},!0)}return b},readNode:function(a,b,c){!0===c&&!0===this.autoConfig&&(this.featureType=null,delete this.namespaceAlias[this.featureNS],delete this.namespaces.feature,this.featureNS=null);this.featureNS||(a.prefix in this.namespaces||a.parentNode.namespaceURI!=this.namespaces.gml||!this.regExes.featureMember.test(a.parentNode.nodeName))|| | |
2069 (this.featureType=a.nodeName.split(":").pop(),this.setNamespace("feature",a.namespaceURI),this.featureNS=a.namespaceURI,this.autoConfig=!0);return OpenLayers.Format.XML.prototype.readNode.apply(this,[a,b])},readers:{gml:{_inherit:function(a,b,c){},featureMember:function(a,b){this.readChildNodes(a,b)},featureMembers:function(a,b){this.readChildNodes(a,b)},name:function(a,b){b.name=this.getChildValue(a)},boundedBy:function(a,b){var c={};this.readChildNodes(a,c);c.components&&0<c.components.length&& | |
2070 (b.bounds=c.components[0])},Point:function(a,b){var c={points:[]};this.readChildNodes(a,c);b.components||(b.components=[]);b.components.push(c.points[0])},coordinates:function(a,b){for(var c=this.getChildValue(a).replace(this.regExes.trimSpace,""),c=c.replace(this.regExes.trimComma,","),c=c.split(this.regExes.splitSpace),d,e=c.length,f=Array(e),g=0;g<e;++g)d=c[g].split(","),f[g]=this.xy?new OpenLayers.Geometry.Point(d[0],d[1],d[2]):new OpenLayers.Geometry.Point(d[1],d[0],d[2]);b.points=f},coord:function(a, | |
2071 b){var c={};this.readChildNodes(a,c);b.points||(b.points=[]);b.points.push(new OpenLayers.Geometry.Point(c.x,c.y,c.z))},X:function(a,b){b.x=this.getChildValue(a)},Y:function(a,b){b.y=this.getChildValue(a)},Z:function(a,b){b.z=this.getChildValue(a)},MultiPoint:function(a,b){var c={components:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.MultiPoint(c.components)]},pointMember:function(a,b){this.readChildNodes(a,b)},LineString:function(a, | |
2072 b){var c={};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);b.components||(b.components=[]);b.components.push(new OpenLayers.Geometry.LineString(c.points))},MultiLineString:function(a,b){var c={components:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.MultiLineString(c.components)]},lineStringMember:function(a,b){this.readChildNodes(a,b)},Polygon:function(a,b){var c={outer:null,inner:[]};this.readers.gml._inherit.apply(this, | |
2073 [a,c,b]);this.readChildNodes(a,c);c.inner.unshift(c.outer);b.components||(b.components=[]);b.components.push(new OpenLayers.Geometry.Polygon(c.inner))},LinearRing:function(a,b){var c={};this.readers.gml._inherit.apply(this,[a,c]);this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.LinearRing(c.points)]},MultiPolygon:function(a,b){var c={components:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.MultiPolygon(c.components)]}, | |
2074 polygonMember:function(a,b){this.readChildNodes(a,b)},GeometryCollection:function(a,b){var c={components:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.Collection(c.components)]},geometryMember:function(a,b){this.readChildNodes(a,b)}},feature:{"*":function(a,b){var c,d=a.localName||a.nodeName.split(":").pop();b.features?this.singleFeatureType||-1===OpenLayers.Util.indexOf(this.featureType,d)?d===this.featureType&&(c="_typeName"):c= | |
2075 "_typeName":0==a.childNodes.length||1==a.childNodes.length&&3==a.firstChild.nodeType?this.extractAttributes&&(c="_attribute"):c="_geometry";c&&this.readers.feature[c].apply(this,[a,b])},_typeName:function(a,b){var c={components:[],attributes:{}};this.readChildNodes(a,c);c.name&&(c.attributes.name=c.name);var d=new OpenLayers.Feature.Vector(c.components[0],c.attributes);this.singleFeatureType||(d.type=a.nodeName.split(":").pop(),d.namespace=a.namespaceURI);var e=a.getAttribute("fid")||this.getAttributeNS(a, | |
2076 this.namespaces.gml,"id");e&&(d.fid=e);this.internalProjection&&(this.externalProjection&&d.geometry)&&d.geometry.transform(this.externalProjection,this.internalProjection);c.bounds&&(d.bounds=c.bounds);b.features.push(d)},_geometry:function(a,b){this.geometryName||(this.geometryName=a.nodeName.split(":").pop());this.readChildNodes(a,b)},_attribute:function(a,b){var c=a.localName||a.nodeName.split(":").pop(),d=this.getChildValue(a);b.attributes[c]=d}},wfs:{FeatureCollection:function(a,b){this.readChildNodes(a, | |
2077 b)}}},write:function(a){var b;b=OpenLayers.Util.isArray(a)?"featureMembers":"featureMember";a=this.writeNode("gml:"+b,a);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[a])},writers:{gml:{featureMember:function(a){var b=this.createElementNSPlus("gml:featureMember");this.writeNode("feature:_typeName",a,b);return b},MultiPoint:function(a){var b=this.createElementNSPlus("gml:MultiPoint");a=a.components||[a]; | |
2078 for(var c=0,d=a.length;c<d;++c)this.writeNode("pointMember",a[c],b);return b},pointMember:function(a){var b=this.createElementNSPlus("gml:pointMember");this.writeNode("Point",a,b);return b},MultiLineString:function(a){var b=this.createElementNSPlus("gml:MultiLineString");a=a.components||[a];for(var c=0,d=a.length;c<d;++c)this.writeNode("lineStringMember",a[c],b);return b},lineStringMember:function(a){var b=this.createElementNSPlus("gml:lineStringMember");this.writeNode("LineString",a,b);return b}, | |
2079 MultiPolygon:function(a){var b=this.createElementNSPlus("gml:MultiPolygon");a=a.components||[a];for(var c=0,d=a.length;c<d;++c)this.writeNode("polygonMember",a[c],b);return b},polygonMember:function(a){var b=this.createElementNSPlus("gml:polygonMember");this.writeNode("Polygon",a,b);return b},GeometryCollection:function(a){for(var b=this.createElementNSPlus("gml:GeometryCollection"),c=0,d=a.components.length;c<d;++c)this.writeNode("geometryMember",a.components[c],b);return b},geometryMember:function(a){var b= | |
2080 this.createElementNSPlus("gml:geometryMember");a=this.writeNode("feature:_geometry",a);b.appendChild(a.firstChild);return b}},feature:{_typeName:function(a){var b=this.createElementNSPlus("feature:"+this.featureType,{attributes:{fid:a.fid}});a.geometry&&this.writeNode("feature:_geometry",a.geometry,b);for(var c in a.attributes){var d=a.attributes[c];null!=d&&this.writeNode("feature:_attribute",{name:c,value:d},b)}return b},_geometry:function(a){this.externalProjection&&this.internalProjection&&(a= | |
2081 a.clone().transform(this.internalProjection,this.externalProjection));var b=this.createElementNSPlus("feature:"+this.geometryName);a=this.writeNode("gml:"+this.geometryTypes[a.CLASS_NAME],a,b);this.srsName&&a.setAttribute("srsName",this.srsName);return b},_attribute:function(a){return this.createElementNSPlus("feature:"+a.name,{value:a.value})}},wfs:{FeatureCollection:function(a){for(var b=this.createElementNSPlus("wfs:FeatureCollection"),c=0,d=a.length;c<d;++c)this.writeNode("gml:featureMember", | |
2082 a[c],b);return b}}},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":"LineString","OpenLayers.Geometry.MultiLineString":"MultiLineString","OpenLayers.Geometry.Polygon":"Polygon","OpenLayers.Geometry.MultiPolygon":"MultiPolygon","OpenLayers.Geometry.Collection":"GeometryCollection"}},CLASS_NAME:"OpenLayers.Format.GML.Base"});OpenLayers.Format.GML.v3=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd",curve:!1,multiCurve:!0,surface:!1,multiSurface:!0,initialize:function(a){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[a])},readers:{gml:OpenLayers.Util.applyDefaults({_inherit:function(a,b,c){if(a=parseInt(a.getAttribute("srsDimension"),10)||c&&c.srsDimension)b.srsDimension=a},featureMembers:function(a, | |
2083 b){this.readChildNodes(a,b)},Curve:function(a,b){var c={points:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);b.components||(b.components=[]);b.components.push(new OpenLayers.Geometry.LineString(c.points))},segments:function(a,b){this.readChildNodes(a,b)},LineStringSegment:function(a,b){var c={};this.readChildNodes(a,c);c.points&&Array.prototype.push.apply(b.points,c.points)},pos:function(a,b){var c=this.getChildValue(a).replace(this.regExes.trimSpace,"").split(this.regExes.splitSpace), | |
2084 c=this.xy?new OpenLayers.Geometry.Point(c[0],c[1],c[2]):new OpenLayers.Geometry.Point(c[1],c[0],c[2]);b.points=[c]},posList:function(a,b){for(var c=this.getChildValue(a).replace(this.regExes.trimSpace,"").split(this.regExes.splitSpace),d=b.srsDimension||parseInt(a.getAttribute("srsDimension")||a.getAttribute("dimension"),10)||2,e,f,g,h=Array(c.length/d),k=0,l=c.length;k<l;k+=d)e=c[k],f=c[k+1],g=2==d?void 0:c[k+2],h[k/d]=this.xy?new OpenLayers.Geometry.Point(e,f,g):new OpenLayers.Geometry.Point(f, | |
2085 e,g);b.points=h},Surface:function(a,b){this.readChildNodes(a,b)},patches:function(a,b){this.readChildNodes(a,b)},PolygonPatch:function(a,b){this.readers.gml.Polygon.apply(this,[a,b])},exterior:function(a,b){var c={};this.readChildNodes(a,c);b.outer=c.components[0]},interior:function(a,b){var c={};this.readChildNodes(a,c);b.inner.push(c.components[0])},MultiCurve:function(a,b){var c={components:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);0<c.components.length&&(b.components= | |
2086 [new OpenLayers.Geometry.MultiLineString(c.components)])},curveMember:function(a,b){this.readChildNodes(a,b)},MultiSurface:function(a,b){var c={components:[]};this.readers.gml._inherit.apply(this,[a,c,b]);this.readChildNodes(a,c);0<c.components.length&&(b.components=[new OpenLayers.Geometry.MultiPolygon(c.components)])},surfaceMember:function(a,b){this.readChildNodes(a,b)},surfaceMembers:function(a,b){this.readChildNodes(a,b)},pointMembers:function(a,b){this.readChildNodes(a,b)},lineStringMembers:function(a, | |
2087 b){this.readChildNodes(a,b)},polygonMembers:function(a,b){this.readChildNodes(a,b)},geometryMembers:function(a,b){this.readChildNodes(a,b)},Envelope:function(a,b){var c={points:Array(2)};this.readChildNodes(a,c);b.components||(b.components=[]);var d=c.points[0],c=c.points[1];b.components.push(new OpenLayers.Bounds(d.x,d.y,c.x,c.y))},lowerCorner:function(a,b){var c={};this.readers.gml.pos.apply(this,[a,c]);b.points[0]=c.points[0]},upperCorner:function(a,b){var c={};this.readers.gml.pos.apply(this, | |
2088 [a,c]);b.points[1]=c.points[0]}},OpenLayers.Format.GML.Base.prototype.readers.gml),feature:OpenLayers.Format.GML.Base.prototype.readers.feature,wfs:OpenLayers.Format.GML.Base.prototype.readers.wfs},write:function(a){var b;b=OpenLayers.Util.isArray(a)?"featureMembers":"featureMember";a=this.writeNode("gml:"+b,a);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[a])},writers:{gml:OpenLayers.Util.applyDefaults({featureMembers:function(a){for(var b= | |
2089 this.createElementNSPlus("gml:featureMembers"),c=0,d=a.length;c<d;++c)this.writeNode("feature:_typeName",a[c],b);return b},Point:function(a){var b=this.createElementNSPlus("gml:Point");this.writeNode("pos",a,b);return b},pos:function(a){return this.createElementNSPlus("gml:pos",{value:this.xy?a.x+" "+a.y:a.y+" "+a.x})},LineString:function(a){var b=this.createElementNSPlus("gml:LineString");this.writeNode("posList",a.components,b);return b},Curve:function(a){var b=this.createElementNSPlus("gml:Curve"); | |
2090 this.writeNode("segments",a,b);return b},segments:function(a){var b=this.createElementNSPlus("gml:segments");this.writeNode("LineStringSegment",a,b);return b},LineStringSegment:function(a){var b=this.createElementNSPlus("gml:LineStringSegment");this.writeNode("posList",a.components,b);return b},posList:function(a){for(var b=a.length,c=Array(b),d,e=0;e<b;++e)d=a[e],c[e]=this.xy?d.x+" "+d.y:d.y+" "+d.x;return this.createElementNSPlus("gml:posList",{value:c.join(" ")})},Surface:function(a){var b=this.createElementNSPlus("gml:Surface"); | |
2091 this.writeNode("patches",a,b);return b},patches:function(a){var b=this.createElementNSPlus("gml:patches");this.writeNode("PolygonPatch",a,b);return b},PolygonPatch:function(a){var b=this.createElementNSPlus("gml:PolygonPatch",{attributes:{interpolation:"planar"}});this.writeNode("exterior",a.components[0],b);for(var c=1,d=a.components.length;c<d;++c)this.writeNode("interior",a.components[c],b);return b},Polygon:function(a){var b=this.createElementNSPlus("gml:Polygon");this.writeNode("exterior",a.components[0], | |
2092 b);for(var c=1,d=a.components.length;c<d;++c)this.writeNode("interior",a.components[c],b);return b},exterior:function(a){var b=this.createElementNSPlus("gml:exterior");this.writeNode("LinearRing",a,b);return b},interior:function(a){var b=this.createElementNSPlus("gml:interior");this.writeNode("LinearRing",a,b);return b},LinearRing:function(a){var b=this.createElementNSPlus("gml:LinearRing");this.writeNode("posList",a.components,b);return b},MultiCurve:function(a){var b=this.createElementNSPlus("gml:MultiCurve"); | |
2093 a=a.components||[a];for(var c=0,d=a.length;c<d;++c)this.writeNode("curveMember",a[c],b);return b},curveMember:function(a){var b=this.createElementNSPlus("gml:curveMember");this.curve?this.writeNode("Curve",a,b):this.writeNode("LineString",a,b);return b},MultiSurface:function(a){var b=this.createElementNSPlus("gml:MultiSurface");a=a.components||[a];for(var c=0,d=a.length;c<d;++c)this.writeNode("surfaceMember",a[c],b);return b},surfaceMember:function(a){var b=this.createElementNSPlus("gml:surfaceMember"); | |
2094 this.surface?this.writeNode("Surface",a,b):this.writeNode("Polygon",a,b);return b},Envelope:function(a){var b=this.createElementNSPlus("gml:Envelope");this.writeNode("lowerCorner",a,b);this.writeNode("upperCorner",a,b);this.srsName&&b.setAttribute("srsName",this.srsName);return b},lowerCorner:function(a){return this.createElementNSPlus("gml:lowerCorner",{value:this.xy?a.left+" "+a.bottom:a.bottom+" "+a.left})},upperCorner:function(a){return this.createElementNSPlus("gml:upperCorner",{value:this.xy? | |
2095 a.right+" "+a.top:a.top+" "+a.right})}},OpenLayers.Format.GML.Base.prototype.writers.gml),feature:OpenLayers.Format.GML.Base.prototype.writers.feature,wfs:OpenLayers.Format.GML.Base.prototype.writers.wfs},setGeometryTypes:function(){this.geometryTypes={"OpenLayers.Geometry.Point":"Point","OpenLayers.Geometry.MultiPoint":"MultiPoint","OpenLayers.Geometry.LineString":!0===this.curve?"Curve":"LineString","OpenLayers.Geometry.MultiLineString":!1===this.multiCurve?"MultiLineString":"MultiCurve","OpenLayers.Geometry.Polygon":!0=== | |
2096 this.surface?"Surface":"Polygon","OpenLayers.Geometry.MultiPolygon":!1===this.multiSurface?"MultiPolygon":"MultiSurface","OpenLayers.Geometry.Collection":"GeometryCollection"}},CLASS_NAME:"OpenLayers.Format.GML.v3"});OpenLayers.Format.Filter.v1_1_0=OpenLayers.Class(OpenLayers.Format.GML.v3,OpenLayers.Format.Filter.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.1.0/filter.xsd",initialize:function(a){OpenLayers.Format.GML.v3.prototype.initialize.apply(this,[a])},readers:{ogc:OpenLayers.Util.applyDefaults({PropertyIsEqualTo:function(a,b){var c=a.getAttribute("matchCase"),c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,matchCase:!("false"===c||"0"===c)});this.readChildNodes(a, | |
2097 c);b.filters.push(c)},PropertyIsNotEqualTo:function(a,b){var c=a.getAttribute("matchCase"),c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO,matchCase:!("false"===c||"0"===c)});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsLike:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(a,c);var d=a.getAttribute("wildCard"),e=a.getAttribute("singleChar"),f=a.getAttribute("escapeChar");c.value2regex(d,e, | |
2098 f);b.filters.push(c)}},OpenLayers.Format.Filter.v1.prototype.readers.ogc),gml:OpenLayers.Format.GML.v3.prototype.readers.gml,feature:OpenLayers.Format.GML.v3.prototype.readers.feature},writers:{ogc:OpenLayers.Util.applyDefaults({PropertyIsEqualTo:function(a){var b=this.createElementNSPlus("ogc:PropertyIsEqualTo",{attributes:{matchCase:a.matchCase}});this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsNotEqualTo:function(a){var b=this.createElementNSPlus("ogc:PropertyIsNotEqualTo", | |
2099 {attributes:{matchCase:a.matchCase}});this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsLike:function(a){var b=this.createElementNSPlus("ogc:PropertyIsLike",{attributes:{matchCase:a.matchCase,wildCard:"*",singleChar:".",escapeChar:"!"}});this.writeNode("PropertyName",a,b);this.writeNode("Literal",a.regex2value(),b);return b},BBOX:function(a){var b=this.createElementNSPlus("ogc:BBOX");a.property&&this.writeNode("PropertyName",a,b);var c=this.writeNode("gml:Envelope", | |
2100 a.value);a.projection&&c.setAttribute("srsName",a.projection);b.appendChild(c);return b},SortBy:function(a){for(var b=this.createElementNSPlus("ogc:SortBy"),c=0,d=a.length;c<d;c++)this.writeNode("ogc:SortProperty",a[c],b);return b},SortProperty:function(a){var b=this.createElementNSPlus("ogc:SortProperty");this.writeNode("ogc:PropertyName",a,b);this.writeNode("ogc:SortOrder","DESC"==a.order?"DESC":"ASC",b);return b},SortOrder:function(a){return this.createElementNSPlus("ogc:SortOrder",{value:a})}}, | |
2101 OpenLayers.Format.Filter.v1.prototype.writers.ogc),gml:OpenLayers.Format.GML.v3.prototype.writers.gml,feature:OpenLayers.Format.GML.v3.prototype.writers.feature},writeSpatial:function(a,b){var c=this.createElementNSPlus("ogc:"+b);this.writeNode("PropertyName",a,c);if(a.value instanceof OpenLayers.Filter.Function)this.writeNode("Function",a.value,c);else{var d;d=a.value instanceof OpenLayers.Geometry?this.writeNode("feature:_geometry",a.value).firstChild:this.writeNode("gml:Envelope",a.value);a.projection&& | |
2102 d.setAttribute("srsName",a.projection);c.appendChild(d)}return c},CLASS_NAME:"OpenLayers.Format.Filter.v1_1_0"});OpenLayers.Format.OWSCommon=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.0.0",getVersion:function(a,b){var c=this.version;if(!c){var d=a.getAttribute("xmlns:ows");d&&"1.1"===d.substring(d.lastIndexOf("/")+1)&&(c="1.1.0");c||(c=this.defaultVersion)}return c},CLASS_NAME:"OpenLayers.Format.OWSCommon"});OpenLayers.Format.OWSCommon.v1=OpenLayers.Class(OpenLayers.Format.XML,{regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},read:function(a,b){OpenLayers.Util.applyDefaults(b,this.options);var c={};this.readChildNodes(a,c);return c},readers:{ows:{Exception:function(a,b){var c={code:a.getAttribute("exceptionCode"),locator:a.getAttribute("locator"),texts:[]};b.exceptions.push(c);this.readChildNodes(a,c)},ExceptionText:function(a,b){var c=this.getChildValue(a);b.texts.push(c)}, | |
2103 ServiceIdentification:function(a,b){b.serviceIdentification={};this.readChildNodes(a,b.serviceIdentification)},Title:function(a,b){b.title=this.getChildValue(a)},Abstract:function(a,b){b["abstract"]=this.getChildValue(a)},Keywords:function(a,b){b.keywords={};this.readChildNodes(a,b.keywords)},Keyword:function(a,b){b[this.getChildValue(a)]=!0},ServiceType:function(a,b){b.serviceType={codeSpace:a.getAttribute("codeSpace"),value:this.getChildValue(a)}},ServiceTypeVersion:function(a,b){b.serviceTypeVersion= | |
2104 this.getChildValue(a)},Fees:function(a,b){b.fees=this.getChildValue(a)},AccessConstraints:function(a,b){b.accessConstraints=this.getChildValue(a)},ServiceProvider:function(a,b){b.serviceProvider={};this.readChildNodes(a,b.serviceProvider)},ProviderName:function(a,b){b.providerName=this.getChildValue(a)},ProviderSite:function(a,b){b.providerSite=this.getAttributeNS(a,this.namespaces.xlink,"href")},ServiceContact:function(a,b){b.serviceContact={};this.readChildNodes(a,b.serviceContact)},IndividualName:function(a, | |
2105 b){b.individualName=this.getChildValue(a)},PositionName:function(a,b){b.positionName=this.getChildValue(a)},ContactInfo:function(a,b){b.contactInfo={};this.readChildNodes(a,b.contactInfo)},Phone:function(a,b){b.phone={};this.readChildNodes(a,b.phone)},Voice:function(a,b){b.voice=this.getChildValue(a)},Address:function(a,b){b.address={};this.readChildNodes(a,b.address)},DeliveryPoint:function(a,b){b.deliveryPoint=this.getChildValue(a)},City:function(a,b){b.city=this.getChildValue(a)},AdministrativeArea:function(a, | |
2106 b){b.administrativeArea=this.getChildValue(a)},PostalCode:function(a,b){b.postalCode=this.getChildValue(a)},Country:function(a,b){b.country=this.getChildValue(a)},ElectronicMailAddress:function(a,b){b.electronicMailAddress=this.getChildValue(a)},Role:function(a,b){b.role=this.getChildValue(a)},OperationsMetadata:function(a,b){b.operationsMetadata={};this.readChildNodes(a,b.operationsMetadata)},Operation:function(a,b){var c=a.getAttribute("name");b[c]={};this.readChildNodes(a,b[c])},DCP:function(a, | |
2107 b){b.dcp={};this.readChildNodes(a,b.dcp)},HTTP:function(a,b){b.http={};this.readChildNodes(a,b.http)},Get:function(a,b){b.get||(b.get=[]);var c={url:this.getAttributeNS(a,this.namespaces.xlink,"href")};this.readChildNodes(a,c);b.get.push(c)},Post:function(a,b){b.post||(b.post=[]);var c={url:this.getAttributeNS(a,this.namespaces.xlink,"href")};this.readChildNodes(a,c);b.post.push(c)},Parameter:function(a,b){b.parameters||(b.parameters={});var c=a.getAttribute("name");b.parameters[c]={};this.readChildNodes(a, | |
2108 b.parameters[c])},Constraint:function(a,b){b.constraints||(b.constraints={});var c=a.getAttribute("name");b.constraints[c]={};this.readChildNodes(a,b.constraints[c])},Value:function(a,b){b[this.getChildValue(a)]=!0},OutputFormat:function(a,b){b.formats.push({value:this.getChildValue(a)});this.readChildNodes(a,b)},WGS84BoundingBox:function(a,b){var c={};c.crs=a.getAttribute("crs");b.BoundingBox?b.BoundingBox.push(c):(b.projection=c.crs,c=b);this.readChildNodes(a,c)},BoundingBox:function(a,b){this.readers.ows.WGS84BoundingBox.apply(this, | |
2109 [a,b])},LowerCorner:function(a,b){var c=this.getChildValue(a).replace(this.regExes.trimSpace,""),c=c.replace(this.regExes.trimComma,","),c=c.split(this.regExes.splitSpace);b.left=c[0];b.bottom=c[1]},UpperCorner:function(a,b){var c=this.getChildValue(a).replace(this.regExes.trimSpace,""),c=c.replace(this.regExes.trimComma,","),c=c.split(this.regExes.splitSpace);b.right=c[0];b.top=c[1];b.bounds=new OpenLayers.Bounds(b.left,b.bottom,b.right,b.top);delete b.left;delete b.bottom;delete b.right;delete b.top}, | |
2110 Language:function(a,b){b.language=this.getChildValue(a)}}},writers:{ows:{BoundingBox:function(a,b){var c=this.createElementNSPlus(b||"ows:BoundingBox",{attributes:{crs:a.projection}});this.writeNode("ows:LowerCorner",a,c);this.writeNode("ows:UpperCorner",a,c);return c},LowerCorner:function(a){return this.createElementNSPlus("ows:LowerCorner",{value:a.bounds.left+" "+a.bounds.bottom})},UpperCorner:function(a){return this.createElementNSPlus("ows:UpperCorner",{value:a.bounds.right+" "+a.bounds.top})}, | |
2111 Identifier:function(a){return this.createElementNSPlus("ows:Identifier",{value:a})},Title:function(a){return this.createElementNSPlus("ows:Title",{value:a})},Abstract:function(a){return this.createElementNSPlus("ows:Abstract",{value:a})},OutputFormat:function(a){return this.createElementNSPlus("ows:OutputFormat",{value:a})}}},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1"});OpenLayers.Format.OWSCommon.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows",xlink:"http://www.w3.org/1999/xlink"},readers:{ows:OpenLayers.Util.applyDefaults({ExceptionReport:function(a,b){b.success=!1;b.exceptionReport={version:a.getAttribute("version"),language:a.getAttribute("language"),exceptions:[]};this.readChildNodes(a,b.exceptionReport)}},OpenLayers.Format.OWSCommon.v1.prototype.readers.ows)},writers:{ows:OpenLayers.Format.OWSCommon.v1.prototype.writers.ows}, | |
2112 CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_0_0"});OpenLayers.Format.WFST.v1_1_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_1_0,OpenLayers.Format.WFST.v1,{version:"1.1.0",schemaLocations:{wfs:"http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"},initialize:function(a){OpenLayers.Format.Filter.v1_1_0.prototype.initialize.apply(this,[a]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[a])},readNode:function(a,b,c){return OpenLayers.Format.GML.v3.prototype.readNode.apply(this,arguments)},readers:{wfs:OpenLayers.Util.applyDefaults({FeatureCollection:function(a, | |
2113 b){b.numberOfFeatures=parseInt(a.getAttribute("numberOfFeatures"));OpenLayers.Format.WFST.v1.prototype.readers.wfs.FeatureCollection.apply(this,arguments)},TransactionResponse:function(a,b){b.insertIds=[];b.success=!1;this.readChildNodes(a,b)},TransactionSummary:function(a,b){b.success=!0},InsertResults:function(a,b){this.readChildNodes(a,b)},Feature:function(a,b){var c={fids:[]};this.readChildNodes(a,c);b.insertIds.push(c.fids[0])}},OpenLayers.Format.WFST.v1.prototype.readers.wfs),gml:OpenLayers.Format.GML.v3.prototype.readers.gml, | |
2114 feature:OpenLayers.Format.GML.v3.prototype.readers.feature,ogc:OpenLayers.Format.Filter.v1_1_0.prototype.readers.ogc,ows:OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows},writers:{wfs:OpenLayers.Util.applyDefaults({GetFeature:function(a){var b=OpenLayers.Format.WFST.v1.prototype.writers.wfs.GetFeature.apply(this,arguments);a&&this.setAttributes(b,{resultType:a.resultType,startIndex:a.startIndex,count:a.count});return b},Query:function(a){a=OpenLayers.Util.extend({featureNS:this.featureNS, | |
2115 featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName},a);var b=a.featurePrefix,c=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(b?b+":":"")+a.featureType,srsName:a.srsName}});a.featureNS&&c.setAttribute("xmlns:"+b,a.featureNS);if(a.propertyNames)for(var b=0,d=a.propertyNames.length;b<d;b++)this.writeNode("wfs:PropertyName",{property:a.propertyNames[b]},c);a.filter&&(OpenLayers.Format.WFST.v1_1_0.prototype.setFilterProperty.call(this,a.filter),this.writeNode("ogc:Filter", | |
2116 a.filter,c));return c},PropertyName:function(a){return this.createElementNSPlus("wfs:PropertyName",{value:a.property})}},OpenLayers.Format.WFST.v1.prototype.writers.wfs),gml:OpenLayers.Format.GML.v3.prototype.writers.gml,feature:OpenLayers.Format.GML.v3.prototype.writers.feature,ogc:OpenLayers.Format.Filter.v1_1_0.prototype.writers.ogc},CLASS_NAME:"OpenLayers.Format.WFST.v1_1_0"});OpenLayers.Protocol=OpenLayers.Class({format:null,options:null,autoDestroy:!0,defaultFilter:null,initialize:function(a){a=a||{};OpenLayers.Util.extend(this,a);this.options=a},mergeWithDefaultFilter:function(a){return a&&this.defaultFilter?new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND,filters:[this.defaultFilter,a]}):a||this.defaultFilter||void 0},destroy:function(){this.format=this.options=null},read:function(a){a=a||{};a.filter=this.mergeWithDefaultFilter(a.filter)},create:function(){}, | |
2117 update:function(){},"delete":function(){},commit:function(){},abort:function(a){},createCallback:function(a,b,c){return OpenLayers.Function.bind(function(){a.apply(this,[b,c])},this)},CLASS_NAME:"OpenLayers.Protocol"});OpenLayers.Protocol.Response=OpenLayers.Class({code:null,requestType:null,last:!0,features:null,data:null,reqFeatures:null,priv:null,error:null,initialize:function(a){OpenLayers.Util.extend(this,a)},success:function(){return 0<this.code},CLASS_NAME:"OpenLayers.Protocol.Response"}); | |
2118 OpenLayers.Protocol.Response.SUCCESS=1;OpenLayers.Protocol.Response.FAILURE=0;OpenLayers.Format.JSON=OpenLayers.Class(OpenLayers.Format,{indent:" ",space:" ",newline:"\n",level:0,pretty:!1,nativeJSON:function(){return!(!window.JSON||"function"!=typeof JSON.parse||"function"!=typeof JSON.stringify)}(),read:function(a,b){var c;if(this.nativeJSON)c=JSON.parse(a,b);else try{if(/^[\],:{}\s]*$/.test(a.replace(/\\["\\\/bfnrtu]/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))&&(c=eval("("+a+")"),"function"=== | |
2119 typeof b)){var d=function(a,c){if(c&&"object"===typeof c)for(var e in c)c.hasOwnProperty(e)&&(c[e]=d(e,c[e]));return b(a,c)};c=d("",c)}}catch(e){}this.keepData&&(this.data=c);return c},write:function(a,b){this.pretty=!!b;var c=null,d=typeof a;if(this.serialize[d])try{c=!this.pretty&&this.nativeJSON?JSON.stringify(a):this.serialize[d].apply(this,[a])}catch(e){OpenLayers.Console.error("Trouble serializing: "+e)}return c},writeIndent:function(){var a=[];if(this.pretty)for(var b=0;b<this.level;++b)a.push(this.indent); | |
2120 return a.join("")},writeNewline:function(){return this.pretty?this.newline:""},writeSpace:function(){return this.pretty?this.space:""},serialize:{object:function(a){if(null==a)return"null";if(a.constructor==Date)return this.serialize.date.apply(this,[a]);if(a.constructor==Array)return this.serialize.array.apply(this,[a]);var b=["{"];this.level+=1;var c,d,e,f=!1;for(c in a)a.hasOwnProperty(c)&&(d=OpenLayers.Format.JSON.prototype.write.apply(this,[c,this.pretty]),e=OpenLayers.Format.JSON.prototype.write.apply(this, | |
2121 [a[c],this.pretty]),null!=d&&null!=e&&(f&&b.push(","),b.push(this.writeNewline(),this.writeIndent(),d,":",this.writeSpace(),e),f=!0));this.level-=1;b.push(this.writeNewline(),this.writeIndent(),"}");return b.join("")},array:function(a){var b,c=["["];this.level+=1;for(var d=0,e=a.length;d<e;++d)b=OpenLayers.Format.JSON.prototype.write.apply(this,[a[d],this.pretty]),null!=b&&(0<d&&c.push(","),c.push(this.writeNewline(),this.writeIndent(),b));this.level-=1;c.push(this.writeNewline(),this.writeIndent(), | |
2122 "]");return c.join("")},string:function(a){var b={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};return/["\\\x00-\x1f]/.test(a)?'"'+a.replace(/([\x00-\x1f\\"])/g,function(a,d){var e=b[d];if(e)return e;e=d.charCodeAt();return"\\u00"+Math.floor(e/16).toString(16)+(e%16).toString(16)})+'"':'"'+a+'"'},number:function(a){return isFinite(a)?String(a):"null"},"boolean":function(a){return String(a)},date:function(a){function b(a){return 10>a?"0"+a:a}return'"'+a.getFullYear()+ | |
2123 "-"+b(a.getMonth()+1)+"-"+b(a.getDate())+"T"+b(a.getHours())+":"+b(a.getMinutes())+":"+b(a.getSeconds())+'"'}},CLASS_NAME:"OpenLayers.Format.JSON"});OpenLayers.Format.GeoJSON=OpenLayers.Class(OpenLayers.Format.JSON,{ignoreExtraDims:!1,read:function(a,b,c){b=b?b:"FeatureCollection";var d=null,e=null,e="string"==typeof a?OpenLayers.Format.JSON.prototype.read.apply(this,[a,c]):a;if(!e)OpenLayers.Console.error("Bad JSON: "+a);else if("string"!=typeof e.type)OpenLayers.Console.error("Bad GeoJSON - no type: "+a);else if(this.isValidType(e,b))switch(b){case "Geometry":try{d=this.parseGeometry(e)}catch(f){OpenLayers.Console.error(f)}break;case "Feature":try{d= | |
2124 this.parseFeature(e),d.type="Feature"}catch(g){OpenLayers.Console.error(g)}break;case "FeatureCollection":switch(d=[],e.type){case "Feature":try{d.push(this.parseFeature(e))}catch(h){d=null,OpenLayers.Console.error(h)}break;case "FeatureCollection":a=0;for(b=e.features.length;a<b;++a)try{d.push(this.parseFeature(e.features[a]))}catch(k){d=null,OpenLayers.Console.error(k)}break;default:try{var l=this.parseGeometry(e);d.push(new OpenLayers.Feature.Vector(l))}catch(m){d=null,OpenLayers.Console.error(m)}}}return d}, | |
2125 isValidType:function(a,b){var c=!1;switch(b){case "Geometry":-1==OpenLayers.Util.indexOf("Point MultiPoint LineString MultiLineString Polygon MultiPolygon Box GeometryCollection".split(" "),a.type)?OpenLayers.Console.error("Unsupported geometry type: "+a.type):c=!0;break;case "FeatureCollection":c=!0;break;default:a.type==b?c=!0:OpenLayers.Console.error("Cannot convert types from "+a.type+" to "+b)}return c},parseFeature:function(a){var b,c,d;c=a.properties?a.properties:{};d=a.geometry&&a.geometry.bbox|| | |
2126 a.bbox;try{b=this.parseGeometry(a.geometry)}catch(e){throw e;}b=new OpenLayers.Feature.Vector(b,c);d&&(b.bounds=OpenLayers.Bounds.fromArray(d));a.id&&(b.fid=a.id);return b},parseGeometry:function(a){if(null==a)return null;var b,c=!1;if("GeometryCollection"==a.type){if(!OpenLayers.Util.isArray(a.geometries))throw"GeometryCollection must have geometries array: "+a;b=a.geometries.length;for(var c=Array(b),d=0;d<b;++d)c[d]=this.parseGeometry.apply(this,[a.geometries[d]]);b=new OpenLayers.Geometry.Collection(c); | |
2127 c=!0}else{if(!OpenLayers.Util.isArray(a.coordinates))throw"Geometry must have coordinates array: "+a;if(!this.parseCoords[a.type.toLowerCase()])throw"Unsupported geometry type: "+a.type;try{b=this.parseCoords[a.type.toLowerCase()].apply(this,[a.coordinates])}catch(e){throw e;}}this.internalProjection&&(this.externalProjection&&!c)&&b.transform(this.externalProjection,this.internalProjection);return b},parseCoords:{point:function(a){if(!1==this.ignoreExtraDims&&2!=a.length)throw"Only 2D points are supported: "+ | |
2128 a;return new OpenLayers.Geometry.Point(a[0],a[1])},multipoint:function(a){for(var b=[],c=null,d=0,e=a.length;d<e;++d){try{c=this.parseCoords.point.apply(this,[a[d]])}catch(f){throw f;}b.push(c)}return new OpenLayers.Geometry.MultiPoint(b)},linestring:function(a){for(var b=[],c=null,d=0,e=a.length;d<e;++d){try{c=this.parseCoords.point.apply(this,[a[d]])}catch(f){throw f;}b.push(c)}return new OpenLayers.Geometry.LineString(b)},multilinestring:function(a){for(var b=[],c=null,d=0,e=a.length;d<e;++d){try{c= | |
2129 this.parseCoords.linestring.apply(this,[a[d]])}catch(f){throw f;}b.push(c)}return new OpenLayers.Geometry.MultiLineString(b)},polygon:function(a){for(var b=[],c,d,e=0,f=a.length;e<f;++e){try{d=this.parseCoords.linestring.apply(this,[a[e]])}catch(g){throw g;}c=new OpenLayers.Geometry.LinearRing(d.components);b.push(c)}return new OpenLayers.Geometry.Polygon(b)},multipolygon:function(a){for(var b=[],c=null,d=0,e=a.length;d<e;++d){try{c=this.parseCoords.polygon.apply(this,[a[d]])}catch(f){throw f;}b.push(c)}return new OpenLayers.Geometry.MultiPolygon(b)}, | |
2130 box:function(a){if(2!=a.length)throw"GeoJSON box coordinates must have 2 elements";return new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([new OpenLayers.Geometry.Point(a[0][0],a[0][1]),new OpenLayers.Geometry.Point(a[1][0],a[0][1]),new OpenLayers.Geometry.Point(a[1][0],a[1][1]),new OpenLayers.Geometry.Point(a[0][0],a[1][1]),new OpenLayers.Geometry.Point(a[0][0],a[0][1])])])}},write:function(a,b){var c={type:null};if(OpenLayers.Util.isArray(a)){c.type="FeatureCollection";var d= | |
2131 a.length;c.features=Array(d);for(var e=0;e<d;++e){var f=a[e];if(!f instanceof OpenLayers.Feature.Vector)throw"FeatureCollection only supports collections of features: "+f;c.features[e]=this.extract.feature.apply(this,[f])}}else 0==a.CLASS_NAME.indexOf("OpenLayers.Geometry")?c=this.extract.geometry.apply(this,[a]):a instanceof OpenLayers.Feature.Vector&&(c=this.extract.feature.apply(this,[a]),a.layer&&a.layer.projection&&(c.crs=this.createCRSObject(a)));return OpenLayers.Format.JSON.prototype.write.apply(this, | |
2132 [c,b])},createCRSObject:function(a){a=a.layer.projection.toString();var b={};a.match(/epsg:/i)&&(a=parseInt(a.substring(a.indexOf(":")+1)),b=4326==a?{type:"name",properties:{name:"urn:ogc:def:crs:OGC:1.3:CRS84"}}:{type:"name",properties:{name:"EPSG:"+a}});return b},extract:{feature:function(a){var b=this.extract.geometry.apply(this,[a.geometry]),b={type:"Feature",properties:a.attributes,geometry:b};null!=a.fid&&(b.id=a.fid);return b},geometry:function(a){if(null==a)return null;this.internalProjection&& | |
2133 this.externalProjection&&(a=a.clone(),a.transform(this.internalProjection,this.externalProjection));var b=a.CLASS_NAME.split(".")[2];a=this.extract[b.toLowerCase()].apply(this,[a]);return"Collection"==b?{type:"GeometryCollection",geometries:a}:{type:b,coordinates:a}},point:function(a){return[a.x,a.y]},multipoint:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push(this.extract.point.apply(this,[a.components[c]]));return b},linestring:function(a){for(var b=[],c=0,d=a.components.length;c< | |
2134 d;++c)b.push(this.extract.point.apply(this,[a.components[c]]));return b},multilinestring:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push(this.extract.linestring.apply(this,[a.components[c]]));return b},polygon:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push(this.extract.linestring.apply(this,[a.components[c]]));return b},multipolygon:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push(this.extract.polygon.apply(this,[a.components[c]]));return b},collection:function(a){for(var b= | |
2135 a.components.length,c=Array(b),d=0;d<b;++d)c[d]=this.extract.geometry.apply(this,[a.components[d]]);return c}},CLASS_NAME:"OpenLayers.Format.GeoJSON"});OpenLayers.Protocol.Script=OpenLayers.Class(OpenLayers.Protocol,{url:null,params:null,callback:null,callbackTemplate:"OpenLayers.Protocol.Script.registry.${id}",callbackKey:"callback",callbackPrefix:"",scope:null,format:null,pendingRequests:null,srsInBBOX:!1,initialize:function(a){a=a||{};this.params={};this.pendingRequests={};OpenLayers.Protocol.prototype.initialize.apply(this,arguments);this.format||(this.format=new OpenLayers.Format.GeoJSON);if(!this.filterToParams&&OpenLayers.Format.QueryStringFilter){var b= | |
2136 new OpenLayers.Format.QueryStringFilter({srsInBBOX:this.srsInBBOX});this.filterToParams=function(a,d){return b.write(a,d)}}},read:function(a){OpenLayers.Protocol.prototype.read.apply(this,arguments);a=OpenLayers.Util.applyDefaults(a,this.options);a.params=OpenLayers.Util.applyDefaults(a.params,this.options.params);a.filter&&this.filterToParams&&(a.params=this.filterToParams(a.filter,a.params));var b=new OpenLayers.Protocol.Response({requestType:"read"}),c=this.createRequest(a.url,a.params,OpenLayers.Function.bind(function(c){b.data= | |
2137 c;this.handleRead(b,a)},this));b.priv=c;return b},createRequest:function(a,b,c){c=OpenLayers.Protocol.Script.register(c);var d=OpenLayers.String.format(this.callbackTemplate,{id:c});b=OpenLayers.Util.extend({},b);b[this.callbackKey]=this.callbackPrefix+d;a=OpenLayers.Util.urlAppend(a,OpenLayers.Util.getParameterString(b));b=document.createElement("script");b.type="text/javascript";b.src=a;b.id="OpenLayers_Protocol_Script_"+c;this.pendingRequests[b.id]=b;document.getElementsByTagName("head")[0].appendChild(b); | |
2138 return b},destroyRequest:function(a){OpenLayers.Protocol.Script.unregister(a.id.split("_").pop());delete this.pendingRequests[a.id];a.parentNode&&a.parentNode.removeChild(a)},handleRead:function(a,b){this.handleResponse(a,b)},handleResponse:function(a,b){b.callback&&(a.data?(a.features=this.parseFeatures(a.data),a.code=OpenLayers.Protocol.Response.SUCCESS):a.code=OpenLayers.Protocol.Response.FAILURE,this.destroyRequest(a.priv),b.callback.call(b.scope,a))},parseFeatures:function(a){return this.format.read(a)}, | |
2139 abort:function(a){if(a)this.destroyRequest(a.priv);else for(var b in this.pendingRequests)this.destroyRequest(this.pendingRequests[b])},destroy:function(){this.abort();delete this.params;delete this.format;OpenLayers.Protocol.prototype.destroy.apply(this)},CLASS_NAME:"OpenLayers.Protocol.Script"});(function(){var a=OpenLayers.Protocol.Script,b=0;a.registry={};a.register=function(c){var d="c"+ ++b;a.registry[d]=function(){c.apply(this,arguments)};return d};a.unregister=function(b){delete a.registry[b]}})();OpenLayers.Format.EncodedPolyline=OpenLayers.Class(OpenLayers.Format,{geometryType:"linestring",initialize:function(a){OpenLayers.Format.prototype.initialize.apply(this,[a])},read:function(a){var b;if("linestring"==this.geometryType)b=OpenLayers.Geometry.LineString;else if("linearring"==this.geometryType)b=OpenLayers.Geometry.LinearRing;else if("multipoint"==this.geometryType)b=OpenLayers.Geometry.MultiPoint;else if("point"!=this.geometryType&&"polygon"!=this.geometryType)return null;a=this.decodeDeltas(a, | |
2140 2);for(var c=a.length,d=[],e=0;e+1<c;){var f=a[e++],g=a[e++];d.push(new OpenLayers.Geometry.Point(g,f))}return"point"==this.geometryType?new OpenLayers.Feature.Vector(d[0]):"polygon"==this.geometryType?new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(d)])):new OpenLayers.Feature.Vector(new b(d))},decode:function(a,b,c){a=this.decodeDeltas(a,b,c||1E5);c=a.length;for(var d=[],e=0;e+(b-1)<c;){for(var f=[],g=0;g<b;++g)f.push(a[e++]);d.push(f)}return d}, | |
2141 write:function(a){a=(a.constructor==Array?a[0]:a).geometry;var b=a.CLASS_NAME.split(".")[2].toLowerCase();if("point"==b)a=Array(a);else if("linestring"==b||"linearring"==b||"multipoint"==b)a=a.components;else if("polygon"==b)a=a.components[0].components;else return null;for(var b=[],c=a.length,d=0;d<c;++d){var e=a[d];b.push(e.y);b.push(e.x)}return this.encodeDeltas(b,2)},encode:function(a,b,c){c=c||1E5;for(var d=[],e=a.length,f=0;f<e;++f)for(var g=a[f],h=0;h<b;++h)d.push(g[h]);return this.encodeDeltas(d, | |
2142 b,c)},encodeDeltas:function(a,b,c){var d,e=Array(b);for(d=0;d<b;++d)e[d]=0;for(var f=a.length,g=0;g<f;)for(d=0;d<b;++d,++g){var h=a[g],k=h-e[d];e[d]=h;a[g]=k}return this.encodeFloats(a,c||1E5)},decodeDeltas:function(a,b,c){var d,e=Array(b);for(d=0;d<b;++d)e[d]=0;a=this.decodeFloats(a,c||1E5);c=a.length;for(var f=0;f<c;)for(d=0;d<b;++d,++f)e[d]+=a[f],a[f]=e[d];return a},encodeFloats:function(a,b){for(var c=b||1E5,d=a.length,e=0;e<d;++e)a[e]=Math.round(a[e]*c);return this.encodeSignedIntegers(a)},decodeFloats:function(a, | |
2143 b){for(var c=b||1E5,d=this.decodeSignedIntegers(a),e=d.length,f=0;f<e;++f)d[f]/=c;return d},encodeSignedIntegers:function(a){for(var b=a.length,c=0;c<b;++c){var d=a[c],e=d<<1;0>d&&(e=~e);a[c]=e}return this.encodeUnsignedIntegers(a)},decodeSignedIntegers:function(a){a=this.decodeUnsignedIntegers(a);for(var b=a.length,c=0;c<b;++c){var d=a[c];a[c]=d&1?~(d>>1):d>>1}return a},encodeUnsignedIntegers:function(a){for(var b="",c=a.length,d=0;d<c;++d)b+=this.encodeUnsignedInteger(a[d]);return b},decodeUnsignedIntegers:function(a){for(var b= | |
2144 [],c=0,d=0,e=a.length,f=0;f<e;++f){var g=a.charCodeAt(f)-63,c=c|(g&31)<<d;32>g?(b.push(c),d=c=0):d+=5}return b},encodeFloat:function(a,b){a=Math.round(a*(b||1E5));return this.encodeSignedInteger(a)},decodeFloat:function(a,b){return this.decodeSignedInteger(a)/(b||1E5)},encodeSignedInteger:function(a){var b=a<<1;0>a&&(b=~b);return this.encodeUnsignedInteger(b)},decodeSignedInteger:function(a){a=this.decodeUnsignedInteger(a);return a&1?~(a>>1):a>>1},encodeUnsignedInteger:function(a){for(var b,c="";32<= | |
2145 a;)b=(32|a&31)+63,c+=String.fromCharCode(b),a>>=5;return c+=String.fromCharCode(a+63)},decodeUnsignedInteger:function(a){for(var b=0,c=0,d=a.length,e=0;e<d;++e){var f=a.charCodeAt(e)-63,b=b|(f&31)<<c;if(32>f)break;c+=5}return b},CLASS_NAME:"OpenLayers.Format.EncodedPolyline"});OpenLayers.Control.Panel=OpenLayers.Class(OpenLayers.Control,{controls:null,autoActivate:!0,defaultControl:null,saveState:!1,allowDepress:!1,activeState:null,initialize:function(a){OpenLayers.Control.prototype.initialize.apply(this,[a]);this.controls=[];this.activeState={}},destroy:function(){this.map&&this.map.events.unregister("buttonclick",this,this.onButtonClick);OpenLayers.Control.prototype.destroy.apply(this,arguments);for(var a,b=this.controls.length-1;0<=b;b--)a=this.controls[b],a.events&& | |
2146 a.events.un({activate:this.iconOn,deactivate:this.iconOff}),a.panel_div=null;this.activeState=null},activate:function(){if(OpenLayers.Control.prototype.activate.apply(this,arguments)){for(var a,b=0,c=this.controls.length;b<c;b++)a=this.controls[b],(a===this.defaultControl||this.saveState&&this.activeState[a.id])&&a.activate();!0===this.saveState&&(this.defaultControl=null);this.redraw();return!0}return!1},deactivate:function(){if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){for(var a, | |
2147 b=0,c=this.controls.length;b<c;b++)a=this.controls[b],this.activeState[a.id]=a.deactivate();this.redraw();return!0}return!1},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.outsideViewport?(this.events.attachToElement(this.div),this.events.register("buttonclick",this,this.onButtonClick)):this.map.events.register("buttonclick",this,this.onButtonClick);this.addControlsToMap(this.controls);return this.div},redraw:function(){for(var a=this.div.childNodes.length-1;0<=a;a--)this.div.removeChild(this.div.childNodes[a]); | |
2148 this.div.innerHTML="";if(this.active)for(var a=0,b=this.controls.length;a<b;a++)this.div.appendChild(this.controls[a].panel_div)},activateControl:function(a){if(!this.active)return!1;if(a.type==OpenLayers.Control.TYPE_BUTTON)a.trigger();else if(a.type==OpenLayers.Control.TYPE_TOGGLE)a.active?a.deactivate():a.activate();else if(this.allowDepress&&a.active)a.deactivate();else{for(var b,c=0,d=this.controls.length;c<d;c++)b=this.controls[c],b==a||b.type!==OpenLayers.Control.TYPE_TOOL&&null!=b.type||b.deactivate(); | |
2149 a.activate()}},addControls:function(a){OpenLayers.Util.isArray(a)||(a=[a]);this.controls=this.controls.concat(a);for(var b=0,c=a.length;b<c;b++){var d=a[b],e=this.createControlMarkup(d);OpenLayers.Element.addClass(e,d.displayClass+"ItemInactive");OpenLayers.Element.addClass(e,"olButton");""==d.title||e.title||(e.title=d.title);d.panel_div=e}this.map&&(this.addControlsToMap(a),this.redraw())},createControlMarkup:function(a){return document.createElement("div")},addControlsToMap:function(a){for(var b, | |
2150 c=0,d=a.length;c<d;c++)b=a[c],!0===b.autoActivate?(b.autoActivate=!1,this.map.addControl(b),b.autoActivate=!0):(this.map.addControl(b),b.deactivate()),b.events.on({activate:this.iconOn,deactivate:this.iconOff})},iconOn:function(){var a=this.panel_div;a.className=a.className.replace(RegExp("\\b("+this.displayClass+"Item)Inactive\\b"),"$1Active")},iconOff:function(){var a=this.panel_div;a.className=a.className.replace(RegExp("\\b("+this.displayClass+"Item)Active\\b"),"$1Inactive")},onButtonClick:function(a){var b= | |
2151 this.controls;a=a.buttonElement;for(var c=b.length-1;0<=c;--c)if(b[c].panel_div===a){this.activateControl(b[c]);break}},getControlsBy:function(a,b){var c="function"==typeof b.test;return OpenLayers.Array.filter(this.controls,function(d){return d[a]==b||c&&b.test(d[a])})},getControlsByName:function(a){return this.getControlsBy("name",a)},getControlsByClass:function(a){return this.getControlsBy("CLASS_NAME",a)},CLASS_NAME:"OpenLayers.Control.Panel"});OpenLayers.Control.Button=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){},CLASS_NAME:"OpenLayers.Control.Button"});OpenLayers.Control.ZoomIn=OpenLayers.Class(OpenLayers.Control.Button,{trigger:function(){this.map&&this.map.zoomIn()},CLASS_NAME:"OpenLayers.Control.ZoomIn"});OpenLayers.Control.ZoomOut=OpenLayers.Class(OpenLayers.Control.Button,{trigger:function(){this.map&&this.map.zoomOut()},CLASS_NAME:"OpenLayers.Control.ZoomOut"});OpenLayers.Control.ZoomToMaxExtent=OpenLayers.Class(OpenLayers.Control.Button,{trigger:function(){this.map&&this.map.zoomToMaxExtent()},CLASS_NAME:"OpenLayers.Control.ZoomToMaxExtent"});OpenLayers.Control.ZoomPanel=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(a){OpenLayers.Control.Panel.prototype.initialize.apply(this,[a]);this.addControls([new OpenLayers.Control.ZoomIn,new OpenLayers.Control.ZoomToMaxExtent,new OpenLayers.Control.ZoomOut])},CLASS_NAME:"OpenLayers.Control.ZoomPanel"});OpenLayers.Layer.HTTPRequest=OpenLayers.Class(OpenLayers.Layer,{URL_HASH_FACTOR:(Math.sqrt(5)-1)/2,url:null,params:null,reproject:!1,initialize:function(a,b,c,d){OpenLayers.Layer.prototype.initialize.apply(this,[a,d]);this.url=b;this.params||(this.params=OpenLayers.Util.extend({},c))},destroy:function(){this.params=this.url=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments)},clone:function(a){null==a&&(a=new OpenLayers.Layer.HTTPRequest(this.name,this.url,this.params,this.getOptions())); | |
2152 return a=OpenLayers.Layer.prototype.clone.apply(this,[a])},setUrl:function(a){this.url=a},mergeNewParams:function(a){this.params=OpenLayers.Util.extend(this.params,a);a=this.redraw();null!=this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"params"});return a},redraw:function(a){return a?this.mergeNewParams({_olSalt:Math.random()}):OpenLayers.Layer.prototype.redraw.apply(this,[])},selectUrl:function(a,b){for(var c=1,d=0,e=a.length;d<e;d++)c*=a.charCodeAt(d)*this.URL_HASH_FACTOR, | |
2153 c-=Math.floor(c);return b[Math.floor(c*b.length)]},getFullRequestString:function(a,b){var c=b||this.url,d=OpenLayers.Util.extend({},this.params),d=OpenLayers.Util.extend(d,a),e=OpenLayers.Util.getParameterString(d);OpenLayers.Util.isArray(c)&&(c=this.selectUrl(e,c));var e=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(c)),f;for(f in d)f.toUpperCase()in e&&delete d[f];e=OpenLayers.Util.getParameterString(d);return OpenLayers.Util.urlAppend(c,e)},CLASS_NAME:"OpenLayers.Layer.HTTPRequest"});OpenLayers.Tile=OpenLayers.Class({events:null,eventListeners:null,id:null,layer:null,url:null,bounds:null,size:null,position:null,isLoading:!1,initialize:function(a,b,c,d,e,f){this.layer=a;this.position=b.clone();this.setBounds(c);this.url=d;e&&(this.size=e.clone());this.id=OpenLayers.Util.createUniqueID("Tile_");OpenLayers.Util.extend(this,f);this.events=new OpenLayers.Events(this);if(this.eventListeners instanceof Object)this.events.on(this.eventListeners)},unload:function(){this.isLoading&&(this.isLoading= | |
2154 !1,this.events.triggerEvent("unload"))},destroy:function(){this.position=this.size=this.bounds=this.layer=null;this.eventListeners&&this.events.un(this.eventListeners);this.events.destroy();this.events=this.eventListeners=null},draw:function(a){a||this.clear();var b=this.shouldDraw();b&&(!a&&!1===this.events.triggerEvent("beforedraw"))&&(b=null);return b},shouldDraw:function(){var a=!1,b=this.layer.maxExtent;if(b){var c=this.layer.map,c=c.baseLayer.wrapDateLine&&c.getMaxExtent();this.bounds.intersectsBounds(b, | |
2155 {inclusive:!1,worldBounds:c})&&(a=!0)}return a||this.layer.displayOutsideMaxExtent},setBounds:function(a){a=a.clone();if(this.layer.map.baseLayer.wrapDateLine){var b=this.layer.map.getMaxExtent(),c=this.layer.map.getResolution();a=a.wrapDateLine(b,{leftTolerance:c,rightTolerance:c})}this.bounds=a},moveTo:function(a,b,c){null==c&&(c=!0);this.setBounds(a);this.position=b.clone();c&&this.draw()},clear:function(a){},CLASS_NAME:"OpenLayers.Tile"});OpenLayers.Tile.Image=OpenLayers.Class(OpenLayers.Tile,{url:null,imgDiv:null,frame:null,imageReloadAttempts:null,layerAlphaHack:null,asyncRequestId:null,maxGetUrlLength:null,canvasContext:null,crossOriginKeyword:null,initialize:function(a,b,c,d,e,f){OpenLayers.Tile.prototype.initialize.apply(this,arguments);this.url=d;this.layerAlphaHack=this.layer.alpha&&OpenLayers.Util.alphaHack();if(null!=this.maxGetUrlLength||this.layer.gutter||this.layerAlphaHack)this.frame=document.createElement("div"),this.frame.style.position= | |
2156 "absolute",this.frame.style.overflow="hidden";null!=this.maxGetUrlLength&&OpenLayers.Util.extend(this,OpenLayers.Tile.Image.IFrame)},destroy:function(){this.imgDiv&&(this.clear(),this.frame=this.imgDiv=null);this.asyncRequestId=null;OpenLayers.Tile.prototype.destroy.apply(this,arguments)},draw:function(){var a=OpenLayers.Tile.prototype.draw.apply(this,arguments);a?(this.layer!=this.layer.map.baseLayer&&this.layer.reproject&&(this.bounds=this.getBoundsFromBaseLayer(this.position)),this.isLoading?this._loadEvent= | |
2157 "reload":(this.isLoading=!0,this._loadEvent="loadstart"),this.renderTile(),this.positionTile()):!1===a&&this.unload();return a},renderTile:function(){if(this.layer.async){var a=this.asyncRequestId=(this.asyncRequestId||0)+1;this.layer.getURLasync(this.bounds,function(b){a==this.asyncRequestId&&(this.url=b,this.initImage())},this)}else this.url=this.layer.getURL(this.bounds),this.initImage()},positionTile:function(){var a=this.getTile().style,b=this.frame?this.size:this.layer.getImageSize(this.bounds), | |
2158 c=1;this.layer instanceof OpenLayers.Layer.Grid&&(c=this.layer.getServerResolution()/this.layer.map.getResolution());a.left=this.position.x+"px";a.top=this.position.y+"px";a.width=Math.round(c*b.w)+"px";a.height=Math.round(c*b.h)+"px"},clear:function(){OpenLayers.Tile.prototype.clear.apply(this,arguments);var a=this.imgDiv;if(a){var b=this.getTile();b.parentNode===this.layer.div&&this.layer.div.removeChild(b);this.setImgSrc();!0===this.layerAlphaHack&&(a.style.filter="");OpenLayers.Element.removeClass(a, | |
2159 "olImageLoadError")}this.canvasContext=null},getImage:function(){if(!this.imgDiv){this.imgDiv=OpenLayers.Tile.Image.IMAGE.cloneNode(!1);var a=this.imgDiv.style;if(this.frame){var b=0,c=0;this.layer.gutter&&(b=100*(this.layer.gutter/this.layer.tileSize.w),c=100*(this.layer.gutter/this.layer.tileSize.h));a.left=-b+"%";a.top=-c+"%";a.width=2*b+100+"%";a.height=2*c+100+"%"}a.visibility="hidden";a.opacity=0;1>this.layer.opacity&&(a.filter="alpha(opacity="+100*this.layer.opacity+")");a.position="absolute"; | |
2160 this.layerAlphaHack&&(a.paddingTop=a.height,a.height="0",a.width="100%");this.frame&&this.frame.appendChild(this.imgDiv)}return this.imgDiv},setImage:function(a){this.imgDiv=a},initImage:function(){if(this.url||this.imgDiv){this.events.triggerEvent("beforeload");this.layer.div.appendChild(this.getTile());this.events.triggerEvent(this._loadEvent);var a=this.getImage(),b=a.getAttribute("src")||"";this.url&&OpenLayers.Util.isEquivalentUrl(b,this.url)?this._loadTimeout=window.setTimeout(OpenLayers.Function.bind(this.onImageLoad, | |
2161 this),0):(this.stopLoading(),this.crossOriginKeyword&&a.removeAttribute("crossorigin"),OpenLayers.Event.observe(a,"load",OpenLayers.Function.bind(this.onImageLoad,this)),OpenLayers.Event.observe(a,"error",OpenLayers.Function.bind(this.onImageError,this)),this.imageReloadAttempts=0,this.setImgSrc(this.url))}else this.isLoading=!1},setImgSrc:function(a){var b=this.imgDiv;a?(b.style.visibility="hidden",b.style.opacity=0,this.crossOriginKeyword&&("data:"!==a.substr(0,5)?b.setAttribute("crossorigin",this.crossOriginKeyword): | |
2162 b.removeAttribute("crossorigin")),b.src=a):(this.stopLoading(),this.imgDiv=null,b.parentNode&&b.parentNode.removeChild(b))},getTile:function(){return this.frame?this.frame:this.getImage()},createBackBuffer:function(){if(this.imgDiv&&!this.isLoading){var a;this.frame?(a=this.frame.cloneNode(!1),a.appendChild(this.imgDiv)):a=this.imgDiv;this.imgDiv=null;return a}},onImageLoad:function(){var a=this.imgDiv;this.stopLoading();a.style.visibility="inherit";a.style.opacity=this.layer.opacity;this.isLoading= | |
2163 !1;this.canvasContext=null;this.events.triggerEvent("loadend");!0===this.layerAlphaHack&&(a.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+a.src+"', sizingMethod='scale')")},onImageError:function(){var a=this.imgDiv;null!=a.src&&(this.imageReloadAttempts++,this.imageReloadAttempts<=OpenLayers.IMAGE_RELOAD_ATTEMPTS?this.setImgSrc(this.layer.getURL(this.bounds)):(OpenLayers.Element.addClass(a,"olImageLoadError"),this.events.triggerEvent("loaderror"),this.onImageLoad()))},stopLoading:function(){OpenLayers.Event.stopObservingElement(this.imgDiv); | |
2164 window.clearTimeout(this._loadTimeout);delete this._loadTimeout},getCanvasContext:function(){if(OpenLayers.CANVAS_SUPPORTED&&this.imgDiv&&!this.isLoading){if(!this.canvasContext){var a=document.createElement("canvas");a.width=this.size.w;a.height=this.size.h;this.canvasContext=a.getContext("2d");this.canvasContext.drawImage(this.imgDiv,0,0)}return this.canvasContext}},CLASS_NAME:"OpenLayers.Tile.Image"}); | |
2165 OpenLayers.Tile.Image.IMAGE=function(){var a=new Image;a.className="olTileImage";a.galleryImg="no";return a}();OpenLayers.Layer.Grid=OpenLayers.Class(OpenLayers.Layer.HTTPRequest,{tileSize:null,tileOriginCorner:"bl",tileOrigin:null,tileOptions:null,tileClass:OpenLayers.Tile.Image,grid:null,singleTile:!1,ratio:1.5,buffer:0,transitionEffect:"resize",numLoadingTiles:0,serverResolutions:null,loading:!1,backBuffer:null,gridResolution:null,backBufferResolution:null,backBufferLonLat:null,backBufferTimerId:null,removeBackBufferDelay:null,className:null,gridLayout:null,rowSign:null,transitionendEvents:["transitionend", | |
2166 "webkitTransitionEnd","otransitionend","oTransitionEnd"],initialize:function(a,b,c,d){OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,arguments);this.grid=[];this._removeBackBuffer=OpenLayers.Function.bind(this.removeBackBuffer,this);this.initProperties();this.rowSign="t"===this.tileOriginCorner.substr(0,1)?1:-1},initProperties:function(){void 0===this.options.removeBackBufferDelay&&(this.removeBackBufferDelay=this.singleTile?0:2500);void 0===this.options.className&&(this.className=this.singleTile? | |
2167 "olLayerGridSingleTile":"olLayerGrid")},setMap:function(a){OpenLayers.Layer.HTTPRequest.prototype.setMap.call(this,a);OpenLayers.Element.addClass(this.div,this.className)},removeMap:function(a){this.removeBackBuffer()},destroy:function(){this.removeBackBuffer();this.clearGrid();this.tileSize=this.grid=null;OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this,arguments)},clearGrid:function(){if(this.grid){for(var a=0,b=this.grid.length;a<b;a++)for(var c=this.grid[a],d=0,e=c.length;d<e;d++)this.destroyTile(c[d]); | |
2168 this.grid=[];this.gridLayout=this.gridResolution=null}},addOptions:function(a,b){var c=void 0!==a.singleTile&&a.singleTile!==this.singleTile;OpenLayers.Layer.HTTPRequest.prototype.addOptions.apply(this,arguments);this.map&&c&&(this.initProperties(),this.clearGrid(),this.tileSize=this.options.tileSize,this.setTileSize(),this.moveTo(null,!0))},clone:function(a){null==a&&(a=new OpenLayers.Layer.Grid(this.name,this.url,this.params,this.getOptions()));a=OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this, | |
2169 [a]);null!=this.tileSize&&(a.tileSize=this.tileSize.clone());a.grid=[];a.gridResolution=null;a.backBuffer=null;a.backBufferTimerId=null;a.loading=!1;a.numLoadingTiles=0;return a},moveTo:function(a,b,c){OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this,arguments);a=a||this.map.getExtent();if(null!=a){var d=!this.grid.length||b,e=this.getTilesBounds(),f=this.map.getResolution();this.getServerResolution(f);if(this.singleTile){if(d||!c&&!e.containsBounds(a))b&&"resize"!==this.transitionEffect&& | |
2170 this.removeBackBuffer(),b&&"resize"!==this.transitionEffect||this.applyBackBuffer(f),this.initSingleTile(a)}else(d=d||!e.intersectsBounds(a,{worldBounds:this.map.baseLayer.wrapDateLine&&this.map.getMaxExtent()}))?(!b||"resize"!==this.transitionEffect&&this.gridResolution!==f||this.applyBackBuffer(f),this.initGriddedTiles(a)):this.moveGriddedTiles()}},getTileData:function(a){var b=null,c=a.lon,d=a.lat,e=this.grid.length;if(this.map&&e){var f=this.map.getResolution();a=this.tileSize.w;var g=this.tileSize.h, | |
2171 h=this.grid[0][0].bounds,k=h.left,h=h.top;if(c<k&&this.map.baseLayer.wrapDateLine)var l=this.map.getMaxExtent().getWidth(),m=Math.ceil((k-c)/l),c=c+l*m;c=(c-k)/(f*a);d=(h-d)/(f*g);f=Math.floor(c);k=Math.floor(d);0<=k&&k<e&&(e=this.grid[k][f])&&(b={tile:e,i:Math.floor((c-f)*a),j:Math.floor((d-k)*g)})}return b},destroyTile:function(a){this.removeTileMonitoringHooks(a);a.destroy()},getServerResolution:function(a){var b=Number.POSITIVE_INFINITY;a=a||this.map.getResolution();if(this.serverResolutions&& | |
2172 -1===OpenLayers.Util.indexOf(this.serverResolutions,a)){var c,d,e,f;for(c=this.serverResolutions.length-1;0<=c;c--){e=this.serverResolutions[c];d=Math.abs(e-a);if(d>b)break;b=d;f=e}a=f}return a},getServerZoom:function(){var a=this.getServerResolution();return this.serverResolutions?OpenLayers.Util.indexOf(this.serverResolutions,a):this.map.getZoomForResolution(a)+(this.zoomOffset||0)},applyBackBuffer:function(a){null!==this.backBufferTimerId&&this.removeBackBuffer();var b=this.backBuffer;if(!b){b= | |
2173 this.createBackBuffer();if(!b)return;a===this.gridResolution?this.div.insertBefore(b,this.div.firstChild):this.map.baseLayer.div.parentNode.insertBefore(b,this.map.baseLayer.div);this.backBuffer=b;var c=this.grid[0][0].bounds;this.backBufferLonLat={lon:c.left,lat:c.top};this.backBufferResolution=this.gridResolution}for(var c=this.backBufferResolution/a,d=b.childNodes,e,f=d.length-1;0<=f;--f)e=d[f],e.style.top=(c*e._i*e._h|0)+"px",e.style.left=(c*e._j*e._w|0)+"px",e.style.width=Math.round(c*e._w)+ | |
2174 "px",e.style.height=Math.round(c*e._h)+"px";a=this.getViewPortPxFromLonLat(this.backBufferLonLat,a);c=this.map.layerContainerOriginPx.y;b.style.left=Math.round(a.x-this.map.layerContainerOriginPx.x)+"px";b.style.top=Math.round(a.y-c)+"px"},createBackBuffer:function(){var a;if(0<this.grid.length){a=document.createElement("div");a.id=this.div.id+"_bb";a.className="olBackBuffer";a.style.position="absolute";var b=this.map;a.style.zIndex="resize"===this.transitionEffect?this.getZIndex()-1:b.Z_INDEX_BASE.BaseLayer- | |
2175 (b.getNumLayers()-b.getLayerIndex(this));for(var b=0,c=this.grid.length;b<c;b++)for(var d=0,e=this.grid[b].length;d<e;d++){var f=this.grid[b][d],g=this.grid[b][d].createBackBuffer();g&&(g._i=b,g._j=d,g._w=f.size.w,g._h=f.size.h,g.id=f.id+"_bb",a.appendChild(g))}}return a},removeBackBuffer:function(){if(this._transitionElement){for(var a=this.transitionendEvents.length-1;0<=a;--a)OpenLayers.Event.stopObserving(this._transitionElement,this.transitionendEvents[a],this._removeBackBuffer);delete this._transitionElement}this.backBuffer&& | |
2176 (this.backBuffer.parentNode&&this.backBuffer.parentNode.removeChild(this.backBuffer),this.backBufferResolution=this.backBuffer=null,null!==this.backBufferTimerId&&(window.clearTimeout(this.backBufferTimerId),this.backBufferTimerId=null))},moveByPx:function(a,b){this.singleTile||this.moveGriddedTiles()},setTileSize:function(a){this.singleTile&&(a=this.map.getSize(),a.h=parseInt(a.h*this.ratio,10),a.w=parseInt(a.w*this.ratio,10));OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this,[a])},getTilesBounds:function(){var a= | |
2177 null,b=this.grid.length;if(b)var a=this.grid[b-1][0].bounds,b=this.grid[0].length*a.getWidth(),c=this.grid.length*a.getHeight(),a=new OpenLayers.Bounds(a.left,a.bottom,a.left+b,a.bottom+c);return a},initSingleTile:function(a){this.events.triggerEvent("retile");var b=a.getCenterLonLat(),c=a.getWidth()*this.ratio;a=a.getHeight()*this.ratio;b=new OpenLayers.Bounds(b.lon-c/2,b.lat-a/2,b.lon+c/2,b.lat+a/2);c=this.map.getLayerPxFromLonLat({lon:b.left,lat:b.top});this.grid.length||(this.grid[0]=[]);(a=this.grid[0][0])? | |
2178 a.moveTo(b,c):(a=this.addTile(b,c),this.addTileMonitoringHooks(a),a.draw(),this.grid[0][0]=a);this.removeExcessTiles(1,1);this.gridResolution=this.getServerResolution()},calculateGridLayout:function(a,b,c){var d=c*this.tileSize.w;c*=this.tileSize.h;var e=Math.floor((a.left-b.lon)/d)-this.buffer,f=this.rowSign;a=Math[~f?"floor":"ceil"](f*(b.lat-a.top+c)/c)-this.buffer*f;return{tilelon:d,tilelat:c,startcol:e,startrow:a}},getTileOrigin:function(){var a=this.tileOrigin;if(!a)var a=this.getMaxExtent(), | |
2179 b={tl:["left","top"],tr:["right","top"],bl:["left","bottom"],br:["right","bottom"]}[this.tileOriginCorner],a=new OpenLayers.LonLat(a[b[0]],a[b[1]]);return a},getTileBoundsForGridIndex:function(a,b){var c=this.getTileOrigin(),d=this.gridLayout,e=d.tilelon,f=d.tilelat,g=d.startcol,d=d.startrow,h=this.rowSign;return new OpenLayers.Bounds(c.lon+(g+b)*e,c.lat-(d+a*h)*f*h,c.lon+(g+b+1)*e,c.lat-(d+(a-1)*h)*f*h)},initGriddedTiles:function(a){this.events.triggerEvent("retile");var b=this.map.getSize(),c=this.getTileOrigin(), | |
2180 d=this.map.getResolution(),e=this.getServerResolution(),f=d/e,d=this.tileSize.w/f,f=this.tileSize.h/f,g=Math.ceil(b.h/f)+2*this.buffer+1,b=Math.ceil(b.w/d)+2*this.buffer+1;this.gridLayout=e=this.calculateGridLayout(a,c,e);var c=e.tilelon,h=e.tilelat,e=this.map.layerContainerOriginPx.x,k=this.map.layerContainerOriginPx.y,l=this.getTileBoundsForGridIndex(0,0),m=this.map.getViewPortPxFromLonLat(new OpenLayers.LonLat(l.left,l.top));m.x=Math.round(m.x)-e;m.y=Math.round(m.y)-k;var e=[],k=this.map.getCenter(), | |
2181 n=0;do{var p=this.grid[n];p||(p=[],this.grid.push(p));var q=0;do{var l=this.getTileBoundsForGridIndex(n,q),r=m.clone();r.x+=q*Math.round(d);r.y+=n*Math.round(f);var s=p[q];s?s.moveTo(l,r,!1):(s=this.addTile(l,r),this.addTileMonitoringHooks(s),p.push(s));r=l.getCenterLonLat();e.push({tile:s,distance:Math.pow(r.lon-k.lon,2)+Math.pow(r.lat-k.lat,2)});q+=1}while(l.right<=a.right+c*this.buffer||q<b);n+=1}while(l.bottom>=a.bottom-h*this.buffer||n<g);this.removeExcessTiles(n,q);this.gridResolution=d=this.getServerResolution(); | |
2182 e.sort(function(a,b){return a.distance-b.distance});a=0;for(d=e.length;a<d;++a)e[a].tile.draw()},getMaxExtent:function(){return this.maxExtent},addTile:function(a,b){var c=new this.tileClass(this,b,a,null,this.tileSize,this.tileOptions);this.events.triggerEvent("addtile",{tile:c});return c},addTileMonitoringHooks:function(a){a.onLoadStart=function(){!1===this.loading&&(this.loading=!0,this.events.triggerEvent("loadstart"));this.events.triggerEvent("tileloadstart",{tile:a});this.numLoadingTiles++; | |
2183 !this.singleTile&&(this.backBuffer&&this.gridResolution===this.backBufferResolution)&&OpenLayers.Element.addClass(a.getTile(),"olTileReplacing")};a.onLoadEnd=function(b){this.numLoadingTiles--;b="unload"===b.type;this.events.triggerEvent("tileloaded",{tile:a,aborted:b});if(!this.singleTile&&!b&&this.backBuffer&&this.gridResolution===this.backBufferResolution){var c=a.getTile();if("none"===OpenLayers.Element.getStyle(c,"display")){var d=document.getElementById(a.id+"_bb");d&&d.parentNode.removeChild(d)}OpenLayers.Element.removeClass(c, | |
2184 "olTileReplacing")}if(0===this.numLoadingTiles){if(this.backBuffer)if(0===this.backBuffer.childNodes.length)this.removeBackBuffer();else{this._transitionElement=b?this.div.lastChild:a.imgDiv;b=this.transitionendEvents;for(c=b.length-1;0<=c;--c)OpenLayers.Event.observe(this._transitionElement,b[c],this._removeBackBuffer);this.backBufferTimerId=window.setTimeout(this._removeBackBuffer,this.removeBackBufferDelay)}this.loading=!1;this.events.triggerEvent("loadend")}};a.onLoadError=function(){this.events.triggerEvent("tileerror", | |
2185 {tile:a})};a.events.on({loadstart:a.onLoadStart,loadend:a.onLoadEnd,unload:a.onLoadEnd,loaderror:a.onLoadError,scope:this})},removeTileMonitoringHooks:function(a){a.unload();a.events.un({loadstart:a.onLoadStart,loadend:a.onLoadEnd,unload:a.onLoadEnd,loaderror:a.onLoadError,scope:this})},moveGriddedTiles:function(){for(var a=this.buffer+1;;){var b=this.grid[0][0],c=b.position.x+this.map.layerContainerOriginPx.x,b=b.position.y+this.map.layerContainerOriginPx.y,d=this.getServerResolution()/this.map.getResolution(), | |
2186 d={w:Math.round(this.tileSize.w*d),h:Math.round(this.tileSize.h*d)};if(c>-d.w*(a-1))this.shiftColumn(!0,d);else if(c<-d.w*a)this.shiftColumn(!1,d);else if(b>-d.h*(a-1))this.shiftRow(!0,d);else if(b<-d.h*a)this.shiftRow(!1,d);else break}},shiftRow:function(a,b){var c=this.grid,d=a?0:c.length-1,e=a?-1:1;this.gridLayout.startrow+=e*this.rowSign;for(var f=c[d],g=c[a?"pop":"shift"](),h=0,k=g.length;h<k;h++){var l=g[h],m=f[h].position.clone();m.y+=b.h*e;l.moveTo(this.getTileBoundsForGridIndex(d,h),m)}c[a? | |
2187 "unshift":"push"](g)},shiftColumn:function(a,b){var c=this.grid,d=a?0:c[0].length-1,e=a?-1:1;this.gridLayout.startcol+=e;for(var f=0,g=c.length;f<g;f++){var h=c[f],k=h[d].position.clone(),l=h[a?"pop":"shift"]();k.x+=b.w*e;l.moveTo(this.getTileBoundsForGridIndex(f,d),k);h[a?"unshift":"push"](l)}},removeExcessTiles:function(a,b){for(var c,d;this.grid.length>a;){var e=this.grid.pop();c=0;for(d=e.length;c<d;c++){var f=e[c];this.destroyTile(f)}}c=0;for(d=this.grid.length;c<d;c++)for(;this.grid[c].length> | |
2188 b;)e=this.grid[c],f=e.pop(),this.destroyTile(f)},onMapResize:function(){this.singleTile&&(this.clearGrid(),this.setTileSize())},getTileBounds:function(a){var b=this.maxExtent,c=this.getResolution(),d=c*this.tileSize.w,c=c*this.tileSize.h,e=this.getLonLatFromViewPortPx(a);a=b.left+d*Math.floor((e.lon-b.left)/d);b=b.bottom+c*Math.floor((e.lat-b.bottom)/c);return new OpenLayers.Bounds(a,b,a+d,b+c)},CLASS_NAME:"OpenLayers.Layer.Grid"});OpenLayers.Format.ArcXML=OpenLayers.Class(OpenLayers.Format.XML,{fontStyleKeys:"antialiasing blockout font fontcolor fontsize fontstyle glowing interval outline printmode shadow transparency".split(" "),request:null,response:null,initialize:function(a){this.request=new OpenLayers.Format.ArcXML.Request;this.response=new OpenLayers.Format.ArcXML.Response;if(a)if("feature"==a.requesttype){this.request.get_image=null;var b=this.request.get_feature.query;this.addCoordSys(b.featurecoordsys,a.featureCoordSys); | |
2189 this.addCoordSys(b.filtercoordsys,a.filterCoordSys);a.polygon?(b.isspatial=!0,b.spatialfilter.polygon=a.polygon):a.envelope&&(b.isspatial=!0,b.spatialfilter.envelope={minx:0,miny:0,maxx:0,maxy:0},this.parseEnvelope(b.spatialfilter.envelope,a.envelope))}else"image"==a.requesttype?(this.request.get_feature=null,b=this.request.get_image.properties,this.parseEnvelope(b.envelope,a.envelope),this.addLayers(b.layerlist,a.layers),this.addImageSize(b.imagesize,a.tileSize),this.addCoordSys(b.featurecoordsys, | |
2190 a.featureCoordSys),this.addCoordSys(b.filtercoordsys,a.filterCoordSys)):this.request=null;OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},parseEnvelope:function(a,b){b&&4==b.length&&(a.minx=b[0],a.miny=b[1],a.maxx=b[2],a.maxy=b[3])},addLayers:function(a,b){for(var c=0,d=b.length;c<d;c++)a.push(b[c])},addImageSize:function(a,b){null!==b&&(a.width=b.w,a.height=b.h,a.printwidth=b.w,a.printheight=b.h)},addCoordSys:function(a,b){"string"==typeof b?(a.id=parseInt(b),a.string=b):"object"==typeof b&& | |
2191 null!==b.proj&&(a.id=b.proj.srsProjNumber,a.string=b.proj.srsCode)},iserror:function(a){var b=null;a?(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]),a=a.documentElement.getElementsByTagName("ERROR"),b=null!==a&&0<a.length):b=""!==this.response.error;return b},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b=null;a&&a.documentElement&&(b="ARCXML"==a.documentElement.nodeName?a.documentElement:a.documentElement.getElementsByTagName("ARCXML")[0]); | |
2192 if(!b||"parsererror"===b.firstChild.nodeName){var c,d;try{c=a.firstChild.nodeValue,d=a.firstChild.childNodes[1].firstChild.nodeValue}catch(e){}throw{message:"Error parsing the ArcXML request",error:c,source:d};}return this.parseResponse(b)},write:function(a){a||(a=this.request);var b=this.createElementNS("","ARCXML");b.setAttribute("version","1.1");var c=this.createElementNS("","REQUEST");if(null!=a.get_image){var d=this.createElementNS("","GET_IMAGE");c.appendChild(d);var e=this.createElementNS("", | |
2193 "PROPERTIES");d.appendChild(e);a=a.get_image.properties;null!=a.featurecoordsys&&(d=this.createElementNS("","FEATURECOORDSYS"),e.appendChild(d),0===a.featurecoordsys.id?d.setAttribute("string",a.featurecoordsys.string):d.setAttribute("id",a.featurecoordsys.id));null!=a.filtercoordsys&&(d=this.createElementNS("","FILTERCOORDSYS"),e.appendChild(d),0===a.filtercoordsys.id?d.setAttribute("string",a.filtercoordsys.string):d.setAttribute("id",a.filtercoordsys.id));null!=a.envelope&&(d=this.createElementNS("", | |
2194 "ENVELOPE"),e.appendChild(d),d.setAttribute("minx",a.envelope.minx),d.setAttribute("miny",a.envelope.miny),d.setAttribute("maxx",a.envelope.maxx),d.setAttribute("maxy",a.envelope.maxy));d=this.createElementNS("","IMAGESIZE");e.appendChild(d);d.setAttribute("height",a.imagesize.height);d.setAttribute("width",a.imagesize.width);if(a.imagesize.height!=a.imagesize.printheight||a.imagesize.width!=a.imagesize.printwidth)d.setAttribute("printheight",a.imagesize.printheight),d.setArrtibute("printwidth",a.imagesize.printwidth); | |
2195 null!=a.background&&(d=this.createElementNS("","BACKGROUND"),e.appendChild(d),d.setAttribute("color",a.background.color.r+","+a.background.color.g+","+a.background.color.b),null!==a.background.transcolor&&d.setAttribute("transcolor",a.background.transcolor.r+","+a.background.transcolor.g+","+a.background.transcolor.b));if(null!=a.layerlist&&0<a.layerlist.length)for(d=this.createElementNS("","LAYERLIST"),e.appendChild(d),e=0;e<a.layerlist.length;e++){var f=this.createElementNS("","LAYERDEF");d.appendChild(f); | |
2196 f.setAttribute("id",a.layerlist[e].id);f.setAttribute("visible",a.layerlist[e].visible);if("object"==typeof a.layerlist[e].query){var g=a.layerlist[e].query;if(0>g.where.length)continue;var h=null,h="boolean"==typeof g.spatialfilter&&g.spatialfilter?this.createElementNS("","SPATIALQUERY"):this.createElementNS("","QUERY");h.setAttribute("where",g.where);"number"==typeof g.accuracy&&0<g.accuracy&&h.setAttribute("accuracy",g.accuracy);"number"==typeof g.featurelimit&&2E3>g.featurelimit&&h.setAttribute("featurelimit", | |
2197 g.featurelimit);"string"==typeof g.subfields&&"#ALL#"!=g.subfields&&h.setAttribute("subfields",g.subfields);"string"==typeof g.joinexpression&&0<g.joinexpression.length&&h.setAttribute("joinexpression",g.joinexpression);"string"==typeof g.jointables&&0<g.jointables.length&&h.setAttribute("jointables",g.jointables);f.appendChild(h)}"object"==typeof a.layerlist[e].renderer&&this.addRenderer(f,a.layerlist[e].renderer)}}else null!=a.get_feature&&(d=this.createElementNS("","GET_FEATURES"),d.setAttribute("outputmode", | |
2198 "newxml"),d.setAttribute("checkesc","true"),a.get_feature.geometry?d.setAttribute("geometry",a.get_feature.geometry):d.setAttribute("geometry","false"),a.get_feature.compact&&d.setAttribute("compact",a.get_feature.compact),"number"==a.get_feature.featurelimit&&d.setAttribute("featurelimit",a.get_feature.featurelimit),d.setAttribute("globalenvelope","true"),c.appendChild(d),null!=a.get_feature.layer&&0<a.get_feature.layer.length&&(e=this.createElementNS("","LAYER"),e.setAttribute("id",a.get_feature.layer), | |
2199 d.appendChild(e)),a=a.get_feature.query,null!=a&&(e=null,e=a.isspatial?this.createElementNS("","SPATIALQUERY"):this.createElementNS("","QUERY"),d.appendChild(e),"number"==typeof a.accuracy&&e.setAttribute("accuracy",a.accuracy),null!=a.featurecoordsys&&(d=this.createElementNS("","FEATURECOORDSYS"),0==a.featurecoordsys.id?d.setAttribute("string",a.featurecoordsys.string):d.setAttribute("id",a.featurecoordsys.id),e.appendChild(d)),null!=a.filtercoordsys&&(d=this.createElementNS("","FILTERCOORDSYS"), | |
2200 0===a.filtercoordsys.id?d.setAttribute("string",a.filtercoordsys.string):d.setAttribute("id",a.filtercoordsys.id),e.appendChild(d)),0<a.buffer&&(d=this.createElementNS("","BUFFER"),d.setAttribute("distance",a.buffer),e.appendChild(d)),a.isspatial&&(d=this.createElementNS("","SPATIALFILTER"),d.setAttribute("relation",a.spatialfilter.relation),e.appendChild(d),a.spatialfilter.envelope?(f=this.createElementNS("","ENVELOPE"),f.setAttribute("minx",a.spatialfilter.envelope.minx),f.setAttribute("miny",a.spatialfilter.envelope.miny), | |
2201 f.setAttribute("maxx",a.spatialfilter.envelope.maxx),f.setAttribute("maxy",a.spatialfilter.envelope.maxy),d.appendChild(f)):"object"==typeof a.spatialfilter.polygon&&d.appendChild(this.writePolygonGeometry(a.spatialfilter.polygon))),null!=a.where&&0<a.where.length&&e.setAttribute("where",a.where)));b.appendChild(c);return OpenLayers.Format.XML.prototype.write.apply(this,[b])},addGroupRenderer:function(a,b){var c=this.createElementNS("","GROUPRENDERER");a.appendChild(c);for(var d=0;d<b.length;d++)this.addRenderer(c, | |
2202 b[d])},addRenderer:function(a,b){if(OpenLayers.Util.isArray(b))this.addGroupRenderer(a,b);else{var c=this.createElementNS("",b.type.toUpperCase()+"RENDERER");a.appendChild(c);"VALUEMAPRENDERER"==c.tagName?this.addValueMapRenderer(c,b):"VALUEMAPLABELRENDERER"==c.tagName?this.addValueMapLabelRenderer(c,b):"SIMPLELABELRENDERER"==c.tagName?this.addSimpleLabelRenderer(c,b):"SCALEDEPENDENTRENDERER"==c.tagName&&this.addScaleDependentRenderer(c,b)}},addScaleDependentRenderer:function(a,b){"string"!=typeof b.lower&& | |
2203 "number"!=typeof b.lower||a.setAttribute("lower",b.lower);"string"!=typeof b.upper&&"number"!=typeof b.upper||a.setAttribute("upper",b.upper);this.addRenderer(a,b.renderer)},addValueMapLabelRenderer:function(a,b){a.setAttribute("lookupfield",b.lookupfield);a.setAttribute("labelfield",b.labelfield);if("object"==typeof b.exacts)for(var c=0,d=b.exacts.length;c<d;c++){var e=b.exacts[c],f=this.createElementNS("","EXACT");"string"==typeof e.value&&f.setAttribute("value",e.value);"string"==typeof e.label&& | |
2204 f.setAttribute("label",e.label);"string"==typeof e.method&&f.setAttribute("method",e.method);a.appendChild(f);if("object"==typeof e.symbol){var g=null;"text"==e.symbol.type&&(g=this.createElementNS("","TEXTSYMBOL"));if(null!=g){for(var h=this.fontStyleKeys,k=0,l=h.length;k<l;k++){var m=h[k];e.symbol[m]&&g.setAttribute(m,e.symbol[m])}f.appendChild(g)}}}},addValueMapRenderer:function(a,b){a.setAttribute("lookupfield",b.lookupfield);if("object"==typeof b.ranges)for(var c=0,d=b.ranges.length;c<d;c++){var e= | |
2205 b.ranges[c],f=this.createElementNS("","RANGE");f.setAttribute("lower",e.lower);f.setAttribute("upper",e.upper);a.appendChild(f);if("object"==typeof e.symbol){var g=null;"simplepolygon"==e.symbol.type&&(g=this.createElementNS("","SIMPLEPOLYGONSYMBOL"));null!=g&&("string"==typeof e.symbol.boundarycolor&&g.setAttribute("boundarycolor",e.symbol.boundarycolor),"string"==typeof e.symbol.fillcolor&&g.setAttribute("fillcolor",e.symbol.fillcolor),"number"==typeof e.symbol.filltransparency&&g.setAttribute("filltransparency", | |
2206 e.symbol.filltransparency),f.appendChild(g))}}else if("object"==typeof b.exacts)for(c=0,d=b.exacts.length;c<d;c++)e=b.exacts[c],f=this.createElementNS("","EXACT"),"string"==typeof e.value&&f.setAttribute("value",e.value),"string"==typeof e.label&&f.setAttribute("label",e.label),"string"==typeof e.method&&f.setAttribute("method",e.method),a.appendChild(f),"object"==typeof e.symbol&&(g=null,"simplemarker"==e.symbol.type&&(g=this.createElementNS("","SIMPLEMARKERSYMBOL")),null!=g&&("string"==typeof e.symbol.antialiasing&& | |
2207 g.setAttribute("antialiasing",e.symbol.antialiasing),"string"==typeof e.symbol.color&&g.setAttribute("color",e.symbol.color),"string"==typeof e.symbol.outline&&g.setAttribute("outline",e.symbol.outline),"string"==typeof e.symbol.overlap&&g.setAttribute("overlap",e.symbol.overlap),"string"==typeof e.symbol.shadow&&g.setAttribute("shadow",e.symbol.shadow),"number"==typeof e.symbol.transparency&&g.setAttribute("transparency",e.symbol.transparency),"string"==typeof e.symbol.usecentroid&&g.setAttribute("usecentroid", | |
2208 e.symbol.usecentroid),"number"==typeof e.symbol.width&&g.setAttribute("width",e.symbol.width),f.appendChild(g)))},addSimpleLabelRenderer:function(a,b){a.setAttribute("field",b.field);for(var c="featureweight howmanylabels labelbufferratio labelpriorities labelweight linelabelposition rotationalangles".split(" "),d=0,e=c.length;d<e;d++){var f=c[d];b[f]&&a.setAttribute(f,b[f])}if("text"==b.symbol.type){var g=b.symbol,h=this.createElementNS("","TEXTSYMBOL");a.appendChild(h);c=this.fontStyleKeys;d=0; | |
2209 for(e=c.length;d<e;d++)f=c[d],g[f]&&h.setAttribute(f,b[f])}},writePolygonGeometry:function(a){if(!(a instanceof OpenLayers.Geometry.Polygon))throw{message:"Cannot write polygon geometry to ArcXML with an "+a.CLASS_NAME+" object.",geometry:a};for(var b=this.createElementNS("","POLYGON"),c=0,d=a.components.length;c<d;c++){for(var e=a.components[c],f=this.createElementNS("","RING"),g=0,h=e.components.length;g<h;g++){var k=e.components[g],l=this.createElementNS("","POINT");l.setAttribute("x",k.x);l.setAttribute("y", | |
2210 k.y);f.appendChild(l)}b.appendChild(f)}return b},parseResponse:function(a){"string"==typeof a&&(a=(new OpenLayers.Format.XML).read(a));var b=new OpenLayers.Format.ArcXML.Response,c=a.getElementsByTagName("ERROR");if(null!=c&&0<c.length)b.error=this.getChildValue(c,"Unknown error.");else{c=a.getElementsByTagName("RESPONSE");if(null==c||0==c.length)return b.error="No RESPONSE tag found in ArcXML response.",b;var d=c[0].firstChild.nodeName;"#text"==d&&(d=c[0].firstChild.nextSibling.nodeName);if("IMAGE"== | |
2211 d)c=a.getElementsByTagName("ENVELOPE"),a=a.getElementsByTagName("OUTPUT"),null==c||0==c.length?b.error="No ENVELOPE tag found in ArcXML response.":null==a||0==a.length?b.error="No OUTPUT tag found in ArcXML response.":(c=this.parseAttributes(c[0]),d=this.parseAttributes(a[0]),b.image="string"==typeof d.type?{envelope:c,output:{type:d.type,data:this.getChildValue(a[0])}}:{envelope:c,output:d});else if("FEATURES"==d){if(a=c[0].getElementsByTagName("FEATURES"),c=a[0].getElementsByTagName("FEATURECOUNT"), | |
2212 b.features.featurecount=c[0].getAttribute("count"),0<b.features.featurecount)for(c=a[0].getElementsByTagName("ENVELOPE"),b.features.envelope=this.parseAttributes(c[0],"number"),a=a[0].getElementsByTagName("FEATURE"),c=0;c<a.length;c++){for(var d=new OpenLayers.Feature.Vector,e=a[c].getElementsByTagName("FIELD"),f=0;f<e.length;f++){var g=e[f].getAttribute("name"),h=e[f].getAttribute("value");d.attributes[g]=h}e=a[c].getElementsByTagName("POLYGON");if(0<e.length){e=e[0].getElementsByTagName("RING"); | |
2213 f=[];for(g=0;g<e.length;g++){h=[];h.push(this.parsePointGeometry(e[g]));for(var k=e[g].getElementsByTagName("HOLE"),l=0;l<k.length;l++)h.push(this.parsePointGeometry(k[l]));f.push(new OpenLayers.Geometry.Polygon(h))}d.geometry=1==f.length?f[0]:new OpenLayers.Geometry.MultiPolygon(f)}b.features.feature.push(d)}}else b.error="Unidentified response type."}return b},parseAttributes:function(a,b){for(var c={},d=0;d<a.attributes.length;d++)c[a.attributes[d].nodeName]="number"==b?parseFloat(a.attributes[d].nodeValue): | |
2214 a.attributes[d].nodeValue;return c},parsePointGeometry:function(a){var b=[],c=a.getElementsByTagName("COORDS");if(0<c.length)for(a=this.getChildValue(c[0]),a=a.split(/;/),c=0;c<a.length;c++){var d=a[c].split(/ /);b.push(new OpenLayers.Geometry.Point(d[0],d[1]))}else if(a=a.getElementsByTagName("POINT"),0<a.length)for(c=0;c<a.length;c++)b.push(new OpenLayers.Geometry.Point(parseFloat(a[c].getAttribute("x")),parseFloat(a[c].getAttribute("y"))));return new OpenLayers.Geometry.LinearRing(b)},CLASS_NAME:"OpenLayers.Format.ArcXML"}); | |
2215 OpenLayers.Format.ArcXML.Request=OpenLayers.Class({initialize:function(a){return OpenLayers.Util.extend(this,{get_image:{properties:{background:null,draw:!0,envelope:{minx:0,miny:0,maxx:0,maxy:0},featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},imagesize:{height:0,width:0,dpi:96,printheight:0,printwidth:0,scalesymbols:!1},layerlist:[],output:{baseurl:"",legendbaseurl:"",legendname:"",legendpath:"", | |
2216 legendurl:"",name:"",path:"",type:"jpg",url:""}}},get_feature:{layer:"",query:{isspatial:!1,featurecoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},filtercoordsys:{id:0,string:"",datumtransformid:0,datumtransformstring:""},buffer:0,where:"",spatialfilter:{relation:"envelope_intersection",envelope:null}}},environment:{separators:{cs:" ",ts:";"}},layer:[],workspaces:[]})},CLASS_NAME:"OpenLayers.Format.ArcXML.Request"}); | |
2217 OpenLayers.Format.ArcXML.Response=OpenLayers.Class({initialize:function(a){return OpenLayers.Util.extend(this,{image:{envelope:null,output:""},features:{featurecount:0,envelope:null,feature:[]},error:""})},CLASS_NAME:"OpenLayers.Format.ArcXML.Response"});(function(){function a(){this._object=f&&!k?new f:new window.ActiveXObject("Microsoft.XMLHTTP");this._listeners=[]}function b(){return new a}function c(a){b.onreadystatechange&&b.onreadystatechange.apply(a);a.dispatchEvent({type:"readystatechange",bubbles:!1,cancelable:!1,timeStamp:new Date+0})}function d(a){try{a.responseText=a._object.responseText}catch(b){}try{var c;var d=a._object,e=d.responseXML,f=d.responseText;h&&(f&&e&&!e.documentElement&&d.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/))&& | |
2218 (e=new window.ActiveXObject("Microsoft.XMLDOM"),e.async=!1,e.validateOnParse=!1,e.loadXML(f));c=e&&(h&&0!=e.parseError||!e.documentElement||e.documentElement&&"parsererror"==e.documentElement.tagName)?null:e;a.responseXML=c}catch(g){}try{a.status=a._object.status}catch(k){}try{a.statusText=a._object.statusText}catch(u){}}function e(a){a._object.onreadystatechange=new window.Function}var f=window.XMLHttpRequest,g=!!window.controllers,h=window.document.all&&!window.opera,k=h&&window.navigator.userAgent.match(/MSIE 7.0/); | |
2219 b.prototype=a.prototype;g&&f.wrapped&&(b.wrapped=f.wrapped);b.UNSENT=0;b.OPENED=1;b.HEADERS_RECEIVED=2;b.LOADING=3;b.DONE=4;b.prototype.readyState=b.UNSENT;b.prototype.responseText="";b.prototype.responseXML=null;b.prototype.status=0;b.prototype.statusText="";b.prototype.priority="NORMAL";b.prototype.onreadystatechange=null;b.onreadystatechange=null;b.onopen=null;b.onsend=null;b.onabort=null;b.prototype.open=function(a,f,k,p,q){delete this._headers;3>arguments.length&&(k=!0);this._async=k;var r=this, | |
2220 s=this.readyState,t;h&&k&&(t=function(){s!=b.DONE&&(e(r),r.abort())},window.attachEvent("onunload",t));b.onopen&&b.onopen.apply(this,arguments);4<arguments.length?this._object.open(a,f,k,p,q):3<arguments.length?this._object.open(a,f,k,p):this._object.open(a,f,k);this.readyState=b.OPENED;c(this);this._object.onreadystatechange=function(){if(!g||k)r.readyState=r._object.readyState,d(r),r._aborted?r.readyState=b.UNSENT:(r.readyState==b.DONE&&(delete r._data,e(r),h&&k&&window.detachEvent("onunload",t)), | |
2221 s!=r.readyState&&c(r),s=r.readyState)}};b.prototype.send=function(a){b.onsend&&b.onsend.apply(this,arguments);arguments.length||(a=null);a&&a.nodeType&&(a=window.XMLSerializer?(new window.XMLSerializer).serializeToString(a):a.xml,this._headers["Content-Type"]||this._object.setRequestHeader("Content-Type","application/xml"));this._data=a;a:if(this._object.send(this._data),g&&!this._async)for(this.readyState=b.OPENED,d(this);this.readyState<b.DONE;)if(this.readyState++,c(this),this._aborted)break a}; | |
2222 b.prototype.abort=function(){b.onabort&&b.onabort.apply(this,arguments);this.readyState>b.UNSENT&&(this._aborted=!0);this._object.abort();e(this);this.readyState=b.UNSENT;delete this._data};b.prototype.getAllResponseHeaders=function(){return this._object.getAllResponseHeaders()};b.prototype.getResponseHeader=function(a){return this._object.getResponseHeader(a)};b.prototype.setRequestHeader=function(a,b){this._headers||(this._headers={});this._headers[a]=b;return this._object.setRequestHeader(a,b)}; | |
2223 b.prototype.addEventListener=function(a,b,c){for(var d=0,e;e=this._listeners[d];d++)if(e[0]==a&&e[1]==b&&e[2]==c)return;this._listeners.push([a,b,c])};b.prototype.removeEventListener=function(a,b,c){for(var d=0,e;(e=this._listeners[d])&&(e[0]!=a||e[1]!=b||e[2]!=c);d++);e&&this._listeners.splice(d,1)};b.prototype.dispatchEvent=function(a){a={type:a.type,target:this,currentTarget:this,eventPhase:2,bubbles:a.bubbles,cancelable:a.cancelable,timeStamp:a.timeStamp,stopPropagation:function(){},preventDefault:function(){}, | |
2224 initEvent:function(){}};"readystatechange"==a.type&&this.onreadystatechange&&(this.onreadystatechange.handleEvent||this.onreadystatechange).apply(this,[a]);for(var b=0,c;c=this._listeners[b];b++)c[0]!=a.type||c[2]||(c[1].handleEvent||c[1]).apply(this,[a])};b.prototype.toString=function(){return"[object XMLHttpRequest]"};b.toString=function(){return"[XMLHttpRequest]"};window.Function.prototype.apply||(window.Function.prototype.apply=function(a,b){b||(b=[]);a.__func=this;a.__func(b[0],b[1],b[2],b[3], | |
2225 b[4]);delete a.__func});OpenLayers.Request||(OpenLayers.Request={});OpenLayers.Request.XMLHttpRequest=b})();OpenLayers.ProxyHost="";OpenLayers.Request||(OpenLayers.Request={}); | |
2226 OpenLayers.Util.extend(OpenLayers.Request,{DEFAULT_CONFIG:{method:"GET",url:window.location.href,async:!0,user:void 0,password:void 0,params:null,proxy:OpenLayers.ProxyHost,headers:{},data:null,callback:function(){},success:null,failure:null,scope:null},URL_SPLIT_REGEX:/([^:]*:)\/\/([^:]*:?[^@]*@)?([^:\/\?]*):?([^\/\?]*)/,events:new OpenLayers.Events(this),makeSameOrigin:function(a,b){var c=0!==a.indexOf("http"),d=!c&&a.match(this.URL_SPLIT_REGEX);if(d){var e=window.location,c=d[1]==e.protocol&&d[3]== | |
2227 e.hostname,d=d[4],e=e.port;if(80!=d&&""!=d||"80"!=e&&""!=e)c=c&&d==e}c||b&&(a="function"==typeof b?b(a):b+encodeURIComponent(a));return a},issue:function(a){var b=OpenLayers.Util.extend(this.DEFAULT_CONFIG,{proxy:OpenLayers.ProxyHost});a=a||{};a.headers=a.headers||{};a=OpenLayers.Util.applyDefaults(a,b);a.headers=OpenLayers.Util.applyDefaults(a.headers,b.headers);var b=!1,c;for(c in a.headers)a.headers.hasOwnProperty(c)&&"x-requested-with"===c.toLowerCase()&&(b=!0);!1===b&&(a.headers["X-Requested-With"]= | |
2228 "XMLHttpRequest");var d=new OpenLayers.Request.XMLHttpRequest,e=OpenLayers.Util.urlAppend(a.url,OpenLayers.Util.getParameterString(a.params||{})),e=OpenLayers.Request.makeSameOrigin(e,a.proxy);d.open(a.method,e,a.async,a.user,a.password);for(var f in a.headers)d.setRequestHeader(f,a.headers[f]);var g=this.events,h=this;d.onreadystatechange=function(){d.readyState==OpenLayers.Request.XMLHttpRequest.DONE&&!1!==g.triggerEvent("complete",{request:d,config:a,requestUrl:e})&&h.runCallbacks({request:d,config:a, | |
2229 requestUrl:e})};!1===a.async?d.send(a.data):window.setTimeout(function(){0!==d.readyState&&d.send(a.data)},0);return d},runCallbacks:function(a){var b=a.request,c=a.config,d=c.scope?OpenLayers.Function.bind(c.callback,c.scope):c.callback,e;c.success&&(e=c.scope?OpenLayers.Function.bind(c.success,c.scope):c.success);var f;c.failure&&(f=c.scope?OpenLayers.Function.bind(c.failure,c.scope):c.failure);"file:"==OpenLayers.Util.createUrlObject(c.url).protocol&&b.responseText&&(b.status=200);d(b);if(!b.status|| | |
2230 200<=b.status&&300>b.status)this.events.triggerEvent("success",a),e&&e(b);b.status&&(200>b.status||300<=b.status)&&(this.events.triggerEvent("failure",a),f&&f(b))},GET:function(a){a=OpenLayers.Util.extend(a,{method:"GET"});return OpenLayers.Request.issue(a)},POST:function(a){a=OpenLayers.Util.extend(a,{method:"POST"});a.headers=a.headers?a.headers:{};"CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(a.headers)||(a.headers["Content-Type"]="application/xml");return OpenLayers.Request.issue(a)},PUT:function(a){a= | |
2231 OpenLayers.Util.extend(a,{method:"PUT"});a.headers=a.headers?a.headers:{};"CONTENT-TYPE"in OpenLayers.Util.upperCaseObject(a.headers)||(a.headers["Content-Type"]="application/xml");return OpenLayers.Request.issue(a)},DELETE:function(a){a=OpenLayers.Util.extend(a,{method:"DELETE"});return OpenLayers.Request.issue(a)},HEAD:function(a){a=OpenLayers.Util.extend(a,{method:"HEAD"});return OpenLayers.Request.issue(a)},OPTIONS:function(a){a=OpenLayers.Util.extend(a,{method:"OPTIONS"});return OpenLayers.Request.issue(a)}});OpenLayers.Layer.ArcIMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{ClientVersion:"9.2",ServiceName:""},featureCoordSys:"4326",filterCoordSys:"4326",layers:null,async:!0,name:"ArcIMS",isBaseLayer:!0,DEFAULT_OPTIONS:{tileSize:new OpenLayers.Size(512,512),featureCoordSys:"4326",filterCoordSys:"4326",layers:null,isBaseLayer:!0,async:!0,name:"ArcIMS"},initialize:function(a,b,c){this.tileSize=new OpenLayers.Size(512,512);this.params=OpenLayers.Util.applyDefaults({ServiceName:c.serviceName}, | |
2232 this.DEFAULT_PARAMS);this.options=OpenLayers.Util.applyDefaults(c,this.DEFAULT_OPTIONS);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a,b,this.params,c]);this.transparent&&(this.isBaseLayer||(this.isBaseLayer=!1),"image/jpeg"==this.format&&(this.format=OpenLayers.Util.alphaHack()?"image/gif":"image/png"));null===this.options.layers&&(this.options.layers=[])},getURL:function(a){var b="";a=this.adjustBounds(a);a=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image", | |
2233 envelope:a.toArray(),tileSize:this.tileSize}));a=new OpenLayers.Request.POST({url:this.getFullRequestString(),data:a.write(),async:!1});null!=a&&(b=a.responseXML,b&&b.documentElement||(b=a.responseText),b=(new OpenLayers.Format.ArcXML).read(b),b=this.getUrlOrImage(b.image.output));return b},getURLasync:function(a,b,c){a=this.adjustBounds(a);a=new OpenLayers.Format.ArcXML(OpenLayers.Util.extend(this.options,{requesttype:"image",envelope:a.toArray(),tileSize:this.tileSize}));OpenLayers.Request.POST({url:this.getFullRequestString(), | |
2234 async:!0,data:a.write(),callback:function(a){var e=a.responseXML;e&&e.documentElement||(e=a.responseText);a=(new OpenLayers.Format.ArcXML).read(e);b.call(c,this.getUrlOrImage(a.image.output))},scope:this})},getUrlOrImage:function(a){var b="";a.url?b=a.url:a.data&&(b="data:image/"+a.type+";base64,"+a.data);return b},setLayerQuery:function(a,b){for(var c=0;c<this.options.layers.length;c++)if(a==this.options.layers[c].id){this.options.layers[c].query=b;return}this.options.layers.push({id:a,visible:!0, | |
2235 query:b})},getFeatureInfo:function(a,b,c){var d=c.buffer||1,e=c.callback||function(){},f=c.scope||window,g={};OpenLayers.Util.extend(g,this.options);g.requesttype="feature";a instanceof OpenLayers.LonLat?(g.polygon=null,g.envelope=[a.lon-d,a.lat-d,a.lon+d,a.lat+d]):a instanceof OpenLayers.Geometry.Polygon&&(g.envelope=null,g.polygon=a);var h=new OpenLayers.Format.ArcXML(g);OpenLayers.Util.extend(h.request.get_feature,c);h.request.get_feature.layer=b.id;"number"==typeof b.query.accuracy?h.request.get_feature.query.accuracy= | |
2236 b.query.accuracy:(a=this.map.getCenter(),c=this.map.getViewPortPxFromLonLat(a),c.x++,c=this.map.getLonLatFromPixel(c),h.request.get_feature.query.accuracy=c.lon-a.lon);h.request.get_feature.query.where=b.query.where;h.request.get_feature.query.spatialfilter.relation="area_intersection";OpenLayers.Request.POST({url:this.getFullRequestString({CustomService:"Query"}),data:h.write(),callback:function(a){a=h.parseResponse(a.responseText);h.iserror()?e.call(f,null):e.call(f,a.features)}})},clone:function(a){null== | |
2237 a&&(a=new OpenLayers.Layer.ArcIMS(this.name,this.url,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},CLASS_NAME:"OpenLayers.Layer.ArcIMS"});OpenLayers.Control.PanZoom=OpenLayers.Class(OpenLayers.Control,{slideFactor:50,slideRatio:null,buttons:null,position:null,initialize:function(a){this.position=new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,OpenLayers.Control.PanZoom.Y);OpenLayers.Control.prototype.initialize.apply(this,arguments)},destroy:function(){this.map&&this.map.events.unregister("buttonclick",this,this.onButtonClick);this.removeButtons();this.position=this.buttons=null;OpenLayers.Control.prototype.destroy.apply(this,arguments)}, | |
2238 setMap:function(a){OpenLayers.Control.prototype.setMap.apply(this,arguments);this.map.events.register("buttonclick",this,this.onButtonClick)},draw:function(a){OpenLayers.Control.prototype.draw.apply(this,arguments);a=this.position;this.buttons=[];var b={w:18,h:18},c=new OpenLayers.Pixel(a.x+b.w/2,a.y);this._addButton("panup","north-mini.png",c,b);a.y=c.y+b.h;this._addButton("panleft","west-mini.png",a,b);this._addButton("panright","east-mini.png",a.add(b.w,0),b);this._addButton("pandown","south-mini.png", | |
2239 c.add(0,2*b.h),b);this._addButton("zoomin","zoom-plus-mini.png",c.add(0,3*b.h+5),b);this._addButton("zoomworld","zoom-world-mini.png",c.add(0,4*b.h+5),b);this._addButton("zoomout","zoom-minus-mini.png",c.add(0,5*b.h+5),b);return this.div},_addButton:function(a,b,c,d){b=OpenLayers.Util.getImageLocation(b);c=OpenLayers.Util.createAlphaImageDiv(this.id+"_"+a,c,d,b,"absolute");c.style.cursor="pointer";this.div.appendChild(c);c.action=a;c.className="olButton";this.buttons.push(c);return c},_removeButton:function(a){this.div.removeChild(a); | |
2240 OpenLayers.Util.removeItem(this.buttons,a)},removeButtons:function(){for(var a=this.buttons.length-1;0<=a;--a)this._removeButton(this.buttons[a])},onButtonClick:function(a){switch(a.buttonElement.action){case "panup":this.map.pan(0,-this.getSlideFactor("h"));break;case "pandown":this.map.pan(0,this.getSlideFactor("h"));break;case "panleft":this.map.pan(-this.getSlideFactor("w"),0);break;case "panright":this.map.pan(this.getSlideFactor("w"),0);break;case "zoomin":this.map.zoomIn();break;case "zoomout":this.map.zoomOut(); | |
2241 break;case "zoomworld":this.map.zoomToMaxExtent()}},getSlideFactor:function(a){return this.slideRatio?this.map.getSize()[a]*this.slideRatio:this.slideFactor},CLASS_NAME:"OpenLayers.Control.PanZoom"});OpenLayers.Control.PanZoom.X=4;OpenLayers.Control.PanZoom.Y=4;OpenLayers.Control.PanZoomBar=OpenLayers.Class(OpenLayers.Control.PanZoom,{zoomStopWidth:18,zoomStopHeight:11,slider:null,sliderEvents:null,zoombarDiv:null,zoomWorldIcon:!1,panIcons:!0,forceFixedZoomLevel:!1,mouseDragStart:null,deltaY:null,zoomStart:null,destroy:function(){this._removeZoomBar();this.map.events.un({changebaselayer:this.redraw,updatesize:this.redraw,scope:this});OpenLayers.Control.PanZoom.prototype.destroy.apply(this,arguments);delete this.mouseDragStart;delete this.zoomStart},setMap:function(a){OpenLayers.Control.PanZoom.prototype.setMap.apply(this, | |
2242 arguments);this.map.events.on({changebaselayer:this.redraw,updatesize:this.redraw,scope:this})},redraw:function(){null!=this.div&&(this.removeButtons(),this._removeZoomBar());this.draw()},draw:function(a){OpenLayers.Control.prototype.draw.apply(this,arguments);a=this.position.clone();this.buttons=[];var b={w:18,h:18};if(this.panIcons){var c=new OpenLayers.Pixel(a.x+b.w/2,a.y),d=b.w;this.zoomWorldIcon&&(c=new OpenLayers.Pixel(a.x+b.w,a.y));this._addButton("panup","north-mini.png",c,b);a.y=c.y+b.h; | |
2243 this._addButton("panleft","west-mini.png",a,b);this.zoomWorldIcon&&(this._addButton("zoomworld","zoom-world-mini.png",a.add(b.w,0),b),d*=2);this._addButton("panright","east-mini.png",a.add(d,0),b);this._addButton("pandown","south-mini.png",c.add(0,2*b.h),b);this._addButton("zoomin","zoom-plus-mini.png",c.add(0,3*b.h+5),b);c=this._addZoomBar(c.add(0,4*b.h+5));this._addButton("zoomout","zoom-minus-mini.png",c,b)}else this._addButton("zoomin","zoom-plus-mini.png",a,b),c=this._addZoomBar(a.add(0,b.h)), | |
2244 this._addButton("zoomout","zoom-minus-mini.png",c,b),this.zoomWorldIcon&&(c=c.add(0,b.h+3),this._addButton("zoomworld","zoom-world-mini.png",c,b));return this.div},_addZoomBar:function(a){var b=OpenLayers.Util.getImageLocation("slider.png"),c=this.id+"_"+this.map.id,d=this.map.getMinZoom(),e=this.map.getNumZoomLevels()-1-this.map.getZoom(),e=OpenLayers.Util.createAlphaImageDiv(c,a.add(-1,e*this.zoomStopHeight),{w:20,h:9},b,"absolute");e.style.cursor="move";this.slider=e;this.sliderEvents=new OpenLayers.Events(this, | |
2245 e,null,!0,{includeXY:!0});this.sliderEvents.on({touchstart:this.zoomBarDown,touchmove:this.zoomBarDrag,touchend:this.zoomBarUp,mousedown:this.zoomBarDown,mousemove:this.zoomBarDrag,mouseup:this.zoomBarUp});var f={w:this.zoomStopWidth,h:this.zoomStopHeight*(this.map.getNumZoomLevels()-d)},b=OpenLayers.Util.getImageLocation("zoombar.png"),c=null;OpenLayers.Util.alphaHack()?(c=this.id+"_"+this.map.id,c=OpenLayers.Util.createAlphaImageDiv(c,a,{w:f.w,h:this.zoomStopHeight},b,"absolute",null,"crop"),c.style.height= | |
2246 f.h+"px"):c=OpenLayers.Util.createDiv("OpenLayers_Control_PanZoomBar_Zoombar"+this.map.id,a,f,b);c.style.cursor="pointer";c.className="olButton";this.zoombarDiv=c;this.div.appendChild(c);this.startTop=parseInt(c.style.top);this.div.appendChild(e);this.map.events.register("zoomend",this,this.moveZoomBar);return a=a.add(0,this.zoomStopHeight*(this.map.getNumZoomLevels()-d))},_removeZoomBar:function(){this.sliderEvents.un({touchstart:this.zoomBarDown,touchmove:this.zoomBarDrag,touchend:this.zoomBarUp, | |
2247 mousedown:this.zoomBarDown,mousemove:this.zoomBarDrag,mouseup:this.zoomBarUp});this.sliderEvents.destroy();this.div.removeChild(this.zoombarDiv);this.zoombarDiv=null;this.div.removeChild(this.slider);this.slider=null;this.map.events.unregister("zoomend",this,this.moveZoomBar)},onButtonClick:function(a){OpenLayers.Control.PanZoom.prototype.onButtonClick.apply(this,arguments);if(a.buttonElement===this.zoombarDiv){var b=a.buttonXY.y/this.zoomStopHeight;if(this.forceFixedZoomLevel||!this.map.fractionalZoom)b= | |
2248 Math.floor(b);b=this.map.getNumZoomLevels()-1-b;b=Math.min(Math.max(b,0),this.map.getNumZoomLevels()-1);this.map.zoomTo(b)}},passEventToSlider:function(a){this.sliderEvents.handleBrowserEvent(a)},zoomBarDown:function(a){if(OpenLayers.Event.isLeftClick(a)||OpenLayers.Event.isSingleTouch(a))this.map.events.on({touchmove:this.passEventToSlider,mousemove:this.passEventToSlider,mouseup:this.passEventToSlider,scope:this}),this.mouseDragStart=a.xy.clone(),this.zoomStart=a.xy.clone(),this.div.style.cursor= | |
2249 "move",this.zoombarDiv.offsets=null,OpenLayers.Event.stop(a)},zoomBarDrag:function(a){if(null!=this.mouseDragStart){var b=this.mouseDragStart.y-a.xy.y,c=OpenLayers.Util.pagePosition(this.zoombarDiv);0<a.clientY-c[1]&&a.clientY-c[1]<parseInt(this.zoombarDiv.style.height)-2&&(b=parseInt(this.slider.style.top)-b,this.slider.style.top=b+"px",this.mouseDragStart=a.xy.clone());this.deltaY=this.zoomStart.y-a.xy.y;OpenLayers.Event.stop(a)}},zoomBarUp:function(a){if((OpenLayers.Event.isLeftClick(a)||"touchend"=== | |
2250 a.type)&&this.mouseDragStart){this.div.style.cursor="";this.map.events.un({touchmove:this.passEventToSlider,mouseup:this.passEventToSlider,mousemove:this.passEventToSlider,scope:this});var b=this.map.zoom;!this.forceFixedZoomLevel&&this.map.fractionalZoom?(b+=this.deltaY/this.zoomStopHeight,b=Math.min(Math.max(b,0),this.map.getNumZoomLevels()-1)):(b+=this.deltaY/this.zoomStopHeight,b=Math.max(Math.round(b),0));this.map.zoomTo(b);this.zoomStart=this.mouseDragStart=null;this.deltaY=0;OpenLayers.Event.stop(a)}}, | |
2251 moveZoomBar:function(){var a=(this.map.getNumZoomLevels()-1-this.map.getZoom())*this.zoomStopHeight+this.startTop+1;this.slider.style.top=a+"px"},CLASS_NAME:"OpenLayers.Control.PanZoomBar"});OpenLayers.Format.WFSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.1.0",CLASS_NAME:"OpenLayers.Format.WFSCapabilities"});OpenLayers.Format.WFSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{wfs:"http://www.opengis.net/wfs",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",ows:"http://www.opengis.net/ows"},errorProperty:"featureTypeList",defaultPrefix:"wfs",read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b},readers:{wfs:{WFS_Capabilities:function(a, | |
2252 b){this.readChildNodes(a,b)},FeatureTypeList:function(a,b){b.featureTypeList={featureTypes:[]};this.readChildNodes(a,b.featureTypeList)},FeatureType:function(a,b){var c={};this.readChildNodes(a,c);b.featureTypes.push(c)},Name:function(a,b){var c=this.getChildValue(a);c&&(c=c.split(":"),b.name=c.pop(),0<c.length&&(b.featureNS=this.lookupNamespaceURI(a,c[0])))},Title:function(a,b){var c=this.getChildValue(a);c&&(b.title=c)},Abstract:function(a,b){var c=this.getChildValue(a);c&&(b["abstract"]=c)}}}, | |
2253 CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1"});OpenLayers.Format.WFSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},readers:{wfs:OpenLayers.Util.applyDefaults({DefaultSRS:function(a,b){var c=this.getChildValue(a);c&&(b.srs=c)}},OpenLayers.Format.WFSCapabilities.v1.prototype.readers.wfs),ows:OpenLayers.Format.OWSCommon.v1.prototype.readers.ows},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_1_0"});OpenLayers.Layer.Image=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:!0,url:null,extent:null,size:null,tile:null,aspectRatio:null,initialize:function(a,b,c,d,e){this.url=b;this.maxExtent=this.extent=c;this.size=d;OpenLayers.Layer.prototype.initialize.apply(this,[a,e]);this.aspectRatio=this.extent.getHeight()/this.size.h/(this.extent.getWidth()/this.size.w)},destroy:function(){this.tile&&(this.removeTileMonitoringHooks(this.tile),this.tile.destroy(),this.tile=null);OpenLayers.Layer.prototype.destroy.apply(this, | |
2254 arguments)},clone:function(a){null==a&&(a=new OpenLayers.Layer.Image(this.name,this.url,this.extent,this.size,this.getOptions()));return a=OpenLayers.Layer.prototype.clone.apply(this,[a])},setMap:function(a){null==this.options.maxResolution&&(this.options.maxResolution=this.aspectRatio*this.extent.getWidth()/this.size.w);OpenLayers.Layer.prototype.setMap.apply(this,arguments)},moveTo:function(a,b,c){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var d=null==this.tile;if(b||d){this.setTileSize(); | |
2255 var e=this.map.getLayerPxFromLonLat({lon:this.extent.left,lat:this.extent.top});d?(this.tile=new OpenLayers.Tile.Image(this,e,this.extent,null,this.tileSize),this.addTileMonitoringHooks(this.tile)):(this.tile.size=this.tileSize.clone(),this.tile.position=e.clone());this.tile.draw()}},setTileSize:function(){var a=this.extent.getWidth()/this.map.getResolution(),b=this.extent.getHeight()/this.map.getResolution();this.tileSize=new OpenLayers.Size(a,b)},addTileMonitoringHooks:function(a){a.onLoadStart= | |
2256 function(){this.events.triggerEvent("loadstart")};a.events.register("loadstart",this,a.onLoadStart);a.onLoadEnd=function(){this.events.triggerEvent("loadend")};a.events.register("loadend",this,a.onLoadEnd);a.events.register("unload",this,a.onLoadEnd)},removeTileMonitoringHooks:function(a){a.unload();a.events.un({loadstart:a.onLoadStart,loadend:a.onLoadEnd,unload:a.onLoadEnd,scope:this})},setUrl:function(a){this.url=a;this.tile.draw()},getURL:function(a){return this.url},CLASS_NAME:"OpenLayers.Layer.Image"});OpenLayers.Strategy=OpenLayers.Class({layer:null,options:null,active:null,autoActivate:!0,autoDestroy:!0,initialize:function(a){OpenLayers.Util.extend(this,a);this.options=a;this.active=!1},destroy:function(){this.deactivate();this.options=this.layer=null},setLayer:function(a){this.layer=a},activate:function(){return this.active?!1:this.active=!0},deactivate:function(){return this.active?(this.active=!1,!0):!1},CLASS_NAME:"OpenLayers.Strategy"});OpenLayers.Strategy.Save=OpenLayers.Class(OpenLayers.Strategy,{events:null,auto:!1,timer:null,initialize:function(a){OpenLayers.Strategy.prototype.initialize.apply(this,[a]);this.events=new OpenLayers.Events(this)},activate:function(){var a=OpenLayers.Strategy.prototype.activate.call(this);if(a&&this.auto)if("number"===typeof this.auto)this.timer=window.setInterval(OpenLayers.Function.bind(this.save,this),1E3*this.auto);else this.layer.events.on({featureadded:this.triggerSave,afterfeaturemodified:this.triggerSave, | |
2257 scope:this});return a},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&this.auto&&("number"===typeof this.auto?window.clearInterval(this.timer):this.layer.events.un({featureadded:this.triggerSave,afterfeaturemodified:this.triggerSave,scope:this}));return a},triggerSave:function(a){var b=a.feature;b.state!==OpenLayers.State.INSERT&&b.state!==OpenLayers.State.UPDATE&&b.state!==OpenLayers.State.DELETE||this.save([a.feature])},save:function(a){a||(a=this.layer.features); | |
2258 this.events.triggerEvent("start",{features:a});var b=this.layer.projection,c=this.layer.map.getProjectionObject();if(!c.equals(b)){for(var d=a.length,e=Array(d),f,g,h=0;h<d;++h)f=a[h],g=f.clone(),g.fid=f.fid,g.state=f.state,f.url&&(g.url=f.url),g._original=f,g.geometry.transform(c,b),e[h]=g;a=e}this.layer.protocol.commit(a,{callback:this.onCommit,scope:this})},onCommit:function(a){var b={response:a};if(a.success()){for(var c=a.reqFeatures,d,e=[],f=a.insertIds||[],g=0,h=0,k=c.length;h<k;++h)if(d=c[h], | |
2259 d=d._original||d,a=d.state)a==OpenLayers.State.DELETE?e.push(d):a==OpenLayers.State.INSERT&&(d.fid=f[g],++g),d.state=null;0<e.length&&this.layer.destroyFeatures(e);this.events.triggerEvent("success",b)}else this.events.triggerEvent("fail",b)},CLASS_NAME:"OpenLayers.Strategy.Save"});OpenLayers.Events.featureclick=OpenLayers.Class({cache:null,map:null,provides:["featureclick","nofeatureclick","featureover","featureout"],initialize:function(a){this.target=a;if(a.object instanceof OpenLayers.Map)this.setMap(a.object);else if(a.object instanceof OpenLayers.Layer.Vector)a.object.map?this.setMap(a.object.map):a.object.events.register("added",this,function(b){this.setMap(a.object.map)});else throw"Listeners for '"+this.provides.join("', '")+"' events can only be registered for OpenLayers.Layer.Vector or OpenLayers.Map instances"; | |
2260 for(var b=this.provides.length-1;0<=b;--b)a.extensions[this.provides[b]]=!0},setMap:function(a){this.map=a;this.cache={};a.events.register("mousedown",this,this.start,{extension:!0});a.events.register("mouseup",this,this.onClick,{extension:!0});a.events.register("touchstart",this,this.start,{extension:!0});a.events.register("touchmove",this,this.cancel,{extension:!0});a.events.register("touchend",this,this.onClick,{extension:!0});a.events.register("mousemove",this,this.onMousemove,{extension:!0})}, | |
2261 start:function(a){this.startEvt=a},cancel:function(a){delete this.startEvt},onClick:function(a){if(this.startEvt&&("touchend"===a.type||OpenLayers.Event.isLeftClick(a))){a=this.getFeatures(this.startEvt);delete this.startEvt;for(var b,c,d={},e=0,f=a.length;e<f&&(b=a[e],c=b.layer,d[c.id]=!0,b=this.triggerEvent("featureclick",{feature:b}),!1!==b);++e);e=0;for(f=this.map.layers.length;e<f;++e)c=this.map.layers[e],c instanceof OpenLayers.Layer.Vector&&!d[c.id]&&this.triggerEvent("nofeatureclick",{layer:c})}}, | |
2262 onMousemove:function(a){delete this.startEvt;var b=this.getFeatures(a),c={};a=[];for(var d,e=0,f=b.length;e<f;++e)d=b[e],c[d.id]=d,this.cache[d.id]||a.push(d);var b=[],g;for(g in this.cache)d=this.cache[g],d.layer&&d.layer.map?c[d.id]||b.push(d):delete this.cache[g];e=0;for(f=a.length;e<f&&(d=a[e],this.cache[d.id]=d,g=this.triggerEvent("featureover",{feature:d}),!1!==g);++e);e=0;for(f=b.length;e<f&&(d=b[e],delete this.cache[d.id],g=this.triggerEvent("featureout",{feature:d}),!1!==g);++e);},triggerEvent:function(a, | |
2263 b){var c=b.feature?b.feature.layer:b.layer,d=this.target.object;if(d instanceof OpenLayers.Map||d===c)return this.target.triggerEvent(a,b)},getFeatures:function(a){var b=a.clientX,c=a.clientY,d=[],e=[],f=[],g,h,k,l;for(l=this.map.layers.length-1;0<=l;--l)if(g=this.map.layers[l],"none"!==g.div.style.display)if(g.renderer instanceof OpenLayers.Renderer.Elements){if(g instanceof OpenLayers.Layer.Vector)for(h=document.elementFromPoint(b,c);h&&h._featureId;)(k=g.getFeatureById(h._featureId))?(d.push(k), | |
2264 h.style.display="none",e.push(h),h=document.elementFromPoint(b,c)):h=!1;f.push(g);g.div.style.display="none"}else g.renderer instanceof OpenLayers.Renderer.Canvas&&(k=g.renderer.getFeatureIdFromEvent(a))&&(d.push(k),f.push(g));l=0;for(a=e.length;l<a;++l)e[l].style.display="";for(l=f.length-1;0<=l;--l)f[l].div.style.display="block";return d},destroy:function(){for(var a=this.provides.length-1;0<=a;--a)delete this.target.extensions[this.provides[a]];this.map.events.un({mousemove:this.onMousemove,mousedown:this.start, | |
2265 mouseup:this.onClick,touchstart:this.start,touchmove:this.cancel,touchend:this.onClick,scope:this});delete this.cache;delete this.map;delete this.target}});OpenLayers.Events.nofeatureclick=OpenLayers.Events.featureclick;OpenLayers.Events.featureover=OpenLayers.Events.featureclick;OpenLayers.Events.featureout=OpenLayers.Events.featureclick;OpenLayers.Format.GPX=OpenLayers.Class(OpenLayers.Format.XML,{defaultDesc:"No description available",extractWaypoints:!0,extractTracks:!0,extractRoutes:!0,extractAttributes:!0,namespaces:{gpx:"http://www.topografix.com/GPX/1/1",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd",creator:"OpenLayers",initialize:function(a){this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this, | |
2266 [a])},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b=[];if(this.extractTracks)for(var c=a.getElementsByTagName("trk"),d=0,e=c.length;d<e;d++){var f={};this.extractAttributes&&(f=this.parseAttributes(c[d]));for(var g=this.getElementsByTagNameNS(c[d],c[d].namespaceURI,"trkseg"),h=0,k=g.length;h<k;h++){var l=this.extractSegment(g[h],"trkpt");b.push(new OpenLayers.Feature.Vector(l,f))}}if(this.extractRoutes)for(e=a.getElementsByTagName("rte"),c=0,d= | |
2267 e.length;c<d;c++)f={},this.extractAttributes&&(f=this.parseAttributes(e[c])),g=this.extractSegment(e[c],"rtept"),b.push(new OpenLayers.Feature.Vector(g,f));if(this.extractWaypoints)for(a=a.getElementsByTagName("wpt"),c=0,e=a.length;c<e;c++)f={},this.extractAttributes&&(f=this.parseAttributes(a[c])),d=new OpenLayers.Geometry.Point(a[c].getAttribute("lon"),a[c].getAttribute("lat")),b.push(new OpenLayers.Feature.Vector(d,f));if(this.internalProjection&&this.externalProjection)for(f=0,a=b.length;f<a;f++)b[f].geometry.transform(this.externalProjection, | |
2268 this.internalProjection);return b},extractSegment:function(a,b){for(var c=this.getElementsByTagNameNS(a,a.namespaceURI,b),d=[],e=0,f=c.length;e<f;e++)d.push(new OpenLayers.Geometry.Point(c[e].getAttribute("lon"),c[e].getAttribute("lat")));return new OpenLayers.Geometry.LineString(d)},parseAttributes:function(a){var b={};a=a.firstChild;for(var c,d;a;)1==a.nodeType&&a.firstChild&&(c=a.firstChild,3==c.nodeType||4==c.nodeType)&&(d=a.prefix?a.nodeName.split(":")[1]:a.nodeName,"trkseg"!=d&&"rtept"!=d&& | |
2269 (b[d]=c.nodeValue)),a=a.nextSibling;return b},write:function(a,b){a=OpenLayers.Util.isArray(a)?a:[a];var c=this.createElementNS(this.namespaces.gpx,"gpx");c.setAttribute("version","1.1");c.setAttribute("creator",this.creator);this.setAttributes(c,{"xsi:schemaLocation":this.schemaLocation});b&&"object"==typeof b&&c.appendChild(this.buildMetadataNode(b));for(var d=0,e=a.length;d<e;d++)c.appendChild(this.buildFeatureNode(a[d]));return OpenLayers.Format.XML.prototype.write.apply(this,[c])},buildMetadataNode:function(a){for(var b= | |
2270 ["name","desc","author"],c=this.createElementNS(this.namespaces.gpx,"metadata"),d=0;d<b.length;d++){var e=b[d];if(a[e]){var f=this.createElementNS(this.namespaces.gpx,e);f.appendChild(this.createTextNode(a[e]));c.appendChild(f)}}return c},buildFeatureNode:function(a){var b=a.geometry,b=b.clone();this.internalProjection&&this.externalProjection&&b.transform(this.internalProjection,this.externalProjection);if("OpenLayers.Geometry.Point"==b.CLASS_NAME){var c=this.buildWptNode(b);this.appendAttributesNode(c, | |
2271 a);return c}c=this.createElementNS(this.namespaces.gpx,"trk");this.appendAttributesNode(c,a);a=this.buildTrkSegNode(b);a=OpenLayers.Util.isArray(a)?a:[a];for(var b=0,d=a.length;b<d;b++)c.appendChild(a[b]);return c},buildTrkSegNode:function(a){var b,c,d,e;if("OpenLayers.Geometry.LineString"==a.CLASS_NAME||"OpenLayers.Geometry.LinearRing"==a.CLASS_NAME){b=this.createElementNS(this.namespaces.gpx,"trkseg");c=0;for(d=a.components.length;c<d;c++)e=a.components[c],b.appendChild(this.buildTrkPtNode(e)); | |
2272 return b}b=[];c=0;for(d=a.components.length;c<d;c++)b.push(this.buildTrkSegNode(a.components[c]));return b},buildTrkPtNode:function(a){var b=this.createElementNS(this.namespaces.gpx,"trkpt");b.setAttribute("lon",a.x);b.setAttribute("lat",a.y);return b},buildWptNode:function(a){var b=this.createElementNS(this.namespaces.gpx,"wpt");b.setAttribute("lon",a.x);b.setAttribute("lat",a.y);return b},appendAttributesNode:function(a,b){var c=this.createElementNS(this.namespaces.gpx,"name");c.appendChild(this.createTextNode(b.attributes.name|| | |
2273 b.id));a.appendChild(c);c=this.createElementNS(this.namespaces.gpx,"desc");c.appendChild(this.createTextNode(b.attributes.description||this.defaultDesc));a.appendChild(c)},CLASS_NAME:"OpenLayers.Format.GPX"});OpenLayers.Format.WMSDescribeLayer=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.1.1",CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer"});OpenLayers.Format.WMSDescribeLayer.v1_1_1=OpenLayers.Class(OpenLayers.Format.WMSDescribeLayer,{initialize:function(a){OpenLayers.Format.WMSDescribeLayer.prototype.initialize.apply(this,[a])},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));for(var b=a.documentElement.childNodes,c={layerDescriptions:[]},d,e,f=0;f<b.length;++f)if(d=b[f],e=d.nodeName,"LayerDescription"==e){e=d.getAttribute("name");var g="",h="",k="";d.getAttribute("owsType")?(g=d.getAttribute("owsType"), | |
2274 h=d.getAttribute("owsURL")):""!=d.getAttribute("wfs")?(g="WFS",h=d.getAttribute("wfs")):""!=d.getAttribute("wcs")&&(g="WCS",h=d.getAttribute("wcs"));d=d.getElementsByTagName("Query");0<d.length&&((k=d[0].getAttribute("typeName"))||(k=d[0].getAttribute("typename")));d={layerName:e,owsType:g,owsURL:h,typeName:k};c.layerDescriptions.push(d);c.length=c.layerDescriptions.length;c[c.length-1]=d}else if("ServiceException"==e)return{error:(new OpenLayers.Format.OGCExceptionReport).read(a)};return c},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer.v1_1_1"}); | |
2275 OpenLayers.Format.WMSDescribeLayer.v1_1_0=OpenLayers.Format.WMSDescribeLayer.v1_1_1;OpenLayers.Layer.XYZ=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:!0,sphericalMercator:!1,zoomOffset:0,serverResolutions:null,initialize:function(a,b,c){if(c&&c.sphericalMercator||this.sphericalMercator)c=OpenLayers.Util.extend({projection:"EPSG:900913",numZoomLevels:19},c);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a||this.name,b||this.url,{},c])},clone:function(a){null==a&&(a=new OpenLayers.Layer.XYZ(this.name,this.url,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this, | |
2276 [a])},getURL:function(a){a=this.getXYZ(a);var b=this.url;OpenLayers.Util.isArray(b)&&(b=this.selectUrl(""+a.x+a.y+a.z,b));return OpenLayers.String.format(b,a)},getXYZ:function(a){var b=this.getServerResolution(),c=Math.round((a.left-this.maxExtent.left)/(b*this.tileSize.w));a=Math.round((this.maxExtent.top-a.top)/(b*this.tileSize.h));b=this.getServerZoom();if(this.wrapDateLine)var d=Math.pow(2,b),c=(c%d+d)%d;return{x:c,y:a,z:b}},setMap:function(a){OpenLayers.Layer.Grid.prototype.setMap.apply(this, | |
2277 arguments);this.tileOrigin||(this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.bottom))},CLASS_NAME:"OpenLayers.Layer.XYZ"});OpenLayers.Layer.OSM=OpenLayers.Class(OpenLayers.Layer.XYZ,{name:"OpenStreetMap",url:["http://a.tile.openstreetmap.org/${z}/${x}/${y}.png","http://b.tile.openstreetmap.org/${z}/${x}/${y}.png","http://c.tile.openstreetmap.org/${z}/${x}/${y}.png"],attribution:"© <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors",sphericalMercator:!0,wrapDateLine:!0,tileOptions:null,initialize:function(a,b,c){OpenLayers.Layer.XYZ.prototype.initialize.apply(this,arguments);this.tileOptions= | |
2278 OpenLayers.Util.extend({crossOriginKeyword:"anonymous"},this.options&&this.options.tileOptions)},clone:function(a){null==a&&(a=new OpenLayers.Layer.OSM(this.name,this.url,this.getOptions()));return a=OpenLayers.Layer.XYZ.prototype.clone.apply(this,[a])},CLASS_NAME:"OpenLayers.Layer.OSM"});OpenLayers.Renderer=OpenLayers.Class({container:null,root:null,extent:null,locked:!1,size:null,resolution:null,map:null,featureDx:0,initialize:function(a,b){this.container=OpenLayers.Util.getElement(a);OpenLayers.Util.extend(this,b)},destroy:function(){this.map=this.resolution=this.size=this.extent=this.container=null},supported:function(){return!1},setExtent:function(a,b){this.extent=a.clone();if(this.map.baseLayer&&this.map.baseLayer.wrapDateLine){var c=a.getWidth()/this.map.getExtent().getWidth(); | |
2279 a=a.scale(1/c);this.extent=a.wrapDateLine(this.map.getMaxExtent()).scale(c)}b&&(this.resolution=null);return!0},setSize:function(a){this.size=a.clone();this.resolution=null},getResolution:function(){return this.resolution=this.resolution||this.map.getResolution()},drawFeature:function(a,b){null==b&&(b=a.style);if(a.geometry){var c=a.geometry.getBounds();if(c){var d;this.map.baseLayer&&this.map.baseLayer.wrapDateLine&&(d=this.map.getMaxExtent());c.intersectsBounds(this.extent,{worldBounds:d})?this.calculateFeatureDx(c, | |
2280 d):b={display:"none"};c=this.drawGeometry(a.geometry,b,a.id);if("none"!=b.display&&b.label&&!1!==c){d=a.geometry.getCentroid();if(b.labelXOffset||b.labelYOffset){var e=isNaN(b.labelXOffset)?0:b.labelXOffset,f=isNaN(b.labelYOffset)?0:b.labelYOffset,g=this.getResolution();d.move(e*g,f*g)}this.drawText(a.id,b,d)}else this.removeText(a.id);return c}}},calculateFeatureDx:function(a,b){this.featureDx=0;if(b){var c=b.getWidth();this.featureDx=Math.round(((a.left+a.right)/2-(this.extent.left+this.extent.right)/ | |
2281 2)/c)*c}},drawGeometry:function(a,b,c){},drawText:function(a,b,c){},removeText:function(a){},clear:function(){},getFeatureIdFromEvent:function(a){},eraseFeatures:function(a){OpenLayers.Util.isArray(a)||(a=[a]);for(var b=0,c=a.length;b<c;++b){var d=a[b];this.eraseGeometry(d.geometry,d.id);this.removeText(d.id)}},eraseGeometry:function(a,b){},moveRoot:function(a){},getRenderLayerId:function(){return this.container.id},applyDefaultSymbolizer:function(a){var b=OpenLayers.Util.extend({},OpenLayers.Renderer.defaultSymbolizer); | |
2282 !1===a.stroke&&(delete b.strokeWidth,delete b.strokeColor);!1===a.fill&&delete b.fillColor;OpenLayers.Util.extend(b,a);return b},CLASS_NAME:"OpenLayers.Renderer"});OpenLayers.Renderer.defaultSymbolizer={fillColor:"#000000",strokeColor:"#000000",strokeWidth:2,fillOpacity:1,strokeOpacity:1,pointRadius:0,labelAlign:"cm"}; | |
2283 OpenLayers.Renderer.symbol={star:[350,75,379,161,469,161,397,215,423,301,350,250,277,301,303,215,231,161,321,161,350,75],cross:[4,0,6,0,6,4,10,4,10,6,6,6,6,10,4,10,4,6,0,6,0,4,4,4,4,0],x:[0,0,25,0,50,35,75,0,100,0,65,50,100,100,75,100,50,65,25,100,0,100,35,50,0,0],square:[0,0,0,1,1,1,1,0,0,0],triangle:[0,10,10,10,5,0,0,10]};OpenLayers.Renderer.Canvas=OpenLayers.Class(OpenLayers.Renderer,{hitDetection:!0,hitOverflow:0,canvas:null,features:null,pendingRedraw:!1,cachedSymbolBounds:{},initialize:function(a,b){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.root=document.createElement("canvas");this.container.appendChild(this.root);this.canvas=this.root.getContext("2d");this.features={};this.hitDetection&&(this.hitCanvas=document.createElement("canvas"),this.hitContext=this.hitCanvas.getContext("2d"))}, | |
2284 setExtent:function(){OpenLayers.Renderer.prototype.setExtent.apply(this,arguments);return!1},eraseGeometry:function(a,b){this.eraseFeatures(this.features[b][0])},supported:function(){return OpenLayers.CANVAS_SUPPORTED},setSize:function(a){this.size=a.clone();var b=this.root;b.style.width=a.w+"px";b.style.height=a.h+"px";b.width=a.w;b.height=a.h;this.resolution=null;this.hitDetection&&(b=this.hitCanvas,b.style.width=a.w+"px",b.style.height=a.h+"px",b.width=a.w,b.height=a.h)},drawFeature:function(a, | |
2285 b){var c;if(a.geometry){b=this.applyDefaultSymbolizer(b||a.style);c=a.geometry.getBounds();var d;this.map.baseLayer&&this.map.baseLayer.wrapDateLine&&(d=this.map.getMaxExtent());d=c&&c.intersectsBounds(this.extent,{worldBounds:d});(c="none"!==b.display&&!!c&&d)?this.features[a.id]=[a,b]:delete this.features[a.id];this.pendingRedraw=!0}this.pendingRedraw&&!this.locked&&(this.redraw(),this.pendingRedraw=!1);return c},drawGeometry:function(a,b,c){var d=a.CLASS_NAME;if("OpenLayers.Geometry.Collection"== | |
2286 d||"OpenLayers.Geometry.MultiPoint"==d||"OpenLayers.Geometry.MultiLineString"==d||"OpenLayers.Geometry.MultiPolygon"==d)for(d=0;d<a.components.length;d++)this.drawGeometry(a.components[d],b,c);else switch(a.CLASS_NAME){case "OpenLayers.Geometry.Point":this.drawPoint(a,b,c);break;case "OpenLayers.Geometry.LineString":this.drawLineString(a,b,c);break;case "OpenLayers.Geometry.LinearRing":this.drawLinearRing(a,b,c);break;case "OpenLayers.Geometry.Polygon":this.drawPolygon(a,b,c)}},drawExternalGraphic:function(a, | |
2287 b,c){var d=new Image,e=b.title||b.graphicTitle;e&&(d.title=e);var f=b.graphicWidth||b.graphicHeight,g=b.graphicHeight||b.graphicWidth,f=f?f:2*b.pointRadius,g=g?g:2*b.pointRadius,h=void 0!=b.graphicXOffset?b.graphicXOffset:-(0.5*f),k=void 0!=b.graphicYOffset?b.graphicYOffset:-(0.5*g),l=b.graphicOpacity||b.fillOpacity;d.onload=OpenLayers.Function.bind(function(){if(this.features[c]){var b=this.getLocalXY(a),e=b[0],b=b[1];if(!isNaN(e)&&!isNaN(b)){var e=e+h|0,b=b+k|0,p=this.canvas;p.globalAlpha=l;var q= | |
2288 OpenLayers.Renderer.Canvas.drawImageScaleFactor||(OpenLayers.Renderer.Canvas.drawImageScaleFactor=/android 2.1/.test(navigator.userAgent.toLowerCase())?320/window.screen.width:1);p.drawImage(d,e*q,b*q,f*q,g*q);this.hitDetection&&(this.setHitContextStyle("fill",c),this.hitContext.fillRect(e,b,f,g))}}},this);d.src=b.externalGraphic},drawNamedSymbol:function(a,b,c){var d,e,f,g;f=Math.PI/180;var h=OpenLayers.Renderer.symbol[b.graphicName];if(!h)throw Error(b.graphicName+" is not a valid symbol name"); | |
2289 if(!(!h.length||2>h.length||(a=this.getLocalXY(a),e=a[0],g=a[1],isNaN(e)||isNaN(g)))){this.canvas.lineCap="round";this.canvas.lineJoin="round";this.hitDetection&&(this.hitContext.lineCap="round",this.hitContext.lineJoin="round");if(b.graphicName in this.cachedSymbolBounds)d=this.cachedSymbolBounds[b.graphicName];else{d=new OpenLayers.Bounds;for(a=0;a<h.length;a+=2)d.extend(new OpenLayers.LonLat(h[a],h[a+1]));this.cachedSymbolBounds[b.graphicName]=d}this.canvas.save();this.hitDetection&&this.hitContext.save(); | |
2290 this.canvas.translate(e,g);this.hitDetection&&this.hitContext.translate(e,g);a=f*b.rotation;isNaN(a)||(this.canvas.rotate(a),this.hitDetection&&this.hitContext.rotate(a));f=2*b.pointRadius/Math.max(d.getWidth(),d.getHeight());this.canvas.scale(f,f);this.hitDetection&&this.hitContext.scale(f,f);a=d.getCenterLonLat().lon;d=d.getCenterLonLat().lat;this.canvas.translate(-a,-d);this.hitDetection&&this.hitContext.translate(-a,-d);g=b.strokeWidth;b.strokeWidth=g/f;if(!1!==b.fill){this.setCanvasStyle("fill", | |
2291 b);this.canvas.beginPath();for(a=0;a<h.length;a+=2)d=h[a],e=h[a+1],0==a&&this.canvas.moveTo(d,e),this.canvas.lineTo(d,e);this.canvas.closePath();this.canvas.fill();if(this.hitDetection){this.setHitContextStyle("fill",c,b);this.hitContext.beginPath();for(a=0;a<h.length;a+=2)d=h[a],e=h[a+1],0==a&&this.canvas.moveTo(d,e),this.hitContext.lineTo(d,e);this.hitContext.closePath();this.hitContext.fill()}}if(!1!==b.stroke){this.setCanvasStyle("stroke",b);this.canvas.beginPath();for(a=0;a<h.length;a+=2)d=h[a], | |
2292 e=h[a+1],0==a&&this.canvas.moveTo(d,e),this.canvas.lineTo(d,e);this.canvas.closePath();this.canvas.stroke();if(this.hitDetection){this.setHitContextStyle("stroke",c,b,f);this.hitContext.beginPath();for(a=0;a<h.length;a+=2)d=h[a],e=h[a+1],0==a&&this.hitContext.moveTo(d,e),this.hitContext.lineTo(d,e);this.hitContext.closePath();this.hitContext.stroke()}}b.strokeWidth=g;this.canvas.restore();this.hitDetection&&this.hitContext.restore();this.setCanvasStyle("reset")}},setCanvasStyle:function(a,b){"fill"=== | |
2293 a?(this.canvas.globalAlpha=b.fillOpacity,this.canvas.fillStyle=b.fillColor):"stroke"===a?(this.canvas.globalAlpha=b.strokeOpacity,this.canvas.strokeStyle=b.strokeColor,this.canvas.lineWidth=b.strokeWidth):(this.canvas.globalAlpha=0,this.canvas.lineWidth=1)},featureIdToHex:function(a){a=Number(a.split("_").pop())+1;16777216<=a&&(this.hitOverflow=a-16777215,a=a%16777216+1);a="000000"+a.toString(16);var b=a.length;return a="#"+a.substring(b-6,b)},setHitContextStyle:function(a,b,c,d){b=this.featureIdToHex(b); | |
2294 "fill"==a?(this.hitContext.globalAlpha=1,this.hitContext.fillStyle=b):"stroke"==a?(this.hitContext.globalAlpha=1,this.hitContext.strokeStyle=b,"undefined"===typeof d?this.hitContext.lineWidth=c.strokeWidth+2:isNaN(d)||(this.hitContext.lineWidth=c.strokeWidth+2/d)):(this.hitContext.globalAlpha=0,this.hitContext.lineWidth=1)},drawPoint:function(a,b,c){if(!1!==b.graphic)if(b.externalGraphic)this.drawExternalGraphic(a,b,c);else if(b.graphicName&&"circle"!=b.graphicName)this.drawNamedSymbol(a,b,c);else{var d= | |
2295 this.getLocalXY(a);a=d[0];d=d[1];if(!isNaN(a)&&!isNaN(d)){var e=2*Math.PI,f=b.pointRadius;!1!==b.fill&&(this.setCanvasStyle("fill",b),this.canvas.beginPath(),this.canvas.arc(a,d,f,0,e,!0),this.canvas.fill(),this.hitDetection&&(this.setHitContextStyle("fill",c,b),this.hitContext.beginPath(),this.hitContext.arc(a,d,f,0,e,!0),this.hitContext.fill()));!1!==b.stroke&&(this.setCanvasStyle("stroke",b),this.canvas.beginPath(),this.canvas.arc(a,d,f,0,e,!0),this.canvas.stroke(),this.hitDetection&&(this.setHitContextStyle("stroke", | |
2296 c,b),this.hitContext.beginPath(),this.hitContext.arc(a,d,f,0,e,!0),this.hitContext.stroke()),this.setCanvasStyle("reset"))}}},drawLineString:function(a,b,c){b=OpenLayers.Util.applyDefaults({fill:!1},b);this.drawLinearRing(a,b,c)},drawLinearRing:function(a,b,c){!1!==b.fill&&(this.setCanvasStyle("fill",b),this.renderPath(this.canvas,a,b,c,"fill"),this.hitDetection&&(this.setHitContextStyle("fill",c,b),this.renderPath(this.hitContext,a,b,c,"fill")));!1!==b.stroke&&(this.setCanvasStyle("stroke",b),this.renderPath(this.canvas, | |
2297 a,b,c,"stroke"),this.hitDetection&&(this.setHitContextStyle("stroke",c,b),this.renderPath(this.hitContext,a,b,c,"stroke")));this.setCanvasStyle("reset")},renderPath:function(a,b,c,d,e){b=b.components;c=b.length;a.beginPath();d=this.getLocalXY(b[0]);var f=d[1];if(!isNaN(d[0])&&!isNaN(f)){a.moveTo(d[0],d[1]);for(d=1;d<c;++d)f=this.getLocalXY(b[d]),a.lineTo(f[0],f[1]);"fill"===e?a.fill():a.stroke()}},drawPolygon:function(a,b,c){a=a.components;var d=a.length;this.drawLinearRing(a[0],b,c);for(var e=1;e< | |
2298 d;++e)this.canvas.globalCompositeOperation="destination-out",this.hitDetection&&(this.hitContext.globalCompositeOperation="destination-out"),this.drawLinearRing(a[e],OpenLayers.Util.applyDefaults({stroke:!1,fillOpacity:1},b),c),this.canvas.globalCompositeOperation="source-over",this.hitDetection&&(this.hitContext.globalCompositeOperation="source-over"),this.drawLinearRing(a[e],OpenLayers.Util.applyDefaults({fill:!1},b),c)},drawText:function(a,b){var c=this.getLocalXY(a);this.setCanvasStyle("reset"); | |
2299 this.canvas.fillStyle=b.fontColor;this.canvas.globalAlpha=b.fontOpacity||1;var d=[b.fontStyle?b.fontStyle:"normal","normal",b.fontWeight?b.fontWeight:"normal",b.fontSize?b.fontSize:"1em",b.fontFamily?b.fontFamily:"sans-serif"].join(" "),e=b.label.split("\n"),f=e.length;if(this.canvas.fillText){this.canvas.font=d;this.canvas.textAlign=OpenLayers.Renderer.Canvas.LABEL_ALIGN[b.labelAlign[0]]||"center";this.canvas.textBaseline=OpenLayers.Renderer.Canvas.LABEL_ALIGN[b.labelAlign[1]]||"middle";var g=OpenLayers.Renderer.Canvas.LABEL_FACTOR[b.labelAlign[1]]; | |
2300 null==g&&(g=-0.5);d=this.canvas.measureText("Mg").height||this.canvas.measureText("xx").width;c[1]+=d*g*(f-1);for(g=0;g<f;g++)b.labelOutlineWidth&&(this.canvas.save(),this.canvas.globalAlpha=b.labelOutlineOpacity||b.fontOpacity||1,this.canvas.strokeStyle=b.labelOutlineColor,this.canvas.lineWidth=b.labelOutlineWidth,this.canvas.strokeText(e[g],c[0],c[1]+d*g+1),this.canvas.restore()),this.canvas.fillText(e[g],c[0],c[1]+d*g)}else if(this.canvas.mozDrawText){this.canvas.mozTextStyle=d;var h=OpenLayers.Renderer.Canvas.LABEL_FACTOR[b.labelAlign[0]]; | |
2301 null==h&&(h=-0.5);g=OpenLayers.Renderer.Canvas.LABEL_FACTOR[b.labelAlign[1]];null==g&&(g=-0.5);d=this.canvas.mozMeasureText("xx");c[1]+=d*(1+g*f);for(g=0;g<f;g++){var k=c[0]+h*this.canvas.mozMeasureText(e[g]),l=c[1]+g*d;this.canvas.translate(k,l);this.canvas.mozDrawText(e[g]);this.canvas.translate(-k,-l)}}this.setCanvasStyle("reset")},getLocalXY:function(a){var b=this.getResolution(),c=this.extent;return[(a.x-this.featureDx)/b+-c.left/b,c.top/b-a.y/b]},clear:function(){var a=this.root.height,b=this.root.width; | |
2302 this.canvas.clearRect(0,0,b,a);this.features={};this.hitDetection&&this.hitContext.clearRect(0,0,b,a)},getFeatureIdFromEvent:function(a){var b;if(this.hitDetection&&"none"!==this.root.style.display&&!this.map.dragging&&(a=a.xy,a=this.hitContext.getImageData(a.x|0,a.y|0,1,1).data,255===a[3]&&(a=a[2]+256*(a[1]+256*a[0])))){a="OpenLayers_Feature_Vector_"+(a-1+this.hitOverflow);try{b=this.features[a][0]}catch(c){}}return b},eraseFeatures:function(a){OpenLayers.Util.isArray(a)||(a=[a]);for(var b=0;b<a.length;++b)delete this.features[a[b].id]; | |
2303 this.redraw()},redraw:function(){if(!this.locked){var a=this.root.height,b=this.root.width;this.canvas.clearRect(0,0,b,a);this.hitDetection&&this.hitContext.clearRect(0,0,b,a);var a=[],c,d,e=this.map.baseLayer&&this.map.baseLayer.wrapDateLine&&this.map.getMaxExtent(),f;for(f in this.features)this.features.hasOwnProperty(f)&&(b=this.features[f][0],c=b.geometry,this.calculateFeatureDx(c.getBounds(),e),d=this.features[f][1],this.drawGeometry(c,d,b.id),d.label&&a.push([b,d]));b=0;for(c=a.length;b<c;++b)f= | |
2304 a[b],this.drawText(f[0].geometry.getCentroid(),f[1])}},CLASS_NAME:"OpenLayers.Renderer.Canvas"});OpenLayers.Renderer.Canvas.LABEL_ALIGN={l:"left",r:"right",t:"top",b:"bottom"};OpenLayers.Renderer.Canvas.LABEL_FACTOR={l:0,r:-1,t:0,b:-1};OpenLayers.Renderer.Canvas.drawImageScaleFactor=null;OpenLayers.Format.OSM=OpenLayers.Class(OpenLayers.Format.XML,{checkTags:!1,interestingTagsExclude:null,areaTags:null,initialize:function(a){var b={interestingTagsExclude:"source source_ref source:ref history attribution created_by".split(" "),areaTags:"area building leisure tourism ruins historic landuse military natural sport".split(" ")},b=OpenLayers.Util.extend(b,a),c={};for(a=0;a<b.interestingTagsExclude.length;a++)c[b.interestingTagsExclude[a]]=!0;b.interestingTagsExclude=c;c={};for(a=0;a<b.areaTags.length;a++)c[b.areaTags[a]]= | |
2305 !0;b.areaTags=c;this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[b])},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b=this.getNodes(a),c=this.getWays(a);a=Array(c.length);for(var d=0;d<c.length;d++){for(var e=Array(c[d].nodes.length),f=this.isWayArea(c[d])?1:0,g=0;g<c[d].nodes.length;g++){var h=b[c[d].nodes[g]],k=new OpenLayers.Geometry.Point(h.lon,h.lat);k.osm_id=parseInt(c[d].nodes[g]); | |
2306 e[g]=k;h.used=!0}h=null;h=f?new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(e)):new OpenLayers.Geometry.LineString(e);this.internalProjection&&this.externalProjection&&h.transform(this.externalProjection,this.internalProjection);e=new OpenLayers.Feature.Vector(h,c[d].tags);e.osm_id=parseInt(c[d].id);e.fid="way."+e.osm_id;a[d]=e}for(var l in b){h=b[l];if(!h.used||this.checkTags){c=null;if(this.checkTags){c=this.getTags(h.node,!0);if(h.used&&!c[1])continue;c=c[0]}else c=this.getTags(h.node); | |
2307 e=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(h.lon,h.lat),c);this.internalProjection&&this.externalProjection&&e.geometry.transform(this.externalProjection,this.internalProjection);e.osm_id=parseInt(l);e.fid="node."+e.osm_id;a.push(e)}h.node=null}return a},getNodes:function(a){a=a.getElementsByTagName("node");for(var b={},c=0;c<a.length;c++){var d=a[c],e=d.getAttribute("id");b[e]={lat:d.getAttribute("lat"),lon:d.getAttribute("lon"),node:d}}return b},getWays:function(a){a=a.getElementsByTagName("way"); | |
2308 for(var b=[],c=0;c<a.length;c++){var d=a[c],e={id:d.getAttribute("id")};e.tags=this.getTags(d);d=d.getElementsByTagName("nd");e.nodes=Array(d.length);for(var f=0;f<d.length;f++)e.nodes[f]=d[f].getAttribute("ref");b.push(e)}return b},getTags:function(a,b){for(var c=a.getElementsByTagName("tag"),d={},e=!1,f=0;f<c.length;f++){var g=c[f].getAttribute("k");d[g]=c[f].getAttribute("v");b&&(this.interestingTagsExclude[g]||(e=!0))}return b?[d,e]:d},isWayArea:function(a){var b=!1,c=!1;a.nodes[0]==a.nodes[a.nodes.length- | |
2309 1]&&(b=!0);if(this.checkTags)for(var d in a.tags)if(this.areaTags[d]){c=!0;break}return b&&(this.checkTags?c:!0)},write:function(a){OpenLayers.Util.isArray(a)||(a=[a]);this.osm_id=1;this.created_nodes={};var b=this.createElementNS(null,"osm");b.setAttribute("version","0.5");b.setAttribute("generator","OpenLayers "+OpenLayers.VERSION_NUMBER);for(var c=a.length-1;0<=c;c--)for(var d=this.createFeatureNodes(a[c]),e=0;e<d.length;e++)b.appendChild(d[e]);return OpenLayers.Format.XML.prototype.write.apply(this, | |
2310 [b])},createFeatureNodes:function(a){var b=[],c=a.geometry.CLASS_NAME,c=c.substring(c.lastIndexOf(".")+1),c=c.toLowerCase();(c=this.createXML[c])&&(b=c.apply(this,[a]));return b},createXML:{point:function(a){var b=null,c=a.geometry?a.geometry:a;this.internalProjection&&this.externalProjection&&(c=c.clone(),c.transform(this.internalProjection,this.externalProjection));var d=!1;a.osm_id?(b=a.osm_id,this.created_nodes[b]&&(d=!0)):(b=-this.osm_id,this.osm_id++);var e=d?this.created_nodes[b]:this.createElementNS(null, | |
2311 "node");this.created_nodes[b]=e;e.setAttribute("id",b);e.setAttribute("lon",c.x);e.setAttribute("lat",c.y);a.attributes&&this.serializeTags(a,e);this.setState(a,e);return d?[]:[e]},linestring:function(a){var b,c=[],d=a.geometry;a.osm_id?b=a.osm_id:(b=-this.osm_id,this.osm_id++);var e=this.createElementNS(null,"way");e.setAttribute("id",b);for(b=0;b<d.components.length;b++){var f=this.createXML.point.apply(this,[d.components[b]]);if(f.length){var f=f[0],g=f.getAttribute("id");c.push(f)}else g=d.components[b].osm_id, | |
2312 f=this.created_nodes[g];this.setState(a,f);f=this.createElementNS(null,"nd");f.setAttribute("ref",g);e.appendChild(f)}this.serializeTags(a,e);c.push(e);return c},polygon:function(a){var b=OpenLayers.Util.extend({area:"yes"},a.attributes),b=new OpenLayers.Feature.Vector(a.geometry.components[0],b);b.osm_id=a.osm_id;return this.createXML.linestring.apply(this,[b])}},serializeTags:function(a,b){for(var c in a.attributes){var d=this.createElementNS(null,"tag");d.setAttribute("k",c);d.setAttribute("v", | |
2313 a.attributes[c]);b.appendChild(d)}},setState:function(a,b){if(a.state){var c=null;switch(a.state){case OpenLayers.State.UPDATE:case OpenLayers.State.DELETE:c="delete"}c&&b.setAttribute("action",c)}},CLASS_NAME:"OpenLayers.Format.OSM"});OpenLayers.Handler.Keyboard=OpenLayers.Class(OpenLayers.Handler,{KEY_EVENTS:["keydown","keyup"],eventListener:null,observeElement:null,initialize:function(a,b,c){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.eventListener=OpenLayers.Function.bindAsEventListener(this.handleKeyEvent,this)},destroy:function(){this.deactivate();this.eventListener=null;OpenLayers.Handler.prototype.destroy.apply(this,arguments)},activate:function(){if(OpenLayers.Handler.prototype.activate.apply(this, | |
2314 arguments)){this.observeElement=this.observeElement||document;for(var a=0,b=this.KEY_EVENTS.length;a<b;a++)OpenLayers.Event.observe(this.observeElement,this.KEY_EVENTS[a],this.eventListener);return!0}return!1},deactivate:function(){var a=!1;if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){for(var a=0,b=this.KEY_EVENTS.length;a<b;a++)OpenLayers.Event.stopObserving(this.observeElement,this.KEY_EVENTS[a],this.eventListener);a=!0}return a},handleKeyEvent:function(a){this.checkModifiers(a)&& | |
2315 this.callback(a.type,[a])},CLASS_NAME:"OpenLayers.Handler.Keyboard"});OpenLayers.Control.ModifyFeature=OpenLayers.Class(OpenLayers.Control,{documentDrag:!1,geometryTypes:null,clickout:!0,toggle:!0,standalone:!1,layer:null,feature:null,vertex:null,vertices:null,virtualVertices:null,handlers:null,deleteCodes:null,virtualStyle:null,vertexRenderIntent:null,mode:null,createVertices:!0,modified:!1,radiusHandle:null,dragHandle:null,onModificationStart:function(){},onModification:function(){},onModificationEnd:function(){},initialize:function(a,b){b=b||{};this.layer=a;this.vertices= | |
2316 [];this.virtualVertices=[];this.virtualStyle=OpenLayers.Util.extend({},this.layer.style||this.layer.styleMap.createSymbolizer(null,b.vertexRenderIntent));this.virtualStyle.fillOpacity=0.3;this.virtualStyle.strokeOpacity=0.3;this.deleteCodes=[46,68];this.mode=OpenLayers.Control.ModifyFeature.RESHAPE;OpenLayers.Control.prototype.initialize.apply(this,[b]);OpenLayers.Util.isArray(this.deleteCodes)||(this.deleteCodes=[this.deleteCodes]);var c={documentDrag:this.documentDrag,stopDown:!1};this.handlers= | |
2317 {keyboard:new OpenLayers.Handler.Keyboard(this,{keydown:this.handleKeypress}),drag:new OpenLayers.Handler.Drag(this,{down:function(a){this.vertex=null;(a=this.layer.getFeatureFromEvent(this.handlers.drag.evt))?this.dragStart(a):this.clickout&&(this._unselect=this.feature)},move:function(a){delete this._unselect;this.vertex&&this.dragVertex(this.vertex,a)},up:function(){this.handlers.drag.stopDown=!1;this._unselect&&(this.unselectFeature(this._unselect),delete this._unselect)},done:function(a){this.vertex&& | |
2318 this.dragComplete(this.vertex)}},c)}},destroy:function(){this.map&&this.map.events.un({removelayer:this.handleMapEvents,changelayer:this.handleMapEvents,scope:this});this.layer=null;OpenLayers.Control.prototype.destroy.apply(this,[])},activate:function(){this.moveLayerToTop();this.map.events.on({removelayer:this.handleMapEvents,changelayer:this.handleMapEvents,scope:this});return this.handlers.keyboard.activate()&&this.handlers.drag.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments)}, | |
2319 deactivate:function(){var a=!1;OpenLayers.Control.prototype.deactivate.apply(this,arguments)&&(this.moveLayerBack(),this.map.events.un({removelayer:this.handleMapEvents,changelayer:this.handleMapEvents,scope:this}),this.layer.removeFeatures(this.vertices,{silent:!0}),this.layer.removeFeatures(this.virtualVertices,{silent:!0}),this.vertices=[],this.handlers.drag.deactivate(),this.handlers.keyboard.deactivate(),(a=this.feature)&&(a.geometry&&a.layer)&&this.unselectFeature(a),a=!0);return a},beforeSelectFeature:function(a){return this.layer.events.triggerEvent("beforefeaturemodified", | |
2320 {feature:a})},selectFeature:function(a){if(!(this.feature===a||this.geometryTypes&&-1==OpenLayers.Util.indexOf(this.geometryTypes,a.geometry.CLASS_NAME))){!1!==this.beforeSelectFeature(a)&&(this.feature&&this.unselectFeature(this.feature),this.feature=a,this.layer.selectedFeatures.push(a),this.layer.drawFeature(a,"select"),this.modified=!1,this.resetVertices(),this.onModificationStart(this.feature));var b=a.modified;!a.geometry||b&&b.geometry||(this._originalGeometry=a.geometry.clone())}},unselectFeature:function(a){this.layer.removeFeatures(this.vertices, | |
2321 {silent:!0});this.vertices=[];this.layer.destroyFeatures(this.virtualVertices,{silent:!0});this.virtualVertices=[];this.dragHandle&&(this.layer.destroyFeatures([this.dragHandle],{silent:!0}),delete this.dragHandle);this.radiusHandle&&(this.layer.destroyFeatures([this.radiusHandle],{silent:!0}),delete this.radiusHandle);this.layer.drawFeature(this.feature,"default");this.feature=null;OpenLayers.Util.removeItem(this.layer.selectedFeatures,a);this.onModificationEnd(a);this.layer.events.triggerEvent("afterfeaturemodified", | |
2322 {feature:a,modified:this.modified});this.modified=!1},dragStart:function(a){var b="OpenLayers.Geometry.Point"==a.geometry.CLASS_NAME;this.standalone||(a._sketch||!b)&&a._sketch||(this.toggle&&this.feature===a&&(this._unselect=a),this.selectFeature(a));if(a._sketch||b)this.vertex=a,this.handlers.drag.stopDown=!0},dragVertex:function(a,b){var c=this.map.getLonLatFromViewPortPx(b),d=a.geometry;d.move(c.lon-d.x,c.lat-d.y);this.modified=!0;"OpenLayers.Geometry.Point"==this.feature.geometry.CLASS_NAME? | |
2323 this.layer.events.triggerEvent("vertexmodified",{vertex:a.geometry,feature:this.feature,pixel:b}):(a._index?(a.geometry.parent.addComponent(a.geometry,a._index),delete a._index,OpenLayers.Util.removeItem(this.virtualVertices,a),this.vertices.push(a)):a==this.dragHandle?(this.layer.removeFeatures(this.vertices,{silent:!0}),this.vertices=[],this.radiusHandle&&(this.layer.destroyFeatures([this.radiusHandle],{silent:!0}),this.radiusHandle=null)):a!==this.radiusHandle&&this.layer.events.triggerEvent("vertexmodified", | |
2324 {vertex:a.geometry,feature:this.feature,pixel:b}),0<this.virtualVertices.length&&(this.layer.destroyFeatures(this.virtualVertices,{silent:!0}),this.virtualVertices=[]),this.layer.drawFeature(this.feature,this.standalone?void 0:"select"));this.layer.drawFeature(a)},dragComplete:function(a){this.resetVertices();this.setFeatureState();this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature})},setFeatureState:function(){if(this.feature.state!=OpenLayers.State.INSERT&& | |
2325 this.feature.state!=OpenLayers.State.DELETE&&(this.feature.state=OpenLayers.State.UPDATE,this.modified&&this._originalGeometry)){var a=this.feature;a.modified=OpenLayers.Util.extend(a.modified,{geometry:this._originalGeometry});delete this._originalGeometry}},resetVertices:function(){0<this.vertices.length&&(this.layer.removeFeatures(this.vertices,{silent:!0}),this.vertices=[]);0<this.virtualVertices.length&&(this.layer.removeFeatures(this.virtualVertices,{silent:!0}),this.virtualVertices=[]);this.dragHandle&& | |
2326 (this.layer.destroyFeatures([this.dragHandle],{silent:!0}),this.dragHandle=null);this.radiusHandle&&(this.layer.destroyFeatures([this.radiusHandle],{silent:!0}),this.radiusHandle=null);this.feature&&"OpenLayers.Geometry.Point"!=this.feature.geometry.CLASS_NAME&&(this.mode&OpenLayers.Control.ModifyFeature.DRAG&&this.collectDragHandle(),this.mode&(OpenLayers.Control.ModifyFeature.ROTATE|OpenLayers.Control.ModifyFeature.RESIZE)&&this.collectRadiusHandle(),this.mode&OpenLayers.Control.ModifyFeature.RESHAPE&& | |
2327 (this.mode&OpenLayers.Control.ModifyFeature.RESIZE||this.collectVertices()))},handleKeypress:function(a){var b=a.keyCode;this.feature&&-1!=OpenLayers.Util.indexOf(this.deleteCodes,b)&&(b=this.layer.getFeatureFromEvent(this.handlers.drag.evt))&&(-1!=OpenLayers.Util.indexOf(this.vertices,b)&&!this.handlers.drag.dragging&&b.geometry.parent)&&(b.geometry.parent.removeComponent(b.geometry),this.layer.events.triggerEvent("vertexremoved",{vertex:b.geometry,feature:this.feature,pixel:a.xy}),this.layer.drawFeature(this.feature, | |
2328 this.standalone?void 0:"select"),this.modified=!0,this.resetVertices(),this.setFeatureState(),this.onModification(this.feature),this.layer.events.triggerEvent("featuremodified",{feature:this.feature}))},collectVertices:function(){function a(c){var d,e,f;if("OpenLayers.Geometry.Point"==c.CLASS_NAME)e=new OpenLayers.Feature.Vector(c),e._sketch=!0,e.renderIntent=b.vertexRenderIntent,b.vertices.push(e);else{f=c.components.length;"OpenLayers.Geometry.LinearRing"==c.CLASS_NAME&&(f-=1);for(d=0;d<f;++d)e= | |
2329 c.components[d],"OpenLayers.Geometry.Point"==e.CLASS_NAME?(e=new OpenLayers.Feature.Vector(e),e._sketch=!0,e.renderIntent=b.vertexRenderIntent,b.vertices.push(e)):a(e);if(b.createVertices&&"OpenLayers.Geometry.MultiPoint"!=c.CLASS_NAME)for(d=0,f=c.components.length;d<f-1;++d){e=c.components[d];var g=c.components[d+1];"OpenLayers.Geometry.Point"==e.CLASS_NAME&&"OpenLayers.Geometry.Point"==g.CLASS_NAME&&(e=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point((e.x+g.x)/2,(e.y+g.y)/2),null,b.virtualStyle), | |
2330 e.geometry.parent=c,e._index=d+1,e._sketch=!0,b.virtualVertices.push(e))}}}this.vertices=[];this.virtualVertices=[];var b=this;a.call(this,this.feature.geometry);this.layer.addFeatures(this.virtualVertices,{silent:!0});this.layer.addFeatures(this.vertices,{silent:!0})},collectDragHandle:function(){var a=this.feature.geometry,b=a.getBounds().getCenterLonLat(),b=new OpenLayers.Geometry.Point(b.lon,b.lat),c=new OpenLayers.Feature.Vector(b);b.move=function(b,c){OpenLayers.Geometry.Point.prototype.move.call(this, | |
2331 b,c);a.move(b,c)};c._sketch=!0;this.dragHandle=c;this.dragHandle.renderIntent=this.vertexRenderIntent;this.layer.addFeatures([this.dragHandle],{silent:!0})},collectRadiusHandle:function(){var a=this.feature.geometry,b=a.getBounds(),c=b.getCenterLonLat(),d=new OpenLayers.Geometry.Point(c.lon,c.lat),b=new OpenLayers.Geometry.Point(b.right,b.bottom),c=new OpenLayers.Feature.Vector(b),e=this.mode&OpenLayers.Control.ModifyFeature.RESIZE,f=this.mode&OpenLayers.Control.ModifyFeature.RESHAPE,g=this.mode& | |
2332 OpenLayers.Control.ModifyFeature.ROTATE;b.move=function(b,c){OpenLayers.Geometry.Point.prototype.move.call(this,b,c);var l=this.x-d.x,m=this.y-d.y,n=l-b,p=m-c;if(g){var q=Math.atan2(p,n),q=Math.atan2(m,l)-q,q=q*(180/Math.PI);a.rotate(q,d)}if(e){var r;f?(m/=p,r=l/n/m):(n=Math.sqrt(n*n+p*p),m=Math.sqrt(l*l+m*m)/n);a.resize(m,d,r)}};c._sketch=!0;this.radiusHandle=c;this.radiusHandle.renderIntent=this.vertexRenderIntent;this.layer.addFeatures([this.radiusHandle],{silent:!0})},setMap:function(a){this.handlers.drag.setMap(a); | |
2333 OpenLayers.Control.prototype.setMap.apply(this,arguments)},handleMapEvents:function(a){"removelayer"!=a.type&&"order"!=a.property||this.moveLayerToTop()},moveLayerToTop:function(){var a=Math.max(this.map.Z_INDEX_BASE.Feature-1,this.layer.getZIndex())+1;this.layer.setZIndex(a)},moveLayerBack:function(){var a=this.layer.getZIndex()-1;a>=this.map.Z_INDEX_BASE.Feature?this.layer.setZIndex(a):this.map.setLayerZIndex(this.layer,this.map.getLayerIndex(this.layer))},CLASS_NAME:"OpenLayers.Control.ModifyFeature"}); | |
2334 OpenLayers.Control.ModifyFeature.RESHAPE=1;OpenLayers.Control.ModifyFeature.RESIZE=2;OpenLayers.Control.ModifyFeature.ROTATE=4;OpenLayers.Control.ModifyFeature.DRAG=8;OpenLayers.Layer.Bing=OpenLayers.Class(OpenLayers.Layer.XYZ,{key:null,serverResolutions:[156543.03390625,78271.516953125,39135.7584765625,19567.87923828125,9783.939619140625,4891.9698095703125,2445.9849047851562,1222.9924523925781,611.4962261962891,305.74811309814453,152.87405654907226,76.43702827453613,38.218514137268066,19.109257068634033,9.554628534317017,4.777314267158508,2.388657133579254,1.194328566789627,0.5971642833948135,0.29858214169740677,0.14929107084870338,0.07464553542435169],attributionTemplate:'<span class="olBingAttribution ${type}"><div><a target="_blank" href="http://www.bing.com/maps/"><img src="${logo}" /></a></div>${copyrights}<a style="white-space: nowrap" target="_blank" href="http://www.microsoft.com/maps/product/terms.html">Terms of Use</a></span>', | |
2335 metadata:null,protocolRegex:/^http:/i,type:"Road",culture:"en-US",metadataParams:null,tileOptions:null,protocol:~window.location.href.indexOf("http")?"":"http:",initialize:function(a){a=OpenLayers.Util.applyDefaults({sphericalMercator:!0},a);OpenLayers.Layer.XYZ.prototype.initialize.apply(this,[a.name||"Bing "+(a.type||this.type),null,a]);this.tileOptions=OpenLayers.Util.extend({crossOriginKeyword:"anonymous"},this.options.tileOptions);this.loadMetadata()},loadMetadata:function(){this._callbackId= | |
2336 "_callback_"+this.id.replace(/\./g,"_");window[this._callbackId]=OpenLayers.Function.bind(OpenLayers.Layer.Bing.processMetadata,this);var a=OpenLayers.Util.applyDefaults({key:this.key,jsonp:this._callbackId,include:"ImageryProviders"},this.metadataParams),a=this.protocol+"//dev.virtualearth.net/REST/v1/Imagery/Metadata/"+this.type+"?"+OpenLayers.Util.getParameterString(a),b=document.createElement("script");b.type="text/javascript";b.src=a;b.id=this._callbackId;document.getElementsByTagName("head")[0].appendChild(b)}, | |
2337 initLayer:function(){var a=this.metadata.resourceSets[0].resources[0],b=a.imageUrl.replace("{quadkey}","${quadkey}"),b=b.replace("{culture}",this.culture),b=b.replace(this.protocolRegex,this.protocol);this.url=[];for(var c=0;c<a.imageUrlSubdomains.length;++c)this.url.push(b.replace("{subdomain}",a.imageUrlSubdomains[c]));this.addOptions({maxResolution:Math.min(this.serverResolutions[a.zoomMin],this.maxResolution||Number.POSITIVE_INFINITY),numZoomLevels:Math.min(a.zoomMax+1-a.zoomMin,this.numZoomLevels)}, | |
2338 !0);this.isBaseLayer||this.redraw();this.updateAttribution()},getURL:function(a){if(this.url){var b=this.getXYZ(a);a=b.x;for(var c=b.y,b=b.z,d=[],e=b;0<e;--e){var f="0",g=1<<e-1;0!=(a&g)&&f++;0!=(c&g)&&(f++,f++);d.push(f)}d=d.join("");a=this.selectUrl(""+a+c+b,this.url);return OpenLayers.String.format(a,{quadkey:d})}},updateAttribution:function(){var a=this.metadata;if(a.resourceSets&&this.map&&this.map.center){var b=a.resourceSets[0].resources[0],c=this.map.getExtent().transform(this.map.getProjectionObject(), | |
2339 new OpenLayers.Projection("EPSG:4326")),d=b.imageryProviders||[],e=OpenLayers.Util.indexOf(this.serverResolutions,this.getServerResolution()),b="",f,g,h,k,l,m,n;g=0;for(h=d.length;g<h;++g)for(f=d[g],k=0,l=f.coverageAreas.length;k<l;++k)n=f.coverageAreas[k],m=OpenLayers.Bounds.fromArray(n.bbox,!0),c.intersectsBounds(m)&&(e<=n.zoomMax&&e>=n.zoomMin)&&(b+=f.attribution+" ");a=a.brandLogoUri.replace(this.protocolRegex,this.protocol);this.attribution=OpenLayers.String.format(this.attributionTemplate,{type:this.type.toLowerCase(), | |
2340 logo:a,copyrights:b});this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"attribution"})}},setMap:function(){OpenLayers.Layer.XYZ.prototype.setMap.apply(this,arguments);this.map.events.register("moveend",this,this.updateAttribution)},clone:function(a){null==a&&(a=new OpenLayers.Layer.Bing(this.options));return a=OpenLayers.Layer.XYZ.prototype.clone.apply(this,[a])},destroy:function(){this.map&&this.map.events.unregister("moveend",this,this.updateAttribution);OpenLayers.Layer.XYZ.prototype.destroy.apply(this, | |
2341 arguments)},CLASS_NAME:"OpenLayers.Layer.Bing"});OpenLayers.Layer.Bing.processMetadata=function(a){this.metadata=a;this.initLayer();a=document.getElementById(this._callbackId);a.parentNode.removeChild(a);window[this._callbackId]=void 0;delete this._callbackId};OpenLayers.StyleMap=OpenLayers.Class({styles:null,extendDefault:!0,initialize:function(a,b){this.styles={"default":new OpenLayers.Style(OpenLayers.Feature.Vector.style["default"]),select:new OpenLayers.Style(OpenLayers.Feature.Vector.style.select),temporary:new OpenLayers.Style(OpenLayers.Feature.Vector.style.temporary),"delete":new OpenLayers.Style(OpenLayers.Feature.Vector.style["delete"])};if(a instanceof OpenLayers.Style)this.styles["default"]=a,this.styles.select=a,this.styles.temporary=a,this.styles["delete"]= | |
2342 a;else if("object"==typeof a)for(var c in a)if(a[c]instanceof OpenLayers.Style)this.styles[c]=a[c];else if("object"==typeof a[c])this.styles[c]=new OpenLayers.Style(a[c]);else{this.styles["default"]=new OpenLayers.Style(a);this.styles.select=new OpenLayers.Style(a);this.styles.temporary=new OpenLayers.Style(a);this.styles["delete"]=new OpenLayers.Style(a);break}OpenLayers.Util.extend(this,b)},destroy:function(){for(var a in this.styles)this.styles[a].destroy();this.styles=null},createSymbolizer:function(a, | |
2343 b){a||(a=new OpenLayers.Feature.Vector);this.styles[b]||(b="default");a.renderIntent=b;var c={};this.extendDefault&&"default"!=b&&(c=this.styles["default"].createSymbolizer(a));return OpenLayers.Util.extend(c,this.styles[b].createSymbolizer(a))},addUniqueValueRules:function(a,b,c,d){var e=[],f;for(f in c)e.push(new OpenLayers.Rule({symbolizer:c[f],context:d,filter:new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO,property:b,value:f})}));this.styles[a].addRules(e)},CLASS_NAME:"OpenLayers.StyleMap"});OpenLayers.Layer.Vector=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:!1,isFixed:!1,features:null,filter:null,selectedFeatures:null,unrenderedFeatures:null,reportError:!0,style:null,styleMap:null,strategies:null,protocol:null,renderers:["SVG","VML","Canvas"],renderer:null,rendererOptions:null,geometryType:null,drawn:!1,ratio:1,initialize:function(a,b){OpenLayers.Layer.prototype.initialize.apply(this,arguments);this.renderer&&this.renderer.supported()||this.assignRenderer();this.renderer&&this.renderer.supported()|| | |
2344 (this.renderer=null,this.displayError());this.styleMap||(this.styleMap=new OpenLayers.StyleMap);this.features=[];this.selectedFeatures=[];this.unrenderedFeatures={};if(this.strategies)for(var c=0,d=this.strategies.length;c<d;c++)this.strategies[c].setLayer(this)},destroy:function(){if(this.strategies){var a,b,c;b=0;for(c=this.strategies.length;b<c;b++)a=this.strategies[b],a.autoDestroy&&a.destroy();this.strategies=null}this.protocol&&(this.protocol.autoDestroy&&this.protocol.destroy(),this.protocol= | |
2345 null);this.destroyFeatures();this.unrenderedFeatures=this.selectedFeatures=this.features=null;this.renderer&&this.renderer.destroy();this.drawn=this.geometryType=this.renderer=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments)},clone:function(a){null==a&&(a=new OpenLayers.Layer.Vector(this.name,this.getOptions()));a=OpenLayers.Layer.prototype.clone.apply(this,[a]);for(var b=this.features,c=b.length,d=Array(c),e=0;e<c;++e)d[e]=b[e].clone();a.features=d;return a},refresh:function(a){this.calculateInRange()&& | |
2346 this.visibility&&this.events.triggerEvent("refresh",a)},assignRenderer:function(){for(var a=0,b=this.renderers.length;a<b;a++){var c=this.renderers[a];if((c="function"==typeof c?c:OpenLayers.Renderer[c])&&c.prototype.supported()){this.renderer=new c(this.div,this.rendererOptions);break}}},displayError:function(){this.reportError&&OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported",{renderers:this.renderers.join("\n")}))},setMap:function(a){OpenLayers.Layer.prototype.setMap.apply(this, | |
2347 arguments);if(this.renderer){this.renderer.map=this.map;var b=this.map.getSize();b.w*=this.ratio;b.h*=this.ratio;this.renderer.setSize(b)}else this.map.removeLayer(this)},afterAdd:function(){if(this.strategies){var a,b,c;b=0;for(c=this.strategies.length;b<c;b++)a=this.strategies[b],a.autoActivate&&a.activate()}},removeMap:function(a){this.drawn=!1;if(this.strategies){var b,c;b=0;for(c=this.strategies.length;b<c;b++)a=this.strategies[b],a.autoActivate&&a.deactivate()}},onMapResize:function(){OpenLayers.Layer.prototype.onMapResize.apply(this, | |
2348 arguments);var a=this.map.getSize();a.w*=this.ratio;a.h*=this.ratio;this.renderer.setSize(a)},moveTo:function(a,b,c){OpenLayers.Layer.prototype.moveTo.apply(this,arguments);var d=!0;if(!c){this.renderer.root.style.visibility="hidden";var d=this.map.getSize(),e=d.w,d=d.h,e=e/2*this.ratio-e/2,d=d/2*this.ratio-d/2,e=e+this.map.layerContainerOriginPx.x,e=-Math.round(e),d=d+this.map.layerContainerOriginPx.y,d=-Math.round(d);this.div.style.left=e+"px";this.div.style.top=d+"px";e=this.map.getExtent().scale(this.ratio); | |
2349 d=this.renderer.setExtent(e,b);this.renderer.root.style.visibility="visible";!0===OpenLayers.IS_GECKO&&(this.div.scrollLeft=this.div.scrollLeft);if(!b&&d)for(var f in this.unrenderedFeatures)e=this.unrenderedFeatures[f],this.drawFeature(e)}if(!this.drawn||b||!d)for(this.drawn=!0,f=0,d=this.features.length;f<d;f++)this.renderer.locked=f!==d-1,e=this.features[f],this.drawFeature(e)},display:function(a){OpenLayers.Layer.prototype.display.apply(this,arguments);var b=this.div.style.display;b!=this.renderer.root.style.display&& | |
2350 (this.renderer.root.style.display=b)},addFeatures:function(a,b){OpenLayers.Util.isArray(a)||(a=[a]);var c=!b||!b.silent;if(c){var d={features:a};if(!1===this.events.triggerEvent("beforefeaturesadded",d))return;a=d.features}for(var d=[],e=0,f=a.length;e<f;e++){this.renderer.locked=e!=a.length-1?!0:!1;var g=a[e];if(this.geometryType&&!(g.geometry instanceof this.geometryType))throw new TypeError("addFeatures: component should be an "+this.geometryType.prototype.CLASS_NAME);g.layer=this;!g.style&&this.style&& | |
2351 (g.style=OpenLayers.Util.extend({},this.style));if(c){if(!1===this.events.triggerEvent("beforefeatureadded",{feature:g}))continue;this.preFeatureInsert(g)}d.push(g);this.features.push(g);this.drawFeature(g);c&&(this.events.triggerEvent("featureadded",{feature:g}),this.onFeatureInsert(g))}c&&this.events.triggerEvent("featuresadded",{features:d})},removeFeatures:function(a,b){if(a&&0!==a.length){if(a===this.features)return this.removeAllFeatures(b);OpenLayers.Util.isArray(a)||(a=[a]);a===this.selectedFeatures&& | |
2352 (a=a.slice());var c=!b||!b.silent;c&&this.events.triggerEvent("beforefeaturesremoved",{features:a});for(var d=a.length-1;0<=d;d--){this.renderer.locked=0!=d&&a[d-1].geometry?!0:!1;var e=a[d];delete this.unrenderedFeatures[e.id];c&&this.events.triggerEvent("beforefeatureremoved",{feature:e});this.features=OpenLayers.Util.removeItem(this.features,e);e.layer=null;e.geometry&&this.renderer.eraseFeatures(e);-1!=OpenLayers.Util.indexOf(this.selectedFeatures,e)&&OpenLayers.Util.removeItem(this.selectedFeatures, | |
2353 e);c&&this.events.triggerEvent("featureremoved",{feature:e})}c&&this.events.triggerEvent("featuresremoved",{features:a})}},removeAllFeatures:function(a){a=!a||!a.silent;var b=this.features;a&&this.events.triggerEvent("beforefeaturesremoved",{features:b});for(var c,d=b.length-1;0<=d;d--)c=b[d],a&&this.events.triggerEvent("beforefeatureremoved",{feature:c}),c.layer=null,a&&this.events.triggerEvent("featureremoved",{feature:c});this.renderer.clear();this.features=[];this.unrenderedFeatures={};this.selectedFeatures= | |
2354 [];a&&this.events.triggerEvent("featuresremoved",{features:b})},destroyFeatures:function(a,b){void 0==a&&(a=this.features);if(a){this.removeFeatures(a,b);for(var c=a.length-1;0<=c;c--)a[c].destroy()}},drawFeature:function(a,b){if(this.drawn){if("object"!=typeof b){b||a.state!==OpenLayers.State.DELETE||(b="delete");var c=b||a.renderIntent;(b=a.style||this.style)||(b=this.styleMap.createSymbolizer(a,c))}c=this.renderer.drawFeature(a,b);!1===c||null===c?this.unrenderedFeatures[a.id]=a:delete this.unrenderedFeatures[a.id]}}, | |
2355 eraseFeatures:function(a){this.renderer.eraseFeatures(a)},getFeatureFromEvent:function(a){if(!this.renderer)throw Error("getFeatureFromEvent called on layer with no renderer. This usually means you destroyed a layer, but not some handler which is associated with it.");var b=null;(a=this.renderer.getFeatureIdFromEvent(a))&&(b="string"===typeof a?this.getFeatureById(a):a);return b},getFeatureBy:function(a,b){for(var c=null,d=0,e=this.features.length;d<e;++d)if(this.features[d][a]==b){c=this.features[d]; | |
2356 break}return c},getFeatureById:function(a){return this.getFeatureBy("id",a)},getFeatureByFid:function(a){return this.getFeatureBy("fid",a)},getFeaturesByAttribute:function(a,b){var c,d,e=this.features.length,f=[];for(c=0;c<e;c++)(d=this.features[c])&&d.attributes&&d.attributes[a]===b&&f.push(d);return f},onFeatureInsert:function(a){},preFeatureInsert:function(a){},getDataExtent:function(){var a=null,b=this.features;if(b&&0<b.length)for(var c=null,d=0,e=b.length;d<e;d++)if(c=b[d].geometry)null===a&& | |
2357 (a=new OpenLayers.Bounds),a.extend(c.getBounds());return a},CLASS_NAME:"OpenLayers.Layer.Vector"});OpenLayers.Layer.PointGrid=OpenLayers.Class(OpenLayers.Layer.Vector,{dx:null,dy:null,ratio:1.5,maxFeatures:250,rotation:0,origin:null,gridBounds:null,initialize:function(a){a=a||{};OpenLayers.Layer.Vector.prototype.initialize.apply(this,[a.name,a])},setMap:function(a){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);a.events.register("moveend",this,this.onMoveEnd)},removeMap:function(a){a.events.unregister("moveend",this,this.onMoveEnd);OpenLayers.Layer.Vector.prototype.removeMap.apply(this, | |
2358 arguments)},setRatio:function(a){this.ratio=a;this.updateGrid(!0)},setMaxFeatures:function(a){this.maxFeatures=a;this.updateGrid(!0)},setSpacing:function(a,b){this.dx=a;this.dy=b||a;this.updateGrid(!0)},setOrigin:function(a){this.origin=a;this.updateGrid(!0)},getOrigin:function(){this.origin||(this.origin=this.map.getExtent().getCenterLonLat());return this.origin},setRotation:function(a){this.rotation=a;this.updateGrid(!0)},onMoveEnd:function(){this.updateGrid()},getViewBounds:function(){var a=this.map.getExtent(); | |
2359 if(this.rotation){var b=this.getOrigin(),b=new OpenLayers.Geometry.Point(b.lon,b.lat),a=a.toGeometry();a.rotate(-this.rotation,b);a=a.getBounds()}return a},updateGrid:function(a){if(a||this.invalidBounds()){var b=this.getViewBounds(),c=this.getOrigin();a=new OpenLayers.Geometry.Point(c.lon,c.lat);var d=b.getWidth(),e=b.getHeight(),f=d/e,g=Math.sqrt(this.dx*this.dy*this.maxFeatures/f),d=Math.min(d*this.ratio,g*f),e=Math.min(e*this.ratio,g),b=b.getCenterLonLat();this.gridBounds=new OpenLayers.Bounds(b.lon- | |
2360 d/2,b.lat-e/2,b.lon+d/2,b.lat+e/2);for(var b=Math.floor(e/this.dy),d=Math.floor(d/this.dx),e=c.lon+this.dx*Math.ceil((this.gridBounds.left-c.lon)/this.dx),c=c.lat+this.dy*Math.ceil((this.gridBounds.bottom-c.lat)/this.dy),g=Array(b*d),h,k=0;k<d;++k)for(var f=e+k*this.dx,l=0;l<b;++l)h=c+l*this.dy,h=new OpenLayers.Geometry.Point(f,h),this.rotation&&h.rotate(this.rotation,a),g[k*b+l]=new OpenLayers.Feature.Vector(h);this.destroyFeatures(this.features,{silent:!0});this.addFeatures(g,{silent:!0})}},invalidBounds:function(){return!this.gridBounds|| | |
2361 !this.gridBounds.containsBounds(this.getViewBounds())},CLASS_NAME:"OpenLayers.Layer.PointGrid"});OpenLayers.Handler.MouseWheel=OpenLayers.Class(OpenLayers.Handler,{wheelListener:null,interval:0,maxDelta:Number.POSITIVE_INFINITY,delta:0,cumulative:!0,initialize:function(a,b,c){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.wheelListener=OpenLayers.Function.bindAsEventListener(this.onWheelEvent,this)},destroy:function(){OpenLayers.Handler.prototype.destroy.apply(this,arguments);this.wheelListener=null},onWheelEvent:function(a){if(this.map&&this.checkModifiers(a)){for(var b= | |
2362 !1,c=!1,d=!1,e=OpenLayers.Event.element(a);null!=e&&!d&&!b;){if(!b)try{var f,b=(f=e.currentStyle?e.currentStyle.overflow:document.defaultView.getComputedStyle(e,null).getPropertyValue("overflow"))&&"auto"==f||"scroll"==f}catch(g){}if(!c&&(c=OpenLayers.Element.hasClass(e,"olScrollable"),!c))for(var d=0,h=this.map.layers.length;d<h;d++){var k=this.map.layers[d];if(e==k.div||e==k.pane){c=!0;break}}d=e==this.map.div;e=e.parentNode}if(!b&&d){if(c)if(b=0,a.wheelDelta?(b=a.wheelDelta,0===b%160&&(b*=0.75), | |
2363 b/=120):a.detail&&(b=-(a.detail/Math.abs(a.detail))),this.delta+=b,window.clearTimeout(this._timeoutId),this.interval&&Math.abs(this.delta)<this.maxDelta){var l=OpenLayers.Util.extend({},a);this._timeoutId=window.setTimeout(OpenLayers.Function.bind(function(){this.wheelZoom(l)},this),this.interval)}else this.wheelZoom(a);OpenLayers.Event.stop(a)}}},wheelZoom:function(a){var b=this.delta;this.delta=0;b&&(a.xy=this.map.events.getMousePosition(a),0>b?this.callback("down",[a,this.cumulative?Math.max(-this.maxDelta, | |
2364 b):-1]):this.callback("up",[a,this.cumulative?Math.min(this.maxDelta,b):1]))},activate:function(a){if(OpenLayers.Handler.prototype.activate.apply(this,arguments)){var b=this.wheelListener;OpenLayers.Event.observe(window,"DOMMouseScroll",b);OpenLayers.Event.observe(window,"mousewheel",b);OpenLayers.Event.observe(document,"mousewheel",b);return!0}return!1},deactivate:function(a){if(OpenLayers.Handler.prototype.deactivate.apply(this,arguments)){var b=this.wheelListener;OpenLayers.Event.stopObserving(window, | |
2365 "DOMMouseScroll",b);OpenLayers.Event.stopObserving(window,"mousewheel",b);OpenLayers.Event.stopObserving(document,"mousewheel",b);return!0}return!1},CLASS_NAME:"OpenLayers.Handler.MouseWheel"});OpenLayers.Symbolizer=OpenLayers.Class({zIndex:0,initialize:function(a){OpenLayers.Util.extend(this,a)},clone:function(){return new (eval(this.CLASS_NAME))(OpenLayers.Util.extend({},this))},CLASS_NAME:"OpenLayers.Symbolizer"});OpenLayers.Symbolizer.Raster=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(a){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments)},CLASS_NAME:"OpenLayers.Symbolizer.Raster"});OpenLayers.Rule=OpenLayers.Class({id:null,name:null,title:null,description:null,context:null,filter:null,elseFilter:!1,symbolizer:null,symbolizers:null,minScaleDenominator:null,maxScaleDenominator:null,initialize:function(a){this.symbolizer={};OpenLayers.Util.extend(this,a);this.symbolizers&&delete this.symbolizer;this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_")},destroy:function(){for(var a in this.symbolizer)this.symbolizer[a]=null;this.symbolizer=null;delete this.symbolizers},evaluate:function(a){var b= | |
2366 this.getContext(a),c=!0;if(this.minScaleDenominator||this.maxScaleDenominator)var d=a.layer.map.getScale();this.minScaleDenominator&&(c=d>=OpenLayers.Style.createLiteral(this.minScaleDenominator,b));c&&this.maxScaleDenominator&&(c=d<OpenLayers.Style.createLiteral(this.maxScaleDenominator,b));c&&this.filter&&(c="OpenLayers.Filter.FeatureId"==this.filter.CLASS_NAME?this.filter.evaluate(a):this.filter.evaluate(b));return c},getContext:function(a){var b=this.context;b||(b=a.attributes||a.data);"function"== | |
2367 typeof this.context&&(b=this.context(a));return b},clone:function(){var a=OpenLayers.Util.extend({},this);if(this.symbolizers){var b=this.symbolizers.length;a.symbolizers=Array(b);for(var c=0;c<b;++c)a.symbolizers[c]=this.symbolizers[c].clone()}else{a.symbolizer={};for(var d in this.symbolizer)b=this.symbolizer[d],c=typeof b,"object"===c?a.symbolizer[d]=OpenLayers.Util.extend({},b):"string"===c&&(a.symbolizer[d]=b)}a.filter=this.filter&&this.filter.clone();a.context=this.context&&OpenLayers.Util.extend({}, | |
2368 this.context);return new OpenLayers.Rule(a)},CLASS_NAME:"OpenLayers.Rule"});OpenLayers.Format.SLD=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{profile:null,defaultVersion:"1.0.0",stringifyOutput:!0,namedLayersAsArray:!1,CLASS_NAME:"OpenLayers.Format.SLD"});OpenLayers.Symbolizer.Polygon=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(a){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments)},CLASS_NAME:"OpenLayers.Symbolizer.Polygon"});OpenLayers.Format.GML.v2=OpenLayers.Class(OpenLayers.Format.GML.Base,{schemaLocation:"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd",initialize:function(a){OpenLayers.Format.GML.Base.prototype.initialize.apply(this,[a])},readers:{gml:OpenLayers.Util.applyDefaults({outerBoundaryIs:function(a,b){var c={};this.readChildNodes(a,c);b.outer=c.components[0]},innerBoundaryIs:function(a,b){var c={};this.readChildNodes(a,c);b.inner.push(c.components[0])},Box:function(a,b){var c= | |
2369 {};this.readChildNodes(a,c);b.components||(b.components=[]);var d=c.points[0],c=c.points[1];b.components.push(new OpenLayers.Bounds(d.x,d.y,c.x,c.y))}},OpenLayers.Format.GML.Base.prototype.readers.gml),feature:OpenLayers.Format.GML.Base.prototype.readers.feature,wfs:OpenLayers.Format.GML.Base.prototype.readers.wfs},write:function(a){var b;b=OpenLayers.Util.isArray(a)?"wfs:FeatureCollection":"gml:featureMember";a=this.writeNode(b,a);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation); | |
2370 return OpenLayers.Format.XML.prototype.write.apply(this,[a])},writers:{gml:OpenLayers.Util.applyDefaults({Point:function(a){var b=this.createElementNSPlus("gml:Point");this.writeNode("coordinates",[a],b);return b},coordinates:function(a){for(var b=a.length,c=Array(b),d,e=0;e<b;++e)d=a[e],c[e]=this.xy?d.x+","+d.y:d.y+","+d.x,void 0!=d.z&&(c[e]+=","+d.z);return this.createElementNSPlus("gml:coordinates",{attributes:{decimal:".",cs:",",ts:" "},value:1==b?c[0]:c.join(" ")})},LineString:function(a){var b= | |
2371 this.createElementNSPlus("gml:LineString");this.writeNode("coordinates",a.components,b);return b},Polygon:function(a){var b=this.createElementNSPlus("gml:Polygon");this.writeNode("outerBoundaryIs",a.components[0],b);for(var c=1;c<a.components.length;++c)this.writeNode("innerBoundaryIs",a.components[c],b);return b},outerBoundaryIs:function(a){var b=this.createElementNSPlus("gml:outerBoundaryIs");this.writeNode("LinearRing",a,b);return b},innerBoundaryIs:function(a){var b=this.createElementNSPlus("gml:innerBoundaryIs"); | |
2372 this.writeNode("LinearRing",a,b);return b},LinearRing:function(a){var b=this.createElementNSPlus("gml:LinearRing");this.writeNode("coordinates",a.components,b);return b},Box:function(a){var b=this.createElementNSPlus("gml:Box");this.writeNode("coordinates",[{x:a.left,y:a.bottom},{x:a.right,y:a.top}],b);this.srsName&&b.setAttribute("srsName",this.srsName);return b}},OpenLayers.Format.GML.Base.prototype.writers.gml),feature:OpenLayers.Format.GML.Base.prototype.writers.feature,wfs:OpenLayers.Format.GML.Base.prototype.writers.wfs}, | |
2373 CLASS_NAME:"OpenLayers.Format.GML.v2"});OpenLayers.Format.Filter.v1_0_0=OpenLayers.Class(OpenLayers.Format.GML.v2,OpenLayers.Format.Filter.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/ogc/filter/1.0.0/filter.xsd",initialize:function(a){OpenLayers.Format.GML.v2.prototype.initialize.apply(this,[a])},readers:{ogc:OpenLayers.Util.applyDefaults({PropertyIsEqualTo:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.EQUAL_TO});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsNotEqualTo:function(a, | |
2374 b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.NOT_EQUAL_TO});this.readChildNodes(a,c);b.filters.push(c)},PropertyIsLike:function(a,b){var c=new OpenLayers.Filter.Comparison({type:OpenLayers.Filter.Comparison.LIKE});this.readChildNodes(a,c);var d=a.getAttribute("wildCard"),e=a.getAttribute("singleChar"),f=a.getAttribute("escape");c.value2regex(d,e,f);b.filters.push(c)}},OpenLayers.Format.Filter.v1.prototype.readers.ogc),gml:OpenLayers.Format.GML.v2.prototype.readers.gml, | |
2375 feature:OpenLayers.Format.GML.v2.prototype.readers.feature},writers:{ogc:OpenLayers.Util.applyDefaults({PropertyIsEqualTo:function(a){var b=this.createElementNSPlus("ogc:PropertyIsEqualTo");this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsNotEqualTo:function(a){var b=this.createElementNSPlus("ogc:PropertyIsNotEqualTo");this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsLike:function(a){var b=this.createElementNSPlus("ogc:PropertyIsLike", | |
2376 {attributes:{wildCard:"*",singleChar:".",escape:"!"}});this.writeNode("PropertyName",a,b);this.writeNode("Literal",a.regex2value(),b);return b},BBOX:function(a){var b=this.createElementNSPlus("ogc:BBOX");a.property&&this.writeNode("PropertyName",a,b);var c=this.writeNode("gml:Box",a.value,b);a.projection&&c.setAttribute("srsName",a.projection);return b}},OpenLayers.Format.Filter.v1.prototype.writers.ogc),gml:OpenLayers.Format.GML.v2.prototype.writers.gml,feature:OpenLayers.Format.GML.v2.prototype.writers.feature}, | |
2377 writeSpatial:function(a,b){var c=this.createElementNSPlus("ogc:"+b);this.writeNode("PropertyName",a,c);if(a.value instanceof OpenLayers.Filter.Function)this.writeNode("Function",a.value,c);else{var d;d=a.value instanceof OpenLayers.Geometry?this.writeNode("feature:_geometry",a.value).firstChild:this.writeNode("gml:Box",a.value);a.projection&&d.setAttribute("srsName",a.projection);c.appendChild(d)}return c},CLASS_NAME:"OpenLayers.Format.Filter.v1_0_0"});OpenLayers.Format.WFST.v1_0_0=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,OpenLayers.Format.WFST.v1,{version:"1.0.0",srsNameInQuery:!1,schemaLocations:{wfs:"http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"},initialize:function(a){OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this,[a]);OpenLayers.Format.WFST.v1.prototype.initialize.apply(this,[a])},readNode:function(a,b,c){return OpenLayers.Format.GML.v2.prototype.readNode.apply(this,arguments)},readers:{wfs:OpenLayers.Util.applyDefaults({WFS_TransactionResponse:function(a, | |
2378 b){b.insertIds=[];b.success=!1;this.readChildNodes(a,b)},InsertResult:function(a,b){var c={fids:[]};this.readChildNodes(a,c);b.insertIds=b.insertIds.concat(c.fids)},TransactionResult:function(a,b){this.readChildNodes(a,b)},Status:function(a,b){this.readChildNodes(a,b)},SUCCESS:function(a,b){b.success=!0}},OpenLayers.Format.WFST.v1.prototype.readers.wfs),gml:OpenLayers.Format.GML.v2.prototype.readers.gml,feature:OpenLayers.Format.GML.v2.prototype.readers.feature,ogc:OpenLayers.Format.Filter.v1_0_0.prototype.readers.ogc}, | |
2379 writers:{wfs:OpenLayers.Util.applyDefaults({Query:function(a){a=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName,srsNameInQuery:this.srsNameInQuery},a);var b=a.featurePrefix,c=this.createElementNSPlus("wfs:Query",{attributes:{typeName:(b?b+":":"")+a.featureType}});a.srsNameInQuery&&a.srsName&&c.setAttribute("srsName",a.srsName);a.featureNS&&c.setAttribute("xmlns:"+b,a.featureNS);if(a.propertyNames)for(var b=0,d=a.propertyNames.length;b< | |
2380 d;b++)this.writeNode("ogc:PropertyName",{property:a.propertyNames[b]},c);a.filter&&(this.setFilterProperty(a.filter),this.writeNode("ogc:Filter",a.filter,c));return c}},OpenLayers.Format.WFST.v1.prototype.writers.wfs),gml:OpenLayers.Format.GML.v2.prototype.writers.gml,feature:OpenLayers.Format.GML.v2.prototype.writers.feature,ogc:OpenLayers.Format.Filter.v1_0_0.prototype.writers.ogc},CLASS_NAME:"OpenLayers.Format.WFST.v1_0_0"});OpenLayers.ElementsIndexer=OpenLayers.Class({maxZIndex:null,order:null,indices:null,compare:null,initialize:function(a){this.compare=a?OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER:OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;this.clear()},insert:function(a){this.exists(a)&&this.remove(a);var b=a.id;this.determineZIndex(a);for(var c=-1,d=this.order.length,e;1<d-c;)e=parseInt((c+d)/2),0<this.compare(this,a,OpenLayers.Util.getElement(this.order[e]))?c=e:d=e;this.order.splice(d, | |
2381 0,b);this.indices[b]=this.getZIndex(a);return this.getNextElement(d)},remove:function(a){a=a.id;var b=OpenLayers.Util.indexOf(this.order,a);0<=b&&(this.order.splice(b,1),delete this.indices[a],this.maxZIndex=0<this.order.length?this.indices[this.order[this.order.length-1]]:0)},clear:function(){this.order=[];this.indices={};this.maxZIndex=0},exists:function(a){return null!=this.indices[a.id]},getZIndex:function(a){return a._style.graphicZIndex},determineZIndex:function(a){var b=a._style.graphicZIndex; | |
2382 null==b?(b=this.maxZIndex,a._style.graphicZIndex=b):b>this.maxZIndex&&(this.maxZIndex=b)},getNextElement:function(a){a+=1;if(a<this.order.length){var b=OpenLayers.Util.getElement(this.order[a]);void 0==b&&(b=this.getNextElement(a));return b}return null},CLASS_NAME:"OpenLayers.ElementsIndexer"}); | |
2383 OpenLayers.ElementsIndexer.IndexingMethods={Z_ORDER:function(a,b,c){b=a.getZIndex(b);var d=0;c&&(a=a.getZIndex(c),d=b-a);return d},Z_ORDER_DRAWING_ORDER:function(a,b,c){a=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(a,b,c);c&&0==a&&(a=1);return a},Z_ORDER_Y_ORDER:function(a,b,c){a=OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(a,b,c);c&&0===a&&(b=c._boundsBottom-b._boundsBottom,a=0===b?1:b);return a}}; | |
2384 OpenLayers.Renderer.Elements=OpenLayers.Class(OpenLayers.Renderer,{rendererRoot:null,root:null,vectorRoot:null,textRoot:null,xmlns:null,xOffset:0,indexer:null,BACKGROUND_ID_SUFFIX:"_background",LABEL_ID_SUFFIX:"_label",LABEL_OUTLINE_SUFFIX:"_outline",initialize:function(a,b){OpenLayers.Renderer.prototype.initialize.apply(this,arguments);this.rendererRoot=this.createRenderRoot();this.root=this.createRoot("_root");this.vectorRoot=this.createRoot("_vroot");this.textRoot=this.createRoot("_troot");this.root.appendChild(this.vectorRoot); | |
2385 this.root.appendChild(this.textRoot);this.rendererRoot.appendChild(this.root);this.container.appendChild(this.rendererRoot);b&&(b.zIndexing||b.yOrdering)&&(this.indexer=new OpenLayers.ElementsIndexer(b.yOrdering))},destroy:function(){this.clear();this.xmlns=this.root=this.rendererRoot=null;OpenLayers.Renderer.prototype.destroy.apply(this,arguments)},clear:function(){var a,b=this.vectorRoot;if(b)for(;a=b.firstChild;)b.removeChild(a);if(b=this.textRoot)for(;a=b.firstChild;)b.removeChild(a);this.indexer&& | |
2386 this.indexer.clear()},setExtent:function(a,b){var c=OpenLayers.Renderer.prototype.setExtent.apply(this,arguments),d=this.getResolution();if(this.map.baseLayer&&this.map.baseLayer.wrapDateLine){var e,f=a.getWidth()/this.map.getExtent().getWidth();a=a.scale(1/f);f=this.map.getMaxExtent();f.right>a.left&&f.right<a.right?e=!0:f.left>a.left&&f.left<a.right&&(e=!1);if(e!==this.rightOfDateLine||b)c=!1,this.xOffset=!0===e?f.getWidth()/d:0;this.rightOfDateLine=e}return c},getNodeType:function(a,b){},drawGeometry:function(a, | |
2387 b,c){var d=a.CLASS_NAME,e=!0;if("OpenLayers.Geometry.Collection"==d||"OpenLayers.Geometry.MultiPoint"==d||"OpenLayers.Geometry.MultiLineString"==d||"OpenLayers.Geometry.MultiPolygon"==d){for(var d=0,f=a.components.length;d<f;d++)e=this.drawGeometry(a.components[d],b,c)&&e;return e}d=e=!1;"none"!=b.display&&(b.backgroundGraphic?this.redrawBackgroundNode(a.id,a,b,c):d=!0,e=this.redrawNode(a.id,a,b,c));!1==e&&(b=document.getElementById(a.id))&&(b._style.backgroundGraphic&&(d=!0),b.parentNode.removeChild(b)); | |
2388 d&&(b=document.getElementById(a.id+this.BACKGROUND_ID_SUFFIX))&&b.parentNode.removeChild(b);return e},redrawNode:function(a,b,c,d){c=this.applyDefaultSymbolizer(c);a=this.nodeFactory(a,this.getNodeType(b,c));a._featureId=d;a._boundsBottom=b.getBounds().bottom;a._geometryClass=b.CLASS_NAME;a._style=c;b=this.drawGeometryNode(a,b,c);if(!1===b)return!1;a=b.node;this.indexer?(c=this.indexer.insert(a))?this.vectorRoot.insertBefore(a,c):this.vectorRoot.appendChild(a):a.parentNode!==this.vectorRoot&&this.vectorRoot.appendChild(a); | |
2389 this.postDraw(a);return b.complete},redrawBackgroundNode:function(a,b,c,d){c=OpenLayers.Util.extend({},c);c.externalGraphic=c.backgroundGraphic;c.graphicXOffset=c.backgroundXOffset;c.graphicYOffset=c.backgroundYOffset;c.graphicZIndex=c.backgroundGraphicZIndex;c.graphicWidth=c.backgroundWidth||c.graphicWidth;c.graphicHeight=c.backgroundHeight||c.graphicHeight;c.backgroundGraphic=null;c.backgroundXOffset=null;c.backgroundYOffset=null;c.backgroundGraphicZIndex=null;return this.redrawNode(a+this.BACKGROUND_ID_SUFFIX, | |
2390 b,c,null)},drawGeometryNode:function(a,b,c){c=c||a._style;var d={isFilled:void 0===c.fill?!0:c.fill,isStroked:void 0===c.stroke?!!c.strokeWidth:c.stroke},e;switch(b.CLASS_NAME){case "OpenLayers.Geometry.Point":!1===c.graphic&&(d.isFilled=!1,d.isStroked=!1);e=this.drawPoint(a,b);break;case "OpenLayers.Geometry.LineString":d.isFilled=!1;e=this.drawLineString(a,b);break;case "OpenLayers.Geometry.LinearRing":e=this.drawLinearRing(a,b);break;case "OpenLayers.Geometry.Polygon":e=this.drawPolygon(a,b);break; | |
2391 case "OpenLayers.Geometry.Rectangle":e=this.drawRectangle(a,b)}a._options=d;return!1!=e?{node:this.setStyle(a,c,d,b),complete:e}:!1},postDraw:function(a){},drawPoint:function(a,b){},drawLineString:function(a,b){},drawLinearRing:function(a,b){},drawPolygon:function(a,b){},drawRectangle:function(a,b){},drawCircle:function(a,b){},removeText:function(a){var b=document.getElementById(a+this.LABEL_ID_SUFFIX);b&&this.textRoot.removeChild(b);(a=document.getElementById(a+this.LABEL_OUTLINE_SUFFIX))&&this.textRoot.removeChild(a)}, | |
2392 getFeatureIdFromEvent:function(a){var b=a.target,c=b&&b.correspondingUseElement;return(c?c:b||a.srcElement)._featureId},eraseGeometry:function(a,b){if("OpenLayers.Geometry.MultiPoint"==a.CLASS_NAME||"OpenLayers.Geometry.MultiLineString"==a.CLASS_NAME||"OpenLayers.Geometry.MultiPolygon"==a.CLASS_NAME||"OpenLayers.Geometry.Collection"==a.CLASS_NAME)for(var c=0,d=a.components.length;c<d;c++)this.eraseGeometry(a.components[c],b);else(c=OpenLayers.Util.getElement(a.id))&&c.parentNode&&(c.geometry&&(c.geometry.destroy(), | |
2393 c.geometry=null),c.parentNode.removeChild(c),this.indexer&&this.indexer.remove(c),c._style.backgroundGraphic&&(c=OpenLayers.Util.getElement(a.id+this.BACKGROUND_ID_SUFFIX))&&c.parentNode&&c.parentNode.removeChild(c))},nodeFactory:function(a,b){var c=OpenLayers.Util.getElement(a);c?this.nodeTypeCompare(c,b)||(c.parentNode.removeChild(c),c=this.nodeFactory(a,b)):c=this.createNode(b,a);return c},nodeTypeCompare:function(a,b){},createNode:function(a,b){},moveRoot:function(a){var b=this.root;a.root.parentNode== | |
2394 this.rendererRoot&&(b=a.root);b.parentNode.removeChild(b);a.rendererRoot.appendChild(b)},getRenderLayerId:function(){return this.root.parentNode.parentNode.id},isComplexSymbol:function(a){return"circle"!=a&&!!a},CLASS_NAME:"OpenLayers.Renderer.Elements"});OpenLayers.Control.ArgParser=OpenLayers.Class(OpenLayers.Control,{center:null,zoom:null,layers:null,displayProjection:null,getParameters:function(a){a=a||window.location.href;var b=OpenLayers.Util.getParameters(a),c=a.indexOf("#");0<c&&(a="?"+a.substring(c+1,a.length),OpenLayers.Util.extend(b,OpenLayers.Util.getParameters(a)));return b},setMap:function(a){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var b=0,c=this.map.controls.length;b<c;b++){var d=this.map.controls[b];if(d!=this&& | |
2395 "OpenLayers.Control.ArgParser"==d.CLASS_NAME){d.displayProjection!=this.displayProjection&&(this.displayProjection=d.displayProjection);break}}b==this.map.controls.length&&(b=this.getParameters(),b.layers&&(this.layers=b.layers,this.map.events.register("addlayer",this,this.configureLayers),this.configureLayers()),b.lat&&b.lon&&(this.center=new OpenLayers.LonLat(parseFloat(b.lon),parseFloat(b.lat)),b.zoom&&(this.zoom=parseFloat(b.zoom)),this.map.events.register("changebaselayer",this,this.setCenter), | |
2396 this.setCenter()))},setCenter:function(){this.map.baseLayer&&(this.map.events.unregister("changebaselayer",this,this.setCenter),this.displayProjection&&this.center.transform(this.displayProjection,this.map.getProjectionObject()),this.map.setCenter(this.center,this.zoom))},configureLayers:function(){if(this.layers.length==this.map.layers.length){this.map.events.unregister("addlayer",this,this.configureLayers);for(var a=0,b=this.layers.length;a<b;a++){var c=this.map.layers[a],d=this.layers.charAt(a); | |
2397 "B"==d?this.map.setBaseLayer(c):"T"!=d&&"F"!=d||c.setVisibility("T"==d)}}},CLASS_NAME:"OpenLayers.Control.ArgParser"});OpenLayers.Control.Permalink=OpenLayers.Class(OpenLayers.Control,{argParserClass:OpenLayers.Control.ArgParser,element:null,anchor:!1,base:"",displayProjection:null,initialize:function(a,b,c){null===a||"object"!=typeof a||OpenLayers.Util.isElement(a)?(OpenLayers.Control.prototype.initialize.apply(this,[c]),this.element=OpenLayers.Util.getElement(a),this.base=b||document.location.href):(this.base=document.location.href,OpenLayers.Control.prototype.initialize.apply(this,[a]),null!=this.element&&(this.element= | |
2398 OpenLayers.Util.getElement(this.element)))},destroy:function(){this.element&&this.element.parentNode==this.div&&(this.div.removeChild(this.element),this.element=null);this.map&&this.map.events.unregister("moveend",this,this.updateLink);OpenLayers.Control.prototype.destroy.apply(this,arguments)},setMap:function(a){OpenLayers.Control.prototype.setMap.apply(this,arguments);for(var b=0,c=this.map.controls.length;b<c;b++){var d=this.map.controls[b];if(d.CLASS_NAME==this.argParserClass.CLASS_NAME){d.displayProjection!= | |
2399 this.displayProjection&&(this.displayProjection=d.displayProjection);break}}b==this.map.controls.length&&this.map.addControl(new this.argParserClass({displayProjection:this.displayProjection}))},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.element||this.anchor||(this.element=document.createElement("a"),this.element.innerHTML=OpenLayers.i18n("Permalink"),this.element.href="",this.div.appendChild(this.element));this.map.events.on({moveend:this.updateLink,changelayer:this.updateLink, | |
2400 changebaselayer:this.updateLink,scope:this});this.updateLink();return this.div},updateLink:function(){var a=this.anchor?"#":"?",b=this.base,c=null;-1!=b.indexOf("#")&&!1==this.anchor&&(c=b.substring(b.indexOf("#"),b.length));-1!=b.indexOf(a)&&(b=b.substring(0,b.indexOf(a)));b=b.split("#")[0]+a+OpenLayers.Util.getParameterString(this.createParams());c&&(b+=c);this.anchor&&!this.element?window.location.href=b:this.element.href=b},createParams:function(a,b,c){a=a||this.map.getCenter();var d=OpenLayers.Util.getParameters(this.base); | |
2401 if(a)for(d.zoom=b||this.map.getZoom(),b=a.lat,a=a.lon,this.displayProjection&&(b=OpenLayers.Projection.transform({x:a,y:b},this.map.getProjectionObject(),this.displayProjection),a=b.x,b=b.y),d.lat=Math.round(1E5*b)/1E5,d.lon=Math.round(1E5*a)/1E5,c=c||this.map.layers,d.layers="",a=0,b=c.length;a<b;a++){var e=c[a];d.layers=e.isBaseLayer?d.layers+(e==this.map.baseLayer?"B":"0"):d.layers+(e.getVisibility()?"T":"F")}return d},CLASS_NAME:"OpenLayers.Control.Permalink"});OpenLayers.Layer.TMS=OpenLayers.Class(OpenLayers.Layer.Grid,{serviceVersion:"1.0.0",layername:null,type:null,isBaseLayer:!0,tileOrigin:null,serverResolutions:null,zoomOffset:0,initialize:function(a,b,c){var d=[];d.push(a,b,{},c);OpenLayers.Layer.Grid.prototype.initialize.apply(this,d)},clone:function(a){null==a&&(a=new OpenLayers.Layer.TMS(this.name,this.url,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getURL:function(a){a=this.adjustBounds(a);var b=this.getServerResolution(), | |
2402 c=Math.round((a.left-this.tileOrigin.lon)/(b*this.tileSize.w));a=Math.round((a.bottom-this.tileOrigin.lat)/(b*this.tileSize.h));b=this.getServerZoom();c=this.serviceVersion+"/"+this.layername+"/"+b+"/"+c+"/"+a+"."+this.type;a=this.url;OpenLayers.Util.isArray(a)&&(a=this.selectUrl(c,a));return a+c},setMap:function(a){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.tileOrigin||(this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left,this.map.maxExtent.bottom))},CLASS_NAME:"OpenLayers.Layer.TMS"});OpenLayers.Format.WCSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.1.0",CLASS_NAME:"OpenLayers.Format.WCSCapabilities"});OpenLayers.Format.WCSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.XML,{regExes:{trimSpace:/^\s*|\s*$/g,splitSpace:/\s+/},defaultPrefix:"wcs",read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b},CLASS_NAME:"OpenLayers.Format.WCSCapabilities.v1"});OpenLayers.Format.WCSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.WCSCapabilities.v1,{namespaces:{wcs:"http://www.opengis.net/wcs",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",ows:"http://www.opengis.net/ows"},errorProperty:"service",readers:{wcs:{WCS_Capabilities:function(a,b){this.readChildNodes(a,b)},Service:function(a,b){b.service={};this.readChildNodes(a,b.service)},name:function(a,b){b.name=this.getChildValue(a)},label:function(a,b){b.label= | |
2403 this.getChildValue(a)},keywords:function(a,b){b.keywords=[];this.readChildNodes(a,b.keywords)},keyword:function(a,b){b.push(this.getChildValue(a))},responsibleParty:function(a,b){b.responsibleParty={};this.readChildNodes(a,b.responsibleParty)},individualName:function(a,b){b.individualName=this.getChildValue(a)},organisationName:function(a,b){b.organisationName=this.getChildValue(a)},positionName:function(a,b){b.positionName=this.getChildValue(a)},contactInfo:function(a,b){b.contactInfo={};this.readChildNodes(a, | |
2404 b.contactInfo)},phone:function(a,b){b.phone={};this.readChildNodes(a,b.phone)},voice:function(a,b){b.voice=this.getChildValue(a)},facsimile:function(a,b){b.facsimile=this.getChildValue(a)},address:function(a,b){b.address={};this.readChildNodes(a,b.address)},deliveryPoint:function(a,b){b.deliveryPoint=this.getChildValue(a)},city:function(a,b){b.city=this.getChildValue(a)},postalCode:function(a,b){b.postalCode=this.getChildValue(a)},country:function(a,b){b.country=this.getChildValue(a)},electronicMailAddress:function(a, | |
2405 b){b.electronicMailAddress=this.getChildValue(a)},fees:function(a,b){b.fees=this.getChildValue(a)},accessConstraints:function(a,b){b.accessConstraints=this.getChildValue(a)},ContentMetadata:function(a,b){b.contentMetadata=[];this.readChildNodes(a,b.contentMetadata)},CoverageOfferingBrief:function(a,b){var c={};this.readChildNodes(a,c);b.push(c)},name:function(a,b){b.name=this.getChildValue(a)},label:function(a,b){b.label=this.getChildValue(a)},lonLatEnvelope:function(a,b){var c=this.getElementsByTagNameNS(a, | |
2406 "http://www.opengis.net/gml","pos");if(2==c.length){var d={},e={};OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(this,[c[0],d]);OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(this,[c[1],e]);b.lonLatEnvelope={};b.lonLatEnvelope.srsName=a.getAttribute("srsName");b.lonLatEnvelope.min=d.points[0];b.lonLatEnvelope.max=e.points[0]}}}},CLASS_NAME:"OpenLayers.Format.WCSCapabilities.v1_0_0"});OpenLayers.Strategy.Fixed=OpenLayers.Class(OpenLayers.Strategy,{preload:!1,activate:function(){var a=OpenLayers.Strategy.prototype.activate.apply(this,arguments);if(a)if(this.layer.events.on({refresh:this.load,scope:this}),!0==this.layer.visibility||this.preload)this.load();else this.layer.events.on({visibilitychanged:this.load,scope:this});return a},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&this.layer.events.un({refresh:this.load,visibilitychanged:this.load, | |
2407 scope:this});return a},load:function(a){var b=this.layer;b.events.triggerEvent("loadstart",{filter:b.filter});b.protocol.read(OpenLayers.Util.applyDefaults({callback:this.merge,filter:b.filter,scope:this},a));b.events.un({visibilitychanged:this.load,scope:this})},merge:function(a){var b=this.layer;b.destroyFeatures();var c=a.features;if(c&&0<c.length){var d=b.projection,e=b.map.getProjectionObject();if(!e.equals(d))for(var f,g=0,h=c.length;g<h;++g)(f=c[g].geometry)&&f.transform(d,e);b.addFeatures(c)}b.events.triggerEvent("loadend", | |
2408 {response:a})},CLASS_NAME:"OpenLayers.Strategy.Fixed"});OpenLayers.Control.Zoom=OpenLayers.Class(OpenLayers.Control,{zoomInText:"+",zoomInId:"olZoomInLink",zoomOutText:"\u2212",zoomOutId:"olZoomOutLink",draw:function(){var a=OpenLayers.Control.prototype.draw.apply(this),b=this.getOrCreateLinks(a),c=b.zoomIn,b=b.zoomOut,d=this.map.events;b.parentNode!==a&&(d=this.events,d.attachToElement(b.parentNode));d.register("buttonclick",this,this.onZoomClick);this.zoomInLink=c;this.zoomOutLink=b;return a},getOrCreateLinks:function(a){var b=document.getElementById(this.zoomInId), | |
2409 c=document.getElementById(this.zoomOutId);b||(b=document.createElement("a"),b.href="#zoomIn",b.appendChild(document.createTextNode(this.zoomInText)),b.className="olControlZoomIn",a.appendChild(b));OpenLayers.Element.addClass(b,"olButton");c||(c=document.createElement("a"),c.href="#zoomOut",c.appendChild(document.createTextNode(this.zoomOutText)),c.className="olControlZoomOut",a.appendChild(c));OpenLayers.Element.addClass(c,"olButton");return{zoomIn:b,zoomOut:c}},onZoomClick:function(a){a=a.buttonElement; | |
2410 a===this.zoomInLink?this.map.zoomIn():a===this.zoomOutLink&&this.map.zoomOut()},destroy:function(){this.map&&this.map.events.unregister("buttonclick",this,this.onZoomClick);delete this.zoomInLink;delete this.zoomOutLink;OpenLayers.Control.prototype.destroy.apply(this)},CLASS_NAME:"OpenLayers.Control.Zoom"});OpenLayers.Layer.PointTrack=OpenLayers.Class(OpenLayers.Layer.Vector,{dataFrom:null,styleFrom:null,addNodes:function(a,b){if(2>a.length)throw Error("At least two point features have to be added to create a line from");for(var c=Array(a.length-1),d,e,f,g=0,h=a.length;g<h;g++){d=a[g];f=d.geometry;if(!f)f=d.lonlat,f=new OpenLayers.Geometry.Point(f.lon,f.lat);else if("OpenLayers.Geometry.Point"!=f.CLASS_NAME)throw new TypeError("Only features with point geometries are supported.");if(0<g){d=null!=this.dataFrom? | |
2411 a[g+this.dataFrom].data||a[g+this.dataFrom].attributes:null;var k=null!=this.styleFrom?a[g+this.styleFrom].style:null;e=new OpenLayers.Geometry.LineString([e,f]);c[g-1]=new OpenLayers.Feature.Vector(e,d,k)}e=f}this.addFeatures(c,b)},CLASS_NAME:"OpenLayers.Layer.PointTrack"});OpenLayers.Layer.PointTrack.SOURCE_NODE=-1;OpenLayers.Layer.PointTrack.TARGET_NODE=0;OpenLayers.Layer.PointTrack.dataFrom={SOURCE_NODE:-1,TARGET_NODE:0};OpenLayers.Protocol.WFS=function(a){a=OpenLayers.Util.applyDefaults(a,OpenLayers.Protocol.WFS.DEFAULTS);var b=OpenLayers.Protocol.WFS["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported WFS version: "+a.version;return new b(a)}; | |
2412 OpenLayers.Protocol.WFS.fromWMSLayer=function(a,b){var c,d;c=a.params.LAYERS;c=(OpenLayers.Util.isArray(c)?c[0]:c).split(":");1<c.length&&(d=c[0]);c=c.pop();d={url:a.url,featureType:c,featurePrefix:d,srsName:a.projection&&a.projection.getCode()||a.map&&a.map.getProjectionObject().getCode(),version:"1.1.0"};return new OpenLayers.Protocol.WFS(OpenLayers.Util.applyDefaults(b,d))};OpenLayers.Protocol.WFS.DEFAULTS={version:"1.0.0"};OpenLayers.Layer.Markers=OpenLayers.Class(OpenLayers.Layer,{isBaseLayer:!1,markers:null,drawn:!1,initialize:function(a,b){OpenLayers.Layer.prototype.initialize.apply(this,arguments);this.markers=[]},destroy:function(){this.clearMarkers();this.markers=null;OpenLayers.Layer.prototype.destroy.apply(this,arguments)},setOpacity:function(a){if(a!=this.opacity){this.opacity=a;a=0;for(var b=this.markers.length;a<b;a++)this.markers[a].setOpacity(this.opacity)}},moveTo:function(a,b,c){OpenLayers.Layer.prototype.moveTo.apply(this, | |
2413 arguments);if(b||!this.drawn){for(var d=0,e=this.markers.length;d<e;d++)this.drawMarker(this.markers[d]);this.drawn=!0}},addMarker:function(a){this.markers.push(a);1>this.opacity&&a.setOpacity(this.opacity);this.map&&this.map.getExtent()&&(a.map=this.map,this.drawMarker(a))},removeMarker:function(a){this.markers&&this.markers.length&&(OpenLayers.Util.removeItem(this.markers,a),a.erase())},clearMarkers:function(){if(null!=this.markers)for(;0<this.markers.length;)this.removeMarker(this.markers[0])}, | |
2414 drawMarker:function(a){var b=this.map.getLayerPxFromLonLat(a.lonlat);null==b?a.display(!1):a.isDrawn()?a.icon&&a.icon.moveTo(b):(a=a.draw(b),this.div.appendChild(a))},getDataExtent:function(){var a=null;if(this.markers&&0<this.markers.length)for(var a=new OpenLayers.Bounds,b=0,c=this.markers.length;b<c;b++)a.extend(this.markers[b].lonlat);return a},CLASS_NAME:"OpenLayers.Layer.Markers"});OpenLayers.Control.Pan=OpenLayers.Class(OpenLayers.Control.Button,{slideFactor:50,slideRatio:null,direction:null,initialize:function(a,b){this.direction=a;this.CLASS_NAME+=this.direction;OpenLayers.Control.prototype.initialize.apply(this,[b])},trigger:function(){if(this.map){var a=OpenLayers.Function.bind(function(a){return this.slideRatio?this.map.getSize()[a]*this.slideRatio:this.slideFactor},this);switch(this.direction){case OpenLayers.Control.Pan.NORTH:this.map.pan(0,-a("h"));break;case OpenLayers.Control.Pan.SOUTH:this.map.pan(0, | |
2415 a("h"));break;case OpenLayers.Control.Pan.WEST:this.map.pan(-a("w"),0);break;case OpenLayers.Control.Pan.EAST:this.map.pan(a("w"),0)}}},CLASS_NAME:"OpenLayers.Control.Pan"});OpenLayers.Control.Pan.NORTH="North";OpenLayers.Control.Pan.SOUTH="South";OpenLayers.Control.Pan.EAST="East";OpenLayers.Control.Pan.WEST="West";OpenLayers.Format.CSWGetDomain=function(a){a=OpenLayers.Util.applyDefaults(a,OpenLayers.Format.CSWGetDomain.DEFAULTS);var b=OpenLayers.Format.CSWGetDomain["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported CSWGetDomain version: "+a.version;return new b(a)};OpenLayers.Format.CSWGetDomain.DEFAULTS={version:"2.0.2"};OpenLayers.Format.CSWGetDomain.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",csw:"http://www.opengis.net/cat/csw/2.0.2"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd",PropertyName:null,ParameterName:null,read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9== | |
2416 a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b},readers:{csw:{GetDomainResponse:function(a,b){this.readChildNodes(a,b)},DomainValues:function(a,b){OpenLayers.Util.isArray(b.DomainValues)||(b.DomainValues=[]);for(var c=a.attributes,d={},e=0,f=c.length;e<f;++e)d[c[e].name]=c[e].nodeValue;this.readChildNodes(a,d);b.DomainValues.push(d)},PropertyName:function(a,b){b.PropertyName=this.getChildValue(a)},ParameterName:function(a,b){b.ParameterName=this.getChildValue(a)},ListOfValues:function(a, | |
2417 b){OpenLayers.Util.isArray(b.ListOfValues)||(b.ListOfValues=[]);this.readChildNodes(a,b.ListOfValues)},Value:function(a,b){for(var c=a.attributes,d={},e=0,f=c.length;e<f;++e)d[c[e].name]=c[e].nodeValue;d.value=this.getChildValue(a);b.push({Value:d})},ConceptualScheme:function(a,b){b.ConceptualScheme={};this.readChildNodes(a,b.ConceptualScheme)},Name:function(a,b){b.Name=this.getChildValue(a)},Document:function(a,b){b.Document=this.getChildValue(a)},Authority:function(a,b){b.Authority=this.getChildValue(a)}, | |
2418 RangeOfValues:function(a,b){b.RangeOfValues={};this.readChildNodes(a,b.RangeOfValues)},MinValue:function(a,b){for(var c=a.attributes,d={},e=0,f=c.length;e<f;++e)d[c[e].name]=c[e].nodeValue;d.value=this.getChildValue(a);b.MinValue=d},MaxValue:function(a,b){for(var c=a.attributes,d={},e=0,f=c.length;e<f;++e)d[c[e].name]=c[e].nodeValue;d.value=this.getChildValue(a);b.MaxValue=d}}},write:function(a){a=this.writeNode("csw:GetDomain",a);return OpenLayers.Format.XML.prototype.write.apply(this,[a])},writers:{csw:{GetDomain:function(a){var b= | |
2419 this.createElementNSPlus("csw:GetDomain",{attributes:{service:"CSW",version:this.version}});a.PropertyName||this.PropertyName?this.writeNode("csw:PropertyName",a.PropertyName||this.PropertyName,b):(a.ParameterName||this.ParameterName)&&this.writeNode("csw:ParameterName",a.ParameterName||this.ParameterName,b);this.readChildNodes(b,a);return b},PropertyName:function(a){return this.createElementNSPlus("csw:PropertyName",{value:a})},ParameterName:function(a){return this.createElementNSPlus("csw:ParameterName", | |
2420 {value:a})}}},CLASS_NAME:"OpenLayers.Format.CSWGetDomain.v2_0_2"});OpenLayers.Format.ArcXML.Features=OpenLayers.Class(OpenLayers.Format.XML,{read:function(a){return(new OpenLayers.Format.ArcXML).read(a).features.feature}});OpenLayers.Control.Snapping=OpenLayers.Class(OpenLayers.Control,{DEFAULTS:{tolerance:10,node:!0,edge:!0,vertex:!0},greedy:!0,precedence:["node","vertex","edge"],resolution:null,geoToleranceCache:null,layer:null,feature:null,point:null,initialize:function(a){OpenLayers.Control.prototype.initialize.apply(this,[a]);this.options=a||{};this.options.layer&&this.setLayer(this.options.layer);a=OpenLayers.Util.extend({},this.options.defaults);this.defaults=OpenLayers.Util.applyDefaults(a,this.DEFAULTS);this.setTargets(this.options.targets); | |
2421 0===this.targets.length&&this.layer&&this.addTargetLayer(this.layer);this.geoToleranceCache={}},setLayer:function(a){this.active?(this.deactivate(),this.layer=a,this.activate()):this.layer=a},setTargets:function(a){this.targets=[];if(a&&a.length)for(var b,c=0,d=a.length;c<d;++c)b=a[c],b instanceof OpenLayers.Layer.Vector?this.addTargetLayer(b):this.addTarget(b)},addTargetLayer:function(a){this.addTarget({layer:a})},addTarget:function(a){a=OpenLayers.Util.applyDefaults(a,this.defaults);a.nodeTolerance= | |
2422 a.nodeTolerance||a.tolerance;a.vertexTolerance=a.vertexTolerance||a.tolerance;a.edgeTolerance=a.edgeTolerance||a.tolerance;this.targets.push(a)},removeTargetLayer:function(a){for(var b,c=this.targets.length-1;0<=c;--c)b=this.targets[c],b.layer===a&&this.removeTarget(b)},removeTarget:function(a){return OpenLayers.Util.removeItem(this.targets,a)},activate:function(){var a=OpenLayers.Control.prototype.activate.call(this);if(a&&this.layer&&this.layer.events)this.layer.events.on({sketchstarted:this.onSketchModified, | |
2423 sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});return a},deactivate:function(){var a=OpenLayers.Control.prototype.deactivate.call(this);a&&this.layer&&this.layer.events&&this.layer.events.un({sketchstarted:this.onSketchModified,sketchmodified:this.onSketchModified,vertexmodified:this.onVertexModified,scope:this});this.point=this.feature=null;return a},onSketchModified:function(a){this.feature=a.feature;this.considerSnapping(a.vertex,a.vertex)},onVertexModified:function(a){this.feature= | |
2424 a.feature;var b=this.layer.map.getLonLatFromViewPortPx(a.pixel);this.considerSnapping(a.vertex,new OpenLayers.Geometry.Point(b.lon,b.lat))},considerSnapping:function(a,b){for(var c={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY,x:null,y:null},d=!1,e,f,g=0,h=this.targets.length;g<h;++g)if(f=this.targets[g],e=this.testTarget(f,b))if(this.greedy){c=e;c.target=f;d=!0;break}else if(e.rank<c.rank||e.rank===c.rank&&e.dist<c.dist)c=e,c.target=f,d=!0;d&&(!1!==this.events.triggerEvent("beforesnap", | |
2425 {point:a,x:c.x,y:c.y,distance:c.dist,layer:c.target.layer,snapType:this.precedence[c.rank]})?(a.x=c.x,a.y=c.y,this.point=a,this.events.triggerEvent("snap",{point:a,snapType:this.precedence[c.rank],layer:c.target.layer,distance:c.dist})):d=!1);this.point&&!d&&(a.x=b.x,a.y=b.y,this.point=null,this.events.triggerEvent("unsnap",{point:a}))},testTarget:function(a,b){var c=this.layer.map.getResolution();if("minResolution"in a&&c<a.minResolution||"maxResolution"in a&&c>=a.maxResolution)return null;for(var c= | |
2426 {node:this.getGeoTolerance(a.nodeTolerance,c),vertex:this.getGeoTolerance(a.vertexTolerance,c),edge:this.getGeoTolerance(a.edgeTolerance,c)},d=Math.max(c.node,c.vertex,c.edge),e={rank:Number.POSITIVE_INFINITY,dist:Number.POSITIVE_INFINITY},f=!1,g=a.layer.features,h,k,l,m,n,p,q=this.precedence.length,r=new OpenLayers.LonLat(b.x,b.y),s=0,t=g.length;s<t;++s)if(h=g[s],h!==this.feature&&(!h._sketch&&h.state!==OpenLayers.State.DELETE&&(!a.filter||a.filter.evaluate(h)))&&h.atPoint(r,d,d))for(var u=0,v=Math.min(e.rank+ | |
2427 1,q);u<v;++u)if(k=this.precedence[u],a[k])if("edge"===k){if(l=h.geometry.distanceTo(b,{details:!0}),n=l.distance,n<=c[k]&&n<e.dist){e={rank:u,dist:n,x:l.x0,y:l.y0};f=!0;break}}else{l=h.geometry.getVertices("node"===k);p=!1;for(var w=0,x=l.length;w<x;++w)m=l[w],n=m.distanceTo(b),n<=c[k]&&(u<e.rank||u===e.rank&&n<e.dist)&&(e={rank:u,dist:n,x:m.x,y:m.y},p=f=!0);if(p)break}return f?e:null},getGeoTolerance:function(a,b){b!==this.resolution&&(this.resolution=b,this.geoToleranceCache={});var c=this.geoToleranceCache[a]; | |
2428 void 0===c&&(c=a*b,this.geoToleranceCache[a]=c);return c},destroy:function(){this.active&&this.deactivate();delete this.layer;delete this.targets;OpenLayers.Control.prototype.destroy.call(this)},CLASS_NAME:"OpenLayers.Control.Snapping"});OpenLayers.Format.OWSCommon.v1_1_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1,{namespaces:{ows:"http://www.opengis.net/ows/1.1",xlink:"http://www.w3.org/1999/xlink"},readers:{ows:OpenLayers.Util.applyDefaults({ExceptionReport:function(a,b){b.exceptionReport={version:a.getAttribute("version"),language:a.getAttribute("xml:lang"),exceptions:[]};this.readChildNodes(a,b.exceptionReport)},AllowedValues:function(a,b){b.allowedValues={};this.readChildNodes(a,b.allowedValues)},AnyValue:function(a,b){b.anyValue= | |
2429 !0},DataType:function(a,b){b.dataType=this.getChildValue(a)},Range:function(a,b){b.range={};this.readChildNodes(a,b.range)},MinimumValue:function(a,b){b.minValue=this.getChildValue(a)},MaximumValue:function(a,b){b.maxValue=this.getChildValue(a)},Identifier:function(a,b){b.identifier=this.getChildValue(a)},SupportedCRS:function(a,b){b.supportedCRS=this.getChildValue(a)}},OpenLayers.Format.OWSCommon.v1.prototype.readers.ows)},writers:{ows:OpenLayers.Util.applyDefaults({Range:function(a){var b=this.createElementNSPlus("ows:Range", | |
2430 {attributes:{"ows:rangeClosure":a.closure}});this.writeNode("ows:MinimumValue",a.minValue,b);this.writeNode("ows:MaximumValue",a.maxValue,b);return b},MinimumValue:function(a){return this.createElementNSPlus("ows:MinimumValue",{value:a})},MaximumValue:function(a){return this.createElementNSPlus("ows:MaximumValue",{value:a})},Value:function(a){return this.createElementNSPlus("ows:Value",{value:a})}},OpenLayers.Format.OWSCommon.v1.prototype.writers.ows)},CLASS_NAME:"OpenLayers.Format.OWSCommon.v1_1_0"});OpenLayers.Format.WCSGetCoverage=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ows:"http://www.opengis.net/ows/1.1",wcs:"http://www.opengis.net/wcs/1.1",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},VERSION:"1.1.2",schemaLocation:"http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsGetCoverage.xsd",write:function(a){a=this.writeNode("wcs:GetCoverage", | |
2431 a);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[a])},writers:{wcs:{GetCoverage:function(a){var b=this.createElementNSPlus("wcs:GetCoverage",{attributes:{version:a.version||this.VERSION,service:"WCS"}});this.writeNode("ows:Identifier",a.identifier,b);this.writeNode("wcs:DomainSubset",a.domainSubset,b);this.writeNode("wcs:Output",a.output,b);return b},DomainSubset:function(a){var b=this.createElementNSPlus("wcs:DomainSubset", | |
2432 {});this.writeNode("ows:BoundingBox",a.boundingBox,b);a.temporalSubset&&this.writeNode("wcs:TemporalSubset",a.temporalSubset,b);return b},TemporalSubset:function(a){for(var b=this.createElementNSPlus("wcs:TemporalSubset",{}),c=0,d=a.timePeriods.length;c<d;++c)this.writeNode("wcs:TimePeriod",a.timePeriods[c],b);return b},TimePeriod:function(a){var b=this.createElementNSPlus("wcs:TimePeriod",{});this.writeNode("wcs:BeginPosition",a.begin,b);this.writeNode("wcs:EndPosition",a.end,b);a.resolution&&this.writeNode("wcs:TimeResolution", | |
2433 a.resolution,b);return b},BeginPosition:function(a){return this.createElementNSPlus("wcs:BeginPosition",{value:a})},EndPosition:function(a){return this.createElementNSPlus("wcs:EndPosition",{value:a})},TimeResolution:function(a){return this.createElementNSPlus("wcs:TimeResolution",{value:a})},Output:function(a){var b=this.createElementNSPlus("wcs:Output",{attributes:{format:a.format,store:a.store}});a.gridCRS&&this.writeNode("wcs:GridCRS",a.gridCRS,b);return b},GridCRS:function(a){var b=this.createElementNSPlus("wcs:GridCRS", | |
2434 {});this.writeNode("wcs:GridBaseCRS",a.baseCRS,b);a.type&&this.writeNode("wcs:GridType",a.type,b);a.origin&&this.writeNode("wcs:GridOrigin",a.origin,b);this.writeNode("wcs:GridOffsets",a.offsets,b);a.CS&&this.writeNode("wcs:GridCS",a.CS,b);return b},GridBaseCRS:function(a){return this.createElementNSPlus("wcs:GridBaseCRS",{value:a})},GridOrigin:function(a){return this.createElementNSPlus("wcs:GridOrigin",{value:a})},GridType:function(a){return this.createElementNSPlus("wcs:GridType",{value:a})},GridOffsets:function(a){return this.createElementNSPlus("wcs:GridOffsets", | |
2435 {value:a})},GridCS:function(a){return this.createElementNSPlus("wcs:GridCS",{value:a})}},ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.writers.ows},CLASS_NAME:"OpenLayers.Format.WCSGetCoverage"});OpenLayers.Format.KML=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{kml:"http://www.opengis.net/kml/2.2",gx:"http://www.google.com/kml/ext/2.2"},kmlns:"http://earth.google.com/kml/2.0",placemarksDesc:"No description available",foldersName:"OpenLayers export",foldersDesc:"Exported on "+new Date,extractAttributes:!0,kvpAttributes:!1,extractStyles:!1,extractTracks:!1,trackAttributes:null,internalns:null,features:null,styles:null,styleBaseUrl:"",fetched:null,maxDepth:0,initialize:function(a){this.regExes= | |
2436 {trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g,kmlColor:/(\w{2})(\w{2})(\w{2})(\w{2})/,kmlIconPalette:/root:\/\/icons\/palette-(\d+)(\.\w+)/,straightBracket:/\$\[(.*?)\]/g};this.externalProjection=new OpenLayers.Projection("EPSG:4326");OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},read:function(a){this.features=[];this.styles={};this.fetched={};return this.parseData(a,{depth:0,styleBaseUrl:this.styleBaseUrl})},parseData:function(a,b){"string"==typeof a&& | |
2437 (a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));for(var c=["Link","NetworkLink","Style","StyleMap","Placemark"],d=0,e=c.length;d<e;++d){var f=c[d],g=this.getElementsByTagNameNS(a,"*",f);if(0!=g.length)switch(f.toLowerCase()){case "link":case "networklink":this.parseLinks(g,b);break;case "style":this.extractStyles&&this.parseStyles(g,b);break;case "stylemap":this.extractStyles&&this.parseStyleMaps(g,b);break;case "placemark":this.parseFeatures(g,b)}}return this.features},parseLinks:function(a, | |
2438 b){if(b.depth>=this.maxDepth)return!1;var c=OpenLayers.Util.extend({},b);c.depth++;for(var d=0,e=a.length;d<e;d++){var f=this.parseProperty(a[d],"*","href");f&&!this.fetched[f]&&(this.fetched[f]=!0,(f=this.fetchLink(f))&&this.parseData(f,c))}},fetchLink:function(a){if(a=OpenLayers.Request.GET({url:a,async:!1}))return a.responseText},parseStyles:function(a,b){for(var c=0,d=a.length;c<d;c++){var e=this.parseStyle(a[c]);e&&(this.styles[(b.styleBaseUrl||"")+"#"+e.id]=e)}},parseKmlColor:function(a){var b= | |
2439 null;a&&(a=a.match(this.regExes.kmlColor))&&(b={color:"#"+a[4]+a[3]+a[2],opacity:parseInt(a[1],16)/255});return b},parseStyle:function(a){for(var b={},c=["LineStyle","PolyStyle","IconStyle","BalloonStyle","LabelStyle"],d,e,f=0,g=c.length;f<g;++f)if(d=c[f],e=this.getElementsByTagNameNS(a,"*",d)[0])switch(d.toLowerCase()){case "linestyle":d=this.parseProperty(e,"*","color");if(d=this.parseKmlColor(d))b.strokeColor=d.color,b.strokeOpacity=d.opacity;(d=this.parseProperty(e,"*","width"))&&(b.strokeWidth= | |
2440 d);break;case "polystyle":d=this.parseProperty(e,"*","color");if(d=this.parseKmlColor(d))b.fillOpacity=d.opacity,b.fillColor=d.color;"0"==this.parseProperty(e,"*","fill")&&(b.fillColor="none");"0"==this.parseProperty(e,"*","outline")&&(b.strokeWidth="0");break;case "iconstyle":var h=parseFloat(this.parseProperty(e,"*","scale")||1);d=32*h;var k=32*h,l=this.getElementsByTagNameNS(e,"*","Icon")[0];if(l){var m=this.parseProperty(l,"*","href");if(m){var n=this.parseProperty(l,"*","w"),p=this.parseProperty(l, | |
2441 "*","h");!OpenLayers.String.startsWith(m,"http://maps.google.com/mapfiles/kml")||(n||p)||(p=n=64,h/=2);n=n||p;p=p||n;n&&(d=parseInt(n)*h);p&&(k=parseInt(p)*h);if(p=m.match(this.regExes.kmlIconPalette))n=p[1],p=p[2],m=this.parseProperty(l,"*","x"),l=this.parseProperty(l,"*","y"),m="http://maps.google.com/mapfiles/kml/pal"+n+"/icon"+(8*(l?7-l/32:7)+(m?m/32:0))+p;b.graphicOpacity=1;b.externalGraphic=m}}if(e=this.getElementsByTagNameNS(e,"*","hotSpot")[0])m=parseFloat(e.getAttribute("x")),l=parseFloat(e.getAttribute("y")), | |
2442 n=e.getAttribute("xunits"),"pixels"==n?b.graphicXOffset=-m*h:"insetPixels"==n?b.graphicXOffset=-d+m*h:"fraction"==n&&(b.graphicXOffset=-d*m),e=e.getAttribute("yunits"),"pixels"==e?b.graphicYOffset=-k+l*h+1:"insetPixels"==e?b.graphicYOffset=-(l*h)+1:"fraction"==e&&(b.graphicYOffset=-k*(1-l)+1);b.graphicWidth=d;b.graphicHeight=k;break;case "balloonstyle":(e=OpenLayers.Util.getXmlNodeValue(e))&&(b.balloonStyle=e.replace(this.regExes.straightBracket,"${$1}"));break;case "labelstyle":if(d=this.parseProperty(e, | |
2443 "*","color"),d=this.parseKmlColor(d))b.fontColor=d.color,b.fontOpacity=d.opacity}!b.strokeColor&&b.fillColor&&(b.strokeColor=b.fillColor);(a=a.getAttribute("id"))&&b&&(b.id=a);return b},parseStyleMaps:function(a,b){for(var c=0,d=a.length;c<d;c++)for(var e=a[c],f=this.getElementsByTagNameNS(e,"*","Pair"),e=e.getAttribute("id"),g=0,h=f.length;g<h;g++){var k=f[g],l=this.parseProperty(k,"*","key");(k=this.parseProperty(k,"*","styleUrl"))&&"normal"==l&&(this.styles[(b.styleBaseUrl||"")+"#"+e]=this.styles[(b.styleBaseUrl|| | |
2444 "")+k])}},parseFeatures:function(a,b){for(var c=[],d=0,e=a.length;d<e;d++){var f=a[d],g=this.parseFeature.apply(this,[f]);if(g){this.extractStyles&&(g.attributes&&g.attributes.styleUrl)&&(g.style=this.getStyle(g.attributes.styleUrl,b));if(this.extractStyles){var h=this.getElementsByTagNameNS(f,"*","Style")[0];h&&(h=this.parseStyle(h))&&(g.style=OpenLayers.Util.extend(g.style,h))}this.extractTracks?(f=this.getElementsByTagNameNS(f,this.namespaces.gx,"Track"))&&0<f.length&&(g={features:[],feature:g}, | |
2445 this.readNode(f[0],g),0<g.features.length&&c.push.apply(c,g.features)):c.push(g)}else throw"Bad Placemark: "+d;}this.features=this.features.concat(c)},readers:{kml:{when:function(a,b){b.whens.push(OpenLayers.Date.parse(this.getChildValue(a)))},_trackPointAttribute:function(a,b){var c=a.nodeName.split(":").pop();b.attributes[c].push(this.getChildValue(a))}},gx:{Track:function(a,b){var c={whens:[],points:[],angles:[]};if(this.trackAttributes){var d;c.attributes={};for(var e=0,f=this.trackAttributes.length;e< | |
2446 f;++e)d=this.trackAttributes[e],c.attributes[d]=[],d in this.readers.kml||(this.readers.kml[d]=this.readers.kml._trackPointAttribute)}this.readChildNodes(a,c);if(c.whens.length!==c.points.length)throw Error("gx:Track with unequal number of when ("+c.whens.length+") and gx:coord ("+c.points.length+") elements.");var g=0<c.angles.length;if(g&&c.whens.length!==c.angles.length)throw Error("gx:Track with unequal number of when ("+c.whens.length+") and gx:angles ("+c.angles.length+") elements.");for(var h, | |
2447 e=0,f=c.whens.length;e<f;++e){h=b.feature.clone();h.fid=b.feature.fid||b.feature.id;d=c.points[e];h.geometry=d;"z"in d&&(h.attributes.altitude=d.z);this.internalProjection&&this.externalProjection&&h.geometry.transform(this.externalProjection,this.internalProjection);if(this.trackAttributes)for(var k=0,l=this.trackAttributes.length;k<l;++k)d=this.trackAttributes[k],h.attributes[d]=c.attributes[d][e];h.attributes.when=c.whens[e];h.attributes.trackId=b.feature.id;g&&(d=c.angles[e],h.attributes.heading= | |
2448 parseFloat(d[0]),h.attributes.tilt=parseFloat(d[1]),h.attributes.roll=parseFloat(d[2]));b.features.push(h)}},coord:function(a,b){var c=this.getChildValue(a).replace(this.regExes.trimSpace,"").split(/\s+/),d=new OpenLayers.Geometry.Point(c[0],c[1]);2<c.length&&(d.z=parseFloat(c[2]));b.points.push(d)},angles:function(a,b){var c=this.getChildValue(a).replace(this.regExes.trimSpace,"").split(/\s+/);b.angles.push(c)}}},parseFeature:function(a){for(var b=["MultiGeometry","Polygon","LineString","Point"], | |
2449 c,d,e,f=0,g=b.length;f<g;++f)if(c=b[f],this.internalns=a.namespaceURI?a.namespaceURI:this.kmlns,d=this.getElementsByTagNameNS(a,this.internalns,c),0<d.length){if(b=this.parseGeometry[c.toLowerCase()])e=b.apply(this,[d[0]]),this.internalProjection&&this.externalProjection&&e.transform(this.externalProjection,this.internalProjection);else throw new TypeError("Unsupported geometry type: "+c);break}var h;this.extractAttributes&&(h=this.parseAttributes(a));c=new OpenLayers.Feature.Vector(e,h);a=a.getAttribute("id")|| | |
2450 a.getAttribute("name");null!=a&&(c.fid=a);return c},getStyle:function(a,b){var c=OpenLayers.Util.removeTail(a),d=OpenLayers.Util.extend({},b);d.depth++;d.styleBaseUrl=c;!this.styles[a]&&!OpenLayers.String.startsWith(a,"#")&&d.depth<=this.maxDepth&&!this.fetched[c]&&(c=this.fetchLink(c))&&this.parseData(c,d);return OpenLayers.Util.extend({},this.styles[a])},parseGeometry:{point:function(a){var b=this.getElementsByTagNameNS(a,this.internalns,"coordinates");a=[];if(0<b.length){var c=b[0].firstChild.nodeValue, | |
2451 c=c.replace(this.regExes.removeSpace,"");a=c.split(",")}b=null;if(1<a.length)2==a.length&&(a[2]=null),b=new OpenLayers.Geometry.Point(a[0],a[1],a[2]);else throw"Bad coordinate string: "+c;return b},linestring:function(a,b){var c=this.getElementsByTagNameNS(a,this.internalns,"coordinates"),d=null;if(0<c.length){for(var c=this.getChildValue(c[0]),c=c.replace(this.regExes.trimSpace,""),c=c.replace(this.regExes.trimComma,","),d=c.split(this.regExes.splitSpace),e=d.length,f=Array(e),g,h,k=0;k<e;++k)if(g= | |
2452 d[k].split(","),h=g.length,1<h)2==g.length&&(g[2]=null),f[k]=new OpenLayers.Geometry.Point(g[0],g[1],g[2]);else throw"Bad LineString point coordinates: "+d[k];if(e)d=b?new OpenLayers.Geometry.LinearRing(f):new OpenLayers.Geometry.LineString(f);else throw"Bad LineString coordinates: "+c;}return d},polygon:function(a){a=this.getElementsByTagNameNS(a,this.internalns,"LinearRing");var b=a.length,c=Array(b);if(0<b)for(var d=0,e=a.length;d<e;++d)if(b=this.parseGeometry.linestring.apply(this,[a[d],!0]))c[d]= | |
2453 b;else throw"Bad LinearRing geometry: "+d;return new OpenLayers.Geometry.Polygon(c)},multigeometry:function(a){for(var b,c=[],d=a.childNodes,e=0,f=d.length;e<f;++e)a=d[e],1==a.nodeType&&(b=a.prefix?a.nodeName.split(":")[1]:a.nodeName,(b=this.parseGeometry[b.toLowerCase()])&&c.push(b.apply(this,[a])));return new OpenLayers.Geometry.Collection(c)}},parseAttributes:function(a){var b={},c=a.getElementsByTagName("ExtendedData");c.length&&(b=this.parseExtendedData(c[0]));var d,e,f;a=a.childNodes;for(var c= | |
2454 0,g=a.length;c<g;++c)if(d=a[c],1==d.nodeType&&(e=d.childNodes,1<=e.length&&3>=e.length)){switch(e.length){case 1:f=e[0];break;case 2:f=e[0];e=e[1];f=3==f.nodeType||4==f.nodeType?f:e;break;default:f=e[1]}if(3==f.nodeType||4==f.nodeType)if(d=d.prefix?d.nodeName.split(":")[1]:d.nodeName,f=OpenLayers.Util.getXmlNodeValue(f))f=f.replace(this.regExes.trimSpace,""),b[d]=f}return b},parseExtendedData:function(a){var b={},c,d,e,f,g=a.getElementsByTagName("Data");c=0;for(d=g.length;c<d;c++){e=g[c];f=e.getAttribute("name"); | |
2455 var h={},k=e.getElementsByTagName("value");k.length&&(h.value=this.getChildValue(k[0]));this.kvpAttributes?b[f]=h.value:(e=e.getElementsByTagName("displayName"),e.length&&(h.displayName=this.getChildValue(e[0])),b[f]=h)}a=a.getElementsByTagName("SimpleData");c=0;for(d=a.length;c<d;c++)h={},e=a[c],f=e.getAttribute("name"),h.value=this.getChildValue(e),this.kvpAttributes?b[f]=h.value:(h.displayName=f,b[f]=h);return b},parseProperty:function(a,b,c){var d;a=this.getElementsByTagNameNS(a,b,c);try{d=OpenLayers.Util.getXmlNodeValue(a[0])}catch(e){d= | |
2456 null}return d},write:function(a){OpenLayers.Util.isArray(a)||(a=[a]);for(var b=this.createElementNS(this.kmlns,"kml"),c=this.createFolderXML(),d=0,e=a.length;d<e;++d)c.appendChild(this.createPlacemarkXML(a[d]));b.appendChild(c);return OpenLayers.Format.XML.prototype.write.apply(this,[b])},createFolderXML:function(){var a=this.createElementNS(this.kmlns,"Folder");if(this.foldersName){var b=this.createElementNS(this.kmlns,"name"),c=this.createTextNode(this.foldersName);b.appendChild(c);a.appendChild(b)}this.foldersDesc&& | |
2457 (b=this.createElementNS(this.kmlns,"description"),c=this.createTextNode(this.foldersDesc),b.appendChild(c),a.appendChild(b));return a},createPlacemarkXML:function(a){var b=this.createElementNS(this.kmlns,"name"),c=a.style&&a.style.label?a.style.label:a.id;b.appendChild(this.createTextNode(a.attributes.name||c));var d=this.createElementNS(this.kmlns,"description");d.appendChild(this.createTextNode(a.attributes.description||this.placemarksDesc));c=this.createElementNS(this.kmlns,"Placemark");null!= | |
2458 a.fid&&c.setAttribute("id",a.fid);c.appendChild(b);c.appendChild(d);b=this.buildGeometryNode(a.geometry);c.appendChild(b);a.attributes&&(a=this.buildExtendedData(a.attributes))&&c.appendChild(a);return c},buildGeometryNode:function(a){var b=a.CLASS_NAME,b=b.substring(b.lastIndexOf(".")+1),b=this.buildGeometry[b.toLowerCase()],c=null;b&&(c=b.apply(this,[a]));return c},buildGeometry:{point:function(a){var b=this.createElementNS(this.kmlns,"Point");b.appendChild(this.buildCoordinatesNode(a));return b}, | |
2459 multipoint:function(a){return this.buildGeometry.collection.apply(this,[a])},linestring:function(a){var b=this.createElementNS(this.kmlns,"LineString");b.appendChild(this.buildCoordinatesNode(a));return b},multilinestring:function(a){return this.buildGeometry.collection.apply(this,[a])},linearring:function(a){var b=this.createElementNS(this.kmlns,"LinearRing");b.appendChild(this.buildCoordinatesNode(a));return b},polygon:function(a){var b=this.createElementNS(this.kmlns,"Polygon");a=a.components; | |
2460 for(var c,d,e=0,f=a.length;e<f;++e)c=0==e?"outerBoundaryIs":"innerBoundaryIs",c=this.createElementNS(this.kmlns,c),d=this.buildGeometry.linearring.apply(this,[a[e]]),c.appendChild(d),b.appendChild(c);return b},multipolygon:function(a){return this.buildGeometry.collection.apply(this,[a])},collection:function(a){for(var b=this.createElementNS(this.kmlns,"MultiGeometry"),c,d=0,e=a.components.length;d<e;++d)(c=this.buildGeometryNode.apply(this,[a.components[d]]))&&b.appendChild(c);return b}},buildCoordinatesNode:function(a){var b= | |
2461 this.createElementNS(this.kmlns,"coordinates"),c;if(c=a.components){for(var d=c.length,e=Array(d),f=0;f<d;++f)a=c[f],e[f]=this.buildCoordinates(a);c=e.join(" ")}else c=this.buildCoordinates(a);c=this.createTextNode(c);b.appendChild(c);return b},buildCoordinates:function(a){this.internalProjection&&this.externalProjection&&(a=a.clone(),a.transform(this.internalProjection,this.externalProjection));return a.x+","+a.y},buildExtendedData:function(a){var b=this.createElementNS(this.kmlns,"ExtendedData"), | |
2462 c;for(c in a)if(a[c]&&"name"!=c&&"description"!=c&&"styleUrl"!=c){var d=this.createElementNS(this.kmlns,"Data");d.setAttribute("name",c);var e=this.createElementNS(this.kmlns,"value");if("object"==typeof a[c]){if(a[c].value&&e.appendChild(this.createTextNode(a[c].value)),a[c].displayName){var f=this.createElementNS(this.kmlns,"displayName");f.appendChild(this.getXMLDoc().createCDATASection(a[c].displayName));d.appendChild(f)}}else e.appendChild(this.createTextNode(a[c]));d.appendChild(e);b.appendChild(d)}return this.isSimpleContent(b)? | |
2463 null:b},CLASS_NAME:"OpenLayers.Format.KML"});OpenLayers.Format.WMSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.1.1",profile:null,CLASS_NAME:"OpenLayers.Format.WMSCapabilities"});OpenLayers.Format.WMSCapabilities.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{wms:"http://www.opengis.net/wms",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"wms",read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b=a;a&&9==a.nodeType&&(a=a.documentElement);var c={};this.readNode(a,c);void 0===c.service&&(a=new OpenLayers.Format.OGCExceptionReport,c.error=a.read(b));return c},readers:{wms:{Service:function(a, | |
2464 b){b.service={};this.readChildNodes(a,b.service)},Name:function(a,b){b.name=this.getChildValue(a)},Title:function(a,b){b.title=this.getChildValue(a)},Abstract:function(a,b){b["abstract"]=this.getChildValue(a)},BoundingBox:function(a,b){var c={};c.bbox=[parseFloat(a.getAttribute("minx")),parseFloat(a.getAttribute("miny")),parseFloat(a.getAttribute("maxx")),parseFloat(a.getAttribute("maxy"))];var d={x:parseFloat(a.getAttribute("resx")),y:parseFloat(a.getAttribute("resy"))};isNaN(d.x)&&isNaN(d.y)||(c.res= | |
2465 d);return c},OnlineResource:function(a,b){b.href=this.getAttributeNS(a,this.namespaces.xlink,"href")},ContactInformation:function(a,b){b.contactInformation={};this.readChildNodes(a,b.contactInformation)},ContactPersonPrimary:function(a,b){b.personPrimary={};this.readChildNodes(a,b.personPrimary)},ContactPerson:function(a,b){b.person=this.getChildValue(a)},ContactOrganization:function(a,b){b.organization=this.getChildValue(a)},ContactPosition:function(a,b){b.position=this.getChildValue(a)},ContactAddress:function(a, | |
2466 b){b.contactAddress={};this.readChildNodes(a,b.contactAddress)},AddressType:function(a,b){b.type=this.getChildValue(a)},Address:function(a,b){b.address=this.getChildValue(a)},City:function(a,b){b.city=this.getChildValue(a)},StateOrProvince:function(a,b){b.stateOrProvince=this.getChildValue(a)},PostCode:function(a,b){b.postcode=this.getChildValue(a)},Country:function(a,b){b.country=this.getChildValue(a)},ContactVoiceTelephone:function(a,b){b.phone=this.getChildValue(a)},ContactFacsimileTelephone:function(a, | |
2467 b){b.fax=this.getChildValue(a)},ContactElectronicMailAddress:function(a,b){b.email=this.getChildValue(a)},Fees:function(a,b){var c=this.getChildValue(a);c&&"none"!=c.toLowerCase()&&(b.fees=c)},AccessConstraints:function(a,b){var c=this.getChildValue(a);c&&"none"!=c.toLowerCase()&&(b.accessConstraints=c)},Capability:function(a,b){b.capability={nestedLayers:[],layers:[]};this.readChildNodes(a,b.capability)},Request:function(a,b){b.request={};this.readChildNodes(a,b.request)},GetCapabilities:function(a, | |
2468 b){b.getcapabilities={formats:[]};this.readChildNodes(a,b.getcapabilities)},Format:function(a,b){OpenLayers.Util.isArray(b.formats)?b.formats.push(this.getChildValue(a)):b.format=this.getChildValue(a)},DCPType:function(a,b){this.readChildNodes(a,b)},HTTP:function(a,b){this.readChildNodes(a,b)},Get:function(a,b){b.get={};this.readChildNodes(a,b.get);b.href||(b.href=b.get.href)},Post:function(a,b){b.post={};this.readChildNodes(a,b.post);b.href||(b.href=b.get.href)},GetMap:function(a,b){b.getmap={formats:[]}; | |
2469 this.readChildNodes(a,b.getmap)},GetFeatureInfo:function(a,b){b.getfeatureinfo={formats:[]};this.readChildNodes(a,b.getfeatureinfo)},Exception:function(a,b){b.exception={formats:[]};this.readChildNodes(a,b.exception)},Layer:function(a,b){var c,d;b.capability?(d=b.capability,c=b):d=b;var e=a.getAttributeNode("queryable"),f=e&&e.specified?a.getAttribute("queryable"):null,g=(e=a.getAttributeNode("cascaded"))&&e.specified?a.getAttribute("cascaded"):null,e=(e=a.getAttributeNode("opaque"))&&e.specified? | |
2470 a.getAttribute("opaque"):null,h=a.getAttribute("noSubsets"),k=a.getAttribute("fixedWidth"),l=a.getAttribute("fixedHeight"),m=c||{},n=OpenLayers.Util.extend;c={nestedLayers:[],styles:c?[].concat(c.styles):[],srs:c?n({},m.srs):{},metadataURLs:[],bbox:c?n({},m.bbox):{},llbbox:m.llbbox,dimensions:c?n({},m.dimensions):{},authorityURLs:c?n({},m.authorityURLs):{},identifiers:{},keywords:[],queryable:f&&""!==f?"1"===f||"true"===f:m.queryable||!1,cascaded:null!==g?parseInt(g):m.cascaded||0,opaque:e?"1"=== | |
2471 e||"true"===e:m.opaque||!1,noSubsets:null!==h?"1"===h||"true"===h:m.noSubsets||!1,fixedWidth:null!=k?parseInt(k):m.fixedWidth||0,fixedHeight:null!=l?parseInt(l):m.fixedHeight||0,minScale:m.minScale,maxScale:m.maxScale,attribution:m.attribution};b.nestedLayers.push(c);c.capability=d;this.readChildNodes(a,c);delete c.capability;c.name&&(f=c.name.split(":"),g=d.request,e=g.getfeatureinfo,0<f.length&&(c.prefix=f[0]),d.layers.push(c),void 0===c.formats&&(c.formats=g.getmap.formats),void 0===c.infoFormats&& | |
2472 e&&(c.infoFormats=e.formats))},Attribution:function(a,b){b.attribution={};this.readChildNodes(a,b.attribution)},LogoURL:function(a,b){b.logo={width:a.getAttribute("width"),height:a.getAttribute("height")};this.readChildNodes(a,b.logo)},Style:function(a,b){var c={};b.styles.push(c);this.readChildNodes(a,c)},LegendURL:function(a,b){var c={width:a.getAttribute("width"),height:a.getAttribute("height")};b.legend=c;this.readChildNodes(a,c)},MetadataURL:function(a,b){var c={type:a.getAttribute("type")}; | |
2473 b.metadataURLs.push(c);this.readChildNodes(a,c)},DataURL:function(a,b){b.dataURL={};this.readChildNodes(a,b.dataURL)},FeatureListURL:function(a,b){b.featureListURL={};this.readChildNodes(a,b.featureListURL)},AuthorityURL:function(a,b){var c=a.getAttribute("name"),d={};this.readChildNodes(a,d);b.authorityURLs[c]=d.href},Identifier:function(a,b){var c=a.getAttribute("authority");b.identifiers[c]=this.getChildValue(a)},KeywordList:function(a,b){this.readChildNodes(a,b)},SRS:function(a,b){b.srs[this.getChildValue(a)]= | |
2474 !0}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1"});OpenLayers.Format.WMSCapabilities.v1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{wms:OpenLayers.Util.applyDefaults({WMT_MS_Capabilities:function(a,b){this.readChildNodes(a,b)},Keyword:function(a,b){b.keywords&&b.keywords.push(this.getChildValue(a))},DescribeLayer:function(a,b){b.describelayer={formats:[]};this.readChildNodes(a,b.describelayer)},GetLegendGraphic:function(a,b){b.getlegendgraphic={formats:[]};this.readChildNodes(a,b.getlegendgraphic)},GetStyles:function(a,b){b.getstyles= | |
2475 {formats:[]};this.readChildNodes(a,b.getstyles)},PutStyles:function(a,b){b.putstyles={formats:[]};this.readChildNodes(a,b.putstyles)},UserDefinedSymbolization:function(a,b){var c={supportSLD:1==parseInt(a.getAttribute("SupportSLD")),userLayer:1==parseInt(a.getAttribute("UserLayer")),userStyle:1==parseInt(a.getAttribute("UserStyle")),remoteWFS:1==parseInt(a.getAttribute("RemoteWFS"))};b.userSymbols=c},LatLonBoundingBox:function(a,b){b.llbbox=[parseFloat(a.getAttribute("minx")),parseFloat(a.getAttribute("miny")), | |
2476 parseFloat(a.getAttribute("maxx")),parseFloat(a.getAttribute("maxy"))]},BoundingBox:function(a,b){var c=OpenLayers.Format.WMSCapabilities.v1.prototype.readers.wms.BoundingBox.apply(this,[a,b]);c.srs=a.getAttribute("SRS");b.bbox[c.srs]=c},ScaleHint:function(a,b){var c=a.getAttribute("min"),d=a.getAttribute("max"),e=Math.pow(2,0.5),f=OpenLayers.INCHES_PER_UNIT.m;0!=c&&(b.maxScale=parseFloat((c/e*f*OpenLayers.DOTS_PER_INCH).toPrecision(13)));d!=Number.POSITIVE_INFINITY&&(b.minScale=parseFloat((d/e*f* | |
2477 OpenLayers.DOTS_PER_INCH).toPrecision(13)))},Dimension:function(a,b){var c={name:a.getAttribute("name").toLowerCase(),units:a.getAttribute("units"),unitsymbol:a.getAttribute("unitSymbol")};b.dimensions[c.name]=c},Extent:function(a,b){var c=a.getAttribute("name").toLowerCase();if(c in b.dimensions){c=b.dimensions[c];c.nearestVal="1"===a.getAttribute("nearestValue");c.multipleVal="1"===a.getAttribute("multipleValues");c.current="1"===a.getAttribute("current");c["default"]=a.getAttribute("default")|| | |
2478 "";var d=this.getChildValue(a);c.values=d.split(",")}}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers.wms)},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1"});OpenLayers.Format.WMSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.0",readers:{wms:OpenLayers.Util.applyDefaults({SRS:function(a,b){for(var c=this.getChildValue(a).split(/ +/),d=0,e=c.length;d<e;d++)b.srs[c[d]]=!0}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers.wms)},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_0"});OpenLayers.Protocol.WFS.v1=OpenLayers.Class(OpenLayers.Protocol,{version:null,srsName:"EPSG:4326",featureType:null,featureNS:null,geometryName:"the_geom",schema:null,featurePrefix:"feature",formatOptions:null,readFormat:null,readOptions:null,initialize:function(a){OpenLayers.Protocol.prototype.initialize.apply(this,[a]);a.format||(this.format=OpenLayers.Format.WFST(OpenLayers.Util.extend({version:this.version,featureType:this.featureType,featureNS:this.featureNS,featurePrefix:this.featurePrefix,geometryName:this.geometryName, | |
2479 srsName:this.srsName,schema:this.schema},this.formatOptions)));!a.geometryName&&1<parseFloat(this.format.version)&&this.setGeometryName(null)},destroy:function(){this.options&&!this.options.format&&this.format.destroy();this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this)},read:function(a){OpenLayers.Protocol.prototype.read.apply(this,arguments);a=OpenLayers.Util.extend({},a);OpenLayers.Util.applyDefaults(a,this.options||{});var b=new OpenLayers.Protocol.Response({requestType:"read"}), | |
2480 c=OpenLayers.Format.XML.prototype.write.apply(this.format,[this.format.writeNode("wfs:GetFeature",a)]);b.priv=OpenLayers.Request.POST({url:a.url,callback:this.createCallback(this.handleRead,b,a),params:a.params,headers:a.headers,data:c});return b},setFeatureType:function(a){this.featureType=a;this.format.featureType=a},setGeometryName:function(a){this.geometryName=a;this.format.geometryName=a},handleRead:function(a,b){b=OpenLayers.Util.extend({},b);OpenLayers.Util.applyDefaults(b,this.options);if(b.callback){var c= | |
2481 a.priv;200<=c.status&&300>c.status?(c=this.parseResponse(c,b.readOptions))&&!1!==c.success?(b.readOptions&&"object"==b.readOptions.output?OpenLayers.Util.extend(a,c):a.features=c,a.code=OpenLayers.Protocol.Response.SUCCESS):(a.code=OpenLayers.Protocol.Response.FAILURE,a.error=c):a.code=OpenLayers.Protocol.Response.FAILURE;b.callback.call(b.scope,a)}},parseResponse:function(a,b){var c=a.responseXML;c&&c.documentElement||(c=a.responseText);if(!c||0>=c.length)return null;c=null!==this.readFormat?this.readFormat.read(c): | |
2482 this.format.read(c,b);if(!this.featureNS){var d=this.readFormat||this.format;this.featureNS=d.featureNS;d.autoConfig=!1;this.geometryName||this.setGeometryName(d.geometryName)}return c},commit:function(a,b){b=OpenLayers.Util.extend({},b);OpenLayers.Util.applyDefaults(b,this.options);var c=new OpenLayers.Protocol.Response({requestType:"commit",reqFeatures:a});c.priv=OpenLayers.Request.POST({url:b.url,headers:b.headers,data:this.format.write(a,b),callback:this.createCallback(this.handleCommit,c,b)}); | |
2483 return c},handleCommit:function(a,b){if(b.callback){var c=a.priv,d=c.responseXML;d&&d.documentElement||(d=c.responseText);c=this.format.read(d)||{};a.insertIds=c.insertIds||[];c.success?a.code=OpenLayers.Protocol.Response.SUCCESS:(a.code=OpenLayers.Protocol.Response.FAILURE,a.error=c);b.callback.call(b.scope,a)}},filterDelete:function(a,b){b=OpenLayers.Util.extend({},b);OpenLayers.Util.applyDefaults(b,this.options);new OpenLayers.Protocol.Response({requestType:"commit"});var c=this.format.createElementNSPlus("wfs:Transaction", | |
2484 {attributes:{service:"WFS",version:this.version}}),d=this.format.createElementNSPlus("wfs:Delete",{attributes:{typeName:(b.featureNS?this.featurePrefix+":":"")+b.featureType}});b.featureNS&&d.setAttribute("xmlns:"+this.featurePrefix,b.featureNS);var e=this.format.writeNode("ogc:Filter",a);d.appendChild(e);c.appendChild(d);c=OpenLayers.Format.XML.prototype.write.apply(this.format,[c]);return OpenLayers.Request.POST({url:this.url,callback:b.callback||function(){},data:c})},abort:function(a){a&&a.priv.abort()}, | |
2485 CLASS_NAME:"OpenLayers.Protocol.WFS.v1"});OpenLayers.Handler.Feature=OpenLayers.Class(OpenLayers.Handler,{EVENTMAP:{click:{"in":"click",out:"clickout"},mousemove:{"in":"over",out:"out"},dblclick:{"in":"dblclick",out:null},mousedown:{"in":null,out:null},mouseup:{"in":null,out:null},touchstart:{"in":"click",out:"clickout"}},feature:null,lastFeature:null,down:null,up:null,clickTolerance:4,geometryTypes:null,stopClick:!0,stopDown:!0,stopUp:!1,initialize:function(a,b,c,d){OpenLayers.Handler.prototype.initialize.apply(this,[a,c,d]);this.layer= | |
2486 b},touchstart:function(a){this.startTouch();return OpenLayers.Event.isMultiTouch(a)?!0:this.mousedown(a)},touchmove:function(a){OpenLayers.Event.preventDefault(a)},mousedown:function(a){if(OpenLayers.Event.isLeftClick(a)||OpenLayers.Event.isSingleTouch(a))this.down=a.xy;return this.handle(a)?!this.stopDown:!0},mouseup:function(a){this.up=a.xy;return this.handle(a)?!this.stopUp:!0},click:function(a){return this.handle(a)?!this.stopClick:!0},mousemove:function(a){if(!this.callbacks.over&&!this.callbacks.out)return!0; | |
2487 this.handle(a);return!0},dblclick:function(a){return!this.handle(a)},geometryTypeMatches:function(a){return null==this.geometryTypes||-1<OpenLayers.Util.indexOf(this.geometryTypes,a.geometry.CLASS_NAME)},handle:function(a){this.feature&&!this.feature.layer&&(this.feature=null);var b=a.type,c=!1,d=!!this.feature,e="click"==b||"dblclick"==b||"touchstart"==b;(this.feature=this.layer.getFeatureFromEvent(a))&&!this.feature.layer&&(this.feature=null);this.lastFeature&&!this.lastFeature.layer&&(this.lastFeature= | |
2488 null);this.feature?("touchstart"===b&&OpenLayers.Event.preventDefault(a),a=this.feature!=this.lastFeature,this.geometryTypeMatches(this.feature)?(d&&a?(this.lastFeature&&this.triggerCallback(b,"out",[this.lastFeature]),this.triggerCallback(b,"in",[this.feature])):d&&!e||this.triggerCallback(b,"in",[this.feature]),this.lastFeature=this.feature,c=!0):(this.lastFeature&&(d&&a||e)&&this.triggerCallback(b,"out",[this.lastFeature]),this.feature=null)):this.lastFeature&&(d||e)&&this.triggerCallback(b,"out", | |
2489 [this.lastFeature]);return c},triggerCallback:function(a,b,c){if(b=this.EVENTMAP[a][b])"click"==a&&this.up&&this.down?(Math.sqrt(Math.pow(this.up.x-this.down.x,2)+Math.pow(this.up.y-this.down.y,2))<=this.clickTolerance&&this.callback(b,c),this.up=this.down=null):this.callback(b,c)},activate:function(){var a=!1;OpenLayers.Handler.prototype.activate.apply(this,arguments)&&(this.moveLayerToTop(),this.map.events.on({removelayer:this.handleMapEvents,changelayer:this.handleMapEvents,scope:this}),a=!0); | |
2490 return a},deactivate:function(){var a=!1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.moveLayerBack(),this.up=this.down=this.lastFeature=this.feature=null,this.map.events.un({removelayer:this.handleMapEvents,changelayer:this.handleMapEvents,scope:this}),a=!0);return a},handleMapEvents:function(a){"removelayer"!=a.type&&"order"!=a.property||this.moveLayerToTop()},moveLayerToTop:function(){var a=Math.max(this.map.Z_INDEX_BASE.Feature-1,this.layer.getZIndex())+1;this.layer.setZIndex(a)}, | |
2491 moveLayerBack:function(){var a=this.layer.getZIndex()-1;a>=this.map.Z_INDEX_BASE.Feature?this.layer.setZIndex(a):this.map.setLayerZIndex(this.layer,this.map.getLayerIndex(this.layer))},CLASS_NAME:"OpenLayers.Handler.Feature"});OpenLayers.Layer.Vector.RootContainer=OpenLayers.Class(OpenLayers.Layer.Vector,{displayInLayerSwitcher:!1,layers:null,display:function(){},getFeatureFromEvent:function(a){for(var b=this.layers,c,d=0;d<b.length;d++)if(c=b[d].getFeatureFromEvent(a))return c},setMap:function(a){OpenLayers.Layer.Vector.prototype.setMap.apply(this,arguments);this.collectRoots();a.events.register("changelayer",this,this.handleChangeLayer)},removeMap:function(a){a.events.unregister("changelayer",this,this.handleChangeLayer); | |
2492 this.resetRoots();OpenLayers.Layer.Vector.prototype.removeMap.apply(this,arguments)},collectRoots:function(){for(var a,b=0;b<this.map.layers.length;++b)a=this.map.layers[b],-1!=OpenLayers.Util.indexOf(this.layers,a)&&a.renderer.moveRoot(this.renderer)},resetRoots:function(){for(var a,b=0;b<this.layers.length;++b)a=this.layers[b],this.renderer&&a.renderer.getRenderLayerId()==this.id&&this.renderer.moveRoot(a.renderer)},handleChangeLayer:function(a){var b=a.layer;"order"==a.property&&-1!=OpenLayers.Util.indexOf(this.layers, | |
2493 b)&&(this.resetRoots(),this.collectRoots())},CLASS_NAME:"OpenLayers.Layer.Vector.RootContainer"});OpenLayers.Control.SelectFeature=OpenLayers.Class(OpenLayers.Control,{multipleKey:null,toggleKey:null,multiple:!1,clickout:!0,toggle:!1,hover:!1,highlightOnly:!1,box:!1,onBeforeSelect:function(){},onSelect:function(){},onUnselect:function(){},scope:null,geometryTypes:null,layer:null,layers:null,callbacks:null,selectStyle:null,renderIntent:"select",handlers:null,initialize:function(a,b){OpenLayers.Control.prototype.initialize.apply(this,[b]);null===this.scope&&(this.scope=this);this.initLayer(a);var c= | |
2494 {click:this.clickFeature,clickout:this.clickoutFeature};this.hover&&(c.over=this.overFeature,c.out=this.outFeature);this.callbacks=OpenLayers.Util.extend(c,this.callbacks);this.handlers={feature:new OpenLayers.Handler.Feature(this,this.layer,this.callbacks,{geometryTypes:this.geometryTypes})};this.box&&(this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},{boxDivClassName:"olHandlerBoxSelectFeature"}))},initLayer:function(a){OpenLayers.Util.isArray(a)?(this.layers=a,this.layer= | |
2495 new OpenLayers.Layer.Vector.RootContainer(this.id+"_container",{layers:a})):this.layer=a},destroy:function(){this.active&&this.layers&&this.map.removeLayer(this.layer);OpenLayers.Control.prototype.destroy.apply(this,arguments);this.layers&&this.layer.destroy()},activate:function(){this.active||(this.layers&&this.map.addLayer(this.layer),this.handlers.feature.activate(),this.box&&this.handlers.box&&this.handlers.box.activate());return OpenLayers.Control.prototype.activate.apply(this,arguments)},deactivate:function(){this.active&& | |
2496 (this.handlers.feature.deactivate(),this.handlers.box&&this.handlers.box.deactivate(),this.layers&&this.map.removeLayer(this.layer));return OpenLayers.Control.prototype.deactivate.apply(this,arguments)},unselectAll:function(a){var b=this.layers||[this.layer],c,d,e,f;for(e=0;e<b.length;++e)if(c=b[e],f=0,null!=c.selectedFeatures)for(;c.selectedFeatures.length>f;)d=c.selectedFeatures[f],a&&a.except==d?++f:this.unselect(d)},clickFeature:function(a){this.hover||(-1<OpenLayers.Util.indexOf(a.layer.selectedFeatures, | |
2497 a)?this.toggleSelect()?this.unselect(a):this.multipleSelect()||this.unselectAll({except:a}):(this.multipleSelect()||this.unselectAll({except:a}),this.select(a)))},multipleSelect:function(){return this.multiple||this.handlers.feature.evt&&this.handlers.feature.evt[this.multipleKey]},toggleSelect:function(){return this.toggle||this.handlers.feature.evt&&this.handlers.feature.evt[this.toggleKey]},clickoutFeature:function(a){!this.hover&&this.clickout&&this.unselectAll()},overFeature:function(a){var b= | |
2498 a.layer;this.hover&&(this.highlightOnly?this.highlight(a):-1==OpenLayers.Util.indexOf(b.selectedFeatures,a)&&this.select(a))},outFeature:function(a){if(this.hover)if(this.highlightOnly){if(a._lastHighlighter==this.id)if(a._prevHighlighter&&a._prevHighlighter!=this.id){delete a._lastHighlighter;var b=this.map.getControl(a._prevHighlighter);b&&b.highlight(a)}else this.unhighlight(a)}else this.unselect(a)},highlight:function(a){var b=a.layer;!1!==this.events.triggerEvent("beforefeaturehighlighted",{feature:a})&& | |
2499 (a._prevHighlighter=a._lastHighlighter,a._lastHighlighter=this.id,b.drawFeature(a,this.selectStyle||this.renderIntent),this.events.triggerEvent("featurehighlighted",{feature:a}))},unhighlight:function(a){var b=a.layer;void 0==a._prevHighlighter?delete a._lastHighlighter:(a._prevHighlighter!=this.id&&(a._lastHighlighter=a._prevHighlighter),delete a._prevHighlighter);b.drawFeature(a,a.style||a.layer.style||"default");this.events.triggerEvent("featureunhighlighted",{feature:a})},select:function(a){var b= | |
2500 this.onBeforeSelect.call(this.scope,a),c=a.layer;!1!==b&&(b=c.events.triggerEvent("beforefeatureselected",{feature:a}),!1!==b&&(c.selectedFeatures.push(a),this.highlight(a),this.handlers.feature.lastFeature||(this.handlers.feature.lastFeature=c.selectedFeatures[0]),c.events.triggerEvent("featureselected",{feature:a}),this.onSelect.call(this.scope,a)))},unselect:function(a){var b=a.layer;this.unhighlight(a);OpenLayers.Util.removeItem(b.selectedFeatures,a);b.events.triggerEvent("featureunselected", | |
2501 {feature:a});this.onUnselect.call(this.scope,a)},selectBox:function(a){if(a instanceof OpenLayers.Bounds){var b=this.map.getLonLatFromPixel({x:a.left,y:a.bottom});a=this.map.getLonLatFromPixel({x:a.right,y:a.top});b=new OpenLayers.Bounds(b.lon,b.lat,a.lon,a.lat);this.multipleSelect()||this.unselectAll();a=this.multiple;this.multiple=!0;var c=this.layers||[this.layer];this.events.triggerEvent("boxselectionstart",{layers:c});for(var d,e=0;e<c.length;++e){d=c[e];for(var f=0,g=d.features.length;f<g;++f){var h= | |
2502 d.features[f];h.getVisibility()&&(null==this.geometryTypes||-1<OpenLayers.Util.indexOf(this.geometryTypes,h.geometry.CLASS_NAME))&&b.toGeometry().intersects(h.geometry)&&-1==OpenLayers.Util.indexOf(d.selectedFeatures,h)&&this.select(h)}}this.multiple=a;this.events.triggerEvent("boxselectionend",{layers:c})}},setMap:function(a){this.handlers.feature.setMap(a);this.box&&this.handlers.box.setMap(a);OpenLayers.Control.prototype.setMap.apply(this,arguments)},setLayer:function(a){var b=this.active;this.unselectAll(); | |
2503 this.deactivate();this.layers&&(this.layer.destroy(),this.layers=null);this.initLayer(a);this.handlers.feature.layer=this.layer;b&&this.activate()},CLASS_NAME:"OpenLayers.Control.SelectFeature"});OpenLayers.Handler.Point=OpenLayers.Class(OpenLayers.Handler,{point:null,layer:null,multi:!1,citeCompliant:!1,mouseDown:!1,stoppedDown:null,lastDown:null,lastUp:null,persist:!1,stopDown:!1,stopUp:!1,layerOptions:null,pixelTolerance:5,lastTouchPx:null,initialize:function(a,b,c){c&&c.layerOptions&&c.layerOptions.styleMap||(this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style["default"],{}));OpenLayers.Handler.prototype.initialize.apply(this,arguments)},activate:function(){if(!OpenLayers.Handler.prototype.activate.apply(this, | |
2504 arguments))return!1;var a=OpenLayers.Util.extend({displayInLayerSwitcher:!1,calculateInRange:OpenLayers.Function.True,wrapDateLine:this.citeCompliant},this.layerOptions);this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,a);this.map.addLayer(this.layer);return!0},createFeature:function(a){a=this.layer.getLonLatFromViewPortPx(a);a=new OpenLayers.Geometry.Point(a.lon,a.lat);this.point=new OpenLayers.Feature.Vector(a);this.callback("create",[this.point.geometry,this.point]);this.point.geometry.clearBounds(); | |
2505 this.layer.addFeatures([this.point],{silent:!0})},deactivate:function(){if(!OpenLayers.Handler.prototype.deactivate.apply(this,arguments))return!1;this.cancel();null!=this.layer.map&&(this.destroyFeature(!0),this.layer.destroy(!1));this.layer=null;return!0},destroyFeature:function(a){!this.layer||!a&&this.persist||this.layer.destroyFeatures();this.point=null},destroyPersistedFeature:function(){var a=this.layer;a&&1<a.features.length&&this.layer.features[0].destroy()},finalize:function(a){this.mouseDown= | |
2506 !1;this.lastTouchPx=this.lastUp=this.lastDown=null;this.callback(a?"cancel":"done",[this.geometryClone()]);this.destroyFeature(a)},cancel:function(){this.finalize(!0)},click:function(a){OpenLayers.Event.stop(a);return!1},dblclick:function(a){OpenLayers.Event.stop(a);return!1},modifyFeature:function(a){this.point||this.createFeature(a);a=this.layer.getLonLatFromViewPortPx(a);this.point.geometry.x=a.lon;this.point.geometry.y=a.lat;this.callback("modify",[this.point.geometry,this.point,!1]);this.point.geometry.clearBounds(); | |
2507 this.drawFeature()},drawFeature:function(){this.layer.drawFeature(this.point,this.style)},getGeometry:function(){var a=this.point&&this.point.geometry;a&&this.multi&&(a=new OpenLayers.Geometry.MultiPoint([a]));return a},geometryClone:function(){var a=this.getGeometry();return a&&a.clone()},mousedown:function(a){return this.down(a)},touchstart:function(a){this.startTouch();this.lastTouchPx=a.xy;return this.down(a)},mousemove:function(a){return this.move(a)},touchmove:function(a){this.lastTouchPx=a.xy; | |
2508 return this.move(a)},mouseup:function(a){return this.up(a)},touchend:function(a){a.xy=this.lastTouchPx;return this.up(a)},down:function(a){this.mouseDown=!0;this.lastDown=a.xy;this.touch||this.modifyFeature(a.xy);this.stoppedDown=this.stopDown;return!this.stopDown},move:function(a){this.touch||this.mouseDown&&!this.stoppedDown||this.modifyFeature(a.xy);return!0},up:function(a){this.mouseDown=!1;this.stoppedDown=this.stopDown;if(!this.checkModifiers(a)||this.lastUp&&this.lastUp.equals(a.xy)||!this.lastDown|| | |
2509 !this.passesTolerance(this.lastDown,a.xy,this.pixelTolerance))return!0;this.touch&&this.modifyFeature(a.xy);this.persist&&this.destroyPersistedFeature();this.lastUp=a.xy;this.finalize();return!this.stopUp},mouseout:function(a){OpenLayers.Util.mouseLeft(a,this.map.viewPortDiv)&&(this.stoppedDown=this.stopDown,this.mouseDown=!1)},passesTolerance:function(a,b,c){var d=!0;null!=c&&a&&b&&a.distanceTo(b)>c&&(d=!1);return d},CLASS_NAME:"OpenLayers.Handler.Point"});OpenLayers.Handler.Path=OpenLayers.Class(OpenLayers.Handler.Point,{line:null,maxVertices:null,doubleTouchTolerance:20,freehand:!1,freehandToggle:"shiftKey",timerId:null,redoStack:null,createFeature:function(a){a=this.layer.getLonLatFromViewPortPx(a);a=new OpenLayers.Geometry.Point(a.lon,a.lat);this.point=new OpenLayers.Feature.Vector(a);this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([this.point.geometry]));this.callback("create",[this.point.geometry,this.getSketch()]); | |
2510 this.point.geometry.clearBounds();this.layer.addFeatures([this.line,this.point],{silent:!0})},destroyFeature:function(a){OpenLayers.Handler.Point.prototype.destroyFeature.call(this,a);this.line=null},destroyPersistedFeature:function(){var a=this.layer;a&&2<a.features.length&&this.layer.features[0].destroy()},removePoint:function(){this.point&&this.layer.removeFeatures([this.point])},addPoint:function(a){this.layer.removeFeatures([this.point]);a=this.layer.getLonLatFromViewPortPx(a);this.point=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(a.lon, | |
2511 a.lat));this.line.geometry.addComponent(this.point.geometry,this.line.geometry.components.length);this.layer.addFeatures([this.point]);this.callback("point",[this.point.geometry,this.getGeometry()]);this.callback("modify",[this.point.geometry,this.getSketch()]);this.drawFeature();delete this.redoStack},insertXY:function(a,b){this.line.geometry.addComponent(new OpenLayers.Geometry.Point(a,b),this.getCurrentPointIndex());this.drawFeature();delete this.redoStack},insertDeltaXY:function(a,b){var c=this.getCurrentPointIndex()- | |
2512 1,c=this.line.geometry.components[c];!c||(isNaN(c.x)||isNaN(c.y))||this.insertXY(c.x+a,c.y+b)},insertDirectionLength:function(a,b){a*=Math.PI/180;var c=b*Math.cos(a),d=b*Math.sin(a);this.insertDeltaXY(c,d)},insertDeflectionLength:function(a,b){var c=this.getCurrentPointIndex()-1;if(0<c){var d=this.line.geometry.components[c],c=this.line.geometry.components[c-1],d=Math.atan2(d.y-c.y,d.x-c.x);this.insertDirectionLength(180*d/Math.PI+a,b)}},getCurrentPointIndex:function(){return this.line.geometry.components.length- | |
2513 1},undo:function(){var a=this.line.geometry,b=a.components,c=this.getCurrentPointIndex()-1,d=b[c],e=a.removeComponent(d);e&&(this.touch&&0<c&&(b=a.components,a=b[c-1],c=this.getCurrentPointIndex(),b=b[c],b.x=a.x,b.y=a.y),this.redoStack||(this.redoStack=[]),this.redoStack.push(d),this.drawFeature());return e},redo:function(){var a=this.redoStack&&this.redoStack.pop();a&&(this.line.geometry.addComponent(a,this.getCurrentPointIndex()),this.drawFeature());return!!a},freehandMode:function(a){return this.freehandToggle&& | |
2514 a[this.freehandToggle]?!this.freehand:this.freehand},modifyFeature:function(a,b){this.line||this.createFeature(a);var c=this.layer.getLonLatFromViewPortPx(a);this.point.geometry.x=c.lon;this.point.geometry.y=c.lat;this.callback("modify",[this.point.geometry,this.getSketch(),b]);this.point.geometry.clearBounds();this.drawFeature()},drawFeature:function(){this.layer.drawFeature(this.line,this.style);this.layer.drawFeature(this.point,this.style)},getSketch:function(){return this.line},getGeometry:function(){var a= | |
2515 this.line&&this.line.geometry;a&&this.multi&&(a=new OpenLayers.Geometry.MultiLineString([a]));return a},touchstart:function(a){if(this.timerId&&this.passesTolerance(this.lastTouchPx,a.xy,this.doubleTouchTolerance))return this.finishGeometry(),window.clearTimeout(this.timerId),this.timerId=null,!1;this.timerId&&(window.clearTimeout(this.timerId),this.timerId=null);this.timerId=window.setTimeout(OpenLayers.Function.bind(function(){this.timerId=null},this),300);return OpenLayers.Handler.Point.prototype.touchstart.call(this, | |
2516 a)},down:function(a){var b=this.stopDown;this.freehandMode(a)&&(b=!0,this.touch&&(this.modifyFeature(a.xy,!!this.lastUp),OpenLayers.Event.stop(a)));this.touch||this.lastDown&&this.passesTolerance(this.lastDown,a.xy,this.pixelTolerance)||this.modifyFeature(a.xy,!!this.lastUp);this.mouseDown=!0;this.lastDown=a.xy;this.stoppedDown=b;return!b},move:function(a){if(this.stoppedDown&&this.freehandMode(a))return this.persist&&this.destroyPersistedFeature(),this.maxVertices&&this.line&&this.line.geometry.components.length=== | |
2517 this.maxVertices?(this.removePoint(),this.finalize()):this.addPoint(a.xy),!1;this.touch||this.mouseDown&&!this.stoppedDown||this.modifyFeature(a.xy,!!this.lastUp);return!0},up:function(a){!this.mouseDown||this.lastUp&&this.lastUp.equals(a.xy)||(this.stoppedDown&&this.freehandMode(a)?(this.persist&&this.destroyPersistedFeature(),this.removePoint(),this.finalize()):this.passesTolerance(this.lastDown,a.xy,this.pixelTolerance)&&(this.touch&&this.modifyFeature(a.xy),null==this.lastUp&&this.persist&&this.destroyPersistedFeature(), | |
2518 this.addPoint(a.xy),this.lastUp=a.xy,this.line.geometry.components.length===this.maxVertices+1&&this.finishGeometry()));this.stoppedDown=this.stopDown;this.mouseDown=!1;return!this.stopUp},finishGeometry:function(){this.line.geometry.removeComponent(this.line.geometry.components[this.line.geometry.components.length-1]);this.removePoint();this.finalize()},dblclick:function(a){this.freehandMode(a)||this.finishGeometry();return!1},CLASS_NAME:"OpenLayers.Handler.Path"});OpenLayers.Spherical=OpenLayers.Spherical||{};OpenLayers.Spherical.DEFAULT_RADIUS=6378137;OpenLayers.Spherical.computeDistanceBetween=function(a,b,c){c=c||OpenLayers.Spherical.DEFAULT_RADIUS;var d=Math.sin(Math.PI*(b.lon-a.lon)/360),e=Math.sin(Math.PI*(b.lat-a.lat)/360);a=e*e+d*d*Math.cos(Math.PI*a.lat/180)*Math.cos(Math.PI*b.lat/180);return 2*c*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))}; | |
2519 OpenLayers.Spherical.computeHeading=function(a,b){var c=Math.sin(Math.PI*(a.lon-b.lon)/180)*Math.cos(Math.PI*b.lat/180),d=Math.cos(Math.PI*a.lat/180)*Math.sin(Math.PI*b.lat/180)-Math.sin(Math.PI*a.lat/180)*Math.cos(Math.PI*b.lat/180)*Math.cos(Math.PI*(a.lon-b.lon)/180);return 180*Math.atan2(c,d)/Math.PI};OpenLayers.Control.CacheWrite=OpenLayers.Class(OpenLayers.Control,{layers:null,imageFormat:"image/png",quotaRegEx:/quota/i,setMap:function(a){OpenLayers.Control.prototype.setMap.apply(this,arguments);var b,c=this.layers||a.layers;for(b=c.length-1;0<=b;--b)this.addLayer({layer:c[b]});if(!this.layers)a.events.on({addlayer:this.addLayer,removeLayer:this.removeLayer,scope:this})},addLayer:function(a){a.layer.events.on({tileloadstart:this.makeSameOrigin,tileloaded:this.onTileLoaded,scope:this})},removeLayer:function(a){a.layer.events.un({tileloadstart:this.makeSameOrigin, | |
2520 tileloaded:this.onTileLoaded,scope:this})},makeSameOrigin:function(a){if(this.active&&(a=a.tile,a instanceof OpenLayers.Tile.Image&&!a.crossOriginKeyword&&"data:"!==a.url.substr(0,5))){var b=OpenLayers.Request.makeSameOrigin(a.url,OpenLayers.ProxyHost);OpenLayers.Control.CacheWrite.urlMap[b]=a.url;a.url=b}},onTileLoaded:function(a){this.active&&(!a.aborted&&a.tile instanceof OpenLayers.Tile.Image&&"data:"!==a.tile.url.substr(0,5))&&(this.cache({tile:a.tile}),delete OpenLayers.Control.CacheWrite.urlMap[a.tile.url])}, | |
2521 cache:function(a){if(window.localStorage){a=a.tile;try{var b=a.getCanvasContext();b&&window.localStorage.setItem("olCache_"+(OpenLayers.Control.CacheWrite.urlMap[a.url]||a.url),b.canvas.toDataURL(this.imageFormat))}catch(c){(b=c.name||c.message)&&this.quotaRegEx.test(b)?this.events.triggerEvent("cachefull",{tile:a}):OpenLayers.Console.error(c.toString())}}},destroy:function(){if(this.layers||this.map){var a,b=this.layers||this.map.layers;for(a=b.length-1;0<=a;--a)this.removeLayer({layer:b[a]})}this.map&& | |
2522 this.map.events.un({addlayer:this.addLayer,removeLayer:this.removeLayer,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments)},CLASS_NAME:"OpenLayers.Control.CacheWrite"});OpenLayers.Control.CacheWrite.clearCache=function(){if(window.localStorage){var a,b;for(a=window.localStorage.length-1;0<=a;--a)b=window.localStorage.key(a),"olCache_"===b.substr(0,8)&&window.localStorage.removeItem(b)}};OpenLayers.Control.CacheWrite.urlMap={};OpenLayers.Format.Context=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{layerOptions:null,layerParams:null,read:function(a,b){var c=OpenLayers.Format.XML.VersionedOGC.prototype.read.apply(this,arguments);if(b&&b.map)if(this.context=c,b.map instanceof OpenLayers.Map)c=this.mergeContextToMap(c,b.map);else{var d=b.map;if(OpenLayers.Util.isElement(d)||"string"==typeof d)d={div:d};c=this.contextToMap(c,d)}return c},getLayerFromContext:function(a){var b,c,d={queryable:a.queryable,visibility:a.visibility, | |
2523 maxExtent:a.maxExtent,metadata:OpenLayers.Util.applyDefaults(a.metadata,{styles:a.styles,formats:a.formats,"abstract":a["abstract"],dataURL:a.dataURL}),numZoomLevels:a.numZoomLevels,units:a.units,isBaseLayer:a.isBaseLayer,opacity:a.opacity,displayInLayerSwitcher:a.displayInLayerSwitcher,singleTile:a.singleTile,tileSize:a.tileSize?new OpenLayers.Size(a.tileSize.width,a.tileSize.height):void 0,minScale:a.minScale||a.maxScaleDenominator,maxScale:a.maxScale||a.minScaleDenominator,srs:a.srs,dimensions:a.dimensions, | |
2524 metadataURL:a.metadataURL};this.layerOptions&&OpenLayers.Util.applyDefaults(d,this.layerOptions);var e={layers:a.name,transparent:a.transparent,version:a.version};if(a.formats&&0<a.formats.length)for(e.format=a.formats[0].value,b=0,c=a.formats.length;b<c;b++){var f=a.formats[b];if(!0==f.current){e.format=f.value;break}}if(a.styles&&0<a.styles.length)for(b=0,c=a.styles.length;b<c;b++)if(f=a.styles[b],!0==f.current){f.href?e.sld=f.href:f.body?e.sld_body=f.body:e.styles=f.name;break}this.layerParams&& | |
2525 OpenLayers.Util.applyDefaults(e,this.layerParams);b=null;c=a.service;c==OpenLayers.Format.Context.serviceTypes.WFS?(d.strategies=[new OpenLayers.Strategy.BBOX],d.protocol=new OpenLayers.Protocol.WFS({url:a.url,featurePrefix:a.name.split(":")[0],featureType:a.name.split(":").pop()}),b=new OpenLayers.Layer.Vector(a.title||a.name,d)):c==OpenLayers.Format.Context.serviceTypes.KML?(d.strategies=[new OpenLayers.Strategy.Fixed],d.protocol=new OpenLayers.Protocol.HTTP({url:a.url,format:new OpenLayers.Format.KML}), | |
2526 b=new OpenLayers.Layer.Vector(a.title||a.name,d)):c==OpenLayers.Format.Context.serviceTypes.GML?(d.strategies=[new OpenLayers.Strategy.Fixed],d.protocol=new OpenLayers.Protocol.HTTP({url:a.url,format:new OpenLayers.Format.GML}),b=new OpenLayers.Layer.Vector(a.title||a.name,d)):a.features?(b=new OpenLayers.Layer.Vector(a.title||a.name,d),b.addFeatures(a.features)):!0!==a.categoryLayer&&(b=new OpenLayers.Layer.WMS(a.title||a.name,a.url,e,d));return b},getLayersFromContext:function(a){for(var b=[],c= | |
2527 0,d=a.length;c<d;c++){var e=this.getLayerFromContext(a[c]);null!==e&&b.push(e)}return b},contextToMap:function(a,b){b=OpenLayers.Util.applyDefaults({maxExtent:a.maxExtent,projection:a.projection,units:a.units},b);b.maxExtent&&(b.maxResolution=b.maxExtent.getWidth()/OpenLayers.Map.TILE_WIDTH);b.metadata={contactInformation:a.contactInformation,"abstract":a["abstract"],keywords:a.keywords,logo:a.logo,descriptionURL:a.descriptionURL};var c=new OpenLayers.Map(b);c.addLayers(this.getLayersFromContext(a.layersContext)); | |
2528 c.setCenter(a.bounds.getCenterLonLat(),c.getZoomForExtent(a.bounds,!0));return c},mergeContextToMap:function(a,b){b.addLayers(this.getLayersFromContext(a.layersContext));return b},write:function(a,b){a=this.toContext(a);return OpenLayers.Format.XML.VersionedOGC.prototype.write.apply(this,arguments)},CLASS_NAME:"OpenLayers.Format.Context"}); | |
2529 OpenLayers.Format.Context.serviceTypes={WMS:"urn:ogc:serviceType:WMS",WFS:"urn:ogc:serviceType:WFS",WCS:"urn:ogc:serviceType:WCS",GML:"urn:ogc:serviceType:GML",SLD:"urn:ogc:serviceType:SLD",FES:"urn:ogc:serviceType:FES",KML:"urn:ogc:serviceType:KML"};OpenLayers.Format.WMC=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"1.1.0",layerToContext:function(a){var b=this.getParser(),c={queryable:a.queryable,visibility:a.visibility,name:a.params.LAYERS,title:a.name,"abstract":a.metadata["abstract"],dataURL:a.metadata.dataURL,metadataURL:a.metadataURL,server:{version:a.params.VERSION,url:a.url},maxExtent:a.maxExtent,transparent:a.params.TRANSPARENT,numZoomLevels:a.numZoomLevels,units:a.units,isBaseLayer:a.isBaseLayer,opacity:1==a.opacity?void 0: | |
2530 a.opacity,displayInLayerSwitcher:a.displayInLayerSwitcher,singleTile:a.singleTile,tileSize:a.singleTile||!a.tileSize?void 0:{width:a.tileSize.w,height:a.tileSize.h},minScale:a.options.resolutions||a.options.scales||a.options.maxResolution||a.options.minScale?a.minScale:void 0,maxScale:a.options.resolutions||a.options.scales||a.options.minResolution||a.options.maxScale?a.maxScale:void 0,formats:[],styles:[],srs:a.srs,dimensions:a.dimensions};a.metadata.servertitle&&(c.server.title=a.metadata.servertitle); | |
2531 if(a.metadata.formats&&0<a.metadata.formats.length)for(var d=0,e=a.metadata.formats.length;d<e;d++){var f=a.metadata.formats[d];c.formats.push({value:f.value,current:f.value==a.params.FORMAT})}else c.formats.push({value:a.params.FORMAT,current:!0});if(a.metadata.styles&&0<a.metadata.styles.length)for(d=0,e=a.metadata.styles.length;d<e;d++)b=a.metadata.styles[d],b.current=b.href==a.params.SLD||b.body==a.params.SLD_BODY||b.name==a.params.STYLES?!0:!1,c.styles.push(b);else c.styles.push({href:a.params.SLD, | |
2532 body:a.params.SLD_BODY,name:a.params.STYLES||b.defaultStyleName,title:b.defaultStyleTitle,current:!0});return c},toContext:function(a){var b={},c=a.layers;if("OpenLayers.Map"==a.CLASS_NAME){var d=a.metadata||{};b.size=a.getSize();b.bounds=a.getExtent();b.projection=a.projection;b.title=a.title;b.keywords=d.keywords;b["abstract"]=d["abstract"];b.logo=d.logo;b.descriptionURL=d.descriptionURL;b.contactInformation=d.contactInformation;b.maxExtent=a.maxExtent}else OpenLayers.Util.applyDefaults(b,a),void 0!= | |
2533 b.layers&&delete b.layers;void 0==b.layersContext&&(b.layersContext=[]);if(void 0!=c&&OpenLayers.Util.isArray(c))for(a=0,d=c.length;a<d;a++){var e=c[a];e instanceof OpenLayers.Layer.WMS&&b.layersContext.push(this.layerToContext(e))}return b},CLASS_NAME:"OpenLayers.Format.WMC"});OpenLayers.Format.WMC.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ol:"http://openlayers.org/context",wmc:"http://www.opengis.net/context",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"",getNamespacePrefix:function(a){var b=null;if(null==a)b=this.namespaces[this.defaultPrefix];else for(b in this.namespaces)if(this.namespaces[b]==a)break;return b},defaultPrefix:"wmc",rootPrefix:null,defaultStyleName:"", | |
2534 defaultStyleTitle:"Default",initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a=a.documentElement;this.rootPrefix=a.prefix;var b={version:a.getAttribute("version")};this.runChildNodes(b,a);return b},runChildNodes:function(a,b){for(var c=b.childNodes,d,e,f,g=0,h=c.length;g<h;++g)d=c[g],1==d.nodeType&&(e=this.getNamespacePrefix(d.namespaceURI),f=d.nodeName.split(":").pop(), | |
2535 (e=this["read_"+e+"_"+f])&&e.apply(this,[a,d]))},read_wmc_General:function(a,b){this.runChildNodes(a,b)},read_wmc_BoundingBox:function(a,b){a.projection=b.getAttribute("SRS");a.bounds=new OpenLayers.Bounds(b.getAttribute("minx"),b.getAttribute("miny"),b.getAttribute("maxx"),b.getAttribute("maxy"))},read_wmc_LayerList:function(a,b){a.layersContext=[];this.runChildNodes(a,b)},read_wmc_Layer:function(a,b){var c={visibility:"1"!=b.getAttribute("hidden"),queryable:"1"==b.getAttribute("queryable"),formats:[], | |
2536 styles:[],metadata:{}};this.runChildNodes(c,b);a.layersContext.push(c)},read_wmc_Extension:function(a,b){this.runChildNodes(a,b)},read_ol_units:function(a,b){a.units=this.getChildValue(b)},read_ol_maxExtent:function(a,b){var c=new OpenLayers.Bounds(b.getAttribute("minx"),b.getAttribute("miny"),b.getAttribute("maxx"),b.getAttribute("maxy"));a.maxExtent=c},read_ol_transparent:function(a,b){a.transparent=this.getChildValue(b)},read_ol_numZoomLevels:function(a,b){a.numZoomLevels=parseInt(this.getChildValue(b))}, | |
2537 read_ol_opacity:function(a,b){a.opacity=parseFloat(this.getChildValue(b))},read_ol_singleTile:function(a,b){a.singleTile="true"==this.getChildValue(b)},read_ol_tileSize:function(a,b){var c={width:b.getAttribute("width"),height:b.getAttribute("height")};a.tileSize=c},read_ol_isBaseLayer:function(a,b){a.isBaseLayer="true"==this.getChildValue(b)},read_ol_displayInLayerSwitcher:function(a,b){a.displayInLayerSwitcher="true"==this.getChildValue(b)},read_wmc_Server:function(a,b){a.version=b.getAttribute("version"); | |
2538 a.url=this.getOnlineResource_href(b);a.metadata.servertitle=b.getAttribute("title")},read_wmc_FormatList:function(a,b){this.runChildNodes(a,b)},read_wmc_Format:function(a,b){var c={value:this.getChildValue(b)};"1"==b.getAttribute("current")&&(c.current=!0);a.formats.push(c)},read_wmc_StyleList:function(a,b){this.runChildNodes(a,b)},read_wmc_Style:function(a,b){var c={};this.runChildNodes(c,b);"1"==b.getAttribute("current")&&(c.current=!0);a.styles.push(c)},read_wmc_SLD:function(a,b){this.runChildNodes(a, | |
2539 b)},read_sld_StyledLayerDescriptor:function(a,b){var c=OpenLayers.Format.XML.prototype.write.apply(this,[b]);a.body=c},read_sld_FeatureTypeStyle:function(a,b){var c=OpenLayers.Format.XML.prototype.write.apply(this,[b]);a.body=c},read_wmc_OnlineResource:function(a,b){a.href=this.getAttributeNS(b,this.namespaces.xlink,"href")},read_wmc_Name:function(a,b){var c=this.getChildValue(b);c&&(a.name=c)},read_wmc_Title:function(a,b){var c=this.getChildValue(b);c&&(a.title=c)},read_wmc_MetadataURL:function(a, | |
2540 b){a.metadataURL=this.getOnlineResource_href(b)},read_wmc_KeywordList:function(a,b){a.keywords=[];this.runChildNodes(a.keywords,b)},read_wmc_Keyword:function(a,b){a.push(this.getChildValue(b))},read_wmc_Abstract:function(a,b){var c=this.getChildValue(b);c&&(a["abstract"]=c)},read_wmc_LogoURL:function(a,b){a.logo={width:b.getAttribute("width"),height:b.getAttribute("height"),format:b.getAttribute("format"),href:this.getOnlineResource_href(b)}},read_wmc_DescriptionURL:function(a,b){a.descriptionURL= | |
2541 this.getOnlineResource_href(b)},read_wmc_ContactInformation:function(a,b){var c={};this.runChildNodes(c,b);a.contactInformation=c},read_wmc_ContactPersonPrimary:function(a,b){var c={};this.runChildNodes(c,b);a.personPrimary=c},read_wmc_ContactPerson:function(a,b){var c=this.getChildValue(b);c&&(a.person=c)},read_wmc_ContactOrganization:function(a,b){var c=this.getChildValue(b);c&&(a.organization=c)},read_wmc_ContactPosition:function(a,b){var c=this.getChildValue(b);c&&(a.position=c)},read_wmc_ContactAddress:function(a, | |
2542 b){var c={};this.runChildNodes(c,b);a.contactAddress=c},read_wmc_AddressType:function(a,b){var c=this.getChildValue(b);c&&(a.type=c)},read_wmc_Address:function(a,b){var c=this.getChildValue(b);c&&(a.address=c)},read_wmc_City:function(a,b){var c=this.getChildValue(b);c&&(a.city=c)},read_wmc_StateOrProvince:function(a,b){var c=this.getChildValue(b);c&&(a.stateOrProvince=c)},read_wmc_PostCode:function(a,b){var c=this.getChildValue(b);c&&(a.postcode=c)},read_wmc_Country:function(a,b){var c=this.getChildValue(b); | |
2543 c&&(a.country=c)},read_wmc_ContactVoiceTelephone:function(a,b){var c=this.getChildValue(b);c&&(a.phone=c)},read_wmc_ContactFacsimileTelephone:function(a,b){var c=this.getChildValue(b);c&&(a.fax=c)},read_wmc_ContactElectronicMailAddress:function(a,b){var c=this.getChildValue(b);c&&(a.email=c)},read_wmc_DataURL:function(a,b){a.dataURL=this.getOnlineResource_href(b)},read_wmc_LegendURL:function(a,b){var c={width:b.getAttribute("width"),height:b.getAttribute("height"),format:b.getAttribute("format"), | |
2544 href:this.getOnlineResource_href(b)};a.legend=c},read_wmc_DimensionList:function(a,b){a.dimensions={};this.runChildNodes(a.dimensions,b)},read_wmc_Dimension:function(a,b){var c={name:b.getAttribute("name").toLowerCase(),units:b.getAttribute("units")||"",unitSymbol:b.getAttribute("unitSymbol")||"",userValue:b.getAttribute("userValue")||"",nearestValue:"1"===b.getAttribute("nearestValue"),multipleValues:"1"===b.getAttribute("multipleValues"),current:"1"===b.getAttribute("current"),"default":b.getAttribute("default")|| | |
2545 ""},d=this.getChildValue(b);c.values=d.split(",");a[c.name]=c},write:function(a,b){var c=this.createElementDefaultNS("ViewContext");this.setAttributes(c,{version:this.VERSION,id:b&&"string"==typeof b.id?b.id:OpenLayers.Util.createUniqueID("OpenLayers_Context_")});this.setAttributeNS(c,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);c.appendChild(this.write_wmc_General(a));c.appendChild(this.write_wmc_LayerList(a));return OpenLayers.Format.XML.prototype.write.apply(this,[c])},createElementDefaultNS:function(a, | |
2546 b,c){a=this.createElementNS(this.namespaces[this.defaultPrefix],a);b&&a.appendChild(this.createTextNode(b));c&&this.setAttributes(a,c);return a},setAttributes:function(a,b){var c,d;for(d in b)c=b[d].toString(),c.match(/[A-Z]/)?this.setAttributeNS(a,null,d,c):a.setAttribute(d,c)},write_wmc_General:function(a){var b=this.createElementDefaultNS("General");a.size&&b.appendChild(this.createElementDefaultNS("Window",null,{width:a.size.w,height:a.size.h}));var c=a.bounds;b.appendChild(this.createElementDefaultNS("BoundingBox", | |
2547 null,{minx:c.left.toPrecision(18),miny:c.bottom.toPrecision(18),maxx:c.right.toPrecision(18),maxy:c.top.toPrecision(18),SRS:a.projection}));b.appendChild(this.createElementDefaultNS("Title",a.title));a.keywords&&b.appendChild(this.write_wmc_KeywordList(a.keywords));a["abstract"]&&b.appendChild(this.createElementDefaultNS("Abstract",a["abstract"]));a.logo&&b.appendChild(this.write_wmc_URLType("LogoURL",a.logo.href,a.logo));a.descriptionURL&&b.appendChild(this.write_wmc_URLType("DescriptionURL",a.descriptionURL)); | |
2548 a.contactInformation&&b.appendChild(this.write_wmc_ContactInformation(a.contactInformation));b.appendChild(this.write_ol_MapExtension(a));return b},write_wmc_KeywordList:function(a){for(var b=this.createElementDefaultNS("KeywordList"),c=0,d=a.length;c<d;c++)b.appendChild(this.createElementDefaultNS("Keyword",a[c]));return b},write_wmc_ContactInformation:function(a){var b=this.createElementDefaultNS("ContactInformation");a.personPrimary&&b.appendChild(this.write_wmc_ContactPersonPrimary(a.personPrimary)); | |
2549 a.position&&b.appendChild(this.createElementDefaultNS("ContactPosition",a.position));a.contactAddress&&b.appendChild(this.write_wmc_ContactAddress(a.contactAddress));a.phone&&b.appendChild(this.createElementDefaultNS("ContactVoiceTelephone",a.phone));a.fax&&b.appendChild(this.createElementDefaultNS("ContactFacsimileTelephone",a.fax));a.email&&b.appendChild(this.createElementDefaultNS("ContactElectronicMailAddress",a.email));return b},write_wmc_ContactPersonPrimary:function(a){var b=this.createElementDefaultNS("ContactPersonPrimary"); | |
2550 a.person&&b.appendChild(this.createElementDefaultNS("ContactPerson",a.person));a.organization&&b.appendChild(this.createElementDefaultNS("ContactOrganization",a.organization));return b},write_wmc_ContactAddress:function(a){var b=this.createElementDefaultNS("ContactAddress");a.type&&b.appendChild(this.createElementDefaultNS("AddressType",a.type));a.address&&b.appendChild(this.createElementDefaultNS("Address",a.address));a.city&&b.appendChild(this.createElementDefaultNS("City",a.city));a.stateOrProvince&& | |
2551 b.appendChild(this.createElementDefaultNS("StateOrProvince",a.stateOrProvince));a.postcode&&b.appendChild(this.createElementDefaultNS("PostCode",a.postcode));a.country&&b.appendChild(this.createElementDefaultNS("Country",a.country));return b},write_ol_MapExtension:function(a){var b=this.createElementDefaultNS("Extension");if(a=a.maxExtent){var c=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(c,{minx:a.left.toPrecision(18),miny:a.bottom.toPrecision(18),maxx:a.right.toPrecision(18), | |
2552 maxy:a.top.toPrecision(18)});b.appendChild(c)}return b},write_wmc_LayerList:function(a){for(var b=this.createElementDefaultNS("LayerList"),c=0,d=a.layersContext.length;c<d;++c)b.appendChild(this.write_wmc_Layer(a.layersContext[c]));return b},write_wmc_Layer:function(a){var b=this.createElementDefaultNS("Layer",null,{queryable:a.queryable?"1":"0",hidden:a.visibility?"0":"1"});b.appendChild(this.write_wmc_Server(a));b.appendChild(this.createElementDefaultNS("Name",a.name));b.appendChild(this.createElementDefaultNS("Title", | |
2553 a.title));a["abstract"]&&b.appendChild(this.createElementDefaultNS("Abstract",a["abstract"]));a.dataURL&&b.appendChild(this.write_wmc_URLType("DataURL",a.dataURL));a.metadataURL&&b.appendChild(this.write_wmc_URLType("MetadataURL",a.metadataURL));return b},write_wmc_LayerExtension:function(a){var b=this.createElementDefaultNS("Extension"),c=a.maxExtent,d=this.createElementNS(this.namespaces.ol,"ol:maxExtent");this.setAttributes(d,{minx:c.left.toPrecision(18),miny:c.bottom.toPrecision(18),maxx:c.right.toPrecision(18), | |
2554 maxy:c.top.toPrecision(18)});b.appendChild(d);a.tileSize&&!a.singleTile&&(c=this.createElementNS(this.namespaces.ol,"ol:tileSize"),this.setAttributes(c,a.tileSize),b.appendChild(c));for(var c="transparent numZoomLevels units isBaseLayer opacity displayInLayerSwitcher singleTile".split(" "),e=0,f=c.length;e<f;++e)(d=this.createOLPropertyNode(a,c[e]))&&b.appendChild(d);return b},createOLPropertyNode:function(a,b){var c=null;null!=a[b]&&(c=this.createElementNS(this.namespaces.ol,"ol:"+b),c.appendChild(this.createTextNode(a[b].toString()))); | |
2555 return c},write_wmc_Server:function(a){a=a.server;var b=this.createElementDefaultNS("Server"),c={service:"OGC:WMS",version:a.version};a.title&&(c.title=a.title);this.setAttributes(b,c);b.appendChild(this.write_wmc_OnlineResource(a.url));return b},write_wmc_URLType:function(a,b,c){a=this.createElementDefaultNS(a);a.appendChild(this.write_wmc_OnlineResource(b));if(c){b=["width","height","format"];for(var d=0;d<b.length;d++)b[d]in c&&a.setAttribute(b[d],c[b[d]])}return a},write_wmc_DimensionList:function(a){var b= | |
2556 this.createElementDefaultNS("DimensionList"),c;for(c in a.dimensions){var d={},e=a.dimensions[c],f;for(f in e)d[f]="boolean"==typeof e[f]?Number(e[f]):e[f];e="";d.values&&(e=d.values.join(","),delete d.values);b.appendChild(this.createElementDefaultNS("Dimension",e,d))}return b},write_wmc_FormatList:function(a){for(var b=this.createElementDefaultNS("FormatList"),c=0,d=a.formats.length;c<d;c++){var e=a.formats[c];b.appendChild(this.createElementDefaultNS("Format",e.value,e.current&&!0==e.current?{current:"1"}: | |
2557 null))}return b},write_wmc_StyleList:function(a){var b=this.createElementDefaultNS("StyleList");if((a=a.styles)&&OpenLayers.Util.isArray(a))for(var c,d=0,e=a.length;d<e;d++){var f=a[d],g=this.createElementDefaultNS("Style",null,f.current&&!0==f.current?{current:"1"}:null);f.href?(c=this.createElementDefaultNS("SLD"),f.name&&c.appendChild(this.createElementDefaultNS("Name",f.name)),f.title&&c.appendChild(this.createElementDefaultNS("Title",f.title)),f.legend&&c.appendChild(this.write_wmc_URLType("LegendURL", | |
2558 f.legend.href,f.legend)),f=this.write_wmc_OnlineResource(f.href),c.appendChild(f),g.appendChild(c)):f.body?(c=this.createElementDefaultNS("SLD"),f.name&&c.appendChild(this.createElementDefaultNS("Name",f.name)),f.title&&c.appendChild(this.createElementDefaultNS("Title",f.title)),f.legend&&c.appendChild(this.write_wmc_URLType("LegendURL",f.legend.href,f.legend)),f=OpenLayers.Format.XML.prototype.read.apply(this,[f.body]).documentElement,c.ownerDocument&&c.ownerDocument.importNode&&(f=c.ownerDocument.importNode(f, | |
2559 !0)),c.appendChild(f),g.appendChild(c)):(g.appendChild(this.createElementDefaultNS("Name",f.name)),g.appendChild(this.createElementDefaultNS("Title",f.title)),f["abstract"]&&g.appendChild(this.createElementDefaultNS("Abstract",f["abstract"])),f.legend&&g.appendChild(this.write_wmc_URLType("LegendURL",f.legend.href,f.legend)));b.appendChild(g)}return b},write_wmc_OnlineResource:function(a){var b=this.createElementDefaultNS("OnlineResource");this.setAttributeNS(b,this.namespaces.xlink,"xlink:type", | |
2560 "simple");this.setAttributeNS(b,this.namespaces.xlink,"xlink:href",a);return b},getOnlineResource_href:function(a){var b={};a=a.getElementsByTagName("OnlineResource");0<a.length&&this.read_wmc_OnlineResource(b,a[0]);return b.href},CLASS_NAME:"OpenLayers.Format.WMC.v1"});OpenLayers.Control.PanPanel=OpenLayers.Class(OpenLayers.Control.Panel,{slideFactor:50,slideRatio:null,initialize:function(a){OpenLayers.Control.Panel.prototype.initialize.apply(this,[a]);a={slideFactor:this.slideFactor,slideRatio:this.slideRatio};this.addControls([new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH,a),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH,a),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST,a),new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST,a)])}, | |
2561 CLASS_NAME:"OpenLayers.Control.PanPanel"});OpenLayers.Control.Attribution=OpenLayers.Class(OpenLayers.Control,{separator:", ",template:"${layers}",destroy:function(){this.map.events.un({removelayer:this.updateAttribution,addlayer:this.updateAttribution,changelayer:this.updateAttribution,changebaselayer:this.updateAttribution,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments)},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.map.events.on({changebaselayer:this.updateAttribution,changelayer:this.updateAttribution, | |
2562 addlayer:this.updateAttribution,removelayer:this.updateAttribution,scope:this});this.updateAttribution();return this.div},updateAttribution:function(){var a=[];if(this.map&&this.map.layers){for(var b=0,c=this.map.layers.length;b<c;b++){var d=this.map.layers[b];d.attribution&&d.getVisibility()&&-1===OpenLayers.Util.indexOf(a,d.attribution)&&a.push(d.attribution)}this.div.innerHTML=OpenLayers.String.format(this.template,{layers:a.join(this.separator)})}},CLASS_NAME:"OpenLayers.Control.Attribution"});OpenLayers.Kinetic=OpenLayers.Class({threshold:0,deceleration:0.0035,nbPoints:100,delay:200,points:void 0,timerId:void 0,initialize:function(a){OpenLayers.Util.extend(this,a)},begin:function(){OpenLayers.Animation.stop(this.timerId);this.timerId=void 0;this.points=[]},update:function(a){this.points.unshift({xy:a,tick:(new Date).getTime()});this.points.length>this.nbPoints&&this.points.pop()},end:function(a){for(var b,c=(new Date).getTime(),d=0,e=this.points.length,f;d<e;d++){f=this.points[d];if(c- | |
2563 f.tick>this.delay)break;b=f}if(b&&(d=(new Date).getTime()-b.tick,c=Math.sqrt(Math.pow(a.x-b.xy.x,2)+Math.pow(a.y-b.xy.y,2)),d=c/d,!(0==d||d<this.threshold)))return c=Math.asin((a.y-b.xy.y)/c),b.xy.x<=a.x&&(c=Math.PI-c),{speed:d,theta:c}},move:function(a,b){var c=a.speed,d=Math.cos(a.theta),e=-Math.sin(a.theta),f=(new Date).getTime(),g=0,h=0;this.timerId=OpenLayers.Animation.start(OpenLayers.Function.bind(function(){if(null!=this.timerId){var a=(new Date).getTime()-f,l=-this.deceleration*Math.pow(a, | |
2564 2)/2+c*a,m=l*d,l=l*e,n,p;n=!1;0>=-this.deceleration*a+c&&(OpenLayers.Animation.stop(this.timerId),this.timerId=null,n=!0);a=m-g;p=l-h;g=m;h=l;b(a,p,n)}},this))},CLASS_NAME:"OpenLayers.Kinetic"});OpenLayers.Format.WPSExecute=OpenLayers.Class(OpenLayers.Format.XML,OpenLayers.Format.Filter.v1_1_0,{namespaces:{ows:"http://www.opengis.net/ows/1.1",gml:"http://www.opengis.net/gml",wps:"http://www.opengis.net/wps/1.0.0",wfs:"http://www.opengis.net/wfs",ogc:"http://www.opengis.net/ogc",wcs:"http://www.opengis.net/wcs",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},VERSION:"1.0.0", | |
2565 schemaLocation:"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd",schemaLocationAttr:function(a){},write:function(a){var b;window.ActiveXObject?this.xmldom=b=new ActiveXObject("Microsoft.XMLDOM"):b=document.implementation.createDocument("","",null);a=this.writeNode("wps:Execute",a,b);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[a])},read:function(a){"string"==typeof a&&(a= | |
2566 OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b},writers:{wps:{Execute:function(a){var b=this.createElementNSPlus("wps:Execute",{attributes:{version:this.VERSION,service:"WPS"}});this.writeNode("ows:Identifier",a.identifier,b);this.writeNode("wps:DataInputs",a.dataInputs,b);this.writeNode("wps:ResponseForm",a.responseForm,b);return b},ResponseForm:function(a){var b=this.createElementNSPlus("wps:ResponseForm",{});a.rawDataOutput&& | |
2567 this.writeNode("wps:RawDataOutput",a.rawDataOutput,b);a.responseDocument&&this.writeNode("wps:ResponseDocument",a.responseDocument,b);return b},ResponseDocument:function(a){var b=this.createElementNSPlus("wps:ResponseDocument",{attributes:{storeExecuteResponse:a.storeExecuteResponse,lineage:a.lineage,status:a.status}});if(a.outputs)for(var c=0,d=a.outputs.length;c<d;c++)this.writeNode("wps:Output",a.outputs[c],b);return b},Output:function(a){var b=this.createElementNSPlus("wps:Output",{attributes:{asReference:a.asReference, | |
2568 mimeType:a.mimeType,encoding:a.encoding,schema:a.schema}});this.writeNode("ows:Identifier",a.identifier,b);this.writeNode("ows:Title",a.title,b);this.writeNode("ows:Abstract",a["abstract"],b);return b},RawDataOutput:function(a){var b=this.createElementNSPlus("wps:RawDataOutput",{attributes:{mimeType:a.mimeType,encoding:a.encoding,schema:a.schema}});this.writeNode("ows:Identifier",a.identifier,b);return b},DataInputs:function(a){for(var b=this.createElementNSPlus("wps:DataInputs",{}),c=0,d=a.length;c< | |
2569 d;++c)this.writeNode("wps:Input",a[c],b);return b},Input:function(a){var b=this.createElementNSPlus("wps:Input",{});this.writeNode("ows:Identifier",a.identifier,b);a.title&&this.writeNode("ows:Title",a.title,b);a.data&&this.writeNode("wps:Data",a.data,b);a.reference&&this.writeNode("wps:Reference",a.reference,b);a.boundingBoxData&&this.writeNode("wps:BoundingBoxData",a.boundingBoxData,b);return b},Data:function(a){var b=this.createElementNSPlus("wps:Data",{});a.literalData?this.writeNode("wps:LiteralData", | |
2570 a.literalData,b):a.complexData?this.writeNode("wps:ComplexData",a.complexData,b):a.boundingBoxData&&this.writeNode("ows:BoundingBox",a.boundingBoxData,b);return b},LiteralData:function(a){return this.createElementNSPlus("wps:LiteralData",{attributes:{uom:a.uom},value:a.value})},ComplexData:function(a){var b=this.createElementNSPlus("wps:ComplexData",{attributes:{mimeType:a.mimeType,encoding:a.encoding,schema:a.schema}}),c=a.value;"string"===typeof c?b.appendChild(this.getXMLDoc().createCDATASection(a.value)): | |
2571 b.appendChild(c);return b},Reference:function(a){var b=this.createElementNSPlus("wps:Reference",{attributes:{mimeType:a.mimeType,"xlink:href":a.href,method:a.method,encoding:a.encoding,schema:a.schema}});a.body&&this.writeNode("wps:Body",a.body,b);return b},BoundingBoxData:function(a,b){this.writers.ows.BoundingBox.apply(this,[a,b,"wps:BoundingBoxData"])},Body:function(a){var b=this.createElementNSPlus("wps:Body",{});a.wcs?this.writeNode("wcs:GetCoverage",a.wcs,b):a.wfs?(this.featureType=a.wfs.featureType, | |
2572 this.version=a.wfs.version,this.writeNode("wfs:GetFeature",a.wfs,b)):this.writeNode("wps:Execute",a,b);return b}},wcs:OpenLayers.Format.WCSGetCoverage.prototype.writers.wcs,wfs:OpenLayers.Format.WFST.v1_1_0.prototype.writers.wfs,ogc:OpenLayers.Format.Filter.v1_1_0.prototype.writers.ogc,ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.writers.ows},readers:{wps:{ExecuteResponse:function(a,b){b.executeResponse={lang:a.getAttribute("lang"),statusLocation:a.getAttribute("statusLocation"),serviceInstance:a.getAttribute("serviceInstance"), | |
2573 service:a.getAttribute("service")};this.readChildNodes(a,b.executeResponse)},Process:function(a,b){b.process={};this.readChildNodes(a,b.process)},Status:function(a,b){b.status={creationTime:a.getAttribute("creationTime")};this.readChildNodes(a,b.status)},ProcessSucceeded:function(a,b){b.processSucceeded=!0},ProcessOutputs:function(a,b){b.processOutputs=[];this.readChildNodes(a,b.processOutputs)},Output:function(a,b){var c={};this.readChildNodes(a,c);b.push(c)},Reference:function(a,b){b.reference= | |
2574 {href:a.getAttribute("href"),mimeType:a.getAttribute("mimeType"),encoding:a.getAttribute("encoding"),schema:a.getAttribute("schema")}},Data:function(a,b){b.data={};this.readChildNodes(a,b)},LiteralData:function(a,b){b.literalData={dataType:a.getAttribute("dataType"),uom:a.getAttribute("uom"),value:this.getChildValue(a)}},ComplexData:function(a,b){b.complexData={mimeType:a.getAttribute("mimeType"),schema:a.getAttribute("schema"),encoding:a.getAttribute("encoding"),value:""};if(this.isSimpleContent(a)){var c; | |
2575 for(c=a.firstChild;c;c=c.nextSibling)switch(c.nodeType){case 3:case 4:b.complexData.value+=c.nodeValue}}else for(c=a.firstChild;c;c=c.nextSibling)1==c.nodeType&&(b.complexData.value=c)},BoundingBox:function(a,b){b.boundingBoxData={dimensions:a.getAttribute("dimensions"),crs:a.getAttribute("crs")};this.readChildNodes(a,b.boundingBoxData)}},ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows},CLASS_NAME:"OpenLayers.Format.WPSExecute"});OpenLayers.Layer.GeoRSS=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,icon:null,popupSize:null,useFeedTitle:!0,initialize:function(a,b,c){OpenLayers.Layer.Markers.prototype.initialize.apply(this,[a,c]);this.location=b;this.features=[]},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null},loadRSS:function(){this.loaded||(this.events.triggerEvent("loadstart"),OpenLayers.Request.GET({url:this.location, | |
2576 success:this.parseData,scope:this}),this.loaded=!0)},moveTo:function(a,b,c){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);this.visibility&&!this.loaded&&this.loadRSS()},parseData:function(a){var b=a.responseXML;b&&b.documentElement||(b=OpenLayers.Format.XML.prototype.read(a.responseText));if(this.useFeedTitle){a=null;try{a=b.getElementsByTagNameNS("*","title")[0].firstChild.nodeValue}catch(c){a=b.getElementsByTagName("title")[0].firstChild.nodeValue}a&&this.setName(a)}a={};OpenLayers.Util.extend(a, | |
2577 this.formatOptions);this.map&&!this.projection.equals(this.map.getProjectionObject())&&(a.externalProjection=this.projection,a.internalProjection=this.map.getProjectionObject());b=(new OpenLayers.Format.GeoRSS(a)).read(b);a=0;for(var d=b.length;a<d;a++){var e={},f=b[a];if(f.geometry){var g=f.attributes.title?f.attributes.title:"Untitled",h=f.attributes.description?f.attributes.description:"No description.",k=f.attributes.link?f.attributes.link:"",f=f.geometry.getBounds().getCenterLonLat();e.icon= | |
2578 null==this.icon?OpenLayers.Marker.defaultIcon():this.icon.clone();e.popupSize=this.popupSize?this.popupSize.clone():new OpenLayers.Size(250,120);if(g||h){e.title=g;e.description=h;var l='<div class="olLayerGeoRSSClose">[x]</div>',l=l+'<div class="olLayerGeoRSSTitle">';k&&(l+='<a class="link" href="'+k+'" target="_blank">');l+=g;k&&(l+="</a>");l+="</div>";l+='<div style="" class="olLayerGeoRSSDescription">';l+=h;l+="</div>";e.popupContentHTML=l}f=new OpenLayers.Feature(this,f,e);this.features.push(f); | |
2579 e=f.createMarker();e.events.register("click",f,this.markerClick);this.addMarker(e)}}this.events.triggerEvent("loadend")},markerClick:function(a){var b=this==this.layer.selectedFeature;this.layer.selectedFeature=b?null:this;for(var c=0,d=this.layer.map.popups.length;c<d;c++)this.layer.map.removePopup(this.layer.map.popups[c]);b||(b=this.createPopup(),OpenLayers.Event.observe(b.div,"click",OpenLayers.Function.bind(function(){for(var a=0,b=this.layer.map.popups.length;a<b;a++)this.layer.map.removePopup(this.layer.map.popups[a])}, | |
2580 this)),this.layer.map.addPopup(b));OpenLayers.Event.stop(a)},clearFeatures:function(){if(null!=this.features)for(;0<this.features.length;){var a=this.features[0];OpenLayers.Util.removeItem(this.features,a);a.destroy()}},CLASS_NAME:"OpenLayers.Layer.GeoRSS"});OpenLayers.Symbolizer.Point=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(a){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments)},CLASS_NAME:"OpenLayers.Symbolizer.Point"});OpenLayers.Symbolizer.Line=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(a){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments)},CLASS_NAME:"OpenLayers.Symbolizer.Line"});OpenLayers.Symbolizer.Text=OpenLayers.Class(OpenLayers.Symbolizer,{initialize:function(a){OpenLayers.Symbolizer.prototype.initialize.apply(this,arguments)},CLASS_NAME:"OpenLayers.Symbolizer.Text"});OpenLayers.Format.SLD.v1=OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0,{namespaces:{sld:"http://www.opengis.net/sld",ogc:"http://www.opengis.net/ogc",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"sld",schemaLocation:null,multipleSymbolizers:!1,featureTypeCounter:null,defaultSymbolizer:{fillColor:"#808080",fillOpacity:1,strokeColor:"#000000",strokeOpacity:1,strokeWidth:1,strokeDashstyle:"solid",pointRadius:3, | |
2581 graphicName:"square"},read:function(a,b){b=OpenLayers.Util.applyDefaults(b,this.options);var c={namedLayers:!0===b.namedLayersAsArray?[]:{}};this.readChildNodes(a,c);return c},readers:OpenLayers.Util.applyDefaults({sld:{StyledLayerDescriptor:function(a,b){b.version=a.getAttribute("version");this.readChildNodes(a,b)},Name:function(a,b){b.name=this.getChildValue(a)},Title:function(a,b){b.title=this.getChildValue(a)},Abstract:function(a,b){b.description=this.getChildValue(a)},NamedLayer:function(a,b){var c= | |
2582 {userStyles:[],namedStyles:[]};this.readChildNodes(a,c);for(var d=0,e=c.userStyles.length;d<e;++d)c.userStyles[d].layerName=c.name;OpenLayers.Util.isArray(b.namedLayers)?b.namedLayers.push(c):b.namedLayers[c.name]=c},NamedStyle:function(a,b){b.namedStyles.push(this.getChildName(a.firstChild))},UserStyle:function(a,b){var c={defaultsPerSymbolizer:!0,rules:[]};this.featureTypeCounter=-1;this.readChildNodes(a,c);this.multipleSymbolizers?(delete c.defaultsPerSymbolizer,c=new OpenLayers.Style2(c)):c=new OpenLayers.Style(this.defaultSymbolizer, | |
2583 c);b.userStyles.push(c)},IsDefault:function(a,b){"1"==this.getChildValue(a)&&(b.isDefault=!0)},FeatureTypeStyle:function(a,b){++this.featureTypeCounter;var c={rules:this.multipleSymbolizers?b.rules:[]};this.readChildNodes(a,c);this.multipleSymbolizers||(b.rules=c.rules)},Rule:function(a,b){var c;this.multipleSymbolizers&&(c={symbolizers:[]});c=new OpenLayers.Rule(c);this.readChildNodes(a,c);b.rules.push(c)},ElseFilter:function(a,b){b.elseFilter=!0},MinScaleDenominator:function(a,b){b.minScaleDenominator= | |
2584 parseFloat(this.getChildValue(a))},MaxScaleDenominator:function(a,b){b.maxScaleDenominator=parseFloat(this.getChildValue(a))},TextSymbolizer:function(a,b){var c={};this.readChildNodes(a,c);this.multipleSymbolizers?(c.zIndex=this.featureTypeCounter,b.symbolizers.push(new OpenLayers.Symbolizer.Text(c))):b.symbolizer.Text=OpenLayers.Util.applyDefaults(c,b.symbolizer.Text)},LabelPlacement:function(a,b){this.readChildNodes(a,b)},PointPlacement:function(a,b){var c={};this.readChildNodes(a,c);c.labelRotation= | |
2585 c.rotation;delete c.rotation;var d,e=b.labelAnchorPointX,f=b.labelAnchorPointY;e<=1/3?d="l":e>1/3&&e<2/3?d="c":e>=2/3&&(d="r");f<=1/3?d+="b":f>1/3&&f<2/3?d+="m":f>=2/3&&(d+="t");c.labelAlign=d;OpenLayers.Util.applyDefaults(b,c)},AnchorPoint:function(a,b){this.readChildNodes(a,b)},AnchorPointX:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.labelAnchorPointX=c)},AnchorPointY:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.labelAnchorPointY=c)},Displacement:function(a, | |
2586 b){this.readChildNodes(a,b)},DisplacementX:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.labelXOffset=c)},DisplacementY:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.labelYOffset=c)},LinePlacement:function(a,b){this.readChildNodes(a,b)},PerpendicularOffset:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.labelPerpendicularOffset=c)},Label:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.label=c)},Font:function(a,b){this.readChildNodes(a, | |
2587 b)},Halo:function(a,b){var c={};this.readChildNodes(a,c);b.haloRadius=c.haloRadius;b.haloColor=c.fillColor;b.haloOpacity=c.fillOpacity},Radius:function(a,b){var c=this.readers.ogc._expression.call(this,a);null!=c&&(b.haloRadius=c)},RasterSymbolizer:function(a,b){var c={};this.readChildNodes(a,c);this.multipleSymbolizers?(c.zIndex=this.featureTypeCounter,b.symbolizers.push(new OpenLayers.Symbolizer.Raster(c))):b.symbolizer.Raster=OpenLayers.Util.applyDefaults(c,b.symbolizer.Raster)},Geometry:function(a, | |
2588 b){b.geometry={};this.readChildNodes(a,b.geometry)},ColorMap:function(a,b){b.colorMap=[];this.readChildNodes(a,b.colorMap)},ColorMapEntry:function(a,b){var c=a.getAttribute("quantity"),d=a.getAttribute("opacity");b.push({color:a.getAttribute("color"),quantity:null!==c?parseFloat(c):void 0,label:a.getAttribute("label")||void 0,opacity:null!==d?parseFloat(d):void 0})},LineSymbolizer:function(a,b){var c={};this.readChildNodes(a,c);this.multipleSymbolizers?(c.zIndex=this.featureTypeCounter,b.symbolizers.push(new OpenLayers.Symbolizer.Line(c))): | |
2589 b.symbolizer.Line=OpenLayers.Util.applyDefaults(c,b.symbolizer.Line)},PolygonSymbolizer:function(a,b){var c={fill:!1,stroke:!1};this.multipleSymbolizers||(c=b.symbolizer.Polygon||c);this.readChildNodes(a,c);this.multipleSymbolizers?(c.zIndex=this.featureTypeCounter,b.symbolizers.push(new OpenLayers.Symbolizer.Polygon(c))):b.symbolizer.Polygon=c},PointSymbolizer:function(a,b){var c={fill:!1,stroke:!1,graphic:!1};this.multipleSymbolizers||(c=b.symbolizer.Point||c);this.readChildNodes(a,c);this.multipleSymbolizers? | |
2590 (c.zIndex=this.featureTypeCounter,b.symbolizers.push(new OpenLayers.Symbolizer.Point(c))):b.symbolizer.Point=c},Stroke:function(a,b){b.stroke=!0;this.readChildNodes(a,b)},Fill:function(a,b){b.fill=!0;this.readChildNodes(a,b)},CssParameter:function(a,b){var c=a.getAttribute("name"),d=this.cssMap[c];b.label&&("fill"===c?d="fontColor":"fill-opacity"===c&&(d="fontOpacity"));d&&(c=this.readers.ogc._expression.call(this,a))&&(b[d]=c)},Graphic:function(a,b){b.graphic=!0;var c={};this.readChildNodes(a,c); | |
2591 for(var d="stroke strokeColor strokeWidth strokeOpacity strokeLinecap fill fillColor fillOpacity graphicName rotation graphicFormat".split(" "),e,f,g=0,h=d.length;g<h;++g)e=d[g],f=c[e],void 0!=f&&(b[e]=f);void 0!=c.opacity&&(b.graphicOpacity=c.opacity);void 0!=c.size&&(isNaN(c.size/2)?b.graphicWidth=c.size:b.pointRadius=c.size/2);void 0!=c.href&&(b.externalGraphic=c.href);void 0!=c.rotation&&(b.rotation=c.rotation)},ExternalGraphic:function(a,b){this.readChildNodes(a,b)},Mark:function(a,b){this.readChildNodes(a, | |
2592 b)},WellKnownName:function(a,b){b.graphicName=this.getChildValue(a)},Opacity:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.opacity=c)},Size:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.size=c)},Rotation:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.rotation=c)},OnlineResource:function(a,b){b.href=this.getAttributeNS(a,this.namespaces.xlink,"href")},Format:function(a,b){b.graphicFormat=this.getChildValue(a)}}},OpenLayers.Format.Filter.v1_0_0.prototype.readers), | |
2593 cssMap:{stroke:"strokeColor","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","stroke-linecap":"strokeLinecap","stroke-dasharray":"strokeDashstyle",fill:"fillColor","fill-opacity":"fillOpacity","font-family":"fontFamily","font-size":"fontSize","font-weight":"fontWeight","font-style":"fontStyle"},getCssProperty:function(a){var b=null,c;for(c in this.cssMap)if(this.cssMap[c]==a){b=c;break}return b},getGraphicFormat:function(a){var b,c;for(c in this.graphicFormats)if(this.graphicFormats[c].test(a)){b= | |
2594 c;break}return b||this.defaultGraphicFormat},defaultGraphicFormat:"image/png",graphicFormats:{"image/jpeg":/\.jpe?g$/i,"image/gif":/\.gif$/i,"image/png":/\.png$/i},write:function(a){return this.writers.sld.StyledLayerDescriptor.apply(this,[a])},writers:OpenLayers.Util.applyDefaults({sld:{_OGCExpression:function(a,b){var c=this.createElementNSPlus(a),d="string"==typeof b?b.split("${"):[b];c.appendChild(this.createTextNode(d[0]));for(var e,f,g=1,h=d.length;g<h;g++)e=d[g],f=e.indexOf("}"),0<f?(this.writeNode("ogc:PropertyName", | |
2595 {property:e.substring(0,f)},c),c.appendChild(this.createTextNode(e.substring(++f)))):c.appendChild(this.createTextNode("${"+e));return c},StyledLayerDescriptor:function(a){var b=this.createElementNSPlus("sld:StyledLayerDescriptor",{attributes:{version:this.VERSION,"xsi:schemaLocation":this.schemaLocation}});b.setAttribute("xmlns:ogc",this.namespaces.ogc);b.setAttribute("xmlns:gml",this.namespaces.gml);a.name&&this.writeNode("Name",a.name,b);a.title&&this.writeNode("Title",a.title,b);a.description&& | |
2596 this.writeNode("Abstract",a.description,b);if(OpenLayers.Util.isArray(a.namedLayers))for(var c=0,d=a.namedLayers.length;c<d;++c)this.writeNode("NamedLayer",a.namedLayers[c],b);else for(c in a.namedLayers)this.writeNode("NamedLayer",a.namedLayers[c],b);return b},Name:function(a){return this.createElementNSPlus("sld:Name",{value:a})},Title:function(a){return this.createElementNSPlus("sld:Title",{value:a})},Abstract:function(a){return this.createElementNSPlus("sld:Abstract",{value:a})},NamedLayer:function(a){var b= | |
2597 this.createElementNSPlus("sld:NamedLayer");this.writeNode("Name",a.name,b);if(a.namedStyles)for(var c=0,d=a.namedStyles.length;c<d;++c)this.writeNode("NamedStyle",a.namedStyles[c],b);if(a.userStyles)for(c=0,d=a.userStyles.length;c<d;++c)this.writeNode("UserStyle",a.userStyles[c],b);return b},NamedStyle:function(a){var b=this.createElementNSPlus("sld:NamedStyle");this.writeNode("Name",a,b);return b},UserStyle:function(a){var b=this.createElementNSPlus("sld:UserStyle");a.name&&this.writeNode("Name", | |
2598 a.name,b);a.title&&this.writeNode("Title",a.title,b);a.description&&this.writeNode("Abstract",a.description,b);a.isDefault&&this.writeNode("IsDefault",a.isDefault,b);if(this.multipleSymbolizers&&a.rules){for(var c={0:[]},d=[0],e,f,g,h,k,l=0,m=a.rules.length;l<m;++l)if(e=a.rules[l],e.symbolizers){f={};for(var n=0,p=e.symbolizers.length;n<p;++n)g=e.symbolizers[n],h=g.zIndex,h in f||(k=e.clone(),k.symbolizers=[],f[h]=k),f[h].symbolizers.push(g.clone());for(h in f)h in c||(d.push(h),c[h]=[]),c[h].push(f[h])}else c[0].push(e.clone()); | |
2599 d.sort();l=0;for(m=d.length;l<m;++l)e=c[d[l]],0<e.length&&(k=a.clone(),k.rules=c[d[l]],this.writeNode("FeatureTypeStyle",k,b))}else this.writeNode("FeatureTypeStyle",a,b);return b},IsDefault:function(a){return this.createElementNSPlus("sld:IsDefault",{value:a?"1":"0"})},FeatureTypeStyle:function(a){for(var b=this.createElementNSPlus("sld:FeatureTypeStyle"),c=0,d=a.rules.length;c<d;++c)this.writeNode("Rule",a.rules[c],b);return b},Rule:function(a){var b=this.createElementNSPlus("sld:Rule");a.name&& | |
2600 this.writeNode("Name",a.name,b);a.title&&this.writeNode("Title",a.title,b);a.description&&this.writeNode("Abstract",a.description,b);a.elseFilter?this.writeNode("ElseFilter",null,b):a.filter&&this.writeNode("ogc:Filter",a.filter,b);void 0!=a.minScaleDenominator&&this.writeNode("MinScaleDenominator",a.minScaleDenominator,b);void 0!=a.maxScaleDenominator&&this.writeNode("MaxScaleDenominator",a.maxScaleDenominator,b);var c,d;if(this.multipleSymbolizers&&a.symbolizers)for(var e=0,f=a.symbolizers.length;e< | |
2601 f;++e)d=a.symbolizers[e],c=d.CLASS_NAME.split(".").pop(),this.writeNode(c+"Symbolizer",d,b);else for(var f=OpenLayers.Style.SYMBOLIZER_PREFIXES,e=0,g=f.length;e<g;++e)c=f[e],(d=a.symbolizer[c])&&this.writeNode(c+"Symbolizer",d,b);return b},ElseFilter:function(){return this.createElementNSPlus("sld:ElseFilter")},MinScaleDenominator:function(a){return this.createElementNSPlus("sld:MinScaleDenominator",{value:a})},MaxScaleDenominator:function(a){return this.createElementNSPlus("sld:MaxScaleDenominator", | |
2602 {value:a})},LineSymbolizer:function(a){var b=this.createElementNSPlus("sld:LineSymbolizer");this.writeNode("Stroke",a,b);return b},Stroke:function(a){var b=this.createElementNSPlus("sld:Stroke");void 0!=a.strokeColor&&this.writeNode("CssParameter",{symbolizer:a,key:"strokeColor"},b);void 0!=a.strokeOpacity&&this.writeNode("CssParameter",{symbolizer:a,key:"strokeOpacity"},b);void 0!=a.strokeWidth&&this.writeNode("CssParameter",{symbolizer:a,key:"strokeWidth"},b);void 0!=a.strokeDashstyle&&"solid"!== | |
2603 a.strokeDashstyle&&this.writeNode("CssParameter",{symbolizer:a,key:"strokeDashstyle"},b);void 0!=a.strokeLinecap&&this.writeNode("CssParameter",{symbolizer:a,key:"strokeLinecap"},b);return b},CssParameter:function(a){return this.createElementNSPlus("sld:CssParameter",{attributes:{name:this.getCssProperty(a.key)},value:a.symbolizer[a.key]})},TextSymbolizer:function(a){var b=this.createElementNSPlus("sld:TextSymbolizer");null!=a.label&&this.writeNode("Label",a.label,b);null==a.fontFamily&&null==a.fontSize&& | |
2604 null==a.fontWeight&&null==a.fontStyle||this.writeNode("Font",a,b);null==a.labelAnchorPointX&&null==a.labelAnchorPointY&&null==a.labelAlign&&null==a.labelXOffset&&null==a.labelYOffset&&null==a.labelRotation&&null==a.labelPerpendicularOffset||this.writeNode("LabelPlacement",a,b);null==a.haloRadius&&null==a.haloColor&&null==a.haloOpacity||this.writeNode("Halo",a,b);null==a.fontColor&&null==a.fontOpacity||this.writeNode("Fill",{fillColor:a.fontColor,fillOpacity:a.fontOpacity},b);return b},LabelPlacement:function(a){var b= | |
2605 this.createElementNSPlus("sld:LabelPlacement");null==a.labelAnchorPointX&&null==a.labelAnchorPointY&&null==a.labelAlign&&null==a.labelXOffset&&null==a.labelYOffset&&null==a.labelRotation||null!=a.labelPerpendicularOffset||this.writeNode("PointPlacement",a,b);null!=a.labelPerpendicularOffset&&this.writeNode("LinePlacement",a,b);return b},LinePlacement:function(a){var b=this.createElementNSPlus("sld:LinePlacement");this.writeNode("PerpendicularOffset",a.labelPerpendicularOffset,b);return b},PerpendicularOffset:function(a){return this.createElementNSPlus("sld:PerpendicularOffset", | |
2606 {value:a})},PointPlacement:function(a){var b=this.createElementNSPlus("sld:PointPlacement");null==a.labelAnchorPointX&&null==a.labelAnchorPointY&&null==a.labelAlign||this.writeNode("AnchorPoint",a,b);null==a.labelXOffset&&null==a.labelYOffset||this.writeNode("Displacement",a,b);null!=a.labelRotation&&this.writeNode("Rotation",a.labelRotation,b);return b},AnchorPoint:function(a){var b=this.createElementNSPlus("sld:AnchorPoint"),c=a.labelAnchorPointX,d=a.labelAnchorPointY;null!=c&&this.writeNode("AnchorPointX", | |
2607 c,b);null!=d&&this.writeNode("AnchorPointY",d,b);if(null==c&&null==d){var e=a.labelAlign.substr(0,1);a=a.labelAlign.substr(1,1);"l"===e?c=0:"c"===e?c=0.5:"r"===e&&(c=1);"b"===a?d=0:"m"===a?d=0.5:"t"===a&&(d=1);this.writeNode("AnchorPointX",c,b);this.writeNode("AnchorPointY",d,b)}return b},AnchorPointX:function(a){return this.createElementNSPlus("sld:AnchorPointX",{value:a})},AnchorPointY:function(a){return this.createElementNSPlus("sld:AnchorPointY",{value:a})},Displacement:function(a){var b=this.createElementNSPlus("sld:Displacement"); | |
2608 null!=a.labelXOffset&&this.writeNode("DisplacementX",a.labelXOffset,b);null!=a.labelYOffset&&this.writeNode("DisplacementY",a.labelYOffset,b);return b},DisplacementX:function(a){return this.createElementNSPlus("sld:DisplacementX",{value:a})},DisplacementY:function(a){return this.createElementNSPlus("sld:DisplacementY",{value:a})},Font:function(a){var b=this.createElementNSPlus("sld:Font");a.fontFamily&&this.writeNode("CssParameter",{symbolizer:a,key:"fontFamily"},b);a.fontSize&&this.writeNode("CssParameter", | |
2609 {symbolizer:a,key:"fontSize"},b);a.fontWeight&&this.writeNode("CssParameter",{symbolizer:a,key:"fontWeight"},b);a.fontStyle&&this.writeNode("CssParameter",{symbolizer:a,key:"fontStyle"},b);return b},Label:function(a){return this.writers.sld._OGCExpression.call(this,"sld:Label",a)},Halo:function(a){var b=this.createElementNSPlus("sld:Halo");a.haloRadius&&this.writeNode("Radius",a.haloRadius,b);(a.haloColor||a.haloOpacity)&&this.writeNode("Fill",{fillColor:a.haloColor,fillOpacity:a.haloOpacity},b); | |
2610 return b},Radius:function(a){return this.createElementNSPlus("sld:Radius",{value:a})},RasterSymbolizer:function(a){var b=this.createElementNSPlus("sld:RasterSymbolizer");a.geometry&&this.writeNode("Geometry",a.geometry,b);a.opacity&&this.writeNode("Opacity",a.opacity,b);a.colorMap&&this.writeNode("ColorMap",a.colorMap,b);return b},Geometry:function(a){var b=this.createElementNSPlus("sld:Geometry");a.property&&this.writeNode("ogc:PropertyName",a,b);return b},ColorMap:function(a){for(var b=this.createElementNSPlus("sld:ColorMap"), | |
2611 c=0,d=a.length;c<d;++c)this.writeNode("ColorMapEntry",a[c],b);return b},ColorMapEntry:function(a){var b=this.createElementNSPlus("sld:ColorMapEntry");b.setAttribute("color",a.color);void 0!==a.opacity&&b.setAttribute("opacity",parseFloat(a.opacity));void 0!==a.quantity&&b.setAttribute("quantity",parseFloat(a.quantity));void 0!==a.label&&b.setAttribute("label",a.label);return b},PolygonSymbolizer:function(a){var b=this.createElementNSPlus("sld:PolygonSymbolizer");!1!==a.fill&&this.writeNode("Fill", | |
2612 a,b);!1!==a.stroke&&this.writeNode("Stroke",a,b);return b},Fill:function(a){var b=this.createElementNSPlus("sld:Fill");a.fillColor&&this.writeNode("CssParameter",{symbolizer:a,key:"fillColor"},b);null!=a.fillOpacity&&this.writeNode("CssParameter",{symbolizer:a,key:"fillOpacity"},b);return b},PointSymbolizer:function(a){var b=this.createElementNSPlus("sld:PointSymbolizer");this.writeNode("Graphic",a,b);return b},Graphic:function(a){var b=this.createElementNSPlus("sld:Graphic");void 0!=a.externalGraphic? | |
2613 this.writeNode("ExternalGraphic",a,b):this.writeNode("Mark",a,b);void 0!=a.graphicOpacity&&this.writeNode("Opacity",a.graphicOpacity,b);void 0!=a.pointRadius?this.writeNode("Size",2*a.pointRadius,b):void 0!=a.graphicWidth&&this.writeNode("Size",a.graphicWidth,b);void 0!=a.rotation&&this.writeNode("Rotation",a.rotation,b);return b},ExternalGraphic:function(a){var b=this.createElementNSPlus("sld:ExternalGraphic");this.writeNode("OnlineResource",a.externalGraphic,b);a=a.graphicFormat||this.getGraphicFormat(a.externalGraphic); | |
2614 this.writeNode("Format",a,b);return b},Mark:function(a){var b=this.createElementNSPlus("sld:Mark");a.graphicName&&this.writeNode("WellKnownName",a.graphicName,b);!1!==a.fill&&this.writeNode("Fill",a,b);!1!==a.stroke&&this.writeNode("Stroke",a,b);return b},WellKnownName:function(a){return this.createElementNSPlus("sld:WellKnownName",{value:a})},Opacity:function(a){return this.createElementNSPlus("sld:Opacity",{value:a})},Size:function(a){return this.writers.sld._OGCExpression.call(this,"sld:Size", | |
2615 a)},Rotation:function(a){return this.createElementNSPlus("sld:Rotation",{value:a})},OnlineResource:function(a){return this.createElementNSPlus("sld:OnlineResource",{attributes:{"xlink:type":"simple","xlink:href":a}})},Format:function(a){return this.createElementNSPlus("sld:Format",{value:a})}}},OpenLayers.Format.Filter.v1_0_0.prototype.writers),CLASS_NAME:"OpenLayers.Format.SLD.v1"});OpenLayers.Layer.WMS=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{service:"WMS",version:"1.1.1",request:"GetMap",styles:"",format:"image/jpeg"},isBaseLayer:!0,encodeBBOX:!1,noMagic:!1,yx:{},initialize:function(a,b,c,d){var e=[];c=OpenLayers.Util.upperCaseObject(c);1.3<=parseFloat(c.VERSION)&&!c.EXCEPTIONS&&(c.EXCEPTIONS="INIMAGE");e.push(a,b,c,d);OpenLayers.Layer.Grid.prototype.initialize.apply(this,e);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)); | |
2616 !this.noMagic&&(this.params.TRANSPARENT&&"true"==this.params.TRANSPARENT.toString().toLowerCase())&&(null!=d&&d.isBaseLayer||(this.isBaseLayer=!1),"image/jpeg"==this.params.FORMAT&&(this.params.FORMAT=OpenLayers.Util.alphaHack()?"image/gif":"image/png"))},clone:function(a){null==a&&(a=new OpenLayers.Layer.WMS(this.name,this.url,this.params,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},reverseAxisOrder:function(){var a=this.projection.getCode();return 1.3<=parseFloat(this.params.VERSION)&& | |
2617 !!(this.yx[a]||OpenLayers.Projection.defaults[a]&&OpenLayers.Projection.defaults[a].yx)},getURL:function(a){a=this.adjustBounds(a);var b=this.getImageSize(),c={},d=this.reverseAxisOrder();c.BBOX=this.encodeBBOX?a.toBBOX(null,d):a.toArray(d);c.WIDTH=b.w;c.HEIGHT=b.h;return this.getFullRequestString(c)},mergeNewParams:function(a){a=[OpenLayers.Util.upperCaseObject(a)];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,a)},getFullRequestString:function(a,b){var c=this.map.getProjectionObject(), | |
2618 c=this.projection&&this.projection.equals(c)?this.projection.getCode():c.getCode(),c="none"==c?null:c;1.3<=parseFloat(this.params.VERSION)?this.params.CRS=c:this.params.SRS=c;"boolean"==typeof this.params.TRANSPARENT&&(a.TRANSPARENT=this.params.TRANSPARENT?"TRUE":"FALSE");return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,arguments)},CLASS_NAME:"OpenLayers.Layer.WMS"});OpenLayers.Layer.KaMap=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:!0,DEFAULT_PARAMS:{i:"jpeg",map:""},initialize:function(a,b,c,d){OpenLayers.Layer.Grid.prototype.initialize.apply(this,arguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS)},getURL:function(a){a=this.adjustBounds(a);var b=this.map.getResolution(),c=Math.round(1E4*this.map.getScale())/1E4,d=Math.round(a.left/b);a=-Math.round(a.top/b);return this.getFullRequestString({t:a,l:d,s:c})},calculateGridLayout:function(a, | |
2619 b,c){b=c*this.tileSize.w;c*=this.tileSize.h;return{tilelon:b,tilelat:c,startcol:Math.floor(a.left/b)-this.buffer,startrow:Math.floor(a.top/c)+this.buffer}},getTileBoundsForGridIndex:function(a,b){this.getTileOrigin();var c=this.gridLayout,d=c.tilelon,e=c.tilelat,f=(c.startcol+b)*d,c=(c.startrow-a)*e;return new OpenLayers.Bounds(f,c,f+d,c+e)},clone:function(a){null==a&&(a=new OpenLayers.Layer.KaMap(this.name,this.url,this.params,this.getOptions()));a=OpenLayers.Layer.Grid.prototype.clone.apply(this, | |
2620 [a]);null!=this.tileSize&&(a.tileSize=this.tileSize.clone());a.grid=[];return a},getTileBounds:function(a){var b=this.getResolution(),c=b*this.tileSize.w,b=b*this.tileSize.h,d=this.getLonLatFromViewPortPx(a);a=c*Math.floor(d.lon/c);d=b*Math.floor(d.lat/b);return new OpenLayers.Bounds(a,d,a+c,d+b)},CLASS_NAME:"OpenLayers.Layer.KaMap"});OpenLayers.Format.WMC.v1_1_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.1.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd",initialize:function(a){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[a])},read_sld_MinScaleDenominator:function(a,b){var c=parseFloat(this.getChildValue(b));0<c&&(a.maxScale=c)},read_sld_MaxScaleDenominator:function(a,b){a.minScale=parseFloat(this.getChildValue(b))},read_wmc_SRS:function(a,b){"srs"in | |
2621 a||(a.srs={});a.srs[this.getChildValue(b)]=!0},write_wmc_Layer:function(a){var b=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this,[a]);if(a.maxScale){var c=this.createElementNS(this.namespaces.sld,"sld:MinScaleDenominator");c.appendChild(this.createTextNode(a.maxScale.toPrecision(16)));b.appendChild(c)}a.minScale&&(c=this.createElementNS(this.namespaces.sld,"sld:MaxScaleDenominator"),c.appendChild(this.createTextNode(a.minScale.toPrecision(16))),b.appendChild(c));if(a.srs)for(var d in a.srs)b.appendChild(this.createElementDefaultNS("SRS", | |
2622 d));b.appendChild(this.write_wmc_FormatList(a));b.appendChild(this.write_wmc_StyleList(a));a.dimensions&&b.appendChild(this.write_wmc_DimensionList(a));b.appendChild(this.write_wmc_LayerExtension(a));return b},CLASS_NAME:"OpenLayers.Format.WMC.v1_1_0"});OpenLayers.Format.XLS=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.1.0",stringifyOutput:!0,CLASS_NAME:"OpenLayers.Format.XLS"});OpenLayers.Format.XLS.v1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{xls:"http://www.opengis.net/xls",gml:"http://www.opengis.net/gml",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},xy:!0,defaultPrefix:"xls",schemaLocation:null,read:function(a,b){OpenLayers.Util.applyDefaults(b,this.options);var c={};this.readChildNodes(a,c);return c},readers:{xls:{XLS:function(a,b){b.version=a.getAttribute("version"); | |
2623 this.readChildNodes(a,b)},Response:function(a,b){this.readChildNodes(a,b)},GeocodeResponse:function(a,b){b.responseLists=[];this.readChildNodes(a,b)},GeocodeResponseList:function(a,b){var c={features:[],numberOfGeocodedAddresses:parseInt(a.getAttribute("numberOfGeocodedAddresses"))};b.responseLists.push(c);this.readChildNodes(a,c)},GeocodedAddress:function(a,b){var c=new OpenLayers.Feature.Vector;b.features.push(c);this.readChildNodes(a,c);c.geometry=c.components[0]},GeocodeMatchCode:function(a,b){b.attributes.matchCode= | |
2624 {accuracy:parseFloat(a.getAttribute("accuracy")),matchType:a.getAttribute("matchType")}},Address:function(a,b){var c={countryCode:a.getAttribute("countryCode"),addressee:a.getAttribute("addressee"),street:[],place:[]};b.attributes.address=c;this.readChildNodes(a,c)},freeFormAddress:function(a,b){b.freeFormAddress=this.getChildValue(a)},StreetAddress:function(a,b){this.readChildNodes(a,b)},Building:function(a,b){b.building={number:a.getAttribute("number"),subdivision:a.getAttribute("subdivision"), | |
2625 buildingName:a.getAttribute("buildingName")}},Street:function(a,b){b.street.push(this.getChildValue(a))},Place:function(a,b){b.place[a.getAttribute("type")]=this.getChildValue(a)},PostalCode:function(a,b){b.postalCode=this.getChildValue(a)}},gml:OpenLayers.Format.GML.v3.prototype.readers.gml},write:function(a){return this.writers.xls.XLS.apply(this,[a])},writers:{xls:{XLS:function(a){var b=this.createElementNSPlus("xls:XLS",{attributes:{version:this.VERSION,"xsi:schemaLocation":this.schemaLocation}}); | |
2626 this.writeNode("RequestHeader",a.header,b);this.writeNode("Request",a,b);return b},RequestHeader:function(a){return this.createElementNSPlus("xls:RequestHeader")},Request:function(a){var b=this.createElementNSPlus("xls:Request",{attributes:{methodName:"GeocodeRequest",requestID:a.requestID||"",version:this.VERSION}});this.writeNode("GeocodeRequest",a.addresses,b);return b},GeocodeRequest:function(a){for(var b=this.createElementNSPlus("xls:GeocodeRequest"),c=0,d=a.length;c<d;c++)this.writeNode("Address", | |
2627 a[c],b);return b},Address:function(a){var b=this.createElementNSPlus("xls:Address",{attributes:{countryCode:a.countryCode}});a.freeFormAddress?this.writeNode("freeFormAddress",a.freeFormAddress,b):(a.street&&this.writeNode("StreetAddress",a,b),a.municipality&&this.writeNode("Municipality",a.municipality,b),a.countrySubdivision&&this.writeNode("CountrySubdivision",a.countrySubdivision,b),a.postalCode&&this.writeNode("PostalCode",a.postalCode,b));return b},freeFormAddress:function(a){return this.createElementNSPlus("freeFormAddress", | |
2628 {value:a})},StreetAddress:function(a){var b=this.createElementNSPlus("xls:StreetAddress");a.building&&this.writeNode(b,"Building",a.building);a=a.street;OpenLayers.Util.isArray(a)||(a=[a]);for(var c=0,d=a.length;c<d;c++)this.writeNode("Street",a[c],b);return b},Building:function(a){return this.createElementNSPlus("xls:Building",{attributes:{number:a.number,subdivision:a.subdivision,buildingName:a.buildingName}})},Street:function(a){return this.createElementNSPlus("xls:Street",{value:a})},Municipality:function(a){return this.createElementNSPlus("xls:Place", | |
2629 {attributes:{type:"Municipality"},value:a})},CountrySubdivision:function(a){return this.createElementNSPlus("xls:Place",{attributes:{type:"CountrySubdivision"},value:a})},PostalCode:function(a){return this.createElementNSPlus("xls:PostalCode",{value:a})}}},CLASS_NAME:"OpenLayers.Format.XLS.v1"});OpenLayers.Format.XLS.v1_1_0=OpenLayers.Class(OpenLayers.Format.XLS.v1,{VERSION:"1.1",schemaLocation:"http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/LocationUtilityService.xsd",CLASS_NAME:"OpenLayers.Format.XLS.v1_1_0"});OpenLayers.Format.XLS.v1_1=OpenLayers.Format.XLS.v1_1_0;OpenLayers.Renderer.SVG=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"http://www.w3.org/2000/svg",xlinkns:"http://www.w3.org/1999/xlink",MAX_PIXEL:15E3,translationParameters:null,symbolMetrics:null,initialize:function(a){this.supported()&&(OpenLayers.Renderer.Elements.prototype.initialize.apply(this,arguments),this.translationParameters={x:0,y:0},this.symbolMetrics={})},supported:function(){return document.implementation&&(document.implementation.hasFeature("org.w3c.svg","1.0")||document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#SVG", | |
2630 "1.1")||document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"))},inValidRange:function(a,b,c){a+=c?0:this.translationParameters.x;b+=c?0:this.translationParameters.y;return a>=-this.MAX_PIXEL&&a<=this.MAX_PIXEL&&b>=-this.MAX_PIXEL&&b<=this.MAX_PIXEL},setExtent:function(a,b){var c=OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments),d=this.getResolution(),e=-a.left/d,d=a.top/d;if(b)return this.left=e,this.top=d,this.rendererRoot.setAttributeNS(null, | |
2631 "viewBox","0 0 "+this.size.w+" "+this.size.h),this.translate(this.xOffset,0),!0;(e=this.translate(e-this.left+this.xOffset,d-this.top))||this.setExtent(a,!0);return c&&e},translate:function(a,b){if(this.inValidRange(a,b,!0)){var c="";if(a||b)c="translate("+a+","+b+")";this.root.setAttributeNS(null,"transform",c);this.translationParameters={x:a,y:b};return!0}return!1},setSize:function(a){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);this.rendererRoot.setAttributeNS(null,"width",this.size.w); | |
2632 this.rendererRoot.setAttributeNS(null,"height",this.size.h)},getNodeType:function(a,b){var c=null;switch(a.CLASS_NAME){case "OpenLayers.Geometry.Point":c=b.externalGraphic?"image":this.isComplexSymbol(b.graphicName)?"svg":"circle";break;case "OpenLayers.Geometry.Rectangle":c="rect";break;case "OpenLayers.Geometry.LineString":c="polyline";break;case "OpenLayers.Geometry.LinearRing":c="polygon";break;case "OpenLayers.Geometry.Polygon":case "OpenLayers.Geometry.Curve":c="path"}return c},setStyle:function(a, | |
2633 b,c){b=b||a._style;c=c||a._options;var d=b.title||b.graphicTitle;if(d){a.setAttributeNS(null,"title",d);var e=a.getElementsByTagName("title");0<e.length?e[0].firstChild.textContent=d:(e=this.nodeFactory(null,"title"),e.textContent=d,a.appendChild(e))}var e=parseFloat(a.getAttributeNS(null,"r")),d=1,f;if("OpenLayers.Geometry.Point"==a._geometryClass&&e){a.style.visibility="";if(!1===b.graphic)a.style.visibility="hidden";else if(b.externalGraphic){f=this.getPosition(a);b.graphicWidth&&b.graphicHeight&& | |
2634 a.setAttributeNS(null,"preserveAspectRatio","none");var e=b.graphicWidth||b.graphicHeight,g=b.graphicHeight||b.graphicWidth,e=e?e:2*b.pointRadius,g=g?g:2*b.pointRadius,h=void 0!=b.graphicYOffset?b.graphicYOffset:-(0.5*g),k=b.graphicOpacity||b.fillOpacity;a.setAttributeNS(null,"x",(f.x+(void 0!=b.graphicXOffset?b.graphicXOffset:-(0.5*e))).toFixed());a.setAttributeNS(null,"y",(f.y+h).toFixed());a.setAttributeNS(null,"width",e);a.setAttributeNS(null,"height",g);a.setAttributeNS(this.xlinkns,"xlink:href", | |
2635 b.externalGraphic);a.setAttributeNS(null,"style","opacity: "+k);a.onclick=OpenLayers.Event.preventDefault}else if(this.isComplexSymbol(b.graphicName)){var e=3*b.pointRadius,g=2*e,l=this.importSymbol(b.graphicName);f=this.getPosition(a);d=3*this.symbolMetrics[l.id][0]/g;h=a.parentNode;k=a.nextSibling;h&&h.removeChild(a);a.firstChild&&a.removeChild(a.firstChild);a.appendChild(l.firstChild.cloneNode(!0));a.setAttributeNS(null,"viewBox",l.getAttributeNS(null,"viewBox"));a.setAttributeNS(null,"width", | |
2636 g);a.setAttributeNS(null,"height",g);a.setAttributeNS(null,"x",f.x-e);a.setAttributeNS(null,"y",f.y-e);k?h.insertBefore(a,k):h&&h.appendChild(a)}else a.setAttributeNS(null,"r",b.pointRadius);e=b.rotation;void 0===e&&void 0===a._rotation||!f||(a._rotation=e,e|=0,"svg"!==a.nodeName?a.setAttributeNS(null,"transform","rotate("+e+" "+f.x+" "+f.y+")"):(f=this.symbolMetrics[l.id],a.firstChild.setAttributeNS(null,"transform","rotate("+e+" "+f[1]+" "+f[2]+")")))}c.isFilled?(a.setAttributeNS(null,"fill",b.fillColor), | |
2637 a.setAttributeNS(null,"fill-opacity",b.fillOpacity)):a.setAttributeNS(null,"fill","none");c.isStroked?(a.setAttributeNS(null,"stroke",b.strokeColor),a.setAttributeNS(null,"stroke-opacity",b.strokeOpacity),a.setAttributeNS(null,"stroke-width",b.strokeWidth*d),a.setAttributeNS(null,"stroke-linecap",b.strokeLinecap||"round"),a.setAttributeNS(null,"stroke-linejoin","round"),b.strokeDashstyle&&a.setAttributeNS(null,"stroke-dasharray",this.dashStyle(b,d))):a.setAttributeNS(null,"stroke","none");b.pointerEvents&& | |
2638 a.setAttributeNS(null,"pointer-events",b.pointerEvents);null!=b.cursor&&a.setAttributeNS(null,"cursor",b.cursor);return a},dashStyle:function(a,b){var c=a.strokeWidth*b,d=a.strokeDashstyle;switch(d){case "solid":return"none";case "dot":return[1,4*c].join();case "dash":return[4*c,4*c].join();case "dashdot":return[4*c,4*c,1,4*c].join();case "longdash":return[8*c,4*c].join();case "longdashdot":return[8*c,4*c,1,4*c].join();default:return OpenLayers.String.trim(d).replace(/\s+/g,",")}},createNode:function(a, | |
2639 b){var c=document.createElementNS(this.xmlns,a);b&&c.setAttributeNS(null,"id",b);return c},nodeTypeCompare:function(a,b){return b==a.nodeName},createRenderRoot:function(){var a=this.nodeFactory(this.container.id+"_svgRoot","svg");a.style.display="block";return a},createRoot:function(a){return this.nodeFactory(this.container.id+a,"g")},createDefs:function(){var a=this.nodeFactory(this.container.id+"_defs","defs");this.rendererRoot.appendChild(a);return a},drawPoint:function(a,b){return this.drawCircle(a, | |
2640 b,1)},drawCircle:function(a,b,c){var d=this.getResolution(),e=(b.x-this.featureDx)/d+this.left;b=this.top-b.y/d;return this.inValidRange(e,b)?(a.setAttributeNS(null,"cx",e),a.setAttributeNS(null,"cy",b),a.setAttributeNS(null,"r",c),a):!1},drawLineString:function(a,b){var c=this.getComponentsString(b.components);return c.path?(a.setAttributeNS(null,"points",c.path),c.complete?a:null):!1},drawLinearRing:function(a,b){var c=this.getComponentsString(b.components);return c.path?(a.setAttributeNS(null, | |
2641 "points",c.path),c.complete?a:null):!1},drawPolygon:function(a,b){for(var c="",d=!0,e=!0,f,g,h=0,k=b.components.length;h<k;h++)c+=" M",f=this.getComponentsString(b.components[h].components," "),(g=f.path)?(c+=" "+g,e=f.complete&&e):d=!1;return d?(a.setAttributeNS(null,"d",c+" z"),a.setAttributeNS(null,"fill-rule","evenodd"),e?a:null):!1},drawRectangle:function(a,b){var c=this.getResolution(),d=(b.x-this.featureDx)/c+this.left,e=this.top-b.y/c;return this.inValidRange(d,e)?(a.setAttributeNS(null,"x", | |
2642 d),a.setAttributeNS(null,"y",e),a.setAttributeNS(null,"width",b.width/c),a.setAttributeNS(null,"height",b.height/c),a):!1},drawText:function(a,b,c){var d=!!b.labelOutlineWidth;if(d){var e=OpenLayers.Util.extend({},b);e.fontColor=e.labelOutlineColor;e.fontStrokeColor=e.labelOutlineColor;e.fontStrokeWidth=b.labelOutlineWidth;b.labelOutlineOpacity&&(e.fontOpacity=b.labelOutlineOpacity);delete e.labelOutlineWidth;this.drawText(a,e,c)}var f=this.getResolution(),e=(c.x-this.featureDx)/f+this.left,g=c.y/ | |
2643 f-this.top,d=d?this.LABEL_OUTLINE_SUFFIX:this.LABEL_ID_SUFFIX,f=this.nodeFactory(a+d,"text");f.setAttributeNS(null,"x",e);f.setAttributeNS(null,"y",-g);b.fontColor&&f.setAttributeNS(null,"fill",b.fontColor);b.fontStrokeColor&&f.setAttributeNS(null,"stroke",b.fontStrokeColor);b.fontStrokeWidth&&f.setAttributeNS(null,"stroke-width",b.fontStrokeWidth);b.fontOpacity&&f.setAttributeNS(null,"opacity",b.fontOpacity);b.fontFamily&&f.setAttributeNS(null,"font-family",b.fontFamily);b.fontSize&&f.setAttributeNS(null, | |
2644 "font-size",b.fontSize);b.fontWeight&&f.setAttributeNS(null,"font-weight",b.fontWeight);b.fontStyle&&f.setAttributeNS(null,"font-style",b.fontStyle);!0===b.labelSelect?(f.setAttributeNS(null,"pointer-events","visible"),f._featureId=a):f.setAttributeNS(null,"pointer-events","none");g=b.labelAlign||OpenLayers.Renderer.defaultSymbolizer.labelAlign;f.setAttributeNS(null,"text-anchor",OpenLayers.Renderer.SVG.LABEL_ALIGN[g[0]]||"middle");!0===OpenLayers.IS_GECKO&&f.setAttributeNS(null,"dominant-baseline", | |
2645 OpenLayers.Renderer.SVG.LABEL_ALIGN[g[1]]||"central");for(var h=b.label.split("\n"),k=h.length;f.childNodes.length>k;)f.removeChild(f.lastChild);for(var l=0;l<k;l++){var m=this.nodeFactory(a+d+"_tspan_"+l,"tspan");!0===b.labelSelect&&(m._featureId=a,m._geometry=c,m._geometryClass=c.CLASS_NAME);!1===OpenLayers.IS_GECKO&&m.setAttributeNS(null,"baseline-shift",OpenLayers.Renderer.SVG.LABEL_VSHIFT[g[1]]||"-35%");m.setAttribute("x",e);if(0==l){var n=OpenLayers.Renderer.SVG.LABEL_VFACTOR[g[1]];null==n&& | |
2646 (n=-0.5);m.setAttribute("dy",n*(k-1)+"em")}else m.setAttribute("dy","1em");m.textContent=""===h[l]?" ":h[l];m.parentNode||f.appendChild(m)}f.parentNode||this.textRoot.appendChild(f)},getComponentsString:function(a,b){for(var c=[],d=!0,e=a.length,f=[],g,h=0;h<e;h++)g=a[h],c.push(g),(g=this.getShortString(g))?f.push(g):(0<h&&this.getShortString(a[h-1])&&f.push(this.clipLine(a[h],a[h-1])),h<e-1&&this.getShortString(a[h+1])&&f.push(this.clipLine(a[h],a[h+1])),d=!1);return{path:f.join(b||","),complete:d}}, | |
2647 clipLine:function(a,b){if(b.equals(a))return"";var c=this.getResolution(),d=this.MAX_PIXEL-this.translationParameters.x,e=this.MAX_PIXEL-this.translationParameters.y,f=(b.x-this.featureDx)/c+this.left,g=this.top-b.y/c,h=(a.x-this.featureDx)/c+this.left,c=this.top-a.y/c,k;if(h<-d||h>d)k=(c-g)/(h-f),h=0>h?-d:d,c=g+(h-f)*k;if(c<-e||c>e)k=(h-f)/(c-g),c=0>c?-e:e,h=f+(c-g)*k;return h+","+c},getShortString:function(a){var b=this.getResolution(),c=(a.x-this.featureDx)/b+this.left;a=this.top-a.y/b;return this.inValidRange(c, | |
2648 a)?c+","+a:!1},getPosition:function(a){return{x:parseFloat(a.getAttributeNS(null,"cx")),y:parseFloat(a.getAttributeNS(null,"cy"))}},importSymbol:function(a){this.defs||(this.defs=this.createDefs());var b=this.container.id+"-"+a,c=document.getElementById(b);if(null!=c)return c;var d=OpenLayers.Renderer.symbol[a];if(!d)throw Error(a+" is not a valid symbol name");a=this.nodeFactory(b,"symbol");var e=this.nodeFactory(null,"polygon");a.appendChild(e);for(var c=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE, | |
2649 0,0),f=[],g,h,k=0;k<d.length;k+=2)g=d[k],h=d[k+1],c.left=Math.min(c.left,g),c.bottom=Math.min(c.bottom,h),c.right=Math.max(c.right,g),c.top=Math.max(c.top,h),f.push(g,",",h);e.setAttributeNS(null,"points",f.join(" "));d=c.getWidth();e=c.getHeight();a.setAttributeNS(null,"viewBox",[c.left-d,c.bottom-e,3*d,3*e].join(" "));this.symbolMetrics[b]=[Math.max(d,e),c.getCenterLonLat().lon,c.getCenterLonLat().lat];this.defs.appendChild(a);return a},getFeatureIdFromEvent:function(a){var b=OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this, | |
2650 arguments);b||(b=a.target,b=b.parentNode&&b!=this.rendererRoot?b.parentNode._featureId:void 0);return b},CLASS_NAME:"OpenLayers.Renderer.SVG"});OpenLayers.Renderer.SVG.LABEL_ALIGN={l:"start",r:"end",b:"bottom",t:"hanging"};OpenLayers.Renderer.SVG.LABEL_VSHIFT={t:"-70%",b:"0"};OpenLayers.Renderer.SVG.LABEL_VFACTOR={t:0,b:-1};OpenLayers.Renderer.SVG.preventDefault=function(a){OpenLayers.Event.preventDefault(a)};OpenLayers.Format.SLD.v1_0_0=OpenLayers.Class(OpenLayers.Format.SLD.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd",CLASS_NAME:"OpenLayers.Format.SLD.v1_0_0"});OpenLayers.Format.OWSContext=OpenLayers.Class(OpenLayers.Format.Context,{defaultVersion:"0.3.1",getVersion:function(a,b){var c=OpenLayers.Format.XML.VersionedOGC.prototype.getVersion.apply(this,arguments);"0.3.0"===c&&(c=this.defaultVersion);return c},toContext:function(a){var b={};"OpenLayers.Map"==a.CLASS_NAME&&(b.bounds=a.getExtent(),b.maxExtent=a.maxExtent,b.projection=a.projection,b.size=a.getSize(),b.layers=a.layers);return b},CLASS_NAME:"OpenLayers.Format.OWSContext"});OpenLayers.Format.OWSContext.v0_3_1=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{owc:"http://www.opengis.net/ows-context",gml:"http://www.opengis.net/gml",kml:"http://www.opengis.net/kml/2.2",ogc:"http://www.opengis.net/ogc",ows:"http://www.opengis.net/ows",sld:"http://www.opengis.net/sld",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},VERSION:"0.3.1",schemaLocation:"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd", | |
2651 defaultPrefix:"owc",extractAttributes:!0,xy:!0,regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},featureNS:"http://mapserver.gis.umn.edu/mapserver",featureType:"vector",geometryName:"geometry",nestingLayerLookup:null,initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a]);OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this)},setNestingPath:function(a){if(a.layersContext)for(var b=0,c=a.layersContext.length;b<c;b++){var d= | |
2652 a.layersContext[b],e=[],f=a.title||"";a.metadata&&a.metadata.nestingPath&&(e=a.metadata.nestingPath.slice());""!=f&&e.push(f);d.metadata.nestingPath=e;d.layersContext&&this.setNestingPath(d)}},decomposeNestingPath:function(a){var b=[];if(OpenLayers.Util.isArray(a)){for(a=a.slice();0<a.length;)b.push(a.slice()),a.pop();b.reverse()}return b},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a, | |
2653 b);this.setNestingPath({layersContext:b.layersContext});a=[];this.processLayer(a,b);delete b.layersContext;b.layersContext=a;return b},processLayer:function(a,b){if(b.layersContext)for(var c=0,d=b.layersContext.length;c<d;c++){var e=b.layersContext[c];a.push(e);e.layersContext&&this.processLayer(a,e)}},write:function(a,b){this.nestingLayerLookup={};b=b||{};OpenLayers.Util.applyDefaults(b,a);var c=this.writeNode("OWSContext",b);this.nestingLayerLookup=null;this.setAttributeNS(c,this.namespaces.xsi, | |
2654 "xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this,[c])},readers:{kml:{Document:function(a,b){b.features=(new OpenLayers.Format.KML({kmlns:this.namespaces.kml,extractStyles:!0})).read(a)}},owc:{OWSContext:function(a,b){this.readChildNodes(a,b)},General:function(a,b){this.readChildNodes(a,b)},ResourceList:function(a,b){this.readChildNodes(a,b)},Layer:function(a,b){var c={metadata:{},visibility:"1"!=a.getAttribute("hidden"),queryable:"1"==a.getAttribute("queryable"), | |
2655 opacity:null!=a.getAttribute("opacity")?parseFloat(a.getAttribute("opacity")):null,name:a.getAttribute("name"),categoryLayer:null==a.getAttribute("name"),formats:[],styles:[]};b.layersContext||(b.layersContext=[]);b.layersContext.push(c);this.readChildNodes(a,c)},InlineGeometry:function(a,b){b.features=[];var c=this.getElementsByTagNameNS(a,this.namespaces.gml,"featureMember"),d;1<=c.length&&(d=c[0]);d&&d.firstChild&&(c=d.firstChild.nextSibling?d.firstChild.nextSibling:d.firstChild,this.setNamespace("feature", | |
2656 c.namespaceURI),this.featureType=c.localName||c.nodeName.split(":").pop(),this.readChildNodes(a,b))},Server:function(a,b){if(!b.service&&!b.version||b.service!=OpenLayers.Format.Context.serviceTypes.WMS)b.service=a.getAttribute("service"),b.version=a.getAttribute("version"),this.readChildNodes(a,b)},Name:function(a,b){b.name=this.getChildValue(a);this.readChildNodes(a,b)},Title:function(a,b){b.title=this.getChildValue(a);this.readChildNodes(a,b)},StyleList:function(a,b){this.readChildNodes(a,b.styles)}, | |
2657 Style:function(a,b){var c={};b.push(c);this.readChildNodes(a,c)},LegendURL:function(a,b){var c={};b.legend=c;this.readChildNodes(a,c)},OnlineResource:function(a,b){b.url=this.getAttributeNS(a,this.namespaces.xlink,"href");this.readChildNodes(a,b)}},ows:OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows,gml:OpenLayers.Format.GML.v2.prototype.readers.gml,sld:OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld,feature:OpenLayers.Format.GML.v2.prototype.readers.feature},writers:{owc:{OWSContext:function(a){var b= | |
2658 this.createElementNSPlus("OWSContext",{attributes:{version:this.VERSION,id:a.id||OpenLayers.Util.createUniqueID("OpenLayers_OWSContext_")}});this.writeNode("General",a,b);this.writeNode("ResourceList",a,b);return b},General:function(a){var b=this.createElementNSPlus("General");this.writeNode("ows:BoundingBox",a,b);this.writeNode("ows:Title",a.title||"OpenLayers OWSContext",b);return b},ResourceList:function(a){for(var b=this.createElementNSPlus("ResourceList"),c=0,d=a.layers.length;c<d;c++){var e= | |
2659 a.layers[c],f=this.decomposeNestingPath(e.metadata.nestingPath);this.writeNode("_Layer",{layer:e,subPaths:f},b)}return b},Server:function(a){var b=this.createElementNSPlus("Server",{attributes:{version:a.version,service:a.service}});this.writeNode("OnlineResource",a,b);return b},OnlineResource:function(a){return this.createElementNSPlus("OnlineResource",{attributes:{"xlink:href":a.url}})},InlineGeometry:function(a){var b=this.createElementNSPlus("InlineGeometry"),c=a.getDataExtent();null!==c&&this.writeNode("gml:boundedBy", | |
2660 c,b);for(var c=0,d=a.features.length;c<d;c++)this.writeNode("gml:featureMember",a.features[c],b);return b},StyleList:function(a){for(var b=this.createElementNSPlus("StyleList"),c=0,d=a.length;c<d;c++)this.writeNode("Style",a[c],b);return b},Style:function(a){var b=this.createElementNSPlus("Style");this.writeNode("Name",a,b);this.writeNode("Title",a,b);a.legend&&this.writeNode("LegendURL",a,b);return b},Name:function(a){return this.createElementNSPlus("Name",{value:a.name})},Title:function(a){return this.createElementNSPlus("Title", | |
2661 {value:a.title})},LegendURL:function(a){var b=this.createElementNSPlus("LegendURL");this.writeNode("OnlineResource",a.legend,b);return b},_WMS:function(a){var b=this.createElementNSPlus("Layer",{attributes:{name:a.params.LAYERS,queryable:a.queryable?"1":"0",hidden:a.visibility?"0":"1",opacity:a.hasOwnProperty("opacity")?a.opacity:null}});this.writeNode("ows:Title",a.name,b);this.writeNode("ows:OutputFormat",a.params.FORMAT,b);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WMS, | |
2662 version:a.params.VERSION,url:a.url},b);a.metadata.styles&&0<a.metadata.styles.length&&this.writeNode("StyleList",a.metadata.styles,b);return b},_Layer:function(a){var b,c,d;b=a.layer;c=a.subPaths;d=null;0<c.length?(b=c[0].join("/"),c=b.lastIndexOf("/"),d=this.nestingLayerLookup[b],c=0<c?b.substring(c+1,b.length):b,d||(d=this.createElementNSPlus("Layer"),this.writeNode("ows:Title",c,d),this.nestingLayerLookup[b]=d),a.subPaths.shift(),this.writeNode("_Layer",a,d)):(b instanceof OpenLayers.Layer.WMS? | |
2663 d=this.writeNode("_WMS",b):b instanceof OpenLayers.Layer.Vector&&(b.protocol instanceof OpenLayers.Protocol.WFS.v1?d=this.writeNode("_WFS",b):b.protocol instanceof OpenLayers.Protocol.HTTP?b.protocol.format instanceof OpenLayers.Format.GML?(b.protocol.format.version="2.1.2",d=this.writeNode("_GML",b)):b.protocol.format instanceof OpenLayers.Format.KML&&(b.protocol.format.version="2.2",d=this.writeNode("_KML",b)):(this.setNamespace("feature",this.featureNS),d=this.writeNode("_InlineGeometry",b))), | |
2664 b.options.maxScale&&this.writeNode("sld:MinScaleDenominator",b.options.maxScale,d),b.options.minScale&&this.writeNode("sld:MaxScaleDenominator",b.options.minScale,d),this.nestingLayerLookup[b.name]=d);return d},_WFS:function(a){var b=this.createElementNSPlus("Layer",{attributes:{name:a.protocol.featurePrefix+":"+a.protocol.featureType,hidden:a.visibility?"0":"1"}});this.writeNode("ows:Title",a.name,b);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.WFS,version:a.protocol.version, | |
2665 url:a.protocol.url},b);return b},_InlineGeometry:function(a){var b=this.createElementNSPlus("Layer",{attributes:{name:this.featureType,hidden:a.visibility?"0":"1"}});this.writeNode("ows:Title",a.name,b);this.writeNode("InlineGeometry",a,b);return b},_GML:function(a){var b=this.createElementNSPlus("Layer");this.writeNode("ows:Title",a.name,b);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.GML,url:a.protocol.url,version:a.protocol.format.version},b);return b},_KML:function(a){var b= | |
2666 this.createElementNSPlus("Layer");this.writeNode("ows:Title",a.name,b);this.writeNode("Server",{service:OpenLayers.Format.Context.serviceTypes.KML,version:a.protocol.format.version,url:a.protocol.url},b);return b}},gml:OpenLayers.Util.applyDefaults({boundedBy:function(a){var b=this.createElementNSPlus("gml:boundedBy");this.writeNode("gml:Box",a,b);return b}},OpenLayers.Format.GML.v2.prototype.writers.gml),ows:OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,sld:OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld, | |
2667 feature:OpenLayers.Format.GML.v2.prototype.writers.feature},CLASS_NAME:"OpenLayers.Format.OWSContext.v0_3_1"});OpenLayers.Popup=OpenLayers.Class({events:null,id:"",lonlat:null,div:null,contentSize:null,size:null,contentHTML:null,backgroundColor:"",opacity:"",border:"",contentDiv:null,groupDiv:null,closeDiv:null,autoSize:!1,minSize:null,maxSize:null,displayClass:"olPopup",contentDisplayClass:"olPopupContent",padding:0,disableFirefoxOverflowHack:!1,fixPadding:function(){"number"==typeof this.padding&&(this.padding=new OpenLayers.Bounds(this.padding,this.padding,this.padding,this.padding))},panMapIfOutOfView:!1, | |
2668 keepInMap:!1,closeOnMove:!1,map:null,initialize:function(a,b,c,d,e,f){null==a&&(a=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_"));this.id=a;this.lonlat=b;this.contentSize=null!=c?c:new OpenLayers.Size(OpenLayers.Popup.WIDTH,OpenLayers.Popup.HEIGHT);null!=d&&(this.contentHTML=d);this.backgroundColor=OpenLayers.Popup.COLOR;this.opacity=OpenLayers.Popup.OPACITY;this.border=OpenLayers.Popup.BORDER;this.div=OpenLayers.Util.createDiv(this.id,null,null,null,null,null,"hidden");this.div.className=this.displayClass; | |
2669 this.groupDiv=OpenLayers.Util.createDiv(this.id+"_GroupDiv",null,null,null,"relative",null,"hidden");a=this.div.id+"_contentDiv";this.contentDiv=OpenLayers.Util.createDiv(a,null,this.contentSize.clone(),null,"relative");this.contentDiv.className=this.contentDisplayClass;this.groupDiv.appendChild(this.contentDiv);this.div.appendChild(this.groupDiv);e&&this.addCloseBox(f);this.registerEvents()},destroy:function(){this.border=this.opacity=this.backgroundColor=this.contentHTML=this.size=this.lonlat=this.id= | |
2670 null;this.closeOnMove&&this.map&&this.map.events.unregister("movestart",this,this.hide);this.events.destroy();this.events=null;this.closeDiv&&(OpenLayers.Event.stopObservingElement(this.closeDiv),this.groupDiv.removeChild(this.closeDiv));this.closeDiv=null;this.div.removeChild(this.groupDiv);this.groupDiv=null;null!=this.map&&this.map.removePopup(this);this.panMapIfOutOfView=this.padding=this.maxSize=this.minSize=this.autoSize=this.div=this.map=null},draw:function(a){null==a&&null!=this.lonlat&&null!= | |
2671 this.map&&(a=this.map.getLayerPxFromLonLat(this.lonlat));this.closeOnMove&&this.map.events.register("movestart",this,this.hide);this.disableFirefoxOverflowHack||"firefox"!=OpenLayers.BROWSER_NAME||(this.map.events.register("movestart",this,function(){var a=document.defaultView.getComputedStyle(this.contentDiv,null).getPropertyValue("overflow");"hidden"!=a&&(this.contentDiv._oldOverflow=a,this.contentDiv.style.overflow="hidden")}),this.map.events.register("moveend",this,function(){var a=this.contentDiv._oldOverflow; | |
2672 a&&(this.contentDiv.style.overflow=a,this.contentDiv._oldOverflow=null)}));this.moveTo(a);this.autoSize||this.size||this.setSize(this.contentSize);this.setBackgroundColor();this.setOpacity();this.setBorder();this.setContentHTML();this.panMapIfOutOfView&&this.panIntoView();return this.div},updatePosition:function(){if(this.lonlat&&this.map){var a=this.map.getLayerPxFromLonLat(this.lonlat);a&&this.moveTo(a)}},moveTo:function(a){null!=a&&null!=this.div&&(this.div.style.left=a.x+"px",this.div.style.top= | |
2673 a.y+"px")},visible:function(){return OpenLayers.Element.visible(this.div)},toggle:function(){this.visible()?this.hide():this.show()},show:function(){this.div.style.display="";this.panMapIfOutOfView&&this.panIntoView()},hide:function(){this.div.style.display="none"},setSize:function(a){this.size=a.clone();var b=this.getContentDivPadding(),c=b.left+b.right,d=b.top+b.bottom;this.fixPadding();c+=this.padding.left+this.padding.right;d+=this.padding.top+this.padding.bottom;if(this.closeDiv)var e=parseInt(this.closeDiv.style.width), | |
2674 c=c+(e+b.right);this.size.w+=c;this.size.h+=d;"msie"==OpenLayers.BROWSER_NAME&&(this.contentSize.w+=b.left+b.right,this.contentSize.h+=b.bottom+b.top);null!=this.div&&(this.div.style.width=this.size.w+"px",this.div.style.height=this.size.h+"px");null!=this.contentDiv&&(this.contentDiv.style.width=a.w+"px",this.contentDiv.style.height=a.h+"px")},updateSize:function(){var a="<div class='"+this.contentDisplayClass+"'>"+this.contentDiv.innerHTML+"</div>",b=this.map?this.map.div:document.body,c=OpenLayers.Util.getRenderedDimensions(a, | |
2675 null,{displayClass:this.displayClass,containerElement:b}),d=this.getSafeContentSize(c),e=null;d.equals(c)?e=c:(c={w:d.w<c.w?d.w:null,h:d.h<c.h?d.h:null},c.w&&c.h?e=d:(a=OpenLayers.Util.getRenderedDimensions(a,c,{displayClass:this.contentDisplayClass,containerElement:b}),"hidden"!=OpenLayers.Element.getStyle(this.contentDiv,"overflow")&&a.equals(d)&&(d=OpenLayers.Util.getScrollbarWidth(),c.w?a.h+=d:a.w+=d),e=this.getSafeContentSize(a)));this.setSize(e)},setBackgroundColor:function(a){void 0!=a&&(this.backgroundColor= | |
2676 a);null!=this.div&&(this.div.style.backgroundColor=this.backgroundColor)},setOpacity:function(a){void 0!=a&&(this.opacity=a);null!=this.div&&(this.div.style.opacity=this.opacity,this.div.style.filter="alpha(opacity="+100*this.opacity+")")},setBorder:function(a){void 0!=a&&(this.border=a);null!=this.div&&(this.div.style.border=this.border)},setContentHTML:function(a){null!=a&&(this.contentHTML=a);null!=this.contentDiv&&(null!=this.contentHTML&&this.contentHTML!=this.contentDiv.innerHTML)&&(this.contentDiv.innerHTML= | |
2677 this.contentHTML,this.autoSize&&(this.registerImageListeners(),this.updateSize()))},registerImageListeners:function(){for(var a=function(){null!==this.popup.id&&(this.popup.updateSize(),this.popup.visible()&&this.popup.panMapIfOutOfView&&this.popup.panIntoView(),OpenLayers.Event.stopObserving(this.img,"load",this.img._onImgLoad))},b=this.contentDiv.getElementsByTagName("img"),c=0,d=b.length;c<d;c++){var e=b[c];if(0==e.width||0==e.height)e._onImgLoad=OpenLayers.Function.bind(a,{popup:this,img:e}), | |
2678 OpenLayers.Event.observe(e,"load",e._onImgLoad)}},getSafeContentSize:function(a){a=a.clone();var b=this.getContentDivPadding(),c=b.left+b.right,d=b.top+b.bottom;this.fixPadding();c+=this.padding.left+this.padding.right;d+=this.padding.top+this.padding.bottom;if(this.closeDiv)var e=parseInt(this.closeDiv.style.width),c=c+(e+b.right);this.minSize&&(a.w=Math.max(a.w,this.minSize.w-c),a.h=Math.max(a.h,this.minSize.h-d));this.maxSize&&(a.w=Math.min(a.w,this.maxSize.w-c),a.h=Math.min(a.h,this.maxSize.h- | |
2679 d));if(this.map&&this.map.size){e=b=0;if(this.keepInMap&&!this.panMapIfOutOfView)switch(e=this.map.getPixelFromLonLat(this.lonlat),this.relativePosition){case "tr":b=e.x;e=this.map.size.h-e.y;break;case "tl":b=this.map.size.w-e.x;e=this.map.size.h-e.y;break;case "bl":b=this.map.size.w-e.x;e=e.y;break;case "br":b=e.x;e=e.y;break;default:b=e.x,e=this.map.size.h-e.y}d=this.map.size.h-this.map.paddingForPopups.top-this.map.paddingForPopups.bottom-d-e;a.w=Math.min(a.w,this.map.size.w-this.map.paddingForPopups.left- | |
2680 this.map.paddingForPopups.right-c-b);a.h=Math.min(a.h,d)}return a},getContentDivPadding:function(){var a=this._contentDivPadding;a||(null==this.div.parentNode&&(this.div.style.display="none",document.body.appendChild(this.div)),this._contentDivPadding=a=new OpenLayers.Bounds(OpenLayers.Element.getStyle(this.contentDiv,"padding-left"),OpenLayers.Element.getStyle(this.contentDiv,"padding-bottom"),OpenLayers.Element.getStyle(this.contentDiv,"padding-right"),OpenLayers.Element.getStyle(this.contentDiv, | |
2681 "padding-top")),this.div.parentNode==document.body&&(document.body.removeChild(this.div),this.div.style.display=""));return a},addCloseBox:function(a){this.closeDiv=OpenLayers.Util.createDiv(this.id+"_close",null,{w:17,h:17});this.closeDiv.className="olPopupCloseBox";var b=this.getContentDivPadding();this.closeDiv.style.right=b.right+"px";this.closeDiv.style.top=b.top+"px";this.groupDiv.appendChild(this.closeDiv);a=a||function(a){this.hide();OpenLayers.Event.stop(a)};OpenLayers.Event.observe(this.closeDiv, | |
2682 "touchend",OpenLayers.Function.bindAsEventListener(a,this));OpenLayers.Event.observe(this.closeDiv,"click",OpenLayers.Function.bindAsEventListener(a,this))},panIntoView:function(){var a=this.map.getSize(),b=this.map.getViewPortPxFromLayerPx(new OpenLayers.Pixel(parseInt(this.div.style.left),parseInt(this.div.style.top))),c=b.clone();b.x<this.map.paddingForPopups.left?c.x=this.map.paddingForPopups.left:b.x+this.size.w>a.w-this.map.paddingForPopups.right&&(c.x=a.w-this.map.paddingForPopups.right-this.size.w); | |
2683 b.y<this.map.paddingForPopups.top?c.y=this.map.paddingForPopups.top:b.y+this.size.h>a.h-this.map.paddingForPopups.bottom&&(c.y=a.h-this.map.paddingForPopups.bottom-this.size.h);this.map.pan(b.x-c.x,b.y-c.y)},registerEvents:function(){this.events=new OpenLayers.Events(this,this.div,null,!0);this.events.on({mousedown:this.onmousedown,mousemove:this.onmousemove,mouseup:this.onmouseup,click:this.onclick,mouseout:this.onmouseout,dblclick:this.ondblclick,touchstart:function(a){OpenLayers.Event.stop(a,!0)}, | |
2684 scope:this})},onmousedown:function(a){this.mousedown=!0;OpenLayers.Event.stop(a,!0)},onmousemove:function(a){this.mousedown&&OpenLayers.Event.stop(a,!0)},onmouseup:function(a){this.mousedown&&(this.mousedown=!1,OpenLayers.Event.stop(a,!0))},onclick:function(a){OpenLayers.Event.stop(a,!0)},onmouseout:function(a){this.mousedown=!1},ondblclick:function(a){OpenLayers.Event.stop(a,!0)},CLASS_NAME:"OpenLayers.Popup"});OpenLayers.Popup.WIDTH=200;OpenLayers.Popup.HEIGHT=200;OpenLayers.Popup.COLOR="white"; | |
2685 OpenLayers.Popup.OPACITY=1;OpenLayers.Popup.BORDER="0px";OpenLayers.Control.ScaleLine=OpenLayers.Class(OpenLayers.Control,{maxWidth:100,topOutUnits:"km",topInUnits:"m",bottomOutUnits:"mi",bottomInUnits:"ft",eTop:null,eBottom:null,geodesic:!1,draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.eTop||(this.eTop=document.createElement("div"),this.eTop.className=this.displayClass+"Top",this.div.appendChild(this.eTop),this.eTop.style.visibility=""==this.topOutUnits||""==this.topInUnits?"hidden":"visible",this.eBottom=document.createElement("div"), | |
2686 this.eBottom.className=this.displayClass+"Bottom",this.div.appendChild(this.eBottom),this.eBottom.style.visibility=""==this.bottomOutUnits||""==this.bottomInUnits?"hidden":"visible");this.map.events.register("moveend",this,this.update);this.update();return this.div},getBarLen:function(a){var b=parseInt(Math.log(a)/Math.log(10)),b=Math.pow(10,b);a=parseInt(a/b);return(5<a?5:2<a?2:1)*b},update:function(){var a=this.map.getResolution();if(a){var b=this.map.getUnits(),c=OpenLayers.INCHES_PER_UNIT,d=this.maxWidth* | |
2687 a*c[b],e=1;!0===this.geodesic&&(e=(this.map.getGeodesicPixelSize().w||1E-6)*this.maxWidth/(d/c.km),d*=e);var f,g;1E5<d?(f=this.topOutUnits,g=this.bottomOutUnits):(f=this.topInUnits,g=this.bottomInUnits);var h=d/c[f],k=d/c[g],d=this.getBarLen(h),l=this.getBarLen(k),h=d/c[b]*c[f],k=l/c[b]*c[g],b=h/a/e,a=k/a/e;"visible"==this.eBottom.style.visibility&&(this.eBottom.style.width=Math.round(a)+"px",this.eBottom.innerHTML=l+" "+g);"visible"==this.eTop.style.visibility&&(this.eTop.style.width=Math.round(b)+ | |
2688 "px",this.eTop.innerHTML=d+" "+f)}},CLASS_NAME:"OpenLayers.Control.ScaleLine"});OpenLayers.Icon=OpenLayers.Class({url:null,size:null,offset:null,calculateOffset:null,imageDiv:null,px:null,initialize:function(a,b,c,d){this.url=a;this.size=b||{w:20,h:20};this.offset=c||{x:-(this.size.w/2),y:-(this.size.h/2)};this.calculateOffset=d;a=OpenLayers.Util.createUniqueID("OL_Icon_");this.imageDiv=OpenLayers.Util.createAlphaImageDiv(a)},destroy:function(){this.erase();OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);this.imageDiv.innerHTML="";this.imageDiv=null},clone:function(){return new OpenLayers.Icon(this.url, | |
2689 this.size,this.offset,this.calculateOffset)},setSize:function(a){null!=a&&(this.size=a);this.draw()},setUrl:function(a){null!=a&&(this.url=a);this.draw()},draw:function(a){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,this.size,this.url,"absolute");this.moveTo(a);return this.imageDiv},erase:function(){null!=this.imageDiv&&null!=this.imageDiv.parentNode&&OpenLayers.Element.remove(this.imageDiv)},setOpacity:function(a){OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,null,null,null, | |
2690 null,null,null,a)},moveTo:function(a){null!=a&&(this.px=a);null!=this.imageDiv&&(null==this.px?this.display(!1):(this.calculateOffset&&(this.offset=this.calculateOffset(this.size)),OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,null,{x:this.px.x+this.offset.x,y:this.px.y+this.offset.y})))},display:function(a){this.imageDiv.style.display=a?"":"none"},isDrawn:function(){return this.imageDiv&&this.imageDiv.parentNode&&11!=this.imageDiv.parentNode.nodeType},CLASS_NAME:"OpenLayers.Icon"});OpenLayers.Marker=OpenLayers.Class({icon:null,lonlat:null,events:null,map:null,initialize:function(a,b){this.lonlat=a;var c=b?b:OpenLayers.Marker.defaultIcon();null==this.icon?this.icon=c:(this.icon.url=c.url,this.icon.size=c.size,this.icon.offset=c.offset,this.icon.calculateOffset=c.calculateOffset);this.events=new OpenLayers.Events(this,this.icon.imageDiv)},destroy:function(){this.erase();this.map=null;this.events.destroy();this.events=null;null!=this.icon&&(this.icon.destroy(),this.icon=null)}, | |
2691 draw:function(a){return this.icon.draw(a)},erase:function(){null!=this.icon&&this.icon.erase()},moveTo:function(a){null!=a&&null!=this.icon&&this.icon.moveTo(a);this.lonlat=this.map.getLonLatFromLayerPx(a)},isDrawn:function(){return this.icon&&this.icon.isDrawn()},onScreen:function(){var a=!1;this.map&&(a=this.map.getExtent().containsLonLat(this.lonlat));return a},inflate:function(a){this.icon&&this.icon.setSize({w:this.icon.size.w*a,h:this.icon.size.h*a})},setOpacity:function(a){this.icon.setOpacity(a)}, | |
2692 setUrl:function(a){this.icon.setUrl(a)},display:function(a){this.icon.display(a)},CLASS_NAME:"OpenLayers.Marker"});OpenLayers.Marker.defaultIcon=function(){return new OpenLayers.Icon(OpenLayers.Util.getImageLocation("marker.png"),{w:21,h:25},{x:-10.5,y:-25})};OpenLayers.Layer.TileCache=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:!0,format:"image/png",serverResolutions:null,initialize:function(a,b,c,d){this.layername=c;OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a,b,{},d]);this.extension=this.format.split("/")[1].toLowerCase();this.extension="jpg"==this.extension?"jpeg":this.extension},clone:function(a){null==a&&(a=new OpenLayers.Layer.TileCache(this.name,this.url,this.layername,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this, | |
2693 [a])},getURL:function(a){var b=this.getServerResolution(),c=this.maxExtent,d=this.tileSize,e=Math.round((a.left-c.left)/(b*d.w));a=Math.round((a.bottom-c.bottom)/(b*d.h));b=null!=this.serverResolutions?OpenLayers.Util.indexOf(this.serverResolutions,b):this.map.getZoom();e=[this.layername,OpenLayers.Number.zeroPad(b,2),OpenLayers.Number.zeroPad(parseInt(e/1E6),3),OpenLayers.Number.zeroPad(parseInt(e/1E3)%1E3,3),OpenLayers.Number.zeroPad(parseInt(e)%1E3,3),OpenLayers.Number.zeroPad(parseInt(a/1E6), | |
2694 3),OpenLayers.Number.zeroPad(parseInt(a/1E3)%1E3,3),OpenLayers.Number.zeroPad(parseInt(a)%1E3,3)+"."+this.extension].join("/");b=this.url;OpenLayers.Util.isArray(b)&&(b=this.selectUrl(e,b));b="/"==b.charAt(b.length-1)?b:b+"/";return b+e},CLASS_NAME:"OpenLayers.Layer.TileCache"});OpenLayers.Strategy.Paging=OpenLayers.Class(OpenLayers.Strategy,{features:null,length:10,num:null,paging:!1,activate:function(){var a=OpenLayers.Strategy.prototype.activate.call(this);if(a)this.layer.events.on({beforefeaturesadded:this.cacheFeatures,scope:this});return a},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&(this.clearCache(),this.layer.events.un({beforefeaturesadded:this.cacheFeatures,scope:this}));return a},cacheFeatures:function(a){this.paging||(this.clearCache(), | |
2695 this.features=a.features,this.pageNext(a))},clearCache:function(){if(this.features)for(var a=0;a<this.features.length;++a)this.features[a].destroy();this.num=this.features=null},pageCount:function(){return Math.ceil((this.features?this.features.length:0)/this.length)},pageNum:function(){return this.num},pageLength:function(a){a&&0<a&&(this.length=a);return this.length},pageNext:function(a){var b=!1;this.features&&(null===this.num&&(this.num=-1),b=this.page((this.num+1)*this.length,a));return b},pagePrevious:function(){var a= | |
2696 !1;this.features&&(null===this.num&&(this.num=this.pageCount()),a=this.page((this.num-1)*this.length));return a},page:function(a,b){var c=!1;if(this.features&&0<=a&&a<this.features.length){var d=Math.floor(a/this.length);d!=this.num&&(this.paging=!0,c=this.features.slice(a,a+this.length),this.layer.removeFeatures(this.layer.features),this.num=d,b&&b.features?b.features=c:this.layer.addFeatures(c),this.paging=!1,c=!0)}return c},CLASS_NAME:"OpenLayers.Strategy.Paging"});OpenLayers.Control.DragFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,onStart:function(a,b){},onDrag:function(a,b){},onComplete:function(a,b){},onEnter:function(a){},onLeave:function(a){},documentDrag:!1,layer:null,feature:null,dragCallbacks:{},featureCallbacks:{},lastPixel:null,initialize:function(a,b){OpenLayers.Control.prototype.initialize.apply(this,[b]);this.layer=a;this.handlers={drag:new OpenLayers.Handler.Drag(this,OpenLayers.Util.extend({down:this.downFeature,move:this.moveFeature, | |
2697 up:this.upFeature,out:this.cancel,done:this.doneDragging},this.dragCallbacks),{documentDrag:this.documentDrag}),feature:new OpenLayers.Handler.Feature(this,this.layer,OpenLayers.Util.extend({click:this.clickFeature,clickout:this.clickoutFeature,over:this.overFeature,out:this.outFeature},this.featureCallbacks),{geometryTypes:this.geometryTypes})}},clickFeature:function(a){this.handlers.feature.touch&&(!this.over&&this.overFeature(a))&&(this.handlers.drag.dragstart(this.handlers.feature.evt),this.handlers.drag.stopDown= | |
2698 !1)},clickoutFeature:function(a){this.handlers.feature.touch&&this.over&&(this.outFeature(a),this.handlers.drag.stopDown=!0)},destroy:function(){this.layer=null;OpenLayers.Control.prototype.destroy.apply(this,[])},activate:function(){return this.handlers.feature.activate()&&OpenLayers.Control.prototype.activate.apply(this,arguments)},deactivate:function(){this.handlers.drag.deactivate();this.handlers.feature.deactivate();this.feature=null;this.dragging=!1;this.lastPixel=null;OpenLayers.Element.removeClass(this.map.viewPortDiv, | |
2699 this.displayClass+"Over");return OpenLayers.Control.prototype.deactivate.apply(this,arguments)},overFeature:function(a){var b=!1;this.handlers.drag.dragging?this.over=this.feature.id==a.id?!0:!1:(this.feature=a,this.handlers.drag.activate(),this.over=b=!0,OpenLayers.Element.addClass(this.map.viewPortDiv,this.displayClass+"Over"),this.onEnter(a));return b},downFeature:function(a){this.lastPixel=a;this.onStart(this.feature,a)},moveFeature:function(a){var b=this.map.getResolution();this.feature.geometry.move(b* | |
2700 (a.x-this.lastPixel.x),b*(this.lastPixel.y-a.y));this.layer.drawFeature(this.feature);this.lastPixel=a;this.onDrag(this.feature,a)},upFeature:function(a){this.over||this.handlers.drag.deactivate()},doneDragging:function(a){this.onComplete(this.feature,a)},outFeature:function(a){this.handlers.drag.dragging?this.feature.id==a.id&&(this.over=!1):(this.over=!1,this.handlers.drag.deactivate(),OpenLayers.Element.removeClass(this.map.viewPortDiv,this.displayClass+"Over"),this.onLeave(a),this.feature=null)}, | |
2701 cancel:function(){this.handlers.drag.deactivate();this.over=!1},setMap:function(a){this.handlers.drag.setMap(a);this.handlers.feature.setMap(a);OpenLayers.Control.prototype.setMap.apply(this,arguments)},CLASS_NAME:"OpenLayers.Control.DragFeature"});OpenLayers.Control.TransformFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,layer:null,preserveAspectRatio:!1,rotate:!0,feature:null,renderIntent:"temporary",rotationHandleSymbolizer:null,box:null,center:null,scale:1,ratio:1,rotation:0,handles:null,rotationHandles:null,dragControl:null,irregular:!1,initialize:function(a,b){OpenLayers.Control.prototype.initialize.apply(this,[b]);this.layer=a;this.rotationHandleSymbolizer||(this.rotationHandleSymbolizer={stroke:!1,pointRadius:10,fillOpacity:0, | |
2702 cursor:"pointer"});this.createBox();this.createControl()},activate:function(){var a=!1;OpenLayers.Control.prototype.activate.apply(this,arguments)&&(this.dragControl.activate(),this.layer.addFeatures([this.box]),this.rotate&&this.layer.addFeatures(this.rotationHandles),this.layer.addFeatures(this.handles),a=!0);return a},deactivate:function(){var a=!1;OpenLayers.Control.prototype.deactivate.apply(this,arguments)&&(this.layer.removeFeatures(this.handles),this.rotate&&this.layer.removeFeatures(this.rotationHandles), | |
2703 this.layer.removeFeatures([this.box]),this.dragControl.deactivate(),a=!0);return a},setMap:function(a){this.dragControl.setMap(a);OpenLayers.Control.prototype.setMap.apply(this,arguments)},setFeature:function(a,b){b=OpenLayers.Util.applyDefaults(b,{rotation:0,scale:1,ratio:1});var c=this.rotation,d=this.center;OpenLayers.Util.extend(this,b);if(!1!==this.events.triggerEvent("beforesetfeature",{feature:a})){this.feature=a;this.activate();this._setfeature=!0;var e=this.feature.geometry.getBounds();this.box.move(e.getCenterLonLat()); | |
2704 this.box.geometry.rotate(-c,d);this._angle=0;this.rotation?(c=a.geometry.clone(),c.rotate(-this.rotation,this.center),c=new OpenLayers.Feature.Vector(c.getBounds().toGeometry()),c.geometry.rotate(this.rotation,this.center),this.box.geometry.rotate(this.rotation,this.center),this.box.move(c.geometry.getBounds().getCenterLonLat()),c=c.geometry.components[0].components[0].getBounds().getCenterLonLat()):c=new OpenLayers.LonLat(e.left,e.bottom);this.handles[0].move(c);delete this._setfeature;this.events.triggerEvent("setfeature", | |
2705 {feature:a})}},unsetFeature:function(){this.active?this.deactivate():(this.feature=null,this.rotation=0,this.ratio=this.scale=1)},createBox:function(){var a=this;this.center=new OpenLayers.Geometry.Point(0,0);this.box=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([new OpenLayers.Geometry.Point(-1,-1),new OpenLayers.Geometry.Point(0,-1),new OpenLayers.Geometry.Point(1,-1),new OpenLayers.Geometry.Point(1,0),new OpenLayers.Geometry.Point(1,1),new OpenLayers.Geometry.Point(0,1),new OpenLayers.Geometry.Point(-1, | |
2706 1),new OpenLayers.Geometry.Point(-1,0),new OpenLayers.Geometry.Point(-1,-1)]),null,"string"==typeof this.renderIntent?null:this.renderIntent);this.box.geometry.move=function(b,c){a._moving=!0;OpenLayers.Geometry.LineString.prototype.move.apply(this,arguments);a.center.move(b,c);delete a._moving};for(var b=function(a,b){OpenLayers.Geometry.Point.prototype.move.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.move(a,b);this._handle.geometry.move(a,b)},c=function(a,b,c){OpenLayers.Geometry.Point.prototype.resize.apply(this, | |
2707 arguments);this._rotationHandle&&this._rotationHandle.geometry.resize(a,b,c);this._handle.geometry.resize(a,b,c)},d=function(a,b){OpenLayers.Geometry.Point.prototype.rotate.apply(this,arguments);this._rotationHandle&&this._rotationHandle.geometry.rotate(a,b);this._handle.geometry.rotate(a,b)},e=function(b,c){var d=this.x,e=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,b,c);if(!a._moving){var f=a.dragControl.handlers.drag.evt,g=!(!a._setfeature&&a.preserveAspectRatio)&&!(f&&f.shiftKey), | |
2708 h=new OpenLayers.Geometry.Point(d,e),f=a.center;this.rotate(-a.rotation,f);h.rotate(-a.rotation,f);var k=this.x-f.x,l=this.y-f.y,m=k-(this.x-h.x),n=l-(this.y-h.y);a.irregular&&!a._setfeature&&(k-=(this.x-h.x)/2,l-=(this.y-h.y)/2);this.x=d;this.y=e;h=1;g?(l=1E-5>Math.abs(n)?1:l/n,h=(1E-5>Math.abs(m)?1:k/m)/l):(m=Math.sqrt(m*m+n*n),l=Math.sqrt(k*k+l*l)/m);a._moving=!0;a.box.geometry.rotate(-a.rotation,f);delete a._moving;a.box.geometry.resize(l,f,h);a.box.geometry.rotate(a.rotation,f);a.transformFeature({scale:l, | |
2709 ratio:h});a.irregular&&!a._setfeature&&(k=f.clone(),k.x+=1E-5>Math.abs(d-f.x)?0:this.x-d,k.y+=1E-5>Math.abs(e-f.y)?0:this.y-e,a.box.geometry.move(this.x-d,this.y-e),a.transformFeature({center:k}))}},f=function(b,c){var d=this.x,e=this.y;OpenLayers.Geometry.Point.prototype.move.call(this,b,c);if(!a._moving){var f=a.dragControl.handlers.drag.evt,f=f&&f.shiftKey?45:1,g=a.center,h=this.x-g.x,k=this.y-g.y;this.x=d;this.y=e;d=Math.atan2(k-c,h-b);d=Math.atan2(k,h)-d;d*=180/Math.PI;a._angle=(a._angle+d)% | |
2710 360;d=a.rotation%f;if(Math.abs(a._angle)>=f||0!==d)d=Math.round(a._angle/f)*f-d,a._angle=0,a.box.geometry.rotate(d,g),a.transformFeature({rotation:d})}},g=Array(8),h=Array(4),k,l,m,n="sw s se e ne n nw w".split(" "),p=0;8>p;++p)k=this.box.geometry.components[p],l=new OpenLayers.Feature.Vector(k.clone(),{role:n[p]+"-resize"},"string"==typeof this.renderIntent?null:this.renderIntent),0==p%2&&(m=new OpenLayers.Feature.Vector(k.clone(),{role:n[p]+"-rotate"},"string"==typeof this.rotationHandleSymbolizer? | |
2711 null:this.rotationHandleSymbolizer),m.geometry.move=f,k._rotationHandle=m,h[p/2]=m),k.move=b,k.resize=c,k.rotate=d,l.geometry.move=e,k._handle=l,g[p]=l;this.rotationHandles=h;this.handles=g},createControl:function(){var a=this;this.dragControl=new OpenLayers.Control.DragFeature(this.layer,{documentDrag:!0,moveFeature:function(b){this.feature===a.feature&&(this.feature=a.box);OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this,arguments)},onDrag:function(b,c){b===a.box&&a.transformFeature({center:a.center})}, | |
2712 onStart:function(b,c){var d=!a.geometryTypes||-1!==OpenLayers.Util.indexOf(a.geometryTypes,b.geometry.CLASS_NAME),e=OpenLayers.Util.indexOf(a.handles,b),e=e+OpenLayers.Util.indexOf(a.rotationHandles,b);b!==a.feature&&(b!==a.box&&-2==e&&d)&&a.setFeature(b)},onComplete:function(b,c){a.events.triggerEvent("transformcomplete",{feature:a.feature})}})},drawHandles:function(){for(var a=this.layer,b=0;8>b;++b)this.rotate&&0===b%2&&a.drawFeature(this.rotationHandles[b/2],this.rotationHandleSymbolizer),a.drawFeature(this.handles[b], | |
2713 this.renderIntent)},transformFeature:function(a){if(!this._setfeature){this.scale*=a.scale||1;this.ratio*=a.ratio||1;var b=this.rotation;this.rotation=(this.rotation+(a.rotation||0))%360;if(!1!==this.events.triggerEvent("beforetransform",a)){var c=this.feature,d=c.geometry,e=this.center;d.rotate(-b,e);a.scale||a.ratio?d.resize(a.scale,e,a.ratio):a.center&&c.move(a.center.getBounds().getCenterLonLat());d.rotate(this.rotation,e);this.layer.drawFeature(c);c.toState(OpenLayers.State.UPDATE);this.events.triggerEvent("transform", | |
2714 a)}}this.layer.drawFeature(this.box,this.renderIntent);this.drawHandles()},destroy:function(){for(var a,b=0;8>b;++b)a=this.box.geometry.components[b],a._handle.destroy(),a._handle=null,a._rotationHandle&&a._rotationHandle.destroy(),a._rotationHandle=null;this.rotationHandles=this.rotationHandleSymbolizer=this.handles=this.feature=this.center=null;this.box.destroy();this.layer=this.box=null;this.dragControl.destroy();this.dragControl=null;OpenLayers.Control.prototype.destroy.apply(this,arguments)}, | |
2715 CLASS_NAME:"OpenLayers.Control.TransformFeature"});OpenLayers.Handler.Box=OpenLayers.Class(OpenLayers.Handler,{dragHandler:null,boxDivClassName:"olHandlerBoxZoomBox",boxOffsets:null,initialize:function(a,b,c){OpenLayers.Handler.prototype.initialize.apply(this,arguments);this.dragHandler=new OpenLayers.Handler.Drag(this,{down:this.startBox,move:this.moveBox,out:this.removeBox,up:this.endBox},{keyMask:this.keyMask})},destroy:function(){OpenLayers.Handler.prototype.destroy.apply(this,arguments);this.dragHandler&&(this.dragHandler.destroy(),this.dragHandler= | |
2716 null)},setMap:function(a){OpenLayers.Handler.prototype.setMap.apply(this,arguments);this.dragHandler&&this.dragHandler.setMap(a)},startBox:function(a){this.callback("start",[]);this.zoomBox=OpenLayers.Util.createDiv("zoomBox",{x:-9999,y:-9999});this.zoomBox.className=this.boxDivClassName;this.zoomBox.style.zIndex=this.map.Z_INDEX_BASE.Popup-1;this.map.viewPortDiv.appendChild(this.zoomBox);OpenLayers.Element.addClass(this.map.viewPortDiv,"olDrawBox")},moveBox:function(a){var b=this.dragHandler.start.x, | |
2717 c=this.dragHandler.start.y,d=Math.abs(b-a.x),e=Math.abs(c-a.y),f=this.getBoxOffsets();this.zoomBox.style.width=d+f.width+1+"px";this.zoomBox.style.height=e+f.height+1+"px";this.zoomBox.style.left=(a.x<b?b-d-f.left:b-f.left)+"px";this.zoomBox.style.top=(a.y<c?c-e-f.top:c-f.top)+"px"},endBox:function(a){var b;if(5<Math.abs(this.dragHandler.start.x-a.x)||5<Math.abs(this.dragHandler.start.y-a.y)){var c=this.dragHandler.start;b=Math.min(c.y,a.y);var d=Math.max(c.y,a.y),e=Math.min(c.x,a.x);a=Math.max(c.x, | |
2718 a.x);b=new OpenLayers.Bounds(e,d,a,b)}else b=this.dragHandler.start.clone();this.removeBox();this.callback("done",[b])},removeBox:function(){this.map.viewPortDiv.removeChild(this.zoomBox);this.boxOffsets=this.zoomBox=null;OpenLayers.Element.removeClass(this.map.viewPortDiv,"olDrawBox")},activate:function(){return OpenLayers.Handler.prototype.activate.apply(this,arguments)?(this.dragHandler.activate(),!0):!1},deactivate:function(){return OpenLayers.Handler.prototype.deactivate.apply(this,arguments)? | |
2719 (this.dragHandler.deactivate()&&this.zoomBox&&this.removeBox(),!0):!1},getBoxOffsets:function(){if(!this.boxOffsets){var a=document.createElement("div");a.style.position="absolute";a.style.border="1px solid black";a.style.width="3px";document.body.appendChild(a);var b=3==a.clientWidth;document.body.removeChild(a);var a=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-left-width")),c=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-right-width")),d=parseInt(OpenLayers.Element.getStyle(this.zoomBox, | |
2720 "border-top-width")),e=parseInt(OpenLayers.Element.getStyle(this.zoomBox,"border-bottom-width"));this.boxOffsets={left:a,right:c,top:d,bottom:e,width:!1===b?a+c:0,height:!1===b?d+e:0}}return this.boxOffsets},CLASS_NAME:"OpenLayers.Handler.Box"});OpenLayers.Control.ZoomBox=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,out:!1,keyMask:null,alwaysZoom:!1,zoomOnClick:!0,draw:function(){this.handler=new OpenLayers.Handler.Box(this,{done:this.zoomBox},{keyMask:this.keyMask})},zoomBox:function(a){if(a instanceof OpenLayers.Bounds){var b,c=a.getCenterPixel();if(this.out){b=Math.min(this.map.size.h/(a.bottom-a.top),this.map.size.w/(a.right-a.left));var d=this.map.getExtent(),e=this.map.getLonLatFromPixel(c),f=e.lon-d.getWidth()/ | |
2721 2*b;a=e.lon+d.getWidth()/2*b;var g=e.lat-d.getHeight()/2*b;b=e.lat+d.getHeight()/2*b;b=new OpenLayers.Bounds(f,g,a,b)}else f=this.map.getLonLatFromPixel({x:a.left,y:a.bottom}),a=this.map.getLonLatFromPixel({x:a.right,y:a.top}),b=new OpenLayers.Bounds(f.lon,f.lat,a.lon,a.lat);f=this.map.getZoom();g=this.map.getSize();a=g.w/2;g=g.h/2;b=this.map.getZoomForExtent(b);d=this.map.getResolution();e=this.map.getResolutionForZoom(b);d==e?this.map.setCenter(this.map.getLonLatFromPixel(c)):this.map.zoomTo(b, | |
2722 {x:(d*c.x-e*a)/(d-e),y:(d*c.y-e*g)/(d-e)});f==this.map.getZoom()&&!0==this.alwaysZoom&&this.map.zoomTo(f+(this.out?-1:1))}else this.zoomOnClick&&(this.out?this.map.zoomTo(this.map.getZoom()-1,a):this.map.zoomTo(this.map.getZoom()+1,a))},CLASS_NAME:"OpenLayers.Control.ZoomBox"});OpenLayers.Control.DragPan=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,panned:!1,interval:0,documentDrag:!1,kinetic:null,enableKinetic:!0,kineticInterval:10,draw:function(){if(this.enableKinetic&&OpenLayers.Kinetic){var a={interval:this.kineticInterval};"object"===typeof this.enableKinetic&&(a=OpenLayers.Util.extend(a,this.enableKinetic));this.kinetic=new OpenLayers.Kinetic(a)}this.handler=new OpenLayers.Handler.Drag(this,{move:this.panMap,done:this.panMapDone,down:this.panMapStart}, | |
2723 {interval:this.interval,documentDrag:this.documentDrag})},panMapStart:function(){this.kinetic&&this.kinetic.begin()},panMap:function(a){this.kinetic&&this.kinetic.update(a);this.panned=!0;this.map.pan(this.handler.last.x-a.x,this.handler.last.y-a.y,{dragging:!0,animate:!1})},panMapDone:function(a){if(this.panned){var b=null;this.kinetic&&(b=this.kinetic.end(a));this.map.pan(this.handler.last.x-a.x,this.handler.last.y-a.y,{dragging:!!b,animate:!1});if(b){var c=this;this.kinetic.move(b,function(a,b, | |
2724 f){c.map.pan(a,b,{dragging:!f,animate:!1})})}this.panned=!1}},CLASS_NAME:"OpenLayers.Control.DragPan"});OpenLayers.Control.Navigation=OpenLayers.Class(OpenLayers.Control,{dragPan:null,dragPanOptions:null,pinchZoom:null,pinchZoomOptions:null,documentDrag:!1,zoomBox:null,zoomBoxEnabled:!0,zoomWheelEnabled:!0,mouseWheelOptions:null,handleRightClicks:!1,zoomBoxKeyMask:OpenLayers.Handler.MOD_SHIFT,autoActivate:!0,initialize:function(a){this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,arguments)},destroy:function(){this.deactivate();this.dragPan&&this.dragPan.destroy();this.dragPan=null; | |
2725 this.zoomBox&&this.zoomBox.destroy();this.zoomBox=null;this.pinchZoom&&this.pinchZoom.destroy();this.pinchZoom=null;OpenLayers.Control.prototype.destroy.apply(this,arguments)},activate:function(){this.dragPan.activate();this.zoomWheelEnabled&&this.handlers.wheel.activate();this.handlers.click.activate();this.zoomBoxEnabled&&this.zoomBox.activate();this.pinchZoom&&this.pinchZoom.activate();return OpenLayers.Control.prototype.activate.apply(this,arguments)},deactivate:function(){this.pinchZoom&&this.pinchZoom.deactivate(); | |
2726 this.zoomBox.deactivate();this.dragPan.deactivate();this.handlers.click.deactivate();this.handlers.wheel.deactivate();return OpenLayers.Control.prototype.deactivate.apply(this,arguments)},draw:function(){this.handleRightClicks&&(this.map.viewPortDiv.oncontextmenu=OpenLayers.Function.False);this.handlers.click=new OpenLayers.Handler.Click(this,{click:this.defaultClick,dblclick:this.defaultDblClick,dblrightclick:this.defaultDblRightClick},{"double":!0,stopDouble:!0});this.dragPan=new OpenLayers.Control.DragPan(OpenLayers.Util.extend({map:this.map, | |
2727 documentDrag:this.documentDrag},this.dragPanOptions));this.zoomBox=new OpenLayers.Control.ZoomBox({map:this.map,keyMask:this.zoomBoxKeyMask});this.dragPan.draw();this.zoomBox.draw();this.handlers.wheel=new OpenLayers.Handler.MouseWheel(this,{up:this.wheelUp,down:this.wheelDown},OpenLayers.Util.extend(this.map.fractionalZoom?{}:{cumulative:!1,interval:50,maxDelta:6},this.mouseWheelOptions));OpenLayers.Control.PinchZoom&&(this.pinchZoom=new OpenLayers.Control.PinchZoom(OpenLayers.Util.extend({map:this.map}, | |
2728 this.pinchZoomOptions)))},defaultClick:function(a){a.lastTouches&&2==a.lastTouches.length&&this.map.zoomOut()},defaultDblClick:function(a){this.map.zoomTo(this.map.zoom+1,a.xy)},defaultDblRightClick:function(a){this.map.zoomTo(this.map.zoom-1,a.xy)},wheelChange:function(a,b){this.map.fractionalZoom||(b=Math.round(b));var c=this.map.getZoom(),d;d=Math.max(c+b,0);d=Math.min(d,this.map.getNumZoomLevels());d!==c&&this.map.zoomTo(d,a.xy)},wheelUp:function(a,b){this.wheelChange(a,b||1)},wheelDown:function(a, | |
2729 b){this.wheelChange(a,b||-1)},disableZoomBox:function(){this.zoomBoxEnabled=!1;this.zoomBox.deactivate()},enableZoomBox:function(){this.zoomBoxEnabled=!0;this.active&&this.zoomBox.activate()},disableZoomWheel:function(){this.zoomWheelEnabled=!1;this.handlers.wheel.deactivate()},enableZoomWheel:function(){this.zoomWheelEnabled=!0;this.active&&this.handlers.wheel.activate()},CLASS_NAME:"OpenLayers.Control.Navigation"});OpenLayers.Control.DrawFeature=OpenLayers.Class(OpenLayers.Control,{layer:null,callbacks:null,multi:!1,featureAdded:function(){},initialize:function(a,b,c){OpenLayers.Control.prototype.initialize.apply(this,[c]);this.callbacks=OpenLayers.Util.extend({done:this.drawFeature,modify:function(a,b){this.layer.events.triggerEvent("sketchmodified",{vertex:a,feature:b})},create:function(a,b){this.layer.events.triggerEvent("sketchstarted",{vertex:a,feature:b})}},this.callbacks);this.layer=a;this.handlerOptions= | |
2730 this.handlerOptions||{};this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{renderers:a.renderers,rendererOptions:a.rendererOptions});"multi"in this.handlerOptions||(this.handlerOptions.multi=this.multi);if(a=this.layer.styleMap&&this.layer.styleMap.styles.temporary)this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":a})});this.handler=new b(this,this.callbacks,this.handlerOptions)}, | |
2731 drawFeature:function(a){a=new OpenLayers.Feature.Vector(a);!1!==this.layer.events.triggerEvent("sketchcomplete",{feature:a})&&(a.state=OpenLayers.State.INSERT,this.layer.addFeatures([a]),this.featureAdded(a),this.events.triggerEvent("featureadded",{feature:a}))},insertXY:function(a,b){this.handler&&this.handler.line&&this.handler.insertXY(a,b)},insertDeltaXY:function(a,b){this.handler&&this.handler.line&&this.handler.insertDeltaXY(a,b)},insertDirectionLength:function(a,b){this.handler&&this.handler.line&& | |
2732 this.handler.insertDirectionLength(a,b)},insertDeflectionLength:function(a,b){this.handler&&this.handler.line&&this.handler.insertDeflectionLength(a,b)},undo:function(){return this.handler.undo&&this.handler.undo()},redo:function(){return this.handler.redo&&this.handler.redo()},finishSketch:function(){this.handler.finishGeometry()},cancel:function(){this.handler.cancel()},CLASS_NAME:"OpenLayers.Control.DrawFeature"});OpenLayers.Handler.Polygon=OpenLayers.Class(OpenLayers.Handler.Path,{holeModifier:null,drawingHole:!1,polygon:null,createFeature:function(a){a=this.layer.getLonLatFromViewPortPx(a);a=new OpenLayers.Geometry.Point(a.lon,a.lat);this.point=new OpenLayers.Feature.Vector(a);this.line=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LinearRing([this.point.geometry]));this.polygon=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon([this.line.geometry]));this.callback("create",[this.point.geometry, | |
2733 this.getSketch()]);this.point.geometry.clearBounds();this.layer.addFeatures([this.polygon,this.point],{silent:!0})},addPoint:function(a){if(!this.drawingHole&&this.holeModifier&&this.evt&&this.evt[this.holeModifier])for(var b=this.point.geometry,c=this.control.layer.features,d,e=c.length-1;0<=e;--e)if(d=c[e].geometry,(d instanceof OpenLayers.Geometry.Polygon||d instanceof OpenLayers.Geometry.MultiPolygon)&&d.intersects(b)){b=c[e];this.control.layer.removeFeatures([b],{silent:!0});this.control.layer.events.registerPriority("sketchcomplete", | |
2734 this,this.finalizeInteriorRing);this.control.layer.events.registerPriority("sketchmodified",this,this.enforceTopology);b.geometry.addComponent(this.line.geometry);this.polygon=b;this.drawingHole=!0;break}OpenLayers.Handler.Path.prototype.addPoint.apply(this,arguments)},getCurrentPointIndex:function(){return this.line.geometry.components.length-2},enforceTopology:function(a){a=a.vertex;var b=this.line.geometry.components;this.polygon.geometry.intersects(a)||(b=b[b.length-3],a.x=b.x,a.y=b.y)},finishGeometry:function(){this.line.geometry.removeComponent(this.line.geometry.components[this.line.geometry.components.length- | |
2735 2]);this.removePoint();this.finalize()},finalizeInteriorRing:function(){var a=this.line.geometry,b=0!==a.getArea();if(b){for(var c=this.polygon.geometry.components,d=c.length-2;0<=d;--d)if(a.intersects(c[d])){b=!1;break}if(b)a:for(d=c.length-2;0<d;--d)for(var e=c[d].components,f=0,g=e.length;f<g;++f)if(a.containsPoint(e[f])){b=!1;break a}}b?this.polygon.state!==OpenLayers.State.INSERT&&(this.polygon.state=OpenLayers.State.UPDATE):this.polygon.geometry.removeComponent(a);this.restoreFeature();return!1}, | |
2736 cancel:function(){this.drawingHole&&(this.polygon.geometry.removeComponent(this.line.geometry),this.restoreFeature(!0));return OpenLayers.Handler.Path.prototype.cancel.apply(this,arguments)},restoreFeature:function(a){this.control.layer.events.unregister("sketchcomplete",this,this.finalizeInteriorRing);this.control.layer.events.unregister("sketchmodified",this,this.enforceTopology);this.layer.removeFeatures([this.polygon],{silent:!0});this.control.layer.addFeatures([this.polygon],{silent:!0});this.drawingHole= | |
2737 !1;a||this.control.layer.events.triggerEvent("sketchcomplete",{feature:this.polygon})},destroyFeature:function(a){OpenLayers.Handler.Path.prototype.destroyFeature.call(this,a);this.polygon=null},drawFeature:function(){this.layer.drawFeature(this.polygon,this.style);this.layer.drawFeature(this.point,this.style)},getSketch:function(){return this.polygon},getGeometry:function(){var a=this.polygon&&this.polygon.geometry;a&&this.multi&&(a=new OpenLayers.Geometry.MultiPolygon([a]));return a},CLASS_NAME:"OpenLayers.Handler.Polygon"});OpenLayers.Control.EditingToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{citeCompliant:!1,initialize:function(a,b){OpenLayers.Control.Panel.prototype.initialize.apply(this,[b]);this.addControls([new OpenLayers.Control.Navigation]);var c=[new OpenLayers.Control.DrawFeature(a,OpenLayers.Handler.Point,{displayClass:"olControlDrawFeaturePoint",handlerOptions:{citeCompliant:this.citeCompliant}}),new OpenLayers.Control.DrawFeature(a,OpenLayers.Handler.Path,{displayClass:"olControlDrawFeaturePath",handlerOptions:{citeCompliant:this.citeCompliant}}), | |
2738 new OpenLayers.Control.DrawFeature(a,OpenLayers.Handler.Polygon,{displayClass:"olControlDrawFeaturePolygon",handlerOptions:{citeCompliant:this.citeCompliant}})];this.addControls(c)},draw:function(){var a=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);null===this.defaultControl&&(this.defaultControl=this.controls[0]);return a},CLASS_NAME:"OpenLayers.Control.EditingToolbar"});OpenLayers.Strategy.BBOX=OpenLayers.Class(OpenLayers.Strategy,{bounds:null,resolution:null,ratio:2,resFactor:null,response:null,activate:function(){var a=OpenLayers.Strategy.prototype.activate.call(this);a&&(this.layer.events.on({moveend:this.update,refresh:this.update,visibilitychanged:this.update,scope:this}),this.update());return a},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&this.layer.events.un({moveend:this.update,refresh:this.update,visibilitychanged:this.update, | |
2739 scope:this});return a},update:function(a){var b=this.getMapBounds();null!==b&&(a&&a.force||this.layer.visibility&&this.layer.calculateInRange()&&this.invalidBounds(b))&&(this.calculateBounds(b),this.resolution=this.layer.map.getResolution(),this.triggerRead(a))},getMapBounds:function(){if(null===this.layer.map)return null;var a=this.layer.map.getExtent();a&&!this.layer.projection.equals(this.layer.map.getProjectionObject())&&(a=a.clone().transform(this.layer.map.getProjectionObject(),this.layer.projection)); | |
2740 return a},invalidBounds:function(a){a||(a=this.getMapBounds());a=!this.bounds||!this.bounds.containsBounds(a);!a&&this.resFactor&&(a=this.resolution/this.layer.map.getResolution(),a=a>=this.resFactor||a<=1/this.resFactor);return a},calculateBounds:function(a){a||(a=this.getMapBounds());var b=a.getCenterLonLat(),c=a.getWidth()*this.ratio;a=a.getHeight()*this.ratio;this.bounds=new OpenLayers.Bounds(b.lon-c/2,b.lat-a/2,b.lon+c/2,b.lat+a/2)},triggerRead:function(a){!this.response||a&&!0===a.noAbort|| | |
2741 (this.layer.protocol.abort(this.response),this.layer.events.triggerEvent("loadend"));var b={filter:this.createFilter()};this.layer.events.triggerEvent("loadstart",b);this.response=this.layer.protocol.read(OpenLayers.Util.applyDefaults({filter:b.filter,callback:this.merge,scope:this},a))},createFilter:function(){var a=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,value:this.bounds,projection:this.layer.projection});this.layer.filter&&(a=new OpenLayers.Filter.Logical({type:OpenLayers.Filter.Logical.AND, | |
2742 filters:[this.layer.filter,a]}));return a},merge:function(a){this.layer.destroyFeatures();if(a.success()){var b=a.features;if(b&&0<b.length){var c=this.layer.projection,d=this.layer.map.getProjectionObject();if(!d.equals(c))for(var e,f=0,g=b.length;f<g;++f)(e=b[f].geometry)&&e.transform(c,d);this.layer.addFeatures(b)}}else this.bounds=null;this.response=null;this.layer.events.triggerEvent("loadend",{response:a})},CLASS_NAME:"OpenLayers.Strategy.BBOX"});OpenLayers.Layer.WorldWind=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{},isBaseLayer:!0,lzd:null,zoomLevels:null,initialize:function(a,b,c,d,e,f){this.lzd=c;this.zoomLevels=d;c=[];c.push(a,b,e,f);OpenLayers.Layer.Grid.prototype.initialize.apply(this,c);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS)},getZoom:function(){var a=this.map.getZoom();this.map.getMaxExtent();return a-=Math.log(this.maxResolution/(this.lzd/512))/Math.log(2)},getURL:function(a){a=this.adjustBounds(a); | |
2743 var b=this.getZoom(),c=this.map.getMaxExtent(),d=this.lzd/Math.pow(2,this.getZoom()),e=Math.floor((a.left-c.left)/d);a=Math.floor((a.bottom-c.bottom)/d);return this.map.getResolution()<=this.lzd/512&&this.getZoom()<=this.zoomLevels?this.getFullRequestString({L:b,X:e,Y:a}):OpenLayers.Util.getImageLocation("blank.gif")},CLASS_NAME:"OpenLayers.Layer.WorldWind"});OpenLayers.Protocol.CSW=function(a){a=OpenLayers.Util.applyDefaults(a,OpenLayers.Protocol.CSW.DEFAULTS);var b=OpenLayers.Protocol.CSW["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported CSW version: "+a.version;return new b(a)};OpenLayers.Protocol.CSW.DEFAULTS={version:"2.0.2"};OpenLayers.Format.WMTSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.0.0",yx:{"urn:ogc:def:crs:EPSG::4326":!0},createLayer:function(a,b){if(!("layer"in b))throw Error("Missing property 'layer' in configuration.");for(var c=a.contents,d,e=0,f=c.layers.length;e<f;++e)if(c.layers[e].identifier===b.layer){d=c.layers[e];break}if(!d)throw Error("Layer not found");var g=b.format;!g&&(d.formats&&d.formats.length)&&(g=d.formats[0]);var h;b.matrixSet?h=c.tileMatrixSets[b.matrixSet]: | |
2744 1<=d.tileMatrixSetLinks.length&&(h=c.tileMatrixSets[d.tileMatrixSetLinks[0].tileMatrixSet]);if(!h)throw Error("matrixSet not found");for(var k,e=0,f=d.styles.length;e<f&&(k=d.styles[e],!k.isDefault);++e);c=b.requestEncoding;if(!c&&(c="KVP",a.operationsMetadata.GetTile.dcp.http)){var l=a.operationsMetadata.GetTile.dcp.http;l.get[0].constraints&&(l=l.get[0].constraints.GetEncoding.allowedValues,l.KVP||!l.REST&&!l.RESTful||(c="REST"))}var l=[],m=b.params||{};delete b.params;for(var n=0,p=d.dimensions.length;n< | |
2745 p;n++){var q=d.dimensions[n];l.push(q.identifier);m.hasOwnProperty(q.identifier)||(m[q.identifier]=q["default"])}var n=b.projection||h.supportedCRS.replace(/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/,"$1:$3"),p=b.units||("EPSG:4326"===n?"degrees":"m"),q=[],r;for(r in h.matrixIds)h.matrixIds.hasOwnProperty(r)&&q.push(2.8E-4*h.matrixIds[r].scaleDenominator/OpenLayers.METERS_PER_INCH/OpenLayers.INCHES_PER_UNIT[p]);if("REST"===c&&d.resourceUrls){r=[];for(var f=0,s=d.resourceUrls.length;f<s;++f)e=d.resourceUrls[f], | |
2746 e.format===g&&"tile"===e.resourceType&&r.push(e.template)}else{s=a.operationsMetadata.GetTile.dcp.http.get;r=[];for(var t,e=0,f=s.length;e<f;e++)t=s[e].constraints,(!t||t&&t.GetEncoding.allowedValues[c])&&r.push(s[e].url)}return new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults(b,{url:r,requestEncoding:c,name:d.title,style:k.identifier,format:g,matrixIds:h.matrixIds,matrixSet:h.identifier,projection:n,units:p,resolutions:!1===b.isBaseLayer?void 0:q,serverResolutions:q,tileFullExtent:h.bounds, | |
2747 dimensions:l,params:m}))},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities"});OpenLayers.Layer.Google.v3={DEFAULTS:{sphericalMercator:!0,projection:"EPSG:900913"},animationEnabled:!0,loadMapObject:function(){this.type||(this.type=google.maps.MapTypeId.ROADMAP);var a,b=OpenLayers.Layer.Google.cache[this.map.id];b?(a=b.mapObject,++b.count):(a=this.map.getCenter(),b=document.createElement("div"),b.className="olForeignContainer",b.style.width="100%",b.style.height="100%",a=new google.maps.Map(b,{center:a?new google.maps.LatLng(a.lat,a.lon):new google.maps.LatLng(0,0),zoom:this.map.getZoom()|| | |
2748 0,mapTypeId:this.type,disableDefaultUI:!0,keyboardShortcuts:!1,draggable:!1,disableDoubleClickZoom:!0,scrollwheel:!1,streetViewControl:!1}),b=document.createElement("div"),b.style.width="100%",b.style.height="100%",a.controls[google.maps.ControlPosition.TOP_LEFT].push(b),b={googleControl:b,mapObject:a,count:1},OpenLayers.Layer.Google.cache[this.map.id]=b);this.mapObject=a;this.setGMapVisibility(this.visibility)},onMapResize:function(){this.visibility&&google.maps.event.trigger(this.mapObject,"resize")}, | |
2749 setGMapVisibility:function(a){var b=OpenLayers.Layer.Google.cache[this.map.id],c=this.map;if(b){for(var d=this.type,e=c.layers,f,g=e.length-1;0<=g;--g)if(f=e[g],f instanceof OpenLayers.Layer.Google&&!0===f.visibility&&!0===f.inRange){d=f.type;a=!0;break}e=this.mapObject.getDiv();if(!0===a){if(e.parentNode!==c.div)if(b.rendered)c.div.appendChild(e),b.googleControl.appendChild(c.viewPortDiv),google.maps.event.trigger(this.mapObject,"resize");else{var h=this;google.maps.event.addListenerOnce(this.mapObject, | |
2750 "tilesloaded",function(){b.rendered=!0;h.setGMapVisibility(h.getVisibility());h.moveTo(h.map.getCenter())})}this.mapObject.setMapTypeId(d)}else b.googleControl.hasChildNodes()&&(c.div.appendChild(c.viewPortDiv),c.div.removeChild(e))}},getMapContainer:function(){return this.mapObject.getDiv()},getMapObjectBoundsFromOLBounds:function(a){var b=null;null!=a&&(b=this.sphericalMercator?this.inverseMercator(a.bottom,a.left):new OpenLayers.LonLat(a.bottom,a.left),a=this.sphericalMercator?this.inverseMercator(a.top, | |
2751 a.right):new OpenLayers.LonLat(a.top,a.right),b=new google.maps.LatLngBounds(new google.maps.LatLng(b.lat,b.lon),new google.maps.LatLng(a.lat,a.lon)));return b},getMapObjectLonLatFromMapObjectPixel:function(a){var b=this.map.getSize(),c=this.getLongitudeFromMapObjectLonLat(this.mapObject.center),d=this.getLatitudeFromMapObjectLonLat(this.mapObject.center),e=this.map.getResolution();a=new OpenLayers.LonLat(c+(a.x-b.w/2)*e,d-(a.y-b.h/2)*e);this.wrapDateLine&&(a=a.wrapDateLine(this.maxExtent));return this.getMapObjectLonLatFromLonLat(a.lon, | |
2752 a.lat)},getMapObjectPixelFromMapObjectLonLat:function(a){var b=this.getLongitudeFromMapObjectLonLat(a);a=this.getLatitudeFromMapObjectLonLat(a);var c=this.map.getResolution(),d=this.map.getExtent();return this.getMapObjectPixelFromXY(1/c*(b-d.left),1/c*(d.top-a))},setMapObjectCenter:function(a,b){if(!1===this.animationEnabled&&b!=this.mapObject.zoom){var c=this.getMapContainer();google.maps.event.addListenerOnce(this.mapObject,"idle",function(){c.style.visibility=""});c.style.visibility="hidden"}this.mapObject.setOptions({center:a, | |
2753 zoom:b})},getMapObjectZoomFromMapObjectBounds:function(a){return this.mapObject.getBoundsZoomLevel(a)},getMapObjectLonLatFromLonLat:function(a,b){var c;this.sphericalMercator?(c=this.inverseMercator(a,b),c=new google.maps.LatLng(c.lat,c.lon)):c=new google.maps.LatLng(b,a);return c},getMapObjectPixelFromXY:function(a,b){return new google.maps.Point(a,b)}};OpenLayers.Format.WPSDescribeProcess=OpenLayers.Class(OpenLayers.Format.XML,{VERSION:"1.0.0",namespaces:{wps:"http://www.opengis.net/wps/1.0.0",ows:"http://www.opengis.net/ows/1.1",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd",defaultPrefix:"wps",regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this, | |
2754 [a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b},readers:{wps:{ProcessDescriptions:function(a,b){b.processDescriptions={};this.readChildNodes(a,b.processDescriptions)},ProcessDescription:function(a,b){var c={processVersion:this.getAttributeNS(a,this.namespaces.wps,"processVersion"),statusSupported:"true"===a.getAttribute("statusSupported"),storeSupported:"true"===a.getAttribute("storeSupported")};this.readChildNodes(a,c);b[c.identifier]=c},DataInputs:function(a, | |
2755 b){b.dataInputs=[];this.readChildNodes(a,b.dataInputs)},ProcessOutputs:function(a,b){b.processOutputs=[];this.readChildNodes(a,b.processOutputs)},Output:function(a,b){var c={};this.readChildNodes(a,c);b.push(c)},ComplexOutput:function(a,b){b.complexOutput={};this.readChildNodes(a,b.complexOutput)},LiteralOutput:function(a,b){b.literalOutput={};this.readChildNodes(a,b.literalOutput)},Input:function(a,b){var c={maxOccurs:parseInt(a.getAttribute("maxOccurs")),minOccurs:parseInt(a.getAttribute("minOccurs"))}; | |
2756 this.readChildNodes(a,c);b.push(c)},BoundingBoxData:function(a,b){b.boundingBoxData={};this.readChildNodes(a,b.boundingBoxData)},CRS:function(a,b){b.CRSs||(b.CRSs={});b.CRSs[this.getChildValue(a)]=!0},LiteralData:function(a,b){b.literalData={};this.readChildNodes(a,b.literalData)},ComplexData:function(a,b){b.complexData={};this.readChildNodes(a,b.complexData)},Default:function(a,b){b["default"]={};this.readChildNodes(a,b["default"])},Supported:function(a,b){b.supported={};this.readChildNodes(a,b.supported)}, | |
2757 Format:function(a,b){var c={};this.readChildNodes(a,c);b.formats||(b.formats={});b.formats[c.mimeType]=!0},MimeType:function(a,b){b.mimeType=this.getChildValue(a)}},ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows},CLASS_NAME:"OpenLayers.Format.WPSDescribeProcess"});OpenLayers.Format.WKT=OpenLayers.Class(OpenLayers.Format,{initialize:function(a){this.regExes={typeStr:/^\s*(\w+)\s*\(\s*(.*)\s*\)\s*$/,spaces:/\s+/,parenComma:/\)\s*,\s*\(/,doubleParenComma:/\)\s*\)\s*,\s*\(\s*\(/,trimParens:/^\s*\(?(.*?)\)?\s*$/};OpenLayers.Format.prototype.initialize.apply(this,[a])},read:function(a){var b,c;a=a.replace(/[\n\r]/g," ");if(c=this.regExes.typeStr.exec(a))if(a=c[1].toLowerCase(),c=c[2],this.parse[a]&&(b=this.parse[a].apply(this,[c])),this.internalProjection&&this.externalProjection)if(b&& | |
2758 "OpenLayers.Feature.Vector"==b.CLASS_NAME)b.geometry.transform(this.externalProjection,this.internalProjection);else if(b&&"geometrycollection"!=a&&"object"==typeof b)for(a=0,c=b.length;a<c;a++)b[a].geometry.transform(this.externalProjection,this.internalProjection);return b},write:function(a){var b,c;a.constructor==Array?c=!0:(a=[a],c=!1);var d=[];c&&d.push("GEOMETRYCOLLECTION(");for(var e=0,f=a.length;e<f;++e)c&&0<e&&d.push(","),b=a[e].geometry,d.push(this.extractGeometry(b));c&&d.push(")");return d.join("")}, | |
2759 extractGeometry:function(a){var b=a.CLASS_NAME.split(".")[2].toLowerCase();if(!this.extract[b])return null;this.internalProjection&&this.externalProjection&&(a=a.clone(),a.transform(this.internalProjection,this.externalProjection));return("collection"==b?"GEOMETRYCOLLECTION":b.toUpperCase())+"("+this.extract[b].apply(this,[a])+")"},extract:{point:function(a){return a.x+" "+a.y},multipoint:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push("("+this.extract.point.apply(this,[a.components[c]])+ | |
2760 ")");return b.join(",")},linestring:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push(this.extract.point.apply(this,[a.components[c]]));return b.join(",")},multilinestring:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push("("+this.extract.linestring.apply(this,[a.components[c]])+")");return b.join(",")},polygon:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push("("+this.extract.linestring.apply(this,[a.components[c]])+")");return b.join(",")},multipolygon:function(a){for(var b= | |
2761 [],c=0,d=a.components.length;c<d;++c)b.push("("+this.extract.polygon.apply(this,[a.components[c]])+")");return b.join(",")},collection:function(a){for(var b=[],c=0,d=a.components.length;c<d;++c)b.push(this.extractGeometry.apply(this,[a.components[c]]));return b.join(",")}},parse:{point:function(a){a=OpenLayers.String.trim(a).split(this.regExes.spaces);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(a[0],a[1]))},multipoint:function(a){for(var b=OpenLayers.String.trim(a).split(","), | |
2762 c=[],d=0,e=b.length;d<e;++d)a=b[d].replace(this.regExes.trimParens,"$1"),c.push(this.parse.point.apply(this,[a]).geometry);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint(c))},linestring:function(a){a=OpenLayers.String.trim(a).split(",");for(var b=[],c=0,d=a.length;c<d;++c)b.push(this.parse.point.apply(this,[a[c]]).geometry);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(b))},multilinestring:function(a){for(var b=OpenLayers.String.trim(a).split(this.regExes.parenComma), | |
2763 c=[],d=0,e=b.length;d<e;++d)a=b[d].replace(this.regExes.trimParens,"$1"),c.push(this.parse.linestring.apply(this,[a]).geometry);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiLineString(c))},polygon:function(a){var b;a=OpenLayers.String.trim(a).split(this.regExes.parenComma);for(var c=[],d=0,e=a.length;d<e;++d)b=a[d].replace(this.regExes.trimParens,"$1"),b=this.parse.linestring.apply(this,[b]).geometry,b=new OpenLayers.Geometry.LinearRing(b.components),c.push(b);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon(c))}, | |
2764 multipolygon:function(a){for(var b=OpenLayers.String.trim(a).split(this.regExes.doubleParenComma),c=[],d=0,e=b.length;d<e;++d)a=b[d].replace(this.regExes.trimParens,"$1"),c.push(this.parse.polygon.apply(this,[a]).geometry);return new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPolygon(c))},geometrycollection:function(a){a=a.replace(/,\s*([A-Za-z])/g,"|$1");a=OpenLayers.String.trim(a).split("|");for(var b=[],c=0,d=a.length;c<d;++c)b.push(OpenLayers.Format.WKT.prototype.read.apply(this,[a[c]])); | |
2765 return b}},CLASS_NAME:"OpenLayers.Format.WKT"});OpenLayers.WPSProcess=OpenLayers.Class({client:null,server:null,identifier:null,description:null,localWPS:"http://geoserver/wps",formats:null,chained:0,executeCallbacks:null,initialize:function(a){OpenLayers.Util.extend(this,a);this.executeCallbacks=[];this.formats={"application/wkt":new OpenLayers.Format.WKT,"application/json":new OpenLayers.Format.GeoJSON}},describe:function(a){a=a||{};if(!this.description)this.client.describeProcess(this.server,this.identifier,function(b){this.description||this.parseDescription(b); | |
2766 a.callback&&a.callback.call(a.scope,this.description)},this);else if(a.callback){var b=this.description;window.setTimeout(function(){a.callback.call(a.scope,b)},0)}},configure:function(a){this.describe({callback:function(){var b=this.description,c=a.inputs,d,e,f;e=0;for(f=b.dataInputs.length;e<f;++e)d=b.dataInputs[e],this.setInputData(d,c[d.identifier]);a.callback&&a.callback.call(a.scope)},scope:this});return this},execute:function(a){this.configure({inputs:a.inputs,callback:function(){var b=this, | |
2767 c=this.getOutputIndex(b.description.processOutputs,a.output);b.setResponseForm({outputIndex:c});(function e(){OpenLayers.Util.removeItem(b.executeCallbacks,e);0!==b.chained?b.executeCallbacks.push(e):OpenLayers.Request.POST({url:b.client.servers[b.server].url,data:(new OpenLayers.Format.WPSExecute).write(b.description),success:function(e){var g=b.findMimeType(b.description.processOutputs[c].complexOutput.supported.formats);e=b.formats[g].read(e.responseText);e instanceof OpenLayers.Feature.Vector&& | |
2768 (e=[e]);a.success&&(g={},g[a.output||"result"]=e,a.success.call(a.scope,g))},scope:b})})()},scope:this})},output:function(a){return new OpenLayers.WPSProcess.ChainLink({process:this,output:a})},parseDescription:function(a){a=this.client.servers[this.server];this.description=(new OpenLayers.Format.WPSDescribeProcess).read(a.processDescription[this.identifier]).processDescriptions[this.identifier]},setInputData:function(a,b){delete a.data;delete a.reference;if(b instanceof OpenLayers.WPSProcess.ChainLink)++this.chained, | |
2769 a.reference={method:"POST",href:b.process.server===this.server?this.localWPS:this.client.servers[b.process.server].url},b.process.describe({callback:function(){--this.chained;this.chainProcess(a,b)},scope:this});else{a.data={};var c=a.complexData;c?(c=this.findMimeType(c.supported.formats),a.data.complexData={mimeType:c,value:this.formats[c].write(this.toFeatures(b))}):a.data.literalData={value:b}}},setResponseForm:function(a){a=a||{};var b=this.description.processOutputs[a.outputIndex||0];this.description.responseForm= | |
2770 {rawDataOutput:{identifier:b.identifier,mimeType:this.findMimeType(b.complexOutput.supported.formats,a.supportedFormats)}}},getOutputIndex:function(a,b){var c;if(b)for(var d=a.length-1;0<=d;--d){if(a[d].identifier===b){c=d;break}}else c=0;return c},chainProcess:function(a,b){var c=this.getOutputIndex(b.process.description.processOutputs,b.output);a.reference.mimeType=this.findMimeType(a.complexData.supported.formats,b.process.description.processOutputs[c].complexOutput.supported.formats);var d={}; | |
2771 d[a.reference.mimeType]=!0;b.process.setResponseForm({outputIndex:c,supportedFormats:d});for(a.reference.body=b.process.description;0<this.executeCallbacks.length;)this.executeCallbacks[0]()},toFeatures:function(a){var b=OpenLayers.Util.isArray(a);b||(a=[a]);for(var c=Array(a.length),d,e=0,f=a.length;e<f;++e)d=a[e],c[e]=d instanceof OpenLayers.Feature.Vector?d:new OpenLayers.Feature.Vector(d);return b?c:c[0]},findMimeType:function(a,b){b=b||this.formats;for(var c in a)if(c in b)return c},CLASS_NAME:"OpenLayers.WPSProcess"}); | |
2772 OpenLayers.WPSProcess.ChainLink=OpenLayers.Class({process:null,output:null,initialize:function(a){OpenLayers.Util.extend(this,a)},CLASS_NAME:"OpenLayers.WPSProcess.ChainLink"});OpenLayers.WPSClient=OpenLayers.Class({servers:null,version:"1.0.0",lazy:!1,events:null,initialize:function(a){OpenLayers.Util.extend(this,a);this.events=new OpenLayers.Events(this);this.servers={};for(var b in a.servers)this.servers[b]="string"==typeof a.servers[b]?{url:a.servers[b],version:this.version,processDescription:{}}:a.servers[b]},execute:function(a){this.getProcess(a.server,a.process).execute({inputs:a.inputs,success:a.success,scope:a.scope})},getProcess:function(a,b){var c=new OpenLayers.WPSProcess({client:this, | |
2773 server:a,identifier:b});this.lazy||c.describe();return c},describeProcess:function(a,b,c,d){var e=this.servers[a];e.processDescription[b]?window.setTimeout(function(){c.call(d,e.processDescription[b])},0):b in e.processDescription?this.events.register("describeprocess",this,function g(a){a.identifier===b&&(this.events.unregister("describeprocess",this,g),c.call(d,a.raw))}):(e.processDescription[b]=null,OpenLayers.Request.GET({url:e.url,params:{SERVICE:"WPS",VERSION:e.version,REQUEST:"DescribeProcess", | |
2774 IDENTIFIER:b},success:function(a){e.processDescription[b]=a.responseText;this.events.triggerEvent("describeprocess",{identifier:b,raw:a.responseText})},scope:this}))},destroy:function(){this.events.destroy();this.servers=this.events=null},CLASS_NAME:"OpenLayers.WPSClient"});OpenLayers.Format.CSWGetRecords.v2_0_2=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{csw:"http://www.opengis.net/cat/csw/2.0.2",dc:"http://purl.org/dc/elements/1.1/",dct:"http://purl.org/dc/terms/",gmd:"http://www.isotc211.org/2005/gmd",geonet:"http://www.fao.org/geonetwork",ogc:"http://www.opengis.net/ogc",ows:"http://www.opengis.net/ows",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},defaultPrefix:"csw",version:"2.0.2",schemaLocation:"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd", | |
2775 requestId:null,resultType:null,outputFormat:null,outputSchema:null,startPosition:null,maxRecords:null,DistributedSearch:null,ResponseHandler:null,Query:null,regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b}, | |
2776 readers:{csw:{GetRecordsResponse:function(a,b){b.records=[];this.readChildNodes(a,b);var c=this.getAttributeNS(a,"","version");""!=c&&(b.version=c)},RequestId:function(a,b){b.RequestId=this.getChildValue(a)},SearchStatus:function(a,b){b.SearchStatus={};var c=this.getAttributeNS(a,"","timestamp");""!=c&&(b.SearchStatus.timestamp=c)},SearchResults:function(a,b){this.readChildNodes(a,b);for(var c=a.attributes,d={},e=0,f=c.length;e<f;++e)d[c[e].name]="numberOfRecordsMatched"==c[e].name||"numberOfRecordsReturned"== | |
2777 c[e].name||"nextRecord"==c[e].name?parseInt(c[e].nodeValue):c[e].nodeValue;b.SearchResults=d},SummaryRecord:function(a,b){var c={type:"SummaryRecord"};this.readChildNodes(a,c);b.records.push(c)},BriefRecord:function(a,b){var c={type:"BriefRecord"};this.readChildNodes(a,c);b.records.push(c)},DCMIRecord:function(a,b){var c={type:"DCMIRecord"};this.readChildNodes(a,c);b.records.push(c)},Record:function(a,b){var c={type:"Record"};this.readChildNodes(a,c);b.records.push(c)},"*":function(a,b){var c=a.localName|| | |
2778 a.nodeName.split(":").pop();b[c]=this.getChildValue(a)}},geonet:{info:function(a,b){var c={};this.readChildNodes(a,c);b.gninfo=c}},dc:{"*":function(a,b){var c=a.localName||a.nodeName.split(":").pop();OpenLayers.Util.isArray(b[c])||(b[c]=[]);for(var d={},e=a.attributes,f=0,g=e.length;f<g;++f)d[e[f].name]=e[f].nodeValue;d.value=this.getChildValue(a);""!=d.value&&b[c].push(d)}},dct:{"*":function(a,b){var c=a.localName||a.nodeName.split(":").pop();OpenLayers.Util.isArray(b[c])||(b[c]=[]);b[c].push(this.getChildValue(a))}}, | |
2779 ows:OpenLayers.Util.applyDefaults({BoundingBox:function(a,b){b.bounds&&(b.BoundingBox=[{crs:b.projection,value:[b.bounds.left,b.bounds.bottom,b.bounds.right,b.bounds.top]}],delete b.projection,delete b.bounds);OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows.BoundingBox.apply(this,arguments)}},OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows)},write:function(a){a=this.writeNode("csw:GetRecords",a);a.setAttribute("xmlns:gmd",this.namespaces.gmd);return OpenLayers.Format.XML.prototype.write.apply(this, | |
2780 [a])},writers:{csw:{GetRecords:function(a){a||(a={});var b=this.createElementNSPlus("csw:GetRecords",{attributes:{service:"CSW",version:this.version,requestId:a.requestId||this.requestId,resultType:a.resultType||this.resultType,outputFormat:a.outputFormat||this.outputFormat,outputSchema:a.outputSchema||this.outputSchema,startPosition:a.startPosition||this.startPosition,maxRecords:a.maxRecords||this.maxRecords}});(a.DistributedSearch||this.DistributedSearch)&&this.writeNode("csw:DistributedSearch", | |
2781 a.DistributedSearch||this.DistributedSearch,b);var c=a.ResponseHandler||this.ResponseHandler;if(OpenLayers.Util.isArray(c)&&0<c.length)for(var d=0,e=c.length;d<e;d++)this.writeNode("csw:ResponseHandler",c[d],b);this.writeNode("Query",a.Query||this.Query,b);return b},DistributedSearch:function(a){return this.createElementNSPlus("csw:DistributedSearch",{attributes:{hopCount:a.hopCount}})},ResponseHandler:function(a){return this.createElementNSPlus("csw:ResponseHandler",{value:a.value})},Query:function(a){a|| | |
2782 (a={});var b=this.createElementNSPlus("csw:Query",{attributes:{typeNames:a.typeNames||"csw:Record"}}),c=a.ElementName;if(OpenLayers.Util.isArray(c)&&0<c.length)for(var d=0,e=c.length;d<e;d++)this.writeNode("csw:ElementName",c[d],b);else this.writeNode("csw:ElementSetName",a.ElementSetName||{value:"summary"},b);a.Constraint&&this.writeNode("csw:Constraint",a.Constraint,b);a.SortBy&&this.writeNode("ogc:SortBy",a.SortBy,b);return b},ElementName:function(a){return this.createElementNSPlus("csw:ElementName", | |
2783 {value:a.value})},ElementSetName:function(a){return this.createElementNSPlus("csw:ElementSetName",{attributes:{typeNames:a.typeNames},value:a.value})},Constraint:function(a){var b=this.createElementNSPlus("csw:Constraint",{attributes:{version:a.version}});if(a.Filter){var c=new OpenLayers.Format.Filter({version:a.version});b.appendChild(c.write(a.Filter))}else a.CqlText&&(a=this.createElementNSPlus("CqlText",{value:a.CqlText.value}),b.appendChild(a));return b}},ogc:OpenLayers.Format.Filter.v1_1_0.prototype.writers.ogc}, | |
2784 CLASS_NAME:"OpenLayers.Format.CSWGetRecords.v2_0_2"});/* | |
2785 Apache 2 | |
2786 | |
2787 Contains portions of Rico <http://openrico.org/> | |
2788 | |
2789 Copyright 2005 Sabre Airline Solutions | |
2790 | |
2791 Licensed under the Apache License, Version 2.0 (the "License"); you | |
2792 may not use this file except in compliance with the License. You | |
2793 may obtain a copy of the License at | |
2794 | |
2795 http://www.apache.org/licenses/LICENSE-2.0 | |
2796 | |
2797 Unless required by applicable law or agreed to in writing, software | |
2798 distributed under the License is distributed on an "AS IS" BASIS, | |
2799 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
2800 implied. See the License for the specific language governing | |
2801 permissions and limitations under the License. | |
2802 */ | |
2803 OpenLayers.Marker.Box=OpenLayers.Class(OpenLayers.Marker,{bounds:null,div:null,initialize:function(a,b,c){this.bounds=a;this.div=OpenLayers.Util.createDiv();this.div.style.overflow="hidden";this.events=new OpenLayers.Events(this,this.div);this.setBorder(b,c)},destroy:function(){this.div=this.bounds=null;OpenLayers.Marker.prototype.destroy.apply(this,arguments)},setBorder:function(a,b){a||(a="red");b||(b=2);this.div.style.border=b+"px solid "+a},draw:function(a,b){OpenLayers.Util.modifyDOMElement(this.div, | |
2804 null,a,b);return this.div},onScreen:function(){var a=!1;this.map&&(a=this.map.getExtent().containsBounds(this.bounds,!0,!0));return a},display:function(a){this.div.style.display=a?"":"none"},CLASS_NAME:"OpenLayers.Marker.Box"});OpenLayers.Format.Text=OpenLayers.Class(OpenLayers.Format,{defaultStyle:null,extractStyles:!0,initialize:function(a){a=a||{};!1!==a.extractStyles&&(a.defaultStyle={externalGraphic:OpenLayers.Util.getImageLocation("marker.png"),graphicWidth:21,graphicHeight:25,graphicXOffset:-10.5,graphicYOffset:-12.5});OpenLayers.Format.prototype.initialize.apply(this,[a])},read:function(a){a=a.split("\n");for(var b,c=[],d=0;d<a.length-1;d++){var e=a[d].replace(/^\s*/,"").replace(/\s*$/,"");if("#"!=e.charAt(0))if(b){for(var e= | |
2805 e.split("\t"),f=new OpenLayers.Geometry.Point(0,0),g={},h=this.defaultStyle?OpenLayers.Util.applyDefaults({},this.defaultStyle):null,k=!1,l=0;l<e.length;l++)if(e[l])if("point"==b[l])k=e[l].split(","),f.y=parseFloat(k[0]),f.x=parseFloat(k[1]),k=!0;else if("lat"==b[l])f.y=parseFloat(e[l]),k=!0;else if("lon"==b[l])f.x=parseFloat(e[l]),k=!0;else if("title"==b[l])g.title=e[l];else if("image"==b[l]||"icon"==b[l]&&h)h.externalGraphic=e[l];else if("iconSize"==b[l]&&h){var m=e[l].split(",");h.graphicWidth= | |
2806 parseFloat(m[0]);h.graphicHeight=parseFloat(m[1])}else"iconOffset"==b[l]&&h?(m=e[l].split(","),h.graphicXOffset=parseFloat(m[0]),h.graphicYOffset=parseFloat(m[1])):"description"==b[l]?g.description=e[l]:"overflow"==b[l]?g.overflow=e[l]:g[b[l]]=e[l];k&&(this.internalProjection&&this.externalProjection&&f.transform(this.externalProjection,this.internalProjection),e=new OpenLayers.Feature.Vector(f,g,h),c.push(e))}else b=e.split("\t")}return c},CLASS_NAME:"OpenLayers.Format.Text"});OpenLayers.Layer.Text=OpenLayers.Class(OpenLayers.Layer.Markers,{location:null,features:null,formatOptions:null,selectedFeature:null,initialize:function(a,b){OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);this.features=[]},destroy:function(){OpenLayers.Layer.Markers.prototype.destroy.apply(this,arguments);this.clearFeatures();this.features=null},loadText:function(){this.loaded||null==this.location||(this.events.triggerEvent("loadstart"),OpenLayers.Request.GET({url:this.location, | |
2807 success:this.parseData,failure:function(a){this.events.triggerEvent("loadend")},scope:this}),this.loaded=!0)},moveTo:function(a,b,c){OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);this.visibility&&!this.loaded&&this.loadText()},parseData:function(a){a=a.responseText;var b={};OpenLayers.Util.extend(b,this.formatOptions);this.map&&!this.projection.equals(this.map.getProjectionObject())&&(b.externalProjection=this.projection,b.internalProjection=this.map.getProjectionObject());a=(new OpenLayers.Format.Text(b)).read(a); | |
2808 for(var b=0,c=a.length;b<c;b++){var d={},e=a[b],f,g,h;f=new OpenLayers.LonLat(e.geometry.x,e.geometry.y);e.style.graphicWidth&&e.style.graphicHeight&&(g=new OpenLayers.Size(e.style.graphicWidth,e.style.graphicHeight));void 0!==e.style.graphicXOffset&&void 0!==e.style.graphicYOffset&&(h=new OpenLayers.Pixel(e.style.graphicXOffset,e.style.graphicYOffset));null!=e.style.externalGraphic?d.icon=new OpenLayers.Icon(e.style.externalGraphic,g,h):(d.icon=OpenLayers.Marker.defaultIcon(),null!=g&&d.icon.setSize(g)); | |
2809 null!=e.attributes.title&&null!=e.attributes.description&&(d.popupContentHTML="<h2>"+e.attributes.title+"</h2><p>"+e.attributes.description+"</p>");d.overflow=e.attributes.overflow||"auto";d=new OpenLayers.Feature(this,f,d);this.features.push(d);f=d.createMarker();null!=e.attributes.title&&null!=e.attributes.description&&f.events.register("click",d,this.markerClick);this.addMarker(f)}this.events.triggerEvent("loadend")},markerClick:function(a){var b=this==this.layer.selectedFeature;this.layer.selectedFeature= | |
2810 b?null:this;for(var c=0,d=this.layer.map.popups.length;c<d;c++)this.layer.map.removePopup(this.layer.map.popups[c]);b||this.layer.map.addPopup(this.createPopup());OpenLayers.Event.stop(a)},clearFeatures:function(){if(null!=this.features)for(;0<this.features.length;){var a=this.features[0];OpenLayers.Util.removeItem(this.features,a);a.destroy()}},CLASS_NAME:"OpenLayers.Layer.Text"});OpenLayers.Handler.RegularPolygon=OpenLayers.Class(OpenLayers.Handler.Drag,{sides:4,radius:null,snapAngle:null,snapToggle:"shiftKey",layerOptions:null,persist:!1,irregular:!1,citeCompliant:!1,angle:null,fixedRadius:!1,feature:null,layer:null,origin:null,initialize:function(a,b,c){c&&c.layerOptions&&c.layerOptions.styleMap||(this.style=OpenLayers.Util.extend(OpenLayers.Feature.Vector.style["default"],{}));OpenLayers.Handler.Drag.prototype.initialize.apply(this,[a,b,c]);this.options=c?c:{}},setOptions:function(a){OpenLayers.Util.extend(this.options, | |
2811 a);OpenLayers.Util.extend(this,a)},activate:function(){var a=!1;OpenLayers.Handler.Drag.prototype.activate.apply(this,arguments)&&(a=OpenLayers.Util.extend({displayInLayerSwitcher:!1,calculateInRange:OpenLayers.Function.True,wrapDateLine:this.citeCompliant},this.layerOptions),this.layer=new OpenLayers.Layer.Vector(this.CLASS_NAME,a),this.map.addLayer(this.layer),a=!0);return a},deactivate:function(){var a=!1;OpenLayers.Handler.Drag.prototype.deactivate.apply(this,arguments)&&(this.dragging&&this.cancel(), | |
2812 null!=this.layer.map&&(this.layer.destroy(!1),this.feature&&this.feature.destroy()),this.feature=this.layer=null,a=!0);return a},down:function(a){this.fixedRadius=!!this.radius;a=this.layer.getLonLatFromViewPortPx(a.xy);this.origin=new OpenLayers.Geometry.Point(a.lon,a.lat);if(!this.fixedRadius||this.irregular)this.radius=this.map.getResolution();this.persist&&this.clear();this.feature=new OpenLayers.Feature.Vector;this.createGeometry();this.callback("create",[this.origin,this.feature]);this.layer.addFeatures([this.feature], | |
2813 {silent:!0});this.layer.drawFeature(this.feature,this.style)},move:function(a){var b=this.layer.getLonLatFromViewPortPx(a.xy),b=new OpenLayers.Geometry.Point(b.lon,b.lat);this.irregular?(a=Math.sqrt(2)*Math.abs(b.y-this.origin.y)/2,this.radius=Math.max(this.map.getResolution()/2,a)):this.fixedRadius?this.origin=b:(this.calculateAngle(b,a),this.radius=Math.max(this.map.getResolution()/2,b.distanceTo(this.origin)));this.modifyGeometry();if(this.irregular){a=b.x-this.origin.x;var b=b.y-this.origin.y, | |
2814 c;c=0==b?a/(this.radius*Math.sqrt(2)):a/b;this.feature.geometry.resize(1,this.origin,c);this.feature.geometry.move(a/2,b/2)}this.layer.drawFeature(this.feature,this.style)},up:function(a){this.finalize();this.start==this.last&&this.callback("done",[a.xy])},out:function(a){this.finalize()},createGeometry:function(){this.angle=Math.PI*(1/this.sides-0.5);this.snapAngle&&(this.angle+=this.snapAngle*(Math.PI/180));this.feature.geometry=OpenLayers.Geometry.Polygon.createRegularPolygon(this.origin,this.radius, | |
2815 this.sides,this.snapAngle)},modifyGeometry:function(){var a,b,c=this.feature.geometry.components[0];c.components.length!=this.sides+1&&(this.createGeometry(),c=this.feature.geometry.components[0]);for(var d=0;d<this.sides;++d)b=c.components[d],a=this.angle+2*d*Math.PI/this.sides,b.x=this.origin.x+this.radius*Math.cos(a),b.y=this.origin.y+this.radius*Math.sin(a),b.clearBounds()},calculateAngle:function(a,b){var c=Math.atan2(a.y-this.origin.y,a.x-this.origin.x);if(this.snapAngle&&this.snapToggle&&!b[this.snapToggle]){var d= | |
2816 Math.PI/180*this.snapAngle;this.angle=Math.round(c/d)*d}else this.angle=c},cancel:function(){this.callback("cancel",null);this.finalize()},finalize:function(){this.origin=null;this.radius=this.options.radius},clear:function(){this.layer&&(this.layer.renderer.clear(),this.layer.destroyFeatures())},callback:function(a,b){this.callbacks[a]&&this.callbacks[a].apply(this.control,[this.feature.geometry.clone()]);this.persist||"done"!=a&&"cancel"!=a||this.clear()},CLASS_NAME:"OpenLayers.Handler.RegularPolygon"});OpenLayers.Control.SLDSelect=OpenLayers.Class(OpenLayers.Control,{clearOnDeactivate:!1,layers:null,callbacks:null,selectionSymbolizer:{Polygon:{fillColor:"#FF0000",stroke:!1},Line:{strokeColor:"#FF0000",strokeWidth:2},Point:{graphicName:"square",fillColor:"#FF0000",pointRadius:5}},layerOptions:null,sketchStyle:null,wfsCache:{},layerCache:{},initialize:function(a,b){OpenLayers.Control.prototype.initialize.apply(this,[b]);this.callbacks=OpenLayers.Util.extend({done:this.select,click:this.select},this.callbacks); | |
2817 this.handlerOptions=this.handlerOptions||{};this.layerOptions=OpenLayers.Util.applyDefaults(this.layerOptions,{displayInLayerSwitcher:!1,tileOptions:{maxGetUrlLength:2048}});this.sketchStyle&&(this.handlerOptions.layerOptions=OpenLayers.Util.applyDefaults(this.handlerOptions.layerOptions,{styleMap:new OpenLayers.StyleMap({"default":this.sketchStyle})}));this.handler=new a(this,this.callbacks,this.handlerOptions)},destroy:function(){for(var a in this.layerCache)delete this.layerCache[a];for(a in this.wfsCache)delete this.wfsCache[a]; | |
2818 OpenLayers.Control.prototype.destroy.apply(this,arguments)},coupleLayerVisiblity:function(a){this.setVisibility(a.object.getVisibility())},createSelectionLayer:function(a){var b;if(this.layerCache[a.id])b=this.layerCache[a.id];else{b=new OpenLayers.Layer.WMS(a.name,a.url,a.params,OpenLayers.Util.applyDefaults(this.layerOptions,a.getOptions()));this.layerCache[a.id]=b;if(!1===this.layerOptions.displayInLayerSwitcher)a.events.on({visibilitychanged:this.coupleLayerVisiblity,scope:b});this.map.addLayer(b)}return b}, | |
2819 createSLD:function(a,b,c){for(var d={version:"1.0.0",namedLayers:{}},e=(""+a.params.LAYERS).split(","),f=0,g=e.length;f<g;f++){var h=e[f];d.namedLayers[h]={name:h,userStyles:[]};var k=this.selectionSymbolizer,l=c[f];0<=l.type.indexOf("Polygon")?k={Polygon:this.selectionSymbolizer.Polygon}:0<=l.type.indexOf("LineString")?k={Line:this.selectionSymbolizer.Line}:0<=l.type.indexOf("Point")&&(k={Point:this.selectionSymbolizer.Point});d.namedLayers[h].userStyles.push({name:"default",rules:[new OpenLayers.Rule({symbolizer:k, | |
2820 filter:b[f],maxScaleDenominator:a.options.minScale})]})}return(new OpenLayers.Format.SLD({srsName:this.map.getProjection()})).write(d)},parseDescribeLayer:function(a){var b=new OpenLayers.Format.WMSDescribeLayer,c=a.responseXML;c&&c.documentElement||(c=a.responseText);a=b.read(c);for(var b=[],c=null,d=0,e=a.length;d<e;d++)"WFS"==a[d].owsType&&(b.push(a[d].typeName),c=a[d].owsURL);OpenLayers.Request.GET({url:c,params:{SERVICE:"WFS",TYPENAME:b.toString(),REQUEST:"DescribeFeatureType",VERSION:"1.0.0"}, | |
2821 callback:function(a){var b=new OpenLayers.Format.WFSDescribeFeatureType,c=a.responseXML;c&&c.documentElement||(c=a.responseText);a=b.read(c);this.control.wfsCache[this.layer.id]=a;this.control._queue&&this.control.applySelection()},scope:this})},getGeometryAttributes:function(a){var b=[];a=this.wfsCache[a.id];for(var c=0,d=a.featureTypes.length;c<d;c++)for(var e=a.featureTypes[c].properties,f=0,g=e.length;f<g;f++){var h=e[f],k=h.type;(0<=k.indexOf("LineString")||0<=k.indexOf("GeometryAssociationType")|| | |
2822 0<=k.indexOf("GeometryPropertyType")||0<=k.indexOf("Point")||0<=k.indexOf("Polygon"))&&b.push(h)}return b},activate:function(){var a=OpenLayers.Control.prototype.activate.call(this);if(a)for(var b=0,c=this.layers.length;b<c;b++){var d=this.layers[b];d&&!this.wfsCache[d.id]&&OpenLayers.Request.GET({url:d.url,params:{SERVICE:"WMS",VERSION:d.params.VERSION,LAYERS:d.params.LAYERS,REQUEST:"DescribeLayer"},callback:this.parseDescribeLayer,scope:{layer:d,control:this}})}return a},deactivate:function(){var a= | |
2823 OpenLayers.Control.prototype.deactivate.call(this);if(a)for(var b=0,c=this.layers.length;b<c;b++){var d=this.layers[b];if(d&&!0===this.clearOnDeactivate){var e=this.layerCache,f=e[d.id];f&&(d.events.un({visibilitychanged:this.coupleLayerVisiblity,scope:f}),f.destroy(),delete e[d.id])}}return a},setLayers:function(a){this.active?(this.deactivate(),this.layers=a,this.activate()):this.layers=a},createFilter:function(a,b){var c=null;this.handler instanceof OpenLayers.Handler.RegularPolygon?c=!0===this.handler.irregular? | |
2824 new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,property:a.name,value:b.getBounds()}):new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:a.name,value:b}):this.handler instanceof OpenLayers.Handler.Polygon?c=new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:a.name,value:b}):this.handler instanceof OpenLayers.Handler.Path?c=0<=a.type.indexOf("Point")?new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN, | |
2825 property:a.name,distance:0.01*this.map.getExtent().getWidth(),distanceUnits:this.map.getUnits(),value:b}):new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:a.name,value:b}):this.handler instanceof OpenLayers.Handler.Click&&(c=0<=a.type.indexOf("Polygon")?new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:a.name,value:b}):new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,property:a.name,distance:0.01*this.map.getExtent().getWidth(), | |
2826 distanceUnits:this.map.getUnits(),value:b}));return c},select:function(a){this._queue=function(){for(var b=0,c=this.layers.length;b<c;b++){for(var d=this.layers[b],e=this.getGeometryAttributes(d),f=[],g=0,h=e.length;g<h;g++){var k=e[g];if(null!==k){if(!(a instanceof OpenLayers.Geometry)){var l=this.map.getLonLatFromPixel(a.xy);a=new OpenLayers.Geometry.Point(l.lon,l.lat)}k=this.createFilter(k,a);null!==k&&f.push(k)}}g=this.createSelectionLayer(d);this.events.triggerEvent("selected",{layer:d,filters:f}); | |
2827 d=this.createSLD(d,f,e);g.mergeNewParams({SLD_BODY:d});delete this._queue}};this.applySelection()},applySelection:function(){for(var a=!0,b=0,c=this.layers.length;b<c;b++)if(!this.wfsCache[this.layers[b].id]){a=!1;break}a&&this._queue.call(this)},CLASS_NAME:"OpenLayers.Control.SLDSelect"});OpenLayers.Control.Scale=OpenLayers.Class(OpenLayers.Control,{element:null,geodesic:!1,initialize:function(a,b){OpenLayers.Control.prototype.initialize.apply(this,[b]);this.element=OpenLayers.Util.getElement(a)},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.element||(this.element=document.createElement("div"),this.div.appendChild(this.element));this.map.events.register("moveend",this,this.updateScale);this.updateScale();return this.div},updateScale:function(){var a; | |
2828 if(!0===this.geodesic){if(!this.map.getUnits())return;a=OpenLayers.INCHES_PER_UNIT;a=(this.map.getGeodesicPixelSize().w||1E-6)*a.km*OpenLayers.DOTS_PER_INCH}else a=this.map.getScale();a&&(a=9500<=a&&95E4>=a?Math.round(a/1E3)+"K":95E4<=a?Math.round(a/1E6)+"M":Math.round(a),this.element.innerHTML=OpenLayers.i18n("Scale = 1 : ${scaleDenom}",{scaleDenom:a}))},CLASS_NAME:"OpenLayers.Control.Scale"});OpenLayers.Layer.MapGuide=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:!0,useHttpTile:!1,singleTile:!1,useOverlay:!1,useAsyncOverlay:!0,TILE_PARAMS:{operation:"GETTILEIMAGE",version:"1.2.0"},SINGLE_TILE_PARAMS:{operation:"GETMAPIMAGE",format:"PNG",locale:"en",clip:"1",version:"1.0.0"},OVERLAY_PARAMS:{operation:"GETDYNAMICMAPOVERLAYIMAGE",format:"PNG",locale:"en",clip:"1",version:"2.0.0"},FOLDER_PARAMS:{tileColumnsPerFolder:30,tileRowsPerFolder:30,format:"png",querystring:null},defaultSize:new OpenLayers.Size(300, | |
2829 300),tileOriginCorner:"tl",initialize:function(a,b,c,d){OpenLayers.Layer.Grid.prototype.initialize.apply(this,arguments);if(null==d||null==d.isBaseLayer)this.isBaseLayer="true"!=this.transparent&&!0!=this.transparent;d&&null!=d.useOverlay&&(this.useOverlay=d.useOverlay);this.singleTile?this.useOverlay?(OpenLayers.Util.applyDefaults(this.params,this.OVERLAY_PARAMS),this.useAsyncOverlay||(this.params.version="1.0.0")):OpenLayers.Util.applyDefaults(this.params,this.SINGLE_TILE_PARAMS):(this.useHttpTile? | |
2830 OpenLayers.Util.applyDefaults(this.params,this.FOLDER_PARAMS):OpenLayers.Util.applyDefaults(this.params,this.TILE_PARAMS),this.setTileSize(this.defaultSize))},clone:function(a){null==a&&(a=new OpenLayers.Layer.MapGuide(this.name,this.url,this.params,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getURL:function(a){var b;b=a.getCenterLonLat();var c=this.map.getSize();this.singleTile?(a={setdisplaydpi:OpenLayers.DOTS_PER_INCH,setdisplayheight:c.h*this.ratio,setdisplaywidth:c.w* | |
2831 this.ratio,setviewcenterx:b.lon,setviewcentery:b.lat,setviewscale:this.map.getScale()},this.useOverlay&&!this.useAsyncOverlay&&(b={},b=OpenLayers.Util.extend(b,a),b.operation="GETVISIBLEMAPEXTENT",b.version="1.0.0",b.session=this.params.session,b.mapName=this.params.mapName,b.format="text/xml",b=this.getFullRequestString(b),OpenLayers.Request.GET({url:b,async:!1})),b=this.getFullRequestString(a)):(c=this.map.getResolution(),b=Math.floor((a.left-this.maxExtent.left)/c),b=Math.round(b/this.tileSize.w), | |
2832 a=Math.floor((this.maxExtent.top-a.top)/c),a=Math.round(a/this.tileSize.h),b=this.useHttpTile?this.getImageFilePath({tilecol:b,tilerow:a,scaleindex:this.resolutions.length-this.map.zoom-1}):this.getFullRequestString({tilecol:b,tilerow:a,scaleindex:this.resolutions.length-this.map.zoom-1}));return b},getFullRequestString:function(a,b){var c=null==b?this.url:b;"object"==typeof c&&(c=c[Math.floor(Math.random()*c.length)]);var d=c,e=OpenLayers.Util.extend({},this.params),e=OpenLayers.Util.extend(e,a), | |
2833 f=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(c)),g;for(g in e)g.toUpperCase()in f&&delete e[g];e=OpenLayers.Util.getParameterString(e);e=e.replace(/,/g,"+");""!=e&&(f=c.charAt(c.length-1),d="&"==f||"?"==f?d+e:-1==c.indexOf("?")?d+("?"+e):d+("&"+e));return d},getImageFilePath:function(a,b){var c=null==b?this.url:b;"object"==typeof c&&(c=c[Math.floor(Math.random()*c.length)]);var d="",e="";0>a.tilerow&&(d="-");d=0==a.tilerow?d+"0":d+Math.floor(Math.abs(a.tilerow/this.params.tileRowsPerFolder))* | |
2834 this.params.tileRowsPerFolder;0>a.tilecol&&(e="-");e=0==a.tilecol?e+"0":e+Math.floor(Math.abs(a.tilecol/this.params.tileColumnsPerFolder))*this.params.tileColumnsPerFolder;d="/S"+Math.floor(a.scaleindex)+"/"+this.params.basemaplayergroupname+"/R"+d+"/C"+e+"/"+a.tilerow%this.params.tileRowsPerFolder+"_"+a.tilecol%this.params.tileColumnsPerFolder+"."+this.params.format;this.params.querystring&&(d+="?"+this.params.querystring);return c+d},CLASS_NAME:"OpenLayers.Layer.MapGuide"});OpenLayers.Control.Measure=OpenLayers.Class(OpenLayers.Control,{callbacks:null,displaySystem:"metric",geodesic:!1,displaySystemUnits:{geographic:["dd"],english:["mi","ft","in"],metric:["km","m"]},partialDelay:300,delayedTrigger:null,persist:!1,immediate:!1,initialize:function(a,b){OpenLayers.Control.prototype.initialize.apply(this,[b]);var c={done:this.measureComplete,point:this.measurePartial};this.immediate&&(c.modify=this.measureImmediate);this.callbacks=OpenLayers.Util.extend(c,this.callbacks); | |
2835 this.handlerOptions=OpenLayers.Util.extend({persist:this.persist},this.handlerOptions);this.handler=new a(this,this.callbacks,this.handlerOptions)},deactivate:function(){this.cancelDelay();return OpenLayers.Control.prototype.deactivate.apply(this,arguments)},cancel:function(){this.cancelDelay();this.handler.cancel()},setImmediate:function(a){(this.immediate=a)?this.callbacks.modify=this.measureImmediate:delete this.callbacks.modify},updateHandler:function(a,b){var c=this.active;c&&this.deactivate(); | |
2836 this.handler=new a(this,this.callbacks,b);c&&this.activate()},measureComplete:function(a){this.cancelDelay();this.measure(a,"measure")},measurePartial:function(a,b){this.cancelDelay();b=b.clone();this.handler.freehandMode(this.handler.evt)?this.measure(b,"measurepartial"):this.delayedTrigger=window.setTimeout(OpenLayers.Function.bind(function(){this.delayedTrigger=null;this.measure(b,"measurepartial")},this),this.partialDelay)},measureImmediate:function(a,b,c){c&&!this.handler.freehandMode(this.handler.evt)&& | |
2837 (this.cancelDelay(),this.measure(b.geometry,"measurepartial"))},cancelDelay:function(){null!==this.delayedTrigger&&(window.clearTimeout(this.delayedTrigger),this.delayedTrigger=null)},measure:function(a,b){var c,d;-1<a.CLASS_NAME.indexOf("LineString")?(c=this.getBestLength(a),d=1):(c=this.getBestArea(a),d=2);this.events.triggerEvent(b,{measure:c[0],units:c[1],order:d,geometry:a})},getBestArea:function(a){for(var b=this.displaySystemUnits[this.displaySystem],c,d,e=0,f=b.length;e<f&&!(c=b[e],d=this.getArea(a, | |
2838 c),1<d);++e);return[d,c]},getArea:function(a,b){var c,d;this.geodesic?(c=a.getGeodesicArea(this.map.getProjectionObject()),d="m"):(c=a.getArea(),d=this.map.getUnits());var e=OpenLayers.INCHES_PER_UNIT[b];e&&(c*=Math.pow(OpenLayers.INCHES_PER_UNIT[d]/e,2));return c},getBestLength:function(a){for(var b=this.displaySystemUnits[this.displaySystem],c,d,e=0,f=b.length;e<f&&!(c=b[e],d=this.getLength(a,c),1<d);++e);return[d,c]},getLength:function(a,b){var c,d;this.geodesic?(c=a.getGeodesicLength(this.map.getProjectionObject()), | |
2839 d="m"):(c=a.getLength(),d=this.map.getUnits());var e=OpenLayers.INCHES_PER_UNIT[b];e&&(c*=OpenLayers.INCHES_PER_UNIT[d]/e);return c},CLASS_NAME:"OpenLayers.Control.Measure"});OpenLayers.Format.WMC.v1_0_0=OpenLayers.Class(OpenLayers.Format.WMC.v1,{VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd",initialize:function(a){OpenLayers.Format.WMC.v1.prototype.initialize.apply(this,[a])},read_wmc_SRS:function(a,b){var c=this.getChildValue(b);"object"!=typeof a.projections&&(a.projections={});for(var c=c.split(/ +/),d=0,e=c.length;d<e;d++)a.projections[c[d]]=!0},write_wmc_Layer:function(a){var b=OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(this, | |
2840 [a]);if(a.srs){var c=[],d;for(d in a.srs)c.push(d);b.appendChild(this.createElementDefaultNS("SRS",c.join(" ")))}b.appendChild(this.write_wmc_FormatList(a));b.appendChild(this.write_wmc_StyleList(a));a.dimensions&&b.appendChild(this.write_wmc_DimensionList(a));b.appendChild(this.write_wmc_LayerExtension(a))},CLASS_NAME:"OpenLayers.Format.WMC.v1_0_0"});OpenLayers.Popup.Anchored=OpenLayers.Class(OpenLayers.Popup,{relativePosition:null,keepInMap:!0,anchor:null,initialize:function(a,b,c,d,e,f,g){OpenLayers.Popup.prototype.initialize.apply(this,[a,b,c,d,f,g]);this.anchor=null!=e?e:{size:new OpenLayers.Size(0,0),offset:new OpenLayers.Pixel(0,0)}},destroy:function(){this.relativePosition=this.anchor=null;OpenLayers.Popup.prototype.destroy.apply(this,arguments)},show:function(){this.updatePosition();OpenLayers.Popup.prototype.show.apply(this,arguments)}, | |
2841 moveTo:function(a){var b=this.relativePosition;this.relativePosition=this.calculateRelativePosition(a);OpenLayers.Popup.prototype.moveTo.call(this,this.calculateNewPx(a));this.relativePosition!=b&&this.updateRelativePosition()},setSize:function(a){OpenLayers.Popup.prototype.setSize.apply(this,arguments);if(this.lonlat&&this.map){var b=this.map.getLayerPxFromLonLat(this.lonlat);this.moveTo(b)}},calculateRelativePosition:function(a){a=this.map.getLonLatFromLayerPx(a);a=this.map.getExtent().determineQuadrant(a); | |
2842 return OpenLayers.Bounds.oppositeQuadrant(a)},updateRelativePosition:function(){},calculateNewPx:function(a){a=a.offset(this.anchor.offset);var b=this.size||this.contentSize,c="t"==this.relativePosition.charAt(0);a.y+=c?-b.h:this.anchor.size.h;c="l"==this.relativePosition.charAt(1);a.x+=c?-b.w:this.anchor.size.w;return a},CLASS_NAME:"OpenLayers.Popup.Anchored"});OpenLayers.Popup.Framed=OpenLayers.Class(OpenLayers.Popup.Anchored,{imageSrc:null,imageSize:null,isAlphaImage:!1,positionBlocks:null,blocks:null,fixedRelativePosition:!1,initialize:function(a,b,c,d,e,f,g){OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments);this.fixedRelativePosition&&(this.updateRelativePosition(),this.calculateRelativePosition=function(a){return this.relativePosition});this.contentDiv.style.position="absolute";this.contentDiv.style.zIndex=1;f&&(this.closeDiv.style.zIndex= | |
2843 1);this.groupDiv.style.position="absolute";this.groupDiv.style.top="0px";this.groupDiv.style.left="0px";this.groupDiv.style.height="100%";this.groupDiv.style.width="100%"},destroy:function(){this.isAlphaImage=this.imageSize=this.imageSrc=null;this.fixedRelativePosition=!1;this.positionBlocks=null;for(var a=0;a<this.blocks.length;a++){var b=this.blocks[a];b.image&&b.div.removeChild(b.image);b.image=null;b.div&&this.groupDiv.removeChild(b.div);b.div=null}this.blocks=null;OpenLayers.Popup.Anchored.prototype.destroy.apply(this, | |
2844 arguments)},setBackgroundColor:function(a){},setBorder:function(){},setOpacity:function(a){},setSize:function(a){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.updateBlocks()},updateRelativePosition:function(){this.padding=this.positionBlocks[this.relativePosition].padding;if(this.closeDiv){var a=this.getContentDivPadding();this.closeDiv.style.right=a.right+this.padding.right+"px";this.closeDiv.style.top=a.top+this.padding.top+"px"}this.updateBlocks()},calculateNewPx:function(a){var b= | |
2845 OpenLayers.Popup.Anchored.prototype.calculateNewPx.apply(this,arguments);return b=b.offset(this.positionBlocks[this.relativePosition].offset)},createBlocks:function(){this.blocks=[];var a=null,b;for(b in this.positionBlocks){a=b;break}a=this.positionBlocks[a];for(b=0;b<a.blocks.length;b++){var c={};this.blocks.push(c);c.div=OpenLayers.Util.createDiv(this.id+"_FrameDecorationDiv_"+b,null,null,null,"absolute",null,"hidden",null);c.image=(this.isAlphaImage?OpenLayers.Util.createAlphaImageDiv:OpenLayers.Util.createImage)(this.id+ | |
2846 "_FrameDecorationImg_"+b,null,this.imageSize,this.imageSrc,"absolute",null,null,null);c.div.appendChild(c.image);this.groupDiv.appendChild(c.div)}},updateBlocks:function(){this.blocks||this.createBlocks();if(this.size&&this.relativePosition){for(var a=this.positionBlocks[this.relativePosition],b=0;b<a.blocks.length;b++){var c=a.blocks[b],d=this.blocks[b],e=c.anchor.left,f=c.anchor.bottom,g=c.anchor.right,h=c.anchor.top,k=isNaN(c.size.w)?this.size.w-(g+e):c.size.w,l=isNaN(c.size.h)?this.size.h-(f+ | |
2847 h):c.size.h;d.div.style.width=(0>k?0:k)+"px";d.div.style.height=(0>l?0:l)+"px";d.div.style.left=null!=e?e+"px":"";d.div.style.bottom=null!=f?f+"px":"";d.div.style.right=null!=g?g+"px":"";d.div.style.top=null!=h?h+"px":"";d.image.style.left=c.position.x+"px";d.image.style.top=c.position.y+"px"}this.contentDiv.style.left=this.padding.left+"px";this.contentDiv.style.top=this.padding.top+"px"}},CLASS_NAME:"OpenLayers.Popup.Framed"});OpenLayers.Popup.FramedCloud=OpenLayers.Class(OpenLayers.Popup.Framed,{contentDisplayClass:"olFramedCloudPopupContent",autoSize:!0,panMapIfOutOfView:!0,imageSize:new OpenLayers.Size(1276,736),isAlphaImage:!1,fixedRelativePosition:!1,positionBlocks:{tl:{offset:new OpenLayers.Pixel(44,0),padding:new OpenLayers.Bounds(8,40,8,9),blocks:[{size:new OpenLayers.Size("auto","auto"),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,"auto"),anchor:new OpenLayers.Bounds(null, | |
2848 50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size("auto",19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,18),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-632)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(0,-688)}]},tr:{offset:new OpenLayers.Pixel(-45,0),padding:new OpenLayers.Bounds(8,40,8,9),blocks:[{size:new OpenLayers.Size("auto", | |
2849 "auto"),anchor:new OpenLayers.Bounds(0,51,22,0),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,"auto"),anchor:new OpenLayers.Bounds(null,50,0,0),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size("auto",19),anchor:new OpenLayers.Bounds(0,32,22,null),position:new OpenLayers.Pixel(0,-631)},{size:new OpenLayers.Size(22,19),anchor:new OpenLayers.Bounds(null,32,0,null),position:new OpenLayers.Pixel(-1238,-631)},{size:new OpenLayers.Size(81,35),anchor:new OpenLayers.Bounds(0, | |
2850 0,null,null),position:new OpenLayers.Pixel(-215,-687)}]},bl:{offset:new OpenLayers.Pixel(45,0),padding:new OpenLayers.Bounds(8,9,8,40),blocks:[{size:new OpenLayers.Size("auto","auto"),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,"auto"),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238,0)},{size:new OpenLayers.Size("auto",21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22, | |
2851 21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(null,null,0,0),position:new OpenLayers.Pixel(-101,-674)}]},br:{offset:new OpenLayers.Pixel(-44,0),padding:new OpenLayers.Bounds(8,9,8,40),blocks:[{size:new OpenLayers.Size("auto","auto"),anchor:new OpenLayers.Bounds(0,21,22,32),position:new OpenLayers.Pixel(0,0)},{size:new OpenLayers.Size(22,"auto"),anchor:new OpenLayers.Bounds(null,21,0,32),position:new OpenLayers.Pixel(-1238, | |
2852 0)},{size:new OpenLayers.Size("auto",21),anchor:new OpenLayers.Bounds(0,0,22,null),position:new OpenLayers.Pixel(0,-629)},{size:new OpenLayers.Size(22,21),anchor:new OpenLayers.Bounds(null,0,0,null),position:new OpenLayers.Pixel(-1238,-629)},{size:new OpenLayers.Size(81,33),anchor:new OpenLayers.Bounds(0,null,null,0),position:new OpenLayers.Pixel(-311,-674)}]}},minSize:new OpenLayers.Size(105,10),maxSize:new OpenLayers.Size(1200,660),initialize:function(a,b,c,d,e,f,g){this.imageSrc=OpenLayers.Util.getImageLocation("cloud-popup-relative.png"); | |
2853 OpenLayers.Popup.Framed.prototype.initialize.apply(this,arguments);this.contentDiv.className=this.contentDisplayClass},CLASS_NAME:"OpenLayers.Popup.FramedCloud"});OpenLayers.Tile.Image.IFrame={useIFrame:null,blankImageUrl:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAQAIBRAA7",draw:function(){if(OpenLayers.Tile.Image.prototype.shouldDraw.call(this)){var a=this.layer.getURL(this.bounds),b=this.useIFrame;this.useIFrame=null!==this.maxGetUrlLength&&!this.layer.async&&a.length>this.maxGetUrlLength;a=b&&!this.useIFrame;b=!b&&this.useIFrame;if(a||b)this.imgDiv&&this.imgDiv.parentNode===this.frame&&this.frame.removeChild(this.imgDiv),this.imgDiv= | |
2854 null,a&&this.frame.removeChild(this.frame.firstChild)}return OpenLayers.Tile.Image.prototype.draw.apply(this,arguments)},getImage:function(){if(!0===this.useIFrame){if(!this.frame.childNodes.length){var a=document.createElement("div"),b=a.style;b.position="absolute";b.width="100%";b.height="100%";b.zIndex=1;b.backgroundImage="url("+this.blankImageUrl+")";this.frame.appendChild(a)}a=this.id+"_iFrame";9>parseFloat(navigator.appVersion.split("MSIE")[1])?(b=document.createElement('<iframe name="'+a+'">'), | |
2855 b.style.backgroundColor="#FFFFFF",b.style.filter="chroma(color=#FFFFFF)"):(b=document.createElement("iframe"),b.style.backgroundColor="transparent",b.name=a);b.scrolling="no";b.marginWidth="0px";b.marginHeight="0px";b.frameBorder="0";b.style.position="absolute";b.style.width="100%";b.style.height="100%";1>this.layer.opacity&&OpenLayers.Util.modifyDOMElement(b,null,null,null,null,null,null,this.layer.opacity);this.frame.appendChild(b);return this.imgDiv=b}return OpenLayers.Tile.Image.prototype.getImage.apply(this, | |
2856 arguments)},createRequestForm:function(){var a=document.createElement("form");a.method="POST";var b=this.layer.params._OLSALT,b=(b?b+"_":"")+this.bounds.toBBOX();a.action=OpenLayers.Util.urlAppend(this.layer.url,b);a.target=this.id+"_iFrame";this.layer.getImageSize();var b=OpenLayers.Util.getParameters(this.url),c,d;for(d in b)c=document.createElement("input"),c.type="hidden",c.name=d,c.value=b[d],a.appendChild(c);return a},setImgSrc:function(a){if(!0===this.useIFrame)if(a){var b=this.createRequestForm(); | |
2857 this.frame.appendChild(b);b.submit();this.frame.removeChild(b)}else this.imgDiv.parentNode===this.frame&&(this.frame.removeChild(this.imgDiv),this.imgDiv=null);else OpenLayers.Tile.Image.prototype.setImgSrc.apply(this,arguments)},onImageLoad:function(){OpenLayers.Tile.Image.prototype.onImageLoad.apply(this,arguments);!0===this.useIFrame&&(this.imgDiv.style.opacity=1,this.frame.style.opacity=this.layer.opacity)},createBackBuffer:function(){var a;!1===this.useIFrame&&(a=OpenLayers.Tile.Image.prototype.createBackBuffer.call(this)); | |
2858 return a}};OpenLayers.Format.SOSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.0.0",CLASS_NAME:"OpenLayers.Format.SOSCapabilities"});OpenLayers.Format.SOSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.SOSCapabilities,{namespaces:{ows:"http://www.opengis.net/ows/1.1",sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",xlink:"http://www.w3.org/1999/xlink"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a]);this.options=a},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this, | |
2859 [a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);return b},readers:{gml:OpenLayers.Util.applyDefaults({name:function(a,b){b.name=this.getChildValue(a)},TimePeriod:function(a,b){b.timePeriod={};this.readChildNodes(a,b.timePeriod)},beginPosition:function(a,b){b.beginPosition=this.getChildValue(a)},endPosition:function(a,b){b.endPosition=this.getChildValue(a)}},OpenLayers.Format.GML.v3.prototype.readers.gml),sos:{Capabilities:function(a,b){this.readChildNodes(a,b)},Contents:function(a, | |
2860 b){b.contents={};this.readChildNodes(a,b.contents)},ObservationOfferingList:function(a,b){b.offeringList={};this.readChildNodes(a,b.offeringList)},ObservationOffering:function(a,b){var c=this.getAttributeNS(a,this.namespaces.gml,"id");b[c]={procedures:[],observedProperties:[],featureOfInterestIds:[],responseFormats:[],resultModels:[],responseModes:[]};this.readChildNodes(a,b[c])},time:function(a,b){b.time={};this.readChildNodes(a,b.time)},procedure:function(a,b){b.procedures.push(this.getAttributeNS(a, | |
2861 this.namespaces.xlink,"href"))},observedProperty:function(a,b){b.observedProperties.push(this.getAttributeNS(a,this.namespaces.xlink,"href"))},featureOfInterest:function(a,b){b.featureOfInterestIds.push(this.getAttributeNS(a,this.namespaces.xlink,"href"))},responseFormat:function(a,b){b.responseFormats.push(this.getChildValue(a))},resultModel:function(a,b){b.resultModels.push(this.getChildValue(a))},responseMode:function(a,b){b.responseModes.push(this.getChildValue(a))}},ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows}, | |
2862 CLASS_NAME:"OpenLayers.Format.SOSCapabilities.v1_0_0"});OpenLayers.Handler.Pinch=OpenLayers.Class(OpenLayers.Handler,{started:!1,stopDown:!1,pinching:!1,last:null,start:null,touchstart:function(a){var b=!0;this.pinching=!1;if(OpenLayers.Event.isMultiTouch(a))this.started=!0,this.last=this.start={distance:this.getDistance(a.touches),delta:0,scale:1},this.callback("start",[a,this.start]),b=!this.stopDown;else{if(this.started)return!1;this.started=!1;this.last=this.start=null}OpenLayers.Event.preventDefault(a);return b},touchmove:function(a){if(this.started&& | |
2863 OpenLayers.Event.isMultiTouch(a)){this.pinching=!0;var b=this.getPinchData(a);this.callback("move",[a,b]);this.last=b;OpenLayers.Event.stop(a)}else if(this.started)return!1;return!0},touchend:function(a){return this.started&&!OpenLayers.Event.isMultiTouch(a)?(this.pinching=this.started=!1,this.callback("done",[a,this.start,this.last]),this.last=this.start=null,!1):!0},activate:function(){var a=!1;OpenLayers.Handler.prototype.activate.apply(this,arguments)&&(this.pinching=!1,a=!0);return a},deactivate:function(){var a= | |
2864 !1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.pinching=this.started=!1,this.last=this.start=null,a=!0);return a},getDistance:function(a){var b=a[0];a=a[1];return Math.sqrt(Math.pow(b.olClientX-a.olClientX,2)+Math.pow(b.olClientY-a.olClientY,2))},getPinchData:function(a){a=this.getDistance(a.touches);return{distance:a,delta:this.last.distance-a,scale:a/this.start.distance}},CLASS_NAME:"OpenLayers.Handler.Pinch"});OpenLayers.Control.NavToolbar=OpenLayers.Class(OpenLayers.Control.Panel,{initialize:function(a){OpenLayers.Control.Panel.prototype.initialize.apply(this,[a]);this.addControls([new OpenLayers.Control.Navigation,new OpenLayers.Control.ZoomBox])},draw:function(){var a=OpenLayers.Control.Panel.prototype.draw.apply(this,arguments);null===this.defaultControl&&(this.defaultControl=this.controls[0]);return a},CLASS_NAME:"OpenLayers.Control.NavToolbar"});OpenLayers.Strategy.Refresh=OpenLayers.Class(OpenLayers.Strategy,{force:!1,interval:0,timer:null,activate:function(){var a=OpenLayers.Strategy.prototype.activate.call(this);a&&(!0===this.layer.visibility&&this.start(),this.layer.events.on({visibilitychanged:this.reset,scope:this}));return a},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&(this.stop(),this.layer.events.un({visibilitychanged:this.reset,scope:this}));return a},reset:function(){!0===this.layer.visibility? | |
2865 this.start():this.stop()},start:function(){this.interval&&("number"===typeof this.interval&&0<this.interval)&&(this.timer=window.setInterval(OpenLayers.Function.bind(this.refresh,this),this.interval))},refresh:function(){this.layer&&(this.layer.refresh&&"function"==typeof this.layer.refresh)&&this.layer.refresh({force:this.force})},stop:function(){null!==this.timer&&(window.clearInterval(this.timer),this.timer=null)},CLASS_NAME:"OpenLayers.Strategy.Refresh"});OpenLayers.Layer.ArcGIS93Rest=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{format:"png"},isBaseLayer:!0,initialize:function(a,b,c,d){var e=[];c=OpenLayers.Util.upperCaseObject(c);e.push(a,b,c,d);OpenLayers.Layer.Grid.prototype.initialize.apply(this,e);OpenLayers.Util.applyDefaults(this.params,OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS));this.params.TRANSPARENT&&"true"==this.params.TRANSPARENT.toString().toLowerCase()&&(null!=d&&d.isBaseLayer||(this.isBaseLayer=!1),"jpg"==this.params.FORMAT&& | |
2866 (this.params.FORMAT=OpenLayers.Util.alphaHack()?"gif":"png"))},clone:function(a){null==a&&(a=new OpenLayers.Layer.ArcGIS93Rest(this.name,this.url,this.params,this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getURL:function(a){a=this.adjustBounds(a);var b=this.projection.getCode().split(":"),b=b[b.length-1],c=this.getImageSize();a={BBOX:a.toBBOX(),SIZE:c.w+","+c.h,F:"image",BBOXSR:b,IMAGESR:b};if(this.layerDefs){var b=[],d;for(d in this.layerDefs)this.layerDefs.hasOwnProperty(d)&& | |
2867 this.layerDefs[d]&&(b.push(d),b.push(":"),b.push(this.layerDefs[d]),b.push(";"));0<b.length&&(a.LAYERDEFS=b.join(""))}return this.getFullRequestString(a)},setLayerFilter:function(a,b){this.layerDefs||(this.layerDefs={});b?this.layerDefs[a]=b:delete this.layerDefs[a]},clearLayerFilter:function(a){a?delete this.layerDefs[a]:delete this.layerDefs},mergeNewParams:function(a){a=[OpenLayers.Util.upperCaseObject(a)];return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,a)},CLASS_NAME:"OpenLayers.Layer.ArcGIS93Rest"});OpenLayers.Handler.Hover=OpenLayers.Class(OpenLayers.Handler,{delay:500,pixelTolerance:null,stopMove:!1,px:null,timerId:null,mousemove:function(a){this.passesTolerance(a.xy)&&(this.clearTimer(),this.callback("move",[a]),this.px=a.xy,a=OpenLayers.Util.extend({},a),this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,this,a),this.delay));return!this.stopMove},mouseout:function(a){OpenLayers.Util.mouseLeft(a,this.map.viewPortDiv)&&(this.clearTimer(),this.callback("move",[a]));return!0}, | |
2868 passesTolerance:function(a){var b=!0;this.pixelTolerance&&this.px&&Math.sqrt(Math.pow(this.px.x-a.x,2)+Math.pow(this.px.y-a.y,2))<this.pixelTolerance&&(b=!1);return b},clearTimer:function(){null!=this.timerId&&(window.clearTimeout(this.timerId),this.timerId=null)},delayedCall:function(a){this.callback("pause",[a])},deactivate:function(){var a=!1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.clearTimer(),a=!0);return a},CLASS_NAME:"OpenLayers.Handler.Hover"});OpenLayers.Control.GetFeature=OpenLayers.Class(OpenLayers.Control,{protocol:null,multipleKey:null,toggleKey:null,modifiers:null,multiple:!1,click:!0,single:!0,clickout:!0,toggle:!1,clickTolerance:5,hover:!1,box:!1,maxFeatures:10,features:null,hoverFeature:null,handlers:null,hoverResponse:null,filterType:OpenLayers.Filter.Spatial.BBOX,initialize:function(a){a.handlerOptions=a.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[a]);this.features={};this.handlers={};this.click&&(this.handlers.click= | |
2869 new OpenLayers.Handler.Click(this,{click:this.selectClick},this.handlerOptions.click||{}));this.box&&(this.handlers.box=new OpenLayers.Handler.Box(this,{done:this.selectBox},OpenLayers.Util.extend(this.handlerOptions.box,{boxDivClassName:"olHandlerBoxSelectFeature"})));this.hover&&(this.handlers.hover=new OpenLayers.Handler.Hover(this,{move:this.cancelHover,pause:this.selectHover},OpenLayers.Util.extend(this.handlerOptions.hover,{delay:250,pixelTolerance:2})))},activate:function(){if(!this.active)for(var a in this.handlers)this.handlers[a].activate(); | |
2870 return OpenLayers.Control.prototype.activate.apply(this,arguments)},deactivate:function(){if(this.active)for(var a in this.handlers)this.handlers[a].deactivate();return OpenLayers.Control.prototype.deactivate.apply(this,arguments)},selectClick:function(a){var b=this.pixelToBounds(a.xy);this.setModifiers(a);this.request(b,{single:this.single})},selectBox:function(a){var b;if(a instanceof OpenLayers.Bounds)b=this.map.getLonLatFromPixel({x:a.left,y:a.bottom}),a=this.map.getLonLatFromPixel({x:a.right, | |
2871 y:a.top}),b=new OpenLayers.Bounds(b.lon,b.lat,a.lon,a.lat);else{if(this.click)return;b=this.pixelToBounds(a)}this.setModifiers(this.handlers.box.dragHandler.evt);this.request(b)},selectHover:function(a){a=this.pixelToBounds(a.xy);this.request(a,{single:!0,hover:!0})},cancelHover:function(){this.hoverResponse&&(this.protocol.abort(this.hoverResponse),this.hoverResponse=null,OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait"))},request:function(a,b){b=b||{};var c=new OpenLayers.Filter.Spatial({type:this.filterType, | |
2872 value:a});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");c=this.protocol.read({maxFeatures:!0==b.single?this.maxFeatures:void 0,filter:c,callback:function(c){c.success()&&(c.features.length?!0==b.single?this.selectBestFeature(c.features,a.getCenterLonLat(),b):this.select(c.features):b.hover?this.hoverSelect():(this.events.triggerEvent("clickout"),this.clickout&&this.unselectAll()));OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait")},scope:this});!0==b.hover&&(this.hoverResponse= | |
2873 c)},selectBestFeature:function(a,b,c){c=c||{};if(a.length){b=new OpenLayers.Geometry.Point(b.lon,b.lat);for(var d,e,f,g=Number.MAX_VALUE,h=0;h<a.length&&!(d=a[h],d.geometry&&(f=b.distanceTo(d.geometry,{edge:!1}),f<g&&(g=f,e=d,0==g)));++h);!0==c.hover?this.hoverSelect(e):this.select(e||a)}},setModifiers:function(a){this.modifiers={multiple:this.multiple||this.multipleKey&&a[this.multipleKey],toggle:this.toggle||this.toggleKey&&a[this.toggleKey]}},select:function(a){this.modifiers.multiple||this.modifiers.toggle|| | |
2874 this.unselectAll();OpenLayers.Util.isArray(a)||(a=[a]);var b=this.events.triggerEvent("beforefeaturesselected",{features:a});if(!1!==b){for(var c=[],d,e=0,f=a.length;e<f;++e)d=a[e],this.features[d.fid||d.id]?this.modifiers.toggle&&this.unselect(this.features[d.fid||d.id]):(b=this.events.triggerEvent("beforefeatureselected",{feature:d}),!1!==b&&(this.features[d.fid||d.id]=d,c.push(d),this.events.triggerEvent("featureselected",{feature:d})));this.events.triggerEvent("featuresselected",{features:c})}}, | |
2875 hoverSelect:function(a){var b=a?a.fid||a.id:null,c=this.hoverFeature?this.hoverFeature.fid||this.hoverFeature.id:null;c&&c!=b&&(this.events.triggerEvent("outfeature",{feature:this.hoverFeature}),this.hoverFeature=null);b&&b!=c&&(this.events.triggerEvent("hoverfeature",{feature:a}),this.hoverFeature=a)},unselect:function(a){delete this.features[a.fid||a.id];this.events.triggerEvent("featureunselected",{feature:a})},unselectAll:function(){for(var a in this.features)this.unselect(this.features[a])}, | |
2876 setMap:function(a){for(var b in this.handlers)this.handlers[b].setMap(a);OpenLayers.Control.prototype.setMap.apply(this,arguments)},pixelToBounds:function(a){var b=a.add(-this.clickTolerance/2,this.clickTolerance/2);a=a.add(this.clickTolerance/2,-this.clickTolerance/2);b=this.map.getLonLatFromPixel(b);a=this.map.getLonLatFromPixel(a);return new OpenLayers.Bounds(b.lon,b.lat,a.lon,a.lat)},CLASS_NAME:"OpenLayers.Control.GetFeature"});OpenLayers.Format.QueryStringFilter=function(){function a(a){a=a.replace(/%/g,"\\%");a=a.replace(/\\\\\.(\*)?/g,function(a,b){return b?a:"\\\\_"});a=a.replace(/\\\\\.\*/g,"\\\\%");a=a.replace(/(\\)?\.(\*)?/g,function(a,b,c){return b||c?a:"_"});a=a.replace(/(\\)?\.\*/g,function(a,b){return b?a:"%"});a=a.replace(/\\\./g,".");return a=a.replace(/(\\)?\\\*/g,function(a,b){return b?a:"*"})}var b={};b[OpenLayers.Filter.Comparison.EQUAL_TO]="eq";b[OpenLayers.Filter.Comparison.NOT_EQUAL_TO]="ne";b[OpenLayers.Filter.Comparison.LESS_THAN]= | |
2877 "lt";b[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO]="lte";b[OpenLayers.Filter.Comparison.GREATER_THAN]="gt";b[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO]="gte";b[OpenLayers.Filter.Comparison.LIKE]="ilike";return OpenLayers.Class(OpenLayers.Format,{wildcarded:!1,srsInBBOX:!1,write:function(c,d){d=d||{};var e=c.CLASS_NAME,e=e.substring(e.lastIndexOf(".")+1);switch(e){case "Spatial":switch(c.type){case OpenLayers.Filter.Spatial.BBOX:d.bbox=c.value.toArray();this.srsInBBOX&&c.projection&& | |
2878 d.bbox.push(c.projection.getCode());break;case OpenLayers.Filter.Spatial.DWITHIN:d.tolerance=c.distance;case OpenLayers.Filter.Spatial.WITHIN:d.lon=c.value.x;d.lat=c.value.y;break;default:OpenLayers.Console.warn("Unknown spatial filter type "+c.type)}break;case "Comparison":e=b[c.type];if(void 0!==e){var f=c.value;c.type==OpenLayers.Filter.Comparison.LIKE&&(f=a(f),this.wildcarded&&(f="%"+f+"%"));d[c.property+"__"+e]=f;d.queryable=d.queryable||[];d.queryable.push(c.property)}else OpenLayers.Console.warn("Unknown comparison filter type "+ | |
2879 c.type);break;case "Logical":if(c.type===OpenLayers.Filter.Logical.AND)for(e=0,f=c.filters.length;e<f;e++)d=this.write(c.filters[e],d);else OpenLayers.Console.warn("Unsupported logical filter type "+c.type);break;default:OpenLayers.Console.warn("Unknown filter type "+e)}return d},CLASS_NAME:"OpenLayers.Format.QueryStringFilter"})}();OpenLayers.Control.MousePosition=OpenLayers.Class(OpenLayers.Control,{autoActivate:!0,element:null,prefix:"",separator:", ",suffix:"",numDigits:5,granularity:10,emptyString:null,lastXy:null,displayProjection:null,destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments)},activate:function(){return OpenLayers.Control.prototype.activate.apply(this,arguments)?(this.map.events.register("mousemove",this,this.redraw),this.map.events.register("mouseout",this,this.reset), | |
2880 this.redraw(),!0):!1},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments)?(this.map.events.unregister("mousemove",this,this.redraw),this.map.events.unregister("mouseout",this,this.reset),this.element.innerHTML="",!0):!1},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.element||(this.div.left="",this.div.top="",this.element=this.div);return this.div},redraw:function(a){var b;if(null==a)this.reset();else if(null==this.lastXy||Math.abs(a.xy.x- | |
2881 this.lastXy.x)>this.granularity||Math.abs(a.xy.y-this.lastXy.y)>this.granularity)this.lastXy=a.xy;else if(b=this.map.getLonLatFromPixel(a.xy))this.displayProjection&&b.transform(this.map.getProjectionObject(),this.displayProjection),this.lastXy=a.xy,a=this.formatOutput(b),a!=this.element.innerHTML&&(this.element.innerHTML=a)},reset:function(a){null!=this.emptyString&&(this.element.innerHTML=this.emptyString)},formatOutput:function(a){var b=parseInt(this.numDigits);return this.prefix+a.lon.toFixed(b)+ | |
2882 this.separator+a.lat.toFixed(b)+this.suffix},CLASS_NAME:"OpenLayers.Control.MousePosition"});OpenLayers.Control.Geolocate=OpenLayers.Class(OpenLayers.Control,{geolocation:null,available:"geolocation"in navigator,bind:!0,watch:!1,geolocationOptions:null,destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments)},activate:function(){this.available&&!this.geolocation&&(this.geolocation=navigator.geolocation);return this.geolocation?OpenLayers.Control.prototype.activate.apply(this,arguments)?(this.watch?this.watchId=this.geolocation.watchPosition(OpenLayers.Function.bind(this.geolocate, | |
2883 this),OpenLayers.Function.bind(this.failure,this),this.geolocationOptions):this.getCurrentLocation(),!0):!1:(this.events.triggerEvent("locationuncapable"),!1)},deactivate:function(){this.active&&null!==this.watchId&&this.geolocation.clearWatch(this.watchId);return OpenLayers.Control.prototype.deactivate.apply(this,arguments)},geolocate:function(a){var b=(new OpenLayers.LonLat(a.coords.longitude,a.coords.latitude)).transform(new OpenLayers.Projection("EPSG:4326"),this.map.getProjectionObject());this.bind&& | |
2884 this.map.setCenter(b);this.events.triggerEvent("locationupdated",{position:a,point:new OpenLayers.Geometry.Point(b.lon,b.lat)})},getCurrentLocation:function(){if(!this.active||this.watch)return!1;this.geolocation.getCurrentPosition(OpenLayers.Function.bind(this.geolocate,this),OpenLayers.Function.bind(this.failure,this),this.geolocationOptions);return!0},failure:function(a){this.events.triggerEvent("locationfailed",{error:a})},CLASS_NAME:"OpenLayers.Control.Geolocate"});OpenLayers.Tile.UTFGrid=OpenLayers.Class(OpenLayers.Tile,{url:null,utfgridResolution:2,json:null,format:null,destroy:function(){this.clear();OpenLayers.Tile.prototype.destroy.apply(this,arguments)},draw:function(){var a=OpenLayers.Tile.prototype.draw.apply(this,arguments);if(a)if(this.isLoading?(this.abortLoading(),this.events.triggerEvent("reload")):(this.isLoading=!0,this.events.triggerEvent("loadstart")),this.url=this.layer.getURL(this.bounds),this.layer.useJSONP){var b=new OpenLayers.Protocol.Script({url:this.url, | |
2885 callback:function(a){this.isLoading=!1;this.events.triggerEvent("loadend");this.json=a.data},scope:this});b.read();this.request=b}else this.request=OpenLayers.Request.GET({url:this.url,callback:function(a){this.isLoading=!1;this.events.triggerEvent("loadend");200===a.status&&this.parseData(a.responseText)},scope:this});else this.unload();return a},abortLoading:function(){this.request&&(this.request.abort(),delete this.request);this.isLoading=!1},getFeatureInfo:function(a,b){var c=null;if(this.json){var d= | |
2886 this.getFeatureId(a,b);null!==d&&(c={id:d,data:this.json.data[d]})}return c},getFeatureId:function(a,b){var c=null;if(this.json){var d=this.utfgridResolution,d=this.json.grid[Math.floor(b/d)].charCodeAt(Math.floor(a/d)),d=this.indexFromCharCode(d),e=this.json.keys;!isNaN(d)&&d in e&&(c=e[d])}return c},indexFromCharCode:function(a){93<=a&&a--;35<=a&&a--;return a-32},parseData:function(a){this.format||(this.format=new OpenLayers.Format.JSON);this.json=this.format.read(a)},clear:function(){this.json= | |
2887 null},CLASS_NAME:"OpenLayers.Tile.UTFGrid"});OpenLayers.Protocol.HTTP=OpenLayers.Class(OpenLayers.Protocol,{url:null,headers:null,params:null,callback:null,scope:null,readWithPOST:!1,updateWithPOST:!1,deleteWithPOST:!1,wildcarded:!1,srsInBBOX:!1,initialize:function(a){a=a||{};this.params={};this.headers={};OpenLayers.Protocol.prototype.initialize.apply(this,arguments);if(!this.filterToParams&&OpenLayers.Format.QueryStringFilter){var b=new OpenLayers.Format.QueryStringFilter({wildcarded:this.wildcarded,srsInBBOX:this.srsInBBOX});this.filterToParams= | |
2888 function(a,d){return b.write(a,d)}}},destroy:function(){this.headers=this.params=null;OpenLayers.Protocol.prototype.destroy.apply(this)},read:function(a){OpenLayers.Protocol.prototype.read.apply(this,arguments);a=a||{};a.params=OpenLayers.Util.applyDefaults(a.params,this.options.params);a=OpenLayers.Util.applyDefaults(a,this.options);a.filter&&this.filterToParams&&(a.params=this.filterToParams(a.filter,a.params));var b=void 0!==a.readWithPOST?a.readWithPOST:this.readWithPOST,c=new OpenLayers.Protocol.Response({requestType:"read"}); | |
2889 b?(b=a.headers||{},b["Content-Type"]="application/x-www-form-urlencoded",c.priv=OpenLayers.Request.POST({url:a.url,callback:this.createCallback(this.handleRead,c,a),data:OpenLayers.Util.getParameterString(a.params),headers:b})):c.priv=OpenLayers.Request.GET({url:a.url,callback:this.createCallback(this.handleRead,c,a),params:a.params,headers:a.headers});return c},handleRead:function(a,b){this.handleResponse(a,b)},create:function(a,b){b=OpenLayers.Util.applyDefaults(b,this.options);var c=new OpenLayers.Protocol.Response({reqFeatures:a, | |
2890 requestType:"create"});c.priv=OpenLayers.Request.POST({url:b.url,callback:this.createCallback(this.handleCreate,c,b),headers:b.headers,data:this.format.write(a)});return c},handleCreate:function(a,b){this.handleResponse(a,b)},update:function(a,b){b=b||{};var c=b.url||a.url||this.options.url+"/"+a.fid;b=OpenLayers.Util.applyDefaults(b,this.options);var d=new OpenLayers.Protocol.Response({reqFeatures:a,requestType:"update"});d.priv=OpenLayers.Request[this.updateWithPOST?"POST":"PUT"]({url:c,callback:this.createCallback(this.handleUpdate, | |
2891 d,b),headers:b.headers,data:this.format.write(a)});return d},handleUpdate:function(a,b){this.handleResponse(a,b)},"delete":function(a,b){b=b||{};var c=b.url||a.url||this.options.url+"/"+a.fid;b=OpenLayers.Util.applyDefaults(b,this.options);var d=new OpenLayers.Protocol.Response({reqFeatures:a,requestType:"delete"}),e=this.deleteWithPOST?"POST":"DELETE",c={url:c,callback:this.createCallback(this.handleDelete,d,b),headers:b.headers};this.deleteWithPOST&&(c.data=this.format.write(a));d.priv=OpenLayers.Request[e](c); | |
2892 return d},handleDelete:function(a,b){this.handleResponse(a,b)},handleResponse:function(a,b){var c=a.priv;b.callback&&(200<=c.status&&300>c.status?("delete"!=a.requestType&&(a.features=this.parseFeatures(c)),a.code=OpenLayers.Protocol.Response.SUCCESS):a.code=OpenLayers.Protocol.Response.FAILURE,b.callback.call(b.scope,a))},parseFeatures:function(a){var b=a.responseXML;b&&b.documentElement||(b=a.responseText);return!b||0>=b.length?null:this.format.read(b)},commit:function(a,b){function c(a){for(var b= | |
2893 a.features?a.features.length:0,c=Array(b),e=0;e<b;++e)c[e]=a.features[e].fid;r.insertIds=c;d.apply(this,[a])}function d(a){this.callUserCallback(a,b);q=q&&a.success();f++;f>=p&&b.callback&&(r.code=q?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE,b.callback.apply(b.scope,[r]))}b=OpenLayers.Util.applyDefaults(b,this.options);var e=[],f=0,g={};g[OpenLayers.State.INSERT]=[];g[OpenLayers.State.UPDATE]=[];g[OpenLayers.State.DELETE]=[];for(var h,k,l=[],m=0,n=a.length;m<n;++m)if(h= | |
2894 a[m],k=g[h.state])k.push(h),l.push(h);var p=(0<g[OpenLayers.State.INSERT].length?1:0)+g[OpenLayers.State.UPDATE].length+g[OpenLayers.State.DELETE].length,q=!0,r=new OpenLayers.Protocol.Response({reqFeatures:l});h=g[OpenLayers.State.INSERT];0<h.length&&e.push(this.create(h,OpenLayers.Util.applyDefaults({callback:c,scope:this},b.create)));h=g[OpenLayers.State.UPDATE];for(m=h.length-1;0<=m;--m)e.push(this.update(h[m],OpenLayers.Util.applyDefaults({callback:d,scope:this},b.update)));h=g[OpenLayers.State.DELETE]; | |
2895 for(m=h.length-1;0<=m;--m)e.push(this["delete"](h[m],OpenLayers.Util.applyDefaults({callback:d,scope:this},b["delete"])));return e},abort:function(a){a&&a.priv.abort()},callUserCallback:function(a,b){var c=b[a.requestType];c&&c.callback&&c.callback.call(c.scope,a)},CLASS_NAME:"OpenLayers.Protocol.HTTP"});OpenLayers.Strategy.Cluster=OpenLayers.Class(OpenLayers.Strategy,{distance:20,threshold:null,features:null,clusters:null,clustering:!1,resolution:null,activate:function(){var a=OpenLayers.Strategy.prototype.activate.call(this);if(a)this.layer.events.on({beforefeaturesadded:this.cacheFeatures,featuresremoved:this.clearCache,moveend:this.cluster,scope:this});return a},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&(this.clearCache(),this.layer.events.un({beforefeaturesadded:this.cacheFeatures, | |
2896 featuresremoved:this.clearCache,moveend:this.cluster,scope:this}));return a},cacheFeatures:function(a){var b=!0;this.clustering||(this.clearCache(),this.features=a.features,this.cluster(),b=!1);return b},clearCache:function(){this.clustering||(this.features=null)},cluster:function(a){if((!a||a.zoomChanged)&&this.features&&(a=this.layer.map.getResolution(),a!=this.resolution||!this.clustersExist())){this.resolution=a;a=[];for(var b,c,d,e=0;e<this.features.length;++e)if(b=this.features[e],b.geometry){c= | |
2897 !1;for(var f=a.length-1;0<=f;--f)if(d=a[f],this.shouldCluster(d,b)){this.addToCluster(d,b);c=!0;break}c||a.push(this.createCluster(this.features[e]))}this.clustering=!0;this.layer.removeAllFeatures();this.clustering=!1;if(0<a.length){if(1<this.threshold)for(b=a.slice(),a=[],e=0,d=b.length;e<d;++e)c=b[e],c.attributes.count<this.threshold?Array.prototype.push.apply(a,c.cluster):a.push(c);this.clustering=!0;this.layer.addFeatures(a);this.clustering=!1}this.clusters=a}},clustersExist:function(){var a= | |
2898 !1;if(this.clusters&&0<this.clusters.length&&this.clusters.length==this.layer.features.length)for(var a=!0,b=0;b<this.clusters.length;++b)if(this.clusters[b]!=this.layer.features[b]){a=!1;break}return a},shouldCluster:function(a,b){var c=a.geometry.getBounds().getCenterLonLat(),d=b.geometry.getBounds().getCenterLonLat();return Math.sqrt(Math.pow(c.lon-d.lon,2)+Math.pow(c.lat-d.lat,2))/this.resolution<=this.distance},addToCluster:function(a,b){a.cluster.push(b);a.attributes.count+=1},createCluster:function(a){var b= | |
2899 a.geometry.getBounds().getCenterLonLat(),b=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(b.lon,b.lat),{count:1});b.cluster=[a];return b},CLASS_NAME:"OpenLayers.Strategy.Cluster"});OpenLayers.Strategy.Filter=OpenLayers.Class(OpenLayers.Strategy,{filter:null,cache:null,caching:!1,activate:function(){var a=OpenLayers.Strategy.prototype.activate.apply(this,arguments);a&&(this.cache=[],this.layer.events.on({beforefeaturesadded:this.handleAdd,beforefeaturesremoved:this.handleRemove,scope:this}));return a},deactivate:function(){this.cache=null;this.layer&&this.layer.events&&this.layer.events.un({beforefeaturesadded:this.handleAdd,beforefeaturesremoved:this.handleRemove,scope:this}); | |
2900 return OpenLayers.Strategy.prototype.deactivate.apply(this,arguments)},handleAdd:function(a){if(!this.caching&&this.filter){var b=a.features;a.features=[];for(var c,d=0,e=b.length;d<e;++d)c=b[d],this.filter.evaluate(c)?a.features.push(c):this.cache.push(c)}},handleRemove:function(a){this.caching||(this.cache=[])},setFilter:function(a){this.filter=a;a=this.cache;this.cache=[];this.handleAdd({features:this.layer.features});0<this.cache.length&&(this.caching=!0,this.layer.removeFeatures(this.cache.slice()), | |
2901 this.caching=!1);0<a.length&&(a={features:a},this.handleAdd(a),0<a.features.length&&(this.caching=!0,this.layer.addFeatures(a.features),this.caching=!1))},CLASS_NAME:"OpenLayers.Strategy.Filter"});OpenLayers.Protocol.SOS=function(a){a=OpenLayers.Util.applyDefaults(a,OpenLayers.Protocol.SOS.DEFAULTS);var b=OpenLayers.Protocol.SOS["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported SOS version: "+a.version;return new b(a)};OpenLayers.Protocol.SOS.DEFAULTS={version:"1.0.0"};OpenLayers.Format.WFSDescribeFeatureType=OpenLayers.Class(OpenLayers.Format.XML,{regExes:{trimSpace:/^\s*|\s*$/g},namespaces:{xsd:"http://www.w3.org/2001/XMLSchema"},readers:{xsd:{schema:function(a,b){var c=[],d={},e,f;this.readChildNodes(a,{complexTypes:c,customTypes:d});var g=a.attributes,h,k;e=0;for(f=g.length;e<f;++e)h=g[e],k=h.name,0===k.indexOf("xmlns")?this.setNamespace(k.split(":")[1]||"",h.value):b[k]=h.value;b.featureTypes=c;b.targetPrefix=this.namespaceAlias[b.targetNamespace];e=0;for(f= | |
2902 c.length;e<f;++e)g=c[e],h=d[g.typeName],d[g.typeName]&&(g.typeName=h.name)},complexType:function(a,b){var c={typeName:a.getAttribute("name")};this.readChildNodes(a,c);b.complexTypes.push(c)},complexContent:function(a,b){this.readChildNodes(a,b)},extension:function(a,b){this.readChildNodes(a,b)},sequence:function(a,b){var c={elements:[]};this.readChildNodes(a,c);b.properties=c.elements},element:function(a,b){var c;if(b.elements){var d={};c=a.attributes;for(var e,f=0,g=c.length;f<g;++f)e=c[f],d[e.name]= | |
2903 e.value;c=d.type;c||(c={},this.readChildNodes(a,c),d.restriction=c,d.type=c.base);d.localType=(c.base||c).split(":").pop();b.elements.push(d);this.readChildNodes(a,d)}b.complexTypes&&(c=a.getAttribute("type"),d=c.split(":").pop(),b.customTypes[d]={name:a.getAttribute("name"),type:c})},annotation:function(a,b){b.annotation={};this.readChildNodes(a,b.annotation)},appinfo:function(a,b){b.appinfo||(b.appinfo=[]);b.appinfo.push(this.getChildValue(a))},documentation:function(a,b){b.documentation||(b.documentation= | |
2904 []);var c=this.getChildValue(a);b.documentation.push({lang:a.getAttribute("xml:lang"),textContent:c.replace(this.regExes.trimSpace,"")})},simpleType:function(a,b){this.readChildNodes(a,b)},restriction:function(a,b){b.base=a.getAttribute("base");this.readRestriction(a,b)}}},readRestriction:function(a,b){for(var c=a.childNodes,d,e,f=0,g=c.length;f<g;++f)d=c[f],1==d.nodeType&&(e=d.nodeName.split(":").pop(),d=d.getAttribute("value"),b[e]?("string"==typeof b[e]&&(b[e]=[b[e]]),b[e].push(d)):b[e]=d)},read:function(a){"string"== | |
2905 typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};if("ExceptionReport"===a.nodeName.split(":").pop()){var c=new OpenLayers.Format.OGCExceptionReport;b.error=c.read(a)}else this.readNode(a,b);return b},CLASS_NAME:"OpenLayers.Format.WFSDescribeFeatureType"});OpenLayers.Format.GeoRSS=OpenLayers.Class(OpenLayers.Format.XML,{rssns:"http://backend.userland.com/rss2",featureNS:"http://mapserver.gis.umn.edu/mapserver",georssns:"http://www.georss.org/georss",geons:"http://www.w3.org/2003/01/geo/wgs84_pos#",featureTitle:"Untitled",featureDescription:"No Description",gmlParser:null,xy:!1,createGeometryFromItem:function(a){var b=this.getElementsByTagNameNS(a,this.georssns,"point"),c=this.getElementsByTagNameNS(a,this.geons,"lat"),d=this.getElementsByTagNameNS(a, | |
2906 this.geons,"long"),e=this.getElementsByTagNameNS(a,this.georssns,"line"),f=this.getElementsByTagNameNS(a,this.georssns,"polygon"),g=this.getElementsByTagNameNS(a,this.georssns,"where");a=this.getElementsByTagNameNS(a,this.georssns,"box");if(0<b.length||0<c.length&&0<d.length){0<b.length?(c=OpenLayers.String.trim(b[0].firstChild.nodeValue).split(/\s+/),2!=c.length&&(c=OpenLayers.String.trim(b[0].firstChild.nodeValue).split(/\s*,\s*/))):c=[parseFloat(c[0].firstChild.nodeValue),parseFloat(d[0].firstChild.nodeValue)]; | |
2907 var h=new OpenLayers.Geometry.Point(c[1],c[0])}else if(0<e.length){c=OpenLayers.String.trim(this.getChildValue(e[0])).split(/\s+/);d=[];e=0;for(f=c.length;e<f;e+=2)b=new OpenLayers.Geometry.Point(c[e+1],c[e]),d.push(b);h=new OpenLayers.Geometry.LineString(d)}else if(0<f.length){c=OpenLayers.String.trim(this.getChildValue(f[0])).split(/\s+/);d=[];e=0;for(f=c.length;e<f;e+=2)b=new OpenLayers.Geometry.Point(c[e+1],c[e]),d.push(b);h=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(d)])}else 0< | |
2908 g.length?(this.gmlParser||(this.gmlParser=new OpenLayers.Format.GML({xy:this.xy})),h=this.gmlParser.parseFeature(g[0]).geometry):0<a.length&&(c=OpenLayers.String.trim(a[0].firstChild.nodeValue).split(/\s+/),d=[],3<c.length&&(b=new OpenLayers.Geometry.Point(c[1],c[0]),d.push(b),b=new OpenLayers.Geometry.Point(c[1],c[2]),d.push(b),b=new OpenLayers.Geometry.Point(c[3],c[2]),d.push(b),b=new OpenLayers.Geometry.Point(c[3],c[0]),d.push(b),b=new OpenLayers.Geometry.Point(c[1],c[0]),d.push(b)),h=new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(d)])); | |
2909 h&&(this.internalProjection&&this.externalProjection)&&h.transform(this.externalProjection,this.internalProjection);return h},createFeatureFromItem:function(a){var b=this.createGeometryFromItem(a),c=this._getChildValue(a,"*","title",this.featureTitle),d=this._getChildValue(a,"*","description",this._getChildValue(a,"*","content",this._getChildValue(a,"*","summary",this.featureDescription))),e=this._getChildValue(a,"*","link");if(!e)try{e=this.getElementsByTagNameNS(a,"*","link")[0].getAttribute("href")}catch(f){e= | |
2910 null}a=this._getChildValue(a,"*","id",null);b=new OpenLayers.Feature.Vector(b,{title:c,description:d,link:e});b.fid=a;return b},_getChildValue:function(a,b,c,d){return(a=this.getElementsByTagNameNS(a,b,c))&&a[0]&&a[0].firstChild&&a[0].firstChild.nodeValue?this.getChildValue(a[0]):void 0==d?"":d},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b=null,b=this.getElementsByTagNameNS(a,"*","item");0==b.length&&(b=this.getElementsByTagNameNS(a,"*","entry")); | |
2911 a=b.length;for(var c=Array(a),d=0;d<a;d++)c[d]=this.createFeatureFromItem(b[d]);return c},write:function(a){var b;if(OpenLayers.Util.isArray(a)){b=this.createElementNS(this.rssns,"rss");for(var c=0,d=a.length;c<d;c++)b.appendChild(this.createFeatureXML(a[c]))}else b=this.createFeatureXML(a);return OpenLayers.Format.XML.prototype.write.apply(this,[b])},createFeatureXML:function(a){var b=this.buildGeometryNode(a.geometry),c=this.createElementNS(this.rssns,"item"),d=this.createElementNS(this.rssns,"title"); | |
2912 d.appendChild(this.createTextNode(a.attributes.title?a.attributes.title:""));var e=this.createElementNS(this.rssns,"description");e.appendChild(this.createTextNode(a.attributes.description?a.attributes.description:""));c.appendChild(d);c.appendChild(e);a.attributes.link&&(d=this.createElementNS(this.rssns,"link"),d.appendChild(this.createTextNode(a.attributes.link)),c.appendChild(d));for(var f in a.attributes)"link"!=f&&("title"!=f&&"description"!=f)&&(d=this.createTextNode(a.attributes[f]),e=f,-1!= | |
2913 f.search(":")&&(e=f.split(":")[1]),e=this.createElementNS(this.featureNS,"feature:"+e),e.appendChild(d),c.appendChild(e));c.appendChild(b);return c},buildGeometryNode:function(a){this.internalProjection&&this.externalProjection&&(a=a.clone(),a.transform(this.internalProjection,this.externalProjection));var b;if("OpenLayers.Geometry.Polygon"==a.CLASS_NAME)b=this.createElementNS(this.georssns,"georss:polygon"),b.appendChild(this.buildCoordinatesNode(a.components[0]));else if("OpenLayers.Geometry.LineString"== | |
2914 a.CLASS_NAME)b=this.createElementNS(this.georssns,"georss:line"),b.appendChild(this.buildCoordinatesNode(a));else if("OpenLayers.Geometry.Point"==a.CLASS_NAME)b=this.createElementNS(this.georssns,"georss:point"),b.appendChild(this.buildCoordinatesNode(a));else throw"Couldn't parse "+a.CLASS_NAME;return b},buildCoordinatesNode:function(a){var b=null;a.components&&(b=a.components);if(b){a=b.length;for(var c=Array(a),d=0;d<a;d++)c[d]=b[d].y+" "+b[d].x;b=c.join(" ")}else b=a.y+" "+a.x;return this.createTextNode(b)}, | |
2915 CLASS_NAME:"OpenLayers.Format.GeoRSS"});OpenLayers.Format.WPSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.0.0",CLASS_NAME:"OpenLayers.Format.WPSCapabilities"});OpenLayers.Format.WPSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ows:"http://www.opengis.net/ows/1.1",wps:"http://www.opengis.net/wps/1.0.0",xlink:"http://www.w3.org/1999/xlink"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a])},read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement); | |
2916 var b={};this.readNode(a,b);return b},readers:{wps:{Capabilities:function(a,b){this.readChildNodes(a,b)},ProcessOfferings:function(a,b){b.processOfferings={};this.readChildNodes(a,b.processOfferings)},Process:function(a,b){var c={processVersion:this.getAttributeNS(a,this.namespaces.wps,"processVersion")};this.readChildNodes(a,c);b[c.identifier]=c},Languages:function(a,b){b.languages=[];this.readChildNodes(a,b.languages)},Default:function(a,b){var c={isDefault:!0};this.readChildNodes(a,c);b.push(c)}, | |
2917 Supported:function(a,b){var c={};this.readChildNodes(a,c);b.push(c)}},ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows},CLASS_NAME:"OpenLayers.Format.WPSCapabilities.v1_0_0"});OpenLayers.Control.PinchZoom=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,pinchOrigin:null,currentCenter:null,autoActivate:!0,preserveCenter:!1,initialize:function(a){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.handler=new OpenLayers.Handler.Pinch(this,{start:this.pinchStart,move:this.pinchMove,done:this.pinchDone},this.handlerOptions)},pinchStart:function(a,b){var c=this.preserveCenter?this.map.getPixelFromLonLat(this.map.getCenter()):a.xy;this.currentCenter= | |
2918 this.pinchOrigin=c},pinchMove:function(a,b){var c=b.scale,d=this.map.layerContainerOriginPx,e=this.pinchOrigin,f=this.preserveCenter?this.map.getPixelFromLonLat(this.map.getCenter()):a.xy,g=Math.round(d.x+f.x-e.x+(c-1)*(d.x-e.x)),d=Math.round(d.y+f.y-e.y+(c-1)*(d.y-e.y));this.map.applyTransform(g,d,c);this.currentCenter=f},pinchDone:function(a,b,c){this.map.applyTransform();a=this.map.getZoomForResolution(this.map.getResolution()/c.scale,!0);if(a!==this.map.getZoom()||!this.currentCenter.equals(this.pinchOrigin)){b= | |
2919 this.map.getResolutionForZoom(a);c=this.map.getLonLatFromPixel(this.pinchOrigin);var d=this.currentCenter,e=this.map.getSize();c.lon+=b*(e.w/2-d.x);c.lat-=b*(e.h/2-d.y);this.map.div.clientWidth=this.map.div.clientWidth;this.map.setCenter(c,a)}},CLASS_NAME:"OpenLayers.Control.PinchZoom"});OpenLayers.Control.TouchNavigation=OpenLayers.Class(OpenLayers.Control,{dragPan:null,dragPanOptions:null,pinchZoom:null,pinchZoomOptions:null,clickHandlerOptions:null,documentDrag:!1,autoActivate:!0,initialize:function(a){this.handlers={};OpenLayers.Control.prototype.initialize.apply(this,arguments)},destroy:function(){this.deactivate();this.dragPan&&this.dragPan.destroy();this.dragPan=null;this.pinchZoom&&(this.pinchZoom.destroy(),delete this.pinchZoom);OpenLayers.Control.prototype.destroy.apply(this, | |
2920 arguments)},activate:function(){return OpenLayers.Control.prototype.activate.apply(this,arguments)?(this.dragPan.activate(),this.handlers.click.activate(),this.pinchZoom.activate(),!0):!1},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this,arguments)?(this.dragPan.deactivate(),this.handlers.click.deactivate(),this.pinchZoom.deactivate(),!0):!1},draw:function(){var a={click:this.defaultClick,dblclick:this.defaultDblClick},b=OpenLayers.Util.extend({"double":!0,stopDouble:!0, | |
2921 pixelTolerance:2},this.clickHandlerOptions);this.handlers.click=new OpenLayers.Handler.Click(this,a,b);this.dragPan=new OpenLayers.Control.DragPan(OpenLayers.Util.extend({map:this.map,documentDrag:this.documentDrag},this.dragPanOptions));this.dragPan.draw();this.pinchZoom=new OpenLayers.Control.PinchZoom(OpenLayers.Util.extend({map:this.map},this.pinchZoomOptions))},defaultClick:function(a){a.lastTouches&&2==a.lastTouches.length&&this.map.zoomOut()},defaultDblClick:function(a){this.map.zoomTo(this.map.zoom+ | |
2922 1,a.xy)},CLASS_NAME:"OpenLayers.Control.TouchNavigation"});OpenLayers.Console.warn("OpenLayers.Rico is deprecated");OpenLayers.Rico=OpenLayers.Rico||{}; | |
2923 OpenLayers.Rico.Color=OpenLayers.Class({initialize:function(a,b,c){this.rgb={r:a,g:b,b:c}},setRed:function(a){this.rgb.r=a},setGreen:function(a){this.rgb.g=a},setBlue:function(a){this.rgb.b=a},setHue:function(a){var b=this.asHSB();b.h=a;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(b.h,b.s,b.b)},setSaturation:function(a){var b=this.asHSB();b.s=a;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(b.h,b.s,b.b)},setBrightness:function(a){var b=this.asHSB();b.b=a;this.rgb=OpenLayers.Rico.Color.HSBtoRGB(b.h,b.s,b.b)}, | |
2924 darken:function(a){var b=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(b.h,b.s,Math.max(b.b-a,0))},brighten:function(a){var b=this.asHSB();this.rgb=OpenLayers.Rico.Color.HSBtoRGB(b.h,b.s,Math.min(b.b+a,1))},blend:function(a){this.rgb.r=Math.floor((this.rgb.r+a.rgb.r)/2);this.rgb.g=Math.floor((this.rgb.g+a.rgb.g)/2);this.rgb.b=Math.floor((this.rgb.b+a.rgb.b)/2)},isBright:function(){this.asHSB();return 0.5<this.asHSB().b},isDark:function(){return!this.isBright()},asRGB:function(){return"rgb("+ | |
2925 this.rgb.r+","+this.rgb.g+","+this.rgb.b+")"},asHex:function(){return"#"+this.rgb.r.toColorPart()+this.rgb.g.toColorPart()+this.rgb.b.toColorPart()},asHSB:function(){return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r,this.rgb.g,this.rgb.b)},toString:function(){return this.asHex()}}); | |
2926 OpenLayers.Rico.Color.createFromHex=function(a){if(4==a.length){var b=a;a="#";for(var c=1;4>c;c++)a+=b.charAt(c)+b.charAt(c)}0==a.indexOf("#")&&(a=a.substring(1));b=a.substring(0,2);c=a.substring(2,4);a=a.substring(4,6);return new OpenLayers.Rico.Color(parseInt(b,16),parseInt(c,16),parseInt(a,16))}; | |
2927 OpenLayers.Rico.Color.createColorFromBackground=function(a){var b=OpenLayers.Element.getStyle(OpenLayers.Util.getElement(a),"backgroundColor");return"transparent"==b&&a.parentNode?OpenLayers.Rico.Color.createColorFromBackground(a.parentNode):null==b?new OpenLayers.Rico.Color(255,255,255):0==b.indexOf("rgb(")?(a=b.substring(4,b.length-1).split(","),new OpenLayers.Rico.Color(parseInt(a[0]),parseInt(a[1]),parseInt(a[2]))):0==b.indexOf("#")?OpenLayers.Rico.Color.createFromHex(b):new OpenLayers.Rico.Color(255, | |
2928 255,255)}; | |
2929 OpenLayers.Rico.Color.HSBtoRGB=function(a,b,c){var d=0,e=0,f=0;if(0==b)f=e=d=parseInt(255*c+0.5);else{a=6*(a-Math.floor(a));var g=a-Math.floor(a),h=c*(1-b),k=c*(1-b*g);b=c*(1-b*(1-g));switch(parseInt(a)){case 0:d=255*c+0.5;e=255*b+0.5;f=255*h+0.5;break;case 1:d=255*k+0.5;e=255*c+0.5;f=255*h+0.5;break;case 2:d=255*h+0.5;e=255*c+0.5;f=255*b+0.5;break;case 3:d=255*h+0.5;e=255*k+0.5;f=255*c+0.5;break;case 4:d=255*b+0.5;e=255*h+0.5;f=255*c+0.5;break;case 5:d=255*c+0.5,e=255*h+0.5,f=255*k+0.5}}return{r:parseInt(d),g:parseInt(e), | |
2930 b:parseInt(f)}};OpenLayers.Rico.Color.RGBtoHSB=function(a,b,c){var d,e=a>b?a:b;c>e&&(e=c);var f=a<b?a:b;c<f&&(f=c);d=0!=e?(e-f)/e:0;if(0==d)a=0;else{var g=(e-a)/(e-f),h=(e-b)/(e-f);c=(e-c)/(e-f);a=(a==e?c-h:b==e?2+g-c:4+h-g)/6;0>a&&(a+=1)}return{h:a,s:d,b:e/255}};OpenLayers.Style2=OpenLayers.Class({id:null,name:null,title:null,description:null,layerName:null,isDefault:!1,rules:null,initialize:function(a){OpenLayers.Util.extend(this,a);this.id=OpenLayers.Util.createUniqueID(this.CLASS_NAME+"_")},destroy:function(){for(var a=0,b=this.rules.length;a<b;a++)this.rules[a].destroy();delete this.rules},clone:function(){var a=OpenLayers.Util.extend({},this);if(this.rules){a.rules=[];for(var b=0,c=this.rules.length;b<c;++b)a.rules.push(this.rules[b].clone())}return new OpenLayers.Style2(a)}, | |
2931 CLASS_NAME:"OpenLayers.Style2"});OpenLayers.Format.WFS=OpenLayers.Class(OpenLayers.Format.GML,{layer:null,wfsns:"http://www.opengis.net/wfs",ogcns:"http://www.opengis.net/ogc",initialize:function(a,b){OpenLayers.Format.GML.prototype.initialize.apply(this,[a]);this.layer=b;this.layer.featureNS&&(this.featureNS=this.layer.featureNS);this.layer.options.geometry_column&&(this.geometryName=this.layer.options.geometry_column);this.layer.options.typename&&(this.featureName=this.layer.options.typename)},write:function(a){var b=this.createElementNS(this.wfsns, | |
2932 "wfs:Transaction");b.setAttribute("version","1.0.0");b.setAttribute("service","WFS");for(var c=0;c<a.length;c++)switch(a[c].state){case OpenLayers.State.INSERT:b.appendChild(this.insert(a[c]));break;case OpenLayers.State.UPDATE:b.appendChild(this.update(a[c]));break;case OpenLayers.State.DELETE:b.appendChild(this.remove(a[c]))}return OpenLayers.Format.XML.prototype.write.apply(this,[b])},createFeatureXML:function(a){var b=this.buildGeometryNode(a.geometry),c=this.createElementNS(this.featureNS,"feature:"+ | |
2933 this.geometryName);c.appendChild(b);b=this.createElementNS(this.featureNS,"feature:"+this.featureName);b.appendChild(c);for(var d in a.attributes){var c=this.createTextNode(a.attributes[d]),e=d;-1!=d.search(":")&&(e=d.split(":")[1]);e=this.createElementNS(this.featureNS,"feature:"+e);e.appendChild(c);b.appendChild(e)}return b},insert:function(a){var b=this.createElementNS(this.wfsns,"wfs:Insert");b.appendChild(this.createFeatureXML(a));return b},update:function(a){a.fid||OpenLayers.Console.userError(OpenLayers.i18n("noFID")); | |
2934 var b=this.createElementNS(this.wfsns,"wfs:Update");b.setAttribute("typeName",this.featurePrefix+":"+this.featureName);b.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var c=this.createElementNS(this.wfsns,"wfs:Property"),d=this.createElementNS(this.wfsns,"wfs:Name"),e=this.createTextNode(this.geometryName);d.appendChild(e);c.appendChild(d);d=this.createElementNS(this.wfsns,"wfs:Value");e=this.buildGeometryNode(a.geometry);a.layer&&e.setAttribute("srsName",a.layer.projection.getCode()); | |
2935 d.appendChild(e);c.appendChild(d);b.appendChild(c);for(var f in a.attributes)c=this.createElementNS(this.wfsns,"wfs:Property"),d=this.createElementNS(this.wfsns,"wfs:Name"),d.appendChild(this.createTextNode(f)),c.appendChild(d),d=this.createElementNS(this.wfsns,"wfs:Value"),d.appendChild(this.createTextNode(a.attributes[f])),c.appendChild(d),b.appendChild(c);c=this.createElementNS(this.ogcns,"ogc:Filter");f=this.createElementNS(this.ogcns,"ogc:FeatureId");f.setAttribute("fid",a.fid);c.appendChild(f); | |
2936 b.appendChild(c);return b},remove:function(a){if(!a.fid)return OpenLayers.Console.userError(OpenLayers.i18n("noFID")),!1;var b=this.createElementNS(this.wfsns,"wfs:Delete");b.setAttribute("typeName",this.featurePrefix+":"+this.featureName);b.setAttribute("xmlns:"+this.featurePrefix,this.featureNS);var c=this.createElementNS(this.ogcns,"ogc:Filter"),d=this.createElementNS(this.ogcns,"ogc:FeatureId");d.setAttribute("fid",a.fid);c.appendChild(d);b.appendChild(c);return b},destroy:function(){this.layer= | |
2937 null},CLASS_NAME:"OpenLayers.Format.WFS"});OpenLayers.Format.SLD.v1_0_0_GeoServer=OpenLayers.Class(OpenLayers.Format.SLD.v1_0_0,{version:"1.0.0",profile:"GeoServer",readers:OpenLayers.Util.applyDefaults({sld:OpenLayers.Util.applyDefaults({Priority:function(a,b){var c=this.readers.ogc._expression.call(this,a);c&&(b.priority=c)},VendorOption:function(a,b){b.vendorOptions||(b.vendorOptions={});b.vendorOptions[a.getAttribute("name")]=this.getChildValue(a)},TextSymbolizer:function(a,b){OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld.TextSymbolizer.apply(this, | |
2938 arguments);var c=this.multipleSymbolizers?b.symbolizers[b.symbolizers.length-1]:b.symbolizer.Text;void 0===c.graphic&&(c.graphic=!1)}},OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld)},OpenLayers.Format.SLD.v1_0_0.prototype.readers),writers:OpenLayers.Util.applyDefaults({sld:OpenLayers.Util.applyDefaults({Priority:function(a){return this.writers.sld._OGCExpression.call(this,"sld:Priority",a)},VendorOption:function(a){return this.createElementNSPlus("sld:VendorOption",{attributes:{name:a.name}, | |
2939 value:a.value})},TextSymbolizer:function(a){var b=OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.TextSymbolizer.apply(this,arguments);!1!==a.graphic&&(a.externalGraphic||a.graphicName)&&this.writeNode("Graphic",a,b);"priority"in a&&this.writeNode("Priority",a.priority,b);return this.addVendorOptions(b,a)},PointSymbolizer:function(a){var b=OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.PointSymbolizer.apply(this,arguments);return this.addVendorOptions(b,a)},LineSymbolizer:function(a){var b= | |
2940 OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.LineSymbolizer.apply(this,arguments);return this.addVendorOptions(b,a)},PolygonSymbolizer:function(a){var b=OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.PolygonSymbolizer.apply(this,arguments);return this.addVendorOptions(b,a)}},OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld)},OpenLayers.Format.SLD.v1_0_0.prototype.writers),addVendorOptions:function(a,b){if(b.vendorOptions)for(var c in b.vendorOptions)this.writeNode("VendorOption",{name:c, | |
2941 value:b.vendorOptions[c]},a);return a},CLASS_NAME:"OpenLayers.Format.SLD.v1_0_0_GeoServer"});OpenLayers.Layer.Boxes=OpenLayers.Class(OpenLayers.Layer.Markers,{drawMarker:function(a){var b=this.map.getLayerPxFromLonLat({lon:a.bounds.left,lat:a.bounds.top}),c=this.map.getLayerPxFromLonLat({lon:a.bounds.right,lat:a.bounds.bottom});null==c||null==b?a.display(!1):(b=a.draw(b,{w:Math.max(1,c.x-b.x),h:Math.max(1,c.y-b.y)}),a.drawn||(this.div.appendChild(b),a.drawn=!0))},removeMarker:function(a){OpenLayers.Util.removeItem(this.markers,a);null!=a.div&&a.div.parentNode==this.div&&this.div.removeChild(a.div)}, | |
2942 CLASS_NAME:"OpenLayers.Layer.Boxes"});OpenLayers.Format.WFSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.WFSCapabilities.v1,{readers:{wfs:OpenLayers.Util.applyDefaults({Service:function(a,b){b.service={};this.readChildNodes(a,b.service)},Fees:function(a,b){var c=this.getChildValue(a);c&&"none"!=c.toLowerCase()&&(b.fees=c)},AccessConstraints:function(a,b){var c=this.getChildValue(a);c&&"none"!=c.toLowerCase()&&(b.accessConstraints=c)},OnlineResource:function(a,b){var c=this.getChildValue(a);c&&"none"!=c.toLowerCase()&&(b.onlineResource= | |
2943 c)},Keywords:function(a,b){var c=this.getChildValue(a);c&&"none"!=c.toLowerCase()&&(b.keywords=c.split(", "))},Capability:function(a,b){b.capability={};this.readChildNodes(a,b.capability)},Request:function(a,b){b.request={};this.readChildNodes(a,b.request)},GetFeature:function(a,b){b.getfeature={href:{},formats:[]};this.readChildNodes(a,b.getfeature)},ResultFormat:function(a,b){for(var c=a.childNodes,d,e=0;e<c.length;e++)d=c[e],1==d.nodeType&&b.formats.push(d.nodeName)},DCPType:function(a,b){this.readChildNodes(a, | |
2944 b)},HTTP:function(a,b){this.readChildNodes(a,b.href)},Get:function(a,b){b.get=a.getAttribute("onlineResource")},Post:function(a,b){b.post=a.getAttribute("onlineResource")},SRS:function(a,b){var c=this.getChildValue(a);c&&(b.srs=c)}},OpenLayers.Format.WFSCapabilities.v1.prototype.readers.wfs)},CLASS_NAME:"OpenLayers.Format.WFSCapabilities.v1_0_0"});OpenLayers.Format.WMSCapabilities.v1_3=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1,{readers:{wms:OpenLayers.Util.applyDefaults({WMS_Capabilities:function(a,b){this.readChildNodes(a,b)},LayerLimit:function(a,b){b.layerLimit=parseInt(this.getChildValue(a))},MaxWidth:function(a,b){b.maxWidth=parseInt(this.getChildValue(a))},MaxHeight:function(a,b){b.maxHeight=parseInt(this.getChildValue(a))},BoundingBox:function(a,b){var c=OpenLayers.Format.WMSCapabilities.v1.prototype.readers.wms.BoundingBox.apply(this, | |
2945 [a,b]);c.srs=a.getAttribute("CRS");b.bbox[c.srs]=c},CRS:function(a,b){this.readers.wms.SRS.apply(this,[a,b])},EX_GeographicBoundingBox:function(a,b){b.llbbox=[];this.readChildNodes(a,b.llbbox)},westBoundLongitude:function(a,b){b[0]=this.getChildValue(a)},eastBoundLongitude:function(a,b){b[2]=this.getChildValue(a)},southBoundLatitude:function(a,b){b[1]=this.getChildValue(a)},northBoundLatitude:function(a,b){b[3]=this.getChildValue(a)},MinScaleDenominator:function(a,b){b.maxScale=parseFloat(this.getChildValue(a)).toPrecision(16)}, | |
2946 MaxScaleDenominator:function(a,b){b.minScale=parseFloat(this.getChildValue(a)).toPrecision(16)},Dimension:function(a,b){var c={name:a.getAttribute("name").toLowerCase(),units:a.getAttribute("units"),unitsymbol:a.getAttribute("unitSymbol"),nearestVal:"1"===a.getAttribute("nearestValue"),multipleVal:"1"===a.getAttribute("multipleValues"),"default":a.getAttribute("default")||"",current:"1"===a.getAttribute("current"),values:this.getChildValue(a).split(",")};b.dimensions[c.name]=c},Keyword:function(a, | |
2947 b){var c={value:this.getChildValue(a),vocabulary:a.getAttribute("vocabulary")};b.keywords&&b.keywords.push(c)}},OpenLayers.Format.WMSCapabilities.v1.prototype.readers.wms),sld:{UserDefinedSymbolization:function(a,b){this.readers.wms.UserDefinedSymbolization.apply(this,[a,b]);b.userSymbols.inlineFeature=1==parseInt(a.getAttribute("InlineFeature"));b.userSymbols.remoteWCS=1==parseInt(a.getAttribute("RemoteWCS"))},DescribeLayer:function(a,b){this.readers.wms.DescribeLayer.apply(this,[a,b])},GetLegendGraphic:function(a, | |
2948 b){this.readers.wms.GetLegendGraphic.apply(this,[a,b])}}},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3"});OpenLayers.Layer.Zoomify=OpenLayers.Class(OpenLayers.Layer.Grid,{size:null,isBaseLayer:!0,standardTileSize:256,tileOriginCorner:"tl",numberOfTiers:0,tileCountUpToTier:null,tierSizeInTiles:null,tierImageSize:null,initialize:function(a,b,c,d){this.initializeZoomify(c);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a,b,c,{},d])},initializeZoomify:function(a){var b=a.clone();this.size=a.clone();a=new OpenLayers.Size(Math.ceil(b.w/this.standardTileSize),Math.ceil(b.h/this.standardTileSize));this.tierSizeInTiles= | |
2949 [a];for(this.tierImageSize=[b];b.w>this.standardTileSize||b.h>this.standardTileSize;)b=new OpenLayers.Size(Math.floor(b.w/2),Math.floor(b.h/2)),a=new OpenLayers.Size(Math.ceil(b.w/this.standardTileSize),Math.ceil(b.h/this.standardTileSize)),this.tierSizeInTiles.push(a),this.tierImageSize.push(b);this.tierSizeInTiles.reverse();this.tierImageSize.reverse();this.numberOfTiers=this.tierSizeInTiles.length;b=[1];this.tileCountUpToTier=[0];for(a=1;a<this.numberOfTiers;a++)b.unshift(Math.pow(2,a)),this.tileCountUpToTier.push(this.tierSizeInTiles[a- | |
2950 1].w*this.tierSizeInTiles[a-1].h+this.tileCountUpToTier[a-1]);this.serverResolutions||(this.serverResolutions=b)},destroy:function(){OpenLayers.Layer.Grid.prototype.destroy.apply(this,arguments);this.tileCountUpToTier.length=0;this.tierSizeInTiles.length=0;this.tierImageSize.length=0},clone:function(a){null==a&&(a=new OpenLayers.Layer.Zoomify(this.name,this.url,this.size,this.options));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getURL:function(a){a=this.adjustBounds(a);var b= | |
2951 this.getServerResolution(),c=Math.round((a.left-this.tileOrigin.lon)/(b*this.tileSize.w));a=Math.round((this.tileOrigin.lat-a.top)/(b*this.tileSize.h));b=this.getZoomForResolution(b);c="TileGroup"+Math.floor((c+a*this.tierSizeInTiles[b].w+this.tileCountUpToTier[b])/256)+"/"+b+"-"+c+"-"+a+".jpg";b=this.url;OpenLayers.Util.isArray(b)&&(b=this.selectUrl(c,b));return b+c},getImageSize:function(){if(0<arguments.length){var a=this.adjustBounds(arguments[0]),b=this.getServerResolution(),c=Math.round((a.left- | |
2952 this.tileOrigin.lon)/(b*this.tileSize.w)),a=Math.round((this.tileOrigin.lat-a.top)/(b*this.tileSize.h)),b=this.getZoomForResolution(b),d=this.standardTileSize,e=this.standardTileSize;c==this.tierSizeInTiles[b].w-1&&(d=this.tierImageSize[b].w%this.standardTileSize);a==this.tierSizeInTiles[b].h-1&&(e=this.tierImageSize[b].h%this.standardTileSize);return new OpenLayers.Size(d,e)}return this.tileSize},setMap:function(a){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.tileOrigin=new OpenLayers.LonLat(this.map.maxExtent.left, | |
2953 this.map.maxExtent.top)},CLASS_NAME:"OpenLayers.Layer.Zoomify"});OpenLayers.Layer.MapServer=OpenLayers.Class(OpenLayers.Layer.Grid,{DEFAULT_PARAMS:{mode:"map",map_imagetype:"png"},initialize:function(a,b,c,d){OpenLayers.Layer.Grid.prototype.initialize.apply(this,arguments);this.params=OpenLayers.Util.applyDefaults(this.params,this.DEFAULT_PARAMS);if(null==d||null==d.isBaseLayer)this.isBaseLayer="true"!=this.params.transparent&&!0!=this.params.transparent},clone:function(a){null==a&&(a=new OpenLayers.Layer.MapServer(this.name,this.url,this.params,this.getOptions())); | |
2954 return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getURL:function(a){a=this.adjustBounds(a);a=[a.left,a.bottom,a.right,a.top];var b=this.getImageSize();return this.getFullRequestString({mapext:a,imgext:a,map_size:[b.w,b.h],imgx:b.w/2,imgy:b.h/2,imgxy:[b.w,b.h]})},getFullRequestString:function(a,b){var c=null==b?this.url:b,d=OpenLayers.Util.extend({},this.params),d=OpenLayers.Util.extend(d,a),e=OpenLayers.Util.getParameterString(d);OpenLayers.Util.isArray(c)&&(c=this.selectUrl(e,c)); | |
2955 var e=OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(c)),f;for(f in d)f.toUpperCase()in e&&delete d[f];e=OpenLayers.Util.getParameterString(d);d=c;e=e.replace(/,/g,"+");""!=e&&(f=c.charAt(c.length-1),d="&"==f||"?"==f?d+e:-1==c.indexOf("?")?d+("?"+e):d+("&"+e));return d},CLASS_NAME:"OpenLayers.Layer.MapServer"});OpenLayers.Renderer.VML=OpenLayers.Class(OpenLayers.Renderer.Elements,{xmlns:"urn:schemas-microsoft-com:vml",symbolCache:{},offset:null,initialize:function(a){if(this.supported()){if(!document.namespaces.olv){document.namespaces.add("olv",this.xmlns);for(var b=document.createStyleSheet(),c="shape rect oval fill stroke imagedata group textbox".split(" "),d=0,e=c.length;d<e;d++)b.addRule("olv\\:"+c[d],"behavior: url(#default#VML); position: absolute; display: inline-block;")}OpenLayers.Renderer.Elements.prototype.initialize.apply(this, | |
2956 arguments)}},supported:function(){return!!document.namespaces},setExtent:function(a,b){var c=OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,arguments),d=this.getResolution(),e=a.left/d|0,d=a.top/d-this.size.h|0;b||!this.offset?(this.offset={x:e,y:d},d=e=0):(e-=this.offset.x,d-=this.offset.y);this.root.coordorigin=e-this.xOffset+" "+d;for(var e=[this.root,this.vectorRoot,this.textRoot],f=0,g=e.length;f<g;++f)d=e[f],d.coordsize=this.size.w+" "+this.size.h;this.root.style.flip="y";return c}, | |
2957 setSize:function(a){OpenLayers.Renderer.prototype.setSize.apply(this,arguments);for(var b=[this.rendererRoot,this.root,this.vectorRoot,this.textRoot],c=this.size.w+"px",d=this.size.h+"px",e,f=0,g=b.length;f<g;++f)e=b[f],e.style.width=c,e.style.height=d},getNodeType:function(a,b){var c=null;switch(a.CLASS_NAME){case "OpenLayers.Geometry.Point":c=b.externalGraphic?"olv:rect":this.isComplexSymbol(b.graphicName)?"olv:shape":"olv:oval";break;case "OpenLayers.Geometry.Rectangle":c="olv:rect";break;case "OpenLayers.Geometry.LineString":case "OpenLayers.Geometry.LinearRing":case "OpenLayers.Geometry.Polygon":case "OpenLayers.Geometry.Curve":c= | |
2958 "olv:shape"}return c},setStyle:function(a,b,c,d){b=b||a._style;c=c||a._options;var e=b.fillColor,f=b.title||b.graphicTitle;f&&(a.title=f);if("OpenLayers.Geometry.Point"===a._geometryClass)if(b.externalGraphic){c.isFilled=!0;var e=b.graphicWidth||b.graphicHeight,f=b.graphicHeight||b.graphicWidth,e=e?e:2*b.pointRadius,f=f?f:2*b.pointRadius,g=this.getResolution(),h=void 0!=b.graphicXOffset?b.graphicXOffset:-(0.5*e),k=void 0!=b.graphicYOffset?b.graphicYOffset:-(0.5*f);a.style.left=((d.x-this.featureDx)/ | |
2959 g-this.offset.x+h|0)+"px";a.style.top=(d.y/g-this.offset.y-(k+f)|0)+"px";a.style.width=e+"px";a.style.height=f+"px";a.style.flip="y";e="none";c.isStroked=!1}else this.isComplexSymbol(b.graphicName)?(f=this.importSymbol(b.graphicName),a.path=f.path,a.coordorigin=f.left+","+f.bottom,f=f.size,a.coordsize=f+","+f,this.drawCircle(a,d,b.pointRadius),a.style.flip="y"):this.drawCircle(a,d,b.pointRadius);c.isFilled?a.fillcolor=e:a.filled="false";d=a.getElementsByTagName("fill");d=0==d.length?null:d[0];c.isFilled? | |
2960 (d||(d=this.createNode("olv:fill",a.id+"_fill")),d.opacity=b.fillOpacity,"OpenLayers.Geometry.Point"===a._geometryClass&&b.externalGraphic&&(b.graphicOpacity&&(d.opacity=b.graphicOpacity),d.src=b.externalGraphic,d.type="frame",b.graphicWidth&&b.graphicHeight||(d.aspect="atmost")),d.parentNode!=a&&a.appendChild(d)):d&&a.removeChild(d);e=b.rotation;if(void 0!==e||void 0!==a._rotation)a._rotation=e,b.externalGraphic?(this.graphicRotate(a,h,k,b),d.opacity=0):"OpenLayers.Geometry.Point"===a._geometryClass&& | |
2961 (a.style.rotation=e||0);h=a.getElementsByTagName("stroke");h=0==h.length?null:h[0];c.isStroked?(h||(h=this.createNode("olv:stroke",a.id+"_stroke"),a.appendChild(h)),h.on=!0,h.color=b.strokeColor,h.weight=b.strokeWidth+"px",h.opacity=b.strokeOpacity,h.endcap="butt"==b.strokeLinecap?"flat":b.strokeLinecap||"round",b.strokeDashstyle&&(h.dashstyle=this.dashStyle(b))):(a.stroked=!1,h&&(h.on=!1));"inherit"!=b.cursor&&null!=b.cursor&&(a.style.cursor=b.cursor);return a},graphicRotate:function(a,b,c,d){d= | |
2962 d||a._style;var e=d.rotation||0,f,g;if(d.graphicWidth&&d.graphicHeight){g=Math.max(d.graphicWidth,d.graphicHeight);f=d.graphicWidth/d.graphicHeight;var h=Math.round(d.graphicWidth||g*f),k=Math.round(d.graphicHeight||g);a.style.width=h+"px";a.style.height=k+"px";var l=document.getElementById(a.id+"_image");l||(l=this.createNode("olv:imagedata",a.id+"_image"),a.appendChild(l));l.style.width=h+"px";l.style.height=k+"px";l.src=d.externalGraphic;l.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='', sizingMethod='scale')"; | |
2963 l=e*Math.PI/180;e=Math.sin(l);l=Math.cos(l);e="progid:DXImageTransform.Microsoft.Matrix(M11="+l+",M12="+-e+",M21="+e+",M22="+l+",SizingMethod='auto expand')\n";(l=d.graphicOpacity||d.fillOpacity)&&1!=l&&(e+="progid:DXImageTransform.Microsoft.BasicImage(opacity="+l+")\n");a.style.filter=e;e=new OpenLayers.Geometry.Point(-b,-c);h=(new OpenLayers.Bounds(0,0,h,k)).toGeometry();h.rotate(d.rotation,e);h=h.getBounds();a.style.left=Math.round(parseInt(a.style.left)+h.left)+"px";a.style.top=Math.round(parseInt(a.style.top)- | |
2964 h.bottom)+"px"}else{var m=new Image;m.onreadystatechange=OpenLayers.Function.bind(function(){if("complete"==m.readyState||"interactive"==m.readyState)f=m.width/m.height,g=Math.max(2*d.pointRadius,d.graphicWidth||0,d.graphicHeight||0),b*=f,d.graphicWidth=g*f,d.graphicHeight=g,this.graphicRotate(a,b,c,d)},this);m.src=d.externalGraphic}},postDraw:function(a){a.style.visibility="visible";var b=a._style.fillColor,c=a._style.strokeColor;"none"==b&&a.fillcolor!=b&&(a.fillcolor=b);"none"==c&&a.strokecolor!= | |
2965 c&&(a.strokecolor=c)},setNodeDimension:function(a,b){var c=b.getBounds();if(c){var d=this.getResolution(),c=new OpenLayers.Bounds((c.left-this.featureDx)/d-this.offset.x|0,c.bottom/d-this.offset.y|0,(c.right-this.featureDx)/d-this.offset.x|0,c.top/d-this.offset.y|0);a.style.left=c.left+"px";a.style.top=c.top+"px";a.style.width=c.getWidth()+"px";a.style.height=c.getHeight()+"px";a.coordorigin=c.left+" "+c.top;a.coordsize=c.getWidth()+" "+c.getHeight()}},dashStyle:function(a){a=a.strokeDashstyle;switch(a){case "solid":case "dot":case "dash":case "dashdot":case "longdash":case "longdashdot":return a; | |
2966 default:return a=a.split(/[ ,]/),2==a.length?1*a[0]>=2*a[1]?"longdash":1==a[0]||1==a[1]?"dot":"dash":4==a.length?1*a[0]>=2*a[1]?"longdashdot":"dashdot":"solid"}},createNode:function(a,b){var c=document.createElement(a);b&&(c.id=b);c.unselectable="on";c.onselectstart=OpenLayers.Function.False;return c},nodeTypeCompare:function(a,b){var c=b,d=c.indexOf(":");-1!=d&&(c=c.substr(d+1));var e=a.nodeName,d=e.indexOf(":");-1!=d&&(e=e.substr(d+1));return c==e},createRenderRoot:function(){return this.nodeFactory(this.container.id+ | |
2967 "_vmlRoot","div")},createRoot:function(a){return this.nodeFactory(this.container.id+a,"olv:group")},drawPoint:function(a,b){return this.drawCircle(a,b,1)},drawCircle:function(a,b,c){if(!isNaN(b.x)&&!isNaN(b.y)){var d=this.getResolution();a.style.left=((b.x-this.featureDx)/d-this.offset.x|0)-c+"px";a.style.top=(b.y/d-this.offset.y|0)-c+"px";b=2*c;a.style.width=b+"px";a.style.height=b+"px";return a}return!1},drawLineString:function(a,b){return this.drawLine(a,b,!1)},drawLinearRing:function(a,b){return this.drawLine(a, | |
2968 b,!0)},drawLine:function(a,b,c){this.setNodeDimension(a,b);for(var d=this.getResolution(),e=b.components.length,f=Array(e),g,h,k=0;k<e;k++)g=b.components[k],h=(g.x-this.featureDx)/d-this.offset.x|0,g=g.y/d-this.offset.y|0,f[k]=" "+h+","+g+" l ";b=c?" x e":" e";a.path="m"+f.join("")+b;return a},drawPolygon:function(a,b){this.setNodeDimension(a,b);var c=this.getResolution(),d=[],e,f,g,h,k,l,m,n,p,q;e=0;for(f=b.components.length;e<f;e++){d.push("m");g=b.components[e].components;h=0===e;l=k=null;m=0; | |
2969 for(n=g.length;m<n;m++)p=g[m],q=(p.x-this.featureDx)/c-this.offset.x|0,p=p.y/c-this.offset.y|0,q=" "+q+","+p,d.push(q),0==m&&d.push(" l"),h||(k?k!=q&&(l?l!=q&&(h=!0):l=q):k=q);d.push(h?" x ":" ")}d.push("e");a.path=d.join("");return a},drawRectangle:function(a,b){var c=this.getResolution();a.style.left=((b.x-this.featureDx)/c-this.offset.x|0)+"px";a.style.top=(b.y/c-this.offset.y|0)+"px";a.style.width=(b.width/c|0)+"px";a.style.height=(b.height/c|0)+"px";return a},drawText:function(a,b,c){var d=this.nodeFactory(a+ | |
2970 this.LABEL_ID_SUFFIX,"olv:rect"),e=this.nodeFactory(a+this.LABEL_ID_SUFFIX+"_textbox","olv:textbox"),f=this.getResolution();d.style.left=((c.x-this.featureDx)/f-this.offset.x|0)+"px";d.style.top=(c.y/f-this.offset.y|0)+"px";d.style.flip="y";e.innerText=b.label;"inherit"!=b.cursor&&null!=b.cursor&&(e.style.cursor=b.cursor);b.fontColor&&(e.style.color=b.fontColor);b.fontOpacity&&(e.style.filter="alpha(opacity="+100*b.fontOpacity+")");b.fontFamily&&(e.style.fontFamily=b.fontFamily);b.fontSize&&(e.style.fontSize= | |
2971 b.fontSize);b.fontWeight&&(e.style.fontWeight=b.fontWeight);b.fontStyle&&(e.style.fontStyle=b.fontStyle);!0===b.labelSelect&&(d._featureId=a,e._featureId=a,e._geometry=c,e._geometryClass=c.CLASS_NAME);e.style.whiteSpace="nowrap";e.inset="1px,0px,0px,0px";d.parentNode||(d.appendChild(e),this.textRoot.appendChild(d));b=b.labelAlign||"cm";1==b.length&&(b+="m");a=e.clientWidth*OpenLayers.Renderer.VML.LABEL_SHIFT[b.substr(0,1)];e=e.clientHeight*OpenLayers.Renderer.VML.LABEL_SHIFT[b.substr(1,1)];d.style.left= | |
2972 parseInt(d.style.left)-a-1+"px";d.style.top=parseInt(d.style.top)+e+"px"},moveRoot:function(a){var b=this.map.getLayer(a.container.id);b instanceof OpenLayers.Layer.Vector.RootContainer&&(b=this.map.getLayer(this.container.id));b&&b.renderer.clear();OpenLayers.Renderer.Elements.prototype.moveRoot.apply(this,arguments);b&&b.redraw()},importSymbol:function(a){var b=this.container.id+"-"+a,c=this.symbolCache[b];if(c)return c;c=OpenLayers.Renderer.symbol[a];if(!c)throw Error(a+" is not a valid symbol name"); | |
2973 a=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0);for(var d=["m"],e=0;e<c.length;e+=2){var f=c[e],g=c[e+1];a.left=Math.min(a.left,f);a.bottom=Math.min(a.bottom,g);a.right=Math.max(a.right,f);a.top=Math.max(a.top,g);d.push(f);d.push(g);0==e&&d.push("l")}d.push("x e");c=d.join(" ");d=(a.getWidth()-a.getHeight())/2;0<d?(a.bottom-=d,a.top+=d):(a.left+=d,a.right-=d);c={path:c,size:a.getWidth(),left:a.left,bottom:a.bottom};return this.symbolCache[b]=c},CLASS_NAME:"OpenLayers.Renderer.VML"}); | |
2974 OpenLayers.Renderer.VML.LABEL_SHIFT={l:0,c:0.5,r:1,t:0,m:0.5,b:1};OpenLayers.Control.CacheRead=OpenLayers.Class(OpenLayers.Control,{fetchEvent:"tileloadstart",layers:null,autoActivate:!0,setMap:function(a){OpenLayers.Control.prototype.setMap.apply(this,arguments);var b,c=this.layers||a.layers;for(b=c.length-1;0<=b;--b)this.addLayer({layer:c[b]});if(!this.layers)a.events.on({addlayer:this.addLayer,removeLayer:this.removeLayer,scope:this})},addLayer:function(a){a.layer.events.register(this.fetchEvent,this,this.fetch)},removeLayer:function(a){a.layer.events.unregister(this.fetchEvent, | |
2975 this,this.fetch)},fetch:function(a){if(this.active&&window.localStorage&&a.tile instanceof OpenLayers.Tile.Image){var b=a.tile,c=b.url;!b.layer.crossOriginKeyword&&(OpenLayers.ProxyHost&&0===c.indexOf(OpenLayers.ProxyHost))&&(c=OpenLayers.Control.CacheWrite.urlMap[c]);if(c=window.localStorage.getItem("olCache_"+c))b.url=c,"tileerror"===a.type&&b.setImgSrc(c)}},destroy:function(){if(this.layers||this.map){var a,b=this.layers||this.map.layers;for(a=b.length-1;0<=a;--a)this.removeLayer({layer:b[a]})}this.map&& | |
2976 this.map.events.un({addlayer:this.addLayer,removeLayer:this.removeLayer,scope:this});OpenLayers.Control.prototype.destroy.apply(this,arguments)},CLASS_NAME:"OpenLayers.Control.CacheRead"});OpenLayers.Protocol.WFS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.0.0",CLASS_NAME:"OpenLayers.Protocol.WFS.v1_0_0"});OpenLayers.Format.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Format.XML,{layerIdentifier:"_layer",featureIdentifier:"_feature",regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},gmlFormat:null,read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));var b=a.documentElement;if(b){var c=this["read_"+b.nodeName];a=c?c.call(this,b):(new OpenLayers.Format.GML(this.options?this.options:{})).read(a)}return a},read_msGMLOutput:function(a){var b= | |
2977 [];if(a=this.getSiblingNodesByTagCriteria(a,this.layerIdentifier))for(var c=0,d=a.length;c<d;++c){var e=a[c],f=e.nodeName;e.prefix&&(f=f.split(":")[1]);f=f.replace(this.layerIdentifier,"");if(e=this.getSiblingNodesByTagCriteria(e,this.featureIdentifier))for(var g=0;g<e.length;g++){var h=e[g],k=this.parseGeometry(h),h=this.parseAttributes(h),h=new OpenLayers.Feature.Vector(k.geometry,h,null);h.bounds=k.bounds;h.type=f;b.push(h)}}return b},read_FeatureInfoResponse:function(a){var b=[];a=this.getElementsByTagNameNS(a, | |
2978 "*","FIELDS");for(var c=0,d=a.length;c<d;c++){var e=a[c],f={},g,h=e.attributes.length;if(0<h)for(g=0;g<h;g++){var k=e.attributes[g];f[k.nodeName]=k.nodeValue}else for(e=e.childNodes,g=0,h=e.length;g<h;++g)k=e[g],3!=k.nodeType&&(f[k.getAttribute("name")]=k.getAttribute("value"));b.push(new OpenLayers.Feature.Vector(null,f,null))}return b},getSiblingNodesByTagCriteria:function(a,b){var c=[],d,e,f,g;if(a&&a.hasChildNodes()){d=a.childNodes;f=d.length;for(var h=0;h<f;h++){for(g=d[h];g&&1!=g.nodeType;)g= | |
2979 g.nextSibling,h++;e=g?g.nodeName:"";0<e.length&&-1<e.indexOf(b)?c.push(g):(e=this.getSiblingNodesByTagCriteria(g,b),0<e.length&&(0==c.length?c=e:c.push(e)))}}return c},parseAttributes:function(a){var b={};if(1==a.nodeType){a=a.childNodes;for(var c=a.length,d=0;d<c;++d){var e=a[d];if(1==e.nodeType){var f=e.childNodes,e=e.prefix?e.nodeName.split(":")[1]:e.nodeName;0==f.length?b[e]=null:1==f.length&&(f=f[0],3==f.nodeType||4==f.nodeType)&&(f=f.nodeValue.replace(this.regExes.trimSpace,""),b[e]=f)}}}return b}, | |
2980 parseGeometry:function(a){this.gmlFormat||(this.gmlFormat=new OpenLayers.Format.GML);a=this.gmlFormat.parseFeature(a);var b,c=null;a&&(b=a.geometry&&a.geometry.clone(),c=a.bounds&&a.bounds.clone(),a.destroy());return{geometry:b,bounds:c}},CLASS_NAME:"OpenLayers.Format.WMSGetFeatureInfo"});OpenLayers.Control.WMTSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:!1,requestEncoding:"KVP",drillDown:!1,maxFeatures:10,clickCallback:"click",layers:null,queryVisible:!0,infoFormat:"text/html",vendorParams:{},format:null,formatOptions:null,handler:null,hoverRequest:null,pending:0,initialize:function(a){a=a||{};a.handlerOptions=a.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[a]);this.format||(this.format=new OpenLayers.Format.WMSGetFeatureInfo(a.formatOptions)); | |
2981 !0===this.drillDown&&(this.hover=!1);this.hover?this.handler=new OpenLayers.Handler.Hover(this,{move:this.cancelHover,pause:this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{delay:250})):(a={},a[this.clickCallback]=this.getInfoForClick,this.handler=new OpenLayers.Handler.Click(this,a,this.handlerOptions.click||{}))},getInfoForClick:function(a){this.request(a.xy,{})},getInfoForHover:function(a){this.request(a.xy,{hover:!0})},cancelHover:function(){this.hoverRequest&&(--this.pending, | |
2982 0>=this.pending&&(OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait"),this.pending=0),this.hoverRequest.abort(),this.hoverRequest=null)},findLayers:function(){for(var a=this.layers||this.map.layers,b=[],c,d=a.length-1;0<=d&&(c=a[d],!(c instanceof OpenLayers.Layer.WMTS)||(c.requestEncoding!==this.requestEncoding||this.queryVisible&&!c.getVisibility())||(b.push(c),this.drillDown&&!this.hover));--d);return b},buildRequestOptions:function(a,b){var c=this.map.getLonLatFromPixel(b),d=a.getURL(new OpenLayers.Bounds(c.lon, | |
2983 c.lat,c.lon,c.lat)),d=OpenLayers.Util.getParameters(d),c=a.getTileInfo(c);OpenLayers.Util.extend(d,{service:"WMTS",version:a.version,request:"GetFeatureInfo",infoFormat:this.infoFormat,i:c.i,j:c.j});OpenLayers.Util.applyDefaults(d,this.vendorParams);return{url:OpenLayers.Util.isArray(a.url)?a.url[0]:a.url,params:OpenLayers.Util.upperCaseObject(d),callback:function(c){this.handleResponse(b,c,a)},scope:this}},request:function(a,b){b=b||{};var c=this.findLayers();if(0<c.length){for(var d,e,f=0,g=c.length;f< | |
2984 g;f++)e=c[f],d=this.events.triggerEvent("beforegetfeatureinfo",{xy:a,layer:e}),!1!==d&&(++this.pending,d=this.buildRequestOptions(e,a),d=OpenLayers.Request.GET(d),!0===b.hover&&(this.hoverRequest=d));0<this.pending&&OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait")}},handleResponse:function(a,b,c){--this.pending;0>=this.pending&&(OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait"),this.pending=0);if(b.status&&(200>b.status||300<=b.status))this.events.triggerEvent("exception", | |
2985 {xy:a,request:b,layer:c});else{var d=b.responseXML;d&&d.documentElement||(d=b.responseText);var e,f;try{e=this.format.read(d)}catch(g){f=!0,this.events.triggerEvent("exception",{xy:a,request:b,error:g,layer:c})}f||this.events.triggerEvent("getfeatureinfo",{text:b.responseText,features:e,request:b,xy:a,layer:c})}},CLASS_NAME:"OpenLayers.Control.WMTSGetFeatureInfo"});OpenLayers.Protocol.CSW.v2_0_2=OpenLayers.Class(OpenLayers.Protocol,{formatOptions:null,initialize:function(a){OpenLayers.Protocol.prototype.initialize.apply(this,[a]);a.format||(this.format=new OpenLayers.Format.CSWGetRecords.v2_0_2(OpenLayers.Util.extend({},this.formatOptions)))},destroy:function(){this.options&&!this.options.format&&this.format.destroy();this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this)},read:function(a){a=OpenLayers.Util.extend({},a);OpenLayers.Util.applyDefaults(a, | |
2986 this.options||{});var b=new OpenLayers.Protocol.Response({requestType:"read"}),c=this.format.write(a.params||a);b.priv=OpenLayers.Request.POST({url:a.url,callback:this.createCallback(this.handleRead,b,a),params:a.params,headers:a.headers,data:c});return b},handleRead:function(a,b){if(b.callback){var c=a.priv;200<=c.status&&300>c.status?(a.data=this.parseData(c),a.code=OpenLayers.Protocol.Response.SUCCESS):a.code=OpenLayers.Protocol.Response.FAILURE;b.callback.call(b.scope,a)}},parseData:function(a){var b= | |
2987 a.responseXML;b&&b.documentElement||(b=a.responseText);return!b||0>=b.length?null:this.format.read(b)},CLASS_NAME:"OpenLayers.Protocol.CSW.v2_0_2"});OpenLayers.Format.WCSCapabilities.v1_1_0=OpenLayers.Class(OpenLayers.Format.WCSCapabilities.v1,{namespaces:{wcs:"http://www.opengis.net/wcs/1.1",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance",ows:"http://www.opengis.net/ows/1.1"},errorProperty:"operationsMetadata",readers:{wcs:OpenLayers.Util.applyDefaults({Capabilities:function(a,b){this.readChildNodes(a,b)},Contents:function(a,b){b.contentMetadata=[];this.readChildNodes(a,b.contentMetadata)},CoverageSummary:function(a, | |
2988 b){var c={};this.readChildNodes(a,c);b.push(c)},Identifier:function(a,b){b.identifier=this.getChildValue(a)},Title:function(a,b){b.title=this.getChildValue(a)},Abstract:function(a,b){b["abstract"]=this.getChildValue(a)},SupportedCRS:function(a,b){var c=this.getChildValue(a);c&&(b.supportedCRS||(b.supportedCRS=[]),b.supportedCRS.push(c))},SupportedFormat:function(a,b){var c=this.getChildValue(a);c&&(b.supportedFormat||(b.supportedFormat=[]),b.supportedFormat.push(c))}},OpenLayers.Format.WCSCapabilities.v1.prototype.readers.wcs), | |
2989 ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows},CLASS_NAME:"OpenLayers.Format.WCSCapabilities.v1_1_0"});OpenLayers.Control.Graticule=OpenLayers.Class(OpenLayers.Control,{autoActivate:!0,intervals:[45,30,20,10,5,2,1,0.5,0.2,0.1,0.05,0.01,0.005,0.002,0.001],displayInLayerSwitcher:!0,visible:!0,numPoints:50,targetSize:200,layerName:null,labelled:!0,labelFormat:"dm",lineSymbolizer:{strokeColor:"#333",strokeWidth:1,strokeOpacity:0.5},labelSymbolizer:{},gratLayer:null,initialize:function(a){a=a||{};a.layerName=a.layerName||OpenLayers.i18n("Graticule");OpenLayers.Control.prototype.initialize.apply(this,[a]); | |
2990 this.labelSymbolizer.stroke=!1;this.labelSymbolizer.fill=!1;this.labelSymbolizer.label="${label}";this.labelSymbolizer.labelAlign="${labelAlign}";this.labelSymbolizer.labelXOffset="${xOffset}";this.labelSymbolizer.labelYOffset="${yOffset}"},destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments);this.gratLayer&&(this.gratLayer.destroy(),this.gratLayer=null)},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);if(!this.gratLayer){var a=new OpenLayers.Style({}, | |
2991 {rules:[new OpenLayers.Rule({symbolizer:{Point:this.labelSymbolizer,Line:this.lineSymbolizer}})]});this.gratLayer=new OpenLayers.Layer.Vector(this.layerName,{styleMap:new OpenLayers.StyleMap({"default":a}),visibility:this.visible,displayInLayerSwitcher:this.displayInLayerSwitcher})}return this.div},activate:function(){return OpenLayers.Control.prototype.activate.apply(this,arguments)?(this.map.addLayer(this.gratLayer),this.map.events.register("moveend",this,this.update),this.update(),!0):!1},deactivate:function(){return OpenLayers.Control.prototype.deactivate.apply(this, | |
2992 arguments)?(this.map.events.unregister("moveend",this,this.update),this.map.removeLayer(this.gratLayer),!0):!1},update:function(){var a=this.map.getExtent();if(a){this.gratLayer.destroyFeatures();var b=new OpenLayers.Projection("EPSG:4326"),c=this.map.getProjectionObject(),d=this.map.getResolution();c.proj&&"longlat"==c.proj.projName&&(this.numPoints=1);var e=this.map.getCenter(),f=new OpenLayers.Pixel(e.lon,e.lat);OpenLayers.Projection.transform(f,c,b);for(var e=this.targetSize*d,e=e*e,g,d=0;d<this.intervals.length;++d){g= | |
2993 this.intervals[d];var h=g/2,k=f.offset({x:-h,y:-h}),h=f.offset({x:h,y:h});OpenLayers.Projection.transform(k,b,c);OpenLayers.Projection.transform(h,b,c);if((k.x-h.x)*(k.x-h.x)+(k.y-h.y)*(k.y-h.y)<=e)break}f.x=Math.floor(f.x/g)*g;f.y=Math.floor(f.y/g)*g;var d=0,e=[f.clone()],h=f.clone(),l;do h=h.offset({x:0,y:g}),l=OpenLayers.Projection.transform(h.clone(),b,c),e.unshift(h);while(a.containsPixel(l)&&1E3>++d);h=f.clone();do h=h.offset({x:0,y:-g}),l=OpenLayers.Projection.transform(h.clone(),b,c),e.push(h); | |
2994 while(a.containsPixel(l)&&1E3>++d);d=0;k=[f.clone()];h=f.clone();do h=h.offset({x:-g,y:0}),l=OpenLayers.Projection.transform(h.clone(),b,c),k.unshift(h);while(a.containsPixel(l)&&1E3>++d);h=f.clone();do h=h.offset({x:g,y:0}),l=OpenLayers.Projection.transform(h.clone(),b,c),k.push(h);while(a.containsPixel(l)&&1E3>++d);g=[];for(d=0;d<k.length;++d){l=k[d].x;for(var f=[],m=null,n=Math.min(e[0].y,90),h=Math.max(e[e.length-1].y,-90),p=(n-h)/this.numPoints,n=h,h=0;h<=this.numPoints;++h){var q=new OpenLayers.Geometry.Point(l, | |
2995 n);q.transform(b,c);f.push(q);n+=p;q.y>=a.bottom&&!m&&(m=q)}this.labelled&&(m=new OpenLayers.Geometry.Point(m.x,a.bottom),l={value:l,label:this.labelled?OpenLayers.Util.getFormattedLonLat(l,"lon",this.labelFormat):"",labelAlign:"cb",xOffset:0,yOffset:2},this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(m,l)));f=new OpenLayers.Geometry.LineString(f);g.push(new OpenLayers.Feature.Vector(f))}for(h=0;h<e.length;++h)if(n=e[h].y,!(-90>n||90<n)){f=[];d=k[0].x;p=(k[k.length-1].x-d)/this.numPoints; | |
2996 l=d;m=null;for(d=0;d<=this.numPoints;++d)q=new OpenLayers.Geometry.Point(l,n),q.transform(b,c),f.push(q),l+=p,q.x<a.right&&(m=q);this.labelled&&(m=new OpenLayers.Geometry.Point(a.right,m.y),l={value:n,label:this.labelled?OpenLayers.Util.getFormattedLonLat(n,"lat",this.labelFormat):"",labelAlign:"rb",xOffset:-2,yOffset:2},this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(m,l)));f=new OpenLayers.Geometry.LineString(f);g.push(new OpenLayers.Feature.Vector(f))}this.gratLayer.addFeatures(g)}},CLASS_NAME:"OpenLayers.Control.Graticule"});OpenLayers.Console.warn("OpenLayers.Rico is deprecated");OpenLayers.Rico=OpenLayers.Rico||{}; | |
2997 OpenLayers.Rico.Corner={round:function(a,b){a=OpenLayers.Util.getElement(a);this._setOptions(b);var c=this.options.color;"fromElement"==this.options.color&&(c=this._background(a));var d=this.options.bgColor;"fromParent"==this.options.bgColor&&(d=this._background(a.offsetParent));this._roundCornersImpl(a,c,d)},changeColor:function(a,b){a.style.backgroundColor=b;for(var c=a.parentNode.getElementsByTagName("span"),d=0;d<c.length;d++)c[d].style.backgroundColor=b},changeOpacity:function(a,b){var c="alpha(opacity="+ | |
2998 100*b+")";a.style.opacity=b;a.style.filter=c;for(var d=a.parentNode.getElementsByTagName("span"),e=0;e<d.length;e++)d[e].style.opacity=b,d[e].style.filter=c},reRound:function(a,b){var c=a.parentNode.childNodes[2];a.parentNode.removeChild(a.parentNode.childNodes[0]);a.parentNode.removeChild(c);this.round(a.parentNode,b)},_roundCornersImpl:function(a,b,c){this.options.border&&this._renderBorder(a,c);this._isTopRounded()&&this._roundTopCorners(a,b,c);this._isBottomRounded()&&this._roundBottomCorners(a, | |
2999 b,c)},_renderBorder:function(a,b){var c="1px solid "+this._borderColor(b);a.innerHTML="<div "+("style='border-left: "+c+";"+("border-right: "+c)+"'")+">"+a.innerHTML+"</div>"},_roundTopCorners:function(a,b,c){for(var d=this._createCorner(c),e=0;e<this.options.numSlices;e++)d.appendChild(this._createCornerSlice(b,c,e,"top"));a.style.paddingTop=0;a.insertBefore(d,a.firstChild)},_roundBottomCorners:function(a,b,c){for(var d=this._createCorner(c),e=this.options.numSlices-1;0<=e;e--)d.appendChild(this._createCornerSlice(b, | |
3000 c,e,"bottom"));a.style.paddingBottom=0;a.appendChild(d)},_createCorner:function(a){var b=document.createElement("div");b.style.backgroundColor=this._isTransparent()?"transparent":a;return b},_createCornerSlice:function(a,b,c,d){var e=document.createElement("span"),f=e.style;f.backgroundColor=a;f.display="block";f.height="1px";f.overflow="hidden";f.fontSize="1px";a=this._borderColor(a,b);this.options.border&&0==c?(f.borderTopStyle="solid",f.borderTopWidth="1px",f.borderLeftWidth="0px",f.borderRightWidth= | |
3001 "0px",f.borderBottomWidth="0px",f.height="0px",f.borderColor=a):a&&(f.borderColor=a,f.borderStyle="solid",f.borderWidth="0px 1px");this.options.compact||c!=this.options.numSlices-1||(f.height="2px");this._setMargin(e,c,d);this._setBorder(e,c,d);return e},_setOptions:function(a){this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:!0,border:!1,compact:!1};OpenLayers.Util.extend(this.options,a||{});this.options.numSlices=this.options.compact?2:4;this._isTransparent()&&(this.options.blend= | |
3002 !1)},_whichSideTop:function(){return this._hasString(this.options.corners,"all","top")||0<=this.options.corners.indexOf("tl")&&0<=this.options.corners.indexOf("tr")?"":0<=this.options.corners.indexOf("tl")?"left":0<=this.options.corners.indexOf("tr")?"right":""},_whichSideBottom:function(){return this._hasString(this.options.corners,"all","bottom")||0<=this.options.corners.indexOf("bl")&&0<=this.options.corners.indexOf("br")?"":0<=this.options.corners.indexOf("bl")?"left":0<=this.options.corners.indexOf("br")? | |
3003 "right":""},_borderColor:function(a,b){return"transparent"==a?b:this.options.border?this.options.border:this.options.blend?this._blend(b,a):""},_setMargin:function(a,b,c){b=this._marginSize(b);c="top"==c?this._whichSideTop():this._whichSideBottom();"left"==c?(a.style.marginLeft=b+"px",a.style.marginRight="0px"):"right"==c?(a.style.marginRight=b+"px",a.style.marginLeft="0px"):(a.style.marginLeft=b+"px",a.style.marginRight=b+"px")},_setBorder:function(a,b,c){b=this._borderSize(b);c="top"==c?this._whichSideTop(): | |
3004 this._whichSideBottom();"left"==c?(a.style.borderLeftWidth=b+"px",a.style.borderRightWidth="0px"):"right"==c?(a.style.borderRightWidth=b+"px",a.style.borderLeftWidth="0px"):(a.style.borderLeftWidth=b+"px",a.style.borderRightWidth=b+"px");!1!=this.options.border&&(a.style.borderLeftWidth=b+"px",a.style.borderRightWidth=b+"px")},_marginSize:function(a){if(this._isTransparent())return 0;var b=[5,3,2,1],c=[3,2,1,0],d=[2,1],e=[1,0];return this.options.compact&&this.options.blend?e[a]:this.options.compact? | |
3005 d[a]:this.options.blend?c[a]:b[a]},_borderSize:function(a){var b=[5,3,2,1],c=[2,1,1,1],d=[1,0],e=[0,2,0,0];return this.options.compact&&(this.options.blend||this._isTransparent())?1:this.options.compact?d[a]:this.options.blend?c[a]:this.options.border?e[a]:this._isTransparent()?b[a]:0},_hasString:function(a){for(var b=1;b<arguments.length;b++)if(0<=a.indexOf(arguments[b]))return!0;return!1},_blend:function(a,b){var c=OpenLayers.Rico.Color.createFromHex(a);c.blend(OpenLayers.Rico.Color.createFromHex(b)); | |
3006 return c},_background:function(a){try{return OpenLayers.Rico.Color.createColorFromBackground(a).asHex()}catch(b){return"#ffffff"}},_isTransparent:function(){return"transparent"==this.options.color},_isTopRounded:function(){return this._hasString(this.options.corners,"all","top","tl","tr")},_isBottomRounded:function(){return this._hasString(this.options.corners,"all","bottom","bl","br")},_hasSingleTextChild:function(a){return 1==a.childNodes.length&&3==a.childNodes[0].nodeType}};OpenLayers.Control.NavigationHistory=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOGGLE,previous:null,previousOptions:null,next:null,nextOptions:null,limit:50,autoActivate:!0,clearOnDeactivate:!1,registry:null,nextStack:null,previousStack:null,listeners:null,restoring:!1,initialize:function(a){OpenLayers.Control.prototype.initialize.apply(this,[a]);this.registry=OpenLayers.Util.extend({moveend:this.getState},this.registry);a={trigger:OpenLayers.Function.bind(this.previousTrigger, | |
3007 this),displayClass:this.displayClass+" "+this.displayClass+"Previous"};OpenLayers.Util.extend(a,this.previousOptions);this.previous=new OpenLayers.Control.Button(a);a={trigger:OpenLayers.Function.bind(this.nextTrigger,this),displayClass:this.displayClass+" "+this.displayClass+"Next"};OpenLayers.Util.extend(a,this.nextOptions);this.next=new OpenLayers.Control.Button(a);this.clear()},onPreviousChange:function(a,b){a&&!this.previous.active?this.previous.activate():!a&&this.previous.active&&this.previous.deactivate()}, | |
3008 onNextChange:function(a,b){a&&!this.next.active?this.next.activate():!a&&this.next.active&&this.next.deactivate()},destroy:function(){OpenLayers.Control.prototype.destroy.apply(this);this.previous.destroy();this.next.destroy();this.deactivate();for(var a in this)this[a]=null},setMap:function(a){this.map=a;this.next.setMap(a);this.previous.setMap(a)},draw:function(){OpenLayers.Control.prototype.draw.apply(this,arguments);this.next.draw();this.previous.draw()},previousTrigger:function(){var a=this.previousStack.shift(), | |
3009 b=this.previousStack.shift();void 0!=b?(this.nextStack.unshift(a),this.previousStack.unshift(b),this.restoring=!0,this.restore(b),this.restoring=!1,this.onNextChange(this.nextStack[0],this.nextStack.length),this.onPreviousChange(this.previousStack[1],this.previousStack.length-1)):this.previousStack.unshift(a);return b},nextTrigger:function(){var a=this.nextStack.shift();void 0!=a&&(this.previousStack.unshift(a),this.restoring=!0,this.restore(a),this.restoring=!1,this.onNextChange(this.nextStack[0], | |
3010 this.nextStack.length),this.onPreviousChange(this.previousStack[1],this.previousStack.length-1));return a},clear:function(){this.previousStack=[];this.previous.deactivate();this.nextStack=[];this.next.deactivate()},getState:function(){return{center:this.map.getCenter(),resolution:this.map.getResolution(),projection:this.map.getProjectionObject(),units:this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units}},restore:function(a){var b,c;if(this.map.getProjectionObject()== | |
3011 a.projection)c=this.map.getZoomForResolution(a.resolution),b=a.center;else{b=a.center.clone();b.transform(a.projection,this.map.getProjectionObject());c=a.units;var d=this.map.getProjectionObject().getUnits()||this.map.units||this.map.baseLayer.units;c=this.map.getZoomForResolution((c&&d?OpenLayers.INCHES_PER_UNIT[c]/OpenLayers.INCHES_PER_UNIT[d]:1)*a.resolution)}this.map.setCenter(b,c)},setListeners:function(){this.listeners={};for(var a in this.registry)this.listeners[a]=OpenLayers.Function.bind(function(){if(!this.restoring){var b= | |
3012 this.registry[a].apply(this,arguments);this.previousStack.unshift(b);if(1<this.previousStack.length)this.onPreviousChange(this.previousStack[1],this.previousStack.length-1);this.previousStack.length>this.limit+1&&this.previousStack.pop();0<this.nextStack.length&&(this.nextStack=[],this.onNextChange(null,0))}return!0},this)},activate:function(){var a=!1;if(this.map&&OpenLayers.Control.prototype.activate.apply(this)){null==this.listeners&&this.setListeners();for(var b in this.listeners)this.map.events.register(b, | |
3013 this,this.listeners[b]);a=!0;0==this.previousStack.length&&this.initStack()}return a},initStack:function(){this.map.getCenter()&&this.listeners.moveend()},deactivate:function(){var a=!1;if(this.map&&OpenLayers.Control.prototype.deactivate.apply(this)){for(var b in this.listeners)this.map.events.unregister(b,this,this.listeners[b]);this.clearOnDeactivate&&this.clear();a=!0}return a},CLASS_NAME:"OpenLayers.Control.NavigationHistory"});OpenLayers.Layer.UTFGrid=OpenLayers.Class(OpenLayers.Layer.XYZ,{isBaseLayer:!1,projection:new OpenLayers.Projection("EPSG:900913"),useJSONP:!1,tileClass:OpenLayers.Tile.UTFGrid,initialize:function(a){OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a.name,a.url,{},a]);this.tileOptions=OpenLayers.Util.extend({utfgridResolution:this.utfgridResolution},this.tileOptions)},createBackBuffer:function(){},clone:function(a){null==a&&(a=new OpenLayers.Layer.UTFGrid(this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this, | |
3014 [a])},getFeatureInfo:function(a){var b=null;(a=this.getTileData(a))&&a.tile&&(b=a.tile.getFeatureInfo(a.i,a.j));return b},getFeatureId:function(a){var b=null;a=this.getTileData(a);a.tile&&(b=a.tile.getFeatureId(a.i,a.j));return b},CLASS_NAME:"OpenLayers.Layer.UTFGrid"});OpenLayers.TileManager=OpenLayers.Class({cacheSize:256,tilesPerFrame:2,frameDelay:16,moveDelay:100,zoomDelay:200,maps:null,tileQueueId:null,tileQueue:null,tileCache:null,tileCacheIndex:null,initialize:function(a){OpenLayers.Util.extend(this,a);this.maps=[];this.tileQueueId={};this.tileQueue={};this.tileCache={};this.tileCacheIndex=[]},addMap:function(a){if(!this._destroyed&&OpenLayers.Layer.Grid){this.maps.push(a);this.tileQueue[a.id]=[];for(var b=0,c=a.layers.length;b<c;++b)this.addLayer({layer:a.layers[b]}); | |
3015 a.events.on({move:this.move,zoomend:this.zoomEnd,changelayer:this.changeLayer,addlayer:this.addLayer,preremovelayer:this.removeLayer,scope:this})}},removeMap:function(a){if(!this._destroyed&&OpenLayers.Layer.Grid){window.clearTimeout(this.tileQueueId[a.id]);if(a.layers)for(var b=0,c=a.layers.length;b<c;++b)this.removeLayer({layer:a.layers[b]});a.events&&a.events.un({move:this.move,zoomend:this.zoomEnd,changelayer:this.changeLayer,addlayer:this.addLayer,preremovelayer:this.removeLayer,scope:this}); | |
3016 delete this.tileQueue[a.id];delete this.tileQueueId[a.id];OpenLayers.Util.removeItem(this.maps,a)}},move:function(a){this.updateTimeout(a.object,this.moveDelay,!0)},zoomEnd:function(a){this.updateTimeout(a.object,this.zoomDelay)},changeLayer:function(a){"visibility"!==a.property&&"params"!==a.property||this.updateTimeout(a.object,0)},addLayer:function(a){a=a.layer;if(a instanceof OpenLayers.Layer.Grid){a.events.on({addtile:this.addTile,retile:this.clearTileQueue,scope:this});var b,c,d;for(b=a.grid.length- | |
3017 1;0<=b;--b)for(c=a.grid[b].length-1;0<=c;--c)d=a.grid[b][c],this.addTile({tile:d}),d.url&&!d.imgDiv&&this.manageTileCache({object:d})}},removeLayer:function(a){a=a.layer;if(a instanceof OpenLayers.Layer.Grid&&(this.clearTileQueue({object:a}),a.events&&a.events.un({addtile:this.addTile,retile:this.clearTileQueue,scope:this}),a.grid)){var b,c,d;for(b=a.grid.length-1;0<=b;--b)for(c=a.grid[b].length-1;0<=c;--c)d=a.grid[b][c],this.unloadTile({object:d})}},updateTimeout:function(a,b,c){window.clearTimeout(this.tileQueueId[a.id]); | |
3018 var d=this.tileQueue[a.id];if(!c||d.length)this.tileQueueId[a.id]=window.setTimeout(OpenLayers.Function.bind(function(){this.drawTilesFromQueue(a);d.length&&this.updateTimeout(a,this.frameDelay)},this),b)},addTile:function(a){if(a.tile instanceof OpenLayers.Tile.Image)a.tile.events.on({beforedraw:this.queueTileDraw,beforeload:this.manageTileCache,loadend:this.addToCache,unload:this.unloadTile,scope:this});else this.removeLayer({layer:a.tile.layer})},unloadTile:function(a){a=a.object;a.events.un({beforedraw:this.queueTileDraw, | |
3019 beforeload:this.manageTileCache,loadend:this.addToCache,unload:this.unloadTile,scope:this});OpenLayers.Util.removeItem(this.tileQueue[a.layer.map.id],a)},queueTileDraw:function(a){a=a.object;var b=!1,c=a.layer,d=c.getURL(a.bounds),e=this.tileCache[d];e&&"olTileImage"!==e.className&&(delete this.tileCache[d],OpenLayers.Util.removeItem(this.tileCacheIndex,d),e=null);!c.url||!c.async&&e||(b=this.tileQueue[c.map.id],~OpenLayers.Util.indexOf(b,a)||b.push(a),b=!0);return!b},drawTilesFromQueue:function(a){var b= | |
3020 this.tileQueue[a.id],c=this.tilesPerFrame;for(a=a.zoomTween&&a.zoomTween.playing;!a&&b.length&&c;)b.shift().draw(!0),--c},manageTileCache:function(a){a=a.object;var b=this.tileCache[a.url];b&&(b.parentNode&&OpenLayers.Element.hasClass(b.parentNode,"olBackBuffer")&&(b.parentNode.removeChild(b),b.id=null),b.parentNode||(b.style.visibility="hidden",b.style.opacity=0,a.setImage(b),OpenLayers.Util.removeItem(this.tileCacheIndex,a.url),this.tileCacheIndex.push(a.url)))},addToCache:function(a){a=a.object; | |
3021 this.tileCache[a.url]||OpenLayers.Element.hasClass(a.imgDiv,"olImageLoadError")||(this.tileCacheIndex.length>=this.cacheSize&&(delete this.tileCache[this.tileCacheIndex[0]],this.tileCacheIndex.shift()),this.tileCache[a.url]=a.imgDiv,this.tileCacheIndex.push(a.url))},clearTileQueue:function(a){a=a.object;for(var b=this.tileQueue[a.map.id],c=b.length-1;0<=c;--c)b[c].layer===a&&b.splice(c,1)},destroy:function(){for(var a=this.maps.length-1;0<=a;--a)this.removeMap(this.maps[a]);this.tileCacheIndex=this.tileCache= | |
3022 this.tileQueueId=this.tileQueue=this.maps=null;this._destroyed=!0}});OpenLayers.Layer.ArcGISCache=OpenLayers.Class(OpenLayers.Layer.XYZ,{url:null,tileOrigin:null,tileSize:new OpenLayers.Size(256,256),useArcGISServer:!0,type:"png",useScales:!1,overrideDPI:!1,initialize:function(a,b,c){OpenLayers.Layer.XYZ.prototype.initialize.apply(this,arguments);this.resolutions&&(this.serverResolutions=this.resolutions,this.maxExtent=this.getMaxExtentForResolution(this.resolutions[0]));if(this.layerInfo){var d=this.layerInfo,e=new OpenLayers.Bounds(d.fullExtent.xmin,d.fullExtent.ymin, | |
3023 d.fullExtent.xmax,d.fullExtent.ymax);this.projection="EPSG:"+d.spatialReference.wkid;this.sphericalMercator=102100==d.spatialReference.wkid;this.units="esriFeet"==d.units?"ft":"m";if(d.tileInfo){this.tileSize=new OpenLayers.Size(d.tileInfo.width||d.tileInfo.cols,d.tileInfo.height||d.tileInfo.rows);this.tileOrigin=new OpenLayers.LonLat(d.tileInfo.origin.x,d.tileInfo.origin.y);var f=new OpenLayers.Geometry.Point(e.left,e.top),e=new OpenLayers.Geometry.Point(e.right,e.bottom);this.useScales?this.scales= | |
3024 []:this.resolutions=[];this.lods=[];for(var g in d.tileInfo.lods)if(d.tileInfo.lods.hasOwnProperty(g)){var h=d.tileInfo.lods[g];this.useScales?this.scales.push(h.scale):this.resolutions.push(h.resolution);var k=this.getContainingTileCoords(f,h.resolution);h.startTileCol=k.x;h.startTileRow=k.y;k=this.getContainingTileCoords(e,h.resolution);h.endTileCol=k.x;h.endTileRow=k.y;this.lods.push(h)}this.maxExtent=this.calculateMaxExtentWithLOD(this.lods[0]);this.serverResolutions=this.resolutions;this.overrideDPI&& | |
3025 d.tileInfo.dpi&&(OpenLayers.DOTS_PER_INCH=d.tileInfo.dpi)}}},getContainingTileCoords:function(a,b){return new OpenLayers.Pixel(Math.max(Math.floor((a.x-this.tileOrigin.lon)/(this.tileSize.w*b)),0),Math.max(Math.floor((this.tileOrigin.lat-a.y)/(this.tileSize.h*b)),0))},calculateMaxExtentWithLOD:function(a){var b=this.tileOrigin.lon+a.startTileCol*this.tileSize.w*a.resolution,c=this.tileOrigin.lat-a.startTileRow*this.tileSize.h*a.resolution;return new OpenLayers.Bounds(b,c-(a.endTileRow-a.startTileRow+ | |
3026 1)*this.tileSize.h*a.resolution,b+(a.endTileCol-a.startTileCol+1)*this.tileSize.w*a.resolution,c)},calculateMaxExtentWithExtent:function(a,b){var c=new OpenLayers.Geometry.Point(a.left,a.top),d=new OpenLayers.Geometry.Point(a.right,a.bottom),c=this.getContainingTileCoords(c,b),d=this.getContainingTileCoords(d,b);return this.calculateMaxExtentWithLOD({resolution:b,startTileCol:c.x,startTileRow:c.y,endTileCol:d.x,endTileRow:d.y})},getUpperLeftTileCoord:function(a){var b=new OpenLayers.Geometry.Point(this.maxExtent.left, | |
3027 this.maxExtent.top);return this.getContainingTileCoords(b,a)},getLowerRightTileCoord:function(a){var b=new OpenLayers.Geometry.Point(this.maxExtent.right,this.maxExtent.bottom);return this.getContainingTileCoords(b,a)},getMaxExtentForResolution:function(a){var b=this.getUpperLeftTileCoord(a),c=this.getLowerRightTileCoord(a),d=this.tileOrigin.lon+b.x*this.tileSize.w*a,e=this.tileOrigin.lat-b.y*this.tileSize.h*a;return new OpenLayers.Bounds(d,e-(c.y-b.y+1)*this.tileSize.h*a,d+(c.x-b.x+1)*this.tileSize.w* | |
3028 a,e)},clone:function(a){null==a&&(a=new OpenLayers.Layer.ArcGISCache(this.name,this.url,this.options));return OpenLayers.Layer.XYZ.prototype.clone.apply(this,[a])},initGriddedTiles:function(a){delete this._tileOrigin;OpenLayers.Layer.XYZ.prototype.initGriddedTiles.apply(this,arguments)},getMaxExtent:function(){var a=this.map.getResolution();return this.maxExtent=this.getMaxExtentForResolution(a)},getTileOrigin:function(){if(!this._tileOrigin){var a=this.getMaxExtent();this._tileOrigin=new OpenLayers.LonLat(a.left, | |
3029 a.bottom)}return this._tileOrigin},getURL:function(a){var b=this.getResolution(),c=this.tileOrigin.lon+b*this.tileSize.w/2,d=this.tileOrigin.lat-b*this.tileSize.h/2;a=a.getCenterLonLat();c=Math.round(Math.abs((a.lon-c)/(b*this.tileSize.w)));d=Math.round(Math.abs((d-a.lat)/(b*this.tileSize.h)));a=this.map.getZoom();if(this.lods){if(b=this.lods[this.map.getZoom()],c<b.startTileCol||c>b.endTileCol||d<b.startTileRow||d>b.endTileRow)return null}else{var e=this.getUpperLeftTileCoord(b),b=this.getLowerRightTileCoord(b); | |
3030 if(c<e.x||c>=b.x||d<e.y||d>=b.y)return null}b=this.url;e=""+c+d+a;OpenLayers.Util.isArray(b)&&(b=this.selectUrl(e,b));this.useArcGISServer?b+="/tile/${z}/${y}/${x}":(c="C"+OpenLayers.Number.zeroPad(c,8,16),d="R"+OpenLayers.Number.zeroPad(d,8,16),a="L"+OpenLayers.Number.zeroPad(a,2,10),b=b+"/${z}/${y}/${x}."+this.type);b=OpenLayers.String.format(b,{x:c,y:d,z:a});return OpenLayers.Util.urlAppend(b,OpenLayers.Util.getParameterString(this.params))},CLASS_NAME:"OpenLayers.Layer.ArcGISCache"});OpenLayers.Control.WMSGetFeatureInfo=OpenLayers.Class(OpenLayers.Control,{hover:!1,drillDown:!1,maxFeatures:10,clickCallback:"click",output:"features",layers:null,queryVisible:!1,url:null,layerUrls:null,infoFormat:"text/html",vendorParams:{},format:null,formatOptions:null,handler:null,hoverRequest:null,initialize:function(a){a=a||{};a.handlerOptions=a.handlerOptions||{};OpenLayers.Control.prototype.initialize.apply(this,[a]);this.format||(this.format=new OpenLayers.Format.WMSGetFeatureInfo(a.formatOptions)); | |
3031 !0===this.drillDown&&(this.hover=!1);this.hover?this.handler=new OpenLayers.Handler.Hover(this,{move:this.cancelHover,pause:this.getInfoForHover},OpenLayers.Util.extend(this.handlerOptions.hover||{},{delay:250})):(a={},a[this.clickCallback]=this.getInfoForClick,this.handler=new OpenLayers.Handler.Click(this,a,this.handlerOptions.click||{}))},getInfoForClick:function(a){this.events.triggerEvent("beforegetfeatureinfo",{xy:a.xy});OpenLayers.Element.addClass(this.map.viewPortDiv,"olCursorWait");this.request(a.xy, | |
3032 {})},getInfoForHover:function(a){this.events.triggerEvent("beforegetfeatureinfo",{xy:a.xy});this.request(a.xy,{hover:!0})},cancelHover:function(){this.hoverRequest&&(this.hoverRequest.abort(),this.hoverRequest=null)},findLayers:function(){for(var a=this.layers||this.map.layers,b=[],c,d,e=a.length-1;0<=e;--e)c=a[e],c instanceof OpenLayers.Layer.WMS&&(!this.queryVisible||c.getVisibility())&&(d=OpenLayers.Util.isArray(c.url)?c.url[0]:c.url,!1!==this.drillDown||this.url||(this.url=d),(!0===this.drillDown|| | |
3033 this.urlMatches(d))&&b.push(c));return b},urlMatches:function(a){var b=OpenLayers.Util.isEquivalentUrl(this.url,a);if(!b&&this.layerUrls)for(var c=0,d=this.layerUrls.length;c<d;++c)if(OpenLayers.Util.isEquivalentUrl(this.layerUrls[c],a)){b=!0;break}return b},buildWMSOptions:function(a,b,c,d){for(var e=[],f=[],g=0,h=b.length;g<h;g++)null!=b[g].params.LAYERS&&(e=e.concat(b[g].params.LAYERS),f=f.concat(this.getStyleNames(b[g])));b=b[0];g=this.map.getProjection();(h=b.projection)&&h.equals(this.map.getProjectionObject())&& | |
3034 (g=h.getCode());d=OpenLayers.Util.extend({service:"WMS",version:b.params.VERSION,request:"GetFeatureInfo",exceptions:b.params.EXCEPTIONS,bbox:this.map.getExtent().toBBOX(null,b.reverseAxisOrder()),feature_count:this.maxFeatures,height:this.map.getSize().h,width:this.map.getSize().w,format:d,info_format:b.params.INFO_FORMAT||this.infoFormat},1.3<=parseFloat(b.params.VERSION)?{crs:g,i:parseInt(c.x),j:parseInt(c.y)}:{srs:g,x:parseInt(c.x),y:parseInt(c.y)});0!=e.length&&(d=OpenLayers.Util.extend({layers:e, | |
3035 query_layers:e,styles:f},d));OpenLayers.Util.applyDefaults(d,this.vendorParams);return{url:a,params:OpenLayers.Util.upperCaseObject(d),callback:function(b){this.handleResponse(c,b,a)},scope:this}},getStyleNames:function(a){return a.params.STYLES?a.params.STYLES:OpenLayers.Util.isArray(a.params.LAYERS)?Array(a.params.LAYERS.length):a.params.LAYERS.replace(/[^,]/g,"")},request:function(a,b){var c=this.findLayers();if(0==c.length)this.events.triggerEvent("nogetfeatureinfo"),OpenLayers.Element.removeClass(this.map.viewPortDiv, | |
3036 "olCursorWait");else if(b=b||{},!1===this.drillDown){var c=this.buildWMSOptions(this.url,c,a,c[0].params.FORMAT),d=OpenLayers.Request.GET(c);!0===b.hover&&(this.hoverRequest=d)}else{this._numRequests=this._requestCount=0;this.features=[];for(var d={},e,f=0,g=c.length;f<g;f++){var h=c[f];e=OpenLayers.Util.isArray(h.url)?h.url[0]:h.url;e in d?d[e].push(h):(this._numRequests++,d[e]=[h])}for(e in d)c=d[e],c=this.buildWMSOptions(e,c,a,c[0].params.FORMAT),OpenLayers.Request.GET(c)}},triggerGetFeatureInfo:function(a, | |
3037 b,c){this.events.triggerEvent("getfeatureinfo",{text:a.responseText,features:c,request:a,xy:b});OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait")},handleResponse:function(a,b,c){var d=b.responseXML;d&&d.documentElement||(d=b.responseText);d=this.format.read(d);!1===this.drillDown?this.triggerGetFeatureInfo(b,a,d):(this._requestCount++,this._features="object"===this.output?(this._features||[]).concat({url:c,features:d}):(this._features||[]).concat(d),this._requestCount===this._numRequests&& | |
3038 (this.triggerGetFeatureInfo(b,a,this._features.concat()),delete this._features,delete this._requestCount,delete this._numRequests))},CLASS_NAME:"OpenLayers.Control.WMSGetFeatureInfo"});OpenLayers.Format.WMSCapabilities.v1_3_0=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_3,{version:"1.3.0",CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_3_0"});OpenLayers.Format.SOSGetFeatureOfInterest=OpenLayers.Class(OpenLayers.Format.XML,{VERSION:"1.0.0",namespaces:{sos:"http://www.opengis.net/sos/1.0",gml:"http://www.opengis.net/gml",sa:"http://www.opengis.net/sampling/1.0",xsi:"http://www.w3.org/2001/XMLSchema-instance"},schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd",defaultPrefix:"sos",regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},read:function(a){"string"== | |
3039 typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={features:[]};this.readNode(a,b);a=[];for(var c=0,d=b.features.length;c<d;c++){var e=b.features[c];this.internalProjection&&(this.externalProjection&&e.components[0])&&e.components[0].transform(this.externalProjection,this.internalProjection);e=new OpenLayers.Feature.Vector(e.components[0],e.attributes);a.push(e)}return a},readers:{sa:{SamplingPoint:function(a,b){if(!b.attributes){var c= | |
3040 {attributes:{}};b.features.push(c);b=c}b.attributes.id=this.getAttributeNS(a,this.namespaces.gml,"id");this.readChildNodes(a,b)},position:function(a,b){this.readChildNodes(a,b)}},gml:OpenLayers.Util.applyDefaults({FeatureCollection:function(a,b){this.readChildNodes(a,b)},featureMember:function(a,b){var c={attributes:{}};b.features.push(c);this.readChildNodes(a,c)},name:function(a,b){b.attributes.name=this.getChildValue(a)},pos:function(a,b){this.externalProjection||(this.externalProjection=new OpenLayers.Projection(a.getAttribute("srsName"))); | |
3041 OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(this,[a,b])}},OpenLayers.Format.GML.v3.prototype.readers.gml)},writers:{sos:{GetFeatureOfInterest:function(a){for(var b=this.createElementNSPlus("GetFeatureOfInterest",{attributes:{version:this.VERSION,service:"SOS","xsi:schemaLocation":this.schemaLocation}}),c=0,d=a.fois.length;c<d;c++)this.writeNode("FeatureOfInterestId",{foi:a.fois[c]},b);return b},FeatureOfInterestId:function(a){return this.createElementNSPlus("FeatureOfInterestId",{value:a.foi})}}}, | |
3042 CLASS_NAME:"OpenLayers.Format.SOSGetFeatureOfInterest"});OpenLayers.Format.SOSGetObservation=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{ows:"http://www.opengis.net/ows",gml:"http://www.opengis.net/gml",sos:"http://www.opengis.net/sos/1.0",ogc:"http://www.opengis.net/ogc",om:"http://www.opengis.net/om/1.0",sa:"http://www.opengis.net/sampling/1.0",xlink:"http://www.w3.org/1999/xlink",xsi:"http://www.w3.org/2001/XMLSchema-instance"},regExes:{trimSpace:/^\s*|\s*$/g,removeSpace:/\s*/g,splitSpace:/\s+/,trimComma:/\s*,\s*/g},VERSION:"1.0.0",schemaLocation:"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd", | |
3043 defaultPrefix:"sos",read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={measurements:[],observations:[]};this.readNode(a,b);return b},write:function(a){a=this.writeNode("sos:GetObservation",a);a.setAttribute("xmlns:om",this.namespaces.om);a.setAttribute("xmlns:ogc",this.namespaces.ogc);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation);return OpenLayers.Format.XML.prototype.write.apply(this, | |
3044 [a])},readers:{om:{ObservationCollection:function(a,b){b.id=this.getAttributeNS(a,this.namespaces.gml,"id");this.readChildNodes(a,b)},member:function(a,b){this.readChildNodes(a,b)},Measurement:function(a,b){var c={};b.measurements.push(c);this.readChildNodes(a,c)},Observation:function(a,b){var c={};b.observations.push(c);this.readChildNodes(a,c)},samplingTime:function(a,b){var c={};b.samplingTime=c;this.readChildNodes(a,c)},observedProperty:function(a,b){b.observedProperty=this.getAttributeNS(a,this.namespaces.xlink, | |
3045 "href");this.readChildNodes(a,b)},procedure:function(a,b){b.procedure=this.getAttributeNS(a,this.namespaces.xlink,"href");this.readChildNodes(a,b)},featureOfInterest:function(a,b){var c={features:[]};b.fois=[];b.fois.push(c);this.readChildNodes(a,c);for(var d=[],e=0,f=c.features.length;e<f;e++){var g=c.features[e];d.push(new OpenLayers.Feature.Vector(g.components[0],g.attributes))}c.features=d},result:function(a,b){var c={};b.result=c;""!==this.getChildValue(a)?(c.value=this.getChildValue(a),c.uom= | |
3046 a.getAttribute("uom")):this.readChildNodes(a,c)}},sa:OpenLayers.Format.SOSGetFeatureOfInterest.prototype.readers.sa,gml:OpenLayers.Util.applyDefaults({TimeInstant:function(a,b){var c={};b.timeInstant=c;this.readChildNodes(a,c)},timePosition:function(a,b){b.timePosition=this.getChildValue(a)}},OpenLayers.Format.SOSGetFeatureOfInterest.prototype.readers.gml)},writers:{sos:{GetObservation:function(a){var b=this.createElementNSPlus("GetObservation",{attributes:{version:this.VERSION,service:"SOS"}});this.writeNode("offering", | |
3047 a,b);a.eventTime&&this.writeNode("eventTime",a,b);for(var c in a.procedures)this.writeNode("procedure",a.procedures[c],b);for(var d in a.observedProperties)this.writeNode("observedProperty",a.observedProperties[d],b);a.foi&&this.writeNode("featureOfInterest",a.foi,b);this.writeNode("responseFormat",a,b);a.resultModel&&this.writeNode("resultModel",a,b);a.responseMode&&this.writeNode("responseMode",a,b);return b},featureOfInterest:function(a){var b=this.createElementNSPlus("featureOfInterest");this.writeNode("ObjectID", | |
3048 a.objectId,b);return b},ObjectID:function(a){return this.createElementNSPlus("ObjectID",{value:a})},responseFormat:function(a){return this.createElementNSPlus("responseFormat",{value:a.responseFormat})},procedure:function(a){return this.createElementNSPlus("procedure",{value:a})},offering:function(a){return this.createElementNSPlus("offering",{value:a.offering})},observedProperty:function(a){return this.createElementNSPlus("observedProperty",{value:a})},eventTime:function(a){var b=this.createElementNSPlus("eventTime"); | |
3049 "latest"===a.eventTime&&this.writeNode("ogc:TM_Equals",a,b);return b},resultModel:function(a){return this.createElementNSPlus("resultModel",{value:a.resultModel})},responseMode:function(a){return this.createElementNSPlus("responseMode",{value:a.responseMode})}},ogc:{TM_Equals:function(a){var b=this.createElementNSPlus("ogc:TM_Equals");this.writeNode("ogc:PropertyName",{property:"urn:ogc:data:time:iso8601"},b);"latest"===a.eventTime&&this.writeNode("gml:TimeInstant",{value:"latest"},b);return b},PropertyName:function(a){return this.createElementNSPlus("ogc:PropertyName", | |
3050 {value:a.property})}},gml:{TimeInstant:function(a){var b=this.createElementNSPlus("gml:TimeInstant");this.writeNode("gml:timePosition",a,b);return b},timePosition:function(a){return this.createElementNSPlus("gml:timePosition",{value:a.value})}}},CLASS_NAME:"OpenLayers.Format.SOSGetObservation"});OpenLayers.Control.UTFGrid=OpenLayers.Class(OpenLayers.Control,{autoActivate:!0,layers:null,defaultHandlerOptions:{delay:300,pixelTolerance:4,stopMove:!1,single:!0,"double":!1,stopSingle:!1,stopDouble:!1},handlerMode:"click",setHandler:function(a){this.handlerMode=a;this.resetHandler()},resetHandler:function(){this.handler&&(this.handler.deactivate(),this.handler.destroy(),this.handler=null);"hover"==this.handlerMode?this.handler=new OpenLayers.Handler.Hover(this,{pause:this.handleEvent,move:this.reset}, | |
3051 this.handlerOptions):"click"==this.handlerMode?this.handler=new OpenLayers.Handler.Click(this,{click:this.handleEvent},this.handlerOptions):"move"==this.handlerMode&&(this.handler=new OpenLayers.Handler.Hover(this,{pause:this.handleEvent,move:this.handleEvent},this.handlerOptions));return this.handler?!0:!1},initialize:function(a){a=a||{};a.handlerOptions=a.handlerOptions||this.defaultHandlerOptions;OpenLayers.Control.prototype.initialize.apply(this,[a]);this.resetHandler()},handleEvent:function(a){if(null== | |
3052 a)this.reset();else{var b=this.map.getLonLatFromPixel(a.xy);if(b){var c=this.findLayers();if(0<c.length){for(var d={},e,f,g=0,h=c.length;g<h;g++)e=c[g],f=OpenLayers.Util.indexOf(this.map.layers,e),d[f]=e.getFeatureInfo(b);this.callback(d,b,a.xy)}}}},callback:function(a){},reset:function(a){this.callback(null)},findLayers:function(){for(var a=this.layers||this.map.layers,b=[],c,d=a.length-1;0<=d;--d)c=a[d],c instanceof OpenLayers.Layer.UTFGrid&&b.push(c);return b},CLASS_NAME:"OpenLayers.Control.UTFGrid"});OpenLayers.Format.CQL=function(){function a(a){function b(){var a=e.pop();switch(a.type){case "LOGICAL":var c=b(),g=b();return new OpenLayers.Filter.Logical({filters:[g,c],type:f[a.text.toUpperCase()]});case "NOT":return a=b(),new OpenLayers.Filter.Logical({filters:[a],type:OpenLayers.Filter.Logical.NOT});case "BETWEEN":return e.pop(),g=b(),a=b(),c=b(),new OpenLayers.Filter.Comparison({property:c,lowerBoundary:a,upperBoundary:g,type:OpenLayers.Filter.Comparison.BETWEEN});case "COMPARISON":return g= | |
3053 b(),c=b(),new OpenLayers.Filter.Comparison({property:c,value:g,type:d[a.text.toUpperCase()]});case "IS_NULL":return c=b(),new OpenLayers.Filter.Comparison({property:c,type:d[a.text.toUpperCase()]});case "VALUE":return(c=a.text.match(/^'(.*)'$/))?c[1].replace(/''/g,"'"):Number(a.text);case "SPATIAL":switch(a.text.toUpperCase()){case "BBOX":var a=b(),c=b(),g=b(),h=b(),k=b();return new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,property:k,value:OpenLayers.Bounds.fromArray([h,g,c, | |
3054 a])});case "INTERSECTS":return g=b(),c=b(),new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS,property:c,value:g});case "WITHIN":return g=b(),c=b(),new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.WITHIN,property:c,value:g});case "CONTAINS":return g=b(),c=b(),new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.CONTAINS,property:c,value:g});case "DWITHIN":return a=b(),g=b(),c=b(),new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.DWITHIN,value:g, | |
3055 property:c,distance:Number(a)})}case "GEOMETRY":return OpenLayers.Geometry.fromWKT(a.text);default:return a.text}}for(var c=[],e=[];a.length;){var g=a.shift();switch(g.type){case "PROPERTY":case "GEOMETRY":case "VALUE":e.push(g);break;case "COMPARISON":case "BETWEEN":case "IS_NULL":case "LOGICAL":for(var k=h[g.type];0<c.length&&h[c[c.length-1].type]<=k;)e.push(c.pop());c.push(g);break;case "SPATIAL":case "NOT":case "LPAREN":c.push(g);break;case "RPAREN":for(;0<c.length&&"LPAREN"!=c[c.length-1].type;)e.push(c.pop()); | |
3056 c.pop();0<c.length&&"SPATIAL"==c[c.length-1].type&&e.push(c.pop());case "COMMA":case "END":break;default:throw Error("Unknown token type "+g.type);}}for(;0<c.length;)e.push(c.pop());a=b();if(0<e.length){a="Remaining tokens after building AST: \n";for(c=e.length-1;0<=c;c--)a+=e[c].type+": "+e[c].text+"\n";throw Error(a);}return a}var b={PROPERTY:/^[_a-zA-Z]\w*/,COMPARISON:/^(=|<>|<=|<|>=|>|LIKE)/i,IS_NULL:/^IS NULL/i,COMMA:/^,/,LOGICAL:/^(AND|OR)/i,VALUE:/^('([^']|'')*'|\d+(\.\d*)?|\.\d+)/,LPAREN:/^\(/, | |
3057 RPAREN:/^\)/,SPATIAL:/^(BBOX|INTERSECTS|DWITHIN|WITHIN|CONTAINS)/i,NOT:/^NOT/i,BETWEEN:/^BETWEEN/i,GEOMETRY:function(a){var b=/^(POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)/.exec(a);if(b){var c=a.length,b=a.indexOf("(",b[0].length);if(-1<b)for(var d=1;b<c&&0<d;)switch(b++,a.charAt(b)){case "(":d++;break;case ")":d--}return[a.substr(0,b+1)]}},END:/^$/},c={LPAREN:["GEOMETRY","SPATIAL","PROPERTY","VALUE","LPAREN"],RPAREN:["NOT","LOGICAL","END","RPAREN"],PROPERTY:["COMPARISON", | |
3058 "BETWEEN","COMMA","IS_NULL"],BETWEEN:["VALUE"],IS_NULL:["END"],COMPARISON:["VALUE"],COMMA:["GEOMETRY","VALUE","PROPERTY"],VALUE:["LOGICAL","COMMA","RPAREN","END"],SPATIAL:["LPAREN"],LOGICAL:["NOT","VALUE","SPATIAL","PROPERTY","LPAREN"],NOT:["PROPERTY","LPAREN"],GEOMETRY:["COMMA","RPAREN"]},d={"=":OpenLayers.Filter.Comparison.EQUAL_TO,"<>":OpenLayers.Filter.Comparison.NOT_EQUAL_TO,"<":OpenLayers.Filter.Comparison.LESS_THAN,"<=":OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,">":OpenLayers.Filter.Comparison.GREATER_THAN, | |
3059 ">=":OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,LIKE:OpenLayers.Filter.Comparison.LIKE,BETWEEN:OpenLayers.Filter.Comparison.BETWEEN,"IS NULL":OpenLayers.Filter.Comparison.IS_NULL},e={},f={AND:OpenLayers.Filter.Logical.AND,OR:OpenLayers.Filter.Logical.OR},g={},h={RPAREN:3,LOGICAL:2,COMPARISON:1},k;for(k in d)d.hasOwnProperty(k)&&(e[d[k]]=k);for(k in f)f.hasOwnProperty(k)&&(g[f[k]]=k);return OpenLayers.Class(OpenLayers.Format,{read:function(d){var e=d;d=[];var f,g=["NOT","GEOMETRY","SPATIAL", | |
3060 "PROPERTY","LPAREN"];do{a:{f=g;for(var h=void 0,g=void 0,k=f.length,h=0;h<k;h++){var g=f[h],s=b[g]instanceof RegExp?b[g].exec(e):(0,b[g])(e);if(s){f=s[0];e=e.substr(f.length).replace(/^\s*/,"");f={type:g,text:f,remainder:e};break a}}d="ERROR: In parsing: ["+e+"], expected one of: ";for(h=0;h<k;h++)g=f[h],d+="\n "+g+": "+b[g];throw Error(d);}e=f.remainder;g=c[f.type];if("END"!=f.type&&!g)throw Error("No follows list for "+f.type);d.push(f)}while("END"!=f.type);d=a(d);this.keepData&&(this.data=d); | |
3061 return d},write:function(a){if(a instanceof OpenLayers.Geometry)return a.toString();switch(a.CLASS_NAME){case "OpenLayers.Filter.Spatial":switch(a.type){case OpenLayers.Filter.Spatial.BBOX:return"BBOX("+a.property+","+a.value.toBBOX()+")";case OpenLayers.Filter.Spatial.DWITHIN:return"DWITHIN("+a.property+", "+this.write(a.value)+", "+a.distance+")";case OpenLayers.Filter.Spatial.WITHIN:return"WITHIN("+a.property+", "+this.write(a.value)+")";case OpenLayers.Filter.Spatial.INTERSECTS:return"INTERSECTS("+ | |
3062 a.property+", "+this.write(a.value)+")";case OpenLayers.Filter.Spatial.CONTAINS:return"CONTAINS("+a.property+", "+this.write(a.value)+")";default:throw Error("Unknown spatial filter type: "+a.type);}case "OpenLayers.Filter.Logical":if(a.type==OpenLayers.Filter.Logical.NOT)return"NOT ("+this.write(a.filters[0])+")";for(var b="(",c=!0,d=0;d<a.filters.length;d++)c?c=!1:b+=") "+g[a.type]+" (",b+=this.write(a.filters[d]);return b+")";case "OpenLayers.Filter.Comparison":return a.type==OpenLayers.Filter.Comparison.BETWEEN? | |
3063 a.property+" BETWEEN "+this.write(a.lowerBoundary)+" AND "+this.write(a.upperBoundary):null!==a.value?a.property+" "+e[a.type]+" "+this.write(a.value):a.property+" "+e[a.type];case void 0:if("string"===typeof a)return"'"+a.replace(/'/g,"''")+"'";if("number"===typeof a)return String(a);default:throw Error("Can't encode: "+a.CLASS_NAME+" "+a);}},CLASS_NAME:"OpenLayers.Format.CQL"})}();OpenLayers.Control.Split=OpenLayers.Class(OpenLayers.Control,{layer:null,source:null,sourceOptions:null,tolerance:null,edge:!0,deferDelete:!1,mutual:!0,targetFilter:null,sourceFilter:null,handler:null,initialize:function(a){OpenLayers.Control.prototype.initialize.apply(this,[a]);this.options=a||{};this.options.source&&this.setSource(this.options.source)},setSource:function(a){this.active?(this.deactivate(),this.handler&&(this.handler.destroy(),delete this.handler),this.source=a,this.activate()):this.source= | |
3064 a},activate:function(){var a=OpenLayers.Control.prototype.activate.call(this);if(a)if(!this.source)this.handler||(this.handler=new OpenLayers.Handler.Path(this,{done:function(a){this.onSketchComplete({feature:new OpenLayers.Feature.Vector(a)})}},{layerOptions:this.sourceOptions})),this.handler.activate();else if(this.source.events)this.source.events.on({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});return a},deactivate:function(){var a=OpenLayers.Control.prototype.deactivate.call(this); | |
3065 a&&this.source&&this.source.events&&this.source.events.un({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this});return a},onSketchComplete:function(a){this.feature=null;return!this.considerSplit(a.feature)},afterFeatureModified:function(a){a.modified&&"function"===typeof a.feature.geometry.split&&(this.feature=a.feature,this.considerSplit(a.feature))},removeByGeometry:function(a,b){for(var c=0,d=a.length;c<d;++c)if(a[c].geometry===b){a.splice(c,1);break}}, | |
3066 isEligible:function(a){return a.geometry?a.state!==OpenLayers.State.DELETE&&"function"===typeof a.geometry.split&&this.feature!==a&&(!this.targetFilter||this.targetFilter.evaluate(a.attributes)):!1},considerSplit:function(a){var b=!1,c=!1;if(!this.sourceFilter||this.sourceFilter.evaluate(a.attributes)){for(var d=this.layer&&this.layer.features||[],e,f,g=[],h=[],k=this.layer===this.source&&this.mutual,l={edge:this.edge,tolerance:this.tolerance,mutual:k},m=[a.geometry],n,p,q,r=0,s=d.length;r<s;++r)if(n= | |
3067 d[r],this.isEligible(n)){p=[n.geometry];for(var t=0;t<m.length;++t){q=m[t];for(var u=0;u<p.length;++u)if(e=p[u],q.getBounds().intersectsBounds(e.getBounds())&&(e=q.split(e,l)))f=this.events.triggerEvent("beforesplit",{source:a,target:n}),!1!==f&&(k&&(f=e[0],1<f.length&&(f.unshift(t,1),Array.prototype.splice.apply(m,f),t+=f.length-3),e=e[1]),1<e.length&&(e.unshift(u,1),Array.prototype.splice.apply(p,e),u+=e.length-3))}p&&1<p.length&&(this.geomsToFeatures(n,p),this.events.triggerEvent("split",{original:n, | |
3068 features:p}),Array.prototype.push.apply(g,p),h.push(n),c=!0)}m&&1<m.length&&(this.geomsToFeatures(a,m),this.events.triggerEvent("split",{original:a,features:m}),Array.prototype.push.apply(g,m),h.push(a),b=!0);if(b||c){if(this.deferDelete){d=[];r=0;for(s=h.length;r<s;++r)c=h[r],c.state===OpenLayers.State.INSERT?d.push(c):(c.state=OpenLayers.State.DELETE,this.layer.drawFeature(c));this.layer.destroyFeatures(d,{silent:!0});r=0;for(s=g.length;r<s;++r)g[r].state=OpenLayers.State.INSERT}else this.layer.destroyFeatures(h, | |
3069 {silent:!0});this.layer.addFeatures(g,{silent:!0});this.events.triggerEvent("aftersplit",{source:a,features:g})}}return b},geomsToFeatures:function(a,b){var c=a.clone();delete c.geometry;for(var d,e=0,f=b.length;e<f;++e)d=c.clone(),d.geometry=b[e],d.state=OpenLayers.State.INSERT,b[e]=d},destroy:function(){this.active&&this.deactivate();OpenLayers.Control.prototype.destroy.call(this)},CLASS_NAME:"OpenLayers.Control.Split"});OpenLayers.Layer.WMTS=OpenLayers.Class(OpenLayers.Layer.Grid,{isBaseLayer:!0,version:"1.0.0",requestEncoding:"KVP",url:null,layer:null,matrixSet:null,style:null,format:"image/jpeg",tileOrigin:null,tileFullExtent:null,formatSuffix:null,matrixIds:null,dimensions:null,params:null,zoomOffset:0,serverResolutions:null,formatSuffixMap:{"image/png":"png","image/png8":"png","image/png24":"png","image/png32":"png",png:"png","image/jpeg":"jpg","image/jpg":"jpg",jpeg:"jpg",jpg:"jpg"},matrix:null,initialize:function(a){var b= | |
3070 {url:!0,layer:!0,style:!0,matrixSet:!0},c;for(c in b)if(!(c in a))throw Error("Missing property '"+c+"' in layer configuration.");a.params=OpenLayers.Util.upperCaseObject(a.params);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a.name,a.url,a.params,a]);this.formatSuffix||(this.formatSuffix=this.formatSuffixMap[this.format]||this.format.split("/").pop());if(this.matrixIds&&(a=this.matrixIds.length)&&"string"===typeof this.matrixIds[0])for(b=this.matrixIds,this.matrixIds=Array(a),c=0;c<a;++c)this.matrixIds[c]= | |
3071 {identifier:b[c]}},setMap:function(){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments)},updateMatrixProperties:function(){if(this.matrix=this.getMatrix())this.matrix.topLeftCorner&&(this.tileOrigin=this.matrix.topLeftCorner),this.matrix.tileWidth&&this.matrix.tileHeight&&(this.tileSize=new OpenLayers.Size(this.matrix.tileWidth,this.matrix.tileHeight)),this.tileOrigin||(this.tileOrigin=new OpenLayers.LonLat(this.maxExtent.left,this.maxExtent.top)),this.tileFullExtent||(this.tileFullExtent= | |
3072 this.maxExtent)},moveTo:function(a,b,c){!b&&this.matrix||this.updateMatrixProperties();return OpenLayers.Layer.Grid.prototype.moveTo.apply(this,arguments)},clone:function(a){null==a&&(a=new OpenLayers.Layer.WMTS(this.options));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getIdentifier:function(){return this.getServerZoom()},getMatrix:function(){var a;if(this.matrixIds&&0!==this.matrixIds.length)if("scaleDenominator"in this.matrixIds[0])for(var b=OpenLayers.METERS_PER_INCH*OpenLayers.INCHES_PER_UNIT[this.units]* | |
3073 this.getServerResolution()/2.8E-4,c=Number.POSITIVE_INFINITY,d,e=0,f=this.matrixIds.length;e<f;++e)d=Math.abs(1-this.matrixIds[e].scaleDenominator/b),d<c&&(c=d,a=this.matrixIds[e]);else a=this.matrixIds[this.getIdentifier()];else a={identifier:this.getIdentifier()};return a},getTileInfo:function(a){var b=this.getServerResolution(),c=(a.lon-this.tileOrigin.lon)/(b*this.tileSize.w);a=(this.tileOrigin.lat-a.lat)/(b*this.tileSize.h);var b=Math.floor(c),d=Math.floor(a);return{col:b,row:d,i:Math.floor((c- | |
3074 b)*this.tileSize.w),j:Math.floor((a-d)*this.tileSize.h)}},getURL:function(a){a=this.adjustBounds(a);var b="";if(!this.tileFullExtent||this.tileFullExtent.intersectsBounds(a)){a=a.getCenterLonLat();var c=this.getTileInfo(a);a=this.dimensions;var d,b=OpenLayers.Util.isArray(this.url)?this.selectUrl([this.version,this.style,this.matrixSet,this.matrix.identifier,c.row,c.col].join(),this.url):this.url;if("REST"===this.requestEncoding.toUpperCase())if(d=this.params,-1!==b.indexOf("{")){b=b.replace(/\{/g, | |
3075 "${");c={style:this.style,Style:this.style,TileMatrixSet:this.matrixSet,TileMatrix:this.matrix.identifier,TileRow:c.row,TileCol:c.col};if(a){var e,f;for(f=a.length-1;0<=f;--f)e=a[f],c[e]=d[e.toUpperCase()]}b=OpenLayers.String.format(b,c)}else{e=this.version+"/"+this.layer+"/"+this.style+"/";if(a)for(f=0;f<a.length;f++)d[a[f]]&&(e=e+d[a[f]]+"/");e=e+this.matrixSet+"/"+this.matrix.identifier+"/"+c.row+"/"+c.col+"."+this.formatSuffix;b.match(/\/$/)||(b+="/");b+=e}else"KVP"===this.requestEncoding.toUpperCase()&& | |
3076 (d={SERVICE:"WMTS",REQUEST:"GetTile",VERSION:this.version,LAYER:this.layer,STYLE:this.style,TILEMATRIXSET:this.matrixSet,TILEMATRIX:this.matrix.identifier,TILEROW:c.row,TILECOL:c.col,FORMAT:this.format},b=OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this,[d]))}return b},mergeNewParams:function(a){if("KVP"===this.requestEncoding.toUpperCase())return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,[OpenLayers.Util.upperCaseObject(a)])},CLASS_NAME:"OpenLayers.Layer.WMTS"});OpenLayers.Protocol.SOS.v1_0_0=OpenLayers.Class(OpenLayers.Protocol,{fois:null,formatOptions:null,initialize:function(a){OpenLayers.Protocol.prototype.initialize.apply(this,[a]);a.format||(this.format=new OpenLayers.Format.SOSGetFeatureOfInterest(this.formatOptions))},destroy:function(){this.options&&!this.options.format&&this.format.destroy();this.format=null;OpenLayers.Protocol.prototype.destroy.apply(this)},read:function(a){a=OpenLayers.Util.extend({},a);OpenLayers.Util.applyDefaults(a,this.options|| | |
3077 {});var b=new OpenLayers.Protocol.Response({requestType:"read"}),c=this.format,c=OpenLayers.Format.XML.prototype.write.apply(c,[c.writeNode("sos:GetFeatureOfInterest",{fois:this.fois})]);b.priv=OpenLayers.Request.POST({url:a.url,callback:this.createCallback(this.handleRead,b,a),data:c});return b},handleRead:function(a,b){if(b.callback){var c=a.priv;200<=c.status&&300>c.status?(a.features=this.parseFeatures(c),a.code=OpenLayers.Protocol.Response.SUCCESS):a.code=OpenLayers.Protocol.Response.FAILURE; | |
3078 b.callback.call(b.scope,a)}},parseFeatures:function(a){var b=a.responseXML;b&&b.documentElement||(b=a.responseText);return!b||0>=b.length?null:this.format.read(b)},CLASS_NAME:"OpenLayers.Protocol.SOS.v1_0_0"});OpenLayers.Layer.KaMapCache=OpenLayers.Class(OpenLayers.Layer.KaMap,{IMAGE_EXTENSIONS:{jpeg:"jpg",gif:"gif",png:"png",png8:"png",png24:"png",dithered:"png"},DEFAULT_FORMAT:"jpeg",initialize:function(a,b,c,d){OpenLayers.Layer.KaMap.prototype.initialize.apply(this,arguments);this.extension=this.IMAGE_EXTENSIONS[this.params.i.toLowerCase()||this.DEFAULT_FORMAT]},getURL:function(a){a=this.adjustBounds(a);var b=this.map.getResolution(),c=Math.round(1E4*this.map.getScale())/1E4,d=Math.round(a.left/b);a= | |
3079 -Math.round(a.top/b);var b=Math.floor(d/this.tileSize.w/this.params.metaTileSize.w)*this.tileSize.w*this.params.metaTileSize.w,e=Math.floor(a/this.tileSize.h/this.params.metaTileSize.h)*this.tileSize.h*this.params.metaTileSize.h,c=["/",this.params.map,"/",c,"/",this.params.g.replace(/\s/g,"_"),"/def/t",e,"/l",b,"/t",a,"l",d,".",this.extension],d=this.url;OpenLayers.Util.isArray(d)&&(d=this.selectUrl(c.join(""),d));return d+c.join("")},CLASS_NAME:"OpenLayers.Layer.KaMapCache"});OpenLayers.Protocol.WFS.v1_1_0=OpenLayers.Class(OpenLayers.Protocol.WFS.v1,{version:"1.1.0",initialize:function(a){OpenLayers.Protocol.WFS.v1.prototype.initialize.apply(this,arguments);this.outputFormat&&!this.readFormat&&("gml2"==this.outputFormat.toLowerCase()?this.readFormat=new OpenLayers.Format.GML.v2({featureType:this.featureType,featureNS:this.featureNS,geometryName:this.geometryName}):"json"==this.outputFormat.toLowerCase()&&(this.readFormat=new OpenLayers.Format.GeoJSON))},CLASS_NAME:"OpenLayers.Protocol.WFS.v1_1_0"});OpenLayers.Format.WMSCapabilities.v1_1_1=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1,{version:"1.1.1",readers:{wms:OpenLayers.Util.applyDefaults({SRS:function(a,b){b.srs[this.getChildValue(a)]=!0}},OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers.wms)},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_1"});OpenLayers.Format.WMSCapabilities.v1_1_1_WMSC=OpenLayers.Class(OpenLayers.Format.WMSCapabilities.v1_1_1,{version:"1.1.1",profile:"WMSC",readers:{wms:OpenLayers.Util.applyDefaults({VendorSpecificCapabilities:function(a,b){b.vendorSpecific={tileSets:[]};this.readChildNodes(a,b.vendorSpecific)},TileSet:function(a,b){var c={srs:{},bbox:{},resolutions:[]};this.readChildNodes(a,c);b.tileSets.push(c)},Resolutions:function(a,b){for(var c=this.getChildValue(a).split(" "),d=0,e=c.length;d<e;d++)""!=c[d]&&b.resolutions.push(parseFloat(c[d]))}, | |
3080 Width:function(a,b){b.width=parseInt(this.getChildValue(a))},Height:function(a,b){b.height=parseInt(this.getChildValue(a))},Layers:function(a,b){b.layers=this.getChildValue(a)},Styles:function(a,b){b.styles=this.getChildValue(a)}},OpenLayers.Format.WMSCapabilities.v1_1_1.prototype.readers.wms)},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1_1_WMSC"});OpenLayers.Control.LayerSwitcher=OpenLayers.Class(OpenLayers.Control,{layerStates:null,layersDiv:null,baseLayersDiv:null,baseLayers:null,dataLbl:null,dataLayersDiv:null,dataLayers:null,minimizeDiv:null,maximizeDiv:null,ascending:!0,initialize:function(a){OpenLayers.Control.prototype.initialize.apply(this,arguments);this.layerStates=[]},destroy:function(){this.clearLayersArray("base");this.clearLayersArray("data");this.map.events.un({buttonclick:this.onButtonClick,addlayer:this.redraw,changelayer:this.redraw, | |
3081 removelayer:this.redraw,changebaselayer:this.redraw,scope:this});this.events.unregister("buttonclick",this,this.onButtonClick);OpenLayers.Control.prototype.destroy.apply(this,arguments)},setMap:function(a){OpenLayers.Control.prototype.setMap.apply(this,arguments);this.map.events.on({addlayer:this.redraw,changelayer:this.redraw,removelayer:this.redraw,changebaselayer:this.redraw,scope:this});this.outsideViewport?(this.events.attachToElement(this.div),this.events.register("buttonclick",this,this.onButtonClick)): | |
3082 this.map.events.register("buttonclick",this,this.onButtonClick)},draw:function(){OpenLayers.Control.prototype.draw.apply(this);this.loadContents();this.outsideViewport||this.minimizeControl();this.redraw();return this.div},onButtonClick:function(a){a=a.buttonElement;a===this.minimizeDiv?this.minimizeControl():a===this.maximizeDiv?this.maximizeControl():a._layerSwitcher===this.id&&(a["for"]&&(a=document.getElementById(a["for"])),a.disabled||("radio"==a.type?(a.checked=!0,this.map.setBaseLayer(this.map.getLayer(a._layer))): | |
3083 (a.checked=!a.checked,this.updateMap())))},clearLayersArray:function(a){this[a+"LayersDiv"].innerHTML="";this[a+"Layers"]=[]},checkRedraw:function(){if(!this.layerStates.length||this.map.layers.length!=this.layerStates.length)return!0;for(var a=0,b=this.layerStates.length;a<b;a++){var c=this.layerStates[a],d=this.map.layers[a];if(c.name!=d.name||c.inRange!=d.inRange||c.id!=d.id||c.visibility!=d.visibility)return!0}return!1},redraw:function(){if(!this.checkRedraw())return this.div;this.clearLayersArray("base"); | |
3084 this.clearLayersArray("data");var a=!1,b=!1,c=this.map.layers.length;this.layerStates=Array(c);for(var d=0;d<c;d++){var e=this.map.layers[d];this.layerStates[d]={name:e.name,visibility:e.visibility,inRange:e.inRange,id:e.id}}var f=this.map.layers.slice();this.ascending||f.reverse();d=0;for(c=f.length;d<c;d++){var e=f[d],g=e.isBaseLayer;if(e.displayInLayerSwitcher){g?b=!0:a=!0;var h=g?e==this.map.baseLayer:e.getVisibility(),k=document.createElement("input"),l=OpenLayers.Util.createUniqueID(this.id+ | |
3085 "_input_");k.id=l;k.name=g?this.id+"_baseLayers":e.name;k.type=g?"radio":"checkbox";k.value=e.name;k.checked=h;k.defaultChecked=h;k.className="olButton";k._layer=e.id;k._layerSwitcher=this.id;g||e.inRange||(k.disabled=!0);h=document.createElement("label");h["for"]=k.id;OpenLayers.Element.addClass(h,"labelSpan olButton");h._layer=e.id;h._layerSwitcher=this.id;g||e.inRange||(h.style.color="gray");h.innerHTML=e.name;h.style.verticalAlign=g?"bottom":"baseline";l=document.createElement("br");(g?this.baseLayers: | |
3086 this.dataLayers).push({layer:e,inputElem:k,labelSpan:h});e=g?this.baseLayersDiv:this.dataLayersDiv;e.appendChild(k);e.appendChild(h);e.appendChild(l)}}this.dataLbl.style.display=a?"":"none";this.baseLbl.style.display=b?"":"none";return this.div},updateMap:function(){for(var a=0,b=this.baseLayers.length;a<b;a++){var c=this.baseLayers[a];c.inputElem.checked&&this.map.setBaseLayer(c.layer,!1)}a=0;for(b=this.dataLayers.length;a<b;a++)c=this.dataLayers[a],c.layer.setVisibility(c.inputElem.checked)},maximizeControl:function(a){this.div.style.width= | |
3087 "";this.div.style.height="";this.showControls(!1);null!=a&&OpenLayers.Event.stop(a)},minimizeControl:function(a){this.div.style.width="0px";this.div.style.height="0px";this.showControls(!0);null!=a&&OpenLayers.Event.stop(a)},showControls:function(a){this.maximizeDiv.style.display=a?"":"none";this.minimizeDiv.style.display=a?"none":"";this.layersDiv.style.display=a?"none":""},loadContents:function(){this.layersDiv=document.createElement("div");this.layersDiv.id=this.id+"_layersDiv";OpenLayers.Element.addClass(this.layersDiv, | |
3088 "layersDiv");this.baseLbl=document.createElement("div");this.baseLbl.innerHTML=OpenLayers.i18n("Base Layer");OpenLayers.Element.addClass(this.baseLbl,"baseLbl");this.baseLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.baseLayersDiv,"baseLayersDiv");this.dataLbl=document.createElement("div");this.dataLbl.innerHTML=OpenLayers.i18n("Overlays");OpenLayers.Element.addClass(this.dataLbl,"dataLbl");this.dataLayersDiv=document.createElement("div");OpenLayers.Element.addClass(this.dataLayersDiv, | |
3089 "dataLayersDiv");this.ascending?(this.layersDiv.appendChild(this.baseLbl),this.layersDiv.appendChild(this.baseLayersDiv),this.layersDiv.appendChild(this.dataLbl),this.layersDiv.appendChild(this.dataLayersDiv)):(this.layersDiv.appendChild(this.dataLbl),this.layersDiv.appendChild(this.dataLayersDiv),this.layersDiv.appendChild(this.baseLbl),this.layersDiv.appendChild(this.baseLayersDiv));this.div.appendChild(this.layersDiv);var a=OpenLayers.Util.getImageLocation("layer-switcher-maximize.png");this.maximizeDiv= | |
3090 OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MaximizeDiv",null,null,a,"absolute");OpenLayers.Element.addClass(this.maximizeDiv,"maximizeDiv olButton");this.maximizeDiv.style.display="none";this.div.appendChild(this.maximizeDiv);a=OpenLayers.Util.getImageLocation("layer-switcher-minimize.png");this.minimizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MinimizeDiv",null,null,a,"absolute");OpenLayers.Element.addClass(this.minimizeDiv,"minimizeDiv olButton");this.minimizeDiv.style.display= | |
3091 "none";this.div.appendChild(this.minimizeDiv)},CLASS_NAME:"OpenLayers.Control.LayerSwitcher"});OpenLayers.Format.Atom=OpenLayers.Class(OpenLayers.Format.XML,{namespaces:{atom:"http://www.w3.org/2005/Atom",georss:"http://www.georss.org/georss"},feedTitle:"untitled",defaultEntryTitle:"untitled",gmlParser:null,xy:!1,read:function(a){"string"==typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));return this.parseFeatures(a)},write:function(a){var b;if(OpenLayers.Util.isArray(a)){b=this.createElementNSPlus("atom:feed");b.appendChild(this.createElementNSPlus("atom:title",{value:this.feedTitle})); | |
3092 for(var c=0,d=a.length;c<d;c++)b.appendChild(this.buildEntryNode(a[c]))}else b=this.buildEntryNode(a);return OpenLayers.Format.XML.prototype.write.apply(this,[b])},buildContentNode:function(a){var b=this.createElementNSPlus("atom:content",{attributes:{type:a.type||null}});if(a.src)b.setAttribute("src",a.src);else if("text"==a.type||null==a.type)b.appendChild(this.createTextNode(a.value));else if("html"==a.type){if("string"!=typeof a.value)throw"HTML content must be in form of an escaped string";b.appendChild(this.createTextNode(a.value))}else"xhtml"== | |
3093 a.type?b.appendChild(a.value):"xhtml"==a.type||a.type.match(/(\+|\/)xml$/)?b.appendChild(a.value):b.appendChild(this.createTextNode(a.value));return b},buildEntryNode:function(a){var b=a.attributes,c=b.atom||{},d=this.createElementNSPlus("atom:entry");if(c.authors)for(var e=OpenLayers.Util.isArray(c.authors)?c.authors:[c.authors],f=0,g=e.length;f<g;f++)d.appendChild(this.buildPersonConstructNode("author",e[f]));if(c.categories)for(var e=OpenLayers.Util.isArray(c.categories)?c.categories:[c.categories], | |
3094 h,f=0,g=e.length;f<g;f++)h=e[f],d.appendChild(this.createElementNSPlus("atom:category",{attributes:{term:h.term,scheme:h.scheme||null,label:h.label||null}}));c.content&&d.appendChild(this.buildContentNode(c.content));if(c.contributors)for(e=OpenLayers.Util.isArray(c.contributors)?c.contributors:[c.contributors],f=0,g=e.length;f<g;f++)d.appendChild(this.buildPersonConstructNode("contributor",e[f]));a.fid&&d.appendChild(this.createElementNSPlus("atom:id",{value:a.fid}));if(c.links)for(e=OpenLayers.Util.isArray(c.links)? | |
3095 c.links:[c.links],f=0,g=e.length;f<g;f++)h=e[f],d.appendChild(this.createElementNSPlus("atom:link",{attributes:{href:h.href,rel:h.rel||null,type:h.type||null,hreflang:h.hreflang||null,title:h.title||null,length:h.length||null}}));c.published&&d.appendChild(this.createElementNSPlus("atom:published",{value:c.published}));c.rights&&d.appendChild(this.createElementNSPlus("atom:rights",{value:c.rights}));(c.summary||b.description)&&d.appendChild(this.createElementNSPlus("atom:summary",{value:c.summary|| | |
3096 b.description}));d.appendChild(this.createElementNSPlus("atom:title",{value:c.title||b.title||this.defaultEntryTitle}));c.updated&&d.appendChild(this.createElementNSPlus("atom:updated",{value:c.updated}));a.geometry&&(b=this.createElementNSPlus("georss:where"),b.appendChild(this.buildGeometryNode(a.geometry)),d.appendChild(b));return d},initGmlParser:function(){this.gmlParser=new OpenLayers.Format.GML.v3({xy:this.xy,featureNS:"http://example.com#feature",internalProjection:this.internalProjection, | |
3097 externalProjection:this.externalProjection})},buildGeometryNode:function(a){this.gmlParser||this.initGmlParser();return this.gmlParser.writeNode("feature:_geometry",a).firstChild},buildPersonConstructNode:function(a,b){var c=["uri","email"],d=this.createElementNSPlus("atom:"+a);d.appendChild(this.createElementNSPlus("atom:name",{value:b.name}));for(var e=0,f=c.length;e<f;e++)b[c[e]]&&d.appendChild(this.createElementNSPlus("atom:"+c[e],{value:b[c[e]]}));return d},getFirstChildValue:function(a,b,c, | |
3098 d){return(a=this.getElementsByTagNameNS(a,b,c))&&0<a.length?this.getChildValue(a[0],d):d},parseFeature:function(a){var b={},c=null,d=null,e=null,f=this.namespaces.atom;this.parsePersonConstructs(a,"author",b);d=this.getElementsByTagNameNS(a,f,"category");0<d.length&&(b.categories=[]);for(var g=0,h=d.length;g<h;g++){c={};c.term=d[g].getAttribute("term");if(e=d[g].getAttribute("scheme"))c.scheme=e;if(e=d[g].getAttribute("label"))c.label=e;b.categories.push(c)}d=this.getElementsByTagNameNS(a,f,"content"); | |
3099 if(0<d.length){c={};if(e=d[0].getAttribute("type"))c.type=e;(e=d[0].getAttribute("src"))?c.src=e:("text"==c.type||"html"==c.type||null==c.type?c.value=this.getFirstChildValue(a,f,"content",null):"xhtml"==c.type||c.type.match(/(\+|\/)xml$/)?c.value=this.getChildEl(d[0]):c.value=this.getFirstChildValue(a,f,"content",null),b.content=c)}this.parsePersonConstructs(a,"contributor",b);b.id=this.getFirstChildValue(a,f,"id",null);d=this.getElementsByTagNameNS(a,f,"link");0<d.length&&(b.links=Array(d.length)); | |
3100 for(var k=["rel","type","hreflang","title","length"],g=0,h=d.length;g<h;g++){c={};c.href=d[g].getAttribute("href");for(var l=0,m=k.length;l<m;l++)(e=d[g].getAttribute(k[l]))&&(c[k[l]]=e);b.links[g]=c}if(c=this.getFirstChildValue(a,f,"published",null))b.published=c;if(c=this.getFirstChildValue(a,f,"rights",null))b.rights=c;if(c=this.getFirstChildValue(a,f,"summary",null))b.summary=c;b.title=this.getFirstChildValue(a,f,"title",null);b.updated=this.getFirstChildValue(a,f,"updated",null);c={title:b.title, | |
3101 description:b.summary,atom:b};a=this.parseLocations(a)[0];a=new OpenLayers.Feature.Vector(a,c);a.fid=b.id;return a},parseFeatures:function(a){var b=[],c=this.getElementsByTagNameNS(a,this.namespaces.atom,"entry");0==c.length&&(c=[a]);a=0;for(var d=c.length;a<d;a++)b.push(this.parseFeature(c[a]));return b},parseLocations:function(a){var b=this.namespaces.georss,c={components:[]},d=this.getElementsByTagNameNS(a,b,"where");if(d&&0<d.length){this.gmlParser||this.initGmlParser();for(var e=0,f=d.length;e< | |
3102 f;e++)this.gmlParser.readChildNodes(d[e],c)}c=c.components;if((d=this.getElementsByTagNameNS(a,b,"point"))&&0<d.length)for(e=0,f=d.length;e<f;e++){var g=OpenLayers.String.trim(d[e].firstChild.nodeValue).split(/\s+/);2!=g.length&&(g=OpenLayers.String.trim(d[e].firstChild.nodeValue).split(/\s*,\s*/));c.push(new OpenLayers.Geometry.Point(g[1],g[0]))}var h=this.getElementsByTagNameNS(a,b,"line");if(h&&0<h.length)for(var k,e=0,f=h.length;e<f;e++){d=OpenLayers.String.trim(h[e].firstChild.nodeValue).split(/\s+/); | |
3103 k=[];for(var l=0,m=d.length;l<m;l+=2)g=new OpenLayers.Geometry.Point(d[l+1],d[l]),k.push(g);c.push(new OpenLayers.Geometry.LineString(k))}if((a=this.getElementsByTagNameNS(a,b,"polygon"))&&0<a.length)for(e=0,f=a.length;e<f;e++){d=OpenLayers.String.trim(a[e].firstChild.nodeValue).split(/\s+/);k=[];l=0;for(m=d.length;l<m;l+=2)g=new OpenLayers.Geometry.Point(d[l+1],d[l]),k.push(g);c.push(new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(k)]))}if(this.internalProjection&&this.externalProjection)for(e= | |
3104 0,f=c.length;e<f;e++)c[e]&&c[e].transform(this.externalProjection,this.internalProjection);return c},parsePersonConstructs:function(a,b,c){var d=[],e=this.namespaces.atom;a=this.getElementsByTagNameNS(a,e,b);for(var f=["uri","email"],g=0,h=a.length;g<h;g++){var k={};k.name=this.getFirstChildValue(a[g],e,"name",null);for(var l=0,m=f.length;l<m;l++){var n=this.getFirstChildValue(a[g],e,f[l],null);n&&(k[f[l]]=n)}d.push(k)}0<d.length&&(c[b+"s"]=d)},CLASS_NAME:"OpenLayers.Format.Atom"});OpenLayers.Control.KeyboardDefaults=OpenLayers.Class(OpenLayers.Control,{autoActivate:!0,slideFactor:75,observeElement:null,draw:function(){this.handler=new OpenLayers.Handler.Keyboard(this,{keydown:this.defaultKeyPress},{observeElement:this.observeElement||document})},defaultKeyPress:function(a){var b,c=!0;b=OpenLayers.Event.element(a);if(!b||"INPUT"!=b.tagName&&"TEXTAREA"!=b.tagName&&"SELECT"!=b.tagName){switch(a.keyCode){case OpenLayers.Event.KEY_LEFT:this.map.pan(-this.slideFactor,0);break;case OpenLayers.Event.KEY_RIGHT:this.map.pan(this.slideFactor, | |
3105 0);break;case OpenLayers.Event.KEY_UP:this.map.pan(0,-this.slideFactor);break;case OpenLayers.Event.KEY_DOWN:this.map.pan(0,this.slideFactor);break;case 33:b=this.map.getSize();this.map.pan(0,-0.75*b.h);break;case 34:b=this.map.getSize();this.map.pan(0,0.75*b.h);break;case 35:b=this.map.getSize();this.map.pan(0.75*b.w,0);break;case 36:b=this.map.getSize();this.map.pan(-0.75*b.w,0);break;case 43:case 61:case 187:case 107:this.map.zoomIn();break;case 45:case 109:case 189:case 95:this.map.zoomOut(); | |
3106 break;default:c=!1}c&&OpenLayers.Event.stop(a)}},CLASS_NAME:"OpenLayers.Control.KeyboardDefaults"});OpenLayers.Format.WMTSCapabilities.v1_0_0=OpenLayers.Class(OpenLayers.Format.OWSCommon.v1_1_0,{version:"1.0.0",namespaces:{ows:"http://www.opengis.net/ows/1.1",wmts:"http://www.opengis.net/wmts/1.0",xlink:"http://www.w3.org/1999/xlink"},yx:null,defaultPrefix:"wmts",initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a]);this.options=a;a=OpenLayers.Util.extend({},OpenLayers.Format.WMTSCapabilities.prototype.yx);this.yx=OpenLayers.Util.extend(a,this.yx)},read:function(a){"string"== | |
3107 typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));a&&9==a.nodeType&&(a=a.documentElement);var b={};this.readNode(a,b);b.version=this.version;return b},readers:{wmts:{Capabilities:function(a,b){this.readChildNodes(a,b)},Contents:function(a,b){b.contents={};b.contents.layers=[];b.contents.tileMatrixSets={};this.readChildNodes(a,b.contents)},Layer:function(a,b){var c={styles:[],formats:[],dimensions:[],tileMatrixSetLinks:[],layers:[]};this.readChildNodes(a,c);b.layers.push(c)},Style:function(a, | |
3108 b){var c={};c.isDefault="true"===a.getAttribute("isDefault");this.readChildNodes(a,c);b.styles.push(c)},Format:function(a,b){b.formats.push(this.getChildValue(a))},TileMatrixSetLink:function(a,b){var c={};this.readChildNodes(a,c);b.tileMatrixSetLinks.push(c)},TileMatrixSet:function(a,b){if(b.layers){var c={matrixIds:[]};this.readChildNodes(a,c);b.tileMatrixSets[c.identifier]=c}else b.tileMatrixSet=this.getChildValue(a)},TileMatrix:function(a,b){var c={supportedCRS:b.supportedCRS};this.readChildNodes(a, | |
3109 c);b.matrixIds.push(c)},ScaleDenominator:function(a,b){b.scaleDenominator=parseFloat(this.getChildValue(a))},TopLeftCorner:function(a,b){var c=this.getChildValue(a).split(" "),d;b.supportedCRS&&(d=b.supportedCRS.replace(/urn:ogc:def:crs:(\w+):.+:(\w+)$/,"urn:ogc:def:crs:$1::$2"),d=!!this.yx[d]);b.topLeftCorner=d?new OpenLayers.LonLat(c[1],c[0]):new OpenLayers.LonLat(c[0],c[1])},TileWidth:function(a,b){b.tileWidth=parseInt(this.getChildValue(a))},TileHeight:function(a,b){b.tileHeight=parseInt(this.getChildValue(a))}, | |
3110 MatrixWidth:function(a,b){b.matrixWidth=parseInt(this.getChildValue(a))},MatrixHeight:function(a,b){b.matrixHeight=parseInt(this.getChildValue(a))},ResourceURL:function(a,b){b.resourceUrl=b.resourceUrl||{};var c=a.getAttribute("resourceType");b.resourceUrls||(b.resourceUrls=[]);c=b.resourceUrl[c]={format:a.getAttribute("format"),template:a.getAttribute("template"),resourceType:c};b.resourceUrls.push(c)},WSDL:function(a,b){b.wsdl={};b.wsdl.href=a.getAttribute("xlink:href")},ServiceMetadataURL:function(a, | |
3111 b){b.serviceMetadataUrl={};b.serviceMetadataUrl.href=a.getAttribute("xlink:href")},LegendURL:function(a,b){b.legend={};b.legend.href=a.getAttribute("xlink:href");b.legend.format=a.getAttribute("format")},Dimension:function(a,b){var c={values:[]};this.readChildNodes(a,c);b.dimensions.push(c)},Default:function(a,b){b["default"]=this.getChildValue(a)},Value:function(a,b){b.values.push(this.getChildValue(a))}},ows:OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows},CLASS_NAME:"OpenLayers.Format.WMTSCapabilities.v1_0_0"}); | |
3112 (function(h){h.deparam=function(i,j){var d={},k={"true":!0,"false":!1,"null":null};h.each(i.replace(/\+/g," ").split("&"),function(i,l){var m;var a=l.split("="),c=decodeURIComponent(a[0]),g=d,f=0,b=c.split("]["),e=b.length-1;/\[/.test(b[0])&&/\]$/.test(b[e])?(b[e]=b[e].replace(/\]$/,""),b=b.shift().split("[").concat(b),e=b.length-1):e=0;if(2===a.length)if(a=decodeURIComponent(a[1]),j&&(a=a&&!isNaN(a)?+a:"undefined"===a?void 0:void 0!==k[a]?k[a]:a),e)for(;f<=e;f++)c=""===b[f]?g.length:b[f],m=g[c]= | |
3113 f<e?g[c]||(b[f+1]&&isNaN(b[f+1])?{}:[]):a,g=m;else h.isArray(d[c])?d[c].push(a):d[c]=void 0!==d[c]?[d[c],a]:a;else c&&(d[c]=j?void 0:"")});return d}})(jQuery); | |
3114 /*! | |
3115 * | |
3116 * jQuery Remember Plugin | |
3117 * Version 0.1.1 | |
3118 * | |
3119 * Copyright Nick Dreckshage, licensed GPL & MIT | |
3120 * https://github.com/ndreckshage/jquery-remember | |
3121 * | |
3122 * A fork of jQuery Cookie Plugin | |
3123 * https://github.com/carhartl/jquery-cookie | |
3124 * Copyright Klaus Hartl | |
3125 * Released under the MIT licensed | |
3126 * | |
3127 */ | |
3128 | |
3129 (function($){ | |
3130 | |
3131 // recommend changing to return function(options) { if using require.js... | |
3132 $.remember = function(options){ | |
3133 var settings, | |
3134 remember, | |
3135 controller; | |
3136 | |
3137 settings = $.extend({ | |
3138 name: null, // name/key of the cookie/localstorage item | |
3139 value: undefined, // value pair of cookie/localstorage | |
3140 getSet: false, // if true, will get if available, set if not. default is to just get OR set | |
3141 remove: false, // if true, will remove based on name/key | |
3142 use: 'default', // whether to use localstorage or cookies. default localstorage with cookie fallback. | |
3143 expires: null, // forces cookie (invalid localstorage attribue). | |
3144 path: null, // forces cookie. | |
3145 domain: null, // forces cookie. | |
3146 secure: null, // forces cookie. | |
3147 json: false, // will convert to json when set. parse with get. | |
3148 fallback: true, // whether to fallback to cookies if localstorage not available. | |
3149 raw: false, // if true, will skip uri encoding/decoding | |
3150 modernizr: false // set true if youd rather handle localstorage detection through modernizr | |
3151 }, options); | |
3152 | |
3153 remember = { | |
3154 init: function(){ | |
3155 var controller; | |
3156 | |
3157 // controls what to do with the input. set - get - set/get - erase | |
3158 // set if name exists, value exists, and not set to remove cookie. | |
3159 // get if name exists, value does not exist, and not set to remove | |
3160 // remove if remove set to true | |
3161 if (settings.name !== null && settings.value !== undefined && settings.remove !== true){ | |
3162 if (settings.getSet === true){ | |
3163 var get = this.get(); | |
3164 // if the value of get exists, return it. otherwise, set the value as specified. | |
3165 if (get === null){ | |
3166 this.set(); | |
3167 } else { | |
3168 controller = get; | |
3169 } | |
3170 } else { | |
3171 this.set(); | |
3172 } | |
3173 } else if (settings.name !== null && settings.value === undefined && settings.remove !== true){ | |
3174 controller = this.get(); | |
3175 } else if (settings.name !== null && settings.remove === true){ | |
3176 this.erase(); | |
3177 } | |
3178 | |
3179 // will return result of everything to calling js | |
3180 return controller; | |
3181 }, | |
3182 get: function(){ | |
3183 var use = this._use(), | |
3184 value = null, | |
3185 cookies, | |
3186 parts, | |
3187 name; | |
3188 | |
3189 // grab the key value pair from localstorage | |
3190 if (use === 'localstorage') { | |
3191 value = localStorage.getItem(settings.name); | |
3192 } | |
3193 | |
3194 // hit if cookie requested, and when double checking a get on an empty localstorage item | |
3195 if ((use === 'cookie') || (use === 'localstorage' && value === null && settings.fallback !== false)) { | |
3196 | |
3197 // grab all the cookies from the browser, check if set, and loop through | |
3198 cookies = document.cookie ? document.cookie : null; | |
3199 if (cookies !== null){ | |
3200 cookies = cookies.split(';'); | |
3201 for (var i = 0; i < cookies.length; i++){ | |
3202 // separate the key value pair | |
3203 parts = cookies[i].split('='); | |
3204 // set name and value to split parts, cleaning up whitespace | |
3205 name = parts.shift(); | |
3206 name = settings.raw === false ? this._trim(this._decode(name)) : this._trim(name); | |
3207 value = parts[0]; | |
3208 // break when we hit a match, or cookie is empty | |
3209 if (settings.name === name) { | |
3210 break; | |
3211 } else if (settings.fallback !== false) { | |
3212 value = localStorage.getItem(settings.name) || null; | |
3213 } else { | |
3214 value = null; | |
3215 } | |
3216 } | |
3217 } | |
3218 } | |
3219 | |
3220 // decode uri and if json is requested, parse the cookie/localstorage and return to controller | |
3221 value = (value && settings.raw === false) ? this._decode(value) : value; | |
3222 value = (value && settings.json === true) ? JSON.parse(value) : value; | |
3223 | |
3224 return value; | |
3225 }, | |
3226 set: function(){ | |
3227 var use = this._use(); | |
3228 | |
3229 // if set is hit, user has intentionally tried to set (get/set not hit) | |
3230 // clear the storage alternative, so the same value isnt stored in both | |
3231 this.erase(); | |
3232 | |
3233 // convert the value to store in json if requested | |
3234 settings.value = settings.json === true ? JSON.stringify(settings.value) : settings.value; | |
3235 | |
3236 // encode | |
3237 settings.name = settings.raw === false ? encodeURIComponent(settings.name) : settings.name; | |
3238 settings.value = settings.raw === false ? encodeURIComponent(settings.value) : settings.value; | |
3239 | |
3240 // store the key value pair in appropriate storage. set unless storage requirements failed | |
3241 if (use === 'localstorage'){ | |
3242 localStorage.setItem(settings.name, settings.value); | |
3243 } else if (use !== false){ | |
3244 // convert values that cant be stored and set | |
3245 settings.value = settings.value === null ? 'null' : settings.value; | |
3246 this._setCookie(); | |
3247 } | |
3248 }, | |
3249 erase: function(){ | |
3250 var use = this._use(); | |
3251 | |
3252 // clear localstorage and cookies by setting expiration to negative | |
3253 if (use !== 'cookie' || settings.fallback !== false){ | |
3254 localStorage.removeItem(settings.name); | |
3255 } | |
3256 if (use !== 'localstorage' || settings.fallback !== false){ | |
3257 this._setCookie('', -1); | |
3258 } | |
3259 }, | |
3260 _use: function(){ | |
3261 var use, | |
3262 localStorageSupport = this._localStorage(); | |
3263 | |
3264 // if cookie requested, or any options set that only apply to cookies | |
3265 if (settings.use === 'cookie' || settings.expires !== null || settings.path !== null || settings.domain !== null || settings.secure !== null){ | |
3266 use = 'cookie'; | |
3267 } else { | |
3268 // use local storage if available | |
3269 if (localStorageSupport){ | |
3270 use = 'localstorage'; | |
3271 } else if (settings.fallback !== false) { | |
3272 // default to cookie, unless fallback banned | |
3273 use = 'cookie'; | |
3274 } else { | |
3275 // if all this fails, nothing can be set | |
3276 use = false; | |
3277 } | |
3278 } | |
3279 | |
3280 return use; | |
3281 }, | |
3282 _setCookie: function(){ | |
3283 // allow for varying parameters with defaults. value then expires as optional params | |
3284 var value = arguments.length > 0 ? arguments[0] : settings.value, | |
3285 expires = arguments.length > 1 ? arguments[1] : settings.expires, | |
3286 expire; | |
3287 | |
3288 // set a date in the future (or negative to delete) based on expires date offset | |
3289 if (typeof expires === 'number') { | |
3290 expire = new Date(); | |
3291 expire.setDate(expire.getDate() + expires); | |
3292 } | |
3293 | |
3294 // set the cookies with all the varying settings | |
3295 document.cookie = [ | |
3296 settings.name, | |
3297 '=', | |
3298 value, | |
3299 expire ? '; expires=' + expire.toUTCString() : '', | |
3300 settings.path ? '; path=' + settings.path : '', | |
3301 settings.domain ? '; domain=' + settings.domain : '', | |
3302 settings.secure ? '; secure' : '' | |
3303 ].join(''); | |
3304 }, | |
3305 _localStorage: function(){ | |
3306 if (settings.modernizr === true && typeof Modernizr !== 'undefined'){ | |
3307 return Modernizr.localstorage; | |
3308 } else { | |
3309 // check if a browser supports localstorage with simple try catch | |
3310 try { | |
3311 localStorage.setItem('jquery-remember-test','jquery-remember-test'); | |
3312 localStorage.removeItem('jquery-remember-test'); | |
3313 return true; | |
3314 } catch(e){ | |
3315 return false; | |
3316 } | |
3317 } | |
3318 }, | |
3319 _trim: function(s){ | |
3320 // trail a strings leading/ending whitespace | |
3321 return s.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); | |
3322 }, | |
3323 _decode: function(s){ | |
3324 return decodeURIComponent(s.replace(/\+/g, ' ')); | |
3325 } | |
3326 }; | |
3327 | |
3328 return remember.init(); | |
3329 }; | |
3330 | |
3331 return $.remember; | |
3332 | |
3333 }(jQuery)); | |
3334 (function(a){if(typeof define==="function"&&define.amd){if(typeof jQuery!=="undefined"){define(["jquery"],a)}else{define([],a)}}else{if(typeof jQuery!=="undefined"){a(jQuery)}else{a()}}})(function(b,e){var q={a:"href",img:"src",form:"action",base:"href",script:"src",iframe:"src",link:"href"},t=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","fragment"],p={anchor:"fragment"},a={strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/},s=/^[0-9]+$/;function o(u,x){var z=decodeURI(u),w=a[x||false?"strict":"loose"].exec(z),y={attr:{},param:{},seg:{}},v=14;while(v--){y.attr[t[v]]=w[v]||""}y.param.query=f(y.attr.query);y.param.fragment=f(y.attr.fragment);y.seg.path=y.attr.path.replace(/^\/+|\/+$/g,"").split("/");y.seg.fragment=y.attr.fragment.replace(/^\/+|\/+$/g,"").split("/");y.attr.base=y.attr.host?(y.attr.protocol?y.attr.protocol+"://"+y.attr.host:y.attr.host)+(y.attr.port?":"+y.attr.port:""):"";return y}function m(v){var u=v.tagName;if(typeof u!=="undefined"){return q[u.toLowerCase()]}return u}function c(x,w){if(x[w].length===0){return x[w]={}}var v={};for(var u in x[w]){v[u]=x[w][u]}x[w]=v;return v}function l(y,w,v,z){var u=y.shift();if(!u){if(g(w[v])){w[v].push(z)}else{if("object"==typeof w[v]){w[v]=z}else{if("undefined"==typeof w[v]){w[v]=z}else{w[v]=[w[v],z]}}}}else{var x=w[v]=w[v]||[];if("]"==u){if(g(x)){if(""!=z){x.push(z)}}else{if("object"==typeof x){x[j(x).length]=z}else{x=w[v]=[w[v],z]}}}else{if(~u.indexOf("]")){u=u.substr(0,u.length-1);if(!s.test(u)&&g(x)){x=c(w,v)}l(y,x,u,z)}else{if(!s.test(u)&&g(x)){x=c(w,v)}l(y,x,u,z)}}}}function d(x,w,z){if(~w.indexOf("]")){var y=w.split("[");l(y,x,"base",z)}else{if(!s.test(w)&&g(x.base)){var v={};for(var u in x.base){v[u]=x.base[u]}x.base=v}i(x.base,w,z)}return x}function f(u){if(u==""){return{}}return h(String(u).split(/&|;/),function(v,A){try{A=decodeURIComponent(A.replace(/\+/g," "))}catch(x){}var B=A.indexOf("="),z=n(A),w=A.substr(0,z||B),y=A.substr(z||B,A.length),y=y.substr(y.indexOf("=")+1,y.length);if(""==w){w=A,y=""}return d(v,w,y)},{base:{}}).base}function i(x,w,y){var u=x[w];if(e===u){x[w]=y}else{if(g(u)){u.push(y)}else{x[w]=[u,y]}}}function n(x){var u=x.length,w,y;for(var v=0;v<u;++v){y=x[v];if("]"==y){w=false}if("["==y){w=true}if("="==y&&!w){return v}}}function h(y,v){var w=0,u=y.length>>0,x=arguments[2];while(w<u){if(w in y){x=v.call(e,x,y[w],w,y)}++w}return x}function g(u){return Object.prototype.toString.call(u)==="[object Array]"}function j(v){var u=[];for(prop in v){if(v.hasOwnProperty(prop)){u.push(prop)}}return u}function k(u){return Object(u)===u&&Object.getPrototypeOf(u)===Object.prototype}function r(u,v){if(arguments.length===1&&u===true){v=true;u=e}v=v||false;u=u||window.location.toString();return{data:o(u,v),attr:function(w){w=p[w]||w;return typeof w!=="undefined"?this.data.attr[w]:this.data.attr},param:function(x,w){if(k(x)){this.data.param.query=x;return this}else{if(w==e){return typeof x!=="undefined"?this.data.param.query[x]:this.data.param.query}else{this.data.param.query[x]=w;return this}}},removeParam:function(w){delete this.data.param.query[w]},fparam:function(w){return typeof w!=="undefined"?this.data.param.fragment[w]:this.data.param.fragment},segment:function(w){if(typeof w==="undefined"){return this.data.seg.path}else{w=w<0?this.data.seg.path.length+w:w-1;return this.data.seg.path[w]}},fsegment:function(w){if(typeof w==="undefined"){return this.data.seg.fragment}else{w=w<0?this.data.seg.fragment.length+w:w-1;return this.data.seg.fragment[w]}},toString:function(){var w="";if(this.data.attr.host!==""){w+=this.data.attr.protocol+"://"+this.data.attr.host}if(this.data.attr.port!=="80"){w+=":"+this.data.attr.port}w+=this.data.attr.path;Object.keys=Object.keys||function(C){var A=[];for(var B in C){if(C.hasOwnProperty(B)){A.push(B)}}return A};if(Object.keys(this.data.param.query).length>0){w+="?";var x=[];for(var y in this.data.param.query){x.push(encodeURIComponent(y)+"="+encodeURIComponent(this.data.param.query[y]))}w+=x.join("&")}if(Object.keys(this.data.param.fragment).length>0){w+="#";var z=[];for(var y in this.data.param.fragment){if(this.data.param.fragment[y]===""){z.push(y)}else{z.push(y+"="+this.data.param.fragment[y])}}w+=z.join("&")}return w}}}if(typeof b!=="undefined"){b.fn.url=function(v){var u="";if(this.length){u=b(this).attr(m(this[0]))||""}return r(u,v)};b.url=r}else{window.purl=r}}); | |
3335 /*! jQuery UI - v1.10.3 - 2013-05-29 | |
3336 * http://jqueryui.com | |
3337 * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js | |
3338 * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ | |
3339 | |
3340 (function( $, undefined ) { | |
3341 | |
3342 var uuid = 0, | |
3343 runiqueId = /^ui-id-\d+$/; | |
3344 | |
3345 // $.ui might exist from components with no dependencies, e.g., $.ui.position | |
3346 $.ui = $.ui || {}; | |
3347 | |
3348 $.extend( $.ui, { | |
3349 version: "1.10.3", | |
3350 | |
3351 keyCode: { | |
3352 BACKSPACE: 8, | |
3353 COMMA: 188, | |
3354 DELETE: 46, | |
3355 DOWN: 40, | |
3356 END: 35, | |
3357 ENTER: 13, | |
3358 ESCAPE: 27, | |
3359 HOME: 36, | |
3360 LEFT: 37, | |
3361 NUMPAD_ADD: 107, | |
3362 NUMPAD_DECIMAL: 110, | |
3363 NUMPAD_DIVIDE: 111, | |
3364 NUMPAD_ENTER: 108, | |
3365 NUMPAD_MULTIPLY: 106, | |
3366 NUMPAD_SUBTRACT: 109, | |
3367 PAGE_DOWN: 34, | |
3368 PAGE_UP: 33, | |
3369 PERIOD: 190, | |
3370 RIGHT: 39, | |
3371 SPACE: 32, | |
3372 TAB: 9, | |
3373 UP: 38 | |
3374 } | |
3375 }); | |
3376 | |
3377 // plugins | |
3378 $.fn.extend({ | |
3379 focus: (function( orig ) { | |
3380 return function( delay, fn ) { | |
3381 return typeof delay === "number" ? | |
3382 this.each(function() { | |
3383 var elem = this; | |
3384 setTimeout(function() { | |
3385 $( elem ).focus(); | |
3386 if ( fn ) { | |
3387 fn.call( elem ); | |
3388 } | |
3389 }, delay ); | |
3390 }) : | |
3391 orig.apply( this, arguments ); | |
3392 }; | |
3393 })( $.fn.focus ), | |
3394 | |
3395 scrollParent: function() { | |
3396 var scrollParent; | |
3397 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { | |
3398 scrollParent = this.parents().filter(function() { | |
3399 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); | |
3400 }).eq(0); | |
3401 } else { | |
3402 scrollParent = this.parents().filter(function() { | |
3403 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); | |
3404 }).eq(0); | |
3405 } | |
3406 | |
3407 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; | |
3408 }, | |
3409 | |
3410 zIndex: function( zIndex ) { | |
3411 if ( zIndex !== undefined ) { | |
3412 return this.css( "zIndex", zIndex ); | |
3413 } | |
3414 | |
3415 if ( this.length ) { | |
3416 var elem = $( this[ 0 ] ), position, value; | |
3417 while ( elem.length && elem[ 0 ] !== document ) { | |
3418 // Ignore z-index if position is set to a value where z-index is ignored by the browser | |
3419 // This makes behavior of this function consistent across browsers | |
3420 // WebKit always returns auto if the element is positioned | |
3421 position = elem.css( "position" ); | |
3422 if ( position === "absolute" || position === "relative" || position === "fixed" ) { | |
3423 // IE returns 0 when zIndex is not specified | |
3424 // other browsers return a string | |
3425 // we ignore the case of nested elements with an explicit value of 0 | |
3426 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> | |
3427 value = parseInt( elem.css( "zIndex" ), 10 ); | |
3428 if ( !isNaN( value ) && value !== 0 ) { | |
3429 return value; | |
3430 } | |
3431 } | |
3432 elem = elem.parent(); | |
3433 } | |
3434 } | |
3435 | |
3436 return 0; | |
3437 }, | |
3438 | |
3439 uniqueId: function() { | |
3440 return this.each(function() { | |
3441 if ( !this.id ) { | |
3442 this.id = "ui-id-" + (++uuid); | |
3443 } | |
3444 }); | |
3445 }, | |
3446 | |
3447 removeUniqueId: function() { | |
3448 return this.each(function() { | |
3449 if ( runiqueId.test( this.id ) ) { | |
3450 $( this ).removeAttr( "id" ); | |
3451 } | |
3452 }); | |
3453 } | |
3454 }); | |
3455 | |
3456 // selectors | |
3457 function focusable( element, isTabIndexNotNaN ) { | |
3458 var map, mapName, img, | |
3459 nodeName = element.nodeName.toLowerCase(); | |
3460 if ( "area" === nodeName ) { | |
3461 map = element.parentNode; | |
3462 mapName = map.name; | |
3463 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { | |
3464 return false; | |
3465 } | |
3466 img = $( "img[usemap=#" + mapName + "]" )[0]; | |
3467 return !!img && visible( img ); | |
3468 } | |
3469 return ( /input|select|textarea|button|object/.test( nodeName ) ? | |
3470 !element.disabled : | |
3471 "a" === nodeName ? | |
3472 element.href || isTabIndexNotNaN : | |
3473 isTabIndexNotNaN) && | |
3474 // the element and all of its ancestors must be visible | |
3475 visible( element ); | |
3476 } | |
3477 | |
3478 function visible( element ) { | |
3479 return $.expr.filters.visible( element ) && | |
3480 !$( element ).parents().addBack().filter(function() { | |
3481 return $.css( this, "visibility" ) === "hidden"; | |
3482 }).length; | |
3483 } | |
3484 | |
3485 $.extend( $.expr[ ":" ], { | |
3486 data: $.expr.createPseudo ? | |
3487 $.expr.createPseudo(function( dataName ) { | |
3488 return function( elem ) { | |
3489 return !!$.data( elem, dataName ); | |
3490 }; | |
3491 }) : | |
3492 // support: jQuery <1.8 | |
3493 function( elem, i, match ) { | |
3494 return !!$.data( elem, match[ 3 ] ); | |
3495 }, | |
3496 | |
3497 focusable: function( element ) { | |
3498 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); | |
3499 }, | |
3500 | |
3501 tabbable: function( element ) { | |
3502 var tabIndex = $.attr( element, "tabindex" ), | |
3503 isTabIndexNaN = isNaN( tabIndex ); | |
3504 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); | |
3505 } | |
3506 }); | |
3507 | |
3508 // support: jQuery <1.8 | |
3509 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { | |
3510 $.each( [ "Width", "Height" ], function( i, name ) { | |
3511 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], | |
3512 type = name.toLowerCase(), | |
3513 orig = { | |
3514 innerWidth: $.fn.innerWidth, | |
3515 innerHeight: $.fn.innerHeight, | |
3516 outerWidth: $.fn.outerWidth, | |
3517 outerHeight: $.fn.outerHeight | |
3518 }; | |
3519 | |
3520 function reduce( elem, size, border, margin ) { | |
3521 $.each( side, function() { | |
3522 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; | |
3523 if ( border ) { | |
3524 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; | |
3525 } | |
3526 if ( margin ) { | |
3527 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; | |
3528 } | |
3529 }); | |
3530 return size; | |
3531 } | |
3532 | |
3533 $.fn[ "inner" + name ] = function( size ) { | |
3534 if ( size === undefined ) { | |
3535 return orig[ "inner" + name ].call( this ); | |
3536 } | |
3537 | |
3538 return this.each(function() { | |
3539 $( this ).css( type, reduce( this, size ) + "px" ); | |
3540 }); | |
3541 }; | |
3542 | |
3543 $.fn[ "outer" + name] = function( size, margin ) { | |
3544 if ( typeof size !== "number" ) { | |
3545 return orig[ "outer" + name ].call( this, size ); | |
3546 } | |
3547 | |
3548 return this.each(function() { | |
3549 $( this).css( type, reduce( this, size, true, margin ) + "px" ); | |
3550 }); | |
3551 }; | |
3552 }); | |
3553 } | |
3554 | |
3555 // support: jQuery <1.8 | |
3556 if ( !$.fn.addBack ) { | |
3557 $.fn.addBack = function( selector ) { | |
3558 return this.add( selector == null ? | |
3559 this.prevObject : this.prevObject.filter( selector ) | |
3560 ); | |
3561 }; | |
3562 } | |
3563 | |
3564 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) | |
3565 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { | |
3566 $.fn.removeData = (function( removeData ) { | |
3567 return function( key ) { | |
3568 if ( arguments.length ) { | |
3569 return removeData.call( this, $.camelCase( key ) ); | |
3570 } else { | |
3571 return removeData.call( this ); | |
3572 } | |
3573 }; | |
3574 })( $.fn.removeData ); | |
3575 } | |
3576 | |
3577 | |
3578 | |
3579 | |
3580 | |
3581 // deprecated | |
3582 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); | |
3583 | |
3584 $.support.selectstart = "onselectstart" in document.createElement( "div" ); | |
3585 $.fn.extend({ | |
3586 disableSelection: function() { | |
3587 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + | |
3588 ".ui-disableSelection", function( event ) { | |
3589 event.preventDefault(); | |
3590 }); | |
3591 }, | |
3592 | |
3593 enableSelection: function() { | |
3594 return this.unbind( ".ui-disableSelection" ); | |
3595 } | |
3596 }); | |
3597 | |
3598 $.extend( $.ui, { | |
3599 // $.ui.plugin is deprecated. Use $.widget() extensions instead. | |
3600 plugin: { | |
3601 add: function( module, option, set ) { | |
3602 var i, | |
3603 proto = $.ui[ module ].prototype; | |
3604 for ( i in set ) { | |
3605 proto.plugins[ i ] = proto.plugins[ i ] || []; | |
3606 proto.plugins[ i ].push( [ option, set[ i ] ] ); | |
3607 } | |
3608 }, | |
3609 call: function( instance, name, args ) { | |
3610 var i, | |
3611 set = instance.plugins[ name ]; | |
3612 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { | |
3613 return; | |
3614 } | |
3615 | |
3616 for ( i = 0; i < set.length; i++ ) { | |
3617 if ( instance.options[ set[ i ][ 0 ] ] ) { | |
3618 set[ i ][ 1 ].apply( instance.element, args ); | |
3619 } | |
3620 } | |
3621 } | |
3622 }, | |
3623 | |
3624 // only used by resizable | |
3625 hasScroll: function( el, a ) { | |
3626 | |
3627 //If overflow is hidden, the element might have extra content, but the user wants to hide it | |
3628 if ( $( el ).css( "overflow" ) === "hidden") { | |
3629 return false; | |
3630 } | |
3631 | |
3632 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", | |
3633 has = false; | |
3634 | |
3635 if ( el[ scroll ] > 0 ) { | |
3636 return true; | |
3637 } | |
3638 | |
3639 // TODO: determine which cases actually cause this to happen | |
3640 // if the element doesn't have the scroll set, see if it's possible to | |
3641 // set the scroll | |
3642 el[ scroll ] = 1; | |
3643 has = ( el[ scroll ] > 0 ); | |
3644 el[ scroll ] = 0; | |
3645 return has; | |
3646 } | |
3647 }); | |
3648 | |
3649 })( jQuery ); | |
3650 (function( $, undefined ) { | |
3651 | |
3652 var uuid = 0, | |
3653 slice = Array.prototype.slice, | |
3654 _cleanData = $.cleanData; | |
3655 $.cleanData = function( elems ) { | |
3656 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
3657 try { | |
3658 $( elem ).triggerHandler( "remove" ); | |
3659 // http://bugs.jquery.com/ticket/8235 | |
3660 } catch( e ) {} | |
3661 } | |
3662 _cleanData( elems ); | |
3663 }; | |
3664 | |
3665 $.widget = function( name, base, prototype ) { | |
3666 var fullName, existingConstructor, constructor, basePrototype, | |
3667 // proxiedPrototype allows the provided prototype to remain unmodified | |
3668 // so that it can be used as a mixin for multiple widgets (#8876) | |
3669 proxiedPrototype = {}, | |
3670 namespace = name.split( "." )[ 0 ]; | |
3671 | |
3672 name = name.split( "." )[ 1 ]; | |
3673 fullName = namespace + "-" + name; | |
3674 | |
3675 if ( !prototype ) { | |
3676 prototype = base; | |
3677 base = $.Widget; | |
3678 } | |
3679 | |
3680 // create selector for plugin | |
3681 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { | |
3682 return !!$.data( elem, fullName ); | |
3683 }; | |
3684 | |
3685 $[ namespace ] = $[ namespace ] || {}; | |
3686 existingConstructor = $[ namespace ][ name ]; | |
3687 constructor = $[ namespace ][ name ] = function( options, element ) { | |
3688 // allow instantiation without "new" keyword | |
3689 if ( !this._createWidget ) { | |
3690 return new constructor( options, element ); | |
3691 } | |
3692 | |
3693 // allow instantiation without initializing for simple inheritance | |
3694 // must use "new" keyword (the code above always passes args) | |
3695 if ( arguments.length ) { | |
3696 this._createWidget( options, element ); | |
3697 } | |
3698 }; | |
3699 // extend with the existing constructor to carry over any static properties | |
3700 $.extend( constructor, existingConstructor, { | |
3701 version: prototype.version, | |
3702 // copy the object used to create the prototype in case we need to | |
3703 // redefine the widget later | |
3704 _proto: $.extend( {}, prototype ), | |
3705 // track widgets that inherit from this widget in case this widget is | |
3706 // redefined after a widget inherits from it | |
3707 _childConstructors: [] | |
3708 }); | |
3709 | |
3710 basePrototype = new base(); | |
3711 // we need to make the options hash a property directly on the new instance | |
3712 // otherwise we'll modify the options hash on the prototype that we're | |
3713 // inheriting from | |
3714 basePrototype.options = $.widget.extend( {}, basePrototype.options ); | |
3715 $.each( prototype, function( prop, value ) { | |
3716 if ( !$.isFunction( value ) ) { | |
3717 proxiedPrototype[ prop ] = value; | |
3718 return; | |
3719 } | |
3720 proxiedPrototype[ prop ] = (function() { | |
3721 var _super = function() { | |
3722 return base.prototype[ prop ].apply( this, arguments ); | |
3723 }, | |
3724 _superApply = function( args ) { | |
3725 return base.prototype[ prop ].apply( this, args ); | |
3726 }; | |
3727 return function() { | |
3728 var __super = this._super, | |
3729 __superApply = this._superApply, | |
3730 returnValue; | |
3731 | |
3732 this._super = _super; | |
3733 this._superApply = _superApply; | |
3734 | |
3735 returnValue = value.apply( this, arguments ); | |
3736 | |
3737 this._super = __super; | |
3738 this._superApply = __superApply; | |
3739 | |
3740 return returnValue; | |
3741 }; | |
3742 })(); | |
3743 }); | |
3744 constructor.prototype = $.widget.extend( basePrototype, { | |
3745 // TODO: remove support for widgetEventPrefix | |
3746 // always use the name + a colon as the prefix, e.g., draggable:start | |
3747 // don't prefix for widgets that aren't DOM-based | |
3748 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name | |
3749 }, proxiedPrototype, { | |
3750 constructor: constructor, | |
3751 namespace: namespace, | |
3752 widgetName: name, | |
3753 widgetFullName: fullName | |
3754 }); | |
3755 | |
3756 // If this widget is being redefined then we need to find all widgets that | |
3757 // are inheriting from it and redefine all of them so that they inherit from | |
3758 // the new version of this widget. We're essentially trying to replace one | |
3759 // level in the prototype chain. | |
3760 if ( existingConstructor ) { | |
3761 $.each( existingConstructor._childConstructors, function( i, child ) { | |
3762 var childPrototype = child.prototype; | |
3763 | |
3764 // redefine the child widget using the same prototype that was | |
3765 // originally used, but inherit from the new version of the base | |
3766 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); | |
3767 }); | |
3768 // remove the list of existing child constructors from the old constructor | |
3769 // so the old child constructors can be garbage collected | |
3770 delete existingConstructor._childConstructors; | |
3771 } else { | |
3772 base._childConstructors.push( constructor ); | |
3773 } | |
3774 | |
3775 $.widget.bridge( name, constructor ); | |
3776 }; | |
3777 | |
3778 $.widget.extend = function( target ) { | |
3779 var input = slice.call( arguments, 1 ), | |
3780 inputIndex = 0, | |
3781 inputLength = input.length, | |
3782 key, | |
3783 value; | |
3784 for ( ; inputIndex < inputLength; inputIndex++ ) { | |
3785 for ( key in input[ inputIndex ] ) { | |
3786 value = input[ inputIndex ][ key ]; | |
3787 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { | |
3788 // Clone objects | |
3789 if ( $.isPlainObject( value ) ) { | |
3790 target[ key ] = $.isPlainObject( target[ key ] ) ? | |
3791 $.widget.extend( {}, target[ key ], value ) : | |
3792 // Don't extend strings, arrays, etc. with objects | |
3793 $.widget.extend( {}, value ); | |
3794 // Copy everything else by reference | |
3795 } else { | |
3796 target[ key ] = value; | |
3797 } | |
3798 } | |
3799 } | |
3800 } | |
3801 return target; | |
3802 }; | |
3803 | |
3804 $.widget.bridge = function( name, object ) { | |
3805 var fullName = object.prototype.widgetFullName || name; | |
3806 $.fn[ name ] = function( options ) { | |
3807 var isMethodCall = typeof options === "string", | |
3808 args = slice.call( arguments, 1 ), | |
3809 returnValue = this; | |
3810 | |
3811 // allow multiple hashes to be passed on init | |
3812 options = !isMethodCall && args.length ? | |
3813 $.widget.extend.apply( null, [ options ].concat(args) ) : | |
3814 options; | |
3815 | |
3816 if ( isMethodCall ) { | |
3817 this.each(function() { | |
3818 var methodValue, | |
3819 instance = $.data( this, fullName ); | |
3820 if ( !instance ) { | |
3821 return $.error( "cannot call methods on " + name + " prior to initialization; " + | |
3822 "attempted to call method '" + options + "'" ); | |
3823 } | |
3824 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { | |
3825 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); | |
3826 } | |
3827 methodValue = instance[ options ].apply( instance, args ); | |
3828 if ( methodValue !== instance && methodValue !== undefined ) { | |
3829 returnValue = methodValue && methodValue.jquery ? | |
3830 returnValue.pushStack( methodValue.get() ) : | |
3831 methodValue; | |
3832 return false; | |
3833 } | |
3834 }); | |
3835 } else { | |
3836 this.each(function() { | |
3837 var instance = $.data( this, fullName ); | |
3838 if ( instance ) { | |
3839 instance.option( options || {} )._init(); | |
3840 } else { | |
3841 $.data( this, fullName, new object( options, this ) ); | |
3842 } | |
3843 }); | |
3844 } | |
3845 | |
3846 return returnValue; | |
3847 }; | |
3848 }; | |
3849 | |
3850 $.Widget = function( /* options, element */ ) {}; | |
3851 $.Widget._childConstructors = []; | |
3852 | |
3853 $.Widget.prototype = { | |
3854 widgetName: "widget", | |
3855 widgetEventPrefix: "", | |
3856 defaultElement: "<div>", | |
3857 options: { | |
3858 disabled: false, | |
3859 | |
3860 // callbacks | |
3861 create: null | |
3862 }, | |
3863 _createWidget: function( options, element ) { | |
3864 element = $( element || this.defaultElement || this )[ 0 ]; | |
3865 this.element = $( element ); | |
3866 this.uuid = uuid++; | |
3867 this.eventNamespace = "." + this.widgetName + this.uuid; | |
3868 this.options = $.widget.extend( {}, | |
3869 this.options, | |
3870 this._getCreateOptions(), | |
3871 options ); | |
3872 | |
3873 this.bindings = $(); | |
3874 this.hoverable = $(); | |
3875 this.focusable = $(); | |
3876 | |
3877 if ( element !== this ) { | |
3878 $.data( element, this.widgetFullName, this ); | |
3879 this._on( true, this.element, { | |
3880 remove: function( event ) { | |
3881 if ( event.target === element ) { | |
3882 this.destroy(); | |
3883 } | |
3884 } | |
3885 }); | |
3886 this.document = $( element.style ? | |
3887 // element within the document | |
3888 element.ownerDocument : | |
3889 // element is window or document | |
3890 element.document || element ); | |
3891 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); | |
3892 } | |
3893 | |
3894 this._create(); | |
3895 this._trigger( "create", null, this._getCreateEventData() ); | |
3896 this._init(); | |
3897 }, | |
3898 _getCreateOptions: $.noop, | |
3899 _getCreateEventData: $.noop, | |
3900 _create: $.noop, | |
3901 _init: $.noop, | |
3902 | |
3903 destroy: function() { | |
3904 this._destroy(); | |
3905 // we can probably remove the unbind calls in 2.0 | |
3906 // all event bindings should go through this._on() | |
3907 this.element | |
3908 .unbind( this.eventNamespace ) | |
3909 // 1.9 BC for #7810 | |
3910 // TODO remove dual storage | |
3911 .removeData( this.widgetName ) | |
3912 .removeData( this.widgetFullName ) | |
3913 // support: jquery <1.6.3 | |
3914 // http://bugs.jquery.com/ticket/9413 | |
3915 .removeData( $.camelCase( this.widgetFullName ) ); | |
3916 this.widget() | |
3917 .unbind( this.eventNamespace ) | |
3918 .removeAttr( "aria-disabled" ) | |
3919 .removeClass( | |
3920 this.widgetFullName + "-disabled " + | |
3921 "ui-state-disabled" ); | |
3922 | |
3923 // clean up events and states | |
3924 this.bindings.unbind( this.eventNamespace ); | |
3925 this.hoverable.removeClass( "ui-state-hover" ); | |
3926 this.focusable.removeClass( "ui-state-focus" ); | |
3927 }, | |
3928 _destroy: $.noop, | |
3929 | |
3930 widget: function() { | |
3931 return this.element; | |
3932 }, | |
3933 | |
3934 option: function( key, value ) { | |
3935 var options = key, | |
3936 parts, | |
3937 curOption, | |
3938 i; | |
3939 | |
3940 if ( arguments.length === 0 ) { | |
3941 // don't return a reference to the internal hash | |
3942 return $.widget.extend( {}, this.options ); | |
3943 } | |
3944 | |
3945 if ( typeof key === "string" ) { | |
3946 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } | |
3947 options = {}; | |
3948 parts = key.split( "." ); | |
3949 key = parts.shift(); | |
3950 if ( parts.length ) { | |
3951 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); | |
3952 for ( i = 0; i < parts.length - 1; i++ ) { | |
3953 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; | |
3954 curOption = curOption[ parts[ i ] ]; | |
3955 } | |
3956 key = parts.pop(); | |
3957 if ( value === undefined ) { | |
3958 return curOption[ key ] === undefined ? null : curOption[ key ]; | |
3959 } | |
3960 curOption[ key ] = value; | |
3961 } else { | |
3962 if ( value === undefined ) { | |
3963 return this.options[ key ] === undefined ? null : this.options[ key ]; | |
3964 } | |
3965 options[ key ] = value; | |
3966 } | |
3967 } | |
3968 | |
3969 this._setOptions( options ); | |
3970 | |
3971 return this; | |
3972 }, | |
3973 _setOptions: function( options ) { | |
3974 var key; | |
3975 | |
3976 for ( key in options ) { | |
3977 this._setOption( key, options[ key ] ); | |
3978 } | |
3979 | |
3980 return this; | |
3981 }, | |
3982 _setOption: function( key, value ) { | |
3983 this.options[ key ] = value; | |
3984 | |
3985 if ( key === "disabled" ) { | |
3986 this.widget() | |
3987 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) | |
3988 .attr( "aria-disabled", value ); | |
3989 this.hoverable.removeClass( "ui-state-hover" ); | |
3990 this.focusable.removeClass( "ui-state-focus" ); | |
3991 } | |
3992 | |
3993 return this; | |
3994 }, | |
3995 | |
3996 enable: function() { | |
3997 return this._setOption( "disabled", false ); | |
3998 }, | |
3999 disable: function() { | |
4000 return this._setOption( "disabled", true ); | |
4001 }, | |
4002 | |
4003 _on: function( suppressDisabledCheck, element, handlers ) { | |
4004 var delegateElement, | |
4005 instance = this; | |
4006 | |
4007 // no suppressDisabledCheck flag, shuffle arguments | |
4008 if ( typeof suppressDisabledCheck !== "boolean" ) { | |
4009 handlers = element; | |
4010 element = suppressDisabledCheck; | |
4011 suppressDisabledCheck = false; | |
4012 } | |
4013 | |
4014 // no element argument, shuffle and use this.element | |
4015 if ( !handlers ) { | |
4016 handlers = element; | |
4017 element = this.element; | |
4018 delegateElement = this.widget(); | |
4019 } else { | |
4020 // accept selectors, DOM elements | |
4021 element = delegateElement = $( element ); | |
4022 this.bindings = this.bindings.add( element ); | |
4023 } | |
4024 | |
4025 $.each( handlers, function( event, handler ) { | |
4026 function handlerProxy() { | |
4027 // allow widgets to customize the disabled handling | |
4028 // - disabled as an array instead of boolean | |
4029 // - disabled class as method for disabling individual parts | |
4030 if ( !suppressDisabledCheck && | |
4031 ( instance.options.disabled === true || | |
4032 $( this ).hasClass( "ui-state-disabled" ) ) ) { | |
4033 return; | |
4034 } | |
4035 return ( typeof handler === "string" ? instance[ handler ] : handler ) | |
4036 .apply( instance, arguments ); | |
4037 } | |
4038 | |
4039 // copy the guid so direct unbinding works | |
4040 if ( typeof handler !== "string" ) { | |
4041 handlerProxy.guid = handler.guid = | |
4042 handler.guid || handlerProxy.guid || $.guid++; | |
4043 } | |
4044 | |
4045 var match = event.match( /^(\w+)\s*(.*)$/ ), | |
4046 eventName = match[1] + instance.eventNamespace, | |
4047 selector = match[2]; | |
4048 if ( selector ) { | |
4049 delegateElement.delegate( selector, eventName, handlerProxy ); | |
4050 } else { | |
4051 element.bind( eventName, handlerProxy ); | |
4052 } | |
4053 }); | |
4054 }, | |
4055 | |
4056 _off: function( element, eventName ) { | |
4057 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; | |
4058 element.unbind( eventName ).undelegate( eventName ); | |
4059 }, | |
4060 | |
4061 _delay: function( handler, delay ) { | |
4062 function handlerProxy() { | |
4063 return ( typeof handler === "string" ? instance[ handler ] : handler ) | |
4064 .apply( instance, arguments ); | |
4065 } | |
4066 var instance = this; | |
4067 return setTimeout( handlerProxy, delay || 0 ); | |
4068 }, | |
4069 | |
4070 _hoverable: function( element ) { | |
4071 this.hoverable = this.hoverable.add( element ); | |
4072 this._on( element, { | |
4073 mouseenter: function( event ) { | |
4074 $( event.currentTarget ).addClass( "ui-state-hover" ); | |
4075 }, | |
4076 mouseleave: function( event ) { | |
4077 $( event.currentTarget ).removeClass( "ui-state-hover" ); | |
4078 } | |
4079 }); | |
4080 }, | |
4081 | |
4082 _focusable: function( element ) { | |
4083 this.focusable = this.focusable.add( element ); | |
4084 this._on( element, { | |
4085 focusin: function( event ) { | |
4086 $( event.currentTarget ).addClass( "ui-state-focus" ); | |
4087 }, | |
4088 focusout: function( event ) { | |
4089 $( event.currentTarget ).removeClass( "ui-state-focus" ); | |
4090 } | |
4091 }); | |
4092 }, | |
4093 | |
4094 _trigger: function( type, event, data ) { | |
4095 var prop, orig, | |
4096 callback = this.options[ type ]; | |
4097 | |
4098 data = data || {}; | |
4099 event = $.Event( event ); | |
4100 event.type = ( type === this.widgetEventPrefix ? | |
4101 type : | |
4102 this.widgetEventPrefix + type ).toLowerCase(); | |
4103 // the original event may come from any element | |
4104 // so we need to reset the target on the new event | |
4105 event.target = this.element[ 0 ]; | |
4106 | |
4107 // copy original event properties over to the new event | |
4108 orig = event.originalEvent; | |
4109 if ( orig ) { | |
4110 for ( prop in orig ) { | |
4111 if ( !( prop in event ) ) { | |
4112 event[ prop ] = orig[ prop ]; | |
4113 } | |
4114 } | |
4115 } | |
4116 | |
4117 this.element.trigger( event, data ); | |
4118 return !( $.isFunction( callback ) && | |
4119 callback.apply( this.element[0], [ event ].concat( data ) ) === false || | |
4120 event.isDefaultPrevented() ); | |
4121 } | |
4122 }; | |
4123 | |
4124 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { | |
4125 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { | |
4126 if ( typeof options === "string" ) { | |
4127 options = { effect: options }; | |
4128 } | |
4129 var hasOptions, | |
4130 effectName = !options ? | |
4131 method : | |
4132 options === true || typeof options === "number" ? | |
4133 defaultEffect : | |
4134 options.effect || defaultEffect; | |
4135 options = options || {}; | |
4136 if ( typeof options === "number" ) { | |
4137 options = { duration: options }; | |
4138 } | |
4139 hasOptions = !$.isEmptyObject( options ); | |
4140 options.complete = callback; | |
4141 if ( options.delay ) { | |
4142 element.delay( options.delay ); | |
4143 } | |
4144 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { | |
4145 element[ method ]( options ); | |
4146 } else if ( effectName !== method && element[ effectName ] ) { | |
4147 element[ effectName ]( options.duration, options.easing, callback ); | |
4148 } else { | |
4149 element.queue(function( next ) { | |
4150 $( this )[ method ](); | |
4151 if ( callback ) { | |
4152 callback.call( element[ 0 ] ); | |
4153 } | |
4154 next(); | |
4155 }); | |
4156 } | |
4157 }; | |
4158 }); | |
4159 | |
4160 })( jQuery ); | |
4161 (function( $, undefined ) { | |
4162 | |
4163 var mouseHandled = false; | |
4164 $( document ).mouseup( function() { | |
4165 mouseHandled = false; | |
4166 }); | |
4167 | |
4168 $.widget("ui.mouse", { | |
4169 version: "1.10.3", | |
4170 options: { | |
4171 cancel: "input,textarea,button,select,option", | |
4172 distance: 1, | |
4173 delay: 0 | |
4174 }, | |
4175 _mouseInit: function() { | |
4176 var that = this; | |
4177 | |
4178 this.element | |
4179 .bind("mousedown."+this.widgetName, function(event) { | |
4180 return that._mouseDown(event); | |
4181 }) | |
4182 .bind("click."+this.widgetName, function(event) { | |
4183 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { | |
4184 $.removeData(event.target, that.widgetName + ".preventClickEvent"); | |
4185 event.stopImmediatePropagation(); | |
4186 return false; | |
4187 } | |
4188 }); | |
4189 | |
4190 this.started = false; | |
4191 }, | |
4192 | |
4193 // TODO: make sure destroying one instance of mouse doesn't mess with | |
4194 // other instances of mouse | |
4195 _mouseDestroy: function() { | |
4196 this.element.unbind("."+this.widgetName); | |
4197 if ( this._mouseMoveDelegate ) { | |
4198 $(document) | |
4199 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) | |
4200 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); | |
4201 } | |
4202 }, | |
4203 | |
4204 _mouseDown: function(event) { | |
4205 // don't let more than one widget handle mouseStart | |
4206 if( mouseHandled ) { return; } | |
4207 | |
4208 // we may have missed mouseup (out of window) | |
4209 (this._mouseStarted && this._mouseUp(event)); | |
4210 | |
4211 this._mouseDownEvent = event; | |
4212 | |
4213 var that = this, | |
4214 btnIsLeft = (event.which === 1), | |
4215 // event.target.nodeName works around a bug in IE 8 with | |
4216 // disabled inputs (#7620) | |
4217 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); | |
4218 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { | |
4219 return true; | |
4220 } | |
4221 | |
4222 this.mouseDelayMet = !this.options.delay; | |
4223 if (!this.mouseDelayMet) { | |
4224 this._mouseDelayTimer = setTimeout(function() { | |
4225 that.mouseDelayMet = true; | |
4226 }, this.options.delay); | |
4227 } | |
4228 | |
4229 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { | |
4230 this._mouseStarted = (this._mouseStart(event) !== false); | |
4231 if (!this._mouseStarted) { | |
4232 event.preventDefault(); | |
4233 return true; | |
4234 } | |
4235 } | |
4236 | |
4237 // Click event may never have fired (Gecko & Opera) | |
4238 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { | |
4239 $.removeData(event.target, this.widgetName + ".preventClickEvent"); | |
4240 } | |
4241 | |
4242 // these delegates are required to keep context | |
4243 this._mouseMoveDelegate = function(event) { | |
4244 return that._mouseMove(event); | |
4245 }; | |
4246 this._mouseUpDelegate = function(event) { | |
4247 return that._mouseUp(event); | |
4248 }; | |
4249 $(document) | |
4250 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) | |
4251 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); | |
4252 | |
4253 event.preventDefault(); | |
4254 | |
4255 mouseHandled = true; | |
4256 return true; | |
4257 }, | |
4258 | |
4259 _mouseMove: function(event) { | |
4260 // IE mouseup check - mouseup happened when mouse was out of window | |
4261 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { | |
4262 return this._mouseUp(event); | |
4263 } | |
4264 | |
4265 if (this._mouseStarted) { | |
4266 this._mouseDrag(event); | |
4267 return event.preventDefault(); | |
4268 } | |
4269 | |
4270 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { | |
4271 this._mouseStarted = | |
4272 (this._mouseStart(this._mouseDownEvent, event) !== false); | |
4273 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); | |
4274 } | |
4275 | |
4276 return !this._mouseStarted; | |
4277 }, | |
4278 | |
4279 _mouseUp: function(event) { | |
4280 $(document) | |
4281 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) | |
4282 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); | |
4283 | |
4284 if (this._mouseStarted) { | |
4285 this._mouseStarted = false; | |
4286 | |
4287 if (event.target === this._mouseDownEvent.target) { | |
4288 $.data(event.target, this.widgetName + ".preventClickEvent", true); | |
4289 } | |
4290 | |
4291 this._mouseStop(event); | |
4292 } | |
4293 | |
4294 return false; | |
4295 }, | |
4296 | |
4297 _mouseDistanceMet: function(event) { | |
4298 return (Math.max( | |
4299 Math.abs(this._mouseDownEvent.pageX - event.pageX), | |
4300 Math.abs(this._mouseDownEvent.pageY - event.pageY) | |
4301 ) >= this.options.distance | |
4302 ); | |
4303 }, | |
4304 | |
4305 _mouseDelayMet: function(/* event */) { | |
4306 return this.mouseDelayMet; | |
4307 }, | |
4308 | |
4309 // These are placeholder methods, to be overriden by extending plugin | |
4310 _mouseStart: function(/* event */) {}, | |
4311 _mouseDrag: function(/* event */) {}, | |
4312 _mouseStop: function(/* event */) {}, | |
4313 _mouseCapture: function(/* event */) { return true; } | |
4314 }); | |
4315 | |
4316 })(jQuery); | |
4317 (function( $, undefined ) { | |
4318 | |
4319 $.ui = $.ui || {}; | |
4320 | |
4321 var cachedScrollbarWidth, | |
4322 max = Math.max, | |
4323 abs = Math.abs, | |
4324 round = Math.round, | |
4325 rhorizontal = /left|center|right/, | |
4326 rvertical = /top|center|bottom/, | |
4327 roffset = /[\+\-]\d+(\.[\d]+)?%?/, | |
4328 rposition = /^\w+/, | |
4329 rpercent = /%$/, | |
4330 _position = $.fn.position; | |
4331 | |
4332 function getOffsets( offsets, width, height ) { | |
4333 return [ | |
4334 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), | |
4335 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) | |
4336 ]; | |
4337 } | |
4338 | |
4339 function parseCss( element, property ) { | |
4340 return parseInt( $.css( element, property ), 10 ) || 0; | |
4341 } | |
4342 | |
4343 function getDimensions( elem ) { | |
4344 var raw = elem[0]; | |
4345 if ( raw.nodeType === 9 ) { | |
4346 return { | |
4347 width: elem.width(), | |
4348 height: elem.height(), | |
4349 offset: { top: 0, left: 0 } | |
4350 }; | |
4351 } | |
4352 if ( $.isWindow( raw ) ) { | |
4353 return { | |
4354 width: elem.width(), | |
4355 height: elem.height(), | |
4356 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } | |
4357 }; | |
4358 } | |
4359 if ( raw.preventDefault ) { | |
4360 return { | |
4361 width: 0, | |
4362 height: 0, | |
4363 offset: { top: raw.pageY, left: raw.pageX } | |
4364 }; | |
4365 } | |
4366 return { | |
4367 width: elem.outerWidth(), | |
4368 height: elem.outerHeight(), | |
4369 offset: elem.offset() | |
4370 }; | |
4371 } | |
4372 | |
4373 $.position = { | |
4374 scrollbarWidth: function() { | |
4375 if ( cachedScrollbarWidth !== undefined ) { | |
4376 return cachedScrollbarWidth; | |
4377 } | |
4378 var w1, w2, | |
4379 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), | |
4380 innerDiv = div.children()[0]; | |
4381 | |
4382 $( "body" ).append( div ); | |
4383 w1 = innerDiv.offsetWidth; | |
4384 div.css( "overflow", "scroll" ); | |
4385 | |
4386 w2 = innerDiv.offsetWidth; | |
4387 | |
4388 if ( w1 === w2 ) { | |
4389 w2 = div[0].clientWidth; | |
4390 } | |
4391 | |
4392 div.remove(); | |
4393 | |
4394 return (cachedScrollbarWidth = w1 - w2); | |
4395 }, | |
4396 getScrollInfo: function( within ) { | |
4397 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), | |
4398 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), | |
4399 hasOverflowX = overflowX === "scroll" || | |
4400 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), | |
4401 hasOverflowY = overflowY === "scroll" || | |
4402 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); | |
4403 return { | |
4404 width: hasOverflowY ? $.position.scrollbarWidth() : 0, | |
4405 height: hasOverflowX ? $.position.scrollbarWidth() : 0 | |
4406 }; | |
4407 }, | |
4408 getWithinInfo: function( element ) { | |
4409 var withinElement = $( element || window ), | |
4410 isWindow = $.isWindow( withinElement[0] ); | |
4411 return { | |
4412 element: withinElement, | |
4413 isWindow: isWindow, | |
4414 offset: withinElement.offset() || { left: 0, top: 0 }, | |
4415 scrollLeft: withinElement.scrollLeft(), | |
4416 scrollTop: withinElement.scrollTop(), | |
4417 width: isWindow ? withinElement.width() : withinElement.outerWidth(), | |
4418 height: isWindow ? withinElement.height() : withinElement.outerHeight() | |
4419 }; | |
4420 } | |
4421 }; | |
4422 | |
4423 $.fn.position = function( options ) { | |
4424 if ( !options || !options.of ) { | |
4425 return _position.apply( this, arguments ); | |
4426 } | |
4427 | |
4428 // make a copy, we don't want to modify arguments | |
4429 options = $.extend( {}, options ); | |
4430 | |
4431 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, | |
4432 target = $( options.of ), | |
4433 within = $.position.getWithinInfo( options.within ), | |
4434 scrollInfo = $.position.getScrollInfo( within ), | |
4435 collision = ( options.collision || "flip" ).split( " " ), | |
4436 offsets = {}; | |
4437 | |
4438 dimensions = getDimensions( target ); | |
4439 if ( target[0].preventDefault ) { | |
4440 // force left top to allow flipping | |
4441 options.at = "left top"; | |
4442 } | |
4443 targetWidth = dimensions.width; | |
4444 targetHeight = dimensions.height; | |
4445 targetOffset = dimensions.offset; | |
4446 // clone to reuse original targetOffset later | |
4447 basePosition = $.extend( {}, targetOffset ); | |
4448 | |
4449 // force my and at to have valid horizontal and vertical positions | |
4450 // if a value is missing or invalid, it will be converted to center | |
4451 $.each( [ "my", "at" ], function() { | |
4452 var pos = ( options[ this ] || "" ).split( " " ), | |
4453 horizontalOffset, | |
4454 verticalOffset; | |
4455 | |
4456 if ( pos.length === 1) { | |
4457 pos = rhorizontal.test( pos[ 0 ] ) ? | |
4458 pos.concat( [ "center" ] ) : | |
4459 rvertical.test( pos[ 0 ] ) ? | |
4460 [ "center" ].concat( pos ) : | |
4461 [ "center", "center" ]; | |
4462 } | |
4463 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; | |
4464 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; | |
4465 | |
4466 // calculate offsets | |
4467 horizontalOffset = roffset.exec( pos[ 0 ] ); | |
4468 verticalOffset = roffset.exec( pos[ 1 ] ); | |
4469 offsets[ this ] = [ | |
4470 horizontalOffset ? horizontalOffset[ 0 ] : 0, | |
4471 verticalOffset ? verticalOffset[ 0 ] : 0 | |
4472 ]; | |
4473 | |
4474 // reduce to just the positions without the offsets | |
4475 options[ this ] = [ | |
4476 rposition.exec( pos[ 0 ] )[ 0 ], | |
4477 rposition.exec( pos[ 1 ] )[ 0 ] | |
4478 ]; | |
4479 }); | |
4480 | |
4481 // normalize collision option | |
4482 if ( collision.length === 1 ) { | |
4483 collision[ 1 ] = collision[ 0 ]; | |
4484 } | |
4485 | |
4486 if ( options.at[ 0 ] === "right" ) { | |
4487 basePosition.left += targetWidth; | |
4488 } else if ( options.at[ 0 ] === "center" ) { | |
4489 basePosition.left += targetWidth / 2; | |
4490 } | |
4491 | |
4492 if ( options.at[ 1 ] === "bottom" ) { | |
4493 basePosition.top += targetHeight; | |
4494 } else if ( options.at[ 1 ] === "center" ) { | |
4495 basePosition.top += targetHeight / 2; | |
4496 } | |
4497 | |
4498 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); | |
4499 basePosition.left += atOffset[ 0 ]; | |
4500 basePosition.top += atOffset[ 1 ]; | |
4501 | |
4502 return this.each(function() { | |
4503 var collisionPosition, using, | |
4504 elem = $( this ), | |
4505 elemWidth = elem.outerWidth(), | |
4506 elemHeight = elem.outerHeight(), | |
4507 marginLeft = parseCss( this, "marginLeft" ), | |
4508 marginTop = parseCss( this, "marginTop" ), | |
4509 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, | |
4510 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, | |
4511 position = $.extend( {}, basePosition ), | |
4512 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); | |
4513 | |
4514 if ( options.my[ 0 ] === "right" ) { | |
4515 position.left -= elemWidth; | |
4516 } else if ( options.my[ 0 ] === "center" ) { | |
4517 position.left -= elemWidth / 2; | |
4518 } | |
4519 | |
4520 if ( options.my[ 1 ] === "bottom" ) { | |
4521 position.top -= elemHeight; | |
4522 } else if ( options.my[ 1 ] === "center" ) { | |
4523 position.top -= elemHeight / 2; | |
4524 } | |
4525 | |
4526 position.left += myOffset[ 0 ]; | |
4527 position.top += myOffset[ 1 ]; | |
4528 | |
4529 // if the browser doesn't support fractions, then round for consistent results | |
4530 if ( !$.support.offsetFractions ) { | |
4531 position.left = round( position.left ); | |
4532 position.top = round( position.top ); | |
4533 } | |
4534 | |
4535 collisionPosition = { | |
4536 marginLeft: marginLeft, | |
4537 marginTop: marginTop | |
4538 }; | |
4539 | |
4540 $.each( [ "left", "top" ], function( i, dir ) { | |
4541 if ( $.ui.position[ collision[ i ] ] ) { | |
4542 $.ui.position[ collision[ i ] ][ dir ]( position, { | |
4543 targetWidth: targetWidth, | |
4544 targetHeight: targetHeight, | |
4545 elemWidth: elemWidth, | |
4546 elemHeight: elemHeight, | |
4547 collisionPosition: collisionPosition, | |
4548 collisionWidth: collisionWidth, | |
4549 collisionHeight: collisionHeight, | |
4550 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], | |
4551 my: options.my, | |
4552 at: options.at, | |
4553 within: within, | |
4554 elem : elem | |
4555 }); | |
4556 } | |
4557 }); | |
4558 | |
4559 if ( options.using ) { | |
4560 // adds feedback as second argument to using callback, if present | |
4561 using = function( props ) { | |
4562 var left = targetOffset.left - position.left, | |
4563 right = left + targetWidth - elemWidth, | |
4564 top = targetOffset.top - position.top, | |
4565 bottom = top + targetHeight - elemHeight, | |
4566 feedback = { | |
4567 target: { | |
4568 element: target, | |
4569 left: targetOffset.left, | |
4570 top: targetOffset.top, | |
4571 width: targetWidth, | |
4572 height: targetHeight | |
4573 }, | |
4574 element: { | |
4575 element: elem, | |
4576 left: position.left, | |
4577 top: position.top, | |
4578 width: elemWidth, | |
4579 height: elemHeight | |
4580 }, | |
4581 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", | |
4582 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" | |
4583 }; | |
4584 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { | |
4585 feedback.horizontal = "center"; | |
4586 } | |
4587 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { | |
4588 feedback.vertical = "middle"; | |
4589 } | |
4590 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { | |
4591 feedback.important = "horizontal"; | |
4592 } else { | |
4593 feedback.important = "vertical"; | |
4594 } | |
4595 options.using.call( this, props, feedback ); | |
4596 }; | |
4597 } | |
4598 | |
4599 elem.offset( $.extend( position, { using: using } ) ); | |
4600 }); | |
4601 }; | |
4602 | |
4603 $.ui.position = { | |
4604 fit: { | |
4605 left: function( position, data ) { | |
4606 var within = data.within, | |
4607 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, | |
4608 outerWidth = within.width, | |
4609 collisionPosLeft = position.left - data.collisionPosition.marginLeft, | |
4610 overLeft = withinOffset - collisionPosLeft, | |
4611 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, | |
4612 newOverRight; | |
4613 | |
4614 // element is wider than within | |
4615 if ( data.collisionWidth > outerWidth ) { | |
4616 // element is initially over the left side of within | |
4617 if ( overLeft > 0 && overRight <= 0 ) { | |
4618 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; | |
4619 position.left += overLeft - newOverRight; | |
4620 // element is initially over right side of within | |
4621 } else if ( overRight > 0 && overLeft <= 0 ) { | |
4622 position.left = withinOffset; | |
4623 // element is initially over both left and right sides of within | |
4624 } else { | |
4625 if ( overLeft > overRight ) { | |
4626 position.left = withinOffset + outerWidth - data.collisionWidth; | |
4627 } else { | |
4628 position.left = withinOffset; | |
4629 } | |
4630 } | |
4631 // too far left -> align with left edge | |
4632 } else if ( overLeft > 0 ) { | |
4633 position.left += overLeft; | |
4634 // too far right -> align with right edge | |
4635 } else if ( overRight > 0 ) { | |
4636 position.left -= overRight; | |
4637 // adjust based on position and margin | |
4638 } else { | |
4639 position.left = max( position.left - collisionPosLeft, position.left ); | |
4640 } | |
4641 }, | |
4642 top: function( position, data ) { | |
4643 var within = data.within, | |
4644 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, | |
4645 outerHeight = data.within.height, | |
4646 collisionPosTop = position.top - data.collisionPosition.marginTop, | |
4647 overTop = withinOffset - collisionPosTop, | |
4648 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, | |
4649 newOverBottom; | |
4650 | |
4651 // element is taller than within | |
4652 if ( data.collisionHeight > outerHeight ) { | |
4653 // element is initially over the top of within | |
4654 if ( overTop > 0 && overBottom <= 0 ) { | |
4655 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; | |
4656 position.top += overTop - newOverBottom; | |
4657 // element is initially over bottom of within | |
4658 } else if ( overBottom > 0 && overTop <= 0 ) { | |
4659 position.top = withinOffset; | |
4660 // element is initially over both top and bottom of within | |
4661 } else { | |
4662 if ( overTop > overBottom ) { | |
4663 position.top = withinOffset + outerHeight - data.collisionHeight; | |
4664 } else { | |
4665 position.top = withinOffset; | |
4666 } | |
4667 } | |
4668 // too far up -> align with top | |
4669 } else if ( overTop > 0 ) { | |
4670 position.top += overTop; | |
4671 // too far down -> align with bottom edge | |
4672 } else if ( overBottom > 0 ) { | |
4673 position.top -= overBottom; | |
4674 // adjust based on position and margin | |
4675 } else { | |
4676 position.top = max( position.top - collisionPosTop, position.top ); | |
4677 } | |
4678 } | |
4679 }, | |
4680 flip: { | |
4681 left: function( position, data ) { | |
4682 var within = data.within, | |
4683 withinOffset = within.offset.left + within.scrollLeft, | |
4684 outerWidth = within.width, | |
4685 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, | |
4686 collisionPosLeft = position.left - data.collisionPosition.marginLeft, | |
4687 overLeft = collisionPosLeft - offsetLeft, | |
4688 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, | |
4689 myOffset = data.my[ 0 ] === "left" ? | |
4690 -data.elemWidth : | |
4691 data.my[ 0 ] === "right" ? | |
4692 data.elemWidth : | |
4693 0, | |
4694 atOffset = data.at[ 0 ] === "left" ? | |
4695 data.targetWidth : | |
4696 data.at[ 0 ] === "right" ? | |
4697 -data.targetWidth : | |
4698 0, | |
4699 offset = -2 * data.offset[ 0 ], | |
4700 newOverRight, | |
4701 newOverLeft; | |
4702 | |
4703 if ( overLeft < 0 ) { | |
4704 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; | |
4705 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { | |
4706 position.left += myOffset + atOffset + offset; | |
4707 } | |
4708 } | |
4709 else if ( overRight > 0 ) { | |
4710 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; | |
4711 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { | |
4712 position.left += myOffset + atOffset + offset; | |
4713 } | |
4714 } | |
4715 }, | |
4716 top: function( position, data ) { | |
4717 var within = data.within, | |
4718 withinOffset = within.offset.top + within.scrollTop, | |
4719 outerHeight = within.height, | |
4720 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, | |
4721 collisionPosTop = position.top - data.collisionPosition.marginTop, | |
4722 overTop = collisionPosTop - offsetTop, | |
4723 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, | |
4724 top = data.my[ 1 ] === "top", | |
4725 myOffset = top ? | |
4726 -data.elemHeight : | |
4727 data.my[ 1 ] === "bottom" ? | |
4728 data.elemHeight : | |
4729 0, | |
4730 atOffset = data.at[ 1 ] === "top" ? | |
4731 data.targetHeight : | |
4732 data.at[ 1 ] === "bottom" ? | |
4733 -data.targetHeight : | |
4734 0, | |
4735 offset = -2 * data.offset[ 1 ], | |
4736 newOverTop, | |
4737 newOverBottom; | |
4738 if ( overTop < 0 ) { | |
4739 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; | |
4740 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { | |
4741 position.top += myOffset + atOffset + offset; | |
4742 } | |
4743 } | |
4744 else if ( overBottom > 0 ) { | |
4745 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; | |
4746 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { | |
4747 position.top += myOffset + atOffset + offset; | |
4748 } | |
4749 } | |
4750 } | |
4751 }, | |
4752 flipfit: { | |
4753 left: function() { | |
4754 $.ui.position.flip.left.apply( this, arguments ); | |
4755 $.ui.position.fit.left.apply( this, arguments ); | |
4756 }, | |
4757 top: function() { | |
4758 $.ui.position.flip.top.apply( this, arguments ); | |
4759 $.ui.position.fit.top.apply( this, arguments ); | |
4760 } | |
4761 } | |
4762 }; | |
4763 | |
4764 // fraction support test | |
4765 (function () { | |
4766 var testElement, testElementParent, testElementStyle, offsetLeft, i, | |
4767 body = document.getElementsByTagName( "body" )[ 0 ], | |
4768 div = document.createElement( "div" ); | |
4769 | |
4770 //Create a "fake body" for testing based on method used in jQuery.support | |
4771 testElement = document.createElement( body ? "div" : "body" ); | |
4772 testElementStyle = { | |
4773 visibility: "hidden", | |
4774 width: 0, | |
4775 height: 0, | |
4776 border: 0, | |
4777 margin: 0, | |
4778 background: "none" | |
4779 }; | |
4780 if ( body ) { | |
4781 $.extend( testElementStyle, { | |
4782 position: "absolute", | |
4783 left: "-1000px", | |
4784 top: "-1000px" | |
4785 }); | |
4786 } | |
4787 for ( i in testElementStyle ) { | |
4788 testElement.style[ i ] = testElementStyle[ i ]; | |
4789 } | |
4790 testElement.appendChild( div ); | |
4791 testElementParent = body || document.documentElement; | |
4792 testElementParent.insertBefore( testElement, testElementParent.firstChild ); | |
4793 | |
4794 div.style.cssText = "position: absolute; left: 10.7432222px;"; | |
4795 | |
4796 offsetLeft = $( div ).offset().left; | |
4797 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; | |
4798 | |
4799 testElement.innerHTML = ""; | |
4800 testElementParent.removeChild( testElement ); | |
4801 })(); | |
4802 | |
4803 }( jQuery ) ); | |
4804 (function( $, undefined ) { | |
4805 | |
4806 $.widget("ui.draggable", $.ui.mouse, { | |
4807 version: "1.10.3", | |
4808 widgetEventPrefix: "drag", | |
4809 options: { | |
4810 addClasses: true, | |
4811 appendTo: "parent", | |
4812 axis: false, | |
4813 connectToSortable: false, | |
4814 containment: false, | |
4815 cursor: "auto", | |
4816 cursorAt: false, | |
4817 grid: false, | |
4818 handle: false, | |
4819 helper: "original", | |
4820 iframeFix: false, | |
4821 opacity: false, | |
4822 refreshPositions: false, | |
4823 revert: false, | |
4824 revertDuration: 500, | |
4825 scope: "default", | |
4826 scroll: true, | |
4827 scrollSensitivity: 20, | |
4828 scrollSpeed: 20, | |
4829 snap: false, | |
4830 snapMode: "both", | |
4831 snapTolerance: 20, | |
4832 stack: false, | |
4833 zIndex: false, | |
4834 | |
4835 // callbacks | |
4836 drag: null, | |
4837 start: null, | |
4838 stop: null | |
4839 }, | |
4840 _create: function() { | |
4841 | |
4842 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { | |
4843 this.element[0].style.position = "relative"; | |
4844 } | |
4845 if (this.options.addClasses){ | |
4846 this.element.addClass("ui-draggable"); | |
4847 } | |
4848 if (this.options.disabled){ | |
4849 this.element.addClass("ui-draggable-disabled"); | |
4850 } | |
4851 | |
4852 this._mouseInit(); | |
4853 | |
4854 }, | |
4855 | |
4856 _destroy: function() { | |
4857 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); | |
4858 this._mouseDestroy(); | |
4859 }, | |
4860 | |
4861 _mouseCapture: function(event) { | |
4862 | |
4863 var o = this.options; | |
4864 | |
4865 // among others, prevent a drag on a resizable-handle | |
4866 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { | |
4867 return false; | |
4868 } | |
4869 | |
4870 //Quit if we're not on a valid handle | |
4871 this.handle = this._getHandle(event); | |
4872 if (!this.handle) { | |
4873 return false; | |
4874 } | |
4875 | |
4876 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { | |
4877 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") | |
4878 .css({ | |
4879 width: this.offsetWidth+"px", height: this.offsetHeight+"px", | |
4880 position: "absolute", opacity: "0.001", zIndex: 1000 | |
4881 }) | |
4882 .css($(this).offset()) | |
4883 .appendTo("body"); | |
4884 }); | |
4885 | |
4886 return true; | |
4887 | |
4888 }, | |
4889 | |
4890 _mouseStart: function(event) { | |
4891 | |
4892 var o = this.options; | |
4893 | |
4894 //Create and append the visible helper | |
4895 this.helper = this._createHelper(event); | |
4896 | |
4897 this.helper.addClass("ui-draggable-dragging"); | |
4898 | |
4899 //Cache the helper size | |
4900 this._cacheHelperProportions(); | |
4901 | |
4902 //If ddmanager is used for droppables, set the global draggable | |
4903 if($.ui.ddmanager) { | |
4904 $.ui.ddmanager.current = this; | |
4905 } | |
4906 | |
4907 /* | |
4908 * - Position generation - | |
4909 * This block generates everything position related - it's the core of draggables. | |
4910 */ | |
4911 | |
4912 //Cache the margins of the original element | |
4913 this._cacheMargins(); | |
4914 | |
4915 //Store the helper's css position | |
4916 this.cssPosition = this.helper.css( "position" ); | |
4917 this.scrollParent = this.helper.scrollParent(); | |
4918 this.offsetParent = this.helper.offsetParent(); | |
4919 this.offsetParentCssPosition = this.offsetParent.css( "position" ); | |
4920 | |
4921 //The element's absolute position on the page minus margins | |
4922 this.offset = this.positionAbs = this.element.offset(); | |
4923 this.offset = { | |
4924 top: this.offset.top - this.margins.top, | |
4925 left: this.offset.left - this.margins.left | |
4926 }; | |
4927 | |
4928 //Reset scroll cache | |
4929 this.offset.scroll = false; | |
4930 | |
4931 $.extend(this.offset, { | |
4932 click: { //Where the click happened, relative to the element | |
4933 left: event.pageX - this.offset.left, | |
4934 top: event.pageY - this.offset.top | |
4935 }, | |
4936 parent: this._getParentOffset(), | |
4937 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper | |
4938 }); | |
4939 | |
4940 //Generate the original position | |
4941 this.originalPosition = this.position = this._generatePosition(event); | |
4942 this.originalPageX = event.pageX; | |
4943 this.originalPageY = event.pageY; | |
4944 | |
4945 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied | |
4946 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); | |
4947 | |
4948 //Set a containment if given in the options | |
4949 this._setContainment(); | |
4950 | |
4951 //Trigger event + callbacks | |
4952 if(this._trigger("start", event) === false) { | |
4953 this._clear(); | |
4954 return false; | |
4955 } | |
4956 | |
4957 //Recache the helper size | |
4958 this._cacheHelperProportions(); | |
4959 | |
4960 //Prepare the droppable offsets | |
4961 if ($.ui.ddmanager && !o.dropBehaviour) { | |
4962 $.ui.ddmanager.prepareOffsets(this, event); | |
4963 } | |
4964 | |
4965 | |
4966 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position | |
4967 | |
4968 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) | |
4969 if ( $.ui.ddmanager ) { | |
4970 $.ui.ddmanager.dragStart(this, event); | |
4971 } | |
4972 | |
4973 return true; | |
4974 }, | |
4975 | |
4976 _mouseDrag: function(event, noPropagation) { | |
4977 // reset any necessary cached properties (see #5009) | |
4978 if ( this.offsetParentCssPosition === "fixed" ) { | |
4979 this.offset.parent = this._getParentOffset(); | |
4980 } | |
4981 | |
4982 //Compute the helpers position | |
4983 this.position = this._generatePosition(event); | |
4984 this.positionAbs = this._convertPositionTo("absolute"); | |
4985 | |
4986 //Call plugins and callbacks and use the resulting position if something is returned | |
4987 if (!noPropagation) { | |
4988 var ui = this._uiHash(); | |
4989 if(this._trigger("drag", event, ui) === false) { | |
4990 this._mouseUp({}); | |
4991 return false; | |
4992 } | |
4993 this.position = ui.position; | |
4994 } | |
4995 | |
4996 if(!this.options.axis || this.options.axis !== "y") { | |
4997 this.helper[0].style.left = this.position.left+"px"; | |
4998 } | |
4999 if(!this.options.axis || this.options.axis !== "x") { | |
5000 this.helper[0].style.top = this.position.top+"px"; | |
5001 } | |
5002 if($.ui.ddmanager) { | |
5003 $.ui.ddmanager.drag(this, event); | |
5004 } | |
5005 | |
5006 return false; | |
5007 }, | |
5008 | |
5009 _mouseStop: function(event) { | |
5010 | |
5011 //If we are using droppables, inform the manager about the drop | |
5012 var that = this, | |
5013 dropped = false; | |
5014 if ($.ui.ddmanager && !this.options.dropBehaviour) { | |
5015 dropped = $.ui.ddmanager.drop(this, event); | |
5016 } | |
5017 | |
5018 //if a drop comes from outside (a sortable) | |
5019 if(this.dropped) { | |
5020 dropped = this.dropped; | |
5021 this.dropped = false; | |
5022 } | |
5023 | |
5024 //if the original element is no longer in the DOM don't bother to continue (see #8269) | |
5025 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { | |
5026 return false; | |
5027 } | |
5028 | |
5029 if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { | |
5030 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { | |
5031 if(that._trigger("stop", event) !== false) { | |
5032 that._clear(); | |
5033 } | |
5034 }); | |
5035 } else { | |
5036 if(this._trigger("stop", event) !== false) { | |
5037 this._clear(); | |
5038 } | |
5039 } | |
5040 | |
5041 return false; | |
5042 }, | |
5043 | |
5044 _mouseUp: function(event) { | |
5045 //Remove frame helpers | |
5046 $("div.ui-draggable-iframeFix").each(function() { | |
5047 this.parentNode.removeChild(this); | |
5048 }); | |
5049 | |
5050 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) | |
5051 if( $.ui.ddmanager ) { | |
5052 $.ui.ddmanager.dragStop(this, event); | |
5053 } | |
5054 | |
5055 return $.ui.mouse.prototype._mouseUp.call(this, event); | |
5056 }, | |
5057 | |
5058 cancel: function() { | |
5059 | |
5060 if(this.helper.is(".ui-draggable-dragging")) { | |
5061 this._mouseUp({}); | |
5062 } else { | |
5063 this._clear(); | |
5064 } | |
5065 | |
5066 return this; | |
5067 | |
5068 }, | |
5069 | |
5070 _getHandle: function(event) { | |
5071 return this.options.handle ? | |
5072 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : | |
5073 true; | |
5074 }, | |
5075 | |
5076 _createHelper: function(event) { | |
5077 | |
5078 var o = this.options, | |
5079 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); | |
5080 | |
5081 if(!helper.parents("body").length) { | |
5082 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); | |
5083 } | |
5084 | |
5085 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { | |
5086 helper.css("position", "absolute"); | |
5087 } | |
5088 | |
5089 return helper; | |
5090 | |
5091 }, | |
5092 | |
5093 _adjustOffsetFromHelper: function(obj) { | |
5094 if (typeof obj === "string") { | |
5095 obj = obj.split(" "); | |
5096 } | |
5097 if ($.isArray(obj)) { | |
5098 obj = {left: +obj[0], top: +obj[1] || 0}; | |
5099 } | |
5100 if ("left" in obj) { | |
5101 this.offset.click.left = obj.left + this.margins.left; | |
5102 } | |
5103 if ("right" in obj) { | |
5104 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; | |
5105 } | |
5106 if ("top" in obj) { | |
5107 this.offset.click.top = obj.top + this.margins.top; | |
5108 } | |
5109 if ("bottom" in obj) { | |
5110 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; | |
5111 } | |
5112 }, | |
5113 | |
5114 _getParentOffset: function() { | |
5115 | |
5116 //Get the offsetParent and cache its position | |
5117 var po = this.offsetParent.offset(); | |
5118 | |
5119 // This is a special case where we need to modify a offset calculated on start, since the following happened: | |
5120 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent | |
5121 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that | |
5122 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag | |
5123 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { | |
5124 po.left += this.scrollParent.scrollLeft(); | |
5125 po.top += this.scrollParent.scrollTop(); | |
5126 } | |
5127 | |
5128 //This needs to be actually done for all browsers, since pageX/pageY includes this information | |
5129 //Ugly IE fix | |
5130 if((this.offsetParent[0] === document.body) || | |
5131 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { | |
5132 po = { top: 0, left: 0 }; | |
5133 } | |
5134 | |
5135 return { | |
5136 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), | |
5137 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) | |
5138 }; | |
5139 | |
5140 }, | |
5141 | |
5142 _getRelativeOffset: function() { | |
5143 | |
5144 if(this.cssPosition === "relative") { | |
5145 var p = this.element.position(); | |
5146 return { | |
5147 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), | |
5148 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() | |
5149 }; | |
5150 } else { | |
5151 return { top: 0, left: 0 }; | |
5152 } | |
5153 | |
5154 }, | |
5155 | |
5156 _cacheMargins: function() { | |
5157 this.margins = { | |
5158 left: (parseInt(this.element.css("marginLeft"),10) || 0), | |
5159 top: (parseInt(this.element.css("marginTop"),10) || 0), | |
5160 right: (parseInt(this.element.css("marginRight"),10) || 0), | |
5161 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) | |
5162 }; | |
5163 }, | |
5164 | |
5165 _cacheHelperProportions: function() { | |
5166 this.helperProportions = { | |
5167 width: this.helper.outerWidth(), | |
5168 height: this.helper.outerHeight() | |
5169 }; | |
5170 }, | |
5171 | |
5172 _setContainment: function() { | |
5173 | |
5174 var over, c, ce, | |
5175 o = this.options; | |
5176 | |
5177 if ( !o.containment ) { | |
5178 this.containment = null; | |
5179 return; | |
5180 } | |
5181 | |
5182 if ( o.containment === "window" ) { | |
5183 this.containment = [ | |
5184 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, | |
5185 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, | |
5186 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, | |
5187 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top | |
5188 ]; | |
5189 return; | |
5190 } | |
5191 | |
5192 if ( o.containment === "document") { | |
5193 this.containment = [ | |
5194 0, | |
5195 0, | |
5196 $( document ).width() - this.helperProportions.width - this.margins.left, | |
5197 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top | |
5198 ]; | |
5199 return; | |
5200 } | |
5201 | |
5202 if ( o.containment.constructor === Array ) { | |
5203 this.containment = o.containment; | |
5204 return; | |
5205 } | |
5206 | |
5207 if ( o.containment === "parent" ) { | |
5208 o.containment = this.helper[ 0 ].parentNode; | |
5209 } | |
5210 | |
5211 c = $( o.containment ); | |
5212 ce = c[ 0 ]; | |
5213 | |
5214 if( !ce ) { | |
5215 return; | |
5216 } | |
5217 | |
5218 over = c.css( "overflow" ) !== "hidden"; | |
5219 | |
5220 this.containment = [ | |
5221 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), | |
5222 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , | |
5223 ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right, | |
5224 ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom | |
5225 ]; | |
5226 this.relative_container = c; | |
5227 }, | |
5228 | |
5229 _convertPositionTo: function(d, pos) { | |
5230 | |
5231 if(!pos) { | |
5232 pos = this.position; | |
5233 } | |
5234 | |
5235 var mod = d === "absolute" ? 1 : -1, | |
5236 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; | |
5237 | |
5238 //Cache the scroll | |
5239 if (!this.offset.scroll) { | |
5240 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; | |
5241 } | |
5242 | |
5243 return { | |
5244 top: ( | |
5245 pos.top + // The absolute mouse position | |
5246 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
5247 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) | |
5248 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) | |
5249 ), | |
5250 left: ( | |
5251 pos.left + // The absolute mouse position | |
5252 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
5253 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) | |
5254 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) | |
5255 ) | |
5256 }; | |
5257 | |
5258 }, | |
5259 | |
5260 _generatePosition: function(event) { | |
5261 | |
5262 var containment, co, top, left, | |
5263 o = this.options, | |
5264 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, | |
5265 pageX = event.pageX, | |
5266 pageY = event.pageY; | |
5267 | |
5268 //Cache the scroll | |
5269 if (!this.offset.scroll) { | |
5270 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; | |
5271 } | |
5272 | |
5273 /* | |
5274 * - Position constraining - | |
5275 * Constrain the position to a mix of grid, containment. | |
5276 */ | |
5277 | |
5278 // If we are not dragging yet, we won't check for options | |
5279 if ( this.originalPosition ) { | |
5280 if ( this.containment ) { | |
5281 if ( this.relative_container ){ | |
5282 co = this.relative_container.offset(); | |
5283 containment = [ | |
5284 this.containment[ 0 ] + co.left, | |
5285 this.containment[ 1 ] + co.top, | |
5286 this.containment[ 2 ] + co.left, | |
5287 this.containment[ 3 ] + co.top | |
5288 ]; | |
5289 } | |
5290 else { | |
5291 containment = this.containment; | |
5292 } | |
5293 | |
5294 if(event.pageX - this.offset.click.left < containment[0]) { | |
5295 pageX = containment[0] + this.offset.click.left; | |
5296 } | |
5297 if(event.pageY - this.offset.click.top < containment[1]) { | |
5298 pageY = containment[1] + this.offset.click.top; | |
5299 } | |
5300 if(event.pageX - this.offset.click.left > containment[2]) { | |
5301 pageX = containment[2] + this.offset.click.left; | |
5302 } | |
5303 if(event.pageY - this.offset.click.top > containment[3]) { | |
5304 pageY = containment[3] + this.offset.click.top; | |
5305 } | |
5306 } | |
5307 | |
5308 if(o.grid) { | |
5309 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) | |
5310 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; | |
5311 pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; | |
5312 | |
5313 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; | |
5314 pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; | |
5315 } | |
5316 | |
5317 } | |
5318 | |
5319 return { | |
5320 top: ( | |
5321 pageY - // The absolute mouse position | |
5322 this.offset.click.top - // Click offset (relative to the element) | |
5323 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent | |
5324 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) | |
5325 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) | |
5326 ), | |
5327 left: ( | |
5328 pageX - // The absolute mouse position | |
5329 this.offset.click.left - // Click offset (relative to the element) | |
5330 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent | |
5331 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) | |
5332 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) | |
5333 ) | |
5334 }; | |
5335 | |
5336 }, | |
5337 | |
5338 _clear: function() { | |
5339 this.helper.removeClass("ui-draggable-dragging"); | |
5340 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { | |
5341 this.helper.remove(); | |
5342 } | |
5343 this.helper = null; | |
5344 this.cancelHelperRemoval = false; | |
5345 }, | |
5346 | |
5347 // From now on bulk stuff - mainly helpers | |
5348 | |
5349 _trigger: function(type, event, ui) { | |
5350 ui = ui || this._uiHash(); | |
5351 $.ui.plugin.call(this, type, [event, ui]); | |
5352 //The absolute position has to be recalculated after plugins | |
5353 if(type === "drag") { | |
5354 this.positionAbs = this._convertPositionTo("absolute"); | |
5355 } | |
5356 return $.Widget.prototype._trigger.call(this, type, event, ui); | |
5357 }, | |
5358 | |
5359 plugins: {}, | |
5360 | |
5361 _uiHash: function() { | |
5362 return { | |
5363 helper: this.helper, | |
5364 position: this.position, | |
5365 originalPosition: this.originalPosition, | |
5366 offset: this.positionAbs | |
5367 }; | |
5368 } | |
5369 | |
5370 }); | |
5371 | |
5372 $.ui.plugin.add("draggable", "connectToSortable", { | |
5373 start: function(event, ui) { | |
5374 | |
5375 var inst = $(this).data("ui-draggable"), o = inst.options, | |
5376 uiSortable = $.extend({}, ui, { item: inst.element }); | |
5377 inst.sortables = []; | |
5378 $(o.connectToSortable).each(function() { | |
5379 var sortable = $.data(this, "ui-sortable"); | |
5380 if (sortable && !sortable.options.disabled) { | |
5381 inst.sortables.push({ | |
5382 instance: sortable, | |
5383 shouldRevert: sortable.options.revert | |
5384 }); | |
5385 sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). | |
5386 sortable._trigger("activate", event, uiSortable); | |
5387 } | |
5388 }); | |
5389 | |
5390 }, | |
5391 stop: function(event, ui) { | |
5392 | |
5393 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper | |
5394 var inst = $(this).data("ui-draggable"), | |
5395 uiSortable = $.extend({}, ui, { item: inst.element }); | |
5396 | |
5397 $.each(inst.sortables, function() { | |
5398 if(this.instance.isOver) { | |
5399 | |
5400 this.instance.isOver = 0; | |
5401 | |
5402 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance | |
5403 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) | |
5404 | |
5405 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" | |
5406 if(this.shouldRevert) { | |
5407 this.instance.options.revert = this.shouldRevert; | |
5408 } | |
5409 | |
5410 //Trigger the stop of the sortable | |
5411 this.instance._mouseStop(event); | |
5412 | |
5413 this.instance.options.helper = this.instance.options._helper; | |
5414 | |
5415 //If the helper has been the original item, restore properties in the sortable | |
5416 if(inst.options.helper === "original") { | |
5417 this.instance.currentItem.css({ top: "auto", left: "auto" }); | |
5418 } | |
5419 | |
5420 } else { | |
5421 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance | |
5422 this.instance._trigger("deactivate", event, uiSortable); | |
5423 } | |
5424 | |
5425 }); | |
5426 | |
5427 }, | |
5428 drag: function(event, ui) { | |
5429 | |
5430 var inst = $(this).data("ui-draggable"), that = this; | |
5431 | |
5432 $.each(inst.sortables, function() { | |
5433 | |
5434 var innermostIntersecting = false, | |
5435 thisSortable = this; | |
5436 | |
5437 //Copy over some variables to allow calling the sortable's native _intersectsWith | |
5438 this.instance.positionAbs = inst.positionAbs; | |
5439 this.instance.helperProportions = inst.helperProportions; | |
5440 this.instance.offset.click = inst.offset.click; | |
5441 | |
5442 if(this.instance._intersectsWith(this.instance.containerCache)) { | |
5443 innermostIntersecting = true; | |
5444 $.each(inst.sortables, function () { | |
5445 this.instance.positionAbs = inst.positionAbs; | |
5446 this.instance.helperProportions = inst.helperProportions; | |
5447 this.instance.offset.click = inst.offset.click; | |
5448 if (this !== thisSortable && | |
5449 this.instance._intersectsWith(this.instance.containerCache) && | |
5450 $.contains(thisSortable.instance.element[0], this.instance.element[0]) | |
5451 ) { | |
5452 innermostIntersecting = false; | |
5453 } | |
5454 return innermostIntersecting; | |
5455 }); | |
5456 } | |
5457 | |
5458 | |
5459 if(innermostIntersecting) { | |
5460 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once | |
5461 if(!this.instance.isOver) { | |
5462 | |
5463 this.instance.isOver = 1; | |
5464 //Now we fake the start of dragging for the sortable instance, | |
5465 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem | |
5466 //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) | |
5467 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); | |
5468 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it | |
5469 this.instance.options.helper = function() { return ui.helper[0]; }; | |
5470 | |
5471 event.target = this.instance.currentItem[0]; | |
5472 this.instance._mouseCapture(event, true); | |
5473 this.instance._mouseStart(event, true, true); | |
5474 | |
5475 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes | |
5476 this.instance.offset.click.top = inst.offset.click.top; | |
5477 this.instance.offset.click.left = inst.offset.click.left; | |
5478 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; | |
5479 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; | |
5480 | |
5481 inst._trigger("toSortable", event); | |
5482 inst.dropped = this.instance.element; //draggable revert needs that | |
5483 //hack so receive/update callbacks work (mostly) | |
5484 inst.currentItem = inst.element; | |
5485 this.instance.fromOutside = inst; | |
5486 | |
5487 } | |
5488 | |
5489 //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable | |
5490 if(this.instance.currentItem) { | |
5491 this.instance._mouseDrag(event); | |
5492 } | |
5493 | |
5494 } else { | |
5495 | |
5496 //If it doesn't intersect with the sortable, and it intersected before, | |
5497 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval | |
5498 if(this.instance.isOver) { | |
5499 | |
5500 this.instance.isOver = 0; | |
5501 this.instance.cancelHelperRemoval = true; | |
5502 | |
5503 //Prevent reverting on this forced stop | |
5504 this.instance.options.revert = false; | |
5505 | |
5506 // The out event needs to be triggered independently | |
5507 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); | |
5508 | |
5509 this.instance._mouseStop(event, true); | |
5510 this.instance.options.helper = this.instance.options._helper; | |
5511 | |
5512 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size | |
5513 this.instance.currentItem.remove(); | |
5514 if(this.instance.placeholder) { | |
5515 this.instance.placeholder.remove(); | |
5516 } | |
5517 | |
5518 inst._trigger("fromSortable", event); | |
5519 inst.dropped = false; //draggable revert needs that | |
5520 } | |
5521 | |
5522 } | |
5523 | |
5524 }); | |
5525 | |
5526 } | |
5527 }); | |
5528 | |
5529 $.ui.plugin.add("draggable", "cursor", { | |
5530 start: function() { | |
5531 var t = $("body"), o = $(this).data("ui-draggable").options; | |
5532 if (t.css("cursor")) { | |
5533 o._cursor = t.css("cursor"); | |
5534 } | |
5535 t.css("cursor", o.cursor); | |
5536 }, | |
5537 stop: function() { | |
5538 var o = $(this).data("ui-draggable").options; | |
5539 if (o._cursor) { | |
5540 $("body").css("cursor", o._cursor); | |
5541 } | |
5542 } | |
5543 }); | |
5544 | |
5545 $.ui.plugin.add("draggable", "opacity", { | |
5546 start: function(event, ui) { | |
5547 var t = $(ui.helper), o = $(this).data("ui-draggable").options; | |
5548 if(t.css("opacity")) { | |
5549 o._opacity = t.css("opacity"); | |
5550 } | |
5551 t.css("opacity", o.opacity); | |
5552 }, | |
5553 stop: function(event, ui) { | |
5554 var o = $(this).data("ui-draggable").options; | |
5555 if(o._opacity) { | |
5556 $(ui.helper).css("opacity", o._opacity); | |
5557 } | |
5558 } | |
5559 }); | |
5560 | |
5561 $.ui.plugin.add("draggable", "scroll", { | |
5562 start: function() { | |
5563 var i = $(this).data("ui-draggable"); | |
5564 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { | |
5565 i.overflowOffset = i.scrollParent.offset(); | |
5566 } | |
5567 }, | |
5568 drag: function( event ) { | |
5569 | |
5570 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; | |
5571 | |
5572 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { | |
5573 | |
5574 if(!o.axis || o.axis !== "x") { | |
5575 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { | |
5576 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; | |
5577 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { | |
5578 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; | |
5579 } | |
5580 } | |
5581 | |
5582 if(!o.axis || o.axis !== "y") { | |
5583 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { | |
5584 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; | |
5585 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { | |
5586 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; | |
5587 } | |
5588 } | |
5589 | |
5590 } else { | |
5591 | |
5592 if(!o.axis || o.axis !== "x") { | |
5593 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { | |
5594 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); | |
5595 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { | |
5596 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); | |
5597 } | |
5598 } | |
5599 | |
5600 if(!o.axis || o.axis !== "y") { | |
5601 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { | |
5602 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); | |
5603 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { | |
5604 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); | |
5605 } | |
5606 } | |
5607 | |
5608 } | |
5609 | |
5610 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { | |
5611 $.ui.ddmanager.prepareOffsets(i, event); | |
5612 } | |
5613 | |
5614 } | |
5615 }); | |
5616 | |
5617 $.ui.plugin.add("draggable", "snap", { | |
5618 start: function() { | |
5619 | |
5620 var i = $(this).data("ui-draggable"), | |
5621 o = i.options; | |
5622 | |
5623 i.snapElements = []; | |
5624 | |
5625 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { | |
5626 var $t = $(this), | |
5627 $o = $t.offset(); | |
5628 if(this !== i.element[0]) { | |
5629 i.snapElements.push({ | |
5630 item: this, | |
5631 width: $t.outerWidth(), height: $t.outerHeight(), | |
5632 top: $o.top, left: $o.left | |
5633 }); | |
5634 } | |
5635 }); | |
5636 | |
5637 }, | |
5638 drag: function(event, ui) { | |
5639 | |
5640 var ts, bs, ls, rs, l, r, t, b, i, first, | |
5641 inst = $(this).data("ui-draggable"), | |
5642 o = inst.options, | |
5643 d = o.snapTolerance, | |
5644 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, | |
5645 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; | |
5646 | |
5647 for (i = inst.snapElements.length - 1; i >= 0; i--){ | |
5648 | |
5649 l = inst.snapElements[i].left; | |
5650 r = l + inst.snapElements[i].width; | |
5651 t = inst.snapElements[i].top; | |
5652 b = t + inst.snapElements[i].height; | |
5653 | |
5654 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { | |
5655 if(inst.snapElements[i].snapping) { | |
5656 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); | |
5657 } | |
5658 inst.snapElements[i].snapping = false; | |
5659 continue; | |
5660 } | |
5661 | |
5662 if(o.snapMode !== "inner") { | |
5663 ts = Math.abs(t - y2) <= d; | |
5664 bs = Math.abs(b - y1) <= d; | |
5665 ls = Math.abs(l - x2) <= d; | |
5666 rs = Math.abs(r - x1) <= d; | |
5667 if(ts) { | |
5668 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; | |
5669 } | |
5670 if(bs) { | |
5671 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; | |
5672 } | |
5673 if(ls) { | |
5674 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; | |
5675 } | |
5676 if(rs) { | |
5677 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; | |
5678 } | |
5679 } | |
5680 | |
5681 first = (ts || bs || ls || rs); | |
5682 | |
5683 if(o.snapMode !== "outer") { | |
5684 ts = Math.abs(t - y1) <= d; | |
5685 bs = Math.abs(b - y2) <= d; | |
5686 ls = Math.abs(l - x1) <= d; | |
5687 rs = Math.abs(r - x2) <= d; | |
5688 if(ts) { | |
5689 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; | |
5690 } | |
5691 if(bs) { | |
5692 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; | |
5693 } | |
5694 if(ls) { | |
5695 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; | |
5696 } | |
5697 if(rs) { | |
5698 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; | |
5699 } | |
5700 } | |
5701 | |
5702 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { | |
5703 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); | |
5704 } | |
5705 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); | |
5706 | |
5707 } | |
5708 | |
5709 } | |
5710 }); | |
5711 | |
5712 $.ui.plugin.add("draggable", "stack", { | |
5713 start: function() { | |
5714 var min, | |
5715 o = this.data("ui-draggable").options, | |
5716 group = $.makeArray($(o.stack)).sort(function(a,b) { | |
5717 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); | |
5718 }); | |
5719 | |
5720 if (!group.length) { return; } | |
5721 | |
5722 min = parseInt($(group[0]).css("zIndex"), 10) || 0; | |
5723 $(group).each(function(i) { | |
5724 $(this).css("zIndex", min + i); | |
5725 }); | |
5726 this.css("zIndex", (min + group.length)); | |
5727 } | |
5728 }); | |
5729 | |
5730 $.ui.plugin.add("draggable", "zIndex", { | |
5731 start: function(event, ui) { | |
5732 var t = $(ui.helper), o = $(this).data("ui-draggable").options; | |
5733 if(t.css("zIndex")) { | |
5734 o._zIndex = t.css("zIndex"); | |
5735 } | |
5736 t.css("zIndex", o.zIndex); | |
5737 }, | |
5738 stop: function(event, ui) { | |
5739 var o = $(this).data("ui-draggable").options; | |
5740 if(o._zIndex) { | |
5741 $(ui.helper).css("zIndex", o._zIndex); | |
5742 } | |
5743 } | |
5744 }); | |
5745 | |
5746 })(jQuery); | |
5747 (function( $, undefined ) { | |
5748 | |
5749 function isOverAxis( x, reference, size ) { | |
5750 return ( x > reference ) && ( x < ( reference + size ) ); | |
5751 } | |
5752 | |
5753 $.widget("ui.droppable", { | |
5754 version: "1.10.3", | |
5755 widgetEventPrefix: "drop", | |
5756 options: { | |
5757 accept: "*", | |
5758 activeClass: false, | |
5759 addClasses: true, | |
5760 greedy: false, | |
5761 hoverClass: false, | |
5762 scope: "default", | |
5763 tolerance: "intersect", | |
5764 | |
5765 // callbacks | |
5766 activate: null, | |
5767 deactivate: null, | |
5768 drop: null, | |
5769 out: null, | |
5770 over: null | |
5771 }, | |
5772 _create: function() { | |
5773 | |
5774 var o = this.options, | |
5775 accept = o.accept; | |
5776 | |
5777 this.isover = false; | |
5778 this.isout = true; | |
5779 | |
5780 this.accept = $.isFunction(accept) ? accept : function(d) { | |
5781 return d.is(accept); | |
5782 }; | |
5783 | |
5784 //Store the droppable's proportions | |
5785 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; | |
5786 | |
5787 // Add the reference and positions to the manager | |
5788 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; | |
5789 $.ui.ddmanager.droppables[o.scope].push(this); | |
5790 | |
5791 (o.addClasses && this.element.addClass("ui-droppable")); | |
5792 | |
5793 }, | |
5794 | |
5795 _destroy: function() { | |
5796 var i = 0, | |
5797 drop = $.ui.ddmanager.droppables[this.options.scope]; | |
5798 | |
5799 for ( ; i < drop.length; i++ ) { | |
5800 if ( drop[i] === this ) { | |
5801 drop.splice(i, 1); | |
5802 } | |
5803 } | |
5804 | |
5805 this.element.removeClass("ui-droppable ui-droppable-disabled"); | |
5806 }, | |
5807 | |
5808 _setOption: function(key, value) { | |
5809 | |
5810 if(key === "accept") { | |
5811 this.accept = $.isFunction(value) ? value : function(d) { | |
5812 return d.is(value); | |
5813 }; | |
5814 } | |
5815 $.Widget.prototype._setOption.apply(this, arguments); | |
5816 }, | |
5817 | |
5818 _activate: function(event) { | |
5819 var draggable = $.ui.ddmanager.current; | |
5820 if(this.options.activeClass) { | |
5821 this.element.addClass(this.options.activeClass); | |
5822 } | |
5823 if(draggable){ | |
5824 this._trigger("activate", event, this.ui(draggable)); | |
5825 } | |
5826 }, | |
5827 | |
5828 _deactivate: function(event) { | |
5829 var draggable = $.ui.ddmanager.current; | |
5830 if(this.options.activeClass) { | |
5831 this.element.removeClass(this.options.activeClass); | |
5832 } | |
5833 if(draggable){ | |
5834 this._trigger("deactivate", event, this.ui(draggable)); | |
5835 } | |
5836 }, | |
5837 | |
5838 _over: function(event) { | |
5839 | |
5840 var draggable = $.ui.ddmanager.current; | |
5841 | |
5842 // Bail if draggable and droppable are same element | |
5843 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { | |
5844 return; | |
5845 } | |
5846 | |
5847 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5848 if(this.options.hoverClass) { | |
5849 this.element.addClass(this.options.hoverClass); | |
5850 } | |
5851 this._trigger("over", event, this.ui(draggable)); | |
5852 } | |
5853 | |
5854 }, | |
5855 | |
5856 _out: function(event) { | |
5857 | |
5858 var draggable = $.ui.ddmanager.current; | |
5859 | |
5860 // Bail if draggable and droppable are same element | |
5861 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { | |
5862 return; | |
5863 } | |
5864 | |
5865 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5866 if(this.options.hoverClass) { | |
5867 this.element.removeClass(this.options.hoverClass); | |
5868 } | |
5869 this._trigger("out", event, this.ui(draggable)); | |
5870 } | |
5871 | |
5872 }, | |
5873 | |
5874 _drop: function(event,custom) { | |
5875 | |
5876 var draggable = custom || $.ui.ddmanager.current, | |
5877 childrenIntersection = false; | |
5878 | |
5879 // Bail if draggable and droppable are same element | |
5880 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { | |
5881 return false; | |
5882 } | |
5883 | |
5884 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { | |
5885 var inst = $.data(this, "ui-droppable"); | |
5886 if( | |
5887 inst.options.greedy && | |
5888 !inst.options.disabled && | |
5889 inst.options.scope === draggable.options.scope && | |
5890 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && | |
5891 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) | |
5892 ) { childrenIntersection = true; return false; } | |
5893 }); | |
5894 if(childrenIntersection) { | |
5895 return false; | |
5896 } | |
5897 | |
5898 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5899 if(this.options.activeClass) { | |
5900 this.element.removeClass(this.options.activeClass); | |
5901 } | |
5902 if(this.options.hoverClass) { | |
5903 this.element.removeClass(this.options.hoverClass); | |
5904 } | |
5905 this._trigger("drop", event, this.ui(draggable)); | |
5906 return this.element; | |
5907 } | |
5908 | |
5909 return false; | |
5910 | |
5911 }, | |
5912 | |
5913 ui: function(c) { | |
5914 return { | |
5915 draggable: (c.currentItem || c.element), | |
5916 helper: c.helper, | |
5917 position: c.position, | |
5918 offset: c.positionAbs | |
5919 }; | |
5920 } | |
5921 | |
5922 }); | |
5923 | |
5924 $.ui.intersect = function(draggable, droppable, toleranceMode) { | |
5925 | |
5926 if (!droppable.offset) { | |
5927 return false; | |
5928 } | |
5929 | |
5930 var draggableLeft, draggableTop, | |
5931 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, | |
5932 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, | |
5933 l = droppable.offset.left, r = l + droppable.proportions.width, | |
5934 t = droppable.offset.top, b = t + droppable.proportions.height; | |
5935 | |
5936 switch (toleranceMode) { | |
5937 case "fit": | |
5938 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); | |
5939 case "intersect": | |
5940 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half | |
5941 x2 - (draggable.helperProportions.width / 2) < r && // Left Half | |
5942 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half | |
5943 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half | |
5944 case "pointer": | |
5945 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); | |
5946 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); | |
5947 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); | |
5948 case "touch": | |
5949 return ( | |
5950 (y1 >= t && y1 <= b) || // Top edge touching | |
5951 (y2 >= t && y2 <= b) || // Bottom edge touching | |
5952 (y1 < t && y2 > b) // Surrounded vertically | |
5953 ) && ( | |
5954 (x1 >= l && x1 <= r) || // Left edge touching | |
5955 (x2 >= l && x2 <= r) || // Right edge touching | |
5956 (x1 < l && x2 > r) // Surrounded horizontally | |
5957 ); | |
5958 default: | |
5959 return false; | |
5960 } | |
5961 | |
5962 }; | |
5963 | |
5964 /* | |
5965 This manager tracks offsets of draggables and droppables | |
5966 */ | |
5967 $.ui.ddmanager = { | |
5968 current: null, | |
5969 droppables: { "default": [] }, | |
5970 prepareOffsets: function(t, event) { | |
5971 | |
5972 var i, j, | |
5973 m = $.ui.ddmanager.droppables[t.options.scope] || [], | |
5974 type = event ? event.type : null, // workaround for #2317 | |
5975 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); | |
5976 | |
5977 droppablesLoop: for (i = 0; i < m.length; i++) { | |
5978 | |
5979 //No disabled and non-accepted | |
5980 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { | |
5981 continue; | |
5982 } | |
5983 | |
5984 // Filter out elements in the current dragged item | |
5985 for (j=0; j < list.length; j++) { | |
5986 if(list[j] === m[i].element[0]) { | |
5987 m[i].proportions.height = 0; | |
5988 continue droppablesLoop; | |
5989 } | |
5990 } | |
5991 | |
5992 m[i].visible = m[i].element.css("display") !== "none"; | |
5993 if(!m[i].visible) { | |
5994 continue; | |
5995 } | |
5996 | |
5997 //Activate the droppable if used directly from draggables | |
5998 if(type === "mousedown") { | |
5999 m[i]._activate.call(m[i], event); | |
6000 } | |
6001 | |
6002 m[i].offset = m[i].element.offset(); | |
6003 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; | |
6004 | |
6005 } | |
6006 | |
6007 }, | |
6008 drop: function(draggable, event) { | |
6009 | |
6010 var dropped = false; | |
6011 // Create a copy of the droppables in case the list changes during the drop (#9116) | |
6012 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { | |
6013 | |
6014 if(!this.options) { | |
6015 return; | |
6016 } | |
6017 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { | |
6018 dropped = this._drop.call(this, event) || dropped; | |
6019 } | |
6020 | |
6021 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
6022 this.isout = true; | |
6023 this.isover = false; | |
6024 this._deactivate.call(this, event); | |
6025 } | |
6026 | |
6027 }); | |
6028 return dropped; | |
6029 | |
6030 }, | |
6031 dragStart: function( draggable, event ) { | |
6032 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) | |
6033 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { | |
6034 if( !draggable.options.refreshPositions ) { | |
6035 $.ui.ddmanager.prepareOffsets( draggable, event ); | |
6036 } | |
6037 }); | |
6038 }, | |
6039 drag: function(draggable, event) { | |
6040 | |
6041 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. | |
6042 if(draggable.options.refreshPositions) { | |
6043 $.ui.ddmanager.prepareOffsets(draggable, event); | |
6044 } | |
6045 | |
6046 //Run through all droppables and check their positions based on specific tolerance options | |
6047 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { | |
6048 | |
6049 if(this.options.disabled || this.greedyChild || !this.visible) { | |
6050 return; | |
6051 } | |
6052 | |
6053 var parentInstance, scope, parent, | |
6054 intersects = $.ui.intersect(draggable, this, this.options.tolerance), | |
6055 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); | |
6056 if(!c) { | |
6057 return; | |
6058 } | |
6059 | |
6060 if (this.options.greedy) { | |
6061 // find droppable parents with same scope | |
6062 scope = this.options.scope; | |
6063 parent = this.element.parents(":data(ui-droppable)").filter(function () { | |
6064 return $.data(this, "ui-droppable").options.scope === scope; | |
6065 }); | |
6066 | |
6067 if (parent.length) { | |
6068 parentInstance = $.data(parent[0], "ui-droppable"); | |
6069 parentInstance.greedyChild = (c === "isover"); | |
6070 } | |
6071 } | |
6072 | |
6073 // we just moved into a greedy child | |
6074 if (parentInstance && c === "isover") { | |
6075 parentInstance.isover = false; | |
6076 parentInstance.isout = true; | |
6077 parentInstance._out.call(parentInstance, event); | |
6078 } | |
6079 | |
6080 this[c] = true; | |
6081 this[c === "isout" ? "isover" : "isout"] = false; | |
6082 this[c === "isover" ? "_over" : "_out"].call(this, event); | |
6083 | |
6084 // we just moved out of a greedy child | |
6085 if (parentInstance && c === "isout") { | |
6086 parentInstance.isout = false; | |
6087 parentInstance.isover = true; | |
6088 parentInstance._over.call(parentInstance, event); | |
6089 } | |
6090 }); | |
6091 | |
6092 }, | |
6093 dragStop: function( draggable, event ) { | |
6094 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); | |
6095 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) | |
6096 if( !draggable.options.refreshPositions ) { | |
6097 $.ui.ddmanager.prepareOffsets( draggable, event ); | |
6098 } | |
6099 } | |
6100 }; | |
6101 | |
6102 })(jQuery); | |
6103 (function( $, undefined ) { | |
6104 | |
6105 function num(v) { | |
6106 return parseInt(v, 10) || 0; | |
6107 } | |
6108 | |
6109 function isNumber(value) { | |
6110 return !isNaN(parseInt(value, 10)); | |
6111 } | |
6112 | |
6113 $.widget("ui.resizable", $.ui.mouse, { | |
6114 version: "1.10.3", | |
6115 widgetEventPrefix: "resize", | |
6116 options: { | |
6117 alsoResize: false, | |
6118 animate: false, | |
6119 animateDuration: "slow", | |
6120 animateEasing: "swing", | |
6121 aspectRatio: false, | |
6122 autoHide: false, | |
6123 containment: false, | |
6124 ghost: false, | |
6125 grid: false, | |
6126 handles: "e,s,se", | |
6127 helper: false, | |
6128 maxHeight: null, | |
6129 maxWidth: null, | |
6130 minHeight: 10, | |
6131 minWidth: 10, | |
6132 // See #7960 | |
6133 zIndex: 90, | |
6134 | |
6135 // callbacks | |
6136 resize: null, | |
6137 start: null, | |
6138 stop: null | |
6139 }, | |
6140 _create: function() { | |
6141 | |
6142 var n, i, handle, axis, hname, | |
6143 that = this, | |
6144 o = this.options; | |
6145 this.element.addClass("ui-resizable"); | |
6146 | |
6147 $.extend(this, { | |
6148 _aspectRatio: !!(o.aspectRatio), | |
6149 aspectRatio: o.aspectRatio, | |
6150 originalElement: this.element, | |
6151 _proportionallyResizeElements: [], | |
6152 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null | |
6153 }); | |
6154 | |
6155 //Wrap the element if it cannot hold child nodes | |
6156 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { | |
6157 | |
6158 //Create a wrapper element and set the wrapper to the new current internal element | |
6159 this.element.wrap( | |
6160 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ | |
6161 position: this.element.css("position"), | |
6162 width: this.element.outerWidth(), | |
6163 height: this.element.outerHeight(), | |
6164 top: this.element.css("top"), | |
6165 left: this.element.css("left") | |
6166 }) | |
6167 ); | |
6168 | |
6169 //Overwrite the original this.element | |
6170 this.element = this.element.parent().data( | |
6171 "ui-resizable", this.element.data("ui-resizable") | |
6172 ); | |
6173 | |
6174 this.elementIsWrapper = true; | |
6175 | |
6176 //Move margins to the wrapper | |
6177 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); | |
6178 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); | |
6179 | |
6180 //Prevent Safari textarea resize | |
6181 this.originalResizeStyle = this.originalElement.css("resize"); | |
6182 this.originalElement.css("resize", "none"); | |
6183 | |
6184 //Push the actual element to our proportionallyResize internal array | |
6185 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); | |
6186 | |
6187 // avoid IE jump (hard set the margin) | |
6188 this.originalElement.css({ margin: this.originalElement.css("margin") }); | |
6189 | |
6190 // fix handlers offset | |
6191 this._proportionallyResize(); | |
6192 | |
6193 } | |
6194 | |
6195 this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" }); | |
6196 if(this.handles.constructor === String) { | |
6197 | |
6198 if ( this.handles === "all") { | |
6199 this.handles = "n,e,s,w,se,sw,ne,nw"; | |
6200 } | |
6201 | |
6202 n = this.handles.split(","); | |
6203 this.handles = {}; | |
6204 | |
6205 for(i = 0; i < n.length; i++) { | |
6206 | |
6207 handle = $.trim(n[i]); | |
6208 hname = "ui-resizable-"+handle; | |
6209 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); | |
6210 | |
6211 // Apply zIndex to all handles - see #7960 | |
6212 axis.css({ zIndex: o.zIndex }); | |
6213 | |
6214 //TODO : What's going on here? | |
6215 if ("se" === handle) { | |
6216 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); | |
6217 } | |
6218 | |
6219 //Insert into internal handles object and append to element | |
6220 this.handles[handle] = ".ui-resizable-"+handle; | |
6221 this.element.append(axis); | |
6222 } | |
6223 | |
6224 } | |
6225 | |
6226 this._renderAxis = function(target) { | |
6227 | |
6228 var i, axis, padPos, padWrapper; | |
6229 | |
6230 target = target || this.element; | |
6231 | |
6232 for(i in this.handles) { | |
6233 | |
6234 if(this.handles[i].constructor === String) { | |
6235 this.handles[i] = $(this.handles[i], this.element).show(); | |
6236 } | |
6237 | |
6238 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) | |
6239 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { | |
6240 | |
6241 axis = $(this.handles[i], this.element); | |
6242 | |
6243 //Checking the correct pad and border | |
6244 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); | |
6245 | |
6246 //The padding type i have to apply... | |
6247 padPos = [ "padding", | |
6248 /ne|nw|n/.test(i) ? "Top" : | |
6249 /se|sw|s/.test(i) ? "Bottom" : | |
6250 /^e$/.test(i) ? "Right" : "Left" ].join(""); | |
6251 | |
6252 target.css(padPos, padWrapper); | |
6253 | |
6254 this._proportionallyResize(); | |
6255 | |
6256 } | |
6257 | |
6258 //TODO: What's that good for? There's not anything to be executed left | |
6259 if(!$(this.handles[i]).length) { | |
6260 continue; | |
6261 } | |
6262 } | |
6263 }; | |
6264 | |
6265 //TODO: make renderAxis a prototype function | |
6266 this._renderAxis(this.element); | |
6267 | |
6268 this._handles = $(".ui-resizable-handle", this.element) | |
6269 .disableSelection(); | |
6270 | |
6271 //Matching axis name | |
6272 this._handles.mouseover(function() { | |
6273 if (!that.resizing) { | |
6274 if (this.className) { | |
6275 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); | |
6276 } | |
6277 //Axis, default = se | |
6278 that.axis = axis && axis[1] ? axis[1] : "se"; | |
6279 } | |
6280 }); | |
6281 | |
6282 //If we want to auto hide the elements | |
6283 if (o.autoHide) { | |
6284 this._handles.hide(); | |
6285 $(this.element) | |
6286 .addClass("ui-resizable-autohide") | |
6287 .mouseenter(function() { | |
6288 if (o.disabled) { | |
6289 return; | |
6290 } | |
6291 $(this).removeClass("ui-resizable-autohide"); | |
6292 that._handles.show(); | |
6293 }) | |
6294 .mouseleave(function(){ | |
6295 if (o.disabled) { | |
6296 return; | |
6297 } | |
6298 if (!that.resizing) { | |
6299 $(this).addClass("ui-resizable-autohide"); | |
6300 that._handles.hide(); | |
6301 } | |
6302 }); | |
6303 } | |
6304 | |
6305 //Initialize the mouse interaction | |
6306 this._mouseInit(); | |
6307 | |
6308 }, | |
6309 | |
6310 _destroy: function() { | |
6311 | |
6312 this._mouseDestroy(); | |
6313 | |
6314 var wrapper, | |
6315 _destroy = function(exp) { | |
6316 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") | |
6317 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); | |
6318 }; | |
6319 | |
6320 //TODO: Unwrap at same DOM position | |
6321 if (this.elementIsWrapper) { | |
6322 _destroy(this.element); | |
6323 wrapper = this.element; | |
6324 this.originalElement.css({ | |
6325 position: wrapper.css("position"), | |
6326 width: wrapper.outerWidth(), | |
6327 height: wrapper.outerHeight(), | |
6328 top: wrapper.css("top"), | |
6329 left: wrapper.css("left") | |
6330 }).insertAfter( wrapper ); | |
6331 wrapper.remove(); | |
6332 } | |
6333 | |
6334 this.originalElement.css("resize", this.originalResizeStyle); | |
6335 _destroy(this.originalElement); | |
6336 | |
6337 return this; | |
6338 }, | |
6339 | |
6340 _mouseCapture: function(event) { | |
6341 var i, handle, | |
6342 capture = false; | |
6343 | |
6344 for (i in this.handles) { | |
6345 handle = $(this.handles[i])[0]; | |
6346 if (handle === event.target || $.contains(handle, event.target)) { | |
6347 capture = true; | |
6348 } | |
6349 } | |
6350 | |
6351 return !this.options.disabled && capture; | |
6352 }, | |
6353 | |
6354 _mouseStart: function(event) { | |
6355 | |
6356 var curleft, curtop, cursor, | |
6357 o = this.options, | |
6358 iniPos = this.element.position(), | |
6359 el = this.element; | |
6360 | |
6361 this.resizing = true; | |
6362 | |
6363 // bugfix for http://dev.jquery.com/ticket/1749 | |
6364 if ( (/absolute/).test( el.css("position") ) ) { | |
6365 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); | |
6366 } else if (el.is(".ui-draggable")) { | |
6367 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); | |
6368 } | |
6369 | |
6370 this._renderProxy(); | |
6371 | |
6372 curleft = num(this.helper.css("left")); | |
6373 curtop = num(this.helper.css("top")); | |
6374 | |
6375 if (o.containment) { | |
6376 curleft += $(o.containment).scrollLeft() || 0; | |
6377 curtop += $(o.containment).scrollTop() || 0; | |
6378 } | |
6379 | |
6380 //Store needed variables | |
6381 this.offset = this.helper.offset(); | |
6382 this.position = { left: curleft, top: curtop }; | |
6383 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; | |
6384 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; | |
6385 this.originalPosition = { left: curleft, top: curtop }; | |
6386 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; | |
6387 this.originalMousePosition = { left: event.pageX, top: event.pageY }; | |
6388 | |
6389 //Aspect Ratio | |
6390 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); | |
6391 | |
6392 cursor = $(".ui-resizable-" + this.axis).css("cursor"); | |
6393 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); | |
6394 | |
6395 el.addClass("ui-resizable-resizing"); | |
6396 this._propagate("start", event); | |
6397 return true; | |
6398 }, | |
6399 | |
6400 _mouseDrag: function(event) { | |
6401 | |
6402 //Increase performance, avoid regex | |
6403 var data, | |
6404 el = this.helper, props = {}, | |
6405 smp = this.originalMousePosition, | |
6406 a = this.axis, | |
6407 prevTop = this.position.top, | |
6408 prevLeft = this.position.left, | |
6409 prevWidth = this.size.width, | |
6410 prevHeight = this.size.height, | |
6411 dx = (event.pageX-smp.left)||0, | |
6412 dy = (event.pageY-smp.top)||0, | |
6413 trigger = this._change[a]; | |
6414 | |
6415 if (!trigger) { | |
6416 return false; | |
6417 } | |
6418 | |
6419 // Calculate the attrs that will be change | |
6420 data = trigger.apply(this, [event, dx, dy]); | |
6421 | |
6422 // Put this in the mouseDrag handler since the user can start pressing shift while resizing | |
6423 this._updateVirtualBoundaries(event.shiftKey); | |
6424 if (this._aspectRatio || event.shiftKey) { | |
6425 data = this._updateRatio(data, event); | |
6426 } | |
6427 | |
6428 data = this._respectSize(data, event); | |
6429 | |
6430 this._updateCache(data); | |
6431 | |
6432 // plugins callbacks need to be called first | |
6433 this._propagate("resize", event); | |
6434 | |
6435 if (this.position.top !== prevTop) { | |
6436 props.top = this.position.top + "px"; | |
6437 } | |
6438 if (this.position.left !== prevLeft) { | |
6439 props.left = this.position.left + "px"; | |
6440 } | |
6441 if (this.size.width !== prevWidth) { | |
6442 props.width = this.size.width + "px"; | |
6443 } | |
6444 if (this.size.height !== prevHeight) { | |
6445 props.height = this.size.height + "px"; | |
6446 } | |
6447 el.css(props); | |
6448 | |
6449 if (!this._helper && this._proportionallyResizeElements.length) { | |
6450 this._proportionallyResize(); | |
6451 } | |
6452 | |
6453 // Call the user callback if the element was resized | |
6454 if ( ! $.isEmptyObject(props) ) { | |
6455 this._trigger("resize", event, this.ui()); | |
6456 } | |
6457 | |
6458 return false; | |
6459 }, | |
6460 | |
6461 _mouseStop: function(event) { | |
6462 | |
6463 this.resizing = false; | |
6464 var pr, ista, soffseth, soffsetw, s, left, top, | |
6465 o = this.options, that = this; | |
6466 | |
6467 if(this._helper) { | |
6468 | |
6469 pr = this._proportionallyResizeElements; | |
6470 ista = pr.length && (/textarea/i).test(pr[0].nodeName); | |
6471 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; | |
6472 soffsetw = ista ? 0 : that.sizeDiff.width; | |
6473 | |
6474 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; | |
6475 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; | |
6476 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; | |
6477 | |
6478 if (!o.animate) { | |
6479 this.element.css($.extend(s, { top: top, left: left })); | |
6480 } | |
6481 | |
6482 that.helper.height(that.size.height); | |
6483 that.helper.width(that.size.width); | |
6484 | |
6485 if (this._helper && !o.animate) { | |
6486 this._proportionallyResize(); | |
6487 } | |
6488 } | |
6489 | |
6490 $("body").css("cursor", "auto"); | |
6491 | |
6492 this.element.removeClass("ui-resizable-resizing"); | |
6493 | |
6494 this._propagate("stop", event); | |
6495 | |
6496 if (this._helper) { | |
6497 this.helper.remove(); | |
6498 } | |
6499 | |
6500 return false; | |
6501 | |
6502 }, | |
6503 | |
6504 _updateVirtualBoundaries: function(forceAspectRatio) { | |
6505 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, | |
6506 o = this.options; | |
6507 | |
6508 b = { | |
6509 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, | |
6510 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, | |
6511 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, | |
6512 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity | |
6513 }; | |
6514 | |
6515 if(this._aspectRatio || forceAspectRatio) { | |
6516 // We want to create an enclosing box whose aspect ration is the requested one | |
6517 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension | |
6518 pMinWidth = b.minHeight * this.aspectRatio; | |
6519 pMinHeight = b.minWidth / this.aspectRatio; | |
6520 pMaxWidth = b.maxHeight * this.aspectRatio; | |
6521 pMaxHeight = b.maxWidth / this.aspectRatio; | |
6522 | |
6523 if(pMinWidth > b.minWidth) { | |
6524 b.minWidth = pMinWidth; | |
6525 } | |
6526 if(pMinHeight > b.minHeight) { | |
6527 b.minHeight = pMinHeight; | |
6528 } | |
6529 if(pMaxWidth < b.maxWidth) { | |
6530 b.maxWidth = pMaxWidth; | |
6531 } | |
6532 if(pMaxHeight < b.maxHeight) { | |
6533 b.maxHeight = pMaxHeight; | |
6534 } | |
6535 } | |
6536 this._vBoundaries = b; | |
6537 }, | |
6538 | |
6539 _updateCache: function(data) { | |
6540 this.offset = this.helper.offset(); | |
6541 if (isNumber(data.left)) { | |
6542 this.position.left = data.left; | |
6543 } | |
6544 if (isNumber(data.top)) { | |
6545 this.position.top = data.top; | |
6546 } | |
6547 if (isNumber(data.height)) { | |
6548 this.size.height = data.height; | |
6549 } | |
6550 if (isNumber(data.width)) { | |
6551 this.size.width = data.width; | |
6552 } | |
6553 }, | |
6554 | |
6555 _updateRatio: function( data ) { | |
6556 | |
6557 var cpos = this.position, | |
6558 csize = this.size, | |
6559 a = this.axis; | |
6560 | |
6561 if (isNumber(data.height)) { | |
6562 data.width = (data.height * this.aspectRatio); | |
6563 } else if (isNumber(data.width)) { | |
6564 data.height = (data.width / this.aspectRatio); | |
6565 } | |
6566 | |
6567 if (a === "sw") { | |
6568 data.left = cpos.left + (csize.width - data.width); | |
6569 data.top = null; | |
6570 } | |
6571 if (a === "nw") { | |
6572 data.top = cpos.top + (csize.height - data.height); | |
6573 data.left = cpos.left + (csize.width - data.width); | |
6574 } | |
6575 | |
6576 return data; | |
6577 }, | |
6578 | |
6579 _respectSize: function( data ) { | |
6580 | |
6581 var o = this._vBoundaries, | |
6582 a = this.axis, | |
6583 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), | |
6584 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), | |
6585 dw = this.originalPosition.left + this.originalSize.width, | |
6586 dh = this.position.top + this.size.height, | |
6587 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); | |
6588 if (isminw) { | |
6589 data.width = o.minWidth; | |
6590 } | |
6591 if (isminh) { | |
6592 data.height = o.minHeight; | |
6593 } | |
6594 if (ismaxw) { | |
6595 data.width = o.maxWidth; | |
6596 } | |
6597 if (ismaxh) { | |
6598 data.height = o.maxHeight; | |
6599 } | |
6600 | |
6601 if (isminw && cw) { | |
6602 data.left = dw - o.minWidth; | |
6603 } | |
6604 if (ismaxw && cw) { | |
6605 data.left = dw - o.maxWidth; | |
6606 } | |
6607 if (isminh && ch) { | |
6608 data.top = dh - o.minHeight; | |
6609 } | |
6610 if (ismaxh && ch) { | |
6611 data.top = dh - o.maxHeight; | |
6612 } | |
6613 | |
6614 // fixing jump error on top/left - bug #2330 | |
6615 if (!data.width && !data.height && !data.left && data.top) { | |
6616 data.top = null; | |
6617 } else if (!data.width && !data.height && !data.top && data.left) { | |
6618 data.left = null; | |
6619 } | |
6620 | |
6621 return data; | |
6622 }, | |
6623 | |
6624 _proportionallyResize: function() { | |
6625 | |
6626 if (!this._proportionallyResizeElements.length) { | |
6627 return; | |
6628 } | |
6629 | |
6630 var i, j, borders, paddings, prel, | |
6631 element = this.helper || this.element; | |
6632 | |
6633 for ( i=0; i < this._proportionallyResizeElements.length; i++) { | |
6634 | |
6635 prel = this._proportionallyResizeElements[i]; | |
6636 | |
6637 if (!this.borderDif) { | |
6638 this.borderDif = []; | |
6639 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; | |
6640 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; | |
6641 | |
6642 for ( j = 0; j < borders.length; j++ ) { | |
6643 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); | |
6644 } | |
6645 } | |
6646 | |
6647 prel.css({ | |
6648 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, | |
6649 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 | |
6650 }); | |
6651 | |
6652 } | |
6653 | |
6654 }, | |
6655 | |
6656 _renderProxy: function() { | |
6657 | |
6658 var el = this.element, o = this.options; | |
6659 this.elementOffset = el.offset(); | |
6660 | |
6661 if(this._helper) { | |
6662 | |
6663 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); | |
6664 | |
6665 this.helper.addClass(this._helper).css({ | |
6666 width: this.element.outerWidth() - 1, | |
6667 height: this.element.outerHeight() - 1, | |
6668 position: "absolute", | |
6669 left: this.elementOffset.left +"px", | |
6670 top: this.elementOffset.top +"px", | |
6671 zIndex: ++o.zIndex //TODO: Don't modify option | |
6672 }); | |
6673 | |
6674 this.helper | |
6675 .appendTo("body") | |
6676 .disableSelection(); | |
6677 | |
6678 } else { | |
6679 this.helper = this.element; | |
6680 } | |
6681 | |
6682 }, | |
6683 | |
6684 _change: { | |
6685 e: function(event, dx) { | |
6686 return { width: this.originalSize.width + dx }; | |
6687 }, | |
6688 w: function(event, dx) { | |
6689 var cs = this.originalSize, sp = this.originalPosition; | |
6690 return { left: sp.left + dx, width: cs.width - dx }; | |
6691 }, | |
6692 n: function(event, dx, dy) { | |
6693 var cs = this.originalSize, sp = this.originalPosition; | |
6694 return { top: sp.top + dy, height: cs.height - dy }; | |
6695 }, | |
6696 s: function(event, dx, dy) { | |
6697 return { height: this.originalSize.height + dy }; | |
6698 }, | |
6699 se: function(event, dx, dy) { | |
6700 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); | |
6701 }, | |
6702 sw: function(event, dx, dy) { | |
6703 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); | |
6704 }, | |
6705 ne: function(event, dx, dy) { | |
6706 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); | |
6707 }, | |
6708 nw: function(event, dx, dy) { | |
6709 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); | |
6710 } | |
6711 }, | |
6712 | |
6713 _propagate: function(n, event) { | |
6714 $.ui.plugin.call(this, n, [event, this.ui()]); | |
6715 (n !== "resize" && this._trigger(n, event, this.ui())); | |
6716 }, | |
6717 | |
6718 plugins: {}, | |
6719 | |
6720 ui: function() { | |
6721 return { | |
6722 originalElement: this.originalElement, | |
6723 element: this.element, | |
6724 helper: this.helper, | |
6725 position: this.position, | |
6726 size: this.size, | |
6727 originalSize: this.originalSize, | |
6728 originalPosition: this.originalPosition | |
6729 }; | |
6730 } | |
6731 | |
6732 }); | |
6733 | |
6734 /* | |
6735 * Resizable Extensions | |
6736 */ | |
6737 | |
6738 $.ui.plugin.add("resizable", "animate", { | |
6739 | |
6740 stop: function( event ) { | |
6741 var that = $(this).data("ui-resizable"), | |
6742 o = that.options, | |
6743 pr = that._proportionallyResizeElements, | |
6744 ista = pr.length && (/textarea/i).test(pr[0].nodeName), | |
6745 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, | |
6746 soffsetw = ista ? 0 : that.sizeDiff.width, | |
6747 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, | |
6748 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, | |
6749 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; | |
6750 | |
6751 that.element.animate( | |
6752 $.extend(style, top && left ? { top: top, left: left } : {}), { | |
6753 duration: o.animateDuration, | |
6754 easing: o.animateEasing, | |
6755 step: function() { | |
6756 | |
6757 var data = { | |
6758 width: parseInt(that.element.css("width"), 10), | |
6759 height: parseInt(that.element.css("height"), 10), | |
6760 top: parseInt(that.element.css("top"), 10), | |
6761 left: parseInt(that.element.css("left"), 10) | |
6762 }; | |
6763 | |
6764 if (pr && pr.length) { | |
6765 $(pr[0]).css({ width: data.width, height: data.height }); | |
6766 } | |
6767 | |
6768 // propagating resize, and updating values for each animation step | |
6769 that._updateCache(data); | |
6770 that._propagate("resize", event); | |
6771 | |
6772 } | |
6773 } | |
6774 ); | |
6775 } | |
6776 | |
6777 }); | |
6778 | |
6779 $.ui.plugin.add("resizable", "containment", { | |
6780 | |
6781 start: function() { | |
6782 var element, p, co, ch, cw, width, height, | |
6783 that = $(this).data("ui-resizable"), | |
6784 o = that.options, | |
6785 el = that.element, | |
6786 oc = o.containment, | |
6787 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; | |
6788 | |
6789 if (!ce) { | |
6790 return; | |
6791 } | |
6792 | |
6793 that.containerElement = $(ce); | |
6794 | |
6795 if (/document/.test(oc) || oc === document) { | |
6796 that.containerOffset = { left: 0, top: 0 }; | |
6797 that.containerPosition = { left: 0, top: 0 }; | |
6798 | |
6799 that.parentData = { | |
6800 element: $(document), left: 0, top: 0, | |
6801 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight | |
6802 }; | |
6803 } | |
6804 | |
6805 // i'm a node, so compute top, left, right, bottom | |
6806 else { | |
6807 element = $(ce); | |
6808 p = []; | |
6809 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); | |
6810 | |
6811 that.containerOffset = element.offset(); | |
6812 that.containerPosition = element.position(); | |
6813 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; | |
6814 | |
6815 co = that.containerOffset; | |
6816 ch = that.containerSize.height; | |
6817 cw = that.containerSize.width; | |
6818 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); | |
6819 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); | |
6820 | |
6821 that.parentData = { | |
6822 element: ce, left: co.left, top: co.top, width: width, height: height | |
6823 }; | |
6824 } | |
6825 }, | |
6826 | |
6827 resize: function( event ) { | |
6828 var woset, hoset, isParent, isOffsetRelative, | |
6829 that = $(this).data("ui-resizable"), | |
6830 o = that.options, | |
6831 co = that.containerOffset, cp = that.position, | |
6832 pRatio = that._aspectRatio || event.shiftKey, | |
6833 cop = { top:0, left:0 }, ce = that.containerElement; | |
6834 | |
6835 if (ce[0] !== document && (/static/).test(ce.css("position"))) { | |
6836 cop = co; | |
6837 } | |
6838 | |
6839 if (cp.left < (that._helper ? co.left : 0)) { | |
6840 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); | |
6841 if (pRatio) { | |
6842 that.size.height = that.size.width / that.aspectRatio; | |
6843 } | |
6844 that.position.left = o.helper ? co.left : 0; | |
6845 } | |
6846 | |
6847 if (cp.top < (that._helper ? co.top : 0)) { | |
6848 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); | |
6849 if (pRatio) { | |
6850 that.size.width = that.size.height * that.aspectRatio; | |
6851 } | |
6852 that.position.top = that._helper ? co.top : 0; | |
6853 } | |
6854 | |
6855 that.offset.left = that.parentData.left+that.position.left; | |
6856 that.offset.top = that.parentData.top+that.position.top; | |
6857 | |
6858 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); | |
6859 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); | |
6860 | |
6861 isParent = that.containerElement.get(0) === that.element.parent().get(0); | |
6862 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); | |
6863 | |
6864 if(isParent && isOffsetRelative) { | |
6865 woset -= that.parentData.left; | |
6866 } | |
6867 | |
6868 if (woset + that.size.width >= that.parentData.width) { | |
6869 that.size.width = that.parentData.width - woset; | |
6870 if (pRatio) { | |
6871 that.size.height = that.size.width / that.aspectRatio; | |
6872 } | |
6873 } | |
6874 | |
6875 if (hoset + that.size.height >= that.parentData.height) { | |
6876 that.size.height = that.parentData.height - hoset; | |
6877 if (pRatio) { | |
6878 that.size.width = that.size.height * that.aspectRatio; | |
6879 } | |
6880 } | |
6881 }, | |
6882 | |
6883 stop: function(){ | |
6884 var that = $(this).data("ui-resizable"), | |
6885 o = that.options, | |
6886 co = that.containerOffset, | |
6887 cop = that.containerPosition, | |
6888 ce = that.containerElement, | |
6889 helper = $(that.helper), | |
6890 ho = helper.offset(), | |
6891 w = helper.outerWidth() - that.sizeDiff.width, | |
6892 h = helper.outerHeight() - that.sizeDiff.height; | |
6893 | |
6894 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { | |
6895 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); | |
6896 } | |
6897 | |
6898 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { | |
6899 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); | |
6900 } | |
6901 | |
6902 } | |
6903 }); | |
6904 | |
6905 $.ui.plugin.add("resizable", "alsoResize", { | |
6906 | |
6907 start: function () { | |
6908 var that = $(this).data("ui-resizable"), | |
6909 o = that.options, | |
6910 _store = function (exp) { | |
6911 $(exp).each(function() { | |
6912 var el = $(this); | |
6913 el.data("ui-resizable-alsoresize", { | |
6914 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), | |
6915 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) | |
6916 }); | |
6917 }); | |
6918 }; | |
6919 | |
6920 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { | |
6921 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } | |
6922 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } | |
6923 }else{ | |
6924 _store(o.alsoResize); | |
6925 } | |
6926 }, | |
6927 | |
6928 resize: function (event, ui) { | |
6929 var that = $(this).data("ui-resizable"), | |
6930 o = that.options, | |
6931 os = that.originalSize, | |
6932 op = that.originalPosition, | |
6933 delta = { | |
6934 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, | |
6935 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 | |
6936 }, | |
6937 | |
6938 _alsoResize = function (exp, c) { | |
6939 $(exp).each(function() { | |
6940 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, | |
6941 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; | |
6942 | |
6943 $.each(css, function (i, prop) { | |
6944 var sum = (start[prop]||0) + (delta[prop]||0); | |
6945 if (sum && sum >= 0) { | |
6946 style[prop] = sum || null; | |
6947 } | |
6948 }); | |
6949 | |
6950 el.css(style); | |
6951 }); | |
6952 }; | |
6953 | |
6954 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { | |
6955 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); | |
6956 }else{ | |
6957 _alsoResize(o.alsoResize); | |
6958 } | |
6959 }, | |
6960 | |
6961 stop: function () { | |
6962 $(this).removeData("resizable-alsoresize"); | |
6963 } | |
6964 }); | |
6965 | |
6966 $.ui.plugin.add("resizable", "ghost", { | |
6967 | |
6968 start: function() { | |
6969 | |
6970 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; | |
6971 | |
6972 that.ghost = that.originalElement.clone(); | |
6973 that.ghost | |
6974 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) | |
6975 .addClass("ui-resizable-ghost") | |
6976 .addClass(typeof o.ghost === "string" ? o.ghost : ""); | |
6977 | |
6978 that.ghost.appendTo(that.helper); | |
6979 | |
6980 }, | |
6981 | |
6982 resize: function(){ | |
6983 var that = $(this).data("ui-resizable"); | |
6984 if (that.ghost) { | |
6985 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); | |
6986 } | |
6987 }, | |
6988 | |
6989 stop: function() { | |
6990 var that = $(this).data("ui-resizable"); | |
6991 if (that.ghost && that.helper) { | |
6992 that.helper.get(0).removeChild(that.ghost.get(0)); | |
6993 } | |
6994 } | |
6995 | |
6996 }); | |
6997 | |
6998 $.ui.plugin.add("resizable", "grid", { | |
6999 | |
7000 resize: function() { | |
7001 var that = $(this).data("ui-resizable"), | |
7002 o = that.options, | |
7003 cs = that.size, | |
7004 os = that.originalSize, | |
7005 op = that.originalPosition, | |
7006 a = that.axis, | |
7007 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, | |
7008 gridX = (grid[0]||1), | |
7009 gridY = (grid[1]||1), | |
7010 ox = Math.round((cs.width - os.width) / gridX) * gridX, | |
7011 oy = Math.round((cs.height - os.height) / gridY) * gridY, | |
7012 newWidth = os.width + ox, | |
7013 newHeight = os.height + oy, | |
7014 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), | |
7015 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), | |
7016 isMinWidth = o.minWidth && (o.minWidth > newWidth), | |
7017 isMinHeight = o.minHeight && (o.minHeight > newHeight); | |
7018 | |
7019 o.grid = grid; | |
7020 | |
7021 if (isMinWidth) { | |
7022 newWidth = newWidth + gridX; | |
7023 } | |
7024 if (isMinHeight) { | |
7025 newHeight = newHeight + gridY; | |
7026 } | |
7027 if (isMaxWidth) { | |
7028 newWidth = newWidth - gridX; | |
7029 } | |
7030 if (isMaxHeight) { | |
7031 newHeight = newHeight - gridY; | |
7032 } | |
7033 | |
7034 if (/^(se|s|e)$/.test(a)) { | |
7035 that.size.width = newWidth; | |
7036 that.size.height = newHeight; | |
7037 } else if (/^(ne)$/.test(a)) { | |
7038 that.size.width = newWidth; | |
7039 that.size.height = newHeight; | |
7040 that.position.top = op.top - oy; | |
7041 } else if (/^(sw)$/.test(a)) { | |
7042 that.size.width = newWidth; | |
7043 that.size.height = newHeight; | |
7044 that.position.left = op.left - ox; | |
7045 } else { | |
7046 that.size.width = newWidth; | |
7047 that.size.height = newHeight; | |
7048 that.position.top = op.top - oy; | |
7049 that.position.left = op.left - ox; | |
7050 } | |
7051 } | |
7052 | |
7053 }); | |
7054 | |
7055 })(jQuery); | |
7056 (function( $, undefined ) { | |
7057 | |
7058 $.widget("ui.selectable", $.ui.mouse, { | |
7059 version: "1.10.3", | |
7060 options: { | |
7061 appendTo: "body", | |
7062 autoRefresh: true, | |
7063 distance: 0, | |
7064 filter: "*", | |
7065 tolerance: "touch", | |
7066 | |
7067 // callbacks | |
7068 selected: null, | |
7069 selecting: null, | |
7070 start: null, | |
7071 stop: null, | |
7072 unselected: null, | |
7073 unselecting: null | |
7074 }, | |
7075 _create: function() { | |
7076 var selectees, | |
7077 that = this; | |
7078 | |
7079 this.element.addClass("ui-selectable"); | |
7080 | |
7081 this.dragged = false; | |
7082 | |
7083 // cache selectee children based on filter | |
7084 this.refresh = function() { | |
7085 selectees = $(that.options.filter, that.element[0]); | |
7086 selectees.addClass("ui-selectee"); | |
7087 selectees.each(function() { | |
7088 var $this = $(this), | |
7089 pos = $this.offset(); | |
7090 $.data(this, "selectable-item", { | |
7091 element: this, | |
7092 $element: $this, | |
7093 left: pos.left, | |
7094 top: pos.top, | |
7095 right: pos.left + $this.outerWidth(), | |
7096 bottom: pos.top + $this.outerHeight(), | |
7097 startselected: false, | |
7098 selected: $this.hasClass("ui-selected"), | |
7099 selecting: $this.hasClass("ui-selecting"), | |
7100 unselecting: $this.hasClass("ui-unselecting") | |
7101 }); | |
7102 }); | |
7103 }; | |
7104 this.refresh(); | |
7105 | |
7106 this.selectees = selectees.addClass("ui-selectee"); | |
7107 | |
7108 this._mouseInit(); | |
7109 | |
7110 this.helper = $("<div class='ui-selectable-helper'></div>"); | |
7111 }, | |
7112 | |
7113 _destroy: function() { | |
7114 this.selectees | |
7115 .removeClass("ui-selectee") | |
7116 .removeData("selectable-item"); | |
7117 this.element | |
7118 .removeClass("ui-selectable ui-selectable-disabled"); | |
7119 this._mouseDestroy(); | |
7120 }, | |
7121 | |
7122 _mouseStart: function(event) { | |
7123 var that = this, | |
7124 options = this.options; | |
7125 | |
7126 this.opos = [event.pageX, event.pageY]; | |
7127 | |
7128 if (this.options.disabled) { | |
7129 return; | |
7130 } | |
7131 | |
7132 this.selectees = $(options.filter, this.element[0]); | |
7133 | |
7134 this._trigger("start", event); | |
7135 | |
7136 $(options.appendTo).append(this.helper); | |
7137 // position helper (lasso) | |
7138 this.helper.css({ | |
7139 "left": event.pageX, | |
7140 "top": event.pageY, | |
7141 "width": 0, | |
7142 "height": 0 | |
7143 }); | |
7144 | |
7145 if (options.autoRefresh) { | |
7146 this.refresh(); | |
7147 } | |
7148 | |
7149 this.selectees.filter(".ui-selected").each(function() { | |
7150 var selectee = $.data(this, "selectable-item"); | |
7151 selectee.startselected = true; | |
7152 if (!event.metaKey && !event.ctrlKey) { | |
7153 selectee.$element.removeClass("ui-selected"); | |
7154 selectee.selected = false; | |
7155 selectee.$element.addClass("ui-unselecting"); | |
7156 selectee.unselecting = true; | |
7157 // selectable UNSELECTING callback | |
7158 that._trigger("unselecting", event, { | |
7159 unselecting: selectee.element | |
7160 }); | |
7161 } | |
7162 }); | |
7163 | |
7164 $(event.target).parents().addBack().each(function() { | |
7165 var doSelect, | |
7166 selectee = $.data(this, "selectable-item"); | |
7167 if (selectee) { | |
7168 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); | |
7169 selectee.$element | |
7170 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") | |
7171 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); | |
7172 selectee.unselecting = !doSelect; | |
7173 selectee.selecting = doSelect; | |
7174 selectee.selected = doSelect; | |
7175 // selectable (UN)SELECTING callback | |
7176 if (doSelect) { | |
7177 that._trigger("selecting", event, { | |
7178 selecting: selectee.element | |
7179 }); | |
7180 } else { | |
7181 that._trigger("unselecting", event, { | |
7182 unselecting: selectee.element | |
7183 }); | |
7184 } | |
7185 return false; | |
7186 } | |
7187 }); | |
7188 | |
7189 }, | |
7190 | |
7191 _mouseDrag: function(event) { | |
7192 | |
7193 this.dragged = true; | |
7194 | |
7195 if (this.options.disabled) { | |
7196 return; | |
7197 } | |
7198 | |
7199 var tmp, | |
7200 that = this, | |
7201 options = this.options, | |
7202 x1 = this.opos[0], | |
7203 y1 = this.opos[1], | |
7204 x2 = event.pageX, | |
7205 y2 = event.pageY; | |
7206 | |
7207 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } | |
7208 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } | |
7209 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); | |
7210 | |
7211 this.selectees.each(function() { | |
7212 var selectee = $.data(this, "selectable-item"), | |
7213 hit = false; | |
7214 | |
7215 //prevent helper from being selected if appendTo: selectable | |
7216 if (!selectee || selectee.element === that.element[0]) { | |
7217 return; | |
7218 } | |
7219 | |
7220 if (options.tolerance === "touch") { | |
7221 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); | |
7222 } else if (options.tolerance === "fit") { | |
7223 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); | |
7224 } | |
7225 | |
7226 if (hit) { | |
7227 // SELECT | |
7228 if (selectee.selected) { | |
7229 selectee.$element.removeClass("ui-selected"); | |
7230 selectee.selected = false; | |
7231 } | |
7232 if (selectee.unselecting) { | |
7233 selectee.$element.removeClass("ui-unselecting"); | |
7234 selectee.unselecting = false; | |
7235 } | |
7236 if (!selectee.selecting) { | |
7237 selectee.$element.addClass("ui-selecting"); | |
7238 selectee.selecting = true; | |
7239 // selectable SELECTING callback | |
7240 that._trigger("selecting", event, { | |
7241 selecting: selectee.element | |
7242 }); | |
7243 } | |
7244 } else { | |
7245 // UNSELECT | |
7246 if (selectee.selecting) { | |
7247 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { | |
7248 selectee.$element.removeClass("ui-selecting"); | |
7249 selectee.selecting = false; | |
7250 selectee.$element.addClass("ui-selected"); | |
7251 selectee.selected = true; | |
7252 } else { | |
7253 selectee.$element.removeClass("ui-selecting"); | |
7254 selectee.selecting = false; | |
7255 if (selectee.startselected) { | |
7256 selectee.$element.addClass("ui-unselecting"); | |
7257 selectee.unselecting = true; | |
7258 } | |
7259 // selectable UNSELECTING callback | |
7260 that._trigger("unselecting", event, { | |
7261 unselecting: selectee.element | |
7262 }); | |
7263 } | |
7264 } | |
7265 if (selectee.selected) { | |
7266 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { | |
7267 selectee.$element.removeClass("ui-selected"); | |
7268 selectee.selected = false; | |
7269 | |
7270 selectee.$element.addClass("ui-unselecting"); | |
7271 selectee.unselecting = true; | |
7272 // selectable UNSELECTING callback | |
7273 that._trigger("unselecting", event, { | |
7274 unselecting: selectee.element | |
7275 }); | |
7276 } | |
7277 } | |
7278 } | |
7279 }); | |
7280 | |
7281 return false; | |
7282 }, | |
7283 | |
7284 _mouseStop: function(event) { | |
7285 var that = this; | |
7286 | |
7287 this.dragged = false; | |
7288 | |
7289 $(".ui-unselecting", this.element[0]).each(function() { | |
7290 var selectee = $.data(this, "selectable-item"); | |
7291 selectee.$element.removeClass("ui-unselecting"); | |
7292 selectee.unselecting = false; | |
7293 selectee.startselected = false; | |
7294 that._trigger("unselected", event, { | |
7295 unselected: selectee.element | |
7296 }); | |
7297 }); | |
7298 $(".ui-selecting", this.element[0]).each(function() { | |
7299 var selectee = $.data(this, "selectable-item"); | |
7300 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); | |
7301 selectee.selecting = false; | |
7302 selectee.selected = true; | |
7303 selectee.startselected = true; | |
7304 that._trigger("selected", event, { | |
7305 selected: selectee.element | |
7306 }); | |
7307 }); | |
7308 this._trigger("stop", event); | |
7309 | |
7310 this.helper.remove(); | |
7311 | |
7312 return false; | |
7313 } | |
7314 | |
7315 }); | |
7316 | |
7317 })(jQuery); | |
7318 (function( $, undefined ) { | |
7319 | |
7320 /*jshint loopfunc: true */ | |
7321 | |
7322 function isOverAxis( x, reference, size ) { | |
7323 return ( x > reference ) && ( x < ( reference + size ) ); | |
7324 } | |
7325 | |
7326 function isFloating(item) { | |
7327 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); | |
7328 } | |
7329 | |
7330 $.widget("ui.sortable", $.ui.mouse, { | |
7331 version: "1.10.3", | |
7332 widgetEventPrefix: "sort", | |
7333 ready: false, | |
7334 options: { | |
7335 appendTo: "parent", | |
7336 axis: false, | |
7337 connectWith: false, | |
7338 containment: false, | |
7339 cursor: "auto", | |
7340 cursorAt: false, | |
7341 dropOnEmpty: true, | |
7342 forcePlaceholderSize: false, | |
7343 forceHelperSize: false, | |
7344 grid: false, | |
7345 handle: false, | |
7346 helper: "original", | |
7347 items: "> *", | |
7348 opacity: false, | |
7349 placeholder: false, | |
7350 revert: false, | |
7351 scroll: true, | |
7352 scrollSensitivity: 20, | |
7353 scrollSpeed: 20, | |
7354 scope: "default", | |
7355 tolerance: "intersect", | |
7356 zIndex: 1000, | |
7357 | |
7358 // callbacks | |
7359 activate: null, | |
7360 beforeStop: null, | |
7361 change: null, | |
7362 deactivate: null, | |
7363 out: null, | |
7364 over: null, | |
7365 receive: null, | |
7366 remove: null, | |
7367 sort: null, | |
7368 start: null, | |
7369 stop: null, | |
7370 update: null | |
7371 }, | |
7372 _create: function() { | |
7373 | |
7374 var o = this.options; | |
7375 this.containerCache = {}; | |
7376 this.element.addClass("ui-sortable"); | |
7377 | |
7378 //Get the items | |
7379 this.refresh(); | |
7380 | |
7381 //Let's determine if the items are being displayed horizontally | |
7382 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; | |
7383 | |
7384 //Let's determine the parent's offset | |
7385 this.offset = this.element.offset(); | |
7386 | |
7387 //Initialize mouse events for interaction | |
7388 this._mouseInit(); | |
7389 | |
7390 //We're ready to go | |
7391 this.ready = true; | |
7392 | |
7393 }, | |
7394 | |
7395 _destroy: function() { | |
7396 this.element | |
7397 .removeClass("ui-sortable ui-sortable-disabled"); | |
7398 this._mouseDestroy(); | |
7399 | |
7400 for ( var i = this.items.length - 1; i >= 0; i-- ) { | |
7401 this.items[i].item.removeData(this.widgetName + "-item"); | |
7402 } | |
7403 | |
7404 return this; | |
7405 }, | |
7406 | |
7407 _setOption: function(key, value){ | |
7408 if ( key === "disabled" ) { | |
7409 this.options[ key ] = value; | |
7410 | |
7411 this.widget().toggleClass( "ui-sortable-disabled", !!value ); | |
7412 } else { | |
7413 // Don't call widget base _setOption for disable as it adds ui-state-disabled class | |
7414 $.Widget.prototype._setOption.apply(this, arguments); | |
7415 } | |
7416 }, | |
7417 | |
7418 _mouseCapture: function(event, overrideHandle) { | |
7419 var currentItem = null, | |
7420 validHandle = false, | |
7421 that = this; | |
7422 | |
7423 if (this.reverting) { | |
7424 return false; | |
7425 } | |
7426 | |
7427 if(this.options.disabled || this.options.type === "static") { | |
7428 return false; | |
7429 } | |
7430 | |
7431 //We have to refresh the items data once first | |
7432 this._refreshItems(event); | |
7433 | |
7434 //Find out if the clicked node (or one of its parents) is a actual item in this.items | |
7435 $(event.target).parents().each(function() { | |
7436 if($.data(this, that.widgetName + "-item") === that) { | |
7437 currentItem = $(this); | |
7438 return false; | |
7439 } | |
7440 }); | |
7441 if($.data(event.target, that.widgetName + "-item") === that) { | |
7442 currentItem = $(event.target); | |
7443 } | |
7444 | |
7445 if(!currentItem) { | |
7446 return false; | |
7447 } | |
7448 if(this.options.handle && !overrideHandle) { | |
7449 $(this.options.handle, currentItem).find("*").addBack().each(function() { | |
7450 if(this === event.target) { | |
7451 validHandle = true; | |
7452 } | |
7453 }); | |
7454 if(!validHandle) { | |
7455 return false; | |
7456 } | |
7457 } | |
7458 | |
7459 this.currentItem = currentItem; | |
7460 this._removeCurrentsFromItems(); | |
7461 return true; | |
7462 | |
7463 }, | |
7464 | |
7465 _mouseStart: function(event, overrideHandle, noActivation) { | |
7466 | |
7467 var i, body, | |
7468 o = this.options; | |
7469 | |
7470 this.currentContainer = this; | |
7471 | |
7472 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture | |
7473 this.refreshPositions(); | |
7474 | |
7475 //Create and append the visible helper | |
7476 this.helper = this._createHelper(event); | |
7477 | |
7478 //Cache the helper size | |
7479 this._cacheHelperProportions(); | |
7480 | |
7481 /* | |
7482 * - Position generation - | |
7483 * This block generates everything position related - it's the core of draggables. | |
7484 */ | |
7485 | |
7486 //Cache the margins of the original element | |
7487 this._cacheMargins(); | |
7488 | |
7489 //Get the next scrolling parent | |
7490 this.scrollParent = this.helper.scrollParent(); | |
7491 | |
7492 //The element's absolute position on the page minus margins | |
7493 this.offset = this.currentItem.offset(); | |
7494 this.offset = { | |
7495 top: this.offset.top - this.margins.top, | |
7496 left: this.offset.left - this.margins.left | |
7497 }; | |
7498 | |
7499 $.extend(this.offset, { | |
7500 click: { //Where the click happened, relative to the element | |
7501 left: event.pageX - this.offset.left, | |
7502 top: event.pageY - this.offset.top | |
7503 }, | |
7504 parent: this._getParentOffset(), | |
7505 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper | |
7506 }); | |
7507 | |
7508 // Only after we got the offset, we can change the helper's position to absolute | |
7509 // TODO: Still need to figure out a way to make relative sorting possible | |
7510 this.helper.css("position", "absolute"); | |
7511 this.cssPosition = this.helper.css("position"); | |
7512 | |
7513 //Generate the original position | |
7514 this.originalPosition = this._generatePosition(event); | |
7515 this.originalPageX = event.pageX; | |
7516 this.originalPageY = event.pageY; | |
7517 | |
7518 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied | |
7519 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); | |
7520 | |
7521 //Cache the former DOM position | |
7522 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; | |
7523 | |
7524 //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way | |
7525 if(this.helper[0] !== this.currentItem[0]) { | |
7526 this.currentItem.hide(); | |
7527 } | |
7528 | |
7529 //Create the placeholder | |
7530 this._createPlaceholder(); | |
7531 | |
7532 //Set a containment if given in the options | |
7533 if(o.containment) { | |
7534 this._setContainment(); | |
7535 } | |
7536 | |
7537 if( o.cursor && o.cursor !== "auto" ) { // cursor option | |
7538 body = this.document.find( "body" ); | |
7539 | |
7540 // support: IE | |
7541 this.storedCursor = body.css( "cursor" ); | |
7542 body.css( "cursor", o.cursor ); | |
7543 | |
7544 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); | |
7545 } | |
7546 | |
7547 if(o.opacity) { // opacity option | |
7548 if (this.helper.css("opacity")) { | |
7549 this._storedOpacity = this.helper.css("opacity"); | |
7550 } | |
7551 this.helper.css("opacity", o.opacity); | |
7552 } | |
7553 | |
7554 if(o.zIndex) { // zIndex option | |
7555 if (this.helper.css("zIndex")) { | |
7556 this._storedZIndex = this.helper.css("zIndex"); | |
7557 } | |
7558 this.helper.css("zIndex", o.zIndex); | |
7559 } | |
7560 | |
7561 //Prepare scrolling | |
7562 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { | |
7563 this.overflowOffset = this.scrollParent.offset(); | |
7564 } | |
7565 | |
7566 //Call callbacks | |
7567 this._trigger("start", event, this._uiHash()); | |
7568 | |
7569 //Recache the helper size | |
7570 if(!this._preserveHelperProportions) { | |
7571 this._cacheHelperProportions(); | |
7572 } | |
7573 | |
7574 | |
7575 //Post "activate" events to possible containers | |
7576 if( !noActivation ) { | |
7577 for ( i = this.containers.length - 1; i >= 0; i-- ) { | |
7578 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); | |
7579 } | |
7580 } | |
7581 | |
7582 //Prepare possible droppables | |
7583 if($.ui.ddmanager) { | |
7584 $.ui.ddmanager.current = this; | |
7585 } | |
7586 | |
7587 if ($.ui.ddmanager && !o.dropBehaviour) { | |
7588 $.ui.ddmanager.prepareOffsets(this, event); | |
7589 } | |
7590 | |
7591 this.dragging = true; | |
7592 | |
7593 this.helper.addClass("ui-sortable-helper"); | |
7594 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position | |
7595 return true; | |
7596 | |
7597 }, | |
7598 | |
7599 _mouseDrag: function(event) { | |
7600 var i, item, itemElement, intersection, | |
7601 o = this.options, | |
7602 scrolled = false; | |
7603 | |
7604 //Compute the helpers position | |
7605 this.position = this._generatePosition(event); | |
7606 this.positionAbs = this._convertPositionTo("absolute"); | |
7607 | |
7608 if (!this.lastPositionAbs) { | |
7609 this.lastPositionAbs = this.positionAbs; | |
7610 } | |
7611 | |
7612 //Do scrolling | |
7613 if(this.options.scroll) { | |
7614 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { | |
7615 | |
7616 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { | |
7617 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; | |
7618 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { | |
7619 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; | |
7620 } | |
7621 | |
7622 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { | |
7623 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; | |
7624 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { | |
7625 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; | |
7626 } | |
7627 | |
7628 } else { | |
7629 | |
7630 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { | |
7631 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); | |
7632 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { | |
7633 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); | |
7634 } | |
7635 | |
7636 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { | |
7637 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); | |
7638 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { | |
7639 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); | |
7640 } | |
7641 | |
7642 } | |
7643 | |
7644 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { | |
7645 $.ui.ddmanager.prepareOffsets(this, event); | |
7646 } | |
7647 } | |
7648 | |
7649 //Regenerate the absolute position used for position checks | |
7650 this.positionAbs = this._convertPositionTo("absolute"); | |
7651 | |
7652 //Set the helper position | |
7653 if(!this.options.axis || this.options.axis !== "y") { | |
7654 this.helper[0].style.left = this.position.left+"px"; | |
7655 } | |
7656 if(!this.options.axis || this.options.axis !== "x") { | |
7657 this.helper[0].style.top = this.position.top+"px"; | |
7658 } | |
7659 | |
7660 //Rearrange | |
7661 for (i = this.items.length - 1; i >= 0; i--) { | |
7662 | |
7663 //Cache variables and intersection, continue if no intersection | |
7664 item = this.items[i]; | |
7665 itemElement = item.item[0]; | |
7666 intersection = this._intersectsWithPointer(item); | |
7667 if (!intersection) { | |
7668 continue; | |
7669 } | |
7670 | |
7671 // Only put the placeholder inside the current Container, skip all | |
7672 // items form other containers. This works because when moving | |
7673 // an item from one container to another the | |
7674 // currentContainer is switched before the placeholder is moved. | |
7675 // | |
7676 // Without this moving items in "sub-sortables" can cause the placeholder to jitter | |
7677 // beetween the outer and inner container. | |
7678 if (item.instance !== this.currentContainer) { | |
7679 continue; | |
7680 } | |
7681 | |
7682 // cannot intersect with itself | |
7683 // no useless actions that have been done before | |
7684 // no action if the item moved is the parent of the item checked | |
7685 if (itemElement !== this.currentItem[0] && | |
7686 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && | |
7687 !$.contains(this.placeholder[0], itemElement) && | |
7688 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) | |
7689 ) { | |
7690 | |
7691 this.direction = intersection === 1 ? "down" : "up"; | |
7692 | |
7693 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { | |
7694 this._rearrange(event, item); | |
7695 } else { | |
7696 break; | |
7697 } | |
7698 | |
7699 this._trigger("change", event, this._uiHash()); | |
7700 break; | |
7701 } | |
7702 } | |
7703 | |
7704 //Post events to containers | |
7705 this._contactContainers(event); | |
7706 | |
7707 //Interconnect with droppables | |
7708 if($.ui.ddmanager) { | |
7709 $.ui.ddmanager.drag(this, event); | |
7710 } | |
7711 | |
7712 //Call callbacks | |
7713 this._trigger("sort", event, this._uiHash()); | |
7714 | |
7715 this.lastPositionAbs = this.positionAbs; | |
7716 return false; | |
7717 | |
7718 }, | |
7719 | |
7720 _mouseStop: function(event, noPropagation) { | |
7721 | |
7722 if(!event) { | |
7723 return; | |
7724 } | |
7725 | |
7726 //If we are using droppables, inform the manager about the drop | |
7727 if ($.ui.ddmanager && !this.options.dropBehaviour) { | |
7728 $.ui.ddmanager.drop(this, event); | |
7729 } | |
7730 | |
7731 if(this.options.revert) { | |
7732 var that = this, | |
7733 cur = this.placeholder.offset(), | |
7734 axis = this.options.axis, | |
7735 animation = {}; | |
7736 | |
7737 if ( !axis || axis === "x" ) { | |
7738 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); | |
7739 } | |
7740 if ( !axis || axis === "y" ) { | |
7741 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); | |
7742 } | |
7743 this.reverting = true; | |
7744 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { | |
7745 that._clear(event); | |
7746 }); | |
7747 } else { | |
7748 this._clear(event, noPropagation); | |
7749 } | |
7750 | |
7751 return false; | |
7752 | |
7753 }, | |
7754 | |
7755 cancel: function() { | |
7756 | |
7757 if(this.dragging) { | |
7758 | |
7759 this._mouseUp({ target: null }); | |
7760 | |
7761 if(this.options.helper === "original") { | |
7762 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); | |
7763 } else { | |
7764 this.currentItem.show(); | |
7765 } | |
7766 | |
7767 //Post deactivating events to containers | |
7768 for (var i = this.containers.length - 1; i >= 0; i--){ | |
7769 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); | |
7770 if(this.containers[i].containerCache.over) { | |
7771 this.containers[i]._trigger("out", null, this._uiHash(this)); | |
7772 this.containers[i].containerCache.over = 0; | |
7773 } | |
7774 } | |
7775 | |
7776 } | |
7777 | |
7778 if (this.placeholder) { | |
7779 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! | |
7780 if(this.placeholder[0].parentNode) { | |
7781 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); | |
7782 } | |
7783 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { | |
7784 this.helper.remove(); | |
7785 } | |
7786 | |
7787 $.extend(this, { | |
7788 helper: null, | |
7789 dragging: false, | |
7790 reverting: false, | |
7791 _noFinalSort: null | |
7792 }); | |
7793 | |
7794 if(this.domPosition.prev) { | |
7795 $(this.domPosition.prev).after(this.currentItem); | |
7796 } else { | |
7797 $(this.domPosition.parent).prepend(this.currentItem); | |
7798 } | |
7799 } | |
7800 | |
7801 return this; | |
7802 | |
7803 }, | |
7804 | |
7805 serialize: function(o) { | |
7806 | |
7807 var items = this._getItemsAsjQuery(o && o.connected), | |
7808 str = []; | |
7809 o = o || {}; | |
7810 | |
7811 $(items).each(function() { | |
7812 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); | |
7813 if (res) { | |
7814 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); | |
7815 } | |
7816 }); | |
7817 | |
7818 if(!str.length && o.key) { | |
7819 str.push(o.key + "="); | |
7820 } | |
7821 | |
7822 return str.join("&"); | |
7823 | |
7824 }, | |
7825 | |
7826 toArray: function(o) { | |
7827 | |
7828 var items = this._getItemsAsjQuery(o && o.connected), | |
7829 ret = []; | |
7830 | |
7831 o = o || {}; | |
7832 | |
7833 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); | |
7834 return ret; | |
7835 | |
7836 }, | |
7837 | |
7838 /* Be careful with the following core functions */ | |
7839 _intersectsWith: function(item) { | |
7840 | |
7841 var x1 = this.positionAbs.left, | |
7842 x2 = x1 + this.helperProportions.width, | |
7843 y1 = this.positionAbs.top, | |
7844 y2 = y1 + this.helperProportions.height, | |
7845 l = item.left, | |
7846 r = l + item.width, | |
7847 t = item.top, | |
7848 b = t + item.height, | |
7849 dyClick = this.offset.click.top, | |
7850 dxClick = this.offset.click.left, | |
7851 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), | |
7852 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), | |
7853 isOverElement = isOverElementHeight && isOverElementWidth; | |
7854 | |
7855 if ( this.options.tolerance === "pointer" || | |
7856 this.options.forcePointerForContainers || | |
7857 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) | |
7858 ) { | |
7859 return isOverElement; | |
7860 } else { | |
7861 | |
7862 return (l < x1 + (this.helperProportions.width / 2) && // Right Half | |
7863 x2 - (this.helperProportions.width / 2) < r && // Left Half | |
7864 t < y1 + (this.helperProportions.height / 2) && // Bottom Half | |
7865 y2 - (this.helperProportions.height / 2) < b ); // Top Half | |
7866 | |
7867 } | |
7868 }, | |
7869 | |
7870 _intersectsWithPointer: function(item) { | |
7871 | |
7872 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), | |
7873 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), | |
7874 isOverElement = isOverElementHeight && isOverElementWidth, | |
7875 verticalDirection = this._getDragVerticalDirection(), | |
7876 horizontalDirection = this._getDragHorizontalDirection(); | |
7877 | |
7878 if (!isOverElement) { | |
7879 return false; | |
7880 } | |
7881 | |
7882 return this.floating ? | |
7883 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) | |
7884 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); | |
7885 | |
7886 }, | |
7887 | |
7888 _intersectsWithSides: function(item) { | |
7889 | |
7890 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), | |
7891 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), | |
7892 verticalDirection = this._getDragVerticalDirection(), | |
7893 horizontalDirection = this._getDragHorizontalDirection(); | |
7894 | |
7895 if (this.floating && horizontalDirection) { | |
7896 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); | |
7897 } else { | |
7898 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); | |
7899 } | |
7900 | |
7901 }, | |
7902 | |
7903 _getDragVerticalDirection: function() { | |
7904 var delta = this.positionAbs.top - this.lastPositionAbs.top; | |
7905 return delta !== 0 && (delta > 0 ? "down" : "up"); | |
7906 }, | |
7907 | |
7908 _getDragHorizontalDirection: function() { | |
7909 var delta = this.positionAbs.left - this.lastPositionAbs.left; | |
7910 return delta !== 0 && (delta > 0 ? "right" : "left"); | |
7911 }, | |
7912 | |
7913 refresh: function(event) { | |
7914 this._refreshItems(event); | |
7915 this.refreshPositions(); | |
7916 return this; | |
7917 }, | |
7918 | |
7919 _connectWith: function() { | |
7920 var options = this.options; | |
7921 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; | |
7922 }, | |
7923 | |
7924 _getItemsAsjQuery: function(connected) { | |
7925 | |
7926 var i, j, cur, inst, | |
7927 items = [], | |
7928 queries = [], | |
7929 connectWith = this._connectWith(); | |
7930 | |
7931 if(connectWith && connected) { | |
7932 for (i = connectWith.length - 1; i >= 0; i--){ | |
7933 cur = $(connectWith[i]); | |
7934 for ( j = cur.length - 1; j >= 0; j--){ | |
7935 inst = $.data(cur[j], this.widgetFullName); | |
7936 if(inst && inst !== this && !inst.options.disabled) { | |
7937 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]); | |
7938 } | |
7939 } | |
7940 } | |
7941 } | |
7942 | |
7943 queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]); | |
7944 | |
7945 for (i = queries.length - 1; i >= 0; i--){ | |
7946 queries[i][0].each(function() { | |
7947 items.push(this); | |
7948 }); | |
7949 } | |
7950 | |
7951 return $(items); | |
7952 | |
7953 }, | |
7954 | |
7955 _removeCurrentsFromItems: function() { | |
7956 | |
7957 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); | |
7958 | |
7959 this.items = $.grep(this.items, function (item) { | |
7960 for (var j=0; j < list.length; j++) { | |
7961 if(list[j] === item.item[0]) { | |
7962 return false; | |
7963 } | |
7964 } | |
7965 return true; | |
7966 }); | |
7967 | |
7968 }, | |
7969 | |
7970 _refreshItems: function(event) { | |
7971 | |
7972 this.items = []; | |
7973 this.containers = [this]; | |
7974 | |
7975 var i, j, cur, inst, targetData, _queries, item, queriesLength, | |
7976 items = this.items, | |
7977 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], | |
7978 connectWith = this._connectWith(); | |
7979 | |
7980 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down | |
7981 for (i = connectWith.length - 1; i >= 0; i--){ | |
7982 cur = $(connectWith[i]); | |
7983 for (j = cur.length - 1; j >= 0; j--){ | |
7984 inst = $.data(cur[j], this.widgetFullName); | |
7985 if(inst && inst !== this && !inst.options.disabled) { | |
7986 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); | |
7987 this.containers.push(inst); | |
7988 } | |
7989 } | |
7990 } | |
7991 } | |
7992 | |
7993 for (i = queries.length - 1; i >= 0; i--) { | |
7994 targetData = queries[i][1]; | |
7995 _queries = queries[i][0]; | |
7996 | |
7997 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { | |
7998 item = $(_queries[j]); | |
7999 | |
8000 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) | |
8001 | |
8002 items.push({ | |
8003 item: item, | |
8004 instance: targetData, | |
8005 width: 0, height: 0, | |
8006 left: 0, top: 0 | |
8007 }); | |
8008 } | |
8009 } | |
8010 | |
8011 }, | |
8012 | |
8013 refreshPositions: function(fast) { | |
8014 | |
8015 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change | |
8016 if(this.offsetParent && this.helper) { | |
8017 this.offset.parent = this._getParentOffset(); | |
8018 } | |
8019 | |
8020 var i, item, t, p; | |
8021 | |
8022 for (i = this.items.length - 1; i >= 0; i--){ | |
8023 item = this.items[i]; | |
8024 | |
8025 //We ignore calculating positions of all connected containers when we're not over them | |
8026 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { | |
8027 continue; | |
8028 } | |
8029 | |
8030 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; | |
8031 | |
8032 if (!fast) { | |
8033 item.width = t.outerWidth(); | |
8034 item.height = t.outerHeight(); | |
8035 } | |
8036 | |
8037 p = t.offset(); | |
8038 item.left = p.left; | |
8039 item.top = p.top; | |
8040 } | |
8041 | |
8042 if(this.options.custom && this.options.custom.refreshContainers) { | |
8043 this.options.custom.refreshContainers.call(this); | |
8044 } else { | |
8045 for (i = this.containers.length - 1; i >= 0; i--){ | |
8046 p = this.containers[i].element.offset(); | |
8047 this.containers[i].containerCache.left = p.left; | |
8048 this.containers[i].containerCache.top = p.top; | |
8049 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); | |
8050 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); | |
8051 } | |
8052 } | |
8053 | |
8054 return this; | |
8055 }, | |
8056 | |
8057 _createPlaceholder: function(that) { | |
8058 that = that || this; | |
8059 var className, | |
8060 o = that.options; | |
8061 | |
8062 if(!o.placeholder || o.placeholder.constructor === String) { | |
8063 className = o.placeholder; | |
8064 o.placeholder = { | |
8065 element: function() { | |
8066 | |
8067 var nodeName = that.currentItem[0].nodeName.toLowerCase(), | |
8068 element = $( "<" + nodeName + ">", that.document[0] ) | |
8069 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") | |
8070 .removeClass("ui-sortable-helper"); | |
8071 | |
8072 if ( nodeName === "tr" ) { | |
8073 that.currentItem.children().each(function() { | |
8074 $( "<td> </td>", that.document[0] ) | |
8075 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) | |
8076 .appendTo( element ); | |
8077 }); | |
8078 } else if ( nodeName === "img" ) { | |
8079 element.attr( "src", that.currentItem.attr( "src" ) ); | |
8080 } | |
8081 | |
8082 if ( !className ) { | |
8083 element.css( "visibility", "hidden" ); | |
8084 } | |
8085 | |
8086 return element; | |
8087 }, | |
8088 update: function(container, p) { | |
8089 | |
8090 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that | |
8091 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified | |
8092 if(className && !o.forcePlaceholderSize) { | |
8093 return; | |
8094 } | |
8095 | |
8096 //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item | |
8097 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } | |
8098 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } | |
8099 } | |
8100 }; | |
8101 } | |
8102 | |
8103 //Create the placeholder | |
8104 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); | |
8105 | |
8106 //Append it after the actual current item | |
8107 that.currentItem.after(that.placeholder); | |
8108 | |
8109 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) | |
8110 o.placeholder.update(that, that.placeholder); | |
8111 | |
8112 }, | |
8113 | |
8114 _contactContainers: function(event) { | |
8115 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, | |
8116 innermostContainer = null, | |
8117 innermostIndex = null; | |
8118 | |
8119 // get innermost container that intersects with item | |
8120 for (i = this.containers.length - 1; i >= 0; i--) { | |
8121 | |
8122 // never consider a container that's located within the item itself | |
8123 if($.contains(this.currentItem[0], this.containers[i].element[0])) { | |
8124 continue; | |
8125 } | |
8126 | |
8127 if(this._intersectsWith(this.containers[i].containerCache)) { | |
8128 | |
8129 // if we've already found a container and it's more "inner" than this, then continue | |
8130 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { | |
8131 continue; | |
8132 } | |
8133 | |
8134 innermostContainer = this.containers[i]; | |
8135 innermostIndex = i; | |
8136 | |
8137 } else { | |
8138 // container doesn't intersect. trigger "out" event if necessary | |
8139 if(this.containers[i].containerCache.over) { | |
8140 this.containers[i]._trigger("out", event, this._uiHash(this)); | |
8141 this.containers[i].containerCache.over = 0; | |
8142 } | |
8143 } | |
8144 | |
8145 } | |
8146 | |
8147 // if no intersecting containers found, return | |
8148 if(!innermostContainer) { | |
8149 return; | |
8150 } | |
8151 | |
8152 // move the item into the container if it's not there already | |
8153 if(this.containers.length === 1) { | |
8154 if (!this.containers[innermostIndex].containerCache.over) { | |
8155 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); | |
8156 this.containers[innermostIndex].containerCache.over = 1; | |
8157 } | |
8158 } else { | |
8159 | |
8160 //When entering a new container, we will find the item with the least distance and append our item near it | |
8161 dist = 10000; | |
8162 itemWithLeastDistance = null; | |
8163 floating = innermostContainer.floating || isFloating(this.currentItem); | |
8164 posProperty = floating ? "left" : "top"; | |
8165 sizeProperty = floating ? "width" : "height"; | |
8166 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; | |
8167 for (j = this.items.length - 1; j >= 0; j--) { | |
8168 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { | |
8169 continue; | |
8170 } | |
8171 if(this.items[j].item[0] === this.currentItem[0]) { | |
8172 continue; | |
8173 } | |
8174 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { | |
8175 continue; | |
8176 } | |
8177 cur = this.items[j].item.offset()[posProperty]; | |
8178 nearBottom = false; | |
8179 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ | |
8180 nearBottom = true; | |
8181 cur += this.items[j][sizeProperty]; | |
8182 } | |
8183 | |
8184 if(Math.abs(cur - base) < dist) { | |
8185 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; | |
8186 this.direction = nearBottom ? "up": "down"; | |
8187 } | |
8188 } | |
8189 | |
8190 //Check if dropOnEmpty is enabled | |
8191 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { | |
8192 return; | |
8193 } | |
8194 | |
8195 if(this.currentContainer === this.containers[innermostIndex]) { | |
8196 return; | |
8197 } | |
8198 | |
8199 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); | |
8200 this._trigger("change", event, this._uiHash()); | |
8201 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); | |
8202 this.currentContainer = this.containers[innermostIndex]; | |
8203 | |
8204 //Update the placeholder | |
8205 this.options.placeholder.update(this.currentContainer, this.placeholder); | |
8206 | |
8207 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); | |
8208 this.containers[innermostIndex].containerCache.over = 1; | |
8209 } | |
8210 | |
8211 | |
8212 }, | |
8213 | |
8214 _createHelper: function(event) { | |
8215 | |
8216 var o = this.options, | |
8217 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); | |
8218 | |
8219 //Add the helper to the DOM if that didn't happen already | |
8220 if(!helper.parents("body").length) { | |
8221 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); | |
8222 } | |
8223 | |
8224 if(helper[0] === this.currentItem[0]) { | |
8225 this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; | |
8226 } | |
8227 | |
8228 if(!helper[0].style.width || o.forceHelperSize) { | |
8229 helper.width(this.currentItem.width()); | |
8230 } | |
8231 if(!helper[0].style.height || o.forceHelperSize) { | |
8232 helper.height(this.currentItem.height()); | |
8233 } | |
8234 | |
8235 return helper; | |
8236 | |
8237 }, | |
8238 | |
8239 _adjustOffsetFromHelper: function(obj) { | |
8240 if (typeof obj === "string") { | |
8241 obj = obj.split(" "); | |
8242 } | |
8243 if ($.isArray(obj)) { | |
8244 obj = {left: +obj[0], top: +obj[1] || 0}; | |
8245 } | |
8246 if ("left" in obj) { | |
8247 this.offset.click.left = obj.left + this.margins.left; | |
8248 } | |
8249 if ("right" in obj) { | |
8250 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; | |
8251 } | |
8252 if ("top" in obj) { | |
8253 this.offset.click.top = obj.top + this.margins.top; | |
8254 } | |
8255 if ("bottom" in obj) { | |
8256 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; | |
8257 } | |
8258 }, | |
8259 | |
8260 _getParentOffset: function() { | |
8261 | |
8262 | |
8263 //Get the offsetParent and cache its position | |
8264 this.offsetParent = this.helper.offsetParent(); | |
8265 var po = this.offsetParent.offset(); | |
8266 | |
8267 // This is a special case where we need to modify a offset calculated on start, since the following happened: | |
8268 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent | |
8269 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that | |
8270 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag | |
8271 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { | |
8272 po.left += this.scrollParent.scrollLeft(); | |
8273 po.top += this.scrollParent.scrollTop(); | |
8274 } | |
8275 | |
8276 // This needs to be actually done for all browsers, since pageX/pageY includes this information | |
8277 // with an ugly IE fix | |
8278 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { | |
8279 po = { top: 0, left: 0 }; | |
8280 } | |
8281 | |
8282 return { | |
8283 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), | |
8284 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) | |
8285 }; | |
8286 | |
8287 }, | |
8288 | |
8289 _getRelativeOffset: function() { | |
8290 | |
8291 if(this.cssPosition === "relative") { | |
8292 var p = this.currentItem.position(); | |
8293 return { | |
8294 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), | |
8295 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() | |
8296 }; | |
8297 } else { | |
8298 return { top: 0, left: 0 }; | |
8299 } | |
8300 | |
8301 }, | |
8302 | |
8303 _cacheMargins: function() { | |
8304 this.margins = { | |
8305 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), | |
8306 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) | |
8307 }; | |
8308 }, | |
8309 | |
8310 _cacheHelperProportions: function() { | |
8311 this.helperProportions = { | |
8312 width: this.helper.outerWidth(), | |
8313 height: this.helper.outerHeight() | |
8314 }; | |
8315 }, | |
8316 | |
8317 _setContainment: function() { | |
8318 | |
8319 var ce, co, over, | |
8320 o = this.options; | |
8321 if(o.containment === "parent") { | |
8322 o.containment = this.helper[0].parentNode; | |
8323 } | |
8324 if(o.containment === "document" || o.containment === "window") { | |
8325 this.containment = [ | |
8326 0 - this.offset.relative.left - this.offset.parent.left, | |
8327 0 - this.offset.relative.top - this.offset.parent.top, | |
8328 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, | |
8329 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top | |
8330 ]; | |
8331 } | |
8332 | |
8333 if(!(/^(document|window|parent)$/).test(o.containment)) { | |
8334 ce = $(o.containment)[0]; | |
8335 co = $(o.containment).offset(); | |
8336 over = ($(ce).css("overflow") !== "hidden"); | |
8337 | |
8338 this.containment = [ | |
8339 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, | |
8340 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, | |
8341 co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, | |
8342 co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top | |
8343 ]; | |
8344 } | |
8345 | |
8346 }, | |
8347 | |
8348 _convertPositionTo: function(d, pos) { | |
8349 | |
8350 if(!pos) { | |
8351 pos = this.position; | |
8352 } | |
8353 var mod = d === "absolute" ? 1 : -1, | |
8354 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, | |
8355 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); | |
8356 | |
8357 return { | |
8358 top: ( | |
8359 pos.top + // The absolute mouse position | |
8360 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
8361 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) | |
8362 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) | |
8363 ), | |
8364 left: ( | |
8365 pos.left + // The absolute mouse position | |
8366 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
8367 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) | |
8368 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) | |
8369 ) | |
8370 }; | |
8371 | |
8372 }, | |
8373 | |
8374 _generatePosition: function(event) { | |
8375 | |
8376 var top, left, | |
8377 o = this.options, | |
8378 pageX = event.pageX, | |
8379 pageY = event.pageY, | |
8380 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); | |
8381 | |
8382 // This is another very weird special case that only happens for relative elements: | |
8383 // 1. If the css position is relative | |
8384 // 2. and the scroll parent is the document or similar to the offset parent | |
8385 // we have to refresh the relative offset during the scroll so there are no jumps | |
8386 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { | |
8387 this.offset.relative = this._getRelativeOffset(); | |
8388 } | |
8389 | |
8390 /* | |
8391 * - Position constraining - | |
8392 * Constrain the position to a mix of grid, containment. | |
8393 */ | |
8394 | |
8395 if(this.originalPosition) { //If we are not dragging yet, we won't check for options | |
8396 | |
8397 if(this.containment) { | |
8398 if(event.pageX - this.offset.click.left < this.containment[0]) { | |
8399 pageX = this.containment[0] + this.offset.click.left; | |
8400 } | |
8401 if(event.pageY - this.offset.click.top < this.containment[1]) { | |
8402 pageY = this.containment[1] + this.offset.click.top; | |
8403 } | |
8404 if(event.pageX - this.offset.click.left > this.containment[2]) { | |
8405 pageX = this.containment[2] + this.offset.click.left; | |
8406 } | |
8407 if(event.pageY - this.offset.click.top > this.containment[3]) { | |
8408 pageY = this.containment[3] + this.offset.click.top; | |
8409 } | |
8410 } | |
8411 | |
8412 if(o.grid) { | |
8413 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; | |
8414 pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; | |
8415 | |
8416 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; | |
8417 pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; | |
8418 } | |
8419 | |
8420 } | |
8421 | |
8422 return { | |
8423 top: ( | |
8424 pageY - // The absolute mouse position | |
8425 this.offset.click.top - // Click offset (relative to the element) | |
8426 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent | |
8427 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) | |
8428 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) | |
8429 ), | |
8430 left: ( | |
8431 pageX - // The absolute mouse position | |
8432 this.offset.click.left - // Click offset (relative to the element) | |
8433 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent | |
8434 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) | |
8435 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) | |
8436 ) | |
8437 }; | |
8438 | |
8439 }, | |
8440 | |
8441 _rearrange: function(event, i, a, hardRefresh) { | |
8442 | |
8443 a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling)); | |
8444 | |
8445 //Various things done here to improve the performance: | |
8446 // 1. we create a setTimeout, that calls refreshPositions | |
8447 // 2. on the instance, we have a counter variable, that get's higher after every append | |
8448 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same | |
8449 // 4. this lets only the last addition to the timeout stack through | |
8450 this.counter = this.counter ? ++this.counter : 1; | |
8451 var counter = this.counter; | |
8452 | |
8453 this._delay(function() { | |
8454 if(counter === this.counter) { | |
8455 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove | |
8456 } | |
8457 }); | |
8458 | |
8459 }, | |
8460 | |
8461 _clear: function(event, noPropagation) { | |
8462 | |
8463 this.reverting = false; | |
8464 // We delay all events that have to be triggered to after the point where the placeholder has been removed and | |
8465 // everything else normalized again | |
8466 var i, | |
8467 delayedTriggers = []; | |
8468 | |
8469 // We first have to update the dom position of the actual currentItem | |
8470 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) | |
8471 if(!this._noFinalSort && this.currentItem.parent().length) { | |
8472 this.placeholder.before(this.currentItem); | |
8473 } | |
8474 this._noFinalSort = null; | |
8475 | |
8476 if(this.helper[0] === this.currentItem[0]) { | |
8477 for(i in this._storedCSS) { | |
8478 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { | |
8479 this._storedCSS[i] = ""; | |
8480 } | |
8481 } | |
8482 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); | |
8483 } else { | |
8484 this.currentItem.show(); | |
8485 } | |
8486 | |
8487 if(this.fromOutside && !noPropagation) { | |
8488 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); | |
8489 } | |
8490 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { | |
8491 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed | |
8492 } | |
8493 | |
8494 // Check if the items Container has Changed and trigger appropriate | |
8495 // events. | |
8496 if (this !== this.currentContainer) { | |
8497 if(!noPropagation) { | |
8498 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); | |
8499 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); | |
8500 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); | |
8501 } | |
8502 } | |
8503 | |
8504 | |
8505 //Post events to containers | |
8506 for (i = this.containers.length - 1; i >= 0; i--){ | |
8507 if(!noPropagation) { | |
8508 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); | |
8509 } | |
8510 if(this.containers[i].containerCache.over) { | |
8511 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); | |
8512 this.containers[i].containerCache.over = 0; | |
8513 } | |
8514 } | |
8515 | |
8516 //Do what was originally in plugins | |
8517 if ( this.storedCursor ) { | |
8518 this.document.find( "body" ).css( "cursor", this.storedCursor ); | |
8519 this.storedStylesheet.remove(); | |
8520 } | |
8521 if(this._storedOpacity) { | |
8522 this.helper.css("opacity", this._storedOpacity); | |
8523 } | |
8524 if(this._storedZIndex) { | |
8525 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); | |
8526 } | |
8527 | |
8528 this.dragging = false; | |
8529 if(this.cancelHelperRemoval) { | |
8530 if(!noPropagation) { | |
8531 this._trigger("beforeStop", event, this._uiHash()); | |
8532 for (i=0; i < delayedTriggers.length; i++) { | |
8533 delayedTriggers[i].call(this, event); | |
8534 } //Trigger all delayed events | |
8535 this._trigger("stop", event, this._uiHash()); | |
8536 } | |
8537 | |
8538 this.fromOutside = false; | |
8539 return false; | |
8540 } | |
8541 | |
8542 if(!noPropagation) { | |
8543 this._trigger("beforeStop", event, this._uiHash()); | |
8544 } | |
8545 | |
8546 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! | |
8547 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); | |
8548 | |
8549 if(this.helper[0] !== this.currentItem[0]) { | |
8550 this.helper.remove(); | |
8551 } | |
8552 this.helper = null; | |
8553 | |
8554 if(!noPropagation) { | |
8555 for (i=0; i < delayedTriggers.length; i++) { | |
8556 delayedTriggers[i].call(this, event); | |
8557 } //Trigger all delayed events | |
8558 this._trigger("stop", event, this._uiHash()); | |
8559 } | |
8560 | |
8561 this.fromOutside = false; | |
8562 return true; | |
8563 | |
8564 }, | |
8565 | |
8566 _trigger: function() { | |
8567 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { | |
8568 this.cancel(); | |
8569 } | |
8570 }, | |
8571 | |
8572 _uiHash: function(_inst) { | |
8573 var inst = _inst || this; | |
8574 return { | |
8575 helper: inst.helper, | |
8576 placeholder: inst.placeholder || $([]), | |
8577 position: inst.position, | |
8578 originalPosition: inst.originalPosition, | |
8579 offset: inst.positionAbs, | |
8580 item: inst.currentItem, | |
8581 sender: _inst ? _inst.element : null | |
8582 }; | |
8583 } | |
8584 | |
8585 }); | |
8586 | |
8587 })(jQuery); | |
8588 (function( $, undefined ) { | |
8589 | |
8590 var uid = 0, | |
8591 hideProps = {}, | |
8592 showProps = {}; | |
8593 | |
8594 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = | |
8595 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; | |
8596 showProps.height = showProps.paddingTop = showProps.paddingBottom = | |
8597 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; | |
8598 | |
8599 $.widget( "ui.accordion", { | |
8600 version: "1.10.3", | |
8601 options: { | |
8602 active: 0, | |
8603 animate: {}, | |
8604 collapsible: false, | |
8605 event: "click", | |
8606 header: "> li > :first-child,> :not(li):even", | |
8607 heightStyle: "auto", | |
8608 icons: { | |
8609 activeHeader: "ui-icon-triangle-1-s", | |
8610 header: "ui-icon-triangle-1-e" | |
8611 }, | |
8612 | |
8613 // callbacks | |
8614 activate: null, | |
8615 beforeActivate: null | |
8616 }, | |
8617 | |
8618 _create: function() { | |
8619 var options = this.options; | |
8620 this.prevShow = this.prevHide = $(); | |
8621 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) | |
8622 // ARIA | |
8623 .attr( "role", "tablist" ); | |
8624 | |
8625 // don't allow collapsible: false and active: false / null | |
8626 if ( !options.collapsible && (options.active === false || options.active == null) ) { | |
8627 options.active = 0; | |
8628 } | |
8629 | |
8630 this._processPanels(); | |
8631 // handle negative values | |
8632 if ( options.active < 0 ) { | |
8633 options.active += this.headers.length; | |
8634 } | |
8635 this._refresh(); | |
8636 }, | |
8637 | |
8638 _getCreateEventData: function() { | |
8639 return { | |
8640 header: this.active, | |
8641 panel: !this.active.length ? $() : this.active.next(), | |
8642 content: !this.active.length ? $() : this.active.next() | |
8643 }; | |
8644 }, | |
8645 | |
8646 _createIcons: function() { | |
8647 var icons = this.options.icons; | |
8648 if ( icons ) { | |
8649 $( "<span>" ) | |
8650 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) | |
8651 .prependTo( this.headers ); | |
8652 this.active.children( ".ui-accordion-header-icon" ) | |
8653 .removeClass( icons.header ) | |
8654 .addClass( icons.activeHeader ); | |
8655 this.headers.addClass( "ui-accordion-icons" ); | |
8656 } | |
8657 }, | |
8658 | |
8659 _destroyIcons: function() { | |
8660 this.headers | |
8661 .removeClass( "ui-accordion-icons" ) | |
8662 .children( ".ui-accordion-header-icon" ) | |
8663 .remove(); | |
8664 }, | |
8665 | |
8666 _destroy: function() { | |
8667 var contents; | |
8668 | |
8669 // clean up main element | |
8670 this.element | |
8671 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) | |
8672 .removeAttr( "role" ); | |
8673 | |
8674 // clean up headers | |
8675 this.headers | |
8676 .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) | |
8677 .removeAttr( "role" ) | |
8678 .removeAttr( "aria-selected" ) | |
8679 .removeAttr( "aria-controls" ) | |
8680 .removeAttr( "tabIndex" ) | |
8681 .each(function() { | |
8682 if ( /^ui-accordion/.test( this.id ) ) { | |
8683 this.removeAttribute( "id" ); | |
8684 } | |
8685 }); | |
8686 this._destroyIcons(); | |
8687 | |
8688 // clean up content panels | |
8689 contents = this.headers.next() | |
8690 .css( "display", "" ) | |
8691 .removeAttr( "role" ) | |
8692 .removeAttr( "aria-expanded" ) | |
8693 .removeAttr( "aria-hidden" ) | |
8694 .removeAttr( "aria-labelledby" ) | |
8695 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) | |
8696 .each(function() { | |
8697 if ( /^ui-accordion/.test( this.id ) ) { | |
8698 this.removeAttribute( "id" ); | |
8699 } | |
8700 }); | |
8701 if ( this.options.heightStyle !== "content" ) { | |
8702 contents.css( "height", "" ); | |
8703 } | |
8704 }, | |
8705 | |
8706 _setOption: function( key, value ) { | |
8707 if ( key === "active" ) { | |
8708 // _activate() will handle invalid values and update this.options | |
8709 this._activate( value ); | |
8710 return; | |
8711 } | |
8712 | |
8713 if ( key === "event" ) { | |
8714 if ( this.options.event ) { | |
8715 this._off( this.headers, this.options.event ); | |
8716 } | |
8717 this._setupEvents( value ); | |
8718 } | |
8719 | |
8720 this._super( key, value ); | |
8721 | |
8722 // setting collapsible: false while collapsed; open first panel | |
8723 if ( key === "collapsible" && !value && this.options.active === false ) { | |
8724 this._activate( 0 ); | |
8725 } | |
8726 | |
8727 if ( key === "icons" ) { | |
8728 this._destroyIcons(); | |
8729 if ( value ) { | |
8730 this._createIcons(); | |
8731 } | |
8732 } | |
8733 | |
8734 // #5332 - opacity doesn't cascade to positioned elements in IE | |
8735 // so we need to add the disabled class to the headers and panels | |
8736 if ( key === "disabled" ) { | |
8737 this.headers.add( this.headers.next() ) | |
8738 .toggleClass( "ui-state-disabled", !!value ); | |
8739 } | |
8740 }, | |
8741 | |
8742 _keydown: function( event ) { | |
8743 /*jshint maxcomplexity:15*/ | |
8744 if ( event.altKey || event.ctrlKey ) { | |
8745 return; | |
8746 } | |
8747 | |
8748 var keyCode = $.ui.keyCode, | |
8749 length = this.headers.length, | |
8750 currentIndex = this.headers.index( event.target ), | |
8751 toFocus = false; | |
8752 | |
8753 switch ( event.keyCode ) { | |
8754 case keyCode.RIGHT: | |
8755 case keyCode.DOWN: | |
8756 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; | |
8757 break; | |
8758 case keyCode.LEFT: | |
8759 case keyCode.UP: | |
8760 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; | |
8761 break; | |
8762 case keyCode.SPACE: | |
8763 case keyCode.ENTER: | |
8764 this._eventHandler( event ); | |
8765 break; | |
8766 case keyCode.HOME: | |
8767 toFocus = this.headers[ 0 ]; | |
8768 break; | |
8769 case keyCode.END: | |
8770 toFocus = this.headers[ length - 1 ]; | |
8771 break; | |
8772 } | |
8773 | |
8774 if ( toFocus ) { | |
8775 $( event.target ).attr( "tabIndex", -1 ); | |
8776 $( toFocus ).attr( "tabIndex", 0 ); | |
8777 toFocus.focus(); | |
8778 event.preventDefault(); | |
8779 } | |
8780 }, | |
8781 | |
8782 _panelKeyDown : function( event ) { | |
8783 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { | |
8784 $( event.currentTarget ).prev().focus(); | |
8785 } | |
8786 }, | |
8787 | |
8788 refresh: function() { | |
8789 var options = this.options; | |
8790 this._processPanels(); | |
8791 | |
8792 // was collapsed or no panel | |
8793 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { | |
8794 options.active = false; | |
8795 this.active = $(); | |
8796 // active false only when collapsible is true | |
8797 } else if ( options.active === false ) { | |
8798 this._activate( 0 ); | |
8799 // was active, but active panel is gone | |
8800 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { | |
8801 // all remaining panel are disabled | |
8802 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { | |
8803 options.active = false; | |
8804 this.active = $(); | |
8805 // activate previous panel | |
8806 } else { | |
8807 this._activate( Math.max( 0, options.active - 1 ) ); | |
8808 } | |
8809 // was active, active panel still exists | |
8810 } else { | |
8811 // make sure active index is correct | |
8812 options.active = this.headers.index( this.active ); | |
8813 } | |
8814 | |
8815 this._destroyIcons(); | |
8816 | |
8817 this._refresh(); | |
8818 }, | |
8819 | |
8820 _processPanels: function() { | |
8821 this.headers = this.element.find( this.options.header ) | |
8822 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); | |
8823 | |
8824 this.headers.next() | |
8825 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) | |
8826 .filter(":not(.ui-accordion-content-active)") | |
8827 .hide(); | |
8828 }, | |
8829 | |
8830 _refresh: function() { | |
8831 var maxHeight, | |
8832 options = this.options, | |
8833 heightStyle = options.heightStyle, | |
8834 parent = this.element.parent(), | |
8835 accordionId = this.accordionId = "ui-accordion-" + | |
8836 (this.element.attr( "id" ) || ++uid); | |
8837 | |
8838 this.active = this._findActive( options.active ) | |
8839 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) | |
8840 .removeClass( "ui-corner-all" ); | |
8841 this.active.next() | |
8842 .addClass( "ui-accordion-content-active" ) | |
8843 .show(); | |
8844 | |
8845 this.headers | |
8846 .attr( "role", "tab" ) | |
8847 .each(function( i ) { | |
8848 var header = $( this ), | |
8849 headerId = header.attr( "id" ), | |
8850 panel = header.next(), | |
8851 panelId = panel.attr( "id" ); | |
8852 if ( !headerId ) { | |
8853 headerId = accordionId + "-header-" + i; | |
8854 header.attr( "id", headerId ); | |
8855 } | |
8856 if ( !panelId ) { | |
8857 panelId = accordionId + "-panel-" + i; | |
8858 panel.attr( "id", panelId ); | |
8859 } | |
8860 header.attr( "aria-controls", panelId ); | |
8861 panel.attr( "aria-labelledby", headerId ); | |
8862 }) | |
8863 .next() | |
8864 .attr( "role", "tabpanel" ); | |
8865 | |
8866 this.headers | |
8867 .not( this.active ) | |
8868 .attr({ | |
8869 "aria-selected": "false", | |
8870 tabIndex: -1 | |
8871 }) | |
8872 .next() | |
8873 .attr({ | |
8874 "aria-expanded": "false", | |
8875 "aria-hidden": "true" | |
8876 }) | |
8877 .hide(); | |
8878 | |
8879 // make sure at least one header is in the tab order | |
8880 if ( !this.active.length ) { | |
8881 this.headers.eq( 0 ).attr( "tabIndex", 0 ); | |
8882 } else { | |
8883 this.active.attr({ | |
8884 "aria-selected": "true", | |
8885 tabIndex: 0 | |
8886 }) | |
8887 .next() | |
8888 .attr({ | |
8889 "aria-expanded": "true", | |
8890 "aria-hidden": "false" | |
8891 }); | |
8892 } | |
8893 | |
8894 this._createIcons(); | |
8895 | |
8896 this._setupEvents( options.event ); | |
8897 | |
8898 if ( heightStyle === "fill" ) { | |
8899 maxHeight = parent.height(); | |
8900 this.element.siblings( ":visible" ).each(function() { | |
8901 var elem = $( this ), | |
8902 position = elem.css( "position" ); | |
8903 | |
8904 if ( position === "absolute" || position === "fixed" ) { | |
8905 return; | |
8906 } | |
8907 maxHeight -= elem.outerHeight( true ); | |
8908 }); | |
8909 | |
8910 this.headers.each(function() { | |
8911 maxHeight -= $( this ).outerHeight( true ); | |
8912 }); | |
8913 | |
8914 this.headers.next() | |
8915 .each(function() { | |
8916 $( this ).height( Math.max( 0, maxHeight - | |
8917 $( this ).innerHeight() + $( this ).height() ) ); | |
8918 }) | |
8919 .css( "overflow", "auto" ); | |
8920 } else if ( heightStyle === "auto" ) { | |
8921 maxHeight = 0; | |
8922 this.headers.next() | |
8923 .each(function() { | |
8924 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); | |
8925 }) | |
8926 .height( maxHeight ); | |
8927 } | |
8928 }, | |
8929 | |
8930 _activate: function( index ) { | |
8931 var active = this._findActive( index )[ 0 ]; | |
8932 | |
8933 // trying to activate the already active panel | |
8934 if ( active === this.active[ 0 ] ) { | |
8935 return; | |
8936 } | |
8937 | |
8938 // trying to collapse, simulate a click on the currently active header | |
8939 active = active || this.active[ 0 ]; | |
8940 | |
8941 this._eventHandler({ | |
8942 target: active, | |
8943 currentTarget: active, | |
8944 preventDefault: $.noop | |
8945 }); | |
8946 }, | |
8947 | |
8948 _findActive: function( selector ) { | |
8949 return typeof selector === "number" ? this.headers.eq( selector ) : $(); | |
8950 }, | |
8951 | |
8952 _setupEvents: function( event ) { | |
8953 var events = { | |
8954 keydown: "_keydown" | |
8955 }; | |
8956 if ( event ) { | |
8957 $.each( event.split(" "), function( index, eventName ) { | |
8958 events[ eventName ] = "_eventHandler"; | |
8959 }); | |
8960 } | |
8961 | |
8962 this._off( this.headers.add( this.headers.next() ) ); | |
8963 this._on( this.headers, events ); | |
8964 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); | |
8965 this._hoverable( this.headers ); | |
8966 this._focusable( this.headers ); | |
8967 }, | |
8968 | |
8969 _eventHandler: function( event ) { | |
8970 var options = this.options, | |
8971 active = this.active, | |
8972 clicked = $( event.currentTarget ), | |
8973 clickedIsActive = clicked[ 0 ] === active[ 0 ], | |
8974 collapsing = clickedIsActive && options.collapsible, | |
8975 toShow = collapsing ? $() : clicked.next(), | |
8976 toHide = active.next(), | |
8977 eventData = { | |
8978 oldHeader: active, | |
8979 oldPanel: toHide, | |
8980 newHeader: collapsing ? $() : clicked, | |
8981 newPanel: toShow | |
8982 }; | |
8983 | |
8984 event.preventDefault(); | |
8985 | |
8986 if ( | |
8987 // click on active header, but not collapsible | |
8988 ( clickedIsActive && !options.collapsible ) || | |
8989 // allow canceling activation | |
8990 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { | |
8991 return; | |
8992 } | |
8993 | |
8994 options.active = collapsing ? false : this.headers.index( clicked ); | |
8995 | |
8996 // when the call to ._toggle() comes after the class changes | |
8997 // it causes a very odd bug in IE 8 (see #6720) | |
8998 this.active = clickedIsActive ? $() : clicked; | |
8999 this._toggle( eventData ); | |
9000 | |
9001 // switch classes | |
9002 // corner classes on the previously active header stay after the animation | |
9003 active.removeClass( "ui-accordion-header-active ui-state-active" ); | |
9004 if ( options.icons ) { | |
9005 active.children( ".ui-accordion-header-icon" ) | |
9006 .removeClass( options.icons.activeHeader ) | |
9007 .addClass( options.icons.header ); | |
9008 } | |
9009 | |
9010 if ( !clickedIsActive ) { | |
9011 clicked | |
9012 .removeClass( "ui-corner-all" ) | |
9013 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); | |
9014 if ( options.icons ) { | |
9015 clicked.children( ".ui-accordion-header-icon" ) | |
9016 .removeClass( options.icons.header ) | |
9017 .addClass( options.icons.activeHeader ); | |
9018 } | |
9019 | |
9020 clicked | |
9021 .next() | |
9022 .addClass( "ui-accordion-content-active" ); | |
9023 } | |
9024 }, | |
9025 | |
9026 _toggle: function( data ) { | |
9027 var toShow = data.newPanel, | |
9028 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; | |
9029 | |
9030 // handle activating a panel during the animation for another activation | |
9031 this.prevShow.add( this.prevHide ).stop( true, true ); | |
9032 this.prevShow = toShow; | |
9033 this.prevHide = toHide; | |
9034 | |
9035 if ( this.options.animate ) { | |
9036 this._animate( toShow, toHide, data ); | |
9037 } else { | |
9038 toHide.hide(); | |
9039 toShow.show(); | |
9040 this._toggleComplete( data ); | |
9041 } | |
9042 | |
9043 toHide.attr({ | |
9044 "aria-expanded": "false", | |
9045 "aria-hidden": "true" | |
9046 }); | |
9047 toHide.prev().attr( "aria-selected", "false" ); | |
9048 // if we're switching panels, remove the old header from the tab order | |
9049 // if we're opening from collapsed state, remove the previous header from the tab order | |
9050 // if we're collapsing, then keep the collapsing header in the tab order | |
9051 if ( toShow.length && toHide.length ) { | |
9052 toHide.prev().attr( "tabIndex", -1 ); | |
9053 } else if ( toShow.length ) { | |
9054 this.headers.filter(function() { | |
9055 return $( this ).attr( "tabIndex" ) === 0; | |
9056 }) | |
9057 .attr( "tabIndex", -1 ); | |
9058 } | |
9059 | |
9060 toShow | |
9061 .attr({ | |
9062 "aria-expanded": "true", | |
9063 "aria-hidden": "false" | |
9064 }) | |
9065 .prev() | |
9066 .attr({ | |
9067 "aria-selected": "true", | |
9068 tabIndex: 0 | |
9069 }); | |
9070 }, | |
9071 | |
9072 _animate: function( toShow, toHide, data ) { | |
9073 var total, easing, duration, | |
9074 that = this, | |
9075 adjust = 0, | |
9076 down = toShow.length && | |
9077 ( !toHide.length || ( toShow.index() < toHide.index() ) ), | |
9078 animate = this.options.animate || {}, | |
9079 options = down && animate.down || animate, | |
9080 complete = function() { | |
9081 that._toggleComplete( data ); | |
9082 }; | |
9083 | |
9084 if ( typeof options === "number" ) { | |
9085 duration = options; | |
9086 } | |
9087 if ( typeof options === "string" ) { | |
9088 easing = options; | |
9089 } | |
9090 // fall back from options to animation in case of partial down settings | |
9091 easing = easing || options.easing || animate.easing; | |
9092 duration = duration || options.duration || animate.duration; | |
9093 | |
9094 if ( !toHide.length ) { | |
9095 return toShow.animate( showProps, duration, easing, complete ); | |
9096 } | |
9097 if ( !toShow.length ) { | |
9098 return toHide.animate( hideProps, duration, easing, complete ); | |
9099 } | |
9100 | |
9101 total = toShow.show().outerHeight(); | |
9102 toHide.animate( hideProps, { | |
9103 duration: duration, | |
9104 easing: easing, | |
9105 step: function( now, fx ) { | |
9106 fx.now = Math.round( now ); | |
9107 } | |
9108 }); | |
9109 toShow | |
9110 .hide() | |
9111 .animate( showProps, { | |
9112 duration: duration, | |
9113 easing: easing, | |
9114 complete: complete, | |
9115 step: function( now, fx ) { | |
9116 fx.now = Math.round( now ); | |
9117 if ( fx.prop !== "height" ) { | |
9118 adjust += fx.now; | |
9119 } else if ( that.options.heightStyle !== "content" ) { | |
9120 fx.now = Math.round( total - toHide.outerHeight() - adjust ); | |
9121 adjust = 0; | |
9122 } | |
9123 } | |
9124 }); | |
9125 }, | |
9126 | |
9127 _toggleComplete: function( data ) { | |
9128 var toHide = data.oldPanel; | |
9129 | |
9130 toHide | |
9131 .removeClass( "ui-accordion-content-active" ) | |
9132 .prev() | |
9133 .removeClass( "ui-corner-top" ) | |
9134 .addClass( "ui-corner-all" ); | |
9135 | |
9136 // Work around for rendering bug in IE (#5421) | |
9137 if ( toHide.length ) { | |
9138 toHide.parent()[0].className = toHide.parent()[0].className; | |
9139 } | |
9140 | |
9141 this._trigger( "activate", null, data ); | |
9142 } | |
9143 }); | |
9144 | |
9145 })( jQuery ); | |
9146 (function( $, undefined ) { | |
9147 | |
9148 // used to prevent race conditions with remote data sources | |
9149 var requestIndex = 0; | |
9150 | |
9151 $.widget( "ui.autocomplete", { | |
9152 version: "1.10.3", | |
9153 defaultElement: "<input>", | |
9154 options: { | |
9155 appendTo: null, | |
9156 autoFocus: false, | |
9157 delay: 300, | |
9158 minLength: 1, | |
9159 position: { | |
9160 my: "left top", | |
9161 at: "left bottom", | |
9162 collision: "none" | |
9163 }, | |
9164 source: null, | |
9165 | |
9166 // callbacks | |
9167 change: null, | |
9168 close: null, | |
9169 focus: null, | |
9170 open: null, | |
9171 response: null, | |
9172 search: null, | |
9173 select: null | |
9174 }, | |
9175 | |
9176 pending: 0, | |
9177 | |
9178 _create: function() { | |
9179 // Some browsers only repeat keydown events, not keypress events, | |
9180 // so we use the suppressKeyPress flag to determine if we've already | |
9181 // handled the keydown event. #7269 | |
9182 // Unfortunately the code for & in keypress is the same as the up arrow, | |
9183 // so we use the suppressKeyPressRepeat flag to avoid handling keypress | |
9184 // events when we know the keydown event was used to modify the | |
9185 // search term. #7799 | |
9186 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, | |
9187 nodeName = this.element[0].nodeName.toLowerCase(), | |
9188 isTextarea = nodeName === "textarea", | |
9189 isInput = nodeName === "input"; | |
9190 | |
9191 this.isMultiLine = | |
9192 // Textareas are always multi-line | |
9193 isTextarea ? true : | |
9194 // Inputs are always single-line, even if inside a contentEditable element | |
9195 // IE also treats inputs as contentEditable | |
9196 isInput ? false : | |
9197 // All other element types are determined by whether or not they're contentEditable | |
9198 this.element.prop( "isContentEditable" ); | |
9199 | |
9200 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; | |
9201 this.isNewMenu = true; | |
9202 | |
9203 this.element | |
9204 .addClass( "ui-autocomplete-input" ) | |
9205 .attr( "autocomplete", "off" ); | |
9206 | |
9207 this._on( this.element, { | |
9208 keydown: function( event ) { | |
9209 /*jshint maxcomplexity:15*/ | |
9210 if ( this.element.prop( "readOnly" ) ) { | |
9211 suppressKeyPress = true; | |
9212 suppressInput = true; | |
9213 suppressKeyPressRepeat = true; | |
9214 return; | |
9215 } | |
9216 | |
9217 suppressKeyPress = false; | |
9218 suppressInput = false; | |
9219 suppressKeyPressRepeat = false; | |
9220 var keyCode = $.ui.keyCode; | |
9221 switch( event.keyCode ) { | |
9222 case keyCode.PAGE_UP: | |
9223 suppressKeyPress = true; | |
9224 this._move( "previousPage", event ); | |
9225 break; | |
9226 case keyCode.PAGE_DOWN: | |
9227 suppressKeyPress = true; | |
9228 this._move( "nextPage", event ); | |
9229 break; | |
9230 case keyCode.UP: | |
9231 suppressKeyPress = true; | |
9232 this._keyEvent( "previous", event ); | |
9233 break; | |
9234 case keyCode.DOWN: | |
9235 suppressKeyPress = true; | |
9236 this._keyEvent( "next", event ); | |
9237 break; | |
9238 case keyCode.ENTER: | |
9239 case keyCode.NUMPAD_ENTER: | |
9240 // when menu is open and has focus | |
9241 if ( this.menu.active ) { | |
9242 // #6055 - Opera still allows the keypress to occur | |
9243 // which causes forms to submit | |
9244 suppressKeyPress = true; | |
9245 event.preventDefault(); | |
9246 this.menu.select( event ); | |
9247 } | |
9248 break; | |
9249 case keyCode.TAB: | |
9250 if ( this.menu.active ) { | |
9251 this.menu.select( event ); | |
9252 } | |
9253 break; | |
9254 case keyCode.ESCAPE: | |
9255 if ( this.menu.element.is( ":visible" ) ) { | |
9256 this._value( this.term ); | |
9257 this.close( event ); | |
9258 // Different browsers have different default behavior for escape | |
9259 // Single press can mean undo or clear | |
9260 // Double press in IE means clear the whole form | |
9261 event.preventDefault(); | |
9262 } | |
9263 break; | |
9264 default: | |
9265 suppressKeyPressRepeat = true; | |
9266 // search timeout should be triggered before the input value is changed | |
9267 this._searchTimeout( event ); | |
9268 break; | |
9269 } | |
9270 }, | |
9271 keypress: function( event ) { | |
9272 if ( suppressKeyPress ) { | |
9273 suppressKeyPress = false; | |
9274 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { | |
9275 event.preventDefault(); | |
9276 } | |
9277 return; | |
9278 } | |
9279 if ( suppressKeyPressRepeat ) { | |
9280 return; | |
9281 } | |
9282 | |
9283 // replicate some key handlers to allow them to repeat in Firefox and Opera | |
9284 var keyCode = $.ui.keyCode; | |
9285 switch( event.keyCode ) { | |
9286 case keyCode.PAGE_UP: | |
9287 this._move( "previousPage", event ); | |
9288 break; | |
9289 case keyCode.PAGE_DOWN: | |
9290 this._move( "nextPage", event ); | |
9291 break; | |
9292 case keyCode.UP: | |
9293 this._keyEvent( "previous", event ); | |
9294 break; | |
9295 case keyCode.DOWN: | |
9296 this._keyEvent( "next", event ); | |
9297 break; | |
9298 } | |
9299 }, | |
9300 input: function( event ) { | |
9301 if ( suppressInput ) { | |
9302 suppressInput = false; | |
9303 event.preventDefault(); | |
9304 return; | |
9305 } | |
9306 this._searchTimeout( event ); | |
9307 }, | |
9308 focus: function() { | |
9309 this.selectedItem = null; | |
9310 this.previous = this._value(); | |
9311 }, | |
9312 blur: function( event ) { | |
9313 if ( this.cancelBlur ) { | |
9314 delete this.cancelBlur; | |
9315 return; | |
9316 } | |
9317 | |
9318 clearTimeout( this.searching ); | |
9319 this.close( event ); | |
9320 this._change( event ); | |
9321 } | |
9322 }); | |
9323 | |
9324 this._initSource(); | |
9325 this.menu = $( "<ul>" ) | |
9326 .addClass( "ui-autocomplete ui-front" ) | |
9327 .appendTo( this._appendTo() ) | |
9328 .menu({ | |
9329 // disable ARIA support, the live region takes care of that | |
9330 role: null | |
9331 }) | |
9332 .hide() | |
9333 .data( "ui-menu" ); | |
9334 | |
9335 this._on( this.menu.element, { | |
9336 mousedown: function( event ) { | |
9337 // prevent moving focus out of the text field | |
9338 event.preventDefault(); | |
9339 | |
9340 // IE doesn't prevent moving focus even with event.preventDefault() | |
9341 // so we set a flag to know when we should ignore the blur event | |
9342 this.cancelBlur = true; | |
9343 this._delay(function() { | |
9344 delete this.cancelBlur; | |
9345 }); | |
9346 | |
9347 // clicking on the scrollbar causes focus to shift to the body | |
9348 // but we can't detect a mouseup or a click immediately afterward | |
9349 // so we have to track the next mousedown and close the menu if | |
9350 // the user clicks somewhere outside of the autocomplete | |
9351 var menuElement = this.menu.element[ 0 ]; | |
9352 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { | |
9353 this._delay(function() { | |
9354 var that = this; | |
9355 this.document.one( "mousedown", function( event ) { | |
9356 if ( event.target !== that.element[ 0 ] && | |
9357 event.target !== menuElement && | |
9358 !$.contains( menuElement, event.target ) ) { | |
9359 that.close(); | |
9360 } | |
9361 }); | |
9362 }); | |
9363 } | |
9364 }, | |
9365 menufocus: function( event, ui ) { | |
9366 // support: Firefox | |
9367 // Prevent accidental activation of menu items in Firefox (#7024 #9118) | |
9368 if ( this.isNewMenu ) { | |
9369 this.isNewMenu = false; | |
9370 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { | |
9371 this.menu.blur(); | |
9372 | |
9373 this.document.one( "mousemove", function() { | |
9374 $( event.target ).trigger( event.originalEvent ); | |
9375 }); | |
9376 | |
9377 return; | |
9378 } | |
9379 } | |
9380 | |
9381 var item = ui.item.data( "ui-autocomplete-item" ); | |
9382 if ( false !== this._trigger( "focus", event, { item: item } ) ) { | |
9383 // use value to match what will end up in the input, if it was a key event | |
9384 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { | |
9385 this._value( item.value ); | |
9386 } | |
9387 } else { | |
9388 // Normally the input is populated with the item's value as the | |
9389 // menu is navigated, causing screen readers to notice a change and | |
9390 // announce the item. Since the focus event was canceled, this doesn't | |
9391 // happen, so we update the live region so that screen readers can | |
9392 // still notice the change and announce it. | |
9393 this.liveRegion.text( item.value ); | |
9394 } | |
9395 }, | |
9396 menuselect: function( event, ui ) { | |
9397 var item = ui.item.data( "ui-autocomplete-item" ), | |
9398 previous = this.previous; | |
9399 | |
9400 // only trigger when focus was lost (click on menu) | |
9401 if ( this.element[0] !== this.document[0].activeElement ) { | |
9402 this.element.focus(); | |
9403 this.previous = previous; | |
9404 // #6109 - IE triggers two focus events and the second | |
9405 // is asynchronous, so we need to reset the previous | |
9406 // term synchronously and asynchronously :-( | |
9407 this._delay(function() { | |
9408 this.previous = previous; | |
9409 this.selectedItem = item; | |
9410 }); | |
9411 } | |
9412 | |
9413 if ( false !== this._trigger( "select", event, { item: item } ) ) { | |
9414 this._value( item.value ); | |
9415 } | |
9416 // reset the term after the select event | |
9417 // this allows custom select handling to work properly | |
9418 this.term = this._value(); | |
9419 | |
9420 this.close( event ); | |
9421 this.selectedItem = item; | |
9422 } | |
9423 }); | |
9424 | |
9425 this.liveRegion = $( "<span>", { | |
9426 role: "status", | |
9427 "aria-live": "polite" | |
9428 }) | |
9429 .addClass( "ui-helper-hidden-accessible" ) | |
9430 .insertBefore( this.element ); | |
9431 | |
9432 // turning off autocomplete prevents the browser from remembering the | |
9433 // value when navigating through history, so we re-enable autocomplete | |
9434 // if the page is unloaded before the widget is destroyed. #7790 | |
9435 this._on( this.window, { | |
9436 beforeunload: function() { | |
9437 this.element.removeAttr( "autocomplete" ); | |
9438 } | |
9439 }); | |
9440 }, | |
9441 | |
9442 _destroy: function() { | |
9443 clearTimeout( this.searching ); | |
9444 this.element | |
9445 .removeClass( "ui-autocomplete-input" ) | |
9446 .removeAttr( "autocomplete" ); | |
9447 this.menu.element.remove(); | |
9448 this.liveRegion.remove(); | |
9449 }, | |
9450 | |
9451 _setOption: function( key, value ) { | |
9452 this._super( key, value ); | |
9453 if ( key === "source" ) { | |
9454 this._initSource(); | |
9455 } | |
9456 if ( key === "appendTo" ) { | |
9457 this.menu.element.appendTo( this._appendTo() ); | |
9458 } | |
9459 if ( key === "disabled" && value && this.xhr ) { | |
9460 this.xhr.abort(); | |
9461 } | |
9462 }, | |
9463 | |
9464 _appendTo: function() { | |
9465 var element = this.options.appendTo; | |
9466 | |
9467 if ( element ) { | |
9468 element = element.jquery || element.nodeType ? | |
9469 $( element ) : | |
9470 this.document.find( element ).eq( 0 ); | |
9471 } | |
9472 | |
9473 if ( !element ) { | |
9474 element = this.element.closest( ".ui-front" ); | |
9475 } | |
9476 | |
9477 if ( !element.length ) { | |
9478 element = this.document[0].body; | |
9479 } | |
9480 | |
9481 return element; | |
9482 }, | |
9483 | |
9484 _initSource: function() { | |
9485 var array, url, | |
9486 that = this; | |
9487 if ( $.isArray(this.options.source) ) { | |
9488 array = this.options.source; | |
9489 this.source = function( request, response ) { | |
9490 response( $.ui.autocomplete.filter( array, request.term ) ); | |
9491 }; | |
9492 } else if ( typeof this.options.source === "string" ) { | |
9493 url = this.options.source; | |
9494 this.source = function( request, response ) { | |
9495 if ( that.xhr ) { | |
9496 that.xhr.abort(); | |
9497 } | |
9498 that.xhr = $.ajax({ | |
9499 url: url, | |
9500 data: request, | |
9501 dataType: "json", | |
9502 success: function( data ) { | |
9503 response( data ); | |
9504 }, | |
9505 error: function() { | |
9506 response( [] ); | |
9507 } | |
9508 }); | |
9509 }; | |
9510 } else { | |
9511 this.source = this.options.source; | |
9512 } | |
9513 }, | |
9514 | |
9515 _searchTimeout: function( event ) { | |
9516 clearTimeout( this.searching ); | |
9517 this.searching = this._delay(function() { | |
9518 // only search if the value has changed | |
9519 if ( this.term !== this._value() ) { | |
9520 this.selectedItem = null; | |
9521 this.search( null, event ); | |
9522 } | |
9523 }, this.options.delay ); | |
9524 }, | |
9525 | |
9526 search: function( value, event ) { | |
9527 value = value != null ? value : this._value(); | |
9528 | |
9529 // always save the actual value, not the one passed as an argument | |
9530 this.term = this._value(); | |
9531 | |
9532 if ( value.length < this.options.minLength ) { | |
9533 return this.close( event ); | |
9534 } | |
9535 | |
9536 if ( this._trigger( "search", event ) === false ) { | |
9537 return; | |
9538 } | |
9539 | |
9540 return this._search( value ); | |
9541 }, | |
9542 | |
9543 _search: function( value ) { | |
9544 this.pending++; | |
9545 this.element.addClass( "ui-autocomplete-loading" ); | |
9546 this.cancelSearch = false; | |
9547 | |
9548 this.source( { term: value }, this._response() ); | |
9549 }, | |
9550 | |
9551 _response: function() { | |
9552 var that = this, | |
9553 index = ++requestIndex; | |
9554 | |
9555 return function( content ) { | |
9556 if ( index === requestIndex ) { | |
9557 that.__response( content ); | |
9558 } | |
9559 | |
9560 that.pending--; | |
9561 if ( !that.pending ) { | |
9562 that.element.removeClass( "ui-autocomplete-loading" ); | |
9563 } | |
9564 }; | |
9565 }, | |
9566 | |
9567 __response: function( content ) { | |
9568 if ( content ) { | |
9569 content = this._normalize( content ); | |
9570 } | |
9571 this._trigger( "response", null, { content: content } ); | |
9572 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { | |
9573 this._suggest( content ); | |
9574 this._trigger( "open" ); | |
9575 } else { | |
9576 // use ._close() instead of .close() so we don't cancel future searches | |
9577 this._close(); | |
9578 } | |
9579 }, | |
9580 | |
9581 close: function( event ) { | |
9582 this.cancelSearch = true; | |
9583 this._close( event ); | |
9584 }, | |
9585 | |
9586 _close: function( event ) { | |
9587 if ( this.menu.element.is( ":visible" ) ) { | |
9588 this.menu.element.hide(); | |
9589 this.menu.blur(); | |
9590 this.isNewMenu = true; | |
9591 this._trigger( "close", event ); | |
9592 } | |
9593 }, | |
9594 | |
9595 _change: function( event ) { | |
9596 if ( this.previous !== this._value() ) { | |
9597 this._trigger( "change", event, { item: this.selectedItem } ); | |
9598 } | |
9599 }, | |
9600 | |
9601 _normalize: function( items ) { | |
9602 // assume all items have the right format when the first item is complete | |
9603 if ( items.length && items[0].label && items[0].value ) { | |
9604 return items; | |
9605 } | |
9606 return $.map( items, function( item ) { | |
9607 if ( typeof item === "string" ) { | |
9608 return { | |
9609 label: item, | |
9610 value: item | |
9611 }; | |
9612 } | |
9613 return $.extend({ | |
9614 label: item.label || item.value, | |
9615 value: item.value || item.label | |
9616 }, item ); | |
9617 }); | |
9618 }, | |
9619 | |
9620 _suggest: function( items ) { | |
9621 var ul = this.menu.element.empty(); | |
9622 this._renderMenu( ul, items ); | |
9623 this.isNewMenu = true; | |
9624 this.menu.refresh(); | |
9625 | |
9626 // size and position menu | |
9627 ul.show(); | |
9628 this._resizeMenu(); | |
9629 ul.position( $.extend({ | |
9630 of: this.element | |
9631 }, this.options.position )); | |
9632 | |
9633 if ( this.options.autoFocus ) { | |
9634 this.menu.next(); | |
9635 } | |
9636 }, | |
9637 | |
9638 _resizeMenu: function() { | |
9639 var ul = this.menu.element; | |
9640 ul.outerWidth( Math.max( | |
9641 // Firefox wraps long text (possibly a rounding bug) | |
9642 // so we add 1px to avoid the wrapping (#7513) | |
9643 ul.width( "" ).outerWidth() + 1, | |
9644 this.element.outerWidth() | |
9645 ) ); | |
9646 }, | |
9647 | |
9648 _renderMenu: function( ul, items ) { | |
9649 var that = this; | |
9650 $.each( items, function( index, item ) { | |
9651 that._renderItemData( ul, item ); | |
9652 }); | |
9653 }, | |
9654 | |
9655 _renderItemData: function( ul, item ) { | |
9656 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); | |
9657 }, | |
9658 | |
9659 _renderItem: function( ul, item ) { | |
9660 return $( "<li>" ) | |
9661 .append( $( "<a>" ).text( item.label ) ) | |
9662 .appendTo( ul ); | |
9663 }, | |
9664 | |
9665 _move: function( direction, event ) { | |
9666 if ( !this.menu.element.is( ":visible" ) ) { | |
9667 this.search( null, event ); | |
9668 return; | |
9669 } | |
9670 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || | |
9671 this.menu.isLastItem() && /^next/.test( direction ) ) { | |
9672 this._value( this.term ); | |
9673 this.menu.blur(); | |
9674 return; | |
9675 } | |
9676 this.menu[ direction ]( event ); | |
9677 }, | |
9678 | |
9679 widget: function() { | |
9680 return this.menu.element; | |
9681 }, | |
9682 | |
9683 _value: function() { | |
9684 return this.valueMethod.apply( this.element, arguments ); | |
9685 }, | |
9686 | |
9687 _keyEvent: function( keyEvent, event ) { | |
9688 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { | |
9689 this._move( keyEvent, event ); | |
9690 | |
9691 // prevents moving cursor to beginning/end of the text field in some browsers | |
9692 event.preventDefault(); | |
9693 } | |
9694 } | |
9695 }); | |
9696 | |
9697 $.extend( $.ui.autocomplete, { | |
9698 escapeRegex: function( value ) { | |
9699 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); | |
9700 }, | |
9701 filter: function(array, term) { | |
9702 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); | |
9703 return $.grep( array, function(value) { | |
9704 return matcher.test( value.label || value.value || value ); | |
9705 }); | |
9706 } | |
9707 }); | |
9708 | |
9709 | |
9710 // live region extension, adding a `messages` option | |
9711 // NOTE: This is an experimental API. We are still investigating | |
9712 // a full solution for string manipulation and internationalization. | |
9713 $.widget( "ui.autocomplete", $.ui.autocomplete, { | |
9714 options: { | |
9715 messages: { | |
9716 noResults: "No search results.", | |
9717 results: function( amount ) { | |
9718 return amount + ( amount > 1 ? " results are" : " result is" ) + | |
9719 " available, use up and down arrow keys to navigate."; | |
9720 } | |
9721 } | |
9722 }, | |
9723 | |
9724 __response: function( content ) { | |
9725 var message; | |
9726 this._superApply( arguments ); | |
9727 if ( this.options.disabled || this.cancelSearch ) { | |
9728 return; | |
9729 } | |
9730 if ( content && content.length ) { | |
9731 message = this.options.messages.results( content.length ); | |
9732 } else { | |
9733 message = this.options.messages.noResults; | |
9734 } | |
9735 this.liveRegion.text( message ); | |
9736 } | |
9737 }); | |
9738 | |
9739 }( jQuery )); | |
9740 (function( $, undefined ) { | |
9741 | |
9742 var lastActive, startXPos, startYPos, clickDragged, | |
9743 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", | |
9744 stateClasses = "ui-state-hover ui-state-active ", | |
9745 typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", | |
9746 formResetHandler = function() { | |
9747 var form = $( this ); | |
9748 setTimeout(function() { | |
9749 form.find( ":ui-button" ).button( "refresh" ); | |
9750 }, 1 ); | |
9751 }, | |
9752 radioGroup = function( radio ) { | |
9753 var name = radio.name, | |
9754 form = radio.form, | |
9755 radios = $( [] ); | |
9756 if ( name ) { | |
9757 name = name.replace( /'/g, "\\'" ); | |
9758 if ( form ) { | |
9759 radios = $( form ).find( "[name='" + name + "']" ); | |
9760 } else { | |
9761 radios = $( "[name='" + name + "']", radio.ownerDocument ) | |
9762 .filter(function() { | |
9763 return !this.form; | |
9764 }); | |
9765 } | |
9766 } | |
9767 return radios; | |
9768 }; | |
9769 | |
9770 $.widget( "ui.button", { | |
9771 version: "1.10.3", | |
9772 defaultElement: "<button>", | |
9773 options: { | |
9774 disabled: null, | |
9775 text: true, | |
9776 label: null, | |
9777 icons: { | |
9778 primary: null, | |
9779 secondary: null | |
9780 } | |
9781 }, | |
9782 _create: function() { | |
9783 this.element.closest( "form" ) | |
9784 .unbind( "reset" + this.eventNamespace ) | |
9785 .bind( "reset" + this.eventNamespace, formResetHandler ); | |
9786 | |
9787 if ( typeof this.options.disabled !== "boolean" ) { | |
9788 this.options.disabled = !!this.element.prop( "disabled" ); | |
9789 } else { | |
9790 this.element.prop( "disabled", this.options.disabled ); | |
9791 } | |
9792 | |
9793 this._determineButtonType(); | |
9794 this.hasTitle = !!this.buttonElement.attr( "title" ); | |
9795 | |
9796 var that = this, | |
9797 options = this.options, | |
9798 toggleButton = this.type === "checkbox" || this.type === "radio", | |
9799 activeClass = !toggleButton ? "ui-state-active" : "", | |
9800 focusClass = "ui-state-focus"; | |
9801 | |
9802 if ( options.label === null ) { | |
9803 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); | |
9804 } | |
9805 | |
9806 this._hoverable( this.buttonElement ); | |
9807 | |
9808 this.buttonElement | |
9809 .addClass( baseClasses ) | |
9810 .attr( "role", "button" ) | |
9811 .bind( "mouseenter" + this.eventNamespace, function() { | |
9812 if ( options.disabled ) { | |
9813 return; | |
9814 } | |
9815 if ( this === lastActive ) { | |
9816 $( this ).addClass( "ui-state-active" ); | |
9817 } | |
9818 }) | |
9819 .bind( "mouseleave" + this.eventNamespace, function() { | |
9820 if ( options.disabled ) { | |
9821 return; | |
9822 } | |
9823 $( this ).removeClass( activeClass ); | |
9824 }) | |
9825 .bind( "click" + this.eventNamespace, function( event ) { | |
9826 if ( options.disabled ) { | |
9827 event.preventDefault(); | |
9828 event.stopImmediatePropagation(); | |
9829 } | |
9830 }); | |
9831 | |
9832 this.element | |
9833 .bind( "focus" + this.eventNamespace, function() { | |
9834 // no need to check disabled, focus won't be triggered anyway | |
9835 that.buttonElement.addClass( focusClass ); | |
9836 }) | |
9837 .bind( "blur" + this.eventNamespace, function() { | |
9838 that.buttonElement.removeClass( focusClass ); | |
9839 }); | |
9840 | |
9841 if ( toggleButton ) { | |
9842 this.element.bind( "change" + this.eventNamespace, function() { | |
9843 if ( clickDragged ) { | |
9844 return; | |
9845 } | |
9846 that.refresh(); | |
9847 }); | |
9848 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag | |
9849 // prevents issue where button state changes but checkbox/radio checked state | |
9850 // does not in Firefox (see ticket #6970) | |
9851 this.buttonElement | |
9852 .bind( "mousedown" + this.eventNamespace, function( event ) { | |
9853 if ( options.disabled ) { | |
9854 return; | |
9855 } | |
9856 clickDragged = false; | |
9857 startXPos = event.pageX; | |
9858 startYPos = event.pageY; | |
9859 }) | |
9860 .bind( "mouseup" + this.eventNamespace, function( event ) { | |
9861 if ( options.disabled ) { | |
9862 return; | |
9863 } | |
9864 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { | |
9865 clickDragged = true; | |
9866 } | |
9867 }); | |
9868 } | |
9869 | |
9870 if ( this.type === "checkbox" ) { | |
9871 this.buttonElement.bind( "click" + this.eventNamespace, function() { | |
9872 if ( options.disabled || clickDragged ) { | |
9873 return false; | |
9874 } | |
9875 }); | |
9876 } else if ( this.type === "radio" ) { | |
9877 this.buttonElement.bind( "click" + this.eventNamespace, function() { | |
9878 if ( options.disabled || clickDragged ) { | |
9879 return false; | |
9880 } | |
9881 $( this ).addClass( "ui-state-active" ); | |
9882 that.buttonElement.attr( "aria-pressed", "true" ); | |
9883 | |
9884 var radio = that.element[ 0 ]; | |
9885 radioGroup( radio ) | |
9886 .not( radio ) | |
9887 .map(function() { | |
9888 return $( this ).button( "widget" )[ 0 ]; | |
9889 }) | |
9890 .removeClass( "ui-state-active" ) | |
9891 .attr( "aria-pressed", "false" ); | |
9892 }); | |
9893 } else { | |
9894 this.buttonElement | |
9895 .bind( "mousedown" + this.eventNamespace, function() { | |
9896 if ( options.disabled ) { | |
9897 return false; | |
9898 } | |
9899 $( this ).addClass( "ui-state-active" ); | |
9900 lastActive = this; | |
9901 that.document.one( "mouseup", function() { | |
9902 lastActive = null; | |
9903 }); | |
9904 }) | |
9905 .bind( "mouseup" + this.eventNamespace, function() { | |
9906 if ( options.disabled ) { | |
9907 return false; | |
9908 } | |
9909 $( this ).removeClass( "ui-state-active" ); | |
9910 }) | |
9911 .bind( "keydown" + this.eventNamespace, function(event) { | |
9912 if ( options.disabled ) { | |
9913 return false; | |
9914 } | |
9915 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { | |
9916 $( this ).addClass( "ui-state-active" ); | |
9917 } | |
9918 }) | |
9919 // see #8559, we bind to blur here in case the button element loses | |
9920 // focus between keydown and keyup, it would be left in an "active" state | |
9921 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { | |
9922 $( this ).removeClass( "ui-state-active" ); | |
9923 }); | |
9924 | |
9925 if ( this.buttonElement.is("a") ) { | |
9926 this.buttonElement.keyup(function(event) { | |
9927 if ( event.keyCode === $.ui.keyCode.SPACE ) { | |
9928 // TODO pass through original event correctly (just as 2nd argument doesn't work) | |
9929 $( this ).click(); | |
9930 } | |
9931 }); | |
9932 } | |
9933 } | |
9934 | |
9935 // TODO: pull out $.Widget's handling for the disabled option into | |
9936 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can | |
9937 // be overridden by individual plugins | |
9938 this._setOption( "disabled", options.disabled ); | |
9939 this._resetButton(); | |
9940 }, | |
9941 | |
9942 _determineButtonType: function() { | |
9943 var ancestor, labelSelector, checked; | |
9944 | |
9945 if ( this.element.is("[type=checkbox]") ) { | |
9946 this.type = "checkbox"; | |
9947 } else if ( this.element.is("[type=radio]") ) { | |
9948 this.type = "radio"; | |
9949 } else if ( this.element.is("input") ) { | |
9950 this.type = "input"; | |
9951 } else { | |
9952 this.type = "button"; | |
9953 } | |
9954 | |
9955 if ( this.type === "checkbox" || this.type === "radio" ) { | |
9956 // we don't search against the document in case the element | |
9957 // is disconnected from the DOM | |
9958 ancestor = this.element.parents().last(); | |
9959 labelSelector = "label[for='" + this.element.attr("id") + "']"; | |
9960 this.buttonElement = ancestor.find( labelSelector ); | |
9961 if ( !this.buttonElement.length ) { | |
9962 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); | |
9963 this.buttonElement = ancestor.filter( labelSelector ); | |
9964 if ( !this.buttonElement.length ) { | |
9965 this.buttonElement = ancestor.find( labelSelector ); | |
9966 } | |
9967 } | |
9968 this.element.addClass( "ui-helper-hidden-accessible" ); | |
9969 | |
9970 checked = this.element.is( ":checked" ); | |
9971 if ( checked ) { | |
9972 this.buttonElement.addClass( "ui-state-active" ); | |
9973 } | |
9974 this.buttonElement.prop( "aria-pressed", checked ); | |
9975 } else { | |
9976 this.buttonElement = this.element; | |
9977 } | |
9978 }, | |
9979 | |
9980 widget: function() { | |
9981 return this.buttonElement; | |
9982 }, | |
9983 | |
9984 _destroy: function() { | |
9985 this.element | |
9986 .removeClass( "ui-helper-hidden-accessible" ); | |
9987 this.buttonElement | |
9988 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) | |
9989 .removeAttr( "role" ) | |
9990 .removeAttr( "aria-pressed" ) | |
9991 .html( this.buttonElement.find(".ui-button-text").html() ); | |
9992 | |
9993 if ( !this.hasTitle ) { | |
9994 this.buttonElement.removeAttr( "title" ); | |
9995 } | |
9996 }, | |
9997 | |
9998 _setOption: function( key, value ) { | |
9999 this._super( key, value ); | |
10000 if ( key === "disabled" ) { | |
10001 if ( value ) { | |
10002 this.element.prop( "disabled", true ); | |
10003 } else { | |
10004 this.element.prop( "disabled", false ); | |
10005 } | |
10006 return; | |
10007 } | |
10008 this._resetButton(); | |
10009 }, | |
10010 | |
10011 refresh: function() { | |
10012 //See #8237 & #8828 | |
10013 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); | |
10014 | |
10015 if ( isDisabled !== this.options.disabled ) { | |
10016 this._setOption( "disabled", isDisabled ); | |
10017 } | |
10018 if ( this.type === "radio" ) { | |
10019 radioGroup( this.element[0] ).each(function() { | |
10020 if ( $( this ).is( ":checked" ) ) { | |
10021 $( this ).button( "widget" ) | |
10022 .addClass( "ui-state-active" ) | |
10023 .attr( "aria-pressed", "true" ); | |
10024 } else { | |
10025 $( this ).button( "widget" ) | |
10026 .removeClass( "ui-state-active" ) | |
10027 .attr( "aria-pressed", "false" ); | |
10028 } | |
10029 }); | |
10030 } else if ( this.type === "checkbox" ) { | |
10031 if ( this.element.is( ":checked" ) ) { | |
10032 this.buttonElement | |
10033 .addClass( "ui-state-active" ) | |
10034 .attr( "aria-pressed", "true" ); | |
10035 } else { | |
10036 this.buttonElement | |
10037 .removeClass( "ui-state-active" ) | |
10038 .attr( "aria-pressed", "false" ); | |
10039 } | |
10040 } | |
10041 }, | |
10042 | |
10043 _resetButton: function() { | |
10044 if ( this.type === "input" ) { | |
10045 if ( this.options.label ) { | |
10046 this.element.val( this.options.label ); | |
10047 } | |
10048 return; | |
10049 } | |
10050 var buttonElement = this.buttonElement.removeClass( typeClasses ), | |
10051 buttonText = $( "<span></span>", this.document[0] ) | |
10052 .addClass( "ui-button-text" ) | |
10053 .html( this.options.label ) | |
10054 .appendTo( buttonElement.empty() ) | |
10055 .text(), | |
10056 icons = this.options.icons, | |
10057 multipleIcons = icons.primary && icons.secondary, | |
10058 buttonClasses = []; | |
10059 | |
10060 if ( icons.primary || icons.secondary ) { | |
10061 if ( this.options.text ) { | |
10062 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); | |
10063 } | |
10064 | |
10065 if ( icons.primary ) { | |
10066 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); | |
10067 } | |
10068 | |
10069 if ( icons.secondary ) { | |
10070 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); | |
10071 } | |
10072 | |
10073 if ( !this.options.text ) { | |
10074 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); | |
10075 | |
10076 if ( !this.hasTitle ) { | |
10077 buttonElement.attr( "title", $.trim( buttonText ) ); | |
10078 } | |
10079 } | |
10080 } else { | |
10081 buttonClasses.push( "ui-button-text-only" ); | |
10082 } | |
10083 buttonElement.addClass( buttonClasses.join( " " ) ); | |
10084 } | |
10085 }); | |
10086 | |
10087 $.widget( "ui.buttonset", { | |
10088 version: "1.10.3", | |
10089 options: { | |
10090 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" | |
10091 }, | |
10092 | |
10093 _create: function() { | |
10094 this.element.addClass( "ui-buttonset" ); | |
10095 }, | |
10096 | |
10097 _init: function() { | |
10098 this.refresh(); | |
10099 }, | |
10100 | |
10101 _setOption: function( key, value ) { | |
10102 if ( key === "disabled" ) { | |
10103 this.buttons.button( "option", key, value ); | |
10104 } | |
10105 | |
10106 this._super( key, value ); | |
10107 }, | |
10108 | |
10109 refresh: function() { | |
10110 var rtl = this.element.css( "direction" ) === "rtl"; | |
10111 | |
10112 this.buttons = this.element.find( this.options.items ) | |
10113 .filter( ":ui-button" ) | |
10114 .button( "refresh" ) | |
10115 .end() | |
10116 .not( ":ui-button" ) | |
10117 .button() | |
10118 .end() | |
10119 .map(function() { | |
10120 return $( this ).button( "widget" )[ 0 ]; | |
10121 }) | |
10122 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) | |
10123 .filter( ":first" ) | |
10124 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) | |
10125 .end() | |
10126 .filter( ":last" ) | |
10127 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) | |
10128 .end() | |
10129 .end(); | |
10130 }, | |
10131 | |
10132 _destroy: function() { | |
10133 this.element.removeClass( "ui-buttonset" ); | |
10134 this.buttons | |
10135 .map(function() { | |
10136 return $( this ).button( "widget" )[ 0 ]; | |
10137 }) | |
10138 .removeClass( "ui-corner-left ui-corner-right" ) | |
10139 .end() | |
10140 .button( "destroy" ); | |
10141 } | |
10142 }); | |
10143 | |
10144 }( jQuery ) ); | |
10145 (function( $, undefined ) { | |
10146 | |
10147 $.extend($.ui, { datepicker: { version: "1.10.3" } }); | |
10148 | |
10149 var PROP_NAME = "datepicker", | |
10150 instActive; | |
10151 | |
10152 /* Date picker manager. | |
10153 Use the singleton instance of this class, $.datepicker, to interact with the date picker. | |
10154 Settings for (groups of) date pickers are maintained in an instance object, | |
10155 allowing multiple different settings on the same page. */ | |
10156 | |
10157 function Datepicker() { | |
10158 this._curInst = null; // The current instance in use | |
10159 this._keyEvent = false; // If the last event was a key event | |
10160 this._disabledInputs = []; // List of date picker inputs that have been disabled | |
10161 this._datepickerShowing = false; // True if the popup picker is showing , false if not | |
10162 this._inDialog = false; // True if showing within a "dialog", false if not | |
10163 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division | |
10164 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class | |
10165 this._appendClass = "ui-datepicker-append"; // The name of the append marker class | |
10166 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class | |
10167 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class | |
10168 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class | |
10169 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class | |
10170 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class | |
10171 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class | |
10172 this.regional = []; // Available regional settings, indexed by language code | |
10173 this.regional[""] = { // Default regional settings | |
10174 closeText: "Done", // Display text for close link | |
10175 prevText: "Prev", // Display text for previous month link | |
10176 nextText: "Next", // Display text for next month link | |
10177 currentText: "Today", // Display text for current month link | |
10178 monthNames: ["January","February","March","April","May","June", | |
10179 "July","August","September","October","November","December"], // Names of months for drop-down and formatting | |
10180 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting | |
10181 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting | |
10182 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting | |
10183 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday | |
10184 weekHeader: "Wk", // Column header for week of the year | |
10185 dateFormat: "mm/dd/yy", // See format options on parseDate | |
10186 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... | |
10187 isRTL: false, // True if right-to-left language, false if left-to-right | |
10188 showMonthAfterYear: false, // True if the year select precedes month, false for month then year | |
10189 yearSuffix: "" // Additional text to append to the year in the month headers | |
10190 }; | |
10191 this._defaults = { // Global defaults for all the date picker instances | |
10192 showOn: "focus", // "focus" for popup on focus, | |
10193 // "button" for trigger button, or "both" for either | |
10194 showAnim: "fadeIn", // Name of jQuery animation for popup | |
10195 showOptions: {}, // Options for enhanced animations | |
10196 defaultDate: null, // Used when field is blank: actual date, | |
10197 // +/-number for offset from today, null for today | |
10198 appendText: "", // Display text following the input box, e.g. showing the format | |
10199 buttonText: "...", // Text for trigger button | |
10200 buttonImage: "", // URL for trigger button image | |
10201 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button | |
10202 hideIfNoPrevNext: false, // True to hide next/previous month links | |
10203 // if not applicable, false to just disable them | |
10204 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links | |
10205 gotoCurrent: false, // True if today link goes back to current selection instead | |
10206 changeMonth: false, // True if month can be selected directly, false if only prev/next | |
10207 changeYear: false, // True if year can be selected directly, false if only prev/next | |
10208 yearRange: "c-10:c+10", // Range of years to display in drop-down, | |
10209 // either relative to today's year (-nn:+nn), relative to currently displayed year | |
10210 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) | |
10211 showOtherMonths: false, // True to show dates in other months, false to leave blank | |
10212 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable | |
10213 showWeek: false, // True to show week of the year, false to not show it | |
10214 calculateWeek: this.iso8601Week, // How to calculate the week of the year, | |
10215 // takes a Date and returns the number of the week for it | |
10216 shortYearCutoff: "+10", // Short year values < this are in the current century, | |
10217 // > this are in the previous century, | |
10218 // string value starting with "+" for current year + value | |
10219 minDate: null, // The earliest selectable date, or null for no limit | |
10220 maxDate: null, // The latest selectable date, or null for no limit | |
10221 duration: "fast", // Duration of display/closure | |
10222 beforeShowDay: null, // Function that takes a date and returns an array with | |
10223 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", | |
10224 // [2] = cell title (optional), e.g. $.datepicker.noWeekends | |
10225 beforeShow: null, // Function that takes an input field and | |
10226 // returns a set of custom settings for the date picker | |
10227 onSelect: null, // Define a callback function when a date is selected | |
10228 onChangeMonthYear: null, // Define a callback function when the month or year is changed | |
10229 onClose: null, // Define a callback function when the datepicker is closed | |
10230 numberOfMonths: 1, // Number of months to show at a time | |
10231 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) | |
10232 stepMonths: 1, // Number of months to step back/forward | |
10233 stepBigMonths: 12, // Number of months to step back/forward for the big links | |
10234 altField: "", // Selector for an alternate field to store selected dates into | |
10235 altFormat: "", // The date format to use for the alternate field | |
10236 constrainInput: true, // The input is constrained by the current date format | |
10237 showButtonPanel: false, // True to show button panel, false to not show it | |
10238 autoSize: false, // True to size the input for the date format, false to leave as is | |
10239 disabled: false // The initial disabled state | |
10240 }; | |
10241 $.extend(this._defaults, this.regional[""]); | |
10242 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); | |
10243 } | |
10244 | |
10245 $.extend(Datepicker.prototype, { | |
10246 /* Class name added to elements to indicate already configured with a date picker. */ | |
10247 markerClassName: "hasDatepicker", | |
10248 | |
10249 //Keep track of the maximum number of rows displayed (see #7043) | |
10250 maxRows: 4, | |
10251 | |
10252 // TODO rename to "widget" when switching to widget factory | |
10253 _widgetDatepicker: function() { | |
10254 return this.dpDiv; | |
10255 }, | |
10256 | |
10257 /* Override the default settings for all instances of the date picker. | |
10258 * @param settings object - the new settings to use as defaults (anonymous object) | |
10259 * @return the manager object | |
10260 */ | |
10261 setDefaults: function(settings) { | |
10262 extendRemove(this._defaults, settings || {}); | |
10263 return this; | |
10264 }, | |
10265 | |
10266 /* Attach the date picker to a jQuery selection. | |
10267 * @param target element - the target input field or division or span | |
10268 * @param settings object - the new settings to use for this date picker instance (anonymous) | |
10269 */ | |
10270 _attachDatepicker: function(target, settings) { | |
10271 var nodeName, inline, inst; | |
10272 nodeName = target.nodeName.toLowerCase(); | |
10273 inline = (nodeName === "div" || nodeName === "span"); | |
10274 if (!target.id) { | |
10275 this.uuid += 1; | |
10276 target.id = "dp" + this.uuid; | |
10277 } | |
10278 inst = this._newInst($(target), inline); | |
10279 inst.settings = $.extend({}, settings || {}); | |
10280 if (nodeName === "input") { | |
10281 this._connectDatepicker(target, inst); | |
10282 } else if (inline) { | |
10283 this._inlineDatepicker(target, inst); | |
10284 } | |
10285 }, | |
10286 | |
10287 /* Create a new instance object. */ | |
10288 _newInst: function(target, inline) { | |
10289 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars | |
10290 return {id: id, input: target, // associated target | |
10291 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection | |
10292 drawMonth: 0, drawYear: 0, // month being drawn | |
10293 inline: inline, // is datepicker inline or not | |
10294 dpDiv: (!inline ? this.dpDiv : // presentation div | |
10295 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; | |
10296 }, | |
10297 | |
10298 /* Attach the date picker to an input field. */ | |
10299 _connectDatepicker: function(target, inst) { | |
10300 var input = $(target); | |
10301 inst.append = $([]); | |
10302 inst.trigger = $([]); | |
10303 if (input.hasClass(this.markerClassName)) { | |
10304 return; | |
10305 } | |
10306 this._attachments(input, inst); | |
10307 input.addClass(this.markerClassName).keydown(this._doKeyDown). | |
10308 keypress(this._doKeyPress).keyup(this._doKeyUp); | |
10309 this._autoSize(inst); | |
10310 $.data(target, PROP_NAME, inst); | |
10311 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) | |
10312 if( inst.settings.disabled ) { | |
10313 this._disableDatepicker( target ); | |
10314 } | |
10315 }, | |
10316 | |
10317 /* Make attachments based on settings. */ | |
10318 _attachments: function(input, inst) { | |
10319 var showOn, buttonText, buttonImage, | |
10320 appendText = this._get(inst, "appendText"), | |
10321 isRTL = this._get(inst, "isRTL"); | |
10322 | |
10323 if (inst.append) { | |
10324 inst.append.remove(); | |
10325 } | |
10326 if (appendText) { | |
10327 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); | |
10328 input[isRTL ? "before" : "after"](inst.append); | |
10329 } | |
10330 | |
10331 input.unbind("focus", this._showDatepicker); | |
10332 | |
10333 if (inst.trigger) { | |
10334 inst.trigger.remove(); | |
10335 } | |
10336 | |
10337 showOn = this._get(inst, "showOn"); | |
10338 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field | |
10339 input.focus(this._showDatepicker); | |
10340 } | |
10341 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked | |
10342 buttonText = this._get(inst, "buttonText"); | |
10343 buttonImage = this._get(inst, "buttonImage"); | |
10344 inst.trigger = $(this._get(inst, "buttonImageOnly") ? | |
10345 $("<img/>").addClass(this._triggerClass). | |
10346 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : | |
10347 $("<button type='button'></button>").addClass(this._triggerClass). | |
10348 html(!buttonImage ? buttonText : $("<img/>").attr( | |
10349 { src:buttonImage, alt:buttonText, title:buttonText }))); | |
10350 input[isRTL ? "before" : "after"](inst.trigger); | |
10351 inst.trigger.click(function() { | |
10352 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { | |
10353 $.datepicker._hideDatepicker(); | |
10354 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { | |
10355 $.datepicker._hideDatepicker(); | |
10356 $.datepicker._showDatepicker(input[0]); | |
10357 } else { | |
10358 $.datepicker._showDatepicker(input[0]); | |
10359 } | |
10360 return false; | |
10361 }); | |
10362 } | |
10363 }, | |
10364 | |
10365 /* Apply the maximum length for the date format. */ | |
10366 _autoSize: function(inst) { | |
10367 if (this._get(inst, "autoSize") && !inst.inline) { | |
10368 var findMax, max, maxI, i, | |
10369 date = new Date(2009, 12 - 1, 20), // Ensure double digits | |
10370 dateFormat = this._get(inst, "dateFormat"); | |
10371 | |
10372 if (dateFormat.match(/[DM]/)) { | |
10373 findMax = function(names) { | |
10374 max = 0; | |
10375 maxI = 0; | |
10376 for (i = 0; i < names.length; i++) { | |
10377 if (names[i].length > max) { | |
10378 max = names[i].length; | |
10379 maxI = i; | |
10380 } | |
10381 } | |
10382 return maxI; | |
10383 }; | |
10384 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? | |
10385 "monthNames" : "monthNamesShort")))); | |
10386 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? | |
10387 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); | |
10388 } | |
10389 inst.input.attr("size", this._formatDate(inst, date).length); | |
10390 } | |
10391 }, | |
10392 | |
10393 /* Attach an inline date picker to a div. */ | |
10394 _inlineDatepicker: function(target, inst) { | |
10395 var divSpan = $(target); | |
10396 if (divSpan.hasClass(this.markerClassName)) { | |
10397 return; | |
10398 } | |
10399 divSpan.addClass(this.markerClassName).append(inst.dpDiv); | |
10400 $.data(target, PROP_NAME, inst); | |
10401 this._setDate(inst, this._getDefaultDate(inst), true); | |
10402 this._updateDatepicker(inst); | |
10403 this._updateAlternate(inst); | |
10404 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) | |
10405 if( inst.settings.disabled ) { | |
10406 this._disableDatepicker( target ); | |
10407 } | |
10408 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements | |
10409 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height | |
10410 inst.dpDiv.css( "display", "block" ); | |
10411 }, | |
10412 | |
10413 /* Pop-up the date picker in a "dialog" box. | |
10414 * @param input element - ignored | |
10415 * @param date string or Date - the initial date to display | |
10416 * @param onSelect function - the function to call when a date is selected | |
10417 * @param settings object - update the dialog date picker instance's settings (anonymous object) | |
10418 * @param pos int[2] - coordinates for the dialog's position within the screen or | |
10419 * event - with x/y coordinates or | |
10420 * leave empty for default (screen centre) | |
10421 * @return the manager object | |
10422 */ | |
10423 _dialogDatepicker: function(input, date, onSelect, settings, pos) { | |
10424 var id, browserWidth, browserHeight, scrollX, scrollY, | |
10425 inst = this._dialogInst; // internal instance | |
10426 | |
10427 if (!inst) { | |
10428 this.uuid += 1; | |
10429 id = "dp" + this.uuid; | |
10430 this._dialogInput = $("<input type='text' id='" + id + | |
10431 "' style='position: absolute; top: -100px; width: 0px;'/>"); | |
10432 this._dialogInput.keydown(this._doKeyDown); | |
10433 $("body").append(this._dialogInput); | |
10434 inst = this._dialogInst = this._newInst(this._dialogInput, false); | |
10435 inst.settings = {}; | |
10436 $.data(this._dialogInput[0], PROP_NAME, inst); | |
10437 } | |
10438 extendRemove(inst.settings, settings || {}); | |
10439 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); | |
10440 this._dialogInput.val(date); | |
10441 | |
10442 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); | |
10443 if (!this._pos) { | |
10444 browserWidth = document.documentElement.clientWidth; | |
10445 browserHeight = document.documentElement.clientHeight; | |
10446 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; | |
10447 scrollY = document.documentElement.scrollTop || document.body.scrollTop; | |
10448 this._pos = // should use actual width/height below | |
10449 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; | |
10450 } | |
10451 | |
10452 // move input on screen for focus, but hidden behind dialog | |
10453 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); | |
10454 inst.settings.onSelect = onSelect; | |
10455 this._inDialog = true; | |
10456 this.dpDiv.addClass(this._dialogClass); | |
10457 this._showDatepicker(this._dialogInput[0]); | |
10458 if ($.blockUI) { | |
10459 $.blockUI(this.dpDiv); | |
10460 } | |
10461 $.data(this._dialogInput[0], PROP_NAME, inst); | |
10462 return this; | |
10463 }, | |
10464 | |
10465 /* Detach a datepicker from its control. | |
10466 * @param target element - the target input field or division or span | |
10467 */ | |
10468 _destroyDatepicker: function(target) { | |
10469 var nodeName, | |
10470 $target = $(target), | |
10471 inst = $.data(target, PROP_NAME); | |
10472 | |
10473 if (!$target.hasClass(this.markerClassName)) { | |
10474 return; | |
10475 } | |
10476 | |
10477 nodeName = target.nodeName.toLowerCase(); | |
10478 $.removeData(target, PROP_NAME); | |
10479 if (nodeName === "input") { | |
10480 inst.append.remove(); | |
10481 inst.trigger.remove(); | |
10482 $target.removeClass(this.markerClassName). | |
10483 unbind("focus", this._showDatepicker). | |
10484 unbind("keydown", this._doKeyDown). | |
10485 unbind("keypress", this._doKeyPress). | |
10486 unbind("keyup", this._doKeyUp); | |
10487 } else if (nodeName === "div" || nodeName === "span") { | |
10488 $target.removeClass(this.markerClassName).empty(); | |
10489 } | |
10490 }, | |
10491 | |
10492 /* Enable the date picker to a jQuery selection. | |
10493 * @param target element - the target input field or division or span | |
10494 */ | |
10495 _enableDatepicker: function(target) { | |
10496 var nodeName, inline, | |
10497 $target = $(target), | |
10498 inst = $.data(target, PROP_NAME); | |
10499 | |
10500 if (!$target.hasClass(this.markerClassName)) { | |
10501 return; | |
10502 } | |
10503 | |
10504 nodeName = target.nodeName.toLowerCase(); | |
10505 if (nodeName === "input") { | |
10506 target.disabled = false; | |
10507 inst.trigger.filter("button"). | |
10508 each(function() { this.disabled = false; }).end(). | |
10509 filter("img").css({opacity: "1.0", cursor: ""}); | |
10510 } else if (nodeName === "div" || nodeName === "span") { | |
10511 inline = $target.children("." + this._inlineClass); | |
10512 inline.children().removeClass("ui-state-disabled"); | |
10513 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). | |
10514 prop("disabled", false); | |
10515 } | |
10516 this._disabledInputs = $.map(this._disabledInputs, | |
10517 function(value) { return (value === target ? null : value); }); // delete entry | |
10518 }, | |
10519 | |
10520 /* Disable the date picker to a jQuery selection. | |
10521 * @param target element - the target input field or division or span | |
10522 */ | |
10523 _disableDatepicker: function(target) { | |
10524 var nodeName, inline, | |
10525 $target = $(target), | |
10526 inst = $.data(target, PROP_NAME); | |
10527 | |
10528 if (!$target.hasClass(this.markerClassName)) { | |
10529 return; | |
10530 } | |
10531 | |
10532 nodeName = target.nodeName.toLowerCase(); | |
10533 if (nodeName === "input") { | |
10534 target.disabled = true; | |
10535 inst.trigger.filter("button"). | |
10536 each(function() { this.disabled = true; }).end(). | |
10537 filter("img").css({opacity: "0.5", cursor: "default"}); | |
10538 } else if (nodeName === "div" || nodeName === "span") { | |
10539 inline = $target.children("." + this._inlineClass); | |
10540 inline.children().addClass("ui-state-disabled"); | |
10541 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). | |
10542 prop("disabled", true); | |
10543 } | |
10544 this._disabledInputs = $.map(this._disabledInputs, | |
10545 function(value) { return (value === target ? null : value); }); // delete entry | |
10546 this._disabledInputs[this._disabledInputs.length] = target; | |
10547 }, | |
10548 | |
10549 /* Is the first field in a jQuery collection disabled as a datepicker? | |
10550 * @param target element - the target input field or division or span | |
10551 * @return boolean - true if disabled, false if enabled | |
10552 */ | |
10553 _isDisabledDatepicker: function(target) { | |
10554 if (!target) { | |
10555 return false; | |
10556 } | |
10557 for (var i = 0; i < this._disabledInputs.length; i++) { | |
10558 if (this._disabledInputs[i] === target) { | |
10559 return true; | |
10560 } | |
10561 } | |
10562 return false; | |
10563 }, | |
10564 | |
10565 /* Retrieve the instance data for the target control. | |
10566 * @param target element - the target input field or division or span | |
10567 * @return object - the associated instance data | |
10568 * @throws error if a jQuery problem getting data | |
10569 */ | |
10570 _getInst: function(target) { | |
10571 try { | |
10572 return $.data(target, PROP_NAME); | |
10573 } | |
10574 catch (err) { | |
10575 throw "Missing instance data for this datepicker"; | |
10576 } | |
10577 }, | |
10578 | |
10579 /* Update or retrieve the settings for a date picker attached to an input field or division. | |
10580 * @param target element - the target input field or division or span | |
10581 * @param name object - the new settings to update or | |
10582 * string - the name of the setting to change or retrieve, | |
10583 * when retrieving also "all" for all instance settings or | |
10584 * "defaults" for all global defaults | |
10585 * @param value any - the new value for the setting | |
10586 * (omit if above is an object or to retrieve a value) | |
10587 */ | |
10588 _optionDatepicker: function(target, name, value) { | |
10589 var settings, date, minDate, maxDate, | |
10590 inst = this._getInst(target); | |
10591 | |
10592 if (arguments.length === 2 && typeof name === "string") { | |
10593 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : | |
10594 (inst ? (name === "all" ? $.extend({}, inst.settings) : | |
10595 this._get(inst, name)) : null)); | |
10596 } | |
10597 | |
10598 settings = name || {}; | |
10599 if (typeof name === "string") { | |
10600 settings = {}; | |
10601 settings[name] = value; | |
10602 } | |
10603 | |
10604 if (inst) { | |
10605 if (this._curInst === inst) { | |
10606 this._hideDatepicker(); | |
10607 } | |
10608 | |
10609 date = this._getDateDatepicker(target, true); | |
10610 minDate = this._getMinMaxDate(inst, "min"); | |
10611 maxDate = this._getMinMaxDate(inst, "max"); | |
10612 extendRemove(inst.settings, settings); | |
10613 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided | |
10614 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { | |
10615 inst.settings.minDate = this._formatDate(inst, minDate); | |
10616 } | |
10617 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { | |
10618 inst.settings.maxDate = this._formatDate(inst, maxDate); | |
10619 } | |
10620 if ( "disabled" in settings ) { | |
10621 if ( settings.disabled ) { | |
10622 this._disableDatepicker(target); | |
10623 } else { | |
10624 this._enableDatepicker(target); | |
10625 } | |
10626 } | |
10627 this._attachments($(target), inst); | |
10628 this._autoSize(inst); | |
10629 this._setDate(inst, date); | |
10630 this._updateAlternate(inst); | |
10631 this._updateDatepicker(inst); | |
10632 } | |
10633 }, | |
10634 | |
10635 // change method deprecated | |
10636 _changeDatepicker: function(target, name, value) { | |
10637 this._optionDatepicker(target, name, value); | |
10638 }, | |
10639 | |
10640 /* Redraw the date picker attached to an input field or division. | |
10641 * @param target element - the target input field or division or span | |
10642 */ | |
10643 _refreshDatepicker: function(target) { | |
10644 var inst = this._getInst(target); | |
10645 if (inst) { | |
10646 this._updateDatepicker(inst); | |
10647 } | |
10648 }, | |
10649 | |
10650 /* Set the dates for a jQuery selection. | |
10651 * @param target element - the target input field or division or span | |
10652 * @param date Date - the new date | |
10653 */ | |
10654 _setDateDatepicker: function(target, date) { | |
10655 var inst = this._getInst(target); | |
10656 if (inst) { | |
10657 this._setDate(inst, date); | |
10658 this._updateDatepicker(inst); | |
10659 this._updateAlternate(inst); | |
10660 } | |
10661 }, | |
10662 | |
10663 /* Get the date(s) for the first entry in a jQuery selection. | |
10664 * @param target element - the target input field or division or span | |
10665 * @param noDefault boolean - true if no default date is to be used | |
10666 * @return Date - the current date | |
10667 */ | |
10668 _getDateDatepicker: function(target, noDefault) { | |
10669 var inst = this._getInst(target); | |
10670 if (inst && !inst.inline) { | |
10671 this._setDateFromField(inst, noDefault); | |
10672 } | |
10673 return (inst ? this._getDate(inst) : null); | |
10674 }, | |
10675 | |
10676 /* Handle keystrokes. */ | |
10677 _doKeyDown: function(event) { | |
10678 var onSelect, dateStr, sel, | |
10679 inst = $.datepicker._getInst(event.target), | |
10680 handled = true, | |
10681 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); | |
10682 | |
10683 inst._keyEvent = true; | |
10684 if ($.datepicker._datepickerShowing) { | |
10685 switch (event.keyCode) { | |
10686 case 9: $.datepicker._hideDatepicker(); | |
10687 handled = false; | |
10688 break; // hide on tab out | |
10689 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + | |
10690 $.datepicker._currentClass + ")", inst.dpDiv); | |
10691 if (sel[0]) { | |
10692 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); | |
10693 } | |
10694 | |
10695 onSelect = $.datepicker._get(inst, "onSelect"); | |
10696 if (onSelect) { | |
10697 dateStr = $.datepicker._formatDate(inst); | |
10698 | |
10699 // trigger custom callback | |
10700 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); | |
10701 } else { | |
10702 $.datepicker._hideDatepicker(); | |
10703 } | |
10704 | |
10705 return false; // don't submit the form | |
10706 case 27: $.datepicker._hideDatepicker(); | |
10707 break; // hide on escape | |
10708 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10709 -$.datepicker._get(inst, "stepBigMonths") : | |
10710 -$.datepicker._get(inst, "stepMonths")), "M"); | |
10711 break; // previous month/year on page up/+ ctrl | |
10712 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10713 +$.datepicker._get(inst, "stepBigMonths") : | |
10714 +$.datepicker._get(inst, "stepMonths")), "M"); | |
10715 break; // next month/year on page down/+ ctrl | |
10716 case 35: if (event.ctrlKey || event.metaKey) { | |
10717 $.datepicker._clearDate(event.target); | |
10718 } | |
10719 handled = event.ctrlKey || event.metaKey; | |
10720 break; // clear on ctrl or command +end | |
10721 case 36: if (event.ctrlKey || event.metaKey) { | |
10722 $.datepicker._gotoToday(event.target); | |
10723 } | |
10724 handled = event.ctrlKey || event.metaKey; | |
10725 break; // current on ctrl or command +home | |
10726 case 37: if (event.ctrlKey || event.metaKey) { | |
10727 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); | |
10728 } | |
10729 handled = event.ctrlKey || event.metaKey; | |
10730 // -1 day on ctrl or command +left | |
10731 if (event.originalEvent.altKey) { | |
10732 $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10733 -$.datepicker._get(inst, "stepBigMonths") : | |
10734 -$.datepicker._get(inst, "stepMonths")), "M"); | |
10735 } | |
10736 // next month/year on alt +left on Mac | |
10737 break; | |
10738 case 38: if (event.ctrlKey || event.metaKey) { | |
10739 $.datepicker._adjustDate(event.target, -7, "D"); | |
10740 } | |
10741 handled = event.ctrlKey || event.metaKey; | |
10742 break; // -1 week on ctrl or command +up | |
10743 case 39: if (event.ctrlKey || event.metaKey) { | |
10744 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); | |
10745 } | |
10746 handled = event.ctrlKey || event.metaKey; | |
10747 // +1 day on ctrl or command +right | |
10748 if (event.originalEvent.altKey) { | |
10749 $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10750 +$.datepicker._get(inst, "stepBigMonths") : | |
10751 +$.datepicker._get(inst, "stepMonths")), "M"); | |
10752 } | |
10753 // next month/year on alt +right | |
10754 break; | |
10755 case 40: if (event.ctrlKey || event.metaKey) { | |
10756 $.datepicker._adjustDate(event.target, +7, "D"); | |
10757 } | |
10758 handled = event.ctrlKey || event.metaKey; | |
10759 break; // +1 week on ctrl or command +down | |
10760 default: handled = false; | |
10761 } | |
10762 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home | |
10763 $.datepicker._showDatepicker(this); | |
10764 } else { | |
10765 handled = false; | |
10766 } | |
10767 | |
10768 if (handled) { | |
10769 event.preventDefault(); | |
10770 event.stopPropagation(); | |
10771 } | |
10772 }, | |
10773 | |
10774 /* Filter entered characters - based on date format. */ | |
10775 _doKeyPress: function(event) { | |
10776 var chars, chr, | |
10777 inst = $.datepicker._getInst(event.target); | |
10778 | |
10779 if ($.datepicker._get(inst, "constrainInput")) { | |
10780 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); | |
10781 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); | |
10782 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); | |
10783 } | |
10784 }, | |
10785 | |
10786 /* Synchronise manual entry and field/alternate field. */ | |
10787 _doKeyUp: function(event) { | |
10788 var date, | |
10789 inst = $.datepicker._getInst(event.target); | |
10790 | |
10791 if (inst.input.val() !== inst.lastVal) { | |
10792 try { | |
10793 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), | |
10794 (inst.input ? inst.input.val() : null), | |
10795 $.datepicker._getFormatConfig(inst)); | |
10796 | |
10797 if (date) { // only if valid | |
10798 $.datepicker._setDateFromField(inst); | |
10799 $.datepicker._updateAlternate(inst); | |
10800 $.datepicker._updateDatepicker(inst); | |
10801 } | |
10802 } | |
10803 catch (err) { | |
10804 } | |
10805 } | |
10806 return true; | |
10807 }, | |
10808 | |
10809 /* Pop-up the date picker for a given input field. | |
10810 * If false returned from beforeShow event handler do not show. | |
10811 * @param input element - the input field attached to the date picker or | |
10812 * event - if triggered by focus | |
10813 */ | |
10814 _showDatepicker: function(input) { | |
10815 input = input.target || input; | |
10816 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger | |
10817 input = $("input", input.parentNode)[0]; | |
10818 } | |
10819 | |
10820 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here | |
10821 return; | |
10822 } | |
10823 | |
10824 var inst, beforeShow, beforeShowSettings, isFixed, | |
10825 offset, showAnim, duration; | |
10826 | |
10827 inst = $.datepicker._getInst(input); | |
10828 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { | |
10829 $.datepicker._curInst.dpDiv.stop(true, true); | |
10830 if ( inst && $.datepicker._datepickerShowing ) { | |
10831 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); | |
10832 } | |
10833 } | |
10834 | |
10835 beforeShow = $.datepicker._get(inst, "beforeShow"); | |
10836 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; | |
10837 if(beforeShowSettings === false){ | |
10838 return; | |
10839 } | |
10840 extendRemove(inst.settings, beforeShowSettings); | |
10841 | |
10842 inst.lastVal = null; | |
10843 $.datepicker._lastInput = input; | |
10844 $.datepicker._setDateFromField(inst); | |
10845 | |
10846 if ($.datepicker._inDialog) { // hide cursor | |
10847 input.value = ""; | |
10848 } | |
10849 if (!$.datepicker._pos) { // position below input | |
10850 $.datepicker._pos = $.datepicker._findPos(input); | |
10851 $.datepicker._pos[1] += input.offsetHeight; // add the height | |
10852 } | |
10853 | |
10854 isFixed = false; | |
10855 $(input).parents().each(function() { | |
10856 isFixed |= $(this).css("position") === "fixed"; | |
10857 return !isFixed; | |
10858 }); | |
10859 | |
10860 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; | |
10861 $.datepicker._pos = null; | |
10862 //to avoid flashes on Firefox | |
10863 inst.dpDiv.empty(); | |
10864 // determine sizing offscreen | |
10865 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); | |
10866 $.datepicker._updateDatepicker(inst); | |
10867 // fix width for dynamic number of date pickers | |
10868 // and adjust position before showing | |
10869 offset = $.datepicker._checkOffset(inst, offset, isFixed); | |
10870 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? | |
10871 "static" : (isFixed ? "fixed" : "absolute")), display: "none", | |
10872 left: offset.left + "px", top: offset.top + "px"}); | |
10873 | |
10874 if (!inst.inline) { | |
10875 showAnim = $.datepicker._get(inst, "showAnim"); | |
10876 duration = $.datepicker._get(inst, "duration"); | |
10877 inst.dpDiv.zIndex($(input).zIndex()+1); | |
10878 $.datepicker._datepickerShowing = true; | |
10879 | |
10880 if ( $.effects && $.effects.effect[ showAnim ] ) { | |
10881 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); | |
10882 } else { | |
10883 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); | |
10884 } | |
10885 | |
10886 if ( $.datepicker._shouldFocusInput( inst ) ) { | |
10887 inst.input.focus(); | |
10888 } | |
10889 | |
10890 $.datepicker._curInst = inst; | |
10891 } | |
10892 }, | |
10893 | |
10894 /* Generate the date picker content. */ | |
10895 _updateDatepicker: function(inst) { | |
10896 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) | |
10897 instActive = inst; // for delegate hover events | |
10898 inst.dpDiv.empty().append(this._generateHTML(inst)); | |
10899 this._attachHandlers(inst); | |
10900 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); | |
10901 | |
10902 var origyearshtml, | |
10903 numMonths = this._getNumberOfMonths(inst), | |
10904 cols = numMonths[1], | |
10905 width = 17; | |
10906 | |
10907 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); | |
10908 if (cols > 1) { | |
10909 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); | |
10910 } | |
10911 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + | |
10912 "Class"]("ui-datepicker-multi"); | |
10913 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + | |
10914 "Class"]("ui-datepicker-rtl"); | |
10915 | |
10916 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { | |
10917 inst.input.focus(); | |
10918 } | |
10919 | |
10920 // deffered render of the years select (to avoid flashes on Firefox) | |
10921 if( inst.yearshtml ){ | |
10922 origyearshtml = inst.yearshtml; | |
10923 setTimeout(function(){ | |
10924 //assure that inst.yearshtml didn't change. | |
10925 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ | |
10926 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); | |
10927 } | |
10928 origyearshtml = inst.yearshtml = null; | |
10929 }, 0); | |
10930 } | |
10931 }, | |
10932 | |
10933 // #6694 - don't focus the input if it's already focused | |
10934 // this breaks the change event in IE | |
10935 // Support: IE and jQuery <1.9 | |
10936 _shouldFocusInput: function( inst ) { | |
10937 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); | |
10938 }, | |
10939 | |
10940 /* Check positioning to remain on screen. */ | |
10941 _checkOffset: function(inst, offset, isFixed) { | |
10942 var dpWidth = inst.dpDiv.outerWidth(), | |
10943 dpHeight = inst.dpDiv.outerHeight(), | |
10944 inputWidth = inst.input ? inst.input.outerWidth() : 0, | |
10945 inputHeight = inst.input ? inst.input.outerHeight() : 0, | |
10946 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), | |
10947 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); | |
10948 | |
10949 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); | |
10950 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; | |
10951 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; | |
10952 | |
10953 // now check if datepicker is showing outside window viewport - move to a better place if so. | |
10954 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? | |
10955 Math.abs(offset.left + dpWidth - viewWidth) : 0); | |
10956 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? | |
10957 Math.abs(dpHeight + inputHeight) : 0); | |
10958 | |
10959 return offset; | |
10960 }, | |
10961 | |
10962 /* Find an object's position on the screen. */ | |
10963 _findPos: function(obj) { | |
10964 var position, | |
10965 inst = this._getInst(obj), | |
10966 isRTL = this._get(inst, "isRTL"); | |
10967 | |
10968 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { | |
10969 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; | |
10970 } | |
10971 | |
10972 position = $(obj).offset(); | |
10973 return [position.left, position.top]; | |
10974 }, | |
10975 | |
10976 /* Hide the date picker from view. | |
10977 * @param input element - the input field attached to the date picker | |
10978 */ | |
10979 _hideDatepicker: function(input) { | |
10980 var showAnim, duration, postProcess, onClose, | |
10981 inst = this._curInst; | |
10982 | |
10983 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { | |
10984 return; | |
10985 } | |
10986 | |
10987 if (this._datepickerShowing) { | |
10988 showAnim = this._get(inst, "showAnim"); | |
10989 duration = this._get(inst, "duration"); | |
10990 postProcess = function() { | |
10991 $.datepicker._tidyDialog(inst); | |
10992 }; | |
10993 | |
10994 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed | |
10995 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { | |
10996 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); | |
10997 } else { | |
10998 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : | |
10999 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); | |
11000 } | |
11001 | |
11002 if (!showAnim) { | |
11003 postProcess(); | |
11004 } | |
11005 this._datepickerShowing = false; | |
11006 | |
11007 onClose = this._get(inst, "onClose"); | |
11008 if (onClose) { | |
11009 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); | |
11010 } | |
11011 | |
11012 this._lastInput = null; | |
11013 if (this._inDialog) { | |
11014 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); | |
11015 if ($.blockUI) { | |
11016 $.unblockUI(); | |
11017 $("body").append(this.dpDiv); | |
11018 } | |
11019 } | |
11020 this._inDialog = false; | |
11021 } | |
11022 }, | |
11023 | |
11024 /* Tidy up after a dialog display. */ | |
11025 _tidyDialog: function(inst) { | |
11026 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); | |
11027 }, | |
11028 | |
11029 /* Close date picker if clicked elsewhere. */ | |
11030 _checkExternalClick: function(event) { | |
11031 if (!$.datepicker._curInst) { | |
11032 return; | |
11033 } | |
11034 | |
11035 var $target = $(event.target), | |
11036 inst = $.datepicker._getInst($target[0]); | |
11037 | |
11038 if ( ( ( $target[0].id !== $.datepicker._mainDivId && | |
11039 $target.parents("#" + $.datepicker._mainDivId).length === 0 && | |
11040 !$target.hasClass($.datepicker.markerClassName) && | |
11041 !$target.closest("." + $.datepicker._triggerClass).length && | |
11042 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || | |
11043 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { | |
11044 $.datepicker._hideDatepicker(); | |
11045 } | |
11046 }, | |
11047 | |
11048 /* Adjust one of the date sub-fields. */ | |
11049 _adjustDate: function(id, offset, period) { | |
11050 var target = $(id), | |
11051 inst = this._getInst(target[0]); | |
11052 | |
11053 if (this._isDisabledDatepicker(target[0])) { | |
11054 return; | |
11055 } | |
11056 this._adjustInstDate(inst, offset + | |
11057 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning | |
11058 period); | |
11059 this._updateDatepicker(inst); | |
11060 }, | |
11061 | |
11062 /* Action for current link. */ | |
11063 _gotoToday: function(id) { | |
11064 var date, | |
11065 target = $(id), | |
11066 inst = this._getInst(target[0]); | |
11067 | |
11068 if (this._get(inst, "gotoCurrent") && inst.currentDay) { | |
11069 inst.selectedDay = inst.currentDay; | |
11070 inst.drawMonth = inst.selectedMonth = inst.currentMonth; | |
11071 inst.drawYear = inst.selectedYear = inst.currentYear; | |
11072 } else { | |
11073 date = new Date(); | |
11074 inst.selectedDay = date.getDate(); | |
11075 inst.drawMonth = inst.selectedMonth = date.getMonth(); | |
11076 inst.drawYear = inst.selectedYear = date.getFullYear(); | |
11077 } | |
11078 this._notifyChange(inst); | |
11079 this._adjustDate(target); | |
11080 }, | |
11081 | |
11082 /* Action for selecting a new month/year. */ | |
11083 _selectMonthYear: function(id, select, period) { | |
11084 var target = $(id), | |
11085 inst = this._getInst(target[0]); | |
11086 | |
11087 inst["selected" + (period === "M" ? "Month" : "Year")] = | |
11088 inst["draw" + (period === "M" ? "Month" : "Year")] = | |
11089 parseInt(select.options[select.selectedIndex].value,10); | |
11090 | |
11091 this._notifyChange(inst); | |
11092 this._adjustDate(target); | |
11093 }, | |
11094 | |
11095 /* Action for selecting a day. */ | |
11096 _selectDay: function(id, month, year, td) { | |
11097 var inst, | |
11098 target = $(id); | |
11099 | |
11100 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { | |
11101 return; | |
11102 } | |
11103 | |
11104 inst = this._getInst(target[0]); | |
11105 inst.selectedDay = inst.currentDay = $("a", td).html(); | |
11106 inst.selectedMonth = inst.currentMonth = month; | |
11107 inst.selectedYear = inst.currentYear = year; | |
11108 this._selectDate(id, this._formatDate(inst, | |
11109 inst.currentDay, inst.currentMonth, inst.currentYear)); | |
11110 }, | |
11111 | |
11112 /* Erase the input field and hide the date picker. */ | |
11113 _clearDate: function(id) { | |
11114 var target = $(id); | |
11115 this._selectDate(target, ""); | |
11116 }, | |
11117 | |
11118 /* Update the input field with the selected date. */ | |
11119 _selectDate: function(id, dateStr) { | |
11120 var onSelect, | |
11121 target = $(id), | |
11122 inst = this._getInst(target[0]); | |
11123 | |
11124 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); | |
11125 if (inst.input) { | |
11126 inst.input.val(dateStr); | |
11127 } | |
11128 this._updateAlternate(inst); | |
11129 | |
11130 onSelect = this._get(inst, "onSelect"); | |
11131 if (onSelect) { | |
11132 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback | |
11133 } else if (inst.input) { | |
11134 inst.input.trigger("change"); // fire the change event | |
11135 } | |
11136 | |
11137 if (inst.inline){ | |
11138 this._updateDatepicker(inst); | |
11139 } else { | |
11140 this._hideDatepicker(); | |
11141 this._lastInput = inst.input[0]; | |
11142 if (typeof(inst.input[0]) !== "object") { | |
11143 inst.input.focus(); // restore focus | |
11144 } | |
11145 this._lastInput = null; | |
11146 } | |
11147 }, | |
11148 | |
11149 /* Update any alternate field to synchronise with the main field. */ | |
11150 _updateAlternate: function(inst) { | |
11151 var altFormat, date, dateStr, | |
11152 altField = this._get(inst, "altField"); | |
11153 | |
11154 if (altField) { // update alternate field too | |
11155 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); | |
11156 date = this._getDate(inst); | |
11157 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); | |
11158 $(altField).each(function() { $(this).val(dateStr); }); | |
11159 } | |
11160 }, | |
11161 | |
11162 /* Set as beforeShowDay function to prevent selection of weekends. | |
11163 * @param date Date - the date to customise | |
11164 * @return [boolean, string] - is this date selectable?, what is its CSS class? | |
11165 */ | |
11166 noWeekends: function(date) { | |
11167 var day = date.getDay(); | |
11168 return [(day > 0 && day < 6), ""]; | |
11169 }, | |
11170 | |
11171 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. | |
11172 * @param date Date - the date to get the week for | |
11173 * @return number - the number of the week within the year that contains this date | |
11174 */ | |
11175 iso8601Week: function(date) { | |
11176 var time, | |
11177 checkDate = new Date(date.getTime()); | |
11178 | |
11179 // Find Thursday of this week starting on Monday | |
11180 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); | |
11181 | |
11182 time = checkDate.getTime(); | |
11183 checkDate.setMonth(0); // Compare with Jan 1 | |
11184 checkDate.setDate(1); | |
11185 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; | |
11186 }, | |
11187 | |
11188 /* Parse a string value into a date object. | |
11189 * See formatDate below for the possible formats. | |
11190 * | |
11191 * @param format string - the expected format of the date | |
11192 * @param value string - the date in the above format | |
11193 * @param settings Object - attributes include: | |
11194 * shortYearCutoff number - the cutoff year for determining the century (optional) | |
11195 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) | |
11196 * dayNames string[7] - names of the days from Sunday (optional) | |
11197 * monthNamesShort string[12] - abbreviated names of the months (optional) | |
11198 * monthNames string[12] - names of the months (optional) | |
11199 * @return Date - the extracted date value or null if value is blank | |
11200 */ | |
11201 parseDate: function (format, value, settings) { | |
11202 if (format == null || value == null) { | |
11203 throw "Invalid arguments"; | |
11204 } | |
11205 | |
11206 value = (typeof value === "object" ? value.toString() : value + ""); | |
11207 if (value === "") { | |
11208 return null; | |
11209 } | |
11210 | |
11211 var iFormat, dim, extra, | |
11212 iValue = 0, | |
11213 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, | |
11214 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : | |
11215 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), | |
11216 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, | |
11217 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, | |
11218 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, | |
11219 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, | |
11220 year = -1, | |
11221 month = -1, | |
11222 day = -1, | |
11223 doy = -1, | |
11224 literal = false, | |
11225 date, | |
11226 // Check whether a format character is doubled | |
11227 lookAhead = function(match) { | |
11228 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); | |
11229 if (matches) { | |
11230 iFormat++; | |
11231 } | |
11232 return matches; | |
11233 }, | |
11234 // Extract a number from the string value | |
11235 getNumber = function(match) { | |
11236 var isDoubled = lookAhead(match), | |
11237 size = (match === "@" ? 14 : (match === "!" ? 20 : | |
11238 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), | |
11239 digits = new RegExp("^\\d{1," + size + "}"), | |
11240 num = value.substring(iValue).match(digits); | |
11241 if (!num) { | |
11242 throw "Missing number at position " + iValue; | |
11243 } | |
11244 iValue += num[0].length; | |
11245 return parseInt(num[0], 10); | |
11246 }, | |
11247 // Extract a name from the string value and convert to an index | |
11248 getName = function(match, shortNames, longNames) { | |
11249 var index = -1, | |
11250 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { | |
11251 return [ [k, v] ]; | |
11252 }).sort(function (a, b) { | |
11253 return -(a[1].length - b[1].length); | |
11254 }); | |
11255 | |
11256 $.each(names, function (i, pair) { | |
11257 var name = pair[1]; | |
11258 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { | |
11259 index = pair[0]; | |
11260 iValue += name.length; | |
11261 return false; | |
11262 } | |
11263 }); | |
11264 if (index !== -1) { | |
11265 return index + 1; | |
11266 } else { | |
11267 throw "Unknown name at position " + iValue; | |
11268 } | |
11269 }, | |
11270 // Confirm that a literal character matches the string value | |
11271 checkLiteral = function() { | |
11272 if (value.charAt(iValue) !== format.charAt(iFormat)) { | |
11273 throw "Unexpected literal at position " + iValue; | |
11274 } | |
11275 iValue++; | |
11276 }; | |
11277 | |
11278 for (iFormat = 0; iFormat < format.length; iFormat++) { | |
11279 if (literal) { | |
11280 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { | |
11281 literal = false; | |
11282 } else { | |
11283 checkLiteral(); | |
11284 } | |
11285 } else { | |
11286 switch (format.charAt(iFormat)) { | |
11287 case "d": | |
11288 day = getNumber("d"); | |
11289 break; | |
11290 case "D": | |
11291 getName("D", dayNamesShort, dayNames); | |
11292 break; | |
11293 case "o": | |
11294 doy = getNumber("o"); | |
11295 break; | |
11296 case "m": | |
11297 month = getNumber("m"); | |
11298 break; | |
11299 case "M": | |
11300 month = getName("M", monthNamesShort, monthNames); | |
11301 break; | |
11302 case "y": | |
11303 year = getNumber("y"); | |
11304 break; | |
11305 case "@": | |
11306 date = new Date(getNumber("@")); | |
11307 year = date.getFullYear(); | |
11308 month = date.getMonth() + 1; | |
11309 day = date.getDate(); | |
11310 break; | |
11311 case "!": | |
11312 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); | |
11313 year = date.getFullYear(); | |
11314 month = date.getMonth() + 1; | |
11315 day = date.getDate(); | |
11316 break; | |
11317 case "'": | |
11318 if (lookAhead("'")){ | |
11319 checkLiteral(); | |
11320 } else { | |
11321 literal = true; | |
11322 } | |
11323 break; | |
11324 default: | |
11325 checkLiteral(); | |
11326 } | |
11327 } | |
11328 } | |
11329 | |
11330 if (iValue < value.length){ | |
11331 extra = value.substr(iValue); | |
11332 if (!/^\s+/.test(extra)) { | |
11333 throw "Extra/unparsed characters found in date: " + extra; | |
11334 } | |
11335 } | |
11336 | |
11337 if (year === -1) { | |
11338 year = new Date().getFullYear(); | |
11339 } else if (year < 100) { | |
11340 year += new Date().getFullYear() - new Date().getFullYear() % 100 + | |
11341 (year <= shortYearCutoff ? 0 : -100); | |
11342 } | |
11343 | |
11344 if (doy > -1) { | |
11345 month = 1; | |
11346 day = doy; | |
11347 do { | |
11348 dim = this._getDaysInMonth(year, month - 1); | |
11349 if (day <= dim) { | |
11350 break; | |
11351 } | |
11352 month++; | |
11353 day -= dim; | |
11354 } while (true); | |
11355 } | |
11356 | |
11357 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); | |
11358 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { | |
11359 throw "Invalid date"; // E.g. 31/02/00 | |
11360 } | |
11361 return date; | |
11362 }, | |
11363 | |
11364 /* Standard date formats. */ | |
11365 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) | |
11366 COOKIE: "D, dd M yy", | |
11367 ISO_8601: "yy-mm-dd", | |
11368 RFC_822: "D, d M y", | |
11369 RFC_850: "DD, dd-M-y", | |
11370 RFC_1036: "D, d M y", | |
11371 RFC_1123: "D, d M yy", | |
11372 RFC_2822: "D, d M yy", | |
11373 RSS: "D, d M y", // RFC 822 | |
11374 TICKS: "!", | |
11375 TIMESTAMP: "@", | |
11376 W3C: "yy-mm-dd", // ISO 8601 | |
11377 | |
11378 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + | |
11379 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), | |
11380 | |
11381 /* Format a date object into a string value. | |
11382 * The format can be combinations of the following: | |
11383 * d - day of month (no leading zero) | |
11384 * dd - day of month (two digit) | |
11385 * o - day of year (no leading zeros) | |
11386 * oo - day of year (three digit) | |
11387 * D - day name short | |
11388 * DD - day name long | |
11389 * m - month of year (no leading zero) | |
11390 * mm - month of year (two digit) | |
11391 * M - month name short | |
11392 * MM - month name long | |
11393 * y - year (two digit) | |
11394 * yy - year (four digit) | |
11395 * @ - Unix timestamp (ms since 01/01/1970) | |
11396 * ! - Windows ticks (100ns since 01/01/0001) | |
11397 * "..." - literal text | |
11398 * '' - single quote | |
11399 * | |
11400 * @param format string - the desired format of the date | |
11401 * @param date Date - the date value to format | |
11402 * @param settings Object - attributes include: | |
11403 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) | |
11404 * dayNames string[7] - names of the days from Sunday (optional) | |
11405 * monthNamesShort string[12] - abbreviated names of the months (optional) | |
11406 * monthNames string[12] - names of the months (optional) | |
11407 * @return string - the date in the above format | |
11408 */ | |
11409 formatDate: function (format, date, settings) { | |
11410 if (!date) { | |
11411 return ""; | |
11412 } | |
11413 | |
11414 var iFormat, | |
11415 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, | |
11416 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, | |
11417 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, | |
11418 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, | |
11419 // Check whether a format character is doubled | |
11420 lookAhead = function(match) { | |
11421 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); | |
11422 if (matches) { | |
11423 iFormat++; | |
11424 } | |
11425 return matches; | |
11426 }, | |
11427 // Format a number, with leading zero if necessary | |
11428 formatNumber = function(match, value, len) { | |
11429 var num = "" + value; | |
11430 if (lookAhead(match)) { | |
11431 while (num.length < len) { | |
11432 num = "0" + num; | |
11433 } | |
11434 } | |
11435 return num; | |
11436 }, | |
11437 // Format a name, short or long as requested | |
11438 formatName = function(match, value, shortNames, longNames) { | |
11439 return (lookAhead(match) ? longNames[value] : shortNames[value]); | |
11440 }, | |
11441 output = "", | |
11442 literal = false; | |
11443 | |
11444 if (date) { | |
11445 for (iFormat = 0; iFormat < format.length; iFormat++) { | |
11446 if (literal) { | |
11447 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { | |
11448 literal = false; | |
11449 } else { | |
11450 output += format.charAt(iFormat); | |
11451 } | |
11452 } else { | |
11453 switch (format.charAt(iFormat)) { | |
11454 case "d": | |
11455 output += formatNumber("d", date.getDate(), 2); | |
11456 break; | |
11457 case "D": | |
11458 output += formatName("D", date.getDay(), dayNamesShort, dayNames); | |
11459 break; | |
11460 case "o": | |
11461 output += formatNumber("o", | |
11462 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); | |
11463 break; | |
11464 case "m": | |
11465 output += formatNumber("m", date.getMonth() + 1, 2); | |
11466 break; | |
11467 case "M": | |
11468 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); | |
11469 break; | |
11470 case "y": | |
11471 output += (lookAhead("y") ? date.getFullYear() : | |
11472 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); | |
11473 break; | |
11474 case "@": | |
11475 output += date.getTime(); | |
11476 break; | |
11477 case "!": | |
11478 output += date.getTime() * 10000 + this._ticksTo1970; | |
11479 break; | |
11480 case "'": | |
11481 if (lookAhead("'")) { | |
11482 output += "'"; | |
11483 } else { | |
11484 literal = true; | |
11485 } | |
11486 break; | |
11487 default: | |
11488 output += format.charAt(iFormat); | |
11489 } | |
11490 } | |
11491 } | |
11492 } | |
11493 return output; | |
11494 }, | |
11495 | |
11496 /* Extract all possible characters from the date format. */ | |
11497 _possibleChars: function (format) { | |
11498 var iFormat, | |
11499 chars = "", | |
11500 literal = false, | |
11501 // Check whether a format character is doubled | |
11502 lookAhead = function(match) { | |
11503 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); | |
11504 if (matches) { | |
11505 iFormat++; | |
11506 } | |
11507 return matches; | |
11508 }; | |
11509 | |
11510 for (iFormat = 0; iFormat < format.length; iFormat++) { | |
11511 if (literal) { | |
11512 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { | |
11513 literal = false; | |
11514 } else { | |
11515 chars += format.charAt(iFormat); | |
11516 } | |
11517 } else { | |
11518 switch (format.charAt(iFormat)) { | |
11519 case "d": case "m": case "y": case "@": | |
11520 chars += "0123456789"; | |
11521 break; | |
11522 case "D": case "M": | |
11523 return null; // Accept anything | |
11524 case "'": | |
11525 if (lookAhead("'")) { | |
11526 chars += "'"; | |
11527 } else { | |
11528 literal = true; | |
11529 } | |
11530 break; | |
11531 default: | |
11532 chars += format.charAt(iFormat); | |
11533 } | |
11534 } | |
11535 } | |
11536 return chars; | |
11537 }, | |
11538 | |
11539 /* Get a setting value, defaulting if necessary. */ | |
11540 _get: function(inst, name) { | |
11541 return inst.settings[name] !== undefined ? | |
11542 inst.settings[name] : this._defaults[name]; | |
11543 }, | |
11544 | |
11545 /* Parse existing date and initialise date picker. */ | |
11546 _setDateFromField: function(inst, noDefault) { | |
11547 if (inst.input.val() === inst.lastVal) { | |
11548 return; | |
11549 } | |
11550 | |
11551 var dateFormat = this._get(inst, "dateFormat"), | |
11552 dates = inst.lastVal = inst.input ? inst.input.val() : null, | |
11553 defaultDate = this._getDefaultDate(inst), | |
11554 date = defaultDate, | |
11555 settings = this._getFormatConfig(inst); | |
11556 | |
11557 try { | |
11558 date = this.parseDate(dateFormat, dates, settings) || defaultDate; | |
11559 } catch (event) { | |
11560 dates = (noDefault ? "" : dates); | |
11561 } | |
11562 inst.selectedDay = date.getDate(); | |
11563 inst.drawMonth = inst.selectedMonth = date.getMonth(); | |
11564 inst.drawYear = inst.selectedYear = date.getFullYear(); | |
11565 inst.currentDay = (dates ? date.getDate() : 0); | |
11566 inst.currentMonth = (dates ? date.getMonth() : 0); | |
11567 inst.currentYear = (dates ? date.getFullYear() : 0); | |
11568 this._adjustInstDate(inst); | |
11569 }, | |
11570 | |
11571 /* Retrieve the default date shown on opening. */ | |
11572 _getDefaultDate: function(inst) { | |
11573 return this._restrictMinMax(inst, | |
11574 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); | |
11575 }, | |
11576 | |
11577 /* A date may be specified as an exact value or a relative one. */ | |
11578 _determineDate: function(inst, date, defaultDate) { | |
11579 var offsetNumeric = function(offset) { | |
11580 var date = new Date(); | |
11581 date.setDate(date.getDate() + offset); | |
11582 return date; | |
11583 }, | |
11584 offsetString = function(offset) { | |
11585 try { | |
11586 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), | |
11587 offset, $.datepicker._getFormatConfig(inst)); | |
11588 } | |
11589 catch (e) { | |
11590 // Ignore | |
11591 } | |
11592 | |
11593 var date = (offset.toLowerCase().match(/^c/) ? | |
11594 $.datepicker._getDate(inst) : null) || new Date(), | |
11595 year = date.getFullYear(), | |
11596 month = date.getMonth(), | |
11597 day = date.getDate(), | |
11598 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, | |
11599 matches = pattern.exec(offset); | |
11600 | |
11601 while (matches) { | |
11602 switch (matches[2] || "d") { | |
11603 case "d" : case "D" : | |
11604 day += parseInt(matches[1],10); break; | |
11605 case "w" : case "W" : | |
11606 day += parseInt(matches[1],10) * 7; break; | |
11607 case "m" : case "M" : | |
11608 month += parseInt(matches[1],10); | |
11609 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); | |
11610 break; | |
11611 case "y": case "Y" : | |
11612 year += parseInt(matches[1],10); | |
11613 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); | |
11614 break; | |
11615 } | |
11616 matches = pattern.exec(offset); | |
11617 } | |
11618 return new Date(year, month, day); | |
11619 }, | |
11620 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : | |
11621 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); | |
11622 | |
11623 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); | |
11624 if (newDate) { | |
11625 newDate.setHours(0); | |
11626 newDate.setMinutes(0); | |
11627 newDate.setSeconds(0); | |
11628 newDate.setMilliseconds(0); | |
11629 } | |
11630 return this._daylightSavingAdjust(newDate); | |
11631 }, | |
11632 | |
11633 /* Handle switch to/from daylight saving. | |
11634 * Hours may be non-zero on daylight saving cut-over: | |
11635 * > 12 when midnight changeover, but then cannot generate | |
11636 * midnight datetime, so jump to 1AM, otherwise reset. | |
11637 * @param date (Date) the date to check | |
11638 * @return (Date) the corrected date | |
11639 */ | |
11640 _daylightSavingAdjust: function(date) { | |
11641 if (!date) { | |
11642 return null; | |
11643 } | |
11644 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); | |
11645 return date; | |
11646 }, | |
11647 | |
11648 /* Set the date(s) directly. */ | |
11649 _setDate: function(inst, date, noChange) { | |
11650 var clear = !date, | |
11651 origMonth = inst.selectedMonth, | |
11652 origYear = inst.selectedYear, | |
11653 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); | |
11654 | |
11655 inst.selectedDay = inst.currentDay = newDate.getDate(); | |
11656 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); | |
11657 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); | |
11658 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { | |
11659 this._notifyChange(inst); | |
11660 } | |
11661 this._adjustInstDate(inst); | |
11662 if (inst.input) { | |
11663 inst.input.val(clear ? "" : this._formatDate(inst)); | |
11664 } | |
11665 }, | |
11666 | |
11667 /* Retrieve the date(s) directly. */ | |
11668 _getDate: function(inst) { | |
11669 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : | |
11670 this._daylightSavingAdjust(new Date( | |
11671 inst.currentYear, inst.currentMonth, inst.currentDay))); | |
11672 return startDate; | |
11673 }, | |
11674 | |
11675 /* Attach the onxxx handlers. These are declared statically so | |
11676 * they work with static code transformers like Caja. | |
11677 */ | |
11678 _attachHandlers: function(inst) { | |
11679 var stepMonths = this._get(inst, "stepMonths"), | |
11680 id = "#" + inst.id.replace( /\\\\/g, "\\" ); | |
11681 inst.dpDiv.find("[data-handler]").map(function () { | |
11682 var handler = { | |
11683 prev: function () { | |
11684 $.datepicker._adjustDate(id, -stepMonths, "M"); | |
11685 }, | |
11686 next: function () { | |
11687 $.datepicker._adjustDate(id, +stepMonths, "M"); | |
11688 }, | |
11689 hide: function () { | |
11690 $.datepicker._hideDatepicker(); | |
11691 }, | |
11692 today: function () { | |
11693 $.datepicker._gotoToday(id); | |
11694 }, | |
11695 selectDay: function () { | |
11696 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); | |
11697 return false; | |
11698 }, | |
11699 selectMonth: function () { | |
11700 $.datepicker._selectMonthYear(id, this, "M"); | |
11701 return false; | |
11702 }, | |
11703 selectYear: function () { | |
11704 $.datepicker._selectMonthYear(id, this, "Y"); | |
11705 return false; | |
11706 } | |
11707 }; | |
11708 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); | |
11709 }); | |
11710 }, | |
11711 | |
11712 /* Generate the HTML for the current state of the date picker. */ | |
11713 _generateHTML: function(inst) { | |
11714 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, | |
11715 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, | |
11716 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, | |
11717 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, | |
11718 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, | |
11719 printDate, dRow, tbody, daySettings, otherMonth, unselectable, | |
11720 tempDate = new Date(), | |
11721 today = this._daylightSavingAdjust( | |
11722 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time | |
11723 isRTL = this._get(inst, "isRTL"), | |
11724 showButtonPanel = this._get(inst, "showButtonPanel"), | |
11725 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), | |
11726 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), | |
11727 numMonths = this._getNumberOfMonths(inst), | |
11728 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), | |
11729 stepMonths = this._get(inst, "stepMonths"), | |
11730 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), | |
11731 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : | |
11732 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), | |
11733 minDate = this._getMinMaxDate(inst, "min"), | |
11734 maxDate = this._getMinMaxDate(inst, "max"), | |
11735 drawMonth = inst.drawMonth - showCurrentAtPos, | |
11736 drawYear = inst.drawYear; | |
11737 | |
11738 if (drawMonth < 0) { | |
11739 drawMonth += 12; | |
11740 drawYear--; | |
11741 } | |
11742 if (maxDate) { | |
11743 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), | |
11744 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); | |
11745 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); | |
11746 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { | |
11747 drawMonth--; | |
11748 if (drawMonth < 0) { | |
11749 drawMonth = 11; | |
11750 drawYear--; | |
11751 } | |
11752 } | |
11753 } | |
11754 inst.drawMonth = drawMonth; | |
11755 inst.drawYear = drawYear; | |
11756 | |
11757 prevText = this._get(inst, "prevText"); | |
11758 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, | |
11759 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), | |
11760 this._getFormatConfig(inst))); | |
11761 | |
11762 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? | |
11763 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + | |
11764 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : | |
11765 (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>")); | |
11766 | |
11767 nextText = this._get(inst, "nextText"); | |
11768 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, | |
11769 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), | |
11770 this._getFormatConfig(inst))); | |
11771 | |
11772 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? | |
11773 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + | |
11774 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : | |
11775 (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>")); | |
11776 | |
11777 currentText = this._get(inst, "currentText"); | |
11778 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); | |
11779 currentText = (!navigationAsDateFormat ? currentText : | |
11780 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); | |
11781 | |
11782 controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + | |
11783 this._get(inst, "closeText") + "</button>" : ""); | |
11784 | |
11785 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + | |
11786 (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + | |
11787 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; | |
11788 | |
11789 firstDay = parseInt(this._get(inst, "firstDay"),10); | |
11790 firstDay = (isNaN(firstDay) ? 0 : firstDay); | |
11791 | |
11792 showWeek = this._get(inst, "showWeek"); | |
11793 dayNames = this._get(inst, "dayNames"); | |
11794 dayNamesMin = this._get(inst, "dayNamesMin"); | |
11795 monthNames = this._get(inst, "monthNames"); | |
11796 monthNamesShort = this._get(inst, "monthNamesShort"); | |
11797 beforeShowDay = this._get(inst, "beforeShowDay"); | |
11798 showOtherMonths = this._get(inst, "showOtherMonths"); | |
11799 selectOtherMonths = this._get(inst, "selectOtherMonths"); | |
11800 defaultDate = this._getDefaultDate(inst); | |
11801 html = ""; | |
11802 dow; | |
11803 for (row = 0; row < numMonths[0]; row++) { | |
11804 group = ""; | |
11805 this.maxRows = 4; | |
11806 for (col = 0; col < numMonths[1]; col++) { | |
11807 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); | |
11808 cornerClass = " ui-corner-all"; | |
11809 calender = ""; | |
11810 if (isMultiMonth) { | |
11811 calender += "<div class='ui-datepicker-group"; | |
11812 if (numMonths[1] > 1) { | |
11813 switch (col) { | |
11814 case 0: calender += " ui-datepicker-group-first"; | |
11815 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; | |
11816 case numMonths[1]-1: calender += " ui-datepicker-group-last"; | |
11817 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; | |
11818 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; | |
11819 } | |
11820 } | |
11821 calender += "'>"; | |
11822 } | |
11823 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + | |
11824 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + | |
11825 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + | |
11826 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, | |
11827 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers | |
11828 "</div><table class='ui-datepicker-calendar'><thead>" + | |
11829 "<tr>"; | |
11830 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); | |
11831 for (dow = 0; dow < 7; dow++) { // days of the week | |
11832 day = (dow + firstDay) % 7; | |
11833 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + | |
11834 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; | |
11835 } | |
11836 calender += thead + "</tr></thead><tbody>"; | |
11837 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); | |
11838 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { | |
11839 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); | |
11840 } | |
11841 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; | |
11842 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate | |
11843 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) | |
11844 this.maxRows = numRows; | |
11845 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); | |
11846 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows | |
11847 calender += "<tr>"; | |
11848 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + | |
11849 this._get(inst, "calculateWeek")(printDate) + "</td>"); | |
11850 for (dow = 0; dow < 7; dow++) { // create date picker days | |
11851 daySettings = (beforeShowDay ? | |
11852 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); | |
11853 otherMonth = (printDate.getMonth() !== drawMonth); | |
11854 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || | |
11855 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); | |
11856 tbody += "<td class='" + | |
11857 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends | |
11858 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months | |
11859 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key | |
11860 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? | |
11861 // or defaultDate is current printedDate and defaultDate is selectedDate | |
11862 " " + this._dayOverClass : "") + // highlight selected day | |
11863 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days | |
11864 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates | |
11865 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day | |
11866 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) | |
11867 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title | |
11868 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions | |
11869 (otherMonth && !showOtherMonths ? " " : // display for other months | |
11870 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + | |
11871 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + | |
11872 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day | |
11873 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months | |
11874 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date | |
11875 printDate.setDate(printDate.getDate() + 1); | |
11876 printDate = this._daylightSavingAdjust(printDate); | |
11877 } | |
11878 calender += tbody + "</tr>"; | |
11879 } | |
11880 drawMonth++; | |
11881 if (drawMonth > 11) { | |
11882 drawMonth = 0; | |
11883 drawYear++; | |
11884 } | |
11885 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + | |
11886 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); | |
11887 group += calender; | |
11888 } | |
11889 html += group; | |
11890 } | |
11891 html += buttonPanel; | |
11892 inst._keyEvent = false; | |
11893 return html; | |
11894 }, | |
11895 | |
11896 /* Generate the month and year header. */ | |
11897 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, | |
11898 secondary, monthNames, monthNamesShort) { | |
11899 | |
11900 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, | |
11901 changeMonth = this._get(inst, "changeMonth"), | |
11902 changeYear = this._get(inst, "changeYear"), | |
11903 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), | |
11904 html = "<div class='ui-datepicker-title'>", | |
11905 monthHtml = ""; | |
11906 | |
11907 // month selection | |
11908 if (secondary || !changeMonth) { | |
11909 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; | |
11910 } else { | |
11911 inMinYear = (minDate && minDate.getFullYear() === drawYear); | |
11912 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); | |
11913 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; | |
11914 for ( month = 0; month < 12; month++) { | |
11915 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { | |
11916 monthHtml += "<option value='" + month + "'" + | |
11917 (month === drawMonth ? " selected='selected'" : "") + | |
11918 ">" + monthNamesShort[month] + "</option>"; | |
11919 } | |
11920 } | |
11921 monthHtml += "</select>"; | |
11922 } | |
11923 | |
11924 if (!showMonthAfterYear) { | |
11925 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); | |
11926 } | |
11927 | |
11928 // year selection | |
11929 if ( !inst.yearshtml ) { | |
11930 inst.yearshtml = ""; | |
11931 if (secondary || !changeYear) { | |
11932 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; | |
11933 } else { | |
11934 // determine range of years to display | |
11935 years = this._get(inst, "yearRange").split(":"); | |
11936 thisYear = new Date().getFullYear(); | |
11937 determineYear = function(value) { | |
11938 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : | |
11939 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : | |
11940 parseInt(value, 10))); | |
11941 return (isNaN(year) ? thisYear : year); | |
11942 }; | |
11943 year = determineYear(years[0]); | |
11944 endYear = Math.max(year, determineYear(years[1] || "")); | |
11945 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); | |
11946 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); | |
11947 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; | |
11948 for (; year <= endYear; year++) { | |
11949 inst.yearshtml += "<option value='" + year + "'" + | |
11950 (year === drawYear ? " selected='selected'" : "") + | |
11951 ">" + year + "</option>"; | |
11952 } | |
11953 inst.yearshtml += "</select>"; | |
11954 | |
11955 html += inst.yearshtml; | |
11956 inst.yearshtml = null; | |
11957 } | |
11958 } | |
11959 | |
11960 html += this._get(inst, "yearSuffix"); | |
11961 if (showMonthAfterYear) { | |
11962 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; | |
11963 } | |
11964 html += "</div>"; // Close datepicker_header | |
11965 return html; | |
11966 }, | |
11967 | |
11968 /* Adjust one of the date sub-fields. */ | |
11969 _adjustInstDate: function(inst, offset, period) { | |
11970 var year = inst.drawYear + (period === "Y" ? offset : 0), | |
11971 month = inst.drawMonth + (period === "M" ? offset : 0), | |
11972 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), | |
11973 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); | |
11974 | |
11975 inst.selectedDay = date.getDate(); | |
11976 inst.drawMonth = inst.selectedMonth = date.getMonth(); | |
11977 inst.drawYear = inst.selectedYear = date.getFullYear(); | |
11978 if (period === "M" || period === "Y") { | |
11979 this._notifyChange(inst); | |
11980 } | |
11981 }, | |
11982 | |
11983 /* Ensure a date is within any min/max bounds. */ | |
11984 _restrictMinMax: function(inst, date) { | |
11985 var minDate = this._getMinMaxDate(inst, "min"), | |
11986 maxDate = this._getMinMaxDate(inst, "max"), | |
11987 newDate = (minDate && date < minDate ? minDate : date); | |
11988 return (maxDate && newDate > maxDate ? maxDate : newDate); | |
11989 }, | |
11990 | |
11991 /* Notify change of month/year. */ | |
11992 _notifyChange: function(inst) { | |
11993 var onChange = this._get(inst, "onChangeMonthYear"); | |
11994 if (onChange) { | |
11995 onChange.apply((inst.input ? inst.input[0] : null), | |
11996 [inst.selectedYear, inst.selectedMonth + 1, inst]); | |
11997 } | |
11998 }, | |
11999 | |
12000 /* Determine the number of months to show. */ | |
12001 _getNumberOfMonths: function(inst) { | |
12002 var numMonths = this._get(inst, "numberOfMonths"); | |
12003 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); | |
12004 }, | |
12005 | |
12006 /* Determine the current maximum date - ensure no time components are set. */ | |
12007 _getMinMaxDate: function(inst, minMax) { | |
12008 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); | |
12009 }, | |
12010 | |
12011 /* Find the number of days in a given month. */ | |
12012 _getDaysInMonth: function(year, month) { | |
12013 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); | |
12014 }, | |
12015 | |
12016 /* Find the day of the week of the first of a month. */ | |
12017 _getFirstDayOfMonth: function(year, month) { | |
12018 return new Date(year, month, 1).getDay(); | |
12019 }, | |
12020 | |
12021 /* Determines if we should allow a "next/prev" month display change. */ | |
12022 _canAdjustMonth: function(inst, offset, curYear, curMonth) { | |
12023 var numMonths = this._getNumberOfMonths(inst), | |
12024 date = this._daylightSavingAdjust(new Date(curYear, | |
12025 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); | |
12026 | |
12027 if (offset < 0) { | |
12028 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); | |
12029 } | |
12030 return this._isInRange(inst, date); | |
12031 }, | |
12032 | |
12033 /* Is the given date in the accepted range? */ | |
12034 _isInRange: function(inst, date) { | |
12035 var yearSplit, currentYear, | |
12036 minDate = this._getMinMaxDate(inst, "min"), | |
12037 maxDate = this._getMinMaxDate(inst, "max"), | |
12038 minYear = null, | |
12039 maxYear = null, | |
12040 years = this._get(inst, "yearRange"); | |
12041 if (years){ | |
12042 yearSplit = years.split(":"); | |
12043 currentYear = new Date().getFullYear(); | |
12044 minYear = parseInt(yearSplit[0], 10); | |
12045 maxYear = parseInt(yearSplit[1], 10); | |
12046 if ( yearSplit[0].match(/[+\-].*/) ) { | |
12047 minYear += currentYear; | |
12048 } | |
12049 if ( yearSplit[1].match(/[+\-].*/) ) { | |
12050 maxYear += currentYear; | |
12051 } | |
12052 } | |
12053 | |
12054 return ((!minDate || date.getTime() >= minDate.getTime()) && | |
12055 (!maxDate || date.getTime() <= maxDate.getTime()) && | |
12056 (!minYear || date.getFullYear() >= minYear) && | |
12057 (!maxYear || date.getFullYear() <= maxYear)); | |
12058 }, | |
12059 | |
12060 /* Provide the configuration settings for formatting/parsing. */ | |
12061 _getFormatConfig: function(inst) { | |
12062 var shortYearCutoff = this._get(inst, "shortYearCutoff"); | |
12063 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : | |
12064 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); | |
12065 return {shortYearCutoff: shortYearCutoff, | |
12066 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), | |
12067 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; | |
12068 }, | |
12069 | |
12070 /* Format the given date for display. */ | |
12071 _formatDate: function(inst, day, month, year) { | |
12072 if (!day) { | |
12073 inst.currentDay = inst.selectedDay; | |
12074 inst.currentMonth = inst.selectedMonth; | |
12075 inst.currentYear = inst.selectedYear; | |
12076 } | |
12077 var date = (day ? (typeof day === "object" ? day : | |
12078 this._daylightSavingAdjust(new Date(year, month, day))) : | |
12079 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); | |
12080 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); | |
12081 } | |
12082 }); | |
12083 | |
12084 /* | |
12085 * Bind hover events for datepicker elements. | |
12086 * Done via delegate so the binding only occurs once in the lifetime of the parent div. | |
12087 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. | |
12088 */ | |
12089 function bindHover(dpDiv) { | |
12090 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; | |
12091 return dpDiv.delegate(selector, "mouseout", function() { | |
12092 $(this).removeClass("ui-state-hover"); | |
12093 if (this.className.indexOf("ui-datepicker-prev") !== -1) { | |
12094 $(this).removeClass("ui-datepicker-prev-hover"); | |
12095 } | |
12096 if (this.className.indexOf("ui-datepicker-next") !== -1) { | |
12097 $(this).removeClass("ui-datepicker-next-hover"); | |
12098 } | |
12099 }) | |
12100 .delegate(selector, "mouseover", function(){ | |
12101 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { | |
12102 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); | |
12103 $(this).addClass("ui-state-hover"); | |
12104 if (this.className.indexOf("ui-datepicker-prev") !== -1) { | |
12105 $(this).addClass("ui-datepicker-prev-hover"); | |
12106 } | |
12107 if (this.className.indexOf("ui-datepicker-next") !== -1) { | |
12108 $(this).addClass("ui-datepicker-next-hover"); | |
12109 } | |
12110 } | |
12111 }); | |
12112 } | |
12113 | |
12114 /* jQuery extend now ignores nulls! */ | |
12115 function extendRemove(target, props) { | |
12116 $.extend(target, props); | |
12117 for (var name in props) { | |
12118 if (props[name] == null) { | |
12119 target[name] = props[name]; | |
12120 } | |
12121 } | |
12122 return target; | |
12123 } | |
12124 | |
12125 /* Invoke the datepicker functionality. | |
12126 @param options string - a command, optionally followed by additional parameters or | |
12127 Object - settings for attaching new datepicker functionality | |
12128 @return jQuery object */ | |
12129 $.fn.datepicker = function(options){ | |
12130 | |
12131 /* Verify an empty collection wasn't passed - Fixes #6976 */ | |
12132 if ( !this.length ) { | |
12133 return this; | |
12134 } | |
12135 | |
12136 /* Initialise the date picker. */ | |
12137 if (!$.datepicker.initialized) { | |
12138 $(document).mousedown($.datepicker._checkExternalClick); | |
12139 $.datepicker.initialized = true; | |
12140 } | |
12141 | |
12142 /* Append datepicker main container to body if not exist. */ | |
12143 if ($("#"+$.datepicker._mainDivId).length === 0) { | |
12144 $("body").append($.datepicker.dpDiv); | |
12145 } | |
12146 | |
12147 var otherArgs = Array.prototype.slice.call(arguments, 1); | |
12148 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { | |
12149 return $.datepicker["_" + options + "Datepicker"]. | |
12150 apply($.datepicker, [this[0]].concat(otherArgs)); | |
12151 } | |
12152 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { | |
12153 return $.datepicker["_" + options + "Datepicker"]. | |
12154 apply($.datepicker, [this[0]].concat(otherArgs)); | |
12155 } | |
12156 return this.each(function() { | |
12157 typeof options === "string" ? | |
12158 $.datepicker["_" + options + "Datepicker"]. | |
12159 apply($.datepicker, [this].concat(otherArgs)) : | |
12160 $.datepicker._attachDatepicker(this, options); | |
12161 }); | |
12162 }; | |
12163 | |
12164 $.datepicker = new Datepicker(); // singleton instance | |
12165 $.datepicker.initialized = false; | |
12166 $.datepicker.uuid = new Date().getTime(); | |
12167 $.datepicker.version = "1.10.3"; | |
12168 | |
12169 })(jQuery); | |
12170 (function( $, undefined ) { | |
12171 | |
12172 var sizeRelatedOptions = { | |
12173 buttons: true, | |
12174 height: true, | |
12175 maxHeight: true, | |
12176 maxWidth: true, | |
12177 minHeight: true, | |
12178 minWidth: true, | |
12179 width: true | |
12180 }, | |
12181 resizableRelatedOptions = { | |
12182 maxHeight: true, | |
12183 maxWidth: true, | |
12184 minHeight: true, | |
12185 minWidth: true | |
12186 }; | |
12187 | |
12188 $.widget( "ui.dialog", { | |
12189 version: "1.10.3", | |
12190 options: { | |
12191 appendTo: "body", | |
12192 autoOpen: true, | |
12193 buttons: [], | |
12194 closeOnEscape: true, | |
12195 closeText: "close", | |
12196 dialogClass: "", | |
12197 draggable: true, | |
12198 hide: null, | |
12199 height: "auto", | |
12200 maxHeight: null, | |
12201 maxWidth: null, | |
12202 minHeight: 150, | |
12203 minWidth: 150, | |
12204 modal: false, | |
12205 position: { | |
12206 my: "center", | |
12207 at: "center", | |
12208 of: window, | |
12209 collision: "fit", | |
12210 // Ensure the titlebar is always visible | |
12211 using: function( pos ) { | |
12212 var topOffset = $( this ).css( pos ).offset().top; | |
12213 if ( topOffset < 0 ) { | |
12214 $( this ).css( "top", pos.top - topOffset ); | |
12215 } | |
12216 } | |
12217 }, | |
12218 resizable: true, | |
12219 show: null, | |
12220 title: null, | |
12221 width: 300, | |
12222 | |
12223 // callbacks | |
12224 beforeClose: null, | |
12225 close: null, | |
12226 drag: null, | |
12227 dragStart: null, | |
12228 dragStop: null, | |
12229 focus: null, | |
12230 open: null, | |
12231 resize: null, | |
12232 resizeStart: null, | |
12233 resizeStop: null | |
12234 }, | |
12235 | |
12236 _create: function() { | |
12237 this.originalCss = { | |
12238 display: this.element[0].style.display, | |
12239 width: this.element[0].style.width, | |
12240 minHeight: this.element[0].style.minHeight, | |
12241 maxHeight: this.element[0].style.maxHeight, | |
12242 height: this.element[0].style.height | |
12243 }; | |
12244 this.originalPosition = { | |
12245 parent: this.element.parent(), | |
12246 index: this.element.parent().children().index( this.element ) | |
12247 }; | |
12248 this.originalTitle = this.element.attr("title"); | |
12249 this.options.title = this.options.title || this.originalTitle; | |
12250 | |
12251 this._createWrapper(); | |
12252 | |
12253 this.element | |
12254 .show() | |
12255 .removeAttr("title") | |
12256 .addClass("ui-dialog-content ui-widget-content") | |
12257 .appendTo( this.uiDialog ); | |
12258 | |
12259 this._createTitlebar(); | |
12260 this._createButtonPane(); | |
12261 | |
12262 if ( this.options.draggable && $.fn.draggable ) { | |
12263 this._makeDraggable(); | |
12264 } | |
12265 if ( this.options.resizable && $.fn.resizable ) { | |
12266 this._makeResizable(); | |
12267 } | |
12268 | |
12269 this._isOpen = false; | |
12270 }, | |
12271 | |
12272 _init: function() { | |
12273 if ( this.options.autoOpen ) { | |
12274 this.open(); | |
12275 } | |
12276 }, | |
12277 | |
12278 _appendTo: function() { | |
12279 var element = this.options.appendTo; | |
12280 if ( element && (element.jquery || element.nodeType) ) { | |
12281 return $( element ); | |
12282 } | |
12283 return this.document.find( element || "body" ).eq( 0 ); | |
12284 }, | |
12285 | |
12286 _destroy: function() { | |
12287 var next, | |
12288 originalPosition = this.originalPosition; | |
12289 | |
12290 this._destroyOverlay(); | |
12291 | |
12292 this.element | |
12293 .removeUniqueId() | |
12294 .removeClass("ui-dialog-content ui-widget-content") | |
12295 .css( this.originalCss ) | |
12296 // Without detaching first, the following becomes really slow | |
12297 .detach(); | |
12298 | |
12299 this.uiDialog.stop( true, true ).remove(); | |
12300 | |
12301 if ( this.originalTitle ) { | |
12302 this.element.attr( "title", this.originalTitle ); | |
12303 } | |
12304 | |
12305 next = originalPosition.parent.children().eq( originalPosition.index ); | |
12306 // Don't try to place the dialog next to itself (#8613) | |
12307 if ( next.length && next[0] !== this.element[0] ) { | |
12308 next.before( this.element ); | |
12309 } else { | |
12310 originalPosition.parent.append( this.element ); | |
12311 } | |
12312 }, | |
12313 | |
12314 widget: function() { | |
12315 return this.uiDialog; | |
12316 }, | |
12317 | |
12318 disable: $.noop, | |
12319 enable: $.noop, | |
12320 | |
12321 close: function( event ) { | |
12322 var that = this; | |
12323 | |
12324 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { | |
12325 return; | |
12326 } | |
12327 | |
12328 this._isOpen = false; | |
12329 this._destroyOverlay(); | |
12330 | |
12331 if ( !this.opener.filter(":focusable").focus().length ) { | |
12332 // Hiding a focused element doesn't trigger blur in WebKit | |
12333 // so in case we have nothing to focus on, explicitly blur the active element | |
12334 // https://bugs.webkit.org/show_bug.cgi?id=47182 | |
12335 $( this.document[0].activeElement ).blur(); | |
12336 } | |
12337 | |
12338 this._hide( this.uiDialog, this.options.hide, function() { | |
12339 that._trigger( "close", event ); | |
12340 }); | |
12341 }, | |
12342 | |
12343 isOpen: function() { | |
12344 return this._isOpen; | |
12345 }, | |
12346 | |
12347 moveToTop: function() { | |
12348 this._moveToTop(); | |
12349 }, | |
12350 | |
12351 _moveToTop: function( event, silent ) { | |
12352 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; | |
12353 if ( moved && !silent ) { | |
12354 this._trigger( "focus", event ); | |
12355 } | |
12356 return moved; | |
12357 }, | |
12358 | |
12359 open: function() { | |
12360 var that = this; | |
12361 if ( this._isOpen ) { | |
12362 if ( this._moveToTop() ) { | |
12363 this._focusTabbable(); | |
12364 } | |
12365 return; | |
12366 } | |
12367 | |
12368 this._isOpen = true; | |
12369 this.opener = $( this.document[0].activeElement ); | |
12370 | |
12371 this._size(); | |
12372 this._position(); | |
12373 this._createOverlay(); | |
12374 this._moveToTop( null, true ); | |
12375 this._show( this.uiDialog, this.options.show, function() { | |
12376 that._focusTabbable(); | |
12377 that._trigger("focus"); | |
12378 }); | |
12379 | |
12380 this._trigger("open"); | |
12381 }, | |
12382 | |
12383 _focusTabbable: function() { | |
12384 // Set focus to the first match: | |
12385 // 1. First element inside the dialog matching [autofocus] | |
12386 // 2. Tabbable element inside the content element | |
12387 // 3. Tabbable element inside the buttonpane | |
12388 // 4. The close button | |
12389 // 5. The dialog itself | |
12390 var hasFocus = this.element.find("[autofocus]"); | |
12391 if ( !hasFocus.length ) { | |
12392 hasFocus = this.element.find(":tabbable"); | |
12393 } | |
12394 if ( !hasFocus.length ) { | |
12395 hasFocus = this.uiDialogButtonPane.find(":tabbable"); | |
12396 } | |
12397 if ( !hasFocus.length ) { | |
12398 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); | |
12399 } | |
12400 if ( !hasFocus.length ) { | |
12401 hasFocus = this.uiDialog; | |
12402 } | |
12403 hasFocus.eq( 0 ).focus(); | |
12404 }, | |
12405 | |
12406 _keepFocus: function( event ) { | |
12407 function checkFocus() { | |
12408 var activeElement = this.document[0].activeElement, | |
12409 isActive = this.uiDialog[0] === activeElement || | |
12410 $.contains( this.uiDialog[0], activeElement ); | |
12411 if ( !isActive ) { | |
12412 this._focusTabbable(); | |
12413 } | |
12414 } | |
12415 event.preventDefault(); | |
12416 checkFocus.call( this ); | |
12417 // support: IE | |
12418 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() | |
12419 // so we check again later | |
12420 this._delay( checkFocus ); | |
12421 }, | |
12422 | |
12423 _createWrapper: function() { | |
12424 this.uiDialog = $("<div>") | |
12425 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + | |
12426 this.options.dialogClass ) | |
12427 .hide() | |
12428 .attr({ | |
12429 // Setting tabIndex makes the div focusable | |
12430 tabIndex: -1, | |
12431 role: "dialog" | |
12432 }) | |
12433 .appendTo( this._appendTo() ); | |
12434 | |
12435 this._on( this.uiDialog, { | |
12436 keydown: function( event ) { | |
12437 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && | |
12438 event.keyCode === $.ui.keyCode.ESCAPE ) { | |
12439 event.preventDefault(); | |
12440 this.close( event ); | |
12441 return; | |
12442 } | |
12443 | |
12444 // prevent tabbing out of dialogs | |
12445 if ( event.keyCode !== $.ui.keyCode.TAB ) { | |
12446 return; | |
12447 } | |
12448 var tabbables = this.uiDialog.find(":tabbable"), | |
12449 first = tabbables.filter(":first"), | |
12450 last = tabbables.filter(":last"); | |
12451 | |
12452 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { | |
12453 first.focus( 1 ); | |
12454 event.preventDefault(); | |
12455 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { | |
12456 last.focus( 1 ); | |
12457 event.preventDefault(); | |
12458 } | |
12459 }, | |
12460 mousedown: function( event ) { | |
12461 if ( this._moveToTop( event ) ) { | |
12462 this._focusTabbable(); | |
12463 } | |
12464 } | |
12465 }); | |
12466 | |
12467 // We assume that any existing aria-describedby attribute means | |
12468 // that the dialog content is marked up properly | |
12469 // otherwise we brute force the content as the description | |
12470 if ( !this.element.find("[aria-describedby]").length ) { | |
12471 this.uiDialog.attr({ | |
12472 "aria-describedby": this.element.uniqueId().attr("id") | |
12473 }); | |
12474 } | |
12475 }, | |
12476 | |
12477 _createTitlebar: function() { | |
12478 var uiDialogTitle; | |
12479 | |
12480 this.uiDialogTitlebar = $("<div>") | |
12481 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") | |
12482 .prependTo( this.uiDialog ); | |
12483 this._on( this.uiDialogTitlebar, { | |
12484 mousedown: function( event ) { | |
12485 // Don't prevent click on close button (#8838) | |
12486 // Focusing a dialog that is partially scrolled out of view | |
12487 // causes the browser to scroll it into view, preventing the click event | |
12488 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { | |
12489 // Dialog isn't getting focus when dragging (#8063) | |
12490 this.uiDialog.focus(); | |
12491 } | |
12492 } | |
12493 }); | |
12494 | |
12495 this.uiDialogTitlebarClose = $("<button></button>") | |
12496 .button({ | |
12497 label: this.options.closeText, | |
12498 icons: { | |
12499 primary: "ui-icon-closethick" | |
12500 }, | |
12501 text: false | |
12502 }) | |
12503 .addClass("ui-dialog-titlebar-close") | |
12504 .appendTo( this.uiDialogTitlebar ); | |
12505 this._on( this.uiDialogTitlebarClose, { | |
12506 click: function( event ) { | |
12507 event.preventDefault(); | |
12508 this.close( event ); | |
12509 } | |
12510 }); | |
12511 | |
12512 uiDialogTitle = $("<span>") | |
12513 .uniqueId() | |
12514 .addClass("ui-dialog-title") | |
12515 .prependTo( this.uiDialogTitlebar ); | |
12516 this._title( uiDialogTitle ); | |
12517 | |
12518 this.uiDialog.attr({ | |
12519 "aria-labelledby": uiDialogTitle.attr("id") | |
12520 }); | |
12521 }, | |
12522 | |
12523 _title: function( title ) { | |
12524 if ( !this.options.title ) { | |
12525 title.html(" "); | |
12526 } | |
12527 title.text( this.options.title ); | |
12528 }, | |
12529 | |
12530 _createButtonPane: function() { | |
12531 this.uiDialogButtonPane = $("<div>") | |
12532 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); | |
12533 | |
12534 this.uiButtonSet = $("<div>") | |
12535 .addClass("ui-dialog-buttonset") | |
12536 .appendTo( this.uiDialogButtonPane ); | |
12537 | |
12538 this._createButtons(); | |
12539 }, | |
12540 | |
12541 _createButtons: function() { | |
12542 var that = this, | |
12543 buttons = this.options.buttons; | |
12544 | |
12545 // if we already have a button pane, remove it | |
12546 this.uiDialogButtonPane.remove(); | |
12547 this.uiButtonSet.empty(); | |
12548 | |
12549 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { | |
12550 this.uiDialog.removeClass("ui-dialog-buttons"); | |
12551 return; | |
12552 } | |
12553 | |
12554 $.each( buttons, function( name, props ) { | |
12555 var click, buttonOptions; | |
12556 props = $.isFunction( props ) ? | |
12557 { click: props, text: name } : | |
12558 props; | |
12559 // Default to a non-submitting button | |
12560 props = $.extend( { type: "button" }, props ); | |
12561 // Change the context for the click callback to be the main element | |
12562 click = props.click; | |
12563 props.click = function() { | |
12564 click.apply( that.element[0], arguments ); | |
12565 }; | |
12566 buttonOptions = { | |
12567 icons: props.icons, | |
12568 text: props.showText | |
12569 }; | |
12570 delete props.icons; | |
12571 delete props.showText; | |
12572 $( "<button></button>", props ) | |
12573 .button( buttonOptions ) | |
12574 .appendTo( that.uiButtonSet ); | |
12575 }); | |
12576 this.uiDialog.addClass("ui-dialog-buttons"); | |
12577 this.uiDialogButtonPane.appendTo( this.uiDialog ); | |
12578 }, | |
12579 | |
12580 _makeDraggable: function() { | |
12581 var that = this, | |
12582 options = this.options; | |
12583 | |
12584 function filteredUi( ui ) { | |
12585 return { | |
12586 position: ui.position, | |
12587 offset: ui.offset | |
12588 }; | |
12589 } | |
12590 | |
12591 this.uiDialog.draggable({ | |
12592 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", | |
12593 handle: ".ui-dialog-titlebar", | |
12594 containment: "document", | |
12595 start: function( event, ui ) { | |
12596 $( this ).addClass("ui-dialog-dragging"); | |
12597 that._blockFrames(); | |
12598 that._trigger( "dragStart", event, filteredUi( ui ) ); | |
12599 }, | |
12600 drag: function( event, ui ) { | |
12601 that._trigger( "drag", event, filteredUi( ui ) ); | |
12602 }, | |
12603 stop: function( event, ui ) { | |
12604 options.position = [ | |
12605 ui.position.left - that.document.scrollLeft(), | |
12606 ui.position.top - that.document.scrollTop() | |
12607 ]; | |
12608 $( this ).removeClass("ui-dialog-dragging"); | |
12609 that._unblockFrames(); | |
12610 that._trigger( "dragStop", event, filteredUi( ui ) ); | |
12611 } | |
12612 }); | |
12613 }, | |
12614 | |
12615 _makeResizable: function() { | |
12616 var that = this, | |
12617 options = this.options, | |
12618 handles = options.resizable, | |
12619 // .ui-resizable has position: relative defined in the stylesheet | |
12620 // but dialogs have to use absolute or fixed positioning | |
12621 position = this.uiDialog.css("position"), | |
12622 resizeHandles = typeof handles === "string" ? | |
12623 handles : | |
12624 "n,e,s,w,se,sw,ne,nw"; | |
12625 | |
12626 function filteredUi( ui ) { | |
12627 return { | |
12628 originalPosition: ui.originalPosition, | |
12629 originalSize: ui.originalSize, | |
12630 position: ui.position, | |
12631 size: ui.size | |
12632 }; | |
12633 } | |
12634 | |
12635 this.uiDialog.resizable({ | |
12636 cancel: ".ui-dialog-content", | |
12637 containment: "document", | |
12638 alsoResize: this.element, | |
12639 maxWidth: options.maxWidth, | |
12640 maxHeight: options.maxHeight, | |
12641 minWidth: options.minWidth, | |
12642 minHeight: this._minHeight(), | |
12643 handles: resizeHandles, | |
12644 start: function( event, ui ) { | |
12645 $( this ).addClass("ui-dialog-resizing"); | |
12646 that._blockFrames(); | |
12647 that._trigger( "resizeStart", event, filteredUi( ui ) ); | |
12648 }, | |
12649 resize: function( event, ui ) { | |
12650 that._trigger( "resize", event, filteredUi( ui ) ); | |
12651 }, | |
12652 stop: function( event, ui ) { | |
12653 options.height = $( this ).height(); | |
12654 options.width = $( this ).width(); | |
12655 $( this ).removeClass("ui-dialog-resizing"); | |
12656 that._unblockFrames(); | |
12657 that._trigger( "resizeStop", event, filteredUi( ui ) ); | |
12658 } | |
12659 }) | |
12660 .css( "position", position ); | |
12661 }, | |
12662 | |
12663 _minHeight: function() { | |
12664 var options = this.options; | |
12665 | |
12666 return options.height === "auto" ? | |
12667 options.minHeight : | |
12668 Math.min( options.minHeight, options.height ); | |
12669 }, | |
12670 | |
12671 _position: function() { | |
12672 // Need to show the dialog to get the actual offset in the position plugin | |
12673 var isVisible = this.uiDialog.is(":visible"); | |
12674 if ( !isVisible ) { | |
12675 this.uiDialog.show(); | |
12676 } | |
12677 this.uiDialog.position( this.options.position ); | |
12678 if ( !isVisible ) { | |
12679 this.uiDialog.hide(); | |
12680 } | |
12681 }, | |
12682 | |
12683 _setOptions: function( options ) { | |
12684 var that = this, | |
12685 resize = false, | |
12686 resizableOptions = {}; | |
12687 | |
12688 $.each( options, function( key, value ) { | |
12689 that._setOption( key, value ); | |
12690 | |
12691 if ( key in sizeRelatedOptions ) { | |
12692 resize = true; | |
12693 } | |
12694 if ( key in resizableRelatedOptions ) { | |
12695 resizableOptions[ key ] = value; | |
12696 } | |
12697 }); | |
12698 | |
12699 if ( resize ) { | |
12700 this._size(); | |
12701 this._position(); | |
12702 } | |
12703 if ( this.uiDialog.is(":data(ui-resizable)") ) { | |
12704 this.uiDialog.resizable( "option", resizableOptions ); | |
12705 } | |
12706 }, | |
12707 | |
12708 _setOption: function( key, value ) { | |
12709 /*jshint maxcomplexity:15*/ | |
12710 var isDraggable, isResizable, | |
12711 uiDialog = this.uiDialog; | |
12712 | |
12713 if ( key === "dialogClass" ) { | |
12714 uiDialog | |
12715 .removeClass( this.options.dialogClass ) | |
12716 .addClass( value ); | |
12717 } | |
12718 | |
12719 if ( key === "disabled" ) { | |
12720 return; | |
12721 } | |
12722 | |
12723 this._super( key, value ); | |
12724 | |
12725 if ( key === "appendTo" ) { | |
12726 this.uiDialog.appendTo( this._appendTo() ); | |
12727 } | |
12728 | |
12729 if ( key === "buttons" ) { | |
12730 this._createButtons(); | |
12731 } | |
12732 | |
12733 if ( key === "closeText" ) { | |
12734 this.uiDialogTitlebarClose.button({ | |
12735 // Ensure that we always pass a string | |
12736 label: "" + value | |
12737 }); | |
12738 } | |
12739 | |
12740 if ( key === "draggable" ) { | |
12741 isDraggable = uiDialog.is(":data(ui-draggable)"); | |
12742 if ( isDraggable && !value ) { | |
12743 uiDialog.draggable("destroy"); | |
12744 } | |
12745 | |
12746 if ( !isDraggable && value ) { | |
12747 this._makeDraggable(); | |
12748 } | |
12749 } | |
12750 | |
12751 if ( key === "position" ) { | |
12752 this._position(); | |
12753 } | |
12754 | |
12755 if ( key === "resizable" ) { | |
12756 // currently resizable, becoming non-resizable | |
12757 isResizable = uiDialog.is(":data(ui-resizable)"); | |
12758 if ( isResizable && !value ) { | |
12759 uiDialog.resizable("destroy"); | |
12760 } | |
12761 | |
12762 // currently resizable, changing handles | |
12763 if ( isResizable && typeof value === "string" ) { | |
12764 uiDialog.resizable( "option", "handles", value ); | |
12765 } | |
12766 | |
12767 // currently non-resizable, becoming resizable | |
12768 if ( !isResizable && value !== false ) { | |
12769 this._makeResizable(); | |
12770 } | |
12771 } | |
12772 | |
12773 if ( key === "title" ) { | |
12774 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); | |
12775 } | |
12776 }, | |
12777 | |
12778 _size: function() { | |
12779 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content | |
12780 // divs will both have width and height set, so we need to reset them | |
12781 var nonContentHeight, minContentHeight, maxContentHeight, | |
12782 options = this.options; | |
12783 | |
12784 // Reset content sizing | |
12785 this.element.show().css({ | |
12786 width: "auto", | |
12787 minHeight: 0, | |
12788 maxHeight: "none", | |
12789 height: 0 | |
12790 }); | |
12791 | |
12792 if ( options.minWidth > options.width ) { | |
12793 options.width = options.minWidth; | |
12794 } | |
12795 | |
12796 // reset wrapper sizing | |
12797 // determine the height of all the non-content elements | |
12798 nonContentHeight = this.uiDialog.css({ | |
12799 height: "auto", | |
12800 width: options.width | |
12801 }) | |
12802 .outerHeight(); | |
12803 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); | |
12804 maxContentHeight = typeof options.maxHeight === "number" ? | |
12805 Math.max( 0, options.maxHeight - nonContentHeight ) : | |
12806 "none"; | |
12807 | |
12808 if ( options.height === "auto" ) { | |
12809 this.element.css({ | |
12810 minHeight: minContentHeight, | |
12811 maxHeight: maxContentHeight, | |
12812 height: "auto" | |
12813 }); | |
12814 } else { | |
12815 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); | |
12816 } | |
12817 | |
12818 if (this.uiDialog.is(":data(ui-resizable)") ) { | |
12819 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); | |
12820 } | |
12821 }, | |
12822 | |
12823 _blockFrames: function() { | |
12824 this.iframeBlocks = this.document.find( "iframe" ).map(function() { | |
12825 var iframe = $( this ); | |
12826 | |
12827 return $( "<div>" ) | |
12828 .css({ | |
12829 position: "absolute", | |
12830 width: iframe.outerWidth(), | |
12831 height: iframe.outerHeight() | |
12832 }) | |
12833 .appendTo( iframe.parent() ) | |
12834 .offset( iframe.offset() )[0]; | |
12835 }); | |
12836 }, | |
12837 | |
12838 _unblockFrames: function() { | |
12839 if ( this.iframeBlocks ) { | |
12840 this.iframeBlocks.remove(); | |
12841 delete this.iframeBlocks; | |
12842 } | |
12843 }, | |
12844 | |
12845 _allowInteraction: function( event ) { | |
12846 if ( $( event.target ).closest(".ui-dialog").length ) { | |
12847 return true; | |
12848 } | |
12849 | |
12850 // TODO: Remove hack when datepicker implements | |
12851 // the .ui-front logic (#8989) | |
12852 return !!$( event.target ).closest(".ui-datepicker").length; | |
12853 }, | |
12854 | |
12855 _createOverlay: function() { | |
12856 if ( !this.options.modal ) { | |
12857 return; | |
12858 } | |
12859 | |
12860 var that = this, | |
12861 widgetFullName = this.widgetFullName; | |
12862 if ( !$.ui.dialog.overlayInstances ) { | |
12863 // Prevent use of anchors and inputs. | |
12864 // We use a delay in case the overlay is created from an | |
12865 // event that we're going to be cancelling. (#2804) | |
12866 this._delay(function() { | |
12867 // Handle .dialog().dialog("close") (#4065) | |
12868 if ( $.ui.dialog.overlayInstances ) { | |
12869 this.document.bind( "focusin.dialog", function( event ) { | |
12870 if ( !that._allowInteraction( event ) ) { | |
12871 event.preventDefault(); | |
12872 $(".ui-dialog:visible:last .ui-dialog-content") | |
12873 .data( widgetFullName )._focusTabbable(); | |
12874 } | |
12875 }); | |
12876 } | |
12877 }); | |
12878 } | |
12879 | |
12880 this.overlay = $("<div>") | |
12881 .addClass("ui-widget-overlay ui-front") | |
12882 .appendTo( this._appendTo() ); | |
12883 this._on( this.overlay, { | |
12884 mousedown: "_keepFocus" | |
12885 }); | |
12886 $.ui.dialog.overlayInstances++; | |
12887 }, | |
12888 | |
12889 _destroyOverlay: function() { | |
12890 if ( !this.options.modal ) { | |
12891 return; | |
12892 } | |
12893 | |
12894 if ( this.overlay ) { | |
12895 $.ui.dialog.overlayInstances--; | |
12896 | |
12897 if ( !$.ui.dialog.overlayInstances ) { | |
12898 this.document.unbind( "focusin.dialog" ); | |
12899 } | |
12900 this.overlay.remove(); | |
12901 this.overlay = null; | |
12902 } | |
12903 } | |
12904 }); | |
12905 | |
12906 $.ui.dialog.overlayInstances = 0; | |
12907 | |
12908 // DEPRECATED | |
12909 if ( $.uiBackCompat !== false ) { | |
12910 // position option with array notation | |
12911 // just override with old implementation | |
12912 $.widget( "ui.dialog", $.ui.dialog, { | |
12913 _position: function() { | |
12914 var position = this.options.position, | |
12915 myAt = [], | |
12916 offset = [ 0, 0 ], | |
12917 isVisible; | |
12918 | |
12919 if ( position ) { | |
12920 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { | |
12921 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; | |
12922 if ( myAt.length === 1 ) { | |
12923 myAt[1] = myAt[0]; | |
12924 } | |
12925 | |
12926 $.each( [ "left", "top" ], function( i, offsetPosition ) { | |
12927 if ( +myAt[ i ] === myAt[ i ] ) { | |
12928 offset[ i ] = myAt[ i ]; | |
12929 myAt[ i ] = offsetPosition; | |
12930 } | |
12931 }); | |
12932 | |
12933 position = { | |
12934 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + | |
12935 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), | |
12936 at: myAt.join(" ") | |
12937 }; | |
12938 } | |
12939 | |
12940 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); | |
12941 } else { | |
12942 position = $.ui.dialog.prototype.options.position; | |
12943 } | |
12944 | |
12945 // need to show the dialog to get the actual offset in the position plugin | |
12946 isVisible = this.uiDialog.is(":visible"); | |
12947 if ( !isVisible ) { | |
12948 this.uiDialog.show(); | |
12949 } | |
12950 this.uiDialog.position( position ); | |
12951 if ( !isVisible ) { | |
12952 this.uiDialog.hide(); | |
12953 } | |
12954 } | |
12955 }); | |
12956 } | |
12957 | |
12958 }( jQuery ) ); | |
12959 (function( $, undefined ) { | |
12960 | |
12961 $.widget( "ui.menu", { | |
12962 version: "1.10.3", | |
12963 defaultElement: "<ul>", | |
12964 delay: 300, | |
12965 options: { | |
12966 icons: { | |
12967 submenu: "ui-icon-carat-1-e" | |
12968 }, | |
12969 menus: "ul", | |
12970 position: { | |
12971 my: "left top", | |
12972 at: "right top" | |
12973 }, | |
12974 role: "menu", | |
12975 | |
12976 // callbacks | |
12977 blur: null, | |
12978 focus: null, | |
12979 select: null | |
12980 }, | |
12981 | |
12982 _create: function() { | |
12983 this.activeMenu = this.element; | |
12984 // flag used to prevent firing of the click handler | |
12985 // as the event bubbles up through nested menus | |
12986 this.mouseHandled = false; | |
12987 this.element | |
12988 .uniqueId() | |
12989 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) | |
12990 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) | |
12991 .attr({ | |
12992 role: this.options.role, | |
12993 tabIndex: 0 | |
12994 }) | |
12995 // need to catch all clicks on disabled menu | |
12996 // not possible through _on | |
12997 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { | |
12998 if ( this.options.disabled ) { | |
12999 event.preventDefault(); | |
13000 } | |
13001 }, this )); | |
13002 | |
13003 if ( this.options.disabled ) { | |
13004 this.element | |
13005 .addClass( "ui-state-disabled" ) | |
13006 .attr( "aria-disabled", "true" ); | |
13007 } | |
13008 | |
13009 this._on({ | |
13010 // Prevent focus from sticking to links inside menu after clicking | |
13011 // them (focus should always stay on UL during navigation). | |
13012 "mousedown .ui-menu-item > a": function( event ) { | |
13013 event.preventDefault(); | |
13014 }, | |
13015 "click .ui-state-disabled > a": function( event ) { | |
13016 event.preventDefault(); | |
13017 }, | |
13018 "click .ui-menu-item:has(a)": function( event ) { | |
13019 var target = $( event.target ).closest( ".ui-menu-item" ); | |
13020 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { | |
13021 this.mouseHandled = true; | |
13022 | |
13023 this.select( event ); | |
13024 // Open submenu on click | |
13025 if ( target.has( ".ui-menu" ).length ) { | |
13026 this.expand( event ); | |
13027 } else if ( !this.element.is( ":focus" ) ) { | |
13028 // Redirect focus to the menu | |
13029 this.element.trigger( "focus", [ true ] ); | |
13030 | |
13031 // If the active item is on the top level, let it stay active. | |
13032 // Otherwise, blur the active item since it is no longer visible. | |
13033 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { | |
13034 clearTimeout( this.timer ); | |
13035 } | |
13036 } | |
13037 } | |
13038 }, | |
13039 "mouseenter .ui-menu-item": function( event ) { | |
13040 var target = $( event.currentTarget ); | |
13041 // Remove ui-state-active class from siblings of the newly focused menu item | |
13042 // to avoid a jump caused by adjacent elements both having a class with a border | |
13043 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); | |
13044 this.focus( event, target ); | |
13045 }, | |
13046 mouseleave: "collapseAll", | |
13047 "mouseleave .ui-menu": "collapseAll", | |
13048 focus: function( event, keepActiveItem ) { | |
13049 // If there's already an active item, keep it active | |
13050 // If not, activate the first item | |
13051 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); | |
13052 | |
13053 if ( !keepActiveItem ) { | |
13054 this.focus( event, item ); | |
13055 } | |
13056 }, | |
13057 blur: function( event ) { | |
13058 this._delay(function() { | |
13059 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { | |
13060 this.collapseAll( event ); | |
13061 } | |
13062 }); | |
13063 }, | |
13064 keydown: "_keydown" | |
13065 }); | |
13066 | |
13067 this.refresh(); | |
13068 | |
13069 // Clicks outside of a menu collapse any open menus | |
13070 this._on( this.document, { | |
13071 click: function( event ) { | |
13072 if ( !$( event.target ).closest( ".ui-menu" ).length ) { | |
13073 this.collapseAll( event ); | |
13074 } | |
13075 | |
13076 // Reset the mouseHandled flag | |
13077 this.mouseHandled = false; | |
13078 } | |
13079 }); | |
13080 }, | |
13081 | |
13082 _destroy: function() { | |
13083 // Destroy (sub)menus | |
13084 this.element | |
13085 .removeAttr( "aria-activedescendant" ) | |
13086 .find( ".ui-menu" ).addBack() | |
13087 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) | |
13088 .removeAttr( "role" ) | |
13089 .removeAttr( "tabIndex" ) | |
13090 .removeAttr( "aria-labelledby" ) | |
13091 .removeAttr( "aria-expanded" ) | |
13092 .removeAttr( "aria-hidden" ) | |
13093 .removeAttr( "aria-disabled" ) | |
13094 .removeUniqueId() | |
13095 .show(); | |
13096 | |
13097 // Destroy menu items | |
13098 this.element.find( ".ui-menu-item" ) | |
13099 .removeClass( "ui-menu-item" ) | |
13100 .removeAttr( "role" ) | |
13101 .removeAttr( "aria-disabled" ) | |
13102 .children( "a" ) | |
13103 .removeUniqueId() | |
13104 .removeClass( "ui-corner-all ui-state-hover" ) | |
13105 .removeAttr( "tabIndex" ) | |
13106 .removeAttr( "role" ) | |
13107 .removeAttr( "aria-haspopup" ) | |
13108 .children().each( function() { | |
13109 var elem = $( this ); | |
13110 if ( elem.data( "ui-menu-submenu-carat" ) ) { | |
13111 elem.remove(); | |
13112 } | |
13113 }); | |
13114 | |
13115 // Destroy menu dividers | |
13116 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); | |
13117 }, | |
13118 | |
13119 _keydown: function( event ) { | |
13120 /*jshint maxcomplexity:20*/ | |
13121 var match, prev, character, skip, regex, | |
13122 preventDefault = true; | |
13123 | |
13124 function escape( value ) { | |
13125 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); | |
13126 } | |
13127 | |
13128 switch ( event.keyCode ) { | |
13129 case $.ui.keyCode.PAGE_UP: | |
13130 this.previousPage( event ); | |
13131 break; | |
13132 case $.ui.keyCode.PAGE_DOWN: | |
13133 this.nextPage( event ); | |
13134 break; | |
13135 case $.ui.keyCode.HOME: | |
13136 this._move( "first", "first", event ); | |
13137 break; | |
13138 case $.ui.keyCode.END: | |
13139 this._move( "last", "last", event ); | |
13140 break; | |
13141 case $.ui.keyCode.UP: | |
13142 this.previous( event ); | |
13143 break; | |
13144 case $.ui.keyCode.DOWN: | |
13145 this.next( event ); | |
13146 break; | |
13147 case $.ui.keyCode.LEFT: | |
13148 this.collapse( event ); | |
13149 break; | |
13150 case $.ui.keyCode.RIGHT: | |
13151 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { | |
13152 this.expand( event ); | |
13153 } | |
13154 break; | |
13155 case $.ui.keyCode.ENTER: | |
13156 case $.ui.keyCode.SPACE: | |
13157 this._activate( event ); | |
13158 break; | |
13159 case $.ui.keyCode.ESCAPE: | |
13160 this.collapse( event ); | |
13161 break; | |
13162 default: | |
13163 preventDefault = false; | |
13164 prev = this.previousFilter || ""; | |
13165 character = String.fromCharCode( event.keyCode ); | |
13166 skip = false; | |
13167 | |
13168 clearTimeout( this.filterTimer ); | |
13169 | |
13170 if ( character === prev ) { | |
13171 skip = true; | |
13172 } else { | |
13173 character = prev + character; | |
13174 } | |
13175 | |
13176 regex = new RegExp( "^" + escape( character ), "i" ); | |
13177 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { | |
13178 return regex.test( $( this ).children( "a" ).text() ); | |
13179 }); | |
13180 match = skip && match.index( this.active.next() ) !== -1 ? | |
13181 this.active.nextAll( ".ui-menu-item" ) : | |
13182 match; | |
13183 | |
13184 // If no matches on the current filter, reset to the last character pressed | |
13185 // to move down the menu to the first item that starts with that character | |
13186 if ( !match.length ) { | |
13187 character = String.fromCharCode( event.keyCode ); | |
13188 regex = new RegExp( "^" + escape( character ), "i" ); | |
13189 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { | |
13190 return regex.test( $( this ).children( "a" ).text() ); | |
13191 }); | |
13192 } | |
13193 | |
13194 if ( match.length ) { | |
13195 this.focus( event, match ); | |
13196 if ( match.length > 1 ) { | |
13197 this.previousFilter = character; | |
13198 this.filterTimer = this._delay(function() { | |
13199 delete this.previousFilter; | |
13200 }, 1000 ); | |
13201 } else { | |
13202 delete this.previousFilter; | |
13203 } | |
13204 } else { | |
13205 delete this.previousFilter; | |
13206 } | |
13207 } | |
13208 | |
13209 if ( preventDefault ) { | |
13210 event.preventDefault(); | |
13211 } | |
13212 }, | |
13213 | |
13214 _activate: function( event ) { | |
13215 if ( !this.active.is( ".ui-state-disabled" ) ) { | |
13216 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { | |
13217 this.expand( event ); | |
13218 } else { | |
13219 this.select( event ); | |
13220 } | |
13221 } | |
13222 }, | |
13223 | |
13224 refresh: function() { | |
13225 var menus, | |
13226 icon = this.options.icons.submenu, | |
13227 submenus = this.element.find( this.options.menus ); | |
13228 | |
13229 // Initialize nested menus | |
13230 submenus.filter( ":not(.ui-menu)" ) | |
13231 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) | |
13232 .hide() | |
13233 .attr({ | |
13234 role: this.options.role, | |
13235 "aria-hidden": "true", | |
13236 "aria-expanded": "false" | |
13237 }) | |
13238 .each(function() { | |
13239 var menu = $( this ), | |
13240 item = menu.prev( "a" ), | |
13241 submenuCarat = $( "<span>" ) | |
13242 .addClass( "ui-menu-icon ui-icon " + icon ) | |
13243 .data( "ui-menu-submenu-carat", true ); | |
13244 | |
13245 item | |
13246 .attr( "aria-haspopup", "true" ) | |
13247 .prepend( submenuCarat ); | |
13248 menu.attr( "aria-labelledby", item.attr( "id" ) ); | |
13249 }); | |
13250 | |
13251 menus = submenus.add( this.element ); | |
13252 | |
13253 // Don't refresh list items that are already adapted | |
13254 menus.children( ":not(.ui-menu-item):has(a)" ) | |
13255 .addClass( "ui-menu-item" ) | |
13256 .attr( "role", "presentation" ) | |
13257 .children( "a" ) | |
13258 .uniqueId() | |
13259 .addClass( "ui-corner-all" ) | |
13260 .attr({ | |
13261 tabIndex: -1, | |
13262 role: this._itemRole() | |
13263 }); | |
13264 | |
13265 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers | |
13266 menus.children( ":not(.ui-menu-item)" ).each(function() { | |
13267 var item = $( this ); | |
13268 // hyphen, em dash, en dash | |
13269 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { | |
13270 item.addClass( "ui-widget-content ui-menu-divider" ); | |
13271 } | |
13272 }); | |
13273 | |
13274 // Add aria-disabled attribute to any disabled menu item | |
13275 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); | |
13276 | |
13277 // If the active item has been removed, blur the menu | |
13278 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { | |
13279 this.blur(); | |
13280 } | |
13281 }, | |
13282 | |
13283 _itemRole: function() { | |
13284 return { | |
13285 menu: "menuitem", | |
13286 listbox: "option" | |
13287 }[ this.options.role ]; | |
13288 }, | |
13289 | |
13290 _setOption: function( key, value ) { | |
13291 if ( key === "icons" ) { | |
13292 this.element.find( ".ui-menu-icon" ) | |
13293 .removeClass( this.options.icons.submenu ) | |
13294 .addClass( value.submenu ); | |
13295 } | |
13296 this._super( key, value ); | |
13297 }, | |
13298 | |
13299 focus: function( event, item ) { | |
13300 var nested, focused; | |
13301 this.blur( event, event && event.type === "focus" ); | |
13302 | |
13303 this._scrollIntoView( item ); | |
13304 | |
13305 this.active = item.first(); | |
13306 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); | |
13307 // Only update aria-activedescendant if there's a role | |
13308 // otherwise we assume focus is managed elsewhere | |
13309 if ( this.options.role ) { | |
13310 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); | |
13311 } | |
13312 | |
13313 // Highlight active parent menu item, if any | |
13314 this.active | |
13315 .parent() | |
13316 .closest( ".ui-menu-item" ) | |
13317 .children( "a:first" ) | |
13318 .addClass( "ui-state-active" ); | |
13319 | |
13320 if ( event && event.type === "keydown" ) { | |
13321 this._close(); | |
13322 } else { | |
13323 this.timer = this._delay(function() { | |
13324 this._close(); | |
13325 }, this.delay ); | |
13326 } | |
13327 | |
13328 nested = item.children( ".ui-menu" ); | |
13329 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { | |
13330 this._startOpening(nested); | |
13331 } | |
13332 this.activeMenu = item.parent(); | |
13333 | |
13334 this._trigger( "focus", event, { item: item } ); | |
13335 }, | |
13336 | |
13337 _scrollIntoView: function( item ) { | |
13338 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; | |
13339 if ( this._hasScroll() ) { | |
13340 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; | |
13341 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; | |
13342 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; | |
13343 scroll = this.activeMenu.scrollTop(); | |
13344 elementHeight = this.activeMenu.height(); | |
13345 itemHeight = item.height(); | |
13346 | |
13347 if ( offset < 0 ) { | |
13348 this.activeMenu.scrollTop( scroll + offset ); | |
13349 } else if ( offset + itemHeight > elementHeight ) { | |
13350 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); | |
13351 } | |
13352 } | |
13353 }, | |
13354 | |
13355 blur: function( event, fromFocus ) { | |
13356 if ( !fromFocus ) { | |
13357 clearTimeout( this.timer ); | |
13358 } | |
13359 | |
13360 if ( !this.active ) { | |
13361 return; | |
13362 } | |
13363 | |
13364 this.active.children( "a" ).removeClass( "ui-state-focus" ); | |
13365 this.active = null; | |
13366 | |
13367 this._trigger( "blur", event, { item: this.active } ); | |
13368 }, | |
13369 | |
13370 _startOpening: function( submenu ) { | |
13371 clearTimeout( this.timer ); | |
13372 | |
13373 // Don't open if already open fixes a Firefox bug that caused a .5 pixel | |
13374 // shift in the submenu position when mousing over the carat icon | |
13375 if ( submenu.attr( "aria-hidden" ) !== "true" ) { | |
13376 return; | |
13377 } | |
13378 | |
13379 this.timer = this._delay(function() { | |
13380 this._close(); | |
13381 this._open( submenu ); | |
13382 }, this.delay ); | |
13383 }, | |
13384 | |
13385 _open: function( submenu ) { | |
13386 var position = $.extend({ | |
13387 of: this.active | |
13388 }, this.options.position ); | |
13389 | |
13390 clearTimeout( this.timer ); | |
13391 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) | |
13392 .hide() | |
13393 .attr( "aria-hidden", "true" ); | |
13394 | |
13395 submenu | |
13396 .show() | |
13397 .removeAttr( "aria-hidden" ) | |
13398 .attr( "aria-expanded", "true" ) | |
13399 .position( position ); | |
13400 }, | |
13401 | |
13402 collapseAll: function( event, all ) { | |
13403 clearTimeout( this.timer ); | |
13404 this.timer = this._delay(function() { | |
13405 // If we were passed an event, look for the submenu that contains the event | |
13406 var currentMenu = all ? this.element : | |
13407 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); | |
13408 | |
13409 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway | |
13410 if ( !currentMenu.length ) { | |
13411 currentMenu = this.element; | |
13412 } | |
13413 | |
13414 this._close( currentMenu ); | |
13415 | |
13416 this.blur( event ); | |
13417 this.activeMenu = currentMenu; | |
13418 }, this.delay ); | |
13419 }, | |
13420 | |
13421 // With no arguments, closes the currently active menu - if nothing is active | |
13422 // it closes all menus. If passed an argument, it will search for menus BELOW | |
13423 _close: function( startMenu ) { | |
13424 if ( !startMenu ) { | |
13425 startMenu = this.active ? this.active.parent() : this.element; | |
13426 } | |
13427 | |
13428 startMenu | |
13429 .find( ".ui-menu" ) | |
13430 .hide() | |
13431 .attr( "aria-hidden", "true" ) | |
13432 .attr( "aria-expanded", "false" ) | |
13433 .end() | |
13434 .find( "a.ui-state-active" ) | |
13435 .removeClass( "ui-state-active" ); | |
13436 }, | |
13437 | |
13438 collapse: function( event ) { | |
13439 var newItem = this.active && | |
13440 this.active.parent().closest( ".ui-menu-item", this.element ); | |
13441 if ( newItem && newItem.length ) { | |
13442 this._close(); | |
13443 this.focus( event, newItem ); | |
13444 } | |
13445 }, | |
13446 | |
13447 expand: function( event ) { | |
13448 var newItem = this.active && | |
13449 this.active | |
13450 .children( ".ui-menu " ) | |
13451 .children( ".ui-menu-item" ) | |
13452 .first(); | |
13453 | |
13454 if ( newItem && newItem.length ) { | |
13455 this._open( newItem.parent() ); | |
13456 | |
13457 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT | |
13458 this._delay(function() { | |
13459 this.focus( event, newItem ); | |
13460 }); | |
13461 } | |
13462 }, | |
13463 | |
13464 next: function( event ) { | |
13465 this._move( "next", "first", event ); | |
13466 }, | |
13467 | |
13468 previous: function( event ) { | |
13469 this._move( "prev", "last", event ); | |
13470 }, | |
13471 | |
13472 isFirstItem: function() { | |
13473 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; | |
13474 }, | |
13475 | |
13476 isLastItem: function() { | |
13477 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; | |
13478 }, | |
13479 | |
13480 _move: function( direction, filter, event ) { | |
13481 var next; | |
13482 if ( this.active ) { | |
13483 if ( direction === "first" || direction === "last" ) { | |
13484 next = this.active | |
13485 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) | |
13486 .eq( -1 ); | |
13487 } else { | |
13488 next = this.active | |
13489 [ direction + "All" ]( ".ui-menu-item" ) | |
13490 .eq( 0 ); | |
13491 } | |
13492 } | |
13493 if ( !next || !next.length || !this.active ) { | |
13494 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); | |
13495 } | |
13496 | |
13497 this.focus( event, next ); | |
13498 }, | |
13499 | |
13500 nextPage: function( event ) { | |
13501 var item, base, height; | |
13502 | |
13503 if ( !this.active ) { | |
13504 this.next( event ); | |
13505 return; | |
13506 } | |
13507 if ( this.isLastItem() ) { | |
13508 return; | |
13509 } | |
13510 if ( this._hasScroll() ) { | |
13511 base = this.active.offset().top; | |
13512 height = this.element.height(); | |
13513 this.active.nextAll( ".ui-menu-item" ).each(function() { | |
13514 item = $( this ); | |
13515 return item.offset().top - base - height < 0; | |
13516 }); | |
13517 | |
13518 this.focus( event, item ); | |
13519 } else { | |
13520 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) | |
13521 [ !this.active ? "first" : "last" ]() ); | |
13522 } | |
13523 }, | |
13524 | |
13525 previousPage: function( event ) { | |
13526 var item, base, height; | |
13527 if ( !this.active ) { | |
13528 this.next( event ); | |
13529 return; | |
13530 } | |
13531 if ( this.isFirstItem() ) { | |
13532 return; | |
13533 } | |
13534 if ( this._hasScroll() ) { | |
13535 base = this.active.offset().top; | |
13536 height = this.element.height(); | |
13537 this.active.prevAll( ".ui-menu-item" ).each(function() { | |
13538 item = $( this ); | |
13539 return item.offset().top - base + height > 0; | |
13540 }); | |
13541 | |
13542 this.focus( event, item ); | |
13543 } else { | |
13544 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); | |
13545 } | |
13546 }, | |
13547 | |
13548 _hasScroll: function() { | |
13549 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); | |
13550 }, | |
13551 | |
13552 select: function( event ) { | |
13553 // TODO: It should never be possible to not have an active item at this | |
13554 // point, but the tests don't trigger mouseenter before click. | |
13555 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); | |
13556 var ui = { item: this.active }; | |
13557 if ( !this.active.has( ".ui-menu" ).length ) { | |
13558 this.collapseAll( event, true ); | |
13559 } | |
13560 this._trigger( "select", event, ui ); | |
13561 } | |
13562 }); | |
13563 | |
13564 }( jQuery )); | |
13565 (function( $, undefined ) { | |
13566 | |
13567 $.widget( "ui.progressbar", { | |
13568 version: "1.10.3", | |
13569 options: { | |
13570 max: 100, | |
13571 value: 0, | |
13572 | |
13573 change: null, | |
13574 complete: null | |
13575 }, | |
13576 | |
13577 min: 0, | |
13578 | |
13579 _create: function() { | |
13580 // Constrain initial value | |
13581 this.oldValue = this.options.value = this._constrainedValue(); | |
13582 | |
13583 this.element | |
13584 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) | |
13585 .attr({ | |
13586 // Only set static values, aria-valuenow and aria-valuemax are | |
13587 // set inside _refreshValue() | |
13588 role: "progressbar", | |
13589 "aria-valuemin": this.min | |
13590 }); | |
13591 | |
13592 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) | |
13593 .appendTo( this.element ); | |
13594 | |
13595 this._refreshValue(); | |
13596 }, | |
13597 | |
13598 _destroy: function() { | |
13599 this.element | |
13600 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) | |
13601 .removeAttr( "role" ) | |
13602 .removeAttr( "aria-valuemin" ) | |
13603 .removeAttr( "aria-valuemax" ) | |
13604 .removeAttr( "aria-valuenow" ); | |
13605 | |
13606 this.valueDiv.remove(); | |
13607 }, | |
13608 | |
13609 value: function( newValue ) { | |
13610 if ( newValue === undefined ) { | |
13611 return this.options.value; | |
13612 } | |
13613 | |
13614 this.options.value = this._constrainedValue( newValue ); | |
13615 this._refreshValue(); | |
13616 }, | |
13617 | |
13618 _constrainedValue: function( newValue ) { | |
13619 if ( newValue === undefined ) { | |
13620 newValue = this.options.value; | |
13621 } | |
13622 | |
13623 this.indeterminate = newValue === false; | |
13624 | |
13625 // sanitize value | |
13626 if ( typeof newValue !== "number" ) { | |
13627 newValue = 0; | |
13628 } | |
13629 | |
13630 return this.indeterminate ? false : | |
13631 Math.min( this.options.max, Math.max( this.min, newValue ) ); | |
13632 }, | |
13633 | |
13634 _setOptions: function( options ) { | |
13635 // Ensure "value" option is set after other values (like max) | |
13636 var value = options.value; | |
13637 delete options.value; | |
13638 | |
13639 this._super( options ); | |
13640 | |
13641 this.options.value = this._constrainedValue( value ); | |
13642 this._refreshValue(); | |
13643 }, | |
13644 | |
13645 _setOption: function( key, value ) { | |
13646 if ( key === "max" ) { | |
13647 // Don't allow a max less than min | |
13648 value = Math.max( this.min, value ); | |
13649 } | |
13650 | |
13651 this._super( key, value ); | |
13652 }, | |
13653 | |
13654 _percentage: function() { | |
13655 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); | |
13656 }, | |
13657 | |
13658 _refreshValue: function() { | |
13659 var value = this.options.value, | |
13660 percentage = this._percentage(); | |
13661 | |
13662 this.valueDiv | |
13663 .toggle( this.indeterminate || value > this.min ) | |
13664 .toggleClass( "ui-corner-right", value === this.options.max ) | |
13665 .width( percentage.toFixed(0) + "%" ); | |
13666 | |
13667 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); | |
13668 | |
13669 if ( this.indeterminate ) { | |
13670 this.element.removeAttr( "aria-valuenow" ); | |
13671 if ( !this.overlayDiv ) { | |
13672 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); | |
13673 } | |
13674 } else { | |
13675 this.element.attr({ | |
13676 "aria-valuemax": this.options.max, | |
13677 "aria-valuenow": value | |
13678 }); | |
13679 if ( this.overlayDiv ) { | |
13680 this.overlayDiv.remove(); | |
13681 this.overlayDiv = null; | |
13682 } | |
13683 } | |
13684 | |
13685 if ( this.oldValue !== value ) { | |
13686 this.oldValue = value; | |
13687 this._trigger( "change" ); | |
13688 } | |
13689 if ( value === this.options.max ) { | |
13690 this._trigger( "complete" ); | |
13691 } | |
13692 } | |
13693 }); | |
13694 | |
13695 })( jQuery ); | |
13696 (function( $, undefined ) { | |
13697 | |
13698 // number of pages in a slider | |
13699 // (how many times can you page up/down to go through the whole range) | |
13700 var numPages = 5; | |
13701 | |
13702 $.widget( "ui.slider", $.ui.mouse, { | |
13703 version: "1.10.3", | |
13704 widgetEventPrefix: "slide", | |
13705 | |
13706 options: { | |
13707 animate: false, | |
13708 distance: 0, | |
13709 max: 100, | |
13710 min: 0, | |
13711 orientation: "horizontal", | |
13712 range: false, | |
13713 step: 1, | |
13714 value: 0, | |
13715 values: null, | |
13716 | |
13717 // callbacks | |
13718 change: null, | |
13719 slide: null, | |
13720 start: null, | |
13721 stop: null | |
13722 }, | |
13723 | |
13724 _create: function() { | |
13725 this._keySliding = false; | |
13726 this._mouseSliding = false; | |
13727 this._animateOff = true; | |
13728 this._handleIndex = null; | |
13729 this._detectOrientation(); | |
13730 this._mouseInit(); | |
13731 | |
13732 this.element | |
13733 .addClass( "ui-slider" + | |
13734 " ui-slider-" + this.orientation + | |
13735 " ui-widget" + | |
13736 " ui-widget-content" + | |
13737 " ui-corner-all"); | |
13738 | |
13739 this._refresh(); | |
13740 this._setOption( "disabled", this.options.disabled ); | |
13741 | |
13742 this._animateOff = false; | |
13743 }, | |
13744 | |
13745 _refresh: function() { | |
13746 this._createRange(); | |
13747 this._createHandles(); | |
13748 this._setupEvents(); | |
13749 this._refreshValue(); | |
13750 }, | |
13751 | |
13752 _createHandles: function() { | |
13753 var i, handleCount, | |
13754 options = this.options, | |
13755 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), | |
13756 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", | |
13757 handles = []; | |
13758 | |
13759 handleCount = ( options.values && options.values.length ) || 1; | |
13760 | |
13761 if ( existingHandles.length > handleCount ) { | |
13762 existingHandles.slice( handleCount ).remove(); | |
13763 existingHandles = existingHandles.slice( 0, handleCount ); | |
13764 } | |
13765 | |
13766 for ( i = existingHandles.length; i < handleCount; i++ ) { | |
13767 handles.push( handle ); | |
13768 } | |
13769 | |
13770 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); | |
13771 | |
13772 this.handle = this.handles.eq( 0 ); | |
13773 | |
13774 this.handles.each(function( i ) { | |
13775 $( this ).data( "ui-slider-handle-index", i ); | |
13776 }); | |
13777 }, | |
13778 | |
13779 _createRange: function() { | |
13780 var options = this.options, | |
13781 classes = ""; | |
13782 | |
13783 if ( options.range ) { | |
13784 if ( options.range === true ) { | |
13785 if ( !options.values ) { | |
13786 options.values = [ this._valueMin(), this._valueMin() ]; | |
13787 } else if ( options.values.length && options.values.length !== 2 ) { | |
13788 options.values = [ options.values[0], options.values[0] ]; | |
13789 } else if ( $.isArray( options.values ) ) { | |
13790 options.values = options.values.slice(0); | |
13791 } | |
13792 } | |
13793 | |
13794 if ( !this.range || !this.range.length ) { | |
13795 this.range = $( "<div></div>" ) | |
13796 .appendTo( this.element ); | |
13797 | |
13798 classes = "ui-slider-range" + | |
13799 // note: this isn't the most fittingly semantic framework class for this element, | |
13800 // but worked best visually with a variety of themes | |
13801 " ui-widget-header ui-corner-all"; | |
13802 } else { | |
13803 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) | |
13804 // Handle range switching from true to min/max | |
13805 .css({ | |
13806 "left": "", | |
13807 "bottom": "" | |
13808 }); | |
13809 } | |
13810 | |
13811 this.range.addClass( classes + | |
13812 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); | |
13813 } else { | |
13814 this.range = $([]); | |
13815 } | |
13816 }, | |
13817 | |
13818 _setupEvents: function() { | |
13819 var elements = this.handles.add( this.range ).filter( "a" ); | |
13820 this._off( elements ); | |
13821 this._on( elements, this._handleEvents ); | |
13822 this._hoverable( elements ); | |
13823 this._focusable( elements ); | |
13824 }, | |
13825 | |
13826 _destroy: function() { | |
13827 this.handles.remove(); | |
13828 this.range.remove(); | |
13829 | |
13830 this.element | |
13831 .removeClass( "ui-slider" + | |
13832 " ui-slider-horizontal" + | |
13833 " ui-slider-vertical" + | |
13834 " ui-widget" + | |
13835 " ui-widget-content" + | |
13836 " ui-corner-all" ); | |
13837 | |
13838 this._mouseDestroy(); | |
13839 }, | |
13840 | |
13841 _mouseCapture: function( event ) { | |
13842 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, | |
13843 that = this, | |
13844 o = this.options; | |
13845 | |
13846 if ( o.disabled ) { | |
13847 return false; | |
13848 } | |
13849 | |
13850 this.elementSize = { | |
13851 width: this.element.outerWidth(), | |
13852 height: this.element.outerHeight() | |
13853 }; | |
13854 this.elementOffset = this.element.offset(); | |
13855 | |
13856 position = { x: event.pageX, y: event.pageY }; | |
13857 normValue = this._normValueFromMouse( position ); | |
13858 distance = this._valueMax() - this._valueMin() + 1; | |
13859 this.handles.each(function( i ) { | |
13860 var thisDistance = Math.abs( normValue - that.values(i) ); | |
13861 if (( distance > thisDistance ) || | |
13862 ( distance === thisDistance && | |
13863 (i === that._lastChangedValue || that.values(i) === o.min ))) { | |
13864 distance = thisDistance; | |
13865 closestHandle = $( this ); | |
13866 index = i; | |
13867 } | |
13868 }); | |
13869 | |
13870 allowed = this._start( event, index ); | |
13871 if ( allowed === false ) { | |
13872 return false; | |
13873 } | |
13874 this._mouseSliding = true; | |
13875 | |
13876 this._handleIndex = index; | |
13877 | |
13878 closestHandle | |
13879 .addClass( "ui-state-active" ) | |
13880 .focus(); | |
13881 | |
13882 offset = closestHandle.offset(); | |
13883 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); | |
13884 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { | |
13885 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), | |
13886 top: event.pageY - offset.top - | |
13887 ( closestHandle.height() / 2 ) - | |
13888 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - | |
13889 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + | |
13890 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) | |
13891 }; | |
13892 | |
13893 if ( !this.handles.hasClass( "ui-state-hover" ) ) { | |
13894 this._slide( event, index, normValue ); | |
13895 } | |
13896 this._animateOff = true; | |
13897 return true; | |
13898 }, | |
13899 | |
13900 _mouseStart: function() { | |
13901 return true; | |
13902 }, | |
13903 | |
13904 _mouseDrag: function( event ) { | |
13905 var position = { x: event.pageX, y: event.pageY }, | |
13906 normValue = this._normValueFromMouse( position ); | |
13907 | |
13908 this._slide( event, this._handleIndex, normValue ); | |
13909 | |
13910 return false; | |
13911 }, | |
13912 | |
13913 _mouseStop: function( event ) { | |
13914 this.handles.removeClass( "ui-state-active" ); | |
13915 this._mouseSliding = false; | |
13916 | |
13917 this._stop( event, this._handleIndex ); | |
13918 this._change( event, this._handleIndex ); | |
13919 | |
13920 this._handleIndex = null; | |
13921 this._clickOffset = null; | |
13922 this._animateOff = false; | |
13923 | |
13924 return false; | |
13925 }, | |
13926 | |
13927 _detectOrientation: function() { | |
13928 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; | |
13929 }, | |
13930 | |
13931 _normValueFromMouse: function( position ) { | |
13932 var pixelTotal, | |
13933 pixelMouse, | |
13934 percentMouse, | |
13935 valueTotal, | |
13936 valueMouse; | |
13937 | |
13938 if ( this.orientation === "horizontal" ) { | |
13939 pixelTotal = this.elementSize.width; | |
13940 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); | |
13941 } else { | |
13942 pixelTotal = this.elementSize.height; | |
13943 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); | |
13944 } | |
13945 | |
13946 percentMouse = ( pixelMouse / pixelTotal ); | |
13947 if ( percentMouse > 1 ) { | |
13948 percentMouse = 1; | |
13949 } | |
13950 if ( percentMouse < 0 ) { | |
13951 percentMouse = 0; | |
13952 } | |
13953 if ( this.orientation === "vertical" ) { | |
13954 percentMouse = 1 - percentMouse; | |
13955 } | |
13956 | |
13957 valueTotal = this._valueMax() - this._valueMin(); | |
13958 valueMouse = this._valueMin() + percentMouse * valueTotal; | |
13959 | |
13960 return this._trimAlignValue( valueMouse ); | |
13961 }, | |
13962 | |
13963 _start: function( event, index ) { | |
13964 var uiHash = { | |
13965 handle: this.handles[ index ], | |
13966 value: this.value() | |
13967 }; | |
13968 if ( this.options.values && this.options.values.length ) { | |
13969 uiHash.value = this.values( index ); | |
13970 uiHash.values = this.values(); | |
13971 } | |
13972 return this._trigger( "start", event, uiHash ); | |
13973 }, | |
13974 | |
13975 _slide: function( event, index, newVal ) { | |
13976 var otherVal, | |
13977 newValues, | |
13978 allowed; | |
13979 | |
13980 if ( this.options.values && this.options.values.length ) { | |
13981 otherVal = this.values( index ? 0 : 1 ); | |
13982 | |
13983 if ( ( this.options.values.length === 2 && this.options.range === true ) && | |
13984 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) | |
13985 ) { | |
13986 newVal = otherVal; | |
13987 } | |
13988 | |
13989 if ( newVal !== this.values( index ) ) { | |
13990 newValues = this.values(); | |
13991 newValues[ index ] = newVal; | |
13992 // A slide can be canceled by returning false from the slide callback | |
13993 allowed = this._trigger( "slide", event, { | |
13994 handle: this.handles[ index ], | |
13995 value: newVal, | |
13996 values: newValues | |
13997 } ); | |
13998 otherVal = this.values( index ? 0 : 1 ); | |
13999 if ( allowed !== false ) { | |
14000 this.values( index, newVal, true ); | |
14001 } | |
14002 } | |
14003 } else { | |
14004 if ( newVal !== this.value() ) { | |
14005 // A slide can be canceled by returning false from the slide callback | |
14006 allowed = this._trigger( "slide", event, { | |
14007 handle: this.handles[ index ], | |
14008 value: newVal | |
14009 } ); | |
14010 if ( allowed !== false ) { | |
14011 this.value( newVal ); | |
14012 } | |
14013 } | |
14014 } | |
14015 }, | |
14016 | |
14017 _stop: function( event, index ) { | |
14018 var uiHash = { | |
14019 handle: this.handles[ index ], | |
14020 value: this.value() | |
14021 }; | |
14022 if ( this.options.values && this.options.values.length ) { | |
14023 uiHash.value = this.values( index ); | |
14024 uiHash.values = this.values(); | |
14025 } | |
14026 | |
14027 this._trigger( "stop", event, uiHash ); | |
14028 }, | |
14029 | |
14030 _change: function( event, index ) { | |
14031 if ( !this._keySliding && !this._mouseSliding ) { | |
14032 var uiHash = { | |
14033 handle: this.handles[ index ], | |
14034 value: this.value() | |
14035 }; | |
14036 if ( this.options.values && this.options.values.length ) { | |
14037 uiHash.value = this.values( index ); | |
14038 uiHash.values = this.values(); | |
14039 } | |
14040 | |
14041 //store the last changed value index for reference when handles overlap | |
14042 this._lastChangedValue = index; | |
14043 | |
14044 this._trigger( "change", event, uiHash ); | |
14045 } | |
14046 }, | |
14047 | |
14048 value: function( newValue ) { | |
14049 if ( arguments.length ) { | |
14050 this.options.value = this._trimAlignValue( newValue ); | |
14051 this._refreshValue(); | |
14052 this._change( null, 0 ); | |
14053 return; | |
14054 } | |
14055 | |
14056 return this._value(); | |
14057 }, | |
14058 | |
14059 values: function( index, newValue ) { | |
14060 var vals, | |
14061 newValues, | |
14062 i; | |
14063 | |
14064 if ( arguments.length > 1 ) { | |
14065 this.options.values[ index ] = this._trimAlignValue( newValue ); | |
14066 this._refreshValue(); | |
14067 this._change( null, index ); | |
14068 return; | |
14069 } | |
14070 | |
14071 if ( arguments.length ) { | |
14072 if ( $.isArray( arguments[ 0 ] ) ) { | |
14073 vals = this.options.values; | |
14074 newValues = arguments[ 0 ]; | |
14075 for ( i = 0; i < vals.length; i += 1 ) { | |
14076 vals[ i ] = this._trimAlignValue( newValues[ i ] ); | |
14077 this._change( null, i ); | |
14078 } | |
14079 this._refreshValue(); | |
14080 } else { | |
14081 if ( this.options.values && this.options.values.length ) { | |
14082 return this._values( index ); | |
14083 } else { | |
14084 return this.value(); | |
14085 } | |
14086 } | |
14087 } else { | |
14088 return this._values(); | |
14089 } | |
14090 }, | |
14091 | |
14092 _setOption: function( key, value ) { | |
14093 var i, | |
14094 valsLength = 0; | |
14095 | |
14096 if ( key === "range" && this.options.range === true ) { | |
14097 if ( value === "min" ) { | |
14098 this.options.value = this._values( 0 ); | |
14099 this.options.values = null; | |
14100 } else if ( value === "max" ) { | |
14101 this.options.value = this._values( this.options.values.length-1 ); | |
14102 this.options.values = null; | |
14103 } | |
14104 } | |
14105 | |
14106 if ( $.isArray( this.options.values ) ) { | |
14107 valsLength = this.options.values.length; | |
14108 } | |
14109 | |
14110 $.Widget.prototype._setOption.apply( this, arguments ); | |
14111 | |
14112 switch ( key ) { | |
14113 case "orientation": | |
14114 this._detectOrientation(); | |
14115 this.element | |
14116 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) | |
14117 .addClass( "ui-slider-" + this.orientation ); | |
14118 this._refreshValue(); | |
14119 break; | |
14120 case "value": | |
14121 this._animateOff = true; | |
14122 this._refreshValue(); | |
14123 this._change( null, 0 ); | |
14124 this._animateOff = false; | |
14125 break; | |
14126 case "values": | |
14127 this._animateOff = true; | |
14128 this._refreshValue(); | |
14129 for ( i = 0; i < valsLength; i += 1 ) { | |
14130 this._change( null, i ); | |
14131 } | |
14132 this._animateOff = false; | |
14133 break; | |
14134 case "min": | |
14135 case "max": | |
14136 this._animateOff = true; | |
14137 this._refreshValue(); | |
14138 this._animateOff = false; | |
14139 break; | |
14140 case "range": | |
14141 this._animateOff = true; | |
14142 this._refresh(); | |
14143 this._animateOff = false; | |
14144 break; | |
14145 } | |
14146 }, | |
14147 | |
14148 //internal value getter | |
14149 // _value() returns value trimmed by min and max, aligned by step | |
14150 _value: function() { | |
14151 var val = this.options.value; | |
14152 val = this._trimAlignValue( val ); | |
14153 | |
14154 return val; | |
14155 }, | |
14156 | |
14157 //internal values getter | |
14158 // _values() returns array of values trimmed by min and max, aligned by step | |
14159 // _values( index ) returns single value trimmed by min and max, aligned by step | |
14160 _values: function( index ) { | |
14161 var val, | |
14162 vals, | |
14163 i; | |
14164 | |
14165 if ( arguments.length ) { | |
14166 val = this.options.values[ index ]; | |
14167 val = this._trimAlignValue( val ); | |
14168 | |
14169 return val; | |
14170 } else if ( this.options.values && this.options.values.length ) { | |
14171 // .slice() creates a copy of the array | |
14172 // this copy gets trimmed by min and max and then returned | |
14173 vals = this.options.values.slice(); | |
14174 for ( i = 0; i < vals.length; i+= 1) { | |
14175 vals[ i ] = this._trimAlignValue( vals[ i ] ); | |
14176 } | |
14177 | |
14178 return vals; | |
14179 } else { | |
14180 return []; | |
14181 } | |
14182 }, | |
14183 | |
14184 // returns the step-aligned value that val is closest to, between (inclusive) min and max | |
14185 _trimAlignValue: function( val ) { | |
14186 if ( val <= this._valueMin() ) { | |
14187 return this._valueMin(); | |
14188 } | |
14189 if ( val >= this._valueMax() ) { | |
14190 return this._valueMax(); | |
14191 } | |
14192 var step = ( this.options.step > 0 ) ? this.options.step : 1, | |
14193 valModStep = (val - this._valueMin()) % step, | |
14194 alignValue = val - valModStep; | |
14195 | |
14196 if ( Math.abs(valModStep) * 2 >= step ) { | |
14197 alignValue += ( valModStep > 0 ) ? step : ( -step ); | |
14198 } | |
14199 | |
14200 // Since JavaScript has problems with large floats, round | |
14201 // the final value to 5 digits after the decimal point (see #4124) | |
14202 return parseFloat( alignValue.toFixed(5) ); | |
14203 }, | |
14204 | |
14205 _valueMin: function() { | |
14206 return this.options.min; | |
14207 }, | |
14208 | |
14209 _valueMax: function() { | |
14210 return this.options.max; | |
14211 }, | |
14212 | |
14213 _refreshValue: function() { | |
14214 var lastValPercent, valPercent, value, valueMin, valueMax, | |
14215 oRange = this.options.range, | |
14216 o = this.options, | |
14217 that = this, | |
14218 animate = ( !this._animateOff ) ? o.animate : false, | |
14219 _set = {}; | |
14220 | |
14221 if ( this.options.values && this.options.values.length ) { | |
14222 this.handles.each(function( i ) { | |
14223 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; | |
14224 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; | |
14225 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); | |
14226 if ( that.options.range === true ) { | |
14227 if ( that.orientation === "horizontal" ) { | |
14228 if ( i === 0 ) { | |
14229 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); | |
14230 } | |
14231 if ( i === 1 ) { | |
14232 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14233 } | |
14234 } else { | |
14235 if ( i === 0 ) { | |
14236 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); | |
14237 } | |
14238 if ( i === 1 ) { | |
14239 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14240 } | |
14241 } | |
14242 } | |
14243 lastValPercent = valPercent; | |
14244 }); | |
14245 } else { | |
14246 value = this.value(); | |
14247 valueMin = this._valueMin(); | |
14248 valueMax = this._valueMax(); | |
14249 valPercent = ( valueMax !== valueMin ) ? | |
14250 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : | |
14251 0; | |
14252 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; | |
14253 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); | |
14254 | |
14255 if ( oRange === "min" && this.orientation === "horizontal" ) { | |
14256 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); | |
14257 } | |
14258 if ( oRange === "max" && this.orientation === "horizontal" ) { | |
14259 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14260 } | |
14261 if ( oRange === "min" && this.orientation === "vertical" ) { | |
14262 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); | |
14263 } | |
14264 if ( oRange === "max" && this.orientation === "vertical" ) { | |
14265 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14266 } | |
14267 } | |
14268 }, | |
14269 | |
14270 _handleEvents: { | |
14271 keydown: function( event ) { | |
14272 /*jshint maxcomplexity:25*/ | |
14273 var allowed, curVal, newVal, step, | |
14274 index = $( event.target ).data( "ui-slider-handle-index" ); | |
14275 | |
14276 switch ( event.keyCode ) { | |
14277 case $.ui.keyCode.HOME: | |
14278 case $.ui.keyCode.END: | |
14279 case $.ui.keyCode.PAGE_UP: | |
14280 case $.ui.keyCode.PAGE_DOWN: | |
14281 case $.ui.keyCode.UP: | |
14282 case $.ui.keyCode.RIGHT: | |
14283 case $.ui.keyCode.DOWN: | |
14284 case $.ui.keyCode.LEFT: | |
14285 event.preventDefault(); | |
14286 if ( !this._keySliding ) { | |
14287 this._keySliding = true; | |
14288 $( event.target ).addClass( "ui-state-active" ); | |
14289 allowed = this._start( event, index ); | |
14290 if ( allowed === false ) { | |
14291 return; | |
14292 } | |
14293 } | |
14294 break; | |
14295 } | |
14296 | |
14297 step = this.options.step; | |
14298 if ( this.options.values && this.options.values.length ) { | |
14299 curVal = newVal = this.values( index ); | |
14300 } else { | |
14301 curVal = newVal = this.value(); | |
14302 } | |
14303 | |
14304 switch ( event.keyCode ) { | |
14305 case $.ui.keyCode.HOME: | |
14306 newVal = this._valueMin(); | |
14307 break; | |
14308 case $.ui.keyCode.END: | |
14309 newVal = this._valueMax(); | |
14310 break; | |
14311 case $.ui.keyCode.PAGE_UP: | |
14312 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); | |
14313 break; | |
14314 case $.ui.keyCode.PAGE_DOWN: | |
14315 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); | |
14316 break; | |
14317 case $.ui.keyCode.UP: | |
14318 case $.ui.keyCode.RIGHT: | |
14319 if ( curVal === this._valueMax() ) { | |
14320 return; | |
14321 } | |
14322 newVal = this._trimAlignValue( curVal + step ); | |
14323 break; | |
14324 case $.ui.keyCode.DOWN: | |
14325 case $.ui.keyCode.LEFT: | |
14326 if ( curVal === this._valueMin() ) { | |
14327 return; | |
14328 } | |
14329 newVal = this._trimAlignValue( curVal - step ); | |
14330 break; | |
14331 } | |
14332 | |
14333 this._slide( event, index, newVal ); | |
14334 }, | |
14335 click: function( event ) { | |
14336 event.preventDefault(); | |
14337 }, | |
14338 keyup: function( event ) { | |
14339 var index = $( event.target ).data( "ui-slider-handle-index" ); | |
14340 | |
14341 if ( this._keySliding ) { | |
14342 this._keySliding = false; | |
14343 this._stop( event, index ); | |
14344 this._change( event, index ); | |
14345 $( event.target ).removeClass( "ui-state-active" ); | |
14346 } | |
14347 } | |
14348 } | |
14349 | |
14350 }); | |
14351 | |
14352 }(jQuery)); | |
14353 (function( $ ) { | |
14354 | |
14355 function modifier( fn ) { | |
14356 return function() { | |
14357 var previous = this.element.val(); | |
14358 fn.apply( this, arguments ); | |
14359 this._refresh(); | |
14360 if ( previous !== this.element.val() ) { | |
14361 this._trigger( "change" ); | |
14362 } | |
14363 }; | |
14364 } | |
14365 | |
14366 $.widget( "ui.spinner", { | |
14367 version: "1.10.3", | |
14368 defaultElement: "<input>", | |
14369 widgetEventPrefix: "spin", | |
14370 options: { | |
14371 culture: null, | |
14372 icons: { | |
14373 down: "ui-icon-triangle-1-s", | |
14374 up: "ui-icon-triangle-1-n" | |
14375 }, | |
14376 incremental: true, | |
14377 max: null, | |
14378 min: null, | |
14379 numberFormat: null, | |
14380 page: 10, | |
14381 step: 1, | |
14382 | |
14383 change: null, | |
14384 spin: null, | |
14385 start: null, | |
14386 stop: null | |
14387 }, | |
14388 | |
14389 _create: function() { | |
14390 // handle string values that need to be parsed | |
14391 this._setOption( "max", this.options.max ); | |
14392 this._setOption( "min", this.options.min ); | |
14393 this._setOption( "step", this.options.step ); | |
14394 | |
14395 // format the value, but don't constrain | |
14396 this._value( this.element.val(), true ); | |
14397 | |
14398 this._draw(); | |
14399 this._on( this._events ); | |
14400 this._refresh(); | |
14401 | |
14402 // turning off autocomplete prevents the browser from remembering the | |
14403 // value when navigating through history, so we re-enable autocomplete | |
14404 // if the page is unloaded before the widget is destroyed. #7790 | |
14405 this._on( this.window, { | |
14406 beforeunload: function() { | |
14407 this.element.removeAttr( "autocomplete" ); | |
14408 } | |
14409 }); | |
14410 }, | |
14411 | |
14412 _getCreateOptions: function() { | |
14413 var options = {}, | |
14414 element = this.element; | |
14415 | |
14416 $.each( [ "min", "max", "step" ], function( i, option ) { | |
14417 var value = element.attr( option ); | |
14418 if ( value !== undefined && value.length ) { | |
14419 options[ option ] = value; | |
14420 } | |
14421 }); | |
14422 | |
14423 return options; | |
14424 }, | |
14425 | |
14426 _events: { | |
14427 keydown: function( event ) { | |
14428 if ( this._start( event ) && this._keydown( event ) ) { | |
14429 event.preventDefault(); | |
14430 } | |
14431 }, | |
14432 keyup: "_stop", | |
14433 focus: function() { | |
14434 this.previous = this.element.val(); | |
14435 }, | |
14436 blur: function( event ) { | |
14437 if ( this.cancelBlur ) { | |
14438 delete this.cancelBlur; | |
14439 return; | |
14440 } | |
14441 | |
14442 this._stop(); | |
14443 this._refresh(); | |
14444 if ( this.previous !== this.element.val() ) { | |
14445 this._trigger( "change", event ); | |
14446 } | |
14447 }, | |
14448 mousewheel: function( event, delta ) { | |
14449 if ( !delta ) { | |
14450 return; | |
14451 } | |
14452 if ( !this.spinning && !this._start( event ) ) { | |
14453 return false; | |
14454 } | |
14455 | |
14456 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); | |
14457 clearTimeout( this.mousewheelTimer ); | |
14458 this.mousewheelTimer = this._delay(function() { | |
14459 if ( this.spinning ) { | |
14460 this._stop( event ); | |
14461 } | |
14462 }, 100 ); | |
14463 event.preventDefault(); | |
14464 }, | |
14465 "mousedown .ui-spinner-button": function( event ) { | |
14466 var previous; | |
14467 | |
14468 // We never want the buttons to have focus; whenever the user is | |
14469 // interacting with the spinner, the focus should be on the input. | |
14470 // If the input is focused then this.previous is properly set from | |
14471 // when the input first received focus. If the input is not focused | |
14472 // then we need to set this.previous based on the value before spinning. | |
14473 previous = this.element[0] === this.document[0].activeElement ? | |
14474 this.previous : this.element.val(); | |
14475 function checkFocus() { | |
14476 var isActive = this.element[0] === this.document[0].activeElement; | |
14477 if ( !isActive ) { | |
14478 this.element.focus(); | |
14479 this.previous = previous; | |
14480 // support: IE | |
14481 // IE sets focus asynchronously, so we need to check if focus | |
14482 // moved off of the input because the user clicked on the button. | |
14483 this._delay(function() { | |
14484 this.previous = previous; | |
14485 }); | |
14486 } | |
14487 } | |
14488 | |
14489 // ensure focus is on (or stays on) the text field | |
14490 event.preventDefault(); | |
14491 checkFocus.call( this ); | |
14492 | |
14493 // support: IE | |
14494 // IE doesn't prevent moving focus even with event.preventDefault() | |
14495 // so we set a flag to know when we should ignore the blur event | |
14496 // and check (again) if focus moved off of the input. | |
14497 this.cancelBlur = true; | |
14498 this._delay(function() { | |
14499 delete this.cancelBlur; | |
14500 checkFocus.call( this ); | |
14501 }); | |
14502 | |
14503 if ( this._start( event ) === false ) { | |
14504 return; | |
14505 } | |
14506 | |
14507 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); | |
14508 }, | |
14509 "mouseup .ui-spinner-button": "_stop", | |
14510 "mouseenter .ui-spinner-button": function( event ) { | |
14511 // button will add ui-state-active if mouse was down while mouseleave and kept down | |
14512 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { | |
14513 return; | |
14514 } | |
14515 | |
14516 if ( this._start( event ) === false ) { | |
14517 return false; | |
14518 } | |
14519 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); | |
14520 }, | |
14521 // TODO: do we really want to consider this a stop? | |
14522 // shouldn't we just stop the repeater and wait until mouseup before | |
14523 // we trigger the stop event? | |
14524 "mouseleave .ui-spinner-button": "_stop" | |
14525 }, | |
14526 | |
14527 _draw: function() { | |
14528 var uiSpinner = this.uiSpinner = this.element | |
14529 .addClass( "ui-spinner-input" ) | |
14530 .attr( "autocomplete", "off" ) | |
14531 .wrap( this._uiSpinnerHtml() ) | |
14532 .parent() | |
14533 // add buttons | |
14534 .append( this._buttonHtml() ); | |
14535 | |
14536 this.element.attr( "role", "spinbutton" ); | |
14537 | |
14538 // button bindings | |
14539 this.buttons = uiSpinner.find( ".ui-spinner-button" ) | |
14540 .attr( "tabIndex", -1 ) | |
14541 .button() | |
14542 .removeClass( "ui-corner-all" ); | |
14543 | |
14544 // IE 6 doesn't understand height: 50% for the buttons | |
14545 // unless the wrapper has an explicit height | |
14546 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && | |
14547 uiSpinner.height() > 0 ) { | |
14548 uiSpinner.height( uiSpinner.height() ); | |
14549 } | |
14550 | |
14551 // disable spinner if element was already disabled | |
14552 if ( this.options.disabled ) { | |
14553 this.disable(); | |
14554 } | |
14555 }, | |
14556 | |
14557 _keydown: function( event ) { | |
14558 var options = this.options, | |
14559 keyCode = $.ui.keyCode; | |
14560 | |
14561 switch ( event.keyCode ) { | |
14562 case keyCode.UP: | |
14563 this._repeat( null, 1, event ); | |
14564 return true; | |
14565 case keyCode.DOWN: | |
14566 this._repeat( null, -1, event ); | |
14567 return true; | |
14568 case keyCode.PAGE_UP: | |
14569 this._repeat( null, options.page, event ); | |
14570 return true; | |
14571 case keyCode.PAGE_DOWN: | |
14572 this._repeat( null, -options.page, event ); | |
14573 return true; | |
14574 } | |
14575 | |
14576 return false; | |
14577 }, | |
14578 | |
14579 _uiSpinnerHtml: function() { | |
14580 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; | |
14581 }, | |
14582 | |
14583 _buttonHtml: function() { | |
14584 return "" + | |
14585 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + | |
14586 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + | |
14587 "</a>" + | |
14588 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + | |
14589 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + | |
14590 "</a>"; | |
14591 }, | |
14592 | |
14593 _start: function( event ) { | |
14594 if ( !this.spinning && this._trigger( "start", event ) === false ) { | |
14595 return false; | |
14596 } | |
14597 | |
14598 if ( !this.counter ) { | |
14599 this.counter = 1; | |
14600 } | |
14601 this.spinning = true; | |
14602 return true; | |
14603 }, | |
14604 | |
14605 _repeat: function( i, steps, event ) { | |
14606 i = i || 500; | |
14607 | |
14608 clearTimeout( this.timer ); | |
14609 this.timer = this._delay(function() { | |
14610 this._repeat( 40, steps, event ); | |
14611 }, i ); | |
14612 | |
14613 this._spin( steps * this.options.step, event ); | |
14614 }, | |
14615 | |
14616 _spin: function( step, event ) { | |
14617 var value = this.value() || 0; | |
14618 | |
14619 if ( !this.counter ) { | |
14620 this.counter = 1; | |
14621 } | |
14622 | |
14623 value = this._adjustValue( value + step * this._increment( this.counter ) ); | |
14624 | |
14625 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { | |
14626 this._value( value ); | |
14627 this.counter++; | |
14628 } | |
14629 }, | |
14630 | |
14631 _increment: function( i ) { | |
14632 var incremental = this.options.incremental; | |
14633 | |
14634 if ( incremental ) { | |
14635 return $.isFunction( incremental ) ? | |
14636 incremental( i ) : | |
14637 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); | |
14638 } | |
14639 | |
14640 return 1; | |
14641 }, | |
14642 | |
14643 _precision: function() { | |
14644 var precision = this._precisionOf( this.options.step ); | |
14645 if ( this.options.min !== null ) { | |
14646 precision = Math.max( precision, this._precisionOf( this.options.min ) ); | |
14647 } | |
14648 return precision; | |
14649 }, | |
14650 | |
14651 _precisionOf: function( num ) { | |
14652 var str = num.toString(), | |
14653 decimal = str.indexOf( "." ); | |
14654 return decimal === -1 ? 0 : str.length - decimal - 1; | |
14655 }, | |
14656 | |
14657 _adjustValue: function( value ) { | |
14658 var base, aboveMin, | |
14659 options = this.options; | |
14660 | |
14661 // make sure we're at a valid step | |
14662 // - find out where we are relative to the base (min or 0) | |
14663 base = options.min !== null ? options.min : 0; | |
14664 aboveMin = value - base; | |
14665 // - round to the nearest step | |
14666 aboveMin = Math.round(aboveMin / options.step) * options.step; | |
14667 // - rounding is based on 0, so adjust back to our base | |
14668 value = base + aboveMin; | |
14669 | |
14670 // fix precision from bad JS floating point math | |
14671 value = parseFloat( value.toFixed( this._precision() ) ); | |
14672 | |
14673 // clamp the value | |
14674 if ( options.max !== null && value > options.max) { | |
14675 return options.max; | |
14676 } | |
14677 if ( options.min !== null && value < options.min ) { | |
14678 return options.min; | |
14679 } | |
14680 | |
14681 return value; | |
14682 }, | |
14683 | |
14684 _stop: function( event ) { | |
14685 if ( !this.spinning ) { | |
14686 return; | |
14687 } | |
14688 | |
14689 clearTimeout( this.timer ); | |
14690 clearTimeout( this.mousewheelTimer ); | |
14691 this.counter = 0; | |
14692 this.spinning = false; | |
14693 this._trigger( "stop", event ); | |
14694 }, | |
14695 | |
14696 _setOption: function( key, value ) { | |
14697 if ( key === "culture" || key === "numberFormat" ) { | |
14698 var prevValue = this._parse( this.element.val() ); | |
14699 this.options[ key ] = value; | |
14700 this.element.val( this._format( prevValue ) ); | |
14701 return; | |
14702 } | |
14703 | |
14704 if ( key === "max" || key === "min" || key === "step" ) { | |
14705 if ( typeof value === "string" ) { | |
14706 value = this._parse( value ); | |
14707 } | |
14708 } | |
14709 if ( key === "icons" ) { | |
14710 this.buttons.first().find( ".ui-icon" ) | |
14711 .removeClass( this.options.icons.up ) | |
14712 .addClass( value.up ); | |
14713 this.buttons.last().find( ".ui-icon" ) | |
14714 .removeClass( this.options.icons.down ) | |
14715 .addClass( value.down ); | |
14716 } | |
14717 | |
14718 this._super( key, value ); | |
14719 | |
14720 if ( key === "disabled" ) { | |
14721 if ( value ) { | |
14722 this.element.prop( "disabled", true ); | |
14723 this.buttons.button( "disable" ); | |
14724 } else { | |
14725 this.element.prop( "disabled", false ); | |
14726 this.buttons.button( "enable" ); | |
14727 } | |
14728 } | |
14729 }, | |
14730 | |
14731 _setOptions: modifier(function( options ) { | |
14732 this._super( options ); | |
14733 this._value( this.element.val() ); | |
14734 }), | |
14735 | |
14736 _parse: function( val ) { | |
14737 if ( typeof val === "string" && val !== "" ) { | |
14738 val = window.Globalize && this.options.numberFormat ? | |
14739 Globalize.parseFloat( val, 10, this.options.culture ) : +val; | |
14740 } | |
14741 return val === "" || isNaN( val ) ? null : val; | |
14742 }, | |
14743 | |
14744 _format: function( value ) { | |
14745 if ( value === "" ) { | |
14746 return ""; | |
14747 } | |
14748 return window.Globalize && this.options.numberFormat ? | |
14749 Globalize.format( value, this.options.numberFormat, this.options.culture ) : | |
14750 value; | |
14751 }, | |
14752 | |
14753 _refresh: function() { | |
14754 this.element.attr({ | |
14755 "aria-valuemin": this.options.min, | |
14756 "aria-valuemax": this.options.max, | |
14757 // TODO: what should we do with values that can't be parsed? | |
14758 "aria-valuenow": this._parse( this.element.val() ) | |
14759 }); | |
14760 }, | |
14761 | |
14762 // update the value without triggering change | |
14763 _value: function( value, allowAny ) { | |
14764 var parsed; | |
14765 if ( value !== "" ) { | |
14766 parsed = this._parse( value ); | |
14767 if ( parsed !== null ) { | |
14768 if ( !allowAny ) { | |
14769 parsed = this._adjustValue( parsed ); | |
14770 } | |
14771 value = this._format( parsed ); | |
14772 } | |
14773 } | |
14774 this.element.val( value ); | |
14775 this._refresh(); | |
14776 }, | |
14777 | |
14778 _destroy: function() { | |
14779 this.element | |
14780 .removeClass( "ui-spinner-input" ) | |
14781 .prop( "disabled", false ) | |
14782 .removeAttr( "autocomplete" ) | |
14783 .removeAttr( "role" ) | |
14784 .removeAttr( "aria-valuemin" ) | |
14785 .removeAttr( "aria-valuemax" ) | |
14786 .removeAttr( "aria-valuenow" ); | |
14787 this.uiSpinner.replaceWith( this.element ); | |
14788 }, | |
14789 | |
14790 stepUp: modifier(function( steps ) { | |
14791 this._stepUp( steps ); | |
14792 }), | |
14793 _stepUp: function( steps ) { | |
14794 if ( this._start() ) { | |
14795 this._spin( (steps || 1) * this.options.step ); | |
14796 this._stop(); | |
14797 } | |
14798 }, | |
14799 | |
14800 stepDown: modifier(function( steps ) { | |
14801 this._stepDown( steps ); | |
14802 }), | |
14803 _stepDown: function( steps ) { | |
14804 if ( this._start() ) { | |
14805 this._spin( (steps || 1) * -this.options.step ); | |
14806 this._stop(); | |
14807 } | |
14808 }, | |
14809 | |
14810 pageUp: modifier(function( pages ) { | |
14811 this._stepUp( (pages || 1) * this.options.page ); | |
14812 }), | |
14813 | |
14814 pageDown: modifier(function( pages ) { | |
14815 this._stepDown( (pages || 1) * this.options.page ); | |
14816 }), | |
14817 | |
14818 value: function( newVal ) { | |
14819 if ( !arguments.length ) { | |
14820 return this._parse( this.element.val() ); | |
14821 } | |
14822 modifier( this._value ).call( this, newVal ); | |
14823 }, | |
14824 | |
14825 widget: function() { | |
14826 return this.uiSpinner; | |
14827 } | |
14828 }); | |
14829 | |
14830 }( jQuery ) ); | |
14831 (function( $, undefined ) { | |
14832 | |
14833 var tabId = 0, | |
14834 rhash = /#.*$/; | |
14835 | |
14836 function getNextTabId() { | |
14837 return ++tabId; | |
14838 } | |
14839 | |
14840 function isLocal( anchor ) { | |
14841 return anchor.hash.length > 1 && | |
14842 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === | |
14843 decodeURIComponent( location.href.replace( rhash, "" ) ); | |
14844 } | |
14845 | |
14846 $.widget( "ui.tabs", { | |
14847 version: "1.10.3", | |
14848 delay: 300, | |
14849 options: { | |
14850 active: null, | |
14851 collapsible: false, | |
14852 event: "click", | |
14853 heightStyle: "content", | |
14854 hide: null, | |
14855 show: null, | |
14856 | |
14857 // callbacks | |
14858 activate: null, | |
14859 beforeActivate: null, | |
14860 beforeLoad: null, | |
14861 load: null | |
14862 }, | |
14863 | |
14864 _create: function() { | |
14865 var that = this, | |
14866 options = this.options; | |
14867 | |
14868 this.running = false; | |
14869 | |
14870 this.element | |
14871 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) | |
14872 .toggleClass( "ui-tabs-collapsible", options.collapsible ) | |
14873 // Prevent users from focusing disabled tabs via click | |
14874 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { | |
14875 if ( $( this ).is( ".ui-state-disabled" ) ) { | |
14876 event.preventDefault(); | |
14877 } | |
14878 }) | |
14879 // support: IE <9 | |
14880 // Preventing the default action in mousedown doesn't prevent IE | |
14881 // from focusing the element, so if the anchor gets focused, blur. | |
14882 // We don't have to worry about focusing the previously focused | |
14883 // element since clicking on a non-focusable element should focus | |
14884 // the body anyway. | |
14885 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { | |
14886 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { | |
14887 this.blur(); | |
14888 } | |
14889 }); | |
14890 | |
14891 this._processTabs(); | |
14892 options.active = this._initialActive(); | |
14893 | |
14894 // Take disabling tabs via class attribute from HTML | |
14895 // into account and update option properly. | |
14896 if ( $.isArray( options.disabled ) ) { | |
14897 options.disabled = $.unique( options.disabled.concat( | |
14898 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { | |
14899 return that.tabs.index( li ); | |
14900 }) | |
14901 ) ).sort(); | |
14902 } | |
14903 | |
14904 // check for length avoids error when initializing empty list | |
14905 if ( this.options.active !== false && this.anchors.length ) { | |
14906 this.active = this._findActive( options.active ); | |
14907 } else { | |
14908 this.active = $(); | |
14909 } | |
14910 | |
14911 this._refresh(); | |
14912 | |
14913 if ( this.active.length ) { | |
14914 this.load( options.active ); | |
14915 } | |
14916 }, | |
14917 | |
14918 _initialActive: function() { | |
14919 var active = this.options.active, | |
14920 collapsible = this.options.collapsible, | |
14921 locationHash = location.hash.substring( 1 ); | |
14922 | |
14923 if ( active === null ) { | |
14924 // check the fragment identifier in the URL | |
14925 if ( locationHash ) { | |
14926 this.tabs.each(function( i, tab ) { | |
14927 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { | |
14928 active = i; | |
14929 return false; | |
14930 } | |
14931 }); | |
14932 } | |
14933 | |
14934 // check for a tab marked active via a class | |
14935 if ( active === null ) { | |
14936 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); | |
14937 } | |
14938 | |
14939 // no active tab, set to false | |
14940 if ( active === null || active === -1 ) { | |
14941 active = this.tabs.length ? 0 : false; | |
14942 } | |
14943 } | |
14944 | |
14945 // handle numbers: negative, out of range | |
14946 if ( active !== false ) { | |
14947 active = this.tabs.index( this.tabs.eq( active ) ); | |
14948 if ( active === -1 ) { | |
14949 active = collapsible ? false : 0; | |
14950 } | |
14951 } | |
14952 | |
14953 // don't allow collapsible: false and active: false | |
14954 if ( !collapsible && active === false && this.anchors.length ) { | |
14955 active = 0; | |
14956 } | |
14957 | |
14958 return active; | |
14959 }, | |
14960 | |
14961 _getCreateEventData: function() { | |
14962 return { | |
14963 tab: this.active, | |
14964 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) | |
14965 }; | |
14966 }, | |
14967 | |
14968 _tabKeydown: function( event ) { | |
14969 /*jshint maxcomplexity:15*/ | |
14970 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), | |
14971 selectedIndex = this.tabs.index( focusedTab ), | |
14972 goingForward = true; | |
14973 | |
14974 if ( this._handlePageNav( event ) ) { | |
14975 return; | |
14976 } | |
14977 | |
14978 switch ( event.keyCode ) { | |
14979 case $.ui.keyCode.RIGHT: | |
14980 case $.ui.keyCode.DOWN: | |
14981 selectedIndex++; | |
14982 break; | |
14983 case $.ui.keyCode.UP: | |
14984 case $.ui.keyCode.LEFT: | |
14985 goingForward = false; | |
14986 selectedIndex--; | |
14987 break; | |
14988 case $.ui.keyCode.END: | |
14989 selectedIndex = this.anchors.length - 1; | |
14990 break; | |
14991 case $.ui.keyCode.HOME: | |
14992 selectedIndex = 0; | |
14993 break; | |
14994 case $.ui.keyCode.SPACE: | |
14995 // Activate only, no collapsing | |
14996 event.preventDefault(); | |
14997 clearTimeout( this.activating ); | |
14998 this._activate( selectedIndex ); | |
14999 return; | |
15000 case $.ui.keyCode.ENTER: | |
15001 // Toggle (cancel delayed activation, allow collapsing) | |
15002 event.preventDefault(); | |
15003 clearTimeout( this.activating ); | |
15004 // Determine if we should collapse or activate | |
15005 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); | |
15006 return; | |
15007 default: | |
15008 return; | |
15009 } | |
15010 | |
15011 // Focus the appropriate tab, based on which key was pressed | |
15012 event.preventDefault(); | |
15013 clearTimeout( this.activating ); | |
15014 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); | |
15015 | |
15016 // Navigating with control key will prevent automatic activation | |
15017 if ( !event.ctrlKey ) { | |
15018 // Update aria-selected immediately so that AT think the tab is already selected. | |
15019 // Otherwise AT may confuse the user by stating that they need to activate the tab, | |
15020 // but the tab will already be activated by the time the announcement finishes. | |
15021 focusedTab.attr( "aria-selected", "false" ); | |
15022 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); | |
15023 | |
15024 this.activating = this._delay(function() { | |
15025 this.option( "active", selectedIndex ); | |
15026 }, this.delay ); | |
15027 } | |
15028 }, | |
15029 | |
15030 _panelKeydown: function( event ) { | |
15031 if ( this._handlePageNav( event ) ) { | |
15032 return; | |
15033 } | |
15034 | |
15035 // Ctrl+up moves focus to the current tab | |
15036 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { | |
15037 event.preventDefault(); | |
15038 this.active.focus(); | |
15039 } | |
15040 }, | |
15041 | |
15042 // Alt+page up/down moves focus to the previous/next tab (and activates) | |
15043 _handlePageNav: function( event ) { | |
15044 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { | |
15045 this._activate( this._focusNextTab( this.options.active - 1, false ) ); | |
15046 return true; | |
15047 } | |
15048 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { | |
15049 this._activate( this._focusNextTab( this.options.active + 1, true ) ); | |
15050 return true; | |
15051 } | |
15052 }, | |
15053 | |
15054 _findNextTab: function( index, goingForward ) { | |
15055 var lastTabIndex = this.tabs.length - 1; | |
15056 | |
15057 function constrain() { | |
15058 if ( index > lastTabIndex ) { | |
15059 index = 0; | |
15060 } | |
15061 if ( index < 0 ) { | |
15062 index = lastTabIndex; | |
15063 } | |
15064 return index; | |
15065 } | |
15066 | |
15067 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { | |
15068 index = goingForward ? index + 1 : index - 1; | |
15069 } | |
15070 | |
15071 return index; | |
15072 }, | |
15073 | |
15074 _focusNextTab: function( index, goingForward ) { | |
15075 index = this._findNextTab( index, goingForward ); | |
15076 this.tabs.eq( index ).focus(); | |
15077 return index; | |
15078 }, | |
15079 | |
15080 _setOption: function( key, value ) { | |
15081 if ( key === "active" ) { | |
15082 // _activate() will handle invalid values and update this.options | |
15083 this._activate( value ); | |
15084 return; | |
15085 } | |
15086 | |
15087 if ( key === "disabled" ) { | |
15088 // don't use the widget factory's disabled handling | |
15089 this._setupDisabled( value ); | |
15090 return; | |
15091 } | |
15092 | |
15093 this._super( key, value); | |
15094 | |
15095 if ( key === "collapsible" ) { | |
15096 this.element.toggleClass( "ui-tabs-collapsible", value ); | |
15097 // Setting collapsible: false while collapsed; open first panel | |
15098 if ( !value && this.options.active === false ) { | |
15099 this._activate( 0 ); | |
15100 } | |
15101 } | |
15102 | |
15103 if ( key === "event" ) { | |
15104 this._setupEvents( value ); | |
15105 } | |
15106 | |
15107 if ( key === "heightStyle" ) { | |
15108 this._setupHeightStyle( value ); | |
15109 } | |
15110 }, | |
15111 | |
15112 _tabId: function( tab ) { | |
15113 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); | |
15114 }, | |
15115 | |
15116 _sanitizeSelector: function( hash ) { | |
15117 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; | |
15118 }, | |
15119 | |
15120 refresh: function() { | |
15121 var options = this.options, | |
15122 lis = this.tablist.children( ":has(a[href])" ); | |
15123 | |
15124 // get disabled tabs from class attribute from HTML | |
15125 // this will get converted to a boolean if needed in _refresh() | |
15126 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { | |
15127 return lis.index( tab ); | |
15128 }); | |
15129 | |
15130 this._processTabs(); | |
15131 | |
15132 // was collapsed or no tabs | |
15133 if ( options.active === false || !this.anchors.length ) { | |
15134 options.active = false; | |
15135 this.active = $(); | |
15136 // was active, but active tab is gone | |
15137 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { | |
15138 // all remaining tabs are disabled | |
15139 if ( this.tabs.length === options.disabled.length ) { | |
15140 options.active = false; | |
15141 this.active = $(); | |
15142 // activate previous tab | |
15143 } else { | |
15144 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); | |
15145 } | |
15146 // was active, active tab still exists | |
15147 } else { | |
15148 // make sure active index is correct | |
15149 options.active = this.tabs.index( this.active ); | |
15150 } | |
15151 | |
15152 this._refresh(); | |
15153 }, | |
15154 | |
15155 _refresh: function() { | |
15156 this._setupDisabled( this.options.disabled ); | |
15157 this._setupEvents( this.options.event ); | |
15158 this._setupHeightStyle( this.options.heightStyle ); | |
15159 | |
15160 this.tabs.not( this.active ).attr({ | |
15161 "aria-selected": "false", | |
15162 tabIndex: -1 | |
15163 }); | |
15164 this.panels.not( this._getPanelForTab( this.active ) ) | |
15165 .hide() | |
15166 .attr({ | |
15167 "aria-expanded": "false", | |
15168 "aria-hidden": "true" | |
15169 }); | |
15170 | |
15171 // Make sure one tab is in the tab order | |
15172 if ( !this.active.length ) { | |
15173 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); | |
15174 } else { | |
15175 this.active | |
15176 .addClass( "ui-tabs-active ui-state-active" ) | |
15177 .attr({ | |
15178 "aria-selected": "true", | |
15179 tabIndex: 0 | |
15180 }); | |
15181 this._getPanelForTab( this.active ) | |
15182 .show() | |
15183 .attr({ | |
15184 "aria-expanded": "true", | |
15185 "aria-hidden": "false" | |
15186 }); | |
15187 } | |
15188 }, | |
15189 | |
15190 _processTabs: function() { | |
15191 var that = this; | |
15192 | |
15193 this.tablist = this._getList() | |
15194 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) | |
15195 .attr( "role", "tablist" ); | |
15196 | |
15197 this.tabs = this.tablist.find( "> li:has(a[href])" ) | |
15198 .addClass( "ui-state-default ui-corner-top" ) | |
15199 .attr({ | |
15200 role: "tab", | |
15201 tabIndex: -1 | |
15202 }); | |
15203 | |
15204 this.anchors = this.tabs.map(function() { | |
15205 return $( "a", this )[ 0 ]; | |
15206 }) | |
15207 .addClass( "ui-tabs-anchor" ) | |
15208 .attr({ | |
15209 role: "presentation", | |
15210 tabIndex: -1 | |
15211 }); | |
15212 | |
15213 this.panels = $(); | |
15214 | |
15215 this.anchors.each(function( i, anchor ) { | |
15216 var selector, panel, panelId, | |
15217 anchorId = $( anchor ).uniqueId().attr( "id" ), | |
15218 tab = $( anchor ).closest( "li" ), | |
15219 originalAriaControls = tab.attr( "aria-controls" ); | |
15220 | |
15221 // inline tab | |
15222 if ( isLocal( anchor ) ) { | |
15223 selector = anchor.hash; | |
15224 panel = that.element.find( that._sanitizeSelector( selector ) ); | |
15225 // remote tab | |
15226 } else { | |
15227 panelId = that._tabId( tab ); | |
15228 selector = "#" + panelId; | |
15229 panel = that.element.find( selector ); | |
15230 if ( !panel.length ) { | |
15231 panel = that._createPanel( panelId ); | |
15232 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); | |
15233 } | |
15234 panel.attr( "aria-live", "polite" ); | |
15235 } | |
15236 | |
15237 if ( panel.length) { | |
15238 that.panels = that.panels.add( panel ); | |
15239 } | |
15240 if ( originalAriaControls ) { | |
15241 tab.data( "ui-tabs-aria-controls", originalAriaControls ); | |
15242 } | |
15243 tab.attr({ | |
15244 "aria-controls": selector.substring( 1 ), | |
15245 "aria-labelledby": anchorId | |
15246 }); | |
15247 panel.attr( "aria-labelledby", anchorId ); | |
15248 }); | |
15249 | |
15250 this.panels | |
15251 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) | |
15252 .attr( "role", "tabpanel" ); | |
15253 }, | |
15254 | |
15255 // allow overriding how to find the list for rare usage scenarios (#7715) | |
15256 _getList: function() { | |
15257 return this.element.find( "ol,ul" ).eq( 0 ); | |
15258 }, | |
15259 | |
15260 _createPanel: function( id ) { | |
15261 return $( "<div>" ) | |
15262 .attr( "id", id ) | |
15263 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) | |
15264 .data( "ui-tabs-destroy", true ); | |
15265 }, | |
15266 | |
15267 _setupDisabled: function( disabled ) { | |
15268 if ( $.isArray( disabled ) ) { | |
15269 if ( !disabled.length ) { | |
15270 disabled = false; | |
15271 } else if ( disabled.length === this.anchors.length ) { | |
15272 disabled = true; | |
15273 } | |
15274 } | |
15275 | |
15276 // disable tabs | |
15277 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { | |
15278 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { | |
15279 $( li ) | |
15280 .addClass( "ui-state-disabled" ) | |
15281 .attr( "aria-disabled", "true" ); | |
15282 } else { | |
15283 $( li ) | |
15284 .removeClass( "ui-state-disabled" ) | |
15285 .removeAttr( "aria-disabled" ); | |
15286 } | |
15287 } | |
15288 | |
15289 this.options.disabled = disabled; | |
15290 }, | |
15291 | |
15292 _setupEvents: function( event ) { | |
15293 var events = { | |
15294 click: function( event ) { | |
15295 event.preventDefault(); | |
15296 } | |
15297 }; | |
15298 if ( event ) { | |
15299 $.each( event.split(" "), function( index, eventName ) { | |
15300 events[ eventName ] = "_eventHandler"; | |
15301 }); | |
15302 } | |
15303 | |
15304 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); | |
15305 this._on( this.anchors, events ); | |
15306 this._on( this.tabs, { keydown: "_tabKeydown" } ); | |
15307 this._on( this.panels, { keydown: "_panelKeydown" } ); | |
15308 | |
15309 this._focusable( this.tabs ); | |
15310 this._hoverable( this.tabs ); | |
15311 }, | |
15312 | |
15313 _setupHeightStyle: function( heightStyle ) { | |
15314 var maxHeight, | |
15315 parent = this.element.parent(); | |
15316 | |
15317 if ( heightStyle === "fill" ) { | |
15318 maxHeight = parent.height(); | |
15319 maxHeight -= this.element.outerHeight() - this.element.height(); | |
15320 | |
15321 this.element.siblings( ":visible" ).each(function() { | |
15322 var elem = $( this ), | |
15323 position = elem.css( "position" ); | |
15324 | |
15325 if ( position === "absolute" || position === "fixed" ) { | |
15326 return; | |
15327 } | |
15328 maxHeight -= elem.outerHeight( true ); | |
15329 }); | |
15330 | |
15331 this.element.children().not( this.panels ).each(function() { | |
15332 maxHeight -= $( this ).outerHeight( true ); | |
15333 }); | |
15334 | |
15335 this.panels.each(function() { | |
15336 $( this ).height( Math.max( 0, maxHeight - | |
15337 $( this ).innerHeight() + $( this ).height() ) ); | |
15338 }) | |
15339 .css( "overflow", "auto" ); | |
15340 } else if ( heightStyle === "auto" ) { | |
15341 maxHeight = 0; | |
15342 this.panels.each(function() { | |
15343 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); | |
15344 }).height( maxHeight ); | |
15345 } | |
15346 }, | |
15347 | |
15348 _eventHandler: function( event ) { | |
15349 var options = this.options, | |
15350 active = this.active, | |
15351 anchor = $( event.currentTarget ), | |
15352 tab = anchor.closest( "li" ), | |
15353 clickedIsActive = tab[ 0 ] === active[ 0 ], | |
15354 collapsing = clickedIsActive && options.collapsible, | |
15355 toShow = collapsing ? $() : this._getPanelForTab( tab ), | |
15356 toHide = !active.length ? $() : this._getPanelForTab( active ), | |
15357 eventData = { | |
15358 oldTab: active, | |
15359 oldPanel: toHide, | |
15360 newTab: collapsing ? $() : tab, | |
15361 newPanel: toShow | |
15362 }; | |
15363 | |
15364 event.preventDefault(); | |
15365 | |
15366 if ( tab.hasClass( "ui-state-disabled" ) || | |
15367 // tab is already loading | |
15368 tab.hasClass( "ui-tabs-loading" ) || | |
15369 // can't switch durning an animation | |
15370 this.running || | |
15371 // click on active header, but not collapsible | |
15372 ( clickedIsActive && !options.collapsible ) || | |
15373 // allow canceling activation | |
15374 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { | |
15375 return; | |
15376 } | |
15377 | |
15378 options.active = collapsing ? false : this.tabs.index( tab ); | |
15379 | |
15380 this.active = clickedIsActive ? $() : tab; | |
15381 if ( this.xhr ) { | |
15382 this.xhr.abort(); | |
15383 } | |
15384 | |
15385 if ( !toHide.length && !toShow.length ) { | |
15386 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); | |
15387 } | |
15388 | |
15389 if ( toShow.length ) { | |
15390 this.load( this.tabs.index( tab ), event ); | |
15391 } | |
15392 this._toggle( event, eventData ); | |
15393 }, | |
15394 | |
15395 // handles show/hide for selecting tabs | |
15396 _toggle: function( event, eventData ) { | |
15397 var that = this, | |
15398 toShow = eventData.newPanel, | |
15399 toHide = eventData.oldPanel; | |
15400 | |
15401 this.running = true; | |
15402 | |
15403 function complete() { | |
15404 that.running = false; | |
15405 that._trigger( "activate", event, eventData ); | |
15406 } | |
15407 | |
15408 function show() { | |
15409 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); | |
15410 | |
15411 if ( toShow.length && that.options.show ) { | |
15412 that._show( toShow, that.options.show, complete ); | |
15413 } else { | |
15414 toShow.show(); | |
15415 complete(); | |
15416 } | |
15417 } | |
15418 | |
15419 // start out by hiding, then showing, then completing | |
15420 if ( toHide.length && this.options.hide ) { | |
15421 this._hide( toHide, this.options.hide, function() { | |
15422 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); | |
15423 show(); | |
15424 }); | |
15425 } else { | |
15426 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); | |
15427 toHide.hide(); | |
15428 show(); | |
15429 } | |
15430 | |
15431 toHide.attr({ | |
15432 "aria-expanded": "false", | |
15433 "aria-hidden": "true" | |
15434 }); | |
15435 eventData.oldTab.attr( "aria-selected", "false" ); | |
15436 // If we're switching tabs, remove the old tab from the tab order. | |
15437 // If we're opening from collapsed state, remove the previous tab from the tab order. | |
15438 // If we're collapsing, then keep the collapsing tab in the tab order. | |
15439 if ( toShow.length && toHide.length ) { | |
15440 eventData.oldTab.attr( "tabIndex", -1 ); | |
15441 } else if ( toShow.length ) { | |
15442 this.tabs.filter(function() { | |
15443 return $( this ).attr( "tabIndex" ) === 0; | |
15444 }) | |
15445 .attr( "tabIndex", -1 ); | |
15446 } | |
15447 | |
15448 toShow.attr({ | |
15449 "aria-expanded": "true", | |
15450 "aria-hidden": "false" | |
15451 }); | |
15452 eventData.newTab.attr({ | |
15453 "aria-selected": "true", | |
15454 tabIndex: 0 | |
15455 }); | |
15456 }, | |
15457 | |
15458 _activate: function( index ) { | |
15459 var anchor, | |
15460 active = this._findActive( index ); | |
15461 | |
15462 // trying to activate the already active panel | |
15463 if ( active[ 0 ] === this.active[ 0 ] ) { | |
15464 return; | |
15465 } | |
15466 | |
15467 // trying to collapse, simulate a click on the current active header | |
15468 if ( !active.length ) { | |
15469 active = this.active; | |
15470 } | |
15471 | |
15472 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; | |
15473 this._eventHandler({ | |
15474 target: anchor, | |
15475 currentTarget: anchor, | |
15476 preventDefault: $.noop | |
15477 }); | |
15478 }, | |
15479 | |
15480 _findActive: function( index ) { | |
15481 return index === false ? $() : this.tabs.eq( index ); | |
15482 }, | |
15483 | |
15484 _getIndex: function( index ) { | |
15485 // meta-function to give users option to provide a href string instead of a numerical index. | |
15486 if ( typeof index === "string" ) { | |
15487 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); | |
15488 } | |
15489 | |
15490 return index; | |
15491 }, | |
15492 | |
15493 _destroy: function() { | |
15494 if ( this.xhr ) { | |
15495 this.xhr.abort(); | |
15496 } | |
15497 | |
15498 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); | |
15499 | |
15500 this.tablist | |
15501 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) | |
15502 .removeAttr( "role" ); | |
15503 | |
15504 this.anchors | |
15505 .removeClass( "ui-tabs-anchor" ) | |
15506 .removeAttr( "role" ) | |
15507 .removeAttr( "tabIndex" ) | |
15508 .removeUniqueId(); | |
15509 | |
15510 this.tabs.add( this.panels ).each(function() { | |
15511 if ( $.data( this, "ui-tabs-destroy" ) ) { | |
15512 $( this ).remove(); | |
15513 } else { | |
15514 $( this ) | |
15515 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + | |
15516 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) | |
15517 .removeAttr( "tabIndex" ) | |
15518 .removeAttr( "aria-live" ) | |
15519 .removeAttr( "aria-busy" ) | |
15520 .removeAttr( "aria-selected" ) | |
15521 .removeAttr( "aria-labelledby" ) | |
15522 .removeAttr( "aria-hidden" ) | |
15523 .removeAttr( "aria-expanded" ) | |
15524 .removeAttr( "role" ); | |
15525 } | |
15526 }); | |
15527 | |
15528 this.tabs.each(function() { | |
15529 var li = $( this ), | |
15530 prev = li.data( "ui-tabs-aria-controls" ); | |
15531 if ( prev ) { | |
15532 li | |
15533 .attr( "aria-controls", prev ) | |
15534 .removeData( "ui-tabs-aria-controls" ); | |
15535 } else { | |
15536 li.removeAttr( "aria-controls" ); | |
15537 } | |
15538 }); | |
15539 | |
15540 this.panels.show(); | |
15541 | |
15542 if ( this.options.heightStyle !== "content" ) { | |
15543 this.panels.css( "height", "" ); | |
15544 } | |
15545 }, | |
15546 | |
15547 enable: function( index ) { | |
15548 var disabled = this.options.disabled; | |
15549 if ( disabled === false ) { | |
15550 return; | |
15551 } | |
15552 | |
15553 if ( index === undefined ) { | |
15554 disabled = false; | |
15555 } else { | |
15556 index = this._getIndex( index ); | |
15557 if ( $.isArray( disabled ) ) { | |
15558 disabled = $.map( disabled, function( num ) { | |
15559 return num !== index ? num : null; | |
15560 }); | |
15561 } else { | |
15562 disabled = $.map( this.tabs, function( li, num ) { | |
15563 return num !== index ? num : null; | |
15564 }); | |
15565 } | |
15566 } | |
15567 this._setupDisabled( disabled ); | |
15568 }, | |
15569 | |
15570 disable: function( index ) { | |
15571 var disabled = this.options.disabled; | |
15572 if ( disabled === true ) { | |
15573 return; | |
15574 } | |
15575 | |
15576 if ( index === undefined ) { | |
15577 disabled = true; | |
15578 } else { | |
15579 index = this._getIndex( index ); | |
15580 if ( $.inArray( index, disabled ) !== -1 ) { | |
15581 return; | |
15582 } | |
15583 if ( $.isArray( disabled ) ) { | |
15584 disabled = $.merge( [ index ], disabled ).sort(); | |
15585 } else { | |
15586 disabled = [ index ]; | |
15587 } | |
15588 } | |
15589 this._setupDisabled( disabled ); | |
15590 }, | |
15591 | |
15592 load: function( index, event ) { | |
15593 index = this._getIndex( index ); | |
15594 var that = this, | |
15595 tab = this.tabs.eq( index ), | |
15596 anchor = tab.find( ".ui-tabs-anchor" ), | |
15597 panel = this._getPanelForTab( tab ), | |
15598 eventData = { | |
15599 tab: tab, | |
15600 panel: panel | |
15601 }; | |
15602 | |
15603 // not remote | |
15604 if ( isLocal( anchor[ 0 ] ) ) { | |
15605 return; | |
15606 } | |
15607 | |
15608 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); | |
15609 | |
15610 // support: jQuery <1.8 | |
15611 // jQuery <1.8 returns false if the request is canceled in beforeSend, | |
15612 // but as of 1.8, $.ajax() always returns a jqXHR object. | |
15613 if ( this.xhr && this.xhr.statusText !== "canceled" ) { | |
15614 tab.addClass( "ui-tabs-loading" ); | |
15615 panel.attr( "aria-busy", "true" ); | |
15616 | |
15617 this.xhr | |
15618 .success(function( response ) { | |
15619 // support: jQuery <1.8 | |
15620 // http://bugs.jquery.com/ticket/11778 | |
15621 setTimeout(function() { | |
15622 panel.html( response ); | |
15623 that._trigger( "load", event, eventData ); | |
15624 }, 1 ); | |
15625 }) | |
15626 .complete(function( jqXHR, status ) { | |
15627 // support: jQuery <1.8 | |
15628 // http://bugs.jquery.com/ticket/11778 | |
15629 setTimeout(function() { | |
15630 if ( status === "abort" ) { | |
15631 that.panels.stop( false, true ); | |
15632 } | |
15633 | |
15634 tab.removeClass( "ui-tabs-loading" ); | |
15635 panel.removeAttr( "aria-busy" ); | |
15636 | |
15637 if ( jqXHR === that.xhr ) { | |
15638 delete that.xhr; | |
15639 } | |
15640 }, 1 ); | |
15641 }); | |
15642 } | |
15643 }, | |
15644 | |
15645 _ajaxSettings: function( anchor, event, eventData ) { | |
15646 var that = this; | |
15647 return { | |
15648 url: anchor.attr( "href" ), | |
15649 beforeSend: function( jqXHR, settings ) { | |
15650 return that._trigger( "beforeLoad", event, | |
15651 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); | |
15652 } | |
15653 }; | |
15654 }, | |
15655 | |
15656 _getPanelForTab: function( tab ) { | |
15657 var id = $( tab ).attr( "aria-controls" ); | |
15658 return this.element.find( this._sanitizeSelector( "#" + id ) ); | |
15659 } | |
15660 }); | |
15661 | |
15662 })( jQuery ); | |
15663 (function( $ ) { | |
15664 | |
15665 var increments = 0; | |
15666 | |
15667 function addDescribedBy( elem, id ) { | |
15668 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); | |
15669 describedby.push( id ); | |
15670 elem | |
15671 .data( "ui-tooltip-id", id ) | |
15672 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); | |
15673 } | |
15674 | |
15675 function removeDescribedBy( elem ) { | |
15676 var id = elem.data( "ui-tooltip-id" ), | |
15677 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), | |
15678 index = $.inArray( id, describedby ); | |
15679 if ( index !== -1 ) { | |
15680 describedby.splice( index, 1 ); | |
15681 } | |
15682 | |
15683 elem.removeData( "ui-tooltip-id" ); | |
15684 describedby = $.trim( describedby.join( " " ) ); | |
15685 if ( describedby ) { | |
15686 elem.attr( "aria-describedby", describedby ); | |
15687 } else { | |
15688 elem.removeAttr( "aria-describedby" ); | |
15689 } | |
15690 } | |
15691 | |
15692 $.widget( "ui.tooltip", { | |
15693 version: "1.10.3", | |
15694 options: { | |
15695 content: function() { | |
15696 // support: IE<9, Opera in jQuery <1.7 | |
15697 // .text() can't accept undefined, so coerce to a string | |
15698 var title = $( this ).attr( "title" ) || ""; | |
15699 // Escape title, since we're going from an attribute to raw HTML | |
15700 return $( "<a>" ).text( title ).html(); | |
15701 }, | |
15702 hide: true, | |
15703 // Disabled elements have inconsistent behavior across browsers (#8661) | |
15704 items: "[title]:not([disabled])", | |
15705 position: { | |
15706 my: "left top+15", | |
15707 at: "left bottom", | |
15708 collision: "flipfit flip" | |
15709 }, | |
15710 show: true, | |
15711 tooltipClass: null, | |
15712 track: false, | |
15713 | |
15714 // callbacks | |
15715 close: null, | |
15716 open: null | |
15717 }, | |
15718 | |
15719 _create: function() { | |
15720 this._on({ | |
15721 mouseover: "open", | |
15722 focusin: "open" | |
15723 }); | |
15724 | |
15725 // IDs of generated tooltips, needed for destroy | |
15726 this.tooltips = {}; | |
15727 // IDs of parent tooltips where we removed the title attribute | |
15728 this.parents = {}; | |
15729 | |
15730 if ( this.options.disabled ) { | |
15731 this._disable(); | |
15732 } | |
15733 }, | |
15734 | |
15735 _setOption: function( key, value ) { | |
15736 var that = this; | |
15737 | |
15738 if ( key === "disabled" ) { | |
15739 this[ value ? "_disable" : "_enable" ](); | |
15740 this.options[ key ] = value; | |
15741 // disable element style changes | |
15742 return; | |
15743 } | |
15744 | |
15745 this._super( key, value ); | |
15746 | |
15747 if ( key === "content" ) { | |
15748 $.each( this.tooltips, function( id, element ) { | |
15749 that._updateContent( element ); | |
15750 }); | |
15751 } | |
15752 }, | |
15753 | |
15754 _disable: function() { | |
15755 var that = this; | |
15756 | |
15757 // close open tooltips | |
15758 $.each( this.tooltips, function( id, element ) { | |
15759 var event = $.Event( "blur" ); | |
15760 event.target = event.currentTarget = element[0]; | |
15761 that.close( event, true ); | |
15762 }); | |
15763 | |
15764 // remove title attributes to prevent native tooltips | |
15765 this.element.find( this.options.items ).addBack().each(function() { | |
15766 var element = $( this ); | |
15767 if ( element.is( "[title]" ) ) { | |
15768 element | |
15769 .data( "ui-tooltip-title", element.attr( "title" ) ) | |
15770 .attr( "title", "" ); | |
15771 } | |
15772 }); | |
15773 }, | |
15774 | |
15775 _enable: function() { | |
15776 // restore title attributes | |
15777 this.element.find( this.options.items ).addBack().each(function() { | |
15778 var element = $( this ); | |
15779 if ( element.data( "ui-tooltip-title" ) ) { | |
15780 element.attr( "title", element.data( "ui-tooltip-title" ) ); | |
15781 } | |
15782 }); | |
15783 }, | |
15784 | |
15785 open: function( event ) { | |
15786 var that = this, | |
15787 target = $( event ? event.target : this.element ) | |
15788 // we need closest here due to mouseover bubbling, | |
15789 // but always pointing at the same event target | |
15790 .closest( this.options.items ); | |
15791 | |
15792 // No element to show a tooltip for or the tooltip is already open | |
15793 if ( !target.length || target.data( "ui-tooltip-id" ) ) { | |
15794 return; | |
15795 } | |
15796 | |
15797 if ( target.attr( "title" ) ) { | |
15798 target.data( "ui-tooltip-title", target.attr( "title" ) ); | |
15799 } | |
15800 | |
15801 target.data( "ui-tooltip-open", true ); | |
15802 | |
15803 // kill parent tooltips, custom or native, for hover | |
15804 if ( event && event.type === "mouseover" ) { | |
15805 target.parents().each(function() { | |
15806 var parent = $( this ), | |
15807 blurEvent; | |
15808 if ( parent.data( "ui-tooltip-open" ) ) { | |
15809 blurEvent = $.Event( "blur" ); | |
15810 blurEvent.target = blurEvent.currentTarget = this; | |
15811 that.close( blurEvent, true ); | |
15812 } | |
15813 if ( parent.attr( "title" ) ) { | |
15814 parent.uniqueId(); | |
15815 that.parents[ this.id ] = { | |
15816 element: this, | |
15817 title: parent.attr( "title" ) | |
15818 }; | |
15819 parent.attr( "title", "" ); | |
15820 } | |
15821 }); | |
15822 } | |
15823 | |
15824 this._updateContent( target, event ); | |
15825 }, | |
15826 | |
15827 _updateContent: function( target, event ) { | |
15828 var content, | |
15829 contentOption = this.options.content, | |
15830 that = this, | |
15831 eventType = event ? event.type : null; | |
15832 | |
15833 if ( typeof contentOption === "string" ) { | |
15834 return this._open( event, target, contentOption ); | |
15835 } | |
15836 | |
15837 content = contentOption.call( target[0], function( response ) { | |
15838 // ignore async response if tooltip was closed already | |
15839 if ( !target.data( "ui-tooltip-open" ) ) { | |
15840 return; | |
15841 } | |
15842 // IE may instantly serve a cached response for ajax requests | |
15843 // delay this call to _open so the other call to _open runs first | |
15844 that._delay(function() { | |
15845 // jQuery creates a special event for focusin when it doesn't | |
15846 // exist natively. To improve performance, the native event | |
15847 // object is reused and the type is changed. Therefore, we can't | |
15848 // rely on the type being correct after the event finished | |
15849 // bubbling, so we set it back to the previous value. (#8740) | |
15850 if ( event ) { | |
15851 event.type = eventType; | |
15852 } | |
15853 this._open( event, target, response ); | |
15854 }); | |
15855 }); | |
15856 if ( content ) { | |
15857 this._open( event, target, content ); | |
15858 } | |
15859 }, | |
15860 | |
15861 _open: function( event, target, content ) { | |
15862 var tooltip, events, delayedShow, | |
15863 positionOption = $.extend( {}, this.options.position ); | |
15864 | |
15865 if ( !content ) { | |
15866 return; | |
15867 } | |
15868 | |
15869 // Content can be updated multiple times. If the tooltip already | |
15870 // exists, then just update the content and bail. | |
15871 tooltip = this._find( target ); | |
15872 if ( tooltip.length ) { | |
15873 tooltip.find( ".ui-tooltip-content" ).html( content ); | |
15874 return; | |
15875 } | |
15876 | |
15877 // if we have a title, clear it to prevent the native tooltip | |
15878 // we have to check first to avoid defining a title if none exists | |
15879 // (we don't want to cause an element to start matching [title]) | |
15880 // | |
15881 // We use removeAttr only for key events, to allow IE to export the correct | |
15882 // accessible attributes. For mouse events, set to empty string to avoid | |
15883 // native tooltip showing up (happens only when removing inside mouseover). | |
15884 if ( target.is( "[title]" ) ) { | |
15885 if ( event && event.type === "mouseover" ) { | |
15886 target.attr( "title", "" ); | |
15887 } else { | |
15888 target.removeAttr( "title" ); | |
15889 } | |
15890 } | |
15891 | |
15892 tooltip = this._tooltip( target ); | |
15893 addDescribedBy( target, tooltip.attr( "id" ) ); | |
15894 tooltip.find( ".ui-tooltip-content" ).html( content ); | |
15895 | |
15896 function position( event ) { | |
15897 positionOption.of = event; | |
15898 if ( tooltip.is( ":hidden" ) ) { | |
15899 return; | |
15900 } | |
15901 tooltip.position( positionOption ); | |
15902 } | |
15903 if ( this.options.track && event && /^mouse/.test( event.type ) ) { | |
15904 this._on( this.document, { | |
15905 mousemove: position | |
15906 }); | |
15907 // trigger once to override element-relative positioning | |
15908 position( event ); | |
15909 } else { | |
15910 tooltip.position( $.extend({ | |
15911 of: target | |
15912 }, this.options.position ) ); | |
15913 } | |
15914 | |
15915 tooltip.hide(); | |
15916 | |
15917 this._show( tooltip, this.options.show ); | |
15918 // Handle tracking tooltips that are shown with a delay (#8644). As soon | |
15919 // as the tooltip is visible, position the tooltip using the most recent | |
15920 // event. | |
15921 if ( this.options.show && this.options.show.delay ) { | |
15922 delayedShow = this.delayedShow = setInterval(function() { | |
15923 if ( tooltip.is( ":visible" ) ) { | |
15924 position( positionOption.of ); | |
15925 clearInterval( delayedShow ); | |
15926 } | |
15927 }, $.fx.interval ); | |
15928 } | |
15929 | |
15930 this._trigger( "open", event, { tooltip: tooltip } ); | |
15931 | |
15932 events = { | |
15933 keyup: function( event ) { | |
15934 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { | |
15935 var fakeEvent = $.Event(event); | |
15936 fakeEvent.currentTarget = target[0]; | |
15937 this.close( fakeEvent, true ); | |
15938 } | |
15939 }, | |
15940 remove: function() { | |
15941 this._removeTooltip( tooltip ); | |
15942 } | |
15943 }; | |
15944 if ( !event || event.type === "mouseover" ) { | |
15945 events.mouseleave = "close"; | |
15946 } | |
15947 if ( !event || event.type === "focusin" ) { | |
15948 events.focusout = "close"; | |
15949 } | |
15950 this._on( true, target, events ); | |
15951 }, | |
15952 | |
15953 close: function( event ) { | |
15954 var that = this, | |
15955 target = $( event ? event.currentTarget : this.element ), | |
15956 tooltip = this._find( target ); | |
15957 | |
15958 // disabling closes the tooltip, so we need to track when we're closing | |
15959 // to avoid an infinite loop in case the tooltip becomes disabled on close | |
15960 if ( this.closing ) { | |
15961 return; | |
15962 } | |
15963 | |
15964 // Clear the interval for delayed tracking tooltips | |
15965 clearInterval( this.delayedShow ); | |
15966 | |
15967 // only set title if we had one before (see comment in _open()) | |
15968 if ( target.data( "ui-tooltip-title" ) ) { | |
15969 target.attr( "title", target.data( "ui-tooltip-title" ) ); | |
15970 } | |
15971 | |
15972 removeDescribedBy( target ); | |
15973 | |
15974 tooltip.stop( true ); | |
15975 this._hide( tooltip, this.options.hide, function() { | |
15976 that._removeTooltip( $( this ) ); | |
15977 }); | |
15978 | |
15979 target.removeData( "ui-tooltip-open" ); | |
15980 this._off( target, "mouseleave focusout keyup" ); | |
15981 // Remove 'remove' binding only on delegated targets | |
15982 if ( target[0] !== this.element[0] ) { | |
15983 this._off( target, "remove" ); | |
15984 } | |
15985 this._off( this.document, "mousemove" ); | |
15986 | |
15987 if ( event && event.type === "mouseleave" ) { | |
15988 $.each( this.parents, function( id, parent ) { | |
15989 $( parent.element ).attr( "title", parent.title ); | |
15990 delete that.parents[ id ]; | |
15991 }); | |
15992 } | |
15993 | |
15994 this.closing = true; | |
15995 this._trigger( "close", event, { tooltip: tooltip } ); | |
15996 this.closing = false; | |
15997 }, | |
15998 | |
15999 _tooltip: function( element ) { | |
16000 var id = "ui-tooltip-" + increments++, | |
16001 tooltip = $( "<div>" ) | |
16002 .attr({ | |
16003 id: id, | |
16004 role: "tooltip" | |
16005 }) | |
16006 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + | |
16007 ( this.options.tooltipClass || "" ) ); | |
16008 $( "<div>" ) | |
16009 .addClass( "ui-tooltip-content" ) | |
16010 .appendTo( tooltip ); | |
16011 tooltip.appendTo( this.document[0].body ); | |
16012 this.tooltips[ id ] = element; | |
16013 return tooltip; | |
16014 }, | |
16015 | |
16016 _find: function( target ) { | |
16017 var id = target.data( "ui-tooltip-id" ); | |
16018 return id ? $( "#" + id ) : $(); | |
16019 }, | |
16020 | |
16021 _removeTooltip: function( tooltip ) { | |
16022 tooltip.remove(); | |
16023 delete this.tooltips[ tooltip.attr( "id" ) ]; | |
16024 }, | |
16025 | |
16026 _destroy: function() { | |
16027 var that = this; | |
16028 | |
16029 // close open tooltips | |
16030 $.each( this.tooltips, function( id, element ) { | |
16031 // Delegate to close method to handle common cleanup | |
16032 var event = $.Event( "blur" ); | |
16033 event.target = event.currentTarget = element[0]; | |
16034 that.close( event, true ); | |
16035 | |
16036 // Remove immediately; destroying an open tooltip doesn't use the | |
16037 // hide animation | |
16038 $( "#" + id ).remove(); | |
16039 | |
16040 // Restore the title | |
16041 if ( element.data( "ui-tooltip-title" ) ) { | |
16042 element.attr( "title", element.data( "ui-tooltip-title" ) ); | |
16043 element.removeData( "ui-tooltip-title" ); | |
16044 } | |
16045 }); | |
16046 } | |
16047 }); | |
16048 | |
16049 }( jQuery ) ); | |
16050 (function($, undefined) { | |
16051 | |
16052 var dataSpace = "ui-effects-"; | |
16053 | |
16054 $.effects = { | |
16055 effect: {} | |
16056 }; | |
16057 | |
16058 /*! | |
16059 * jQuery Color Animations v2.1.2 | |
16060 * https://github.com/jquery/jquery-color | |
16061 * | |
16062 * Copyright 2013 jQuery Foundation and other contributors | |
16063 * Released under the MIT license. | |
16064 * http://jquery.org/license | |
16065 * | |
16066 * Date: Wed Jan 16 08:47:09 2013 -0600 | |
16067 */ | |
16068 (function( jQuery, undefined ) { | |
16069 | |
16070 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", | |
16071 | |
16072 // plusequals test for += 100 -= 100 | |
16073 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, | |
16074 // a set of RE's that can match strings and generate color tuples. | |
16075 stringParsers = [{ | |
16076 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, | |
16077 parse: function( execResult ) { | |
16078 return [ | |
16079 execResult[ 1 ], | |
16080 execResult[ 2 ], | |
16081 execResult[ 3 ], | |
16082 execResult[ 4 ] | |
16083 ]; | |
16084 } | |
16085 }, { | |
16086 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, | |
16087 parse: function( execResult ) { | |
16088 return [ | |
16089 execResult[ 1 ] * 2.55, | |
16090 execResult[ 2 ] * 2.55, | |
16091 execResult[ 3 ] * 2.55, | |
16092 execResult[ 4 ] | |
16093 ]; | |
16094 } | |
16095 }, { | |
16096 // this regex ignores A-F because it's compared against an already lowercased string | |
16097 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, | |
16098 parse: function( execResult ) { | |
16099 return [ | |
16100 parseInt( execResult[ 1 ], 16 ), | |
16101 parseInt( execResult[ 2 ], 16 ), | |
16102 parseInt( execResult[ 3 ], 16 ) | |
16103 ]; | |
16104 } | |
16105 }, { | |
16106 // this regex ignores A-F because it's compared against an already lowercased string | |
16107 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, | |
16108 parse: function( execResult ) { | |
16109 return [ | |
16110 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), | |
16111 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), | |
16112 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) | |
16113 ]; | |
16114 } | |
16115 }, { | |
16116 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, | |
16117 space: "hsla", | |
16118 parse: function( execResult ) { | |
16119 return [ | |
16120 execResult[ 1 ], | |
16121 execResult[ 2 ] / 100, | |
16122 execResult[ 3 ] / 100, | |
16123 execResult[ 4 ] | |
16124 ]; | |
16125 } | |
16126 }], | |
16127 | |
16128 // jQuery.Color( ) | |
16129 color = jQuery.Color = function( color, green, blue, alpha ) { | |
16130 return new jQuery.Color.fn.parse( color, green, blue, alpha ); | |
16131 }, | |
16132 spaces = { | |
16133 rgba: { | |
16134 props: { | |
16135 red: { | |
16136 idx: 0, | |
16137 type: "byte" | |
16138 }, | |
16139 green: { | |
16140 idx: 1, | |
16141 type: "byte" | |
16142 }, | |
16143 blue: { | |
16144 idx: 2, | |
16145 type: "byte" | |
16146 } | |
16147 } | |
16148 }, | |
16149 | |
16150 hsla: { | |
16151 props: { | |
16152 hue: { | |
16153 idx: 0, | |
16154 type: "degrees" | |
16155 }, | |
16156 saturation: { | |
16157 idx: 1, | |
16158 type: "percent" | |
16159 }, | |
16160 lightness: { | |
16161 idx: 2, | |
16162 type: "percent" | |
16163 } | |
16164 } | |
16165 } | |
16166 }, | |
16167 propTypes = { | |
16168 "byte": { | |
16169 floor: true, | |
16170 max: 255 | |
16171 }, | |
16172 "percent": { | |
16173 max: 1 | |
16174 }, | |
16175 "degrees": { | |
16176 mod: 360, | |
16177 floor: true | |
16178 } | |
16179 }, | |
16180 support = color.support = {}, | |
16181 | |
16182 // element for support tests | |
16183 supportElem = jQuery( "<p>" )[ 0 ], | |
16184 | |
16185 // colors = jQuery.Color.names | |
16186 colors, | |
16187 | |
16188 // local aliases of functions called often | |
16189 each = jQuery.each; | |
16190 | |
16191 // determine rgba support immediately | |
16192 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; | |
16193 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; | |
16194 | |
16195 // define cache name and alpha properties | |
16196 // for rgba and hsla spaces | |
16197 each( spaces, function( spaceName, space ) { | |
16198 space.cache = "_" + spaceName; | |
16199 space.props.alpha = { | |
16200 idx: 3, | |
16201 type: "percent", | |
16202 def: 1 | |
16203 }; | |
16204 }); | |
16205 | |
16206 function clamp( value, prop, allowEmpty ) { | |
16207 var type = propTypes[ prop.type ] || {}; | |
16208 | |
16209 if ( value == null ) { | |
16210 return (allowEmpty || !prop.def) ? null : prop.def; | |
16211 } | |
16212 | |
16213 // ~~ is an short way of doing floor for positive numbers | |
16214 value = type.floor ? ~~value : parseFloat( value ); | |
16215 | |
16216 // IE will pass in empty strings as value for alpha, | |
16217 // which will hit this case | |
16218 if ( isNaN( value ) ) { | |
16219 return prop.def; | |
16220 } | |
16221 | |
16222 if ( type.mod ) { | |
16223 // we add mod before modding to make sure that negatives values | |
16224 // get converted properly: -10 -> 350 | |
16225 return (value + type.mod) % type.mod; | |
16226 } | |
16227 | |
16228 // for now all property types without mod have min and max | |
16229 return 0 > value ? 0 : type.max < value ? type.max : value; | |
16230 } | |
16231 | |
16232 function stringParse( string ) { | |
16233 var inst = color(), | |
16234 rgba = inst._rgba = []; | |
16235 | |
16236 string = string.toLowerCase(); | |
16237 | |
16238 each( stringParsers, function( i, parser ) { | |
16239 var parsed, | |
16240 match = parser.re.exec( string ), | |
16241 values = match && parser.parse( match ), | |
16242 spaceName = parser.space || "rgba"; | |
16243 | |
16244 if ( values ) { | |
16245 parsed = inst[ spaceName ]( values ); | |
16246 | |
16247 // if this was an rgba parse the assignment might happen twice | |
16248 // oh well.... | |
16249 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; | |
16250 rgba = inst._rgba = parsed._rgba; | |
16251 | |
16252 // exit each( stringParsers ) here because we matched | |
16253 return false; | |
16254 } | |
16255 }); | |
16256 | |
16257 // Found a stringParser that handled it | |
16258 if ( rgba.length ) { | |
16259 | |
16260 // if this came from a parsed string, force "transparent" when alpha is 0 | |
16261 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) | |
16262 if ( rgba.join() === "0,0,0,0" ) { | |
16263 jQuery.extend( rgba, colors.transparent ); | |
16264 } | |
16265 return inst; | |
16266 } | |
16267 | |
16268 // named colors | |
16269 return colors[ string ]; | |
16270 } | |
16271 | |
16272 color.fn = jQuery.extend( color.prototype, { | |
16273 parse: function( red, green, blue, alpha ) { | |
16274 if ( red === undefined ) { | |
16275 this._rgba = [ null, null, null, null ]; | |
16276 return this; | |
16277 } | |
16278 if ( red.jquery || red.nodeType ) { | |
16279 red = jQuery( red ).css( green ); | |
16280 green = undefined; | |
16281 } | |
16282 | |
16283 var inst = this, | |
16284 type = jQuery.type( red ), | |
16285 rgba = this._rgba = []; | |
16286 | |
16287 // more than 1 argument specified - assume ( red, green, blue, alpha ) | |
16288 if ( green !== undefined ) { | |
16289 red = [ red, green, blue, alpha ]; | |
16290 type = "array"; | |
16291 } | |
16292 | |
16293 if ( type === "string" ) { | |
16294 return this.parse( stringParse( red ) || colors._default ); | |
16295 } | |
16296 | |
16297 if ( type === "array" ) { | |
16298 each( spaces.rgba.props, function( key, prop ) { | |
16299 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); | |
16300 }); | |
16301 return this; | |
16302 } | |
16303 | |
16304 if ( type === "object" ) { | |
16305 if ( red instanceof color ) { | |
16306 each( spaces, function( spaceName, space ) { | |
16307 if ( red[ space.cache ] ) { | |
16308 inst[ space.cache ] = red[ space.cache ].slice(); | |
16309 } | |
16310 }); | |
16311 } else { | |
16312 each( spaces, function( spaceName, space ) { | |
16313 var cache = space.cache; | |
16314 each( space.props, function( key, prop ) { | |
16315 | |
16316 // if the cache doesn't exist, and we know how to convert | |
16317 if ( !inst[ cache ] && space.to ) { | |
16318 | |
16319 // if the value was null, we don't need to copy it | |
16320 // if the key was alpha, we don't need to copy it either | |
16321 if ( key === "alpha" || red[ key ] == null ) { | |
16322 return; | |
16323 } | |
16324 inst[ cache ] = space.to( inst._rgba ); | |
16325 } | |
16326 | |
16327 // this is the only case where we allow nulls for ALL properties. | |
16328 // call clamp with alwaysAllowEmpty | |
16329 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); | |
16330 }); | |
16331 | |
16332 // everything defined but alpha? | |
16333 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { | |
16334 // use the default of 1 | |
16335 inst[ cache ][ 3 ] = 1; | |
16336 if ( space.from ) { | |
16337 inst._rgba = space.from( inst[ cache ] ); | |
16338 } | |
16339 } | |
16340 }); | |
16341 } | |
16342 return this; | |
16343 } | |
16344 }, | |
16345 is: function( compare ) { | |
16346 var is = color( compare ), | |
16347 same = true, | |
16348 inst = this; | |
16349 | |
16350 each( spaces, function( _, space ) { | |
16351 var localCache, | |
16352 isCache = is[ space.cache ]; | |
16353 if (isCache) { | |
16354 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; | |
16355 each( space.props, function( _, prop ) { | |
16356 if ( isCache[ prop.idx ] != null ) { | |
16357 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); | |
16358 return same; | |
16359 } | |
16360 }); | |
16361 } | |
16362 return same; | |
16363 }); | |
16364 return same; | |
16365 }, | |
16366 _space: function() { | |
16367 var used = [], | |
16368 inst = this; | |
16369 each( spaces, function( spaceName, space ) { | |
16370 if ( inst[ space.cache ] ) { | |
16371 used.push( spaceName ); | |
16372 } | |
16373 }); | |
16374 return used.pop(); | |
16375 }, | |
16376 transition: function( other, distance ) { | |
16377 var end = color( other ), | |
16378 spaceName = end._space(), | |
16379 space = spaces[ spaceName ], | |
16380 startColor = this.alpha() === 0 ? color( "transparent" ) : this, | |
16381 start = startColor[ space.cache ] || space.to( startColor._rgba ), | |
16382 result = start.slice(); | |
16383 | |
16384 end = end[ space.cache ]; | |
16385 each( space.props, function( key, prop ) { | |
16386 var index = prop.idx, | |
16387 startValue = start[ index ], | |
16388 endValue = end[ index ], | |
16389 type = propTypes[ prop.type ] || {}; | |
16390 | |
16391 // if null, don't override start value | |
16392 if ( endValue === null ) { | |
16393 return; | |
16394 } | |
16395 // if null - use end | |
16396 if ( startValue === null ) { | |
16397 result[ index ] = endValue; | |
16398 } else { | |
16399 if ( type.mod ) { | |
16400 if ( endValue - startValue > type.mod / 2 ) { | |
16401 startValue += type.mod; | |
16402 } else if ( startValue - endValue > type.mod / 2 ) { | |
16403 startValue -= type.mod; | |
16404 } | |
16405 } | |
16406 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); | |
16407 } | |
16408 }); | |
16409 return this[ spaceName ]( result ); | |
16410 }, | |
16411 blend: function( opaque ) { | |
16412 // if we are already opaque - return ourself | |
16413 if ( this._rgba[ 3 ] === 1 ) { | |
16414 return this; | |
16415 } | |
16416 | |
16417 var rgb = this._rgba.slice(), | |
16418 a = rgb.pop(), | |
16419 blend = color( opaque )._rgba; | |
16420 | |
16421 return color( jQuery.map( rgb, function( v, i ) { | |
16422 return ( 1 - a ) * blend[ i ] + a * v; | |
16423 })); | |
16424 }, | |
16425 toRgbaString: function() { | |
16426 var prefix = "rgba(", | |
16427 rgba = jQuery.map( this._rgba, function( v, i ) { | |
16428 return v == null ? ( i > 2 ? 1 : 0 ) : v; | |
16429 }); | |
16430 | |
16431 if ( rgba[ 3 ] === 1 ) { | |
16432 rgba.pop(); | |
16433 prefix = "rgb("; | |
16434 } | |
16435 | |
16436 return prefix + rgba.join() + ")"; | |
16437 }, | |
16438 toHslaString: function() { | |
16439 var prefix = "hsla(", | |
16440 hsla = jQuery.map( this.hsla(), function( v, i ) { | |
16441 if ( v == null ) { | |
16442 v = i > 2 ? 1 : 0; | |
16443 } | |
16444 | |
16445 // catch 1 and 2 | |
16446 if ( i && i < 3 ) { | |
16447 v = Math.round( v * 100 ) + "%"; | |
16448 } | |
16449 return v; | |
16450 }); | |
16451 | |
16452 if ( hsla[ 3 ] === 1 ) { | |
16453 hsla.pop(); | |
16454 prefix = "hsl("; | |
16455 } | |
16456 return prefix + hsla.join() + ")"; | |
16457 }, | |
16458 toHexString: function( includeAlpha ) { | |
16459 var rgba = this._rgba.slice(), | |
16460 alpha = rgba.pop(); | |
16461 | |
16462 if ( includeAlpha ) { | |
16463 rgba.push( ~~( alpha * 255 ) ); | |
16464 } | |
16465 | |
16466 return "#" + jQuery.map( rgba, function( v ) { | |
16467 | |
16468 // default to 0 when nulls exist | |
16469 v = ( v || 0 ).toString( 16 ); | |
16470 return v.length === 1 ? "0" + v : v; | |
16471 }).join(""); | |
16472 }, | |
16473 toString: function() { | |
16474 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); | |
16475 } | |
16476 }); | |
16477 color.fn.parse.prototype = color.fn; | |
16478 | |
16479 // hsla conversions adapted from: | |
16480 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 | |
16481 | |
16482 function hue2rgb( p, q, h ) { | |
16483 h = ( h + 1 ) % 1; | |
16484 if ( h * 6 < 1 ) { | |
16485 return p + (q - p) * h * 6; | |
16486 } | |
16487 if ( h * 2 < 1) { | |
16488 return q; | |
16489 } | |
16490 if ( h * 3 < 2 ) { | |
16491 return p + (q - p) * ((2/3) - h) * 6; | |
16492 } | |
16493 return p; | |
16494 } | |
16495 | |
16496 spaces.hsla.to = function ( rgba ) { | |
16497 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { | |
16498 return [ null, null, null, rgba[ 3 ] ]; | |
16499 } | |
16500 var r = rgba[ 0 ] / 255, | |
16501 g = rgba[ 1 ] / 255, | |
16502 b = rgba[ 2 ] / 255, | |
16503 a = rgba[ 3 ], | |
16504 max = Math.max( r, g, b ), | |
16505 min = Math.min( r, g, b ), | |
16506 diff = max - min, | |
16507 add = max + min, | |
16508 l = add * 0.5, | |
16509 h, s; | |
16510 | |
16511 if ( min === max ) { | |
16512 h = 0; | |
16513 } else if ( r === max ) { | |
16514 h = ( 60 * ( g - b ) / diff ) + 360; | |
16515 } else if ( g === max ) { | |
16516 h = ( 60 * ( b - r ) / diff ) + 120; | |
16517 } else { | |
16518 h = ( 60 * ( r - g ) / diff ) + 240; | |
16519 } | |
16520 | |
16521 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% | |
16522 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) | |
16523 if ( diff === 0 ) { | |
16524 s = 0; | |
16525 } else if ( l <= 0.5 ) { | |
16526 s = diff / add; | |
16527 } else { | |
16528 s = diff / ( 2 - add ); | |
16529 } | |
16530 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; | |
16531 }; | |
16532 | |
16533 spaces.hsla.from = function ( hsla ) { | |
16534 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { | |
16535 return [ null, null, null, hsla[ 3 ] ]; | |
16536 } | |
16537 var h = hsla[ 0 ] / 360, | |
16538 s = hsla[ 1 ], | |
16539 l = hsla[ 2 ], | |
16540 a = hsla[ 3 ], | |
16541 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, | |
16542 p = 2 * l - q; | |
16543 | |
16544 return [ | |
16545 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), | |
16546 Math.round( hue2rgb( p, q, h ) * 255 ), | |
16547 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), | |
16548 a | |
16549 ]; | |
16550 }; | |
16551 | |
16552 | |
16553 each( spaces, function( spaceName, space ) { | |
16554 var props = space.props, | |
16555 cache = space.cache, | |
16556 to = space.to, | |
16557 from = space.from; | |
16558 | |
16559 // makes rgba() and hsla() | |
16560 color.fn[ spaceName ] = function( value ) { | |
16561 | |
16562 // generate a cache for this space if it doesn't exist | |
16563 if ( to && !this[ cache ] ) { | |
16564 this[ cache ] = to( this._rgba ); | |
16565 } | |
16566 if ( value === undefined ) { | |
16567 return this[ cache ].slice(); | |
16568 } | |
16569 | |
16570 var ret, | |
16571 type = jQuery.type( value ), | |
16572 arr = ( type === "array" || type === "object" ) ? value : arguments, | |
16573 local = this[ cache ].slice(); | |
16574 | |
16575 each( props, function( key, prop ) { | |
16576 var val = arr[ type === "object" ? key : prop.idx ]; | |
16577 if ( val == null ) { | |
16578 val = local[ prop.idx ]; | |
16579 } | |
16580 local[ prop.idx ] = clamp( val, prop ); | |
16581 }); | |
16582 | |
16583 if ( from ) { | |
16584 ret = color( from( local ) ); | |
16585 ret[ cache ] = local; | |
16586 return ret; | |
16587 } else { | |
16588 return color( local ); | |
16589 } | |
16590 }; | |
16591 | |
16592 // makes red() green() blue() alpha() hue() saturation() lightness() | |
16593 each( props, function( key, prop ) { | |
16594 // alpha is included in more than one space | |
16595 if ( color.fn[ key ] ) { | |
16596 return; | |
16597 } | |
16598 color.fn[ key ] = function( value ) { | |
16599 var vtype = jQuery.type( value ), | |
16600 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), | |
16601 local = this[ fn ](), | |
16602 cur = local[ prop.idx ], | |
16603 match; | |
16604 | |
16605 if ( vtype === "undefined" ) { | |
16606 return cur; | |
16607 } | |
16608 | |
16609 if ( vtype === "function" ) { | |
16610 value = value.call( this, cur ); | |
16611 vtype = jQuery.type( value ); | |
16612 } | |
16613 if ( value == null && prop.empty ) { | |
16614 return this; | |
16615 } | |
16616 if ( vtype === "string" ) { | |
16617 match = rplusequals.exec( value ); | |
16618 if ( match ) { | |
16619 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); | |
16620 } | |
16621 } | |
16622 local[ prop.idx ] = value; | |
16623 return this[ fn ]( local ); | |
16624 }; | |
16625 }); | |
16626 }); | |
16627 | |
16628 // add cssHook and .fx.step function for each named hook. | |
16629 // accept a space separated string of properties | |
16630 color.hook = function( hook ) { | |
16631 var hooks = hook.split( " " ); | |
16632 each( hooks, function( i, hook ) { | |
16633 jQuery.cssHooks[ hook ] = { | |
16634 set: function( elem, value ) { | |
16635 var parsed, curElem, | |
16636 backgroundColor = ""; | |
16637 | |
16638 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { | |
16639 value = color( parsed || value ); | |
16640 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { | |
16641 curElem = hook === "backgroundColor" ? elem.parentNode : elem; | |
16642 while ( | |
16643 (backgroundColor === "" || backgroundColor === "transparent") && | |
16644 curElem && curElem.style | |
16645 ) { | |
16646 try { | |
16647 backgroundColor = jQuery.css( curElem, "backgroundColor" ); | |
16648 curElem = curElem.parentNode; | |
16649 } catch ( e ) { | |
16650 } | |
16651 } | |
16652 | |
16653 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? | |
16654 backgroundColor : | |
16655 "_default" ); | |
16656 } | |
16657 | |
16658 value = value.toRgbaString(); | |
16659 } | |
16660 try { | |
16661 elem.style[ hook ] = value; | |
16662 } catch( e ) { | |
16663 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' | |
16664 } | |
16665 } | |
16666 }; | |
16667 jQuery.fx.step[ hook ] = function( fx ) { | |
16668 if ( !fx.colorInit ) { | |
16669 fx.start = color( fx.elem, hook ); | |
16670 fx.end = color( fx.end ); | |
16671 fx.colorInit = true; | |
16672 } | |
16673 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); | |
16674 }; | |
16675 }); | |
16676 | |
16677 }; | |
16678 | |
16679 color.hook( stepHooks ); | |
16680 | |
16681 jQuery.cssHooks.borderColor = { | |
16682 expand: function( value ) { | |
16683 var expanded = {}; | |
16684 | |
16685 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { | |
16686 expanded[ "border" + part + "Color" ] = value; | |
16687 }); | |
16688 return expanded; | |
16689 } | |
16690 }; | |
16691 | |
16692 // Basic color names only. | |
16693 // Usage of any of the other color names requires adding yourself or including | |
16694 // jquery.color.svg-names.js. | |
16695 colors = jQuery.Color.names = { | |
16696 // 4.1. Basic color keywords | |
16697 aqua: "#00ffff", | |
16698 black: "#000000", | |
16699 blue: "#0000ff", | |
16700 fuchsia: "#ff00ff", | |
16701 gray: "#808080", | |
16702 green: "#008000", | |
16703 lime: "#00ff00", | |
16704 maroon: "#800000", | |
16705 navy: "#000080", | |
16706 olive: "#808000", | |
16707 purple: "#800080", | |
16708 red: "#ff0000", | |
16709 silver: "#c0c0c0", | |
16710 teal: "#008080", | |
16711 white: "#ffffff", | |
16712 yellow: "#ffff00", | |
16713 | |
16714 // 4.2.3. "transparent" color keyword | |
16715 transparent: [ null, null, null, 0 ], | |
16716 | |
16717 _default: "#ffffff" | |
16718 }; | |
16719 | |
16720 })( jQuery ); | |
16721 | |
16722 | |
16723 /******************************************************************************/ | |
16724 /****************************** CLASS ANIMATIONS ******************************/ | |
16725 /******************************************************************************/ | |
16726 (function() { | |
16727 | |
16728 var classAnimationActions = [ "add", "remove", "toggle" ], | |
16729 shorthandStyles = { | |
16730 border: 1, | |
16731 borderBottom: 1, | |
16732 borderColor: 1, | |
16733 borderLeft: 1, | |
16734 borderRight: 1, | |
16735 borderTop: 1, | |
16736 borderWidth: 1, | |
16737 margin: 1, | |
16738 padding: 1 | |
16739 }; | |
16740 | |
16741 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { | |
16742 $.fx.step[ prop ] = function( fx ) { | |
16743 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { | |
16744 jQuery.style( fx.elem, prop, fx.end ); | |
16745 fx.setAttr = true; | |
16746 } | |
16747 }; | |
16748 }); | |
16749 | |
16750 function getElementStyles( elem ) { | |
16751 var key, len, | |
16752 style = elem.ownerDocument.defaultView ? | |
16753 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : | |
16754 elem.currentStyle, | |
16755 styles = {}; | |
16756 | |
16757 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { | |
16758 len = style.length; | |
16759 while ( len-- ) { | |
16760 key = style[ len ]; | |
16761 if ( typeof style[ key ] === "string" ) { | |
16762 styles[ $.camelCase( key ) ] = style[ key ]; | |
16763 } | |
16764 } | |
16765 // support: Opera, IE <9 | |
16766 } else { | |
16767 for ( key in style ) { | |
16768 if ( typeof style[ key ] === "string" ) { | |
16769 styles[ key ] = style[ key ]; | |
16770 } | |
16771 } | |
16772 } | |
16773 | |
16774 return styles; | |
16775 } | |
16776 | |
16777 | |
16778 function styleDifference( oldStyle, newStyle ) { | |
16779 var diff = {}, | |
16780 name, value; | |
16781 | |
16782 for ( name in newStyle ) { | |
16783 value = newStyle[ name ]; | |
16784 if ( oldStyle[ name ] !== value ) { | |
16785 if ( !shorthandStyles[ name ] ) { | |
16786 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { | |
16787 diff[ name ] = value; | |
16788 } | |
16789 } | |
16790 } | |
16791 } | |
16792 | |
16793 return diff; | |
16794 } | |
16795 | |
16796 // support: jQuery <1.8 | |
16797 if ( !$.fn.addBack ) { | |
16798 $.fn.addBack = function( selector ) { | |
16799 return this.add( selector == null ? | |
16800 this.prevObject : this.prevObject.filter( selector ) | |
16801 ); | |
16802 }; | |
16803 } | |
16804 | |
16805 $.effects.animateClass = function( value, duration, easing, callback ) { | |
16806 var o = $.speed( duration, easing, callback ); | |
16807 | |
16808 return this.queue( function() { | |
16809 var animated = $( this ), | |
16810 baseClass = animated.attr( "class" ) || "", | |
16811 applyClassChange, | |
16812 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; | |
16813 | |
16814 // map the animated objects to store the original styles. | |
16815 allAnimations = allAnimations.map(function() { | |
16816 var el = $( this ); | |
16817 return { | |
16818 el: el, | |
16819 start: getElementStyles( this ) | |
16820 }; | |
16821 }); | |
16822 | |
16823 // apply class change | |
16824 applyClassChange = function() { | |
16825 $.each( classAnimationActions, function(i, action) { | |
16826 if ( value[ action ] ) { | |
16827 animated[ action + "Class" ]( value[ action ] ); | |
16828 } | |
16829 }); | |
16830 }; | |
16831 applyClassChange(); | |
16832 | |
16833 // map all animated objects again - calculate new styles and diff | |
16834 allAnimations = allAnimations.map(function() { | |
16835 this.end = getElementStyles( this.el[ 0 ] ); | |
16836 this.diff = styleDifference( this.start, this.end ); | |
16837 return this; | |
16838 }); | |
16839 | |
16840 // apply original class | |
16841 animated.attr( "class", baseClass ); | |
16842 | |
16843 // map all animated objects again - this time collecting a promise | |
16844 allAnimations = allAnimations.map(function() { | |
16845 var styleInfo = this, | |
16846 dfd = $.Deferred(), | |
16847 opts = $.extend({}, o, { | |
16848 queue: false, | |
16849 complete: function() { | |
16850 dfd.resolve( styleInfo ); | |
16851 } | |
16852 }); | |
16853 | |
16854 this.el.animate( this.diff, opts ); | |
16855 return dfd.promise(); | |
16856 }); | |
16857 | |
16858 // once all animations have completed: | |
16859 $.when.apply( $, allAnimations.get() ).done(function() { | |
16860 | |
16861 // set the final class | |
16862 applyClassChange(); | |
16863 | |
16864 // for each animated element, | |
16865 // clear all css properties that were animated | |
16866 $.each( arguments, function() { | |
16867 var el = this.el; | |
16868 $.each( this.diff, function(key) { | |
16869 el.css( key, "" ); | |
16870 }); | |
16871 }); | |
16872 | |
16873 // this is guarnteed to be there if you use jQuery.speed() | |
16874 // it also handles dequeuing the next anim... | |
16875 o.complete.call( animated[ 0 ] ); | |
16876 }); | |
16877 }); | |
16878 }; | |
16879 | |
16880 $.fn.extend({ | |
16881 addClass: (function( orig ) { | |
16882 return function( classNames, speed, easing, callback ) { | |
16883 return speed ? | |
16884 $.effects.animateClass.call( this, | |
16885 { add: classNames }, speed, easing, callback ) : | |
16886 orig.apply( this, arguments ); | |
16887 }; | |
16888 })( $.fn.addClass ), | |
16889 | |
16890 removeClass: (function( orig ) { | |
16891 return function( classNames, speed, easing, callback ) { | |
16892 return arguments.length > 1 ? | |
16893 $.effects.animateClass.call( this, | |
16894 { remove: classNames }, speed, easing, callback ) : | |
16895 orig.apply( this, arguments ); | |
16896 }; | |
16897 })( $.fn.removeClass ), | |
16898 | |
16899 toggleClass: (function( orig ) { | |
16900 return function( classNames, force, speed, easing, callback ) { | |
16901 if ( typeof force === "boolean" || force === undefined ) { | |
16902 if ( !speed ) { | |
16903 // without speed parameter | |
16904 return orig.apply( this, arguments ); | |
16905 } else { | |
16906 return $.effects.animateClass.call( this, | |
16907 (force ? { add: classNames } : { remove: classNames }), | |
16908 speed, easing, callback ); | |
16909 } | |
16910 } else { | |
16911 // without force parameter | |
16912 return $.effects.animateClass.call( this, | |
16913 { toggle: classNames }, force, speed, easing ); | |
16914 } | |
16915 }; | |
16916 })( $.fn.toggleClass ), | |
16917 | |
16918 switchClass: function( remove, add, speed, easing, callback) { | |
16919 return $.effects.animateClass.call( this, { | |
16920 add: add, | |
16921 remove: remove | |
16922 }, speed, easing, callback ); | |
16923 } | |
16924 }); | |
16925 | |
16926 })(); | |
16927 | |
16928 /******************************************************************************/ | |
16929 /*********************************** EFFECTS **********************************/ | |
16930 /******************************************************************************/ | |
16931 | |
16932 (function() { | |
16933 | |
16934 $.extend( $.effects, { | |
16935 version: "1.10.3", | |
16936 | |
16937 // Saves a set of properties in a data storage | |
16938 save: function( element, set ) { | |
16939 for( var i=0; i < set.length; i++ ) { | |
16940 if ( set[ i ] !== null ) { | |
16941 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); | |
16942 } | |
16943 } | |
16944 }, | |
16945 | |
16946 // Restores a set of previously saved properties from a data storage | |
16947 restore: function( element, set ) { | |
16948 var val, i; | |
16949 for( i=0; i < set.length; i++ ) { | |
16950 if ( set[ i ] !== null ) { | |
16951 val = element.data( dataSpace + set[ i ] ); | |
16952 // support: jQuery 1.6.2 | |
16953 // http://bugs.jquery.com/ticket/9917 | |
16954 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. | |
16955 // We can't differentiate between "" and 0 here, so we just assume | |
16956 // empty string since it's likely to be a more common value... | |
16957 if ( val === undefined ) { | |
16958 val = ""; | |
16959 } | |
16960 element.css( set[ i ], val ); | |
16961 } | |
16962 } | |
16963 }, | |
16964 | |
16965 setMode: function( el, mode ) { | |
16966 if (mode === "toggle") { | |
16967 mode = el.is( ":hidden" ) ? "show" : "hide"; | |
16968 } | |
16969 return mode; | |
16970 }, | |
16971 | |
16972 // Translates a [top,left] array into a baseline value | |
16973 // this should be a little more flexible in the future to handle a string & hash | |
16974 getBaseline: function( origin, original ) { | |
16975 var y, x; | |
16976 switch ( origin[ 0 ] ) { | |
16977 case "top": y = 0; break; | |
16978 case "middle": y = 0.5; break; | |
16979 case "bottom": y = 1; break; | |
16980 default: y = origin[ 0 ] / original.height; | |
16981 } | |
16982 switch ( origin[ 1 ] ) { | |
16983 case "left": x = 0; break; | |
16984 case "center": x = 0.5; break; | |
16985 case "right": x = 1; break; | |
16986 default: x = origin[ 1 ] / original.width; | |
16987 } | |
16988 return { | |
16989 x: x, | |
16990 y: y | |
16991 }; | |
16992 }, | |
16993 | |
16994 // Wraps the element around a wrapper that copies position properties | |
16995 createWrapper: function( element ) { | |
16996 | |
16997 // if the element is already wrapped, return it | |
16998 if ( element.parent().is( ".ui-effects-wrapper" )) { | |
16999 return element.parent(); | |
17000 } | |
17001 | |
17002 // wrap the element | |
17003 var props = { | |
17004 width: element.outerWidth(true), | |
17005 height: element.outerHeight(true), | |
17006 "float": element.css( "float" ) | |
17007 }, | |
17008 wrapper = $( "<div></div>" ) | |
17009 .addClass( "ui-effects-wrapper" ) | |
17010 .css({ | |
17011 fontSize: "100%", | |
17012 background: "transparent", | |
17013 border: "none", | |
17014 margin: 0, | |
17015 padding: 0 | |
17016 }), | |
17017 // Store the size in case width/height are defined in % - Fixes #5245 | |
17018 size = { | |
17019 width: element.width(), | |
17020 height: element.height() | |
17021 }, | |
17022 active = document.activeElement; | |
17023 | |
17024 // support: Firefox | |
17025 // Firefox incorrectly exposes anonymous content | |
17026 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 | |
17027 try { | |
17028 active.id; | |
17029 } catch( e ) { | |
17030 active = document.body; | |
17031 } | |
17032 | |
17033 element.wrap( wrapper ); | |
17034 | |
17035 // Fixes #7595 - Elements lose focus when wrapped. | |
17036 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { | |
17037 $( active ).focus(); | |
17038 } | |
17039 | |
17040 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element | |
17041 | |
17042 // transfer positioning properties to the wrapper | |
17043 if ( element.css( "position" ) === "static" ) { | |
17044 wrapper.css({ position: "relative" }); | |
17045 element.css({ position: "relative" }); | |
17046 } else { | |
17047 $.extend( props, { | |
17048 position: element.css( "position" ), | |
17049 zIndex: element.css( "z-index" ) | |
17050 }); | |
17051 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { | |
17052 props[ pos ] = element.css( pos ); | |
17053 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { | |
17054 props[ pos ] = "auto"; | |
17055 } | |
17056 }); | |
17057 element.css({ | |
17058 position: "relative", | |
17059 top: 0, | |
17060 left: 0, | |
17061 right: "auto", | |
17062 bottom: "auto" | |
17063 }); | |
17064 } | |
17065 element.css(size); | |
17066 | |
17067 return wrapper.css( props ).show(); | |
17068 }, | |
17069 | |
17070 removeWrapper: function( element ) { | |
17071 var active = document.activeElement; | |
17072 | |
17073 if ( element.parent().is( ".ui-effects-wrapper" ) ) { | |
17074 element.parent().replaceWith( element ); | |
17075 | |
17076 // Fixes #7595 - Elements lose focus when wrapped. | |
17077 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { | |
17078 $( active ).focus(); | |
17079 } | |
17080 } | |
17081 | |
17082 | |
17083 return element; | |
17084 }, | |
17085 | |
17086 setTransition: function( element, list, factor, value ) { | |
17087 value = value || {}; | |
17088 $.each( list, function( i, x ) { | |
17089 var unit = element.cssUnit( x ); | |
17090 if ( unit[ 0 ] > 0 ) { | |
17091 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; | |
17092 } | |
17093 }); | |
17094 return value; | |
17095 } | |
17096 }); | |
17097 | |
17098 // return an effect options object for the given parameters: | |
17099 function _normalizeArguments( effect, options, speed, callback ) { | |
17100 | |
17101 // allow passing all options as the first parameter | |
17102 if ( $.isPlainObject( effect ) ) { | |
17103 options = effect; | |
17104 effect = effect.effect; | |
17105 } | |
17106 | |
17107 // convert to an object | |
17108 effect = { effect: effect }; | |
17109 | |
17110 // catch (effect, null, ...) | |
17111 if ( options == null ) { | |
17112 options = {}; | |
17113 } | |
17114 | |
17115 // catch (effect, callback) | |
17116 if ( $.isFunction( options ) ) { | |
17117 callback = options; | |
17118 speed = null; | |
17119 options = {}; | |
17120 } | |
17121 | |
17122 // catch (effect, speed, ?) | |
17123 if ( typeof options === "number" || $.fx.speeds[ options ] ) { | |
17124 callback = speed; | |
17125 speed = options; | |
17126 options = {}; | |
17127 } | |
17128 | |
17129 // catch (effect, options, callback) | |
17130 if ( $.isFunction( speed ) ) { | |
17131 callback = speed; | |
17132 speed = null; | |
17133 } | |
17134 | |
17135 // add options to effect | |
17136 if ( options ) { | |
17137 $.extend( effect, options ); | |
17138 } | |
17139 | |
17140 speed = speed || options.duration; | |
17141 effect.duration = $.fx.off ? 0 : | |
17142 typeof speed === "number" ? speed : | |
17143 speed in $.fx.speeds ? $.fx.speeds[ speed ] : | |
17144 $.fx.speeds._default; | |
17145 | |
17146 effect.complete = callback || options.complete; | |
17147 | |
17148 return effect; | |
17149 } | |
17150 | |
17151 function standardAnimationOption( option ) { | |
17152 // Valid standard speeds (nothing, number, named speed) | |
17153 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { | |
17154 return true; | |
17155 } | |
17156 | |
17157 // Invalid strings - treat as "normal" speed | |
17158 if ( typeof option === "string" && !$.effects.effect[ option ] ) { | |
17159 return true; | |
17160 } | |
17161 | |
17162 // Complete callback | |
17163 if ( $.isFunction( option ) ) { | |
17164 return true; | |
17165 } | |
17166 | |
17167 // Options hash (but not naming an effect) | |
17168 if ( typeof option === "object" && !option.effect ) { | |
17169 return true; | |
17170 } | |
17171 | |
17172 // Didn't match any standard API | |
17173 return false; | |
17174 } | |
17175 | |
17176 $.fn.extend({ | |
17177 effect: function( /* effect, options, speed, callback */ ) { | |
17178 var args = _normalizeArguments.apply( this, arguments ), | |
17179 mode = args.mode, | |
17180 queue = args.queue, | |
17181 effectMethod = $.effects.effect[ args.effect ]; | |
17182 | |
17183 if ( $.fx.off || !effectMethod ) { | |
17184 // delegate to the original method (e.g., .show()) if possible | |
17185 if ( mode ) { | |
17186 return this[ mode ]( args.duration, args.complete ); | |
17187 } else { | |
17188 return this.each( function() { | |
17189 if ( args.complete ) { | |
17190 args.complete.call( this ); | |
17191 } | |
17192 }); | |
17193 } | |
17194 } | |
17195 | |
17196 function run( next ) { | |
17197 var elem = $( this ), | |
17198 complete = args.complete, | |
17199 mode = args.mode; | |
17200 | |
17201 function done() { | |
17202 if ( $.isFunction( complete ) ) { | |
17203 complete.call( elem[0] ); | |
17204 } | |
17205 if ( $.isFunction( next ) ) { | |
17206 next(); | |
17207 } | |
17208 } | |
17209 | |
17210 // If the element already has the correct final state, delegate to | |
17211 // the core methods so the internal tracking of "olddisplay" works. | |
17212 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { | |
17213 elem[ mode ](); | |
17214 done(); | |
17215 } else { | |
17216 effectMethod.call( elem[0], args, done ); | |
17217 } | |
17218 } | |
17219 | |
17220 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); | |
17221 }, | |
17222 | |
17223 show: (function( orig ) { | |
17224 return function( option ) { | |
17225 if ( standardAnimationOption( option ) ) { | |
17226 return orig.apply( this, arguments ); | |
17227 } else { | |
17228 var args = _normalizeArguments.apply( this, arguments ); | |
17229 args.mode = "show"; | |
17230 return this.effect.call( this, args ); | |
17231 } | |
17232 }; | |
17233 })( $.fn.show ), | |
17234 | |
17235 hide: (function( orig ) { | |
17236 return function( option ) { | |
17237 if ( standardAnimationOption( option ) ) { | |
17238 return orig.apply( this, arguments ); | |
17239 } else { | |
17240 var args = _normalizeArguments.apply( this, arguments ); | |
17241 args.mode = "hide"; | |
17242 return this.effect.call( this, args ); | |
17243 } | |
17244 }; | |
17245 })( $.fn.hide ), | |
17246 | |
17247 toggle: (function( orig ) { | |
17248 return function( option ) { | |
17249 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { | |
17250 return orig.apply( this, arguments ); | |
17251 } else { | |
17252 var args = _normalizeArguments.apply( this, arguments ); | |
17253 args.mode = "toggle"; | |
17254 return this.effect.call( this, args ); | |
17255 } | |
17256 }; | |
17257 })( $.fn.toggle ), | |
17258 | |
17259 // helper functions | |
17260 cssUnit: function(key) { | |
17261 var style = this.css( key ), | |
17262 val = []; | |
17263 | |
17264 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { | |
17265 if ( style.indexOf( unit ) > 0 ) { | |
17266 val = [ parseFloat( style ), unit ]; | |
17267 } | |
17268 }); | |
17269 return val; | |
17270 } | |
17271 }); | |
17272 | |
17273 })(); | |
17274 | |
17275 /******************************************************************************/ | |
17276 /*********************************** EASING ***********************************/ | |
17277 /******************************************************************************/ | |
17278 | |
17279 (function() { | |
17280 | |
17281 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing) | |
17282 | |
17283 var baseEasings = {}; | |
17284 | |
17285 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { | |
17286 baseEasings[ name ] = function( p ) { | |
17287 return Math.pow( p, i + 2 ); | |
17288 }; | |
17289 }); | |
17290 | |
17291 $.extend( baseEasings, { | |
17292 Sine: function ( p ) { | |
17293 return 1 - Math.cos( p * Math.PI / 2 ); | |
17294 }, | |
17295 Circ: function ( p ) { | |
17296 return 1 - Math.sqrt( 1 - p * p ); | |
17297 }, | |
17298 Elastic: function( p ) { | |
17299 return p === 0 || p === 1 ? p : | |
17300 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); | |
17301 }, | |
17302 Back: function( p ) { | |
17303 return p * p * ( 3 * p - 2 ); | |
17304 }, | |
17305 Bounce: function ( p ) { | |
17306 var pow2, | |
17307 bounce = 4; | |
17308 | |
17309 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} | |
17310 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); | |
17311 } | |
17312 }); | |
17313 | |
17314 $.each( baseEasings, function( name, easeIn ) { | |
17315 $.easing[ "easeIn" + name ] = easeIn; | |
17316 $.easing[ "easeOut" + name ] = function( p ) { | |
17317 return 1 - easeIn( 1 - p ); | |
17318 }; | |
17319 $.easing[ "easeInOut" + name ] = function( p ) { | |
17320 return p < 0.5 ? | |
17321 easeIn( p * 2 ) / 2 : | |
17322 1 - easeIn( p * -2 + 2 ) / 2; | |
17323 }; | |
17324 }); | |
17325 | |
17326 })(); | |
17327 | |
17328 })(jQuery); | |
17329 (function( $, undefined ) { | |
17330 | |
17331 var rvertical = /up|down|vertical/, | |
17332 rpositivemotion = /up|left|vertical|horizontal/; | |
17333 | |
17334 $.effects.effect.blind = function( o, done ) { | |
17335 // Create element | |
17336 var el = $( this ), | |
17337 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17338 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17339 direction = o.direction || "up", | |
17340 vertical = rvertical.test( direction ), | |
17341 ref = vertical ? "height" : "width", | |
17342 ref2 = vertical ? "top" : "left", | |
17343 motion = rpositivemotion.test( direction ), | |
17344 animation = {}, | |
17345 show = mode === "show", | |
17346 wrapper, distance, margin; | |
17347 | |
17348 // if already wrapped, the wrapper's properties are my property. #6245 | |
17349 if ( el.parent().is( ".ui-effects-wrapper" ) ) { | |
17350 $.effects.save( el.parent(), props ); | |
17351 } else { | |
17352 $.effects.save( el, props ); | |
17353 } | |
17354 el.show(); | |
17355 wrapper = $.effects.createWrapper( el ).css({ | |
17356 overflow: "hidden" | |
17357 }); | |
17358 | |
17359 distance = wrapper[ ref ](); | |
17360 margin = parseFloat( wrapper.css( ref2 ) ) || 0; | |
17361 | |
17362 animation[ ref ] = show ? distance : 0; | |
17363 if ( !motion ) { | |
17364 el | |
17365 .css( vertical ? "bottom" : "right", 0 ) | |
17366 .css( vertical ? "top" : "left", "auto" ) | |
17367 .css({ position: "absolute" }); | |
17368 | |
17369 animation[ ref2 ] = show ? margin : distance + margin; | |
17370 } | |
17371 | |
17372 // start at 0 if we are showing | |
17373 if ( show ) { | |
17374 wrapper.css( ref, 0 ); | |
17375 if ( ! motion ) { | |
17376 wrapper.css( ref2, margin + distance ); | |
17377 } | |
17378 } | |
17379 | |
17380 // Animate | |
17381 wrapper.animate( animation, { | |
17382 duration: o.duration, | |
17383 easing: o.easing, | |
17384 queue: false, | |
17385 complete: function() { | |
17386 if ( mode === "hide" ) { | |
17387 el.hide(); | |
17388 } | |
17389 $.effects.restore( el, props ); | |
17390 $.effects.removeWrapper( el ); | |
17391 done(); | |
17392 } | |
17393 }); | |
17394 | |
17395 }; | |
17396 | |
17397 })(jQuery); | |
17398 (function( $, undefined ) { | |
17399 | |
17400 $.effects.effect.bounce = function( o, done ) { | |
17401 var el = $( this ), | |
17402 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17403 | |
17404 // defaults: | |
17405 mode = $.effects.setMode( el, o.mode || "effect" ), | |
17406 hide = mode === "hide", | |
17407 show = mode === "show", | |
17408 direction = o.direction || "up", | |
17409 distance = o.distance, | |
17410 times = o.times || 5, | |
17411 | |
17412 // number of internal animations | |
17413 anims = times * 2 + ( show || hide ? 1 : 0 ), | |
17414 speed = o.duration / anims, | |
17415 easing = o.easing, | |
17416 | |
17417 // utility: | |
17418 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", | |
17419 motion = ( direction === "up" || direction === "left" ), | |
17420 i, | |
17421 upAnim, | |
17422 downAnim, | |
17423 | |
17424 // we will need to re-assemble the queue to stack our animations in place | |
17425 queue = el.queue(), | |
17426 queuelen = queue.length; | |
17427 | |
17428 // Avoid touching opacity to prevent clearType and PNG issues in IE | |
17429 if ( show || hide ) { | |
17430 props.push( "opacity" ); | |
17431 } | |
17432 | |
17433 $.effects.save( el, props ); | |
17434 el.show(); | |
17435 $.effects.createWrapper( el ); // Create Wrapper | |
17436 | |
17437 // default distance for the BIGGEST bounce is the outer Distance / 3 | |
17438 if ( !distance ) { | |
17439 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; | |
17440 } | |
17441 | |
17442 if ( show ) { | |
17443 downAnim = { opacity: 1 }; | |
17444 downAnim[ ref ] = 0; | |
17445 | |
17446 // if we are showing, force opacity 0 and set the initial position | |
17447 // then do the "first" animation | |
17448 el.css( "opacity", 0 ) | |
17449 .css( ref, motion ? -distance * 2 : distance * 2 ) | |
17450 .animate( downAnim, speed, easing ); | |
17451 } | |
17452 | |
17453 // start at the smallest distance if we are hiding | |
17454 if ( hide ) { | |
17455 distance = distance / Math.pow( 2, times - 1 ); | |
17456 } | |
17457 | |
17458 downAnim = {}; | |
17459 downAnim[ ref ] = 0; | |
17460 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here | |
17461 for ( i = 0; i < times; i++ ) { | |
17462 upAnim = {}; | |
17463 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; | |
17464 | |
17465 el.animate( upAnim, speed, easing ) | |
17466 .animate( downAnim, speed, easing ); | |
17467 | |
17468 distance = hide ? distance * 2 : distance / 2; | |
17469 } | |
17470 | |
17471 // Last Bounce when Hiding | |
17472 if ( hide ) { | |
17473 upAnim = { opacity: 0 }; | |
17474 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; | |
17475 | |
17476 el.animate( upAnim, speed, easing ); | |
17477 } | |
17478 | |
17479 el.queue(function() { | |
17480 if ( hide ) { | |
17481 el.hide(); | |
17482 } | |
17483 $.effects.restore( el, props ); | |
17484 $.effects.removeWrapper( el ); | |
17485 done(); | |
17486 }); | |
17487 | |
17488 // inject all the animations we just queued to be first in line (after "inprogress") | |
17489 if ( queuelen > 1) { | |
17490 queue.splice.apply( queue, | |
17491 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); | |
17492 } | |
17493 el.dequeue(); | |
17494 | |
17495 }; | |
17496 | |
17497 })(jQuery); | |
17498 (function( $, undefined ) { | |
17499 | |
17500 $.effects.effect.clip = function( o, done ) { | |
17501 // Create element | |
17502 var el = $( this ), | |
17503 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17504 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17505 show = mode === "show", | |
17506 direction = o.direction || "vertical", | |
17507 vert = direction === "vertical", | |
17508 size = vert ? "height" : "width", | |
17509 position = vert ? "top" : "left", | |
17510 animation = {}, | |
17511 wrapper, animate, distance; | |
17512 | |
17513 // Save & Show | |
17514 $.effects.save( el, props ); | |
17515 el.show(); | |
17516 | |
17517 // Create Wrapper | |
17518 wrapper = $.effects.createWrapper( el ).css({ | |
17519 overflow: "hidden" | |
17520 }); | |
17521 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; | |
17522 distance = animate[ size ](); | |
17523 | |
17524 // Shift | |
17525 if ( show ) { | |
17526 animate.css( size, 0 ); | |
17527 animate.css( position, distance / 2 ); | |
17528 } | |
17529 | |
17530 // Create Animation Object: | |
17531 animation[ size ] = show ? distance : 0; | |
17532 animation[ position ] = show ? 0 : distance / 2; | |
17533 | |
17534 // Animate | |
17535 animate.animate( animation, { | |
17536 queue: false, | |
17537 duration: o.duration, | |
17538 easing: o.easing, | |
17539 complete: function() { | |
17540 if ( !show ) { | |
17541 el.hide(); | |
17542 } | |
17543 $.effects.restore( el, props ); | |
17544 $.effects.removeWrapper( el ); | |
17545 done(); | |
17546 } | |
17547 }); | |
17548 | |
17549 }; | |
17550 | |
17551 })(jQuery); | |
17552 (function( $, undefined ) { | |
17553 | |
17554 $.effects.effect.drop = function( o, done ) { | |
17555 | |
17556 var el = $( this ), | |
17557 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], | |
17558 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17559 show = mode === "show", | |
17560 direction = o.direction || "left", | |
17561 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", | |
17562 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", | |
17563 animation = { | |
17564 opacity: show ? 1 : 0 | |
17565 }, | |
17566 distance; | |
17567 | |
17568 // Adjust | |
17569 $.effects.save( el, props ); | |
17570 el.show(); | |
17571 $.effects.createWrapper( el ); | |
17572 | |
17573 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; | |
17574 | |
17575 if ( show ) { | |
17576 el | |
17577 .css( "opacity", 0 ) | |
17578 .css( ref, motion === "pos" ? -distance : distance ); | |
17579 } | |
17580 | |
17581 // Animation | |
17582 animation[ ref ] = ( show ? | |
17583 ( motion === "pos" ? "+=" : "-=" ) : | |
17584 ( motion === "pos" ? "-=" : "+=" ) ) + | |
17585 distance; | |
17586 | |
17587 // Animate | |
17588 el.animate( animation, { | |
17589 queue: false, | |
17590 duration: o.duration, | |
17591 easing: o.easing, | |
17592 complete: function() { | |
17593 if ( mode === "hide" ) { | |
17594 el.hide(); | |
17595 } | |
17596 $.effects.restore( el, props ); | |
17597 $.effects.removeWrapper( el ); | |
17598 done(); | |
17599 } | |
17600 }); | |
17601 }; | |
17602 | |
17603 })(jQuery); | |
17604 (function( $, undefined ) { | |
17605 | |
17606 $.effects.effect.explode = function( o, done ) { | |
17607 | |
17608 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, | |
17609 cells = rows, | |
17610 el = $( this ), | |
17611 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17612 show = mode === "show", | |
17613 | |
17614 // show and then visibility:hidden the element before calculating offset | |
17615 offset = el.show().css( "visibility", "hidden" ).offset(), | |
17616 | |
17617 // width and height of a piece | |
17618 width = Math.ceil( el.outerWidth() / cells ), | |
17619 height = Math.ceil( el.outerHeight() / rows ), | |
17620 pieces = [], | |
17621 | |
17622 // loop | |
17623 i, j, left, top, mx, my; | |
17624 | |
17625 // children animate complete: | |
17626 function childComplete() { | |
17627 pieces.push( this ); | |
17628 if ( pieces.length === rows * cells ) { | |
17629 animComplete(); | |
17630 } | |
17631 } | |
17632 | |
17633 // clone the element for each row and cell. | |
17634 for( i = 0; i < rows ; i++ ) { // ===> | |
17635 top = offset.top + i * height; | |
17636 my = i - ( rows - 1 ) / 2 ; | |
17637 | |
17638 for( j = 0; j < cells ; j++ ) { // ||| | |
17639 left = offset.left + j * width; | |
17640 mx = j - ( cells - 1 ) / 2 ; | |
17641 | |
17642 // Create a clone of the now hidden main element that will be absolute positioned | |
17643 // within a wrapper div off the -left and -top equal to size of our pieces | |
17644 el | |
17645 .clone() | |
17646 .appendTo( "body" ) | |
17647 .wrap( "<div></div>" ) | |
17648 .css({ | |
17649 position: "absolute", | |
17650 visibility: "visible", | |
17651 left: -j * width, | |
17652 top: -i * height | |
17653 }) | |
17654 | |
17655 // select the wrapper - make it overflow: hidden and absolute positioned based on | |
17656 // where the original was located +left and +top equal to the size of pieces | |
17657 .parent() | |
17658 .addClass( "ui-effects-explode" ) | |
17659 .css({ | |
17660 position: "absolute", | |
17661 overflow: "hidden", | |
17662 width: width, | |
17663 height: height, | |
17664 left: left + ( show ? mx * width : 0 ), | |
17665 top: top + ( show ? my * height : 0 ), | |
17666 opacity: show ? 0 : 1 | |
17667 }).animate({ | |
17668 left: left + ( show ? 0 : mx * width ), | |
17669 top: top + ( show ? 0 : my * height ), | |
17670 opacity: show ? 1 : 0 | |
17671 }, o.duration || 500, o.easing, childComplete ); | |
17672 } | |
17673 } | |
17674 | |
17675 function animComplete() { | |
17676 el.css({ | |
17677 visibility: "visible" | |
17678 }); | |
17679 $( pieces ).remove(); | |
17680 if ( !show ) { | |
17681 el.hide(); | |
17682 } | |
17683 done(); | |
17684 } | |
17685 }; | |
17686 | |
17687 })(jQuery); | |
17688 (function( $, undefined ) { | |
17689 | |
17690 $.effects.effect.fade = function( o, done ) { | |
17691 var el = $( this ), | |
17692 mode = $.effects.setMode( el, o.mode || "toggle" ); | |
17693 | |
17694 el.animate({ | |
17695 opacity: mode | |
17696 }, { | |
17697 queue: false, | |
17698 duration: o.duration, | |
17699 easing: o.easing, | |
17700 complete: done | |
17701 }); | |
17702 }; | |
17703 | |
17704 })( jQuery ); | |
17705 (function( $, undefined ) { | |
17706 | |
17707 $.effects.effect.fold = function( o, done ) { | |
17708 | |
17709 // Create element | |
17710 var el = $( this ), | |
17711 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17712 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17713 show = mode === "show", | |
17714 hide = mode === "hide", | |
17715 size = o.size || 15, | |
17716 percent = /([0-9]+)%/.exec( size ), | |
17717 horizFirst = !!o.horizFirst, | |
17718 widthFirst = show !== horizFirst, | |
17719 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], | |
17720 duration = o.duration / 2, | |
17721 wrapper, distance, | |
17722 animation1 = {}, | |
17723 animation2 = {}; | |
17724 | |
17725 $.effects.save( el, props ); | |
17726 el.show(); | |
17727 | |
17728 // Create Wrapper | |
17729 wrapper = $.effects.createWrapper( el ).css({ | |
17730 overflow: "hidden" | |
17731 }); | |
17732 distance = widthFirst ? | |
17733 [ wrapper.width(), wrapper.height() ] : | |
17734 [ wrapper.height(), wrapper.width() ]; | |
17735 | |
17736 if ( percent ) { | |
17737 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; | |
17738 } | |
17739 if ( show ) { | |
17740 wrapper.css( horizFirst ? { | |
17741 height: 0, | |
17742 width: size | |
17743 } : { | |
17744 height: size, | |
17745 width: 0 | |
17746 }); | |
17747 } | |
17748 | |
17749 // Animation | |
17750 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; | |
17751 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; | |
17752 | |
17753 // Animate | |
17754 wrapper | |
17755 .animate( animation1, duration, o.easing ) | |
17756 .animate( animation2, duration, o.easing, function() { | |
17757 if ( hide ) { | |
17758 el.hide(); | |
17759 } | |
17760 $.effects.restore( el, props ); | |
17761 $.effects.removeWrapper( el ); | |
17762 done(); | |
17763 }); | |
17764 | |
17765 }; | |
17766 | |
17767 })(jQuery); | |
17768 (function( $, undefined ) { | |
17769 | |
17770 $.effects.effect.highlight = function( o, done ) { | |
17771 var elem = $( this ), | |
17772 props = [ "backgroundImage", "backgroundColor", "opacity" ], | |
17773 mode = $.effects.setMode( elem, o.mode || "show" ), | |
17774 animation = { | |
17775 backgroundColor: elem.css( "backgroundColor" ) | |
17776 }; | |
17777 | |
17778 if (mode === "hide") { | |
17779 animation.opacity = 0; | |
17780 } | |
17781 | |
17782 $.effects.save( elem, props ); | |
17783 | |
17784 elem | |
17785 .show() | |
17786 .css({ | |
17787 backgroundImage: "none", | |
17788 backgroundColor: o.color || "#ffff99" | |
17789 }) | |
17790 .animate( animation, { | |
17791 queue: false, | |
17792 duration: o.duration, | |
17793 easing: o.easing, | |
17794 complete: function() { | |
17795 if ( mode === "hide" ) { | |
17796 elem.hide(); | |
17797 } | |
17798 $.effects.restore( elem, props ); | |
17799 done(); | |
17800 } | |
17801 }); | |
17802 }; | |
17803 | |
17804 })(jQuery); | |
17805 (function( $, undefined ) { | |
17806 | |
17807 $.effects.effect.pulsate = function( o, done ) { | |
17808 var elem = $( this ), | |
17809 mode = $.effects.setMode( elem, o.mode || "show" ), | |
17810 show = mode === "show", | |
17811 hide = mode === "hide", | |
17812 showhide = ( show || mode === "hide" ), | |
17813 | |
17814 // showing or hiding leaves of the "last" animation | |
17815 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), | |
17816 duration = o.duration / anims, | |
17817 animateTo = 0, | |
17818 queue = elem.queue(), | |
17819 queuelen = queue.length, | |
17820 i; | |
17821 | |
17822 if ( show || !elem.is(":visible")) { | |
17823 elem.css( "opacity", 0 ).show(); | |
17824 animateTo = 1; | |
17825 } | |
17826 | |
17827 // anims - 1 opacity "toggles" | |
17828 for ( i = 1; i < anims; i++ ) { | |
17829 elem.animate({ | |
17830 opacity: animateTo | |
17831 }, duration, o.easing ); | |
17832 animateTo = 1 - animateTo; | |
17833 } | |
17834 | |
17835 elem.animate({ | |
17836 opacity: animateTo | |
17837 }, duration, o.easing); | |
17838 | |
17839 elem.queue(function() { | |
17840 if ( hide ) { | |
17841 elem.hide(); | |
17842 } | |
17843 done(); | |
17844 }); | |
17845 | |
17846 // We just queued up "anims" animations, we need to put them next in the queue | |
17847 if ( queuelen > 1 ) { | |
17848 queue.splice.apply( queue, | |
17849 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); | |
17850 } | |
17851 elem.dequeue(); | |
17852 }; | |
17853 | |
17854 })(jQuery); | |
17855 (function( $, undefined ) { | |
17856 | |
17857 $.effects.effect.puff = function( o, done ) { | |
17858 var elem = $( this ), | |
17859 mode = $.effects.setMode( elem, o.mode || "hide" ), | |
17860 hide = mode === "hide", | |
17861 percent = parseInt( o.percent, 10 ) || 150, | |
17862 factor = percent / 100, | |
17863 original = { | |
17864 height: elem.height(), | |
17865 width: elem.width(), | |
17866 outerHeight: elem.outerHeight(), | |
17867 outerWidth: elem.outerWidth() | |
17868 }; | |
17869 | |
17870 $.extend( o, { | |
17871 effect: "scale", | |
17872 queue: false, | |
17873 fade: true, | |
17874 mode: mode, | |
17875 complete: done, | |
17876 percent: hide ? percent : 100, | |
17877 from: hide ? | |
17878 original : | |
17879 { | |
17880 height: original.height * factor, | |
17881 width: original.width * factor, | |
17882 outerHeight: original.outerHeight * factor, | |
17883 outerWidth: original.outerWidth * factor | |
17884 } | |
17885 }); | |
17886 | |
17887 elem.effect( o ); | |
17888 }; | |
17889 | |
17890 $.effects.effect.scale = function( o, done ) { | |
17891 | |
17892 // Create element | |
17893 var el = $( this ), | |
17894 options = $.extend( true, {}, o ), | |
17895 mode = $.effects.setMode( el, o.mode || "effect" ), | |
17896 percent = parseInt( o.percent, 10 ) || | |
17897 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), | |
17898 direction = o.direction || "both", | |
17899 origin = o.origin, | |
17900 original = { | |
17901 height: el.height(), | |
17902 width: el.width(), | |
17903 outerHeight: el.outerHeight(), | |
17904 outerWidth: el.outerWidth() | |
17905 }, | |
17906 factor = { | |
17907 y: direction !== "horizontal" ? (percent / 100) : 1, | |
17908 x: direction !== "vertical" ? (percent / 100) : 1 | |
17909 }; | |
17910 | |
17911 // We are going to pass this effect to the size effect: | |
17912 options.effect = "size"; | |
17913 options.queue = false; | |
17914 options.complete = done; | |
17915 | |
17916 // Set default origin and restore for show/hide | |
17917 if ( mode !== "effect" ) { | |
17918 options.origin = origin || ["middle","center"]; | |
17919 options.restore = true; | |
17920 } | |
17921 | |
17922 options.from = o.from || ( mode === "show" ? { | |
17923 height: 0, | |
17924 width: 0, | |
17925 outerHeight: 0, | |
17926 outerWidth: 0 | |
17927 } : original ); | |
17928 options.to = { | |
17929 height: original.height * factor.y, | |
17930 width: original.width * factor.x, | |
17931 outerHeight: original.outerHeight * factor.y, | |
17932 outerWidth: original.outerWidth * factor.x | |
17933 }; | |
17934 | |
17935 // Fade option to support puff | |
17936 if ( options.fade ) { | |
17937 if ( mode === "show" ) { | |
17938 options.from.opacity = 0; | |
17939 options.to.opacity = 1; | |
17940 } | |
17941 if ( mode === "hide" ) { | |
17942 options.from.opacity = 1; | |
17943 options.to.opacity = 0; | |
17944 } | |
17945 } | |
17946 | |
17947 // Animate | |
17948 el.effect( options ); | |
17949 | |
17950 }; | |
17951 | |
17952 $.effects.effect.size = function( o, done ) { | |
17953 | |
17954 // Create element | |
17955 var original, baseline, factor, | |
17956 el = $( this ), | |
17957 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], | |
17958 | |
17959 // Always restore | |
17960 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], | |
17961 | |
17962 // Copy for children | |
17963 props2 = [ "width", "height", "overflow" ], | |
17964 cProps = [ "fontSize" ], | |
17965 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], | |
17966 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], | |
17967 | |
17968 // Set options | |
17969 mode = $.effects.setMode( el, o.mode || "effect" ), | |
17970 restore = o.restore || mode !== "effect", | |
17971 scale = o.scale || "both", | |
17972 origin = o.origin || [ "middle", "center" ], | |
17973 position = el.css( "position" ), | |
17974 props = restore ? props0 : props1, | |
17975 zero = { | |
17976 height: 0, | |
17977 width: 0, | |
17978 outerHeight: 0, | |
17979 outerWidth: 0 | |
17980 }; | |
17981 | |
17982 if ( mode === "show" ) { | |
17983 el.show(); | |
17984 } | |
17985 original = { | |
17986 height: el.height(), | |
17987 width: el.width(), | |
17988 outerHeight: el.outerHeight(), | |
17989 outerWidth: el.outerWidth() | |
17990 }; | |
17991 | |
17992 if ( o.mode === "toggle" && mode === "show" ) { | |
17993 el.from = o.to || zero; | |
17994 el.to = o.from || original; | |
17995 } else { | |
17996 el.from = o.from || ( mode === "show" ? zero : original ); | |
17997 el.to = o.to || ( mode === "hide" ? zero : original ); | |
17998 } | |
17999 | |
18000 // Set scaling factor | |
18001 factor = { | |
18002 from: { | |
18003 y: el.from.height / original.height, | |
18004 x: el.from.width / original.width | |
18005 }, | |
18006 to: { | |
18007 y: el.to.height / original.height, | |
18008 x: el.to.width / original.width | |
18009 } | |
18010 }; | |
18011 | |
18012 // Scale the css box | |
18013 if ( scale === "box" || scale === "both" ) { | |
18014 | |
18015 // Vertical props scaling | |
18016 if ( factor.from.y !== factor.to.y ) { | |
18017 props = props.concat( vProps ); | |
18018 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); | |
18019 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); | |
18020 } | |
18021 | |
18022 // Horizontal props scaling | |
18023 if ( factor.from.x !== factor.to.x ) { | |
18024 props = props.concat( hProps ); | |
18025 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); | |
18026 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); | |
18027 } | |
18028 } | |
18029 | |
18030 // Scale the content | |
18031 if ( scale === "content" || scale === "both" ) { | |
18032 | |
18033 // Vertical props scaling | |
18034 if ( factor.from.y !== factor.to.y ) { | |
18035 props = props.concat( cProps ).concat( props2 ); | |
18036 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); | |
18037 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); | |
18038 } | |
18039 } | |
18040 | |
18041 $.effects.save( el, props ); | |
18042 el.show(); | |
18043 $.effects.createWrapper( el ); | |
18044 el.css( "overflow", "hidden" ).css( el.from ); | |
18045 | |
18046 // Adjust | |
18047 if (origin) { // Calculate baseline shifts | |
18048 baseline = $.effects.getBaseline( origin, original ); | |
18049 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; | |
18050 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; | |
18051 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; | |
18052 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; | |
18053 } | |
18054 el.css( el.from ); // set top & left | |
18055 | |
18056 // Animate | |
18057 if ( scale === "content" || scale === "both" ) { // Scale the children | |
18058 | |
18059 // Add margins/font-size | |
18060 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); | |
18061 hProps = hProps.concat([ "marginLeft", "marginRight" ]); | |
18062 props2 = props0.concat(vProps).concat(hProps); | |
18063 | |
18064 el.find( "*[width]" ).each( function(){ | |
18065 var child = $( this ), | |
18066 c_original = { | |
18067 height: child.height(), | |
18068 width: child.width(), | |
18069 outerHeight: child.outerHeight(), | |
18070 outerWidth: child.outerWidth() | |
18071 }; | |
18072 if (restore) { | |
18073 $.effects.save(child, props2); | |
18074 } | |
18075 | |
18076 child.from = { | |
18077 height: c_original.height * factor.from.y, | |
18078 width: c_original.width * factor.from.x, | |
18079 outerHeight: c_original.outerHeight * factor.from.y, | |
18080 outerWidth: c_original.outerWidth * factor.from.x | |
18081 }; | |
18082 child.to = { | |
18083 height: c_original.height * factor.to.y, | |
18084 width: c_original.width * factor.to.x, | |
18085 outerHeight: c_original.height * factor.to.y, | |
18086 outerWidth: c_original.width * factor.to.x | |
18087 }; | |
18088 | |
18089 // Vertical props scaling | |
18090 if ( factor.from.y !== factor.to.y ) { | |
18091 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); | |
18092 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); | |
18093 } | |
18094 | |
18095 // Horizontal props scaling | |
18096 if ( factor.from.x !== factor.to.x ) { | |
18097 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); | |
18098 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); | |
18099 } | |
18100 | |
18101 // Animate children | |
18102 child.css( child.from ); | |
18103 child.animate( child.to, o.duration, o.easing, function() { | |
18104 | |
18105 // Restore children | |
18106 if ( restore ) { | |
18107 $.effects.restore( child, props2 ); | |
18108 } | |
18109 }); | |
18110 }); | |
18111 } | |
18112 | |
18113 // Animate | |
18114 el.animate( el.to, { | |
18115 queue: false, | |
18116 duration: o.duration, | |
18117 easing: o.easing, | |
18118 complete: function() { | |
18119 if ( el.to.opacity === 0 ) { | |
18120 el.css( "opacity", el.from.opacity ); | |
18121 } | |
18122 if( mode === "hide" ) { | |
18123 el.hide(); | |
18124 } | |
18125 $.effects.restore( el, props ); | |
18126 if ( !restore ) { | |
18127 | |
18128 // we need to calculate our new positioning based on the scaling | |
18129 if ( position === "static" ) { | |
18130 el.css({ | |
18131 position: "relative", | |
18132 top: el.to.top, | |
18133 left: el.to.left | |
18134 }); | |
18135 } else { | |
18136 $.each([ "top", "left" ], function( idx, pos ) { | |
18137 el.css( pos, function( _, str ) { | |
18138 var val = parseInt( str, 10 ), | |
18139 toRef = idx ? el.to.left : el.to.top; | |
18140 | |
18141 // if original was "auto", recalculate the new value from wrapper | |
18142 if ( str === "auto" ) { | |
18143 return toRef + "px"; | |
18144 } | |
18145 | |
18146 return val + toRef + "px"; | |
18147 }); | |
18148 }); | |
18149 } | |
18150 } | |
18151 | |
18152 $.effects.removeWrapper( el ); | |
18153 done(); | |
18154 } | |
18155 }); | |
18156 | |
18157 }; | |
18158 | |
18159 })(jQuery); | |
18160 (function( $, undefined ) { | |
18161 | |
18162 $.effects.effect.shake = function( o, done ) { | |
18163 | |
18164 var el = $( this ), | |
18165 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
18166 mode = $.effects.setMode( el, o.mode || "effect" ), | |
18167 direction = o.direction || "left", | |
18168 distance = o.distance || 20, | |
18169 times = o.times || 3, | |
18170 anims = times * 2 + 1, | |
18171 speed = Math.round(o.duration/anims), | |
18172 ref = (direction === "up" || direction === "down") ? "top" : "left", | |
18173 positiveMotion = (direction === "up" || direction === "left"), | |
18174 animation = {}, | |
18175 animation1 = {}, | |
18176 animation2 = {}, | |
18177 i, | |
18178 | |
18179 // we will need to re-assemble the queue to stack our animations in place | |
18180 queue = el.queue(), | |
18181 queuelen = queue.length; | |
18182 | |
18183 $.effects.save( el, props ); | |
18184 el.show(); | |
18185 $.effects.createWrapper( el ); | |
18186 | |
18187 // Animation | |
18188 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; | |
18189 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; | |
18190 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; | |
18191 | |
18192 // Animate | |
18193 el.animate( animation, speed, o.easing ); | |
18194 | |
18195 // Shakes | |
18196 for ( i = 1; i < times; i++ ) { | |
18197 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); | |
18198 } | |
18199 el | |
18200 .animate( animation1, speed, o.easing ) | |
18201 .animate( animation, speed / 2, o.easing ) | |
18202 .queue(function() { | |
18203 if ( mode === "hide" ) { | |
18204 el.hide(); | |
18205 } | |
18206 $.effects.restore( el, props ); | |
18207 $.effects.removeWrapper( el ); | |
18208 done(); | |
18209 }); | |
18210 | |
18211 // inject all the animations we just queued to be first in line (after "inprogress") | |
18212 if ( queuelen > 1) { | |
18213 queue.splice.apply( queue, | |
18214 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); | |
18215 } | |
18216 el.dequeue(); | |
18217 | |
18218 }; | |
18219 | |
18220 })(jQuery); | |
18221 (function( $, undefined ) { | |
18222 | |
18223 $.effects.effect.slide = function( o, done ) { | |
18224 | |
18225 // Create element | |
18226 var el = $( this ), | |
18227 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], | |
18228 mode = $.effects.setMode( el, o.mode || "show" ), | |
18229 show = mode === "show", | |
18230 direction = o.direction || "left", | |
18231 ref = (direction === "up" || direction === "down") ? "top" : "left", | |
18232 positiveMotion = (direction === "up" || direction === "left"), | |
18233 distance, | |
18234 animation = {}; | |
18235 | |
18236 // Adjust | |
18237 $.effects.save( el, props ); | |
18238 el.show(); | |
18239 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); | |
18240 | |
18241 $.effects.createWrapper( el ).css({ | |
18242 overflow: "hidden" | |
18243 }); | |
18244 | |
18245 if ( show ) { | |
18246 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); | |
18247 } | |
18248 | |
18249 // Animation | |
18250 animation[ ref ] = ( show ? | |
18251 ( positiveMotion ? "+=" : "-=") : | |
18252 ( positiveMotion ? "-=" : "+=")) + | |
18253 distance; | |
18254 | |
18255 // Animate | |
18256 el.animate( animation, { | |
18257 queue: false, | |
18258 duration: o.duration, | |
18259 easing: o.easing, | |
18260 complete: function() { | |
18261 if ( mode === "hide" ) { | |
18262 el.hide(); | |
18263 } | |
18264 $.effects.restore( el, props ); | |
18265 $.effects.removeWrapper( el ); | |
18266 done(); | |
18267 } | |
18268 }); | |
18269 }; | |
18270 | |
18271 })(jQuery); | |
18272 (function( $, undefined ) { | |
18273 | |
18274 $.effects.effect.transfer = function( o, done ) { | |
18275 var elem = $( this ), | |
18276 target = $( o.to ), | |
18277 targetFixed = target.css( "position" ) === "fixed", | |
18278 body = $("body"), | |
18279 fixTop = targetFixed ? body.scrollTop() : 0, | |
18280 fixLeft = targetFixed ? body.scrollLeft() : 0, | |
18281 endPosition = target.offset(), | |
18282 animation = { | |
18283 top: endPosition.top - fixTop , | |
18284 left: endPosition.left - fixLeft , | |
18285 height: target.innerHeight(), | |
18286 width: target.innerWidth() | |
18287 }, | |
18288 startPosition = elem.offset(), | |
18289 transfer = $( "<div class='ui-effects-transfer'></div>" ) | |
18290 .appendTo( document.body ) | |
18291 .addClass( o.className ) | |
18292 .css({ | |
18293 top: startPosition.top - fixTop , | |
18294 left: startPosition.left - fixLeft , | |
18295 height: elem.innerHeight(), | |
18296 width: elem.innerWidth(), | |
18297 position: targetFixed ? "fixed" : "absolute" | |
18298 }) | |
18299 .animate( animation, o.duration, o.easing, function() { | |
18300 transfer.remove(); | |
18301 done(); | |
18302 }); | |
18303 }; | |
18304 | |
18305 })(jQuery); | |
18306 /** | |
18307 | |
18308 JSZip - A Javascript class for generating and reading zip files | |
18309 <http://stuartk.com/jszip> | |
18310 | |
18311 (c) 2009-2012 Stuart Knightley <stuart [at] stuartk.com> | |
18312 Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. | |
18313 | |
18314 Usage: | |
18315 zip = new JSZip(); | |
18316 zip.file("hello.txt", "Hello, World!").add("tempfile", "nothing"); | |
18317 zip.folder("images").file("smile.gif", base64Data, {base64: true}); | |
18318 zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); | |
18319 zip.remove("tempfile"); | |
18320 | |
18321 base64zip = zip.generate(); | |
18322 | |
18323 **/ | |
18324 | |
18325 /** | |
18326 * Representation a of zip file in js | |
18327 * @constructor | |
18328 * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). | |
18329 * @param {Object=} options the options for creating this objects (optional). | |
18330 */ | |
18331 var JSZip = function(data, options) { | |
18332 // object containing the files : | |
18333 // { | |
18334 // "folder/" : {...}, | |
18335 // "folder/data.txt" : {...} | |
18336 // } | |
18337 this.files = {}; | |
18338 | |
18339 // Where we are in the hierarchy | |
18340 this.root = ""; | |
18341 | |
18342 if (data) { | |
18343 this.load(data, options); | |
18344 } | |
18345 }; | |
18346 | |
18347 JSZip.signature = { | |
18348 LOCAL_FILE_HEADER : "\x50\x4b\x03\x04", | |
18349 CENTRAL_FILE_HEADER : "\x50\x4b\x01\x02", | |
18350 CENTRAL_DIRECTORY_END : "\x50\x4b\x05\x06", | |
18351 ZIP64_CENTRAL_DIRECTORY_LOCATOR : "\x50\x4b\x06\x07", | |
18352 ZIP64_CENTRAL_DIRECTORY_END : "\x50\x4b\x06\x06", | |
18353 DATA_DESCRIPTOR : "\x50\x4b\x07\x08" | |
18354 }; | |
18355 | |
18356 // Default properties for a new file | |
18357 JSZip.defaults = { | |
18358 base64: false, | |
18359 binary: false, | |
18360 dir: false, | |
18361 date: null | |
18362 }; | |
18363 | |
18364 | |
18365 JSZip.prototype = (function () { | |
18366 /** | |
18367 * A simple object representing a file in the zip file. | |
18368 * @constructor | |
18369 * @param {string} name the name of the file | |
18370 * @param {string} data the data | |
18371 * @param {Object} options the options of the file | |
18372 */ | |
18373 var ZipObject = function (name, data, options) { | |
18374 this.name = name; | |
18375 this.data = data; | |
18376 this.options = options; | |
18377 }; | |
18378 | |
18379 ZipObject.prototype = { | |
18380 /** | |
18381 * Return the content as UTF8 string. | |
18382 * @return {string} the UTF8 string. | |
18383 */ | |
18384 asText : function () { | |
18385 var result = this.data; | |
18386 if (result === null || typeof result === "undefined") { | |
18387 return ""; | |
18388 } | |
18389 if (this.options.base64) { | |
18390 result = JSZipBase64.decode(result); | |
18391 } | |
18392 if (this.options.binary) { | |
18393 result = JSZip.prototype.utf8decode(result); | |
18394 } | |
18395 return result; | |
18396 }, | |
18397 /** | |
18398 * Returns the binary content. | |
18399 * @return {string} the content as binary. | |
18400 */ | |
18401 asBinary : function () { | |
18402 var result = this.data; | |
18403 if (result === null || typeof result === "undefined") { | |
18404 return ""; | |
18405 } | |
18406 if (this.options.base64) { | |
18407 result = JSZipBase64.decode(result); | |
18408 } | |
18409 if (!this.options.binary) { | |
18410 result = JSZip.prototype.utf8encode(result); | |
18411 } | |
18412 return result; | |
18413 }, | |
18414 /** | |
18415 * Returns the content as an Uint8Array. | |
18416 * @return {Uint8Array} the content as an Uint8Array. | |
18417 */ | |
18418 asUint8Array : function () { | |
18419 return JSZip.utils.string2Uint8Array(this.asBinary()); | |
18420 }, | |
18421 /** | |
18422 * Returns the content as an ArrayBuffer. | |
18423 * @return {ArrayBuffer} the content as an ArrayBufer. | |
18424 */ | |
18425 asArrayBuffer : function () { | |
18426 return JSZip.utils.string2Uint8Array(this.asBinary()).buffer; | |
18427 } | |
18428 }; | |
18429 | |
18430 /** | |
18431 * Transform an integer into a string in hexadecimal. | |
18432 * @private | |
18433 * @param {number} dec the number to convert. | |
18434 * @param {number} bytes the number of bytes to generate. | |
18435 * @returns {string} the result. | |
18436 */ | |
18437 var decToHex = function(dec, bytes) { | |
18438 var hex = "", i; | |
18439 for(i = 0; i < bytes; i++) { | |
18440 hex += String.fromCharCode(dec&0xff); | |
18441 dec=dec>>>8; | |
18442 } | |
18443 return hex; | |
18444 }; | |
18445 | |
18446 /** | |
18447 * Merge the objects passed as parameters into a new one. | |
18448 * @private | |
18449 * @param {...Object} var_args All objects to merge. | |
18450 * @return {Object} a new object with the data of the others. | |
18451 */ | |
18452 var extend = function () { | |
18453 var result = {}, i, attr; | |
18454 for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers | |
18455 for (attr in arguments[i]) { | |
18456 if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { | |
18457 result[attr] = arguments[i][attr]; | |
18458 } | |
18459 } | |
18460 } | |
18461 return result; | |
18462 }; | |
18463 | |
18464 /** | |
18465 * Transforms the (incomplete) options from the user into the complete | |
18466 * set of options to create a file. | |
18467 * @private | |
18468 * @param {Object} o the options from the user. | |
18469 * @return {Object} the complete set of options. | |
18470 */ | |
18471 var prepareFileAttrs = function (o) { | |
18472 o = o || {}; | |
18473 if (o.base64 === true && o.binary == null) { | |
18474 o.binary = true; | |
18475 } | |
18476 o = extend(o, JSZip.defaults); | |
18477 o.date = o.date || new Date(); | |
18478 | |
18479 return o; | |
18480 }; | |
18481 | |
18482 /** | |
18483 * Add a file in the current folder. | |
18484 * @private | |
18485 * @param {string} name the name of the file | |
18486 * @param {String|ArrayBuffer|Uint8Array} data the data of the file | |
18487 * @param {Object} o the options of the file | |
18488 * @return {Object} the new file. | |
18489 */ | |
18490 var fileAdd = function (name, data, o) { | |
18491 // be sure sub folders exist | |
18492 var parent = parentFolder(name); | |
18493 if (parent) { | |
18494 folderAdd.call(this, parent); | |
18495 } | |
18496 | |
18497 o = prepareFileAttrs(o); | |
18498 | |
18499 if (o.dir || data === null || typeof data === "undefined") { | |
18500 o.base64 = false; | |
18501 o.binary = false; | |
18502 data = null; | |
18503 } else if (JSZip.support.uint8array && data instanceof Uint8Array) { | |
18504 o.base64 = false; | |
18505 o.binary = true; | |
18506 data = JSZip.utils.uint8Array2String(data); | |
18507 } else if (JSZip.support.arraybuffer && data instanceof ArrayBuffer) { | |
18508 o.base64 = false; | |
18509 o.binary = true; | |
18510 var bufferView = new Uint8Array(data); | |
18511 data = JSZip.utils.uint8Array2String(bufferView); | |
18512 } else if (o.binary && !o.base64) { | |
18513 // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask | |
18514 if (o.optimizedBinaryString !== true) { | |
18515 // this is a string, not in a base64 format. | |
18516 // Be sure that this is a correct "binary string" | |
18517 data = JSZip.utils.string2binary(data); | |
18518 } | |
18519 // we remove this option since it's only relevant here | |
18520 delete o.optimizedBinaryString; | |
18521 } | |
18522 | |
18523 return this.files[name] = new ZipObject(name, data, o); | |
18524 }; | |
18525 | |
18526 | |
18527 /** | |
18528 * Find the parent folder of the path. | |
18529 * @private | |
18530 * @param {string} path the path to use | |
18531 * @return {string} the parent folder, or "" | |
18532 */ | |
18533 var parentFolder = function (path) { | |
18534 if (path.slice(-1) == '/') { | |
18535 path = path.substring(0, path.length - 1); | |
18536 } | |
18537 var lastSlash = path.lastIndexOf('/'); | |
18538 return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; | |
18539 }; | |
18540 | |
18541 /** | |
18542 * Add a (sub) folder in the current folder. | |
18543 * @private | |
18544 * @param {string} name the folder's name | |
18545 * @return {Object} the new folder. | |
18546 */ | |
18547 var folderAdd = function (name) { | |
18548 // Check the name ends with a / | |
18549 if (name.slice(-1) != "/") { | |
18550 name += "/"; // IE doesn't like substr(-1) | |
18551 } | |
18552 | |
18553 // Does this folder already exist? | |
18554 if (!this.files[name]) { | |
18555 // be sure sub folders exist | |
18556 var parent = parentFolder(name); | |
18557 if (parent) { | |
18558 folderAdd.call(this, parent); | |
18559 } | |
18560 | |
18561 fileAdd.call(this, name, null, {dir:true}); | |
18562 } | |
18563 return this.files[name]; | |
18564 }; | |
18565 | |
18566 /** | |
18567 * Generate the data found in the local header of a zip file. | |
18568 * Do not create it now, as some parts are re-used later. | |
18569 * @private | |
18570 * @param {Object} file the file to use. | |
18571 * @param {string} utfEncodedFileName the file name, utf8 encoded. | |
18572 * @param {string} compressionType the compression to use. | |
18573 * @return {Object} an object containing header and compressedData. | |
18574 */ | |
18575 var prepareLocalHeaderData = function(file, utfEncodedFileName, compressionType) { | |
18576 var useUTF8 = utfEncodedFileName !== file.name, | |
18577 data = file.asBinary(), | |
18578 o = file.options, | |
18579 dosTime, | |
18580 dosDate; | |
18581 | |
18582 // date | |
18583 // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html | |
18584 // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html | |
18585 // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html | |
18586 | |
18587 dosTime = o.date.getHours(); | |
18588 dosTime = dosTime << 6; | |
18589 dosTime = dosTime | o.date.getMinutes(); | |
18590 dosTime = dosTime << 5; | |
18591 dosTime = dosTime | o.date.getSeconds() / 2; | |
18592 | |
18593 dosDate = o.date.getFullYear() - 1980; | |
18594 dosDate = dosDate << 4; | |
18595 dosDate = dosDate | (o.date.getMonth() + 1); | |
18596 dosDate = dosDate << 5; | |
18597 dosDate = dosDate | o.date.getDate(); | |
18598 | |
18599 var hasData = data !== null && data.length !== 0; | |
18600 | |
18601 var compression = JSZip.compressions[compressionType]; | |
18602 var compressedData = hasData ? compression.compress(data) : ''; | |
18603 | |
18604 var header = ""; | |
18605 | |
18606 // version needed to extract | |
18607 header += "\x0A\x00"; | |
18608 // general purpose bit flag | |
18609 // set bit 11 if utf8 | |
18610 header += useUTF8 ? "\x00\x08" : "\x00\x00"; | |
18611 // compression method | |
18612 header += hasData ? compression.magic : JSZip.compressions['STORE'].magic; | |
18613 // last mod file time | |
18614 header += decToHex(dosTime, 2); | |
18615 // last mod file date | |
18616 header += decToHex(dosDate, 2); | |
18617 // crc-32 | |
18618 header += hasData ? decToHex(this.crc32(data), 4) : '\x00\x00\x00\x00'; | |
18619 // compressed size | |
18620 header += hasData ? decToHex(compressedData.length, 4) : '\x00\x00\x00\x00'; | |
18621 // uncompressed size | |
18622 header += hasData ? decToHex(data.length, 4) : '\x00\x00\x00\x00'; | |
18623 // file name length | |
18624 header += decToHex(utfEncodedFileName.length, 2); | |
18625 // extra field length | |
18626 header += "\x00\x00"; | |
18627 | |
18628 return { | |
18629 header:header, | |
18630 compressedData:compressedData | |
18631 }; | |
18632 }; | |
18633 | |
18634 | |
18635 // return the actual prototype of JSZip | |
18636 return { | |
18637 /** | |
18638 * Read an existing zip and merge the data in the current JSZip object. | |
18639 * The implementation is in jszip-load.js, don't forget to include it. | |
18640 * @param {String|ArrayBuffer|Uint8Array} stream The stream to load | |
18641 * @param {Object} options Options for loading the stream. | |
18642 * options.base64 : is the stream in base64 ? default : false | |
18643 * @return {JSZip} the current JSZip object | |
18644 */ | |
18645 load : function (stream, options) { | |
18646 throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); | |
18647 }, | |
18648 | |
18649 /** | |
18650 * Filter nested files/folders with the specified function. | |
18651 * @param {Function} search the predicate to use : | |
18652 * function (relativePath, file) {...} | |
18653 * It takes 2 arguments : the relative path and the file. | |
18654 * @return {Array} An array of matching elements. | |
18655 */ | |
18656 filter : function (search) { | |
18657 var result = [], filename, relativePath, file, fileClone; | |
18658 for (filename in this.files) { | |
18659 if ( !this.files.hasOwnProperty(filename) ) { continue; } | |
18660 file = this.files[filename]; | |
18661 // return a new object, don't let the user mess with our internal objects :) | |
18662 fileClone = new ZipObject(file.name, file.data, extend(file.options)); | |
18663 relativePath = filename.slice(this.root.length, filename.length); | |
18664 if (filename.slice(0, this.root.length) === this.root && // the file is in the current root | |
18665 search(relativePath, fileClone)) { // and the file matches the function | |
18666 result.push(fileClone); | |
18667 } | |
18668 } | |
18669 return result; | |
18670 }, | |
18671 | |
18672 /** | |
18673 * Add a file to the zip file, or search a file. | |
18674 * @param {string|RegExp} name The name of the file to add (if data is defined), | |
18675 * the name of the file to find (if no data) or a regex to match files. | |
18676 * @param {String|ArrayBuffer|Uint8Array} data The file data, either raw or base64 encoded | |
18677 * @param {Object} o File options | |
18678 * @return {JSZip|Object|Array} this JSZip object (when adding a file), | |
18679 * a file (when searching by string) or an array of files (when searching by regex). | |
18680 */ | |
18681 file : function(name, data, o) { | |
18682 if (arguments.length === 1) { | |
18683 if (name instanceof RegExp) { | |
18684 var regexp = name; | |
18685 return this.filter(function(relativePath, file) { | |
18686 return !file.options.dir && regexp.test(relativePath); | |
18687 }); | |
18688 } else { // text | |
18689 return this.filter(function (relativePath, file) { | |
18690 return !file.options.dir && relativePath === name; | |
18691 })[0]||null; | |
18692 } | |
18693 } else { // more than one argument : we have data ! | |
18694 name = this.root+name; | |
18695 fileAdd.call(this, name, data, o); | |
18696 } | |
18697 return this; | |
18698 }, | |
18699 | |
18700 /** | |
18701 * Add a directory to the zip file, or search. | |
18702 * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. | |
18703 * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. | |
18704 */ | |
18705 folder : function(arg) { | |
18706 if (!arg) { | |
18707 return this; | |
18708 } | |
18709 | |
18710 if (arg instanceof RegExp) { | |
18711 return this.filter(function(relativePath, file) { | |
18712 return file.options.dir && arg.test(relativePath); | |
18713 }); | |
18714 } | |
18715 | |
18716 // else, name is a new folder | |
18717 var name = this.root + arg; | |
18718 var newFolder = folderAdd.call(this, name); | |
18719 | |
18720 // Allow chaining by returning a new object with this folder as the root | |
18721 var ret = this.clone(); | |
18722 ret.root = newFolder.name; | |
18723 return ret; | |
18724 }, | |
18725 | |
18726 /** | |
18727 * Delete a file, or a directory and all sub-files, from the zip | |
18728 * @param {string} name the name of the file to delete | |
18729 * @return {JSZip} this JSZip object | |
18730 */ | |
18731 remove : function(name) { | |
18732 name = this.root + name; | |
18733 var file = this.files[name]; | |
18734 if (!file) { | |
18735 // Look for any folders | |
18736 if (name.slice(-1) != "/") { | |
18737 name += "/"; | |
18738 } | |
18739 file = this.files[name]; | |
18740 } | |
18741 | |
18742 if (file) { | |
18743 if (!file.options.dir) { | |
18744 // file | |
18745 delete this.files[name]; | |
18746 } else { | |
18747 // folder | |
18748 var kids = this.filter(function (relativePath, file) { | |
18749 return file.name.slice(0, name.length) === name; | |
18750 }); | |
18751 for (var i = 0; i < kids.length; i++) { | |
18752 delete this.files[kids[i].name]; | |
18753 } | |
18754 } | |
18755 } | |
18756 | |
18757 return this; | |
18758 }, | |
18759 | |
18760 /** | |
18761 * Generate the complete zip file | |
18762 * @param {Object} options the options to generate the zip file : | |
18763 * - base64, (deprecated, use type instead) true to generate base64. | |
18764 * - compression, "STORE" by default. | |
18765 * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. | |
18766 * @return {String|Uint8Array|ArrayBuffer|Blob} the zip file | |
18767 */ | |
18768 generate : function(options) { | |
18769 options = extend(options || {}, { | |
18770 base64 : true, | |
18771 compression : "STORE", | |
18772 type : "base64" | |
18773 }); | |
18774 var compression = options.compression.toUpperCase(); | |
18775 | |
18776 // The central directory, and files data | |
18777 var directory = [], files = [], fileOffset = 0; | |
18778 | |
18779 if (!JSZip.compressions[compression]) { | |
18780 throw compression + " is not a valid compression method !"; | |
18781 } | |
18782 | |
18783 for (var name in this.files) { | |
18784 if ( !this.files.hasOwnProperty(name) ) { continue; } | |
18785 | |
18786 var file = this.files[name]; | |
18787 | |
18788 var utfEncodedFileName = this.utf8encode(file.name); | |
18789 | |
18790 var fileRecord = "", | |
18791 dirRecord = "", | |
18792 data = prepareLocalHeaderData.call(this, file, utfEncodedFileName, compression); | |
18793 fileRecord = JSZip.signature.LOCAL_FILE_HEADER + data.header + utfEncodedFileName + data.compressedData; | |
18794 | |
18795 dirRecord = JSZip.signature.CENTRAL_FILE_HEADER + | |
18796 // version made by (00: DOS) | |
18797 "\x14\x00" + | |
18798 // file header (common to file and central directory) | |
18799 data.header + | |
18800 // file comment length | |
18801 "\x00\x00" + | |
18802 // disk number start | |
18803 "\x00\x00" + | |
18804 // internal file attributes TODO | |
18805 "\x00\x00" + | |
18806 // external file attributes | |
18807 (this.files[name].options.dir===true?"\x10\x00\x00\x00":"\x00\x00\x00\x00")+ | |
18808 // relative offset of local header | |
18809 decToHex(fileOffset, 4) + | |
18810 // file name | |
18811 utfEncodedFileName; | |
18812 | |
18813 fileOffset += fileRecord.length; | |
18814 | |
18815 files.push(fileRecord); | |
18816 directory.push(dirRecord); | |
18817 } | |
18818 | |
18819 var fileData = files.join(""); | |
18820 var dirData = directory.join(""); | |
18821 | |
18822 var dirEnd = ""; | |
18823 | |
18824 // end of central dir signature | |
18825 dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END + | |
18826 // number of this disk | |
18827 "\x00\x00" + | |
18828 // number of the disk with the start of the central directory | |
18829 "\x00\x00" + | |
18830 // total number of entries in the central directory on this disk | |
18831 decToHex(files.length, 2) + | |
18832 // total number of entries in the central directory | |
18833 decToHex(files.length, 2) + | |
18834 // size of the central directory 4 bytes | |
18835 decToHex(dirData.length, 4) + | |
18836 // offset of start of central directory with respect to the starting disk number | |
18837 decToHex(fileData.length, 4) + | |
18838 // .ZIP file comment length | |
18839 "\x00\x00"; | |
18840 | |
18841 var zip = fileData + dirData + dirEnd; | |
18842 | |
18843 | |
18844 switch(options.type.toLowerCase()) { | |
18845 case "uint8array" : | |
18846 return JSZip.utils.string2Uint8Array(zip); | |
18847 case "arraybuffer" : | |
18848 return JSZip.utils.string2Uint8Array(zip).buffer; | |
18849 case "blob" : | |
18850 return JSZip.utils.string2Blob(zip); | |
18851 case "base64" : | |
18852 return (options.base64) ? JSZipBase64.encode(zip) : zip; | |
18853 default : // case "string" : | |
18854 return zip; | |
18855 } | |
18856 }, | |
18857 | |
18858 /** | |
18859 * | |
18860 * Javascript crc32 | |
18861 * http://www.webtoolkit.info/ | |
18862 * | |
18863 */ | |
18864 crc32 : function(str, crc) { | |
18865 | |
18866 if (str === "" || typeof str === "undefined") { | |
18867 return 0; | |
18868 } | |
18869 | |
18870 var table = [ | |
18871 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, | |
18872 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, | |
18873 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, | |
18874 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, | |
18875 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, | |
18876 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, | |
18877 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, | |
18878 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, | |
18879 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, | |
18880 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, | |
18881 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, | |
18882 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, | |
18883 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, | |
18884 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, | |
18885 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, | |
18886 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, | |
18887 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, | |
18888 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, | |
18889 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, | |
18890 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, | |
18891 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, | |
18892 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, | |
18893 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, | |
18894 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, | |
18895 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, | |
18896 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, | |
18897 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, | |
18898 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, | |
18899 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, | |
18900 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, | |
18901 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, | |
18902 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, | |
18903 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, | |
18904 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, | |
18905 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, | |
18906 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, | |
18907 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, | |
18908 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, | |
18909 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, | |
18910 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, | |
18911 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, | |
18912 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, | |
18913 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, | |
18914 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, | |
18915 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, | |
18916 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, | |
18917 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, | |
18918 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, | |
18919 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, | |
18920 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, | |
18921 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, | |
18922 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, | |
18923 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, | |
18924 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, | |
18925 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, | |
18926 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, | |
18927 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, | |
18928 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, | |
18929 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, | |
18930 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, | |
18931 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, | |
18932 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, | |
18933 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, | |
18934 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D | |
18935 ]; | |
18936 | |
18937 if (typeof(crc) == "undefined") { crc = 0; } | |
18938 var x = 0; | |
18939 var y = 0; | |
18940 | |
18941 crc = crc ^ (-1); | |
18942 for( var i = 0, iTop = str.length; i < iTop; i++ ) { | |
18943 y = ( crc ^ str.charCodeAt( i ) ) & 0xFF; | |
18944 x = table[y]; | |
18945 crc = ( crc >>> 8 ) ^ x; | |
18946 } | |
18947 | |
18948 return crc ^ (-1); | |
18949 }, | |
18950 | |
18951 // Inspired by http://my.opera.com/GreyWyvern/blog/show.dml/1725165 | |
18952 clone : function() { | |
18953 var newObj = new JSZip(); | |
18954 for (var i in this) { | |
18955 if (typeof this[i] !== "function") { | |
18956 newObj[i] = this[i]; | |
18957 } | |
18958 } | |
18959 return newObj; | |
18960 }, | |
18961 | |
18962 | |
18963 /** | |
18964 * http://www.webtoolkit.info/javascript-utf8.html | |
18965 */ | |
18966 utf8encode : function (string) { | |
18967 string = string.replace(/\r\n/g,"\n"); | |
18968 var utftext = ""; | |
18969 | |
18970 for (var n = 0; n < string.length; n++) { | |
18971 | |
18972 var c = string.charCodeAt(n); | |
18973 | |
18974 if (c < 128) { | |
18975 utftext += String.fromCharCode(c); | |
18976 } else if ((c > 127) && (c < 2048)) { | |
18977 utftext += String.fromCharCode((c >> 6) | 192); | |
18978 utftext += String.fromCharCode((c & 63) | 128); | |
18979 } else { | |
18980 utftext += String.fromCharCode((c >> 12) | 224); | |
18981 utftext += String.fromCharCode(((c >> 6) & 63) | 128); | |
18982 utftext += String.fromCharCode((c & 63) | 128); | |
18983 } | |
18984 | |
18985 } | |
18986 | |
18987 return utftext; | |
18988 }, | |
18989 | |
18990 /** | |
18991 * http://www.webtoolkit.info/javascript-utf8.html | |
18992 */ | |
18993 utf8decode : function (utftext) { | |
18994 var string = ""; | |
18995 var i = 0; | |
18996 var c = 0, c1 = 0, c2 = 0, c3 = 0; | |
18997 | |
18998 while ( i < utftext.length ) { | |
18999 | |
19000 c = utftext.charCodeAt(i); | |
19001 | |
19002 if (c < 128) { | |
19003 string += String.fromCharCode(c); | |
19004 i++; | |
19005 } else if ((c > 191) && (c < 224)) { | |
19006 c2 = utftext.charCodeAt(i+1); | |
19007 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); | |
19008 i += 2; | |
19009 } else { | |
19010 c2 = utftext.charCodeAt(i+1); | |
19011 c3 = utftext.charCodeAt(i+2); | |
19012 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); | |
19013 i += 3; | |
19014 } | |
19015 | |
19016 } | |
19017 | |
19018 return string; | |
19019 } | |
19020 }; | |
19021 }()); | |
19022 | |
19023 /* | |
19024 * Compression methods | |
19025 * This object is filled in as follow : | |
19026 * name : { | |
19027 * magic // the 2 bytes indentifying the compression method | |
19028 * compress // function, take the uncompressed content and return it compressed. | |
19029 * uncompress // function, take the compressed content and return it uncompressed. | |
19030 * } | |
19031 * | |
19032 * STORE is the default compression method, so it's included in this file. | |
19033 * Other methods should go to separated files : the user wants modularity. | |
19034 */ | |
19035 JSZip.compressions = { | |
19036 "STORE" : { | |
19037 magic : "\x00\x00", | |
19038 compress : function (content) { | |
19039 return content; // no compression | |
19040 }, | |
19041 uncompress : function (content) { | |
19042 return content; // no compression | |
19043 } | |
19044 } | |
19045 }; | |
19046 | |
19047 /* | |
19048 * List features that require a modern browser, and if the current browser support them. | |
19049 */ | |
19050 JSZip.support = { | |
19051 // contains true if JSZip can read/generate ArrayBuffer, false otherwise. | |
19052 arraybuffer : (function(){ | |
19053 return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; | |
19054 })(), | |
19055 // contains true if JSZip can read/generate Uint8Array, false otherwise. | |
19056 uint8array : (function(){ | |
19057 return typeof Uint8Array !== "undefined"; | |
19058 })(), | |
19059 // contains true if JSZip can read/generate Blob, false otherwise. | |
19060 blob : (function(){ | |
19061 // the spec started with BlobBuilder then replaced it with a construtor for Blob. | |
19062 // Result : we have browsers that : | |
19063 // * know the BlobBuilder (but with prefix) | |
19064 // * know the Blob constructor | |
19065 // * know about Blob but not about how to build them | |
19066 // About the "=== 0" test : if given the wrong type, it may be converted to a string. | |
19067 // Instead of an empty content, we will get "[object Uint8Array]" for example. | |
19068 if (typeof ArrayBuffer === "undefined") { | |
19069 return false; | |
19070 } | |
19071 var buffer = new ArrayBuffer(0); | |
19072 try { | |
19073 return new Blob([buffer], { type: "application/zip" }).size === 0; | |
19074 } | |
19075 catch(e) {} | |
19076 | |
19077 try { | |
19078 var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || | |
19079 window.MozBlobBuilder || window.MSBlobBuilder)(); | |
19080 builder.append(buffer); | |
19081 return builder.getBlob('application/zip').size === 0; | |
19082 } | |
19083 catch(e) {} | |
19084 | |
19085 return false; | |
19086 })() | |
19087 }; | |
19088 | |
19089 JSZip.utils = { | |
19090 /** | |
19091 * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. | |
19092 * @param {string} str the string to transform. | |
19093 * @return {String} the binary string. | |
19094 */ | |
19095 string2binary : function (str) { | |
19096 var result = ""; | |
19097 for (var i = 0; i < str.length; i++) { | |
19098 result += String.fromCharCode(str.charCodeAt(i) & 0xff); | |
19099 } | |
19100 return result; | |
19101 }, | |
19102 /** | |
19103 * Create a Uint8Array from the string. | |
19104 * @param {string} str the string to transform. | |
19105 * @return {Uint8Array} the typed array. | |
19106 * @throws {Error} an Error if the browser doesn't support the requested feature. | |
19107 */ | |
19108 string2Uint8Array : function (str) { | |
19109 if (!JSZip.support.uint8array) { | |
19110 throw new Error("Uint8Array is not supported by this browser"); | |
19111 } | |
19112 var buffer = new ArrayBuffer(str.length); | |
19113 var bufferView = new Uint8Array(buffer); | |
19114 for(var i = 0; i < str.length; i++) { | |
19115 bufferView[i] = str.charCodeAt(i); | |
19116 } | |
19117 | |
19118 return bufferView; | |
19119 }, | |
19120 | |
19121 /** | |
19122 * Create a string from the Uint8Array. | |
19123 * @param {Uint8Array} array the array to transform. | |
19124 * @return {string} the string. | |
19125 * @throws {Error} an Error if the browser doesn't support the requested feature. | |
19126 */ | |
19127 uint8Array2String : function (array) { | |
19128 if (!JSZip.support.uint8array) { | |
19129 throw new Error("Uint8Array is not supported by this browser"); | |
19130 } | |
19131 var result = ""; | |
19132 for(var i = 0; i < array.length; i++) { | |
19133 result += String.fromCharCode(array[i]); | |
19134 } | |
19135 | |
19136 return result; | |
19137 }, | |
19138 /** | |
19139 * Create a blob from the given string. | |
19140 * @param {string} str the string to transform. | |
19141 * @return {Blob} the string. | |
19142 * @throws {Error} an Error if the browser doesn't support the requested feature. | |
19143 */ | |
19144 string2Blob : function (str) { | |
19145 if (!JSZip.support.blob) { | |
19146 throw new Error("Blob is not supported by this browser"); | |
19147 } | |
19148 | |
19149 var buffer = JSZip.utils.string2Uint8Array(str).buffer; | |
19150 try { | |
19151 // Blob constructor | |
19152 return new Blob([buffer], { type: "application/zip" }); | |
19153 } | |
19154 catch(e) {} | |
19155 | |
19156 try { | |
19157 // deprecated, browser only, old way | |
19158 var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || | |
19159 window.MozBlobBuilder || window.MSBlobBuilder)(); | |
19160 builder.append(buffer); | |
19161 return builder.getBlob('application/zip'); | |
19162 } | |
19163 catch(e) {} | |
19164 | |
19165 // well, fuck ?! | |
19166 throw new Error("Bug : can't construct the Blob."); | |
19167 } | |
19168 }; | |
19169 | |
19170 /** | |
19171 * | |
19172 * Base64 encode / decode | |
19173 * http://www.webtoolkit.info/ | |
19174 * | |
19175 * Hacked so that it doesn't utf8 en/decode everything | |
19176 **/ | |
19177 var JSZipBase64 = (function() { | |
19178 // private property | |
19179 var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; | |
19180 | |
19181 return { | |
19182 // public method for encoding | |
19183 encode : function(input, utf8) { | |
19184 var output = ""; | |
19185 var chr1, chr2, chr3, enc1, enc2, enc3, enc4; | |
19186 var i = 0; | |
19187 | |
19188 while (i < input.length) { | |
19189 | |
19190 chr1 = input.charCodeAt(i++); | |
19191 chr2 = input.charCodeAt(i++); | |
19192 chr3 = input.charCodeAt(i++); | |
19193 | |
19194 enc1 = chr1 >> 2; | |
19195 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | |
19196 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | |
19197 enc4 = chr3 & 63; | |
19198 | |
19199 if (isNaN(chr2)) { | |
19200 enc3 = enc4 = 64; | |
19201 } else if (isNaN(chr3)) { | |
19202 enc4 = 64; | |
19203 } | |
19204 | |
19205 output = output + | |
19206 _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + | |
19207 _keyStr.charAt(enc3) + _keyStr.charAt(enc4); | |
19208 | |
19209 } | |
19210 | |
19211 return output; | |
19212 }, | |
19213 | |
19214 // public method for decoding | |
19215 decode : function(input, utf8) { | |
19216 var output = ""; | |
19217 var chr1, chr2, chr3; | |
19218 var enc1, enc2, enc3, enc4; | |
19219 var i = 0; | |
19220 | |
19221 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); | |
19222 | |
19223 while (i < input.length) { | |
19224 | |
19225 enc1 = _keyStr.indexOf(input.charAt(i++)); | |
19226 enc2 = _keyStr.indexOf(input.charAt(i++)); | |
19227 enc3 = _keyStr.indexOf(input.charAt(i++)); | |
19228 enc4 = _keyStr.indexOf(input.charAt(i++)); | |
19229 | |
19230 chr1 = (enc1 << 2) | (enc2 >> 4); | |
19231 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | |
19232 chr3 = ((enc3 & 3) << 6) | enc4; | |
19233 | |
19234 output = output + String.fromCharCode(chr1); | |
19235 | |
19236 if (enc3 != 64) { | |
19237 output = output + String.fromCharCode(chr2); | |
19238 } | |
19239 if (enc4 != 64) { | |
19240 output = output + String.fromCharCode(chr3); | |
19241 } | |
19242 | |
19243 } | |
19244 | |
19245 return output; | |
19246 | |
19247 } | |
19248 }; | |
19249 }()); | |
19250 | |
19251 // enforcing Stuk's coding style | |
19252 // vim: set shiftwidth=3 softtabstop=3: | |
19253 /* | |
19254 * Port of a script by Masanao Izumo. | |
19255 * | |
19256 * Only changes : wrap all the variables in a function and add the | |
19257 * main function to JSZip (DEFLATE compression method). | |
19258 * Everything else was written by M. Izumo. | |
19259 * | |
19260 * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt | |
19261 */ | |
19262 | |
19263 if(!JSZip) { | |
19264 throw "JSZip not defined"; | |
19265 } | |
19266 | |
19267 /* | |
19268 * Original: | |
19269 * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt | |
19270 */ | |
19271 | |
19272 (function(){ | |
19273 | |
19274 /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp> | |
19275 * Version: 1.0.1 | |
19276 * LastModified: Dec 25 1999 | |
19277 */ | |
19278 | |
19279 /* Interface: | |
19280 * data = zip_deflate(src); | |
19281 */ | |
19282 | |
19283 /* constant parameters */ | |
19284 var zip_WSIZE = 32768; // Sliding Window size | |
19285 var zip_STORED_BLOCK = 0; | |
19286 var zip_STATIC_TREES = 1; | |
19287 var zip_DYN_TREES = 2; | |
19288 | |
19289 /* for deflate */ | |
19290 var zip_DEFAULT_LEVEL = 6; | |
19291 var zip_FULL_SEARCH = true; | |
19292 var zip_INBUFSIZ = 32768; // Input buffer size | |
19293 var zip_INBUF_EXTRA = 64; // Extra buffer | |
19294 var zip_OUTBUFSIZ = 1024 * 8; | |
19295 var zip_window_size = 2 * zip_WSIZE; | |
19296 var zip_MIN_MATCH = 3; | |
19297 var zip_MAX_MATCH = 258; | |
19298 var zip_BITS = 16; | |
19299 // for SMALL_MEM | |
19300 var zip_LIT_BUFSIZE = 0x2000; | |
19301 var zip_HASH_BITS = 13; | |
19302 // for MEDIUM_MEM | |
19303 // var zip_LIT_BUFSIZE = 0x4000; | |
19304 // var zip_HASH_BITS = 14; | |
19305 // for BIG_MEM | |
19306 // var zip_LIT_BUFSIZE = 0x8000; | |
19307 // var zip_HASH_BITS = 15; | |
19308 if(zip_LIT_BUFSIZE > zip_INBUFSIZ) | |
19309 alert("error: zip_INBUFSIZ is too small"); | |
19310 if((zip_WSIZE<<1) > (1<<zip_BITS)) | |
19311 alert("error: zip_WSIZE is too large"); | |
19312 if(zip_HASH_BITS > zip_BITS-1) | |
19313 alert("error: zip_HASH_BITS is too large"); | |
19314 if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258) | |
19315 alert("error: Code too clever"); | |
19316 var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE; | |
19317 var zip_HASH_SIZE = 1 << zip_HASH_BITS; | |
19318 var zip_HASH_MASK = zip_HASH_SIZE - 1; | |
19319 var zip_WMASK = zip_WSIZE - 1; | |
19320 var zip_NIL = 0; // Tail of hash chains | |
19321 var zip_TOO_FAR = 4096; | |
19322 var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1; | |
19323 var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD; | |
19324 var zip_SMALLEST = 1; | |
19325 var zip_MAX_BITS = 15; | |
19326 var zip_MAX_BL_BITS = 7; | |
19327 var zip_LENGTH_CODES = 29; | |
19328 var zip_LITERALS =256; | |
19329 var zip_END_BLOCK = 256; | |
19330 var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES; | |
19331 var zip_D_CODES = 30; | |
19332 var zip_BL_CODES = 19; | |
19333 var zip_REP_3_6 = 16; | |
19334 var zip_REPZ_3_10 = 17; | |
19335 var zip_REPZ_11_138 = 18; | |
19336 var zip_HEAP_SIZE = 2 * zip_L_CODES + 1; | |
19337 var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / | |
19338 zip_MIN_MATCH); | |
19339 | |
19340 /* variables */ | |
19341 var zip_free_queue; | |
19342 var zip_qhead, zip_qtail; | |
19343 var zip_initflag; | |
19344 var zip_outbuf = null; | |
19345 var zip_outcnt, zip_outoff; | |
19346 var zip_complete; | |
19347 var zip_window; | |
19348 var zip_d_buf; | |
19349 var zip_l_buf; | |
19350 var zip_prev; | |
19351 var zip_bi_buf; | |
19352 var zip_bi_valid; | |
19353 var zip_block_start; | |
19354 var zip_ins_h; | |
19355 var zip_hash_head; | |
19356 var zip_prev_match; | |
19357 var zip_match_available; | |
19358 var zip_match_length; | |
19359 var zip_prev_length; | |
19360 var zip_strstart; | |
19361 var zip_match_start; | |
19362 var zip_eofile; | |
19363 var zip_lookahead; | |
19364 var zip_max_chain_length; | |
19365 var zip_max_lazy_match; | |
19366 var zip_compr_level; | |
19367 var zip_good_match; | |
19368 var zip_nice_match; | |
19369 var zip_dyn_ltree; | |
19370 var zip_dyn_dtree; | |
19371 var zip_static_ltree; | |
19372 var zip_static_dtree; | |
19373 var zip_bl_tree; | |
19374 var zip_l_desc; | |
19375 var zip_d_desc; | |
19376 var zip_bl_desc; | |
19377 var zip_bl_count; | |
19378 var zip_heap; | |
19379 var zip_heap_len; | |
19380 var zip_heap_max; | |
19381 var zip_depth; | |
19382 var zip_length_code; | |
19383 var zip_dist_code; | |
19384 var zip_base_length; | |
19385 var zip_base_dist; | |
19386 var zip_flag_buf; | |
19387 var zip_last_lit; | |
19388 var zip_last_dist; | |
19389 var zip_last_flags; | |
19390 var zip_flags; | |
19391 var zip_flag_bit; | |
19392 var zip_opt_len; | |
19393 var zip_static_len; | |
19394 var zip_deflate_data; | |
19395 var zip_deflate_pos; | |
19396 | |
19397 /* objects (deflate) */ | |
19398 | |
19399 var zip_DeflateCT = function() { | |
19400 this.fc = 0; // frequency count or bit string | |
19401 this.dl = 0; // father node in Huffman tree or length of bit string | |
19402 } | |
19403 | |
19404 var zip_DeflateTreeDesc = function() { | |
19405 this.dyn_tree = null; // the dynamic tree | |
19406 this.static_tree = null; // corresponding static tree or NULL | |
19407 this.extra_bits = null; // extra bits for each code or NULL | |
19408 this.extra_base = 0; // base index for extra_bits | |
19409 this.elems = 0; // max number of elements in the tree | |
19410 this.max_length = 0; // max bit length for the codes | |
19411 this.max_code = 0; // largest code with non zero frequency | |
19412 } | |
19413 | |
19414 /* Values for max_lazy_match, good_match and max_chain_length, depending on | |
19415 * the desired pack level (0..9). The values given below have been tuned to | |
19416 * exclude worst case performance for pathological files. Better values may be | |
19417 * found for specific files. | |
19418 */ | |
19419 var zip_DeflateConfiguration = function(a, b, c, d) { | |
19420 this.good_length = a; // reduce lazy search above this match length | |
19421 this.max_lazy = b; // do not perform lazy search above this match length | |
19422 this.nice_length = c; // quit search above this match length | |
19423 this.max_chain = d; | |
19424 } | |
19425 | |
19426 var zip_DeflateBuffer = function() { | |
19427 this.next = null; | |
19428 this.len = 0; | |
19429 this.ptr = new Array(zip_OUTBUFSIZ); | |
19430 this.off = 0; | |
19431 } | |
19432 | |
19433 /* constant tables */ | |
19434 var zip_extra_lbits = new Array( | |
19435 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0); | |
19436 var zip_extra_dbits = new Array( | |
19437 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13); | |
19438 var zip_extra_blbits = new Array( | |
19439 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7); | |
19440 var zip_bl_order = new Array( | |
19441 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15); | |
19442 var zip_configuration_table = new Array( | |
19443 new zip_DeflateConfiguration(0, 0, 0, 0), | |
19444 new zip_DeflateConfiguration(4, 4, 8, 4), | |
19445 new zip_DeflateConfiguration(4, 5, 16, 8), | |
19446 new zip_DeflateConfiguration(4, 6, 32, 32), | |
19447 new zip_DeflateConfiguration(4, 4, 16, 16), | |
19448 new zip_DeflateConfiguration(8, 16, 32, 32), | |
19449 new zip_DeflateConfiguration(8, 16, 128, 128), | |
19450 new zip_DeflateConfiguration(8, 32, 128, 256), | |
19451 new zip_DeflateConfiguration(32, 128, 258, 1024), | |
19452 new zip_DeflateConfiguration(32, 258, 258, 4096)); | |
19453 | |
19454 | |
19455 /* routines (deflate) */ | |
19456 | |
19457 var zip_deflate_start = function(level) { | |
19458 var i; | |
19459 | |
19460 if(!level) | |
19461 level = zip_DEFAULT_LEVEL; | |
19462 else if(level < 1) | |
19463 level = 1; | |
19464 else if(level > 9) | |
19465 level = 9; | |
19466 | |
19467 zip_compr_level = level; | |
19468 zip_initflag = false; | |
19469 zip_eofile = false; | |
19470 if(zip_outbuf != null) | |
19471 return; | |
19472 | |
19473 zip_free_queue = zip_qhead = zip_qtail = null; | |
19474 zip_outbuf = new Array(zip_OUTBUFSIZ); | |
19475 zip_window = new Array(zip_window_size); | |
19476 zip_d_buf = new Array(zip_DIST_BUFSIZE); | |
19477 zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); | |
19478 zip_prev = new Array(1 << zip_BITS); | |
19479 zip_dyn_ltree = new Array(zip_HEAP_SIZE); | |
19480 for(i = 0; i < zip_HEAP_SIZE; i++) | |
19481 zip_dyn_ltree[i] = new zip_DeflateCT(); | |
19482 zip_dyn_dtree = new Array(2*zip_D_CODES+1); | |
19483 for(i = 0; i < 2*zip_D_CODES+1; i++) | |
19484 zip_dyn_dtree[i] = new zip_DeflateCT(); | |
19485 zip_static_ltree = new Array(zip_L_CODES+2); | |
19486 for(i = 0; i < zip_L_CODES+2; i++) | |
19487 zip_static_ltree[i] = new zip_DeflateCT(); | |
19488 zip_static_dtree = new Array(zip_D_CODES); | |
19489 for(i = 0; i < zip_D_CODES; i++) | |
19490 zip_static_dtree[i] = new zip_DeflateCT(); | |
19491 zip_bl_tree = new Array(2*zip_BL_CODES+1); | |
19492 for(i = 0; i < 2*zip_BL_CODES+1; i++) | |
19493 zip_bl_tree[i] = new zip_DeflateCT(); | |
19494 zip_l_desc = new zip_DeflateTreeDesc(); | |
19495 zip_d_desc = new zip_DeflateTreeDesc(); | |
19496 zip_bl_desc = new zip_DeflateTreeDesc(); | |
19497 zip_bl_count = new Array(zip_MAX_BITS+1); | |
19498 zip_heap = new Array(2*zip_L_CODES+1); | |
19499 zip_depth = new Array(2*zip_L_CODES+1); | |
19500 zip_length_code = new Array(zip_MAX_MATCH-zip_MIN_MATCH+1); | |
19501 zip_dist_code = new Array(512); | |
19502 zip_base_length = new Array(zip_LENGTH_CODES); | |
19503 zip_base_dist = new Array(zip_D_CODES); | |
19504 zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8)); | |
19505 } | |
19506 | |
19507 var zip_deflate_end = function() { | |
19508 zip_free_queue = zip_qhead = zip_qtail = null; | |
19509 zip_outbuf = null; | |
19510 zip_window = null; | |
19511 zip_d_buf = null; | |
19512 zip_l_buf = null; | |
19513 zip_prev = null; | |
19514 zip_dyn_ltree = null; | |
19515 zip_dyn_dtree = null; | |
19516 zip_static_ltree = null; | |
19517 zip_static_dtree = null; | |
19518 zip_bl_tree = null; | |
19519 zip_l_desc = null; | |
19520 zip_d_desc = null; | |
19521 zip_bl_desc = null; | |
19522 zip_bl_count = null; | |
19523 zip_heap = null; | |
19524 zip_depth = null; | |
19525 zip_length_code = null; | |
19526 zip_dist_code = null; | |
19527 zip_base_length = null; | |
19528 zip_base_dist = null; | |
19529 zip_flag_buf = null; | |
19530 } | |
19531 | |
19532 var zip_reuse_queue = function(p) { | |
19533 p.next = zip_free_queue; | |
19534 zip_free_queue = p; | |
19535 } | |
19536 | |
19537 var zip_new_queue = function() { | |
19538 var p; | |
19539 | |
19540 if(zip_free_queue != null) | |
19541 { | |
19542 p = zip_free_queue; | |
19543 zip_free_queue = zip_free_queue.next; | |
19544 } | |
19545 else | |
19546 p = new zip_DeflateBuffer(); | |
19547 p.next = null; | |
19548 p.len = p.off = 0; | |
19549 | |
19550 return p; | |
19551 } | |
19552 | |
19553 var zip_head1 = function(i) { | |
19554 return zip_prev[zip_WSIZE + i]; | |
19555 } | |
19556 | |
19557 var zip_head2 = function(i, val) { | |
19558 return zip_prev[zip_WSIZE + i] = val; | |
19559 } | |
19560 | |
19561 /* put_byte is used for the compressed output, put_ubyte for the | |
19562 * uncompressed output. However unlzw() uses window for its | |
19563 * suffix table instead of its output buffer, so it does not use put_ubyte | |
19564 * (to be cleaned up). | |
19565 */ | |
19566 var zip_put_byte = function(c) { | |
19567 zip_outbuf[zip_outoff + zip_outcnt++] = c; | |
19568 if(zip_outoff + zip_outcnt == zip_OUTBUFSIZ) | |
19569 zip_qoutbuf(); | |
19570 } | |
19571 | |
19572 /* Output a 16 bit value, lsb first */ | |
19573 var zip_put_short = function(w) { | |
19574 w &= 0xffff; | |
19575 if(zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { | |
19576 zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); | |
19577 zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); | |
19578 } else { | |
19579 zip_put_byte(w & 0xff); | |
19580 zip_put_byte(w >>> 8); | |
19581 } | |
19582 } | |
19583 | |
19584 /* ========================================================================== | |
19585 * Insert string s in the dictionary and set match_head to the previous head | |
19586 * of the hash chain (the most recent string with same hash key). Return | |
19587 * the previous length of the hash chain. | |
19588 * IN assertion: all calls to to INSERT_STRING are made with consecutive | |
19589 * input characters and the first MIN_MATCH bytes of s are valid | |
19590 * (except for the last MIN_MATCH-1 bytes of the input file). | |
19591 */ | |
19592 var zip_INSERT_STRING = function() { | |
19593 zip_ins_h = ((zip_ins_h << zip_H_SHIFT) | |
19594 ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff)) | |
19595 & zip_HASH_MASK; | |
19596 zip_hash_head = zip_head1(zip_ins_h); | |
19597 zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; | |
19598 zip_head2(zip_ins_h, zip_strstart); | |
19599 } | |
19600 | |
19601 /* Send a code of the given tree. c and tree must not have side effects */ | |
19602 var zip_SEND_CODE = function(c, tree) { | |
19603 zip_send_bits(tree[c].fc, tree[c].dl); | |
19604 } | |
19605 | |
19606 /* Mapping from a distance to a distance code. dist is the distance - 1 and | |
19607 * must not have side effects. dist_code[256] and dist_code[257] are never | |
19608 * used. | |
19609 */ | |
19610 var zip_D_CODE = function(dist) { | |
19611 return (dist < 256 ? zip_dist_code[dist] | |
19612 : zip_dist_code[256 + (dist>>7)]) & 0xff; | |
19613 } | |
19614 | |
19615 /* ========================================================================== | |
19616 * Compares to subtrees, using the tree depth as tie breaker when | |
19617 * the subtrees have equal frequency. This minimizes the worst case length. | |
19618 */ | |
19619 var zip_SMALLER = function(tree, n, m) { | |
19620 return tree[n].fc < tree[m].fc || | |
19621 (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); | |
19622 } | |
19623 | |
19624 /* ========================================================================== | |
19625 * read string data | |
19626 */ | |
19627 var zip_read_buff = function(buff, offset, n) { | |
19628 var i; | |
19629 for(i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) | |
19630 buff[offset + i] = | |
19631 zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff; | |
19632 return i; | |
19633 } | |
19634 | |
19635 /* ========================================================================== | |
19636 * Initialize the "longest match" routines for a new file | |
19637 */ | |
19638 var zip_lm_init = function() { | |
19639 var j; | |
19640 | |
19641 /* Initialize the hash table. */ | |
19642 for(j = 0; j < zip_HASH_SIZE; j++) | |
19643 // zip_head2(j, zip_NIL); | |
19644 zip_prev[zip_WSIZE + j] = 0; | |
19645 /* prev will be initialized on the fly */ | |
19646 | |
19647 /* Set the default configuration parameters: | |
19648 */ | |
19649 zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; | |
19650 zip_good_match = zip_configuration_table[zip_compr_level].good_length; | |
19651 if(!zip_FULL_SEARCH) | |
19652 zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; | |
19653 zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; | |
19654 | |
19655 zip_strstart = 0; | |
19656 zip_block_start = 0; | |
19657 | |
19658 zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); | |
19659 if(zip_lookahead <= 0) { | |
19660 zip_eofile = true; | |
19661 zip_lookahead = 0; | |
19662 return; | |
19663 } | |
19664 zip_eofile = false; | |
19665 /* Make sure that we always have enough lookahead. This is important | |
19666 * if input comes from a device such as a tty. | |
19667 */ | |
19668 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) | |
19669 zip_fill_window(); | |
19670 | |
19671 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is | |
19672 * not important since only literal bytes will be emitted. | |
19673 */ | |
19674 zip_ins_h = 0; | |
19675 for(j = 0; j < zip_MIN_MATCH - 1; j++) { | |
19676 // UPDATE_HASH(ins_h, window[j]); | |
19677 zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; | |
19678 } | |
19679 } | |
19680 | |
19681 /* ========================================================================== | |
19682 * Set match_start to the longest match starting at the given string and | |
19683 * return its length. Matches shorter or equal to prev_length are discarded, | |
19684 * in which case the result is equal to prev_length and match_start is | |
19685 * garbage. | |
19686 * IN assertions: cur_match is the head of the hash chain for the current | |
19687 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 | |
19688 */ | |
19689 var zip_longest_match = function(cur_match) { | |
19690 var chain_length = zip_max_chain_length; // max hash chain length | |
19691 var scanp = zip_strstart; // current string | |
19692 var matchp; // matched string | |
19693 var len; // length of current match | |
19694 var best_len = zip_prev_length; // best match length so far | |
19695 | |
19696 /* Stop when cur_match becomes <= limit. To simplify the code, | |
19697 * we prevent matches with the string of window index 0. | |
19698 */ | |
19699 var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); | |
19700 | |
19701 var strendp = zip_strstart + zip_MAX_MATCH; | |
19702 var scan_end1 = zip_window[scanp + best_len - 1]; | |
19703 var scan_end = zip_window[scanp + best_len]; | |
19704 | |
19705 /* Do not waste too much time if we already have a good match: */ | |
19706 if(zip_prev_length >= zip_good_match) | |
19707 chain_length >>= 2; | |
19708 | |
19709 // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); | |
19710 | |
19711 do { | |
19712 // Assert(cur_match < encoder->strstart, "no future"); | |
19713 matchp = cur_match; | |
19714 | |
19715 /* Skip to next match if the match length cannot increase | |
19716 * or if the match length is less than 2: | |
19717 */ | |
19718 if(zip_window[matchp + best_len] != scan_end || | |
19719 zip_window[matchp + best_len - 1] != scan_end1 || | |
19720 zip_window[matchp] != zip_window[scanp] || | |
19721 zip_window[++matchp] != zip_window[scanp + 1]) { | |
19722 continue; | |
19723 } | |
19724 | |
19725 /* The check at best_len-1 can be removed because it will be made | |
19726 * again later. (This heuristic is not always a win.) | |
19727 * It is not necessary to compare scan[2] and match[2] since they | |
19728 * are always equal when the other bytes match, given that | |
19729 * the hash keys are equal and that HASH_BITS >= 8. | |
19730 */ | |
19731 scanp += 2; | |
19732 matchp++; | |
19733 | |
19734 /* We check for insufficient lookahead only every 8th comparison; | |
19735 * the 256th check will be made at strstart+258. | |
19736 */ | |
19737 do { | |
19738 } while(zip_window[++scanp] == zip_window[++matchp] && | |
19739 zip_window[++scanp] == zip_window[++matchp] && | |
19740 zip_window[++scanp] == zip_window[++matchp] && | |
19741 zip_window[++scanp] == zip_window[++matchp] && | |
19742 zip_window[++scanp] == zip_window[++matchp] && | |
19743 zip_window[++scanp] == zip_window[++matchp] && | |
19744 zip_window[++scanp] == zip_window[++matchp] && | |
19745 zip_window[++scanp] == zip_window[++matchp] && | |
19746 scanp < strendp); | |
19747 | |
19748 len = zip_MAX_MATCH - (strendp - scanp); | |
19749 scanp = strendp - zip_MAX_MATCH; | |
19750 | |
19751 if(len > best_len) { | |
19752 zip_match_start = cur_match; | |
19753 best_len = len; | |
19754 if(zip_FULL_SEARCH) { | |
19755 if(len >= zip_MAX_MATCH) break; | |
19756 } else { | |
19757 if(len >= zip_nice_match) break; | |
19758 } | |
19759 | |
19760 scan_end1 = zip_window[scanp + best_len-1]; | |
19761 scan_end = zip_window[scanp + best_len]; | |
19762 } | |
19763 } while((cur_match = zip_prev[cur_match & zip_WMASK]) > limit | |
19764 && --chain_length != 0); | |
19765 | |
19766 return best_len; | |
19767 } | |
19768 | |
19769 /* ========================================================================== | |
19770 * Fill the window when the lookahead becomes insufficient. | |
19771 * Updates strstart and lookahead, and sets eofile if end of input file. | |
19772 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 | |
19773 * OUT assertions: at least one byte has been read, or eofile is set; | |
19774 * file reads are performed for at least two bytes (required for the | |
19775 * translate_eol option). | |
19776 */ | |
19777 var zip_fill_window = function() { | |
19778 var n, m; | |
19779 | |
19780 // Amount of free space at the end of the window. | |
19781 var more = zip_window_size - zip_lookahead - zip_strstart; | |
19782 | |
19783 /* If the window is almost full and there is insufficient lookahead, | |
19784 * move the upper half to the lower one to make room in the upper half. | |
19785 */ | |
19786 if(more == -1) { | |
19787 /* Very unlikely, but possible on 16 bit machine if strstart == 0 | |
19788 * and lookahead == 1 (input done one byte at time) | |
19789 */ | |
19790 more--; | |
19791 } else if(zip_strstart >= zip_WSIZE + zip_MAX_DIST) { | |
19792 /* By the IN assertion, the window is not empty so we can't confuse | |
19793 * more == 0 with more == 64K on a 16 bit machine. | |
19794 */ | |
19795 // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); | |
19796 | |
19797 // System.arraycopy(window, WSIZE, window, 0, WSIZE); | |
19798 for(n = 0; n < zip_WSIZE; n++) | |
19799 zip_window[n] = zip_window[n + zip_WSIZE]; | |
19800 | |
19801 zip_match_start -= zip_WSIZE; | |
19802 zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */ | |
19803 zip_block_start -= zip_WSIZE; | |
19804 | |
19805 for(n = 0; n < zip_HASH_SIZE; n++) { | |
19806 m = zip_head1(n); | |
19807 zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); | |
19808 } | |
19809 for(n = 0; n < zip_WSIZE; n++) { | |
19810 /* If n is not on any hash chain, prev[n] is garbage but | |
19811 * its value will never be used. | |
19812 */ | |
19813 m = zip_prev[n]; | |
19814 zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); | |
19815 } | |
19816 more += zip_WSIZE; | |
19817 } | |
19818 // At this point, more >= 2 | |
19819 if(!zip_eofile) { | |
19820 n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); | |
19821 if(n <= 0) | |
19822 zip_eofile = true; | |
19823 else | |
19824 zip_lookahead += n; | |
19825 } | |
19826 } | |
19827 | |
19828 /* ========================================================================== | |
19829 * Processes a new input file and return its compressed length. This | |
19830 * function does not perform lazy evaluationof matches and inserts | |
19831 * new strings in the dictionary only for unmatched strings or for short | |
19832 * matches. It is used only for the fast compression options. | |
19833 */ | |
19834 var zip_deflate_fast = function() { | |
19835 while(zip_lookahead != 0 && zip_qhead == null) { | |
19836 var flush; // set if current block must be flushed | |
19837 | |
19838 /* Insert the string window[strstart .. strstart+2] in the | |
19839 * dictionary, and set hash_head to the head of the hash chain: | |
19840 */ | |
19841 zip_INSERT_STRING(); | |
19842 | |
19843 /* Find the longest match, discarding those <= prev_length. | |
19844 * At this point we have always match_length < MIN_MATCH | |
19845 */ | |
19846 if(zip_hash_head != zip_NIL && | |
19847 zip_strstart - zip_hash_head <= zip_MAX_DIST) { | |
19848 /* To simplify the code, we prevent matches with the string | |
19849 * of window index 0 (in particular we have to avoid a match | |
19850 * of the string with itself at the start of the input file). | |
19851 */ | |
19852 zip_match_length = zip_longest_match(zip_hash_head); | |
19853 /* longest_match() sets match_start */ | |
19854 if(zip_match_length > zip_lookahead) | |
19855 zip_match_length = zip_lookahead; | |
19856 } | |
19857 if(zip_match_length >= zip_MIN_MATCH) { | |
19858 // check_match(strstart, match_start, match_length); | |
19859 | |
19860 flush = zip_ct_tally(zip_strstart - zip_match_start, | |
19861 zip_match_length - zip_MIN_MATCH); | |
19862 zip_lookahead -= zip_match_length; | |
19863 | |
19864 /* Insert new strings in the hash table only if the match length | |
19865 * is not too large. This saves time but degrades compression. | |
19866 */ | |
19867 if(zip_match_length <= zip_max_lazy_match) { | |
19868 zip_match_length--; // string at strstart already in hash table | |
19869 do { | |
19870 zip_strstart++; | |
19871 zip_INSERT_STRING(); | |
19872 /* strstart never exceeds WSIZE-MAX_MATCH, so there are | |
19873 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | |
19874 * these bytes are garbage, but it does not matter since | |
19875 * the next lookahead bytes will be emitted as literals. | |
19876 */ | |
19877 } while(--zip_match_length != 0); | |
19878 zip_strstart++; | |
19879 } else { | |
19880 zip_strstart += zip_match_length; | |
19881 zip_match_length = 0; | |
19882 zip_ins_h = zip_window[zip_strstart] & 0xff; | |
19883 // UPDATE_HASH(ins_h, window[strstart + 1]); | |
19884 zip_ins_h = ((zip_ins_h<<zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK; | |
19885 | |
19886 //#if MIN_MATCH != 3 | |
19887 // Call UPDATE_HASH() MIN_MATCH-3 more times | |
19888 //#endif | |
19889 | |
19890 } | |
19891 } else { | |
19892 /* No match, output a literal byte */ | |
19893 flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff); | |
19894 zip_lookahead--; | |
19895 zip_strstart++; | |
19896 } | |
19897 if(flush) { | |
19898 zip_flush_block(0); | |
19899 zip_block_start = zip_strstart; | |
19900 } | |
19901 | |
19902 /* Make sure that we always have enough lookahead, except | |
19903 * at the end of the input file. We need MAX_MATCH bytes | |
19904 * for the next match, plus MIN_MATCH bytes to insert the | |
19905 * string following the next match. | |
19906 */ | |
19907 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) | |
19908 zip_fill_window(); | |
19909 } | |
19910 } | |
19911 | |
19912 var zip_deflate_better = function() { | |
19913 /* Process the input block. */ | |
19914 while(zip_lookahead != 0 && zip_qhead == null) { | |
19915 /* Insert the string window[strstart .. strstart+2] in the | |
19916 * dictionary, and set hash_head to the head of the hash chain: | |
19917 */ | |
19918 zip_INSERT_STRING(); | |
19919 | |
19920 /* Find the longest match, discarding those <= prev_length. | |
19921 */ | |
19922 zip_prev_length = zip_match_length; | |
19923 zip_prev_match = zip_match_start; | |
19924 zip_match_length = zip_MIN_MATCH - 1; | |
19925 | |
19926 if(zip_hash_head != zip_NIL && | |
19927 zip_prev_length < zip_max_lazy_match && | |
19928 zip_strstart - zip_hash_head <= zip_MAX_DIST) { | |
19929 /* To simplify the code, we prevent matches with the string | |
19930 * of window index 0 (in particular we have to avoid a match | |
19931 * of the string with itself at the start of the input file). | |
19932 */ | |
19933 zip_match_length = zip_longest_match(zip_hash_head); | |
19934 /* longest_match() sets match_start */ | |
19935 if(zip_match_length > zip_lookahead) | |
19936 zip_match_length = zip_lookahead; | |
19937 | |
19938 /* Ignore a length 3 match if it is too distant: */ | |
19939 if(zip_match_length == zip_MIN_MATCH && | |
19940 zip_strstart - zip_match_start > zip_TOO_FAR) { | |
19941 /* If prev_match is also MIN_MATCH, match_start is garbage | |
19942 * but we will ignore the current match anyway. | |
19943 */ | |
19944 zip_match_length--; | |
19945 } | |
19946 } | |
19947 /* If there was a match at the previous step and the current | |
19948 * match is not better, output the previous match: | |
19949 */ | |
19950 if(zip_prev_length >= zip_MIN_MATCH && | |
19951 zip_match_length <= zip_prev_length) { | |
19952 var flush; // set if current block must be flushed | |
19953 | |
19954 // check_match(strstart - 1, prev_match, prev_length); | |
19955 flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, | |
19956 zip_prev_length - zip_MIN_MATCH); | |
19957 | |
19958 /* Insert in hash table all strings up to the end of the match. | |
19959 * strstart-1 and strstart are already inserted. | |
19960 */ | |
19961 zip_lookahead -= zip_prev_length - 1; | |
19962 zip_prev_length -= 2; | |
19963 do { | |
19964 zip_strstart++; | |
19965 zip_INSERT_STRING(); | |
19966 /* strstart never exceeds WSIZE-MAX_MATCH, so there are | |
19967 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | |
19968 * these bytes are garbage, but it does not matter since the | |
19969 * next lookahead bytes will always be emitted as literals. | |
19970 */ | |
19971 } while(--zip_prev_length != 0); | |
19972 zip_match_available = 0; | |
19973 zip_match_length = zip_MIN_MATCH - 1; | |
19974 zip_strstart++; | |
19975 if(flush) { | |
19976 zip_flush_block(0); | |
19977 zip_block_start = zip_strstart; | |
19978 } | |
19979 } else if(zip_match_available != 0) { | |
19980 /* If there was no match at the previous position, output a | |
19981 * single literal. If there was a match but the current match | |
19982 * is longer, truncate the previous match to a single literal. | |
19983 */ | |
19984 if(zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { | |
19985 zip_flush_block(0); | |
19986 zip_block_start = zip_strstart; | |
19987 } | |
19988 zip_strstart++; | |
19989 zip_lookahead--; | |
19990 } else { | |
19991 /* There is no previous match to compare with, wait for | |
19992 * the next step to decide. | |
19993 */ | |
19994 zip_match_available = 1; | |
19995 zip_strstart++; | |
19996 zip_lookahead--; | |
19997 } | |
19998 | |
19999 /* Make sure that we always have enough lookahead, except | |
20000 * at the end of the input file. We need MAX_MATCH bytes | |
20001 * for the next match, plus MIN_MATCH bytes to insert the | |
20002 * string following the next match. | |
20003 */ | |
20004 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) | |
20005 zip_fill_window(); | |
20006 } | |
20007 } | |
20008 | |
20009 var zip_init_deflate = function() { | |
20010 if(zip_eofile) | |
20011 return; | |
20012 zip_bi_buf = 0; | |
20013 zip_bi_valid = 0; | |
20014 zip_ct_init(); | |
20015 zip_lm_init(); | |
20016 | |
20017 zip_qhead = null; | |
20018 zip_outcnt = 0; | |
20019 zip_outoff = 0; | |
20020 | |
20021 if(zip_compr_level <= 3) | |
20022 { | |
20023 zip_prev_length = zip_MIN_MATCH - 1; | |
20024 zip_match_length = 0; | |
20025 } | |
20026 else | |
20027 { | |
20028 zip_match_length = zip_MIN_MATCH - 1; | |
20029 zip_match_available = 0; | |
20030 } | |
20031 | |
20032 zip_complete = false; | |
20033 } | |
20034 | |
20035 /* ========================================================================== | |
20036 * Same as above, but achieves better compression. We use a lazy | |
20037 * evaluation for matches: a match is finally adopted only if there is | |
20038 * no better match at the next window position. | |
20039 */ | |
20040 var zip_deflate_internal = function(buff, off, buff_size) { | |
20041 var n; | |
20042 | |
20043 if(!zip_initflag) | |
20044 { | |
20045 zip_init_deflate(); | |
20046 zip_initflag = true; | |
20047 if(zip_lookahead == 0) { // empty | |
20048 zip_complete = true; | |
20049 return 0; | |
20050 } | |
20051 } | |
20052 | |
20053 if((n = zip_qcopy(buff, off, buff_size)) == buff_size) | |
20054 return buff_size; | |
20055 | |
20056 if(zip_complete) | |
20057 return n; | |
20058 | |
20059 if(zip_compr_level <= 3) // optimized for speed | |
20060 zip_deflate_fast(); | |
20061 else | |
20062 zip_deflate_better(); | |
20063 if(zip_lookahead == 0) { | |
20064 if(zip_match_available != 0) | |
20065 zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); | |
20066 zip_flush_block(1); | |
20067 zip_complete = true; | |
20068 } | |
20069 return n + zip_qcopy(buff, n + off, buff_size - n); | |
20070 } | |
20071 | |
20072 var zip_qcopy = function(buff, off, buff_size) { | |
20073 var n, i, j; | |
20074 | |
20075 n = 0; | |
20076 while(zip_qhead != null && n < buff_size) | |
20077 { | |
20078 i = buff_size - n; | |
20079 if(i > zip_qhead.len) | |
20080 i = zip_qhead.len; | |
20081 // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i); | |
20082 for(j = 0; j < i; j++) | |
20083 buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; | |
20084 | |
20085 zip_qhead.off += i; | |
20086 zip_qhead.len -= i; | |
20087 n += i; | |
20088 if(zip_qhead.len == 0) { | |
20089 var p; | |
20090 p = zip_qhead; | |
20091 zip_qhead = zip_qhead.next; | |
20092 zip_reuse_queue(p); | |
20093 } | |
20094 } | |
20095 | |
20096 if(n == buff_size) | |
20097 return n; | |
20098 | |
20099 if(zip_outoff < zip_outcnt) { | |
20100 i = buff_size - n; | |
20101 if(i > zip_outcnt - zip_outoff) | |
20102 i = zip_outcnt - zip_outoff; | |
20103 // System.arraycopy(outbuf, outoff, buff, off + n, i); | |
20104 for(j = 0; j < i; j++) | |
20105 buff[off + n + j] = zip_outbuf[zip_outoff + j]; | |
20106 zip_outoff += i; | |
20107 n += i; | |
20108 if(zip_outcnt == zip_outoff) | |
20109 zip_outcnt = zip_outoff = 0; | |
20110 } | |
20111 return n; | |
20112 } | |
20113 | |
20114 /* ========================================================================== | |
20115 * Allocate the match buffer, initialize the various tables and save the | |
20116 * location of the internal file attribute (ascii/binary) and method | |
20117 * (DEFLATE/STORE). | |
20118 */ | |
20119 var zip_ct_init = function() { | |
20120 var n; // iterates over tree elements | |
20121 var bits; // bit counter | |
20122 var length; // length value | |
20123 var code; // code value | |
20124 var dist; // distance index | |
20125 | |
20126 if(zip_static_dtree[0].dl != 0) return; // ct_init already called | |
20127 | |
20128 zip_l_desc.dyn_tree = zip_dyn_ltree; | |
20129 zip_l_desc.static_tree = zip_static_ltree; | |
20130 zip_l_desc.extra_bits = zip_extra_lbits; | |
20131 zip_l_desc.extra_base = zip_LITERALS + 1; | |
20132 zip_l_desc.elems = zip_L_CODES; | |
20133 zip_l_desc.max_length = zip_MAX_BITS; | |
20134 zip_l_desc.max_code = 0; | |
20135 | |
20136 zip_d_desc.dyn_tree = zip_dyn_dtree; | |
20137 zip_d_desc.static_tree = zip_static_dtree; | |
20138 zip_d_desc.extra_bits = zip_extra_dbits; | |
20139 zip_d_desc.extra_base = 0; | |
20140 zip_d_desc.elems = zip_D_CODES; | |
20141 zip_d_desc.max_length = zip_MAX_BITS; | |
20142 zip_d_desc.max_code = 0; | |
20143 | |
20144 zip_bl_desc.dyn_tree = zip_bl_tree; | |
20145 zip_bl_desc.static_tree = null; | |
20146 zip_bl_desc.extra_bits = zip_extra_blbits; | |
20147 zip_bl_desc.extra_base = 0; | |
20148 zip_bl_desc.elems = zip_BL_CODES; | |
20149 zip_bl_desc.max_length = zip_MAX_BL_BITS; | |
20150 zip_bl_desc.max_code = 0; | |
20151 | |
20152 // Initialize the mapping length (0..255) -> length code (0..28) | |
20153 length = 0; | |
20154 for(code = 0; code < zip_LENGTH_CODES-1; code++) { | |
20155 zip_base_length[code] = length; | |
20156 for(n = 0; n < (1<<zip_extra_lbits[code]); n++) | |
20157 zip_length_code[length++] = code; | |
20158 } | |
20159 // Assert (length == 256, "ct_init: length != 256"); | |
20160 | |
20161 /* Note that the length 255 (match length 258) can be represented | |
20162 * in two different ways: code 284 + 5 bits or code 285, so we | |
20163 * overwrite length_code[255] to use the best encoding: | |
20164 */ | |
20165 zip_length_code[length-1] = code; | |
20166 | |
20167 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ | |
20168 dist = 0; | |
20169 for(code = 0 ; code < 16; code++) { | |
20170 zip_base_dist[code] = dist; | |
20171 for(n = 0; n < (1<<zip_extra_dbits[code]); n++) { | |
20172 zip_dist_code[dist++] = code; | |
20173 } | |
20174 } | |
20175 // Assert (dist == 256, "ct_init: dist != 256"); | |
20176 dist >>= 7; // from now on, all distances are divided by 128 | |
20177 for( ; code < zip_D_CODES; code++) { | |
20178 zip_base_dist[code] = dist << 7; | |
20179 for(n = 0; n < (1<<(zip_extra_dbits[code]-7)); n++) | |
20180 zip_dist_code[256 + dist++] = code; | |
20181 } | |
20182 // Assert (dist == 256, "ct_init: 256+dist != 512"); | |
20183 | |
20184 // Construct the codes of the static literal tree | |
20185 for(bits = 0; bits <= zip_MAX_BITS; bits++) | |
20186 zip_bl_count[bits] = 0; | |
20187 n = 0; | |
20188 while(n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } | |
20189 while(n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; } | |
20190 while(n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; } | |
20191 while(n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } | |
20192 /* Codes 286 and 287 do not exist, but we must include them in the | |
20193 * tree construction to get a canonical Huffman tree (longest code | |
20194 * all ones) | |
20195 */ | |
20196 zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); | |
20197 | |
20198 /* The static distance tree is trivial: */ | |
20199 for(n = 0; n < zip_D_CODES; n++) { | |
20200 zip_static_dtree[n].dl = 5; | |
20201 zip_static_dtree[n].fc = zip_bi_reverse(n, 5); | |
20202 } | |
20203 | |
20204 // Initialize the first block of the first file: | |
20205 zip_init_block(); | |
20206 } | |
20207 | |
20208 /* ========================================================================== | |
20209 * Initialize a new block. | |
20210 */ | |
20211 var zip_init_block = function() { | |
20212 var n; // iterates over tree elements | |
20213 | |
20214 // Initialize the trees. | |
20215 for(n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; | |
20216 for(n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; | |
20217 for(n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; | |
20218 | |
20219 zip_dyn_ltree[zip_END_BLOCK].fc = 1; | |
20220 zip_opt_len = zip_static_len = 0; | |
20221 zip_last_lit = zip_last_dist = zip_last_flags = 0; | |
20222 zip_flags = 0; | |
20223 zip_flag_bit = 1; | |
20224 } | |
20225 | |
20226 /* ========================================================================== | |
20227 * Restore the heap property by moving down the tree starting at node k, | |
20228 * exchanging a node with the smallest of its two sons if necessary, stopping | |
20229 * when the heap property is re-established (each father smaller than its | |
20230 * two sons). | |
20231 */ | |
20232 var zip_pqdownheap = function( | |
20233 tree, // the tree to restore | |
20234 k) { // node to move down | |
20235 var v = zip_heap[k]; | |
20236 var j = k << 1; // left son of k | |
20237 | |
20238 while(j <= zip_heap_len) { | |
20239 // Set j to the smallest of the two sons: | |
20240 if(j < zip_heap_len && | |
20241 zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) | |
20242 j++; | |
20243 | |
20244 // Exit if v is smaller than both sons | |
20245 if(zip_SMALLER(tree, v, zip_heap[j])) | |
20246 break; | |
20247 | |
20248 // Exchange v with the smallest son | |
20249 zip_heap[k] = zip_heap[j]; | |
20250 k = j; | |
20251 | |
20252 // And continue down the tree, setting j to the left son of k | |
20253 j <<= 1; | |
20254 } | |
20255 zip_heap[k] = v; | |
20256 } | |
20257 | |
20258 /* ========================================================================== | |
20259 * Compute the optimal bit lengths for a tree and update the total bit length | |
20260 * for the current block. | |
20261 * IN assertion: the fields freq and dad are set, heap[heap_max] and | |
20262 * above are the tree nodes sorted by increasing frequency. | |
20263 * OUT assertions: the field len is set to the optimal bit length, the | |
20264 * array bl_count contains the frequencies for each bit length. | |
20265 * The length opt_len is updated; static_len is also updated if stree is | |
20266 * not null. | |
20267 */ | |
20268 var zip_gen_bitlen = function(desc) { // the tree descriptor | |
20269 var tree = desc.dyn_tree; | |
20270 var extra = desc.extra_bits; | |
20271 var base = desc.extra_base; | |
20272 var max_code = desc.max_code; | |
20273 var max_length = desc.max_length; | |
20274 var stree = desc.static_tree; | |
20275 var h; // heap index | |
20276 var n, m; // iterate over the tree elements | |
20277 var bits; // bit length | |
20278 var xbits; // extra bits | |
20279 var f; // frequency | |
20280 var overflow = 0; // number of elements with bit length too large | |
20281 | |
20282 for(bits = 0; bits <= zip_MAX_BITS; bits++) | |
20283 zip_bl_count[bits] = 0; | |
20284 | |
20285 /* In a first pass, compute the optimal bit lengths (which may | |
20286 * overflow in the case of the bit length tree). | |
20287 */ | |
20288 tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap | |
20289 | |
20290 for(h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { | |
20291 n = zip_heap[h]; | |
20292 bits = tree[tree[n].dl].dl + 1; | |
20293 if(bits > max_length) { | |
20294 bits = max_length; | |
20295 overflow++; | |
20296 } | |
20297 tree[n].dl = bits; | |
20298 // We overwrite tree[n].dl which is no longer needed | |
20299 | |
20300 if(n > max_code) | |
20301 continue; // not a leaf node | |
20302 | |
20303 zip_bl_count[bits]++; | |
20304 xbits = 0; | |
20305 if(n >= base) | |
20306 xbits = extra[n - base]; | |
20307 f = tree[n].fc; | |
20308 zip_opt_len += f * (bits + xbits); | |
20309 if(stree != null) | |
20310 zip_static_len += f * (stree[n].dl + xbits); | |
20311 } | |
20312 if(overflow == 0) | |
20313 return; | |
20314 | |
20315 // This happens for example on obj2 and pic of the Calgary corpus | |
20316 | |
20317 // Find the first bit length which could increase: | |
20318 do { | |
20319 bits = max_length - 1; | |
20320 while(zip_bl_count[bits] == 0) | |
20321 bits--; | |
20322 zip_bl_count[bits]--; // move one leaf down the tree | |
20323 zip_bl_count[bits + 1] += 2; // move one overflow item as its brother | |
20324 zip_bl_count[max_length]--; | |
20325 /* The brother of the overflow item also moves one step up, | |
20326 * but this does not affect bl_count[max_length] | |
20327 */ | |
20328 overflow -= 2; | |
20329 } while(overflow > 0); | |
20330 | |
20331 /* Now recompute all bit lengths, scanning in increasing frequency. | |
20332 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all | |
20333 * lengths instead of fixing only the wrong ones. This idea is taken | |
20334 * from 'ar' written by Haruhiko Okumura.) | |
20335 */ | |
20336 for(bits = max_length; bits != 0; bits--) { | |
20337 n = zip_bl_count[bits]; | |
20338 while(n != 0) { | |
20339 m = zip_heap[--h]; | |
20340 if(m > max_code) | |
20341 continue; | |
20342 if(tree[m].dl != bits) { | |
20343 zip_opt_len += (bits - tree[m].dl) * tree[m].fc; | |
20344 tree[m].fc = bits; | |
20345 } | |
20346 n--; | |
20347 } | |
20348 } | |
20349 } | |
20350 | |
20351 /* ========================================================================== | |
20352 * Generate the codes for a given tree and bit counts (which need not be | |
20353 * optimal). | |
20354 * IN assertion: the array bl_count contains the bit length statistics for | |
20355 * the given tree and the field len is set for all tree elements. | |
20356 * OUT assertion: the field code is set for all tree elements of non | |
20357 * zero code length. | |
20358 */ | |
20359 var zip_gen_codes = function(tree, // the tree to decorate | |
20360 max_code) { // largest code with non zero frequency | |
20361 var next_code = new Array(zip_MAX_BITS+1); // next code value for each bit length | |
20362 var code = 0; // running code value | |
20363 var bits; // bit index | |
20364 var n; // code index | |
20365 | |
20366 /* The distribution counts are first used to generate the code values | |
20367 * without bit reversal. | |
20368 */ | |
20369 for(bits = 1; bits <= zip_MAX_BITS; bits++) { | |
20370 code = ((code + zip_bl_count[bits-1]) << 1); | |
20371 next_code[bits] = code; | |
20372 } | |
20373 | |
20374 /* Check that the bit counts in bl_count are consistent. The last code | |
20375 * must be all ones. | |
20376 */ | |
20377 // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, | |
20378 // "inconsistent bit counts"); | |
20379 // Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); | |
20380 | |
20381 for(n = 0; n <= max_code; n++) { | |
20382 var len = tree[n].dl; | |
20383 if(len == 0) | |
20384 continue; | |
20385 // Now reverse the bits | |
20386 tree[n].fc = zip_bi_reverse(next_code[len]++, len); | |
20387 | |
20388 // Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", | |
20389 // n, (isgraph(n) ? n : ' '), len, tree[n].fc, next_code[len]-1)); | |
20390 } | |
20391 } | |
20392 | |
20393 /* ========================================================================== | |
20394 * Construct one Huffman tree and assigns the code bit strings and lengths. | |
20395 * Update the total bit length for the current block. | |
20396 * IN assertion: the field freq is set for all tree elements. | |
20397 * OUT assertions: the fields len and code are set to the optimal bit length | |
20398 * and corresponding code. The length opt_len is updated; static_len is | |
20399 * also updated if stree is not null. The field max_code is set. | |
20400 */ | |
20401 var zip_build_tree = function(desc) { // the tree descriptor | |
20402 var tree = desc.dyn_tree; | |
20403 var stree = desc.static_tree; | |
20404 var elems = desc.elems; | |
20405 var n, m; // iterate over heap elements | |
20406 var max_code = -1; // largest code with non zero frequency | |
20407 var node = elems; // next internal node of the tree | |
20408 | |
20409 /* Construct the initial heap, with least frequent element in | |
20410 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. | |
20411 * heap[0] is not used. | |
20412 */ | |
20413 zip_heap_len = 0; | |
20414 zip_heap_max = zip_HEAP_SIZE; | |
20415 | |
20416 for(n = 0; n < elems; n++) { | |
20417 if(tree[n].fc != 0) { | |
20418 zip_heap[++zip_heap_len] = max_code = n; | |
20419 zip_depth[n] = 0; | |
20420 } else | |
20421 tree[n].dl = 0; | |
20422 } | |
20423 | |
20424 /* The pkzip format requires that at least one distance code exists, | |
20425 * and that at least one bit should be sent even if there is only one | |
20426 * possible code. So to avoid special checks later on we force at least | |
20427 * two codes of non zero frequency. | |
20428 */ | |
20429 while(zip_heap_len < 2) { | |
20430 var xnew = zip_heap[++zip_heap_len] = (max_code < 2 ? ++max_code : 0); | |
20431 tree[xnew].fc = 1; | |
20432 zip_depth[xnew] = 0; | |
20433 zip_opt_len--; | |
20434 if(stree != null) | |
20435 zip_static_len -= stree[xnew].dl; | |
20436 // new is 0 or 1 so it does not have extra bits | |
20437 } | |
20438 desc.max_code = max_code; | |
20439 | |
20440 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, | |
20441 * establish sub-heaps of increasing lengths: | |
20442 */ | |
20443 for(n = zip_heap_len >> 1; n >= 1; n--) | |
20444 zip_pqdownheap(tree, n); | |
20445 | |
20446 /* Construct the Huffman tree by repeatedly combining the least two | |
20447 * frequent nodes. | |
20448 */ | |
20449 do { | |
20450 n = zip_heap[zip_SMALLEST]; | |
20451 zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; | |
20452 zip_pqdownheap(tree, zip_SMALLEST); | |
20453 | |
20454 m = zip_heap[zip_SMALLEST]; // m = node of next least frequency | |
20455 | |
20456 // keep the nodes sorted by frequency | |
20457 zip_heap[--zip_heap_max] = n; | |
20458 zip_heap[--zip_heap_max] = m; | |
20459 | |
20460 // Create a new node father of n and m | |
20461 tree[node].fc = tree[n].fc + tree[m].fc; | |
20462 // depth[node] = (char)(MAX(depth[n], depth[m]) + 1); | |
20463 if(zip_depth[n] > zip_depth[m] + 1) | |
20464 zip_depth[node] = zip_depth[n]; | |
20465 else | |
20466 zip_depth[node] = zip_depth[m] + 1; | |
20467 tree[n].dl = tree[m].dl = node; | |
20468 | |
20469 // and insert the new node in the heap | |
20470 zip_heap[zip_SMALLEST] = node++; | |
20471 zip_pqdownheap(tree, zip_SMALLEST); | |
20472 | |
20473 } while(zip_heap_len >= 2); | |
20474 | |
20475 zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; | |
20476 | |
20477 /* At this point, the fields freq and dad are set. We can now | |
20478 * generate the bit lengths. | |
20479 */ | |
20480 zip_gen_bitlen(desc); | |
20481 | |
20482 // The field len is now set, we can generate the bit codes | |
20483 zip_gen_codes(tree, max_code); | |
20484 } | |
20485 | |
20486 /* ========================================================================== | |
20487 * Scan a literal or distance tree to determine the frequencies of the codes | |
20488 * in the bit length tree. Updates opt_len to take into account the repeat | |
20489 * counts. (The contribution of the bit length codes will be added later | |
20490 * during the construction of bl_tree.) | |
20491 */ | |
20492 var zip_scan_tree = function(tree,// the tree to be scanned | |
20493 max_code) { // and its largest code of non zero frequency | |
20494 var n; // iterates over all tree elements | |
20495 var prevlen = -1; // last emitted length | |
20496 var curlen; // length of current code | |
20497 var nextlen = tree[0].dl; // length of next code | |
20498 var count = 0; // repeat count of the current code | |
20499 var max_count = 7; // max repeat count | |
20500 var min_count = 4; // min repeat count | |
20501 | |
20502 if(nextlen == 0) { | |
20503 max_count = 138; | |
20504 min_count = 3; | |
20505 } | |
20506 tree[max_code + 1].dl = 0xffff; // guard | |
20507 | |
20508 for(n = 0; n <= max_code; n++) { | |
20509 curlen = nextlen; | |
20510 nextlen = tree[n + 1].dl; | |
20511 if(++count < max_count && curlen == nextlen) | |
20512 continue; | |
20513 else if(count < min_count) | |
20514 zip_bl_tree[curlen].fc += count; | |
20515 else if(curlen != 0) { | |
20516 if(curlen != prevlen) | |
20517 zip_bl_tree[curlen].fc++; | |
20518 zip_bl_tree[zip_REP_3_6].fc++; | |
20519 } else if(count <= 10) | |
20520 zip_bl_tree[zip_REPZ_3_10].fc++; | |
20521 else | |
20522 zip_bl_tree[zip_REPZ_11_138].fc++; | |
20523 count = 0; prevlen = curlen; | |
20524 if(nextlen == 0) { | |
20525 max_count = 138; | |
20526 min_count = 3; | |
20527 } else if(curlen == nextlen) { | |
20528 max_count = 6; | |
20529 min_count = 3; | |
20530 } else { | |
20531 max_count = 7; | |
20532 min_count = 4; | |
20533 } | |
20534 } | |
20535 } | |
20536 | |
20537 /* ========================================================================== | |
20538 * Send a literal or distance tree in compressed form, using the codes in | |
20539 * bl_tree. | |
20540 */ | |
20541 var zip_send_tree = function(tree, // the tree to be scanned | |
20542 max_code) { // and its largest code of non zero frequency | |
20543 var n; // iterates over all tree elements | |
20544 var prevlen = -1; // last emitted length | |
20545 var curlen; // length of current code | |
20546 var nextlen = tree[0].dl; // length of next code | |
20547 var count = 0; // repeat count of the current code | |
20548 var max_count = 7; // max repeat count | |
20549 var min_count = 4; // min repeat count | |
20550 | |
20551 /* tree[max_code+1].dl = -1; */ /* guard already set */ | |
20552 if(nextlen == 0) { | |
20553 max_count = 138; | |
20554 min_count = 3; | |
20555 } | |
20556 | |
20557 for(n = 0; n <= max_code; n++) { | |
20558 curlen = nextlen; | |
20559 nextlen = tree[n+1].dl; | |
20560 if(++count < max_count && curlen == nextlen) { | |
20561 continue; | |
20562 } else if(count < min_count) { | |
20563 do { zip_SEND_CODE(curlen, zip_bl_tree); } while(--count != 0); | |
20564 } else if(curlen != 0) { | |
20565 if(curlen != prevlen) { | |
20566 zip_SEND_CODE(curlen, zip_bl_tree); | |
20567 count--; | |
20568 } | |
20569 // Assert(count >= 3 && count <= 6, " 3_6?"); | |
20570 zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); | |
20571 zip_send_bits(count - 3, 2); | |
20572 } else if(count <= 10) { | |
20573 zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); | |
20574 zip_send_bits(count-3, 3); | |
20575 } else { | |
20576 zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); | |
20577 zip_send_bits(count-11, 7); | |
20578 } | |
20579 count = 0; | |
20580 prevlen = curlen; | |
20581 if(nextlen == 0) { | |
20582 max_count = 138; | |
20583 min_count = 3; | |
20584 } else if(curlen == nextlen) { | |
20585 max_count = 6; | |
20586 min_count = 3; | |
20587 } else { | |
20588 max_count = 7; | |
20589 min_count = 4; | |
20590 } | |
20591 } | |
20592 } | |
20593 | |
20594 /* ========================================================================== | |
20595 * Construct the Huffman tree for the bit lengths and return the index in | |
20596 * bl_order of the last bit length code to send. | |
20597 */ | |
20598 var zip_build_bl_tree = function() { | |
20599 var max_blindex; // index of last bit length code of non zero freq | |
20600 | |
20601 // Determine the bit length frequencies for literal and distance trees | |
20602 zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); | |
20603 zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); | |
20604 | |
20605 // Build the bit length tree: | |
20606 zip_build_tree(zip_bl_desc); | |
20607 /* opt_len now includes the length of the tree representations, except | |
20608 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. | |
20609 */ | |
20610 | |
20611 /* Determine the number of bit length codes to send. The pkzip format | |
20612 * requires that at least 4 bit length codes be sent. (appnote.txt says | |
20613 * 3 but the actual value used is 4.) | |
20614 */ | |
20615 for(max_blindex = zip_BL_CODES-1; max_blindex >= 3; max_blindex--) { | |
20616 if(zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; | |
20617 } | |
20618 /* Update opt_len to include the bit length tree and counts */ | |
20619 zip_opt_len += 3*(max_blindex+1) + 5+5+4; | |
20620 // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", | |
20621 // encoder->opt_len, encoder->static_len)); | |
20622 | |
20623 return max_blindex; | |
20624 } | |
20625 | |
20626 /* ========================================================================== | |
20627 * Send the header for a block using dynamic Huffman trees: the counts, the | |
20628 * lengths of the bit length codes, the literal tree and the distance tree. | |
20629 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. | |
20630 */ | |
20631 var zip_send_all_trees = function(lcodes, dcodes, blcodes) { // number of codes for each tree | |
20632 var rank; // index in bl_order | |
20633 | |
20634 // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); | |
20635 // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, | |
20636 // "too many codes"); | |
20637 // Tracev((stderr, "\nbl counts: ")); | |
20638 zip_send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt | |
20639 zip_send_bits(dcodes-1, 5); | |
20640 zip_send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt | |
20641 for(rank = 0; rank < blcodes; rank++) { | |
20642 // Tracev((stderr, "\nbl code %2d ", bl_order[rank])); | |
20643 zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); | |
20644 } | |
20645 | |
20646 // send the literal tree | |
20647 zip_send_tree(zip_dyn_ltree,lcodes-1); | |
20648 | |
20649 // send the distance tree | |
20650 zip_send_tree(zip_dyn_dtree,dcodes-1); | |
20651 } | |
20652 | |
20653 /* ========================================================================== | |
20654 * Determine the best encoding for the current block: dynamic trees, static | |
20655 * trees or store, and output the encoded block to the zip file. | |
20656 */ | |
20657 var zip_flush_block = function(eof) { // true if this is the last block for a file | |
20658 var opt_lenb, static_lenb; // opt_len and static_len in bytes | |
20659 var max_blindex; // index of last bit length code of non zero freq | |
20660 var stored_len; // length of input block | |
20661 | |
20662 stored_len = zip_strstart - zip_block_start; | |
20663 zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items | |
20664 | |
20665 // Construct the literal and distance trees | |
20666 zip_build_tree(zip_l_desc); | |
20667 // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", | |
20668 // encoder->opt_len, encoder->static_len)); | |
20669 | |
20670 zip_build_tree(zip_d_desc); | |
20671 // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", | |
20672 // encoder->opt_len, encoder->static_len)); | |
20673 /* At this point, opt_len and static_len are the total bit lengths of | |
20674 * the compressed block data, excluding the tree representations. | |
20675 */ | |
20676 | |
20677 /* Build the bit length tree for the above two trees, and get the index | |
20678 * in bl_order of the last bit length code to send. | |
20679 */ | |
20680 max_blindex = zip_build_bl_tree(); | |
20681 | |
20682 // Determine the best encoding. Compute first the block length in bytes | |
20683 opt_lenb = (zip_opt_len +3+7)>>3; | |
20684 static_lenb = (zip_static_len+3+7)>>3; | |
20685 | |
20686 // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", | |
20687 // opt_lenb, encoder->opt_len, | |
20688 // static_lenb, encoder->static_len, stored_len, | |
20689 // encoder->last_lit, encoder->last_dist)); | |
20690 | |
20691 if(static_lenb <= opt_lenb) | |
20692 opt_lenb = static_lenb; | |
20693 if(stored_len + 4 <= opt_lenb // 4: two words for the lengths | |
20694 && zip_block_start >= 0) { | |
20695 var i; | |
20696 | |
20697 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. | |
20698 * Otherwise we can't have processed more than WSIZE input bytes since | |
20699 * the last block flush, because compression would have been | |
20700 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to | |
20701 * transform a block into a stored block. | |
20702 */ | |
20703 zip_send_bits((zip_STORED_BLOCK<<1)+eof, 3); /* send block type */ | |
20704 zip_bi_windup(); /* align on byte boundary */ | |
20705 zip_put_short(stored_len); | |
20706 zip_put_short(~stored_len); | |
20707 | |
20708 // copy block | |
20709 /* | |
20710 p = &window[block_start]; | |
20711 for(i = 0; i < stored_len; i++) | |
20712 put_byte(p[i]); | |
20713 */ | |
20714 for(i = 0; i < stored_len; i++) | |
20715 zip_put_byte(zip_window[zip_block_start + i]); | |
20716 | |
20717 } else if(static_lenb == opt_lenb) { | |
20718 zip_send_bits((zip_STATIC_TREES<<1)+eof, 3); | |
20719 zip_compress_block(zip_static_ltree, zip_static_dtree); | |
20720 } else { | |
20721 zip_send_bits((zip_DYN_TREES<<1)+eof, 3); | |
20722 zip_send_all_trees(zip_l_desc.max_code+1, | |
20723 zip_d_desc.max_code+1, | |
20724 max_blindex+1); | |
20725 zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); | |
20726 } | |
20727 | |
20728 zip_init_block(); | |
20729 | |
20730 if(eof != 0) | |
20731 zip_bi_windup(); | |
20732 } | |
20733 | |
20734 /* ========================================================================== | |
20735 * Save the match info and tally the frequency counts. Return true if | |
20736 * the current block must be flushed. | |
20737 */ | |
20738 var zip_ct_tally = function( | |
20739 dist, // distance of matched string | |
20740 lc) { // match length-MIN_MATCH or unmatched char (if dist==0) | |
20741 zip_l_buf[zip_last_lit++] = lc; | |
20742 if(dist == 0) { | |
20743 // lc is the unmatched char | |
20744 zip_dyn_ltree[lc].fc++; | |
20745 } else { | |
20746 // Here, lc is the match length - MIN_MATCH | |
20747 dist--; // dist = match distance - 1 | |
20748 // Assert((ush)dist < (ush)MAX_DIST && | |
20749 // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && | |
20750 // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match"); | |
20751 | |
20752 zip_dyn_ltree[zip_length_code[lc]+zip_LITERALS+1].fc++; | |
20753 zip_dyn_dtree[zip_D_CODE(dist)].fc++; | |
20754 | |
20755 zip_d_buf[zip_last_dist++] = dist; | |
20756 zip_flags |= zip_flag_bit; | |
20757 } | |
20758 zip_flag_bit <<= 1; | |
20759 | |
20760 // Output the flags if they fill a byte | |
20761 if((zip_last_lit & 7) == 0) { | |
20762 zip_flag_buf[zip_last_flags++] = zip_flags; | |
20763 zip_flags = 0; | |
20764 zip_flag_bit = 1; | |
20765 } | |
20766 // Try to guess if it is profitable to stop the current block here | |
20767 if(zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { | |
20768 // Compute an upper bound for the compressed length | |
20769 var out_length = zip_last_lit * 8; | |
20770 var in_length = zip_strstart - zip_block_start; | |
20771 var dcode; | |
20772 | |
20773 for(dcode = 0; dcode < zip_D_CODES; dcode++) { | |
20774 out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); | |
20775 } | |
20776 out_length >>= 3; | |
20777 // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", | |
20778 // encoder->last_lit, encoder->last_dist, in_length, out_length, | |
20779 // 100L - out_length*100L/in_length)); | |
20780 if(zip_last_dist < parseInt(zip_last_lit/2) && | |
20781 out_length < parseInt(in_length/2)) | |
20782 return true; | |
20783 } | |
20784 return (zip_last_lit == zip_LIT_BUFSIZE-1 || | |
20785 zip_last_dist == zip_DIST_BUFSIZE); | |
20786 /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K | |
20787 * on 16 bit machines and because stored blocks are restricted to | |
20788 * 64K-1 bytes. | |
20789 */ | |
20790 } | |
20791 | |
20792 /* ========================================================================== | |
20793 * Send the block data compressed using the given Huffman trees | |
20794 */ | |
20795 var zip_compress_block = function( | |
20796 ltree, // literal tree | |
20797 dtree) { // distance tree | |
20798 var dist; // distance of matched string | |
20799 var lc; // match length or unmatched char (if dist == 0) | |
20800 var lx = 0; // running index in l_buf | |
20801 var dx = 0; // running index in d_buf | |
20802 var fx = 0; // running index in flag_buf | |
20803 var flag = 0; // current flags | |
20804 var code; // the code to send | |
20805 var extra; // number of extra bits to send | |
20806 | |
20807 if(zip_last_lit != 0) do { | |
20808 if((lx & 7) == 0) | |
20809 flag = zip_flag_buf[fx++]; | |
20810 lc = zip_l_buf[lx++] & 0xff; | |
20811 if((flag & 1) == 0) { | |
20812 zip_SEND_CODE(lc, ltree); /* send a literal byte */ | |
20813 // Tracecv(isgraph(lc), (stderr," '%c' ", lc)); | |
20814 } else { | |
20815 // Here, lc is the match length - MIN_MATCH | |
20816 code = zip_length_code[lc]; | |
20817 zip_SEND_CODE(code+zip_LITERALS+1, ltree); // send the length code | |
20818 extra = zip_extra_lbits[code]; | |
20819 if(extra != 0) { | |
20820 lc -= zip_base_length[code]; | |
20821 zip_send_bits(lc, extra); // send the extra length bits | |
20822 } | |
20823 dist = zip_d_buf[dx++]; | |
20824 // Here, dist is the match distance - 1 | |
20825 code = zip_D_CODE(dist); | |
20826 // Assert (code < D_CODES, "bad d_code"); | |
20827 | |
20828 zip_SEND_CODE(code, dtree); // send the distance code | |
20829 extra = zip_extra_dbits[code]; | |
20830 if(extra != 0) { | |
20831 dist -= zip_base_dist[code]; | |
20832 zip_send_bits(dist, extra); // send the extra distance bits | |
20833 } | |
20834 } // literal or match pair ? | |
20835 flag >>= 1; | |
20836 } while(lx < zip_last_lit); | |
20837 | |
20838 zip_SEND_CODE(zip_END_BLOCK, ltree); | |
20839 } | |
20840 | |
20841 /* ========================================================================== | |
20842 * Send a value on a given number of bits. | |
20843 * IN assertion: length <= 16 and value fits in length bits. | |
20844 */ | |
20845 var zip_Buf_size = 16; // bit size of bi_buf | |
20846 var zip_send_bits = function( | |
20847 value, // value to send | |
20848 length) { // number of bits | |
20849 /* If not enough room in bi_buf, use (valid) bits from bi_buf and | |
20850 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | |
20851 * unused bits in value. | |
20852 */ | |
20853 if(zip_bi_valid > zip_Buf_size - length) { | |
20854 zip_bi_buf |= (value << zip_bi_valid); | |
20855 zip_put_short(zip_bi_buf); | |
20856 zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); | |
20857 zip_bi_valid += length - zip_Buf_size; | |
20858 } else { | |
20859 zip_bi_buf |= value << zip_bi_valid; | |
20860 zip_bi_valid += length; | |
20861 } | |
20862 } | |
20863 | |
20864 /* ========================================================================== | |
20865 * Reverse the first len bits of a code, using straightforward code (a faster | |
20866 * method would use a table) | |
20867 * IN assertion: 1 <= len <= 15 | |
20868 */ | |
20869 var zip_bi_reverse = function( | |
20870 code, // the value to invert | |
20871 len) { // its bit length | |
20872 var res = 0; | |
20873 do { | |
20874 res |= code & 1; | |
20875 code >>= 1; | |
20876 res <<= 1; | |
20877 } while(--len > 0); | |
20878 return res >> 1; | |
20879 } | |
20880 | |
20881 /* ========================================================================== | |
20882 * Write out any remaining bits in an incomplete byte. | |
20883 */ | |
20884 var zip_bi_windup = function() { | |
20885 if(zip_bi_valid > 8) { | |
20886 zip_put_short(zip_bi_buf); | |
20887 } else if(zip_bi_valid > 0) { | |
20888 zip_put_byte(zip_bi_buf); | |
20889 } | |
20890 zip_bi_buf = 0; | |
20891 zip_bi_valid = 0; | |
20892 } | |
20893 | |
20894 var zip_qoutbuf = function() { | |
20895 if(zip_outcnt != 0) { | |
20896 var q, i; | |
20897 q = zip_new_queue(); | |
20898 if(zip_qhead == null) | |
20899 zip_qhead = zip_qtail = q; | |
20900 else | |
20901 zip_qtail = zip_qtail.next = q; | |
20902 q.len = zip_outcnt - zip_outoff; | |
20903 // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len); | |
20904 for(i = 0; i < q.len; i++) | |
20905 q.ptr[i] = zip_outbuf[zip_outoff + i]; | |
20906 zip_outcnt = zip_outoff = 0; | |
20907 } | |
20908 } | |
20909 | |
20910 var zip_deflate = function(str, level) { | |
20911 var i, j; | |
20912 | |
20913 zip_deflate_data = str; | |
20914 zip_deflate_pos = 0; | |
20915 if(typeof level == "undefined") | |
20916 level = zip_DEFAULT_LEVEL; | |
20917 zip_deflate_start(level); | |
20918 | |
20919 var buff = new Array(1024); | |
20920 var aout = []; | |
20921 while((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { | |
20922 var cbuf = new Array(i); | |
20923 for(j = 0; j < i; j++){ | |
20924 cbuf[j] = String.fromCharCode(buff[j]); | |
20925 } | |
20926 aout[aout.length] = cbuf.join(""); | |
20927 } | |
20928 zip_deflate_data = null; // G.C. | |
20929 return aout.join(""); | |
20930 } | |
20931 | |
20932 // | |
20933 // end of the script of Masanao Izumo. | |
20934 // | |
20935 | |
20936 // we add the compression method for JSZip | |
20937 if(!JSZip.compressions["DEFLATE"]) { | |
20938 JSZip.compressions["DEFLATE"] = { | |
20939 magic : "\x08\x00", | |
20940 compress : zip_deflate | |
20941 } | |
20942 } else { | |
20943 JSZip.compressions["DEFLATE"].compress = zip_deflate; | |
20944 } | |
20945 | |
20946 })(); | |
20947 | |
20948 // enforcing Stuk's coding style | |
20949 // vim: set shiftwidth=3 softtabstop=3: | |
20950 /* | |
20951 * Port of a script by Masanao Izumo. | |
20952 * | |
20953 * Only changes : wrap all the variables in a function and add the | |
20954 * main function to JSZip (DEFLATE compression method). | |
20955 * Everything else was written by M. Izumo. | |
20956 * | |
20957 * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt | |
20958 */ | |
20959 | |
20960 if(!JSZip) { | |
20961 throw "JSZip not defined"; | |
20962 } | |
20963 | |
20964 /* | |
20965 * Original: | |
20966 * http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt | |
20967 */ | |
20968 | |
20969 (function(){ | |
20970 // the original implementation leaks a global variable. | |
20971 // Defining the variable here doesn't break anything. | |
20972 var zip_fixed_bd; | |
20973 | |
20974 /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp> | |
20975 * Version: 1.0.0.1 | |
20976 * LastModified: Dec 25 1999 | |
20977 */ | |
20978 | |
20979 /* Interface: | |
20980 * data = zip_inflate(src); | |
20981 */ | |
20982 | |
20983 /* constant parameters */ | |
20984 var zip_WSIZE = 32768; // Sliding Window size | |
20985 var zip_STORED_BLOCK = 0; | |
20986 var zip_STATIC_TREES = 1; | |
20987 var zip_DYN_TREES = 2; | |
20988 | |
20989 /* for inflate */ | |
20990 var zip_lbits = 9; // bits in base literal/length lookup table | |
20991 var zip_dbits = 6; // bits in base distance lookup table | |
20992 var zip_INBUFSIZ = 32768; // Input buffer size | |
20993 var zip_INBUF_EXTRA = 64; // Extra buffer | |
20994 | |
20995 /* variables (inflate) */ | |
20996 var zip_slide; | |
20997 var zip_wp; // current position in slide | |
20998 var zip_fixed_tl = null; // inflate static | |
20999 var zip_fixed_td; // inflate static | |
21000 var zip_fixed_bl, fixed_bd; // inflate static | |
21001 var zip_bit_buf; // bit buffer | |
21002 var zip_bit_len; // bits in bit buffer | |
21003 var zip_method; | |
21004 var zip_eof; | |
21005 var zip_copy_leng; | |
21006 var zip_copy_dist; | |
21007 var zip_tl, zip_td; // literal/length and distance decoder tables | |
21008 var zip_bl, zip_bd; // number of bits decoded by tl and td | |
21009 | |
21010 var zip_inflate_data; | |
21011 var zip_inflate_pos; | |
21012 | |
21013 | |
21014 /* constant tables (inflate) */ | |
21015 var zip_MASK_BITS = new Array( | |
21016 0x0000, | |
21017 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | |
21018 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff); | |
21019 // Tables for deflate from PKZIP's appnote.txt. | |
21020 var zip_cplens = new Array( // Copy lengths for literal codes 257..285 | |
21021 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | |
21022 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0); | |
21023 /* note: see note #13 above about the 258 in this list. */ | |
21024 var zip_cplext = new Array( // Extra bits for literal codes 257..285 | |
21025 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | |
21026 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid | |
21027 var zip_cpdist = new Array( // Copy offsets for distance codes 0..29 | |
21028 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | |
21029 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | |
21030 8193, 12289, 16385, 24577); | |
21031 var zip_cpdext = new Array( // Extra bits for distance codes | |
21032 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | |
21033 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | |
21034 12, 12, 13, 13); | |
21035 var zip_border = new Array( // Order of the bit length code lengths | |
21036 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); | |
21037 /* objects (inflate) */ | |
21038 | |
21039 function zip_HuftList() { | |
21040 this.next = null; | |
21041 this.list = null; | |
21042 } | |
21043 | |
21044 function zip_HuftNode() { | |
21045 this.e = 0; // number of extra bits or operation | |
21046 this.b = 0; // number of bits in this code or subcode | |
21047 | |
21048 // union | |
21049 this.n = 0; // literal, length base, or distance base | |
21050 this.t = null; // (zip_HuftNode) pointer to next level of table | |
21051 } | |
21052 | |
21053 function zip_HuftBuild(b, // code lengths in bits (all assumed <= BMAX) | |
21054 n, // number of codes (assumed <= N_MAX) | |
21055 s, // number of simple-valued codes (0..s-1) | |
21056 d, // list of base values for non-simple codes | |
21057 e, // list of extra bits for non-simple codes | |
21058 mm // maximum lookup bits | |
21059 ) { | |
21060 this.BMAX = 16; // maximum bit length of any code | |
21061 this.N_MAX = 288; // maximum number of codes in any set | |
21062 this.status = 0; // 0: success, 1: incomplete table, 2: bad input | |
21063 this.root = null; // (zip_HuftList) starting table | |
21064 this.m = 0; // maximum lookup bits, returns actual | |
21065 | |
21066 /* Given a list of code lengths and a maximum table size, make a set of | |
21067 tables to decode that set of codes. Return zero on success, one if | |
21068 the given code set is incomplete (the tables are still built in this | |
21069 case), two if the input is invalid (all zero length codes or an | |
21070 oversubscribed set of lengths), and three if not enough memory. | |
21071 The code with value 256 is special, and the tables are constructed | |
21072 so that no bits beyond that code are fetched when that code is | |
21073 decoded. */ | |
21074 { | |
21075 var a; // counter for codes of length k | |
21076 var c = new Array(this.BMAX+1); // bit length count table | |
21077 var el; // length of EOB code (value 256) | |
21078 var f; // i repeats in table every f entries | |
21079 var g; // maximum code length | |
21080 var h; // table level | |
21081 var i; // counter, current code | |
21082 var j; // counter | |
21083 var k; // number of bits in current code | |
21084 var lx = new Array(this.BMAX+1); // stack of bits per table | |
21085 var p; // pointer into c[], b[], or v[] | |
21086 var pidx; // index of p | |
21087 var q; // (zip_HuftNode) points to current table | |
21088 var r = new zip_HuftNode(); // table entry for structure assignment | |
21089 var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack | |
21090 var v = new Array(this.N_MAX); // values in order of bit length | |
21091 var w; | |
21092 var x = new Array(this.BMAX+1);// bit offsets, then code stack | |
21093 var xp; // pointer into x or c | |
21094 var y; // number of dummy codes added | |
21095 var z; // number of entries in current table | |
21096 var o; | |
21097 var tail; // (zip_HuftList) | |
21098 | |
21099 tail = this.root = null; | |
21100 for(i = 0; i < c.length; i++) | |
21101 c[i] = 0; | |
21102 for(i = 0; i < lx.length; i++) | |
21103 lx[i] = 0; | |
21104 for(i = 0; i < u.length; i++) | |
21105 u[i] = null; | |
21106 for(i = 0; i < v.length; i++) | |
21107 v[i] = 0; | |
21108 for(i = 0; i < x.length; i++) | |
21109 x[i] = 0; | |
21110 | |
21111 // Generate counts for each bit length | |
21112 el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any | |
21113 p = b; pidx = 0; | |
21114 i = n; | |
21115 do { | |
21116 c[p[pidx]]++; // assume all entries <= BMAX | |
21117 pidx++; | |
21118 } while(--i > 0); | |
21119 if(c[0] == n) { // null input--all zero length codes | |
21120 this.root = null; | |
21121 this.m = 0; | |
21122 this.status = 0; | |
21123 return; | |
21124 } | |
21125 | |
21126 // Find minimum and maximum length, bound *m by those | |
21127 for(j = 1; j <= this.BMAX; j++) | |
21128 if(c[j] != 0) | |
21129 break; | |
21130 k = j; // minimum code length | |
21131 if(mm < j) | |
21132 mm = j; | |
21133 for(i = this.BMAX; i != 0; i--) | |
21134 if(c[i] != 0) | |
21135 break; | |
21136 g = i; // maximum code length | |
21137 if(mm > i) | |
21138 mm = i; | |
21139 | |
21140 // Adjust last length count to fill out codes, if needed | |
21141 for(y = 1 << j; j < i; j++, y <<= 1) | |
21142 if((y -= c[j]) < 0) { | |
21143 this.status = 2; // bad input: more codes than bits | |
21144 this.m = mm; | |
21145 return; | |
21146 } | |
21147 if((y -= c[i]) < 0) { | |
21148 this.status = 2; | |
21149 this.m = mm; | |
21150 return; | |
21151 } | |
21152 c[i] += y; | |
21153 | |
21154 // Generate starting offsets into the value table for each length | |
21155 x[1] = j = 0; | |
21156 p = c; | |
21157 pidx = 1; | |
21158 xp = 2; | |
21159 while(--i > 0) // note that i == g from above | |
21160 x[xp++] = (j += p[pidx++]); | |
21161 | |
21162 // Make a table of values in order of bit lengths | |
21163 p = b; pidx = 0; | |
21164 i = 0; | |
21165 do { | |
21166 if((j = p[pidx++]) != 0) | |
21167 v[x[j]++] = i; | |
21168 } while(++i < n); | |
21169 n = x[g]; // set n to length of v | |
21170 | |
21171 // Generate the Huffman codes and for each, make the table entries | |
21172 x[0] = i = 0; // first Huffman code is zero | |
21173 p = v; pidx = 0; // grab values in bit order | |
21174 h = -1; // no tables yet--level -1 | |
21175 w = lx[0] = 0; // no bits decoded yet | |
21176 q = null; // ditto | |
21177 z = 0; // ditto | |
21178 | |
21179 // go through the bit lengths (k already is bits in shortest code) | |
21180 for(; k <= g; k++) { | |
21181 a = c[k]; | |
21182 while(a-- > 0) { | |
21183 // here i is the Huffman code of length k bits for value p[pidx] | |
21184 // make tables up to required level | |
21185 while(k > w + lx[1 + h]) { | |
21186 w += lx[1 + h]; // add bits already decoded | |
21187 h++; | |
21188 | |
21189 // compute minimum size table less than or equal to *m bits | |
21190 z = (z = g - w) > mm ? mm : z; // upper limit | |
21191 if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table | |
21192 // too few codes for k-w bit table | |
21193 f -= a + 1; // deduct codes from patterns left | |
21194 xp = k; | |
21195 while(++j < z) { // try smaller tables up to z bits | |
21196 if((f <<= 1) <= c[++xp]) | |
21197 break; // enough codes to use up j bits | |
21198 f -= c[xp]; // else deduct codes from patterns | |
21199 } | |
21200 } | |
21201 if(w + j > el && w < el) | |
21202 j = el - w; // make EOB code end at table | |
21203 z = 1 << j; // table entries for j-bit table | |
21204 lx[1 + h] = j; // set table size in stack | |
21205 | |
21206 // allocate and link in new table | |
21207 q = new Array(z); | |
21208 for(o = 0; o < z; o++) { | |
21209 q[o] = new zip_HuftNode(); | |
21210 } | |
21211 | |
21212 if(tail == null) | |
21213 tail = this.root = new zip_HuftList(); | |
21214 else | |
21215 tail = tail.next = new zip_HuftList(); | |
21216 tail.next = null; | |
21217 tail.list = q; | |
21218 u[h] = q; // table starts after link | |
21219 | |
21220 /* connect to last table, if there is one */ | |
21221 if(h > 0) { | |
21222 x[h] = i; // save pattern for backing up | |
21223 r.b = lx[h]; // bits to dump before this table | |
21224 r.e = 16 + j; // bits in this table | |
21225 r.t = q; // pointer to this table | |
21226 j = (i & ((1 << w) - 1)) >> (w - lx[h]); | |
21227 u[h-1][j].e = r.e; | |
21228 u[h-1][j].b = r.b; | |
21229 u[h-1][j].n = r.n; | |
21230 u[h-1][j].t = r.t; | |
21231 } | |
21232 } | |
21233 | |
21234 // set up table entry in r | |
21235 r.b = k - w; | |
21236 if(pidx >= n) | |
21237 r.e = 99; // out of values--invalid code | |
21238 else if(p[pidx] < s) { | |
21239 r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code | |
21240 r.n = p[pidx++]; // simple code is just the value | |
21241 } else { | |
21242 r.e = e[p[pidx] - s]; // non-simple--look up in lists | |
21243 r.n = d[p[pidx++] - s]; | |
21244 } | |
21245 | |
21246 // fill code-like entries with r // | |
21247 f = 1 << (k - w); | |
21248 for(j = i >> w; j < z; j += f) { | |
21249 q[j].e = r.e; | |
21250 q[j].b = r.b; | |
21251 q[j].n = r.n; | |
21252 q[j].t = r.t; | |
21253 } | |
21254 | |
21255 // backwards increment the k-bit code i | |
21256 for(j = 1 << (k - 1); (i & j) != 0; j >>= 1) | |
21257 i ^= j; | |
21258 i ^= j; | |
21259 | |
21260 // backup over finished tables | |
21261 while((i & ((1 << w) - 1)) != x[h]) { | |
21262 w -= lx[h]; // don't need to update q | |
21263 h--; | |
21264 } | |
21265 } | |
21266 } | |
21267 | |
21268 /* return actual size of base table */ | |
21269 this.m = lx[1]; | |
21270 | |
21271 /* Return true (1) if we were given an incomplete table */ | |
21272 this.status = ((y != 0 && g != 1) ? 1 : 0); | |
21273 } /* end of constructor */ | |
21274 } | |
21275 | |
21276 | |
21277 /* routines (inflate) */ | |
21278 | |
21279 function zip_GET_BYTE() { | |
21280 if(zip_inflate_data.length == zip_inflate_pos) | |
21281 return -1; | |
21282 return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff; | |
21283 } | |
21284 | |
21285 function zip_NEEDBITS(n) { | |
21286 while(zip_bit_len < n) { | |
21287 zip_bit_buf |= zip_GET_BYTE() << zip_bit_len; | |
21288 zip_bit_len += 8; | |
21289 } | |
21290 } | |
21291 | |
21292 function zip_GETBITS(n) { | |
21293 return zip_bit_buf & zip_MASK_BITS[n]; | |
21294 } | |
21295 | |
21296 function zip_DUMPBITS(n) { | |
21297 zip_bit_buf >>= n; | |
21298 zip_bit_len -= n; | |
21299 } | |
21300 | |
21301 function zip_inflate_codes(buff, off, size) { | |
21302 /* inflate (decompress) the codes in a deflated (compressed) block. | |
21303 Return an error code or zero if it all goes ok. */ | |
21304 var e; // table entry flag/number of extra bits | |
21305 var t; // (zip_HuftNode) pointer to table entry | |
21306 var n; | |
21307 | |
21308 if(size == 0) | |
21309 return 0; | |
21310 | |
21311 // inflate the coded data | |
21312 n = 0; | |
21313 for(;;) { // do until end of block | |
21314 zip_NEEDBITS(zip_bl); | |
21315 t = zip_tl.list[zip_GETBITS(zip_bl)]; | |
21316 e = t.e; | |
21317 while(e > 16) { | |
21318 if(e == 99) | |
21319 return -1; | |
21320 zip_DUMPBITS(t.b); | |
21321 e -= 16; | |
21322 zip_NEEDBITS(e); | |
21323 t = t.t[zip_GETBITS(e)]; | |
21324 e = t.e; | |
21325 } | |
21326 zip_DUMPBITS(t.b); | |
21327 | |
21328 if(e == 16) { // then it's a literal | |
21329 zip_wp &= zip_WSIZE - 1; | |
21330 buff[off + n++] = zip_slide[zip_wp++] = t.n; | |
21331 if(n == size) | |
21332 return size; | |
21333 continue; | |
21334 } | |
21335 | |
21336 // exit if end of block | |
21337 if(e == 15) | |
21338 break; | |
21339 | |
21340 // it's an EOB or a length | |
21341 | |
21342 // get length of block to copy | |
21343 zip_NEEDBITS(e); | |
21344 zip_copy_leng = t.n + zip_GETBITS(e); | |
21345 zip_DUMPBITS(e); | |
21346 | |
21347 // decode distance of block to copy | |
21348 zip_NEEDBITS(zip_bd); | |
21349 t = zip_td.list[zip_GETBITS(zip_bd)]; | |
21350 e = t.e; | |
21351 | |
21352 while(e > 16) { | |
21353 if(e == 99) | |
21354 return -1; | |
21355 zip_DUMPBITS(t.b); | |
21356 e -= 16; | |
21357 zip_NEEDBITS(e); | |
21358 t = t.t[zip_GETBITS(e)]; | |
21359 e = t.e; | |
21360 } | |
21361 zip_DUMPBITS(t.b); | |
21362 zip_NEEDBITS(e); | |
21363 zip_copy_dist = zip_wp - t.n - zip_GETBITS(e); | |
21364 zip_DUMPBITS(e); | |
21365 | |
21366 // do the copy | |
21367 while(zip_copy_leng > 0 && n < size) { | |
21368 zip_copy_leng--; | |
21369 zip_copy_dist &= zip_WSIZE - 1; | |
21370 zip_wp &= zip_WSIZE - 1; | |
21371 buff[off + n++] = zip_slide[zip_wp++] | |
21372 = zip_slide[zip_copy_dist++]; | |
21373 } | |
21374 | |
21375 if(n == size) | |
21376 return size; | |
21377 } | |
21378 | |
21379 zip_method = -1; // done | |
21380 return n; | |
21381 } | |
21382 | |
21383 function zip_inflate_stored(buff, off, size) { | |
21384 /* "decompress" an inflated type 0 (stored) block. */ | |
21385 var n; | |
21386 | |
21387 // go to byte boundary | |
21388 n = zip_bit_len & 7; | |
21389 zip_DUMPBITS(n); | |
21390 | |
21391 // get the length and its complement | |
21392 zip_NEEDBITS(16); | |
21393 n = zip_GETBITS(16); | |
21394 zip_DUMPBITS(16); | |
21395 zip_NEEDBITS(16); | |
21396 if(n != ((~zip_bit_buf) & 0xffff)) | |
21397 return -1; // error in compressed data | |
21398 zip_DUMPBITS(16); | |
21399 | |
21400 // read and output the compressed data | |
21401 zip_copy_leng = n; | |
21402 | |
21403 n = 0; | |
21404 while(zip_copy_leng > 0 && n < size) { | |
21405 zip_copy_leng--; | |
21406 zip_wp &= zip_WSIZE - 1; | |
21407 zip_NEEDBITS(8); | |
21408 buff[off + n++] = zip_slide[zip_wp++] = | |
21409 zip_GETBITS(8); | |
21410 zip_DUMPBITS(8); | |
21411 } | |
21412 | |
21413 if(zip_copy_leng == 0) | |
21414 zip_method = -1; // done | |
21415 return n; | |
21416 } | |
21417 | |
21418 function zip_inflate_fixed(buff, off, size) { | |
21419 /* decompress an inflated type 1 (fixed Huffman codes) block. We should | |
21420 either replace this with a custom decoder, or at least precompute the | |
21421 Huffman tables. */ | |
21422 | |
21423 // if first time, set up tables for fixed blocks | |
21424 if(zip_fixed_tl == null) { | |
21425 var i; // temporary variable | |
21426 var l = new Array(288); // length list for huft_build | |
21427 var h; // zip_HuftBuild | |
21428 | |
21429 // literal table | |
21430 for(i = 0; i < 144; i++) | |
21431 l[i] = 8; | |
21432 for(; i < 256; i++) | |
21433 l[i] = 9; | |
21434 for(; i < 280; i++) | |
21435 l[i] = 7; | |
21436 for(; i < 288; i++) // make a complete, but wrong code set | |
21437 l[i] = 8; | |
21438 zip_fixed_bl = 7; | |
21439 | |
21440 h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext, | |
21441 zip_fixed_bl); | |
21442 if(h.status != 0) { | |
21443 alert("HufBuild error: "+h.status); | |
21444 return -1; | |
21445 } | |
21446 zip_fixed_tl = h.root; | |
21447 zip_fixed_bl = h.m; | |
21448 | |
21449 // distance table | |
21450 for(i = 0; i < 30; i++) // make an incomplete code set | |
21451 l[i] = 5; | |
21452 zip_fixed_bd = 5; | |
21453 | |
21454 h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd); | |
21455 if(h.status > 1) { | |
21456 zip_fixed_tl = null; | |
21457 alert("HufBuild error: "+h.status); | |
21458 return -1; | |
21459 } | |
21460 zip_fixed_td = h.root; | |
21461 zip_fixed_bd = h.m; | |
21462 } | |
21463 | |
21464 zip_tl = zip_fixed_tl; | |
21465 zip_td = zip_fixed_td; | |
21466 zip_bl = zip_fixed_bl; | |
21467 zip_bd = zip_fixed_bd; | |
21468 return zip_inflate_codes(buff, off, size); | |
21469 } | |
21470 | |
21471 function zip_inflate_dynamic(buff, off, size) { | |
21472 // decompress an inflated type 2 (dynamic Huffman codes) block. | |
21473 var i; // temporary variables | |
21474 var j; | |
21475 var l; // last length | |
21476 var n; // number of lengths to get | |
21477 var t; // (zip_HuftNode) literal/length code table | |
21478 var nb; // number of bit length codes | |
21479 var nl; // number of literal/length codes | |
21480 var nd; // number of distance codes | |
21481 var ll = new Array(286+30); // literal/length and distance code lengths | |
21482 var h; // (zip_HuftBuild) | |
21483 | |
21484 for(i = 0; i < ll.length; i++) | |
21485 ll[i] = 0; | |
21486 | |
21487 // read in table lengths | |
21488 zip_NEEDBITS(5); | |
21489 nl = 257 + zip_GETBITS(5); // number of literal/length codes | |
21490 zip_DUMPBITS(5); | |
21491 zip_NEEDBITS(5); | |
21492 nd = 1 + zip_GETBITS(5); // number of distance codes | |
21493 zip_DUMPBITS(5); | |
21494 zip_NEEDBITS(4); | |
21495 nb = 4 + zip_GETBITS(4); // number of bit length codes | |
21496 zip_DUMPBITS(4); | |
21497 if(nl > 286 || nd > 30) | |
21498 return -1; // bad lengths | |
21499 | |
21500 // read in bit-length-code lengths | |
21501 for(j = 0; j < nb; j++) | |
21502 { | |
21503 zip_NEEDBITS(3); | |
21504 ll[zip_border[j]] = zip_GETBITS(3); | |
21505 zip_DUMPBITS(3); | |
21506 } | |
21507 for(; j < 19; j++) | |
21508 ll[zip_border[j]] = 0; | |
21509 | |
21510 // build decoding table for trees--single level, 7 bit lookup | |
21511 zip_bl = 7; | |
21512 h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl); | |
21513 if(h.status != 0) | |
21514 return -1; // incomplete code set | |
21515 | |
21516 zip_tl = h.root; | |
21517 zip_bl = h.m; | |
21518 | |
21519 // read in literal and distance code lengths | |
21520 n = nl + nd; | |
21521 i = l = 0; | |
21522 while(i < n) { | |
21523 zip_NEEDBITS(zip_bl); | |
21524 t = zip_tl.list[zip_GETBITS(zip_bl)]; | |
21525 j = t.b; | |
21526 zip_DUMPBITS(j); | |
21527 j = t.n; | |
21528 if(j < 16) // length of code in bits (0..15) | |
21529 ll[i++] = l = j; // save last length in l | |
21530 else if(j == 16) { // repeat last length 3 to 6 times | |
21531 zip_NEEDBITS(2); | |
21532 j = 3 + zip_GETBITS(2); | |
21533 zip_DUMPBITS(2); | |
21534 if(i + j > n) | |
21535 return -1; | |
21536 while(j-- > 0) | |
21537 ll[i++] = l; | |
21538 } else if(j == 17) { // 3 to 10 zero length codes | |
21539 zip_NEEDBITS(3); | |
21540 j = 3 + zip_GETBITS(3); | |
21541 zip_DUMPBITS(3); | |
21542 if(i + j > n) | |
21543 return -1; | |
21544 while(j-- > 0) | |
21545 ll[i++] = 0; | |
21546 l = 0; | |
21547 } else { // j == 18: 11 to 138 zero length codes | |
21548 zip_NEEDBITS(7); | |
21549 j = 11 + zip_GETBITS(7); | |
21550 zip_DUMPBITS(7); | |
21551 if(i + j > n) | |
21552 return -1; | |
21553 while(j-- > 0) | |
21554 ll[i++] = 0; | |
21555 l = 0; | |
21556 } | |
21557 } | |
21558 | |
21559 // build the decoding tables for literal/length and distance codes | |
21560 zip_bl = zip_lbits; | |
21561 h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl); | |
21562 if(zip_bl == 0) // no literals or lengths | |
21563 h.status = 1; | |
21564 if(h.status != 0) { | |
21565 if(h.status == 1) | |
21566 ;// **incomplete literal tree** | |
21567 return -1; // incomplete code set | |
21568 } | |
21569 zip_tl = h.root; | |
21570 zip_bl = h.m; | |
21571 | |
21572 for(i = 0; i < nd; i++) | |
21573 ll[i] = ll[i + nl]; | |
21574 zip_bd = zip_dbits; | |
21575 h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd); | |
21576 zip_td = h.root; | |
21577 zip_bd = h.m; | |
21578 | |
21579 if(zip_bd == 0 && nl > 257) { // lengths but no distances | |
21580 // **incomplete distance tree** | |
21581 return -1; | |
21582 } | |
21583 | |
21584 if(h.status == 1) { | |
21585 ;// **incomplete distance tree** | |
21586 } | |
21587 if(h.status != 0) | |
21588 return -1; | |
21589 | |
21590 // decompress until an end-of-block code | |
21591 return zip_inflate_codes(buff, off, size); | |
21592 } | |
21593 | |
21594 function zip_inflate_start() { | |
21595 var i; | |
21596 | |
21597 if(zip_slide == null) | |
21598 zip_slide = new Array(2 * zip_WSIZE); | |
21599 zip_wp = 0; | |
21600 zip_bit_buf = 0; | |
21601 zip_bit_len = 0; | |
21602 zip_method = -1; | |
21603 zip_eof = false; | |
21604 zip_copy_leng = zip_copy_dist = 0; | |
21605 zip_tl = null; | |
21606 } | |
21607 | |
21608 function zip_inflate_internal(buff, off, size) { | |
21609 // decompress an inflated entry | |
21610 var n, i; | |
21611 | |
21612 n = 0; | |
21613 while(n < size) { | |
21614 if(zip_eof && zip_method == -1) | |
21615 return n; | |
21616 | |
21617 if(zip_copy_leng > 0) { | |
21618 if(zip_method != zip_STORED_BLOCK) { | |
21619 // STATIC_TREES or DYN_TREES | |
21620 while(zip_copy_leng > 0 && n < size) { | |
21621 zip_copy_leng--; | |
21622 zip_copy_dist &= zip_WSIZE - 1; | |
21623 zip_wp &= zip_WSIZE - 1; | |
21624 buff[off + n++] = zip_slide[zip_wp++] = | |
21625 zip_slide[zip_copy_dist++]; | |
21626 } | |
21627 } else { | |
21628 while(zip_copy_leng > 0 && n < size) { | |
21629 zip_copy_leng--; | |
21630 zip_wp &= zip_WSIZE - 1; | |
21631 zip_NEEDBITS(8); | |
21632 buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8); | |
21633 zip_DUMPBITS(8); | |
21634 } | |
21635 if(zip_copy_leng == 0) | |
21636 zip_method = -1; // done | |
21637 } | |
21638 if(n == size) | |
21639 return n; | |
21640 } | |
21641 | |
21642 if(zip_method == -1) { | |
21643 if(zip_eof) | |
21644 break; | |
21645 | |
21646 // read in last block bit | |
21647 zip_NEEDBITS(1); | |
21648 if(zip_GETBITS(1) != 0) | |
21649 zip_eof = true; | |
21650 zip_DUMPBITS(1); | |
21651 | |
21652 // read in block type | |
21653 zip_NEEDBITS(2); | |
21654 zip_method = zip_GETBITS(2); | |
21655 zip_DUMPBITS(2); | |
21656 zip_tl = null; | |
21657 zip_copy_leng = 0; | |
21658 } | |
21659 | |
21660 switch(zip_method) { | |
21661 case 0: // zip_STORED_BLOCK | |
21662 i = zip_inflate_stored(buff, off + n, size - n); | |
21663 break; | |
21664 | |
21665 case 1: // zip_STATIC_TREES | |
21666 if(zip_tl != null) | |
21667 i = zip_inflate_codes(buff, off + n, size - n); | |
21668 else | |
21669 i = zip_inflate_fixed(buff, off + n, size - n); | |
21670 break; | |
21671 | |
21672 case 2: // zip_DYN_TREES | |
21673 if(zip_tl != null) | |
21674 i = zip_inflate_codes(buff, off + n, size - n); | |
21675 else | |
21676 i = zip_inflate_dynamic(buff, off + n, size - n); | |
21677 break; | |
21678 | |
21679 default: // error | |
21680 i = -1; | |
21681 break; | |
21682 } | |
21683 | |
21684 if(i == -1) { | |
21685 if(zip_eof) | |
21686 return 0; | |
21687 return -1; | |
21688 } | |
21689 n += i; | |
21690 } | |
21691 return n; | |
21692 } | |
21693 | |
21694 function zip_inflate(str) { | |
21695 var out, buff; | |
21696 var i, j; | |
21697 | |
21698 zip_inflate_start(); | |
21699 zip_inflate_data = str; | |
21700 zip_inflate_pos = 0; | |
21701 | |
21702 buff = new Array(1024); | |
21703 out = ""; | |
21704 while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) { | |
21705 for(j = 0; j < i; j++) | |
21706 out += String.fromCharCode(buff[j]); | |
21707 } | |
21708 zip_inflate_data = null; // G.C. | |
21709 return out; | |
21710 } | |
21711 | |
21712 // | |
21713 // end of the script of Masanao Izumo. | |
21714 // | |
21715 | |
21716 // we add the compression method for JSZip | |
21717 if(!JSZip.compressions["DEFLATE"]) { | |
21718 JSZip.compressions["DEFLATE"] = { | |
21719 magic : "\x08\x00", | |
21720 uncompress : zip_inflate | |
21721 } | |
21722 } else { | |
21723 JSZip.compressions["DEFLATE"].uncompress = zip_inflate; | |
21724 } | |
21725 | |
21726 })(); | |
21727 | |
21728 // enforcing Stuk's coding style | |
21729 // vim: set shiftwidth=3 softtabstop=3: | |
21730 /** | |
21731 | |
21732 JSZip - A Javascript class for generating and reading zip files | |
21733 <http://stuartk.com/jszip> | |
21734 | |
21735 (c) 2011 David Duponchel <d.duponchel@gmail.com> | |
21736 Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. | |
21737 | |
21738 **/ | |
21739 /*global JSZip,JSZipBase64 */ | |
21740 (function () { | |
21741 | |
21742 var MAX_VALUE_16BITS = 65535; | |
21743 var MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 | |
21744 | |
21745 /** | |
21746 * Prettify a string read as binary. | |
21747 * @param {string} str the string to prettify. | |
21748 * @return {string} a pretty string. | |
21749 */ | |
21750 var pretty = function (str) { | |
21751 var res = '', code, i; | |
21752 for (i = 0; i < (str||"").length; i++) { | |
21753 code = str.charCodeAt(i); | |
21754 res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); | |
21755 } | |
21756 return res; | |
21757 }; | |
21758 | |
21759 /** | |
21760 * Find a compression registered in JSZip. | |
21761 * @param {string} compressionMethod the method magic to find. | |
21762 * @return {Object|null} the JSZip compression object, null if none found. | |
21763 */ | |
21764 var findCompression = function (compressionMethod) { | |
21765 for (var method in JSZip.compressions) { | |
21766 if( !JSZip.compressions.hasOwnProperty(method) ) { continue; } | |
21767 if (JSZip.compressions[method].magic === compressionMethod) { | |
21768 return JSZip.compressions[method]; | |
21769 } | |
21770 } | |
21771 return null; | |
21772 }; | |
21773 | |
21774 // class StreamReader {{{ | |
21775 /** | |
21776 * Read bytes from a stream. | |
21777 * Developer tip : when debugging, a watch on pretty(this.reader.stream.slice(this.reader.index)) | |
21778 * is very useful :) | |
21779 * @constructor | |
21780 * @param {String|ArrayBuffer|Uint8Array} stream the stream to read. | |
21781 */ | |
21782 function StreamReader(stream) { | |
21783 this.stream = ""; | |
21784 if (JSZip.support.uint8array && stream instanceof Uint8Array) { | |
21785 this.stream = JSZip.utils.uint8Array2String(stream); | |
21786 } else if (JSZip.support.arraybuffer && stream instanceof ArrayBuffer) { | |
21787 var bufferView = new Uint8Array(stream); | |
21788 this.stream = JSZip.utils.uint8Array2String(bufferView); | |
21789 } else { | |
21790 this.stream = JSZip.utils.string2binary(stream); | |
21791 } | |
21792 this.index = 0; | |
21793 } | |
21794 StreamReader.prototype = { | |
21795 /** | |
21796 * Check that the offset will not go too far. | |
21797 * @param {string} offset the additional offset to check. | |
21798 * @throws {Error} an Error if the offset is out of bounds. | |
21799 */ | |
21800 checkOffset : function (offset) { | |
21801 this.checkIndex(this.index + offset); | |
21802 }, | |
21803 /** | |
21804 * Check that the specifed index will not be too far. | |
21805 * @param {string} newIndex the index to check. | |
21806 * @throws {Error} an Error if the index is out of bounds. | |
21807 */ | |
21808 checkIndex : function (newIndex) { | |
21809 if (this.stream.length < newIndex || newIndex < 0) { | |
21810 throw new Error("End of stream reached (stream length = " + | |
21811 this.stream.length + ", asked index = " + | |
21812 (newIndex) + "). Corrupted zip ?"); | |
21813 } | |
21814 }, | |
21815 /** | |
21816 * Change the index. | |
21817 * @param {number} newIndex The new index. | |
21818 * @throws {Error} if the new index is out of the stream. | |
21819 */ | |
21820 setIndex : function (newIndex) { | |
21821 this.checkIndex(newIndex); | |
21822 this.index = newIndex; | |
21823 }, | |
21824 /** | |
21825 * Skip the next n bytes. | |
21826 * @param {number} n the number of bytes to skip. | |
21827 * @throws {Error} if the new index is out of the stream. | |
21828 */ | |
21829 skip : function (n) { | |
21830 this.setIndex(this.index + n); | |
21831 }, | |
21832 /** | |
21833 * Get the byte at the specified index. | |
21834 * @param {number} i the index to use. | |
21835 * @return {number} a byte. | |
21836 */ | |
21837 byteAt : function(i) { | |
21838 return this.stream.charCodeAt(i); | |
21839 }, | |
21840 /** | |
21841 * Get the next number with a given byte size. | |
21842 * @param {number} size the number of bytes to read. | |
21843 * @return {number} the corresponding number. | |
21844 */ | |
21845 readInt : function (size) { | |
21846 var result = 0, i; | |
21847 this.checkOffset(size); | |
21848 for(i = this.index + size - 1; i >= this.index; i--) { | |
21849 result = (result << 8) + this.byteAt(i); | |
21850 } | |
21851 this.index += size; | |
21852 return result; | |
21853 }, | |
21854 /** | |
21855 * Get the next string with a given byte size. | |
21856 * @param {number} size the number of bytes to read. | |
21857 * @return {string} the corresponding string. | |
21858 */ | |
21859 readString : function (size) { | |
21860 this.checkOffset(size); | |
21861 // this will work because the constructor applied the "& 0xff" mask. | |
21862 var result = this.stream.slice(this.index, this.index + size); | |
21863 this.index += size; | |
21864 return result; | |
21865 }, | |
21866 /** | |
21867 * Get the next date. | |
21868 * @return {Date} the date. | |
21869 */ | |
21870 readDate : function () { | |
21871 var dostime = this.readInt(4); | |
21872 return new Date( | |
21873 ((dostime >> 25) & 0x7f) + 1980, // year | |
21874 ((dostime >> 21) & 0x0f) - 1, // month | |
21875 (dostime >> 16) & 0x1f, // day | |
21876 (dostime >> 11) & 0x1f, // hour | |
21877 (dostime >> 5) & 0x3f, // minute | |
21878 (dostime & 0x1f) << 1); // second | |
21879 } | |
21880 }; | |
21881 // }}} end of StreamReader | |
21882 | |
21883 // class ZipEntry {{{ | |
21884 /** | |
21885 * An entry in the zip file. | |
21886 * @constructor | |
21887 * @param {Object} options Options of the current file. | |
21888 * @param {Object} loadOptions Options for loading the stream. | |
21889 */ | |
21890 function ZipEntry(options, loadOptions) { | |
21891 this.options = options; | |
21892 this.loadOptions = loadOptions; | |
21893 } | |
21894 ZipEntry.prototype = { | |
21895 /** | |
21896 * say if the file is encrypted. | |
21897 * @return {boolean} true if the file is encrypted, false otherwise. | |
21898 */ | |
21899 isEncrypted : function () { | |
21900 // bit 1 is set | |
21901 return (this.bitFlag & 0x0001) === 0x0001; | |
21902 }, | |
21903 /** | |
21904 * say if the file has utf-8 filename/comment. | |
21905 * @return {boolean} true if the filename/comment is in utf-8, false otherwise. | |
21906 */ | |
21907 useUTF8 : function () { | |
21908 // bit 11 is set | |
21909 return (this.bitFlag & 0x0800) === 0x0800; | |
21910 }, | |
21911 /** | |
21912 * Read the local part of a zip file and add the info in this object. | |
21913 * @param {StreamReader} reader the reader to use. | |
21914 */ | |
21915 readLocalPart : function(reader) { | |
21916 var compression, localExtraFieldsLength; | |
21917 | |
21918 // we already know everything from the central dir ! | |
21919 // If the central dir data are false, we are doomed. | |
21920 // On the bright side, the local part is scary : zip64, data descriptors, both, etc. | |
21921 // The less data we get here, the more reliable this should be. | |
21922 // Let's skip the whole header and dash to the data ! | |
21923 reader.skip(22); | |
21924 // in some zip created on windows, the filename stored in the central dir contains \ instead of /. | |
21925 // Strangely, the filename here is OK. | |
21926 // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes | |
21927 // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... | |
21928 // Search "unzip mismatching "local" filename continuing with "central" filename version" on | |
21929 // the internet. | |
21930 // | |
21931 // I think I see the logic here : the central directory is used to display | |
21932 // content and the local directory is used to extract the files. Mixing / and \ | |
21933 // may be used to display \ to windows users and use / when extracting the files. | |
21934 // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 | |
21935 this.fileNameLength = reader.readInt(2); | |
21936 localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir | |
21937 this.fileName = reader.readString(this.fileNameLength); | |
21938 reader.skip(localExtraFieldsLength); | |
21939 | |
21940 if (this.compressedSize == -1 || this.uncompressedSize == -1) { | |
21941 throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + | |
21942 "(compressedSize == -1 || uncompressedSize == -1)"); | |
21943 } | |
21944 this.compressedFileData = reader.readString(this.compressedSize); | |
21945 | |
21946 compression = findCompression(this.compressionMethod); | |
21947 if (compression === null) { // no compression found | |
21948 throw new Error("Corrupted zip : compression " + pretty(this.compressionMethod) + | |
21949 " unknown (inner file : " + this.fileName + ")"); | |
21950 } | |
21951 this.uncompressedFileData = compression.uncompress(this.compressedFileData); | |
21952 | |
21953 if (this.uncompressedFileData.length !== this.uncompressedSize) { | |
21954 throw new Error("Bug : uncompressed data size mismatch"); | |
21955 } | |
21956 | |
21957 if (this.loadOptions.checkCRC32 && JSZip.prototype.crc32(this.uncompressedFileData) !== this.crc32) { | |
21958 throw new Error("Corrupted zip : CRC32 mismatch"); | |
21959 } | |
21960 }, | |
21961 | |
21962 /** | |
21963 * Read the central part of a zip file and add the info in this object. | |
21964 * @param {StreamReader} reader the reader to use. | |
21965 */ | |
21966 readCentralPart : function(reader) { | |
21967 this.versionMadeBy = reader.readString(2); | |
21968 this.versionNeeded = reader.readInt(2); | |
21969 this.bitFlag = reader.readInt(2); | |
21970 this.compressionMethod = reader.readString(2); | |
21971 this.date = reader.readDate(); | |
21972 this.crc32 = reader.readInt(4); | |
21973 this.compressedSize = reader.readInt(4); | |
21974 this.uncompressedSize = reader.readInt(4); | |
21975 this.fileNameLength = reader.readInt(2); | |
21976 this.extraFieldsLength = reader.readInt(2); | |
21977 this.fileCommentLength = reader.readInt(2); | |
21978 this.diskNumberStart = reader.readInt(2); | |
21979 this.internalFileAttributes = reader.readInt(2); | |
21980 this.externalFileAttributes = reader.readInt(4); | |
21981 this.localHeaderOffset = reader.readInt(4); | |
21982 | |
21983 if (this.isEncrypted()) { | |
21984 throw new Error("Encrypted zip are not supported"); | |
21985 } | |
21986 | |
21987 this.fileName = reader.readString(this.fileNameLength); | |
21988 this.readExtraFields(reader); | |
21989 this.parseZIP64ExtraField(reader); | |
21990 this.fileComment = reader.readString(this.fileCommentLength); | |
21991 | |
21992 // warning, this is true only for zip with madeBy == DOS (plateform dependent feature) | |
21993 this.dir = this.externalFileAttributes & 0x00000010 ? true : false; | |
21994 }, | |
21995 /** | |
21996 * Parse the ZIP64 extra field and merge the info in the current ZipEntry. | |
21997 * @param {StreamReader} reader the reader to use. | |
21998 */ | |
21999 parseZIP64ExtraField : function(reader) { | |
22000 | |
22001 if(!this.extraFields[0x0001]) { | |
22002 return; | |
22003 } | |
22004 | |
22005 // should be something, preparing the extra reader | |
22006 var extraReader = new StreamReader(this.extraFields[0x0001].value); | |
22007 | |
22008 // I really hope that these 64bits integer can fit in 32 bits integer, because js | |
22009 // won't let us have more. | |
22010 if(this.uncompressedSize === MAX_VALUE_32BITS) { | |
22011 this.uncompressedSize = extraReader.readInt(8); | |
22012 } | |
22013 if(this.compressedSize === MAX_VALUE_32BITS) { | |
22014 this.compressedSize = extraReader.readInt(8); | |
22015 } | |
22016 if(this.localHeaderOffset === MAX_VALUE_32BITS) { | |
22017 this.localHeaderOffset = extraReader.readInt(8); | |
22018 } | |
22019 if(this.diskNumberStart === MAX_VALUE_32BITS) { | |
22020 this.diskNumberStart = extraReader.readInt(4); | |
22021 } | |
22022 }, | |
22023 /** | |
22024 * Read the central part of a zip file and add the info in this object. | |
22025 * @param {StreamReader} reader the reader to use. | |
22026 */ | |
22027 readExtraFields : function(reader) { | |
22028 var start = reader.index, | |
22029 extraFieldId, | |
22030 extraFieldLength, | |
22031 extraFieldValue; | |
22032 | |
22033 this.extraFields = this.extraFields || {}; | |
22034 | |
22035 while (reader.index < start + this.extraFieldsLength) { | |
22036 extraFieldId = reader.readInt(2); | |
22037 extraFieldLength = reader.readInt(2); | |
22038 extraFieldValue = reader.readString(extraFieldLength); | |
22039 | |
22040 this.extraFields[extraFieldId] = { | |
22041 id: extraFieldId, | |
22042 length: extraFieldLength, | |
22043 value: extraFieldValue | |
22044 }; | |
22045 } | |
22046 }, | |
22047 /** | |
22048 * Apply an UTF8 transformation if needed. | |
22049 */ | |
22050 handleUTF8 : function() { | |
22051 if (this.useUTF8()) { | |
22052 this.fileName = JSZip.prototype.utf8decode(this.fileName); | |
22053 this.fileComment = JSZip.prototype.utf8decode(this.fileComment); | |
22054 } | |
22055 } | |
22056 }; | |
22057 // }}} end of ZipEntry | |
22058 | |
22059 // class ZipEntries {{{ | |
22060 /** | |
22061 * All the entries in the zip file. | |
22062 * @constructor | |
22063 * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. | |
22064 * @param {Object} loadOptions Options for loading the stream. | |
22065 */ | |
22066 function ZipEntries(data, loadOptions) { | |
22067 this.files = []; | |
22068 this.loadOptions = loadOptions; | |
22069 if (data) { | |
22070 this.load(data); | |
22071 } | |
22072 } | |
22073 ZipEntries.prototype = { | |
22074 /** | |
22075 * Check that the reader is on the speficied signature. | |
22076 * @param {string} expectedSignature the expected signature. | |
22077 * @throws {Error} if it is an other signature. | |
22078 */ | |
22079 checkSignature : function(expectedSignature) { | |
22080 var signature = this.reader.readString(4); | |
22081 if (signature !== expectedSignature) { | |
22082 throw new Error("Corrupted zip or bug : unexpected signature " + | |
22083 "(" + pretty(signature) + ", expected " + pretty(expectedSignature) + ")"); | |
22084 } | |
22085 }, | |
22086 /** | |
22087 * Read the end of the central directory. | |
22088 */ | |
22089 readBlockEndOfCentral : function () { | |
22090 this.diskNumber = this.reader.readInt(2); | |
22091 this.diskWithCentralDirStart = this.reader.readInt(2); | |
22092 this.centralDirRecordsOnThisDisk = this.reader.readInt(2); | |
22093 this.centralDirRecords = this.reader.readInt(2); | |
22094 this.centralDirSize = this.reader.readInt(4); | |
22095 this.centralDirOffset = this.reader.readInt(4); | |
22096 | |
22097 this.zipCommentLength = this.reader.readInt(2); | |
22098 this.zipComment = this.reader.readString(this.zipCommentLength); | |
22099 }, | |
22100 /** | |
22101 * Read the end of the Zip 64 central directory. | |
22102 * Not merged with the method readEndOfCentral : | |
22103 * The end of central can coexist with its Zip64 brother, | |
22104 * I don't want to read the wrong number of bytes ! | |
22105 */ | |
22106 readBlockZip64EndOfCentral : function () { | |
22107 this.zip64EndOfCentralSize = this.reader.readInt(8); | |
22108 this.versionMadeBy = this.reader.readString(2); | |
22109 this.versionNeeded = this.reader.readInt(2); | |
22110 this.diskNumber = this.reader.readInt(4); | |
22111 this.diskWithCentralDirStart = this.reader.readInt(4); | |
22112 this.centralDirRecordsOnThisDisk = this.reader.readInt(8); | |
22113 this.centralDirRecords = this.reader.readInt(8); | |
22114 this.centralDirSize = this.reader.readInt(8); | |
22115 this.centralDirOffset = this.reader.readInt(8); | |
22116 | |
22117 this.zip64ExtensibleData = {}; | |
22118 var extraDataSize = this.zip64EndOfCentralSize - 44, | |
22119 index = 0, | |
22120 extraFieldId, | |
22121 extraFieldLength, | |
22122 extraFieldValue; | |
22123 while(index < extraDataSize) { | |
22124 extraFieldId = this.reader.readInt(2); | |
22125 extraFieldLength = this.reader.readInt(4); | |
22126 extraFieldValue = this.reader.readString(extraFieldLength); | |
22127 this.zip64ExtensibleData[extraFieldId] = { | |
22128 id: extraFieldId, | |
22129 length: extraFieldLength, | |
22130 value: extraFieldValue | |
22131 }; | |
22132 } | |
22133 }, | |
22134 /** | |
22135 * Read the end of the Zip 64 central directory locator. | |
22136 */ | |
22137 readBlockZip64EndOfCentralLocator : function () { | |
22138 this.diskWithZip64CentralDirStart = this.reader.readInt(4); | |
22139 this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); | |
22140 this.disksCount = this.reader.readInt(4); | |
22141 if (this.disksCount > 1) { | |
22142 throw new Error("Multi-volumes zip are not supported"); | |
22143 } | |
22144 }, | |
22145 /** | |
22146 * Read the local files, based on the offset read in the central part. | |
22147 */ | |
22148 readLocalFiles : function() { | |
22149 var i, file; | |
22150 for(i = 0; i < this.files.length; i++) { | |
22151 file = this.files[i]; | |
22152 this.reader.setIndex(file.localHeaderOffset); | |
22153 this.checkSignature(JSZip.signature.LOCAL_FILE_HEADER); | |
22154 file.readLocalPart(this.reader); | |
22155 file.handleUTF8(); | |
22156 } | |
22157 }, | |
22158 /** | |
22159 * Read the central directory. | |
22160 */ | |
22161 readCentralDir : function() { | |
22162 var file; | |
22163 | |
22164 this.reader.setIndex(this.centralDirOffset); | |
22165 while(this.reader.readString(4) === JSZip.signature.CENTRAL_FILE_HEADER) { | |
22166 file = new ZipEntry({ | |
22167 zip64: this.zip64 | |
22168 }, this.loadOptions); | |
22169 file.readCentralPart(this.reader); | |
22170 this.files.push(file); | |
22171 } | |
22172 }, | |
22173 /** | |
22174 * Read the end of central directory. | |
22175 */ | |
22176 readEndOfCentral : function() { | |
22177 var offset = this.reader.stream.lastIndexOf(JSZip.signature.CENTRAL_DIRECTORY_END); | |
22178 if (offset === -1) { | |
22179 throw new Error("Corrupted zip : can't find end of central directory"); | |
22180 } | |
22181 this.reader.setIndex(offset); | |
22182 this.checkSignature(JSZip.signature.CENTRAL_DIRECTORY_END); | |
22183 this.readBlockEndOfCentral(); | |
22184 | |
22185 | |
22186 /* extract from the zip spec : | |
22187 4) If one of the fields in the end of central directory | |
22188 record is too small to hold required data, the field | |
22189 should be set to -1 (0xFFFF or 0xFFFFFFFF) and the | |
22190 ZIP64 format record should be created. | |
22191 5) The end of central directory record and the | |
22192 Zip64 end of central directory locator record must | |
22193 reside on the same disk when splitting or spanning | |
22194 an archive. | |
22195 */ | |
22196 if ( this.diskNumber === MAX_VALUE_16BITS | |
22197 || this.diskWithCentralDirStart === MAX_VALUE_16BITS | |
22198 || this.centralDirRecordsOnThisDisk === MAX_VALUE_16BITS | |
22199 || this.centralDirRecords === MAX_VALUE_16BITS | |
22200 || this.centralDirSize === MAX_VALUE_32BITS | |
22201 || this.centralDirOffset === MAX_VALUE_32BITS | |
22202 ) { | |
22203 this.zip64 = true; | |
22204 | |
22205 /* | |
22206 Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from | |
22207 the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents | |
22208 all numbers as 64-bit double precision IEEE 754 floating point numbers. | |
22209 So, we have 53bits for integers and bitwise operations treat everything as 32bits. | |
22210 see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators | |
22211 and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 | |
22212 */ | |
22213 | |
22214 // should look for a zip64 EOCD locator | |
22215 offset = this.reader.stream.lastIndexOf(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR); | |
22216 if (offset === -1) { | |
22217 throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); | |
22218 } | |
22219 this.reader.setIndex(offset); | |
22220 this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR); | |
22221 this.readBlockZip64EndOfCentralLocator(); | |
22222 | |
22223 // now the zip64 EOCD record | |
22224 this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); | |
22225 this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_END); | |
22226 this.readBlockZip64EndOfCentral(); | |
22227 } | |
22228 }, | |
22229 /** | |
22230 * Read a zip file and create ZipEntries. | |
22231 * @param {String|ArrayBuffer|Uint8Array} data the binary string representing a zip file. | |
22232 */ | |
22233 load : function(data) { | |
22234 this.reader = new StreamReader(data); | |
22235 | |
22236 this.readEndOfCentral(); | |
22237 this.readCentralDir(); | |
22238 this.readLocalFiles(); | |
22239 } | |
22240 }; | |
22241 // }}} end of ZipEntries | |
22242 | |
22243 /** | |
22244 * Implementation of the load method of JSZip. | |
22245 * It uses the above classes to decode a zip file, and load every files. | |
22246 * @param {String|ArrayBuffer|Uint8Array} data the data to load. | |
22247 * @param {Object} options Options for loading the stream. | |
22248 * options.base64 : is the stream in base64 ? default : false | |
22249 */ | |
22250 JSZip.prototype.load = function(data, options) { | |
22251 var files, zipEntries, i, input; | |
22252 options = options || {}; | |
22253 if(options.base64) { | |
22254 data = JSZipBase64.decode(data); | |
22255 } | |
22256 | |
22257 zipEntries = new ZipEntries(data, options); | |
22258 files = zipEntries.files; | |
22259 for (i = 0; i < files.length; i++) { | |
22260 input = files[i]; | |
22261 this.file(input.fileName, input.uncompressedFileData, { | |
22262 binary:true, | |
22263 optimizedBinaryString:true, | |
22264 date:input.date, | |
22265 dir:input.dir | |
22266 }); | |
22267 } | |
22268 | |
22269 return this; | |
22270 }; | |
22271 | |
22272 }()); | |
22273 // enforcing Stuk's coding style | |
22274 // vim: set shiftwidth=3 softtabstop=3 foldmethod=marker: | |
22275 //! moment.js | |
22276 //! version : 2.5.1 | |
22277 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors | |
22278 //! license : MIT | |
22279 //! momentjs.com | |
22280 | |
22281 (function (undefined) { | |
22282 | |
22283 /************************************ | |
22284 Constants | |
22285 ************************************/ | |
22286 | |
22287 var moment, | |
22288 VERSION = "2.5.1", | |
22289 global = this, | |
22290 round = Math.round, | |
22291 i, | |
22292 | |
22293 YEAR = 0, | |
22294 MONTH = 1, | |
22295 DATE = 2, | |
22296 HOUR = 3, | |
22297 MINUTE = 4, | |
22298 SECOND = 5, | |
22299 MILLISECOND = 6, | |
22300 | |
22301 // internal storage for language config files | |
22302 languages = {}, | |
22303 | |
22304 // moment internal properties | |
22305 momentProperties = { | |
22306 _isAMomentObject: null, | |
22307 _i : null, | |
22308 _f : null, | |
22309 _l : null, | |
22310 _strict : null, | |
22311 _isUTC : null, | |
22312 _offset : null, // optional. Combine with _isUTC | |
22313 _pf : null, | |
22314 _lang : null // optional | |
22315 }, | |
22316 | |
22317 // check for nodeJS | |
22318 hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'), | |
22319 | |
22320 // ASP.NET json date format regex | |
22321 aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, | |
22322 aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, | |
22323 | |
22324 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html | |
22325 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere | |
22326 isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, | |
22327 | |
22328 // format tokens | |
22329 formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g, | |
22330 localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, | |
22331 | |
22332 // parsing token regexes | |
22333 parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 | |
22334 parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 | |
22335 parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 | |
22336 parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 | |
22337 parseTokenDigits = /\d+/, // nonzero number of digits | |
22338 parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic. | |
22339 parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z | |
22340 parseTokenT = /T/i, // T (ISO separator) | |
22341 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 | |
22342 | |
22343 //strict parsing regexes | |
22344 parseTokenOneDigit = /\d/, // 0 - 9 | |
22345 parseTokenTwoDigits = /\d\d/, // 00 - 99 | |
22346 parseTokenThreeDigits = /\d{3}/, // 000 - 999 | |
22347 parseTokenFourDigits = /\d{4}/, // 0000 - 9999 | |
22348 parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 | |
22349 parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf | |
22350 | |
22351 // iso 8601 regex | |
22352 // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) | |
22353 isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/, | |
22354 | |
22355 isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', | |
22356 | |
22357 isoDates = [ | |
22358 ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], | |
22359 ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], | |
22360 ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], | |
22361 ['GGGG-[W]WW', /\d{4}-W\d{2}/], | |
22362 ['YYYY-DDD', /\d{4}-\d{3}/] | |
22363 ], | |
22364 | |
22365 // iso time formats and regexes | |
22366 isoTimes = [ | |
22367 ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], | |
22368 ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], | |
22369 ['HH:mm', /(T| )\d\d:\d\d/], | |
22370 ['HH', /(T| )\d\d/] | |
22371 ], | |
22372 | |
22373 // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] | |
22374 parseTimezoneChunker = /([\+\-]|\d\d)/gi, | |
22375 | |
22376 // getter and setter names | |
22377 proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), | |
22378 unitMillisecondFactors = { | |
22379 'Milliseconds' : 1, | |
22380 'Seconds' : 1e3, | |
22381 'Minutes' : 6e4, | |
22382 'Hours' : 36e5, | |
22383 'Days' : 864e5, | |
22384 'Months' : 2592e6, | |
22385 'Years' : 31536e6 | |
22386 }, | |
22387 | |
22388 unitAliases = { | |
22389 ms : 'millisecond', | |
22390 s : 'second', | |
22391 m : 'minute', | |
22392 h : 'hour', | |
22393 d : 'day', | |
22394 D : 'date', | |
22395 w : 'week', | |
22396 W : 'isoWeek', | |
22397 M : 'month', | |
22398 y : 'year', | |
22399 DDD : 'dayOfYear', | |
22400 e : 'weekday', | |
22401 E : 'isoWeekday', | |
22402 gg: 'weekYear', | |
22403 GG: 'isoWeekYear' | |
22404 }, | |
22405 | |
22406 camelFunctions = { | |
22407 dayofyear : 'dayOfYear', | |
22408 isoweekday : 'isoWeekday', | |
22409 isoweek : 'isoWeek', | |
22410 weekyear : 'weekYear', | |
22411 isoweekyear : 'isoWeekYear' | |
22412 }, | |
22413 | |
22414 // format function strings | |
22415 formatFunctions = {}, | |
22416 | |
22417 // tokens to ordinalize and pad | |
22418 ordinalizeTokens = 'DDD w W M D d'.split(' '), | |
22419 paddedTokens = 'M D H h m s w W'.split(' '), | |
22420 | |
22421 formatTokenFunctions = { | |
22422 M : function () { | |
22423 return this.month() + 1; | |
22424 }, | |
22425 MMM : function (format) { | |
22426 return this.lang().monthsShort(this, format); | |
22427 }, | |
22428 MMMM : function (format) { | |
22429 return this.lang().months(this, format); | |
22430 }, | |
22431 D : function () { | |
22432 return this.date(); | |
22433 }, | |
22434 DDD : function () { | |
22435 return this.dayOfYear(); | |
22436 }, | |
22437 d : function () { | |
22438 return this.day(); | |
22439 }, | |
22440 dd : function (format) { | |
22441 return this.lang().weekdaysMin(this, format); | |
22442 }, | |
22443 ddd : function (format) { | |
22444 return this.lang().weekdaysShort(this, format); | |
22445 }, | |
22446 dddd : function (format) { | |
22447 return this.lang().weekdays(this, format); | |
22448 }, | |
22449 w : function () { | |
22450 return this.week(); | |
22451 }, | |
22452 W : function () { | |
22453 return this.isoWeek(); | |
22454 }, | |
22455 YY : function () { | |
22456 return leftZeroFill(this.year() % 100, 2); | |
22457 }, | |
22458 YYYY : function () { | |
22459 return leftZeroFill(this.year(), 4); | |
22460 }, | |
22461 YYYYY : function () { | |
22462 return leftZeroFill(this.year(), 5); | |
22463 }, | |
22464 YYYYYY : function () { | |
22465 var y = this.year(), sign = y >= 0 ? '+' : '-'; | |
22466 return sign + leftZeroFill(Math.abs(y), 6); | |
22467 }, | |
22468 gg : function () { | |
22469 return leftZeroFill(this.weekYear() % 100, 2); | |
22470 }, | |
22471 gggg : function () { | |
22472 return leftZeroFill(this.weekYear(), 4); | |
22473 }, | |
22474 ggggg : function () { | |
22475 return leftZeroFill(this.weekYear(), 5); | |
22476 }, | |
22477 GG : function () { | |
22478 return leftZeroFill(this.isoWeekYear() % 100, 2); | |
22479 }, | |
22480 GGGG : function () { | |
22481 return leftZeroFill(this.isoWeekYear(), 4); | |
22482 }, | |
22483 GGGGG : function () { | |
22484 return leftZeroFill(this.isoWeekYear(), 5); | |
22485 }, | |
22486 e : function () { | |
22487 return this.weekday(); | |
22488 }, | |
22489 E : function () { | |
22490 return this.isoWeekday(); | |
22491 }, | |
22492 a : function () { | |
22493 return this.lang().meridiem(this.hours(), this.minutes(), true); | |
22494 }, | |
22495 A : function () { | |
22496 return this.lang().meridiem(this.hours(), this.minutes(), false); | |
22497 }, | |
22498 H : function () { | |
22499 return this.hours(); | |
22500 }, | |
22501 h : function () { | |
22502 return this.hours() % 12 || 12; | |
22503 }, | |
22504 m : function () { | |
22505 return this.minutes(); | |
22506 }, | |
22507 s : function () { | |
22508 return this.seconds(); | |
22509 }, | |
22510 S : function () { | |
22511 return toInt(this.milliseconds() / 100); | |
22512 }, | |
22513 SS : function () { | |
22514 return leftZeroFill(toInt(this.milliseconds() / 10), 2); | |
22515 }, | |
22516 SSS : function () { | |
22517 return leftZeroFill(this.milliseconds(), 3); | |
22518 }, | |
22519 SSSS : function () { | |
22520 return leftZeroFill(this.milliseconds(), 3); | |
22521 }, | |
22522 Z : function () { | |
22523 var a = -this.zone(), | |
22524 b = "+"; | |
22525 if (a < 0) { | |
22526 a = -a; | |
22527 b = "-"; | |
22528 } | |
22529 return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2); | |
22530 }, | |
22531 ZZ : function () { | |
22532 var a = -this.zone(), | |
22533 b = "+"; | |
22534 if (a < 0) { | |
22535 a = -a; | |
22536 b = "-"; | |
22537 } | |
22538 return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); | |
22539 }, | |
22540 z : function () { | |
22541 return this.zoneAbbr(); | |
22542 }, | |
22543 zz : function () { | |
22544 return this.zoneName(); | |
22545 }, | |
22546 X : function () { | |
22547 return this.unix(); | |
22548 }, | |
22549 Q : function () { | |
22550 return this.quarter(); | |
22551 } | |
22552 }, | |
22553 | |
22554 lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; | |
22555 | |
22556 function defaultParsingFlags() { | |
22557 // We need to deep clone this object, and es5 standard is not very | |
22558 // helpful. | |
22559 return { | |
22560 empty : false, | |
22561 unusedTokens : [], | |
22562 unusedInput : [], | |
22563 overflow : -2, | |
22564 charsLeftOver : 0, | |
22565 nullInput : false, | |
22566 invalidMonth : null, | |
22567 invalidFormat : false, | |
22568 userInvalidated : false, | |
22569 iso: false | |
22570 }; | |
22571 } | |
22572 | |
22573 function padToken(func, count) { | |
22574 return function (a) { | |
22575 return leftZeroFill(func.call(this, a), count); | |
22576 }; | |
22577 } | |
22578 function ordinalizeToken(func, period) { | |
22579 return function (a) { | |
22580 return this.lang().ordinal(func.call(this, a), period); | |
22581 }; | |
22582 } | |
22583 | |
22584 while (ordinalizeTokens.length) { | |
22585 i = ordinalizeTokens.pop(); | |
22586 formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); | |
22587 } | |
22588 while (paddedTokens.length) { | |
22589 i = paddedTokens.pop(); | |
22590 formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); | |
22591 } | |
22592 formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); | |
22593 | |
22594 | |
22595 /************************************ | |
22596 Constructors | |
22597 ************************************/ | |
22598 | |
22599 function Language() { | |
22600 | |
22601 } | |
22602 | |
22603 // Moment prototype object | |
22604 function Moment(config) { | |
22605 checkOverflow(config); | |
22606 extend(this, config); | |
22607 } | |
22608 | |
22609 // Duration Constructor | |
22610 function Duration(duration) { | |
22611 var normalizedInput = normalizeObjectUnits(duration), | |
22612 years = normalizedInput.year || 0, | |
22613 months = normalizedInput.month || 0, | |
22614 weeks = normalizedInput.week || 0, | |
22615 days = normalizedInput.day || 0, | |
22616 hours = normalizedInput.hour || 0, | |
22617 minutes = normalizedInput.minute || 0, | |
22618 seconds = normalizedInput.second || 0, | |
22619 milliseconds = normalizedInput.millisecond || 0; | |
22620 | |
22621 // representation for dateAddRemove | |
22622 this._milliseconds = +milliseconds + | |
22623 seconds * 1e3 + // 1000 | |
22624 minutes * 6e4 + // 1000 * 60 | |
22625 hours * 36e5; // 1000 * 60 * 60 | |
22626 // Because of dateAddRemove treats 24 hours as different from a | |
22627 // day when working around DST, we need to store them separately | |
22628 this._days = +days + | |
22629 weeks * 7; | |
22630 // It is impossible translate months into days without knowing | |
22631 // which months you are are talking about, so we have to store | |
22632 // it separately. | |
22633 this._months = +months + | |
22634 years * 12; | |
22635 | |
22636 this._data = {}; | |
22637 | |
22638 this._bubble(); | |
22639 } | |
22640 | |
22641 /************************************ | |
22642 Helpers | |
22643 ************************************/ | |
22644 | |
22645 | |
22646 function extend(a, b) { | |
22647 for (var i in b) { | |
22648 if (b.hasOwnProperty(i)) { | |
22649 a[i] = b[i]; | |
22650 } | |
22651 } | |
22652 | |
22653 if (b.hasOwnProperty("toString")) { | |
22654 a.toString = b.toString; | |
22655 } | |
22656 | |
22657 if (b.hasOwnProperty("valueOf")) { | |
22658 a.valueOf = b.valueOf; | |
22659 } | |
22660 | |
22661 return a; | |
22662 } | |
22663 | |
22664 function cloneMoment(m) { | |
22665 var result = {}, i; | |
22666 for (i in m) { | |
22667 if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) { | |
22668 result[i] = m[i]; | |
22669 } | |
22670 } | |
22671 | |
22672 return result; | |
22673 } | |
22674 | |
22675 function absRound(number) { | |
22676 if (number < 0) { | |
22677 return Math.ceil(number); | |
22678 } else { | |
22679 return Math.floor(number); | |
22680 } | |
22681 } | |
22682 | |
22683 // left zero fill a number | |
22684 // see http://jsperf.com/left-zero-filling for performance comparison | |
22685 function leftZeroFill(number, targetLength, forceSign) { | |
22686 var output = '' + Math.abs(number), | |
22687 sign = number >= 0; | |
22688 | |
22689 while (output.length < targetLength) { | |
22690 output = '0' + output; | |
22691 } | |
22692 return (sign ? (forceSign ? '+' : '') : '-') + output; | |
22693 } | |
22694 | |
22695 // helper function for _.addTime and _.subtractTime | |
22696 function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) { | |
22697 var milliseconds = duration._milliseconds, | |
22698 days = duration._days, | |
22699 months = duration._months, | |
22700 minutes, | |
22701 hours; | |
22702 | |
22703 if (milliseconds) { | |
22704 mom._d.setTime(+mom._d + milliseconds * isAdding); | |
22705 } | |
22706 // store the minutes and hours so we can restore them | |
22707 if (days || months) { | |
22708 minutes = mom.minute(); | |
22709 hours = mom.hour(); | |
22710 } | |
22711 if (days) { | |
22712 mom.date(mom.date() + days * isAdding); | |
22713 } | |
22714 if (months) { | |
22715 mom.month(mom.month() + months * isAdding); | |
22716 } | |
22717 if (milliseconds && !ignoreUpdateOffset) { | |
22718 moment.updateOffset(mom); | |
22719 } | |
22720 // restore the minutes and hours after possibly changing dst | |
22721 if (days || months) { | |
22722 mom.minute(minutes); | |
22723 mom.hour(hours); | |
22724 } | |
22725 } | |
22726 | |
22727 // check if is an array | |
22728 function isArray(input) { | |
22729 return Object.prototype.toString.call(input) === '[object Array]'; | |
22730 } | |
22731 | |
22732 function isDate(input) { | |
22733 return Object.prototype.toString.call(input) === '[object Date]' || | |
22734 input instanceof Date; | |
22735 } | |
22736 | |
22737 // compare two arrays, return the number of differences | |
22738 function compareArrays(array1, array2, dontConvert) { | |
22739 var len = Math.min(array1.length, array2.length), | |
22740 lengthDiff = Math.abs(array1.length - array2.length), | |
22741 diffs = 0, | |
22742 i; | |
22743 for (i = 0; i < len; i++) { | |
22744 if ((dontConvert && array1[i] !== array2[i]) || | |
22745 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { | |
22746 diffs++; | |
22747 } | |
22748 } | |
22749 return diffs + lengthDiff; | |
22750 } | |
22751 | |
22752 function normalizeUnits(units) { | |
22753 if (units) { | |
22754 var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); | |
22755 units = unitAliases[units] || camelFunctions[lowered] || lowered; | |
22756 } | |
22757 return units; | |
22758 } | |
22759 | |
22760 function normalizeObjectUnits(inputObject) { | |
22761 var normalizedInput = {}, | |
22762 normalizedProp, | |
22763 prop; | |
22764 | |
22765 for (prop in inputObject) { | |
22766 if (inputObject.hasOwnProperty(prop)) { | |
22767 normalizedProp = normalizeUnits(prop); | |
22768 if (normalizedProp) { | |
22769 normalizedInput[normalizedProp] = inputObject[prop]; | |
22770 } | |
22771 } | |
22772 } | |
22773 | |
22774 return normalizedInput; | |
22775 } | |
22776 | |
22777 function makeList(field) { | |
22778 var count, setter; | |
22779 | |
22780 if (field.indexOf('week') === 0) { | |
22781 count = 7; | |
22782 setter = 'day'; | |
22783 } | |
22784 else if (field.indexOf('month') === 0) { | |
22785 count = 12; | |
22786 setter = 'month'; | |
22787 } | |
22788 else { | |
22789 return; | |
22790 } | |
22791 | |
22792 moment[field] = function (format, index) { | |
22793 var i, getter, | |
22794 method = moment.fn._lang[field], | |
22795 results = []; | |
22796 | |
22797 if (typeof format === 'number') { | |
22798 index = format; | |
22799 format = undefined; | |
22800 } | |
22801 | |
22802 getter = function (i) { | |
22803 var m = moment().utc().set(setter, i); | |
22804 return method.call(moment.fn._lang, m, format || ''); | |
22805 }; | |
22806 | |
22807 if (index != null) { | |
22808 return getter(index); | |
22809 } | |
22810 else { | |
22811 for (i = 0; i < count; i++) { | |
22812 results.push(getter(i)); | |
22813 } | |
22814 return results; | |
22815 } | |
22816 }; | |
22817 } | |
22818 | |
22819 function toInt(argumentForCoercion) { | |
22820 var coercedNumber = +argumentForCoercion, | |
22821 value = 0; | |
22822 | |
22823 if (coercedNumber !== 0 && isFinite(coercedNumber)) { | |
22824 if (coercedNumber >= 0) { | |
22825 value = Math.floor(coercedNumber); | |
22826 } else { | |
22827 value = Math.ceil(coercedNumber); | |
22828 } | |
22829 } | |
22830 | |
22831 return value; | |
22832 } | |
22833 | |
22834 function daysInMonth(year, month) { | |
22835 return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); | |
22836 } | |
22837 | |
22838 function daysInYear(year) { | |
22839 return isLeapYear(year) ? 366 : 365; | |
22840 } | |
22841 | |
22842 function isLeapYear(year) { | |
22843 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; | |
22844 } | |
22845 | |
22846 function checkOverflow(m) { | |
22847 var overflow; | |
22848 if (m._a && m._pf.overflow === -2) { | |
22849 overflow = | |
22850 m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : | |
22851 m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : | |
22852 m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : | |
22853 m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : | |
22854 m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : | |
22855 m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : | |
22856 -1; | |
22857 | |
22858 if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { | |
22859 overflow = DATE; | |
22860 } | |
22861 | |
22862 m._pf.overflow = overflow; | |
22863 } | |
22864 } | |
22865 | |
22866 function isValid(m) { | |
22867 if (m._isValid == null) { | |
22868 m._isValid = !isNaN(m._d.getTime()) && | |
22869 m._pf.overflow < 0 && | |
22870 !m._pf.empty && | |
22871 !m._pf.invalidMonth && | |
22872 !m._pf.nullInput && | |
22873 !m._pf.invalidFormat && | |
22874 !m._pf.userInvalidated; | |
22875 | |
22876 if (m._strict) { | |
22877 m._isValid = m._isValid && | |
22878 m._pf.charsLeftOver === 0 && | |
22879 m._pf.unusedTokens.length === 0; | |
22880 } | |
22881 } | |
22882 return m._isValid; | |
22883 } | |
22884 | |
22885 function normalizeLanguage(key) { | |
22886 return key ? key.toLowerCase().replace('_', '-') : key; | |
22887 } | |
22888 | |
22889 // Return a moment from input, that is local/utc/zone equivalent to model. | |
22890 function makeAs(input, model) { | |
22891 return model._isUTC ? moment(input).zone(model._offset || 0) : | |
22892 moment(input).local(); | |
22893 } | |
22894 | |
22895 /************************************ | |
22896 Languages | |
22897 ************************************/ | |
22898 | |
22899 | |
22900 extend(Language.prototype, { | |
22901 | |
22902 set : function (config) { | |
22903 var prop, i; | |
22904 for (i in config) { | |
22905 prop = config[i]; | |
22906 if (typeof prop === 'function') { | |
22907 this[i] = prop; | |
22908 } else { | |
22909 this['_' + i] = prop; | |
22910 } | |
22911 } | |
22912 }, | |
22913 | |
22914 _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), | |
22915 months : function (m) { | |
22916 return this._months[m.month()]; | |
22917 }, | |
22918 | |
22919 _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), | |
22920 monthsShort : function (m) { | |
22921 return this._monthsShort[m.month()]; | |
22922 }, | |
22923 | |
22924 monthsParse : function (monthName) { | |
22925 var i, mom, regex; | |
22926 | |
22927 if (!this._monthsParse) { | |
22928 this._monthsParse = []; | |
22929 } | |
22930 | |
22931 for (i = 0; i < 12; i++) { | |
22932 // make the regex if we don't have it already | |
22933 if (!this._monthsParse[i]) { | |
22934 mom = moment.utc([2000, i]); | |
22935 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); | |
22936 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); | |
22937 } | |
22938 // test the regex | |
22939 if (this._monthsParse[i].test(monthName)) { | |
22940 return i; | |
22941 } | |
22942 } | |
22943 }, | |
22944 | |
22945 _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), | |
22946 weekdays : function (m) { | |
22947 return this._weekdays[m.day()]; | |
22948 }, | |
22949 | |
22950 _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), | |
22951 weekdaysShort : function (m) { | |
22952 return this._weekdaysShort[m.day()]; | |
22953 }, | |
22954 | |
22955 _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), | |
22956 weekdaysMin : function (m) { | |
22957 return this._weekdaysMin[m.day()]; | |
22958 }, | |
22959 | |
22960 weekdaysParse : function (weekdayName) { | |
22961 var i, mom, regex; | |
22962 | |
22963 if (!this._weekdaysParse) { | |
22964 this._weekdaysParse = []; | |
22965 } | |
22966 | |
22967 for (i = 0; i < 7; i++) { | |
22968 // make the regex if we don't have it already | |
22969 if (!this._weekdaysParse[i]) { | |
22970 mom = moment([2000, 1]).day(i); | |
22971 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); | |
22972 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); | |
22973 } | |
22974 // test the regex | |
22975 if (this._weekdaysParse[i].test(weekdayName)) { | |
22976 return i; | |
22977 } | |
22978 } | |
22979 }, | |
22980 | |
22981 _longDateFormat : { | |
22982 LT : "h:mm A", | |
22983 L : "MM/DD/YYYY", | |
22984 LL : "MMMM D YYYY", | |
22985 LLL : "MMMM D YYYY LT", | |
22986 LLLL : "dddd, MMMM D YYYY LT" | |
22987 }, | |
22988 longDateFormat : function (key) { | |
22989 var output = this._longDateFormat[key]; | |
22990 if (!output && this._longDateFormat[key.toUpperCase()]) { | |
22991 output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { | |
22992 return val.slice(1); | |
22993 }); | |
22994 this._longDateFormat[key] = output; | |
22995 } | |
22996 return output; | |
22997 }, | |
22998 | |
22999 isPM : function (input) { | |
23000 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays | |
23001 // Using charAt should be more compatible. | |
23002 return ((input + '').toLowerCase().charAt(0) === 'p'); | |
23003 }, | |
23004 | |
23005 _meridiemParse : /[ap]\.?m?\.?/i, | |
23006 meridiem : function (hours, minutes, isLower) { | |
23007 if (hours > 11) { | |
23008 return isLower ? 'pm' : 'PM'; | |
23009 } else { | |
23010 return isLower ? 'am' : 'AM'; | |
23011 } | |
23012 }, | |
23013 | |
23014 _calendar : { | |
23015 sameDay : '[Today at] LT', | |
23016 nextDay : '[Tomorrow at] LT', | |
23017 nextWeek : 'dddd [at] LT', | |
23018 lastDay : '[Yesterday at] LT', | |
23019 lastWeek : '[Last] dddd [at] LT', | |
23020 sameElse : 'L' | |
23021 }, | |
23022 calendar : function (key, mom) { | |
23023 var output = this._calendar[key]; | |
23024 return typeof output === 'function' ? output.apply(mom) : output; | |
23025 }, | |
23026 | |
23027 _relativeTime : { | |
23028 future : "in %s", | |
23029 past : "%s ago", | |
23030 s : "a few seconds", | |
23031 m : "a minute", | |
23032 mm : "%d minutes", | |
23033 h : "an hour", | |
23034 hh : "%d hours", | |
23035 d : "a day", | |
23036 dd : "%d days", | |
23037 M : "a month", | |
23038 MM : "%d months", | |
23039 y : "a year", | |
23040 yy : "%d years" | |
23041 }, | |
23042 relativeTime : function (number, withoutSuffix, string, isFuture) { | |
23043 var output = this._relativeTime[string]; | |
23044 return (typeof output === 'function') ? | |
23045 output(number, withoutSuffix, string, isFuture) : | |
23046 output.replace(/%d/i, number); | |
23047 }, | |
23048 pastFuture : function (diff, output) { | |
23049 var format = this._relativeTime[diff > 0 ? 'future' : 'past']; | |
23050 return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); | |
23051 }, | |
23052 | |
23053 ordinal : function (number) { | |
23054 return this._ordinal.replace("%d", number); | |
23055 }, | |
23056 _ordinal : "%d", | |
23057 | |
23058 preparse : function (string) { | |
23059 return string; | |
23060 }, | |
23061 | |
23062 postformat : function (string) { | |
23063 return string; | |
23064 }, | |
23065 | |
23066 week : function (mom) { | |
23067 return weekOfYear(mom, this._week.dow, this._week.doy).week; | |
23068 }, | |
23069 | |
23070 _week : { | |
23071 dow : 0, // Sunday is the first day of the week. | |
23072 doy : 6 // The week that contains Jan 1st is the first week of the year. | |
23073 }, | |
23074 | |
23075 _invalidDate: 'Invalid date', | |
23076 invalidDate: function () { | |
23077 return this._invalidDate; | |
23078 } | |
23079 }); | |
23080 | |
23081 // Loads a language definition into the `languages` cache. The function | |
23082 // takes a key and optionally values. If not in the browser and no values | |
23083 // are provided, it will load the language file module. As a convenience, | |
23084 // this function also returns the language values. | |
23085 function loadLang(key, values) { | |
23086 values.abbr = key; | |
23087 if (!languages[key]) { | |
23088 languages[key] = new Language(); | |
23089 } | |
23090 languages[key].set(values); | |
23091 return languages[key]; | |
23092 } | |
23093 | |
23094 // Remove a language from the `languages` cache. Mostly useful in tests. | |
23095 function unloadLang(key) { | |
23096 delete languages[key]; | |
23097 } | |
23098 | |
23099 // Determines which language definition to use and returns it. | |
23100 // | |
23101 // With no parameters, it will return the global language. If you | |
23102 // pass in a language key, such as 'en', it will return the | |
23103 // definition for 'en', so long as 'en' has already been loaded using | |
23104 // moment.lang. | |
23105 function getLangDefinition(key) { | |
23106 var i = 0, j, lang, next, split, | |
23107 get = function (k) { | |
23108 if (!languages[k] && hasModule) { | |
23109 try { | |
23110 require('./lang/' + k); | |
23111 } catch (e) { } | |
23112 } | |
23113 return languages[k]; | |
23114 }; | |
23115 | |
23116 if (!key) { | |
23117 return moment.fn._lang; | |
23118 } | |
23119 | |
23120 if (!isArray(key)) { | |
23121 //short-circuit everything else | |
23122 lang = get(key); | |
23123 if (lang) { | |
23124 return lang; | |
23125 } | |
23126 key = [key]; | |
23127 } | |
23128 | |
23129 //pick the language from the array | |
23130 //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each | |
23131 //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root | |
23132 while (i < key.length) { | |
23133 split = normalizeLanguage(key[i]).split('-'); | |
23134 j = split.length; | |
23135 next = normalizeLanguage(key[i + 1]); | |
23136 next = next ? next.split('-') : null; | |
23137 while (j > 0) { | |
23138 lang = get(split.slice(0, j).join('-')); | |
23139 if (lang) { | |
23140 return lang; | |
23141 } | |
23142 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { | |
23143 //the next array item is better than a shallower substring of this one | |
23144 break; | |
23145 } | |
23146 j--; | |
23147 } | |
23148 i++; | |
23149 } | |
23150 return moment.fn._lang; | |
23151 } | |
23152 | |
23153 /************************************ | |
23154 Formatting | |
23155 ************************************/ | |
23156 | |
23157 | |
23158 function removeFormattingTokens(input) { | |
23159 if (input.match(/\[[\s\S]/)) { | |
23160 return input.replace(/^\[|\]$/g, ""); | |
23161 } | |
23162 return input.replace(/\\/g, ""); | |
23163 } | |
23164 | |
23165 function makeFormatFunction(format) { | |
23166 var array = format.match(formattingTokens), i, length; | |
23167 | |
23168 for (i = 0, length = array.length; i < length; i++) { | |
23169 if (formatTokenFunctions[array[i]]) { | |
23170 array[i] = formatTokenFunctions[array[i]]; | |
23171 } else { | |
23172 array[i] = removeFormattingTokens(array[i]); | |
23173 } | |
23174 } | |
23175 | |
23176 return function (mom) { | |
23177 var output = ""; | |
23178 for (i = 0; i < length; i++) { | |
23179 output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; | |
23180 } | |
23181 return output; | |
23182 }; | |
23183 } | |
23184 | |
23185 // format date using native date object | |
23186 function formatMoment(m, format) { | |
23187 | |
23188 if (!m.isValid()) { | |
23189 return m.lang().invalidDate(); | |
23190 } | |
23191 | |
23192 format = expandFormat(format, m.lang()); | |
23193 | |
23194 if (!formatFunctions[format]) { | |
23195 formatFunctions[format] = makeFormatFunction(format); | |
23196 } | |
23197 | |
23198 return formatFunctions[format](m); | |
23199 } | |
23200 | |
23201 function expandFormat(format, lang) { | |
23202 var i = 5; | |
23203 | |
23204 function replaceLongDateFormatTokens(input) { | |
23205 return lang.longDateFormat(input) || input; | |
23206 } | |
23207 | |
23208 localFormattingTokens.lastIndex = 0; | |
23209 while (i >= 0 && localFormattingTokens.test(format)) { | |
23210 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); | |
23211 localFormattingTokens.lastIndex = 0; | |
23212 i -= 1; | |
23213 } | |
23214 | |
23215 return format; | |
23216 } | |
23217 | |
23218 | |
23219 /************************************ | |
23220 Parsing | |
23221 ************************************/ | |
23222 | |
23223 | |
23224 // get the regex to find the next token | |
23225 function getParseRegexForToken(token, config) { | |
23226 var a, strict = config._strict; | |
23227 switch (token) { | |
23228 case 'DDDD': | |
23229 return parseTokenThreeDigits; | |
23230 case 'YYYY': | |
23231 case 'GGGG': | |
23232 case 'gggg': | |
23233 return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; | |
23234 case 'Y': | |
23235 case 'G': | |
23236 case 'g': | |
23237 return parseTokenSignedNumber; | |
23238 case 'YYYYYY': | |
23239 case 'YYYYY': | |
23240 case 'GGGGG': | |
23241 case 'ggggg': | |
23242 return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; | |
23243 case 'S': | |
23244 if (strict) { return parseTokenOneDigit; } | |
23245 /* falls through */ | |
23246 case 'SS': | |
23247 if (strict) { return parseTokenTwoDigits; } | |
23248 /* falls through */ | |
23249 case 'SSS': | |
23250 if (strict) { return parseTokenThreeDigits; } | |
23251 /* falls through */ | |
23252 case 'DDD': | |
23253 return parseTokenOneToThreeDigits; | |
23254 case 'MMM': | |
23255 case 'MMMM': | |
23256 case 'dd': | |
23257 case 'ddd': | |
23258 case 'dddd': | |
23259 return parseTokenWord; | |
23260 case 'a': | |
23261 case 'A': | |
23262 return getLangDefinition(config._l)._meridiemParse; | |
23263 case 'X': | |
23264 return parseTokenTimestampMs; | |
23265 case 'Z': | |
23266 case 'ZZ': | |
23267 return parseTokenTimezone; | |
23268 case 'T': | |
23269 return parseTokenT; | |
23270 case 'SSSS': | |
23271 return parseTokenDigits; | |
23272 case 'MM': | |
23273 case 'DD': | |
23274 case 'YY': | |
23275 case 'GG': | |
23276 case 'gg': | |
23277 case 'HH': | |
23278 case 'hh': | |
23279 case 'mm': | |
23280 case 'ss': | |
23281 case 'ww': | |
23282 case 'WW': | |
23283 return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; | |
23284 case 'M': | |
23285 case 'D': | |
23286 case 'd': | |
23287 case 'H': | |
23288 case 'h': | |
23289 case 'm': | |
23290 case 's': | |
23291 case 'w': | |
23292 case 'W': | |
23293 case 'e': | |
23294 case 'E': | |
23295 return parseTokenOneOrTwoDigits; | |
23296 default : | |
23297 a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i")); | |
23298 return a; | |
23299 } | |
23300 } | |
23301 | |
23302 function timezoneMinutesFromString(string) { | |
23303 string = string || ""; | |
23304 var possibleTzMatches = (string.match(parseTokenTimezone) || []), | |
23305 tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], | |
23306 parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], | |
23307 minutes = +(parts[1] * 60) + toInt(parts[2]); | |
23308 | |
23309 return parts[0] === '+' ? -minutes : minutes; | |
23310 } | |
23311 | |
23312 // function to convert string input to date | |
23313 function addTimeToArrayFromToken(token, input, config) { | |
23314 var a, datePartArray = config._a; | |
23315 | |
23316 switch (token) { | |
23317 // MONTH | |
23318 case 'M' : // fall through to MM | |
23319 case 'MM' : | |
23320 if (input != null) { | |
23321 datePartArray[MONTH] = toInt(input) - 1; | |
23322 } | |
23323 break; | |
23324 case 'MMM' : // fall through to MMMM | |
23325 case 'MMMM' : | |
23326 a = getLangDefinition(config._l).monthsParse(input); | |
23327 // if we didn't find a month name, mark the date as invalid. | |
23328 if (a != null) { | |
23329 datePartArray[MONTH] = a; | |
23330 } else { | |
23331 config._pf.invalidMonth = input; | |
23332 } | |
23333 break; | |
23334 // DAY OF MONTH | |
23335 case 'D' : // fall through to DD | |
23336 case 'DD' : | |
23337 if (input != null) { | |
23338 datePartArray[DATE] = toInt(input); | |
23339 } | |
23340 break; | |
23341 // DAY OF YEAR | |
23342 case 'DDD' : // fall through to DDDD | |
23343 case 'DDDD' : | |
23344 if (input != null) { | |
23345 config._dayOfYear = toInt(input); | |
23346 } | |
23347 | |
23348 break; | |
23349 // YEAR | |
23350 case 'YY' : | |
23351 datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000); | |
23352 break; | |
23353 case 'YYYY' : | |
23354 case 'YYYYY' : | |
23355 case 'YYYYYY' : | |
23356 datePartArray[YEAR] = toInt(input); | |
23357 break; | |
23358 // AM / PM | |
23359 case 'a' : // fall through to A | |
23360 case 'A' : | |
23361 config._isPm = getLangDefinition(config._l).isPM(input); | |
23362 break; | |
23363 // 24 HOUR | |
23364 case 'H' : // fall through to hh | |
23365 case 'HH' : // fall through to hh | |
23366 case 'h' : // fall through to hh | |
23367 case 'hh' : | |
23368 datePartArray[HOUR] = toInt(input); | |
23369 break; | |
23370 // MINUTE | |
23371 case 'm' : // fall through to mm | |
23372 case 'mm' : | |
23373 datePartArray[MINUTE] = toInt(input); | |
23374 break; | |
23375 // SECOND | |
23376 case 's' : // fall through to ss | |
23377 case 'ss' : | |
23378 datePartArray[SECOND] = toInt(input); | |
23379 break; | |
23380 // MILLISECOND | |
23381 case 'S' : | |
23382 case 'SS' : | |
23383 case 'SSS' : | |
23384 case 'SSSS' : | |
23385 datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); | |
23386 break; | |
23387 // UNIX TIMESTAMP WITH MS | |
23388 case 'X': | |
23389 config._d = new Date(parseFloat(input) * 1000); | |
23390 break; | |
23391 // TIMEZONE | |
23392 case 'Z' : // fall through to ZZ | |
23393 case 'ZZ' : | |
23394 config._useUTC = true; | |
23395 config._tzm = timezoneMinutesFromString(input); | |
23396 break; | |
23397 case 'w': | |
23398 case 'ww': | |
23399 case 'W': | |
23400 case 'WW': | |
23401 case 'd': | |
23402 case 'dd': | |
23403 case 'ddd': | |
23404 case 'dddd': | |
23405 case 'e': | |
23406 case 'E': | |
23407 token = token.substr(0, 1); | |
23408 /* falls through */ | |
23409 case 'gg': | |
23410 case 'gggg': | |
23411 case 'GG': | |
23412 case 'GGGG': | |
23413 case 'GGGGG': | |
23414 token = token.substr(0, 2); | |
23415 if (input) { | |
23416 config._w = config._w || {}; | |
23417 config._w[token] = input; | |
23418 } | |
23419 break; | |
23420 } | |
23421 } | |
23422 | |
23423 // convert an array to a date. | |
23424 // the array should mirror the parameters below | |
23425 // note: all values past the year are optional and will default to the lowest possible value. | |
23426 // [year, month, day , hour, minute, second, millisecond] | |
23427 function dateFromConfig(config) { | |
23428 var i, date, input = [], currentDate, | |
23429 yearToUse, fixYear, w, temp, lang, weekday, week; | |
23430 | |
23431 if (config._d) { | |
23432 return; | |
23433 } | |
23434 | |
23435 currentDate = currentDateArray(config); | |
23436 | |
23437 //compute day of the year from weeks and weekdays | |
23438 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { | |
23439 fixYear = function (val) { | |
23440 var int_val = parseInt(val, 10); | |
23441 return val ? | |
23442 (val.length < 3 ? (int_val > 68 ? 1900 + int_val : 2000 + int_val) : int_val) : | |
23443 (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); | |
23444 }; | |
23445 | |
23446 w = config._w; | |
23447 if (w.GG != null || w.W != null || w.E != null) { | |
23448 temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); | |
23449 } | |
23450 else { | |
23451 lang = getLangDefinition(config._l); | |
23452 weekday = w.d != null ? parseWeekday(w.d, lang) : | |
23453 (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); | |
23454 | |
23455 week = parseInt(w.w, 10) || 1; | |
23456 | |
23457 //if we're parsing 'd', then the low day numbers may be next week | |
23458 if (w.d != null && weekday < lang._week.dow) { | |
23459 week++; | |
23460 } | |
23461 | |
23462 temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); | |
23463 } | |
23464 | |
23465 config._a[YEAR] = temp.year; | |
23466 config._dayOfYear = temp.dayOfYear; | |
23467 } | |
23468 | |
23469 //if the day of the year is set, figure out what it is | |
23470 if (config._dayOfYear) { | |
23471 yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; | |
23472 | |
23473 if (config._dayOfYear > daysInYear(yearToUse)) { | |
23474 config._pf._overflowDayOfYear = true; | |
23475 } | |
23476 | |
23477 date = makeUTCDate(yearToUse, 0, config._dayOfYear); | |
23478 config._a[MONTH] = date.getUTCMonth(); | |
23479 config._a[DATE] = date.getUTCDate(); | |
23480 } | |
23481 | |
23482 // Default to current date. | |
23483 // * if no year, month, day of month are given, default to today | |
23484 // * if day of month is given, default month and year | |
23485 // * if month is given, default only year | |
23486 // * if year is given, don't default anything | |
23487 for (i = 0; i < 3 && config._a[i] == null; ++i) { | |
23488 config._a[i] = input[i] = currentDate[i]; | |
23489 } | |
23490 | |
23491 // Zero out whatever was not defaulted, including time | |
23492 for (; i < 7; i++) { | |
23493 config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; | |
23494 } | |
23495 | |
23496 // add the offsets to the time to be parsed so that we can have a clean array for checking isValid | |
23497 input[HOUR] += toInt((config._tzm || 0) / 60); | |
23498 input[MINUTE] += toInt((config._tzm || 0) % 60); | |
23499 | |
23500 config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); | |
23501 } | |
23502 | |
23503 function dateFromObject(config) { | |
23504 var normalizedInput; | |
23505 | |
23506 if (config._d) { | |
23507 return; | |
23508 } | |
23509 | |
23510 normalizedInput = normalizeObjectUnits(config._i); | |
23511 config._a = [ | |
23512 normalizedInput.year, | |
23513 normalizedInput.month, | |
23514 normalizedInput.day, | |
23515 normalizedInput.hour, | |
23516 normalizedInput.minute, | |
23517 normalizedInput.second, | |
23518 normalizedInput.millisecond | |
23519 ]; | |
23520 | |
23521 dateFromConfig(config); | |
23522 } | |
23523 | |
23524 function currentDateArray(config) { | |
23525 var now = new Date(); | |
23526 if (config._useUTC) { | |
23527 return [ | |
23528 now.getUTCFullYear(), | |
23529 now.getUTCMonth(), | |
23530 now.getUTCDate() | |
23531 ]; | |
23532 } else { | |
23533 return [now.getFullYear(), now.getMonth(), now.getDate()]; | |
23534 } | |
23535 } | |
23536 | |
23537 // date from string and format string | |
23538 function makeDateFromStringAndFormat(config) { | |
23539 | |
23540 config._a = []; | |
23541 config._pf.empty = true; | |
23542 | |
23543 // This array is used to make a Date, either with `new Date` or `Date.UTC` | |
23544 var lang = getLangDefinition(config._l), | |
23545 string = '' + config._i, | |
23546 i, parsedInput, tokens, token, skipped, | |
23547 stringLength = string.length, | |
23548 totalParsedInputLength = 0; | |
23549 | |
23550 tokens = expandFormat(config._f, lang).match(formattingTokens) || []; | |
23551 | |
23552 for (i = 0; i < tokens.length; i++) { | |
23553 token = tokens[i]; | |
23554 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; | |
23555 if (parsedInput) { | |
23556 skipped = string.substr(0, string.indexOf(parsedInput)); | |
23557 if (skipped.length > 0) { | |
23558 config._pf.unusedInput.push(skipped); | |
23559 } | |
23560 string = string.slice(string.indexOf(parsedInput) + parsedInput.length); | |
23561 totalParsedInputLength += parsedInput.length; | |
23562 } | |
23563 // don't parse if it's not a known token | |
23564 if (formatTokenFunctions[token]) { | |
23565 if (parsedInput) { | |
23566 config._pf.empty = false; | |
23567 } | |
23568 else { | |
23569 config._pf.unusedTokens.push(token); | |
23570 } | |
23571 addTimeToArrayFromToken(token, parsedInput, config); | |
23572 } | |
23573 else if (config._strict && !parsedInput) { | |
23574 config._pf.unusedTokens.push(token); | |
23575 } | |
23576 } | |
23577 | |
23578 // add remaining unparsed input length to the string | |
23579 config._pf.charsLeftOver = stringLength - totalParsedInputLength; | |
23580 if (string.length > 0) { | |
23581 config._pf.unusedInput.push(string); | |
23582 } | |
23583 | |
23584 // handle am pm | |
23585 if (config._isPm && config._a[HOUR] < 12) { | |
23586 config._a[HOUR] += 12; | |
23587 } | |
23588 // if is 12 am, change hours to 0 | |
23589 if (config._isPm === false && config._a[HOUR] === 12) { | |
23590 config._a[HOUR] = 0; | |
23591 } | |
23592 | |
23593 dateFromConfig(config); | |
23594 checkOverflow(config); | |
23595 } | |
23596 | |
23597 function unescapeFormat(s) { | |
23598 return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { | |
23599 return p1 || p2 || p3 || p4; | |
23600 }); | |
23601 } | |
23602 | |
23603 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript | |
23604 function regexpEscape(s) { | |
23605 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
23606 } | |
23607 | |
23608 // date from string and array of format strings | |
23609 function makeDateFromStringAndArray(config) { | |
23610 var tempConfig, | |
23611 bestMoment, | |
23612 | |
23613 scoreToBeat, | |
23614 i, | |
23615 currentScore; | |
23616 | |
23617 if (config._f.length === 0) { | |
23618 config._pf.invalidFormat = true; | |
23619 config._d = new Date(NaN); | |
23620 return; | |
23621 } | |
23622 | |
23623 for (i = 0; i < config._f.length; i++) { | |
23624 currentScore = 0; | |
23625 tempConfig = extend({}, config); | |
23626 tempConfig._pf = defaultParsingFlags(); | |
23627 tempConfig._f = config._f[i]; | |
23628 makeDateFromStringAndFormat(tempConfig); | |
23629 | |
23630 if (!isValid(tempConfig)) { | |
23631 continue; | |
23632 } | |
23633 | |
23634 // if there is any input that was not parsed add a penalty for that format | |
23635 currentScore += tempConfig._pf.charsLeftOver; | |
23636 | |
23637 //or tokens | |
23638 currentScore += tempConfig._pf.unusedTokens.length * 10; | |
23639 | |
23640 tempConfig._pf.score = currentScore; | |
23641 | |
23642 if (scoreToBeat == null || currentScore < scoreToBeat) { | |
23643 scoreToBeat = currentScore; | |
23644 bestMoment = tempConfig; | |
23645 } | |
23646 } | |
23647 | |
23648 extend(config, bestMoment || tempConfig); | |
23649 } | |
23650 | |
23651 // date from iso format | |
23652 function makeDateFromString(config) { | |
23653 var i, l, | |
23654 string = config._i, | |
23655 match = isoRegex.exec(string); | |
23656 | |
23657 if (match) { | |
23658 config._pf.iso = true; | |
23659 for (i = 0, l = isoDates.length; i < l; i++) { | |
23660 if (isoDates[i][1].exec(string)) { | |
23661 // match[5] should be "T" or undefined | |
23662 config._f = isoDates[i][0] + (match[6] || " "); | |
23663 break; | |
23664 } | |
23665 } | |
23666 for (i = 0, l = isoTimes.length; i < l; i++) { | |
23667 if (isoTimes[i][1].exec(string)) { | |
23668 config._f += isoTimes[i][0]; | |
23669 break; | |
23670 } | |
23671 } | |
23672 if (string.match(parseTokenTimezone)) { | |
23673 config._f += "Z"; | |
23674 } | |
23675 makeDateFromStringAndFormat(config); | |
23676 } | |
23677 else { | |
23678 config._d = new Date(string); | |
23679 } | |
23680 } | |
23681 | |
23682 function makeDateFromInput(config) { | |
23683 var input = config._i, | |
23684 matched = aspNetJsonRegex.exec(input); | |
23685 | |
23686 if (input === undefined) { | |
23687 config._d = new Date(); | |
23688 } else if (matched) { | |
23689 config._d = new Date(+matched[1]); | |
23690 } else if (typeof input === 'string') { | |
23691 makeDateFromString(config); | |
23692 } else if (isArray(input)) { | |
23693 config._a = input.slice(0); | |
23694 dateFromConfig(config); | |
23695 } else if (isDate(input)) { | |
23696 config._d = new Date(+input); | |
23697 } else if (typeof(input) === 'object') { | |
23698 dateFromObject(config); | |
23699 } else { | |
23700 config._d = new Date(input); | |
23701 } | |
23702 } | |
23703 | |
23704 function makeDate(y, m, d, h, M, s, ms) { | |
23705 //can't just apply() to create a date: | |
23706 //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply | |
23707 var date = new Date(y, m, d, h, M, s, ms); | |
23708 | |
23709 //the date constructor doesn't accept years < 1970 | |
23710 if (y < 1970) { | |
23711 date.setFullYear(y); | |
23712 } | |
23713 return date; | |
23714 } | |
23715 | |
23716 function makeUTCDate(y) { | |
23717 var date = new Date(Date.UTC.apply(null, arguments)); | |
23718 if (y < 1970) { | |
23719 date.setUTCFullYear(y); | |
23720 } | |
23721 return date; | |
23722 } | |
23723 | |
23724 function parseWeekday(input, language) { | |
23725 if (typeof input === 'string') { | |
23726 if (!isNaN(input)) { | |
23727 input = parseInt(input, 10); | |
23728 } | |
23729 else { | |
23730 input = language.weekdaysParse(input); | |
23731 if (typeof input !== 'number') { | |
23732 return null; | |
23733 } | |
23734 } | |
23735 } | |
23736 return input; | |
23737 } | |
23738 | |
23739 /************************************ | |
23740 Relative Time | |
23741 ************************************/ | |
23742 | |
23743 | |
23744 // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize | |
23745 function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { | |
23746 return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); | |
23747 } | |
23748 | |
23749 function relativeTime(milliseconds, withoutSuffix, lang) { | |
23750 var seconds = round(Math.abs(milliseconds) / 1000), | |
23751 minutes = round(seconds / 60), | |
23752 hours = round(minutes / 60), | |
23753 days = round(hours / 24), | |
23754 years = round(days / 365), | |
23755 args = seconds < 45 && ['s', seconds] || | |
23756 minutes === 1 && ['m'] || | |
23757 minutes < 45 && ['mm', minutes] || | |
23758 hours === 1 && ['h'] || | |
23759 hours < 22 && ['hh', hours] || | |
23760 days === 1 && ['d'] || | |
23761 days <= 25 && ['dd', days] || | |
23762 days <= 45 && ['M'] || | |
23763 days < 345 && ['MM', round(days / 30)] || | |
23764 years === 1 && ['y'] || ['yy', years]; | |
23765 args[2] = withoutSuffix; | |
23766 args[3] = milliseconds > 0; | |
23767 args[4] = lang; | |
23768 return substituteTimeAgo.apply({}, args); | |
23769 } | |
23770 | |
23771 | |
23772 /************************************ | |
23773 Week of Year | |
23774 ************************************/ | |
23775 | |
23776 | |
23777 // firstDayOfWeek 0 = sun, 6 = sat | |
23778 // the day of the week that starts the week | |
23779 // (usually sunday or monday) | |
23780 // firstDayOfWeekOfYear 0 = sun, 6 = sat | |
23781 // the first week is the week that contains the first | |
23782 // of this day of the week | |
23783 // (eg. ISO weeks use thursday (4)) | |
23784 function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { | |
23785 var end = firstDayOfWeekOfYear - firstDayOfWeek, | |
23786 daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), | |
23787 adjustedMoment; | |
23788 | |
23789 | |
23790 if (daysToDayOfWeek > end) { | |
23791 daysToDayOfWeek -= 7; | |
23792 } | |
23793 | |
23794 if (daysToDayOfWeek < end - 7) { | |
23795 daysToDayOfWeek += 7; | |
23796 } | |
23797 | |
23798 adjustedMoment = moment(mom).add('d', daysToDayOfWeek); | |
23799 return { | |
23800 week: Math.ceil(adjustedMoment.dayOfYear() / 7), | |
23801 year: adjustedMoment.year() | |
23802 }; | |
23803 } | |
23804 | |
23805 //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday | |
23806 function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { | |
23807 var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; | |
23808 | |
23809 weekday = weekday != null ? weekday : firstDayOfWeek; | |
23810 daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); | |
23811 dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; | |
23812 | |
23813 return { | |
23814 year: dayOfYear > 0 ? year : year - 1, | |
23815 dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear | |
23816 }; | |
23817 } | |
23818 | |
23819 /************************************ | |
23820 Top Level Functions | |
23821 ************************************/ | |
23822 | |
23823 function makeMoment(config) { | |
23824 var input = config._i, | |
23825 format = config._f; | |
23826 | |
23827 if (input === null) { | |
23828 return moment.invalid({nullInput: true}); | |
23829 } | |
23830 | |
23831 if (typeof input === 'string') { | |
23832 config._i = input = getLangDefinition().preparse(input); | |
23833 } | |
23834 | |
23835 if (moment.isMoment(input)) { | |
23836 config = cloneMoment(input); | |
23837 | |
23838 config._d = new Date(+input._d); | |
23839 } else if (format) { | |
23840 if (isArray(format)) { | |
23841 makeDateFromStringAndArray(config); | |
23842 } else { | |
23843 makeDateFromStringAndFormat(config); | |
23844 } | |
23845 } else { | |
23846 makeDateFromInput(config); | |
23847 } | |
23848 | |
23849 return new Moment(config); | |
23850 } | |
23851 | |
23852 moment = function (input, format, lang, strict) { | |
23853 var c; | |
23854 | |
23855 if (typeof(lang) === "boolean") { | |
23856 strict = lang; | |
23857 lang = undefined; | |
23858 } | |
23859 // object construction must be done this way. | |
23860 // https://github.com/moment/moment/issues/1423 | |
23861 c = {}; | |
23862 c._isAMomentObject = true; | |
23863 c._i = input; | |
23864 c._f = format; | |
23865 c._l = lang; | |
23866 c._strict = strict; | |
23867 c._isUTC = false; | |
23868 c._pf = defaultParsingFlags(); | |
23869 | |
23870 return makeMoment(c); | |
23871 }; | |
23872 | |
23873 // creating with utc | |
23874 moment.utc = function (input, format, lang, strict) { | |
23875 var c; | |
23876 | |
23877 if (typeof(lang) === "boolean") { | |
23878 strict = lang; | |
23879 lang = undefined; | |
23880 } | |
23881 // object construction must be done this way. | |
23882 // https://github.com/moment/moment/issues/1423 | |
23883 c = {}; | |
23884 c._isAMomentObject = true; | |
23885 c._useUTC = true; | |
23886 c._isUTC = true; | |
23887 c._l = lang; | |
23888 c._i = input; | |
23889 c._f = format; | |
23890 c._strict = strict; | |
23891 c._pf = defaultParsingFlags(); | |
23892 | |
23893 return makeMoment(c).utc(); | |
23894 }; | |
23895 | |
23896 // creating with unix timestamp (in seconds) | |
23897 moment.unix = function (input) { | |
23898 return moment(input * 1000); | |
23899 }; | |
23900 | |
23901 // duration | |
23902 moment.duration = function (input, key) { | |
23903 var duration = input, | |
23904 // matching against regexp is expensive, do it on demand | |
23905 match = null, | |
23906 sign, | |
23907 ret, | |
23908 parseIso; | |
23909 | |
23910 if (moment.isDuration(input)) { | |
23911 duration = { | |
23912 ms: input._milliseconds, | |
23913 d: input._days, | |
23914 M: input._months | |
23915 }; | |
23916 } else if (typeof input === 'number') { | |
23917 duration = {}; | |
23918 if (key) { | |
23919 duration[key] = input; | |
23920 } else { | |
23921 duration.milliseconds = input; | |
23922 } | |
23923 } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { | |
23924 sign = (match[1] === "-") ? -1 : 1; | |
23925 duration = { | |
23926 y: 0, | |
23927 d: toInt(match[DATE]) * sign, | |
23928 h: toInt(match[HOUR]) * sign, | |
23929 m: toInt(match[MINUTE]) * sign, | |
23930 s: toInt(match[SECOND]) * sign, | |
23931 ms: toInt(match[MILLISECOND]) * sign | |
23932 }; | |
23933 } else if (!!(match = isoDurationRegex.exec(input))) { | |
23934 sign = (match[1] === "-") ? -1 : 1; | |
23935 parseIso = function (inp) { | |
23936 // We'd normally use ~~inp for this, but unfortunately it also | |
23937 // converts floats to ints. | |
23938 // inp may be undefined, so careful calling replace on it. | |
23939 var res = inp && parseFloat(inp.replace(',', '.')); | |
23940 // apply sign while we're at it | |
23941 return (isNaN(res) ? 0 : res) * sign; | |
23942 }; | |
23943 duration = { | |
23944 y: parseIso(match[2]), | |
23945 M: parseIso(match[3]), | |
23946 d: parseIso(match[4]), | |
23947 h: parseIso(match[5]), | |
23948 m: parseIso(match[6]), | |
23949 s: parseIso(match[7]), | |
23950 w: parseIso(match[8]) | |
23951 }; | |
23952 } | |
23953 | |
23954 ret = new Duration(duration); | |
23955 | |
23956 if (moment.isDuration(input) && input.hasOwnProperty('_lang')) { | |
23957 ret._lang = input._lang; | |
23958 } | |
23959 | |
23960 return ret; | |
23961 }; | |
23962 | |
23963 // version number | |
23964 moment.version = VERSION; | |
23965 | |
23966 // default format | |
23967 moment.defaultFormat = isoFormat; | |
23968 | |
23969 // This function will be called whenever a moment is mutated. | |
23970 // It is intended to keep the offset in sync with the timezone. | |
23971 moment.updateOffset = function () {}; | |
23972 | |
23973 // This function will load languages and then set the global language. If | |
23974 // no arguments are passed in, it will simply return the current global | |
23975 // language key. | |
23976 moment.lang = function (key, values) { | |
23977 var r; | |
23978 if (!key) { | |
23979 return moment.fn._lang._abbr; | |
23980 } | |
23981 if (values) { | |
23982 loadLang(normalizeLanguage(key), values); | |
23983 } else if (values === null) { | |
23984 unloadLang(key); | |
23985 key = 'en'; | |
23986 } else if (!languages[key]) { | |
23987 getLangDefinition(key); | |
23988 } | |
23989 r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); | |
23990 return r._abbr; | |
23991 }; | |
23992 | |
23993 // returns language data | |
23994 moment.langData = function (key) { | |
23995 if (key && key._lang && key._lang._abbr) { | |
23996 key = key._lang._abbr; | |
23997 } | |
23998 return getLangDefinition(key); | |
23999 }; | |
24000 | |
24001 // compare moment object | |
24002 moment.isMoment = function (obj) { | |
24003 return obj instanceof Moment || | |
24004 (obj != null && obj.hasOwnProperty('_isAMomentObject')); | |
24005 }; | |
24006 | |
24007 // for typechecking Duration objects | |
24008 moment.isDuration = function (obj) { | |
24009 return obj instanceof Duration; | |
24010 }; | |
24011 | |
24012 for (i = lists.length - 1; i >= 0; --i) { | |
24013 makeList(lists[i]); | |
24014 } | |
24015 | |
24016 moment.normalizeUnits = function (units) { | |
24017 return normalizeUnits(units); | |
24018 }; | |
24019 | |
24020 moment.invalid = function (flags) { | |
24021 var m = moment.utc(NaN); | |
24022 if (flags != null) { | |
24023 extend(m._pf, flags); | |
24024 } | |
24025 else { | |
24026 m._pf.userInvalidated = true; | |
24027 } | |
24028 | |
24029 return m; | |
24030 }; | |
24031 | |
24032 moment.parseZone = function (input) { | |
24033 return moment(input).parseZone(); | |
24034 }; | |
24035 | |
24036 /************************************ | |
24037 Moment Prototype | |
24038 ************************************/ | |
24039 | |
24040 | |
24041 extend(moment.fn = Moment.prototype, { | |
24042 | |
24043 clone : function () { | |
24044 return moment(this); | |
24045 }, | |
24046 | |
24047 valueOf : function () { | |
24048 return +this._d + ((this._offset || 0) * 60000); | |
24049 }, | |
24050 | |
24051 unix : function () { | |
24052 return Math.floor(+this / 1000); | |
24053 }, | |
24054 | |
24055 toString : function () { | |
24056 return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); | |
24057 }, | |
24058 | |
24059 toDate : function () { | |
24060 return this._offset ? new Date(+this) : this._d; | |
24061 }, | |
24062 | |
24063 toISOString : function () { | |
24064 var m = moment(this).utc(); | |
24065 if (0 < m.year() && m.year() <= 9999) { | |
24066 return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); | |
24067 } else { | |
24068 return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); | |
24069 } | |
24070 }, | |
24071 | |
24072 toArray : function () { | |
24073 var m = this; | |
24074 return [ | |
24075 m.year(), | |
24076 m.month(), | |
24077 m.date(), | |
24078 m.hours(), | |
24079 m.minutes(), | |
24080 m.seconds(), | |
24081 m.milliseconds() | |
24082 ]; | |
24083 }, | |
24084 | |
24085 isValid : function () { | |
24086 return isValid(this); | |
24087 }, | |
24088 | |
24089 isDSTShifted : function () { | |
24090 | |
24091 if (this._a) { | |
24092 return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; | |
24093 } | |
24094 | |
24095 return false; | |
24096 }, | |
24097 | |
24098 parsingFlags : function () { | |
24099 return extend({}, this._pf); | |
24100 }, | |
24101 | |
24102 invalidAt: function () { | |
24103 return this._pf.overflow; | |
24104 }, | |
24105 | |
24106 utc : function () { | |
24107 return this.zone(0); | |
24108 }, | |
24109 | |
24110 local : function () { | |
24111 this.zone(0); | |
24112 this._isUTC = false; | |
24113 return this; | |
24114 }, | |
24115 | |
24116 format : function (inputString) { | |
24117 var output = formatMoment(this, inputString || moment.defaultFormat); | |
24118 return this.lang().postformat(output); | |
24119 }, | |
24120 | |
24121 add : function (input, val) { | |
24122 var dur; | |
24123 // switch args to support add('s', 1) and add(1, 's') | |
24124 if (typeof input === 'string') { | |
24125 dur = moment.duration(+val, input); | |
24126 } else { | |
24127 dur = moment.duration(input, val); | |
24128 } | |
24129 addOrSubtractDurationFromMoment(this, dur, 1); | |
24130 return this; | |
24131 }, | |
24132 | |
24133 subtract : function (input, val) { | |
24134 var dur; | |
24135 // switch args to support subtract('s', 1) and subtract(1, 's') | |
24136 if (typeof input === 'string') { | |
24137 dur = moment.duration(+val, input); | |
24138 } else { | |
24139 dur = moment.duration(input, val); | |
24140 } | |
24141 addOrSubtractDurationFromMoment(this, dur, -1); | |
24142 return this; | |
24143 }, | |
24144 | |
24145 diff : function (input, units, asFloat) { | |
24146 var that = makeAs(input, this), | |
24147 zoneDiff = (this.zone() - that.zone()) * 6e4, | |
24148 diff, output; | |
24149 | |
24150 units = normalizeUnits(units); | |
24151 | |
24152 if (units === 'year' || units === 'month') { | |
24153 // average number of days in the months in the given dates | |
24154 diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 | |
24155 // difference in months | |
24156 output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); | |
24157 // adjust by taking difference in days, average number of days | |
24158 // and dst in the given months. | |
24159 output += ((this - moment(this).startOf('month')) - | |
24160 (that - moment(that).startOf('month'))) / diff; | |
24161 // same as above but with zones, to negate all dst | |
24162 output -= ((this.zone() - moment(this).startOf('month').zone()) - | |
24163 (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; | |
24164 if (units === 'year') { | |
24165 output = output / 12; | |
24166 } | |
24167 } else { | |
24168 diff = (this - that); | |
24169 output = units === 'second' ? diff / 1e3 : // 1000 | |
24170 units === 'minute' ? diff / 6e4 : // 1000 * 60 | |
24171 units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 | |
24172 units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst | |
24173 units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst | |
24174 diff; | |
24175 } | |
24176 return asFloat ? output : absRound(output); | |
24177 }, | |
24178 | |
24179 from : function (time, withoutSuffix) { | |
24180 return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); | |
24181 }, | |
24182 | |
24183 fromNow : function (withoutSuffix) { | |
24184 return this.from(moment(), withoutSuffix); | |
24185 }, | |
24186 | |
24187 calendar : function () { | |
24188 // We want to compare the start of today, vs this. | |
24189 // Getting start-of-today depends on whether we're zone'd or not. | |
24190 var sod = makeAs(moment(), this).startOf('day'), | |
24191 diff = this.diff(sod, 'days', true), | |
24192 format = diff < -6 ? 'sameElse' : | |
24193 diff < -1 ? 'lastWeek' : | |
24194 diff < 0 ? 'lastDay' : | |
24195 diff < 1 ? 'sameDay' : | |
24196 diff < 2 ? 'nextDay' : | |
24197 diff < 7 ? 'nextWeek' : 'sameElse'; | |
24198 return this.format(this.lang().calendar(format, this)); | |
24199 }, | |
24200 | |
24201 isLeapYear : function () { | |
24202 return isLeapYear(this.year()); | |
24203 }, | |
24204 | |
24205 isDST : function () { | |
24206 return (this.zone() < this.clone().month(0).zone() || | |
24207 this.zone() < this.clone().month(5).zone()); | |
24208 }, | |
24209 | |
24210 day : function (input) { | |
24211 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); | |
24212 if (input != null) { | |
24213 input = parseWeekday(input, this.lang()); | |
24214 return this.add({ d : input - day }); | |
24215 } else { | |
24216 return day; | |
24217 } | |
24218 }, | |
24219 | |
24220 month : function (input) { | |
24221 var utc = this._isUTC ? 'UTC' : '', | |
24222 dayOfMonth; | |
24223 | |
24224 if (input != null) { | |
24225 if (typeof input === 'string') { | |
24226 input = this.lang().monthsParse(input); | |
24227 if (typeof input !== 'number') { | |
24228 return this; | |
24229 } | |
24230 } | |
24231 | |
24232 dayOfMonth = this.date(); | |
24233 this.date(1); | |
24234 this._d['set' + utc + 'Month'](input); | |
24235 this.date(Math.min(dayOfMonth, this.daysInMonth())); | |
24236 | |
24237 moment.updateOffset(this); | |
24238 return this; | |
24239 } else { | |
24240 return this._d['get' + utc + 'Month'](); | |
24241 } | |
24242 }, | |
24243 | |
24244 startOf: function (units) { | |
24245 units = normalizeUnits(units); | |
24246 // the following switch intentionally omits break keywords | |
24247 // to utilize falling through the cases. | |
24248 switch (units) { | |
24249 case 'year': | |
24250 this.month(0); | |
24251 /* falls through */ | |
24252 case 'month': | |
24253 this.date(1); | |
24254 /* falls through */ | |
24255 case 'week': | |
24256 case 'isoWeek': | |
24257 case 'day': | |
24258 this.hours(0); | |
24259 /* falls through */ | |
24260 case 'hour': | |
24261 this.minutes(0); | |
24262 /* falls through */ | |
24263 case 'minute': | |
24264 this.seconds(0); | |
24265 /* falls through */ | |
24266 case 'second': | |
24267 this.milliseconds(0); | |
24268 /* falls through */ | |
24269 } | |
24270 | |
24271 // weeks are a special case | |
24272 if (units === 'week') { | |
24273 this.weekday(0); | |
24274 } else if (units === 'isoWeek') { | |
24275 this.isoWeekday(1); | |
24276 } | |
24277 | |
24278 return this; | |
24279 }, | |
24280 | |
24281 endOf: function (units) { | |
24282 units = normalizeUnits(units); | |
24283 return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); | |
24284 }, | |
24285 | |
24286 isAfter: function (input, units) { | |
24287 units = typeof units !== 'undefined' ? units : 'millisecond'; | |
24288 return +this.clone().startOf(units) > +moment(input).startOf(units); | |
24289 }, | |
24290 | |
24291 isBefore: function (input, units) { | |
24292 units = typeof units !== 'undefined' ? units : 'millisecond'; | |
24293 return +this.clone().startOf(units) < +moment(input).startOf(units); | |
24294 }, | |
24295 | |
24296 isSame: function (input, units) { | |
24297 units = units || 'ms'; | |
24298 return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); | |
24299 }, | |
24300 | |
24301 min: function (other) { | |
24302 other = moment.apply(null, arguments); | |
24303 return other < this ? this : other; | |
24304 }, | |
24305 | |
24306 max: function (other) { | |
24307 other = moment.apply(null, arguments); | |
24308 return other > this ? this : other; | |
24309 }, | |
24310 | |
24311 zone : function (input) { | |
24312 var offset = this._offset || 0; | |
24313 if (input != null) { | |
24314 if (typeof input === "string") { | |
24315 input = timezoneMinutesFromString(input); | |
24316 } | |
24317 if (Math.abs(input) < 16) { | |
24318 input = input * 60; | |
24319 } | |
24320 this._offset = input; | |
24321 this._isUTC = true; | |
24322 if (offset !== input) { | |
24323 addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true); | |
24324 } | |
24325 } else { | |
24326 return this._isUTC ? offset : this._d.getTimezoneOffset(); | |
24327 } | |
24328 return this; | |
24329 }, | |
24330 | |
24331 zoneAbbr : function () { | |
24332 return this._isUTC ? "UTC" : ""; | |
24333 }, | |
24334 | |
24335 zoneName : function () { | |
24336 return this._isUTC ? "Coordinated Universal Time" : ""; | |
24337 }, | |
24338 | |
24339 parseZone : function () { | |
24340 if (this._tzm) { | |
24341 this.zone(this._tzm); | |
24342 } else if (typeof this._i === 'string') { | |
24343 this.zone(this._i); | |
24344 } | |
24345 return this; | |
24346 }, | |
24347 | |
24348 hasAlignedHourOffset : function (input) { | |
24349 if (!input) { | |
24350 input = 0; | |
24351 } | |
24352 else { | |
24353 input = moment(input).zone(); | |
24354 } | |
24355 | |
24356 return (this.zone() - input) % 60 === 0; | |
24357 }, | |
24358 | |
24359 daysInMonth : function () { | |
24360 return daysInMonth(this.year(), this.month()); | |
24361 }, | |
24362 | |
24363 dayOfYear : function (input) { | |
24364 var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; | |
24365 return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); | |
24366 }, | |
24367 | |
24368 quarter : function () { | |
24369 return Math.ceil((this.month() + 1.0) / 3.0); | |
24370 }, | |
24371 | |
24372 weekYear : function (input) { | |
24373 var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; | |
24374 return input == null ? year : this.add("y", (input - year)); | |
24375 }, | |
24376 | |
24377 isoWeekYear : function (input) { | |
24378 var year = weekOfYear(this, 1, 4).year; | |
24379 return input == null ? year : this.add("y", (input - year)); | |
24380 }, | |
24381 | |
24382 week : function (input) { | |
24383 var week = this.lang().week(this); | |
24384 return input == null ? week : this.add("d", (input - week) * 7); | |
24385 }, | |
24386 | |
24387 isoWeek : function (input) { | |
24388 var week = weekOfYear(this, 1, 4).week; | |
24389 return input == null ? week : this.add("d", (input - week) * 7); | |
24390 }, | |
24391 | |
24392 weekday : function (input) { | |
24393 var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; | |
24394 return input == null ? weekday : this.add("d", input - weekday); | |
24395 }, | |
24396 | |
24397 isoWeekday : function (input) { | |
24398 // behaves the same as moment#day except | |
24399 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) | |
24400 // as a setter, sunday should belong to the previous week. | |
24401 return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); | |
24402 }, | |
24403 | |
24404 get : function (units) { | |
24405 units = normalizeUnits(units); | |
24406 return this[units](); | |
24407 }, | |
24408 | |
24409 set : function (units, value) { | |
24410 units = normalizeUnits(units); | |
24411 if (typeof this[units] === 'function') { | |
24412 this[units](value); | |
24413 } | |
24414 return this; | |
24415 }, | |
24416 | |
24417 // If passed a language key, it will set the language for this | |
24418 // instance. Otherwise, it will return the language configuration | |
24419 // variables for this instance. | |
24420 lang : function (key) { | |
24421 if (key === undefined) { | |
24422 return this._lang; | |
24423 } else { | |
24424 this._lang = getLangDefinition(key); | |
24425 return this; | |
24426 } | |
24427 } | |
24428 }); | |
24429 | |
24430 // helper for adding shortcuts | |
24431 function makeGetterAndSetter(name, key) { | |
24432 moment.fn[name] = moment.fn[name + 's'] = function (input) { | |
24433 var utc = this._isUTC ? 'UTC' : ''; | |
24434 if (input != null) { | |
24435 this._d['set' + utc + key](input); | |
24436 moment.updateOffset(this); | |
24437 return this; | |
24438 } else { | |
24439 return this._d['get' + utc + key](); | |
24440 } | |
24441 }; | |
24442 } | |
24443 | |
24444 // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) | |
24445 for (i = 0; i < proxyGettersAndSetters.length; i ++) { | |
24446 makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]); | |
24447 } | |
24448 | |
24449 // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') | |
24450 makeGetterAndSetter('year', 'FullYear'); | |
24451 | |
24452 // add plural methods | |
24453 moment.fn.days = moment.fn.day; | |
24454 moment.fn.months = moment.fn.month; | |
24455 moment.fn.weeks = moment.fn.week; | |
24456 moment.fn.isoWeeks = moment.fn.isoWeek; | |
24457 | |
24458 // add aliased format methods | |
24459 moment.fn.toJSON = moment.fn.toISOString; | |
24460 | |
24461 /************************************ | |
24462 Duration Prototype | |
24463 ************************************/ | |
24464 | |
24465 | |
24466 extend(moment.duration.fn = Duration.prototype, { | |
24467 | |
24468 _bubble : function () { | |
24469 var milliseconds = this._milliseconds, | |
24470 days = this._days, | |
24471 months = this._months, | |
24472 data = this._data, | |
24473 seconds, minutes, hours, years; | |
24474 | |
24475 // The following code bubbles up values, see the tests for | |
24476 // examples of what that means. | |
24477 data.milliseconds = milliseconds % 1000; | |
24478 | |
24479 seconds = absRound(milliseconds / 1000); | |
24480 data.seconds = seconds % 60; | |
24481 | |
24482 minutes = absRound(seconds / 60); | |
24483 data.minutes = minutes % 60; | |
24484 | |
24485 hours = absRound(minutes / 60); | |
24486 data.hours = hours % 24; | |
24487 | |
24488 days += absRound(hours / 24); | |
24489 data.days = days % 30; | |
24490 | |
24491 months += absRound(days / 30); | |
24492 data.months = months % 12; | |
24493 | |
24494 years = absRound(months / 12); | |
24495 data.years = years; | |
24496 }, | |
24497 | |
24498 weeks : function () { | |
24499 return absRound(this.days() / 7); | |
24500 }, | |
24501 | |
24502 valueOf : function () { | |
24503 return this._milliseconds + | |
24504 this._days * 864e5 + | |
24505 (this._months % 12) * 2592e6 + | |
24506 toInt(this._months / 12) * 31536e6; | |
24507 }, | |
24508 | |
24509 humanize : function (withSuffix) { | |
24510 var difference = +this, | |
24511 output = relativeTime(difference, !withSuffix, this.lang()); | |
24512 | |
24513 if (withSuffix) { | |
24514 output = this.lang().pastFuture(difference, output); | |
24515 } | |
24516 | |
24517 return this.lang().postformat(output); | |
24518 }, | |
24519 | |
24520 add : function (input, val) { | |
24521 // supports only 2.0-style add(1, 's') or add(moment) | |
24522 var dur = moment.duration(input, val); | |
24523 | |
24524 this._milliseconds += dur._milliseconds; | |
24525 this._days += dur._days; | |
24526 this._months += dur._months; | |
24527 | |
24528 this._bubble(); | |
24529 | |
24530 return this; | |
24531 }, | |
24532 | |
24533 subtract : function (input, val) { | |
24534 var dur = moment.duration(input, val); | |
24535 | |
24536 this._milliseconds -= dur._milliseconds; | |
24537 this._days -= dur._days; | |
24538 this._months -= dur._months; | |
24539 | |
24540 this._bubble(); | |
24541 | |
24542 return this; | |
24543 }, | |
24544 | |
24545 get : function (units) { | |
24546 units = normalizeUnits(units); | |
24547 return this[units.toLowerCase() + 's'](); | |
24548 }, | |
24549 | |
24550 as : function (units) { | |
24551 units = normalizeUnits(units); | |
24552 return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); | |
24553 }, | |
24554 | |
24555 lang : moment.fn.lang, | |
24556 | |
24557 toIsoString : function () { | |
24558 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js | |
24559 var years = Math.abs(this.years()), | |
24560 months = Math.abs(this.months()), | |
24561 days = Math.abs(this.days()), | |
24562 hours = Math.abs(this.hours()), | |
24563 minutes = Math.abs(this.minutes()), | |
24564 seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); | |
24565 | |
24566 if (!this.asSeconds()) { | |
24567 // this is the same as C#'s (Noda) and python (isodate)... | |
24568 // but not other JS (goog.date) | |
24569 return 'P0D'; | |
24570 } | |
24571 | |
24572 return (this.asSeconds() < 0 ? '-' : '') + | |
24573 'P' + | |
24574 (years ? years + 'Y' : '') + | |
24575 (months ? months + 'M' : '') + | |
24576 (days ? days + 'D' : '') + | |
24577 ((hours || minutes || seconds) ? 'T' : '') + | |
24578 (hours ? hours + 'H' : '') + | |
24579 (minutes ? minutes + 'M' : '') + | |
24580 (seconds ? seconds + 'S' : ''); | |
24581 } | |
24582 }); | |
24583 | |
24584 function makeDurationGetter(name) { | |
24585 moment.duration.fn[name] = function () { | |
24586 return this._data[name]; | |
24587 }; | |
24588 } | |
24589 | |
24590 function makeDurationAsGetter(name, factor) { | |
24591 moment.duration.fn['as' + name] = function () { | |
24592 return +this / factor; | |
24593 }; | |
24594 } | |
24595 | |
24596 for (i in unitMillisecondFactors) { | |
24597 if (unitMillisecondFactors.hasOwnProperty(i)) { | |
24598 makeDurationAsGetter(i, unitMillisecondFactors[i]); | |
24599 makeDurationGetter(i.toLowerCase()); | |
24600 } | |
24601 } | |
24602 | |
24603 makeDurationAsGetter('Weeks', 6048e5); | |
24604 moment.duration.fn.asMonths = function () { | |
24605 return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; | |
24606 }; | |
24607 | |
24608 | |
24609 /************************************ | |
24610 Default Lang | |
24611 ************************************/ | |
24612 | |
24613 | |
24614 // Set default language, other languages will inherit from English. | |
24615 moment.lang('en', { | |
24616 ordinal : function (number) { | |
24617 var b = number % 10, | |
24618 output = (toInt(number % 100 / 10) === 1) ? 'th' : | |
24619 (b === 1) ? 'st' : | |
24620 (b === 2) ? 'nd' : | |
24621 (b === 3) ? 'rd' : 'th'; | |
24622 return number + output; | |
24623 } | |
24624 }); | |
24625 | |
24626 /* EMBED_LANGUAGES */ | |
24627 | |
24628 /************************************ | |
24629 Exposing Moment | |
24630 ************************************/ | |
24631 | |
24632 function makeGlobal(deprecate) { | |
24633 var warned = false, local_moment = moment; | |
24634 /*global ender:false */ | |
24635 if (typeof ender !== 'undefined') { | |
24636 return; | |
24637 } | |
24638 // here, `this` means `window` in the browser, or `global` on the server | |
24639 // add `moment` as a global object via a string identifier, | |
24640 // for Closure Compiler "advanced" mode | |
24641 if (deprecate) { | |
24642 global.moment = function () { | |
24643 if (!warned && console && console.warn) { | |
24644 warned = true; | |
24645 console.warn( | |
24646 "Accessing Moment through the global scope is " + | |
24647 "deprecated, and will be removed in an upcoming " + | |
24648 "release."); | |
24649 } | |
24650 return local_moment.apply(null, arguments); | |
24651 }; | |
24652 extend(global.moment, local_moment); | |
24653 } else { | |
24654 global['moment'] = moment; | |
24655 } | |
24656 } | |
24657 | |
24658 // CommonJS module is defined | |
24659 if (hasModule) { | |
24660 module.exports = moment; | |
24661 makeGlobal(true); | |
24662 } else if (typeof define === "function" && define.amd) { | |
24663 define("moment", function (require, exports, module) { | |
24664 if (module.config && module.config() && module.config().noGlobal !== true) { | |
24665 // If user provided noGlobal, he is aware of global | |
24666 makeGlobal(module.config().noGlobal === undefined); | |
24667 } | |
24668 | |
24669 return moment; | |
24670 }); | |
24671 } else { | |
24672 makeGlobal(); | |
24673 } | |
24674 }).call(this); | |
24675 /*! | |
24676 * UCSV 1.1.0 | |
24677 * Provided under MIT License. | |
24678 * | |
24679 * Copyright 2010-2012, Peter Johnson | |
24680 * http://www.uselesscode.org/javascript/csv/ | |
24681 */ | |
24682 var CSV=(function(){var f=/^\d+$/,g=/^\d*\.\d+$|^\d+\.\d*$/,i=/^\s|\s$|,|"|\n/,b=(function(){if(String.prototype.trim){return function(j){return j.trim()}}else{return function(j){return j.replace(/^\s*/,"").replace(/\s*$/,"")}}}());function h(j){return Object.prototype.toString.apply(j)==="[object Number]"}function a(j){return Object.prototype.toString.apply(j)==="[object String]"}function d(j){if(j.charAt(j.length-1)!=="\n"){return j}else{return j.substring(0,j.length-1)}}function e(k){var p,m="",o,n,l;for(n=0;n<k.length;n+=1){o=k[n];for(l=0;l<o.length;l+=1){p=o[l];if(a(p)){p=p.replace(/"/g,'""');if(i.test(p)||f.test(p)||g.test(p)){p='"'+p+'"'}else{if(p===""){p='""'}}}else{if(h(p)){p=p.toString(10)}else{if(p===null){p=""}else{p=p.toString()}}}m+=l<o.length-1?p+",":p}m+="\n"}return m}function c(t,p){t=d(t);var q="",l=false,m=false,o="",r=[],j=[],k,n;n=function(s){if(m!==true){if(s===""){s=null}else{if(p===true){s=b(s)}}if(f.test(s)){s=parseInt(s,10)}else{if(g.test(s)){s=parseFloat(s,10)}}}return s};for(k=0;k<t.length;k+=1){q=t.charAt(k);if(l===false&&(q===","||q==="\n")){o=n(o);r.push(o);if(q==="\n"){j.push(r);r=[]}o="";m=false}else{if(q!=='"'){o+=q}else{if(!l){l=true;m=true}else{if(t.charAt(k+1)==='"'){o+='"';k+=1}else{l=false}}}}}o=n(o);r.push(o);j.push(r);return j}if(typeof exports==="object"){exports.arrayToCsv=e;exports.csvToArray=c}return{arrayToCsv:e,csvToArray:c}}()); | |
24683 /* Javascript plotting library for jQuery, version 0.8.3-alpha. | |
24684 | |
24685 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
24686 Licensed under the MIT license. | |
24687 | |
24688 */ | |
24689 | |
24690 // first an inline dependency, jquery.colorhelpers.js, we inline it here | |
24691 // for convenience | |
24692 | |
24693 /* Plugin for jQuery for working with colors. | |
24694 * | |
24695 * Version 1.1. | |
24696 * | |
24697 * Inspiration from jQuery color animation plugin by John Resig. | |
24698 * | |
24699 * Released under the MIT license by Ole Laursen, October 2009. | |
24700 * | |
24701 * Examples: | |
24702 * | |
24703 * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() | |
24704 * var c = $.color.extract($("#mydiv"), 'background-color'); | |
24705 * console.log(c.r, c.g, c.b, c.a); | |
24706 * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" | |
24707 * | |
24708 * Note that .scale() and .add() return the same modified object | |
24709 * instead of making a new one. | |
24710 * | |
24711 * V. 1.1: Fix error handling so e.g. parsing an empty string does | |
24712 * produce a color rather than just crashing. | |
24713 */ | |
24714 (function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); | |
24715 | |
24716 // the actual Flot code | |
24717 (function($) { | |
24718 | |
24719 // Cache the prototype hasOwnProperty for faster access | |
24720 | |
24721 var hasOwnProperty = Object.prototype.hasOwnProperty; | |
24722 | |
24723 /////////////////////////////////////////////////////////////////////////// | |
24724 // The Canvas object is a wrapper around an HTML5 <canvas> tag. | |
24725 // | |
24726 // @constructor | |
24727 // @param {string} cls List of classes to apply to the canvas. | |
24728 // @param {element} container Element onto which to append the canvas. | |
24729 // | |
24730 // Requiring a container is a little iffy, but unfortunately canvas | |
24731 // operations don't work unless the canvas is attached to the DOM. | |
24732 | |
24733 function Canvas(cls, container) { | |
24734 | |
24735 var element = container.children("." + cls)[0]; | |
24736 | |
24737 if (element == null) { | |
24738 | |
24739 element = document.createElement("canvas"); | |
24740 element.className = cls; | |
24741 | |
24742 $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) | |
24743 .appendTo(container); | |
24744 | |
24745 // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas | |
24746 | |
24747 if (!element.getContext) { | |
24748 if (window.G_vmlCanvasManager) { | |
24749 element = window.G_vmlCanvasManager.initElement(element); | |
24750 } else { | |
24751 throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); | |
24752 } | |
24753 } | |
24754 } | |
24755 | |
24756 this.element = element; | |
24757 | |
24758 var context = this.context = element.getContext("2d"); | |
24759 | |
24760 // Determine the screen's ratio of physical to device-independent | |
24761 // pixels. This is the ratio between the canvas width that the browser | |
24762 // advertises and the number of pixels actually present in that space. | |
24763 | |
24764 // The iPhone 4, for example, has a device-independent width of 320px, | |
24765 // but its screen is actually 640px wide. It therefore has a pixel | |
24766 // ratio of 2, while most normal devices have a ratio of 1. | |
24767 | |
24768 var devicePixelRatio = window.devicePixelRatio || 1, | |
24769 backingStoreRatio = | |
24770 context.webkitBackingStorePixelRatio || | |
24771 context.mozBackingStorePixelRatio || | |
24772 context.msBackingStorePixelRatio || | |
24773 context.oBackingStorePixelRatio || | |
24774 context.backingStorePixelRatio || 1; | |
24775 | |
24776 this.pixelRatio = devicePixelRatio / backingStoreRatio; | |
24777 | |
24778 // Size the canvas to match the internal dimensions of its container | |
24779 | |
24780 this.resize(container.width(), container.height()); | |
24781 | |
24782 // Collection of HTML div layers for text overlaid onto the canvas | |
24783 | |
24784 this.textContainer = null; | |
24785 this.text = {}; | |
24786 | |
24787 // Cache of text fragments and metrics, so we can avoid expensively | |
24788 // re-calculating them when the plot is re-rendered in a loop. | |
24789 | |
24790 this._textCache = {}; | |
24791 } | |
24792 | |
24793 // Resizes the canvas to the given dimensions. | |
24794 // | |
24795 // @param {number} width New width of the canvas, in pixels. | |
24796 // @param {number} width New height of the canvas, in pixels. | |
24797 | |
24798 Canvas.prototype.resize = function(width, height) { | |
24799 | |
24800 if (width <= 0 || height <= 0) { | |
24801 throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); | |
24802 } | |
24803 | |
24804 var element = this.element, | |
24805 context = this.context, | |
24806 pixelRatio = this.pixelRatio; | |
24807 | |
24808 // Resize the canvas, increasing its density based on the display's | |
24809 // pixel ratio; basically giving it more pixels without increasing the | |
24810 // size of its element, to take advantage of the fact that retina | |
24811 // displays have that many more pixels in the same advertised space. | |
24812 | |
24813 // Resizing should reset the state (excanvas seems to be buggy though) | |
24814 | |
24815 if (this.width != width) { | |
24816 element.width = width * pixelRatio; | |
24817 element.style.width = width + "px"; | |
24818 this.width = width; | |
24819 } | |
24820 | |
24821 if (this.height != height) { | |
24822 element.height = height * pixelRatio; | |
24823 element.style.height = height + "px"; | |
24824 this.height = height; | |
24825 } | |
24826 | |
24827 // Save the context, so we can reset in case we get replotted. The | |
24828 // restore ensure that we're really back at the initial state, and | |
24829 // should be safe even if we haven't saved the initial state yet. | |
24830 | |
24831 context.restore(); | |
24832 context.save(); | |
24833 | |
24834 // Scale the coordinate space to match the display density; so even though we | |
24835 // may have twice as many pixels, we still want lines and other drawing to | |
24836 // appear at the same size; the extra pixels will just make them crisper. | |
24837 | |
24838 context.scale(pixelRatio, pixelRatio); | |
24839 }; | |
24840 | |
24841 // Clears the entire canvas area, not including any overlaid HTML text | |
24842 | |
24843 Canvas.prototype.clear = function() { | |
24844 this.context.clearRect(0, 0, this.width, this.height); | |
24845 }; | |
24846 | |
24847 // Finishes rendering the canvas, including managing the text overlay. | |
24848 | |
24849 Canvas.prototype.render = function() { | |
24850 | |
24851 var cache = this._textCache; | |
24852 | |
24853 // For each text layer, add elements marked as active that haven't | |
24854 // already been rendered, and remove those that are no longer active. | |
24855 | |
24856 for (var layerKey in cache) { | |
24857 if (hasOwnProperty.call(cache, layerKey)) { | |
24858 | |
24859 var layer = this.getTextLayer(layerKey), | |
24860 layerCache = cache[layerKey]; | |
24861 | |
24862 layer.hide(); | |
24863 | |
24864 for (var styleKey in layerCache) { | |
24865 if (hasOwnProperty.call(layerCache, styleKey)) { | |
24866 var styleCache = layerCache[styleKey]; | |
24867 for (var key in styleCache) { | |
24868 if (hasOwnProperty.call(styleCache, key)) { | |
24869 | |
24870 var positions = styleCache[key].positions; | |
24871 | |
24872 for (var i = 0, position; position = positions[i]; i++) { | |
24873 if (position.active) { | |
24874 if (!position.rendered) { | |
24875 layer.append(position.element); | |
24876 position.rendered = true; | |
24877 } | |
24878 } else { | |
24879 positions.splice(i--, 1); | |
24880 if (position.rendered) { | |
24881 position.element.detach(); | |
24882 } | |
24883 } | |
24884 } | |
24885 | |
24886 if (positions.length == 0) { | |
24887 delete styleCache[key]; | |
24888 } | |
24889 } | |
24890 } | |
24891 } | |
24892 } | |
24893 | |
24894 layer.show(); | |
24895 } | |
24896 } | |
24897 }; | |
24898 | |
24899 // Creates (if necessary) and returns the text overlay container. | |
24900 // | |
24901 // @param {string} classes String of space-separated CSS classes used to | |
24902 // uniquely identify the text layer. | |
24903 // @return {object} The jQuery-wrapped text-layer div. | |
24904 | |
24905 Canvas.prototype.getTextLayer = function(classes) { | |
24906 | |
24907 var layer = this.text[classes]; | |
24908 | |
24909 // Create the text layer if it doesn't exist | |
24910 | |
24911 if (layer == null) { | |
24912 | |
24913 // Create the text layer container, if it doesn't exist | |
24914 | |
24915 if (this.textContainer == null) { | |
24916 this.textContainer = $("<div class='flot-text'></div>") | |
24917 .css({ | |
24918 position: "absolute", | |
24919 top: 0, | |
24920 left: 0, | |
24921 bottom: 0, | |
24922 right: 0, | |
24923 'font-size': "smaller", | |
24924 color: "#545454" | |
24925 }) | |
24926 .insertAfter(this.element); | |
24927 } | |
24928 | |
24929 layer = this.text[classes] = $("<div></div>") | |
24930 .addClass(classes) | |
24931 .css({ | |
24932 position: "absolute", | |
24933 top: 0, | |
24934 left: 0, | |
24935 bottom: 0, | |
24936 right: 0 | |
24937 }) | |
24938 .appendTo(this.textContainer); | |
24939 } | |
24940 | |
24941 return layer; | |
24942 }; | |
24943 | |
24944 // Creates (if necessary) and returns a text info object. | |
24945 // | |
24946 // The object looks like this: | |
24947 // | |
24948 // { | |
24949 // width: Width of the text's wrapper div. | |
24950 // height: Height of the text's wrapper div. | |
24951 // element: The jQuery-wrapped HTML div containing the text. | |
24952 // positions: Array of positions at which this text is drawn. | |
24953 // } | |
24954 // | |
24955 // The positions array contains objects that look like this: | |
24956 // | |
24957 // { | |
24958 // active: Flag indicating whether the text should be visible. | |
24959 // rendered: Flag indicating whether the text is currently visible. | |
24960 // element: The jQuery-wrapped HTML div containing the text. | |
24961 // x: X coordinate at which to draw the text. | |
24962 // y: Y coordinate at which to draw the text. | |
24963 // } | |
24964 // | |
24965 // Each position after the first receives a clone of the original element. | |
24966 // | |
24967 // The idea is that that the width, height, and general 'identity' of the | |
24968 // text is constant no matter where it is placed; the placements are a | |
24969 // secondary property. | |
24970 // | |
24971 // Canvas maintains a cache of recently-used text info objects; getTextInfo | |
24972 // either returns the cached element or creates a new entry. | |
24973 // | |
24974 // @param {string} layer A string of space-separated CSS classes uniquely | |
24975 // identifying the layer containing this text. | |
24976 // @param {string} text Text string to retrieve info for. | |
24977 // @param {(string|object)=} font Either a string of space-separated CSS | |
24978 // classes or a font-spec object, defining the text's font and style. | |
24979 // @param {number=} angle Angle at which to rotate the text, in degrees. | |
24980 // Angle is currently unused, it will be implemented in the future. | |
24981 // @param {number=} width Maximum width of the text before it wraps. | |
24982 // @return {object} a text info object. | |
24983 | |
24984 Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { | |
24985 | |
24986 var textStyle, layerCache, styleCache, info; | |
24987 | |
24988 // Cast the value to a string, in case we were given a number or such | |
24989 | |
24990 text = "" + text; | |
24991 | |
24992 // If the font is a font-spec object, generate a CSS font definition | |
24993 | |
24994 if (typeof font === "object") { | |
24995 textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; | |
24996 } else { | |
24997 textStyle = font; | |
24998 } | |
24999 | |
25000 // Retrieve (or create) the cache for the text's layer and styles | |
25001 | |
25002 layerCache = this._textCache[layer]; | |
25003 | |
25004 if (layerCache == null) { | |
25005 layerCache = this._textCache[layer] = {}; | |
25006 } | |
25007 | |
25008 styleCache = layerCache[textStyle]; | |
25009 | |
25010 if (styleCache == null) { | |
25011 styleCache = layerCache[textStyle] = {}; | |
25012 } | |
25013 | |
25014 info = styleCache[text]; | |
25015 | |
25016 // If we can't find a matching element in our cache, create a new one | |
25017 | |
25018 if (info == null) { | |
25019 | |
25020 var element = $("<div></div>").html(text) | |
25021 .css({ | |
25022 position: "absolute", | |
25023 'max-width': width, | |
25024 top: -9999 | |
25025 }) | |
25026 .appendTo(this.getTextLayer(layer)); | |
25027 | |
25028 if (typeof font === "object") { | |
25029 element.css({ | |
25030 font: textStyle, | |
25031 color: font.color | |
25032 }); | |
25033 } else if (typeof font === "string") { | |
25034 element.addClass(font); | |
25035 } | |
25036 | |
25037 info = styleCache[text] = { | |
25038 width: element.outerWidth(true), | |
25039 height: element.outerHeight(true), | |
25040 element: element, | |
25041 positions: [] | |
25042 }; | |
25043 | |
25044 element.detach(); | |
25045 } | |
25046 | |
25047 return info; | |
25048 }; | |
25049 | |
25050 // Adds a text string to the canvas text overlay. | |
25051 // | |
25052 // The text isn't drawn immediately; it is marked as rendering, which will | |
25053 // result in its addition to the canvas on the next render pass. | |
25054 // | |
25055 // @param {string} layer A string of space-separated CSS classes uniquely | |
25056 // identifying the layer containing this text. | |
25057 // @param {number} x X coordinate at which to draw the text. | |
25058 // @param {number} y Y coordinate at which to draw the text. | |
25059 // @param {string} text Text string to draw. | |
25060 // @param {(string|object)=} font Either a string of space-separated CSS | |
25061 // classes or a font-spec object, defining the text's font and style. | |
25062 // @param {number=} angle Angle at which to rotate the text, in degrees. | |
25063 // Angle is currently unused, it will be implemented in the future. | |
25064 // @param {number=} width Maximum width of the text before it wraps. | |
25065 // @param {string=} halign Horizontal alignment of the text; either "left", | |
25066 // "center" or "right". | |
25067 // @param {string=} valign Vertical alignment of the text; either "top", | |
25068 // "middle" or "bottom". | |
25069 | |
25070 Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { | |
25071 | |
25072 var info = this.getTextInfo(layer, text, font, angle, width), | |
25073 positions = info.positions; | |
25074 | |
25075 // Tweak the div's position to match the text's alignment | |
25076 | |
25077 if (halign == "center") { | |
25078 x -= info.width / 2; | |
25079 } else if (halign == "right") { | |
25080 x -= info.width; | |
25081 } | |
25082 | |
25083 if (valign == "middle") { | |
25084 y -= info.height / 2; | |
25085 } else if (valign == "bottom") { | |
25086 y -= info.height; | |
25087 } | |
25088 | |
25089 // Determine whether this text already exists at this position. | |
25090 // If so, mark it for inclusion in the next render pass. | |
25091 | |
25092 for (var i = 0, position; position = positions[i]; i++) { | |
25093 if (position.x == x && position.y == y) { | |
25094 position.active = true; | |
25095 return; | |
25096 } | |
25097 } | |
25098 | |
25099 // If the text doesn't exist at this position, create a new entry | |
25100 | |
25101 // For the very first position we'll re-use the original element, | |
25102 // while for subsequent ones we'll clone it. | |
25103 | |
25104 position = { | |
25105 active: true, | |
25106 rendered: false, | |
25107 element: positions.length ? info.element.clone() : info.element, | |
25108 x: x, | |
25109 y: y | |
25110 }; | |
25111 | |
25112 positions.push(position); | |
25113 | |
25114 // Move the element to its final position within the container | |
25115 | |
25116 position.element.css({ | |
25117 top: Math.round(y), | |
25118 left: Math.round(x), | |
25119 'text-align': halign // In case the text wraps | |
25120 }); | |
25121 }; | |
25122 | |
25123 // Removes one or more text strings from the canvas text overlay. | |
25124 // | |
25125 // If no parameters are given, all text within the layer is removed. | |
25126 // | |
25127 // Note that the text is not immediately removed; it is simply marked as | |
25128 // inactive, which will result in its removal on the next render pass. | |
25129 // This avoids the performance penalty for 'clear and redraw' behavior, | |
25130 // where we potentially get rid of all text on a layer, but will likely | |
25131 // add back most or all of it later, as when redrawing axes, for example. | |
25132 // | |
25133 // @param {string} layer A string of space-separated CSS classes uniquely | |
25134 // identifying the layer containing this text. | |
25135 // @param {number=} x X coordinate of the text. | |
25136 // @param {number=} y Y coordinate of the text. | |
25137 // @param {string=} text Text string to remove. | |
25138 // @param {(string|object)=} font Either a string of space-separated CSS | |
25139 // classes or a font-spec object, defining the text's font and style. | |
25140 // @param {number=} angle Angle at which the text is rotated, in degrees. | |
25141 // Angle is currently unused, it will be implemented in the future. | |
25142 | |
25143 Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { | |
25144 if (text == null) { | |
25145 var layerCache = this._textCache[layer]; | |
25146 if (layerCache != null) { | |
25147 for (var styleKey in layerCache) { | |
25148 if (hasOwnProperty.call(layerCache, styleKey)) { | |
25149 var styleCache = layerCache[styleKey]; | |
25150 for (var key in styleCache) { | |
25151 if (hasOwnProperty.call(styleCache, key)) { | |
25152 var positions = styleCache[key].positions; | |
25153 for (var i = 0, position; position = positions[i]; i++) { | |
25154 position.active = false; | |
25155 } | |
25156 } | |
25157 } | |
25158 } | |
25159 } | |
25160 } | |
25161 } else { | |
25162 var positions = this.getTextInfo(layer, text, font, angle).positions; | |
25163 for (var i = 0, position; position = positions[i]; i++) { | |
25164 if (position.x == x && position.y == y) { | |
25165 position.active = false; | |
25166 } | |
25167 } | |
25168 } | |
25169 }; | |
25170 | |
25171 /////////////////////////////////////////////////////////////////////////// | |
25172 // The top-level container for the entire plot. | |
25173 | |
25174 function Plot(placeholder, data_, options_, plugins) { | |
25175 // data is on the form: | |
25176 // [ series1, series2 ... ] | |
25177 // where series is either just the data as [ [x1, y1], [x2, y2], ... ] | |
25178 // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } | |
25179 | |
25180 var series = [], | |
25181 options = { | |
25182 // the color theme used for graphs | |
25183 colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], | |
25184 legend: { | |
25185 show: true, | |
25186 noColumns: 1, // number of colums in legend table | |
25187 labelFormatter: null, // fn: string -> string | |
25188 labelBoxBorderColor: "#ccc", // border color for the little label boxes | |
25189 container: null, // container (as jQuery object) to put legend in, null means default on top of graph | |
25190 position: "ne", // position of default legend container within plot | |
25191 margin: 5, // distance from grid edge to default legend container within plot | |
25192 backgroundColor: null, // null means auto-detect | |
25193 backgroundOpacity: 0.85, // set to 0 to avoid background | |
25194 sorted: null // default to no legend sorting | |
25195 }, | |
25196 xaxis: { | |
25197 show: null, // null = auto-detect, true = always, false = never | |
25198 position: "bottom", // or "top" | |
25199 mode: null, // null or "time" | |
25200 font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } | |
25201 color: null, // base color, labels, ticks | |
25202 tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" | |
25203 transform: null, // null or f: number -> number to transform axis | |
25204 inverseTransform: null, // if transform is set, this should be the inverse function | |
25205 min: null, // min. value to show, null means set automatically | |
25206 max: null, // max. value to show, null means set automatically | |
25207 autoscaleMargin: null, // margin in % to add if auto-setting min/max | |
25208 ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks | |
25209 tickFormatter: null, // fn: number -> string | |
25210 labelWidth: null, // size of tick labels in pixels | |
25211 labelHeight: null, | |
25212 reserveSpace: null, // whether to reserve space even if axis isn't shown | |
25213 tickLength: null, // size in pixels of ticks, or "full" for whole line | |
25214 alignTicksWithAxis: null, // axis number or null for no sync | |
25215 tickDecimals: null, // no. of decimals, null means auto | |
25216 tickSize: null, // number or [number, "unit"] | |
25217 minTickSize: null // number or [number, "unit"] | |
25218 }, | |
25219 yaxis: { | |
25220 autoscaleMargin: 0.02, | |
25221 position: "left" // or "right" | |
25222 }, | |
25223 xaxes: [], | |
25224 yaxes: [], | |
25225 series: { | |
25226 points: { | |
25227 show: false, | |
25228 radius: 3, | |
25229 lineWidth: 2, // in pixels | |
25230 fill: true, | |
25231 fillColor: "#ffffff", | |
25232 symbol: "circle" // or callback | |
25233 }, | |
25234 lines: { | |
25235 // we don't put in show: false so we can see | |
25236 // whether lines were actively disabled | |
25237 lineWidth: 2, // in pixels | |
25238 fill: false, | |
25239 fillColor: null, | |
25240 steps: false | |
25241 // Omit 'zero', so we can later default its value to | |
25242 // match that of the 'fill' option. | |
25243 }, | |
25244 bars: { | |
25245 show: false, | |
25246 lineWidth: 2, // in pixels | |
25247 barWidth: 1, // in units of the x axis | |
25248 fill: true, | |
25249 fillColor: null, | |
25250 align: "left", // "left", "right", or "center" | |
25251 horizontal: false, | |
25252 zero: true | |
25253 }, | |
25254 shadowSize: 3, | |
25255 highlightColor: null | |
25256 }, | |
25257 grid: { | |
25258 show: true, | |
25259 aboveData: false, | |
25260 color: "#545454", // primary color used for outline and labels | |
25261 backgroundColor: null, // null for transparent, else color | |
25262 borderColor: null, // set if different from the grid color | |
25263 tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" | |
25264 margin: 0, // distance from the canvas edge to the grid | |
25265 labelMargin: 5, // in pixels | |
25266 axisMargin: 8, // in pixels | |
25267 borderWidth: 2, // in pixels | |
25268 minBorderMargin: null, // in pixels, null means taken from points radius | |
25269 markings: null, // array of ranges or fn: axes -> array of ranges | |
25270 markingsColor: "#f4f4f4", | |
25271 markingsLineWidth: 2, | |
25272 // interactive stuff | |
25273 clickable: false, | |
25274 hoverable: false, | |
25275 autoHighlight: true, // highlight in case mouse is near | |
25276 mouseActiveRadius: 10 // how far the mouse can be away to activate an item | |
25277 }, | |
25278 interaction: { | |
25279 redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow | |
25280 }, | |
25281 hooks: {} | |
25282 }, | |
25283 surface = null, // the canvas for the plot itself | |
25284 overlay = null, // canvas for interactive stuff on top of plot | |
25285 eventHolder = null, // jQuery object that events should be bound to | |
25286 ctx = null, octx = null, | |
25287 xaxes = [], yaxes = [], | |
25288 plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, | |
25289 plotWidth = 0, plotHeight = 0, | |
25290 hooks = { | |
25291 processOptions: [], | |
25292 processRawData: [], | |
25293 processDatapoints: [], | |
25294 processOffset: [], | |
25295 drawBackground: [], | |
25296 drawSeries: [], | |
25297 draw: [], | |
25298 bindEvents: [], | |
25299 drawOverlay: [], | |
25300 shutdown: [] | |
25301 }, | |
25302 plot = this; | |
25303 | |
25304 // public functions | |
25305 plot.setData = setData; | |
25306 plot.setupGrid = setupGrid; | |
25307 plot.draw = draw; | |
25308 plot.getPlaceholder = function() { return placeholder; }; | |
25309 plot.getCanvas = function() { return surface.element; }; | |
25310 plot.getPlotOffset = function() { return plotOffset; }; | |
25311 plot.width = function () { return plotWidth; }; | |
25312 plot.height = function () { return plotHeight; }; | |
25313 plot.offset = function () { | |
25314 var o = eventHolder.offset(); | |
25315 o.left += plotOffset.left; | |
25316 o.top += plotOffset.top; | |
25317 return o; | |
25318 }; | |
25319 plot.getData = function () { return series; }; | |
25320 plot.getAxes = function () { | |
25321 var res = {}, i; | |
25322 $.each(xaxes.concat(yaxes), function (_, axis) { | |
25323 if (axis) | |
25324 res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; | |
25325 }); | |
25326 return res; | |
25327 }; | |
25328 plot.getXAxes = function () { return xaxes; }; | |
25329 plot.getYAxes = function () { return yaxes; }; | |
25330 plot.c2p = canvasToAxisCoords; | |
25331 plot.p2c = axisToCanvasCoords; | |
25332 plot.getOptions = function () { return options; }; | |
25333 plot.highlight = highlight; | |
25334 plot.unhighlight = unhighlight; | |
25335 plot.triggerRedrawOverlay = triggerRedrawOverlay; | |
25336 plot.pointOffset = function(point) { | |
25337 return { | |
25338 left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), | |
25339 top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) | |
25340 }; | |
25341 }; | |
25342 plot.shutdown = shutdown; | |
25343 plot.destroy = function () { | |
25344 shutdown(); | |
25345 placeholder.removeData("plot").empty(); | |
25346 | |
25347 series = []; | |
25348 options = null; | |
25349 surface = null; | |
25350 overlay = null; | |
25351 eventHolder = null; | |
25352 ctx = null; | |
25353 octx = null; | |
25354 xaxes = []; | |
25355 yaxes = []; | |
25356 hooks = null; | |
25357 highlights = []; | |
25358 plot = null; | |
25359 }; | |
25360 plot.resize = function () { | |
25361 var width = placeholder.width(), | |
25362 height = placeholder.height(); | |
25363 surface.resize(width, height); | |
25364 overlay.resize(width, height); | |
25365 }; | |
25366 | |
25367 // public attributes | |
25368 plot.hooks = hooks; | |
25369 | |
25370 // initialize | |
25371 initPlugins(plot); | |
25372 parseOptions(options_); | |
25373 setupCanvases(); | |
25374 setData(data_); | |
25375 setupGrid(); | |
25376 draw(); | |
25377 bindEvents(); | |
25378 | |
25379 | |
25380 function executeHooks(hook, args) { | |
25381 args = [plot].concat(args); | |
25382 for (var i = 0; i < hook.length; ++i) | |
25383 hook[i].apply(this, args); | |
25384 } | |
25385 | |
25386 function initPlugins() { | |
25387 | |
25388 // References to key classes, allowing plugins to modify them | |
25389 | |
25390 var classes = { | |
25391 Canvas: Canvas | |
25392 }; | |
25393 | |
25394 for (var i = 0; i < plugins.length; ++i) { | |
25395 var p = plugins[i]; | |
25396 p.init(plot, classes); | |
25397 if (p.options) | |
25398 $.extend(true, options, p.options); | |
25399 } | |
25400 } | |
25401 | |
25402 function parseOptions(opts) { | |
25403 | |
25404 $.extend(true, options, opts); | |
25405 | |
25406 // $.extend merges arrays, rather than replacing them. When less | |
25407 // colors are provided than the size of the default palette, we | |
25408 // end up with those colors plus the remaining defaults, which is | |
25409 // not expected behavior; avoid it by replacing them here. | |
25410 | |
25411 if (opts && opts.colors) { | |
25412 options.colors = opts.colors; | |
25413 } | |
25414 | |
25415 if (options.xaxis.color == null) | |
25416 options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); | |
25417 if (options.yaxis.color == null) | |
25418 options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); | |
25419 | |
25420 if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility | |
25421 options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; | |
25422 if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility | |
25423 options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; | |
25424 | |
25425 if (options.grid.borderColor == null) | |
25426 options.grid.borderColor = options.grid.color; | |
25427 if (options.grid.tickColor == null) | |
25428 options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); | |
25429 | |
25430 // Fill in defaults for axis options, including any unspecified | |
25431 // font-spec fields, if a font-spec was provided. | |
25432 | |
25433 // If no x/y axis options were provided, create one of each anyway, | |
25434 // since the rest of the code assumes that they exist. | |
25435 | |
25436 var i, axisOptions, axisCount, | |
25437 fontSize = placeholder.css("font-size"), | |
25438 fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13, | |
25439 fontDefaults = { | |
25440 style: placeholder.css("font-style"), | |
25441 size: Math.round(0.8 * fontSizeDefault), | |
25442 variant: placeholder.css("font-variant"), | |
25443 weight: placeholder.css("font-weight"), | |
25444 family: placeholder.css("font-family") | |
25445 }; | |
25446 | |
25447 axisCount = options.xaxes.length || 1; | |
25448 for (i = 0; i < axisCount; ++i) { | |
25449 | |
25450 axisOptions = options.xaxes[i]; | |
25451 if (axisOptions && !axisOptions.tickColor) { | |
25452 axisOptions.tickColor = axisOptions.color; | |
25453 } | |
25454 | |
25455 axisOptions = $.extend(true, {}, options.xaxis, axisOptions); | |
25456 options.xaxes[i] = axisOptions; | |
25457 | |
25458 if (axisOptions.font) { | |
25459 axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); | |
25460 if (!axisOptions.font.color) { | |
25461 axisOptions.font.color = axisOptions.color; | |
25462 } | |
25463 if (!axisOptions.font.lineHeight) { | |
25464 axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); | |
25465 } | |
25466 } | |
25467 } | |
25468 | |
25469 axisCount = options.yaxes.length || 1; | |
25470 for (i = 0; i < axisCount; ++i) { | |
25471 | |
25472 axisOptions = options.yaxes[i]; | |
25473 if (axisOptions && !axisOptions.tickColor) { | |
25474 axisOptions.tickColor = axisOptions.color; | |
25475 } | |
25476 | |
25477 axisOptions = $.extend(true, {}, options.yaxis, axisOptions); | |
25478 options.yaxes[i] = axisOptions; | |
25479 | |
25480 if (axisOptions.font) { | |
25481 axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); | |
25482 if (!axisOptions.font.color) { | |
25483 axisOptions.font.color = axisOptions.color; | |
25484 } | |
25485 if (!axisOptions.font.lineHeight) { | |
25486 axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); | |
25487 } | |
25488 } | |
25489 } | |
25490 | |
25491 // backwards compatibility, to be removed in future | |
25492 if (options.xaxis.noTicks && options.xaxis.ticks == null) | |
25493 options.xaxis.ticks = options.xaxis.noTicks; | |
25494 if (options.yaxis.noTicks && options.yaxis.ticks == null) | |
25495 options.yaxis.ticks = options.yaxis.noTicks; | |
25496 if (options.x2axis) { | |
25497 options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); | |
25498 options.xaxes[1].position = "top"; | |
25499 } | |
25500 if (options.y2axis) { | |
25501 options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); | |
25502 options.yaxes[1].position = "right"; | |
25503 } | |
25504 if (options.grid.coloredAreas) | |
25505 options.grid.markings = options.grid.coloredAreas; | |
25506 if (options.grid.coloredAreasColor) | |
25507 options.grid.markingsColor = options.grid.coloredAreasColor; | |
25508 if (options.lines) | |
25509 $.extend(true, options.series.lines, options.lines); | |
25510 if (options.points) | |
25511 $.extend(true, options.series.points, options.points); | |
25512 if (options.bars) | |
25513 $.extend(true, options.series.bars, options.bars); | |
25514 if (options.shadowSize != null) | |
25515 options.series.shadowSize = options.shadowSize; | |
25516 if (options.highlightColor != null) | |
25517 options.series.highlightColor = options.highlightColor; | |
25518 | |
25519 // save options on axes for future reference | |
25520 for (i = 0; i < options.xaxes.length; ++i) | |
25521 getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; | |
25522 for (i = 0; i < options.yaxes.length; ++i) | |
25523 getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; | |
25524 | |
25525 // add hooks from options | |
25526 for (var n in hooks) | |
25527 if (options.hooks[n] && options.hooks[n].length) | |
25528 hooks[n] = hooks[n].concat(options.hooks[n]); | |
25529 | |
25530 executeHooks(hooks.processOptions, [options]); | |
25531 } | |
25532 | |
25533 function setData(d) { | |
25534 series = parseData(d); | |
25535 fillInSeriesOptions(); | |
25536 processData(); | |
25537 } | |
25538 | |
25539 function parseData(d) { | |
25540 var res = []; | |
25541 for (var i = 0; i < d.length; ++i) { | |
25542 var s = $.extend(true, {}, options.series); | |
25543 | |
25544 if (d[i].data != null) { | |
25545 s.data = d[i].data; // move the data instead of deep-copy | |
25546 delete d[i].data; | |
25547 | |
25548 $.extend(true, s, d[i]); | |
25549 | |
25550 d[i].data = s.data; | |
25551 } | |
25552 else | |
25553 s.data = d[i]; | |
25554 res.push(s); | |
25555 } | |
25556 | |
25557 return res; | |
25558 } | |
25559 | |
25560 function axisNumber(obj, coord) { | |
25561 var a = obj[coord + "axis"]; | |
25562 if (typeof a == "object") // if we got a real axis, extract number | |
25563 a = a.n; | |
25564 if (typeof a != "number") | |
25565 a = 1; // default to first axis | |
25566 return a; | |
25567 } | |
25568 | |
25569 function allAxes() { | |
25570 // return flat array without annoying null entries | |
25571 return $.grep(xaxes.concat(yaxes), function (a) { return a; }); | |
25572 } | |
25573 | |
25574 function canvasToAxisCoords(pos) { | |
25575 // return an object with x/y corresponding to all used axes | |
25576 var res = {}, i, axis; | |
25577 for (i = 0; i < xaxes.length; ++i) { | |
25578 axis = xaxes[i]; | |
25579 if (axis && axis.used) | |
25580 res["x" + axis.n] = axis.c2p(pos.left); | |
25581 } | |
25582 | |
25583 for (i = 0; i < yaxes.length; ++i) { | |
25584 axis = yaxes[i]; | |
25585 if (axis && axis.used) | |
25586 res["y" + axis.n] = axis.c2p(pos.top); | |
25587 } | |
25588 | |
25589 if (res.x1 !== undefined) | |
25590 res.x = res.x1; | |
25591 if (res.y1 !== undefined) | |
25592 res.y = res.y1; | |
25593 | |
25594 return res; | |
25595 } | |
25596 | |
25597 function axisToCanvasCoords(pos) { | |
25598 // get canvas coords from the first pair of x/y found in pos | |
25599 var res = {}, i, axis, key; | |
25600 | |
25601 for (i = 0; i < xaxes.length; ++i) { | |
25602 axis = xaxes[i]; | |
25603 if (axis && axis.used) { | |
25604 key = "x" + axis.n; | |
25605 if (pos[key] == null && axis.n == 1) | |
25606 key = "x"; | |
25607 | |
25608 if (pos[key] != null) { | |
25609 res.left = axis.p2c(pos[key]); | |
25610 break; | |
25611 } | |
25612 } | |
25613 } | |
25614 | |
25615 for (i = 0; i < yaxes.length; ++i) { | |
25616 axis = yaxes[i]; | |
25617 if (axis && axis.used) { | |
25618 key = "y" + axis.n; | |
25619 if (pos[key] == null && axis.n == 1) | |
25620 key = "y"; | |
25621 | |
25622 if (pos[key] != null) { | |
25623 res.top = axis.p2c(pos[key]); | |
25624 break; | |
25625 } | |
25626 } | |
25627 } | |
25628 | |
25629 return res; | |
25630 } | |
25631 | |
25632 function getOrCreateAxis(axes, number) { | |
25633 if (!axes[number - 1]) | |
25634 axes[number - 1] = { | |
25635 n: number, // save the number for future reference | |
25636 direction: axes == xaxes ? "x" : "y", | |
25637 options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) | |
25638 }; | |
25639 | |
25640 return axes[number - 1]; | |
25641 } | |
25642 | |
25643 function fillInSeriesOptions() { | |
25644 | |
25645 var neededColors = series.length, maxIndex = -1, i; | |
25646 | |
25647 // Subtract the number of series that already have fixed colors or | |
25648 // color indexes from the number that we still need to generate. | |
25649 | |
25650 for (i = 0; i < series.length; ++i) { | |
25651 var sc = series[i].color; | |
25652 if (sc != null) { | |
25653 neededColors--; | |
25654 if (typeof sc == "number" && sc > maxIndex) { | |
25655 maxIndex = sc; | |
25656 } | |
25657 } | |
25658 } | |
25659 | |
25660 // If any of the series have fixed color indexes, then we need to | |
25661 // generate at least as many colors as the highest index. | |
25662 | |
25663 if (neededColors <= maxIndex) { | |
25664 neededColors = maxIndex + 1; | |
25665 } | |
25666 | |
25667 // Generate all the colors, using first the option colors and then | |
25668 // variations on those colors once they're exhausted. | |
25669 | |
25670 var c, colors = [], colorPool = options.colors, | |
25671 colorPoolSize = colorPool.length, variation = 0; | |
25672 | |
25673 for (i = 0; i < neededColors; i++) { | |
25674 | |
25675 c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); | |
25676 | |
25677 // Each time we exhaust the colors in the pool we adjust | |
25678 // a scaling factor used to produce more variations on | |
25679 // those colors. The factor alternates negative/positive | |
25680 // to produce lighter/darker colors. | |
25681 | |
25682 // Reset the variation after every few cycles, or else | |
25683 // it will end up producing only white or black colors. | |
25684 | |
25685 if (i % colorPoolSize == 0 && i) { | |
25686 if (variation >= 0) { | |
25687 if (variation < 0.5) { | |
25688 variation = -variation - 0.2; | |
25689 } else variation = 0; | |
25690 } else variation = -variation; | |
25691 } | |
25692 | |
25693 colors[i] = c.scale('rgb', 1 + variation); | |
25694 } | |
25695 | |
25696 // Finalize the series options, filling in their colors | |
25697 | |
25698 var colori = 0, s; | |
25699 for (i = 0; i < series.length; ++i) { | |
25700 s = series[i]; | |
25701 | |
25702 // assign colors | |
25703 if (s.color == null) { | |
25704 s.color = colors[colori].toString(); | |
25705 ++colori; | |
25706 } | |
25707 else if (typeof s.color == "number") | |
25708 s.color = colors[s.color].toString(); | |
25709 | |
25710 // turn on lines automatically in case nothing is set | |
25711 if (s.lines.show == null) { | |
25712 var v, show = true; | |
25713 for (v in s) | |
25714 if (s[v] && s[v].show) { | |
25715 show = false; | |
25716 break; | |
25717 } | |
25718 if (show) | |
25719 s.lines.show = true; | |
25720 } | |
25721 | |
25722 // If nothing was provided for lines.zero, default it to match | |
25723 // lines.fill, since areas by default should extend to zero. | |
25724 | |
25725 if (s.lines.zero == null) { | |
25726 s.lines.zero = !!s.lines.fill; | |
25727 } | |
25728 | |
25729 // setup axes | |
25730 s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); | |
25731 s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); | |
25732 } | |
25733 } | |
25734 | |
25735 function processData() { | |
25736 var topSentry = Number.POSITIVE_INFINITY, | |
25737 bottomSentry = Number.NEGATIVE_INFINITY, | |
25738 fakeInfinity = Number.MAX_VALUE, | |
25739 i, j, k, m, length, | |
25740 s, points, ps, x, y, axis, val, f, p, | |
25741 data, format; | |
25742 | |
25743 function updateAxis(axis, min, max) { | |
25744 if (min < axis.datamin && min != -fakeInfinity) | |
25745 axis.datamin = min; | |
25746 if (max > axis.datamax && max != fakeInfinity) | |
25747 axis.datamax = max; | |
25748 } | |
25749 | |
25750 $.each(allAxes(), function (_, axis) { | |
25751 // init axis | |
25752 axis.datamin = topSentry; | |
25753 axis.datamax = bottomSentry; | |
25754 axis.used = false; | |
25755 }); | |
25756 | |
25757 for (i = 0; i < series.length; ++i) { | |
25758 s = series[i]; | |
25759 s.datapoints = { points: [] }; | |
25760 | |
25761 executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); | |
25762 } | |
25763 | |
25764 // first pass: clean and copy data | |
25765 for (i = 0; i < series.length; ++i) { | |
25766 s = series[i]; | |
25767 | |
25768 data = s.data; | |
25769 format = s.datapoints.format; | |
25770 | |
25771 if (!format) { | |
25772 format = []; | |
25773 // find out how to copy | |
25774 format.push({ x: true, number: true, required: true }); | |
25775 format.push({ y: true, number: true, required: true }); | |
25776 | |
25777 if (s.bars.show || (s.lines.show && s.lines.fill)) { | |
25778 var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); | |
25779 format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); | |
25780 if (s.bars.horizontal) { | |
25781 delete format[format.length - 1].y; | |
25782 format[format.length - 1].x = true; | |
25783 } | |
25784 } | |
25785 | |
25786 s.datapoints.format = format; | |
25787 } | |
25788 | |
25789 if (s.datapoints.pointsize != null) | |
25790 continue; // already filled in | |
25791 | |
25792 s.datapoints.pointsize = format.length; | |
25793 | |
25794 ps = s.datapoints.pointsize; | |
25795 points = s.datapoints.points; | |
25796 | |
25797 var insertSteps = s.lines.show && s.lines.steps; | |
25798 s.xaxis.used = s.yaxis.used = true; | |
25799 | |
25800 for (j = k = 0; j < data.length; ++j, k += ps) { | |
25801 p = data[j]; | |
25802 | |
25803 var nullify = p == null; | |
25804 if (!nullify) { | |
25805 for (m = 0; m < ps; ++m) { | |
25806 val = p[m]; | |
25807 f = format[m]; | |
25808 | |
25809 if (f) { | |
25810 if (f.number && val != null) { | |
25811 val = +val; // convert to number | |
25812 if (isNaN(val)) | |
25813 val = null; | |
25814 else if (val == Infinity) | |
25815 val = fakeInfinity; | |
25816 else if (val == -Infinity) | |
25817 val = -fakeInfinity; | |
25818 } | |
25819 | |
25820 if (val == null) { | |
25821 if (f.required) | |
25822 nullify = true; | |
25823 | |
25824 if (f.defaultValue != null) | |
25825 val = f.defaultValue; | |
25826 } | |
25827 } | |
25828 | |
25829 points[k + m] = val; | |
25830 } | |
25831 } | |
25832 | |
25833 if (nullify) { | |
25834 for (m = 0; m < ps; ++m) { | |
25835 val = points[k + m]; | |
25836 if (val != null) { | |
25837 f = format[m]; | |
25838 // extract min/max info | |
25839 if (f.autoscale !== false) { | |
25840 if (f.x) { | |
25841 updateAxis(s.xaxis, val, val); | |
25842 } | |
25843 if (f.y) { | |
25844 updateAxis(s.yaxis, val, val); | |
25845 } | |
25846 } | |
25847 } | |
25848 points[k + m] = null; | |
25849 } | |
25850 } | |
25851 else { | |
25852 // a little bit of line specific stuff that | |
25853 // perhaps shouldn't be here, but lacking | |
25854 // better means... | |
25855 if (insertSteps && k > 0 | |
25856 && points[k - ps] != null | |
25857 && points[k - ps] != points[k] | |
25858 && points[k - ps + 1] != points[k + 1]) { | |
25859 // copy the point to make room for a middle point | |
25860 for (m = 0; m < ps; ++m) | |
25861 points[k + ps + m] = points[k + m]; | |
25862 | |
25863 // middle point has same y | |
25864 points[k + 1] = points[k - ps + 1]; | |
25865 | |
25866 // we've added a point, better reflect that | |
25867 k += ps; | |
25868 } | |
25869 } | |
25870 } | |
25871 } | |
25872 | |
25873 // give the hooks a chance to run | |
25874 for (i = 0; i < series.length; ++i) { | |
25875 s = series[i]; | |
25876 | |
25877 executeHooks(hooks.processDatapoints, [ s, s.datapoints]); | |
25878 } | |
25879 | |
25880 // second pass: find datamax/datamin for auto-scaling | |
25881 for (i = 0; i < series.length; ++i) { | |
25882 s = series[i]; | |
25883 points = s.datapoints.points; | |
25884 ps = s.datapoints.pointsize; | |
25885 format = s.datapoints.format; | |
25886 | |
25887 var xmin = topSentry, ymin = topSentry, | |
25888 xmax = bottomSentry, ymax = bottomSentry; | |
25889 | |
25890 for (j = 0; j < points.length; j += ps) { | |
25891 if (points[j] == null) | |
25892 continue; | |
25893 | |
25894 for (m = 0; m < ps; ++m) { | |
25895 val = points[j + m]; | |
25896 f = format[m]; | |
25897 if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) | |
25898 continue; | |
25899 | |
25900 if (f.x) { | |
25901 if (val < xmin) | |
25902 xmin = val; | |
25903 if (val > xmax) | |
25904 xmax = val; | |
25905 } | |
25906 if (f.y) { | |
25907 if (val < ymin) | |
25908 ymin = val; | |
25909 if (val > ymax) | |
25910 ymax = val; | |
25911 } | |
25912 } | |
25913 } | |
25914 | |
25915 if (s.bars.show) { | |
25916 // make sure we got room for the bar on the dancing floor | |
25917 var delta; | |
25918 | |
25919 switch (s.bars.align) { | |
25920 case "left": | |
25921 delta = 0; | |
25922 break; | |
25923 case "right": | |
25924 delta = -s.bars.barWidth; | |
25925 break; | |
25926 default: | |
25927 delta = -s.bars.barWidth / 2; | |
25928 } | |
25929 | |
25930 if (s.bars.horizontal) { | |
25931 ymin += delta; | |
25932 ymax += delta + s.bars.barWidth; | |
25933 } | |
25934 else { | |
25935 xmin += delta; | |
25936 xmax += delta + s.bars.barWidth; | |
25937 } | |
25938 } | |
25939 | |
25940 updateAxis(s.xaxis, xmin, xmax); | |
25941 updateAxis(s.yaxis, ymin, ymax); | |
25942 } | |
25943 | |
25944 $.each(allAxes(), function (_, axis) { | |
25945 if (axis.datamin == topSentry) | |
25946 axis.datamin = null; | |
25947 if (axis.datamax == bottomSentry) | |
25948 axis.datamax = null; | |
25949 }); | |
25950 } | |
25951 | |
25952 function setupCanvases() { | |
25953 | |
25954 // Make sure the placeholder is clear of everything except canvases | |
25955 // from a previous plot in this container that we'll try to re-use. | |
25956 | |
25957 placeholder.css("padding", 0) // padding messes up the positioning | |
25958 .children().filter(function(){ | |
25959 return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base'); | |
25960 }).remove(); | |
25961 | |
25962 if (placeholder.css("position") == 'static') | |
25963 placeholder.css("position", "relative"); // for positioning labels and overlay | |
25964 | |
25965 surface = new Canvas("flot-base", placeholder); | |
25966 overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features | |
25967 | |
25968 ctx = surface.context; | |
25969 octx = overlay.context; | |
25970 | |
25971 // define which element we're listening for events on | |
25972 eventHolder = $(overlay.element).unbind(); | |
25973 | |
25974 // If we're re-using a plot object, shut down the old one | |
25975 | |
25976 var existing = placeholder.data("plot"); | |
25977 | |
25978 if (existing) { | |
25979 existing.shutdown(); | |
25980 overlay.clear(); | |
25981 } | |
25982 | |
25983 // save in case we get replotted | |
25984 placeholder.data("plot", plot); | |
25985 } | |
25986 | |
25987 function bindEvents() { | |
25988 // bind events | |
25989 if (options.grid.hoverable) { | |
25990 eventHolder.mousemove(onMouseMove); | |
25991 | |
25992 // Use bind, rather than .mouseleave, because we officially | |
25993 // still support jQuery 1.2.6, which doesn't define a shortcut | |
25994 // for mouseenter or mouseleave. This was a bug/oversight that | |
25995 // was fixed somewhere around 1.3.x. We can return to using | |
25996 // .mouseleave when we drop support for 1.2.6. | |
25997 | |
25998 eventHolder.bind("mouseleave", onMouseLeave); | |
25999 } | |
26000 | |
26001 if (options.grid.clickable) | |
26002 eventHolder.click(onClick); | |
26003 | |
26004 executeHooks(hooks.bindEvents, [eventHolder]); | |
26005 } | |
26006 | |
26007 function shutdown() { | |
26008 if (redrawTimeout) | |
26009 clearTimeout(redrawTimeout); | |
26010 | |
26011 eventHolder.unbind("mousemove", onMouseMove); | |
26012 eventHolder.unbind("mouseleave", onMouseLeave); | |
26013 eventHolder.unbind("click", onClick); | |
26014 | |
26015 executeHooks(hooks.shutdown, [eventHolder]); | |
26016 } | |
26017 | |
26018 function setTransformationHelpers(axis) { | |
26019 // set helper functions on the axis, assumes plot area | |
26020 // has been computed already | |
26021 | |
26022 function identity(x) { return x; } | |
26023 | |
26024 var s, m, t = axis.options.transform || identity, | |
26025 it = axis.options.inverseTransform; | |
26026 | |
26027 // precompute how much the axis is scaling a point | |
26028 // in canvas space | |
26029 if (axis.direction == "x") { | |
26030 s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); | |
26031 m = Math.min(t(axis.max), t(axis.min)); | |
26032 } | |
26033 else { | |
26034 s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); | |
26035 s = -s; | |
26036 m = Math.max(t(axis.max), t(axis.min)); | |
26037 } | |
26038 | |
26039 // data point to canvas coordinate | |
26040 if (t == identity) // slight optimization | |
26041 axis.p2c = function (p) { return (p - m) * s; }; | |
26042 else | |
26043 axis.p2c = function (p) { return (t(p) - m) * s; }; | |
26044 // canvas coordinate to data point | |
26045 if (!it) | |
26046 axis.c2p = function (c) { return m + c / s; }; | |
26047 else | |
26048 axis.c2p = function (c) { return it(m + c / s); }; | |
26049 } | |
26050 | |
26051 function measureTickLabels(axis) { | |
26052 | |
26053 var opts = axis.options, | |
26054 ticks = axis.ticks || [], | |
26055 labelWidth = opts.labelWidth || 0, | |
26056 labelHeight = opts.labelHeight || 0, | |
26057 maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null), | |
26058 legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", | |
26059 layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, | |
26060 font = opts.font || "flot-tick-label tickLabel"; | |
26061 | |
26062 for (var i = 0; i < ticks.length; ++i) { | |
26063 | |
26064 var t = ticks[i]; | |
26065 | |
26066 if (!t.label) | |
26067 continue; | |
26068 | |
26069 var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); | |
26070 | |
26071 labelWidth = Math.max(labelWidth, info.width); | |
26072 labelHeight = Math.max(labelHeight, info.height); | |
26073 } | |
26074 | |
26075 axis.labelWidth = opts.labelWidth || labelWidth; | |
26076 axis.labelHeight = opts.labelHeight || labelHeight; | |
26077 } | |
26078 | |
26079 function allocateAxisBoxFirstPhase(axis) { | |
26080 // find the bounding box of the axis by looking at label | |
26081 // widths/heights and ticks, make room by diminishing the | |
26082 // plotOffset; this first phase only looks at one | |
26083 // dimension per axis, the other dimension depends on the | |
26084 // other axes so will have to wait | |
26085 | |
26086 var lw = axis.labelWidth, | |
26087 lh = axis.labelHeight, | |
26088 pos = axis.options.position, | |
26089 isXAxis = axis.direction === "x", | |
26090 tickLength = axis.options.tickLength, | |
26091 axisMargin = options.grid.axisMargin, | |
26092 padding = options.grid.labelMargin, | |
26093 innermost = true, | |
26094 outermost = true, | |
26095 first = true, | |
26096 found = false; | |
26097 | |
26098 // Determine the axis's position in its direction and on its side | |
26099 | |
26100 $.each(isXAxis ? xaxes : yaxes, function(i, a) { | |
26101 if (a && a.reserveSpace) { | |
26102 if (a === axis) { | |
26103 found = true; | |
26104 } else if (a.options.position === pos) { | |
26105 if (found) { | |
26106 outermost = false; | |
26107 } else { | |
26108 innermost = false; | |
26109 } | |
26110 } | |
26111 if (!found) { | |
26112 first = false; | |
26113 } | |
26114 } | |
26115 }); | |
26116 | |
26117 // The outermost axis on each side has no margin | |
26118 | |
26119 if (outermost) { | |
26120 axisMargin = 0; | |
26121 } | |
26122 | |
26123 // The ticks for the first axis in each direction stretch across | |
26124 | |
26125 if (tickLength == null) { | |
26126 tickLength = first ? "full" : 5; | |
26127 } | |
26128 | |
26129 if (!isNaN(+tickLength)) | |
26130 padding += +tickLength; | |
26131 | |
26132 if (isXAxis) { | |
26133 lh += padding; | |
26134 | |
26135 if (pos == "bottom") { | |
26136 plotOffset.bottom += lh + axisMargin; | |
26137 axis.box = { top: surface.height - plotOffset.bottom, height: lh }; | |
26138 } | |
26139 else { | |
26140 axis.box = { top: plotOffset.top + axisMargin, height: lh }; | |
26141 plotOffset.top += lh + axisMargin; | |
26142 } | |
26143 } | |
26144 else { | |
26145 lw += padding; | |
26146 | |
26147 if (pos == "left") { | |
26148 axis.box = { left: plotOffset.left + axisMargin, width: lw }; | |
26149 plotOffset.left += lw + axisMargin; | |
26150 } | |
26151 else { | |
26152 plotOffset.right += lw + axisMargin; | |
26153 axis.box = { left: surface.width - plotOffset.right, width: lw }; | |
26154 } | |
26155 } | |
26156 | |
26157 // save for future reference | |
26158 axis.position = pos; | |
26159 axis.tickLength = tickLength; | |
26160 axis.box.padding = padding; | |
26161 axis.innermost = innermost; | |
26162 } | |
26163 | |
26164 function allocateAxisBoxSecondPhase(axis) { | |
26165 // now that all axis boxes have been placed in one | |
26166 // dimension, we can set the remaining dimension coordinates | |
26167 if (axis.direction == "x") { | |
26168 axis.box.left = plotOffset.left - axis.labelWidth / 2; | |
26169 axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; | |
26170 } | |
26171 else { | |
26172 axis.box.top = plotOffset.top - axis.labelHeight / 2; | |
26173 axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; | |
26174 } | |
26175 } | |
26176 | |
26177 function adjustLayoutForThingsStickingOut() { | |
26178 // possibly adjust plot offset to ensure everything stays | |
26179 // inside the canvas and isn't clipped off | |
26180 | |
26181 var minMargin = options.grid.minBorderMargin, | |
26182 axis, i; | |
26183 | |
26184 // check stuff from the plot (FIXME: this should just read | |
26185 // a value from the series, otherwise it's impossible to | |
26186 // customize) | |
26187 if (minMargin == null) { | |
26188 minMargin = 0; | |
26189 for (i = 0; i < series.length; ++i) | |
26190 minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); | |
26191 } | |
26192 | |
26193 var margins = { | |
26194 left: minMargin, | |
26195 right: minMargin, | |
26196 top: minMargin, | |
26197 bottom: minMargin | |
26198 }; | |
26199 | |
26200 // check axis labels, note we don't check the actual | |
26201 // labels but instead use the overall width/height to not | |
26202 // jump as much around with replots | |
26203 $.each(allAxes(), function (_, axis) { | |
26204 if (axis.reserveSpace && axis.ticks && axis.ticks.length) { | |
26205 var lastTick = axis.ticks[axis.ticks.length - 1]; | |
26206 if (axis.direction === "x") { | |
26207 margins.left = Math.max(margins.left, axis.labelWidth / 2); | |
26208 if (lastTick.v <= axis.max) { | |
26209 margins.right = Math.max(margins.right, axis.labelWidth / 2); | |
26210 } | |
26211 } else { | |
26212 margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); | |
26213 if (lastTick.v <= axis.max) { | |
26214 margins.top = Math.max(margins.top, axis.labelHeight / 2); | |
26215 } | |
26216 } | |
26217 } | |
26218 }); | |
26219 | |
26220 plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left)); | |
26221 plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right)); | |
26222 plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); | |
26223 plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); | |
26224 } | |
26225 | |
26226 function setupGrid() { | |
26227 var i, axes = allAxes(), showGrid = options.grid.show; | |
26228 | |
26229 // Initialize the plot's offset from the edge of the canvas | |
26230 | |
26231 for (var a in plotOffset) { | |
26232 var margin = options.grid.margin || 0; | |
26233 plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; | |
26234 } | |
26235 | |
26236 executeHooks(hooks.processOffset, [plotOffset]); | |
26237 | |
26238 // If the grid is visible, add its border width to the offset | |
26239 | |
26240 for (var a in plotOffset) { | |
26241 if(typeof(options.grid.borderWidth) == "object") { | |
26242 plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; | |
26243 } | |
26244 else { | |
26245 plotOffset[a] += showGrid ? options.grid.borderWidth : 0; | |
26246 } | |
26247 } | |
26248 | |
26249 // init axes | |
26250 $.each(axes, function (_, axis) { | |
26251 axis.show = axis.options.show; | |
26252 if (axis.show == null) | |
26253 axis.show = axis.used; // by default an axis is visible if it's got data | |
26254 | |
26255 axis.reserveSpace = axis.show || axis.options.reserveSpace; | |
26256 | |
26257 setRange(axis); | |
26258 }); | |
26259 | |
26260 if (showGrid) { | |
26261 | |
26262 var allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; }); | |
26263 | |
26264 $.each(allocatedAxes, function (_, axis) { | |
26265 // make the ticks | |
26266 setupTickGeneration(axis); | |
26267 setTicks(axis); | |
26268 snapRangeToTicks(axis, axis.ticks); | |
26269 // find labelWidth/Height for axis | |
26270 measureTickLabels(axis); | |
26271 }); | |
26272 | |
26273 // with all dimensions calculated, we can compute the | |
26274 // axis bounding boxes, start from the outside | |
26275 // (reverse order) | |
26276 for (i = allocatedAxes.length - 1; i >= 0; --i) | |
26277 allocateAxisBoxFirstPhase(allocatedAxes[i]); | |
26278 | |
26279 // make sure we've got enough space for things that | |
26280 // might stick out | |
26281 adjustLayoutForThingsStickingOut(); | |
26282 | |
26283 $.each(allocatedAxes, function (_, axis) { | |
26284 allocateAxisBoxSecondPhase(axis); | |
26285 }); | |
26286 } | |
26287 | |
26288 plotWidth = surface.width - plotOffset.left - plotOffset.right; | |
26289 plotHeight = surface.height - plotOffset.bottom - plotOffset.top; | |
26290 | |
26291 // now we got the proper plot dimensions, we can compute the scaling | |
26292 $.each(axes, function (_, axis) { | |
26293 setTransformationHelpers(axis); | |
26294 }); | |
26295 | |
26296 if (showGrid) { | |
26297 drawAxisLabels(); | |
26298 } | |
26299 | |
26300 insertLegend(); | |
26301 } | |
26302 | |
26303 function setRange(axis) { | |
26304 var opts = axis.options, | |
26305 min = +(opts.min != null ? opts.min : axis.datamin), | |
26306 max = +(opts.max != null ? opts.max : axis.datamax), | |
26307 delta = max - min; | |
26308 | |
26309 if (delta == 0.0) { | |
26310 // degenerate case | |
26311 var widen = max == 0 ? 1 : 0.01; | |
26312 | |
26313 if (opts.min == null) | |
26314 min -= widen; | |
26315 // always widen max if we couldn't widen min to ensure we | |
26316 // don't fall into min == max which doesn't work | |
26317 if (opts.max == null || opts.min != null) | |
26318 max += widen; | |
26319 } | |
26320 else { | |
26321 // consider autoscaling | |
26322 var margin = opts.autoscaleMargin; | |
26323 if (margin != null) { | |
26324 if (opts.min == null) { | |
26325 min -= delta * margin; | |
26326 // make sure we don't go below zero if all values | |
26327 // are positive | |
26328 if (min < 0 && axis.datamin != null && axis.datamin >= 0) | |
26329 min = 0; | |
26330 } | |
26331 if (opts.max == null) { | |
26332 max += delta * margin; | |
26333 if (max > 0 && axis.datamax != null && axis.datamax <= 0) | |
26334 max = 0; | |
26335 } | |
26336 } | |
26337 } | |
26338 axis.min = min; | |
26339 axis.max = max; | |
26340 } | |
26341 | |
26342 function setupTickGeneration(axis) { | |
26343 var opts = axis.options; | |
26344 | |
26345 // estimate number of ticks | |
26346 var noTicks; | |
26347 if (typeof opts.ticks == "number" && opts.ticks > 0) | |
26348 noTicks = opts.ticks; | |
26349 else | |
26350 // heuristic based on the model a*sqrt(x) fitted to | |
26351 // some data points that seemed reasonable | |
26352 noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); | |
26353 | |
26354 var delta = (axis.max - axis.min) / noTicks, | |
26355 dec = -Math.floor(Math.log(delta) / Math.LN10), | |
26356 maxDec = opts.tickDecimals; | |
26357 | |
26358 if (maxDec != null && dec > maxDec) { | |
26359 dec = maxDec; | |
26360 } | |
26361 | |
26362 var magn = Math.pow(10, -dec), | |
26363 norm = delta / magn, // norm is between 1.0 and 10.0 | |
26364 size; | |
26365 | |
26366 if (norm < 1.5) { | |
26367 size = 1; | |
26368 } else if (norm < 3) { | |
26369 size = 2; | |
26370 // special case for 2.5, requires an extra decimal | |
26371 if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { | |
26372 size = 2.5; | |
26373 ++dec; | |
26374 } | |
26375 } else if (norm < 7.5) { | |
26376 size = 5; | |
26377 } else { | |
26378 size = 10; | |
26379 } | |
26380 | |
26381 size *= magn; | |
26382 | |
26383 if (opts.minTickSize != null && size < opts.minTickSize) { | |
26384 size = opts.minTickSize; | |
26385 } | |
26386 | |
26387 axis.delta = delta; | |
26388 axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); | |
26389 axis.tickSize = opts.tickSize || size; | |
26390 | |
26391 // Time mode was moved to a plug-in in 0.8, and since so many people use it | |
26392 // we'll add an especially friendly reminder to make sure they included it. | |
26393 | |
26394 if (opts.mode == "time" && !axis.tickGenerator) { | |
26395 throw new Error("Time mode requires the flot.time plugin."); | |
26396 } | |
26397 | |
26398 // Flot supports base-10 axes; any other mode else is handled by a plug-in, | |
26399 // like flot.time.js. | |
26400 | |
26401 if (!axis.tickGenerator) { | |
26402 | |
26403 axis.tickGenerator = function (axis) { | |
26404 | |
26405 var ticks = [], | |
26406 start = floorInBase(axis.min, axis.tickSize), | |
26407 i = 0, | |
26408 v = Number.NaN, | |
26409 prev; | |
26410 | |
26411 do { | |
26412 prev = v; | |
26413 v = start + i * axis.tickSize; | |
26414 ticks.push(v); | |
26415 ++i; | |
26416 } while (v < axis.max && v != prev); | |
26417 return ticks; | |
26418 }; | |
26419 | |
26420 axis.tickFormatter = function (value, axis) { | |
26421 | |
26422 var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; | |
26423 var formatted = "" + Math.round(value * factor) / factor; | |
26424 | |
26425 // If tickDecimals was specified, ensure that we have exactly that | |
26426 // much precision; otherwise default to the value's own precision. | |
26427 | |
26428 if (axis.tickDecimals != null) { | |
26429 var decimal = formatted.indexOf("."); | |
26430 var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; | |
26431 if (precision < axis.tickDecimals) { | |
26432 return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); | |
26433 } | |
26434 } | |
26435 | |
26436 return formatted; | |
26437 }; | |
26438 } | |
26439 | |
26440 if ($.isFunction(opts.tickFormatter)) | |
26441 axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; | |
26442 | |
26443 if (opts.alignTicksWithAxis != null) { | |
26444 var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; | |
26445 if (otherAxis && otherAxis.used && otherAxis != axis) { | |
26446 // consider snapping min/max to outermost nice ticks | |
26447 var niceTicks = axis.tickGenerator(axis); | |
26448 if (niceTicks.length > 0) { | |
26449 if (opts.min == null) | |
26450 axis.min = Math.min(axis.min, niceTicks[0]); | |
26451 if (opts.max == null && niceTicks.length > 1) | |
26452 axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); | |
26453 } | |
26454 | |
26455 axis.tickGenerator = function (axis) { | |
26456 // copy ticks, scaled to this axis | |
26457 var ticks = [], v, i; | |
26458 for (i = 0; i < otherAxis.ticks.length; ++i) { | |
26459 v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); | |
26460 v = axis.min + v * (axis.max - axis.min); | |
26461 ticks.push(v); | |
26462 } | |
26463 return ticks; | |
26464 }; | |
26465 | |
26466 // we might need an extra decimal since forced | |
26467 // ticks don't necessarily fit naturally | |
26468 if (!axis.mode && opts.tickDecimals == null) { | |
26469 var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), | |
26470 ts = axis.tickGenerator(axis); | |
26471 | |
26472 // only proceed if the tick interval rounded | |
26473 // with an extra decimal doesn't give us a | |
26474 // zero at end | |
26475 if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) | |
26476 axis.tickDecimals = extraDec; | |
26477 } | |
26478 } | |
26479 } | |
26480 } | |
26481 | |
26482 function setTicks(axis) { | |
26483 var oticks = axis.options.ticks, ticks = []; | |
26484 if (oticks == null || (typeof oticks == "number" && oticks > 0)) | |
26485 ticks = axis.tickGenerator(axis); | |
26486 else if (oticks) { | |
26487 if ($.isFunction(oticks)) | |
26488 // generate the ticks | |
26489 ticks = oticks(axis); | |
26490 else | |
26491 ticks = oticks; | |
26492 } | |
26493 | |
26494 // clean up/labelify the supplied ticks, copy them over | |
26495 var i, v; | |
26496 axis.ticks = []; | |
26497 for (i = 0; i < ticks.length; ++i) { | |
26498 var label = null; | |
26499 var t = ticks[i]; | |
26500 if (typeof t == "object") { | |
26501 v = +t[0]; | |
26502 if (t.length > 1) | |
26503 label = t[1]; | |
26504 } | |
26505 else | |
26506 v = +t; | |
26507 if (label == null) | |
26508 label = axis.tickFormatter(v, axis); | |
26509 if (!isNaN(v)) | |
26510 axis.ticks.push({ v: v, label: label }); | |
26511 } | |
26512 } | |
26513 | |
26514 function snapRangeToTicks(axis, ticks) { | |
26515 if (axis.options.autoscaleMargin && ticks.length > 0) { | |
26516 // snap to ticks | |
26517 if (axis.options.min == null) | |
26518 axis.min = Math.min(axis.min, ticks[0].v); | |
26519 if (axis.options.max == null && ticks.length > 1) | |
26520 axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); | |
26521 } | |
26522 } | |
26523 | |
26524 function draw() { | |
26525 | |
26526 surface.clear(); | |
26527 | |
26528 executeHooks(hooks.drawBackground, [ctx]); | |
26529 | |
26530 var grid = options.grid; | |
26531 | |
26532 // draw background, if any | |
26533 if (grid.show && grid.backgroundColor) | |
26534 drawBackground(); | |
26535 | |
26536 if (grid.show && !grid.aboveData) { | |
26537 drawGrid(); | |
26538 } | |
26539 | |
26540 for (var i = 0; i < series.length; ++i) { | |
26541 executeHooks(hooks.drawSeries, [ctx, series[i]]); | |
26542 drawSeries(series[i]); | |
26543 } | |
26544 | |
26545 executeHooks(hooks.draw, [ctx]); | |
26546 | |
26547 if (grid.show && grid.aboveData) { | |
26548 drawGrid(); | |
26549 } | |
26550 | |
26551 surface.render(); | |
26552 | |
26553 // A draw implies that either the axes or data have changed, so we | |
26554 // should probably update the overlay highlights as well. | |
26555 | |
26556 triggerRedrawOverlay(); | |
26557 } | |
26558 | |
26559 function extractRange(ranges, coord) { | |
26560 var axis, from, to, key, axes = allAxes(); | |
26561 | |
26562 for (var i = 0; i < axes.length; ++i) { | |
26563 axis = axes[i]; | |
26564 if (axis.direction == coord) { | |
26565 key = coord + axis.n + "axis"; | |
26566 if (!ranges[key] && axis.n == 1) | |
26567 key = coord + "axis"; // support x1axis as xaxis | |
26568 if (ranges[key]) { | |
26569 from = ranges[key].from; | |
26570 to = ranges[key].to; | |
26571 break; | |
26572 } | |
26573 } | |
26574 } | |
26575 | |
26576 // backwards-compat stuff - to be removed in future | |
26577 if (!ranges[key]) { | |
26578 axis = coord == "x" ? xaxes[0] : yaxes[0]; | |
26579 from = ranges[coord + "1"]; | |
26580 to = ranges[coord + "2"]; | |
26581 } | |
26582 | |
26583 // auto-reverse as an added bonus | |
26584 if (from != null && to != null && from > to) { | |
26585 var tmp = from; | |
26586 from = to; | |
26587 to = tmp; | |
26588 } | |
26589 | |
26590 return { from: from, to: to, axis: axis }; | |
26591 } | |
26592 | |
26593 function drawBackground() { | |
26594 ctx.save(); | |
26595 ctx.translate(plotOffset.left, plotOffset.top); | |
26596 | |
26597 ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); | |
26598 ctx.fillRect(0, 0, plotWidth, plotHeight); | |
26599 ctx.restore(); | |
26600 } | |
26601 | |
26602 function drawGrid() { | |
26603 var i, axes, bw, bc; | |
26604 | |
26605 ctx.save(); | |
26606 ctx.translate(plotOffset.left, plotOffset.top); | |
26607 | |
26608 // draw markings | |
26609 var markings = options.grid.markings; | |
26610 if (markings) { | |
26611 if ($.isFunction(markings)) { | |
26612 axes = plot.getAxes(); | |
26613 // xmin etc. is backwards compatibility, to be | |
26614 // removed in the future | |
26615 axes.xmin = axes.xaxis.min; | |
26616 axes.xmax = axes.xaxis.max; | |
26617 axes.ymin = axes.yaxis.min; | |
26618 axes.ymax = axes.yaxis.max; | |
26619 | |
26620 markings = markings(axes); | |
26621 } | |
26622 | |
26623 for (i = 0; i < markings.length; ++i) { | |
26624 var m = markings[i], | |
26625 xrange = extractRange(m, "x"), | |
26626 yrange = extractRange(m, "y"); | |
26627 | |
26628 // fill in missing | |
26629 if (xrange.from == null) | |
26630 xrange.from = xrange.axis.min; | |
26631 if (xrange.to == null) | |
26632 xrange.to = xrange.axis.max; | |
26633 if (yrange.from == null) | |
26634 yrange.from = yrange.axis.min; | |
26635 if (yrange.to == null) | |
26636 yrange.to = yrange.axis.max; | |
26637 | |
26638 // clip | |
26639 if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || | |
26640 yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) | |
26641 continue; | |
26642 | |
26643 xrange.from = Math.max(xrange.from, xrange.axis.min); | |
26644 xrange.to = Math.min(xrange.to, xrange.axis.max); | |
26645 yrange.from = Math.max(yrange.from, yrange.axis.min); | |
26646 yrange.to = Math.min(yrange.to, yrange.axis.max); | |
26647 | |
26648 var xequal = xrange.from === xrange.to, | |
26649 yequal = yrange.from === yrange.to; | |
26650 | |
26651 if (xequal && yequal) { | |
26652 continue; | |
26653 } | |
26654 | |
26655 // then draw | |
26656 xrange.from = Math.floor(xrange.axis.p2c(xrange.from)); | |
26657 xrange.to = Math.floor(xrange.axis.p2c(xrange.to)); | |
26658 yrange.from = Math.floor(yrange.axis.p2c(yrange.from)); | |
26659 yrange.to = Math.floor(yrange.axis.p2c(yrange.to)); | |
26660 | |
26661 if (xequal || yequal) { | |
26662 var lineWidth = m.lineWidth || options.grid.markingsLineWidth, | |
26663 subPixel = lineWidth % 2 ? 0.5 : 0; | |
26664 ctx.beginPath(); | |
26665 ctx.strokeStyle = m.color || options.grid.markingsColor; | |
26666 ctx.lineWidth = lineWidth; | |
26667 if (xequal) { | |
26668 ctx.moveTo(xrange.to + subPixel, yrange.from); | |
26669 ctx.lineTo(xrange.to + subPixel, yrange.to); | |
26670 } else { | |
26671 ctx.moveTo(xrange.from, yrange.to + subPixel); | |
26672 ctx.lineTo(xrange.to, yrange.to + subPixel); | |
26673 } | |
26674 ctx.stroke(); | |
26675 } else { | |
26676 ctx.fillStyle = m.color || options.grid.markingsColor; | |
26677 ctx.fillRect(xrange.from, yrange.to, | |
26678 xrange.to - xrange.from, | |
26679 yrange.from - yrange.to); | |
26680 } | |
26681 } | |
26682 } | |
26683 | |
26684 // draw the ticks | |
26685 axes = allAxes(); | |
26686 bw = options.grid.borderWidth; | |
26687 | |
26688 for (var j = 0; j < axes.length; ++j) { | |
26689 var axis = axes[j], box = axis.box, | |
26690 t = axis.tickLength, x, y, xoff, yoff; | |
26691 if (!axis.show || axis.ticks.length == 0) | |
26692 continue; | |
26693 | |
26694 ctx.lineWidth = 1; | |
26695 | |
26696 // find the edges | |
26697 if (axis.direction == "x") { | |
26698 x = 0; | |
26699 if (t == "full") | |
26700 y = (axis.position == "top" ? 0 : plotHeight); | |
26701 else | |
26702 y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); | |
26703 } | |
26704 else { | |
26705 y = 0; | |
26706 if (t == "full") | |
26707 x = (axis.position == "left" ? 0 : plotWidth); | |
26708 else | |
26709 x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); | |
26710 } | |
26711 | |
26712 // draw tick bar | |
26713 if (!axis.innermost) { | |
26714 ctx.strokeStyle = axis.options.color; | |
26715 ctx.beginPath(); | |
26716 xoff = yoff = 0; | |
26717 if (axis.direction == "x") | |
26718 xoff = plotWidth + 1; | |
26719 else | |
26720 yoff = plotHeight + 1; | |
26721 | |
26722 if (ctx.lineWidth == 1) { | |
26723 if (axis.direction == "x") { | |
26724 y = Math.floor(y) + 0.5; | |
26725 } else { | |
26726 x = Math.floor(x) + 0.5; | |
26727 } | |
26728 } | |
26729 | |
26730 ctx.moveTo(x, y); | |
26731 ctx.lineTo(x + xoff, y + yoff); | |
26732 ctx.stroke(); | |
26733 } | |
26734 | |
26735 // draw ticks | |
26736 | |
26737 ctx.strokeStyle = axis.options.tickColor; | |
26738 | |
26739 ctx.beginPath(); | |
26740 for (i = 0; i < axis.ticks.length; ++i) { | |
26741 var v = axis.ticks[i].v; | |
26742 | |
26743 xoff = yoff = 0; | |
26744 | |
26745 if (isNaN(v) || v < axis.min || v > axis.max | |
26746 // skip those lying on the axes if we got a border | |
26747 || (t == "full" | |
26748 && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) | |
26749 && (v == axis.min || v == axis.max))) | |
26750 continue; | |
26751 | |
26752 if (axis.direction == "x") { | |
26753 x = axis.p2c(v); | |
26754 yoff = t == "full" ? -plotHeight : t; | |
26755 | |
26756 if (axis.position == "top") | |
26757 yoff = -yoff; | |
26758 } | |
26759 else { | |
26760 y = axis.p2c(v); | |
26761 xoff = t == "full" ? -plotWidth : t; | |
26762 | |
26763 if (axis.position == "left") | |
26764 xoff = -xoff; | |
26765 } | |
26766 | |
26767 if (ctx.lineWidth == 1) { | |
26768 if (axis.direction == "x") | |
26769 x = Math.floor(x) + 0.5; | |
26770 else | |
26771 y = Math.floor(y) + 0.5; | |
26772 } | |
26773 | |
26774 ctx.moveTo(x, y); | |
26775 ctx.lineTo(x + xoff, y + yoff); | |
26776 } | |
26777 | |
26778 ctx.stroke(); | |
26779 } | |
26780 | |
26781 | |
26782 // draw border | |
26783 if (bw) { | |
26784 // If either borderWidth or borderColor is an object, then draw the border | |
26785 // line by line instead of as one rectangle | |
26786 bc = options.grid.borderColor; | |
26787 if(typeof bw == "object" || typeof bc == "object") { | |
26788 if (typeof bw !== "object") { | |
26789 bw = {top: bw, right: bw, bottom: bw, left: bw}; | |
26790 } | |
26791 if (typeof bc !== "object") { | |
26792 bc = {top: bc, right: bc, bottom: bc, left: bc}; | |
26793 } | |
26794 | |
26795 if (bw.top > 0) { | |
26796 ctx.strokeStyle = bc.top; | |
26797 ctx.lineWidth = bw.top; | |
26798 ctx.beginPath(); | |
26799 ctx.moveTo(0 - bw.left, 0 - bw.top/2); | |
26800 ctx.lineTo(plotWidth, 0 - bw.top/2); | |
26801 ctx.stroke(); | |
26802 } | |
26803 | |
26804 if (bw.right > 0) { | |
26805 ctx.strokeStyle = bc.right; | |
26806 ctx.lineWidth = bw.right; | |
26807 ctx.beginPath(); | |
26808 ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); | |
26809 ctx.lineTo(plotWidth + bw.right / 2, plotHeight); | |
26810 ctx.stroke(); | |
26811 } | |
26812 | |
26813 if (bw.bottom > 0) { | |
26814 ctx.strokeStyle = bc.bottom; | |
26815 ctx.lineWidth = bw.bottom; | |
26816 ctx.beginPath(); | |
26817 ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); | |
26818 ctx.lineTo(0, plotHeight + bw.bottom / 2); | |
26819 ctx.stroke(); | |
26820 } | |
26821 | |
26822 if (bw.left > 0) { | |
26823 ctx.strokeStyle = bc.left; | |
26824 ctx.lineWidth = bw.left; | |
26825 ctx.beginPath(); | |
26826 ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); | |
26827 ctx.lineTo(0- bw.left/2, 0); | |
26828 ctx.stroke(); | |
26829 } | |
26830 } | |
26831 else { | |
26832 ctx.lineWidth = bw; | |
26833 ctx.strokeStyle = options.grid.borderColor; | |
26834 ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); | |
26835 } | |
26836 } | |
26837 | |
26838 ctx.restore(); | |
26839 } | |
26840 | |
26841 function drawAxisLabels() { | |
26842 | |
26843 $.each(allAxes(), function (_, axis) { | |
26844 var box = axis.box, | |
26845 legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", | |
26846 layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, | |
26847 font = axis.options.font || "flot-tick-label tickLabel", | |
26848 tick, x, y, halign, valign; | |
26849 | |
26850 // Remove text before checking for axis.show and ticks.length; | |
26851 // otherwise plugins, like flot-tickrotor, that draw their own | |
26852 // tick labels will end up with both theirs and the defaults. | |
26853 | |
26854 surface.removeText(layer); | |
26855 | |
26856 if (!axis.show || axis.ticks.length == 0) | |
26857 return; | |
26858 | |
26859 for (var i = 0; i < axis.ticks.length; ++i) { | |
26860 | |
26861 tick = axis.ticks[i]; | |
26862 if (!tick.label || tick.v < axis.min || tick.v > axis.max) | |
26863 continue; | |
26864 | |
26865 if (axis.direction == "x") { | |
26866 halign = "center"; | |
26867 x = plotOffset.left + axis.p2c(tick.v); | |
26868 if (axis.position == "bottom") { | |
26869 y = box.top + box.padding; | |
26870 } else { | |
26871 y = box.top + box.height - box.padding; | |
26872 valign = "bottom"; | |
26873 } | |
26874 } else { | |
26875 valign = "middle"; | |
26876 y = plotOffset.top + axis.p2c(tick.v); | |
26877 if (axis.position == "left") { | |
26878 x = box.left + box.width - box.padding; | |
26879 halign = "right"; | |
26880 } else { | |
26881 x = box.left + box.padding; | |
26882 } | |
26883 } | |
26884 | |
26885 surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); | |
26886 } | |
26887 }); | |
26888 } | |
26889 | |
26890 function drawSeries(series) { | |
26891 if (series.lines.show) | |
26892 drawSeriesLines(series); | |
26893 if (series.bars.show) | |
26894 drawSeriesBars(series); | |
26895 if (series.points.show) | |
26896 drawSeriesPoints(series); | |
26897 } | |
26898 | |
26899 function drawSeriesLines(series) { | |
26900 function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { | |
26901 var points = datapoints.points, | |
26902 ps = datapoints.pointsize, | |
26903 prevx = null, prevy = null; | |
26904 | |
26905 ctx.beginPath(); | |
26906 for (var i = ps; i < points.length; i += ps) { | |
26907 var x1 = points[i - ps], y1 = points[i - ps + 1], | |
26908 x2 = points[i], y2 = points[i + 1]; | |
26909 | |
26910 if (x1 == null || x2 == null) | |
26911 continue; | |
26912 | |
26913 // clip with ymin | |
26914 if (y1 <= y2 && y1 < axisy.min) { | |
26915 if (y2 < axisy.min) | |
26916 continue; // line segment is outside | |
26917 // compute new intersection point | |
26918 x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26919 y1 = axisy.min; | |
26920 } | |
26921 else if (y2 <= y1 && y2 < axisy.min) { | |
26922 if (y1 < axisy.min) | |
26923 continue; | |
26924 x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26925 y2 = axisy.min; | |
26926 } | |
26927 | |
26928 // clip with ymax | |
26929 if (y1 >= y2 && y1 > axisy.max) { | |
26930 if (y2 > axisy.max) | |
26931 continue; | |
26932 x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26933 y1 = axisy.max; | |
26934 } | |
26935 else if (y2 >= y1 && y2 > axisy.max) { | |
26936 if (y1 > axisy.max) | |
26937 continue; | |
26938 x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26939 y2 = axisy.max; | |
26940 } | |
26941 | |
26942 // clip with xmin | |
26943 if (x1 <= x2 && x1 < axisx.min) { | |
26944 if (x2 < axisx.min) | |
26945 continue; | |
26946 y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26947 x1 = axisx.min; | |
26948 } | |
26949 else if (x2 <= x1 && x2 < axisx.min) { | |
26950 if (x1 < axisx.min) | |
26951 continue; | |
26952 y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26953 x2 = axisx.min; | |
26954 } | |
26955 | |
26956 // clip with xmax | |
26957 if (x1 >= x2 && x1 > axisx.max) { | |
26958 if (x2 > axisx.max) | |
26959 continue; | |
26960 y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26961 x1 = axisx.max; | |
26962 } | |
26963 else if (x2 >= x1 && x2 > axisx.max) { | |
26964 if (x1 > axisx.max) | |
26965 continue; | |
26966 y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26967 x2 = axisx.max; | |
26968 } | |
26969 | |
26970 if (x1 != prevx || y1 != prevy) | |
26971 ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); | |
26972 | |
26973 prevx = x2; | |
26974 prevy = y2; | |
26975 ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); | |
26976 } | |
26977 ctx.stroke(); | |
26978 } | |
26979 | |
26980 function plotLineArea(datapoints, axisx, axisy) { | |
26981 var points = datapoints.points, | |
26982 ps = datapoints.pointsize, | |
26983 bottom = Math.min(Math.max(0, axisy.min), axisy.max), | |
26984 i = 0, top, areaOpen = false, | |
26985 ypos = 1, segmentStart = 0, segmentEnd = 0; | |
26986 | |
26987 // we process each segment in two turns, first forward | |
26988 // direction to sketch out top, then once we hit the | |
26989 // end we go backwards to sketch the bottom | |
26990 while (true) { | |
26991 if (ps > 0 && i > points.length + ps) | |
26992 break; | |
26993 | |
26994 i += ps; // ps is negative if going backwards | |
26995 | |
26996 var x1 = points[i - ps], | |
26997 y1 = points[i - ps + ypos], | |
26998 x2 = points[i], y2 = points[i + ypos]; | |
26999 | |
27000 if (areaOpen) { | |
27001 if (ps > 0 && x1 != null && x2 == null) { | |
27002 // at turning point | |
27003 segmentEnd = i; | |
27004 ps = -ps; | |
27005 ypos = 2; | |
27006 continue; | |
27007 } | |
27008 | |
27009 if (ps < 0 && i == segmentStart + ps) { | |
27010 // done with the reverse sweep | |
27011 ctx.fill(); | |
27012 areaOpen = false; | |
27013 ps = -ps; | |
27014 ypos = 1; | |
27015 i = segmentStart = segmentEnd + ps; | |
27016 continue; | |
27017 } | |
27018 } | |
27019 | |
27020 if (x1 == null || x2 == null) | |
27021 continue; | |
27022 | |
27023 // clip x values | |
27024 | |
27025 // clip with xmin | |
27026 if (x1 <= x2 && x1 < axisx.min) { | |
27027 if (x2 < axisx.min) | |
27028 continue; | |
27029 y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
27030 x1 = axisx.min; | |
27031 } | |
27032 else if (x2 <= x1 && x2 < axisx.min) { | |
27033 if (x1 < axisx.min) | |
27034 continue; | |
27035 y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
27036 x2 = axisx.min; | |
27037 } | |
27038 | |
27039 // clip with xmax | |
27040 if (x1 >= x2 && x1 > axisx.max) { | |
27041 if (x2 > axisx.max) | |
27042 continue; | |
27043 y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
27044 x1 = axisx.max; | |
27045 } | |
27046 else if (x2 >= x1 && x2 > axisx.max) { | |
27047 if (x1 > axisx.max) | |
27048 continue; | |
27049 y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
27050 x2 = axisx.max; | |
27051 } | |
27052 | |
27053 if (!areaOpen) { | |
27054 // open area | |
27055 ctx.beginPath(); | |
27056 ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); | |
27057 areaOpen = true; | |
27058 } | |
27059 | |
27060 // now first check the case where both is outside | |
27061 if (y1 >= axisy.max && y2 >= axisy.max) { | |
27062 ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); | |
27063 ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); | |
27064 continue; | |
27065 } | |
27066 else if (y1 <= axisy.min && y2 <= axisy.min) { | |
27067 ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); | |
27068 ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); | |
27069 continue; | |
27070 } | |
27071 | |
27072 // else it's a bit more complicated, there might | |
27073 // be a flat maxed out rectangle first, then a | |
27074 // triangular cutout or reverse; to find these | |
27075 // keep track of the current x values | |
27076 var x1old = x1, x2old = x2; | |
27077 | |
27078 // clip the y values, without shortcutting, we | |
27079 // go through all cases in turn | |
27080 | |
27081 // clip with ymin | |
27082 if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { | |
27083 x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27084 y1 = axisy.min; | |
27085 } | |
27086 else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { | |
27087 x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27088 y2 = axisy.min; | |
27089 } | |
27090 | |
27091 // clip with ymax | |
27092 if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { | |
27093 x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27094 y1 = axisy.max; | |
27095 } | |
27096 else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { | |
27097 x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27098 y2 = axisy.max; | |
27099 } | |
27100 | |
27101 // if the x value was changed we got a rectangle | |
27102 // to fill | |
27103 if (x1 != x1old) { | |
27104 ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); | |
27105 // it goes to (x1, y1), but we fill that below | |
27106 } | |
27107 | |
27108 // fill triangular section, this sometimes result | |
27109 // in redundant points if (x1, y1) hasn't changed | |
27110 // from previous line to, but we just ignore that | |
27111 ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); | |
27112 ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); | |
27113 | |
27114 // fill the other rectangle if it's there | |
27115 if (x2 != x2old) { | |
27116 ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); | |
27117 ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); | |
27118 } | |
27119 } | |
27120 } | |
27121 | |
27122 ctx.save(); | |
27123 ctx.translate(plotOffset.left, plotOffset.top); | |
27124 ctx.lineJoin = "round"; | |
27125 | |
27126 var lw = series.lines.lineWidth, | |
27127 sw = series.shadowSize; | |
27128 // FIXME: consider another form of shadow when filling is turned on | |
27129 if (lw > 0 && sw > 0) { | |
27130 // draw shadow as a thick and thin line with transparency | |
27131 ctx.lineWidth = sw; | |
27132 ctx.strokeStyle = "rgba(0,0,0,0.1)"; | |
27133 // position shadow at angle from the mid of line | |
27134 var angle = Math.PI/18; | |
27135 plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); | |
27136 ctx.lineWidth = sw/2; | |
27137 plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); | |
27138 } | |
27139 | |
27140 ctx.lineWidth = lw; | |
27141 ctx.strokeStyle = series.color; | |
27142 var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); | |
27143 if (fillStyle) { | |
27144 ctx.fillStyle = fillStyle; | |
27145 plotLineArea(series.datapoints, series.xaxis, series.yaxis); | |
27146 } | |
27147 | |
27148 if (lw > 0) | |
27149 plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); | |
27150 ctx.restore(); | |
27151 } | |
27152 | |
27153 function drawSeriesPoints(series) { | |
27154 function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { | |
27155 var points = datapoints.points, ps = datapoints.pointsize; | |
27156 | |
27157 for (var i = 0; i < points.length; i += ps) { | |
27158 var x = points[i], y = points[i + 1]; | |
27159 if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) | |
27160 continue; | |
27161 | |
27162 ctx.beginPath(); | |
27163 x = axisx.p2c(x); | |
27164 y = axisy.p2c(y) + offset; | |
27165 if (symbol == "circle") | |
27166 ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); | |
27167 else | |
27168 symbol(ctx, x, y, radius, shadow); | |
27169 ctx.closePath(); | |
27170 | |
27171 if (fillStyle) { | |
27172 ctx.fillStyle = fillStyle; | |
27173 ctx.fill(); | |
27174 } | |
27175 ctx.stroke(); | |
27176 } | |
27177 } | |
27178 | |
27179 ctx.save(); | |
27180 ctx.translate(plotOffset.left, plotOffset.top); | |
27181 | |
27182 var lw = series.points.lineWidth, | |
27183 sw = series.shadowSize, | |
27184 radius = series.points.radius, | |
27185 symbol = series.points.symbol; | |
27186 | |
27187 // If the user sets the line width to 0, we change it to a very | |
27188 // small value. A line width of 0 seems to force the default of 1. | |
27189 // Doing the conditional here allows the shadow setting to still be | |
27190 // optional even with a lineWidth of 0. | |
27191 | |
27192 if( lw == 0 ) | |
27193 lw = 0.0001; | |
27194 | |
27195 if (lw > 0 && sw > 0) { | |
27196 // draw shadow in two steps | |
27197 var w = sw / 2; | |
27198 ctx.lineWidth = w; | |
27199 ctx.strokeStyle = "rgba(0,0,0,0.1)"; | |
27200 plotPoints(series.datapoints, radius, null, w + w/2, true, | |
27201 series.xaxis, series.yaxis, symbol); | |
27202 | |
27203 ctx.strokeStyle = "rgba(0,0,0,0.2)"; | |
27204 plotPoints(series.datapoints, radius, null, w/2, true, | |
27205 series.xaxis, series.yaxis, symbol); | |
27206 } | |
27207 | |
27208 ctx.lineWidth = lw; | |
27209 ctx.strokeStyle = series.color; | |
27210 plotPoints(series.datapoints, radius, | |
27211 getFillStyle(series.points, series.color), 0, false, | |
27212 series.xaxis, series.yaxis, symbol); | |
27213 ctx.restore(); | |
27214 } | |
27215 | |
27216 function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { | |
27217 var left, right, bottom, top, | |
27218 drawLeft, drawRight, drawTop, drawBottom, | |
27219 tmp; | |
27220 | |
27221 // in horizontal mode, we start the bar from the left | |
27222 // instead of from the bottom so it appears to be | |
27223 // horizontal rather than vertical | |
27224 if (horizontal) { | |
27225 drawBottom = drawRight = drawTop = true; | |
27226 drawLeft = false; | |
27227 left = b; | |
27228 right = x; | |
27229 top = y + barLeft; | |
27230 bottom = y + barRight; | |
27231 | |
27232 // account for negative bars | |
27233 if (right < left) { | |
27234 tmp = right; | |
27235 right = left; | |
27236 left = tmp; | |
27237 drawLeft = true; | |
27238 drawRight = false; | |
27239 } | |
27240 } | |
27241 else { | |
27242 drawLeft = drawRight = drawTop = true; | |
27243 drawBottom = false; | |
27244 left = x + barLeft; | |
27245 right = x + barRight; | |
27246 bottom = b; | |
27247 top = y; | |
27248 | |
27249 // account for negative bars | |
27250 if (top < bottom) { | |
27251 tmp = top; | |
27252 top = bottom; | |
27253 bottom = tmp; | |
27254 drawBottom = true; | |
27255 drawTop = false; | |
27256 } | |
27257 } | |
27258 | |
27259 // clip | |
27260 if (right < axisx.min || left > axisx.max || | |
27261 top < axisy.min || bottom > axisy.max) | |
27262 return; | |
27263 | |
27264 if (left < axisx.min) { | |
27265 left = axisx.min; | |
27266 drawLeft = false; | |
27267 } | |
27268 | |
27269 if (right > axisx.max) { | |
27270 right = axisx.max; | |
27271 drawRight = false; | |
27272 } | |
27273 | |
27274 if (bottom < axisy.min) { | |
27275 bottom = axisy.min; | |
27276 drawBottom = false; | |
27277 } | |
27278 | |
27279 if (top > axisy.max) { | |
27280 top = axisy.max; | |
27281 drawTop = false; | |
27282 } | |
27283 | |
27284 left = axisx.p2c(left); | |
27285 bottom = axisy.p2c(bottom); | |
27286 right = axisx.p2c(right); | |
27287 top = axisy.p2c(top); | |
27288 | |
27289 // fill the bar | |
27290 if (fillStyleCallback) { | |
27291 c.fillStyle = fillStyleCallback(bottom, top); | |
27292 c.fillRect(left, top, right - left, bottom - top) | |
27293 } | |
27294 | |
27295 // draw outline | |
27296 if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { | |
27297 c.beginPath(); | |
27298 | |
27299 // FIXME: inline moveTo is buggy with excanvas | |
27300 c.moveTo(left, bottom); | |
27301 if (drawLeft) | |
27302 c.lineTo(left, top); | |
27303 else | |
27304 c.moveTo(left, top); | |
27305 if (drawTop) | |
27306 c.lineTo(right, top); | |
27307 else | |
27308 c.moveTo(right, top); | |
27309 if (drawRight) | |
27310 c.lineTo(right, bottom); | |
27311 else | |
27312 c.moveTo(right, bottom); | |
27313 if (drawBottom) | |
27314 c.lineTo(left, bottom); | |
27315 else | |
27316 c.moveTo(left, bottom); | |
27317 c.stroke(); | |
27318 } | |
27319 } | |
27320 | |
27321 function drawSeriesBars(series) { | |
27322 function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { | |
27323 var points = datapoints.points, ps = datapoints.pointsize; | |
27324 | |
27325 for (var i = 0; i < points.length; i += ps) { | |
27326 if (points[i] == null) | |
27327 continue; | |
27328 drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); | |
27329 } | |
27330 } | |
27331 | |
27332 ctx.save(); | |
27333 ctx.translate(plotOffset.left, plotOffset.top); | |
27334 | |
27335 // FIXME: figure out a way to add shadows (for instance along the right edge) | |
27336 ctx.lineWidth = series.bars.lineWidth; | |
27337 ctx.strokeStyle = series.color; | |
27338 | |
27339 var barLeft; | |
27340 | |
27341 switch (series.bars.align) { | |
27342 case "left": | |
27343 barLeft = 0; | |
27344 break; | |
27345 case "right": | |
27346 barLeft = -series.bars.barWidth; | |
27347 break; | |
27348 default: | |
27349 barLeft = -series.bars.barWidth / 2; | |
27350 } | |
27351 | |
27352 var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; | |
27353 plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); | |
27354 ctx.restore(); | |
27355 } | |
27356 | |
27357 function getFillStyle(filloptions, seriesColor, bottom, top) { | |
27358 var fill = filloptions.fill; | |
27359 if (!fill) | |
27360 return null; | |
27361 | |
27362 if (filloptions.fillColor) | |
27363 return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); | |
27364 | |
27365 var c = $.color.parse(seriesColor); | |
27366 c.a = typeof fill == "number" ? fill : 0.4; | |
27367 c.normalize(); | |
27368 return c.toString(); | |
27369 } | |
27370 | |
27371 function insertLegend() { | |
27372 | |
27373 if (options.legend.container != null) { | |
27374 $(options.legend.container).html(""); | |
27375 } else { | |
27376 placeholder.find(".legend").remove(); | |
27377 } | |
27378 | |
27379 if (!options.legend.show) { | |
27380 return; | |
27381 } | |
27382 | |
27383 var fragments = [], entries = [], rowStarted = false, | |
27384 lf = options.legend.labelFormatter, s, label; | |
27385 | |
27386 // Build a list of legend entries, with each having a label and a color | |
27387 | |
27388 for (var i = 0; i < series.length; ++i) { | |
27389 s = series[i]; | |
27390 if (s.label) { | |
27391 label = lf ? lf(s.label, s) : s.label; | |
27392 if (label) { | |
27393 entries.push({ | |
27394 label: label, | |
27395 color: s.color | |
27396 }); | |
27397 } | |
27398 } | |
27399 } | |
27400 | |
27401 // Sort the legend using either the default or a custom comparator | |
27402 | |
27403 if (options.legend.sorted) { | |
27404 if ($.isFunction(options.legend.sorted)) { | |
27405 entries.sort(options.legend.sorted); | |
27406 } else if (options.legend.sorted == "reverse") { | |
27407 entries.reverse(); | |
27408 } else { | |
27409 var ascending = options.legend.sorted != "descending"; | |
27410 entries.sort(function(a, b) { | |
27411 return a.label == b.label ? 0 : ( | |
27412 (a.label < b.label) != ascending ? 1 : -1 // Logical XOR | |
27413 ); | |
27414 }); | |
27415 } | |
27416 } | |
27417 | |
27418 // Generate markup for the list of entries, in their final order | |
27419 | |
27420 for (var i = 0; i < entries.length; ++i) { | |
27421 | |
27422 var entry = entries[i]; | |
27423 | |
27424 if (i % options.legend.noColumns == 0) { | |
27425 if (rowStarted) | |
27426 fragments.push('</tr>'); | |
27427 fragments.push('<tr>'); | |
27428 rowStarted = true; | |
27429 } | |
27430 | |
27431 fragments.push( | |
27432 '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' + | |
27433 '<td class="legendLabel">' + entry.label + '</td>' | |
27434 ); | |
27435 } | |
27436 | |
27437 if (rowStarted) | |
27438 fragments.push('</tr>'); | |
27439 | |
27440 if (fragments.length == 0) | |
27441 return; | |
27442 | |
27443 var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>'; | |
27444 if (options.legend.container != null) | |
27445 $(options.legend.container).html(table); | |
27446 else { | |
27447 var pos = "", | |
27448 p = options.legend.position, | |
27449 m = options.legend.margin; | |
27450 if (m[0] == null) | |
27451 m = [m, m]; | |
27452 if (p.charAt(0) == "n") | |
27453 pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; | |
27454 else if (p.charAt(0) == "s") | |
27455 pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; | |
27456 if (p.charAt(1) == "e") | |
27457 pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; | |
27458 else if (p.charAt(1) == "w") | |
27459 pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; | |
27460 var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder); | |
27461 if (options.legend.backgroundOpacity != 0.0) { | |
27462 // put in the transparent background | |
27463 // separately to avoid blended labels and | |
27464 // label boxes | |
27465 var c = options.legend.backgroundColor; | |
27466 if (c == null) { | |
27467 c = options.grid.backgroundColor; | |
27468 if (c && typeof c == "string") | |
27469 c = $.color.parse(c); | |
27470 else | |
27471 c = $.color.extract(legend, 'background-color'); | |
27472 c.a = 1; | |
27473 c = c.toString(); | |
27474 } | |
27475 var div = legend.children(); | |
27476 $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity); | |
27477 } | |
27478 } | |
27479 } | |
27480 | |
27481 | |
27482 // interactive features | |
27483 | |
27484 var highlights = [], | |
27485 redrawTimeout = null; | |
27486 | |
27487 // returns the data item the mouse is over, or null if none is found | |
27488 function findNearbyItem(mouseX, mouseY, seriesFilter) { | |
27489 var maxDistance = options.grid.mouseActiveRadius, | |
27490 smallestDistance = maxDistance * maxDistance + 1, | |
27491 item = null, foundPoint = false, i, j, ps; | |
27492 | |
27493 for (i = series.length - 1; i >= 0; --i) { | |
27494 if (!seriesFilter(series[i])) | |
27495 continue; | |
27496 | |
27497 var s = series[i], | |
27498 axisx = s.xaxis, | |
27499 axisy = s.yaxis, | |
27500 points = s.datapoints.points, | |
27501 mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster | |
27502 my = axisy.c2p(mouseY), | |
27503 maxx = maxDistance / axisx.scale, | |
27504 maxy = maxDistance / axisy.scale; | |
27505 | |
27506 ps = s.datapoints.pointsize; | |
27507 // with inverse transforms, we can't use the maxx/maxy | |
27508 // optimization, sadly | |
27509 if (axisx.options.inverseTransform) | |
27510 maxx = Number.MAX_VALUE; | |
27511 if (axisy.options.inverseTransform) | |
27512 maxy = Number.MAX_VALUE; | |
27513 | |
27514 if (s.lines.show || s.points.show) { | |
27515 for (j = 0; j < points.length; j += ps) { | |
27516 var x = points[j], y = points[j + 1]; | |
27517 if (x == null) | |
27518 continue; | |
27519 | |
27520 // For points and lines, the cursor must be within a | |
27521 // certain distance to the data point | |
27522 if (x - mx > maxx || x - mx < -maxx || | |
27523 y - my > maxy || y - my < -maxy) | |
27524 continue; | |
27525 | |
27526 // We have to calculate distances in pixels, not in | |
27527 // data units, because the scales of the axes may be different | |
27528 var dx = Math.abs(axisx.p2c(x) - mouseX), | |
27529 dy = Math.abs(axisy.p2c(y) - mouseY), | |
27530 dist = dx * dx + dy * dy; // we save the sqrt | |
27531 | |
27532 // use <= to ensure last point takes precedence | |
27533 // (last generally means on top of) | |
27534 if (dist < smallestDistance) { | |
27535 smallestDistance = dist; | |
27536 item = [i, j / ps]; | |
27537 } | |
27538 } | |
27539 } | |
27540 | |
27541 if (s.bars.show && !item) { // no other point can be nearby | |
27542 | |
27543 var barLeft, barRight; | |
27544 | |
27545 switch (s.bars.align) { | |
27546 case "left": | |
27547 barLeft = 0; | |
27548 break; | |
27549 case "right": | |
27550 barLeft = -s.bars.barWidth; | |
27551 break; | |
27552 default: | |
27553 barLeft = -s.bars.barWidth / 2; | |
27554 } | |
27555 | |
27556 barRight = barLeft + s.bars.barWidth; | |
27557 | |
27558 for (j = 0; j < points.length; j += ps) { | |
27559 var x = points[j], y = points[j + 1], b = points[j + 2]; | |
27560 if (x == null) | |
27561 continue; | |
27562 | |
27563 // for a bar graph, the cursor must be inside the bar | |
27564 if (series[i].bars.horizontal ? | |
27565 (mx <= Math.max(b, x) && mx >= Math.min(b, x) && | |
27566 my >= y + barLeft && my <= y + barRight) : | |
27567 (mx >= x + barLeft && mx <= x + barRight && | |
27568 my >= Math.min(b, y) && my <= Math.max(b, y))) | |
27569 item = [i, j / ps]; | |
27570 } | |
27571 } | |
27572 } | |
27573 | |
27574 if (item) { | |
27575 i = item[0]; | |
27576 j = item[1]; | |
27577 ps = series[i].datapoints.pointsize; | |
27578 | |
27579 return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), | |
27580 dataIndex: j, | |
27581 series: series[i], | |
27582 seriesIndex: i }; | |
27583 } | |
27584 | |
27585 return null; | |
27586 } | |
27587 | |
27588 function onMouseMove(e) { | |
27589 if (options.grid.hoverable) | |
27590 triggerClickHoverEvent("plothover", e, | |
27591 function (s) { return s["hoverable"] != false; }); | |
27592 } | |
27593 | |
27594 function onMouseLeave(e) { | |
27595 if (options.grid.hoverable) | |
27596 triggerClickHoverEvent("plothover", e, | |
27597 function (s) { return false; }); | |
27598 } | |
27599 | |
27600 function onClick(e) { | |
27601 triggerClickHoverEvent("plotclick", e, | |
27602 function (s) { return s["clickable"] != false; }); | |
27603 } | |
27604 | |
27605 // trigger click or hover event (they send the same parameters | |
27606 // so we share their code) | |
27607 function triggerClickHoverEvent(eventname, event, seriesFilter) { | |
27608 var offset = eventHolder.offset(), | |
27609 canvasX = event.pageX - offset.left - plotOffset.left, | |
27610 canvasY = event.pageY - offset.top - plotOffset.top, | |
27611 pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); | |
27612 | |
27613 pos.pageX = event.pageX; | |
27614 pos.pageY = event.pageY; | |
27615 | |
27616 var item = findNearbyItem(canvasX, canvasY, seriesFilter); | |
27617 | |
27618 if (item) { | |
27619 // fill in mouse pos for any listeners out there | |
27620 item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); | |
27621 item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); | |
27622 } | |
27623 | |
27624 if (options.grid.autoHighlight) { | |
27625 // clear auto-highlights | |
27626 for (var i = 0; i < highlights.length; ++i) { | |
27627 var h = highlights[i]; | |
27628 if (h.auto == eventname && | |
27629 !(item && h.series == item.series && | |
27630 h.point[0] == item.datapoint[0] && | |
27631 h.point[1] == item.datapoint[1])) | |
27632 unhighlight(h.series, h.point); | |
27633 } | |
27634 | |
27635 if (item) | |
27636 highlight(item.series, item.datapoint, eventname); | |
27637 } | |
27638 | |
27639 placeholder.trigger(eventname, [ pos, item ]); | |
27640 } | |
27641 | |
27642 function triggerRedrawOverlay() { | |
27643 var t = options.interaction.redrawOverlayInterval; | |
27644 if (t == -1) { // skip event queue | |
27645 drawOverlay(); | |
27646 return; | |
27647 } | |
27648 | |
27649 if (!redrawTimeout) | |
27650 redrawTimeout = setTimeout(drawOverlay, t); | |
27651 } | |
27652 | |
27653 function drawOverlay() { | |
27654 redrawTimeout = null; | |
27655 | |
27656 // draw highlights | |
27657 octx.save(); | |
27658 overlay.clear(); | |
27659 octx.translate(plotOffset.left, plotOffset.top); | |
27660 | |
27661 var i, hi; | |
27662 for (i = 0; i < highlights.length; ++i) { | |
27663 hi = highlights[i]; | |
27664 | |
27665 if (hi.series.bars.show) | |
27666 drawBarHighlight(hi.series, hi.point); | |
27667 else | |
27668 drawPointHighlight(hi.series, hi.point); | |
27669 } | |
27670 octx.restore(); | |
27671 | |
27672 executeHooks(hooks.drawOverlay, [octx]); | |
27673 } | |
27674 | |
27675 function highlight(s, point, auto) { | |
27676 if (typeof s == "number") | |
27677 s = series[s]; | |
27678 | |
27679 if (typeof point == "number") { | |
27680 var ps = s.datapoints.pointsize; | |
27681 point = s.datapoints.points.slice(ps * point, ps * (point + 1)); | |
27682 } | |
27683 | |
27684 var i = indexOfHighlight(s, point); | |
27685 if (i == -1) { | |
27686 highlights.push({ series: s, point: point, auto: auto }); | |
27687 | |
27688 triggerRedrawOverlay(); | |
27689 } | |
27690 else if (!auto) | |
27691 highlights[i].auto = false; | |
27692 } | |
27693 | |
27694 function unhighlight(s, point) { | |
27695 if (s == null && point == null) { | |
27696 highlights = []; | |
27697 triggerRedrawOverlay(); | |
27698 return; | |
27699 } | |
27700 | |
27701 if (typeof s == "number") | |
27702 s = series[s]; | |
27703 | |
27704 if (typeof point == "number") { | |
27705 var ps = s.datapoints.pointsize; | |
27706 point = s.datapoints.points.slice(ps * point, ps * (point + 1)); | |
27707 } | |
27708 | |
27709 var i = indexOfHighlight(s, point); | |
27710 if (i != -1) { | |
27711 highlights.splice(i, 1); | |
27712 | |
27713 triggerRedrawOverlay(); | |
27714 } | |
27715 } | |
27716 | |
27717 function indexOfHighlight(s, p) { | |
27718 for (var i = 0; i < highlights.length; ++i) { | |
27719 var h = highlights[i]; | |
27720 if (h.series == s && h.point[0] == p[0] | |
27721 && h.point[1] == p[1]) | |
27722 return i; | |
27723 } | |
27724 return -1; | |
27725 } | |
27726 | |
27727 function drawPointHighlight(series, point) { | |
27728 var x = point[0], y = point[1], | |
27729 axisx = series.xaxis, axisy = series.yaxis, | |
27730 highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); | |
27731 | |
27732 if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) | |
27733 return; | |
27734 | |
27735 var pointRadius = series.points.radius + series.points.lineWidth / 2; | |
27736 octx.lineWidth = pointRadius; | |
27737 octx.strokeStyle = highlightColor; | |
27738 var radius = 1.5 * pointRadius; | |
27739 x = axisx.p2c(x); | |
27740 y = axisy.p2c(y); | |
27741 | |
27742 octx.beginPath(); | |
27743 if (series.points.symbol == "circle") | |
27744 octx.arc(x, y, radius, 0, 2 * Math.PI, false); | |
27745 else | |
27746 series.points.symbol(octx, x, y, radius, false); | |
27747 octx.closePath(); | |
27748 octx.stroke(); | |
27749 } | |
27750 | |
27751 function drawBarHighlight(series, point) { | |
27752 var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), | |
27753 fillStyle = highlightColor, | |
27754 barLeft; | |
27755 | |
27756 switch (series.bars.align) { | |
27757 case "left": | |
27758 barLeft = 0; | |
27759 break; | |
27760 case "right": | |
27761 barLeft = -series.bars.barWidth; | |
27762 break; | |
27763 default: | |
27764 barLeft = -series.bars.barWidth / 2; | |
27765 } | |
27766 | |
27767 octx.lineWidth = series.bars.lineWidth; | |
27768 octx.strokeStyle = highlightColor; | |
27769 | |
27770 drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, | |
27771 function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); | |
27772 } | |
27773 | |
27774 function getColorOrGradient(spec, bottom, top, defaultColor) { | |
27775 if (typeof spec == "string") | |
27776 return spec; | |
27777 else { | |
27778 // assume this is a gradient spec; IE currently only | |
27779 // supports a simple vertical gradient properly, so that's | |
27780 // what we support too | |
27781 var gradient = ctx.createLinearGradient(0, top, 0, bottom); | |
27782 | |
27783 for (var i = 0, l = spec.colors.length; i < l; ++i) { | |
27784 var c = spec.colors[i]; | |
27785 if (typeof c != "string") { | |
27786 var co = $.color.parse(defaultColor); | |
27787 if (c.brightness != null) | |
27788 co = co.scale('rgb', c.brightness); | |
27789 if (c.opacity != null) | |
27790 co.a *= c.opacity; | |
27791 c = co.toString(); | |
27792 } | |
27793 gradient.addColorStop(i / (l - 1), c); | |
27794 } | |
27795 | |
27796 return gradient; | |
27797 } | |
27798 } | |
27799 } | |
27800 | |
27801 // Add the plot function to the top level of the jQuery object | |
27802 | |
27803 $.plot = function(placeholder, data, options) { | |
27804 //var t0 = new Date(); | |
27805 var plot = new Plot($(placeholder), data, options, $.plot.plugins); | |
27806 //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); | |
27807 return plot; | |
27808 }; | |
27809 | |
27810 $.plot.version = "0.8.3-alpha"; | |
27811 | |
27812 $.plot.plugins = []; | |
27813 | |
27814 // Also add the plot function as a chainable property | |
27815 | |
27816 $.fn.plot = function(data, options) { | |
27817 return this.each(function() { | |
27818 $.plot(this, data, options); | |
27819 }); | |
27820 }; | |
27821 | |
27822 // round to nearby lower multiple of base | |
27823 function floorInBase(n, base) { | |
27824 return base * Math.floor(n / base); | |
27825 } | |
27826 | |
27827 })(jQuery); | |
27828 /* Flot plugin for rendering pie charts. | |
27829 | |
27830 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
27831 Licensed under the MIT license. | |
27832 | |
27833 The plugin assumes that each series has a single data value, and that each | |
27834 value is a positive integer or zero. Negative numbers don't make sense for a | |
27835 pie chart, and have unpredictable results. The values do NOT need to be | |
27836 passed in as percentages; the plugin will calculate the total and per-slice | |
27837 percentages internally. | |
27838 | |
27839 * Created by Brian Medendorp | |
27840 | |
27841 * Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars | |
27842 | |
27843 The plugin supports these options: | |
27844 | |
27845 series: { | |
27846 pie: { | |
27847 show: true/false | |
27848 radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto' | |
27849 innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect | |
27850 startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result | |
27851 tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show) | |
27852 offset: { | |
27853 top: integer value to move the pie up or down | |
27854 left: integer value to move the pie left or right, or 'auto' | |
27855 }, | |
27856 stroke: { | |
27857 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF') | |
27858 width: integer pixel width of the stroke | |
27859 }, | |
27860 label: { | |
27861 show: true/false, or 'auto' | |
27862 formatter: a user-defined function that modifies the text/style of the label text | |
27863 radius: 0-1 for percentage of fullsize, or a specified pixel length | |
27864 background: { | |
27865 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000') | |
27866 opacity: 0-1 | |
27867 }, | |
27868 threshold: 0-1 for the percentage value at which to hide labels (if they're too small) | |
27869 }, | |
27870 combine: { | |
27871 threshold: 0-1 for the percentage value at which to combine slices (if they're too small) | |
27872 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined | |
27873 label: any text value of what the combined slice should be labeled | |
27874 } | |
27875 highlight: { | |
27876 opacity: 0-1 | |
27877 } | |
27878 } | |
27879 } | |
27880 | |
27881 More detail and specific examples can be found in the included HTML file. | |
27882 | |
27883 */ | |
27884 | |
27885 (function($) { | |
27886 | |
27887 // Maximum redraw attempts when fitting labels within the plot | |
27888 | |
27889 var REDRAW_ATTEMPTS = 10; | |
27890 | |
27891 // Factor by which to shrink the pie when fitting labels within the plot | |
27892 | |
27893 var REDRAW_SHRINK = 0.95; | |
27894 | |
27895 function init(plot) { | |
27896 | |
27897 var canvas = null, | |
27898 target = null, | |
27899 options = null, | |
27900 maxRadius = null, | |
27901 centerLeft = null, | |
27902 centerTop = null, | |
27903 processed = false, | |
27904 ctx = null; | |
27905 | |
27906 // interactive variables | |
27907 | |
27908 var highlights = []; | |
27909 | |
27910 // add hook to determine if pie plugin in enabled, and then perform necessary operations | |
27911 | |
27912 plot.hooks.processOptions.push(function(plot, options) { | |
27913 if (options.series.pie.show) { | |
27914 | |
27915 options.grid.show = false; | |
27916 | |
27917 // set labels.show | |
27918 | |
27919 if (options.series.pie.label.show == "auto") { | |
27920 if (options.legend.show) { | |
27921 options.series.pie.label.show = false; | |
27922 } else { | |
27923 options.series.pie.label.show = true; | |
27924 } | |
27925 } | |
27926 | |
27927 // set radius | |
27928 | |
27929 if (options.series.pie.radius == "auto") { | |
27930 if (options.series.pie.label.show) { | |
27931 options.series.pie.radius = 3/4; | |
27932 } else { | |
27933 options.series.pie.radius = 1; | |
27934 } | |
27935 } | |
27936 | |
27937 // ensure sane tilt | |
27938 | |
27939 if (options.series.pie.tilt > 1) { | |
27940 options.series.pie.tilt = 1; | |
27941 } else if (options.series.pie.tilt < 0) { | |
27942 options.series.pie.tilt = 0; | |
27943 } | |
27944 } | |
27945 }); | |
27946 | |
27947 plot.hooks.bindEvents.push(function(plot, eventHolder) { | |
27948 var options = plot.getOptions(); | |
27949 if (options.series.pie.show) { | |
27950 if (options.grid.hoverable) { | |
27951 eventHolder.unbind("mousemove").mousemove(onMouseMove); | |
27952 } | |
27953 if (options.grid.clickable) { | |
27954 eventHolder.unbind("click").click(onClick); | |
27955 } | |
27956 } | |
27957 }); | |
27958 | |
27959 plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) { | |
27960 var options = plot.getOptions(); | |
27961 if (options.series.pie.show) { | |
27962 processDatapoints(plot, series, data, datapoints); | |
27963 } | |
27964 }); | |
27965 | |
27966 plot.hooks.drawOverlay.push(function(plot, octx) { | |
27967 var options = plot.getOptions(); | |
27968 if (options.series.pie.show) { | |
27969 drawOverlay(plot, octx); | |
27970 } | |
27971 }); | |
27972 | |
27973 plot.hooks.draw.push(function(plot, newCtx) { | |
27974 var options = plot.getOptions(); | |
27975 if (options.series.pie.show) { | |
27976 draw(plot, newCtx); | |
27977 } | |
27978 }); | |
27979 | |
27980 function processDatapoints(plot, series, datapoints) { | |
27981 if (!processed) { | |
27982 processed = true; | |
27983 canvas = plot.getCanvas(); | |
27984 target = $(canvas).parent(); | |
27985 options = plot.getOptions(); | |
27986 plot.setData(combine(plot.getData())); | |
27987 } | |
27988 } | |
27989 | |
27990 function combine(data) { | |
27991 | |
27992 var total = 0, | |
27993 combined = 0, | |
27994 numCombined = 0, | |
27995 color = options.series.pie.combine.color, | |
27996 newdata = []; | |
27997 | |
27998 // Fix up the raw data from Flot, ensuring the data is numeric | |
27999 | |
28000 for (var i = 0; i < data.length; ++i) { | |
28001 | |
28002 var value = data[i].data; | |
28003 | |
28004 // If the data is an array, we'll assume that it's a standard | |
28005 // Flot x-y pair, and are concerned only with the second value. | |
28006 | |
28007 // Note how we use the original array, rather than creating a | |
28008 // new one; this is more efficient and preserves any extra data | |
28009 // that the user may have stored in higher indexes. | |
28010 | |
28011 if ($.isArray(value) && value.length == 1) { | |
28012 value = value[0]; | |
28013 } | |
28014 | |
28015 if ($.isArray(value)) { | |
28016 // Equivalent to $.isNumeric() but compatible with jQuery < 1.7 | |
28017 if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) { | |
28018 value[1] = +value[1]; | |
28019 } else { | |
28020 value[1] = 0; | |
28021 } | |
28022 } else if (!isNaN(parseFloat(value)) && isFinite(value)) { | |
28023 value = [1, +value]; | |
28024 } else { | |
28025 value = [1, 0]; | |
28026 } | |
28027 | |
28028 data[i].data = [value]; | |
28029 } | |
28030 | |
28031 // Sum up all the slices, so we can calculate percentages for each | |
28032 | |
28033 for (var i = 0; i < data.length; ++i) { | |
28034 total += data[i].data[0][1]; | |
28035 } | |
28036 | |
28037 // Count the number of slices with percentages below the combine | |
28038 // threshold; if it turns out to be just one, we won't combine. | |
28039 | |
28040 for (var i = 0; i < data.length; ++i) { | |
28041 var value = data[i].data[0][1]; | |
28042 if (value / total <= options.series.pie.combine.threshold) { | |
28043 combined += value; | |
28044 numCombined++; | |
28045 if (!color) { | |
28046 color = data[i].color; | |
28047 } | |
28048 } | |
28049 } | |
28050 | |
28051 for (var i = 0; i < data.length; ++i) { | |
28052 var value = data[i].data[0][1]; | |
28053 if (numCombined < 2 || value / total > options.series.pie.combine.threshold) { | |
28054 newdata.push( | |
28055 $.extend(data[i], { /* extend to allow keeping all other original data values | |
28056 and using them e.g. in labelFormatter. */ | |
28057 data: [[1, value]], | |
28058 color: data[i].color, | |
28059 label: data[i].label, | |
28060 angle: value * Math.PI * 2 / total, | |
28061 percent: value / (total / 100) | |
28062 }) | |
28063 ); | |
28064 } | |
28065 } | |
28066 | |
28067 if (numCombined > 1) { | |
28068 newdata.push({ | |
28069 data: [[1, combined]], | |
28070 color: color, | |
28071 label: options.series.pie.combine.label, | |
28072 angle: combined * Math.PI * 2 / total, | |
28073 percent: combined / (total / 100) | |
28074 }); | |
28075 } | |
28076 | |
28077 return newdata; | |
28078 } | |
28079 | |
28080 function draw(plot, newCtx) { | |
28081 | |
28082 if (!target) { | |
28083 return; // if no series were passed | |
28084 } | |
28085 | |
28086 var canvasWidth = plot.getPlaceholder().width(), | |
28087 canvasHeight = plot.getPlaceholder().height(), | |
28088 legendWidth = target.children().filter(".legend").children().width() || 0; | |
28089 | |
28090 ctx = newCtx; | |
28091 | |
28092 // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE! | |
28093 | |
28094 // When combining smaller slices into an 'other' slice, we need to | |
28095 // add a new series. Since Flot gives plugins no way to modify the | |
28096 // list of series, the pie plugin uses a hack where the first call | |
28097 // to processDatapoints results in a call to setData with the new | |
28098 // list of series, then subsequent processDatapoints do nothing. | |
28099 | |
28100 // The plugin-global 'processed' flag is used to control this hack; | |
28101 // it starts out false, and is set to true after the first call to | |
28102 // processDatapoints. | |
28103 | |
28104 // Unfortunately this turns future setData calls into no-ops; they | |
28105 // call processDatapoints, the flag is true, and nothing happens. | |
28106 | |
28107 // To fix this we'll set the flag back to false here in draw, when | |
28108 // all series have been processed, so the next sequence of calls to | |
28109 // processDatapoints once again starts out with a slice-combine. | |
28110 // This is really a hack; in 0.9 we need to give plugins a proper | |
28111 // way to modify series before any processing begins. | |
28112 | |
28113 processed = false; | |
28114 | |
28115 // calculate maximum radius and center point | |
28116 | |
28117 maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2; | |
28118 centerTop = canvasHeight / 2 + options.series.pie.offset.top; | |
28119 centerLeft = canvasWidth / 2; | |
28120 | |
28121 if (options.series.pie.offset.left == "auto") { | |
28122 if (options.legend.position.match("w")) { | |
28123 centerLeft += legendWidth / 2; | |
28124 } else { | |
28125 centerLeft -= legendWidth / 2; | |
28126 } | |
28127 if (centerLeft < maxRadius) { | |
28128 centerLeft = maxRadius; | |
28129 } else if (centerLeft > canvasWidth - maxRadius) { | |
28130 centerLeft = canvasWidth - maxRadius; | |
28131 } | |
28132 } else { | |
28133 centerLeft += options.series.pie.offset.left; | |
28134 } | |
28135 | |
28136 var slices = plot.getData(), | |
28137 attempts = 0; | |
28138 | |
28139 // Keep shrinking the pie's radius until drawPie returns true, | |
28140 // indicating that all the labels fit, or we try too many times. | |
28141 | |
28142 do { | |
28143 if (attempts > 0) { | |
28144 maxRadius *= REDRAW_SHRINK; | |
28145 } | |
28146 attempts += 1; | |
28147 clear(); | |
28148 if (options.series.pie.tilt <= 0.8) { | |
28149 drawShadow(); | |
28150 } | |
28151 } while (!drawPie() && attempts < REDRAW_ATTEMPTS) | |
28152 | |
28153 if (attempts >= REDRAW_ATTEMPTS) { | |
28154 clear(); | |
28155 target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>"); | |
28156 } | |
28157 | |
28158 if (plot.setSeries && plot.insertLegend) { | |
28159 plot.setSeries(slices); | |
28160 plot.insertLegend(); | |
28161 } | |
28162 | |
28163 // we're actually done at this point, just defining internal functions at this point | |
28164 | |
28165 function clear() { | |
28166 ctx.clearRect(0, 0, canvasWidth, canvasHeight); | |
28167 target.children().filter(".pieLabel, .pieLabelBackground").remove(); | |
28168 } | |
28169 | |
28170 function drawShadow() { | |
28171 | |
28172 var shadowLeft = options.series.pie.shadow.left; | |
28173 var shadowTop = options.series.pie.shadow.top; | |
28174 var edge = 10; | |
28175 var alpha = options.series.pie.shadow.alpha; | |
28176 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; | |
28177 | |
28178 if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) { | |
28179 return; // shadow would be outside canvas, so don't draw it | |
28180 } | |
28181 | |
28182 ctx.save(); | |
28183 ctx.translate(shadowLeft,shadowTop); | |
28184 ctx.globalAlpha = alpha; | |
28185 ctx.fillStyle = "#000"; | |
28186 | |
28187 // center and rotate to starting position | |
28188 | |
28189 ctx.translate(centerLeft,centerTop); | |
28190 ctx.scale(1, options.series.pie.tilt); | |
28191 | |
28192 //radius -= edge; | |
28193 | |
28194 for (var i = 1; i <= edge; i++) { | |
28195 ctx.beginPath(); | |
28196 ctx.arc(0, 0, radius, 0, Math.PI * 2, false); | |
28197 ctx.fill(); | |
28198 radius -= i; | |
28199 } | |
28200 | |
28201 ctx.restore(); | |
28202 } | |
28203 | |
28204 function drawPie() { | |
28205 | |
28206 var startAngle = Math.PI * options.series.pie.startAngle; | |
28207 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; | |
28208 | |
28209 // center and rotate to starting position | |
28210 | |
28211 ctx.save(); | |
28212 ctx.translate(centerLeft,centerTop); | |
28213 ctx.scale(1, options.series.pie.tilt); | |
28214 //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera | |
28215 | |
28216 // draw slices | |
28217 | |
28218 ctx.save(); | |
28219 var currentAngle = startAngle; | |
28220 for (var i = 0; i < slices.length; ++i) { | |
28221 slices[i].startAngle = currentAngle; | |
28222 drawSlice(slices[i].angle, slices[i].color, true); | |
28223 } | |
28224 ctx.restore(); | |
28225 | |
28226 // draw slice outlines | |
28227 | |
28228 if (options.series.pie.stroke.width > 0) { | |
28229 ctx.save(); | |
28230 ctx.lineWidth = options.series.pie.stroke.width; | |
28231 currentAngle = startAngle; | |
28232 for (var i = 0; i < slices.length; ++i) { | |
28233 drawSlice(slices[i].angle, options.series.pie.stroke.color, false); | |
28234 } | |
28235 ctx.restore(); | |
28236 } | |
28237 | |
28238 // draw donut hole | |
28239 | |
28240 drawDonutHole(ctx); | |
28241 | |
28242 ctx.restore(); | |
28243 | |
28244 // Draw the labels, returning true if they fit within the plot | |
28245 | |
28246 if (options.series.pie.label.show) { | |
28247 return drawLabels(); | |
28248 } else return true; | |
28249 | |
28250 function drawSlice(angle, color, fill) { | |
28251 | |
28252 if (angle <= 0 || isNaN(angle)) { | |
28253 return; | |
28254 } | |
28255 | |
28256 if (fill) { | |
28257 ctx.fillStyle = color; | |
28258 } else { | |
28259 ctx.strokeStyle = color; | |
28260 ctx.lineJoin = "round"; | |
28261 } | |
28262 | |
28263 ctx.beginPath(); | |
28264 if (Math.abs(angle - Math.PI * 2) > 0.000000001) { | |
28265 ctx.moveTo(0, 0); // Center of the pie | |
28266 } | |
28267 | |
28268 //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera | |
28269 ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false); | |
28270 ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false); | |
28271 ctx.closePath(); | |
28272 //ctx.rotate(angle); // This doesn't work properly in Opera | |
28273 currentAngle += angle; | |
28274 | |
28275 if (fill) { | |
28276 ctx.fill(); | |
28277 } else { | |
28278 ctx.stroke(); | |
28279 } | |
28280 } | |
28281 | |
28282 function drawLabels() { | |
28283 | |
28284 var currentAngle = startAngle; | |
28285 var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius; | |
28286 | |
28287 for (var i = 0; i < slices.length; ++i) { | |
28288 if (slices[i].percent >= options.series.pie.label.threshold * 100) { | |
28289 if (!drawLabel(slices[i], currentAngle, i)) { | |
28290 return false; | |
28291 } | |
28292 } | |
28293 currentAngle += slices[i].angle; | |
28294 } | |
28295 | |
28296 return true; | |
28297 | |
28298 function drawLabel(slice, startAngle, index) { | |
28299 | |
28300 if (slice.data[0][1] == 0) { | |
28301 return true; | |
28302 } | |
28303 | |
28304 // format label text | |
28305 | |
28306 var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter; | |
28307 | |
28308 if (lf) { | |
28309 text = lf(slice.label, slice); | |
28310 } else { | |
28311 text = slice.label; | |
28312 } | |
28313 | |
28314 if (plf) { | |
28315 text = plf(text, slice); | |
28316 } | |
28317 | |
28318 var halfAngle = ((startAngle + slice.angle) + startAngle) / 2; | |
28319 var x = centerLeft + Math.round(Math.cos(halfAngle) * radius); | |
28320 var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt; | |
28321 | |
28322 var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>"; | |
28323 target.append(html); | |
28324 | |
28325 var label = target.children("#pieLabel" + index); | |
28326 var labelTop = (y - label.height() / 2); | |
28327 var labelLeft = (x - label.width() / 2); | |
28328 | |
28329 label.css("top", labelTop); | |
28330 label.css("left", labelLeft); | |
28331 | |
28332 // check to make sure that the label is not outside the canvas | |
28333 | |
28334 if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) { | |
28335 return false; | |
28336 } | |
28337 | |
28338 if (options.series.pie.label.background.opacity != 0) { | |
28339 | |
28340 // put in the transparent background separately to avoid blended labels and label boxes | |
28341 | |
28342 var c = options.series.pie.label.background.color; | |
28343 | |
28344 if (c == null) { | |
28345 c = slice.color; | |
28346 } | |
28347 | |
28348 var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;"; | |
28349 $("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>") | |
28350 .css("opacity", options.series.pie.label.background.opacity) | |
28351 .insertBefore(label); | |
28352 } | |
28353 | |
28354 return true; | |
28355 } // end individual label function | |
28356 } // end drawLabels function | |
28357 } // end drawPie function | |
28358 } // end draw function | |
28359 | |
28360 // Placed here because it needs to be accessed from multiple locations | |
28361 | |
28362 function drawDonutHole(layer) { | |
28363 if (options.series.pie.innerRadius > 0) { | |
28364 | |
28365 // subtract the center | |
28366 | |
28367 layer.save(); | |
28368 var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; | |
28369 layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color | |
28370 layer.beginPath(); | |
28371 layer.fillStyle = options.series.pie.stroke.color; | |
28372 layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); | |
28373 layer.fill(); | |
28374 layer.closePath(); | |
28375 layer.restore(); | |
28376 | |
28377 // add inner stroke | |
28378 | |
28379 layer.save(); | |
28380 layer.beginPath(); | |
28381 layer.strokeStyle = options.series.pie.stroke.color; | |
28382 layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); | |
28383 layer.stroke(); | |
28384 layer.closePath(); | |
28385 layer.restore(); | |
28386 | |
28387 // TODO: add extra shadow inside hole (with a mask) if the pie is tilted. | |
28388 } | |
28389 } | |
28390 | |
28391 //-- Additional Interactive related functions -- | |
28392 | |
28393 function isPointInPoly(poly, pt) { | |
28394 for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) | |
28395 ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1])) | |
28396 && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) | |
28397 && (c = !c); | |
28398 return c; | |
28399 } | |
28400 | |
28401 function findNearbySlice(mouseX, mouseY) { | |
28402 | |
28403 var slices = plot.getData(), | |
28404 options = plot.getOptions(), | |
28405 radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius, | |
28406 x, y; | |
28407 | |
28408 for (var i = 0; i < slices.length; ++i) { | |
28409 | |
28410 var s = slices[i]; | |
28411 | |
28412 if (s.pie.show) { | |
28413 | |
28414 ctx.save(); | |
28415 ctx.beginPath(); | |
28416 ctx.moveTo(0, 0); // Center of the pie | |
28417 //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here. | |
28418 ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false); | |
28419 ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false); | |
28420 ctx.closePath(); | |
28421 x = mouseX - centerLeft; | |
28422 y = mouseY - centerTop; | |
28423 | |
28424 if (ctx.isPointInPath) { | |
28425 if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) { | |
28426 ctx.restore(); | |
28427 return { | |
28428 datapoint: [s.percent, s.data], | |
28429 dataIndex: 0, | |
28430 series: s, | |
28431 seriesIndex: i | |
28432 }; | |
28433 } | |
28434 } else { | |
28435 | |
28436 // excanvas for IE doesn;t support isPointInPath, this is a workaround. | |
28437 | |
28438 var p1X = radius * Math.cos(s.startAngle), | |
28439 p1Y = radius * Math.sin(s.startAngle), | |
28440 p2X = radius * Math.cos(s.startAngle + s.angle / 4), | |
28441 p2Y = radius * Math.sin(s.startAngle + s.angle / 4), | |
28442 p3X = radius * Math.cos(s.startAngle + s.angle / 2), | |
28443 p3Y = radius * Math.sin(s.startAngle + s.angle / 2), | |
28444 p4X = radius * Math.cos(s.startAngle + s.angle / 1.5), | |
28445 p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5), | |
28446 p5X = radius * Math.cos(s.startAngle + s.angle), | |
28447 p5Y = radius * Math.sin(s.startAngle + s.angle), | |
28448 arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]], | |
28449 arrPoint = [x, y]; | |
28450 | |
28451 // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? | |
28452 | |
28453 if (isPointInPoly(arrPoly, arrPoint)) { | |
28454 ctx.restore(); | |
28455 return { | |
28456 datapoint: [s.percent, s.data], | |
28457 dataIndex: 0, | |
28458 series: s, | |
28459 seriesIndex: i | |
28460 }; | |
28461 } | |
28462 } | |
28463 | |
28464 ctx.restore(); | |
28465 } | |
28466 } | |
28467 | |
28468 return null; | |
28469 } | |
28470 | |
28471 function onMouseMove(e) { | |
28472 triggerClickHoverEvent("plothover", e); | |
28473 } | |
28474 | |
28475 function onClick(e) { | |
28476 triggerClickHoverEvent("plotclick", e); | |
28477 } | |
28478 | |
28479 // trigger click or hover event (they send the same parameters so we share their code) | |
28480 | |
28481 function triggerClickHoverEvent(eventname, e) { | |
28482 | |
28483 var offset = plot.offset(); | |
28484 var canvasX = parseInt(e.pageX - offset.left); | |
28485 var canvasY = parseInt(e.pageY - offset.top); | |
28486 var item = findNearbySlice(canvasX, canvasY); | |
28487 | |
28488 if (options.grid.autoHighlight) { | |
28489 | |
28490 // clear auto-highlights | |
28491 | |
28492 for (var i = 0; i < highlights.length; ++i) { | |
28493 var h = highlights[i]; | |
28494 if (h.auto == eventname && !(item && h.series == item.series)) { | |
28495 unhighlight(h.series); | |
28496 } | |
28497 } | |
28498 } | |
28499 | |
28500 // highlight the slice | |
28501 | |
28502 if (item) { | |
28503 highlight(item.series, eventname); | |
28504 } | |
28505 | |
28506 // trigger any hover bind events | |
28507 | |
28508 var pos = { pageX: e.pageX, pageY: e.pageY }; | |
28509 target.trigger(eventname, [pos, item]); | |
28510 } | |
28511 | |
28512 function highlight(s, auto) { | |
28513 //if (typeof s == "number") { | |
28514 // s = series[s]; | |
28515 //} | |
28516 | |
28517 var i = indexOfHighlight(s); | |
28518 | |
28519 if (i == -1) { | |
28520 highlights.push({ series: s, auto: auto }); | |
28521 plot.triggerRedrawOverlay(); | |
28522 } else if (!auto) { | |
28523 highlights[i].auto = false; | |
28524 } | |
28525 } | |
28526 | |
28527 function unhighlight(s) { | |
28528 if (s == null) { | |
28529 highlights = []; | |
28530 plot.triggerRedrawOverlay(); | |
28531 } | |
28532 | |
28533 //if (typeof s == "number") { | |
28534 // s = series[s]; | |
28535 //} | |
28536 | |
28537 var i = indexOfHighlight(s); | |
28538 | |
28539 if (i != -1) { | |
28540 highlights.splice(i, 1); | |
28541 plot.triggerRedrawOverlay(); | |
28542 } | |
28543 } | |
28544 | |
28545 function indexOfHighlight(s) { | |
28546 for (var i = 0; i < highlights.length; ++i) { | |
28547 var h = highlights[i]; | |
28548 if (h.series == s) | |
28549 return i; | |
28550 } | |
28551 return -1; | |
28552 } | |
28553 | |
28554 function drawOverlay(plot, octx) { | |
28555 | |
28556 var options = plot.getOptions(); | |
28557 | |
28558 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; | |
28559 | |
28560 octx.save(); | |
28561 octx.translate(centerLeft, centerTop); | |
28562 octx.scale(1, options.series.pie.tilt); | |
28563 | |
28564 for (var i = 0; i < highlights.length; ++i) { | |
28565 drawHighlight(highlights[i].series); | |
28566 } | |
28567 | |
28568 drawDonutHole(octx); | |
28569 | |
28570 octx.restore(); | |
28571 | |
28572 function drawHighlight(series) { | |
28573 | |
28574 if (series.angle <= 0 || isNaN(series.angle)) { | |
28575 return; | |
28576 } | |
28577 | |
28578 //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString(); | |
28579 octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor | |
28580 octx.beginPath(); | |
28581 if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) { | |
28582 octx.moveTo(0, 0); // Center of the pie | |
28583 } | |
28584 octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false); | |
28585 octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false); | |
28586 octx.closePath(); | |
28587 octx.fill(); | |
28588 } | |
28589 } | |
28590 } // end init (plugin body) | |
28591 | |
28592 // define pie specific options and their default values | |
28593 | |
28594 var options = { | |
28595 series: { | |
28596 pie: { | |
28597 show: false, | |
28598 radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value) | |
28599 innerRadius: 0, /* for donut */ | |
28600 startAngle: 3/2, | |
28601 tilt: 1, | |
28602 shadow: { | |
28603 left: 5, // shadow left offset | |
28604 top: 15, // shadow top offset | |
28605 alpha: 0.02 // shadow alpha | |
28606 }, | |
28607 offset: { | |
28608 top: 0, | |
28609 left: "auto" | |
28610 }, | |
28611 stroke: { | |
28612 color: "#fff", | |
28613 width: 1 | |
28614 }, | |
28615 label: { | |
28616 show: "auto", | |
28617 formatter: function(label, slice) { | |
28618 return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>"; | |
28619 }, // formatter function | |
28620 radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value) | |
28621 background: { | |
28622 color: null, | |
28623 opacity: 0 | |
28624 }, | |
28625 threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow) | |
28626 }, | |
28627 combine: { | |
28628 threshold: -1, // percentage at which to combine little slices into one larger slice | |
28629 color: null, // color to give the new slice (auto-generated if null) | |
28630 label: "Other" // label to give the new slice | |
28631 }, | |
28632 highlight: { | |
28633 //color: "#fff", // will add this functionality once parseColor is available | |
28634 opacity: 0.5 | |
28635 } | |
28636 } | |
28637 } | |
28638 }; | |
28639 | |
28640 $.plot.plugins.push({ | |
28641 init: init, | |
28642 options: options, | |
28643 name: "pie", | |
28644 version: "1.1" | |
28645 }); | |
28646 | |
28647 })(jQuery); | |
28648 /* Flot plugin for automatically redrawing plots as the placeholder resizes. | |
28649 | |
28650 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
28651 Licensed under the MIT license. | |
28652 | |
28653 It works by listening for changes on the placeholder div (through the jQuery | |
28654 resize event plugin) - if the size changes, it will redraw the plot. | |
28655 | |
28656 There are no options. If you need to disable the plugin for some plots, you | |
28657 can just fix the size of their placeholders. | |
28658 | |
28659 */ | |
28660 | |
28661 /* Inline dependency: | |
28662 * jQuery resize event - v1.1 - 3/14/2010 | |
28663 * http://benalman.com/projects/jquery-resize-plugin/ | |
28664 * | |
28665 * Copyright (c) 2010 "Cowboy" Ben Alman | |
28666 * Dual licensed under the MIT and GPL licenses. | |
28667 * http://benalman.com/about/license/ | |
28668 */ | |
28669 | |
28670 (function($,t,n){function p(){for(var n=r.length-1;n>=0;n--){var o=$(r[n]);if(o[0]==t||o.is(":visible")){var h=o.width(),d=o.height(),v=o.data(a);!v||h===v.w&&d===v.h?i[f]=i[l]:(i[f]=i[c],o.trigger(u,[v.w=h,v.h=d]))}else v=o.data(a),v.w=0,v.h=0}s!==null&&(s=t.requestAnimationFrame(p))}var r=[],i=$.resize=$.extend($.resize,{}),s,o="setTimeout",u="resize",a=u+"-special-event",f="delay",l="pendingDelay",c="activeDelay",h="throttleWindow";i[l]=250,i[c]=20,i[f]=i[l],i[h]=!0,$.event.special[u]={setup:function(){if(!i[h]&&this[o])return!1;var t=$(this);r.push(this),t.data(a,{w:t.width(),h:t.height()}),r.length===1&&(s=n,p())},teardown:function(){if(!i[h]&&this[o])return!1;var t=$(this);for(var n=r.length-1;n>=0;n--)if(r[n]==this){r.splice(n,1);break}t.removeData(a),r.length||(cancelAnimationFrame(s),s=null)},add:function(t){function s(t,i,s){var o=$(this),u=o.data(a);u.w=i!==n?i:o.width(),u.h=s!==n?s:o.height(),r.apply(this,arguments)}if(!i[h]&&this[o])return!1;var r;if($.isFunction(t))return r=t,s;r=t.handler,t.handler=s}},t.requestAnimationFrame||(t.requestAnimationFrame=function(){return t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||t.msRequestAnimationFrame||function(e,n){return t.setTimeout(e,i[f])}}()),t.cancelAnimationFrame||(t.cancelAnimationFrame=function(){return t.webkitCancelRequestAnimationFrame||t.mozCancelRequestAnimationFrame||t.oCancelRequestAnimationFrame||t.msCancelRequestAnimationFrame||clearTimeout}())})(jQuery,this); | |
28671 | |
28672 (function ($) { | |
28673 var options = { }; // no options | |
28674 | |
28675 function init(plot) { | |
28676 function onResize() { | |
28677 var placeholder = plot.getPlaceholder(); | |
28678 | |
28679 // somebody might have hidden us and we can't plot | |
28680 // when we don't have the dimensions | |
28681 if (placeholder.width() == 0 || placeholder.height() == 0) | |
28682 return; | |
28683 | |
28684 plot.resize(); | |
28685 plot.setupGrid(); | |
28686 plot.draw(); | |
28687 } | |
28688 | |
28689 function bindEvents(plot, eventHolder) { | |
28690 plot.getPlaceholder().resize(onResize); | |
28691 } | |
28692 | |
28693 function shutdown(plot, eventHolder) { | |
28694 plot.getPlaceholder().unbind("resize", onResize); | |
28695 } | |
28696 | |
28697 plot.hooks.bindEvents.push(bindEvents); | |
28698 plot.hooks.shutdown.push(shutdown); | |
28699 } | |
28700 | |
28701 $.plot.plugins.push({ | |
28702 init: init, | |
28703 options: options, | |
28704 name: 'resize', | |
28705 version: '1.0' | |
28706 }); | |
28707 })(jQuery); | |
28708 /* Flot plugin for selecting regions of a plot. | |
28709 | |
28710 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
28711 Licensed under the MIT license. | |
28712 | |
28713 The plugin supports these options: | |
28714 | |
28715 selection: { | |
28716 mode: null or "x" or "y" or "xy", | |
28717 color: color, | |
28718 shape: "round" or "miter" or "bevel", | |
28719 minSize: number of pixels | |
28720 } | |
28721 | |
28722 Selection support is enabled by setting the mode to one of "x", "y" or "xy". | |
28723 In "x" mode, the user will only be able to specify the x range, similarly for | |
28724 "y" mode. For "xy", the selection becomes a rectangle where both ranges can be | |
28725 specified. "color" is color of the selection (if you need to change the color | |
28726 later on, you can get to it with plot.getOptions().selection.color). "shape" | |
28727 is the shape of the corners of the selection. | |
28728 | |
28729 "minSize" is the minimum size a selection can be in pixels. This value can | |
28730 be customized to determine the smallest size a selection can be and still | |
28731 have the selection rectangle be displayed. When customizing this value, the | |
28732 fact that it refers to pixels, not axis units must be taken into account. | |
28733 Thus, for example, if there is a bar graph in time mode with BarWidth set to 1 | |
28734 minute, setting "minSize" to 1 will not make the minimum selection size 1 | |
28735 minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent | |
28736 "plotunselected" events from being fired when the user clicks the mouse without | |
28737 dragging. | |
28738 | |
28739 When selection support is enabled, a "plotselected" event will be emitted on | |
28740 the DOM element you passed into the plot function. The event handler gets a | |
28741 parameter with the ranges selected on the axes, like this: | |
28742 | |
28743 placeholder.bind( "plotselected", function( event, ranges ) { | |
28744 alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to) | |
28745 // similar for yaxis - with multiple axes, the extra ones are in | |
28746 // x2axis, x3axis, ... | |
28747 }); | |
28748 | |
28749 The "plotselected" event is only fired when the user has finished making the | |
28750 selection. A "plotselecting" event is fired during the process with the same | |
28751 parameters as the "plotselected" event, in case you want to know what's | |
28752 happening while it's happening, | |
28753 | |
28754 A "plotunselected" event with no arguments is emitted when the user clicks the | |
28755 mouse to remove the selection. As stated above, setting "minSize" to 0 will | |
28756 destroy this behavior. | |
28757 | |
28758 The plugin allso adds the following methods to the plot object: | |
28759 | |
28760 - setSelection( ranges, preventEvent ) | |
28761 | |
28762 Set the selection rectangle. The passed in ranges is on the same form as | |
28763 returned in the "plotselected" event. If the selection mode is "x", you | |
28764 should put in either an xaxis range, if the mode is "y" you need to put in | |
28765 an yaxis range and both xaxis and yaxis if the selection mode is "xy", like | |
28766 this: | |
28767 | |
28768 setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } }); | |
28769 | |
28770 setSelection will trigger the "plotselected" event when called. If you don't | |
28771 want that to happen, e.g. if you're inside a "plotselected" handler, pass | |
28772 true as the second parameter. If you are using multiple axes, you can | |
28773 specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of | |
28774 xaxis, the plugin picks the first one it sees. | |
28775 | |
28776 - clearSelection( preventEvent ) | |
28777 | |
28778 Clear the selection rectangle. Pass in true to avoid getting a | |
28779 "plotunselected" event. | |
28780 | |
28781 - getSelection() | |
28782 | |
28783 Returns the current selection in the same format as the "plotselected" | |
28784 event. If there's currently no selection, the function returns null. | |
28785 | |
28786 */ | |
28787 | |
28788 (function ($) { | |
28789 function init(plot) { | |
28790 var selection = { | |
28791 first: { x: -1, y: -1}, second: { x: -1, y: -1}, | |
28792 show: false, | |
28793 active: false | |
28794 }; | |
28795 | |
28796 // FIXME: The drag handling implemented here should be | |
28797 // abstracted out, there's some similar code from a library in | |
28798 // the navigation plugin, this should be massaged a bit to fit | |
28799 // the Flot cases here better and reused. Doing this would | |
28800 // make this plugin much slimmer. | |
28801 var savedhandlers = {}; | |
28802 | |
28803 var mouseUpHandler = null; | |
28804 | |
28805 function onMouseMove(e) { | |
28806 if (selection.active) { | |
28807 updateSelection(e); | |
28808 | |
28809 plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]); | |
28810 } | |
28811 } | |
28812 | |
28813 function onMouseDown(e) { | |
28814 if (e.which != 1) // only accept left-click | |
28815 return; | |
28816 | |
28817 // cancel out any text selections | |
28818 document.body.focus(); | |
28819 | |
28820 // prevent text selection and drag in old-school browsers | |
28821 if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) { | |
28822 savedhandlers.onselectstart = document.onselectstart; | |
28823 document.onselectstart = function () { return false; }; | |
28824 } | |
28825 if (document.ondrag !== undefined && savedhandlers.ondrag == null) { | |
28826 savedhandlers.ondrag = document.ondrag; | |
28827 document.ondrag = function () { return false; }; | |
28828 } | |
28829 | |
28830 setSelectionPos(selection.first, e); | |
28831 | |
28832 selection.active = true; | |
28833 | |
28834 // this is a bit silly, but we have to use a closure to be | |
28835 // able to whack the same handler again | |
28836 mouseUpHandler = function (e) { onMouseUp(e); }; | |
28837 | |
28838 $(document).one("mouseup", mouseUpHandler); | |
28839 } | |
28840 | |
28841 function onMouseUp(e) { | |
28842 mouseUpHandler = null; | |
28843 | |
28844 // revert drag stuff for old-school browsers | |
28845 if (document.onselectstart !== undefined) | |
28846 document.onselectstart = savedhandlers.onselectstart; | |
28847 if (document.ondrag !== undefined) | |
28848 document.ondrag = savedhandlers.ondrag; | |
28849 | |
28850 // no more dragging | |
28851 selection.active = false; | |
28852 updateSelection(e); | |
28853 | |
28854 if (selectionIsSane()) | |
28855 triggerSelectedEvent(); | |
28856 else { | |
28857 // this counts as a clear | |
28858 plot.getPlaceholder().trigger("plotunselected", [ ]); | |
28859 plot.getPlaceholder().trigger("plotselecting", [ null ]); | |
28860 } | |
28861 | |
28862 return false; | |
28863 } | |
28864 | |
28865 function getSelection() { | |
28866 if (!selectionIsSane()) | |
28867 return null; | |
28868 | |
28869 if (!selection.show) return null; | |
28870 | |
28871 var r = {}, c1 = selection.first, c2 = selection.second; | |
28872 $.each(plot.getAxes(), function (name, axis) { | |
28873 if (axis.used) { | |
28874 var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); | |
28875 r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) }; | |
28876 } | |
28877 }); | |
28878 return r; | |
28879 } | |
28880 | |
28881 function triggerSelectedEvent() { | |
28882 var r = getSelection(); | |
28883 | |
28884 plot.getPlaceholder().trigger("plotselected", [ r ]); | |
28885 | |
28886 // backwards-compat stuff, to be removed in future | |
28887 if (r.xaxis && r.yaxis) | |
28888 plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]); | |
28889 } | |
28890 | |
28891 function clamp(min, value, max) { | |
28892 return value < min ? min: (value > max ? max: value); | |
28893 } | |
28894 | |
28895 function setSelectionPos(pos, e) { | |
28896 var o = plot.getOptions(); | |
28897 var offset = plot.getPlaceholder().offset(); | |
28898 var plotOffset = plot.getPlotOffset(); | |
28899 pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width()); | |
28900 pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height()); | |
28901 | |
28902 if (o.selection.mode == "y") | |
28903 pos.x = pos == selection.first ? 0 : plot.width(); | |
28904 | |
28905 if (o.selection.mode == "x") | |
28906 pos.y = pos == selection.first ? 0 : plot.height(); | |
28907 } | |
28908 | |
28909 function updateSelection(pos) { | |
28910 if (pos.pageX == null) | |
28911 return; | |
28912 | |
28913 setSelectionPos(selection.second, pos); | |
28914 if (selectionIsSane()) { | |
28915 selection.show = true; | |
28916 plot.triggerRedrawOverlay(); | |
28917 } | |
28918 else | |
28919 clearSelection(true); | |
28920 } | |
28921 | |
28922 function clearSelection(preventEvent) { | |
28923 if (selection.show) { | |
28924 selection.show = false; | |
28925 plot.triggerRedrawOverlay(); | |
28926 if (!preventEvent) | |
28927 plot.getPlaceholder().trigger("plotunselected", [ ]); | |
28928 } | |
28929 } | |
28930 | |
28931 // function taken from markings support in Flot | |
28932 function extractRange(ranges, coord) { | |
28933 var axis, from, to, key, axes = plot.getAxes(); | |
28934 | |
28935 for (var k in axes) { | |
28936 axis = axes[k]; | |
28937 if (axis.direction == coord) { | |
28938 key = coord + axis.n + "axis"; | |
28939 if (!ranges[key] && axis.n == 1) | |
28940 key = coord + "axis"; // support x1axis as xaxis | |
28941 if (ranges[key]) { | |
28942 from = ranges[key].from; | |
28943 to = ranges[key].to; | |
28944 break; | |
28945 } | |
28946 } | |
28947 } | |
28948 | |
28949 // backwards-compat stuff - to be removed in future | |
28950 if (!ranges[key]) { | |
28951 axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0]; | |
28952 from = ranges[coord + "1"]; | |
28953 to = ranges[coord + "2"]; | |
28954 } | |
28955 | |
28956 // auto-reverse as an added bonus | |
28957 if (from != null && to != null && from > to) { | |
28958 var tmp = from; | |
28959 from = to; | |
28960 to = tmp; | |
28961 } | |
28962 | |
28963 return { from: from, to: to, axis: axis }; | |
28964 } | |
28965 | |
28966 function setSelection(ranges, preventEvent) { | |
28967 var axis, range, o = plot.getOptions(); | |
28968 | |
28969 if (o.selection.mode == "y") { | |
28970 selection.first.x = 0; | |
28971 selection.second.x = plot.width(); | |
28972 } | |
28973 else { | |
28974 range = extractRange(ranges, "x"); | |
28975 | |
28976 selection.first.x = range.axis.p2c(range.from); | |
28977 selection.second.x = range.axis.p2c(range.to); | |
28978 } | |
28979 | |
28980 if (o.selection.mode == "x") { | |
28981 selection.first.y = 0; | |
28982 selection.second.y = plot.height(); | |
28983 } | |
28984 else { | |
28985 range = extractRange(ranges, "y"); | |
28986 | |
28987 selection.first.y = range.axis.p2c(range.from); | |
28988 selection.second.y = range.axis.p2c(range.to); | |
28989 } | |
28990 | |
28991 selection.show = true; | |
28992 plot.triggerRedrawOverlay(); | |
28993 if (!preventEvent && selectionIsSane()) | |
28994 triggerSelectedEvent(); | |
28995 } | |
28996 | |
28997 function selectionIsSane() { | |
28998 var minSize = plot.getOptions().selection.minSize; | |
28999 return Math.abs(selection.second.x - selection.first.x) >= minSize && | |
29000 Math.abs(selection.second.y - selection.first.y) >= minSize; | |
29001 } | |
29002 | |
29003 plot.clearSelection = clearSelection; | |
29004 plot.setSelection = setSelection; | |
29005 plot.getSelection = getSelection; | |
29006 | |
29007 plot.hooks.bindEvents.push(function(plot, eventHolder) { | |
29008 var o = plot.getOptions(); | |
29009 if (o.selection.mode != null) { | |
29010 eventHolder.mousemove(onMouseMove); | |
29011 eventHolder.mousedown(onMouseDown); | |
29012 } | |
29013 }); | |
29014 | |
29015 | |
29016 plot.hooks.drawOverlay.push(function (plot, ctx) { | |
29017 // draw selection | |
29018 if (selection.show && selectionIsSane()) { | |
29019 var plotOffset = plot.getPlotOffset(); | |
29020 var o = plot.getOptions(); | |
29021 | |
29022 ctx.save(); | |
29023 ctx.translate(plotOffset.left, plotOffset.top); | |
29024 | |
29025 var c = $.color.parse(o.selection.color); | |
29026 | |
29027 ctx.strokeStyle = c.scale('a', 0.8).toString(); | |
29028 ctx.lineWidth = 1; | |
29029 ctx.lineJoin = o.selection.shape; | |
29030 ctx.fillStyle = c.scale('a', 0.4).toString(); | |
29031 | |
29032 var x = Math.min(selection.first.x, selection.second.x) + 0.5, | |
29033 y = Math.min(selection.first.y, selection.second.y) + 0.5, | |
29034 w = Math.abs(selection.second.x - selection.first.x) - 1, | |
29035 h = Math.abs(selection.second.y - selection.first.y) - 1; | |
29036 | |
29037 ctx.fillRect(x, y, w, h); | |
29038 ctx.strokeRect(x, y, w, h); | |
29039 | |
29040 ctx.restore(); | |
29041 } | |
29042 }); | |
29043 | |
29044 plot.hooks.shutdown.push(function (plot, eventHolder) { | |
29045 eventHolder.unbind("mousemove", onMouseMove); | |
29046 eventHolder.unbind("mousedown", onMouseDown); | |
29047 | |
29048 if (mouseUpHandler) | |
29049 $(document).unbind("mouseup", mouseUpHandler); | |
29050 }); | |
29051 | |
29052 } | |
29053 | |
29054 $.plot.plugins.push({ | |
29055 init: init, | |
29056 options: { | |
29057 selection: { | |
29058 mode: null, // one of null, "x", "y" or "xy" | |
29059 color: "#e8cfac", | |
29060 shape: "round", // one of "round", "miter", or "bevel" | |
29061 minSize: 5 // minimum number of pixels | |
29062 } | |
29063 }, | |
29064 name: 'selection', | |
29065 version: '1.1' | |
29066 }); | |
29067 })(jQuery); | |
29068 /* Pretty handling of time axes. | |
29069 | |
29070 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
29071 Licensed under the MIT license. | |
29072 | |
29073 Set axis.mode to "time" to enable. See the section "Time series data" in | |
29074 API.txt for details. | |
29075 | |
29076 */ | |
29077 | |
29078 (function($) { | |
29079 | |
29080 var options = { | |
29081 xaxis: { | |
29082 timezone: null, // "browser" for local to the client or timezone for timezone-js | |
29083 timeformat: null, // format string to use | |
29084 twelveHourClock: false, // 12 or 24 time in time mode | |
29085 monthNames: null // list of names of months | |
29086 } | |
29087 }; | |
29088 | |
29089 // round to nearby lower multiple of base | |
29090 | |
29091 function floorInBase(n, base) { | |
29092 return base * Math.floor(n / base); | |
29093 } | |
29094 | |
29095 // Returns a string with the date d formatted according to fmt. | |
29096 // A subset of the Open Group's strftime format is supported. | |
29097 | |
29098 function formatDate(d, fmt, monthNames, dayNames) { | |
29099 | |
29100 if (typeof d.strftime == "function") { | |
29101 return d.strftime(fmt); | |
29102 } | |
29103 | |
29104 var leftPad = function(n, pad) { | |
29105 n = "" + n; | |
29106 pad = "" + (pad == null ? "0" : pad); | |
29107 return n.length == 1 ? pad + n : n; | |
29108 }; | |
29109 | |
29110 var r = []; | |
29111 var escape = false; | |
29112 var hours = d.getHours(); | |
29113 var isAM = hours < 12; | |
29114 | |
29115 if (monthNames == null) { | |
29116 monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | |
29117 } | |
29118 | |
29119 if (dayNames == null) { | |
29120 dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; | |
29121 } | |
29122 | |
29123 var hours12; | |
29124 | |
29125 if (hours > 12) { | |
29126 hours12 = hours - 12; | |
29127 } else if (hours == 0) { | |
29128 hours12 = 12; | |
29129 } else { | |
29130 hours12 = hours; | |
29131 } | |
29132 | |
29133 for (var i = 0; i < fmt.length; ++i) { | |
29134 | |
29135 var c = fmt.charAt(i); | |
29136 | |
29137 if (escape) { | |
29138 switch (c) { | |
29139 case 'a': c = "" + dayNames[d.getDay()]; break; | |
29140 case 'b': c = "" + monthNames[d.getMonth()]; break; | |
29141 case 'd': c = leftPad(d.getDate()); break; | |
29142 case 'e': c = leftPad(d.getDate(), " "); break; | |
29143 case 'h': // For back-compat with 0.7; remove in 1.0 | |
29144 case 'H': c = leftPad(hours); break; | |
29145 case 'I': c = leftPad(hours12); break; | |
29146 case 'l': c = leftPad(hours12, " "); break; | |
29147 case 'm': c = leftPad(d.getMonth() + 1); break; | |
29148 case 'M': c = leftPad(d.getMinutes()); break; | |
29149 // quarters not in Open Group's strftime specification | |
29150 case 'q': | |
29151 c = "" + (Math.floor(d.getMonth() / 3) + 1); break; | |
29152 case 'S': c = leftPad(d.getSeconds()); break; | |
29153 case 'y': c = leftPad(d.getFullYear() % 100); break; | |
29154 case 'Y': c = "" + d.getFullYear(); break; | |
29155 case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; | |
29156 case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; | |
29157 case 'w': c = "" + d.getDay(); break; | |
29158 } | |
29159 r.push(c); | |
29160 escape = false; | |
29161 } else { | |
29162 if (c == "%") { | |
29163 escape = true; | |
29164 } else { | |
29165 r.push(c); | |
29166 } | |
29167 } | |
29168 } | |
29169 | |
29170 return r.join(""); | |
29171 } | |
29172 | |
29173 // To have a consistent view of time-based data independent of which time | |
29174 // zone the client happens to be in we need a date-like object independent | |
29175 // of time zones. This is done through a wrapper that only calls the UTC | |
29176 // versions of the accessor methods. | |
29177 | |
29178 function makeUtcWrapper(d) { | |
29179 | |
29180 function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { | |
29181 sourceObj[sourceMethod] = function() { | |
29182 return targetObj[targetMethod].apply(targetObj, arguments); | |
29183 }; | |
29184 }; | |
29185 | |
29186 var utc = { | |
29187 date: d | |
29188 }; | |
29189 | |
29190 // support strftime, if found | |
29191 | |
29192 if (d.strftime != undefined) { | |
29193 addProxyMethod(utc, "strftime", d, "strftime"); | |
29194 } | |
29195 | |
29196 addProxyMethod(utc, "getTime", d, "getTime"); | |
29197 addProxyMethod(utc, "setTime", d, "setTime"); | |
29198 | |
29199 var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; | |
29200 | |
29201 for (var p = 0; p < props.length; p++) { | |
29202 addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); | |
29203 addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); | |
29204 } | |
29205 | |
29206 return utc; | |
29207 }; | |
29208 | |
29209 // select time zone strategy. This returns a date-like object tied to the | |
29210 // desired timezone | |
29211 | |
29212 function dateGenerator(ts, opts) { | |
29213 if (opts.timezone == "browser") { | |
29214 return new Date(ts); | |
29215 } else if (!opts.timezone || opts.timezone == "utc") { | |
29216 return makeUtcWrapper(new Date(ts)); | |
29217 } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { | |
29218 var d = new timezoneJS.Date(); | |
29219 // timezone-js is fickle, so be sure to set the time zone before | |
29220 // setting the time. | |
29221 d.setTimezone(opts.timezone); | |
29222 d.setTime(ts); | |
29223 return d; | |
29224 } else { | |
29225 return makeUtcWrapper(new Date(ts)); | |
29226 } | |
29227 } | |
29228 | |
29229 // map of app. size of time units in milliseconds | |
29230 | |
29231 var timeUnitSize = { | |
29232 "second": 1000, | |
29233 "minute": 60 * 1000, | |
29234 "hour": 60 * 60 * 1000, | |
29235 "day": 24 * 60 * 60 * 1000, | |
29236 "month": 30 * 24 * 60 * 60 * 1000, | |
29237 "quarter": 3 * 30 * 24 * 60 * 60 * 1000, | |
29238 "year": 365.2425 * 24 * 60 * 60 * 1000 | |
29239 }; | |
29240 | |
29241 // the allowed tick sizes, after 1 year we use | |
29242 // an integer algorithm | |
29243 | |
29244 var baseSpec = [ | |
29245 [1, "second"], [2, "second"], [5, "second"], [10, "second"], | |
29246 [30, "second"], | |
29247 [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], | |
29248 [30, "minute"], | |
29249 [1, "hour"], [2, "hour"], [4, "hour"], | |
29250 [8, "hour"], [12, "hour"], | |
29251 [1, "day"], [2, "day"], [3, "day"], | |
29252 [0.25, "month"], [0.5, "month"], [1, "month"], | |
29253 [2, "month"] | |
29254 ]; | |
29255 | |
29256 // we don't know which variant(s) we'll need yet, but generating both is | |
29257 // cheap | |
29258 | |
29259 var specMonths = baseSpec.concat([[3, "month"], [6, "month"], | |
29260 [1, "year"]]); | |
29261 var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], | |
29262 [1, "year"]]); | |
29263 | |
29264 function init(plot) { | |
29265 plot.hooks.processOptions.push(function (plot, options) { | |
29266 $.each(plot.getAxes(), function(axisName, axis) { | |
29267 | |
29268 var opts = axis.options; | |
29269 | |
29270 if (opts.mode == "time") { | |
29271 axis.tickGenerator = function(axis) { | |
29272 | |
29273 var ticks = []; | |
29274 var d = dateGenerator(axis.min, opts); | |
29275 var minSize = 0; | |
29276 | |
29277 // make quarter use a possibility if quarters are | |
29278 // mentioned in either of these options | |
29279 | |
29280 var spec = (opts.tickSize && opts.tickSize[1] === | |
29281 "quarter") || | |
29282 (opts.minTickSize && opts.minTickSize[1] === | |
29283 "quarter") ? specQuarters : specMonths; | |
29284 | |
29285 if (opts.minTickSize != null) { | |
29286 if (typeof opts.tickSize == "number") { | |
29287 minSize = opts.tickSize; | |
29288 } else { | |
29289 minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; | |
29290 } | |
29291 } | |
29292 | |
29293 for (var i = 0; i < spec.length - 1; ++i) { | |
29294 if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] | |
29295 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 | |
29296 && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { | |
29297 break; | |
29298 } | |
29299 } | |
29300 | |
29301 var size = spec[i][0]; | |
29302 var unit = spec[i][1]; | |
29303 | |
29304 // special-case the possibility of several years | |
29305 | |
29306 if (unit == "year") { | |
29307 | |
29308 // if given a minTickSize in years, just use it, | |
29309 // ensuring that it's an integer | |
29310 | |
29311 if (opts.minTickSize != null && opts.minTickSize[1] == "year") { | |
29312 size = Math.floor(opts.minTickSize[0]); | |
29313 } else { | |
29314 | |
29315 var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); | |
29316 var norm = (axis.delta / timeUnitSize.year) / magn; | |
29317 | |
29318 if (norm < 1.5) { | |
29319 size = 1; | |
29320 } else if (norm < 3) { | |
29321 size = 2; | |
29322 } else if (norm < 7.5) { | |
29323 size = 5; | |
29324 } else { | |
29325 size = 10; | |
29326 } | |
29327 | |
29328 size *= magn; | |
29329 } | |
29330 | |
29331 // minimum size for years is 1 | |
29332 | |
29333 if (size < 1) { | |
29334 size = 1; | |
29335 } | |
29336 } | |
29337 | |
29338 axis.tickSize = opts.tickSize || [size, unit]; | |
29339 var tickSize = axis.tickSize[0]; | |
29340 unit = axis.tickSize[1]; | |
29341 | |
29342 var step = tickSize * timeUnitSize[unit]; | |
29343 | |
29344 if (unit == "second") { | |
29345 d.setSeconds(floorInBase(d.getSeconds(), tickSize)); | |
29346 } else if (unit == "minute") { | |
29347 d.setMinutes(floorInBase(d.getMinutes(), tickSize)); | |
29348 } else if (unit == "hour") { | |
29349 d.setHours(floorInBase(d.getHours(), tickSize)); | |
29350 } else if (unit == "month") { | |
29351 d.setMonth(floorInBase(d.getMonth(), tickSize)); | |
29352 } else if (unit == "quarter") { | |
29353 d.setMonth(3 * floorInBase(d.getMonth() / 3, | |
29354 tickSize)); | |
29355 } else if (unit == "year") { | |
29356 d.setFullYear(floorInBase(d.getFullYear(), tickSize)); | |
29357 } | |
29358 | |
29359 // reset smaller components | |
29360 | |
29361 d.setMilliseconds(0); | |
29362 | |
29363 if (step >= timeUnitSize.minute) { | |
29364 d.setSeconds(0); | |
29365 } | |
29366 if (step >= timeUnitSize.hour) { | |
29367 d.setMinutes(0); | |
29368 } | |
29369 if (step >= timeUnitSize.day) { | |
29370 d.setHours(0); | |
29371 } | |
29372 if (step >= timeUnitSize.day * 4) { | |
29373 d.setDate(1); | |
29374 } | |
29375 if (step >= timeUnitSize.month * 2) { | |
29376 d.setMonth(floorInBase(d.getMonth(), 3)); | |
29377 } | |
29378 if (step >= timeUnitSize.quarter * 2) { | |
29379 d.setMonth(floorInBase(d.getMonth(), 6)); | |
29380 } | |
29381 if (step >= timeUnitSize.year) { | |
29382 d.setMonth(0); | |
29383 } | |
29384 | |
29385 var carry = 0; | |
29386 var v = Number.NaN; | |
29387 var prev; | |
29388 | |
29389 do { | |
29390 | |
29391 prev = v; | |
29392 v = d.getTime(); | |
29393 ticks.push(v); | |
29394 | |
29395 if (unit == "month" || unit == "quarter") { | |
29396 if (tickSize < 1) { | |
29397 | |
29398 // a bit complicated - we'll divide the | |
29399 // month/quarter up but we need to take | |
29400 // care of fractions so we don't end up in | |
29401 // the middle of a day | |
29402 | |
29403 d.setDate(1); | |
29404 var start = d.getTime(); | |
29405 d.setMonth(d.getMonth() + | |
29406 (unit == "quarter" ? 3 : 1)); | |
29407 var end = d.getTime(); | |
29408 d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); | |
29409 carry = d.getHours(); | |
29410 d.setHours(0); | |
29411 } else { | |
29412 d.setMonth(d.getMonth() + | |
29413 tickSize * (unit == "quarter" ? 3 : 1)); | |
29414 } | |
29415 } else if (unit == "year") { | |
29416 d.setFullYear(d.getFullYear() + tickSize); | |
29417 } else { | |
29418 d.setTime(v + step); | |
29419 } | |
29420 } while (v < axis.max && v != prev); | |
29421 | |
29422 return ticks; | |
29423 }; | |
29424 | |
29425 axis.tickFormatter = function (v, axis) { | |
29426 | |
29427 var d = dateGenerator(v, axis.options); | |
29428 | |
29429 // first check global format | |
29430 | |
29431 if (opts.timeformat != null) { | |
29432 return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); | |
29433 } | |
29434 | |
29435 // possibly use quarters if quarters are mentioned in | |
29436 // any of these places | |
29437 | |
29438 var useQuarters = (axis.options.tickSize && | |
29439 axis.options.tickSize[1] == "quarter") || | |
29440 (axis.options.minTickSize && | |
29441 axis.options.minTickSize[1] == "quarter"); | |
29442 | |
29443 var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; | |
29444 var span = axis.max - axis.min; | |
29445 var suffix = (opts.twelveHourClock) ? " %p" : ""; | |
29446 var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; | |
29447 var fmt; | |
29448 | |
29449 if (t < timeUnitSize.minute) { | |
29450 fmt = hourCode + ":%M:%S" + suffix; | |
29451 } else if (t < timeUnitSize.day) { | |
29452 if (span < 2 * timeUnitSize.day) { | |
29453 fmt = hourCode + ":%M" + suffix; | |
29454 } else { | |
29455 fmt = "%b %d " + hourCode + ":%M" + suffix; | |
29456 } | |
29457 } else if (t < timeUnitSize.month) { | |
29458 fmt = "%b %d"; | |
29459 } else if ((useQuarters && t < timeUnitSize.quarter) || | |
29460 (!useQuarters && t < timeUnitSize.year)) { | |
29461 if (span < timeUnitSize.year) { | |
29462 fmt = "%b"; | |
29463 } else { | |
29464 fmt = "%b %Y"; | |
29465 } | |
29466 } else if (useQuarters && t < timeUnitSize.year) { | |
29467 if (span < timeUnitSize.year) { | |
29468 fmt = "Q%q"; | |
29469 } else { | |
29470 fmt = "Q%q %Y"; | |
29471 } | |
29472 } else { | |
29473 fmt = "%Y"; | |
29474 } | |
29475 | |
29476 var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); | |
29477 | |
29478 return rt; | |
29479 }; | |
29480 } | |
29481 }); | |
29482 }); | |
29483 } | |
29484 | |
29485 $.plot.plugins.push({ | |
29486 init: init, | |
29487 options: options, | |
29488 name: 'time', | |
29489 version: '1.0' | |
29490 }); | |
29491 | |
29492 // Time-axis support used to be in Flot core, which exposed the | |
29493 // formatDate function on the plot object. Various plugins depend | |
29494 // on the function, so we need to re-expose it here. | |
29495 | |
29496 $.plot.formatDate = formatDate; | |
29497 $.plot.dateGenerator = dateGenerator; | |
29498 | |
29499 })(jQuery); | |
29500 /* | |
29501 * jquery.flot.tooltip | |
29502 * | |
29503 * description: easy-to-use tooltips for Flot charts | |
29504 * version: 0.6.7 | |
29505 * author: Krzysztof Urbas @krzysu [myviews.pl] | |
29506 * website: https://github.com/krzysu/flot.tooltip | |
29507 * | |
29508 * build on 2014-03-26 | |
29509 * released under MIT License, 2012 | |
29510 */ | |
29511 // IE8 polyfill for Array.indexOf | |
29512 if (!Array.prototype.indexOf) { | |
29513 Array.prototype.indexOf = function (searchElement, fromIndex) { | |
29514 if ( this === undefined || this === null ) { | |
29515 throw new TypeError( '"this" is null or not defined' ); | |
29516 } | |
29517 var length = this.length >>> 0; // Hack to convert object.length to a UInt32 | |
29518 fromIndex = +fromIndex || 0; | |
29519 if (Math.abs(fromIndex) === Infinity) { | |
29520 fromIndex = 0; | |
29521 } | |
29522 if (fromIndex < 0) { | |
29523 fromIndex += length; | |
29524 if (fromIndex < 0) { | |
29525 fromIndex = 0; | |
29526 } | |
29527 } | |
29528 | |
29529 for (;fromIndex < length; fromIndex++) { | |
29530 if (this[fromIndex] === searchElement) { | |
29531 return fromIndex; | |
29532 } | |
29533 } | |
29534 | |
29535 return -1; | |
29536 }; | |
29537 } | |
29538 | |
29539 (function ($) { | |
29540 | |
29541 // plugin options, default values | |
29542 var defaultOptions = { | |
29543 tooltip: false, | |
29544 tooltipOpts: { | |
29545 content: "%s | X: %x | Y: %y", | |
29546 // allowed templates are: | |
29547 // %s -> series label, | |
29548 // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), | |
29549 // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), | |
29550 // %x -> X value, | |
29551 // %y -> Y value, | |
29552 // %x.2 -> precision of X value, | |
29553 // %p -> percent | |
29554 xDateFormat: null, | |
29555 yDateFormat: null, | |
29556 monthNames: null, | |
29557 dayNames: null, | |
29558 shifts: { | |
29559 x: 10, | |
29560 y: 20 | |
29561 }, | |
29562 defaultTheme: true, | |
29563 | |
29564 // callbacks | |
29565 onHover: function(flotItem, $tooltipEl) {} | |
29566 } | |
29567 }; | |
29568 | |
29569 // object | |
29570 var FlotTooltip = function(plot) { | |
29571 | |
29572 // variables | |
29573 this.tipPosition = {x: 0, y: 0}; | |
29574 | |
29575 this.init(plot); | |
29576 }; | |
29577 | |
29578 // main plugin function | |
29579 FlotTooltip.prototype.init = function(plot) { | |
29580 | |
29581 var that = this; | |
29582 | |
29583 // detect other flot plugins | |
29584 var plotPluginsLength = $.plot.plugins.length; | |
29585 this.plotPlugins = []; | |
29586 | |
29587 if (plotPluginsLength) { | |
29588 for (var p = 0; p < plotPluginsLength; p++) { | |
29589 this.plotPlugins.push($.plot.plugins[p].name); | |
29590 } | |
29591 } | |
29592 | |
29593 plot.hooks.bindEvents.push(function (plot, eventHolder) { | |
29594 | |
29595 // get plot options | |
29596 that.plotOptions = plot.getOptions(); | |
29597 | |
29598 // if not enabled return | |
29599 if (that.plotOptions.tooltip === false || typeof that.plotOptions.tooltip === 'undefined') return; | |
29600 | |
29601 // shortcut to access tooltip options | |
29602 that.tooltipOptions = that.plotOptions.tooltipOpts; | |
29603 | |
29604 // create tooltip DOM element | |
29605 var $tip = that.getDomElement(); | |
29606 | |
29607 // bind event | |
29608 $( plot.getPlaceholder() ).bind("plothover", plothover); | |
29609 | |
29610 $(eventHolder).bind('mousemove', mouseMove); | |
29611 }); | |
29612 | |
29613 plot.hooks.shutdown.push(function (plot, eventHolder){ | |
29614 $(plot.getPlaceholder()).unbind("plothover", plothover); | |
29615 $(eventHolder).unbind("mousemove", mouseMove); | |
29616 }); | |
29617 | |
29618 function mouseMove(e){ | |
29619 var pos = {}; | |
29620 pos.x = e.pageX; | |
29621 pos.y = e.pageY; | |
29622 that.updateTooltipPosition(pos); | |
29623 } | |
29624 | |
29625 function plothover(event, pos, item) { | |
29626 var $tip = that.getDomElement(); | |
29627 if (item) { | |
29628 var tipText; | |
29629 | |
29630 // convert tooltip content template to real tipText | |
29631 tipText = that.stringFormat(that.tooltipOptions.content, item); | |
29632 | |
29633 $tip.html( tipText ); | |
29634 that.updateTooltipPosition({ x: pos.pageX, y: pos.pageY }); | |
29635 $tip.css({ | |
29636 left: that.tipPosition.x + that.tooltipOptions.shifts.x, | |
29637 top: that.tipPosition.y + that.tooltipOptions.shifts.y | |
29638 }) | |
29639 .show(); | |
29640 | |
29641 // run callback | |
29642 if(typeof that.tooltipOptions.onHover === 'function') { | |
29643 that.tooltipOptions.onHover(item, $tip); | |
29644 } | |
29645 } | |
29646 else { | |
29647 $tip.hide().html(''); | |
29648 } | |
29649 } | |
29650 }; | |
29651 | |
29652 /** | |
29653 * get or create tooltip DOM element | |
29654 * @return jQuery object | |
29655 */ | |
29656 FlotTooltip.prototype.getDomElement = function() { | |
29657 var $tip; | |
29658 | |
29659 if( $('#flotTip').length > 0 ){ | |
29660 $tip = $('#flotTip'); | |
29661 } | |
29662 else { | |
29663 $tip = $('<div />').attr('id', 'flotTip'); | |
29664 $tip.appendTo('body').hide().css({position: 'absolute'}); | |
29665 | |
29666 if(this.tooltipOptions.defaultTheme) { | |
29667 $tip.css({ | |
29668 'background': '#fff', | |
29669 'z-index': '21040',//***lchang | |
29670 'padding': '0.4em 0.6em', | |
29671 'border-radius': '0.5em', | |
29672 'font-size': '0.8em', | |
29673 'border': '1px solid #111', | |
29674 'display': 'none', | |
29675 'white-space': 'nowrap' | |
29676 }); | |
29677 } | |
29678 } | |
29679 | |
29680 return $tip; | |
29681 }; | |
29682 | |
29683 // as the name says | |
29684 FlotTooltip.prototype.updateTooltipPosition = function(pos) { | |
29685 var totalTipWidth = $("#flotTip").outerWidth() + this.tooltipOptions.shifts.x; | |
29686 var totalTipHeight = $("#flotTip").outerHeight() + this.tooltipOptions.shifts.y; | |
29687 if ((pos.x - $(window).scrollLeft()) > ($(window).innerWidth() - totalTipWidth)) { | |
29688 pos.x -= totalTipWidth; | |
29689 } | |
29690 if ((pos.y - $(window).scrollTop()) > ($(window).innerHeight() - totalTipHeight)) { | |
29691 pos.y -= totalTipHeight; | |
29692 } | |
29693 this.tipPosition.x = pos.x; | |
29694 this.tipPosition.y = pos.y; | |
29695 }; | |
29696 | |
29697 /** | |
29698 * core function, create tooltip content | |
29699 * @param {string} content - template with tooltip content | |
29700 * @param {object} item - Flot item | |
29701 * @return {string} real tooltip content for current item | |
29702 */ | |
29703 FlotTooltip.prototype.stringFormat = function(content, item) { | |
29704 | |
29705 var percentPattern = /%p\.{0,1}(\d{0,})/; | |
29706 var seriesPattern = /%s/; | |
29707 var xLabelPattern = /%lx/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded | |
29708 var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded | |
29709 var xPattern = /%x\.{0,1}(\d{0,})/; | |
29710 var yPattern = /%y\.{0,1}(\d{0,})/; | |
29711 var xPatternWithoutPrecision = "%x"; | |
29712 var yPatternWithoutPrecision = "%y"; | |
29713 | |
29714 var x, y; | |
29715 | |
29716 // for threshold plugin we need to read data from different place | |
29717 if (typeof item.series.threshold !== "undefined") { | |
29718 x = item.datapoint[0]; | |
29719 y = item.datapoint[1]; | |
29720 } else { | |
29721 x = item.series.data[item.dataIndex][0]; | |
29722 y = item.series.data[item.dataIndex][1]; | |
29723 } | |
29724 | |
29725 // I think this is only in case of threshold plugin | |
29726 if (item.series.label === null && item.series.originSeries) { | |
29727 item.series.label = item.series.originSeries.label; | |
29728 } | |
29729 | |
29730 // if it is a function callback get the content string | |
29731 if( typeof(content) === 'function' ) { | |
29732 content = content(item.series.label, x, y, item); | |
29733 } | |
29734 | |
29735 // percent match for pie charts | |
29736 if( typeof (item.series.percent) !== 'undefined' ) { | |
29737 content = this.adjustValPrecision(percentPattern, content, item.series.percent); | |
29738 } | |
29739 | |
29740 // series match | |
29741 if( typeof(item.series.label) !== 'undefined' ) { | |
29742 content = content.replace(seriesPattern, item.series.label); | |
29743 } | |
29744 else { | |
29745 //remove %s if label is undefined | |
29746 content = content.replace(seriesPattern, ""); | |
29747 } | |
29748 | |
29749 // x axis label match | |
29750 if( this.hasAxisLabel('xaxis', item) ) { | |
29751 content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel); | |
29752 } | |
29753 else { | |
29754 //remove %lx if axis label is undefined or axislabels plugin not present | |
29755 content = content.replace(xLabelPattern, ""); | |
29756 } | |
29757 | |
29758 // y axis label match | |
29759 if( this.hasAxisLabel('yaxis', item) ) { | |
29760 content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel); | |
29761 } | |
29762 else { | |
29763 //remove %ly if axis label is undefined or axislabels plugin not present | |
29764 content = content.replace(yLabelPattern, ""); | |
29765 } | |
29766 | |
29767 // time mode axes with custom dateFormat | |
29768 if(this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) { | |
29769 content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat)); | |
29770 } | |
29771 | |
29772 if(this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) { | |
29773 content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat)); | |
29774 } | |
29775 | |
29776 // set precision if defined | |
29777 if(typeof x === 'number') { | |
29778 content = this.adjustValPrecision(xPattern, content, x); | |
29779 } | |
29780 if(typeof y === 'number') { | |
29781 content = this.adjustValPrecision(yPattern, content, y); | |
29782 } | |
29783 | |
29784 // change x from number to given label, if given | |
29785 if(typeof item.series.xaxis.ticks !== 'undefined') { | |
29786 | |
29787 var ticks; | |
29788 if(this.hasRotatedXAxisTicks(item)) { | |
29789 // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks | |
29790 ticks = 'rotatedTicks'; | |
29791 } | |
29792 else { | |
29793 ticks = 'ticks'; | |
29794 } | |
29795 | |
29796 // see https://github.com/krzysu/flot.tooltip/issues/65 | |
29797 var tickIndex = item.dataIndex + item.seriesIndex; | |
29798 | |
29799 if(item.series.xaxis[ticks].length > tickIndex && !this.isTimeMode('xaxis', item)) | |
29800 content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label); | |
29801 } | |
29802 | |
29803 // change y from number to given label, if given | |
29804 if(typeof item.series.yaxis.ticks !== 'undefined') { | |
29805 for (var index in item.series.yaxis.ticks) { | |
29806 if (item.series.yaxis.ticks.hasOwnProperty(index)) { | |
29807 var value = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[index].label : item.series.yaxis.ticks[index].v; | |
29808 if (value === y) { | |
29809 content = content.replace(yPattern, item.series.yaxis.ticks[index].label); | |
29810 } | |
29811 } | |
29812 } | |
29813 } | |
29814 | |
29815 // if no value customization, use tickFormatter by default | |
29816 if(typeof item.series.xaxis.tickFormatter !== 'undefined') { | |
29817 //escape dollar | |
29818 content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\$/g, '$$')); | |
29819 } | |
29820 if(typeof item.series.yaxis.tickFormatter !== 'undefined') { | |
29821 //escape dollar | |
29822 content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\$/g, '$$')); | |
29823 } | |
29824 | |
29825 return content; | |
29826 }; | |
29827 | |
29828 // helpers just for readability | |
29829 FlotTooltip.prototype.isTimeMode = function(axisName, item) { | |
29830 return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time'); | |
29831 }; | |
29832 | |
29833 FlotTooltip.prototype.isXDateFormat = function(item) { | |
29834 return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null); | |
29835 }; | |
29836 | |
29837 FlotTooltip.prototype.isYDateFormat = function(item) { | |
29838 return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null); | |
29839 }; | |
29840 | |
29841 FlotTooltip.prototype.isCategoriesMode = function(axisName, item) { | |
29842 return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories'); | |
29843 }; | |
29844 | |
29845 // | |
29846 FlotTooltip.prototype.timestampToDate = function(tmst, dateFormat) { | |
29847 var theDate = new Date(tmst*1); | |
29848 return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames); | |
29849 }; | |
29850 | |
29851 // | |
29852 FlotTooltip.prototype.adjustValPrecision = function(pattern, content, value) { | |
29853 | |
29854 var precision; | |
29855 var matchResult = content.match(pattern); | |
29856 if( matchResult !== null ) { | |
29857 if(RegExp.$1 !== '') { | |
29858 precision = RegExp.$1; | |
29859 value = value.toFixed(precision); | |
29860 | |
29861 // only replace content if precision exists, in other case use thickformater | |
29862 content = content.replace(pattern, value); | |
29863 } | |
29864 } | |
29865 return content; | |
29866 }; | |
29867 | |
29868 // other plugins detection below | |
29869 | |
29870 // check if flot-axislabels plugin (https://github.com/markrcote/flot-axislabels) is used and that an axis label is given | |
29871 FlotTooltip.prototype.hasAxisLabel = function(axisName, item) { | |
29872 return (this.plotPlugins.indexOf('axisLabels') !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0); | |
29873 }; | |
29874 | |
29875 // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used | |
29876 FlotTooltip.prototype.hasRotatedXAxisTicks = function(item) { | |
29877 return ($.grep($.plot.plugins, function(p){ return p.name === "tickRotor"; }).length === 1 && typeof item.series.xaxis.rotatedTicks !== 'undefined'); | |
29878 }; | |
29879 | |
29880 // | |
29881 var init = function(plot) { | |
29882 new FlotTooltip(plot); | |
29883 }; | |
29884 | |
29885 // define Flot plugin | |
29886 $.plot.plugins.push({ | |
29887 init: init, | |
29888 options: defaultOptions, | |
29889 name: 'tooltip', | |
29890 version: '0.6.7' | |
29891 }); | |
29892 | |
29893 })(jQuery); | |
29894 // SIMILE is not used anymore (and messes with jQuery!) so it was removed | |
29895 // TimeplotLoader.load(GeoTemCoLoader.urlPrefix + 'lib/', GeoTemCoLoader.loadScripts); | |
29896 | |
29897 // ..but we still need (and use) the following defines, that where copied from there | |
29898 /* string.js */ | |
29899 String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,""); | |
29900 }; | |
29901 String.prototype.startsWith=function(A){return this.length>=A.length&&this.substr(0,A.length)==A; | |
29902 }; | |
29903 String.prototype.endsWith=function(A){return this.length>=A.length&&this.substr(this.length-A.length)==A; | |
29904 }; | |
29905 String.substitute=function(B,D){var A=""; | |
29906 var F=0; | |
29907 while(F<B.length-1){var C=B.indexOf("%",F); | |
29908 if(C<0||C==B.length-1){break; | |
29909 }else{if(C>F&&B.charAt(C-1)=="\\"){A+=B.substring(F,C-1)+"%"; | |
29910 F=C+1; | |
29911 }else{var E=parseInt(B.charAt(C+1)); | |
29912 if(isNaN(E)||E>=D.length){A+=B.substring(F,C+2); | |
29913 }else{A+=B.substring(F,C)+D[E].toString(); | |
29914 }F=C+2; | |
29915 }}}if(F<B.length){A+=B.substring(F); | |
29916 }return A; | |
29917 }; | |
29918 | |
29919 /* date-time.js */ | |
29920 SimileAjax=new Object(); | |
29921 SimileAjax.DateTime=new Object(); | |
29922 SimileAjax.DateTime.MILLISECOND=0; | |
29923 SimileAjax.DateTime.SECOND=1; | |
29924 SimileAjax.DateTime.MINUTE=2; | |
29925 SimileAjax.DateTime.HOUR=3; | |
29926 SimileAjax.DateTime.DAY=4; | |
29927 SimileAjax.DateTime.WEEK=5; | |
29928 SimileAjax.DateTime.MONTH=6; | |
29929 SimileAjax.DateTime.YEAR=7; | |
29930 SimileAjax.DateTime.DECADE=8; | |
29931 SimileAjax.DateTime.CENTURY=9; | |
29932 SimileAjax.DateTime.MILLENNIUM=10; | |
29933 SimileAjax.DateTime.EPOCH=-1; | |
29934 SimileAjax.DateTime.ERA=-2; | |
29935 | |
29936 SimileAjax.includeCssFile = function(doc, url) { | |
29937 var link = doc.createElement("link"); | |
29938 link.setAttribute("rel", "stylesheet"); | |
29939 link.setAttribute("type", "text/css"); | |
29940 link.setAttribute("href", url); | |
29941 doc.getElementsByTagName("head")[0].appendChild(link); | |
29942 }; | |
29943 /* | |
29944 * Tooltips.js | |
29945 * | |
29946 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
29947 * | |
29948 * This library is free software; you can redistribute it and/or | |
29949 * modify it under the terms of the GNU Lesser General Public | |
29950 * License as published by the Free Software Foundation; either | |
29951 * version 3 of the License, or (at your option) any later version. | |
29952 * | |
29953 * This library is distributed in the hope that it will be useful, | |
29954 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
29955 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
29956 * Lesser General Public License for more details. | |
29957 * | |
29958 * You should have received a copy of the GNU Lesser General Public | |
29959 * License along with this library; if not, write to the Free Software | |
29960 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
29961 * MA 02110-1301 USA | |
29962 */ | |
29963 | |
29964 /** | |
29965 * Tooltips JSON | |
29966 * GeoTemCo tooltips definition file | |
29967 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
29968 * @release 1.0 | |
29969 * @release date: 2012-07-27 | |
29970 * @version date: 2012-07-27 | |
29971 */ | |
29972 var Tooltips = { | |
29973 "en" : { | |
29974 "locationType" : "Location type", | |
29975 "selectLocationType" : "Select location type", | |
29976 "mapType" : "Background map", | |
29977 "selectMapType" : "Select background map", | |
29978 "selectOverlay" : "Select layer for spatial filtering", | |
29979 "overlays" : "Select layer", | |
29980 "mapSelectorTools" : "Map selector tools", | |
29981 "overlaySelector" : "Selection layer", | |
29982 "square" : "Square selection: Mouse down for the center and mouse move to set square bounds", | |
29983 "circle" : "Circle selection: Mouse down for the center and mouse move to set circle radius", | |
29984 "polygon" : "Polygon selection: Click to add vertex and double click to complete the polygon", | |
29985 "country" : "Country selection: Click inside the political borders of a country", | |
29986 "singleEntry" : "Only 1 entry available", | |
29987 "resultsLocation" : "with location information", | |
29988 "home" : "Reset map to initial view", | |
29989 "zoomIn" : "Zoom in", | |
29990 "zoomOut" : "Zoom out", | |
29991 "zoomSlider" : "Zoom slider", | |
29992 "dragSelection" : "Drag&Drop shape", | |
29993 "zoomSelection" : "Zoom into selection", | |
29994 "clearSelection" : "Clear selection", | |
29995 "contemporaryMap" : "Contemporary Map", | |
29996 "activateGeoLocation" : "Show my location", | |
29997 "deactivateGeoLocation" : "Hide my location", | |
29998 "mapOf" : "Map of", | |
29999 "close" : "Close", | |
30000 "genericBinning" : "delaunay", | |
30001 "squareBinning" : "square", | |
30002 "hexagonalBinning" : "hexagonal", | |
30003 "triangularBinning" : "triangular", | |
30004 "noBinning" : "none", | |
30005 "selectBinningType" : "Select aggregation type", | |
30006 "binningType" : "Aggregation type", | |
30007 "binningTooltip" : "Select the aggregation type for the data sources", | |
30008 "results" : "results", | |
30009 "result" : "result", | |
30010 "timeType" : "Time type", | |
30011 "timeUnit" : "Time unit:", | |
30012 "selectTimeType" : "Select time type", | |
30013 "timeAnimation" : "Animation", | |
30014 "resultsTime" : "with time information", | |
30015 "animationDisabled" : "Animation control (disabled)", | |
30016 "animationPlay" : "Animate selected time range", | |
30017 "animationPause" : "Pause animation", | |
30018 "leftHandle" : "Drag&Drop left border", | |
30019 "rightHandle" : "Drag&Drop right border", | |
30020 "dragTimeRange" : "Drag&Drop time range", | |
30021 "connectionsOn" : "Switch on time-dependent connections between map circles", | |
30022 "connectionsOff" : "Switch off time-dependent connections", | |
30023 "timeFeather" : "Adjust time range feather to smoothen map animations", | |
30024 "allResults" : "all", | |
30025 "pageInfo" : "Page PAGE_ID of PAGES_ID", | |
30026 "resultsInfo" : "RESULTS_FROM_ID-RESULTS_TO_ID of RESULTS_ID Results", | |
30027 "otherResults" : "others", | |
30028 "mapAggregation" : "Aggregation", | |
30029 "aggregation" : "Circle aggregation", | |
30030 "noAggregation" : "No circle aggregation", | |
30031 "showBoxTitle" : "Boundingbox", | |
30032 "showBbox" : "Shows given Boundingbox extension", | |
30033 "hideBbox" : "Hides given Boundingbox extension", | |
30034 "spaceHelp" : "A point on the map corresponds to one or more objects from the result list. ", | |
30035 "timeHelp" : "On the timeline are the search results sorted by year. You can choose different time-based categories as basis for the representation.", | |
30036 "selectTablePageItemsHelp" : "Click to select all rows of this page", | |
30037 "deselectTablePageItemsHelp" : "Click to deselect all rows of this page", | |
30038 "selectAllTableItemsHelp" : "Click to select all rows of the table", | |
30039 "deselectAllTableItemsHelp" : "Click to deselect all rows of the table", | |
30040 "filter" : "Filter", | |
30041 "filterSelectedItemsHelp" : "Filter the selected items", | |
30042 "inverseFilterSelectedItemsHelp" : "Apply an inverse filter on the selected items removing them from the views", | |
30043 "undoFilterSelection" : "Undo the last filter / inverse filter", | |
30044 "cancelSelection" : "Discard the current selection (all items appear as deselected)", | |
30045 "showSelectedHelp" : "Show only elements within the selection", | |
30046 "selectByTextHelp" : "Select elements that contain the given text", | |
30047 "showAllElementsHelp" : "Show all elements", | |
30048 "paginationFirsPageHelp" : "Show first page", | |
30049 "paginationPreviousPageHelp" : "Show previous page", | |
30050 "paginationNextPageHelp" : "Show next page", | |
30051 "paginationLastPageHelp" : "Show last page", | |
30052 "sortAZHelp" : "Sort table elements ascending according this column", | |
30053 "sortZAHelp" : "Sort table elements descending according this column", | |
30054 "paginationDropdownHelp" : "Select number of elements per page", | |
30055 "selectTimeUnit" : "Select Time Unit", | |
30056 "valueScale" : "Value Scale", | |
30057 "linearPlot" : "Linear Value Scale", | |
30058 "logarithmicPlot" : "Logarithmic Value Scale", | |
30059 "playButton" : "Animate Selected Range", | |
30060 "pauseButton" : "Pause Animation", | |
30061 "createNewFromSelectedHelp" : "Create new dataset from selected values", | |
30062 "removeDatasetHelp" : "Remove this dataset", | |
30063 "exportDatasetHelp" : "Export this dataset to a KML file", | |
30064 "invertSelectionHelp" : "Invert the current selection", | |
30065 "colorShapeDatasetHelp" : "change color or shape of dataset", | |
30066 "lockMap" : "lock the map in this state" | |
30067 }, | |
30068 "de" : { | |
30069 "locationType" : "Ortsfacette", | |
30070 "selectLocationType" : "Wähle Ortsfacette", | |
30071 "mapType" : "Kartentyp", | |
30072 "selectMapType" : "Wähle Kartentyp", | |
30073 "selectOverlay" : "Kartenauswahl für rämliches filtern", | |
30074 "overlays" : "Wähle layer", | |
30075 "mapSelectorTools" : "Bereichsauswahl", | |
30076 "overlaySelector" : "Selection layer", | |
30077 "square" : "Quadratauswahl: Maus ziehen und loslassen um Mittelpunkt und Seitenlänge des Quadrats zu bestimmen", | |
30078 "circle" : "Kreisauswahl: Maus ziehen und loslassen um Mittelpunkt und Radius des Kreises zu bestimmen", | |
30079 "polygon" : "Polygonauswahl: Mausklick zum Hinzufügen eines Eckpunktes, Doppelklick zum Fertigstellen", | |
30080 "country" : "Landauswahl: Mausklick innerhalb politischer Grenze eines Landes", | |
30081 "singleEntry" : "Nur 1 Eintrag vorhanden", | |
30082 "resultsLocation" : "mit Geoinformation", | |
30083 "home" : "Zurücksetzen zur initialen Sicht", | |
30084 "zoomIn" : "Vergrößern", | |
30085 "zoomOut" : "Verkleinern", | |
30086 "zoomSlider" : "Zoomregler", | |
30087 "dragSelection" : "Verschiebe Auswahl", | |
30088 "zoomSelection" : "Vergrößere Auswahl", | |
30089 "clearSelection" : "Entferne Auswahlbereich", | |
30090 "contemporaryMap" : "Aktuelle Weltkarte", | |
30091 "activateGeoLocation" : "Meinen Standort anzeigen", | |
30092 "deactivateGeoLocation" : "Meinen Standort ausblenden", | |
30093 "mapOf" : "Karte von", | |
30094 "close" : "Schliessen", | |
30095 "genericBinning" : "Generisch", | |
30096 "squareBinning" : "Quadrate", | |
30097 "hexagonalBinning" : "Hexagone", | |
30098 "triangularBinning" : "Dreiecke", | |
30099 "noBinning" : "Keine Bins", | |
30100 "selectBinningType" : "Wähle Binningart", | |
30101 "binningTooltip" : "W&aunl;hle die Binninart für die Datenquellen", | |
30102 "binningType" : "Binningart", | |
30103 "results" : "Resultate", | |
30104 "result" : "Resultat", | |
30105 "timeType" : "Zeitfacette", | |
30106 "timeUnit" : "Zeiteinheit", | |
30107 "selectTimeType" : "Wähle Zeitfacette", | |
30108 "timeAnimation" : "Animation", | |
30109 "resultsTime" : "mit Zeitinformation", | |
30110 "animationDisabled" : "Animationswerkzeug (deaktiviert)", | |
30111 "animationPlay" : "Animiere ausgewählten Zeitbereich", | |
30112 "animationPause" : "Animation anhalten", | |
30113 "leftHandle" : "Verschiebe linke Grenze", | |
30114 "rightHandle" : "Verschiebe rechte Grenze", | |
30115 "dragTimeRange" : "Verschiebe Zeitbereich", | |
30116 "connectionsOn" : "Aktiviere zeitabhängige Verbindungen zwischen Kreisen auf der Karte", | |
30117 "connectionsOff" : "Deaktiviere zeitabhängige Verbindungen", | |
30118 "timeFeather" : "Verändere Zeitbereichsübergänge zum Glätten der Animation", | |
30119 "pageInfo" : "Seite PAGE_ID von PAGES_ID", | |
30120 "resultsInfo" : "RESULTS_FROM_ID-RESULTS_TO_ID von RESULTS_ID Ergebnissen", | |
30121 "allResults" : "alle", | |
30122 "otherResults" : "sonstige", | |
30123 "mapAggregation" : "Aggregation", | |
30124 "aggregation" : "Kreise aggregiert", | |
30125 "noAggregation" : "Kreise nicht aggregiert", | |
30126 "showBbox" : "Geografische Ausdehnung anzeigen", | |
30127 "hideBbox" : "Geografische Ausdehnung ausblenden", | |
30128 "spaceHelp" : "Jeder Punkt auf der Karte entspricht einem oder mehreren Objekten der Ergebnisliste. Sie können verschiedene ortsbezogene Kategorien als Grundlage für die Darstellung wählen (Auswahlfeld <strong>Ortsfacette</strong>) und verschiedene Kartentypen. <br> Da es Objekte geben kann, die keine Ortsangabe in ihrer Beschreibung enthalten, ist die Menge der in der Karte dargestellten Objekte in der Regel kleiner als in der Ergebnisliste (Anzahl darstellbarer Objekte siehe rechts oben über der Karte). <br> Mit der Karte können Sie die Suchergebnisse weiter eingrenzen, indem Sie auf einen der Punkte klicken. Wählen Sie einen Ort aus und klicken Sie auf die kleine Lupe, um die Ergebnisliste so einzuschränken, dass nur noch die diesem Ort zugeordneten Objekte als Suchergebnis erscheinen. Mehr zur Karte im Benutzerhandbuch ...", | |
30129 "timeHelp" : "In der Zeitleiste sind die Suchergebnisse nach Jahren geordnet. Sie können verschiedene zeitbezogene Kategorien als Grundlage für die Darstellung wählen (Auswahlfeld <strong>Zeitfacette</strong>). <br> Da es Objekte geben kann, die keine Zeitangabe in ihrer Beschreibung enthalten, ist die Zahl der in der Zeitleiste dargestellten Objekte in der Regel kleiner als in der Ergebnisliste. Die Angabe über darstellbare Objekte finden Sie rechts über der Zeitleiste. <br>Mit der Zeitleiste können Sie die Suchergebnisse weiter eingrenzen. Wählen Sie ein Jahr oder einen Zeitraum durch Klicken und Ziehen und klicken Sie auf die kleine Lupe. Die Ergebnisliste zeigt nur noch die Objekte in diesem Zeitraum. Mehr zur Zeitleiste im Benutzerhandbuch ...", | |
30130 "selectTablePageItemsHelp" : "Click to select all rows of this page", | |
30131 "deselectTablePageItemsHelp" : "Click to deselect all rows of this page", | |
30132 "selectAllTableItemsHelp" : "Click to select all rows of the table", | |
30133 "deselectAllTableItemsHelp" : "Click to deselect all rows of the table", | |
30134 "filter" : "Filter", | |
30135 "filterSelectedItemsHelp" : "Filter the selected items", | |
30136 "inverseFilterSelectedItemsHelp" : "Apply an inverse filter on the selected items removing them from the views", | |
30137 "undoFilterSelection" : "Undo the last filter / inverse filter", | |
30138 "cancelSelection" : "Discard the current selection (all items appear as deselected)", | |
30139 "showSelectedHelp" : "Show only elements within the selection", | |
30140 "selectByTextHelp" : "Select elements that contain the given text", | |
30141 "showAllElementsHelp" : "Show all elements", | |
30142 "paginationFirsPageHelp" : "Show first page", | |
30143 "paginationPreviousPageHelp" : "Show previous page", | |
30144 "paginationNextPageHelp" : "Show next page", | |
30145 "paginationLastPageHelp" : "Show last page", | |
30146 "sortAZHelp" : "Sort table elements ascending according this column", | |
30147 "sortZAHelp" : "Sort table elements descending according this column", | |
30148 "paginationDropdownHelp" : "Select number of elements per page", | |
30149 "selectTimeUnit" : "Wähle Zeitinervalle", | |
30150 "valueScale" : "Value Scale", | |
30151 "linearPlot" : "Linear Value Scale", | |
30152 "logarithmicPlot" : "Logarithmic Value Scale", | |
30153 "playButton" : "Animate Selected Range", | |
30154 "pauseButton" : "Pause Animation", | |
30155 "createNewFromSelectedHelp" : "Erstelle neuen Datensatz aus den selektierten Einträgen", | |
30156 "removeDatasetHelp" : "Diesen Datensatz entfernen", | |
30157 "exportDatasetHelp" : "Diesen Datensatz in KML Datei exportieren", | |
30158 "invertSelectionHelp" : "Jetzige Selektion umkehren", | |
30159 "colorShapeDatasetHelp" : "Farbe oder Form des Datensatzes ändern", | |
30160 "lockMap" : "Karte in diesem Zustand halten." | |
30161 } | |
30162 } | |
30163 /* | |
30164 * GeoTemConfig.js | |
30165 * | |
30166 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
30167 * | |
30168 * This library is free software; you can redistribute it and/or | |
30169 * modify it under the terms of the GNU Lesser General Public | |
30170 * License as published by the Free Software Foundation; either | |
30171 * version 3 of the License, or (at your option) any later version. | |
30172 * | |
30173 * This library is distributed in the hope that it will be useful, | |
30174 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
30175 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
30176 * Lesser General Public License for more details. | |
30177 * | |
30178 * You should have received a copy of the GNU Lesser General Public | |
30179 * License along with this library; if not, write to the Free Software | |
30180 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
30181 * MA 02110-1301 USA | |
30182 */ | |
30183 | |
30184 /** | |
30185 * @class GeoTemConfig | |
30186 * Global GeoTemCo Configuration File | |
30187 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
30188 * @release 1.0 | |
30189 * @release date: 2012-07-27 | |
30190 * @version date: 2012-07-27 | |
30191 */ | |
30192 | |
30193 | |
30194 // credits: user76888, The Digital Gabeg (http://stackoverflow.com/questions/1539367) | |
30195 $.fn.cleanWhitespace = function() { | |
30196 textNodes = this.contents().filter( function() { | |
30197 return (this.nodeType == 3 && !/\S/.test(this.nodeValue)); | |
30198 }).remove(); | |
30199 return this; | |
30200 }; | |
30201 | |
30202 GeoTemConfig = { | |
30203 debug : false, //show debug output (esp. regarding corrupt datasets) | |
30204 incompleteData : true, // show/hide data with either temporal or spatial metadata | |
30205 inverseFilter : true, // if inverse filtering is offered | |
30206 mouseWheelZoom : true, // enable/disable zoom with mouse wheel on map & timeplot | |
30207 language : 'en', // default language of GeoTemCo | |
30208 allowFilter : true, // if filtering should be allowed | |
30209 highlightEvents : true, // if updates after highlight events | |
30210 selectionEvents : true, // if updates after selection events | |
30211 tableExportDataset : true, // export dataset to KML | |
30212 allowCustomColoring : false, // if DataObjects can have an own color (useful for weighted coloring) | |
30213 allowUserShapeAndColorChange: false, // if the user can change the shapes and color of datasets | |
30214 // this turns MapConfig.useGraphics auto-on, but uses circles as default | |
30215 loadColorFromDataset : false, // if DataObject color should be loaded automatically (from column "color") | |
30216 allowColumnRenaming : true, | |
30217 //proxy : 'php/proxy.php?address=', //set this if a HTTP proxy shall be used (e.g. to bypass X-Domain problems) | |
30218 //colors for several datasets; rgb1 will be used for selected objects, rgb0 for unselected | |
30219 colors : [{//blue /***lchang changed the color set***/ | |
30220 r1 : 0, | |
30221 g1 : 128, | |
30222 b1 : 255, | |
30223 r0 : 205, | |
30224 g0 : 230, | |
30225 b0 : 255 | |
30226 },{//red | |
30227 r1 : 255, | |
30228 g1 : 84, | |
30229 b1 : 22, | |
30230 r0 : 255, | |
30231 g0 : 218, | |
30232 b0 : 205 | |
30233 }, {//purple | |
30234 r1 : 132, | |
30235 g1 : 0, | |
30236 b1 : 255, | |
30237 r0 : 231, | |
30238 g0 : 205, | |
30239 b0 : 255 | |
30240 }, {//green | |
30241 r1 : 0, | |
30242 g1 : 225, | |
30243 b1 : 116, | |
30244 r0 : 180, | |
30245 g0 : 225, | |
30246 b0 : 204 | |
30247 }, {//yellow | |
30248 r1 : 255, | |
30249 g1 : 191, | |
30250 b1 : 0, | |
30251 r0 : 255, | |
30252 g0 : 243, | |
30253 b0 : 205 | |
30254 }] | |
30255 | |
30256 } | |
30257 | |
30258 GeoTemConfig.ie = false; | |
30259 GeoTemConfig.ie8 = false; | |
30260 | |
30261 GeoTemConfig.independentMapId = 0; | |
30262 GeoTemConfig.independentTimeId = 0; | |
30263 | |
30264 if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { | |
30265 GeoTemConfig.ie = true; | |
30266 var ieversion = new Number(RegExp.$1); | |
30267 if (ieversion == 8) { | |
30268 GeoTemConfig.ie8 = true; | |
30269 } | |
30270 } | |
30271 | |
30272 GeoTemConfig.getIndependentId = function(target){ | |
30273 if( target == 'map' ){ | |
30274 return ++GeoTemConfig.independentMapId; | |
30275 } | |
30276 if( target == 'time' ){ | |
30277 return ++GeoTemConfig.independentTimeId; | |
30278 } | |
30279 return 0; | |
30280 }; | |
30281 | |
30282 GeoTemConfig.setHexColor = function(hex,index,fill){ | |
30283 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); | |
30284 if( fill ){ | |
30285 GeoTemConfig.colors[index].r0 = parseInt(result[1], 16); | |
30286 GeoTemConfig.colors[index].g0 = parseInt(result[2], 16); | |
30287 GeoTemConfig.colors[index].b0 = parseInt(result[3], 16); | |
30288 } | |
30289 else { | |
30290 GeoTemConfig.colors[index].r1 = parseInt(result[1], 16); | |
30291 GeoTemConfig.colors[index].g1 = parseInt(result[2], 16); | |
30292 GeoTemConfig.colors[index].b1 = parseInt(result[3], 16); | |
30293 } | |
30294 } | |
30295 | |
30296 GeoTemConfig.setRgbColor = function(r,g,b,index,fill){ | |
30297 if( fill ){ | |
30298 GeoTemConfig.colors[index].r0 = r; | |
30299 GeoTemConfig.colors[index].g0 = g; | |
30300 GeoTemConfig.colors[index].b0 = b; | |
30301 } | |
30302 else { | |
30303 GeoTemConfig.colors[index].r1 = r; | |
30304 GeoTemConfig.colors[index].g1 = g; | |
30305 GeoTemConfig.colors[index].b1 = b; | |
30306 } | |
30307 } | |
30308 | |
30309 GeoTemConfig.configure = function(urlPrefix) { | |
30310 GeoTemConfig.urlPrefix = urlPrefix; | |
30311 GeoTemConfig.path = GeoTemConfig.urlPrefix + "images/"; | |
30312 } | |
30313 | |
30314 GeoTemConfig.applySettings = function(settings) { | |
30315 $.extend(this, settings); | |
30316 }; | |
30317 function HSVtoRGB(h, s, v) { | |
30318 var r, g, b, i, f, p, q, t; | |
30319 if (h && s === undefined && v === undefined) { | |
30320 s = h.s, v = h.v, h = h.h; | |
30321 } | |
30322 i = Math.floor(h * 6); | |
30323 f = h * 6 - i; | |
30324 p = v * (1 - s); | |
30325 q = v * (1 - f * s); | |
30326 t = v * (1 - (1 - f) * s); | |
30327 switch (i % 6) { | |
30328 case 0: r = v, g = t, b = p; break; | |
30329 case 1: r = q, g = v, b = p; break; | |
30330 case 2: r = p, g = v, b = t; break; | |
30331 case 3: r = p, g = q, b = v; break; | |
30332 case 4: r = t, g = p, b = v; break; | |
30333 case 5: r = v, g = p, b = q; break; | |
30334 } | |
30335 return { | |
30336 r: Math.floor(r * 255), | |
30337 g: Math.floor(g * 255), | |
30338 b: Math.floor(b * 255) | |
30339 }; | |
30340 } | |
30341 //Keeps track of how many colors where assigned yet. | |
30342 GeoTemConfig.assignedColorCount = 0; | |
30343 GeoTemConfig.getColor = function(id){ | |
30344 if (typeof GeoTemConfig.datasets[id].color === "undefined"){ | |
30345 var color; | |
30346 | |
30347 while (true){ | |
30348 if( GeoTemConfig.colors.length <= GeoTemConfig.assignedColorCount ){ | |
30349 var h=Math.random(); | |
30350 var rgb=HSVtoRGB(h,1.0,1.0); | |
30351 var rgb0=HSVtoRGB(h,0.2,1.0); | |
30352 color = { | |
30353 r1 : rgb.r, | |
30354 g1 : rgb.g, | |
30355 b1 : rgb.b, | |
30356 r0 : rgb0.r, | |
30357 g0 : rgb0.g, | |
30358 b0 : rgb0.b | |
30359 }; | |
30360 /* | |
30361 color = { | |
30362 r1 : Math.floor((Math.random()*255)+1), | |
30363 g1 : Math.floor((Math.random()*255)+1), | |
30364 b1 : Math.floor((Math.random()*255)+1), | |
30365 r0 : 230, | |
30366 g0 : 230, | |
30367 b0 : 230 | |
30368 };*/ | |
30369 } else | |
30370 color = GeoTemConfig.colors[GeoTemConfig.assignedColorCount]; | |
30371 | |
30372 //make sure that no other dataset has this color | |
30373 //TODO: one could also check that they are not too much alike | |
30374 var found = false; | |
30375 for (var i = 0; i < GeoTemConfig.datasets.length; i++){ | |
30376 var dataset = GeoTemConfig.datasets[i]; | |
30377 | |
30378 if (typeof dataset.color === "undefined") | |
30379 continue; | |
30380 | |
30381 if ( (dataset.color.r1 == color.r1) && | |
30382 (dataset.color.g1 == color.g1) && | |
30383 (dataset.color.b1 == color.b1) ){ | |
30384 found = true; | |
30385 break; | |
30386 } | |
30387 } | |
30388 if (found === true){ | |
30389 //***lchang: GeoTemConfig.colors.length is never <= GeoTemConfig.assignedColorCount, so the GeoTemConfig.assignedColorCount never changes, and infinite loops occurs | |
30390 GeoTemConfig.assignedColorCount++; | |
30391 if( GeoTemConfig.colors.length <= GeoTemConfig.assignedColorCount ){ | |
30392 //next time skip over this color | |
30393 //GeoTemConfig.assignedColorCount++;//***lchang | |
30394 } | |
30395 continue; | |
30396 } else { | |
30397 GeoTemConfig.colors.push(color); | |
30398 break; | |
30399 } | |
30400 } | |
30401 GeoTemConfig.datasets[id].color = color; | |
30402 | |
30403 GeoTemConfig.assignedColorCount++; | |
30404 } | |
30405 return GeoTemConfig.datasets[id].color; | |
30406 }; | |
30407 | |
30408 GeoTemConfig.getAverageDatasetColor = function(id, objects){ | |
30409 var c = new Object(); | |
30410 var datasetColor = GeoTemConfig.getColor(id); | |
30411 c.r0 = datasetColor.r0; | |
30412 c.g0 = datasetColor.g0; | |
30413 c.b0 = datasetColor.b0; | |
30414 c.r1 = datasetColor.r1; | |
30415 c.g1 = datasetColor.g1; | |
30416 c.b1 = datasetColor.b1; | |
30417 if (!GeoTemConfig.allowCustomColoring) | |
30418 return c; | |
30419 if (objects.length == 0) | |
30420 return c; | |
30421 var avgColor = new Object(); | |
30422 avgColor.r0 = 0; | |
30423 avgColor.g0 = 0; | |
30424 avgColor.b0 = 0; | |
30425 avgColor.r1 = 0; | |
30426 avgColor.g1 = 0; | |
30427 avgColor.b1 = 0; | |
30428 | |
30429 $(objects).each(function(){ | |
30430 if (this.hasColorInformation){ | |
30431 avgColor.r0 += this.color.r0; | |
30432 avgColor.g0 += this.color.g0; | |
30433 avgColor.b0 += this.color.b0; | |
30434 avgColor.r1 += this.color.r1; | |
30435 avgColor.g1 += this.color.g1; | |
30436 avgColor.b1 += this.color.b1; | |
30437 } else { | |
30438 avgColor.r0 += datasetColor.r0; | |
30439 avgColor.g0 += datasetColor.g0; | |
30440 avgColor.b0 += datasetColor.b0; | |
30441 avgColor.r1 += datasetColor.r1; | |
30442 avgColor.g1 += datasetColor.g1; | |
30443 avgColor.b1 += datasetColor.b1; | |
30444 } | |
30445 }); | |
30446 | |
30447 c.r0 = Math.floor(avgColor.r0/objects.length); | |
30448 c.g0 = Math.floor(avgColor.g0/objects.length); | |
30449 c.b0 = Math.floor(avgColor.b0/objects.length); | |
30450 c.r1 = Math.floor(avgColor.r1/objects.length); | |
30451 c.g1 = Math.floor(avgColor.g1/objects.length); | |
30452 c.b1 = Math.floor(avgColor.b1/objects.length); | |
30453 | |
30454 return c; | |
30455 }; | |
30456 | |
30457 GeoTemConfig.getString = function(field) { | |
30458 if ( typeof Tooltips[GeoTemConfig.language] == 'undefined') { | |
30459 GeoTemConfig.language = 'en'; | |
30460 } | |
30461 return Tooltips[GeoTemConfig.language][field]; | |
30462 } | |
30463 /** | |
30464 * returns the actual mouse position | |
30465 * @param {Event} e the mouseevent | |
30466 * @return the top and left position on the screen | |
30467 */ | |
30468 GeoTemConfig.getMousePosition = function(e) { | |
30469 if (!e) { | |
30470 e = window.event; | |
30471 } | |
30472 var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ? window.document.documentElement : window.document.body; | |
30473 return { | |
30474 top : e.pageY ? e.pageY : e.clientY, | |
30475 left : e.pageX ? e.pageX : e.clientX | |
30476 }; | |
30477 } | |
30478 /** | |
30479 * returns the json object of the file from the given url | |
30480 * @param {String} url the url of the file to load | |
30481 * @return json object of given file | |
30482 */ | |
30483 GeoTemConfig.getJson = function(url) { | |
30484 var data; | |
30485 $.ajax({ | |
30486 url : url, | |
30487 async : false, | |
30488 dataType : 'json', | |
30489 success : function(json) { | |
30490 data = json; | |
30491 } | |
30492 }); | |
30493 return data; | |
30494 } | |
30495 | |
30496 GeoTemConfig.mergeObjects = function(set1, set2) { | |
30497 var inside = []; | |
30498 var newSet = []; | |
30499 for (var i = 0; i < GeoTemConfig.datasets.length; i++){ | |
30500 inside.push([]); | |
30501 newSet.push([]); | |
30502 } | |
30503 for (var i = 0; i < set1.length; i++) { | |
30504 for (var j = 0; j < set1[i].length; j++) { | |
30505 inside[i][set1[i][j].index] = true; | |
30506 newSet[i].push(set1[i][j]); | |
30507 } | |
30508 } | |
30509 for (var i = 0; i < set2.length; i++) { | |
30510 for (var j = 0; j < set2[i].length; j++) { | |
30511 if (!inside[i][set2[i][j].index]) { | |
30512 newSet[i].push(set2[i][j]); | |
30513 } | |
30514 } | |
30515 } | |
30516 return newSet; | |
30517 }; | |
30518 | |
30519 GeoTemConfig.datasets = []; | |
30520 | |
30521 GeoTemConfig.addDataset = function(newDataset){ | |
30522 GeoTemConfig.datasets.push(newDataset); | |
30523 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
30524 }; | |
30525 | |
30526 GeoTemConfig.addDatasets = function(newDatasets){ | |
30527 $(newDatasets).each(function(){ | |
30528 GeoTemConfig.datasets.push(this); | |
30529 }); | |
30530 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
30531 }; | |
30532 | |
30533 GeoTemConfig.removeDataset = function(index){ | |
30534 GeoTemConfig.datasets.splice(index,1); | |
30535 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
30536 }; | |
30537 | |
30538 /** | |
30539 * converts the csv-file into json-format | |
30540 * | |
30541 * @param {String} | |
30542 * text | |
30543 */ | |
30544 GeoTemConfig.convertCsv = function(text){ | |
30545 /* convert here from CSV to JSON */ | |
30546 var json = []; | |
30547 /* define expected csv table headers (first line) */ | |
30548 var expectedHeaders = new Array("Name","Address","Description","Longitude","Latitude","TimeStamp","TimeSpan:begin","TimeSpan:end","weight"); | |
30549 /* convert csv string to array of arrays using ucsv library */ | |
30550 var csvArray = CSV.csvToArray(text); | |
30551 /* get real used table headers from csv file (first line) */ | |
30552 var usedHeaders = csvArray[0]; | |
30553 /* loop outer array, begin with second line */ | |
30554 for (var i = 1; i < csvArray.length; i++) { | |
30555 var innerArray = csvArray[i]; | |
30556 var dataObject = new Object(); | |
30557 var tableContent = new Object(); | |
30558 /* exclude lines with no content */ | |
30559 var hasContent = false; | |
30560 for (var j = 0; j < innerArray.length; j++) { | |
30561 if (typeof innerArray[j] !== "undefined"){ | |
30562 if (typeof innerArray[j] === "string"){ | |
30563 if (innerArray[j].length > 0) | |
30564 hasContent = true; | |
30565 } else { | |
30566 hasContent = true; | |
30567 } | |
30568 } | |
30569 | |
30570 if (hasContent === true) | |
30571 break; | |
30572 } | |
30573 if (hasContent === false) | |
30574 continue; | |
30575 /* loop inner array */ | |
30576 for (var j = 0; j < innerArray.length; j++) { | |
30577 /* Name */ | |
30578 if (usedHeaders[j] == expectedHeaders[0]) { | |
30579 dataObject["name"] = ""+innerArray[j]; | |
30580 tableContent["name"] = ""+innerArray[j]; | |
30581 } | |
30582 /* Address */ | |
30583 else if (usedHeaders[j] == expectedHeaders[1]) { | |
30584 dataObject["place"] = ""+innerArray[j]; | |
30585 tableContent["place"] = ""+innerArray[j]; | |
30586 } | |
30587 /* Description */ | |
30588 else if (usedHeaders[j] == expectedHeaders[2]) { | |
30589 dataObject["description"] = ""+innerArray[j]; | |
30590 tableContent["description"] = ""+innerArray[j]; | |
30591 } | |
30592 /* TimeStamp */ | |
30593 else if (usedHeaders[j] == expectedHeaders[5]) { | |
30594 dataObject["time"] = ""+innerArray[j]; | |
30595 } | |
30596 /* TimeSpan:begin */ | |
30597 else if (usedHeaders[j] == expectedHeaders[6]) { | |
30598 tableContent["TimeSpan:begin"] = ""+innerArray[j]; | |
30599 } | |
30600 /* TimeSpan:end */ | |
30601 else if (usedHeaders[j] == expectedHeaders[7]) { | |
30602 tableContent["TimeSpan:end"] = ""+innerArray[j]; | |
30603 } | |
30604 /* weight */ | |
30605 else if (usedHeaders[j] == expectedHeaders[8]) { | |
30606 dataObject["weight"] = ""+innerArray[j]; | |
30607 } | |
30608 /* Longitude */ | |
30609 else if (usedHeaders[j] == expectedHeaders[3]) { | |
30610 dataObject["lon"] = parseFloat(innerArray[j]); | |
30611 } | |
30612 /* Latitude */ | |
30613 else if (usedHeaders[j] == expectedHeaders[4]) { | |
30614 dataObject["lat"] = parseFloat(innerArray[j]); | |
30615 } | |
30616 else { | |
30617 var header = new String(usedHeaders[j]); | |
30618 //remove leading and trailing Whitespace | |
30619 header = $.trim(header); | |
30620 tableContent[header] = ""+innerArray[j]; | |
30621 } | |
30622 } | |
30623 | |
30624 dataObject["tableContent"] = tableContent; | |
30625 | |
30626 json.push(dataObject); | |
30627 } | |
30628 | |
30629 return json; | |
30630 }; | |
30631 | |
30632 /** | |
30633 * returns the xml dom object of the file from the given url | |
30634 * @param {String} url the url of the file to load | |
30635 * @return xml dom object of given file | |
30636 */ | |
30637 GeoTemConfig.getKml = function(url,asyncFunc) { | |
30638 var data; | |
30639 var async = false; | |
30640 if( asyncFunc ){ | |
30641 async = true; | |
30642 } | |
30643 $.ajax({ | |
30644 url : url, | |
30645 async : async, | |
30646 dataType : 'xml', | |
30647 success : function(xml) { | |
30648 if( asyncFunc ){ | |
30649 asyncFunc(xml); | |
30650 } | |
30651 else { | |
30652 data = xml; | |
30653 } | |
30654 } | |
30655 }); | |
30656 if( !async ){ | |
30657 return data; | |
30658 } | |
30659 } | |
30660 | |
30661 /** | |
30662 * returns an array of all xml dom object of the kmls | |
30663 * found in the zip file from the given url | |
30664 * | |
30665 * can only be used with asyncFunc (because of browser | |
30666 * constraints regarding arraybuffer) | |
30667 * | |
30668 * @param {String} url the url of the file to load | |
30669 * @return xml dom object of given file | |
30670 */ | |
30671 GeoTemConfig.getKmz = function(url,asyncFunc) { | |
30672 var kmlDom = new Array(); | |
30673 | |
30674 var async = true; | |
30675 if( !asyncFunc ){ | |
30676 //if no asyncFunc is given return an empty array | |
30677 return kmlDom; | |
30678 } | |
30679 | |
30680 //use XMLHttpRequest as "arraybuffer" is not | |
30681 //supported in jQuery native $.get | |
30682 var req = new XMLHttpRequest(); | |
30683 req.open("GET",url,async); | |
30684 req.responseType = "arraybuffer"; | |
30685 req.onload = function() { | |
30686 var zip = new JSZip(); | |
30687 zip.load(req.response, {base64:false}); | |
30688 var kmlFiles = zip.file(new RegExp("kml$")); | |
30689 | |
30690 $(kmlFiles).each(function(){ | |
30691 var kml = this; | |
30692 if (kml.data != null) { | |
30693 kmlDom.push($.parseXML(kml.data)); | |
30694 } | |
30695 }); | |
30696 | |
30697 asyncFunc(kmlDom); | |
30698 }; | |
30699 req.send(); | |
30700 }; | |
30701 | |
30702 /** | |
30703 * returns the JSON "object" | |
30704 * from the csv file from the given url | |
30705 * @param {String} url the url of the file to load | |
30706 * @return xml dom object of given file | |
30707 */ | |
30708 GeoTemConfig.getCsv = function(url,asyncFunc) { | |
30709 var async = false; | |
30710 if( asyncFunc ){ | |
30711 async = true; | |
30712 } | |
30713 | |
30714 //use XMLHttpRequest as synchronous behaviour | |
30715 //is not supported in jQuery native $.get | |
30716 var req = new XMLHttpRequest(); | |
30717 req.open("GET",url,async); | |
30718 //can only be set on asynchronous now | |
30719 //req.responseType = "text"; | |
30720 var json; | |
30721 req.onload = function() { | |
30722 json = GeoTemConfig.convertCsv(req.response); | |
30723 if( asyncFunc ) | |
30724 asyncFunc(json); | |
30725 }; | |
30726 req.send(); | |
30727 | |
30728 if( !async ){ | |
30729 return json; | |
30730 } | |
30731 }; | |
30732 | |
30733 /** | |
30734 * returns a Date and a SimileAjax.DateTime granularity value for a given XML time | |
30735 * @param {String} xmlTime the XML time as String | |
30736 * @return JSON object with a Date and a SimileAjax.DateTime granularity | |
30737 */ | |
30738 GeoTemConfig.getTimeData = function(xmlTime) { | |
30739 if (!xmlTime) | |
30740 return; | |
30741 var dateData; | |
30742 try { | |
30743 var bc = false; | |
30744 if (xmlTime.startsWith("-")) { | |
30745 bc = true; | |
30746 xmlTime = xmlTime.substring(1); | |
30747 } | |
30748 var timeSplit = xmlTime.split("T"); | |
30749 var timeData = timeSplit[0].split("-"); | |
30750 for (var i = 0; i < timeData.length; i++) { | |
30751 parseInt(timeData[i]); | |
30752 } | |
30753 if (bc) { | |
30754 timeData[0] = "-" + timeData[0]; | |
30755 } | |
30756 if (timeSplit.length == 1) { | |
30757 dateData = timeData; | |
30758 } else { | |
30759 var dayData; | |
30760 if (timeSplit[1].indexOf("Z") != -1) { | |
30761 dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("Z") - 1).split(":"); | |
30762 } else { | |
30763 dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("+") - 1).split(":"); | |
30764 } | |
30765 for (var i = 0; i < timeData.length; i++) { | |
30766 parseInt(dayData[i]); | |
30767 } | |
30768 dateData = timeData.concat(dayData); | |
30769 } | |
30770 } catch (exception) { | |
30771 return null; | |
30772 } | |
30773 var date, granularity; | |
30774 if (dateData.length == 6) { | |
30775 granularity = SimileAjax.DateTime.SECOND; | |
30776 date = new Date(Date.UTC(dateData[0], dateData[1] - 1, dateData[2], dateData[3], dateData[4], dateData[5])); | |
30777 } else if (dateData.length == 3) { | |
30778 granularity = SimileAjax.DateTime.DAY; | |
30779 date = new Date(Date.UTC(dateData[0], dateData[1] - 1, dateData[2])); | |
30780 } else if (dateData.length == 2) { | |
30781 granularity = SimileAjax.DateTime.MONTH; | |
30782 date = new Date(Date.UTC(dateData[0], dateData[1] - 1, 1)); | |
30783 } else if (dateData.length == 1) { | |
30784 granularity = SimileAjax.DateTime.YEAR; | |
30785 date = new Date(Date.UTC(dateData[0], 0, 1)); | |
30786 } | |
30787 if (timeData[0] && timeData[0] < 100) { | |
30788 date.setFullYear(timeData[0]); | |
30789 } | |
30790 | |
30791 //check data validity; | |
30792 var isValidDate = true; | |
30793 if ( date instanceof Date ) { | |
30794 if ( isNaN( date.getTime() ) ) | |
30795 isValidDate = false; | |
30796 } else | |
30797 isValidDate = false; | |
30798 | |
30799 if (!isValidDate){ | |
30800 if ((GeoTemConfig.debug)&&(typeof console !== "undefined")) | |
30801 console.error(xmlTime + " is no valid time format"); | |
30802 return null; | |
30803 } | |
30804 | |
30805 return { | |
30806 date : date, | |
30807 granularity : granularity | |
30808 }; | |
30809 } | |
30810 /** | |
30811 * converts a JSON array into an array of data objects | |
30812 * @param {JSON} JSON a JSON array of data items | |
30813 * @return an array of data objects | |
30814 */ | |
30815 GeoTemConfig.loadJson = function(JSON) { | |
30816 var mapTimeObjects = []; | |
30817 var runningIndex = 0; | |
30818 for (var i in JSON ) { | |
30819 try { | |
30820 var item = JSON[i]; | |
30821 var index = item.index || item.id || runningIndex++; | |
30822 var name = item.name || ""; | |
30823 var description = item.description || ""; | |
30824 var tableContent = item.tableContent || []; | |
30825 var locations = []; | |
30826 if (item.location instanceof Array) { | |
30827 for (var j = 0; j < item.location.length; j++) { | |
30828 var place = item.location[j].place || "unknown"; | |
30829 var lon = item.location[j].lon; | |
30830 var lat = item.location[j].lat; | |
30831 if ((typeof lon === "undefined" || typeof lat === "undefined" || isNaN(lon) || isNaN(lat) ) && !GeoTemConfig.incompleteData) { | |
30832 throw "e"; | |
30833 } | |
30834 locations.push({ | |
30835 longitude : lon, | |
30836 latitude : lat, | |
30837 place : place | |
30838 }); | |
30839 } | |
30840 } else { | |
30841 var place = item.place || "unknown"; | |
30842 var lon = item.lon; | |
30843 var lat = item.lat; | |
30844 if ((typeof lon === "undefined" || typeof lat === "undefined" || isNaN(lon) || isNaN(lat) ) && !GeoTemConfig.incompleteData) { | |
30845 throw "e"; | |
30846 } | |
30847 locations.push({ | |
30848 longitude : lon, | |
30849 latitude : lat, | |
30850 place : place | |
30851 }); | |
30852 } | |
30853 var dates = []; | |
30854 if (item.time instanceof Array) { | |
30855 for (var j = 0; j < item.time.length; j++) { | |
30856 var time = GeoTemConfig.getTimeData(item.time[j]); | |
30857 if (time == null && !GeoTemConfig.incompleteData) { | |
30858 throw "e"; | |
30859 } | |
30860 dates.push(time); | |
30861 } | |
30862 } else { | |
30863 var time = GeoTemConfig.getTimeData(item.time); | |
30864 if (time == null && !GeoTemConfig.incompleteData) { | |
30865 throw "e"; | |
30866 } | |
30867 if (time != null) { | |
30868 dates.push(time); | |
30869 } | |
30870 } | |
30871 var weight = parseInt(item.weight) || 1; | |
30872 //add all "other" attributes to table data | |
30873 //this is a hack to allow "invalid" JSONs | |
30874 var specialAttributes = ["id", "name", "description", "lon", "lat", "place", "time", | |
30875 "tableContent", "location", "time"]; | |
30876 for (var attribute in item){ | |
30877 if ($.inArray(attribute, specialAttributes) == -1){ | |
30878 tableContent[attribute] = item[attribute]; | |
30879 } | |
30880 } | |
30881 | |
30882 var mapTimeObject = new DataObject(name, description, locations, dates, weight, tableContent); | |
30883 mapTimeObject.setIndex(index); | |
30884 mapTimeObjects.push(mapTimeObject); | |
30885 } catch(e) { | |
30886 continue; | |
30887 } | |
30888 } | |
30889 | |
30890 if (GeoTemConfig.loadColorFromDataset) | |
30891 GeoTemConfig.loadDataObjectColoring(mapTimeObjects); | |
30892 | |
30893 return mapTimeObjects; | |
30894 } | |
30895 /** | |
30896 * converts a KML dom into an array of data objects | |
30897 * @param {XML dom} kml the XML dom for the KML file | |
30898 * @return an array of data objects | |
30899 */ | |
30900 GeoTemConfig.loadKml = function(kml) { | |
30901 var mapObjects = []; | |
30902 var elements = kml.getElementsByTagName("Placemark"); | |
30903 if (elements.length == 0) { | |
30904 return []; | |
30905 } | |
30906 var index = 0; | |
30907 var descriptionTableHeaders = []; | |
30908 var xmlSerializer = new XMLSerializer(); | |
30909 | |
30910 for (var i = 0; i < elements.length; i++) { | |
30911 var placemark = elements[i]; | |
30912 var name, description, place, granularity, lon, lat, tableContent = [], time = [], location = []; | |
30913 var weight = 1; | |
30914 var timeData = false, mapData = false; | |
30915 | |
30916 try { | |
30917 description = placemark.getElementsByTagName("description")[0].childNodes[0].nodeValue; | |
30918 | |
30919 //cleanWhitespace removes non-sense text-nodes (space, tab) | |
30920 //and is an addition to jquery defined above | |
30921 try { | |
30922 var descriptionDocument = $($.parseXML(description)).cleanWhitespace(); | |
30923 | |
30924 //check whether the description element contains a table | |
30925 //if yes, this data will be loaded as separate columns | |
30926 $(descriptionDocument).find("table").each(function(){ | |
30927 $(this).find("tr").each( | |
30928 function() { | |
30929 var isHeader = true; | |
30930 var lastHeader = ""; | |
30931 | |
30932 $(this).find("td").each( | |
30933 function() { | |
30934 if (isHeader) { | |
30935 lastHeader = $.trim($(this).text()); | |
30936 isHeader = false; | |
30937 } else { | |
30938 var value = ""; | |
30939 | |
30940 //if this td contains HTML, serialize all | |
30941 //it's children (the "content"!) | |
30942 $(this).children().each( | |
30943 function() { | |
30944 value += xmlSerializer.serializeToString(this); | |
30945 } | |
30946 ); | |
30947 | |
30948 //no HTML content (or no content at all) | |
30949 if (value.length == 0) | |
30950 value = $(this).text(); | |
30951 if (typeof value === "undefined") | |
30952 value = ""; | |
30953 | |
30954 if ($.inArray(lastHeader, descriptionTableHeaders) === -1) | |
30955 descriptionTableHeaders.push(lastHeader); | |
30956 | |
30957 if (tableContent[lastHeader] != null) | |
30958 //append if a field occures more than once | |
30959 tableContent[lastHeader] += "\n" + value; | |
30960 else | |
30961 tableContent[lastHeader] = value; | |
30962 | |
30963 isHeader = true; | |
30964 } | |
30965 } | |
30966 ); | |
30967 } | |
30968 ); | |
30969 }); | |
30970 } catch(e) { | |
30971 //couldn't be parsed, so it contains no html table | |
30972 //or is not in valid XHTML syntax | |
30973 } | |
30974 | |
30975 //check whether the description element contains content in the form of equations | |
30976 //e.g. someDescriptor = someValue, where these eqations are separated by <br/> | |
30977 //if yes, this data will be loaded as separate columns | |
30978 var descriptionRows = description.replace(/<\s*br\s*[\/]*\s*>/g,"<br/>"); | |
30979 $(descriptionRows.split("<br/>")).each(function(){ | |
30980 var row = this; | |
30981 | |
30982 if (typeof row === "undefined") | |
30983 return; | |
30984 | |
30985 var headerAndValue = row.split("="); | |
30986 if (headerAndValue.length != 2) | |
30987 return; | |
30988 | |
30989 var header = $.trim(headerAndValue[0]); | |
30990 var value = $.trim(headerAndValue[1]); | |
30991 | |
30992 if ($.inArray(header, descriptionTableHeaders) === -1) | |
30993 descriptionTableHeaders.push(header); | |
30994 | |
30995 if (tableContent[header] != null) | |
30996 //append if a field occures more than once | |
30997 tableContent[header] += "\n" + value; | |
30998 else | |
30999 tableContent[header] = value; | |
31000 }); | |
31001 | |
31002 tableContent["description"] = description; | |
31003 } catch(e) { | |
31004 description = ""; | |
31005 } | |
31006 | |
31007 try { | |
31008 name = placemark.getElementsByTagName("name")[0].childNodes[0].nodeValue; | |
31009 tableContent["name"] = name; | |
31010 } catch(e) { | |
31011 if (typeof tableContent["name"] !== "undefined") | |
31012 name = tableContent["name"]; | |
31013 else | |
31014 name = ""; | |
31015 } | |
31016 | |
31017 try { | |
31018 place = placemark.getElementsByTagName("address")[0].childNodes[0].nodeValue; | |
31019 tableContent["place"] = place; | |
31020 } catch(e) { | |
31021 if (typeof tableContent["place"] !== "undefined") | |
31022 place = tableContent["place"]; | |
31023 else | |
31024 place = ""; | |
31025 } | |
31026 | |
31027 try { | |
31028 var coordinates = placemark.getElementsByTagName("Point")[0].getElementsByTagName("coordinates")[0].childNodes[0].nodeValue; | |
31029 var lonlat = coordinates.split(","); | |
31030 lon = lonlat[0]; | |
31031 lat = lonlat[1]; | |
31032 if (lon == "" || lat == "" || isNaN(lon) || isNaN(lat)) { | |
31033 throw "e"; | |
31034 } | |
31035 location.push({ | |
31036 longitude : lon, | |
31037 latitude : lat, | |
31038 place : place | |
31039 }); | |
31040 } catch(e) { | |
31041 if (!GeoTemConfig.incompleteData) { | |
31042 continue; | |
31043 } | |
31044 } | |
31045 | |
31046 try { | |
31047 var tuple = GeoTemConfig.getTimeData(placemark.getElementsByTagName("TimeStamp")[0].getElementsByTagName("when")[0].childNodes[0].nodeValue); | |
31048 if (tuple != null) { | |
31049 time.push(tuple); | |
31050 timeData = true; | |
31051 } else if (!GeoTemConfig.incompleteData) { | |
31052 continue; | |
31053 } | |
31054 } catch(e) { | |
31055 try { | |
31056 if ( (typeof tableContent["TimeSpan:begin"] === "undefined") && | |
31057 (typeof tableContent["TimeSpan:end"] === "undefined") ){ | |
31058 var timeStart = $(placemark).find("TimeSpan begin").text(); | |
31059 var timeEnd = $(placemark).find("TimeSpan end").text(); | |
31060 | |
31061 if ( (timeStart != "") && (timeStart != "") ){ | |
31062 tableContent["TimeSpan:begin"] = timeStart; | |
31063 tableContent["TimeSpan:end"] = timeEnd; | |
31064 | |
31065 timeData = true; | |
31066 } | |
31067 } | |
31068 } catch(e) { | |
31069 if (!GeoTemConfig.incompleteData) { | |
31070 continue; | |
31071 } | |
31072 } | |
31073 } | |
31074 var object = new DataObject(name, description, location, time, 1, tableContent); | |
31075 object.setIndex(index); | |
31076 index++; | |
31077 mapObjects.push(object); | |
31078 } | |
31079 | |
31080 //make sure that all "description table" columns exists in all rows | |
31081 if (descriptionTableHeaders.length > 0){ | |
31082 $(mapObjects).each(function(){ | |
31083 var object = this; | |
31084 $(descriptionTableHeaders).each(function(){ | |
31085 if (typeof object.tableContent[this] === "undefined") | |
31086 object.tableContent[this] = ""; | |
31087 }); | |
31088 }); | |
31089 } | |
31090 | |
31091 if (GeoTemConfig.loadColorFromDataset) | |
31092 GeoTemConfig.loadDataObjectColoring(mapObjects); | |
31093 | |
31094 return mapObjects; | |
31095 }; | |
31096 | |
31097 GeoTemConfig.createKMLfromDataset = function(index){ | |
31098 var kmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document>"; | |
31099 | |
31100 //credits: Anatoly Mironov, http://stackoverflow.com/questions/2573521/how-do-i-output-an-iso-8601-formatted-string-in-javascript | |
31101 function pad(number) { | |
31102 var r = String(number); | |
31103 if ( r.length === 1 ) { | |
31104 r = '0' + r; | |
31105 } | |
31106 return r; | |
31107 } | |
31108 | |
31109 var dateToISOString = function(date, granularity) { | |
31110 var ISOString = date.getFullYear(); | |
31111 | |
31112 if (granularity <= SimileAjax.DateTime.MONTH) | |
31113 ISOString += '-' + pad( date.getMonth() + 1 ); | |
31114 if (granularity <= SimileAjax.DateTime.DAY) | |
31115 ISOString += '-' + pad( date.getDate() ); | |
31116 if (granularity <= SimileAjax.DateTime.HOUR){ | |
31117 ISOString += 'T' + pad( date.getHours() ); | |
31118 if (granularity <= SimileAjax.DateTime.MINUTE) | |
31119 ISOString += ':' + pad( date.getMinutes() ); | |
31120 if (granularity <= SimileAjax.DateTime.SECOND) | |
31121 ISOString += ':' + pad( date.getSeconds() ); | |
31122 if (granularity <= SimileAjax.DateTime.MILLISECOND) | |
31123 ISOString += '.' + String( (date.getMilliseconds()/1000).toFixed(3) ).slice( 2, 5 ); | |
31124 ISOString += 'Z'; | |
31125 } | |
31126 | |
31127 return ISOString; | |
31128 }; | |
31129 | |
31130 $(GeoTemConfig.datasets[index].objects).each(function(){ | |
31131 var name = this.name; | |
31132 var description = this.description; | |
31133 //TODO: allow multiple time/date | |
31134 var place = this.getPlace(0,0); | |
31135 var lat = this.getLatitude(0); | |
31136 var lon = this.getLongitude(0); | |
31137 | |
31138 var kmlEntry = "<Placemark>"; | |
31139 | |
31140 kmlEntry += "<name><![CDATA[" + name + "]]></name>"; | |
31141 kmlEntry += "<address><![CDATA[" + place + "]]></address>"; | |
31142 kmlEntry += "<description><![CDATA[" + description + "]]></description>"; | |
31143 kmlEntry += "<Point><coordinates>" + lon + "," + lat + "</coordinates></Point>"; | |
31144 | |
31145 if (this.isTemporal){ | |
31146 kmlEntry += "<TimeStamp><when>" + dateToISOString(this.getDate(0), this.getTimeGranularity(0)) + "</when></TimeStamp>"; | |
31147 } else if (this.isFuzzyTemporal){ | |
31148 kmlEntry += "<TimeSpan>"+ | |
31149 "<begin>" + dateToISOString(this.TimeSpanBegin.utc().toDate(), this.TimeSpanBeginGranularity) + "</begin>" + | |
31150 "<end>" + dateToISOString(this.TimeSpanEnd.utc().toDate(), this.TimeSpanEndGranularity) + "</end>" + | |
31151 "</TimeSpan>"; | |
31152 } | |
31153 | |
31154 kmlEntry += "</Placemark>"; | |
31155 | |
31156 kmlContent += kmlEntry; | |
31157 }); | |
31158 | |
31159 kmlContent += "</Document></kml>"; | |
31160 | |
31161 return(kmlContent); | |
31162 }; | |
31163 | |
31164 GeoTemConfig.createCSVfromDataset = function(index){ | |
31165 var csvContent = ""; | |
31166 var header = ["name", "description", "weight"]; | |
31167 var tableContent = []; | |
31168 | |
31169 var firstDataObject = GeoTemConfig.datasets[index].objects[0]; | |
31170 | |
31171 for(var key in firstDataObject.tableContent){ | |
31172 var found = false; | |
31173 $(header).each(function(index,val){ | |
31174 if (val === key){ | |
31175 found = true; | |
31176 return false; | |
31177 } | |
31178 }); | |
31179 if (found === true) | |
31180 continue; | |
31181 else | |
31182 tableContent.push(key); | |
31183 } | |
31184 | |
31185 var isFirst = true; | |
31186 $(header).each(function(key,val){ | |
31187 if (isFirst){ | |
31188 isFirst = false; | |
31189 } else { | |
31190 csvContent += ","; | |
31191 } | |
31192 | |
31193 //Rename according to CSV import definition | |
31194 if (val === "name") | |
31195 val = "Name"; | |
31196 else if (val === "description") | |
31197 val = "Description"; | |
31198 csvContent += "\""+val+"\""; | |
31199 }); | |
31200 $(tableContent).each(function(key,val){ | |
31201 if (isFirst){ | |
31202 isFirst = false; | |
31203 } else { | |
31204 csvContent += ","; | |
31205 } | |
31206 csvContent += "\""+val+"\""; | |
31207 }); | |
31208 //Names according to CSV import definition | |
31209 csvContent += ",\"Address\",\"Latitude\",\"Longitude\",\"TimeStamp\""; | |
31210 csvContent += "\n"; | |
31211 | |
31212 var isFirstRow = true; | |
31213 $(GeoTemConfig.datasets[index].objects).each(function(){ | |
31214 var elem = this; | |
31215 | |
31216 if (isFirstRow){ | |
31217 isFirstRow = false; | |
31218 } else { | |
31219 csvContent += "\n"; | |
31220 } | |
31221 | |
31222 var isFirst = true; | |
31223 $(header).each(function(key,val){ | |
31224 if (isFirst){ | |
31225 isFirst = false; | |
31226 } else { | |
31227 csvContent += ","; | |
31228 } | |
31229 csvContent += "\""+elem[val]+"\""; | |
31230 }); | |
31231 $(tableContent).each(function(key,val){ | |
31232 if (isFirst){ | |
31233 isFirst = false; | |
31234 } else { | |
31235 csvContent += ","; | |
31236 } | |
31237 csvContent += "\""+elem.tableContent[val]+"\""; | |
31238 }); | |
31239 | |
31240 csvContent += ","; | |
31241 csvContent += "\""; | |
31242 if (elem.isGeospatial){ | |
31243 csvContent += elem.locations[0].place; | |
31244 } | |
31245 csvContent += "\""; | |
31246 | |
31247 csvContent += ","; | |
31248 csvContent += "\""; | |
31249 if ( (elem.isGeospatial) && (typeof elem.getLatitude(0) !== "undefined") ){ | |
31250 csvContent += elem.getLatitude(0); | |
31251 } | |
31252 csvContent += "\""; | |
31253 | |
31254 csvContent += ","; | |
31255 csvContent += "\""; | |
31256 if ( (elem.isGeospatial) && (typeof elem.getLongitude(0) !== "undefined") ){ | |
31257 csvContent += elem.getLongitude(0); | |
31258 } | |
31259 csvContent += "\""; | |
31260 | |
31261 csvContent += ","; | |
31262 csvContent += "\""; | |
31263 if ( (elem.isTemporal) && (typeof elem.getDate(0) !== "undefined") ){ | |
31264 //TODO: not supported in IE8 switch to moment.js | |
31265 csvContent += elem.getDate(0).toISOString(); | |
31266 } | |
31267 csvContent += "\""; | |
31268 }); | |
31269 | |
31270 return(csvContent); | |
31271 }; | |
31272 /** | |
31273 * iterates over Datasets/DataObjects and loads color values | |
31274 * from the "color0" and "color1" elements, which contains RGB | |
31275 * values in hex (CSS style #RRGGBB) | |
31276 * @param {dataObjects} array of DataObjects | |
31277 */ | |
31278 GeoTemConfig.loadDataObjectColoring = function(dataObjects) { | |
31279 $(dataObjects).each(function(){ | |
31280 var r0,g0,b0,r1,g1,b1; | |
31281 if ( (typeof this.tableContent !== "undefined") && | |
31282 (typeof this.tableContent["color0"] !== "undefined") ){ | |
31283 var color = this.tableContent["color0"]; | |
31284 if ( (color.indexOf("#") == 0) && (color.length == 7) ){ | |
31285 r0 = parseInt("0x"+color.substr(1,2)); | |
31286 g0 = parseInt("0x"+color.substr(3,2)); | |
31287 b0 = parseInt("0x"+color.substr(5,2)); | |
31288 } | |
31289 } | |
31290 if ( (typeof this.tableContent !== "undefined") && | |
31291 (typeof this.tableContent["color1"] !== "undefined") ){ | |
31292 var color = this.tableContent["color1"]; | |
31293 if ( (color.indexOf("#") == 0) && (color.length == 7) ){ | |
31294 r1 = parseInt("0x"+color.substr(1,2)); | |
31295 g1 = parseInt("0x"+color.substr(3,2)); | |
31296 b1 = parseInt("0x"+color.substr(5,2)); | |
31297 } | |
31298 } | |
31299 | |
31300 if ( (typeof r0 !== "undefined") && (typeof g0 !== "undefined") && (typeof b0 !== "undefined") && | |
31301 (typeof r1 !== "undefined") && (typeof g1 !== "undefined") && (typeof b1 !== "undefined") ){ | |
31302 this.setColor(r0,g0,b0,r1,g1,b1); | |
31303 delete this.tableContent["color0"]; | |
31304 delete this.tableContent["color1"]; | |
31305 } else { | |
31306 if ((GeoTemConfig.debug)&&(typeof console !== undefined)) | |
31307 console.error("Object '" + this.name + "' has invalid color information"); | |
31308 } | |
31309 }); | |
31310 }; | |
31311 | |
31312 /** | |
31313 * renames (or copies, see below) a column of each DataObject in a Dataset | |
31314 * @param {Dataset} dataset the dataset where the rename should take place | |
31315 * @param {String} oldColumn name of column that will be renamed | |
31316 * @param {String} newColumn new name of column | |
31317 * @param {Boolean} keepOld keep old column (copy mode) | |
31318 * @return an array of data objects | |
31319 */ | |
31320 GeoTemConfig.renameColumns = function(dataset, renames){ | |
31321 if (renames.length===0){ | |
31322 return; | |
31323 } | |
31324 for (var renCnt = 0; renCnt < renames.length; renCnt++){ | |
31325 var oldColumn = renames[renCnt].oldColumn; | |
31326 var newColumn = renames[renCnt].newColumn; | |
31327 | |
31328 var keepOld = renames[renCnt].keepOld; | |
31329 if (typeof keepOld === "undefined"){ | |
31330 keepOld = true; | |
31331 } | |
31332 var oldColumObject = {}; | |
31333 if (oldColumn.indexOf("[") != -1){ | |
31334 oldColumObject.columnName = oldColumn.split("[")[0]; | |
31335 var IndexAndAttribute = oldColumn.split("[")[1]; | |
31336 if (IndexAndAttribute.indexOf("]") != -1){ | |
31337 oldColumObject.type = 2; | |
31338 oldColumObject.arrayIndex = IndexAndAttribute.split("]")[0]; | |
31339 var attribute = IndexAndAttribute.split("]")[1]; | |
31340 if (attribute.length > 0){ | |
31341 oldColumObject.type = 3; | |
31342 oldColumObject.attribute = attribute.split(".")[1]; | |
31343 } | |
31344 } | |
31345 } else { | |
31346 oldColumObject.type = 1; | |
31347 oldColumObject.name = oldColumn; | |
31348 } | |
31349 | |
31350 var newColumObject = {}; | |
31351 if (newColumn.indexOf("[") != -1){ | |
31352 newColumObject.name = newColumn.split("[")[0]; | |
31353 var IndexAndAttribute = newColumn.split("[")[1]; | |
31354 if (IndexAndAttribute.indexOf("]") != -1){ | |
31355 newColumObject.type = 2; | |
31356 newColumObject.arrayIndex = IndexAndAttribute.split("]")[0]; | |
31357 var attribute = IndexAndAttribute.split("]")[1]; | |
31358 if (attribute.length > 0){ | |
31359 newColumObject.type = 3; | |
31360 newColumObject.attribute = attribute.split(".")[1]; | |
31361 } | |
31362 } | |
31363 } else { | |
31364 newColumObject.type = 1; | |
31365 newColumObject.name = newColumn; | |
31366 } | |
31367 | |
31368 for (var i = 0; i < dataset.objects.length; i++){ | |
31369 var dataObject = dataset.objects[i]; | |
31370 | |
31371 //get value from old column name | |
31372 var value; | |
31373 if (oldColumObject.type == 1){ | |
31374 value = dataObject[oldColumObject.name]; | |
31375 if (typeof value === "undefined"){ | |
31376 value = dataObject.tableContent[oldColumObject.name]; | |
31377 } | |
31378 if (!keepOld){ | |
31379 delete dataObject.tableContent[oldColumObject.name]; | |
31380 delete dataObject[oldColumObject.name]; | |
31381 } | |
31382 } else if (oldColumObject.type == 2){ | |
31383 value = dataObject[oldColumObject.name][oldColumObject.arrayIndex]; | |
31384 if (!keepOld){ | |
31385 delete dataObject[oldColumObject.name][oldColumObject.arrayIndex]; | |
31386 } | |
31387 } else if (oldColumObject.type == 3){ | |
31388 value = dataObject[oldColumObject.name][oldColumObject.arrayIndex][oldColumObject.attribute]; | |
31389 if (!keepOld){ | |
31390 delete dataObject[oldColumObject.name][oldColumObject.arrayIndex][oldColumObject.attribute]; | |
31391 } | |
31392 } | |
31393 | |
31394 //create new column | |
31395 if (newColumObject.type == 1){ | |
31396 dataObject[newColumObject.name] = value; | |
31397 dataObject.tableContent[newColumObject.name] = value; | |
31398 } else if (newColumObject.type == 2){ | |
31399 if (typeof dataObject[newColumObject.name] == "undefined"){ | |
31400 dataObject[newColumObject.name] = []; | |
31401 } | |
31402 dataObject[newColumObject.name][newColumObject.arrayIndex] = value; | |
31403 } else if (newColumObject.type == 3){ | |
31404 if (typeof dataObject[newColumObject.name] == "undefined"){ | |
31405 dataObject[newColumObject.name] = []; | |
31406 } | |
31407 if (typeof dataObject[newColumObject.name][newColumObject.arrayIndex] == "undefined"){ | |
31408 dataObject[newColumObject.name][newColumObject.arrayIndex] = {}; | |
31409 } | |
31410 dataObject[newColumObject.name][newColumObject.arrayIndex][newColumObject.attribute] = value; | |
31411 } | |
31412 } | |
31413 } | |
31414 | |
31415 //actually create new dataObjects | |
31416 for (var i = 0; i < dataset.objects.length; i++){ | |
31417 var dataObject = dataset.objects[i]; | |
31418 //save index | |
31419 var index = dataObject.index; | |
31420 | |
31421 dataset.objects[i] = new DataObject(dataObject.name, dataObject.description, dataObject.locations, | |
31422 dataObject.dates, dataObject.weight, dataObject.tableContent, dataObject.projection); | |
31423 //set index | |
31424 dataset.objects[i].setIndex(index); | |
31425 } | |
31426 }; | |
31427 /* | |
31428 * MapControl.js | |
31429 * | |
31430 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31431 * | |
31432 * This library is free software; you can redistribute it and/or | |
31433 * modify it under the terms of the GNU Lesser General Public | |
31434 * License as published by the Free Software Foundation; either | |
31435 * version 3 of the License, or (at your option) any later version. | |
31436 * | |
31437 * This library is distributed in the hope that it will be useful, | |
31438 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31439 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31440 * Lesser General Public License for more details. | |
31441 * | |
31442 * You should have received a copy of the GNU Lesser General Public | |
31443 * License along with this library; if not, write to the Free Software | |
31444 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31445 * MA 02110-1301 USA | |
31446 */ | |
31447 | |
31448 /** | |
31449 * @class MapControl | |
31450 * Generic map control interface | |
31451 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31452 * @release 1.0 | |
31453 * @release date: 2012-07-27 | |
31454 * @version date: 2012-07-27 | |
31455 */ | |
31456 function MapControl(map, button, label, onActivate, onDeactivate) { | |
31457 | |
31458 var control = this; | |
31459 this.button = button; | |
31460 this.enabled = true; | |
31461 this.activated = false; | |
31462 this.label = label; | |
31463 | |
31464 if (this.button != null) { | |
31465 $(this.button).addClass(label + 'Deactivated'); | |
31466 $(this.button).attr("title", GeoTemConfig.getString(GeoTemConfig.language, label)); | |
31467 //vhz | |
31468 $(this.button).click(function() { | |
31469 control.checkStatus(); | |
31470 }); | |
31471 } | |
31472 | |
31473 this.checkStatus = function() { | |
31474 if (control.enabled) { | |
31475 if ( typeof map.activeControl != 'undefined') { | |
31476 if (control.activated) { | |
31477 control.deactivate(); | |
31478 } else { | |
31479 map.activeControl.deactivate(); | |
31480 control.activate(); | |
31481 } | |
31482 } else { | |
31483 control.activate(); | |
31484 } | |
31485 } | |
31486 }; | |
31487 | |
31488 this.setButtonClass = function(removeClass, addClass) { | |
31489 if (this.button != null) { | |
31490 $(this.button).removeClass(label + removeClass); | |
31491 $(this.button).addClass(label + addClass); | |
31492 $(this.button).attr("title", GeoTemConfig.getString(GeoTemConfig.language, label)); | |
31493 } | |
31494 }; | |
31495 | |
31496 this.disable = function() { | |
31497 this.enabled = false; | |
31498 this.setButtonClass('Deactivated', 'Disabled'); | |
31499 }; | |
31500 | |
31501 this.enable = function() { | |
31502 this.enabled = true; | |
31503 this.setButtonClass('Disabled', 'Deactivated'); | |
31504 }; | |
31505 | |
31506 this.activate = function() { | |
31507 onActivate(); | |
31508 this.activated = true; | |
31509 this.setButtonClass('Deactivated', 'Activated'); | |
31510 map.activeControl = this; | |
31511 }; | |
31512 | |
31513 this.deactivate = function() { | |
31514 onDeactivate(); | |
31515 this.activated = false; | |
31516 this.setButtonClass('Activated', 'Deactivated'); | |
31517 map.activeControl = undefined; | |
31518 }; | |
31519 | |
31520 }; | |
31521 /* | |
31522 * CircleObject.js | |
31523 * | |
31524 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31525 * | |
31526 * This library is free software; you can redistribute it and/or | |
31527 * modify it under the terms of the GNU Lesser General Public | |
31528 * License as published by the Free Software Foundation; either | |
31529 * version 3 of the License, or (at your option) any later version. | |
31530 * | |
31531 * This library is distributed in the hope that it will be useful, | |
31532 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31533 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31534 * Lesser General Public License for more details. | |
31535 * | |
31536 * You should have received a copy of the GNU Lesser General Public | |
31537 * License along with this library; if not, write to the Free Software | |
31538 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31539 * MA 02110-1301 USA | |
31540 */ | |
31541 | |
31542 /** | |
31543 * @class CircleObject | |
31544 * circle object aggregate for the map | |
31545 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31546 * @release 1.0 | |
31547 * @release date: 2012-07-27 | |
31548 * @version date: 2012-07-27 | |
31549 * | |
31550 * @param {float} x the x (longitude) value for the circle | |
31551 * @param {float} y the y (latitude) value for the circle | |
31552 * @param {DataObject[]} elements array of data objects belonging to the circle | |
31553 * @param {float} radius the resulting radius (in pixel) for the circle | |
31554 * @param {int} search dataset index | |
31555 * @param {int} weight summed weight of all elements | |
31556 * @param {JSON} fatherBin bin of the circle object if its part of a circle pack | |
31557 */ | |
31558 CircleObject = function(originX, originY, shiftX, shiftY, elements, radius, search, weight, fatherBin) { | |
31559 | |
31560 this.originX = originX; | |
31561 this.originY = originY; | |
31562 this.shiftX = shiftX; | |
31563 this.shiftY = shiftY; | |
31564 this.elements = elements; | |
31565 this.radius = radius; | |
31566 this.search = search; | |
31567 this.weight = weight; | |
31568 this.overlay = 0; | |
31569 this.overlayElements = []; | |
31570 this.smoothness = 0; | |
31571 this.fatherBin = fatherBin; | |
31572 | |
31573 this.feature | |
31574 this.olFeature | |
31575 this.percentage = 0; | |
31576 this.selected = false; | |
31577 | |
31578 }; | |
31579 | |
31580 CircleObject.prototype = { | |
31581 | |
31582 /** | |
31583 * sets the OpenLayers point feature for this point object | |
31584 * @param {OpenLayers.Feature} pointFeature the point feature for this object | |
31585 */ | |
31586 setFeature : function(feature) { | |
31587 this.feature = feature; | |
31588 }, | |
31589 | |
31590 /** | |
31591 * sets the OpenLayers point feature for this point object to manage its selection status | |
31592 * @param {OpenLayers.Feature} olPointFeature the overlay point feature for this object | |
31593 */ | |
31594 setOlFeature : function(olFeature) { | |
31595 this.olFeature = olFeature; | |
31596 }, | |
31597 | |
31598 reset : function() { | |
31599 this.overlay = 0; | |
31600 this.overlayElements = []; | |
31601 this.smoothness = 0; | |
31602 }, | |
31603 | |
31604 setSelection : function(s) { | |
31605 this.selected = s; | |
31606 }, | |
31607 | |
31608 toggleSelection : function() { | |
31609 this.selected = !this.selected; | |
31610 } | |
31611 }; | |
31612 /* | |
31613 * FilterBar.js | |
31614 * | |
31615 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31616 * | |
31617 * This library is free software; you can redistribute it and/or | |
31618 * modify it under the terms of the GNU Lesser General Public | |
31619 * License as published by the Free Software Foundation; either | |
31620 * version 3 of the License, or (at your option) any later version. | |
31621 * | |
31622 * This library is distributed in the hope that it will be useful, | |
31623 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31624 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31625 * Lesser General Public License for more details. | |
31626 * | |
31627 * You should have received a copy of the GNU Lesser General Public | |
31628 * License along with this library; if not, write to the Free Software | |
31629 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31630 * MA 02110-1301 USA | |
31631 */ | |
31632 | |
31633 /** | |
31634 * @class FilterBar | |
31635 * Implementation for FilterBar Object | |
31636 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31637 * @release 1.0 | |
31638 * @release date: 2012-07-27 | |
31639 * @version date: 2012-07-27 | |
31640 * | |
31641 * @param {Object} parent parent to call filter functions | |
31642 * @param {HTML object} parentDiv div to append filter buttons | |
31643 */ | |
31644 function FilterBar(parent, parentDiv) { | |
31645 | |
31646 var bar = this; | |
31647 | |
31648 this.filter = document.createElement('div'); | |
31649 this.filter.setAttribute('class', 'smallButton filterDisabled'); | |
31650 this.filter.onclick = function() { | |
31651 parent.filtering(); | |
31652 }; | |
31653 | |
31654 this.filterInverse = document.createElement('div'); | |
31655 this.filterInverse.setAttribute('class', 'smallButton filterInverseDisabled'); | |
31656 this.filterInverse.onclick = function() { | |
31657 parent.inverseFiltering(); | |
31658 }; | |
31659 if (!GeoTemConfig.inverseFilter) { | |
31660 this.filterInverse.style.display = 'none'; | |
31661 } | |
31662 | |
31663 this.cancelSelection = document.createElement('div'); | |
31664 this.cancelSelection.setAttribute('class', 'smallButton filterCancelDisabled'); | |
31665 this.cancelSelection.onclick = function() { | |
31666 parent.deselection(); | |
31667 }; | |
31668 | |
31669 this.appendTo = function(parentDiv) { | |
31670 parentDiv.appendChild(this.filter); | |
31671 parentDiv.appendChild(this.filterInverse); | |
31672 parentDiv.appendChild(this.cancelSelection); | |
31673 } | |
31674 if ( typeof parentDiv != 'undefined') { | |
31675 this.appendTo(parentDiv); | |
31676 } | |
31677 | |
31678 this.reset = function(show) { | |
31679 if (show) { | |
31680 this.filter.setAttribute('class', 'smallButton filter'); | |
31681 this.filterInverse.setAttribute('class', 'smallButton filterInverse'); | |
31682 this.cancelSelection.setAttribute('class', 'smallButton filterCancel'); | |
31683 } else { | |
31684 this.filter.setAttribute('class', 'smallButton filterDisabled'); | |
31685 this.filterInverse.setAttribute('class', 'smallButton filterInverseDisabled'); | |
31686 this.cancelSelection.setAttribute('class', 'smallButton filterCancelDisabled'); | |
31687 } | |
31688 }; | |
31689 | |
31690 }; | |
31691 /* | |
31692 * Selection.js | |
31693 * | |
31694 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31695 * | |
31696 * This library is free software; you can redistribute it and/or | |
31697 * modify it under the terms of the GNU Lesser General Public | |
31698 * License as published by the Free Software Foundation; either | |
31699 * version 3 of the License, or (at your option) any later version. | |
31700 * | |
31701 * This library is distributed in the hope that it will be useful, | |
31702 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31703 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31704 * Lesser General Public License for more details. | |
31705 * | |
31706 * You should have received a copy of the GNU Lesser General Public | |
31707 * License along with this library; if not, write to the Free Software | |
31708 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31709 * MA 02110-1301 USA | |
31710 */ | |
31711 | |
31712 /** | |
31713 * @class Selection | |
31714 * Selection Class | |
31715 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31716 * @release 1.0 | |
31717 * @release date: 2012-07-27 | |
31718 * @version date: 2012-07-27 | |
31719 * | |
31720 * @param {Array} objects array of selected objects | |
31721 * @param {Object} widget which belongs to selection | |
31722 */ | |
31723 function Selection(objects, widget) { | |
31724 | |
31725 this.objects = objects; | |
31726 if ( typeof objects == 'undefined') { | |
31727 this.objects = []; | |
31728 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
31729 this.objects.push([]); | |
31730 } | |
31731 } | |
31732 this.widget = widget; | |
31733 | |
31734 this.getObjects = function(widget) { | |
31735 if (!this.equal(widget)) { | |
31736 return this.objects; | |
31737 } | |
31738 this.objects = []; | |
31739 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
31740 this.objects.push([]); | |
31741 } | |
31742 return this.objects; | |
31743 }; | |
31744 | |
31745 this.equal = function(widget) { | |
31746 if (this.valid() && this.widget != widget) { | |
31747 return false; | |
31748 } | |
31749 return true; | |
31750 }; | |
31751 | |
31752 this.valid = function() { | |
31753 if ( typeof this.widget != 'undefined') { | |
31754 return true; | |
31755 } | |
31756 return false; | |
31757 }; | |
31758 | |
31759 this.loadAllObjects = function() { | |
31760 allObjects = []; | |
31761 $(GeoTemConfig.datasets).each(function(){ | |
31762 var singleDatasetObjects = []; | |
31763 $(this.objects).each(function(){ | |
31764 singleDatasetObjects.push(this); | |
31765 }); | |
31766 allObjects.push(singleDatasetObjects); | |
31767 }); | |
31768 this.objects = allObjects; | |
31769 }; | |
31770 }; | |
31771 | |
31772 /* | |
31773 * PlacenameTags.js | |
31774 * | |
31775 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31776 * | |
31777 * This library is free software; you can redistribute it and/or | |
31778 * modify it under the terms of the GNU Lesser General Public | |
31779 * License as published by the Free Software Foundation; either | |
31780 * version 3 of the License, or (at your option) any later version. | |
31781 * | |
31782 * This library is distributed in the hope that it will be useful, | |
31783 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31784 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31785 * Lesser General Public License for more details. | |
31786 * | |
31787 * You should have received a copy of the GNU Lesser General Public | |
31788 * License along with this library; if not, write to the Free Software | |
31789 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31790 * MA 02110-1301 USA | |
31791 */ | |
31792 | |
31793 /** | |
31794 * @class PlacenameTags | |
31795 * place labels computation for circles | |
31796 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31797 * @release 1.0 | |
31798 * @release date: 2012-07-27 | |
31799 * @version date: 2012-07-27 | |
31800 */ | |
31801 function PlacenameTags(circle, map) { | |
31802 | |
31803 this.circle = circle; | |
31804 this.map = map; | |
31805 | |
31806 this.placeLabels | |
31807 this.selectedLabel | |
31808 | |
31809 this.allLabel | |
31810 this.othersLabel | |
31811 this.unknownLabel | |
31812 | |
31813 this.calculate = function() { | |
31814 this.calculateLabels(); | |
31815 this.calculatePlacenameTags(); | |
31816 } | |
31817 | |
31818 this.calculateLabels = function() { | |
31819 var elements = this.circle.elements; | |
31820 var k = this.circle.search; | |
31821 var weight = 0; | |
31822 var labels = []; | |
31823 | |
31824 var levelOfDetail = 0; | |
31825 if (this.map.options.placenameTagsStyle === 'zoom') | |
31826 levelOfDetail = this.map.getLevelOfDetail(); | |
31827 | |
31828 if (this.map.options.placenameTagsStyle === 'value'){ | |
31829 //find max level that _all_ elements have a value for | |
31830 var maxLevel; | |
31831 for (var i = 0; i < elements.length; i++) { | |
31832 var level = elements[i].placeDetails[this.map.options.mapIndex].length-1; | |
31833 | |
31834 if (typeof maxLevel === "undefined") | |
31835 maxLevel = level; | |
31836 if (maxLevel > level) | |
31837 maxLevel = level; | |
31838 //smallest level anyway, no need to look any further | |
31839 if (level == 0) | |
31840 break; | |
31841 } | |
31842 //search for highest level where the values differ | |
31843 for (levelOfDetail = 0; levelOfDetail < maxLevel; levelOfDetail++){ | |
31844 var differenceFound = false; | |
31845 for (var i = 0; i < (elements.length-1); i++) { | |
31846 if ( elements[i].getPlace(this.map.options.mapIndex, levelOfDetail) !== | |
31847 elements[i+1].getPlace(this.map.options.mapIndex, levelOfDetail)) | |
31848 differenceFound = true; | |
31849 } | |
31850 if (differenceFound === true) | |
31851 break; | |
31852 } | |
31853 } | |
31854 | |
31855 for (var i = 0; i < elements.length; i++) { | |
31856 weight += elements[i].weight; | |
31857 var found = false; | |
31858 var label = elements[i].getPlace(this.map.options.mapIndex, levelOfDetail); | |
31859 if (label == "") { | |
31860 label = "unknown"; | |
31861 } | |
31862 for (var j = 0; j < labels.length; j++) { | |
31863 if (labels[j].place == label) { | |
31864 labels[j].elements.push(elements[i]); | |
31865 labels[j].weight += elements[i].weight; | |
31866 found = true; | |
31867 break; | |
31868 } | |
31869 } | |
31870 if (!found) { | |
31871 labels.push({ | |
31872 id : elements[i].name, | |
31873 place : label, | |
31874 elements : new Array(elements[i]), | |
31875 weight : elements[i].weight, | |
31876 index : k | |
31877 }); | |
31878 } | |
31879 } | |
31880 var sortBySize = function(label1, label2) { | |
31881 if (label1.weight > label2.weight) { | |
31882 return -1; | |
31883 } | |
31884 return 1; | |
31885 } | |
31886 labels.sort(sortBySize); | |
31887 if (map.options.maxPlaceLabels) { | |
31888 var ml = map.options.maxPlaceLabels; | |
31889 if (ml == 1) { | |
31890 labels = []; | |
31891 labels.push({ | |
31892 place : "all", | |
31893 elements : elements, | |
31894 weight : weight, | |
31895 index : k | |
31896 }); | |
31897 } | |
31898 if (ml == 2) { | |
31899 ml++; | |
31900 } | |
31901 if (ml > 2 && labels.length + 1 > ml) { | |
31902 var c = []; | |
31903 var w = 0; | |
31904 for (var i = ml - 2; i < labels.length; i++) { | |
31905 c = c.concat(labels[i].elements); | |
31906 w += labels[i].weight; | |
31907 } | |
31908 labels = labels.slice(0, ml - 2); | |
31909 labels.push({ | |
31910 place : "others", | |
31911 elements : c, | |
31912 weight : w, | |
31913 index : k | |
31914 }); | |
31915 } | |
31916 } | |
31917 if (labels.length > 1) { | |
31918 labels.push({ | |
31919 place : "all", | |
31920 elements : elements, | |
31921 weight : weight, | |
31922 index : k | |
31923 }); | |
31924 } | |
31925 this.placeLabels = labels; | |
31926 }; | |
31927 | |
31928 this.calculatePlacenameTags = function() { | |
31929 var cloud = this; | |
31930 var c = GeoTemConfig.getColor(this.circle.search); | |
31931 if( map.options.useGraphics ){ | |
31932 c = map.config.getGraphic(this.circle.search).color; | |
31933 } | |
31934 var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
31935 var color1 = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
31936 var allStyles = "", hoverStyle = "", highlightStyle = "", selectedStyle = "", unselectedStyle = ""; | |
31937 | |
31938 if (GeoTemConfig.ie) { | |
31939 highlightStyle += map.options.ieHighlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31940 hoverStyle += map.options.ieHoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31941 selectedStyle += map.options.ieSelectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31942 unselectedStyle += map.options.ieUnselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31943 } else { | |
31944 highlightStyle += map.options.highlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31945 hoverStyle += map.options.hoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31946 selectedStyle += map.options.selectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31947 unselectedStyle += map.options.unselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31948 } | |
31949 | |
31950 var clickFunction = function(label) { | |
31951 label.div.onclick = function() { | |
31952 cloud.changeLabelSelection(label); | |
31953 } | |
31954 } | |
31955 var maxLabelSize = this.count | |
31956 for (var i = 0; i < this.placeLabels.length; i++) { | |
31957 var l = this.placeLabels[i]; | |
31958 l.selected = false; | |
31959 var div = document.createElement("div"); | |
31960 div.setAttribute('class', 'tagCloudItem'); | |
31961 var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; | |
31962 if (l.place == "all") { | |
31963 fontSize = 1; | |
31964 } | |
31965 div.style.fontSize = fontSize + "em"; | |
31966 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
31967 l.selectedStyle = selectedStyle; | |
31968 l.unselectedStyle = unselectedStyle; | |
31969 l.highlightStyle = highlightStyle; | |
31970 l.hoverStyle = hoverStyle; | |
31971 div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; | |
31972 l.div = div; | |
31973 clickFunction(l); | |
31974 } | |
31975 if (map.options.labelGrid) { | |
31976 this.showPlacelabels(); | |
31977 } else { | |
31978 for (var i = 0; i < this.placeLabels.length; i++) { | |
31979 this.placeLabels[i].div.setAttribute('style', this.placeLabels[i].allStyle + "" + this.placeLabels[i].highlightStyle); | |
31980 } | |
31981 } | |
31982 }; | |
31983 | |
31984 this.selectLabel = function(label) { | |
31985 if ( typeof label == 'undefined') { | |
31986 label = this.placeLabels[this.placeLabels.length - 1]; | |
31987 } | |
31988 if (this.map.popup) { | |
31989 this.map.popup.showLabelContent(label); | |
31990 } | |
31991 this.selectedLabel = label; | |
31992 this.selectedLabel.div.setAttribute('style', this.selectedLabel.allStyle + "" + this.selectedLabel.selectedStyle); | |
31993 this.map.mapLabelSelection(label); | |
31994 }; | |
31995 | |
31996 // changes selection between labels (click, hover) | |
31997 this.changeLabelSelection = function(label) { | |
31998 if (this.selectedLabel == label) { | |
31999 return; | |
32000 } | |
32001 if ( typeof this.selectedLabel != 'undefined') { | |
32002 this.selectedLabel.div.setAttribute('style', this.selectedLabel.allStyle + "" + this.selectedLabel.unselectedStyle); | |
32003 } | |
32004 this.selectLabel(label); | |
32005 }; | |
32006 | |
32007 this.showPlacelabels = function() { | |
32008 this.leftDiv = document.createElement("div"); | |
32009 this.leftDiv.setAttribute('class', 'tagCloudDiv'); | |
32010 this.map.gui.mapWindow.appendChild(this.leftDiv); | |
32011 this.rightDiv = document.createElement("div"); | |
32012 this.rightDiv.setAttribute('class', 'tagCloudDiv'); | |
32013 this.map.gui.mapWindow.appendChild(this.rightDiv); | |
32014 for (var i = 0; i < this.placeLabels.length; i++) { | |
32015 if (i % 2 == 0) { | |
32016 this.leftDiv.appendChild(this.placeLabels[i].div); | |
32017 } else { | |
32018 this.rightDiv.appendChild(this.placeLabels[i].div); | |
32019 } | |
32020 this.placeLabels[i].div.setAttribute('style', this.placeLabels[i].allStyle + "" + this.placeLabels[i].highlightStyle); | |
32021 } | |
32022 this.placeTagCloud(); | |
32023 }; | |
32024 | |
32025 this.placeTagCloud = function() { | |
32026 var lonlat = new OpenLayers.LonLat(this.circle.feature.geometry.x, this.circle.feature.geometry.y); | |
32027 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
32028 var radius = this.circle.feature.style.pointRadius; | |
32029 var lw = this.leftDiv.offsetWidth; | |
32030 var rw = this.rightDiv.offsetWidth; | |
32031 this.leftDiv.style.left = (pixel.x - radius - lw - 5) + "px"; | |
32032 this.rightDiv.style.left = (pixel.x + radius + 5) + "px"; | |
32033 var lh = this.leftDiv.offsetHeight; | |
32034 var rh = this.rightDiv.offsetHeight; | |
32035 var lt = pixel.y - lh / 2; | |
32036 var rt = pixel.y - rh / 2; | |
32037 this.leftDiv.style.top = lt + "px"; | |
32038 this.rightDiv.style.top = rt + "px"; | |
32039 }; | |
32040 | |
32041 this.remove = function() { | |
32042 $(this.leftDiv).remove(); | |
32043 $(this.rightDiv).remove(); | |
32044 }; | |
32045 | |
32046 }; | |
32047 | |
32048 function PackPlacenameTags(circle, map) { | |
32049 | |
32050 this.circle = circle; | |
32051 this.map = map; | |
32052 | |
32053 this.placeLabels | |
32054 this.selectedLabel | |
32055 | |
32056 this.allLabel | |
32057 this.othersLabel | |
32058 this.unknownLabel | |
32059 | |
32060 this.calculate = function() { | |
32061 this.calculateLabels(); | |
32062 this.calculatePlacenameTags(); | |
32063 } | |
32064 | |
32065 this.getLabelList = function(circle) { | |
32066 | |
32067 var elements = circle.elements; | |
32068 var k = circle.search; | |
32069 var weight = 0; | |
32070 var labels = []; | |
32071 var levelOfDetail = this.map.getLevelOfDetail(); | |
32072 for (var i = 0; i < elements.length; i++) { | |
32073 weight += elements[i].weight; | |
32074 var found = false; | |
32075 var label = elements[i].getPlace(this.map.options.mapIndex, levelOfDetail); | |
32076 if (label == "") { | |
32077 label = "unknown"; | |
32078 } | |
32079 for (var j = 0; j < labels.length; j++) { | |
32080 if (labels[j].place == label) { | |
32081 labels[j].elements.push(elements[i]); | |
32082 labels[j].weight += elements[i].weight; | |
32083 found = true; | |
32084 break; | |
32085 } | |
32086 } | |
32087 if (!found) { | |
32088 labels.push({ | |
32089 id : elements[i].name, | |
32090 place : label, | |
32091 elements : new Array(elements[i]), | |
32092 weight : elements[i].weight, | |
32093 index : k | |
32094 }); | |
32095 } | |
32096 } | |
32097 var sortBySize = function(label1, label2) { | |
32098 if (label1.weight > label2.weight) { | |
32099 return -1; | |
32100 } | |
32101 return 1; | |
32102 } | |
32103 labels.sort(sortBySize); | |
32104 var droppedLabels = []; | |
32105 if (map.options.maxPlaceLabels) { | |
32106 var ml = map.options.maxPlaceLabels; | |
32107 if (ml == 1) { | |
32108 labels = []; | |
32109 labels.push({ | |
32110 place : "all", | |
32111 elements : elements, | |
32112 weight : weight, | |
32113 index : k | |
32114 }); | |
32115 } | |
32116 if (ml == 2) { | |
32117 ml++; | |
32118 } | |
32119 if (ml > 2 && labels.length + 1 > ml) { | |
32120 var c = []; | |
32121 var w = 0; | |
32122 for (var i = ml - 2; i < labels.length; i++) { | |
32123 c = c.concat(labels[i].elements); | |
32124 w += labels[i].weight; | |
32125 droppedLabels.push(labels[i]); | |
32126 } | |
32127 labels = labels.slice(0, ml - 2); | |
32128 var ol = { | |
32129 place : "others", | |
32130 elements : c, | |
32131 weight : w, | |
32132 index : k | |
32133 }; | |
32134 labels.push(ol); | |
32135 this.othersLabels.push(ol); | |
32136 } | |
32137 } | |
32138 if (labels.length > 1) { | |
32139 labels.push({ | |
32140 place : "all", | |
32141 elements : elements, | |
32142 weight : weight, | |
32143 index : k | |
32144 }); | |
32145 } | |
32146 this.placeLabels.push(labels); | |
32147 this.droppedLabels.push(droppedLabels); | |
32148 }; | |
32149 | |
32150 this.calculateLabels = function() { | |
32151 var circles = this.circle.circles; | |
32152 this.placeLabels = []; | |
32153 this.droppedLabels = []; | |
32154 this.othersLabels = []; | |
32155 for (var i = 0; i < circles.length; i++) { | |
32156 this.getLabelList(circles[i]); | |
32157 } | |
32158 }; | |
32159 | |
32160 this.calculatePlacenameTags = function() { | |
32161 var cloud = this; | |
32162 | |
32163 var unselectedStyles = []; | |
32164 var selectedStyles = []; | |
32165 var hoverStyles = []; | |
32166 | |
32167 for (var k = 0; k < this.placeLabels.length; k++) { | |
32168 var c = GeoTemConfig.getColor(this.circle.circles[k].search); | |
32169 if( map.options.useGraphics ){ | |
32170 c = map.config.getGraphic(this.circle.circles[k].search).color; | |
32171 } | |
32172 var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
32173 var color1 = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
32174 var allStyles = "", hoverStyle = "", highlightStyle = "", selectedStyle = "", unselectedStyle = ""; | |
32175 | |
32176 if (GeoTemConfig.ie) { | |
32177 highlightStyle += map.options.ieHighlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32178 hoverStyle += map.options.ieHoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32179 selectedStyle += map.options.ieSelectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32180 unselectedStyle += map.options.ieUnselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32181 } else { | |
32182 highlightStyle += map.options.highlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32183 hoverStyle += map.options.hoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32184 selectedStyle += map.options.selectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32185 unselectedStyle += map.options.unselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
32186 } | |
32187 | |
32188 allStyles += 'margin-right:5px;'; | |
32189 allStyles += 'margin-left:5px;'; | |
32190 unselectedStyles.push(unselectedStyle); | |
32191 selectedStyles.push(selectedStyle); | |
32192 hoverStyles.push(hoverStyle); | |
32193 | |
32194 var clickFunction = function(label, id) { | |
32195 label.div.onmouseover = function() { | |
32196 if (!label.opposite) { | |
32197 var oppositeLabel, oppositeLabelDiv; | |
32198 label.div.setAttribute('style', allStyles + "" + selectedStyles[id]); | |
32199 var c = GeoTemConfig.getColor(id); | |
32200 if( map.options.useGraphics ){ | |
32201 c = map.config.getGraphic(id).color; | |
32202 } | |
32203 var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
32204 if (id == 0) { | |
32205 for (var i = 0; i < cloud.droppedLabels[1].length; i++) { | |
32206 if (cloud.droppedLabels[1][i].place == label.place) { | |
32207 oppositeLabel = cloud.droppedLabels[1][i]; | |
32208 cloud.rightDiv.appendChild(oppositeLabel.div); | |
32209 cloud.drawLine(cloud.ctxOl, label.div, oppositeLabel.div); | |
32210 var olDiv = cloud.othersLabels[1].div; | |
32211 olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + (cloud.othersLabels[1].weight - oppositeLabel.weight) + ')'); | |
32212 break; | |
32213 } | |
32214 } | |
32215 } else { | |
32216 for (var i = 0; i < cloud.droppedLabels[0].length; i++) { | |
32217 if (cloud.droppedLabels[0][i].place == label.place) { | |
32218 oppositeLabel = cloud.droppedLabels[0][i]; | |
32219 cloud.leftDiv.appendChild(oppositeLabel.div); | |
32220 cloud.drawLine(cloud.ctxOl, oppositeLabel.div, label.div); | |
32221 var olDiv = cloud.othersLabels[0].div; | |
32222 olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + (cloud.othersLabels[0].weight - oppositeLabel.weight) + ')'); | |
32223 break; | |
32224 } | |
32225 } | |
32226 } | |
32227 if ( typeof oppositeLabel == 'undefined') { | |
32228 oppositeLabel = { | |
32229 div : cloud.naDiv | |
32230 }; | |
32231 if (id == 0) { | |
32232 cloud.rightDiv.appendChild(cloud.naDiv); | |
32233 cloud.drawLine(cloud.ctxOl, label.div, cloud.naDiv); | |
32234 oppositeLabel.div.setAttribute('style', allStyles + "" + selectedStyles[1]); | |
32235 } else { | |
32236 cloud.leftDiv.appendChild(cloud.naDiv); | |
32237 cloud.drawLine(cloud.ctxOl, cloud.naDiv, label.div); | |
32238 oppositeLabel.div.setAttribute('style', allStyles + "" + selectedStyles[0]); | |
32239 } | |
32240 cloud.map.mapLabelHighlight(label); | |
32241 } else { | |
32242 cloud.map.mapLabelHighlight([label, oppositeLabel]); | |
32243 } | |
32244 label.div.onmouseout = function() { | |
32245 label.div.setAttribute('style', allStyles + "" + unselectedStyles[id]); | |
32246 var olDiv = cloud.othersLabels[0].div; | |
32247 olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + cloud.othersLabels[0].weight + ')'); | |
32248 var olDiv2 = cloud.othersLabels[1].div; | |
32249 olDiv2.innerHTML = olDiv2.innerHTML.replace(/\(\d*\)/g, '(' + cloud.othersLabels[1].weight + ')'); | |
32250 $(oppositeLabel.div).remove(); | |
32251 cloud.ctxOl.clearRect(0, 0, cloud.cvOl.width, cloud.cvOl.height); | |
32252 cloud.map.mapLabelHighlight(); | |
32253 } | |
32254 } | |
32255 } | |
32256 } | |
32257 var maxLabelSize = this.count | |
32258 for (var i = 0; i < this.placeLabels[k].length; i++) { | |
32259 var l = this.placeLabels[k][i]; | |
32260 l.selected = false; | |
32261 var div = document.createElement("div"); | |
32262 div.setAttribute('class', 'tagCloudItem'); | |
32263 var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; | |
32264 if (l.place == "all") { | |
32265 fontSize = 1; | |
32266 } | |
32267 div.style.fontSize = fontSize + "em"; | |
32268 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
32269 l.selectedStyle = selectedStyle; | |
32270 l.unselectedStyle = unselectedStyle; | |
32271 l.hoverStyle = hoverStyle; | |
32272 div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; | |
32273 l.div = div; | |
32274 clickFunction(l, k); | |
32275 } | |
32276 for (var i = 0; i < this.droppedLabels[k].length; i++) { | |
32277 var l = this.droppedLabels[k][i]; | |
32278 l.selected = false; | |
32279 var div = document.createElement("div"); | |
32280 div.setAttribute('class', 'tagCloudItem'); | |
32281 var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; | |
32282 div.style.fontSize = fontSize + "em"; | |
32283 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
32284 l.selectedStyle = selectedStyle; | |
32285 l.unselectedStyle = unselectedStyle; | |
32286 l.hoverStyle = hoverStyle; | |
32287 div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; | |
32288 l.div = div; | |
32289 div.setAttribute('style', allStyles + "" + selectedStyle); | |
32290 } | |
32291 } | |
32292 | |
32293 this.naDiv = document.createElement("div"); | |
32294 this.naDiv.setAttribute('class', 'tagCloudItem'); | |
32295 var fontSize = 1; | |
32296 div.style.fontSize = fontSize + "em"; | |
32297 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
32298 l.selectedStyle = selectedStyle; | |
32299 l.unselectedStyle = unselectedStyle; | |
32300 l.hoverStyle = hoverStyle; | |
32301 this.naDiv.innerHTML = "Not available"; | |
32302 l.div = this.naDiv; | |
32303 | |
32304 if (map.options.labelGrid) { | |
32305 this.showPlacelabels(); | |
32306 } | |
32307 }; | |
32308 | |
32309 this.showPlacelabels = function() { | |
32310 this.leftDiv = document.createElement("div"); | |
32311 this.leftDiv.setAttribute('class', 'tagCloudDiv'); | |
32312 this.leftDiv.style.textAlign = 'right'; | |
32313 this.map.gui.mapWindow.appendChild(this.leftDiv); | |
32314 this.centerDiv = document.createElement("div"); | |
32315 this.centerDiv.setAttribute('class', 'tagCloudDiv'); | |
32316 this.centerDiv.style.opacity = 0.7; | |
32317 this.map.gui.mapWindow.appendChild(this.centerDiv); | |
32318 this.centerDivOl = document.createElement("div"); | |
32319 this.centerDivOl.setAttribute('class', 'tagCloudDiv'); | |
32320 this.centerDivOl.style.opacity = 0.7; | |
32321 this.map.gui.mapWindow.appendChild(this.centerDivOl); | |
32322 this.rightDiv = document.createElement("div"); | |
32323 this.rightDiv.setAttribute('class', 'tagCloudDiv'); | |
32324 this.rightDiv.style.textAlign = 'left'; | |
32325 this.map.gui.mapWindow.appendChild(this.rightDiv); | |
32326 for (var i = 0; i < this.placeLabels.length; i++) { | |
32327 for (var j = 0; j < this.placeLabels[i].length; j++) { | |
32328 if (i == 0) { | |
32329 this.leftDiv.appendChild(this.placeLabels[i][j].div); | |
32330 } else { | |
32331 this.rightDiv.appendChild(this.placeLabels[i][j].div); | |
32332 } | |
32333 this.placeLabels[i][j].div.setAttribute('style', this.placeLabels[i][j].allStyle + "" + this.placeLabels[i][j].unselectedStyle); | |
32334 } | |
32335 } | |
32336 this.placeTagCloud(); | |
32337 this.setCanvas(); | |
32338 }; | |
32339 | |
32340 this.placeTagCloud = function() { | |
32341 var lonlat = new OpenLayers.LonLat(this.circle.feature.geometry.x, this.circle.feature.geometry.y); | |
32342 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
32343 var radius = this.circle.feature.style.pointRadius; | |
32344 var lw = this.leftDiv.offsetWidth; | |
32345 var rw = this.rightDiv.offsetWidth; | |
32346 this.leftDiv.style.left = (pixel.x - radius - lw - 5) + "px"; | |
32347 this.rightDiv.style.left = (pixel.x + radius + 5) + "px"; | |
32348 var lh = this.leftDiv.offsetHeight; | |
32349 var rh = this.rightDiv.offsetHeight; | |
32350 var lt = pixel.y - lh / 2; | |
32351 var rt = pixel.y - rh / 2; | |
32352 this.leftDiv.style.top = lt + "px"; | |
32353 this.rightDiv.style.top = rt + "px"; | |
32354 }; | |
32355 | |
32356 this.setCanvas = function() { | |
32357 var height = Math.max(this.leftDiv.offsetHeight, this.rightDiv.offsetHeight); | |
32358 var top = Math.min(this.leftDiv.offsetTop, this.rightDiv.offsetTop); | |
32359 var left = this.leftDiv.offsetLeft + this.leftDiv.offsetWidth; | |
32360 this.width = this.rightDiv.offsetLeft - left; | |
32361 this.centerDiv.style.left = left + "px"; | |
32362 this.centerDiv.style.top = top + "px"; | |
32363 this.centerDiv.style.height = height + "px"; | |
32364 this.centerDiv.style.width = this.width + "px"; | |
32365 | |
32366 this.centerDivOl.style.left = left + "px"; | |
32367 this.centerDivOl.style.top = top + "px"; | |
32368 this.centerDivOl.style.height = height + "px"; | |
32369 this.centerDivOl.style.width = this.width + "px"; | |
32370 | |
32371 var cv = document.createElement("canvas"); | |
32372 this.centerDiv.appendChild(cv); | |
32373 if (!cv.getContext && G_vmlCanvasManager) { | |
32374 cv = G_vmlCanvasManager.initElement(cv); | |
32375 } | |
32376 cv.width = this.width; | |
32377 cv.height = height; | |
32378 ctx = cv.getContext('2d'); | |
32379 | |
32380 this.cvOl = document.createElement("canvas"); | |
32381 this.centerDivOl.appendChild(this.cvOl); | |
32382 if (!this.cvOl.getContext && G_vmlCanvasManager) { | |
32383 this.cvOl = G_vmlCanvasManager.initElement(this.cvOl); | |
32384 } | |
32385 this.cvOl.width = this.width; | |
32386 this.cvOl.height = height + 50; | |
32387 this.ctxOl = this.cvOl.getContext('2d'); | |
32388 | |
32389 for (var i = 0; i < this.placeLabels[0].length; i++) { | |
32390 this.placeLabels[0][i].opposite = false; | |
32391 } | |
32392 for (var i = 0; i < this.placeLabels[1].length; i++) { | |
32393 this.placeLabels[1][i].opposite = false; | |
32394 } | |
32395 for (var i = 0; i < this.placeLabels[0].length; i++) { | |
32396 for (var j = 0; j < this.placeLabels[1].length; j++) { | |
32397 if (this.placeLabels[0][i].place == this.placeLabels[1][j].place) { | |
32398 this.drawLine(ctx, this.placeLabels[0][i].div, this.placeLabels[1][j].div); | |
32399 this.placeLabels[0][i].opposite = true; | |
32400 this.placeLabels[1][j].opposite = true; | |
32401 } | |
32402 } | |
32403 } | |
32404 } | |
32405 | |
32406 this.drawLine = function(ctx, label1, label2) { | |
32407 var x1 = 5; | |
32408 var x2 = this.width - 5; | |
32409 var y1 = label1.offsetTop + label1.offsetHeight / 2; | |
32410 var y2 = label2.offsetTop + label2.offsetHeight / 2; | |
32411 if (this.leftDiv.offsetTop > this.rightDiv.offsetTop) { | |
32412 y1 += this.leftDiv.offsetTop - this.rightDiv.offsetTop; | |
32413 } else { | |
32414 y2 += this.rightDiv.offsetTop - this.leftDiv.offsetTop; | |
32415 } | |
32416 ctx.lineCap = 'round'; | |
32417 ctx.lineWidth = 5; | |
32418 ctx.beginPath(); | |
32419 ctx.moveTo(x1, y1); | |
32420 ctx.lineTo(x2, y2); | |
32421 ctx.strokeStyle = '#555'; | |
32422 ctx.stroke(); | |
32423 } | |
32424 | |
32425 this.remove = function() { | |
32426 $(this.leftDiv).remove(); | |
32427 $(this.rightDiv).remove(); | |
32428 $(this.centerDiv).remove(); | |
32429 $(this.centerDivOl).remove(); | |
32430 }; | |
32431 | |
32432 }; | |
32433 /* | |
32434 * MapConfig.js | |
32435 * | |
32436 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
32437 * | |
32438 * This library is free software; you can redistribute it and/or | |
32439 * modify it under the terms of the GNU Lesser General Public | |
32440 * License as published by the Free Software Foundation; either | |
32441 * version 3 of the License, or (at your option) any later version. | |
32442 * | |
32443 * This library is distributed in the hope that it will be useful, | |
32444 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32445 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
32446 * Lesser General Public License for more details. | |
32447 * | |
32448 * You should have received a copy of the GNU Lesser General Public | |
32449 * License along with this library; if not, write to the Free Software | |
32450 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
32451 * MA 02110-1301 USA | |
32452 */ | |
32453 | |
32454 /** | |
32455 * @class MapConfig | |
32456 * Map Configuration File | |
32457 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
32458 * @release 1.0 | |
32459 * @release date: 2012-07-27 | |
32460 * @version date: 2012-07-27 | |
32461 */ | |
32462 function MapConfig(options) { | |
32463 | |
32464 this.options = { | |
32465 mapWidth : false, // false or desired width css definition for the map | |
32466 mapHeight : false, // false or desired height css definition for the map | |
32467 mapTitle : 'GeoTemCo Map View', // title will be shown in map header | |
32468 mapIndex : 0, // index = position in location array; for multiple locations the 2nd map refers to index 1 | |
32469 alternativeMap : [ | |
32470 /* { | |
32471 name: 'Barrington Roman Empire', | |
32472 url: 'http://pelagios.dme.ait.ac.at/tilesets/imperium/${z}/${x}/${y}.png', | |
32473 type:'XYZ', | |
32474 attribution: "(c) Barrington Roman Empiry, <a href='http://pelagios.dme.ait.ac.at/maps/greco-roman/'>Pelagios</a>" | |
32475 }, | |
32476 { | |
32477 name: 'Maps-for-Free Relief Map', | |
32478 url: 'http://maps-for-free.com/layer/relief/z${z}/row${y}/${z}_${x}-${y}.jpg', | |
32479 type:'XYZ', | |
32480 attribution: "(c) <a href='http://www.maps-for-free.com/html/about.html'>Maps for Free</a>" | |
32481 }, | |
32482 { | |
32483 name: 'Contemporary Map (2010)', | |
32484 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32485 layer: 'historic:cntry2010', | |
32486 attribution: "(c) <a href='http://epp.eurostat.ec.europa.eu/portal/page/portal/gisco_Geographical_information_maps/popups/references/administrative_units_statistical_units_1'>EuroStat</a>" | |
32487 }, | |
32488 { | |
32489 name: 'Historical Map of 2006', | |
32490 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32491 layer: 'historic:cntry2006', | |
32492 attribution: "(c) <a href='http://epp.eurostat.ec.europa.eu/portal/page/portal/gisco_Geographical_information_maps/popups/references/administrative_units_statistical_units_1'>EuroStat</a>" | |
32493 }, | |
32494 { | |
32495 name: 'Historical Map of 1994', | |
32496 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32497 layer: 'historic:cntry1994', | |
32498 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32499 }, | |
32500 { | |
32501 name: 'Historical Map of 1945', | |
32502 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32503 layer: 'historic:cntry1945', | |
32504 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32505 }, | |
32506 { | |
32507 name: 'Historical Map of 1938', | |
32508 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32509 layer: 'historic:cntry1938', | |
32510 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32511 }, | |
32512 { | |
32513 name: 'Historical Map of 1920', | |
32514 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32515 layer: 'historic:cntry1920', | |
32516 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32517 }, | |
32518 { | |
32519 name: 'Historical Map of 1914', | |
32520 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32521 layer: 'historic:cntry1914', | |
32522 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32523 }, | |
32524 { | |
32525 name: 'Historical Map of 1880', | |
32526 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32527 layer: 'historic:cntry1880', | |
32528 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32529 }, | |
32530 { | |
32531 name: 'Historical Map of 1815', | |
32532 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32533 layer: 'historic:cntry1815', | |
32534 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32535 }, | |
32536 { | |
32537 name: 'Historical Map of 1783', | |
32538 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32539 layer: 'historic:cntry1783', | |
32540 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32541 }, | |
32542 { | |
32543 name: 'Historical Map of 1715', | |
32544 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32545 layer: 'historic:cntry1715', | |
32546 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32547 }, | |
32548 { | |
32549 name: 'Historical Map of 1650', | |
32550 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32551 layer: 'historic:cntry1650', | |
32552 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32553 }, | |
32554 { | |
32555 name: 'Historical Map of 1530', | |
32556 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32557 layer: 'historic:cntry1530', | |
32558 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32559 }, | |
32560 { | |
32561 name: 'Historical Map of 1492', | |
32562 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32563 layer: 'historic:cntry1492', | |
32564 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32565 }, | |
32566 { | |
32567 name: 'Historical Map of 1279', | |
32568 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32569 layer: 'historic:cntry1279', | |
32570 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32571 }, | |
32572 { | |
32573 name: 'Historical Map of 1000', | |
32574 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32575 layer: 'historic:cntry1000', | |
32576 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32577 }, | |
32578 { | |
32579 name: 'Historical Map of 800', | |
32580 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32581 layer: 'historic:cntry800', | |
32582 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32583 }, | |
32584 { | |
32585 name: 'Historical Map of 600', | |
32586 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32587 layer: 'historic:cntry600', | |
32588 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32589 }, | |
32590 { | |
32591 name: 'Historical Map of 400', | |
32592 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32593 layer: 'historic:cntry400', | |
32594 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32595 }, | |
32596 { | |
32597 name: 'Historical Map of 1 BC', | |
32598 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32599 layer: 'historic:cntry1bc', | |
32600 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32601 }, | |
32602 { | |
32603 name: 'Historical Map of 200 BC', | |
32604 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32605 layer: 'historic:cntry200bc', | |
32606 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32607 }, | |
32608 { | |
32609 name: 'Historical Map of 323 BC', | |
32610 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32611 layer: 'historic:cntry323bc', | |
32612 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32613 }, | |
32614 { | |
32615 name: 'Historical Map of 500 BC', | |
32616 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32617 layer: 'historic:cntry500bc', | |
32618 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32619 }, | |
32620 */ | |
32621 { | |
32622 name: 'Historical Map of 1000 BC', | |
32623 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32624 layer: 'historic:cntry1000bc', | |
32625 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32626 }, | |
32627 { | |
32628 name: 'Historical Map of 2000 BC', | |
32629 url: 'http://geoserver.mpiwg-berlin.mpg.de/geoserver/mpiwg/wms', | |
32630 layer: 'historic:cntry2000bc', | |
32631 attribution: "(c) <a href='http://webcache.googleusercontent.com/search?q=cache:NbaEeiehhzQJ:library.thinkquest.org/C006628/citations.html&client=ubuntu&hl=de&gl=de&strip=1'> ThinkQuest Team C006628</a>" | |
32632 }, | |
32633 ], | |
32634 legend : true, // if a legend at the bottom of the map should be shown or not | |
32635 mapMerge : false, // if the elements of distinct datasets should be merged into one set or not | |
32636 useGraphics : false, // if different graphics should represent different datasets or not | |
32637 graphics : [ | |
32638 { | |
32639 shape: "circle", | |
32640 rotation: 0 | |
32641 }, | |
32642 { | |
32643 shape: "square", | |
32644 rotation: 0 | |
32645 }, | |
32646 { | |
32647 shape: "triangle", | |
32648 rotation: 0 | |
32649 }, | |
32650 { | |
32651 shape: "square", | |
32652 rotation: 45 | |
32653 } | |
32654 ], | |
32655 googleMaps : false, // enable/disable Google maps (actually, no Google Maps API key is required) | |
32656 bingMaps : false, // enable/disable Bing maps (you need to set the Bing Maps API key below) | |
32657 bingApiKey : 'none', // bing maps api key, see informations at http://bingmapsportal.com/ | |
32658 osmMaps : true, // enable/disable OSM maps | |
32659 osmMapsMapQuest : true, // enable/disable OSM maps with MapQuest tiles | |
32660 baseLayer : 'Open Street Map', // initial layer to show (e.g. 'Google Streets') | |
32661 resetMap : true, // show/hide map reset button | |
32662 countrySelect : true, // show/hide map country selection control button | |
32663 polygonSelect : true, // show/hide map polygon selection control button | |
32664 circleSelect : true, // show/hide map circle selection control button | |
32665 squareSelect : true, // show/hide map square selection control button | |
32666 multiSelection : true, // true, if multiple polygons or multiple circles should be selectable | |
32667 popups : true, // enabled popups will show popup windows for circles on the map | |
32668 olNavigation : false, // show/hide OpenLayers navigation panel | |
32669 olLayerSwitcher : false, // show/hide OpenLayers layer switcher | |
32670 olMapOverview : false, // show/hide OpenLayers map overview | |
32671 olKeyboardDefaults : true, // (de)activate Openlayers keyboard defaults | |
32672 olScaleLine : false, // (de)activate Openlayers keyboard defaults | |
32673 geoLocation : true, // show/hide GeoLocation feature | |
32674 boundaries : { | |
32675 minLon : -29, | |
32676 minLat : 35, | |
32677 maxLon : 44, | |
32678 maxLat : 67 | |
32679 }, // initial map boundaries or 'false' for no boundaries | |
32680 mapBackground : '#bbd0ed', | |
32681 labelGrid : true, // show label grid on hover | |
32682 maxPlaceLabels : 6, // Integer value for fixed number of place labels: 0 --> unlimited, 1 --> 1 label (won't be shown in popup, 2 --> is not possible because of others & all labels --> 3 labels, [3,...,N] --> [3,...,N] place labels) | |
32683 selectDefault : true, // true, if strongest label should be selected as default | |
32684 maxLabelIncrease : 2, // maximum increase (in em) for the font size of a label | |
32685 labelHover : false, // true, to update on label hover | |
32686 ieHighlightLabel : "color: COLOR1; background-color: COLOR0; filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';", // css code for a highlighted place label in IE | |
32687 highlightLabel : "color: COLOR0; text-shadow: 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em COLOR0;", // css code for a highlighted place label | |
32688 ieSelectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label in IE | |
32689 selectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label | |
32690 ieUnselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label in IE | |
32691 unselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label | |
32692 ieHoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label in IE | |
32693 hoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label | |
32694 circleGap : 0, // gap between the circles on the map (>=0) | |
32695 circleOverlap : { | |
32696 type: 'area', // 'area' or 'diameter' is possible | |
32697 overlap: 1 // the percentage of allowed overlap (0<=overlap<=1) | |
32698 }, // maximum allowed overlap in percent (if circleGap = 0, circleOverlap will be used) | |
32699 minimumRadius : 1, // minimum radius of a circle with mimimal weight (>0) | |
32700 circleOutline : 2, // false for no outline or a pixel value v with 0 < v | |
32701 circleOpacity : 'balloon', // 'balloon' for dynamic opacity of the circles or a value t with 0 <= t <= 1 | |
32702 minTransparency : 0.55, // maximum transparency of a circle | |
32703 maxTransparency : 0.8, // minimum transparency of a circle | |
32704 binning : 'generic', // binning algorithm for the map, possible values are: 'generic', 'square', 'hexagonal', 'triangular' or false for 'no binning' | |
32705 noBinningRadii : 'dynamic', // for 'no binning': 'static' for only minimum radii, 'dynamic' for increasing radii for increasing weights | |
32706 circlePackings : true, // if circles of multiple result sets should be displayed in circle packs, if a binning is performed | |
32707 binCount : 10, // number of bins for x and y dimension for lowest zoom level | |
32708 showDescriptions : true, // true to show descriptions of data items (must be provided by kml/json), false if not | |
32709 mapSelection : true, // show/hide select map dropdown | |
32710 binningSelection : false, // show/hide binning algorithms dropdown | |
32711 mapSelectionTools : true, // show/hide map selector tools | |
32712 dataInformation : true, // show/hide data information | |
32713 overlayVisibility : false, // initial visibility of additional overlays | |
32714 //proxyHost : 'php/proxy.php?address=', //required for selectCountry feature, if the requested GeoServer and GeoTemCo are NOT on the same server | |
32715 placenameTagsStyle : 'value' // the style of the placenames "surrounding" a circle on hover. 'zoom' for tags based on zoom level (old behaviour), 'value' for new value-based | |
32716 | |
32717 }; | |
32718 if ( typeof options != 'undefined') { | |
32719 $.extend(this.options, options); | |
32720 } | |
32721 | |
32722 //if the user can change shape/color graphics have to be used | |
32723 //but this will use circles as default shape | |
32724 if (GeoTemConfig.allowUserShapeAndColorChange){ | |
32725 this.options.useGraphics = true; | |
32726 } | |
32727 | |
32728 }; | |
32729 | |
32730 MapConfig.prototype.getGraphic = function(id){ | |
32731 var dataset = GeoTemConfig.datasets[id]; | |
32732 | |
32733 var graphic; | |
32734 if (typeof dataset.graphic !== "undefined"){ | |
32735 graphic = dataset.graphic; | |
32736 } else{ | |
32737 graphic = this.options.graphics[id % this.options.graphics.length]; | |
32738 } | |
32739 | |
32740 var color; | |
32741 if (typeof dataset.color !== "undefined"){ | |
32742 color = dataset.color; | |
32743 } else{ | |
32744 color = GeoTemConfig.getColor(id); | |
32745 } | |
32746 return { | |
32747 shape: graphic.shape, | |
32748 rotation: graphic.rotation, | |
32749 color: color | |
32750 }; | |
32751 }; | |
32752 /* | |
32753 * MapGui.js | |
32754 * | |
32755 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
32756 * | |
32757 * This library is free software; you can redistribute it and/or | |
32758 * modify it under the terms of the GNU Lesser General Public | |
32759 * License as published by the Free Software Foundation; either | |
32760 * version 3 of the License, or (at your option) any later version. | |
32761 * | |
32762 * This library is distributed in the hope that it will be useful, | |
32763 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32764 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
32765 * Lesser General Public License for more details. | |
32766 * | |
32767 * You should have received a copy of the GNU Lesser General Public | |
32768 * License along with this library; if not, write to the Free Software | |
32769 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
32770 * MA 02110-1301 USA | |
32771 */ | |
32772 | |
32773 /** | |
32774 * @class MapGui | |
32775 * Map GUI Implementation | |
32776 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
32777 * @release 1.0 | |
32778 * @release date: 2012-07-27 | |
32779 * @version date: 2012-07-27 | |
32780 * | |
32781 * @param {MapWidget} parent map widget object | |
32782 * @param {HTML object} div parent div to append the map gui | |
32783 * @param {JSON} options map configuration | |
32784 */ | |
32785 function MapGui(map, div, options, iid) { | |
32786 | |
32787 this.map = map; | |
32788 | |
32789 this.container = div; | |
32790 if (options.mapWidth) { | |
32791 this.container.style.width = options.mapWidth; | |
32792 } | |
32793 if (options.mapHeight) { | |
32794 this.container.style.height = options.mapHeight; | |
32795 } | |
32796 this.container.style.position = 'relative'; | |
32797 | |
32798 this.mapWindow = document.createElement("div"); | |
32799 this.mapWindow.setAttribute('class', 'mapWindow'); | |
32800 this.mapWindow.id = "mapWindow"+iid; | |
32801 this.mapWindow.style.background = options.mapBackground; | |
32802 this.container.appendChild(this.mapWindow); | |
32803 | |
32804 this.mapContainer = document.createElement("div"); | |
32805 this.mapContainer.setAttribute('class', 'mapContainer'); | |
32806 this.mapContainer.id = "mapContainer"+iid; | |
32807 this.mapContainer.style.position = "absolute"; | |
32808 this.mapContainer.style.zIndex = 0; | |
32809 this.mapWindow.appendChild(this.mapContainer); | |
32810 | |
32811 var toolbarTable = document.createElement("table"); | |
32812 toolbarTable.setAttribute('class', 'absoluteToolbar ddbToolbar'); | |
32813 this.container.appendChild(toolbarTable); | |
32814 this.mapToolbar = toolbarTable; | |
32815 | |
32816 var titles = document.createElement("tr"); | |
32817 toolbarTable.appendChild(titles); | |
32818 var tools = document.createElement("tr"); | |
32819 toolbarTable.appendChild(tools); | |
32820 | |
32821 if (options.mapSelection) { | |
32822 this.mapTypeTitle = document.createElement("td"); | |
32823 titles.appendChild(this.mapTypeTitle); | |
32824 this.mapTypeTitle.innerHTML = GeoTemConfig.getString('mapType'); | |
32825 this.mapTypeSelector = document.createElement("td"); | |
32826 tools.appendChild(this.mapTypeSelector); | |
32827 } | |
32828 | |
32829 if (options.mapSelectionTools) { | |
32830 this.mapSelectorTitle = document.createElement("td"); | |
32831 titles.appendChild(this.mapSelectorTitle); | |
32832 this.mapSelectorTitle.innerHTML = GeoTemConfig.getString('mapSelectorTools'); | |
32833 var mapSelectorTools = document.createElement("td"); | |
32834 var selectorTools = this.map.initSelectorTools(); | |
32835 for (var i in selectorTools ) { | |
32836 mapSelectorTools.appendChild(selectorTools[i].button); | |
32837 } | |
32838 tools.appendChild(mapSelectorTools); | |
32839 } | |
32840 | |
32841 if (options.binningSelection) { | |
32842 this.binningTitle = document.createElement("td"); | |
32843 titles.appendChild(this.binningTitle); | |
32844 this.binningTitle.innerHTML = GeoTemConfig.getString('binningType'); | |
32845 this.binningSelector = document.createElement("td"); | |
32846 tools.appendChild(this.binningSelector); | |
32847 } | |
32848 | |
32849 if (GeoTemConfig.allowFilter) { | |
32850 this.filterTitle = document.createElement("td"); | |
32851 titles.appendChild(this.filterTitle); | |
32852 this.filterTitle.innerHTML = GeoTemConfig.getString('filter'); | |
32853 this.filterOptions = document.createElement("td"); | |
32854 tools.appendChild(this.filterOptions); | |
32855 } | |
32856 | |
32857 if (options.dataInformation) { | |
32858 this.infoTitle = document.createElement("td"); | |
32859 this.infoTitle.innerHTML = options.mapTitle; | |
32860 titles.appendChild(this.infoTitle); | |
32861 var mapSum = document.createElement("td"); | |
32862 this.mapElements = document.createElement("div"); | |
32863 this.mapElements.setAttribute('class', 'ddbElementsCount'); | |
32864 mapSum.appendChild(this.mapElements); | |
32865 tools.appendChild(mapSum); | |
32866 } | |
32867 | |
32868 this.lockTitle = document.createElement("td"); | |
32869 titles.appendChild(this.lockTitle); | |
32870 this.lockIcon = document.createElement("td"); | |
32871 var lockButton = document.createElement("div"); | |
32872 $(lockButton).addClass('mapControl'); | |
32873 var activateLock = function() { | |
32874 map.navigation.deactivate(); | |
32875 } | |
32876 var deactivateLock = function() { | |
32877 map.navigation.activate(); | |
32878 } | |
32879 var lockMapControl = new MapControl(this.map, lockButton, 'lock', activateLock, deactivateLock); | |
32880 tools.appendChild(lockMapControl.button); | |
32881 | |
32882 | |
32883 var gui = this; | |
32884 if (navigator.geolocation && options.geoLocation) { | |
32885 this.geoActive = false; | |
32886 this.geoLocation = document.createElement("div"); | |
32887 this.geoLocation.setAttribute('class', 'geoLocationOff'); | |
32888 this.geoLocation.title = GeoTemConfig.getString('activateGeoLocation'); | |
32889 this.container.appendChild(this.geoLocation); | |
32890 this.geoLocation.style.left = "20px"; | |
32891 this.geoLocation.onclick = function() { | |
32892 var changeStyle = function() { | |
32893 if (gui.geoActive) { | |
32894 gui.geoLocation.setAttribute('class', 'geoLocationOn'); | |
32895 gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'deactivateGeoLocation'); | |
32896 } else { | |
32897 gui.geoLocation.setAttribute('class', 'geoLocationOff'); | |
32898 gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'activateGeoLocation'); | |
32899 } | |
32900 } | |
32901 if (!gui.geoActive) { | |
32902 if ( typeof gui.longitude == 'undefined') { | |
32903 navigator.geolocation.getCurrentPosition(function(position) { | |
32904 gui.longitude = position.coords.longitude; | |
32905 gui.latitude = position.coords.latitude; | |
32906 gui.map.setMarker(gui.longitude, gui.latitude); | |
32907 gui.geoActive = true; | |
32908 changeStyle(); | |
32909 }, function(msg) { | |
32910 console.log( typeof msg == 'string' ? msg : "error"); | |
32911 }); | |
32912 } else { | |
32913 gui.map.setMarker(gui.longitude, gui.latitude); | |
32914 gui.geoActive = true; | |
32915 changeStyle(); | |
32916 } | |
32917 } else { | |
32918 gui.map.removeMarker(); | |
32919 gui.geoActive = false; | |
32920 changeStyle(); | |
32921 } | |
32922 } | |
32923 } | |
32924 | |
32925 if (!options.olNavigation) { | |
32926 this.map.zoomSlider = new MapZoomSlider(this.map, "vertical"); | |
32927 this.container.appendChild(this.map.zoomSlider.div); | |
32928 this.map.zoomSlider.div.style.left = "20px"; | |
32929 } | |
32930 | |
32931 if (options.resetMap) { | |
32932 this.homeButton = document.createElement("div"); | |
32933 this.homeButton.setAttribute('class', 'mapHome'); | |
32934 this.homeButton.title = GeoTemConfig.getString('home'); | |
32935 this.container.appendChild(this.homeButton); | |
32936 this.homeButton.style.left = "20px"; | |
32937 this.homeButton.onclick = function() { | |
32938 if (map.mds.getAllObjects() == null){ | |
32939 map.openlayersMap.setCenter(new OpenLayers.LonLat(0, 0)); | |
32940 map.openlayersMap.zoomTo(0); | |
32941 } | |
32942 gui.map.drawObjectLayer(true); | |
32943 } | |
32944 } | |
32945 | |
32946 if (options.legend) { | |
32947 this.legendDiv = document.createElement("div"); | |
32948 this.legendDiv.setAttribute('class', 'mapLegend'); | |
32949 this.mapWindow.appendChild(this.legendDiv); | |
32950 } | |
32951 | |
32952 var linkForOsm = 'http://www.openstreetmap.org/'; | |
32953 var linkForLicense = 'http://creativecommons.org/licenses/by-sa/2.0/'; | |
32954 this.osmLink = document.createElement("div"); | |
32955 this.osmLink.setAttribute('class', 'osmLink'); | |
32956 this.osmLink.innerHTML = '(c) <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>'; | |
32957 this.mapWindow.appendChild(this.osmLink); | |
32958 this.osmMapQuestLink = document.createElement("div"); | |
32959 this.osmMapQuestLink.setAttribute('class', 'osmLink'); | |
32960 this.osmMapQuestLink.innerHTML = '(c) Data, imagery and map information provided by MapQuest <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png"> <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>'; | |
32961 this.mapWindow.appendChild(this.osmMapQuestLink); | |
32962 | |
32963 // var tooltip = document.createElement("div"); | |
32964 // tooltip.setAttribute('class','ddbTooltip'); | |
32965 // toolbarTable.appendChild(tooltip); | |
32966 | |
32967 // var tooltip = document.createElement("div"); | |
32968 // tooltip.setAttribute('class','ddbTooltip'); | |
32969 // toolbarTable.appendChild(tooltip); | |
32970 // | |
32971 // tooltip.onmouseover = function(){ | |
32972 // /* | |
32973 // Publisher.Publish('TooltipContent', { | |
32974 // content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'), | |
32975 // target: $(tooltip) | |
32976 // }); | |
32977 // */ | |
32978 // } | |
32979 // tooltip.onmouseout = function(){ | |
32980 // // Publisher.Publish('TooltipContent'); | |
32981 // } | |
32982 // //vhz tooltip on click should open a help file if defined in GeoTemConfig | |
32983 // if(GeoTemConfig.helpURL) { | |
32984 // tooltip.onclick = function () { | |
32985 // | |
32986 // } | |
32987 // } | |
32988 | |
32989 // } | |
32990 // tooltip.onmouseout = function(){ | |
32991 // Publisher.Publish('TooltipContent'); | |
32992 // } | |
32993 | |
32994 this.resize = function() { | |
32995 var w = this.container.offsetWidth; | |
32996 var h = this.container.offsetHeight; | |
32997 // this.mapWindow.style.width = w + "px"; | |
32998 this.mapWindow.style.height = h + "px"; | |
32999 // this.mapContainer.style.width = w + "px"; | |
33000 this.mapContainer.style.height = h + "px"; | |
33001 var top = toolbarTable.offsetHeight + 20; | |
33002 if (options.olLayerSwitcher) { | |
33003 var switcherDiv = $('.olControlLayerSwitcher')[0]; | |
33004 $(switcherDiv).css('top', top + "px"); | |
33005 } | |
33006 if ( typeof this.geoLocation != "undefined") { | |
33007 this.geoLocation.style.top = top + "px"; | |
33008 top += this.geoLocation.offsetHeight + 4; | |
33009 } | |
33010 if (options.olNavigation) { | |
33011 var panZoomBar = $('.olControlPanZoom')[0]; | |
33012 $(panZoomBar).css('top', top + 'px'); | |
33013 $(panZoomBar).css('left', '12px'); | |
33014 var zoomOut = document.getElementById('OpenLayers.Control.PanZoom_23_zoomout'); | |
33015 top += $(zoomOut).height() + $(zoomOut).position().top + 4; | |
33016 } else { | |
33017 this.map.zoomSlider.div.style.top = top + "px"; | |
33018 top += this.map.zoomSlider.div.offsetHeight + 2; | |
33019 } | |
33020 if (options.resetMap) { | |
33021 this.homeButton.style.top = top + "px"; | |
33022 } | |
33023 this.headerHeight = toolbarTable.offsetHeight; | |
33024 this.headerWidth = toolbarTable.offsetWidth; | |
33025 this.map.openlayersMap.updateSize(); | |
33026 this.map.drawObjectLayer(true); | |
33027 }; | |
33028 | |
33029 this.updateLegend = function(datasets){ | |
33030 $(this.legendDiv).empty(); | |
33031 var table = $('<table style="margin:10px"/>').appendTo(this.legendDiv); | |
33032 for( var i=0; i<datasets.length; i++ ){ | |
33033 var row = $('<tr/>').appendTo(table); | |
33034 if( options.useGraphics ){ | |
33035 var graphic = map.config.getGraphic(i); | |
33036 var fill = 'rgb(' + graphic.color.r0 + ',' + graphic.color.g0 + ',' + graphic.color.b0 + ')'; | |
33037 var stroke = 'rgb(' + graphic.color.r1 + ',' + graphic.color.g1 + ',' + graphic.color.b1 + ')'; | |
33038 var rot = graphic.rotation; | |
33039 var svg; | |
33040 if( graphic.shape == 'circle' ){ | |
33041 svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>'; | |
33042 } | |
33043 else if( graphic.shape == 'square' ){ | |
33044 svg = '<svg style="width:20px;height:20px;"><polygon points="4,4 16,4 16,16 4,16" style="fill:'+fill+';stroke:'+stroke+';stroke-width:2" transform="rotate('+rot+' 10,10)"/></svg>'; | |
33045 } | |
33046 else if( graphic.shape == 'triangle' ){ | |
33047 svg = '<svg style="width:20px;height:20px;"><polygon points="3,17 17,17 10,5" style="fill:'+fill+';stroke:'+stroke+';stroke-width:2" transform="rotate('+rot+' 10,10)"/></svg>'; | |
33048 } | |
33049 $('<td>'+svg+'</td>').appendTo(row); | |
33050 } | |
33051 else { | |
33052 var c = GeoTemConfig.getColor(i); | |
33053 var fill = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
33054 var stroke = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
33055 var svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>'; | |
33056 $('<td>'+svg+'</td>').appendTo(row); | |
33057 } | |
33058 $('<td>'+datasets[i].label+'</td>').appendTo(row); | |
33059 } | |
33060 }; | |
33061 | |
33062 this.updateSpaceQuantity = function(count) { | |
33063 if (!options.dataInformation) { | |
33064 return; | |
33065 } | |
33066 this.mapCount = count; | |
33067 if (count != 1) { | |
33068 this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results'); | |
33069 } else { | |
33070 this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result'); | |
33071 } | |
33072 } | |
33073 | |
33074 this.setMapsDropdown = function() { | |
33075 if (!options.mapSelection) { | |
33076 return; | |
33077 } | |
33078 $(this.mapTypeSelector).empty(); | |
33079 var maps = []; | |
33080 var gui = this; | |
33081 var addMap = function(name, index) { | |
33082 var setMap = function() { | |
33083 gui.map.setMap(index); | |
33084 } | |
33085 maps.push({ | |
33086 name : name, | |
33087 onclick : setMap | |
33088 }); | |
33089 } | |
33090 for (var i = 0; i < this.map.baseLayers.length; i++) { | |
33091 addMap(this.map.baseLayers[i].name, i); | |
33092 } | |
33093 this.mapTypeDropdown = new Dropdown(this.mapTypeSelector, maps, GeoTemConfig.getString('selectMapType')); | |
33094 } | |
33095 | |
33096 this.setMap = function() { | |
33097 if (options.mapSelection) { | |
33098 this.mapTypeDropdown.setEntry(this.map.baselayerIndex); | |
33099 } | |
33100 } | |
33101 | |
33102 this.setBinningDropdown = function() { | |
33103 if (!options.binningSelection) { | |
33104 return; | |
33105 } | |
33106 $(this.binningSelector).empty(); | |
33107 var binnings = []; | |
33108 var gui = this; | |
33109 var index = 0; | |
33110 var entry; | |
33111 var addBinning = function(name, id) { | |
33112 if (options.binning == id) { | |
33113 entry = index; | |
33114 } else { | |
33115 index++; | |
33116 } | |
33117 var setBinning = function() { | |
33118 options.binning = id; | |
33119 gui.map.initWidget(gui.map.datasets, false); | |
33120 gui.map.riseLayer(); | |
33121 } | |
33122 binnings.push({ | |
33123 name : name, | |
33124 onclick : setBinning | |
33125 }); | |
33126 } | |
33127 addBinning(GeoTemConfig.getString('genericBinning'), 'generic'); | |
33128 addBinning(GeoTemConfig.getString('squareBinning'), 'square'); | |
33129 addBinning(GeoTemConfig.getString('hexagonalBinning'), 'hexagonal'); | |
33130 addBinning(GeoTemConfig.getString('triangularBinning'), 'triangular'); | |
33131 addBinning(GeoTemConfig.getString('noBinning'), false); | |
33132 var binningDropdown = new Dropdown(this.binningSelector, binnings, GeoTemConfig.getString('binningTooltip')); | |
33133 binningDropdown.setEntry(entry); | |
33134 } | |
33135 this.setBinningDropdown(); | |
33136 | |
33137 this.beautifyCount = function(count) { | |
33138 var c = count + ''; | |
33139 var p = 0; | |
33140 var l = c.length; | |
33141 while (l - p > 3) { | |
33142 p += 3; | |
33143 c = c.substring(0, l - p) + "." + c.substring(l - p); | |
33144 p++; | |
33145 l++; | |
33146 } | |
33147 return c; | |
33148 } | |
33149 | |
33150 }; | |
33151 /* | |
33152 * MapWidget.js | |
33153 * | |
33154 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
33155 * | |
33156 * This library is free software; you can redistribute it and/or | |
33157 * modify it under the terms of the GNU Lesser General Public | |
33158 * License as published by the Free Software Foundation; either | |
33159 * version 3 of the License, or (at your option) any later version. | |
33160 * | |
33161 * This library is distributed in the hope that it will be useful, | |
33162 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
33163 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
33164 * Lesser General Public License for more details. | |
33165 * | |
33166 * You should have received a copy of the GNU Lesser General Public | |
33167 * License along with this library; if not, write to the Free Software | |
33168 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
33169 * MA 02110-1301 USA | |
33170 */ | |
33171 | |
33172 /** | |
33173 * @class MapWidget | |
33174 * MapWidget Implementation | |
33175 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
33176 * @release 1.0 | |
33177 * @release date: 2012-07-27 | |
33178 * @version date: 2012-07-27 | |
33179 * | |
33180 * @param {MapWrapper} core wrapper for interaction to other widgets | |
33181 * @param {HTML object} div parent div to append the map widget div | |
33182 * @param {JSON} options user specified configuration that overwrites options in MapConfig.js | |
33183 */ | |
33184 MapWidget = function(core, div, options) { | |
33185 | |
33186 this.core = core; | |
33187 this.core.setWidget(this); | |
33188 this.openlayersMap | |
33189 this.baseLayers | |
33190 this.objectLayer | |
33191 | |
33192 this.drawPolygon | |
33193 this.drawCircle | |
33194 this.selectCountry | |
33195 this.dragArea | |
33196 this.selectFeature | |
33197 this.navigation | |
33198 | |
33199 this.div = div; | |
33200 | |
33201 this.iid = GeoTemConfig.getIndependentId('map'); | |
33202 this.config = new MapConfig(options); | |
33203 this.options = this.config.options; | |
33204 this.formerCP = this.options.circlePackings; | |
33205 this.gui = new MapGui(this, this.div, this.options, this.iid); | |
33206 | |
33207 this.initialize(); | |
33208 | |
33209 } | |
33210 | |
33211 MapWidget.prototype = { | |
33212 | |
33213 /** | |
33214 * initializes the map for the Spatio Temporal Interface. | |
33215 * it includes setting up all layers of the map and defines all map specific interaction possibilities | |
33216 */ | |
33217 initialize : function() { | |
33218 | |
33219 var map = this; | |
33220 | |
33221 //OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url="; | |
33222 if (map.options.proxyHost) { | |
33223 OpenLayers.ProxyHost = map.options.proxyHost; | |
33224 } | |
33225 | |
33226 this.polygons = []; | |
33227 this.connections = []; | |
33228 this.selection = new Selection(); | |
33229 this.wmsOverlays = []; | |
33230 | |
33231 this.layerZIndex = 1; | |
33232 this.zIndices = []; | |
33233 | |
33234 var activateDrag = function() { | |
33235 map.dragArea.activate(); | |
33236 } | |
33237 var deactivateDrag = function() { | |
33238 map.dragArea.deactivate(); | |
33239 } | |
33240 this.dragControl = new MapControl(this, null, 'drag', activateDrag, deactivateDrag); | |
33241 | |
33242 /* | |
33243 this.editPolygon = document.createElement("div"); | |
33244 this.editPolygon.title = GeoTemConfig.getString('editPolygon'); | |
33245 this.editPolygon.setAttribute('class','editMapPolygon'); | |
33246 this.toolbar.appendChild(this.editPolygon); | |
33247 this.drag.onclick = function(evt){ | |
33248 if( map.activeControl == "drag" ){ | |
33249 map.deactivate("drag"); | |
33250 if( GeoTemConfig.navigate ){ | |
33251 map.activate("navigate"); | |
33252 } | |
33253 } | |
33254 else { | |
33255 map.deactivate(map.activControl); | |
33256 map.activate("drag"); | |
33257 } | |
33258 } | |
33259 map.addEditingMode(new OpenLayers.Control.EditingMode.PointArraySnapping()); | |
33260 */ | |
33261 | |
33262 this.filterBar = new FilterBar(this, this.gui.filterOptions); | |
33263 | |
33264 this.objectLayer = new OpenLayers.Layer.Vector("Data Objects", { | |
33265 projection : "EPSG:4326", | |
33266 'displayInLayerSwitcher' : false, | |
33267 rendererOptions : { | |
33268 zIndexing : true | |
33269 } | |
33270 }); | |
33271 | |
33272 this.markerLayer = new OpenLayers.Layer.Markers("Markers"); | |
33273 | |
33274 this.navigation = new OpenLayers.Control.Navigation({ | |
33275 zoomWheelEnabled : GeoTemConfig.mouseWheelZoom | |
33276 }); | |
33277 this.navigation.defaultDblClick = function(evt) { | |
33278 var newCenter = this.map.getLonLatFromViewPortPx(evt.xy); | |
33279 this.map.setCenter(newCenter, this.map.zoom + 1); | |
33280 map.drawObjectLayer(false); | |
33281 if (map.zoomSlider) { | |
33282 map.zoomSlider.setValue(map.getZoom()); | |
33283 } | |
33284 } | |
33285 this.navigation.wheelUp = function(evt) { | |
33286 this.wheelChange(evt, 1); | |
33287 } | |
33288 this.navigation.wheelDown = function(evt) { | |
33289 this.wheelChange(evt, -1); | |
33290 } | |
33291 | |
33292 this.resolutions = [78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.29858214169740677]; | |
33293 | |
33294 var options = { | |
33295 controls : [this.navigation], | |
33296 projection : new OpenLayers.Projection("EPSG:900913"), | |
33297 displayProjection : new OpenLayers.Projection("EPSG:4326"), | |
33298 resolutions : this.resolutions, | |
33299 units : 'meters', | |
33300 maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34) | |
33301 }; | |
33302 this.openlayersMap = new OpenLayers.Map("mapContainer"+this.iid, options); | |
33303 if (map.options.navigate) { | |
33304 this.activeControl = "navigate"; | |
33305 } | |
33306 //add attribution control | |
33307 this.openlayersMap.addControl(new OpenLayers.Control.Attribution()); | |
33308 this.mds = new MapDataSource(this, this.options); | |
33309 | |
33310 //on zoomend, redraw objects and set slider (if it exists) accordingly (zoom by mouse wheel) | |
33311 this.openlayersMap.events.register("zoomend", map, function(){ | |
33312 map.drawObjectLayer(false); | |
33313 if (map.zoomSlider) { | |
33314 map.zoomSlider.setValue(map.getZoom()); | |
33315 } | |
33316 map.core.triggerHighlight([]); | |
33317 }); | |
33318 | |
33319 if (map.options.olNavigation) { | |
33320 var zoomPanel = new OpenLayers.Control.PanZoom(); | |
33321 zoomPanel.onButtonClick = function(evt) { | |
33322 var btn = evt.buttonElement; | |
33323 switch (btn.action) { | |
33324 case "panup": | |
33325 this.map.pan(0, -this.getSlideFactor("h")); | |
33326 break; | |
33327 case "pandown": | |
33328 this.map.pan(0, this.getSlideFactor("h")); | |
33329 break; | |
33330 case "panleft": | |
33331 this.map.pan(-this.getSlideFactor("w"), 0); | |
33332 break; | |
33333 case "panright": | |
33334 this.map.pan(this.getSlideFactor("w"), 0); | |
33335 break; | |
33336 case "zoomin": | |
33337 map.zoom(1); | |
33338 break; | |
33339 case "zoomout": | |
33340 map.zoom(-1); | |
33341 break; | |
33342 case "zoomworld": | |
33343 if (this.map) { | |
33344 map.zoom(this.map.zoom * -1); | |
33345 } | |
33346 break; | |
33347 } | |
33348 }; | |
33349 this.openlayersMap.addControl(zoomPanel); | |
33350 } | |
33351 | |
33352 if (map.options.popups) { | |
33353 var panMap = function() { | |
33354 if (map.selectedGlyph) { | |
33355 var lonlat = new OpenLayers.LonLat(map.selectedGlyph.lon, map.selectedGlyph.lat); | |
33356 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
33357 if (map.popup) { | |
33358 map.popup.shift(pixel.x, pixel.y); | |
33359 } | |
33360 } | |
33361 } | |
33362 this.openlayersMap.events.register("move", this.openlayersMap, panMap); | |
33363 } | |
33364 | |
33365 if (map.options.olMapOverview) { | |
33366 this.openlayersMap.addControl(new OpenLayers.Control.OverviewMap()); | |
33367 } | |
33368 if (map.options.olKeyboardDefaults) { | |
33369 var keyboardControl = new OpenLayers.Control.KeyboardDefaults(); | |
33370 keyboardControl.defaultKeyPress = function(evt) { | |
33371 switch(evt.keyCode) { | |
33372 case OpenLayers.Event.KEY_LEFT: | |
33373 this.map.pan(-this.slideFactor, 0); | |
33374 break; | |
33375 case OpenLayers.Event.KEY_RIGHT: | |
33376 this.map.pan(this.slideFactor, 0); | |
33377 break; | |
33378 case OpenLayers.Event.KEY_UP: | |
33379 this.map.pan(0, -this.slideFactor); | |
33380 break; | |
33381 case OpenLayers.Event.KEY_DOWN: | |
33382 this.map.pan(0, this.slideFactor); | |
33383 break; | |
33384 | |
33385 case 33: | |
33386 // Page Up. Same in all browsers. | |
33387 var size = this.map.getSize(); | |
33388 this.map.pan(0, -0.75 * size.h); | |
33389 break; | |
33390 case 34: | |
33391 // Page Down. Same in all browsers. | |
33392 var size = this.map.getSize(); | |
33393 this.map.pan(0, 0.75 * size.h); | |
33394 break; | |
33395 case 35: | |
33396 // End. Same in all browsers. | |
33397 var size = this.map.getSize(); | |
33398 this.map.pan(0.75 * size.w, 0); | |
33399 break; | |
33400 case 36: | |
33401 // Home. Same in all browsers. | |
33402 var size = this.map.getSize(); | |
33403 this.map.pan(-0.75 * size.w, 0); | |
33404 break; | |
33405 | |
33406 case 43: | |
33407 // +/= (ASCII), keypad + (ASCII, Opera) | |
33408 case 61: | |
33409 // +/= (Mozilla, Opera, some ASCII) | |
33410 case 187: | |
33411 // +/= (IE) | |
33412 case 107: | |
33413 // keypad + (IE, Mozilla) | |
33414 map.zoom(1); | |
33415 break; | |
33416 case 45: | |
33417 // -/_ (ASCII, Opera), keypad - (ASCII, Opera) | |
33418 case 109: | |
33419 // -/_ (Mozilla), keypad - (Mozilla, IE) | |
33420 case 189: | |
33421 // -/_ (IE) | |
33422 case 95: | |
33423 // -/_ (some ASCII) | |
33424 map.zoom(-1); | |
33425 break; | |
33426 } | |
33427 }; | |
33428 this.openlayersMap.addControl(keyboardControl); | |
33429 } | |
33430 if (map.options.olLayerSwitcher) { | |
33431 this.openlayersMap.addControl(new OpenLayers.Control.LayerSwitcher()); | |
33432 } | |
33433 if (map.options.olScaleLine) { | |
33434 this.openlayersMap.addControl(new OpenLayers.Control.ScaleLine()); | |
33435 } | |
33436 this.gui.resize(); | |
33437 this.setBaseLayers(); | |
33438 this.gui.setMapsDropdown(); | |
33439 this.gui.setMap(); | |
33440 this.openlayersMap.addLayers([this.objectLayer, this.markerLayer]); | |
33441 | |
33442 if (map.options.boundaries) { | |
33443 var boundaries = map.options.boundaries; | |
33444 var bounds = new OpenLayers.Bounds(boundaries.minLon, boundaries.minLat, boundaries.maxLon, boundaries.maxLat); | |
33445 var projectionBounds = bounds.transform(this.openlayersMap.displayProjection, this.openlayersMap.projection); | |
33446 this.openlayersMap.zoomToExtent(projectionBounds); | |
33447 } else { | |
33448 this.openlayersMap.zoomToMaxExtent(); | |
33449 } | |
33450 | |
33451 // manages selection of elements if a polygon was drawn | |
33452 this.drawnPolygonHandler = function(polygon) { | |
33453 if (map.mds.getAllObjects() == null) { | |
33454 return; | |
33455 } | |
33456 var polygonFeature; | |
33457 if ( polygon instanceof OpenLayers.Geometry.Polygon) { | |
33458 polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPolygon([polygon])); | |
33459 } else if ( polygon instanceof OpenLayers.Geometry.MultiPolygon) { | |
33460 polygonFeature = new OpenLayers.Feature.Vector(polygon); | |
33461 } | |
33462 map.polygons.push(polygonFeature); | |
33463 var style = $.extend(true, {}, OpenLayers.Feature.Vector.style['default']); | |
33464 style.graphicZIndex = 0; | |
33465 polygonFeature.style = style; | |
33466 map.objectLayer.addFeatures([polygonFeature]); | |
33467 try { | |
33468 map.activeControl.deactivate(); | |
33469 } catch(e) { | |
33470 } | |
33471 var circles = map.mds.getObjectsByZoom(); | |
33472 for (var i = 0; i < circles.length; i++) { | |
33473 for (var j = 0; j < circles[i].length; j++) { | |
33474 var c = circles[i][j]; | |
33475 if (map.inPolygon(c)) { | |
33476 if ( typeof c.fatherBin != 'undefined') { | |
33477 for (var k = 0; k < c.fatherBin.circles.length; k++) { | |
33478 if (c.fatherBin.circles[k]) { | |
33479 c.fatherBin.circles[k].setSelection(true); | |
33480 } | |
33481 } | |
33482 } else { | |
33483 c.setSelection(true); | |
33484 } | |
33485 } | |
33486 } | |
33487 } | |
33488 map.mapSelection(); | |
33489 } | |
33490 | |
33491 this.polygonDeselection = function() { | |
33492 var circles = map.mds.getObjectsByZoom(); | |
33493 for (var i = 0; i < circles.length; i++) { | |
33494 for (var j = 0; j < circles[i].length; j++) { | |
33495 var c = circles[i][j]; | |
33496 if (map.inPolygon(c)) { | |
33497 c.setSelection(false); | |
33498 } | |
33499 } | |
33500 } | |
33501 } | |
33502 this.snapper = function() { | |
33503 if (map.polygons.length == 0 || !map.options.multiSelection) { | |
33504 map.deselection(); | |
33505 } | |
33506 } | |
33507 if (map.options.polygonSelect) { | |
33508 this.drawPolygon = new OpenLayers.Control.DrawFeature(map.objectLayer, OpenLayers.Handler.Polygon, { | |
33509 displayClass : "olControlDrawFeaturePolygon", | |
33510 callbacks : { | |
33511 "done" : map.drawnPolygonHandler, | |
33512 "create" : map.snapper | |
33513 } | |
33514 }); | |
33515 this.openlayersMap.addControl(this.drawPolygon); | |
33516 } | |
33517 | |
33518 if (map.options.circleSelect) { | |
33519 this.drawCircle = new OpenLayers.Control.DrawFeature(map.objectLayer, OpenLayers.Handler.RegularPolygon, { | |
33520 displayClass : "olControlDrawFeaturePolygon", | |
33521 handlerOptions : { | |
33522 sides : 40 | |
33523 }, | |
33524 callbacks : { | |
33525 "done" : map.drawnPolygonHandler, | |
33526 "create" : map.snapper | |
33527 } | |
33528 }); | |
33529 this.openlayersMap.addControl(this.drawCircle); | |
33530 } | |
33531 | |
33532 if (map.options.squareSelect) { | |
33533 this.drawSquare = new OpenLayers.Control.DrawFeature(map.objectLayer, OpenLayers.Handler.RegularPolygon, { | |
33534 displayClass : "olControlDrawFeaturePolygon", | |
33535 handlerOptions : { | |
33536 sides : 4, | |
33537 irregular: true | |
33538 }, | |
33539 callbacks : { | |
33540 "done" : map.drawnPolygonHandler, | |
33541 "create" : map.snapper | |
33542 } | |
33543 }); | |
33544 this.openlayersMap.addControl(this.drawSquare); | |
33545 } | |
33546 | |
33547 if (map.options.polygonSelect || map.options.circleSelect || map.options.squareSelect) { | |
33548 this.dragArea = new OpenLayers.Control.DragFeature(map.objectLayer, { | |
33549 onStart : function(feature) { | |
33550 feature.style.graphicZIndex = 10000; | |
33551 map.polygonDeselection(); | |
33552 }, | |
33553 onComplete : function(feature) { | |
33554 feature.style.graphicZIndex = 0; | |
33555 map.drawnPolygonHandler(feature.geometry); | |
33556 } | |
33557 }); | |
33558 this.openlayersMap.addControl(this.dragArea); | |
33559 | |
33560 this.modifyArea = new OpenLayers.Control.ModifyFeature(map.objectLayer, { | |
33561 onStart : function(feature) { | |
33562 feature.style.graphicZIndex = 10000; | |
33563 map.polygonDeselection(); | |
33564 }, | |
33565 onComplete : function(feature) { | |
33566 feature.style.graphicZIndex = 0; | |
33567 map.drawnPolygonHandler(feature.geometry); | |
33568 } | |
33569 }); | |
33570 this.openlayersMap.addControl(this.modifyArea); | |
33571 this.modifyArea.mode = OpenLayers.Control.ModifyFeature.RESHAPE; | |
33572 | |
33573 } | |
33574 | |
33575 // calculates the tag cloud | |
33576 // manages hover selection of point objects | |
33577 var hoverSelect = function(event) { | |
33578 var object = event.feature; | |
33579 if (object.geometry instanceof OpenLayers.Geometry.Point) { | |
33580 if ( typeof map.placenameTags != 'undefined') { | |
33581 map.placenameTags.remove(); | |
33582 } | |
33583 var circle = event.feature.parent; | |
33584 if ( circle instanceof CircleObject) { | |
33585 circle.placenameTags = new PlacenameTags(circle, map); | |
33586 map.placenameTags = circle.placenameTags; | |
33587 } else { | |
33588 return; | |
33589 /* | |
33590 event.feature.style.fillOpacity = 0.2; | |
33591 event.feature.style.strokeOpacity = 1; | |
33592 map.objectLayer.drawFeature(event.feature); | |
33593 circle.placenameTags = new PackPlacenameTags(circle,map); | |
33594 */ | |
33595 } | |
33596 circle.placenameTags.calculate(); | |
33597 map.mapCircleHighlight(object.parent, false); | |
33598 if ( typeof map.featureInfo != 'undefined') { | |
33599 map.featureInfo.deactivate(); | |
33600 } | |
33601 } else { | |
33602 map.dragControl.checkStatus(); | |
33603 } | |
33604 }; | |
33605 var hoverUnselect = function(event) { | |
33606 var object = event.feature; | |
33607 if (object.geometry instanceof OpenLayers.Geometry.Point) { | |
33608 var circle = event.feature.parent; | |
33609 if (!( circle instanceof CircleObject )) { | |
33610 return; | |
33611 /* | |
33612 event.feature.style.fillOpacity = 0; | |
33613 event.feature.style.strokeOpacity = 0; | |
33614 map.objectLayer.drawFeature(event.feature); | |
33615 */ | |
33616 } | |
33617 circle.placenameTags.remove(); | |
33618 map.mapCircleHighlight(object.parent, true); | |
33619 if ( typeof map.featureInfo != 'undefined') { | |
33620 map.featureInfo.activate(); | |
33621 } | |
33622 } else { | |
33623 map.dragControl.deactivate(); | |
33624 } | |
33625 }; | |
33626 var highlightCtrl = new OpenLayers.Control.SelectFeature(this.objectLayer, { | |
33627 hover : true, | |
33628 highlightOnly : true, | |
33629 renderIntent : "temporary", | |
33630 eventListeners : { | |
33631 featurehighlighted : hoverSelect, | |
33632 featureunhighlighted : hoverUnselect | |
33633 } | |
33634 }); | |
33635 this.openlayersMap.addControl(highlightCtrl); | |
33636 highlightCtrl.activate(); | |
33637 | |
33638 this.selectFeature = new OpenLayers.Control.SelectFeature(this.objectLayer); | |
33639 | |
33640 document.onkeydown = function(e) { | |
33641 if (e.ctrlKey) { | |
33642 map.ctrlKey = true; | |
33643 } | |
33644 } | |
33645 document.onkeyup = function(e) { | |
33646 map.ctrlKey = false; | |
33647 } | |
33648 // manages click selection of point objects | |
33649 var onFeatureSelect = function(event, evt) { | |
33650 if (!(event.feature.geometry instanceof OpenLayers.Geometry.Point)) { | |
33651 return; | |
33652 } | |
33653 var circle = event.feature.parent; | |
33654 if (map.options.multiSelection && map.ctrlKey) { | |
33655 if (map.popup) { | |
33656 map.popup.reset(); | |
33657 map.selectedGlyph = false; | |
33658 } | |
33659 circle.toggleSelection(); | |
33660 map.mapSelection(); | |
33661 return; | |
33662 } | |
33663 map.reset(); | |
33664 circle.setSelection(true); | |
33665 map.objectLayer.drawFeature(circle.feature); | |
33666 if (map.options.popups) { | |
33667 if (map.popup) { | |
33668 map.popup.reset(); | |
33669 } | |
33670 var lonlat = event.feature.geometry.getBounds().getCenterLonLat(); | |
33671 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
33672 map.selectedGlyph = { | |
33673 lon : lonlat.lon, | |
33674 lat : lonlat.lat | |
33675 }; | |
33676 map.popup = new PlacenamePopup(map); | |
33677 map.popup.createPopup(pixel.x, pixel.y, circle.placenameTags.placeLabels); | |
33678 if (map.options.selectDefault) { | |
33679 circle.placenameTags.selectLabel(); | |
33680 } | |
33681 } | |
33682 } | |
33683 this.objectLayer.events.on({ | |
33684 "featureselected" : onFeatureSelect | |
33685 }); | |
33686 | |
33687 this.openlayersMap.addControl(this.selectFeature); | |
33688 this.selectFeature.activate(); | |
33689 | |
33690 if (this.zoomSlider) { | |
33691 this.zoomSlider.setMaxAndLevels(1000, this.openlayersMap.getNumZoomLevels()); | |
33692 this.zoomSlider.setValue(this.getZoom()); | |
33693 } | |
33694 | |
33695 Publisher.Subscribe('mapChanged', this, function(mapName) { | |
33696 this.client.setBaseLayerByName(mapName); | |
33697 this.client.gui.setMap(); | |
33698 }); | |
33699 | |
33700 }, | |
33701 | |
33702 shift : function(shiftX, shiftY) { | |
33703 this.openlayersMap.pan(shiftX, shiftY); | |
33704 }, | |
33705 | |
33706 addBaseLayers : function(layers) { | |
33707 if ( layers instanceof Array) { | |
33708 for (var i in layers ) { | |
33709 var layer; | |
33710 if (layers[i].type === "XYZ"){ | |
33711 layer = new OpenLayers.Layer.XYZ( | |
33712 layers[i].name, | |
33713 [ | |
33714 layers[i].url | |
33715 ], | |
33716 { | |
33717 sphericalMercator: true, | |
33718 transitionEffect: "resize", | |
33719 buffer: 1, | |
33720 numZoomLevels: 12, | |
33721 transparent : true, | |
33722 attribution: layers[i].attribution | |
33723 }, | |
33724 { | |
33725 isBaseLayer : true | |
33726 } | |
33727 ); | |
33728 } else { | |
33729 layer = new OpenLayers.Layer.WMS( | |
33730 layers[i].name, layers[i].url, | |
33731 { | |
33732 projection : "EPSG:4326", | |
33733 layers : layers[i].layer, | |
33734 transparent : "true", | |
33735 format : "image/png" | |
33736 }, | |
33737 { | |
33738 attribution: layers[i].attribution, | |
33739 isBaseLayer : true | |
33740 } | |
33741 ); | |
33742 } | |
33743 this.baseLayers.push(layer); | |
33744 this.openlayersMap.addLayers([layer]); | |
33745 } | |
33746 } | |
33747 this.gui.setMapsDropdown(); | |
33748 }, | |
33749 | |
33750 /** | |
33751 * set online available maps for Google, Bing and OSM | |
33752 */ | |
33753 setBaseLayers : function() { | |
33754 this.baseLayers = []; | |
33755 if (this.options.googleMaps) { | |
33756 // see http://openlayers.org/blog/2010/07/10/google-maps-v3-for-openlayers/ for information | |
33757 var gphy = new OpenLayers.Layer.Google("Google Physical", { | |
33758 type : google.maps.MapTypeId.TERRAIN, | |
33759 minZoomLevel : 1, | |
33760 maxZoomLevel : 19 | |
33761 }); | |
33762 var gmap = new OpenLayers.Layer.Google("Google Streets", { | |
33763 minZoomLevel : 1, | |
33764 maxZoomLevel : 19 | |
33765 }); | |
33766 var ghyb = new OpenLayers.Layer.Google("Google Hybrid", { | |
33767 type : google.maps.MapTypeId.HYBRID, | |
33768 minZoomLevel : 1, | |
33769 maxZoomLevel : 19 | |
33770 }); | |
33771 var gsat = new OpenLayers.Layer.Google("Google Satellite", { | |
33772 type : google.maps.MapTypeId.SATELLITE, | |
33773 minZoomLevel : 1, | |
33774 maxZoomLevel : 19 | |
33775 }); | |
33776 this.baseLayers.push(gphy); | |
33777 this.baseLayers.push(gmap); | |
33778 this.baseLayers.push(ghyb); | |
33779 this.baseLayers.push(gsat); | |
33780 } | |
33781 if (this.options.bingMaps) { | |
33782 // see http://openlayers.org/blog/2010/12/18/bing-tiles-for-openlayers/ for information | |
33783 var apiKey = this.options.bingApiKey; | |
33784 var road = new OpenLayers.Layer.Bing({ | |
33785 name : "Road", | |
33786 key : apiKey, | |
33787 type : "Road" | |
33788 }); | |
33789 var hybrid = new OpenLayers.Layer.Bing({ | |
33790 name : "Hybrid", | |
33791 key : apiKey, | |
33792 type : "AerialWithLabels" | |
33793 }); | |
33794 var aerial = new OpenLayers.Layer.Bing({ | |
33795 name : "Aerial", | |
33796 key : apiKey, | |
33797 type : "Aerial" | |
33798 }); | |
33799 this.baseLayers.push(road); | |
33800 this.baseLayers.push(hybrid); | |
33801 this.baseLayers.push(aerial); | |
33802 } | |
33803 if (this.options.osmMaps) { | |
33804 this.baseLayers.push(new OpenLayers.Layer.OSM('Open Street Map', '', { | |
33805 sphericalMercator : true, | |
33806 zoomOffset : 1, | |
33807 resolutions : this.resolutions | |
33808 })); | |
33809 } | |
33810 if (this.options.osmMapsMapQuest) { | |
33811 this.baseLayers.push(new OpenLayers.Layer.OSM('Open Street Map (MapQuest)', | |
33812 ["http://otile1.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png", | |
33813 "http://otile2.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png", | |
33814 "http://otile3.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png", | |
33815 "http://otile4.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png"], | |
33816 { | |
33817 sphericalMercator : true, | |
33818 zoomOffset : 1, | |
33819 resolutions : this.resolutions | |
33820 } | |
33821 )); | |
33822 } | |
33823 for (var i = 0; i < this.baseLayers.length; i++) { | |
33824 this.openlayersMap.addLayers([this.baseLayers[i]]); | |
33825 } | |
33826 if (this.options.alternativeMap) { | |
33827 if (!(this.options.alternativeMap instanceof Array)) | |
33828 this.options.alternativeMap = [this.options.alternativeMap]; | |
33829 this.addBaseLayers(this.options.alternativeMap); | |
33830 } | |
33831 this.setBaseLayerByName(this.options.baseLayer); | |
33832 }, | |
33833 | |
33834 setBaseLayerByName : function(name){ | |
33835 for (var i = 0; i < this.baseLayers.length; i++) { | |
33836 if (this.baseLayers[i].name == name) { | |
33837 this.setMap(i); | |
33838 } | |
33839 } | |
33840 }, | |
33841 | |
33842 getBaseLayerName : function() { | |
33843 return this.openlayersMap.baseLayer.name; | |
33844 }, | |
33845 | |
33846 setOverlays : function(layers) { | |
33847 var map = this; | |
33848 for (var i in this.wmsOverlays ) { | |
33849 this.openlayersMap.removeLayer(this.wmsOverlays[i]); | |
33850 } | |
33851 this.wmsOverlays = []; | |
33852 var featureInfoLayers = []; | |
33853 if ( layers instanceof Array) { | |
33854 for (var i in layers ) { | |
33855 var layer = new OpenLayers.Layer.WMS(layers[i].name, layers[i].url, { | |
33856 projection : "EPSG:4326", | |
33857 layers : layers[i].layer, | |
33858 transparent : "true", | |
33859 format : "image/png" | |
33860 }, { | |
33861 isBaseLayer : false, | |
33862 visibility : map.options.overlayVisibility | |
33863 }); | |
33864 this.wmsOverlays.push(layer); | |
33865 if (layers[i].featureInfo) { | |
33866 featureInfoLayers.push(layer); | |
33867 } | |
33868 } | |
33869 this.openlayersMap.addLayers(this.wmsOverlays); | |
33870 } | |
33871 if (this.wmsOverlays.length > 0 && map.options.overlayVisibility) { | |
33872 var map = this; | |
33873 if ( typeof this.featureInfo != 'undefined') { | |
33874 this.featureInfo.deactivate(); | |
33875 this.openlayersMap.removeControl(this.featureInfo); | |
33876 } | |
33877 this.featureInfo = new OpenLayers.Control.WMSGetFeatureInfo({ | |
33878 url : '/geoserver/wms', | |
33879 layers : featureInfoLayers, | |
33880 eventListeners : { | |
33881 getfeatureinfo : function(event) { | |
33882 if (event.text == '') { | |
33883 return; | |
33884 } | |
33885 var lonlat = map.openlayersMap.getLonLatFromPixel(new OpenLayers.Pixel(event.xy.x, event.xy.y)); | |
33886 map.selectedGlyph = { | |
33887 lon : lonlat.lon, | |
33888 lat : lonlat.lat | |
33889 }; | |
33890 if ( typeof map.popup != 'undefined') { | |
33891 map.popup.reset(); | |
33892 } | |
33893 map.popup = new MapPopup(map); | |
33894 map.popup.initialize(event.xy.x, event.xy.y); | |
33895 map.popup.setContent(event.text); | |
33896 } | |
33897 } | |
33898 }); | |
33899 this.openlayersMap.addControl(this.featureInfo); | |
33900 this.featureInfo.activate(); | |
33901 this.activateCountrySelector(this.wmsOverlays[this.wmsOverlays.length - 1]); | |
33902 } else { | |
33903 this.deactivateCountrySelector(); | |
33904 if (this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS) { | |
33905 this.activateCountrySelector(this.openlayersMap.baseLayer); | |
33906 } | |
33907 } | |
33908 }, | |
33909 | |
33910 addBaseLayer : function(layer) { | |
33911 this.baseLayers.push(layer); | |
33912 this.openlayersMap.addLayers([layer]); | |
33913 for (var i in this.baseLayers ) { | |
33914 if (this.baseLayers[i].name == this.options.baseLayer) { | |
33915 this.setMap(i); | |
33916 } | |
33917 } | |
33918 }, | |
33919 | |
33920 /** | |
33921 * draws the object layer. | |
33922 * @param {boolean} zoom if there was a zoom; if not, the new boundary of the map is calculated | |
33923 */ | |
33924 drawObjectLayer : function(zoom) { | |
33925 if ( typeof this.placenameTags != 'undefined') { | |
33926 this.placenameTags.remove(); | |
33927 } | |
33928 var points = this.mds.getAllObjects(); | |
33929 if (points == null) { | |
33930 return; | |
33931 } | |
33932 this.objectLayer.removeAllFeatures(); | |
33933 | |
33934 if (zoom) { | |
33935 var minLat, maxLat, minLon, maxLon; | |
33936 var pointsHighestZoom = points[points.length - 1]; | |
33937 for (var i = 0; i < pointsHighestZoom.length; i++) { | |
33938 for (var j = 0; j < pointsHighestZoom[i].length; j++) { | |
33939 var point = pointsHighestZoom[i][j]; | |
33940 if (minLon == null || point.originX < minLon) { | |
33941 minLon = point.originX; | |
33942 } | |
33943 if (maxLon == null || point.originX > maxLon) { | |
33944 maxLon = point.originX; | |
33945 } | |
33946 if (minLat == null || point.originY < minLat) { | |
33947 minLat = point.originY; | |
33948 } | |
33949 if (maxLat == null || point.originY > maxLat) { | |
33950 maxLat = point.originY; | |
33951 } | |
33952 } | |
33953 } | |
33954 if (minLon == maxLon && minLat == maxLat) { | |
33955 this.openlayersMap.setCenter(new OpenLayers.LonLat(minLon, minLat)); | |
33956 } else { | |
33957 var gapX = 0.1 * (maxLon - minLon ); | |
33958 var gapY1 = 0.1 * (maxLat - minLat ); | |
33959 var gapY2 = (this.gui.headerHeight / this.gui.mapWindow.offsetHeight + 0.1 ) * (maxLat - minLat ); | |
33960 this.openlayersMap.zoomToExtent(new OpenLayers.Bounds(minLon - gapX, minLat - gapY1, maxLon + gapX, maxLat + gapY2)); | |
33961 this.openlayersMap.zoomTo(Math.floor(this.getZoom())); | |
33962 } | |
33963 if (this.zoomSlider) { | |
33964 this.zoomSlider.setValue(this.getZoom()); | |
33965 } | |
33966 } | |
33967 var displayPoints = this.mds.getObjectsByZoom(); | |
33968 var resolution = this.openlayersMap.getResolution(); | |
33969 for (var i = 0; i < displayPoints.length; i++) { | |
33970 for (var j = 0; j < displayPoints[i].length; j++) { | |
33971 var p = displayPoints[i][j]; | |
33972 var x = p.originX + resolution * p.shiftX; | |
33973 var y = p.originY + resolution * p.shiftY; | |
33974 p.feature.geometry.x = x; | |
33975 p.feature.geometry.y = y; | |
33976 p.olFeature.geometry.x = x; | |
33977 p.olFeature.geometry.y = y; | |
33978 p.feature.style.graphicZIndex = this.zIndices[i]; | |
33979 p.olFeature.style.graphicZIndex = this.zIndices[i] + 1; | |
33980 this.objectLayer.addFeatures([p.feature]); | |
33981 this.objectLayer.addFeatures([p.olFeature]); | |
33982 } | |
33983 } | |
33984 var zoomLevel = this.getZoom(); | |
33985 /* | |
33986 for (var i = 0; i < this.bins[zoomLevel].length; i++) { | |
33987 var p = this.bins[zoomLevel][i]; | |
33988 p.feature.style.graphicZIndex = 0; | |
33989 this.objectLayer.addFeatures([p.feature]); | |
33990 } | |
33991 */ | |
33992 | |
33993 var dist = function(p1, p2) { | |
33994 return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); | |
33995 } | |
33996 | |
33997 this.highlightChanged(this.selection.getObjects(this.core)); | |
33998 | |
33999 }, | |
34000 | |
34001 riseLayer : function(id) { | |
34002 this.lastId = id; | |
34003 if ( typeof id == 'undefined') { | |
34004 id = this.lastId || 0; | |
34005 } | |
34006 this.zIndices[id] = this.layerZIndex; | |
34007 this.layerZIndex += 2; | |
34008 this.drawObjectLayer(false); | |
34009 for( var i=0; i<this.polygons.length; i++ ){ | |
34010 this.objectLayer.addFeatures([this.polygons[i]]); | |
34011 } | |
34012 }, | |
34013 | |
34014 /** | |
34015 * initializes the object layer. | |
34016 * all point representations for all zoom levels are calculated and initialized | |
34017 * @param {MapObject[][]} mapObjects an array of map objects from different (1-4) sets | |
34018 */ | |
34019 initWidget : function(datasets, zoom) { | |
34020 | |
34021 this.clearMap(); | |
34022 | |
34023 this.datasets = datasets; | |
34024 var mapObjects = []; | |
34025 for (var i = 0; i < datasets.length; i++) { | |
34026 mapObjects.push(datasets[i].objects); | |
34027 } | |
34028 if (mapObjects.length > 4) { | |
34029 this.options.circlePackings = false; | |
34030 } else { | |
34031 this.options.circlePackings = this.formerCP; | |
34032 } | |
34033 | |
34034 if ( typeof mapObjects == 'undefined') { | |
34035 return; | |
34036 } | |
34037 | |
34038 this.count = 0; | |
34039 this.objectCount = 0; | |
34040 for (var i = 0; i < mapObjects.length; i++) { | |
34041 var c = 0; | |
34042 for (var j = 0; j < mapObjects[i].length; j++) { | |
34043 if (mapObjects[i][j].isGeospatial) { | |
34044 c += mapObjects[i][j].weight; | |
34045 this.objectCount++; | |
34046 } | |
34047 } | |
34048 this.count += c; | |
34049 this.zIndices.push(this.layerZIndex); | |
34050 this.layerZIndex += 2; | |
34051 } | |
34052 | |
34053 this.mds.initialize(mapObjects); | |
34054 var points = this.mds.getAllObjects(); | |
34055 if (points == null) { | |
34056 return; | |
34057 } | |
34058 | |
34059 var getArea = function(radius) { | |
34060 return Math.PI * radius * radius; | |
34061 } | |
34062 for (var i = 0; i < points.length; i++) { | |
34063 var area = 0; | |
34064 var maxRadius = 0; | |
34065 for (var j = 0; j < points[i].length; j++) { | |
34066 for (var k = 0; k < points[i][j].length; k++) { | |
34067 if (points[i][j][k].radius > maxRadius) { | |
34068 maxRadius = points[i][j][k].radius; | |
34069 area = getArea(maxRadius); | |
34070 } | |
34071 } | |
34072 } | |
34073 var minArea = getArea(this.options.minimumRadius); | |
34074 var areaDiff = area - minArea; | |
34075 for (var j = 0; j < points[i].length; j++) { | |
34076 for (var k = 0; k < points[i][j].length; k++) { | |
34077 var point = points[i][j][k]; | |
34078 var c, shape, rotation, multiplier = 1; | |
34079 if( this.options.useGraphics ){ | |
34080 var graphic = this.config.getGraphic(point.search); | |
34081 c = graphic.color; | |
34082 shape = graphic.shape; | |
34083 rotation = graphic.rotation; | |
34084 if( shape == 'square' ){ | |
34085 multiplier = 0.75; | |
34086 } | |
34087 } | |
34088 else { | |
34089 c = GeoTemConfig.getAverageDatasetColor(point.search,point.elements); | |
34090 shape = 'circle'; | |
34091 rotation = 0; | |
34092 } | |
34093 var opacity; | |
34094 if (this.options.circleOpacity == 'balloon') { | |
34095 var min = this.options.minTransparency; | |
34096 var max = this.options.maxTransparency; | |
34097 opacity = min + Math.abs(min - max) * (1 - (getArea(point.radius) - minArea) / areaDiff); | |
34098 } | |
34099 else { | |
34100 opacity = this.options.circleOpacity; | |
34101 } | |
34102 var col = false, ols = 0; | |
34103 if( this.options.circleOutline ){ | |
34104 col = true; | |
34105 ols = this.options.circleOutline; | |
34106 } | |
34107 var style = { | |
34108 graphicName: shape, | |
34109 rotation: rotation, | |
34110 fillColor : 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')', | |
34111 fillOpacity : opacity, | |
34112 strokeWidth : ols, | |
34113 strokeColor : 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')', | |
34114 stroke : col, | |
34115 pointRadius : point.radius * multiplier, | |
34116 cursor : "pointer" | |
34117 }; | |
34118 var pointGeometry = new OpenLayers.Geometry.Point(point.originX, point.originY, null); | |
34119 var feature = new OpenLayers.Feature.Vector(pointGeometry); | |
34120 feature.style = style; | |
34121 feature.parent = point; | |
34122 point.setFeature(feature); | |
34123 var olStyle = { | |
34124 graphicName: shape, | |
34125 rotation: rotation, | |
34126 fillColor : 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')', | |
34127 fillOpacity : opacity, | |
34128 stroke : false, | |
34129 pointRadius : 0, | |
34130 cursor : "pointer" | |
34131 }; | |
34132 var olPointGeometry = new OpenLayers.Geometry.Point(point.originX, point.originY, null); | |
34133 var olFeature = new OpenLayers.Feature.Vector(olPointGeometry); | |
34134 olFeature.style = olStyle; | |
34135 olFeature.parent = point; | |
34136 point.setOlFeature(olFeature); | |
34137 } | |
34138 } | |
34139 } | |
34140 | |
34141 /* | |
34142 this.bins = this.mds.getAllBins(); | |
34143 for (var i = 0; i < this.bins.length; i++) { | |
34144 for (var j = 0; j < this.bins[i].length; j++) { | |
34145 var bin = this.bins[i][j]; | |
34146 var style = { | |
34147 fillColor : 'rgb(140,140,140)', | |
34148 fillOpacity : 0, | |
34149 strokeWidth : 2, | |
34150 strokeOpacity : 0, | |
34151 strokeColor : 'rgb(140,140,140)', | |
34152 // stroke: false, | |
34153 pointRadius : bin.radius, | |
34154 cursor : "pointer" | |
34155 }; | |
34156 var pointGeometry = new OpenLayers.Geometry.Point(bin.x, bin.y, null); | |
34157 var feature = new OpenLayers.Feature.Vector(pointGeometry); | |
34158 feature.style = style; | |
34159 feature.parent = bin; | |
34160 bin.feature = feature; | |
34161 } | |
34162 } | |
34163 */ | |
34164 | |
34165 this.gui.updateLegend(datasets); | |
34166 | |
34167 if ( typeof zoom == "undefined") { | |
34168 this.drawObjectLayer(true); | |
34169 } else { | |
34170 this.drawObjectLayer(zoom); | |
34171 } | |
34172 this.gui.updateSpaceQuantity(this.count); | |
34173 | |
34174 }, | |
34175 | |
34176 /** | |
34177 * resets the map by destroying all additional elements except the point objects, which are replaced | |
34178 */ | |
34179 reset : function() { | |
34180 if ( typeof this.placenameTags != 'undefined') { | |
34181 this.placenameTags.remove(); | |
34182 } | |
34183 this.objectLayer.removeFeatures(this.polygons); | |
34184 this.polygons = []; | |
34185 this.objectLayer.removeFeatures(this.connections); | |
34186 this.connections = []; | |
34187 this.selectFeature.unselectAll(); | |
34188 this.selectedGlyph = false; | |
34189 if (this.dragControl.activated) { | |
34190 this.dragControl.deactivate(); | |
34191 } | |
34192 if (this.popup) { | |
34193 this.popup.reset(); | |
34194 } | |
34195 this.filterBar.reset(false); | |
34196 var points = this.mds.getObjectsByZoom(); | |
34197 if (points == null) { | |
34198 return; | |
34199 } | |
34200 for (var i = 0; i < points.length; i++) { | |
34201 for (var j = 0; j < points[i].length; j++) { | |
34202 points[i][j].setSelection(false); | |
34203 } | |
34204 } | |
34205 }, | |
34206 | |
34207 /** | |
34208 * resets the map by destroying all elements | |
34209 */ | |
34210 clearMap : function() { | |
34211 this.reset(); | |
34212 this.selection = new Selection(); | |
34213 this.zIndices = []; | |
34214 this.layerZIndex = 1; | |
34215 this.objectLayer.destroyFeatures(); | |
34216 }, | |
34217 | |
34218 /** | |
34219 * updates the proportional selection status of a point object | |
34220 * @param {PointObject} point the point to update | |
34221 * @param {OpenLayers.Geometry.Polygon} polygon the actual displayed map polygon | |
34222 */ | |
34223 updatePoint : function(point, polygon) { | |
34224 var olRadius = this.mds.binning.getRadius(point.overlay); | |
34225 if( this.options.useGraphics ){ | |
34226 var graphic = this.config.getGraphic(point.search); | |
34227 if( graphic.shape == 'square' ){ | |
34228 olRadius *= 0.75; | |
34229 } | |
34230 } | |
34231 point.olFeature.style.pointRadius = olRadius; | |
34232 var c = GeoTemConfig.getAverageDatasetColor(point.search, point.overlayElements); | |
34233 point.olFeature.style.fillColor = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
34234 if (polygon.containsPoint(point.feature.geometry)) { | |
34235 this.objectLayer.drawFeature(point.olFeature); | |
34236 } | |
34237 }, | |
34238 | |
34239 /** | |
34240 * updates the the object layer of the map after selections had been executed in timeplot or table or zoom level has changed | |
34241 */ | |
34242 highlightChanged : function(mapObjects) { | |
34243 if( !GeoTemConfig.highlightEvents ){ | |
34244 return; | |
34245 } | |
34246 this.mds.clearOverlay(); | |
34247 if (this.selection.valid()) { | |
34248 this.mds.setOverlay(GeoTemConfig.mergeObjects(mapObjects, this.selection.getObjects())); | |
34249 } else { | |
34250 this.mds.setOverlay(mapObjects); | |
34251 } | |
34252 var points = this.mds.getObjectsByZoom(); | |
34253 var polygon = this.openlayersMap.getExtent().toGeometry(); | |
34254 for (var i in points ) { | |
34255 for (var j in points[i] ) { | |
34256 this.updatePoint(points[i][j], polygon); | |
34257 } | |
34258 } | |
34259 this.displayConnections(); | |
34260 }, | |
34261 | |
34262 selectionChanged : function(selection) { | |
34263 if( !GeoTemConfig.selectionEvents ){ | |
34264 return; | |
34265 } | |
34266 this.reset(); | |
34267 this.selection = selection; | |
34268 this.highlightChanged(selection.objects); | |
34269 }, | |
34270 | |
34271 inPolygon : function(point) { | |
34272 for (var i = 0; i < this.polygons.length; i++) { | |
34273 var polygon = this.polygons[i].geometry; | |
34274 for (var j = 0; j < polygon.components.length; j++) { | |
34275 if (polygon.components[j].containsPoint(point.feature.geometry)) { | |
34276 return true; | |
34277 } | |
34278 } | |
34279 } | |
34280 return false; | |
34281 }, | |
34282 | |
34283 mapSelection : function() { | |
34284 var selectedObjects = []; | |
34285 for (var i = 0; i < this.mds.size(); i++) { | |
34286 selectedObjects.push([]); | |
34287 } | |
34288 var circles = this.mds.getObjectsByZoom(); | |
34289 for (var i = 0; i < circles.length; i++) { | |
34290 | |
34291 for (var j = 0; j < circles[i].length; j++) { | |
34292 var c = circles[i][j]; | |
34293 if (c.selected) { | |
34294 selectedObjects[i] = selectedObjects[i].concat(c.elements); | |
34295 } | |
34296 } | |
34297 } | |
34298 this.selection = new Selection(selectedObjects, this); | |
34299 this.highlightChanged(selectedObjects); | |
34300 this.core.triggerSelection(this.selection); | |
34301 this.filterBar.reset(true); | |
34302 }, | |
34303 | |
34304 deselection : function() { | |
34305 this.reset(); | |
34306 this.selection = new Selection(); | |
34307 this.highlightChanged([]); | |
34308 this.core.triggerSelection(this.selection); | |
34309 }, | |
34310 | |
34311 filtering : function() { | |
34312 for (var i = 0; i < this.datasets.length; i++) { | |
34313 this.datasets[i].objects = this.selection.objects[i]; | |
34314 } | |
34315 this.core.triggerRefining(this.datasets); | |
34316 }, | |
34317 | |
34318 inverseFiltering : function() { | |
34319 var selectedObjects = []; | |
34320 for (var i = 0; i < this.mds.size(); i++) { | |
34321 selectedObjects.push([]); | |
34322 } | |
34323 var circles = this.mds.getObjectsByZoom(); | |
34324 for (var i = 0; i < circles.length; i++) { | |
34325 for (var j = 0; j < circles[i].length; j++) { | |
34326 var c = circles[i][j]; | |
34327 if (!c.selected) { | |
34328 selectedObjects[i] = selectedObjects[i].concat(c.elements); | |
34329 } | |
34330 } | |
34331 } | |
34332 this.selection = new Selection(selectedObjects, this); | |
34333 this.filtering(); | |
34334 }, | |
34335 | |
34336 mapCircleHighlight : function(circle, undo) { | |
34337 if (this.polygons.length > 0 && this.inPolygon(circle)) { | |
34338 return; | |
34339 } | |
34340 var mapObjects = []; | |
34341 for (var i = 0; i < this.mds.size(); i++) { | |
34342 mapObjects.push([]); | |
34343 } | |
34344 if (!undo && !circle.selected) { | |
34345 mapObjects[circle.search] = circle.elements; | |
34346 } | |
34347 this.objectLayer.drawFeature(circle.feature); | |
34348 this.core.triggerHighlight(mapObjects); | |
34349 }, | |
34350 | |
34351 mapLabelSelection : function(label) { | |
34352 var selectedObjects = []; | |
34353 for (var i = 0; i < this.mds.size(); i++) { | |
34354 selectedObjects.push([]); | |
34355 } | |
34356 selectedObjects[label.index] = label.elements; | |
34357 this.selection = new Selection(selectedObjects, this); | |
34358 this.highlightChanged(selectedObjects); | |
34359 this.core.triggerSelection(this.selection); | |
34360 this.filterBar.reset(true); | |
34361 }, | |
34362 | |
34363 triggerMapChanged : function(mapName) { | |
34364 Publisher.Publish('mapChanged', mapName, this); | |
34365 }, | |
34366 | |
34367 /** | |
34368 * displays connections between data objects | |
34369 */ | |
34370 displayConnections : function() { | |
34371 return; | |
34372 if ( typeof this.connection != 'undefined') { | |
34373 this.objectLayer.removeFeatures(this.connections); | |
34374 this.connections = []; | |
34375 } | |
34376 if (this.options.connections) { | |
34377 var points = this.mds.getObjectsByZoom(); | |
34378 for (var i in points ) { | |
34379 for (var j in points[i] ) { | |
34380 | |
34381 } | |
34382 } | |
34383 | |
34384 var slices = this.core.timeplot.getSlices(); | |
34385 for (var i = 0; i < slices.length; i++) { | |
34386 for (var j = 0; j < slices[i].stacks.length; j++) { | |
34387 var e = slices[i].stacks[j].elements; | |
34388 if (e.length == 0) { | |
34389 continue; | |
34390 } | |
34391 var points = []; | |
34392 for (var k = 0; k < e.length; k++) { | |
34393 var point = this.mds.getCircle(j, e[k].index).feature.geometry; | |
34394 if (arrayIndex(points, point) == -1) { | |
34395 points.push(point); | |
34396 } | |
34397 } | |
34398 var matrix = new AdjMatrix(points.length); | |
34399 for (var k = 0; k < points.length - 1; k++) { | |
34400 for (var l = k + 1; l < points.length; l++) { | |
34401 matrix.setEdge(k, l, dist(points[k], points[l])); | |
34402 } | |
34403 } | |
34404 var tree = Prim(matrix); | |
34405 var lines = []; | |
34406 for (var z = 0; z < tree.length; z++) { | |
34407 lines.push(new OpenLayers.Geometry.LineString(new Array(points[tree[z].v1], points[tree[z].v2]))); | |
34408 } | |
34409 this.connections[j].push({ | |
34410 first : this.mds.getCircle(j, e[0].index).feature.geometry, | |
34411 last : this.mds.getCircle(j, e[e.length - 1].index).feature.geometry, | |
34412 lines : lines, | |
34413 time : slices[i].date | |
34414 }); | |
34415 } | |
34416 } | |
34417 var ltm = this.core.timeplot.leftFlagTime; | |
34418 var rtm = this.core.timeplot.rightFlagTime; | |
34419 if (ltm == undefined || ltm == null) { | |
34420 return; | |
34421 } else { | |
34422 ltm = ltm.getTime(); | |
34423 rtm = rtm.getTime(); | |
34424 } | |
34425 // this.connectionLayer.destroyFeatures(); | |
34426 if (thisConnections) { | |
34427 for (var i = 0; i < this.connections.length; i++) { | |
34428 var c = GeoTemConfig.colors[i]; | |
34429 var style = { | |
34430 strokeColor : 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')', | |
34431 strokeOpacity : 0.5, | |
34432 strokeWidth : 3 | |
34433 }; | |
34434 var pointsToConnect = []; | |
34435 var last = undefined; | |
34436 for (var j = 0; j < this.connections[i].length; j++) { | |
34437 var c = this.connections[i][j]; | |
34438 var ct = c.time.getTime(); | |
34439 if (ct >= ltm && ct <= rtm) { | |
34440 if (last != undefined) { | |
34441 var line = new OpenLayers.Geometry.LineString(new Array(last, c.first)); | |
34442 this.connectionLayer.addFeatures([new OpenLayers.Feature.Vector(line, null, style)]); | |
34443 } | |
34444 for (var k = 0; k < c.lines.length; k++) { | |
34445 this.connectionLayer.addFeatures([new OpenLayers.Feature.Vector(c.lines[k], null, style)]); | |
34446 } | |
34447 last = c.last; | |
34448 } | |
34449 } | |
34450 } | |
34451 // this.connectionLayer.redraw(); | |
34452 } | |
34453 } | |
34454 }, | |
34455 | |
34456 /** | |
34457 * performs a zoom on the map | |
34458 * @param {int} delta the change of zoom levels | |
34459 */ | |
34460 zoom : function(delta) { | |
34461 var zoom = this.getZoom() + delta; | |
34462 if (this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS) { | |
34463 this.openlayersMap.zoomTo(zoom); | |
34464 } else { | |
34465 this.openlayersMap.zoomTo(Math.round(zoom)); | |
34466 if (this.zoomSlider) { | |
34467 this.zoomSlider.setValue(this.getZoom()); | |
34468 } | |
34469 } | |
34470 return true; | |
34471 }, | |
34472 | |
34473 deactivateCountrySelector : function() { | |
34474 this.openlayersMap.removeControl(this.selectCountry); | |
34475 this.selectCountry = undefined; | |
34476 }, | |
34477 | |
34478 activateCountrySelector : function(layer) { | |
34479 var map = this; | |
34480 if (this.options.countrySelect && this.options.mapSelectionTools) { | |
34481 this.selectCountry = new OpenLayers.Control.GetFeature({ | |
34482 protocol : OpenLayers.Protocol.WFS.fromWMSLayer(layer), | |
34483 click : true | |
34484 }); | |
34485 this.selectCountry.events.register("featureselected", this, function(e) { | |
34486 map.snapper(); | |
34487 map.drawnPolygonHandler(e.feature.geometry); | |
34488 }); | |
34489 this.openlayersMap.addControl(this.selectCountry); | |
34490 this.countrySelectionControl.enable(); | |
34491 } | |
34492 }, | |
34493 | |
34494 setMap : function(index) { | |
34495 this.baselayerIndex = index; | |
34496 if (this.selectCountry) { | |
34497 // if( this.wmsOverlays.length == 0 ){ | |
34498 this.deactivateCountrySelector(); | |
34499 // } | |
34500 } | |
34501 if (this.baseLayers[index] instanceof OpenLayers.Layer.WMS) { | |
34502 // if( this.wmsOverlays.length == 0 ){ | |
34503 this.activateCountrySelector(this.baseLayers[index]); | |
34504 // } | |
34505 } else { | |
34506 if (this.countrySelectionControl) { | |
34507 this.countrySelectionControl.disable(); | |
34508 } | |
34509 } | |
34510 this.openlayersMap.zoomTo(Math.floor(this.getZoom())); | |
34511 this.openlayersMap.setBaseLayer(this.baseLayers[index]); | |
34512 if (this.baseLayers[index].name == 'Open Street Map') { | |
34513 this.gui.osmLink.style.visibility = 'visible'; | |
34514 } else { | |
34515 this.gui.osmLink.style.visibility = 'hidden'; | |
34516 } | |
34517 if (this.baseLayers[index].name == 'Open Street Map (MapQuest)') { | |
34518 this.gui.osmMapQuestLink.style.visibility = 'visible'; | |
34519 } else { | |
34520 this.gui.osmMapQuestLink.style.visibility = 'hidden'; | |
34521 } | |
34522 this.triggerMapChanged(this.baseLayers[index].name); | |
34523 }, | |
34524 | |
34525 //vhz added title to buttons | |
34526 initSelectorTools : function() { | |
34527 var map = this; | |
34528 this.mapControls = []; | |
34529 | |
34530 if (this.options.squareSelect) { | |
34531 var button = document.createElement("div"); | |
34532 $(button).addClass('mapControl'); | |
34533 var activate = function() { | |
34534 map.drawSquare.activate(); | |
34535 } | |
34536 var deactivate = function() { | |
34537 map.drawSquare.deactivate(); | |
34538 } | |
34539 this.mapControls.push(new MapControl(this, button, 'square', activate, deactivate)); | |
34540 } | |
34541 if (this.options.circleSelect) { | |
34542 var button = document.createElement("div"); | |
34543 $(button).addClass('mapControl'); | |
34544 var activate = function() { | |
34545 map.drawCircle.activate(); | |
34546 } | |
34547 var deactivate = function() { | |
34548 map.drawCircle.deactivate(); | |
34549 } | |
34550 this.mapControls.push(new MapControl(this, button, 'circle', activate, deactivate)); | |
34551 } | |
34552 if (this.options.polygonSelect) { | |
34553 var button = document.createElement("div"); | |
34554 $(button).addClass('mapControl'); | |
34555 var activate = function() { | |
34556 map.drawPolygon.activate(); | |
34557 } | |
34558 var deactivate = function() { | |
34559 map.drawPolygon.deactivate(); | |
34560 } | |
34561 this.mapControls.push(new MapControl(this, button, 'polygon', activate, deactivate)); | |
34562 } | |
34563 if (this.options.countrySelect) { | |
34564 var button = document.createElement("div"); | |
34565 $(button).addClass('mapControl'); | |
34566 var activate = function() { | |
34567 map.selectCountry.activate(); | |
34568 map.dragControl.disable(); | |
34569 } | |
34570 var deactivate = function() { | |
34571 map.selectCountry.deactivate(); | |
34572 map.dragControl.enable(); | |
34573 } | |
34574 this.countrySelectionControl = new MapControl(this, button, 'country', activate, deactivate); | |
34575 this.mapControls.push(this.countrySelectionControl); | |
34576 /* | |
34577 if( !(this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS) ){ | |
34578 this.countrySelectionControl.disable(); | |
34579 } | |
34580 */ | |
34581 } | |
34582 return this.mapControls; | |
34583 }, | |
34584 | |
34585 getZoom : function() { | |
34586 //calculate zoom from active resolution | |
34587 var resolution = this.openlayersMap.getResolution(); | |
34588 var zoom = this.resolutions.indexOf(resolution); | |
34589 if (zoom == -1){ | |
34590 //fractional zoom | |
34591 for (zoom = 0; zoom < this.resolutions.length; zoom++){ | |
34592 if (resolution>=this.resolutions[zoom]){ | |
34593 break; | |
34594 } | |
34595 } | |
34596 if (zoom == this.resolutions.length){ | |
34597 zoom--; | |
34598 } | |
34599 } | |
34600 return(zoom); | |
34601 }, | |
34602 | |
34603 setMarker : function(lon, lat) { | |
34604 var p = new OpenLayers.Geometry.Point(lon, lat, null); | |
34605 p.transform(this.openlayersMap.displayProjection, this.openlayersMap.projection); | |
34606 this.openlayersMap.setCenter(new OpenLayers.LonLat(p.x, p.y)); | |
34607 var size = new OpenLayers.Size(22, 33); | |
34608 var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h); | |
34609 var icon = new OpenLayers.Icon(GeoTemConfig.path + 'marker.png', size, offset); | |
34610 var marker = new OpenLayers.Marker(new OpenLayers.LonLat(p.x, p.y), icon); | |
34611 marker.setOpacity(0.9); | |
34612 this.markerLayer.setZIndex(parseInt(this.objectLayer.getZIndex()) + 1); | |
34613 this.markerLayer.addMarker(marker); | |
34614 // find nearest neighbor | |
34615 var nearestNeighbor; | |
34616 var points = this.mds.getAllObjects(); | |
34617 if (points == null) { | |
34618 return; | |
34619 } | |
34620 var dist = function(p1, p2) { | |
34621 return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); | |
34622 } | |
34623 var zoomLevels = this.openlayersMap.getNumZoomLevels(); | |
34624 var pointSet = points[zoomLevels - 1]; | |
34625 var closestDistance = undefined; | |
34626 var closestPoint; | |
34627 for (var i = 0; i < pointSet.length; i++) { | |
34628 for (var j = 0; j < pointSet[i].length; j++) { | |
34629 var point = pointSet[i][j].feature.geometry; | |
34630 var d = dist(point, p); | |
34631 if (!closestDistance || d < closestDistance) { | |
34632 closestDistance = d; | |
34633 closestPoint = point; | |
34634 } | |
34635 } | |
34636 } | |
34637 // find minimal zoom level | |
34638 var gap = 0; | |
34639 var x_s = this.gui.mapWindow.offsetWidth / 2 - gap; | |
34640 var y_s = this.gui.mapWindow.offsetHeight / 2 - gap; | |
34641 if (typeof closestPoint !== "undefined"){ | |
34642 var xDist = Math.abs(p.x - closestPoint.x); | |
34643 var yDist = Math.abs(p.y - closestPoint.y); | |
34644 for (var i = 0; i < zoomLevels; i++) { | |
34645 var resolution = this.openlayersMap.getResolutionForZoom(zoomLevels - i - 1); | |
34646 if (xDist / resolution < x_s && yDist / resolution < y_s) { | |
34647 this.openlayersMap.zoomTo(zoomLevels - i - 1); | |
34648 if (this.zoomSlider) { | |
34649 this.zoomSlider.setValue(this.getZoom()); | |
34650 } | |
34651 this.drawObjectLayer(false); | |
34652 break; | |
34653 } | |
34654 } | |
34655 } else { | |
34656 //if there are no points on the map, zoom to max | |
34657 this.openlayersMap.zoomTo(0); | |
34658 if (this.zoomSlider) { | |
34659 this.zoomSlider.setValue(this.getZoom()); | |
34660 } | |
34661 this.drawObjectLayer(false); | |
34662 } | |
34663 }, | |
34664 | |
34665 removeMarker : function() { | |
34666 this.markerLayer.removeMarker(this.markerLayer.markers[0]); | |
34667 }, | |
34668 | |
34669 getLevelOfDetail : function() { | |
34670 var zoom = Math.floor(this.getZoom()); | |
34671 if (zoom <= 1) { | |
34672 return 0; | |
34673 } else if (zoom <= 3) { | |
34674 return 1; | |
34675 } else if (zoom <= 8) { | |
34676 return 2; | |
34677 } else { | |
34678 return 3; | |
34679 } | |
34680 } | |
34681 } | |
34682 /* | |
34683 * TimeConfig.js | |
34684 * | |
34685 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
34686 * | |
34687 * This library is free software; you can redistribute it and/or | |
34688 * modify it under the terms of the GNU Lesser General Public | |
34689 * License as published by the Free Software Foundation; either | |
34690 * version 3 of the License, or (at your option) any later version. | |
34691 * | |
34692 * This library is distributed in the hope that it will be useful, | |
34693 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34694 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
34695 * Lesser General Public License for more details. | |
34696 * | |
34697 * You should have received a copy of the GNU Lesser General Public | |
34698 * License along with this library; if not, write to the Free Software | |
34699 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
34700 * MA 02110-1301 USA | |
34701 */ | |
34702 | |
34703 /** | |
34704 * @class TimeConfig | |
34705 * Time Configuration File | |
34706 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
34707 * @release 1.0 | |
34708 * @release date: 2012-07-27 | |
34709 * @version date: 2012-07-27 | |
34710 */ | |
34711 function TimeConfig(options) { | |
34712 | |
34713 this.options = { | |
34714 timeTitle : 'GeoTemCo Time View', // title will be shown in timeplot header | |
34715 timeIndex : 0, // index = position in date array; for multiple dates the 2nd timeplot refers to index 1 | |
34716 timeWidth : false, // false or desired width css definition for the timeplot | |
34717 timeHeight : '100px', // false or desired height css definition for the timeplot | |
34718 defaultMinDate : new Date(2012, 0, 1), // required, when empty timelines are possible | |
34719 defaultMaxDate : new Date(), // required, when empty timelines are possible | |
34720 timeCanvasFrom : '#EEE', // time widget background gradient color top | |
34721 timeCanvasTo : '#EEE', // time widget background gradient color bottom | |
34722 rangeBoxColor : "white", // fill color for time range box | |
34723 rangeBorder : "1px solid #de7708", // border of frames | |
34724 dataInformation : true, // show/hide data information | |
34725 rangeAnimation : true, // show/hide animation buttons | |
34726 scaleSelection : true, // show/hide scale selection buttons | |
34727 linearScale : true, // true for linear value scaling, false for logarithmic | |
34728 unitSelection : true, // show/hide time unit selection dropdown | |
34729 timeUnit : -1, // minimum temporal unit (SimileAjax.DateTime or -1 if none) of the data | |
34730 timeMerge : false // if the elements of distinct datasets should be merged into one set or not | |
34731 }; | |
34732 if ( typeof options != 'undefined') { | |
34733 $.extend(this.options, options); | |
34734 } | |
34735 | |
34736 }; | |
34737 /* | |
34738 * TimeGui.js | |
34739 * | |
34740 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
34741 * | |
34742 * This library is free software; you can redistribute it and/or | |
34743 * modify it under the terms of the GNU Lesser General Public | |
34744 * License as published by the Free Software Foundation; either | |
34745 * version 3 of the License, or (at your option) any later version. | |
34746 * | |
34747 * This library is distributed in the hope that it will be useful, | |
34748 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34749 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
34750 * Lesser General Public License for more details. | |
34751 * | |
34752 * You should have received a copy of the GNU Lesser General Public | |
34753 * License along with this library; if not, write to the Free Software | |
34754 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
34755 * MA 02110-1301 USA | |
34756 */ | |
34757 | |
34758 /** | |
34759 * @class TimeGui | |
34760 * Time GUI Implementation | |
34761 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
34762 * @release 1.0 | |
34763 * @release date: 2012-07-27 | |
34764 * @version date: 2012-07-27 | |
34765 * | |
34766 * @param {TimeWidget} parent time widget object | |
34767 * @param {HTML object} div parent div to append the time gui | |
34768 * @param {JSON} options time configuration | |
34769 */ | |
34770 function TimeGui(plot, div, options, iid) { | |
34771 | |
34772 var gui = this; | |
34773 | |
34774 this.plot = plot; | |
34775 | |
34776 this.container = div; | |
34777 if (options.timeWidth) { | |
34778 this.container.style.width = options.timeWidth; | |
34779 } | |
34780 if (options.timeHeight) { | |
34781 this.container.style.height = options.timeHeight; | |
34782 } | |
34783 this.container.style.position = 'relative'; | |
34784 | |
34785 var w = this.container.offsetWidth; | |
34786 var h = this.container.offsetHeight; | |
34787 | |
34788 var toolbarTable = document.createElement("table"); | |
34789 toolbarTable.setAttribute('class', 'ddbToolbar'); | |
34790 this.container.appendChild(toolbarTable); | |
34791 | |
34792 this.plotWindow = document.createElement("div"); | |
34793 this.plotWindow.id = "plotWindow"+iid; | |
34794 this.plotWindow.setAttribute('class', 'plotWindow'); | |
34795 // this.plotWindow.style.width = w + "px"; | |
34796 | |
34797 this.plotWindow.style.height = (h + 12) + "px"; | |
34798 this.container.style.height = (h + 12) + "px"; | |
34799 | |
34800 this.plotWindow.onmousedown = function() { | |
34801 return false; | |
34802 } | |
34803 | |
34804 this.plotContainer = document.createElement("div"); | |
34805 this.plotContainer.id = "plotContainer"+iid; | |
34806 this.plotContainer.setAttribute('class', 'plotContainer'); | |
34807 // this.plotContainer.style.width = w + "px"; | |
34808 this.plotContainer.style.height = h + "px"; | |
34809 this.plotContainer.style.position = "absolute"; | |
34810 this.plotContainer.style.zIndex = 0; | |
34811 this.plotContainer.style.top = "12px"; | |
34812 this.plotWindow.appendChild(this.plotContainer); | |
34813 this.container.appendChild(this.plotWindow); | |
34814 | |
34815 this.timeplotDiv = document.createElement("div"); | |
34816 this.timeplotDiv.style.left = "16px"; | |
34817 this.timeplotDiv.style.width = (w - 32) + "px"; | |
34818 this.timeplotDiv.style.height = h + "px"; | |
34819 this.plotContainer.appendChild(this.timeplotDiv); | |
34820 | |
34821 var cv = document.createElement("canvas"); | |
34822 cv.setAttribute('class', 'plotCanvas'); | |
34823 this.plotWindow.appendChild(cv); | |
34824 if (!cv.getContext && G_vmlCanvasManager) | |
34825 cv = G_vmlCanvasManager.initElement(cv); | |
34826 var ctx = cv.getContext('2d'); | |
34827 | |
34828 var setCanvas = function(){ | |
34829 cv.width = gui.plotWindow.clientWidth; | |
34830 cv.height = gui.plotWindow.clientHeight; | |
34831 var gradient = ctx.createLinearGradient(0, 0, 0, gui.plotWindow.clientHeight); | |
34832 gradient.addColorStop(0, options.timeCanvasFrom); | |
34833 gradient.addColorStop(1, options.timeCanvasTo); | |
34834 ctx.fillStyle = gradient; | |
34835 ctx.fillRect(0, 0, gui.plotWindow.clientWidth, gui.plotWindow.clientHeight); | |
34836 } | |
34837 setCanvas(); | |
34838 | |
34839 this.resize = function(){ | |
34840 gui.timeplotDiv.style.width = (gui.container.offsetWidth - 32) + "px"; | |
34841 ctx.clearRect(0,0,gui.plotWindow.clientWidth, gui.plotWindow.clientHeight); | |
34842 if( typeof plot.datasets != "undefined" ){ | |
34843 plot.redrawPlot(); | |
34844 plot.resetOpacityPlots(); | |
34845 } | |
34846 setCanvas(); | |
34847 }; | |
34848 | |
34849 var titles = document.createElement("tr"); | |
34850 toolbarTable.appendChild(titles); | |
34851 var tools = document.createElement("tr"); | |
34852 toolbarTable.appendChild(tools); | |
34853 | |
34854 this.timeUnitTitle = document.createElement("td"); | |
34855 this.timeUnitTitle.innerHTML = GeoTemConfig.getString('timeUnit'); | |
34856 this.timeUnitSelector = document.createElement("td"); | |
34857 if (options.unitSelection) { | |
34858 tools.appendChild(this.timeUnitSelector); | |
34859 titles.appendChild(this.timeUnitTitle); | |
34860 } | |
34861 | |
34862 this.timeAnimation = document.createElement("td"); | |
34863 this.timeAnimation.innerHTML = GeoTemConfig.getString('timeAnimation'); | |
34864 var timeAnimationTools = document.createElement("td"); | |
34865 | |
34866 var status; | |
34867 this.updateAnimationButtons = function(s) { | |
34868 status = s; | |
34869 if (status == 0) { | |
34870 gui.playButton.setAttribute('class', 'smallButton playDisabled'); | |
34871 gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled'); | |
34872 } else if (status == 1) { | |
34873 gui.playButton.setAttribute('class', 'smallButton playEnabled'); | |
34874 gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled'); | |
34875 } else { | |
34876 gui.playButton.setAttribute('class', 'smallButton playDisabled'); | |
34877 gui.pauseButton.setAttribute('class', 'smallButton pauseEnabled'); | |
34878 } | |
34879 }; | |
34880 this.playButton = document.createElement("div"); | |
34881 this.playButton.title = GeoTemConfig.getString('playButton'); | |
34882 timeAnimationTools.appendChild(this.playButton); | |
34883 this.playButton.onclick = function() { | |
34884 if (status == 1) { | |
34885 plot.play(); | |
34886 } | |
34887 } | |
34888 | |
34889 this.pauseButton = document.createElement("div"); | |
34890 this.pauseButton.title = GeoTemConfig.getString('pauseButton'); | |
34891 timeAnimationTools.appendChild(this.pauseButton); | |
34892 this.pauseButton.onclick = function() { | |
34893 if (status == 2) { | |
34894 plot.stop(); | |
34895 } | |
34896 } | |
34897 | |
34898 this.valueScale = document.createElement("td"); | |
34899 this.valueScale.innerHTML = GeoTemConfig.getString('valueScale'); | |
34900 var valueScaleTools = document.createElement("td"); | |
34901 | |
34902 var linearPlot; | |
34903 var setValueScale = function(linScale) { | |
34904 if (linearPlot != linScale) { | |
34905 linearPlot = linScale; | |
34906 if (linearPlot) { | |
34907 gui.linButton.setAttribute('class', 'smallButton linearPlotActivated'); | |
34908 gui.logButton.setAttribute('class', 'smallButton logarithmicPlotDeactivated'); | |
34909 plot.drawLinearPlot(); | |
34910 } else { | |
34911 gui.linButton.setAttribute('class', 'smallButton linearPlotDeactivated'); | |
34912 gui.logButton.setAttribute('class', 'smallButton logarithmicPlotActivated'); | |
34913 plot.drawLogarithmicPlot(); | |
34914 } | |
34915 } | |
34916 }; | |
34917 this.linButton = document.createElement("div"); | |
34918 this.linButton.title = GeoTemConfig.getString('linearPlot'); | |
34919 valueScaleTools.appendChild(this.linButton); | |
34920 this.linButton.onclick = function() { | |
34921 setValueScale(true); | |
34922 } | |
34923 | |
34924 this.logButton = document.createElement("div"); | |
34925 this.logButton.title = GeoTemConfig.getString('logarithmicPlot'); | |
34926 valueScaleTools.appendChild(this.logButton); | |
34927 this.logButton.onclick = function() { | |
34928 setValueScale(false); | |
34929 } | |
34930 if (options.rangeAnimation) { | |
34931 titles.appendChild(this.timeAnimation); | |
34932 tools.appendChild(timeAnimationTools); | |
34933 this.updateAnimationButtons(0); | |
34934 } | |
34935 | |
34936 if (options.scaleSelection) { | |
34937 titles.appendChild(this.valueScale); | |
34938 tools.appendChild(valueScaleTools); | |
34939 setValueScale(options.linearScale); | |
34940 } | |
34941 | |
34942 if (GeoTemConfig.allowFilter) { | |
34943 this.filterTitle = document.createElement("td"); | |
34944 titles.appendChild(this.filterTitle); | |
34945 this.filterTitle.innerHTML = GeoTemConfig.getString('filter'); | |
34946 this.filterOptions = document.createElement("td"); | |
34947 tools.appendChild(this.filterOptions); | |
34948 } | |
34949 | |
34950 if (options.dataInformation) { | |
34951 this.infoTitle = document.createElement("td"); | |
34952 this.infoTitle.innerHTML = options.timeTitle; | |
34953 titles.appendChild(this.infoTitle); | |
34954 var timeSum = document.createElement("td"); | |
34955 this.timeElements = document.createElement("div"); | |
34956 this.timeElements.setAttribute('class', 'ddbElementsCount'); | |
34957 timeSum.appendChild(this.timeElements); | |
34958 tools.appendChild(timeSum); | |
34959 } | |
34960 | |
34961 /* | |
34962 var tooltip = document.createElement("div"); | |
34963 tooltip.setAttribute('class','ddbTooltip'); | |
34964 toolbarTable.appendChild(tooltip); | |
34965 | |
34966 tooltip.onmouseover = function(){ | |
34967 /* | |
34968 getPublisher().Publish('TooltipContent', { | |
34969 content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'), | |
34970 target: $(tooltip) | |
34971 }); | |
34972 | |
34973 } | |
34974 tooltip.onmouseout = function(){ | |
34975 //getPublisher().Publish('TooltipContent'); | |
34976 } | |
34977 */ | |
34978 | |
34979 this.setHeight = function() { | |
34980 this.container.style.height = (this.plotWindow.offsetHeight + toolbarTable.offsetHeight) + "px"; | |
34981 }; | |
34982 | |
34983 this.updateTimeQuantity = function(count) { | |
34984 if (options.dataInformation) { | |
34985 this.plotCount = count; | |
34986 if (count != 1) { | |
34987 this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results'); | |
34988 } else { | |
34989 this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result'); | |
34990 } | |
34991 } | |
34992 } | |
34993 | |
34994 this.setTimeUnitDropdown = function(units) { | |
34995 $(this.timeUnitSelector).empty(); | |
34996 var gui = this; | |
34997 var timeUnits = []; | |
34998 var addUnit = function(unit, index) { | |
34999 var setUnit = function() { | |
35000 gui.plot.setTimeUnit(unit.unit); | |
35001 } | |
35002 timeUnits.push({ | |
35003 name : unit.label, | |
35004 onclick : setUnit | |
35005 }); | |
35006 } | |
35007 for (var i = 0; i < units.length; i++) { | |
35008 addUnit(units[i], i); | |
35009 } | |
35010 this.timeUnitDropdown = new Dropdown(this.timeUnitSelector, timeUnits, GeoTemConfig.getString('selectTimeUnit'), '100px'); | |
35011 this.timeUnitDropdown.setEntry(0); | |
35012 } | |
35013 this.setTimeUnitDropdown([{ | |
35014 name : 'none', | |
35015 id : -1 | |
35016 }]); | |
35017 | |
35018 this.beautifyCount = function(count) { | |
35019 var c = count + ''; | |
35020 var p = 0; | |
35021 var l = c.length; | |
35022 while (l - p > 3) { | |
35023 p += 3; | |
35024 c = c.substring(0, l - p) + "." + c.substring(l - p); | |
35025 p++; | |
35026 l++; | |
35027 } | |
35028 return c; | |
35029 } | |
35030 | |
35031 this.hideTimeUnitSelection = function() { | |
35032 this.timeUnitTitle.style.display = 'none'; | |
35033 this.timeUnitSelector.style.display = 'none'; | |
35034 } | |
35035 }; | |
35036 /* | |
35037 * TimeWidget.js | |
35038 * | |
35039 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
35040 * | |
35041 * This library is free software; you can redistribute it and/or | |
35042 * modify it under the terms of the GNU Lesser General Public | |
35043 * License as published by the Free Software Foundation; either | |
35044 * version 3 of the License, or (at your option) any later version. | |
35045 * | |
35046 * This library is distributed in the hope that it will be useful, | |
35047 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35048 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
35049 * Lesser General Public License for more details. | |
35050 * | |
35051 * You should have received a copy of the GNU Lesser General Public | |
35052 * License along with this library; if not, write to the Free Software | |
35053 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
35054 * MA 02110-1301 USA | |
35055 */ | |
35056 | |
35057 /** | |
35058 * @class TimeWidget | |
35059 * TableWidget Implementation | |
35060 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
35061 * @release 1.0 | |
35062 * @release date: 2012-07-27 | |
35063 * @version date: 2012-07-27 | |
35064 * | |
35065 * @param {TimeWrapper} core wrapper for interaction to other widgets | |
35066 * @param {HTML object} div parent div to append the time widget div | |
35067 * @param {JSON} options user specified configuration that overwrites options in TimeConfig.js | |
35068 */ | |
35069 TimeWidget = function(core, div, options) { | |
35070 | |
35071 this.core = core; | |
35072 this.core.setWidget(this); | |
35073 this.timeplot | |
35074 this.dataSources | |
35075 this.eventSources | |
35076 this.tds | |
35077 this.timeGeometry | |
35078 this.valueGeometry | |
35079 this.canvas | |
35080 | |
35081 this.leftFlagPole | |
35082 this.rightFlagPole | |
35083 this.rangeBox | |
35084 this.leftHandle | |
35085 this.rightHandle | |
35086 | |
35087 this.leftFlagPos = null; | |
35088 this.leftFlagTime = null; | |
35089 this.rightFlagPos = null; | |
35090 this.rightFlagTime = null; | |
35091 | |
35092 this.mouseDownTime | |
35093 this.mouseUpTime | |
35094 this.mouseTempTime | |
35095 this.mouseDownPos | |
35096 this.mouseUpPos | |
35097 this.mouseTempPos | |
35098 | |
35099 this.status | |
35100 this.slider | |
35101 | |
35102 this.iid = GeoTemConfig.getIndependentId('time'); | |
35103 this.options = (new TimeConfig(options)).options; | |
35104 this.gui = new TimeGui(this, div, this.options, this.iid); | |
35105 this.initialize(); | |
35106 | |
35107 } | |
35108 | |
35109 TimeWidget.prototype = { | |
35110 | |
35111 /** | |
35112 * clears the timeplot canvas and the timeGeometry properties | |
35113 */ | |
35114 clearTimeplot : function() { | |
35115 this.timeplot._clearCanvas(); | |
35116 this.timeGeometry._earliestDate = null; | |
35117 this.timeGeometry._latestDate = null; | |
35118 this.valueGeometry._minValue = 0; | |
35119 this.valueGeometry._maxValue = 0; | |
35120 this.highlightedSlice = undefined; | |
35121 this.timeGeometry._clearLabels(); | |
35122 this.selection = new Selection(); | |
35123 }, | |
35124 | |
35125 /** | |
35126 * initializes the timeplot elements with arrays of time objects | |
35127 * @param {TimeObject[][]} timeObjects an array of time objects from different (1-4) sets | |
35128 */ | |
35129 initWidget : function(datasets) { | |
35130 this.datasets = datasets; | |
35131 var timeObjects = []; | |
35132 for (var i = 0; i < datasets.length; i++) { | |
35133 timeObjects.push(datasets[i].objects); | |
35134 } | |
35135 this.clearTimeplot(); | |
35136 this.reset(); | |
35137 for (var i = 0; i < this.timeplot._plots.length; i++) { | |
35138 this.timeplot._plots[i].dispose(); | |
35139 } | |
35140 this.dataSources = new Array(); | |
35141 this.plotInfos = new Array(); | |
35142 this.eventSources = new Array(); | |
35143 var granularity = 0; | |
35144 this.count = 0; | |
35145 for (var i = 0; i < timeObjects.length; i++) { | |
35146 if( i==0 || !this.options.timeMerge ){ | |
35147 var eventSource = new Timeplot.DefaultEventSource(); | |
35148 var dataSource = new Timeplot.ColumnSource(eventSource, 1); | |
35149 this.dataSources.push(dataSource); | |
35150 this.eventSources.push(eventSource); | |
35151 var c = GeoTemConfig.getColor(i); | |
35152 var plotInfo = Timeplot.createPlotInfo({ | |
35153 id : "plot" + i, | |
35154 dataSource : dataSource, | |
35155 timeGeometry : this.timeGeometry, | |
35156 valueGeometry : this.valueGeometry, | |
35157 fillGradient : false, | |
35158 lineColor : 'rgba(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ', 1)', | |
35159 fillColor : 'rgba(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ', 0.3)', | |
35160 showValues : true | |
35161 }); | |
35162 this.plotInfos.push(plotInfo); | |
35163 } | |
35164 for (var j = 0; j < timeObjects[i].length; j++) { | |
35165 var o = timeObjects[i][j]; | |
35166 if (o.isTemporal) { | |
35167 var g = o.dates[this.options.timeIndex].granularity; | |
35168 if (g == null) { | |
35169 continue; | |
35170 } else if (g > granularity) { | |
35171 granularity = g; | |
35172 } | |
35173 this.count += o.weight; | |
35174 } | |
35175 } | |
35176 } | |
35177 this.timeGeometry._granularity = granularity; | |
35178 this.timeGeometry._clearLabels(); | |
35179 this.timeplot.resetPlots(this.plotInfos); | |
35180 if (this.plotInfos.length == 0) { | |
35181 this.initLabels(this.timeplot.regularGrid()); | |
35182 return; | |
35183 } | |
35184 this.timeGeometry.extendedDataSource = this.tds; | |
35185 this.tds.initialize(this.dataSources, this.eventSources, timeObjects, granularity, this.options.timeUnit, this.gui.timeplotDiv.offsetWidth); | |
35186 this.gui.setTimeUnitDropdown(this.tds.availableUnits); | |
35187 this.gui.timeUnitDropdown.setEntry(this.tds.getUnitIndex()); | |
35188 var plots = this.timeplot._plots; | |
35189 for (var i = 0; i < plots.length; i++) { | |
35190 plots[i].pins = []; | |
35191 plots[i].style = this.style; | |
35192 for (var j = 0; j < this.tds.getSliceNumber(); j++) { | |
35193 plots[i].pins.push({ | |
35194 height : 0, | |
35195 count : 0 | |
35196 }); | |
35197 } | |
35198 } | |
35199 /* | |
35200 var levels = Math.round( (this.tds.timeSlices.length-3)/2 ); | |
35201 if( GeoTemConfig.timeZoom ){ | |
35202 this.zoomSlider.setMaxAndLevels(levels,levels); | |
35203 } | |
35204 */ | |
35205 this.timeplot.repaint(); | |
35206 this.timeplot._resizeCanvas(); | |
35207 // set maximum number of slider steps | |
35208 var slices = this.tds.timeSlices.length; | |
35209 var numSlices = Math.floor(slices / this.canvas.width * this.canvas.height + 0.5); | |
35210 | |
35211 this.initLabels([]); | |
35212 this.initOverview(); | |
35213 this.gui.updateTimeQuantity(this.count); | |
35214 | |
35215 }, | |
35216 | |
35217 setTimeUnit : function(unit) { | |
35218 this.clearTimeplot(); | |
35219 this.reset(); | |
35220 this.tds.setTimeUnit(unit); | |
35221 var plots = this.timeplot._plots; | |
35222 for (var i = 0; i < plots.length; i++) { | |
35223 plots[i].pins = []; | |
35224 plots[i].style = this.style; | |
35225 for (var j = 0; j < this.tds.getSliceNumber(); j++) { | |
35226 plots[i].pins.push({ | |
35227 height : 0, | |
35228 count : 0 | |
35229 }); | |
35230 } | |
35231 } | |
35232 this.initLabels([]); | |
35233 }, | |
35234 | |
35235 /** | |
35236 * initializes the timeplot for the Spatio Temporal Interface. | |
35237 * all elements (including their events) that are needed for user interaction are instantiated here, the slider element as well | |
35238 */ | |
35239 initialize : function() { | |
35240 | |
35241 this.status = 0; | |
35242 this.selection = new Selection(); | |
35243 this.paused = true; | |
35244 this.dataSources = new Array(); | |
35245 this.plotInfos = new Array(); | |
35246 this.eventSources = new Array(); | |
35247 this.timeGeometry = new Timeplot.DefaultTimeGeometry({ | |
35248 gridColor : "#000000", | |
35249 axisLabelsPlacement : "top" | |
35250 }); | |
35251 this.style = 'graph'; | |
35252 this.timeGeometry._hideLabels = true; | |
35253 this.timeGeometry._granularity = 0; | |
35254 this.valueGeometry = new Timeplot.LogarithmicValueGeometry({ | |
35255 min : 0 | |
35256 }); | |
35257 this.valueGeometry.actLinear(); | |
35258 | |
35259 var plot = this; | |
35260 | |
35261 this.timeplot = Timeplot.create(this.gui.timeplotDiv, this.plotInfos); | |
35262 this.tds = new TimeDataSource(this.options); | |
35263 | |
35264 this.canvas = this.timeplot.getCanvas(); | |
35265 | |
35266 this.leftFlagPole = this.timeplot.putDiv("leftflagpole", "timeplot-dayflag-pole"); | |
35267 this.rightFlagPole = this.timeplot.putDiv("rightflagpole", "timeplot-dayflag-pole"); | |
35268 SimileAjax.Graphics.setOpacity(this.leftFlagPole, 50); | |
35269 SimileAjax.Graphics.setOpacity(this.rightFlagPole, 50); | |
35270 | |
35271 this.rangeBox = this.timeplot.putDiv("rangebox", "range-box"); | |
35272 this.rangeBox.style.backgroundColor = plot.options.rangeBoxColor; | |
35273 this.rangeBox.style.border = plot.options.rangeBorder; | |
35274 | |
35275 this.leftHandle = document.createElement("div"); | |
35276 this.rightHandle = document.createElement("div"); | |
35277 this.gui.plotWindow.appendChild(this.leftHandle); | |
35278 this.gui.plotWindow.appendChild(this.rightHandle); | |
35279 this.leftHandle.title = GeoTemConfig.getString('leftHandle'); | |
35280 this.rightHandle.title = GeoTemConfig.getString('rightHandle'); | |
35281 | |
35282 this.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
35283 this.leftHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
35284 this.rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")"; | |
35285 this.rightHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
35286 | |
35287 this.poles = this.timeplot.putDiv("poles", "pole"); | |
35288 this.timeplot.placeDiv(this.poles, { | |
35289 left : 0, | |
35290 bottom : 0, | |
35291 width : this.canvas.width, | |
35292 height : this.canvas.height, | |
35293 display : "block" | |
35294 }); | |
35295 this.poles.appendChild(document.createElement("canvas")); | |
35296 | |
35297 this.filterBar = new FilterBar(this, this.gui.filterOptions); | |
35298 | |
35299 var plot = this; | |
35300 | |
35301 this.dragButton = document.createElement("div"); | |
35302 this.dragButton.title = GeoTemConfig.getString('dragTimeRange'); | |
35303 this.cancelButton = document.createElement("div"); | |
35304 this.cancelButton.title = GeoTemConfig.getString('clearSelection'); | |
35305 this.cancelButton.onclick = function() { | |
35306 plot.deselection(); | |
35307 } | |
35308 | |
35309 this.toolbar = document.createElement("div"); | |
35310 this.toolbar.setAttribute('class', 'plotToolbar'); | |
35311 this.toolbar.style.borderTop = plot.options.rangeBorder; | |
35312 this.toolbar.style.textAlign = "center"; | |
35313 this.gui.plotWindow.appendChild(this.toolbar); | |
35314 | |
35315 this.toolbarAbsoluteDiv = document.createElement("div"); | |
35316 this.toolbarAbsoluteDiv.setAttribute('class', 'absoluteToolbar'); | |
35317 this.toolbar.appendChild(this.toolbarAbsoluteDiv); | |
35318 | |
35319 this.dragButton.setAttribute('class', 'dragTimeRangeAlt'); | |
35320 this.dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")"; | |
35321 // this.zoomButton.setAttribute('class','zoomRangeAlt'); | |
35322 this.cancelButton.setAttribute('class', 'cancelRangeAlt'); | |
35323 this.toolbarAbsoluteDiv.appendChild(this.dragButton); | |
35324 this.toolbarAbsoluteDiv.style.width = this.dragButton.offsetWidth + "px"; | |
35325 // this.gui.plotWindow.appendChild(this.zoomButton); | |
35326 this.gui.plotWindow.appendChild(this.cancelButton); | |
35327 | |
35328 this.overview = document.createElement("div"); | |
35329 this.overview.setAttribute('class', 'timeOverview'); | |
35330 this.gui.plotWindow.appendChild(this.overview); | |
35331 | |
35332 var mousedown = false; | |
35333 this.shift = function(shift) { | |
35334 if (!mousedown) { | |
35335 return; | |
35336 } | |
35337 if (plot.tds.setShift(shift)) { | |
35338 plot.redrawPlot(); | |
35339 } | |
35340 setTimeout(function() { | |
35341 plot.shift(shift); | |
35342 }, 200); | |
35343 } | |
35344 var shiftPressed = function(shift) { | |
35345 mousedown = true; | |
35346 document.onmouseup = function() { | |
35347 mousedown = false; | |
35348 document.onmouseup = null; | |
35349 } | |
35350 plot.shift(shift); | |
35351 } | |
35352 | |
35353 this.shiftLeft = document.createElement("div"); | |
35354 this.shiftLeft.setAttribute('class', 'shiftLeft'); | |
35355 this.gui.plotWindow.appendChild(this.shiftLeft); | |
35356 this.shiftLeft.onmousedown = function() { | |
35357 shiftPressed(1); | |
35358 } | |
35359 | |
35360 this.shiftRight = document.createElement("div"); | |
35361 this.shiftRight.setAttribute('class', 'shiftRight'); | |
35362 this.gui.plotWindow.appendChild(this.shiftRight); | |
35363 this.shiftRight.onmousedown = function() { | |
35364 shiftPressed(-1); | |
35365 } | |
35366 | |
35367 this.plotLabels = document.createElement("div"); | |
35368 this.plotLabels.setAttribute('class', 'plotLabels'); | |
35369 this.gui.plotWindow.appendChild(this.plotLabels); | |
35370 | |
35371 this.initLabels(this.timeplot.regularGrid()); | |
35372 | |
35373 //Finds the time corresponding to the position x on the timeplot | |
35374 var getCorrelatedTime = function(x) { | |
35375 if (x >= plot.canvas.width) | |
35376 x = plot.canvas.width; | |
35377 if (isNaN(x) || x < 0) | |
35378 x = 0; | |
35379 var t = plot.timeGeometry.fromScreen(x); | |
35380 if (t == 0) | |
35381 return; | |
35382 return plot.dataSources[0].getClosestValidTime(t); | |
35383 } | |
35384 //Finds the position corresponding to the time t on the timeplot | |
35385 var getCorrelatedPosition = function(t) { | |
35386 var x = plot.timeGeometry.toScreen(t); | |
35387 if (x >= plot.canvas.width) | |
35388 x = plot.canvas.width; | |
35389 if (isNaN(x) || x < 0) | |
35390 x = 0; | |
35391 return x; | |
35392 } | |
35393 //Maps the 2 positions in the right order to left and right bound of the chosen timeRange | |
35394 var mapPositions = function(pos1, pos2) { | |
35395 if (pos1 > pos2) { | |
35396 plot.leftFlagPos = pos2; | |
35397 plot.rightFlagPos = pos1; | |
35398 } else { | |
35399 plot.leftFlagPos = pos1; | |
35400 plot.rightFlagPos = pos2; | |
35401 } | |
35402 plot.leftFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.leftFlagPos)); | |
35403 plot.rightFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.rightFlagPos)); | |
35404 } | |
35405 //Sets the divs corresponding to the actual chosen timeRange | |
35406 var setRangeDivs = function() { | |
35407 plot.leftFlagPole.style.visibility = "visible"; | |
35408 plot.rightFlagPole.style.visibility = "visible"; | |
35409 plot.rangeBox.style.visibility = "visible"; | |
35410 plot.timeplot.placeDiv(plot.leftFlagPole, { | |
35411 left : plot.leftFlagPos, | |
35412 bottom : 0, | |
35413 height : plot.canvas.height, | |
35414 display : "block" | |
35415 }); | |
35416 plot.timeplot.placeDiv(plot.rightFlagPole, { | |
35417 left : plot.rightFlagPos, | |
35418 bottom : 0, | |
35419 height : plot.canvas.height, | |
35420 display : "block" | |
35421 }); | |
35422 var boxWidth = plot.rightFlagPos - plot.leftFlagPos; | |
35423 if (plot.popup) { | |
35424 plot.popupClickDiv.style.visibility = "visible"; | |
35425 plot.timeplot.placeDiv(plot.popupClickDiv, { | |
35426 left : plot.leftFlagPos, | |
35427 width : boxWidth + 1, | |
35428 height : plot.canvas.height, | |
35429 display : "block" | |
35430 }); | |
35431 } | |
35432 plot.timeplot.placeDiv(plot.rangeBox, { | |
35433 left : plot.leftFlagPos, | |
35434 width : boxWidth + 1, | |
35435 height : plot.canvas.height, | |
35436 display : "block" | |
35437 }); | |
35438 var plots = plot.timeplot._plots; | |
35439 for ( i = 0; i < plots.length; i++) { | |
35440 plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i)); | |
35441 plots[i].opacityPlot.style.visibility = "visible"; | |
35442 } | |
35443 var unit = plot.tds.unit; | |
35444 | |
35445 var top = plot.gui.plotContainer.offsetTop; | |
35446 var left = plot.gui.plotContainer.offsetLeft; | |
35447 var leftPos = plot.leftFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft; | |
35448 var rightPos = plot.rightFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft; | |
35449 var rW = rightPos - leftPos; | |
35450 var pW = plot.canvas.width; | |
35451 var pL = plot.timeplot.getElement().offsetLeft; | |
35452 | |
35453 var handleTop = top + Math.floor(plot.gui.timeplotDiv.offsetHeight / 2 - plot.leftHandle.offsetHeight / 2); | |
35454 plot.leftHandle.style.visibility = "visible"; | |
35455 plot.rightHandle.style.visibility = "visible"; | |
35456 plot.leftHandle.style.left = (leftPos - plot.leftHandle.offsetWidth / 2) + "px"; | |
35457 plot.rightHandle.style.left = (rightPos - plot.rightHandle.offsetWidth + 1 + plot.rightHandle.offsetWidth / 2) + "px"; | |
35458 plot.leftHandle.style.top = handleTop + "px"; | |
35459 plot.rightHandle.style.top = handleTop + "px"; | |
35460 if (rightPos == leftPos) { | |
35461 plot.rightHandle.style.visibility = "hidden"; | |
35462 plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "mergedHandle.png" + ")"; | |
35463 } else { | |
35464 plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
35465 } | |
35466 plot.cancelButton.style.visibility = "visible"; | |
35467 plot.cancelButton.style.top = top + "px"; | |
35468 | |
35469 if (rW > plot.cancelButton.offsetWidth) { | |
35470 plot.cancelButton.style.left = (left + rightPos - plot.cancelButton.offsetWidth) + "px"; | |
35471 } else { | |
35472 plot.cancelButton.style.left = (left + rightPos) + "px"; | |
35473 } | |
35474 var tW = plot.toolbarAbsoluteDiv.offsetWidth; | |
35475 if (rW >= tW) { | |
35476 plot.toolbar.style.left = leftPos + "px"; | |
35477 plot.toolbar.style.width = (rW + 1) + "px"; | |
35478 plot.toolbarAbsoluteDiv.style.left = ((rW - tW) / 2) + "px"; | |
35479 } else { | |
35480 plot.toolbar.style.left = (pL + plot.leftFlagPos * (pW - tW) / (pW - rW)) + "px"; | |
35481 plot.toolbar.style.width = (tW + 2) + "px"; | |
35482 plot.toolbarAbsoluteDiv.style.left = "0px"; | |
35483 } | |
35484 plot.toolbar.style.top = (top + plot.timeplot.getElement().offsetHeight) + "px"; | |
35485 plot.toolbar.style.visibility = "visible"; | |
35486 plot.toolbarAbsoluteDiv.style.visibility = "visible"; | |
35487 | |
35488 } | |
35489 var getAbsoluteLeft = function(div) { | |
35490 var left = 0; | |
35491 while (div) { | |
35492 left += div.offsetLeft; | |
35493 div = div.offsetParent; | |
35494 } | |
35495 return left; | |
35496 } | |
35497 var timeplotLeft = getAbsoluteLeft(plot.timeplot.getElement()); | |
35498 | |
35499 var checkPolesForStyle = function(x) { | |
35500 if (plot.style == 'bars' && plot.leftFlagTime == plot.rightFlagTime) { | |
35501 var index = plot.tds.getSliceIndex(plot.leftFlagTime); | |
35502 var time1 = plot.leftFlagTime; | |
35503 var pos1 = plot.leftFlagPos; | |
35504 var time2, pos2; | |
35505 if (index == 0) { | |
35506 time2 = plot.tds.getSliceTime(index + 1); | |
35507 } else if (index == plot.tds.getSliceNumber() - 1) { | |
35508 time2 = plot.tds.getSliceTime(index - 1); | |
35509 } else { | |
35510 if (x < plot.leftFlagPos) { | |
35511 time2 = plot.tds.getSliceTime(index - 1); | |
35512 } else { | |
35513 time2 = plot.tds.getSliceTime(index + 1); | |
35514 } | |
35515 } | |
35516 pos2 = plot.timeGeometry.toScreen(time2); | |
35517 mapPositions(pos1, pos2, time1, time2); | |
35518 } | |
35519 } | |
35520 var startX, startY, multiplier; | |
35521 | |
35522 // mousemove function that causes moving selection of objects and toolbar divs | |
35523 var moveToolbar = function(start, actual) { | |
35524 var pixelShift = actual - start; | |
35525 if (plot.status == 2) { | |
35526 var newTime = getCorrelatedTime(startX + pixelShift); | |
35527 if (newTime == plot.mouseTempTime) { | |
35528 return; | |
35529 } | |
35530 plot.mouseTempTime = newTime; | |
35531 plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime); | |
35532 mapPositions(plot.mouseDownPos, plot.mouseTempPos); | |
35533 } else if (plot.status == 3) { | |
35534 pixelShift *= multiplier; | |
35535 var plotPos = actual - timeplotLeft; | |
35536 if (plotPos <= plot.canvas.width / 2) { | |
35537 var newTime = getCorrelatedTime(startX + pixelShift); | |
35538 if (newTime == plot.leftFlagTime) { | |
35539 return; | |
35540 } | |
35541 plot.leftFlagTime = newTime; | |
35542 var diff = plot.leftFlagPos; | |
35543 plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime); | |
35544 diff -= plot.leftFlagPos; | |
35545 plot.rightFlagTime = getCorrelatedTime(plot.rightFlagPos - diff); | |
35546 plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime); | |
35547 } else { | |
35548 var newTime = getCorrelatedTime(startY + pixelShift); | |
35549 if (newTime == plot.rightFlagTime) { | |
35550 return; | |
35551 } | |
35552 plot.rightFlagTime = newTime; | |
35553 var diff = plot.rightFlagPos; | |
35554 plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime); | |
35555 diff -= plot.rightFlagPos; | |
35556 plot.leftFlagTime = getCorrelatedTime(plot.leftFlagPos - diff); | |
35557 plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime); | |
35558 } | |
35559 } | |
35560 checkPolesForStyle(actual - timeplotLeft); | |
35561 setRangeDivs(); | |
35562 plot.timeSelection(); | |
35563 } | |
35564 // fakes user interaction mouse move | |
35565 var playIt = function(start, actual, reset) { | |
35566 if (!plot.paused) { | |
35567 var pixel = plot.canvas.width / (plot.tds.timeSlices.length - 1 ) / 5; | |
35568 var wait = 20 * pixel; | |
35569 if (reset) { | |
35570 actual = 0; | |
35571 } | |
35572 moveToolbar(start, actual); | |
35573 if (plot.rightFlagPos >= plot.canvas.width) { | |
35574 reset = true; | |
35575 wait = 1000; | |
35576 } else { | |
35577 reset = false; | |
35578 } | |
35579 setTimeout(function() { | |
35580 playIt(start, actual + pixel, reset) | |
35581 }, wait); | |
35582 } | |
35583 } | |
35584 var setMultiplier = function() { | |
35585 var rangeWidth = plot.rightFlagPos - plot.leftFlagPos; | |
35586 var toolbarWidth = plot.toolbarAbsoluteDiv.offsetWidth; | |
35587 var plotWidth = plot.canvas.width; | |
35588 if (rangeWidth < toolbarWidth) { | |
35589 multiplier = (plotWidth - rangeWidth) / (plotWidth - toolbarWidth); | |
35590 } else { | |
35591 multiplier = 1; | |
35592 } | |
35593 } | |
35594 /** | |
35595 * starts the animation | |
35596 */ | |
35597 this.play = function() { | |
35598 if (this.leftFlagPos == null) { | |
35599 return; | |
35600 } | |
35601 plot.paused = false; | |
35602 plot.gui.updateAnimationButtons(2); | |
35603 plot.status = 3; | |
35604 setMultiplier(); | |
35605 startX = plot.leftFlagPos; | |
35606 startY = plot.rightFlagPos; | |
35607 var position = Math.round(plot.leftFlagPos); | |
35608 playIt(position, position + 1, false); | |
35609 } | |
35610 /** | |
35611 * stops the animation | |
35612 */ | |
35613 this.stop = function() { | |
35614 plot.paused = true; | |
35615 plot.status = 0; | |
35616 plot.gui.updateAnimationButtons(1); | |
35617 } | |
35618 // triggers the mousemove function to move the range and toolbar | |
35619 var toolbarEvent = function(evt) { | |
35620 var left = GeoTemConfig.getMousePosition(evt).left; | |
35621 document.onmousemove = function(evt) { | |
35622 moveToolbar(left, GeoTemConfig.getMousePosition(evt).left); | |
35623 if (plot.popup) { | |
35624 plot.popup.reset(); | |
35625 } | |
35626 } | |
35627 } | |
35628 var initializeLeft = function() { | |
35629 plot.mouseDownTime = plot.rightFlagTime; | |
35630 plot.mouseTempTime = plot.leftFlagTime; | |
35631 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
35632 startX = plot.leftFlagPos; | |
35633 } | |
35634 var initializeRight = function() { | |
35635 plot.mouseDownTime = plot.leftFlagTime; | |
35636 plot.mouseTempTime = plot.rightFlagTime; | |
35637 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
35638 startX = plot.rightFlagPos; | |
35639 } | |
35640 var initializeDrag = function() { | |
35641 startX = plot.leftFlagPos; | |
35642 startY = plot.rightFlagPos; | |
35643 setMultiplier(); | |
35644 } | |
35645 var checkBorders = function() { | |
35646 if (plot.style == 'bars' && plot.mouseUpTime == plot.mouseDownTime) { | |
35647 var index = plot.tds.getSliceIndex(plot.mouseUpTime); | |
35648 if (index == 0) { | |
35649 plot.mouseUpTime = plot.tds.getSliceTime(index + 1); | |
35650 } else if (index == plot.tds.getSliceNumber() - 1) { | |
35651 plot.mouseUpTime = plot.tds.getSliceTime(index - 1); | |
35652 } else { | |
35653 if (plot.x < plot.leftFlagPos) { | |
35654 plot.mouseUpTime = plot.tds.getSliceTime(index - 1); | |
35655 } else { | |
35656 plot.mouseUpTime = plot.tds.getSliceTime(index + 1); | |
35657 } | |
35658 } | |
35659 } | |
35660 } | |
35661 // handles mousedown on left handle | |
35662 this.leftHandle.onmousedown = function(evt) { | |
35663 if (plot.status != 2) { | |
35664 | |
35665 initializeLeft(); | |
35666 plot.status = 2; | |
35667 toolbarEvent(evt); | |
35668 document.onmouseup = function() { | |
35669 document.onmousemove = null; | |
35670 document.onmouseup = null; | |
35671 plot.stop(); | |
35672 } | |
35673 } | |
35674 } | |
35675 // handles mousedown on right handle | |
35676 this.rightHandle.onmousedown = function(evt) { | |
35677 if (plot.status != 2) { | |
35678 initializeRight(); | |
35679 plot.status = 2; | |
35680 toolbarEvent(evt); | |
35681 document.onmouseup = function() { | |
35682 document.onmousemove = null; | |
35683 document.onmouseup = null; | |
35684 plot.stop(); | |
35685 } | |
35686 } | |
35687 } | |
35688 // handles mousedown on drag button | |
35689 this.dragButton.onmousedown = function(evt) { | |
35690 if (plot.status != 3) { | |
35691 plot.status = 3; | |
35692 initializeDrag(); | |
35693 toolbarEvent(evt); | |
35694 document.onmouseup = function() { | |
35695 document.onmousemove = null; | |
35696 document.onmouseup = null; | |
35697 plot.stop(); | |
35698 } | |
35699 } | |
35700 } | |
35701 // handles mousedown-Event on timeplot | |
35702 var mouseDownHandler = function(elmt, evt, target) { | |
35703 if (plot.dataSources.length > 0) { | |
35704 | |
35705 plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35706 if (plot.status == 0) { | |
35707 var time = getCorrelatedTime(plot.x); | |
35708 if (plot.leftFlagPos != null && plot.popup && time >= plot.leftFlagTime && time <= plot.rightFlagTime) { | |
35709 var x = plot.leftFlagPos + (plot.rightFlagPos - plot.leftFlagPos) / 2; | |
35710 var elements = []; | |
35711 for (var i = 0; i < plot.dataSources.length; i++) { | |
35712 elements.push([]); | |
35713 } | |
35714 for (var i = 0; i < plot.selectedObjects.length; i++) { | |
35715 if (plot.selectedObjects[i].value == 1) { | |
35716 for (var j = 0; j < plot.selectedObjects[i].objects.length; j++) { | |
35717 elements[j] = elements[j].concat(plot.selectedObjects[i].objects[j]); | |
35718 } | |
35719 } | |
35720 } | |
35721 var labels = []; | |
35722 for (var i = 0; i < elements.length; i++) { | |
35723 if (elements[i].length == 0) { | |
35724 continue; | |
35725 } | |
35726 var c = GeoTemConfig.getColor(i); | |
35727 var color = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
35728 var div = document.createElement("div"); | |
35729 div.setAttribute('class', 'tagCloudItem'); | |
35730 div.style.color = color; | |
35731 var label = { | |
35732 div : div, | |
35733 elements : elements[i] | |
35734 }; | |
35735 var weight = 0; | |
35736 for (j in elements[i] ) { | |
35737 weight += elements[i][j].weight; | |
35738 } | |
35739 var fs = 2 * weight / 1000; | |
35740 if (fs > 2) { | |
35741 fs = 2; | |
35742 } | |
35743 div.style.fontSize = (1 + fs) + "em"; | |
35744 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + c.hex; | |
35745 if (weight == 1) { | |
35746 div.innerHTML = weight + " object"; | |
35747 } else { | |
35748 div.innerHTML = weight + " objects"; | |
35749 } | |
35750 var appendMouseFunctions = function(label, div, color) { | |
35751 div.onclick = function() { | |
35752 plot.popup.showLabelContent(label); | |
35753 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color; | |
35754 } | |
35755 div.onmouseover = function() { | |
35756 div.style.textShadow = "0 -1px " + color + ", 1px 0 " + color + ", 0 1px " + color + ", -1px 0 " + color; | |
35757 } | |
35758 div.onmouseout = function() { | |
35759 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color; | |
35760 } | |
35761 } | |
35762 appendMouseFunctions(label, div, c.hex); | |
35763 labels.push(label); | |
35764 } | |
35765 if (labels.length > 0) { | |
35766 plot.popup.createPopup(x + 20, 0, labels); | |
35767 } | |
35768 } else { | |
35769 plot.deselection(); | |
35770 plot.status = 1; | |
35771 plot.mouseDownTime = time; | |
35772 plot.mouseTempTime = plot.mouseDownTime; | |
35773 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
35774 mapPositions(plot.mouseDownPos, plot.mouseDownPos, plot.mouseDownTime, plot.mouseDownTime); | |
35775 // handles mouseup-Event on timeplot | |
35776 document.onmouseup = function() { | |
35777 if (plot.status == 1) { | |
35778 plot.mouseUpTime = plot.mouseTempTime; | |
35779 plot.mouseUpPos = plot.timeGeometry.toScreen(plot.mouseUpTime); | |
35780 mapPositions(plot.mouseDownPos, plot.mouseUpPos, plot.mouseDownTime, plot.mouseUpTime); | |
35781 checkPolesForStyle(plot.x); | |
35782 setRangeDivs(); | |
35783 plot.timeSelection(); | |
35784 plot.gui.updateAnimationButtons(1); | |
35785 document.onmouseup = null; | |
35786 plot.status = 0; | |
35787 } | |
35788 } | |
35789 } | |
35790 } | |
35791 } | |
35792 } | |
35793 // handles mousemove-Event on timeplot | |
35794 var mouseMoveHandler = function(elmt, evt, target) { | |
35795 if (plot.dataSources.length > 0) { | |
35796 plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35797 if (plot.status == 1) { | |
35798 plot.mouseTempTime = getCorrelatedTime(plot.x); | |
35799 plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime); | |
35800 mapPositions(plot.mouseDownPos, plot.mouseTempPos, plot.mouseDownTime, plot.mouseTempTime); | |
35801 checkPolesForStyle(plot.x); | |
35802 setRangeDivs(); | |
35803 } | |
35804 } | |
35805 } | |
35806 // handles mouseout-Event on timeplot | |
35807 var mouseOutHandler = function(elmt, evt, target) { | |
35808 if (plot.dataSources.length > 0) { | |
35809 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35810 var y = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).y); | |
35811 if (x > plot.canvas.width - 2 || isNaN(x) || x < 2) { | |
35812 plot.timeHighlight(true); | |
35813 plot.highlightedSlice = undefined; | |
35814 } else if (y > plot.canvas.height - 2 || isNaN(y) || y < 2) { | |
35815 plot.timeHighlight(true); | |
35816 plot.highlightedSlice = undefined; | |
35817 } | |
35818 } | |
35819 } | |
35820 // handles mouse(h)over-Event on timeplot | |
35821 var mouseHoverHandler = function(elmt, evt, target) { | |
35822 if (plot.dataSources.length > 0) { | |
35823 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35824 var time = getCorrelatedTime(x); | |
35825 if (time == undefined) { | |
35826 return; | |
35827 } | |
35828 var highlightSlice; | |
35829 var slices = plot.tds.timeSlices; | |
35830 var index = plot.tds.getSliceIndex(time); | |
35831 if (plot.style == 'graph') { | |
35832 highlightSlice = slices[index]; | |
35833 } | |
35834 if (plot.style == 'bars') { | |
35835 var pos = plot.timeGeometry.toScreen(time); | |
35836 if (x < pos && index > 0) { | |
35837 highlightSlice = slices[index - 1]; | |
35838 } else { | |
35839 highlightSlice = slices[index]; | |
35840 } | |
35841 } | |
35842 if (plot.highlightedSlice == undefined || plot.highlightedSlice != highlightSlice) { | |
35843 plot.highlightedSlice = highlightSlice; | |
35844 plot.timeHighlight(false); | |
35845 } | |
35846 } | |
35847 } | |
35848 | |
35849 this.redrawPlot = function() { | |
35850 plot.clearTimeplot(); | |
35851 plot.tds.reset(this.timeGeometry); | |
35852 plot.timeplot._prepareCanvas(); | |
35853 plot.timeplot.repaint(); | |
35854 if (plot.leftFlagPos != null) { | |
35855 plot.leftFlagPos = getCorrelatedPosition(plot.leftFlagTime); | |
35856 plot.rightFlagPos = getCorrelatedPosition(plot.rightFlagTime); | |
35857 setRangeDivs(); | |
35858 } else { | |
35859 plot.displayOverlay(); | |
35860 } | |
35861 plot.initLabels([]); | |
35862 plot.updateOverview(); | |
35863 } | |
35864 | |
35865 this.resetOpacityPlots = function() { | |
35866 var plots = plot.timeplot._plots; | |
35867 for ( var i = 0; i < plots.length; i++) { | |
35868 plots[i]._opacityCanvas.width = this.canvas.width; | |
35869 plots[i]._opacityCanvas.height = this.canvas.height; | |
35870 if( plot.leftFlagTime != null ){ | |
35871 plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i)); | |
35872 } | |
35873 } | |
35874 } | |
35875 | |
35876 /** | |
35877 * handles zoom of the timeplot | |
35878 * @param {int} delta the change of zoom | |
35879 * @param {Date} time a time that corresponds to a slice, that was clicked | |
35880 */ | |
35881 /* | |
35882 this.zoom = function(delta,time){ | |
35883 if( this.eventSources.length == 0 ){ | |
35884 if( GeoTemConfig.timeZoom ){ | |
35885 this.zoomSlider.setValue(0); | |
35886 } | |
35887 return false; | |
35888 } | |
35889 if( time == null ){ | |
35890 time = getCorrelatedTime(this.canvas.width/2); | |
35891 } | |
35892 if( this.tds.setZoom(delta,time,this.leftFlagTime,this.rightFlagTime) ){ | |
35893 this.redrawPlot(); | |
35894 } | |
35895 if( GeoTemConfig.timeZoom ){ | |
35896 this.zoomSlider.setValue(this.tds.getZoom()); | |
35897 } | |
35898 return true; | |
35899 } | |
35900 */ | |
35901 | |
35902 // handles mousewheel event on the timeplot | |
35903 var mouseWheelHandler = function(elmt, evt, target) { | |
35904 if (evt.preventDefault) { | |
35905 evt.preventDefault(); | |
35906 } | |
35907 if (plot.dataSources.length == 0) { | |
35908 return; | |
35909 } | |
35910 var delta = 0; | |
35911 if (!evt) | |
35912 evt = window.event; | |
35913 if (evt.wheelDelta) { | |
35914 delta = evt.wheelDelta / 120; | |
35915 if (window.opera) | |
35916 delta = -delta; | |
35917 } else if (evt.detail) { | |
35918 delta = -evt.detail / 3; | |
35919 } | |
35920 if (delta) { | |
35921 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35922 var time = getCorrelatedTime(x); | |
35923 plot.zoom(delta, time); | |
35924 } | |
35925 } | |
35926 var timeplotElement = this.timeplot.getElement(); | |
35927 SimileAjax.DOM.registerEvent(timeplotElement, "mousedown", mouseDownHandler); | |
35928 SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler); | |
35929 SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseHoverHandler); | |
35930 SimileAjax.DOM.registerEvent(timeplotElement, "mouseout", mouseOutHandler); | |
35931 if (GeoTemConfig.mouseWheelZoom) { | |
35932 //SimileAjax.DOM.registerEvent(timeplotElement, "mousewheel", mouseWheelHandler); | |
35933 } | |
35934 | |
35935 this.gui.setHeight(); | |
35936 | |
35937 }, | |
35938 | |
35939 resetOverlay : function() { | |
35940 this.poles.style.visibility = "hidden"; | |
35941 var plots = this.timeplot._plots; | |
35942 for (var i = 0; i < plots.length; i++) { | |
35943 for (var j = 0; j < plots[i].pins.length; j++) { | |
35944 plots[i].pins[j] = { | |
35945 height : 0, | |
35946 count : 0 | |
35947 }; | |
35948 } | |
35949 } | |
35950 }, | |
35951 | |
35952 /** | |
35953 * resets the timeplot to non selection status | |
35954 */ | |
35955 reset : function() { | |
35956 | |
35957 this.leftFlagPole.style.visibility = "hidden"; | |
35958 this.rightFlagPole.style.visibility = "hidden"; | |
35959 this.rangeBox.style.visibility = "hidden"; | |
35960 this.leftHandle.style.visibility = "hidden"; | |
35961 this.rightHandle.style.visibility = "hidden"; | |
35962 this.toolbar.style.visibility = "hidden"; | |
35963 this.toolbarAbsoluteDiv.style.visibility = "hidden"; | |
35964 this.cancelButton.style.visibility = "hidden"; | |
35965 | |
35966 var plots = this.timeplot._plots; | |
35967 for (var i = 0; i < plots.length; i++) { | |
35968 plots[i].opacityPlot.style.visibility = "hidden"; | |
35969 } | |
35970 this.resetOverlay(); | |
35971 this.filterBar.reset(false); | |
35972 | |
35973 var slices = this.tds.timeSlices; | |
35974 if (slices != undefined) { | |
35975 for (var i = 0; i < slices.length; i++) { | |
35976 slices[i].reset(); | |
35977 } | |
35978 } | |
35979 | |
35980 this.status = 0; | |
35981 this.stop(); | |
35982 this.gui.updateAnimationButtons(0); | |
35983 | |
35984 this.leftFlagPos = null; | |
35985 this.leftFlagTime = null; | |
35986 this.rightFlagPos = null; | |
35987 this.rightFlagTime = null; | |
35988 | |
35989 this.mouseDownTime = null; | |
35990 this.mouseUpTime = null; | |
35991 this.mouseTempTime = null; | |
35992 | |
35993 this.mouseDownPos = null; | |
35994 this.mouseUpPos = null; | |
35995 this.mouseTempPos = null; | |
35996 | |
35997 if (this.popup) { | |
35998 this.popup.reset(); | |
35999 this.popupClickDiv.style.visibility = "hidden"; | |
36000 } | |
36001 | |
36002 }, | |
36003 | |
36004 /** | |
36005 * sets a pole on the timeplot | |
36006 * @param {Date} time the time of the specific timeslice | |
36007 * @param {int[]} the number of selected elements per dataset | |
36008 */ | |
36009 displayOverlay : function() { | |
36010 this.poles.style.visibility = "visible"; | |
36011 var cv = this.poles.getElementsByTagName("canvas")[0]; | |
36012 cv.width = this.canvas.width; | |
36013 cv.height = this.canvas.height; | |
36014 if (!cv.getContext && G_vmlCanvasManager) { | |
36015 cv = G_vmlCanvasManager.initElement(cv); | |
36016 } | |
36017 var ctx = cv.getContext('2d'); | |
36018 ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | |
36019 var plots = this.timeplot._plots; | |
36020 var slices = this.tds.timeSlices; | |
36021 for (var i = 0; i < slices.length; i++) { | |
36022 if (this.style == 'bars' && i + 1 == slices.length) { | |
36023 return; | |
36024 } | |
36025 if (slices[i].overlay() == 0) { | |
36026 continue; | |
36027 } | |
36028 var projStacks = slices[i].projStacks; | |
36029 var time = slices[i].date; | |
36030 var pos; | |
36031 if (this.style == 'graph') { | |
36032 pos = this.timeGeometry.toScreen(time); | |
36033 } else if (this.style == 'bars') { | |
36034 var x1 = this.timeGeometry.toScreen(time); | |
36035 var x2 = this.timeGeometry.toScreen(slices[i + 1].date); | |
36036 pos = (x1 + x2 ) / 2; | |
36037 } | |
36038 var heights = []; | |
36039 var h = 0; | |
36040 for (var j = 0; j < projStacks.length; j++) { | |
36041 var data = plots[j]._dataSource.getData(); | |
36042 for (var k = 0; k < data.times.length; k++) { | |
36043 if (data.times[k].getTime() == time.getTime()) { | |
36044 var height = plots[j]._valueGeometry.toScreen(plots[j]._dataSource.getData().values[k]) * projStacks[j].overlay / projStacks[j].value; | |
36045 heights.push(height); | |
36046 plots[j].pins[i] = { | |
36047 height : height, | |
36048 count : projStacks[j].overlay | |
36049 }; | |
36050 if (height > h) { | |
36051 h = height; | |
36052 } | |
36053 break; | |
36054 } | |
36055 } | |
36056 } | |
36057 ctx.fillStyle = "rgb(102,102,102)"; | |
36058 ctx.beginPath(); | |
36059 ctx.rect(pos - 1, this.canvas.height - h, 2, h); | |
36060 ctx.fill(); | |
36061 for (var j = 0; j < heights.length; j++) { | |
36062 if (heights[j] > 0) { | |
36063 var color = GeoTemConfig.getColor(j); | |
36064 ctx.fillStyle = "rgba(" + color.r1 + "," + color.g1 + "," + color.b1 + ",0.6)"; | |
36065 ctx.beginPath(); | |
36066 ctx.arc(pos, this.canvas.height - heights[j], 2.5, 0, Math.PI * 2, true); | |
36067 ctx.closePath(); | |
36068 ctx.fill(); | |
36069 } | |
36070 } | |
36071 } | |
36072 }, | |
36073 | |
36074 /** | |
36075 * updates the timeplot by displaying place poles, after a selection had been executed in another widget | |
36076 */ | |
36077 highlightChanged : function(timeObjects) { | |
36078 if( !GeoTemConfig.highlightEvents ){ | |
36079 return; | |
36080 } | |
36081 this.resetOverlay(); | |
36082 if (this.selection.valid()) { | |
36083 if (!this.selection.equal(this)) { | |
36084 this.tds.setOverlay(GeoTemConfig.mergeObjects(timeObjects, this.selection.getObjects(this))); | |
36085 } else { | |
36086 this.tds.setOverlay(timeObjects); | |
36087 } | |
36088 } else { | |
36089 this.tds.setOverlay(timeObjects); | |
36090 } | |
36091 this.displayOverlay(); | |
36092 }, | |
36093 | |
36094 /** | |
36095 * updates the timeplot by displaying place poles, after a selection had been executed in another widget | |
36096 */ | |
36097 selectionChanged : function(selection) { | |
36098 if( !GeoTemConfig.selectionEvents ){ | |
36099 return; | |
36100 } | |
36101 this.reset(); | |
36102 this.selection = selection; | |
36103 this.tds.setOverlay(selection.objects); | |
36104 this.displayOverlay(); | |
36105 }, | |
36106 | |
36107 /** | |
36108 * returns the approximate left position of a slice inside the overview representation | |
36109 * @param {Date} time time of the slice | |
36110 */ | |
36111 getOverviewLeft : function(time) { | |
36112 var w = this.overview.offsetWidth; | |
36113 var s = this.tds.earliest().getTime(); | |
36114 var e = this.tds.latest().getTime(); | |
36115 var t = time.getTime(); | |
36116 return Math.round(w * (t - s) / (e - s)); | |
36117 }, | |
36118 | |
36119 /** | |
36120 * visualizes the overview div (shows viewable part of zoomed timeplot) | |
36121 */ | |
36122 initOverview : function() { | |
36123 var labels = this.timeGeometry._grid; | |
36124 if (labels.length == 0) { | |
36125 var plot = this; | |
36126 setTimeout(function() { | |
36127 plot.initOverview(); | |
36128 }, 10); | |
36129 return; | |
36130 } | |
36131 | |
36132 this.overview.style.width = this.canvas.width + "px"; | |
36133 var left = this.gui.timeplotDiv.offsetLeft; | |
36134 this.overview.innerHTML = ""; | |
36135 this.overview.style.left = left + "px"; | |
36136 | |
36137 this.overviewRange = document.createElement("div"); | |
36138 this.overviewRange.setAttribute('class', 'overviewRange'); | |
36139 this.overview.appendChild(this.overviewRange); | |
36140 | |
36141 for (var i = 0; i < labels.length; i++) { | |
36142 var label = document.createElement("div"); | |
36143 label.setAttribute('class', 'overviewLabel'); | |
36144 label.innerHTML = labels[i].label; | |
36145 label.style.left = Math.floor(labels[i].x) + "px"; | |
36146 this.overview.appendChild(label); | |
36147 } | |
36148 | |
36149 this.updateOverview(); | |
36150 }, | |
36151 | |
36152 /** | |
36153 * visualizes the labels of the timeplot | |
36154 */ | |
36155 initLabels : function(labels) { | |
36156 if (labels.length == 0) { | |
36157 labels = this.timeGeometry._grid; | |
36158 if (labels.length == 0) { | |
36159 var plot = this; | |
36160 setTimeout(function() { | |
36161 plot.initLabels([]); | |
36162 }, 10); | |
36163 return; | |
36164 } | |
36165 } | |
36166 this.plotLabels.style.width = this.canvas.width + "px"; | |
36167 var left = this.gui.timeplotDiv.offsetLeft; | |
36168 this.plotLabels.style.left = left + "px"; | |
36169 this.plotLabels.innerHTML = ""; | |
36170 for (var i = 0; i < labels.length; i++) { | |
36171 var label = document.createElement("div"); | |
36172 label.setAttribute('class', 'plotLabel'); | |
36173 label.innerHTML = labels[i].label; | |
36174 label.style.left = Math.floor(labels[i].x) + "px"; | |
36175 this.plotLabels.appendChild(label); | |
36176 } | |
36177 }, | |
36178 | |
36179 /** | |
36180 * updates the overview div | |
36181 */ | |
36182 updateOverview : function() { | |
36183 if (this.tds.getZoom() > 0) { | |
36184 this.plotLabels.style.visibility = "hidden"; | |
36185 this.timeGeometry._hideLabels = false; | |
36186 this.overview.style.visibility = "visible"; | |
36187 this.shiftLeft.style.visibility = "visible"; | |
36188 this.shiftRight.style.visibility = "visible"; | |
36189 var left = this.getOverviewLeft(this.tds.timeSlices[this.tds.leftSlice].date); | |
36190 var right = this.getOverviewLeft(this.tds.timeSlices[this.tds.rightSlice].date); | |
36191 this.overviewRange.style.left = left + "px"; | |
36192 this.overviewRange.style.width = (right - left) + "px"; | |
36193 } else { | |
36194 this.timeGeometry._hideLabels = true; | |
36195 this.plotLabels.style.visibility = "visible"; | |
36196 this.overview.style.visibility = "hidden"; | |
36197 this.shiftLeft.style.visibility = "hidden"; | |
36198 this.shiftRight.style.visibility = "hidden"; | |
36199 } | |
36200 }, | |
36201 | |
36202 /** | |
36203 * returns the time slices which are created by the extended data source | |
36204 */ | |
36205 getSlices : function() { | |
36206 return this.tds.timeSlices; | |
36207 }, | |
36208 | |
36209 timeSelection : function() { | |
36210 var slices = this.tds.timeSlices; | |
36211 var ls, rs; | |
36212 for (var i = 0; i < slices.length; i++) { | |
36213 if (slices[i].date.getTime() == this.leftFlagTime.getTime()) | |
36214 ls = i; | |
36215 if (slices[i].date.getTime() == this.rightFlagTime.getTime()) { | |
36216 if (this.style == 'graph') { | |
36217 rs = i; | |
36218 } | |
36219 if (this.style == 'bars') { | |
36220 rs = i - 1; | |
36221 } | |
36222 } | |
36223 } | |
36224 var selectedObjects = []; | |
36225 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36226 selectedObjects.push([]); | |
36227 } | |
36228 for (var i = 0; i < slices.length; i++) { | |
36229 if (i >= ls && i <= rs) { | |
36230 for (var j in slices[i].stacks ) { | |
36231 selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements); | |
36232 } | |
36233 } | |
36234 } | |
36235 this.selection = new Selection(selectedObjects, this); | |
36236 this.core.triggerSelection(this.selection); | |
36237 this.filterBar.reset(true); | |
36238 }, | |
36239 | |
36240 deselection : function() { | |
36241 this.reset(); | |
36242 this.selection = new Selection(); | |
36243 this.core.triggerSelection(this.selection); | |
36244 }, | |
36245 | |
36246 filtering : function() { | |
36247 for (var i = 0; i < this.datasets.length; i++) { | |
36248 this.datasets[i].objects = this.selection.objects[i]; | |
36249 } | |
36250 this.core.triggerRefining(this.datasets); | |
36251 }, | |
36252 | |
36253 inverseFiltering : function() { | |
36254 var slices = this.tds.timeSlices; | |
36255 var ls, rs; | |
36256 for (var i = 0; i < slices.length; i++) { | |
36257 if (slices[i].date.getTime() == this.leftFlagTime.getTime()) | |
36258 ls = i; | |
36259 if (slices[i].date.getTime() == this.rightFlagTime.getTime()) { | |
36260 if (this.style == 'graph') { | |
36261 rs = i; | |
36262 } | |
36263 if (this.style == 'bars') { | |
36264 rs = i - 1; | |
36265 } | |
36266 } | |
36267 } | |
36268 var selectedObjects = []; | |
36269 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36270 selectedObjects.push([]); | |
36271 } | |
36272 for (var i = 0; i < slices.length; i++) { | |
36273 if (i >= ls && i <= rs) { | |
36274 continue; | |
36275 } | |
36276 for (var j in slices[i].stacks ) { | |
36277 selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements); | |
36278 } | |
36279 } | |
36280 this.selection = new Selection(selectedObjects, this); | |
36281 this.filtering(); | |
36282 }, | |
36283 | |
36284 timeHighlight : function(undo) { | |
36285 if (this.status == 0) { | |
36286 var s = this.highlightedSlice; | |
36287 var timeObjects = []; | |
36288 for (var i = 0; i < this.tds.size(); i++) { | |
36289 timeObjects.push([]); | |
36290 } | |
36291 var add = true; | |
36292 if (this.leftFlagTime != null) { | |
36293 if (this.style == 'graph' && s.date >= this.leftFlagTime && s.date <= this.rightFlagTime) { | |
36294 add = false; | |
36295 } | |
36296 if (this.style == 'bars' && s.date >= this.leftFlagTime && s.date < this.rightFlagTime) { | |
36297 add = false; | |
36298 } | |
36299 } | |
36300 if (!undo && add) { | |
36301 for (var i in s.stacks ) { | |
36302 timeObjects[i] = timeObjects[i].concat(s.stacks[i].elements); | |
36303 } | |
36304 } | |
36305 this.core.triggerHighlight(timeObjects); | |
36306 } | |
36307 }, | |
36308 | |
36309 timeRefining : function() { | |
36310 this.core.triggerRefining(this.selection.objects); | |
36311 }, | |
36312 | |
36313 setStyle : function(style) { | |
36314 this.style = style; | |
36315 }, | |
36316 | |
36317 drawLinearPlot : function() { | |
36318 if ( typeof this.valueGeometry != 'undefined') { | |
36319 this.valueGeometry.actLinear(); | |
36320 this.timeplot.repaint(); | |
36321 this.resetOpacityPlots(); | |
36322 this.displayOverlay(); | |
36323 } | |
36324 }, | |
36325 | |
36326 drawLogarithmicPlot : function() { | |
36327 if ( typeof this.valueGeometry != 'undefined') { | |
36328 this.valueGeometry.actLogarithmic(); | |
36329 this.timeplot.repaint(); | |
36330 this.resetOpacityPlots(); | |
36331 this.displayOverlay(); | |
36332 } | |
36333 } | |
36334 } | |
36335 /* | |
36336 * TableConfig.js | |
36337 * | |
36338 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
36339 * | |
36340 * This library is free software; you can redistribute it and/or | |
36341 * modify it under the terms of the GNU Lesser General Public | |
36342 * License as published by the Free Software Foundation; either | |
36343 * version 3 of the License, or (at your option) any later version. | |
36344 * | |
36345 * This library is distributed in the hope that it will be useful, | |
36346 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36347 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36348 * Lesser General Public License for more details. | |
36349 * | |
36350 * You should have received a copy of the GNU Lesser General Public | |
36351 * License along with this library; if not, write to the Free Software | |
36352 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
36353 * MA 02110-1301 USA | |
36354 */ | |
36355 | |
36356 /** | |
36357 * @class TableConfig | |
36358 * Table Configuration File | |
36359 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
36360 * @release 1.0 | |
36361 * @release date: 2012-07-27 | |
36362 * @version date: 2012-07-27 | |
36363 */ | |
36364 function TableConfig(options) { | |
36365 | |
36366 this.options = { | |
36367 tableWidth : false, // false or desired width css definition for the table | |
36368 tableHeight : false, // false or desired height css definition for the table | |
36369 validResultsPerPage : [10, 20, 50, 100], // valid number of elements per page | |
36370 initialResultsPerPage : 10, // initial number of elements per page | |
36371 tableSorting : true, // true, if sorting of columns should be possible | |
36372 tableContentOffset : 250, // maximum display number of characters in a table cell | |
36373 tableSelectPage : true, // selection of complete table pages | |
36374 tableSelectAll : false, // selection of complete tables | |
36375 tableShowSelected : true, // show selected objects only option | |
36376 tableKeepShowSelected : true, // don't revert to show all on "reset" (e.g. selection) | |
36377 tableInvertSelection : true, // show invert selection option | |
36378 tableSelectByText : true, // select objects by full-text search | |
36379 tableCreateNewFromSelected : true, // create new dataset from selected objects | |
36380 unselectedCellColor : '#EEE', // color for an unselected row/tab | |
36381 verticalAlign : 'top', // vertical alignment of the table cells ('top','center','bottom') | |
36382 }; | |
36383 if ( typeof options != 'undefined') { | |
36384 $.extend(this.options, options); | |
36385 } | |
36386 | |
36387 }; | |
36388 /* | |
36389 * TableGui.js | |
36390 * | |
36391 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
36392 * | |
36393 * This library is free software; you can redistribute it and/or | |
36394 * modify it under the terms of the GNU Lesser General Public | |
36395 * License as published by the Free Software Foundation; either | |
36396 * version 3 of the License, or (at your option) any later version. | |
36397 * | |
36398 * This library is distributed in the hope that it will be useful, | |
36399 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36400 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36401 * Lesser General Public License for more details. | |
36402 * | |
36403 * You should have received a copy of the GNU Lesser General Public | |
36404 * License along with this library; if not, write to the Free Software | |
36405 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
36406 * MA 02110-1301 USA | |
36407 */ | |
36408 | |
36409 /** | |
36410 * @class TableGui | |
36411 * Table GUI Implementation | |
36412 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
36413 * @release 1.0 | |
36414 * @release date: 2012-07-27 | |
36415 * @version date: 2012-07-27 | |
36416 * | |
36417 * @param {TableWidget} parent table widget object | |
36418 * @param {HTML object} div parent div to append the table gui | |
36419 * @param {JSON} options table configuration | |
36420 */ | |
36421 function TableGui(table, div, options) { | |
36422 | |
36423 this.tableContainer = div; | |
36424 if (options.tableWidth) { | |
36425 this.tableContainer.style.width = options.tableWidth; | |
36426 } | |
36427 if (options.tableHeight) { | |
36428 this.tableContainer.style.height = options.tableHeight; | |
36429 } | |
36430 this.tableContainer.style.position = 'relative'; | |
36431 | |
36432 this.tabs = document.createElement('div'); | |
36433 this.tabs.setAttribute('class', 'tableTabs'); | |
36434 div.appendChild(this.tabs); | |
36435 | |
36436 this.input = document.createElement('div'); | |
36437 this.input.setAttribute('class', 'tableInput'); | |
36438 div.appendChild(this.input); | |
36439 | |
36440 }; | |
36441 /* | |
36442 * TableWidget.js | |
36443 * | |
36444 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
36445 * | |
36446 * This library is free software; you can redistribute it and/or | |
36447 * modify it under the terms of the GNU Lesser General Public | |
36448 * License as published by the Free Software Foundation; either | |
36449 * version 3 of the License, or (at your option) any later version. | |
36450 * | |
36451 * This library is distributed in the hope that it will be useful, | |
36452 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36453 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36454 * Lesser General Public License for more details. | |
36455 * | |
36456 * You should have received a copy of the GNU Lesser General Public | |
36457 * License along with this library; if not, write to the Free Software | |
36458 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
36459 * MA 02110-1301 USA | |
36460 */ | |
36461 | |
36462 /** | |
36463 * @class TableWidget | |
36464 * TableWidget Implementation | |
36465 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
36466 * @release 1.0 | |
36467 * @release date: 2012-07-27 | |
36468 * @version date: 2012-07-27 | |
36469 * | |
36470 * @param {TableWrapper} core wrapper for interaction to other widgets | |
36471 * @param {HTML object} div parent div to append the table widget div | |
36472 * @param {JSON} options user specified configuration that overwrites options in TableConfig.js | |
36473 */ | |
36474 TableWidget = function(core, div, options) { | |
36475 | |
36476 this.core = core; | |
36477 this.core.setWidget(this); | |
36478 this.tables = []; | |
36479 this.tableTabs = []; | |
36480 this.tableElements = []; | |
36481 this.tableHash = []; | |
36482 | |
36483 this.options = (new TableConfig(options)).options; | |
36484 this.gui = new TableGui(this, div, this.options); | |
36485 this.filterBar = new FilterBar(this); | |
36486 | |
36487 } | |
36488 | |
36489 TableWidget.prototype = { | |
36490 | |
36491 initWidget : function(data) { | |
36492 this.datasets = data; | |
36493 | |
36494 $(this.gui.tabs).empty(); | |
36495 $(this.gui.input).empty(); | |
36496 this.activeTable = undefined; | |
36497 this.tables = []; | |
36498 this.tableTabs = []; | |
36499 this.tableElements = []; | |
36500 this.tableHash = []; | |
36501 this.selection = new Selection(); | |
36502 this.filterBar.reset(false); | |
36503 | |
36504 var tableWidget = this; | |
36505 var addTab = function(name, index) { | |
36506 var dataSet = GeoTemConfig.datasets[index]; | |
36507 var tableTab = document.createElement('div'); | |
36508 var tableTabTable = document.createElement('table'); | |
36509 $(tableTab).append(tableTabTable); | |
36510 var tableTabTableRow = document.createElement('tr'); | |
36511 $(tableTabTable).append(tableTabTableRow); | |
36512 tableTab.setAttribute('class', 'tableTab'); | |
36513 var c = GeoTemConfig.getColor(index); | |
36514 tableTab.style.backgroundColor = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
36515 tableTab.onclick = function() { | |
36516 tableWidget.selectTable(index); | |
36517 } | |
36518 var tableNameDiv = document.createElement('div'); | |
36519 $(tableNameDiv).append(name); | |
36520 | |
36521 if (typeof dataSet.url !== "undefined"){ | |
36522 var tableLinkDiv = document.createElement('a'); | |
36523 tableLinkDiv.title = dataSet.url; | |
36524 tableLinkDiv.href = dataSet.url; | |
36525 tableLinkDiv.target = '_'; | |
36526 tableLinkDiv.setAttribute('class', 'externalLink'); | |
36527 $(tableNameDiv).append(tableLinkDiv); | |
36528 } | |
36529 $(tableTabTableRow).append($(document.createElement('td')).append(tableNameDiv)); | |
36530 | |
36531 var removeTabDiv = document.createElement('div'); | |
36532 removeTabDiv.setAttribute('class', 'smallButton removeDataset'); | |
36533 removeTabDiv.title = GeoTemConfig.getString('removeDatasetHelp'); | |
36534 removeTabDiv.onclick = $.proxy(function(e) { | |
36535 GeoTemConfig.removeDataset(index); | |
36536 //don't let the event propagate to the DIV above | |
36537 e.stopPropagation(); | |
36538 //discard link click | |
36539 return(false); | |
36540 },{index:index}); | |
36541 $(tableTabTableRow).append($(document.createElement('td')).append(removeTabDiv)); | |
36542 | |
36543 if (GeoTemConfig.tableExportDataset){ | |
36544 var exportTabDiv = document.createElement('div'); | |
36545 exportTabDiv.setAttribute('class', 'smallButton exportDataset'); | |
36546 exportTabDiv.title = GeoTemConfig.getString('exportDatasetHelp'); | |
36547 var exportTabForm = document.createElement('form'); | |
36548 //TODO: make this configurable | |
36549 exportTabForm.action = 'php/download.php'; | |
36550 exportTabForm.method = 'post'; | |
36551 var exportTabHiddenValue = document.createElement('input'); | |
36552 exportTabHiddenValue.name = 'file'; | |
36553 exportTabHiddenValue.type = 'hidden'; | |
36554 exportTabForm.appendChild(exportTabHiddenValue); | |
36555 exportTabDiv.onclick = $.proxy(function(e) { | |
36556 $(exportTabHiddenValue).val(GeoTemConfig.createKMLfromDataset(index)); | |
36557 $(exportTabForm).submit(); | |
36558 //don't let the event propagate to the DIV | |
36559 e.stopPropagation(); | |
36560 //discard link click | |
36561 return(false); | |
36562 },{index:index}); | |
36563 exportTabDiv.appendChild(exportTabForm); | |
36564 $(tableTabTableRow).append($(document.createElement('td')).append(exportTabDiv)); | |
36565 } | |
36566 | |
36567 if (GeoTemConfig.allowUserShapeAndColorChange){ | |
36568 var dataset = GeoTemConfig.datasets[index]; | |
36569 | |
36570 var changeColorShapeSelect = $("<select></select>"); | |
36571 changeColorShapeSelect.attr("title", GeoTemConfig.getString("colorShapeDatasetHelp")); | |
36572 changeColorShapeSelect.css("font-size","1.5em"); | |
36573 | |
36574 var currentOptgroup = $("<optgroup label='Current'></optgroup>"); | |
36575 var currentOption = $("<option value='current'></option>"); | |
36576 var color = GeoTemConfig.getColor(index); | |
36577 currentOption.css("color","rgb("+color.r1+","+color.g1+","+color.b1+")"); | |
36578 currentOption.data("color",{r1:color.r1,g1:color.g1,b1:color.b1,r0:color.r0,g0:color.g0,b0:color.b0}); | |
36579 if (dataset.graphic.shape=="circle"){ | |
36580 currentOption.append("●"); | |
36581 } else if (dataset.graphic.shape=="triangel"){ | |
36582 currentOption.append("▲"); | |
36583 } else if (dataset.graphic.shape=="square"){ | |
36584 if (dataset.graphic.rotation===0){ | |
36585 currentOption.append("■"); | |
36586 } else { | |
36587 currentOption.append("◆"); | |
36588 } | |
36589 } | |
36590 currentOptgroup.append(currentOption); | |
36591 changeColorShapeSelect.append(currentOptgroup); | |
36592 | |
36593 var defaultOptgroup = $("<optgroup label='Default'></optgroup>"); | |
36594 var defaultOption = $("<option value='default'></option>"); | |
36595 var color = GeoTemConfig.colors[index]; | |
36596 defaultOption.css("color","rgb("+color.r1+","+color.g1+","+color.b1+")"); | |
36597 defaultOption.data("color",{r1:color.r1,g1:color.g1,b1:color.b1,r0:color.r0,g0:color.g0,b0:color.b0}); | |
36598 defaultOption.append("●"); | |
36599 defaultOptgroup.append(defaultOption); | |
36600 changeColorShapeSelect.append(defaultOptgroup); | |
36601 | |
36602 var shapeOptgroup = $("<optgroup label='Shapes'></optgroup>"); | |
36603 shapeOptgroup.append("<option>○</option>"); | |
36604 shapeOptgroup.append("<option>□</option>"); | |
36605 shapeOptgroup.append("<option>◇</option>"); | |
36606 shapeOptgroup.append("<option>△</option>"); | |
36607 changeColorShapeSelect.append(shapeOptgroup); | |
36608 | |
36609 var colorOptgroup = $("<optgroup label='Colors'></optgroup>"); | |
36610 var red = $("<option style='color:red'>■</option>"); | |
36611 red.data("color",{r1:255,g1:0,b1:0}); | |
36612 colorOptgroup.append(red); | |
36613 var green = $("<option style='color:green'>■</option>"); | |
36614 green.data("color",{r1:0,g1:255,b1:0}); | |
36615 colorOptgroup.append(green); | |
36616 var blue = $("<option style='color:blue'>■</option>"); | |
36617 blue.data("color",{r1:0,g1:0,b1:255}); | |
36618 colorOptgroup.append(blue); | |
36619 var yellow = $("<option style='color:yellow'>■</option>"); | |
36620 yellow.data("color",{r1:255,g1:255,b1:0}); | |
36621 colorOptgroup.append(yellow); | |
36622 changeColorShapeSelect.append(colorOptgroup); | |
36623 | |
36624 changeColorShapeSelect.change($.proxy(function(e) { | |
36625 var selected = changeColorShapeSelect.find("option:selected"); | |
36626 | |
36627 //credits: Pimp Trizkit @ http://stackoverflow.com/a/13542669 | |
36628 function shadeRGBColor(color, percent) { | |
36629 var f=color.split(","),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=parseInt(f[0].slice(4)),G=parseInt(f[1]),B=parseInt(f[2]); | |
36630 return "rgb("+(Math.round((t-R)*p)+R)+","+(Math.round((t-G)*p)+G)+","+(Math.round((t-B)*p)+B)+")"; | |
36631 } | |
36632 | |
36633 var color = selected.data("color"); | |
36634 | |
36635 if (typeof color !== "undefined"){ | |
36636 if ( (typeof color.r0 === "undefined") || | |
36637 (typeof color.g0 === "undefined") || | |
36638 (typeof color.b0 === "undefined") ){ | |
36639 var shadedrgb = shadeRGBColor("rgb("+color.r1+","+color.g1+","+color.b1+")",0.7); | |
36640 shadedrgb = shadedrgb.replace("rgb(","").replace(")",""); | |
36641 shadedrgb = shadedrgb.split(","); | |
36642 | |
36643 color.r0 = parseInt(shadedrgb[0]); | |
36644 color.g0 = parseInt(shadedrgb[1]); | |
36645 color.b0 = parseInt(shadedrgb[2]); | |
36646 } | |
36647 } | |
36648 | |
36649 var shapeText = selected.text(); | |
36650 var graphic; | |
36651 if ((shapeText=="■") || (shapeText=="□")){ | |
36652 graphic = { | |
36653 shape: "square", | |
36654 rotation: 0 | |
36655 }; | |
36656 } else if ((shapeText=="●") || (shapeText=="○")){ | |
36657 graphic = { | |
36658 shape: "circle", | |
36659 rotation: 0 | |
36660 }; | |
36661 } else if ((shapeText=="◆") || (shapeText=="◇")){ | |
36662 graphic = { | |
36663 shape: "square", | |
36664 rotation: 45 | |
36665 }; | |
36666 } else if ((shapeText=="▲") || (shapeText=="△")){ | |
36667 graphic = { | |
36668 shape: "triangle", | |
36669 rotation: 0 | |
36670 }; | |
36671 } | |
36672 | |
36673 if (shapeOptgroup.has(selected).length>0){ | |
36674 //shape change | |
36675 dataset.graphic = graphic; | |
36676 } else if (colorOptgroup.has(selected).length>0){ | |
36677 //color changed | |
36678 dataset.color = color; | |
36679 } else { | |
36680 //back to default | |
36681 dataset.graphic = graphic; | |
36682 dataset.color = color; | |
36683 } | |
36684 | |
36685 //reload data | |
36686 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
36687 | |
36688 //don't let the event propagate to the DIV | |
36689 e.stopPropagation(); | |
36690 //discard link click | |
36691 return(false); | |
36692 },{index:index})); | |
36693 $(tableTabTableRow).append($(document.createElement('td')).append(changeColorShapeSelect)); | |
36694 } | |
36695 | |
36696 return tableTab; | |
36697 } | |
36698 tableWidget.addTab = addTab; | |
36699 | |
36700 for (var i in data ) { | |
36701 this.tableHash.push([]); | |
36702 var tableTab = addTab(data[i].label, i); | |
36703 this.gui.tabs.appendChild(tableTab); | |
36704 this.tableTabs.push(tableTab); | |
36705 var elements = []; | |
36706 for (var j in data[i].objects ) { | |
36707 elements.push(new TableElement(data[i].objects[j])); | |
36708 this.tableHash[i][data[i].objects[j].index] = elements[elements.length - 1]; | |
36709 } | |
36710 var table = new Table(elements, this, i); | |
36711 this.tables.push(table); | |
36712 this.tableElements.push(elements); | |
36713 } | |
36714 | |
36715 if (data.length > 0) { | |
36716 this.selectTable(0); | |
36717 } | |
36718 | |
36719 }, | |
36720 | |
36721 getHeight : function() { | |
36722 if (this.options.tableHeight) { | |
36723 return this.gui.tableContainer.offsetHeight - this.gui.tabs.offsetHeight; | |
36724 } | |
36725 return false; | |
36726 }, | |
36727 | |
36728 selectTable : function(index) { | |
36729 if (this.activeTable != index) { | |
36730 if ( typeof this.activeTable != 'undefined') { | |
36731 this.tables[this.activeTable].hide(); | |
36732 var c = GeoTemConfig.getColor(this.activeTable); | |
36733 this.tableTabs[this.activeTable].style.backgroundColor = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
36734 this.tableTabs[this.activeTable].style.paddingBottom = '5px'; | |
36735 } | |
36736 this.activeTable = index; | |
36737 this.tables[this.activeTable].show(); | |
36738 var c = GeoTemConfig.getColor(this.activeTable); | |
36739 this.tableTabs[this.activeTable].style.backgroundColor = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
36740 this.tableTabs[this.activeTable].style.paddingBottom = '8px'; | |
36741 this.gui.tabs.style.borderBottom = '6px solid rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
36742 this.core.triggerRise(index); | |
36743 } | |
36744 | |
36745 }, | |
36746 | |
36747 highlightChanged : function(objects) { | |
36748 if( !GeoTemConfig.highlightEvents || (typeof this.tables[this.activeTable] === "undefined")){ | |
36749 return; | |
36750 } | |
36751 if( this.tables.length > 0 ){ | |
36752 return; | |
36753 } | |
36754 for (var i = 0; i < this.tableElements.length; i++) { | |
36755 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36756 this.tableElements[i][j].highlighted = false; | |
36757 } | |
36758 } | |
36759 for (var i = 0; i < objects.length; i++) { | |
36760 for (var j = 0; j < objects[i].length; j++) { | |
36761 this.tableHash[i][objects[i][j].index].highlighted = true; | |
36762 } | |
36763 } | |
36764 this.tables[this.activeTable].update(); | |
36765 }, | |
36766 | |
36767 selectionChanged : function(selection) { | |
36768 if( !GeoTemConfig.selectionEvents || (typeof this.tables[this.activeTable] === "undefined")){ | |
36769 return; | |
36770 } | |
36771 this.reset(); | |
36772 if( this.tables.length == 0 ){ | |
36773 return; | |
36774 } | |
36775 this.selection = selection; | |
36776 for (var i = 0; i < this.tableElements.length; i++) { | |
36777 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36778 this.tableElements[i][j].selected = false; | |
36779 this.tableElements[i][j].highlighted = false; | |
36780 } | |
36781 } | |
36782 var objects = selection.getObjects(this); | |
36783 for (var i = 0; i < objects.length; i++) { | |
36784 for (var j = 0; j < objects[i].length; j++) { | |
36785 this.tableHash[i][objects[i][j].index].selected = true; | |
36786 } | |
36787 } | |
36788 this.tables[this.activeTable].reset(); | |
36789 this.tables[this.activeTable].update(); | |
36790 }, | |
36791 | |
36792 triggerHighlight : function(item) { | |
36793 var selectedObjects = []; | |
36794 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36795 selectedObjects.push([]); | |
36796 } | |
36797 if ( typeof item != 'undefined') { | |
36798 selectedObjects[this.activeTable].push(item); | |
36799 } | |
36800 this.core.triggerHighlight(selectedObjects); | |
36801 }, | |
36802 | |
36803 tableSelection : function() { | |
36804 var selectedObjects = []; | |
36805 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36806 selectedObjects.push([]); | |
36807 } | |
36808 var valid = false; | |
36809 for (var i = 0; i < this.tableElements.length; i++) { | |
36810 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36811 var e = this.tableElements[i][j]; | |
36812 if (e.selected) { | |
36813 selectedObjects[i].push(e.object); | |
36814 valid = true; | |
36815 } | |
36816 } | |
36817 } | |
36818 this.selection = new Selection(); | |
36819 if (valid) { | |
36820 this.selection = new Selection(selectedObjects, this); | |
36821 } | |
36822 this.core.triggerSelection(this.selection); | |
36823 this.filterBar.reset(true); | |
36824 }, | |
36825 | |
36826 deselection : function() { | |
36827 this.reset(); | |
36828 this.selection = new Selection(); | |
36829 this.core.triggerSelection(this.selection); | |
36830 }, | |
36831 | |
36832 filtering : function() { | |
36833 for (var i = 0; i < this.datasets.length; i++) { | |
36834 this.datasets[i].objects = this.selection.objects[i]; | |
36835 } | |
36836 this.core.triggerRefining(this.datasets); | |
36837 }, | |
36838 | |
36839 inverseFiltering : function() { | |
36840 var selectedObjects = []; | |
36841 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36842 selectedObjects.push([]); | |
36843 } | |
36844 var valid = false; | |
36845 for (var i = 0; i < this.tableElements.length; i++) { | |
36846 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36847 var e = this.tableElements[i][j]; | |
36848 if (!e.selected) { | |
36849 selectedObjects[i].push(e.object); | |
36850 valid = true; | |
36851 } | |
36852 } | |
36853 } | |
36854 this.selection = new Selection(); | |
36855 if (valid) { | |
36856 this.selection = new Selection(selectedObjects, this); | |
36857 } | |
36858 this.filtering(); | |
36859 }, | |
36860 | |
36861 triggerRefining : function() { | |
36862 this.core.triggerRefining(this.selection.objects); | |
36863 }, | |
36864 | |
36865 reset : function() { | |
36866 this.filterBar.reset(false); | |
36867 if( this.tables.length > 0 ){ | |
36868 this.tables[this.activeTable].resetElements(); | |
36869 this.tables[this.activeTable].reset(); | |
36870 this.tables[this.activeTable].update(); | |
36871 } | |
36872 } | |
36873 } | |
36874 /* | |
36875 * Table.js | |
36876 * | |
36877 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
36878 * | |
36879 * This library is free software; you can redistribute it and/or | |
36880 * modify it under the terms of the GNU Lesser General Public | |
36881 * License as published by the Free Software Foundation; either | |
36882 * version 3 of the License, or (at your option) any later version. | |
36883 * | |
36884 * This library is distributed in the hope that it will be useful, | |
36885 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36886 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36887 * Lesser General Public License for more details. | |
36888 * | |
36889 * You should have received a copy of the GNU Lesser General Public | |
36890 * License along with this library; if not, write to the Free Software | |
36891 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
36892 * MA 02110-1301 USA | |
36893 */ | |
36894 | |
36895 /** | |
36896 * @class Table | |
36897 * Implementation for a single table | |
36898 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
36899 * @release 1.0 | |
36900 * @release date: 2012-07-27 | |
36901 * @version date: 2012-07-27 | |
36902 * | |
36903 * @param {Array} elements list of data items | |
36904 * @param {HTML object} parent div to append the table | |
36905 * @param {int} id dataset index | |
36906 */ | |
36907 function Table(elements, parent, id) { | |
36908 | |
36909 this.elements = elements; | |
36910 this.showElementsLength = elements.length; | |
36911 this.parent = parent; | |
36912 this.id = id; | |
36913 this.options = parent.options; | |
36914 | |
36915 this.validResultsPerPage = [10, 20, 50, 100]; | |
36916 this.keyHeaderList = []; | |
36917 this.initialize(); | |
36918 | |
36919 } | |
36920 | |
36921 Table.prototype = { | |
36922 | |
36923 initToolbar : function() { | |
36924 | |
36925 var table = this; | |
36926 | |
36927 this.toolbar = document.createElement("table"); | |
36928 this.toolbar.setAttribute('class', 'ddbToolbar'); | |
36929 this.toolbar.style.overflow = 'auto'; | |
36930 this.tableDiv.appendChild(this.toolbar); | |
36931 | |
36932 var navigation = document.createElement("tr"); | |
36933 this.toolbar.appendChild(navigation); | |
36934 | |
36935 var selectors = document.createElement("td"); | |
36936 navigation.appendChild(selectors); | |
36937 | |
36938 if (table.options.tableSelectPage) { | |
36939 var selectPageItems = true; | |
36940 this.selectPage = document.createElement('div'); | |
36941 $(this.selectPage).css("float","left"); | |
36942 this.selectPage.setAttribute('class', 'smallButton selectPage'); | |
36943 this.selectPage.title = GeoTemConfig.getString('selectTablePageItemsHelp'); | |
36944 selectors.appendChild(this.selectPage); | |
36945 this.selectPage.onclick = function() { | |
36946 selectPageItems = !selectPageItems; | |
36947 if (selectPageItems) { | |
36948 var items = 0; | |
36949 for (var i = table.first; i < table.elements.length; i++) { | |
36950 table.elements[i].selected = false; | |
36951 items++; | |
36952 if (items == table.resultsPerPage) { | |
36953 break; | |
36954 } | |
36955 } | |
36956 table.selectPage.setAttribute('class', 'smallButton selectPage'); | |
36957 table.selectPage.title = GeoTemConfig.getString('selectTablePageItemsHelp'); | |
36958 } else { | |
36959 var items = 0; | |
36960 for (var i = table.first; i < table.elements.length; i++) { | |
36961 table.elements[i].selected = true; | |
36962 items++; | |
36963 if (items == table.resultsPerPage) { | |
36964 break; | |
36965 } | |
36966 } | |
36967 table.selectPage.setAttribute('class', 'smallButton deselectPage'); | |
36968 table.selectPage.title = GeoTemConfig.getString('deselectTablePageItemsHelp'); | |
36969 } | |
36970 table.update(); | |
36971 table.parent.tableSelection(); | |
36972 } | |
36973 } | |
36974 | |
36975 if (table.options.tableSelectAll) { | |
36976 var selectAllItems = true; | |
36977 this.selectAll = document.createElement('div'); | |
36978 this.selectAll.setAttribute('class', 'smallButton selectAll'); | |
36979 $(this.selectAll).css("float","left"); | |
36980 table.selectAll.title = GeoTemConfig.getString('selectAllTableItemsHelp'); | |
36981 selectors.appendChild(this.selectAll); | |
36982 this.selectAll.onclick = function() { | |
36983 selectAllItems = !selectAllItems; | |
36984 if (selectAllItems) { | |
36985 for (var i = 0; i < table.elements.length; i++) { | |
36986 table.elements[i].selected = false; | |
36987 } | |
36988 table.selectAll.setAttribute('class', 'smallButton selectAll'); | |
36989 table.selectAll.title = GeoTemConfig.getString('selectAllTableItemsHelp'); | |
36990 } else { | |
36991 for (var i = 0; i < table.elements.length; i++) { | |
36992 table.elements[i].selected = true; | |
36993 } | |
36994 table.selectAll.setAttribute('class', 'smallButton deselectAll'); | |
36995 table.selectAll.title = GeoTemConfig.getString('deselectAllTableItemsHelp'); | |
36996 } | |
36997 table.update(); | |
36998 table.parent.tableSelection(); | |
36999 } | |
37000 } | |
37001 | |
37002 if (table.options.tableInvertSelection) { | |
37003 this.invertSelection = document.createElement('div'); | |
37004 this.invertSelection.setAttribute('class', 'smallButton invertSelection'); | |
37005 $(this.invertSelection).css("float","left"); | |
37006 table.invertSelection.title = GeoTemConfig.getString('invertSelectionHelp'); | |
37007 selectors.appendChild(this.invertSelection); | |
37008 this.invertSelection.onclick = function() { | |
37009 for (var i = 0; i < table.elements.length; i++) { | |
37010 if (table.elements[i].selected === true) | |
37011 table.elements[i].selected = false; | |
37012 else | |
37013 table.elements[i].selected = true; | |
37014 } | |
37015 table.update(); | |
37016 table.parent.tableSelection(); | |
37017 } | |
37018 } | |
37019 | |
37020 this.showSelectedItems = false; | |
37021 if (table.options.tableShowSelected) { | |
37022 this.showSelected = document.createElement('div'); | |
37023 this.showSelected.setAttribute('class', 'smallButton showSelected'); | |
37024 $(this.showSelected).css("float","left"); | |
37025 table.showSelected.title = GeoTemConfig.getString('showSelectedHelp'); | |
37026 selectors.appendChild(this.showSelected); | |
37027 this.showSelected.onclick = function() { | |
37028 table.showSelectedItems = !table.showSelectedItems; | |
37029 if (table.showSelectedItems) { | |
37030 table.showElementsLength = 0; | |
37031 for (var i = 0; i < table.elements.length; i++) { | |
37032 if (table.elements[i].selected) { | |
37033 table.showElementsLength++; | |
37034 } | |
37035 } | |
37036 table.showSelected.setAttribute('class', 'smallButton showAll'); | |
37037 // table.selectAll.title = GeoTemConfig.getString('showAllElementsHelp'); | |
37038 } else { | |
37039 table.showElementsLength = table.elements.length; | |
37040 table.showSelected.setAttribute('class', 'smallButton showSelected'); | |
37041 // table.selectAll.title = GeoTemConfig.getString('showSelectedHelp'); | |
37042 } | |
37043 table.updateIndices(table.resultsPerPage); | |
37044 table.update(); | |
37045 } | |
37046 } | |
37047 | |
37048 if (table.options.tableSelectByText) { | |
37049 this.selectByTextDiv = document.createElement('div'); | |
37050 $(this.selectByTextDiv).css("float","left"); | |
37051 $(this.selectByTextDiv).css("vertical-align", "top"); | |
37052 //TODO: improve appearance (wrong margin) | |
37053 $(this.selectByTextDiv).css("display", "inline-block"); | |
37054 //create and append the input field | |
37055 this.selectByTextInput = document.createElement('input'); | |
37056 $(this.selectByTextInput).attr("type","text"); | |
37057 $(this.selectByTextDiv).append(this.selectByTextInput); | |
37058 //create and append the button | |
37059 this.selectByTextButton = document.createElement('input'); | |
37060 $(this.selectByTextButton).attr("type","button"); | |
37061 //TODO: add button-image | |
37062 $(this.selectByTextButton).val("search"); | |
37063 $(this.selectByTextDiv).append(this.selectByTextButton); | |
37064 | |
37065 table.selectByTextDiv.title = GeoTemConfig.getString('selectByTextHelp'); | |
37066 selectors.appendChild(this.selectByTextDiv); | |
37067 $(this.selectByTextButton).click($.proxy(function() { | |
37068 this.selectByText($(this.selectByTextInput).val()); | |
37069 },this)); | |
37070 } | |
37071 | |
37072 if (table.options.tableCreateNewFromSelected) { | |
37073 this.createNewFromSelected = document.createElement('div'); | |
37074 this.createNewFromSelected.setAttribute('class', 'smallButton createNewRefined'); | |
37075 $(this.createNewFromSelected).css("float","left"); | |
37076 this.createNewFromSelected.title = GeoTemConfig.getString('createNewFromSelectedHelp'); | |
37077 selectors.appendChild(this.createNewFromSelected); | |
37078 this.createNewFromSelected.onclick = function() { | |
37079 var copyID = table.id; | |
37080 var tableWidget = table.parent; | |
37081 | |
37082 var newObjects = []; | |
37083 $(table.elements).each(function(){ | |
37084 if (this.selected) | |
37085 newObjects.push(this.object); | |
37086 }); | |
37087 | |
37088 var newDataset = new Dataset(); | |
37089 newDataset.label = tableWidget.datasets[copyID].label + " refined"; | |
37090 newDataset.objects = newObjects; | |
37091 | |
37092 GeoTemConfig.addDataset(newDataset); | |
37093 }; | |
37094 } | |
37095 | |
37096 this.selectors = selectors; | |
37097 | |
37098 // selectors.style.width = (this.filter.offsetWidth + this.selectAll.offsetWidth + this.selectPage.offsetWidth)+"px"; | |
37099 | |
37100 var results = document.createElement("td"); | |
37101 navigation.appendChild(results); | |
37102 | |
37103 var pagination = document.createElement("td"); | |
37104 $(pagination).css('float', 'right'); | |
37105 navigation.appendChild(pagination); | |
37106 | |
37107 this.resultsInfo = document.createElement('div'); | |
37108 this.resultsInfo.setAttribute('class', 'resultsInfo'); | |
37109 results.appendChild(this.resultsInfo); | |
37110 | |
37111 this.resultsDropdown = document.createElement('div'); | |
37112 this.resultsDropdown.setAttribute('class', 'resultsDropdown'); | |
37113 pagination.appendChild(this.resultsDropdown); | |
37114 var itemNumbers = []; | |
37115 var addItemNumber = function(count, index) { | |
37116 var setItemNumber = function() { | |
37117 table.updateIndices(count); | |
37118 table.update(); | |
37119 } | |
37120 itemNumbers.push({ | |
37121 name : count, | |
37122 onclick : setItemNumber | |
37123 }); | |
37124 } | |
37125 for (var i = 0; i < table.options.validResultsPerPage.length; i++) { | |
37126 addItemNumber(table.options.validResultsPerPage[i], i); | |
37127 } | |
37128 var dropdown = new Dropdown(this.resultsDropdown, itemNumbers, GeoTemConfig.getString('paginationDropdownHelp')); | |
37129 for (var i = 0; i < table.options.validResultsPerPage.length; i++) { | |
37130 if (table.options.initialResultsPerPage == table.options.validResultsPerPage[i]) { | |
37131 dropdown.setEntry(i); | |
37132 break; | |
37133 } | |
37134 } | |
37135 dropdown.div.title = GeoTemConfig.getString('paginationDropdownHelp'); | |
37136 | |
37137 this.firstPage = document.createElement('div'); | |
37138 this.firstPage.setAttribute('class', 'paginationButton'); | |
37139 this.firstPage.title = GeoTemConfig.getString('paginationFirsPageHelp'); | |
37140 | |
37141 pagination.appendChild(this.firstPage); | |
37142 this.firstPage.onclick = function() { | |
37143 if (table.page != 0) { | |
37144 table.page = 0; | |
37145 table.update(); | |
37146 } | |
37147 } | |
37148 | |
37149 this.previousPage = document.createElement('div'); | |
37150 this.previousPage.setAttribute('class', 'paginationButton'); | |
37151 this.previousPage.title = GeoTemConfig.getString('paginationPreviousPageHelp'); | |
37152 pagination.appendChild(this.previousPage); | |
37153 this.previousPage.onclick = function() { | |
37154 if (table.page > 0) { | |
37155 table.page--; | |
37156 table.update(); | |
37157 } | |
37158 } | |
37159 | |
37160 this.pageInfo = document.createElement('div'); | |
37161 this.pageInfo.setAttribute('class', 'pageInfo'); | |
37162 pagination.appendChild(this.pageInfo); | |
37163 | |
37164 this.nextPage = document.createElement('div'); | |
37165 this.nextPage.setAttribute('class', 'paginationButton'); | |
37166 this.nextPage.title = GeoTemConfig.getString('paginationNextPageHelp'); | |
37167 pagination.appendChild(this.nextPage); | |
37168 this.nextPage.onclick = function() { | |
37169 if (table.page < table.pages - 1) { | |
37170 table.page++; | |
37171 table.update(); | |
37172 } | |
37173 } | |
37174 | |
37175 this.lastPage = document.createElement('div'); | |
37176 this.lastPage.setAttribute('class', 'paginationButton'); | |
37177 this.lastPage.title = GeoTemConfig.getString('paginationLastPageHelp'); | |
37178 pagination.appendChild(this.lastPage); | |
37179 this.lastPage.onclick = function() { | |
37180 if (table.page != table.pages - 1) { | |
37181 table.page = table.pages - 1; | |
37182 table.update(); | |
37183 } | |
37184 } | |
37185 | |
37186 this.input = document.createElement("div"); | |
37187 this.input.style.overflow = 'auto'; | |
37188 this.tableDiv.appendChild(this.input); | |
37189 | |
37190 this.elementList = document.createElement("table"); | |
37191 this.elementList.setAttribute('class', 'resultList'); | |
37192 this.input.appendChild(this.elementList); | |
37193 var height = this.parent.getHeight(); | |
37194 if (height) { | |
37195 this.input.style.height = (height - pagination.offsetHeight) + 'px'; | |
37196 this.input.style.overflowY = 'auto'; | |
37197 } | |
37198 | |
37199 this.elementListHeader = document.createElement("tr"); | |
37200 this.elementList.appendChild(this.elementListHeader); | |
37201 | |
37202 if (GeoTemConfig.allowFilter) { | |
37203 var cell = document.createElement('th'); | |
37204 this.elementListHeader.appendChild(cell); | |
37205 } | |
37206 | |
37207 //Bottom pagination elements | |
37208 this.bottomToolbar = document.createElement("table"); | |
37209 this.bottomToolbar.setAttribute('class', 'ddbToolbar'); | |
37210 this.bottomToolbar.style.overflow = 'auto'; | |
37211 this.tableDiv.appendChild(this.bottomToolbar); | |
37212 | |
37213 var bottomNavigation = document.createElement("tr"); | |
37214 this.bottomToolbar.appendChild(bottomNavigation); | |
37215 | |
37216 var bottomPagination = document.createElement("td"); | |
37217 bottomNavigation.appendChild(bottomPagination); | |
37218 | |
37219 this.bottomLastPage = document.createElement('div'); | |
37220 this.bottomLastPage.setAttribute('class', 'paginationButton'); | |
37221 this.bottomLastPage.title = GeoTemConfig.getString('paginationLastPageHelp'); | |
37222 $(this.bottomLastPage).css('float', 'right'); | |
37223 bottomPagination.appendChild(this.bottomLastPage); | |
37224 this.bottomLastPage.onclick = function() { | |
37225 if (table.page != table.pages - 1) { | |
37226 table.page = table.pages - 1; | |
37227 table.update(); | |
37228 } | |
37229 } | |
37230 | |
37231 this.bottomNextPage = document.createElement('div'); | |
37232 this.bottomNextPage.setAttribute('class', 'paginationButton'); | |
37233 this.bottomNextPage.title = GeoTemConfig.getString('paginationNextPageHelp'); | |
37234 $(this.bottomNextPage).css('float', 'right'); | |
37235 bottomPagination.appendChild(this.bottomNextPage); | |
37236 this.bottomNextPage.onclick = function() { | |
37237 if (table.page < table.pages - 1) { | |
37238 table.page++; | |
37239 table.update(); | |
37240 } | |
37241 } | |
37242 | |
37243 this.bottomPageInfo = document.createElement('div'); | |
37244 this.bottomPageInfo.setAttribute('class', 'pageInfo'); | |
37245 $(this.bottomPageInfo).css('float', 'right'); | |
37246 bottomPagination.appendChild(this.bottomPageInfo); | |
37247 | |
37248 this.bottomPreviousPage = document.createElement('div'); | |
37249 this.bottomPreviousPage.setAttribute('class', 'paginationButton'); | |
37250 this.bottomPreviousPage.title = GeoTemConfig.getString('paginationPreviousPageHelp'); | |
37251 $(this.bottomPreviousPage).css('float', 'right'); | |
37252 bottomPagination.appendChild(this.bottomPreviousPage); | |
37253 this.bottomPreviousPage.onclick = function() { | |
37254 if (table.page > 0) { | |
37255 table.page--; | |
37256 table.update(); | |
37257 } | |
37258 } | |
37259 | |
37260 this.bottomFirstPage = document.createElement('div'); | |
37261 this.bottomFirstPage.setAttribute('class', 'paginationButton'); | |
37262 this.bottomFirstPage.title = GeoTemConfig.getString('paginationFirsPageHelp'); | |
37263 $(this.bottomFirstPage).css('float', 'right'); | |
37264 bottomPagination.appendChild(this.bottomFirstPage); | |
37265 this.bottomFirstPage.onclick = function() { | |
37266 if (table.page != 0) { | |
37267 table.page = 0; | |
37268 table.update(); | |
37269 } | |
37270 } | |
37271 | |
37272 if ( typeof (this.elements[0]) == 'undefined') { | |
37273 return; | |
37274 } | |
37275 | |
37276 var ascButtons = []; | |
37277 var descButtons = []; | |
37278 var clearButtons = function() { | |
37279 for (var i in ascButtons ) { | |
37280 ascButtons[i].setAttribute('class', 'sort sortAscDeactive'); | |
37281 } | |
37282 for (var i in descButtons ) { | |
37283 descButtons[i].setAttribute('class', 'sort sortDescDeactive'); | |
37284 } | |
37285 } | |
37286 var addSortButton = function(key) { | |
37287 table.keyHeaderList.push(key); | |
37288 var cell = document.createElement('th'); | |
37289 table.elementListHeader.appendChild(cell); | |
37290 var sortAsc = document.createElement('div'); | |
37291 var sortDesc = document.createElement('div'); | |
37292 var span = document.createElement('div'); | |
37293 span.setAttribute('class', 'headerLabel'); | |
37294 span.innerHTML = key; | |
37295 cell.appendChild(sortDesc); | |
37296 cell.appendChild(span); | |
37297 cell.appendChild(sortAsc); | |
37298 sortAsc.setAttribute('class', 'sort sortAscDeactive'); | |
37299 sortAsc.title = GeoTemConfig.getString('sortAZHelp'); | |
37300 sortDesc.setAttribute('class', 'sort sortDescDeactive'); | |
37301 sortDesc.title = GeoTemConfig.getString('sortZAHelp'); | |
37302 ascButtons.push(sortAsc); | |
37303 descButtons.push(sortDesc); | |
37304 sortAsc.onclick = function() { | |
37305 clearButtons(); | |
37306 sortAsc.setAttribute('class', 'sort sortAscActive'); | |
37307 table.sortAscending(key); | |
37308 table.update(); | |
37309 } | |
37310 sortDesc.onclick = function() { | |
37311 clearButtons(); | |
37312 sortDesc.setAttribute('class', 'sort sortDescActive'); | |
37313 table.sortDescending(key); | |
37314 table.update(); | |
37315 } | |
37316 } | |
37317 for (var key in this.elements[0].object.tableContent) { | |
37318 addSortButton(key); | |
37319 } | |
37320 }, | |
37321 | |
37322 sortAscending : function(key) { | |
37323 var sortFunction = function(e1, e2) { | |
37324 if (e1.object.tableContent[key] < e2.object.tableContent[key]) { | |
37325 return -1; | |
37326 } | |
37327 return 1; | |
37328 } | |
37329 this.elements.sort(sortFunction); | |
37330 }, | |
37331 | |
37332 sortDescending : function(key) { | |
37333 var sortFunction = function(e1, e2) { | |
37334 if (e1.object.tableContent[key] > e2.object.tableContent[key]) { | |
37335 return -1; | |
37336 } | |
37337 return 1; | |
37338 } | |
37339 this.elements.sort(sortFunction); | |
37340 }, | |
37341 | |
37342 selectByText : function(text) { | |
37343 //deselect all elements | |
37344 $(this.elements).each(function(){ | |
37345 this.selected = false; | |
37346 }); | |
37347 | |
37348 var selectedCount = 0; | |
37349 $(this.elements).filter(function(index){ | |
37350 return this.object.contains(text); | |
37351 }).each(function(){ | |
37352 this.selected = true; | |
37353 selectedCount++; | |
37354 }); | |
37355 | |
37356 //only show selected elements | |
37357 this.showSelectedItems = true; | |
37358 this.showElementsLength = selectedCount; | |
37359 this.showSelected.setAttribute('class', 'smallButton showAll'); | |
37360 | |
37361 this.update(); | |
37362 this.parent.tableSelection(); | |
37363 }, | |
37364 | |
37365 setPagesText : function() { | |
37366 var infoText = GeoTemConfig.getString('pageInfo'); | |
37367 infoText = infoText.replace('PAGES_ID', this.pages); | |
37368 infoText = infoText.replace('PAGE_ID', this.page + 1); | |
37369 this.pageInfo.innerHTML = infoText; | |
37370 this.bottomPageInfo.innerHTML = infoText; | |
37371 }, | |
37372 | |
37373 setResultsText : function() { | |
37374 if (this.elements.length == 0) { | |
37375 this.resultsInfo.innerHTML = '0 Results'; | |
37376 } else { | |
37377 var infoText = GeoTemConfig.getString('resultsInfo'); | |
37378 var first = this.page * this.resultsPerPage + 1; | |
37379 var last = (this.page + 1 == this.pages ) ? this.showElementsLength : first + this.resultsPerPage - 1; | |
37380 infoText = infoText.replace('RESULTS_FROM_ID', first); | |
37381 infoText = infoText.replace('RESULTS_TO_ID', last); | |
37382 infoText = infoText.replace('RESULTS_ID', this.showElementsLength); | |
37383 this.resultsInfo.innerHTML = infoText; | |
37384 } | |
37385 }, | |
37386 | |
37387 updateIndices : function(rpp) { | |
37388 if ( typeof this.resultsPerPage == 'undefined') { | |
37389 this.page = 0; | |
37390 this.resultsPerPage = 0; | |
37391 } | |
37392 var index = this.page * this.resultsPerPage; | |
37393 this.resultsPerPage = rpp; | |
37394 if (this.showSelectedItems) { | |
37395 index = 0; | |
37396 } | |
37397 this.pages = Math.floor(this.showElementsLength / this.resultsPerPage); | |
37398 if (this.showElementsLength % this.resultsPerPage != 0) { | |
37399 this.pages++; | |
37400 } | |
37401 this.page = Math.floor(index / this.resultsPerPage); | |
37402 }, | |
37403 | |
37404 update : function() { | |
37405 var table = this; | |
37406 $(this.elementList).find("tr:gt(0)").remove(); | |
37407 if (this.page == 0) { | |
37408 this.previousPage.setAttribute('class', 'paginationButton previousPageDisabled'); | |
37409 this.firstPage.setAttribute('class', 'paginationButton firstPageDisabled'); | |
37410 this.bottomPreviousPage.setAttribute('class', 'paginationButton previousPageDisabled'); | |
37411 this.bottomFirstPage.setAttribute('class', 'paginationButton firstPageDisabled'); | |
37412 } else { | |
37413 this.previousPage.setAttribute('class', 'paginationButton previousPageEnabled'); | |
37414 this.firstPage.setAttribute('class', 'paginationButton firstPageEnabled'); | |
37415 this.bottomPreviousPage.setAttribute('class', 'paginationButton previousPageEnabled'); | |
37416 this.bottomFirstPage.setAttribute('class', 'paginationButton firstPageEnabled'); | |
37417 } | |
37418 if (this.page == this.pages - 1) { | |
37419 this.nextPage.setAttribute('class', 'paginationButton nextPageDisabled'); | |
37420 this.lastPage.setAttribute('class', 'paginationButton lastPageDisabled'); | |
37421 this.bottomNextPage.setAttribute('class', 'paginationButton nextPageDisabled'); | |
37422 this.bottomLastPage.setAttribute('class', 'paginationButton lastPageDisabled'); | |
37423 } else { | |
37424 this.nextPage.setAttribute('class', 'paginationButton nextPageEnabled'); | |
37425 this.lastPage.setAttribute('class', 'paginationButton lastPageEnabled'); | |
37426 this.bottomNextPage.setAttribute('class', 'paginationButton nextPageEnabled'); | |
37427 this.bottomLastPage.setAttribute('class', 'paginationButton lastPageEnabled'); | |
37428 } | |
37429 this.setPagesText(); | |
37430 this.setResultsText(); | |
37431 if (this.showSelectedItems) { | |
37432 var start = this.page * this.resultsPerPage; | |
37433 var items = 0; | |
37434 for (var i = 0; i < this.elements.length; i++) { | |
37435 if (items == start) { | |
37436 this.first = i; | |
37437 break; | |
37438 } | |
37439 if (this.elements[i].selected) { | |
37440 items++; | |
37441 } | |
37442 } | |
37443 } else { | |
37444 this.first = this.page * this.resultsPerPage; | |
37445 } | |
37446 //this.last = ( this.page + 1 == this.pages ) ? this.elements.length : this.first + this.resultsPerPage; | |
37447 var c = GeoTemConfig.getColor(this.id); | |
37448 var itemSet = []; | |
37449 var clearDivs = function() { | |
37450 for (var i = 0; i < itemSet.length; i++) { | |
37451 if (!itemSet[i].e.selected) { | |
37452 itemSet[i].e.highlighted = false; | |
37453 $(itemSet[i].div).css('background-color', table.options.unselectedCellColor); | |
37454 } | |
37455 } | |
37456 } | |
37457 var setHighlight = function(item, div) { | |
37458 var enter = function() { | |
37459 clearDivs(); | |
37460 if (!item.selected) { | |
37461 item.highlighted = true; | |
37462 $(div).css('background-color', 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'); | |
37463 table.parent.triggerHighlight(item.object); | |
37464 } | |
37465 } | |
37466 var leave = function() { | |
37467 clearDivs(); | |
37468 if (!item.selected) { | |
37469 table.parent.triggerHighlight(); | |
37470 } | |
37471 } | |
37472 $(div).hover(enter, leave); | |
37473 $(div).mousemove(function() { | |
37474 if (!item.selected && !item.highlighted) { | |
37475 item.highlighted = true; | |
37476 $(div).css('background-color', 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'); | |
37477 table.parent.triggerHighlight(item.object); | |
37478 } | |
37479 }); | |
37480 } | |
37481 var setSelection = function(item, div, checkbox) { | |
37482 var click = function(e) { | |
37483 var checked = $(checkbox).is(':checked'); | |
37484 if (checked) { | |
37485 item.selected = true; | |
37486 item.highlighted = false; | |
37487 } else { | |
37488 item.selected = false; | |
37489 item.highlighted = true; | |
37490 } | |
37491 //if( e.target == div ){ | |
37492 // $(checkbox).attr('checked', !checked); | |
37493 //} | |
37494 table.parent.tableSelection(); | |
37495 } | |
37496 //$(div).click(click); | |
37497 $(checkbox).click(click); | |
37498 } | |
37499 this.checkboxes = []; | |
37500 var items = 0; | |
37501 for (var i = this.first; i < this.elements.length; i++) { | |
37502 var e = this.elements[i]; | |
37503 //vhz because of an error | |
37504 if ( typeof (e) == "undefined") { | |
37505 continue; | |
37506 } | |
37507 if (this.showSelectedItems && !e.selected) { | |
37508 continue; | |
37509 } | |
37510 var itemRow = $("<tr/>").appendTo(this.elementList); | |
37511 if (GeoTemConfig.allowFilter) { | |
37512 var checkColumn = $("<td/>").appendTo(itemRow); | |
37513 var checkbox = $("<input type='checkbox'/>").appendTo(checkColumn); | |
37514 $(checkbox).attr('checked', e.selected); | |
37515 } | |
37516 var makeSubtext = function(cell, text) { | |
37517 var subtext = text.substring(0, table.options.tableContentOffset); | |
37518 subtext = subtext.substring(0, subtext.lastIndexOf(' ')); | |
37519 subtext += ' ... '; | |
37520 var textDiv = $("<div style='display:inline-block;'/>").appendTo(cell); | |
37521 $(textDiv).html(subtext); | |
37522 var show = false; | |
37523 var fullDiv = $("<div style='display:inline-block;'><a href='javascript:void(0)'>\>\></a></div>").appendTo(cell); | |
37524 $(fullDiv).click(function() { | |
37525 show = !show; | |
37526 if (show) { | |
37527 $(textDiv).html(text); | |
37528 $(fullDiv).html('<a href="javascript:void(0)">\<\<</a>'); | |
37529 } else { | |
37530 $(textDiv).html(subtext); | |
37531 $(fullDiv).html('<a href="javascript:void(0)">\>\></a>'); | |
37532 } | |
37533 }); | |
37534 } | |
37535 for (var k = 0; k < table.keyHeaderList.length; k++) { | |
37536 var key = table.keyHeaderList[k]; | |
37537 //vhz | |
37538 var text = e.object.tableContent[key]; | |
37539 if (typeof text === "undefined") | |
37540 text = ""; | |
37541 var cell = $("<td></td>").appendTo(itemRow); | |
37542 | |
37543 //align the elements (if unset: "center") | |
37544 if (typeof table.options.verticalAlign !== "undefined"){ | |
37545 if (table.options.verticalAlign === "top") | |
37546 $(cell).attr("valign","top"); | |
37547 else if (table.options.verticalAlign === "center") | |
37548 $(cell).attr("valign","center"); | |
37549 else if (table.options.verticalAlign === "bottom") | |
37550 $(cell).attr("valign","bottom"); | |
37551 } | |
37552 | |
37553 if (table.options.tableContentOffset && text.length < table.options.tableContentOffset) { | |
37554 $(cell).html(text); | |
37555 } else { | |
37556 makeSubtext(cell, text); | |
37557 } | |
37558 } | |
37559 if (e.selected || e.highlighted) { | |
37560 $(itemRow).css('background-color', 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'); | |
37561 } else { | |
37562 $(itemRow).css('background-color', table.options.unselectedCellColor); | |
37563 } | |
37564 itemSet.push({ | |
37565 e : e, | |
37566 div : itemRow | |
37567 }); | |
37568 setHighlight(e, itemRow); | |
37569 if (GeoTemConfig.allowFilter) { | |
37570 setSelection(e, itemRow, checkbox); | |
37571 this.checkboxes.push(checkbox); | |
37572 $(checkColumn).css('text-align', 'center'); | |
37573 } | |
37574 items++; | |
37575 if (items == this.resultsPerPage) { | |
37576 break; | |
37577 } | |
37578 } | |
37579 }, | |
37580 | |
37581 show : function() { | |
37582 if (GeoTemConfig.allowFilter) { | |
37583 this.parent.filterBar.appendTo(this.selectors); | |
37584 } | |
37585 this.tableDiv.style.display = "block"; | |
37586 }, | |
37587 | |
37588 hide : function() { | |
37589 this.tableDiv.style.display = "none"; | |
37590 }, | |
37591 | |
37592 resetElements : function() { | |
37593 for (var i = 0; i < this.elements.length; i++) { | |
37594 this.elements[i].selected = false; | |
37595 this.elements[i].highlighted = false; | |
37596 } | |
37597 }, | |
37598 | |
37599 reset : function() { | |
37600 if (!this.options.tableKeepShowSelected){ | |
37601 this.showSelectedItems = false; | |
37602 this.showElementsLength = this.elements.length; | |
37603 this.showSelected.setAttribute('class', 'smallButton showSelected'); | |
37604 } | |
37605 this.updateIndices(this.resultsPerPage); | |
37606 }, | |
37607 | |
37608 initialize : function() { | |
37609 | |
37610 this.tableDiv = document.createElement("div"); | |
37611 this.tableDiv.setAttribute('class', 'singleTable'); | |
37612 this.parent.gui.input.appendChild(this.tableDiv); | |
37613 | |
37614 this.initToolbar(); | |
37615 | |
37616 this.tableDiv.style.display = 'none'; | |
37617 this.updateIndices(this.options.initialResultsPerPage); | |
37618 | |
37619 this.update(); | |
37620 | |
37621 } | |
37622 } | |
37623 | |
37624 function TableElement(object) { | |
37625 | |
37626 this.object = object; | |
37627 this.selected = false; | |
37628 this.highlighted = false; | |
37629 | |
37630 } | |
37631 /* | |
37632 * Dataloader.js | |
37633 * | |
37634 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37635 * | |
37636 * This library is free software; you can redistribute it and/or | |
37637 * modify it under the terms of the GNU Lesser General Public | |
37638 * License as published by the Free Software Foundation; either | |
37639 * version 3 of the License, or (at your option) any later version. | |
37640 * | |
37641 * This library is distributed in the hope that it will be useful, | |
37642 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37643 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37644 * Lesser General Public License for more details. | |
37645 * | |
37646 * You should have received a copy of the GNU Lesser General Public | |
37647 * License along with this library; if not, write to the Free Software | |
37648 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37649 * MA 02110-1301 USA | |
37650 */ | |
37651 | |
37652 /** | |
37653 * @class Dataloader | |
37654 * Implementation for a Dataloader UI | |
37655 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37656 * | |
37657 * @param {HTML object} parent div to append the Dataloader | |
37658 */ | |
37659 function Dataloader(parent) { | |
37660 | |
37661 this.dataLoader = this; | |
37662 | |
37663 this.parent = parent; | |
37664 this.options = parent.options; | |
37665 | |
37666 this.initialize(); | |
37667 } | |
37668 | |
37669 Dataloader.prototype = { | |
37670 | |
37671 show : function() { | |
37672 this.dataloaderDiv.style.display = "block"; | |
37673 }, | |
37674 | |
37675 hide : function() { | |
37676 this.dataloaderDiv.style.display = "none"; | |
37677 }, | |
37678 | |
37679 initialize : function() { | |
37680 | |
37681 this.addStaticLoader(); | |
37682 this.addLocalStorageLoader(); | |
37683 this.addKMLLoader(); | |
37684 this.addKMZLoader(); | |
37685 this.addCSVLoader(); | |
37686 this.addLocalKMLLoader(); | |
37687 this.addLocalCSVLoader(); | |
37688 | |
37689 // trigger change event on the select so | |
37690 // that only the first loader div will be shown | |
37691 $(this.parent.gui.loaderTypeSelect).change(); | |
37692 }, | |
37693 | |
37694 getFileName : function(url) { | |
37695 var fileName = $.url(url).attr('file'); | |
37696 if ( (typeof fileName === "undefined") || (fileName.length === 0) ){ | |
37697 fileName = $.url(url).attr('path'); | |
37698 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
37699 while (fileName.endsWith("/")){ | |
37700 fileName = fileName.substr(0,fileName.length-1); | |
37701 } | |
37702 if (fileName.length > 1) | |
37703 fileName = fileName.substr(fileName.lastIndexOf("/")+1); | |
37704 else | |
37705 fileName = "unnamed dataset"; | |
37706 } | |
37707 return fileName; | |
37708 }, | |
37709 | |
37710 distributeDataset : function(dataSet) { | |
37711 GeoTemConfig.addDataset(dataSet); | |
37712 }, | |
37713 | |
37714 distributeDatasets : function(datasets) { | |
37715 GeoTemConfig.addDatasets(datasets); | |
37716 }, | |
37717 | |
37718 addStaticLoader : function() { | |
37719 if (this.options.staticKML.length > 0){ | |
37720 $(this.parent.gui.loaderTypeSelect).append("<option value='StaticLoader'>Static Data</option>"); | |
37721 | |
37722 this.StaticLoaderTab = document.createElement("div"); | |
37723 $(this.StaticLoaderTab).attr("id","StaticLoader"); | |
37724 | |
37725 this.staticKMLList = document.createElement("select"); | |
37726 $(this.StaticLoaderTab).append(this.staticKMLList); | |
37727 | |
37728 var staticKMLList = this.staticKMLList; | |
37729 var isFirstHeader = true; | |
37730 $(this.options.staticKML).each(function(){ | |
37731 var label = this.label; | |
37732 var url = this.url; | |
37733 var header = this.header; | |
37734 if (typeof header !== "undefined"){ | |
37735 if (!isFirstHeader) | |
37736 $(staticKMLList).append("</optgroup>"); | |
37737 $(staticKMLList).append("<optgroup label='"+header+"'>"); | |
37738 isFirstHeader = false; | |
37739 } else | |
37740 $(staticKMLList).append("<option value='"+url+"'> "+label+"</option>"); | |
37741 }); | |
37742 //close last optgroup (if there were any) | |
37743 if (!isFirstHeader) | |
37744 $(staticKMLList).append("</optgroup>"); | |
37745 | |
37746 this.loadStaticKMLButton = document.createElement("button"); | |
37747 $(this.loadStaticKMLButton).text("load"); | |
37748 $(this.StaticLoaderTab).append(this.loadStaticKMLButton); | |
37749 | |
37750 $(this.loadStaticKMLButton).click($.proxy(function(){ | |
37751 var kmlURL = $(this.staticKMLList).find(":selected").attr("value"); | |
37752 if (kmlURL.length === 0) | |
37753 return; | |
37754 var origURL = kmlURL; | |
37755 var fileName = this.getFileName(kmlURL); | |
37756 if (typeof GeoTemConfig.proxy != 'undefined') | |
37757 kmlURL = GeoTemConfig.proxy + kmlURL; | |
37758 var kml = GeoTemConfig.getKml(kmlURL); | |
37759 if ((typeof kml !== "undefined") && (kml != null)) { | |
37760 var dataSet = new Dataset(GeoTemConfig.loadKml(kml), fileName, origURL); | |
37761 | |
37762 if (dataSet != null) | |
37763 this.distributeDataset(dataSet); | |
37764 } else | |
37765 alert("Could not load file."); | |
37766 },this)); | |
37767 | |
37768 $(this.parent.gui.loaders).append(this.StaticLoaderTab); | |
37769 } | |
37770 }, | |
37771 | |
37772 addKMLLoader : function() { | |
37773 $(this.parent.gui.loaderTypeSelect).append("<option value='KMLLoader'>KML File URL</option>"); | |
37774 | |
37775 this.KMLLoaderTab = document.createElement("div"); | |
37776 $(this.KMLLoaderTab).attr("id","KMLLoader"); | |
37777 | |
37778 this.kmlURL = document.createElement("input"); | |
37779 $(this.kmlURL).attr("type","text"); | |
37780 $(this.KMLLoaderTab).append(this.kmlURL); | |
37781 | |
37782 this.loadKMLButton = document.createElement("button"); | |
37783 $(this.loadKMLButton).text("load KML"); | |
37784 $(this.KMLLoaderTab).append(this.loadKMLButton); | |
37785 | |
37786 $(this.loadKMLButton).click($.proxy(function(){ | |
37787 var kmlURL = $(this.kmlURL).val(); | |
37788 if (kmlURL.length === 0) | |
37789 return; | |
37790 var origURL = kmlURL; | |
37791 var fileName = this.getFileName(kmlURL); | |
37792 if (typeof GeoTemConfig.proxy != 'undefined') | |
37793 kmlURL = GeoTemConfig.proxy + kmlURL; | |
37794 var kml = GeoTemConfig.getKml(kmlURL); | |
37795 if ((typeof kml !== "undefined") && (kml != null)) { | |
37796 var dataSet = new Dataset(GeoTemConfig.loadKml(kml), fileName, origURL); | |
37797 | |
37798 if (dataSet != null) | |
37799 this.distributeDataset(dataSet); | |
37800 } else | |
37801 alert("Could not load file."); | |
37802 },this)); | |
37803 | |
37804 $(this.parent.gui.loaders).append(this.KMLLoaderTab); | |
37805 }, | |
37806 | |
37807 addKMZLoader : function() { | |
37808 $(this.parent.gui.loaderTypeSelect).append("<option value='KMZLoader'>KMZ File URL</option>"); | |
37809 | |
37810 this.KMZLoaderTab = document.createElement("div"); | |
37811 $(this.KMZLoaderTab).attr("id","KMZLoader"); | |
37812 | |
37813 this.kmzURL = document.createElement("input"); | |
37814 $(this.kmzURL).attr("type","text"); | |
37815 $(this.KMZLoaderTab).append(this.kmzURL); | |
37816 | |
37817 this.loadKMZButton = document.createElement("button"); | |
37818 $(this.loadKMZButton).text("load KMZ"); | |
37819 $(this.KMZLoaderTab).append(this.loadKMZButton); | |
37820 | |
37821 $(this.loadKMZButton).click($.proxy(function(){ | |
37822 | |
37823 var dataLoader = this; | |
37824 | |
37825 var kmzURL = $(this.kmzURL).val(); | |
37826 if (kmzURL.length === 0) | |
37827 return; | |
37828 var origURL = kmzURL; | |
37829 var fileName = dataLoader.getFileName(kmzURL); | |
37830 if (typeof GeoTemConfig.proxy != 'undefined') | |
37831 kmzURL = GeoTemConfig.proxy + kmzURL; | |
37832 | |
37833 GeoTemConfig.getKmz(kmzURL, function(kmlArray){ | |
37834 $(kmlArray).each(function(){ | |
37835 var dataSet = new Dataset(GeoTemConfig.loadKml(this), fileName, origURL); | |
37836 | |
37837 if (dataSet != null) | |
37838 dataLoader.distributeDataset(dataSet); | |
37839 }); | |
37840 }); | |
37841 },this)); | |
37842 | |
37843 $(this.parent.gui.loaders).append(this.KMZLoaderTab); | |
37844 }, | |
37845 | |
37846 addCSVLoader : function() { | |
37847 $(this.parent.gui.loaderTypeSelect).append("<option value='CSVLoader'>CSV File URL</option>"); | |
37848 | |
37849 this.CSVLoaderTab = document.createElement("div"); | |
37850 $(this.CSVLoaderTab).attr("id","CSVLoader"); | |
37851 | |
37852 this.csvURL = document.createElement("input"); | |
37853 $(this.csvURL).attr("type","text"); | |
37854 $(this.CSVLoaderTab).append(this.csvURL); | |
37855 | |
37856 this.loadCSVButton = document.createElement("button"); | |
37857 $(this.loadCSVButton).text("load CSV"); | |
37858 $(this.CSVLoaderTab).append(this.loadCSVButton); | |
37859 | |
37860 $(this.loadCSVButton).click($.proxy(function(){ | |
37861 var dataLoader = this; | |
37862 | |
37863 var csvURL = $(this.csvURL).val(); | |
37864 if (csvURL.length === 0) | |
37865 return; | |
37866 var origURL = csvURL; | |
37867 var fileName = dataLoader.getFileName(csvURL); | |
37868 if (typeof GeoTemConfig.proxy != 'undefined') | |
37869 csvURL = GeoTemConfig.proxy + csvURL; | |
37870 GeoTemConfig.getCsv(csvURL, function(json){ | |
37871 if ((typeof json !== "undefined") && (json.length > 0)) { | |
37872 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL); | |
37873 | |
37874 if (dataSet != null) | |
37875 dataLoader.distributeDataset(dataSet); | |
37876 } else | |
37877 alert("Could not load file."); | |
37878 }); | |
37879 },this)); | |
37880 | |
37881 $(this.parent.gui.loaders).append(this.CSVLoaderTab); | |
37882 }, | |
37883 | |
37884 addLocalKMLLoader : function() { | |
37885 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalKMLLoader'>local KML File</option>"); | |
37886 | |
37887 this.localKMLLoaderTab = document.createElement("div"); | |
37888 $(this.localKMLLoaderTab).attr("id","LocalKMLLoader"); | |
37889 | |
37890 this.kmlFile = document.createElement("input"); | |
37891 $(this.kmlFile).attr("type","file"); | |
37892 $(this.localKMLLoaderTab).append(this.kmlFile); | |
37893 | |
37894 this.loadLocalKMLButton = document.createElement("button"); | |
37895 $(this.loadLocalKMLButton).text("load KML"); | |
37896 $(this.localKMLLoaderTab).append(this.loadLocalKMLButton); | |
37897 | |
37898 $(this.loadLocalKMLButton).click($.proxy(function(){ | |
37899 var filelist = $(this.kmlFile).get(0).files; | |
37900 if (filelist.length > 0){ | |
37901 var file = filelist[0]; | |
37902 var fileName = file.name; | |
37903 var reader = new FileReader(); | |
37904 | |
37905 reader.onloadend = ($.proxy(function(theFile) { | |
37906 return function(e) { | |
37907 var dataSet = new Dataset(GeoTemConfig.loadKml($.parseXML(reader.result)), fileName); | |
37908 if (dataSet != null) | |
37909 this.distributeDataset(dataSet); | |
37910 }; | |
37911 }(file),this)); | |
37912 | |
37913 reader.readAsText(file); | |
37914 } | |
37915 },this)); | |
37916 | |
37917 $(this.parent.gui.loaders).append(this.localKMLLoaderTab); | |
37918 }, | |
37919 | |
37920 addLocalCSVLoader : function() { | |
37921 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalCSVLoader'>local CSV File</option>"); | |
37922 | |
37923 this.localCSVLoaderTab = document.createElement("div"); | |
37924 $(this.localCSVLoaderTab).attr("id","LocalCSVLoader"); | |
37925 | |
37926 this.csvFile = document.createElement("input"); | |
37927 $(this.csvFile).attr("type","file"); | |
37928 $(this.localCSVLoaderTab).append(this.csvFile); | |
37929 | |
37930 this.loadLocalCSVButton = document.createElement("button"); | |
37931 $(this.loadLocalCSVButton).text("load CSV"); | |
37932 $(this.localCSVLoaderTab).append(this.loadLocalCSVButton); | |
37933 | |
37934 $(this.loadLocalCSVButton).click($.proxy(function(){ | |
37935 var filelist = $(this.csvFile).get(0).files; | |
37936 if (filelist.length > 0){ | |
37937 var file = filelist[0]; | |
37938 var fileName = file.name; | |
37939 var reader = new FileReader(); | |
37940 | |
37941 reader.onloadend = ($.proxy(function(theFile) { | |
37942 return function(e) { | |
37943 var json = GeoTemConfig.convertCsv(reader.result); | |
37944 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName); | |
37945 if (dataSet != null) | |
37946 this.distributeDataset(dataSet); | |
37947 }; | |
37948 }(file),this)); | |
37949 | |
37950 reader.readAsText(file); | |
37951 } | |
37952 },this)); | |
37953 | |
37954 $(this.parent.gui.loaders).append(this.localCSVLoaderTab); | |
37955 }, | |
37956 | |
37957 addLocalStorageLoader : function() { | |
37958 var dataLoader = this; | |
37959 this.localStorageLoaderTab = document.createElement("div"); | |
37960 $(this.localStorageLoaderTab).attr("id","LocalStorageLoader"); | |
37961 | |
37962 var localDatasets = document.createElement("select"); | |
37963 $(this.localStorageLoaderTab).append(localDatasets); | |
37964 | |
37965 var localStorageDatasetCount = 0; | |
37966 for(var key in localStorage){ | |
37967 //TODO: this is a somewhat bad idea, as it is used in multiple widgets. | |
37968 //A global GeoTemCo option "prefix" could be better. But still.. | |
37969 if (key.startsWith("GeoBrowser_dataset_")){ | |
37970 localStorageDatasetCount++; | |
37971 var label = key.substring("GeoBrowser_dataset_".length); | |
37972 var url = key; | |
37973 $(localDatasets).append("<option value='"+url+"'>"+decodeURIComponent(label)+"</option>"); | |
37974 } | |
37975 } | |
37976 | |
37977 //only show if there are datasets | |
37978 if (localStorageDatasetCount > 0) | |
37979 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalStorageLoader'>browser storage</option>"); | |
37980 | |
37981 this.loadLocalStorageButton = document.createElement("button"); | |
37982 $(this.loadLocalStorageButton).text("load"); | |
37983 $(this.localStorageLoaderTab).append(this.loadLocalStorageButton); | |
37984 | |
37985 $(this.loadLocalStorageButton).click($.proxy(function(){ | |
37986 var fileKey = $(localDatasets).find(":selected").attr("value"); | |
37987 if (fileKey.length === 0) | |
37988 return; | |
37989 var csv = $.remember({name:fileKey}); | |
37990 //TODO: this is a somewhat bad idea, as it is used in multiple widgets. | |
37991 //A global GeoTemCo option "prefix" could be better. But still.. | |
37992 var fileName = decodeURIComponent(fileKey.substring("GeoBrowser_dataset_".length)); | |
37993 var json = GeoTemConfig.convertCsv(csv); | |
37994 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, fileKey, "local"); | |
37995 if (dataSet != null) | |
37996 dataLoader.distributeDataset(dataSet); | |
37997 },this)); | |
37998 | |
37999 $(this.parent.gui.loaders).append(this.localStorageLoaderTab); | |
38000 } | |
38001 }; | |
38002 /* | |
38003 * DataloaderConfig.js | |
38004 * | |
38005 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38006 * | |
38007 * This library is free software; you can redistribute it and/or | |
38008 * modify it under the terms of the GNU Lesser General Public | |
38009 * License as published by the Free Software Foundation; either | |
38010 * version 3 of the License, or (at your option) any later version. | |
38011 * | |
38012 * This library is distributed in the hope that it will be useful, | |
38013 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38015 * Lesser General Public License for more details. | |
38016 * | |
38017 * You should have received a copy of the GNU Lesser General Public | |
38018 * License along with this library; if not, write to the Free Software | |
38019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38020 * MA 02110-1301 USA | |
38021 */ | |
38022 | |
38023 /** | |
38024 * @class DataloaderConfig | |
38025 * Dataloader Configuration File | |
38026 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38027 */ | |
38028 function DataloaderConfig(options) { | |
38029 | |
38030 this.options = { | |
38031 staticKML : [ | |
38032 // {header: "header label"}, | |
38033 // {label: "Johann Wolfgang von Goethe", url:"http://.../goethe.kml" }, | |
38034 ] | |
38035 }; | |
38036 if ( typeof options != 'undefined') { | |
38037 $.extend(this.options, options); | |
38038 } | |
38039 | |
38040 }; | |
38041 /* | |
38042 * DataloaderGui.js | |
38043 * | |
38044 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38045 * | |
38046 * This library is free software; you can redistribute it and/or | |
38047 * modify it under the terms of the GNU Lesser General Public | |
38048 * License as published by the Free Software Foundation; either | |
38049 * version 3 of the License, or (at your option) any later version. | |
38050 * | |
38051 * This library is distributed in the hope that it will be useful, | |
38052 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38053 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38054 * Lesser General Public License for more details. | |
38055 * | |
38056 * You should have received a copy of the GNU Lesser General Public | |
38057 * License along with this library; if not, write to the Free Software | |
38058 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38059 * MA 02110-1301 USA | |
38060 */ | |
38061 | |
38062 /** | |
38063 * @class DataloaderGui | |
38064 * Dataloader GUI Implementation | |
38065 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38066 * | |
38067 * @param {DataloaderWidget} parent Dataloader widget object | |
38068 * @param {HTML object} div parent div to append the Dataloader gui | |
38069 * @param {JSON} options Dataloader configuration | |
38070 */ | |
38071 function DataloaderGui(dataloader, div, options) { | |
38072 | |
38073 var dataloaderGui = this; | |
38074 | |
38075 this.dataloaderContainer = div; | |
38076 this.dataloaderContainer.style.position = 'relative'; | |
38077 | |
38078 this.loaderTypeSelect = document.createElement("select"); | |
38079 div.appendChild(this.loaderTypeSelect); | |
38080 | |
38081 this.loaders = document.createElement("div"); | |
38082 div.appendChild(this.loaders); | |
38083 | |
38084 $(this.loaderTypeSelect).change(function(){ | |
38085 var activeLoader = $(this).val(); | |
38086 $(dataloaderGui.loaders).find("div").each(function(){ | |
38087 if ($(this).attr("id") == activeLoader) | |
38088 $(this).show(); | |
38089 else | |
38090 $(this).hide(); | |
38091 }); | |
38092 }); | |
38093 }; | |
38094 /* | |
38095 * DataloaderWidget.js | |
38096 * | |
38097 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38098 * | |
38099 * This library is free software; you can redistribute it and/or | |
38100 * modify it under the terms of the GNU Lesser General Public | |
38101 * License as published by the Free Software Foundation; either | |
38102 * version 3 of the License, or (at your option) any later version. | |
38103 * | |
38104 * This library is distributed in the hope that it will be useful, | |
38105 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38106 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38107 * Lesser General Public License for more details. | |
38108 * | |
38109 * You should have received a copy of the GNU Lesser General Public | |
38110 * License along with this library; if not, write to the Free Software | |
38111 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38112 * MA 02110-1301 USA | |
38113 */ | |
38114 | |
38115 /** | |
38116 * @class DataloaderWidget | |
38117 * DataloaderWidget Implementation | |
38118 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38119 * | |
38120 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
38121 * @param {HTML object} div parent div to append the Dataloader widget div | |
38122 * @param {JSON} options user specified configuration that overwrites options in DataloaderConfig.js | |
38123 */ | |
38124 DataloaderWidget = function(core, div, options) { | |
38125 | |
38126 this.core = core; | |
38127 this.core.setWidget(this); | |
38128 | |
38129 this.options = (new DataloaderConfig(options)).options; | |
38130 this.gui = new DataloaderGui(this, div, this.options); | |
38131 | |
38132 this.dataLoader = new Dataloader(this); | |
38133 } | |
38134 | |
38135 DataloaderWidget.prototype = { | |
38136 | |
38137 initWidget : function() { | |
38138 | |
38139 var dataloaderWidget = this; | |
38140 }, | |
38141 | |
38142 highlightChanged : function(objects) { | |
38143 if( !GeoTemConfig.highlightEvents ){ | |
38144 return; | |
38145 } | |
38146 }, | |
38147 | |
38148 selectionChanged : function(selection) { | |
38149 if( !GeoTemConfig.selectionEvents ){ | |
38150 return; | |
38151 } | |
38152 }, | |
38153 | |
38154 triggerHighlight : function(item) { | |
38155 }, | |
38156 | |
38157 tableSelection : function() { | |
38158 }, | |
38159 | |
38160 deselection : function() { | |
38161 }, | |
38162 | |
38163 filtering : function() { | |
38164 }, | |
38165 | |
38166 inverseFiltering : function() { | |
38167 }, | |
38168 | |
38169 triggerRefining : function() { | |
38170 }, | |
38171 | |
38172 reset : function() { | |
38173 }, | |
38174 | |
38175 loadFromURL : function() { | |
38176 var dataLoaderWidget = this; | |
38177 //using jQuery-URL-Parser (https://github.com/skruse/jQuery-URL-Parser) | |
38178 var datasets = []; | |
38179 $.each($.url().param(),function(paramName, paramValue){ | |
38180 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
38181 var fileName = dataLoaderWidget.dataLoader.getFileName(paramValue); | |
38182 var origURL = paramValue; | |
38183 if (typeof GeoTemConfig.proxy != 'undefined') | |
38184 paramValue = GeoTemConfig.proxy + paramValue; | |
38185 if (paramName.toLowerCase().startsWith("kml")){ | |
38186 var kmlDoc = GeoTemConfig.getKml(paramValue); | |
38187 var dataSet = new Dataset(GeoTemConfig.loadKml(kmlDoc), fileName, origURL); | |
38188 if (dataSet != null){ | |
38189 var datasetID = parseInt(paramName.substr(3)); | |
38190 if (!isNaN(datasetID)){ | |
38191 datasets[datasetID] = dataSet; | |
38192 } else { | |
38193 datasets.push(dataSet); | |
38194 } | |
38195 } | |
38196 } | |
38197 else if (paramName.toLowerCase().startsWith("csv")){ | |
38198 var json = GeoTemConfig.getCsv(paramValue); | |
38199 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL); | |
38200 if (dataSet != null){ | |
38201 var datasetID = parseInt(paramName.substr(3)); | |
38202 if (!isNaN(datasetID)){ | |
38203 datasets[datasetID] = dataSet; | |
38204 } else { | |
38205 datasets.push(dataSet); | |
38206 } | |
38207 } | |
38208 } | |
38209 else if (paramName.toLowerCase().startsWith("json")){ | |
38210 var json = GeoTemConfig.getJson(paramValue); | |
38211 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL); | |
38212 if (dataSet != null){ | |
38213 var datasetID = parseInt(paramName.substr(4)); | |
38214 if (!isNaN(datasetID)){ | |
38215 datasets[datasetID] = dataSet; | |
38216 } else { | |
38217 datasets.push(dataSet); | |
38218 } | |
38219 } | |
38220 } | |
38221 else if (paramName.toLowerCase().startsWith("local")){ | |
38222 var csv = $.remember({name:encodeURIComponent(origURL)}); | |
38223 //TODO: this is a bad idea and will be changed upon having a better | |
38224 //usage model for local stored data | |
38225 var fileName = origURL.substring("GeoBrowser_dataset_".length); | |
38226 var json = GeoTemConfig.convertCsv(csv); | |
38227 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL, "local"); | |
38228 if (dataSet != null){ | |
38229 var datasetID = parseInt(paramName.substr(5)); | |
38230 if (!isNaN(datasetID)){ | |
38231 datasets[datasetID] = dataSet; | |
38232 } else { | |
38233 datasets.push(dataSet); | |
38234 } | |
38235 } | |
38236 } | |
38237 }); | |
38238 //load (optional!) attribute renames | |
38239 //each rename param is {latitude:..,longitude:..,place:..,date:..,timeSpanBegin:..,timeSpanEnd:..} | |
38240 //examples: | |
38241 // &rename1={"latitude":"lat1","longitude":"lon1"} | |
38242 // &rename2=[{"latitude":"lat1","longitude":"lon1"},{"latitude":"lat2","longitude":"lon2"}] | |
38243 $.each($.url().param(),function(paramName, paramValue){ | |
38244 if (paramName.toLowerCase().startsWith("rename")){ | |
38245 var datasetID = parseInt(paramName.substr(6)); | |
38246 var dataset; | |
38247 if (isNaN(datasetID)){ | |
38248 var dataset; | |
38249 for (datasetID in datasets){ | |
38250 break; | |
38251 } | |
38252 } | |
38253 dataset = datasets[datasetID]; | |
38254 | |
38255 if (typeof dataset === "undefined") | |
38256 return; | |
38257 | |
38258 var renameFunc = function(index,latAttr,lonAttr,placeAttr,dateAttr,timespanBeginAttr, | |
38259 timespanEndAttr,indexAttr){ | |
38260 var renameArray = []; | |
38261 | |
38262 if (typeof index === "undefined"){ | |
38263 index = 0; | |
38264 } | |
38265 | |
38266 if ((typeof latAttr !== "undefined") && (typeof lonAttr !== "undefined")){ | |
38267 renameArray.push({ | |
38268 oldColumn:latAttr, | |
38269 newColumn:"locations["+index+"].latitude" | |
38270 }); | |
38271 renameArray.push({ | |
38272 oldColumn:lonAttr, | |
38273 newColumn:"locations["+index+"].longitude" | |
38274 }); | |
38275 } | |
38276 | |
38277 if (typeof placeAttr !== "undefined"){ | |
38278 renameArray.push({ | |
38279 oldColumn:placeAttr, | |
38280 newColumn:"locations["+index+"].place" | |
38281 }); | |
38282 } | |
38283 | |
38284 if (typeof dateAttr !== "undefined"){ | |
38285 renameArray.push({ | |
38286 oldColumn:dateAttr, | |
38287 newColumn:"dates["+index+"]" | |
38288 }); | |
38289 } | |
38290 | |
38291 if ((typeof timespanBeginAttr !== "undefined") && | |
38292 (typeof timespanEndAttr !== "undefined")){ | |
38293 renameArray.push({ | |
38294 oldColumn:timespanBeginAttr, | |
38295 newColumn:"tableContent[TimeSpan:begin]" | |
38296 }); | |
38297 renameArray.push({ | |
38298 oldColumn:timespanEndAttr, | |
38299 newColumn:"tableContent[TimeSpan:end]" | |
38300 }); | |
38301 } | |
38302 | |
38303 if (typeof indexAttr !== "undefined"){ | |
38304 renameArray.push({ | |
38305 oldColumn:indexAttr, | |
38306 newColumn:"index" | |
38307 }); | |
38308 } | |
38309 | |
38310 GeoTemConfig.renameColumns(dataset,renameArray); | |
38311 }; | |
38312 | |
38313 var renames = JSON.parse(paramValue); | |
38314 | |
38315 if (renames instanceof Array){ | |
38316 for (var i=0; i < renames.length; i++){ | |
38317 renameFunc(i,renames[i].latitude,renames[i].longitude,renames[i].place,renames[i].date, | |
38318 renames[i].timeSpanBegin,renames[i].timeSpanEnd,renames[i].index); | |
38319 } | |
38320 } else { | |
38321 renameFunc(0,renames.latitude,renames.longitude,renames.place,renames.date, | |
38322 renames.timeSpanBegin,renames.timeSpanEnd,renames.index); | |
38323 } | |
38324 } | |
38325 }); | |
38326 //load (optional!) filters | |
38327 //those will create a new(!) dataset, that only contains the filtered IDs | |
38328 $.each($.url().param(),function(paramName, paramValue){ | |
38329 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
38330 if (paramName.toLowerCase().startsWith("filter")){ | |
38331 var datasetID = parseInt(paramName.substr(6)); | |
38332 var dataset; | |
38333 if (isNaN(datasetID)){ | |
38334 var dataset; | |
38335 for (datasetID in datasets){ | |
38336 break; | |
38337 } | |
38338 } | |
38339 dataset = datasets[datasetID]; | |
38340 | |
38341 if (typeof dataset === "undefined") | |
38342 return; | |
38343 | |
38344 var filterValues = function(paramValue){ | |
38345 var filter = JSON.parse(paramValue); | |
38346 var filteredObjects = []; | |
38347 for(var i = 0; i < dataset.objects.length; i++){ | |
38348 var dataObject = dataset.objects[i]; | |
38349 if ($.inArray(dataObject.index,filter) != -1){ | |
38350 filteredObjects.push(dataObject); | |
38351 } | |
38352 } | |
38353 var filteredDataset = new Dataset(filteredObjects, dataset.label + " (filtered)", dataset.url, dataset.type); | |
38354 datasets.push(filteredDataset); | |
38355 } | |
38356 | |
38357 if (paramValue instanceof Array){ | |
38358 for (var i=0; i < paramValue.length; i++){ | |
38359 filterValues(paramValue[i]); | |
38360 } | |
38361 } else { | |
38362 filterValues(paramValue); | |
38363 } | |
38364 | |
38365 } | |
38366 }); | |
38367 //Load the (optional!) dataset colors | |
38368 $.each($.url().param(),function(paramName, paramValue){ | |
38369 if (paramName.toLowerCase().startsWith("color")){ | |
38370 //color is 1-based, index is 0-based! | |
38371 var datasetID = parseInt(paramName.substring("color".length))-1; | |
38372 if (datasets.length > datasetID){ | |
38373 if (typeof datasets[datasetID].color === "undefined"){ | |
38374 var color = new Object(); | |
38375 var colorsSelectedUnselected = paramValue.split(","); | |
38376 if (colorsSelectedUnselected.length > 2) | |
38377 return; | |
38378 | |
38379 var color1 = colorsSelectedUnselected[0]; | |
38380 if (color1.length != 6) | |
38381 return; | |
38382 | |
38383 color.r1 = parseInt(color1.substr(0,2),16); | |
38384 color.g1 = parseInt(color1.substr(2,2),16); | |
38385 color.b1 = parseInt(color1.substr(4,2),16); | |
38386 | |
38387 //check if a unselected color is given | |
38388 if (colorsSelectedUnselected.length == 2){ | |
38389 var color0 = colorsSelectedUnselected[1]; | |
38390 if (color0.length != 6) | |
38391 return; | |
38392 | |
38393 color.r0 = parseInt(color0.substr(0,2),16); | |
38394 color.g0 = parseInt(color0.substr(2,2),16); | |
38395 color.b0 = parseInt(color0.substr(4,2),16); | |
38396 } else { | |
38397 //if not: use the selected color "halved" | |
38398 color.r0 = Math.round(color.r1/2); | |
38399 color.g0 = Math.round(color.g1/2); | |
38400 color.b0 = Math.round(color.b1/2); | |
38401 } | |
38402 | |
38403 datasets[datasetID].color = color; | |
38404 } | |
38405 } | |
38406 } | |
38407 }); | |
38408 //delete undefined entries in the array | |
38409 //(can happen if the sequence given in the URL is not complete | |
38410 // e.g. kml0=..,kml2=..) | |
38411 //this also reorders the array, starting with 0 | |
38412 var tempDatasets = []; | |
38413 for(var index in datasets){ | |
38414 if (datasets[index] instanceof Dataset){ | |
38415 tempDatasets.push(datasets[index]); | |
38416 } | |
38417 } | |
38418 datasets = tempDatasets; | |
38419 | |
38420 if (datasets.length > 0) | |
38421 dataLoaderWidget.dataLoader.distributeDatasets(datasets); | |
38422 } | |
38423 }; | |
38424 /* | |
38425 * FuzzyTimelineConfig.js | |
38426 * | |
38427 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38428 * | |
38429 * This library is free software; you can redistribute it and/or | |
38430 * modify it under the terms of the GNU Lesser General Public | |
38431 * License as published by the Free Software Foundation; either | |
38432 * version 3 of the License, or (at your option) any later version. | |
38433 * | |
38434 * This library is distributed in the hope that it will be useful, | |
38435 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38436 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38437 * Lesser General Public License for more details. | |
38438 * | |
38439 * You should have received a copy of the GNU Lesser General Public | |
38440 * License along with this library; if not, write to the Free Software | |
38441 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38442 * MA 02110-1301 USA | |
38443 */ | |
38444 | |
38445 /** | |
38446 * @class FuzzyTimelineConfig | |
38447 * FuzzyTimeline Configuration File | |
38448 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38449 */ | |
38450 function FuzzyTimelineConfig(options) { | |
38451 | |
38452 this.options = { | |
38453 //TODO: experiment with number of ticks, 150 seems to be ok for now | |
38454 maxBars : 50, | |
38455 maxDensityTicks : 150, | |
38456 /*drawing modes: | |
38457 * fuzzy - weight is distributed over all spans an object overlaps, so that the sum remains the weight, | |
38458 * stacking - every span that on object overlaps gets the complete weight (limited by the amount the span is overlapped, e.g. first span and last might get less) | |
38459 */ | |
38460 timelineMode : 'stacking', | |
38461 showRangePiechart : false, | |
38462 backgroundColor : "#EEEEEE", | |
38463 showYAxis : true, | |
38464 //whether time-spans that "enlargen" the plot are allowed | |
38465 //if set to true, a span that creates more "bars" than fit on the screen | |
38466 //will lead to a width-increase of the chart (and a scroll bar appears) | |
38467 showAllPossibleSpans : true, | |
38468 }; | |
38469 if ( typeof options != 'undefined') { | |
38470 $.extend(this.options, options); | |
38471 } | |
38472 | |
38473 }; | |
38474 /* | |
38475 * FuzzyTimelineDensity.js | |
38476 * | |
38477 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38478 * | |
38479 * This library is free software; you can redistribute it and/or | |
38480 * modify it under the terms of the GNU Lesser General Public | |
38481 * License as published by the Free Software Foundation; either | |
38482 * version 3 of the License, or (at your option) any later version. | |
38483 * | |
38484 * This library is distributed in the hope that it will be useful, | |
38485 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38486 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38487 * Lesser General Public License for more details. | |
38488 * | |
38489 * You should have received a copy of the GNU Lesser General Public | |
38490 * License along with this library; if not, write to the Free Software | |
38491 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38492 * MA 02110-1301 USA | |
38493 */ | |
38494 | |
38495 /** | |
38496 * @class FuzzyTimelineDensity | |
38497 * Implementation for a fuzzy time-ranges density plot | |
38498 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38499 * | |
38500 * @param {HTML object} parent div to append the FuzzyTimeline | |
38501 */ | |
38502 function FuzzyTimelineDensity(parent,div) { | |
38503 | |
38504 this.index; | |
38505 this.fuzzyTimeline = this; | |
38506 this.singleTickWidth; | |
38507 this.singleTickCenter = function(){return this.singleTickWidth/2;}; | |
38508 //contains all data | |
38509 this.datasetsPlot; | |
38510 this.datasetsHash; | |
38511 this.highlightedDatasetsPlot; | |
38512 this.yValMin; | |
38513 this.yValMax; | |
38514 this.displayType; | |
38515 //contains selected data | |
38516 this.selected = undefined; | |
38517 //contains the last selected "date" | |
38518 this.highlighted; | |
38519 | |
38520 this.parent = parent; | |
38521 this.div = div; | |
38522 this.options = parent.options; | |
38523 this.plot; | |
38524 this.maxTickCount = this.options.maxDensityTicks; | |
38525 | |
38526 this.datasets; | |
38527 } | |
38528 | |
38529 FuzzyTimelineDensity.prototype = { | |
38530 | |
38531 initialize : function(datasets) { | |
38532 var density = this; | |
38533 | |
38534 density.datasets = datasets; | |
38535 density.selected = []; | |
38536 }, | |
38537 | |
38538 createPlot : function(data){ | |
38539 density = this; | |
38540 var chartData = []; | |
38541 | |
38542 chartData.push([density.parent.overallMin,0]); | |
38543 $.each(data, function(name,val){ | |
38544 var tickCenterTime = density.parent.overallMin+name*density.singleTickWidth+density.singleTickCenter(); | |
38545 var dateObj = moment(tickCenterTime); | |
38546 chartData.push([dateObj,val]); | |
38547 }); | |
38548 var maxPlotedDate = chartData[chartData.length-1][0]; | |
38549 if (density.parent.overallMax > maxPlotedDate){ | |
38550 chartData.push([density.parent.overallMax,0]); | |
38551 } else { | |
38552 chartData.push([maxPlotedDate+1,0]); | |
38553 } | |
38554 | |
38555 | |
38556 | |
38557 return chartData; | |
38558 }, | |
38559 | |
38560 //uniform distribution (UD) | |
38561 createUDData : function(datasets) { | |
38562 var density = this; | |
38563 var plots = []; | |
38564 var objectHashes = []; | |
38565 $(datasets).each(function(){ | |
38566 var chartDataCounter = new Object(); | |
38567 var objectHash = new Object(); | |
38568 | |
38569 for (var i = 0; i < density.tickCount; i++){ | |
38570 chartDataCounter[i]=0; | |
38571 } | |
38572 //check if we got "real" datasets, or just array of objects | |
38573 var datasetObjects = this; | |
38574 if (typeof this.objects !== "undefined") | |
38575 datasetObjects = this.objects; | |
38576 $(datasetObjects).each(function(){ | |
38577 var ticks = density.parent.getTicks(this, density.singleTickWidth); | |
38578 if (typeof ticks !== "undefined"){ | |
38579 var exactTickCount = | |
38580 ticks.firstTickPercentage+ | |
38581 ticks.lastTickPercentage+ | |
38582 (ticks.lastTick-ticks.firstTick-1); | |
38583 for (var i = ticks.firstTick; i <= ticks.lastTick; i++){ | |
38584 var weight = 0; | |
38585 //calculate the weight for each span, that the object overlaps | |
38586 if (density.parent.options.timelineMode == 'fuzzy'){ | |
38587 //in fuzzy mode, each span gets just a fraction of the complete weight | |
38588 if (i == ticks.firstTick) | |
38589 weight = this.weight * ticks.firstTickPercentage/exactTickCount; | |
38590 else if (i == ticks.lastTick) | |
38591 weight = this.weight * ticks.lastTickPercentage/exactTickCount; | |
38592 else | |
38593 weight = this.weight * 1/exactTickCount; | |
38594 } else if (density.parent.options.timelineMode == 'stacking'){ | |
38595 //in stacking mode each span gets the same amount. | |
38596 //(besides first and last..) | |
38597 if (i == ticks.firstTick) | |
38598 weight = this.weight * ticks.firstTickPercentage; | |
38599 else if (i == ticks.lastTick) | |
38600 weight = this.weight * ticks.lastTickPercentage; | |
38601 else | |
38602 weight = this.weight; | |
38603 } | |
38604 | |
38605 chartDataCounter[i] += weight; | |
38606 //add this object to the hash | |
38607 if (typeof objectHash[i] === "undefined") | |
38608 objectHash[i] = []; | |
38609 objectHash[i].push(this); | |
38610 } | |
38611 } | |
38612 }); | |
38613 | |
38614 //scale according to selected type | |
38615 chartDataCounter = density.parent.scaleData(chartDataCounter); | |
38616 | |
38617 var udChartData = density.createPlot(chartDataCounter); | |
38618 if (udChartData.length > 0) | |
38619 plots.push(udChartData); | |
38620 | |
38621 objectHashes.push(objectHash); | |
38622 }); | |
38623 | |
38624 return {plots:plots, hashs:objectHashes}; | |
38625 }, | |
38626 | |
38627 showPlot : function() { | |
38628 var density = this; | |
38629 var plot = density.datasetsPlot; | |
38630 var highlight_select_plot = $.merge([],plot); | |
38631 | |
38632 //see if there are selected/highlighted values | |
38633 if (density.highlightedDatasetsPlot instanceof Array){ | |
38634 //check if plot is some other - external - graph | |
38635 if (plot === density.datasetsPlot) | |
38636 highlight_select_plot = $.merge(highlight_select_plot,density.highlightedDatasetsPlot); | |
38637 } | |
38638 | |
38639 var axisFormatString = "%Y"; | |
38640 var tooltipFormatString = "YYYY"; | |
38641 if (density.singleTickWidth<60*1000){ | |
38642 axisFormatString = "%Y/%m/%d %H:%M:%S"; | |
38643 tooltipFormatString = "YYYY/MM/DD HH:mm:ss"; | |
38644 } else if (density.singleTickWidth<60*60*1000) { | |
38645 axisFormatString = "%Y/%m/%d %H:%M"; | |
38646 tooltipFormatString = "YYYY/MM/DD HH:mm"; | |
38647 } else if (density.singleTickWidth<24*60*60*1000){ | |
38648 axisFormatString = "%Y/%m/%d %H"; | |
38649 tooltipFormatString = "YYYY/MM/DD HH"; | |
38650 } else if (density.singleTickWidth<31*24*60*60*1000){ | |
38651 axisFormatString = "%Y/%m/%d"; | |
38652 tooltipFormatString = "YYYY/MM/DD"; | |
38653 } else if (density.singleTickWidth<12*31*24*60*60*1000){ | |
38654 axisFormatString = "%Y/%m"; | |
38655 tooltipFormatString = "YYYY/MM"; | |
38656 } | |
38657 | |
38658 //credits: Pimp Trizkit @ http://stackoverflow.com/a/13542669 | |
38659 function shadeRGBColor(color, percent) { | |
38660 var f=color.split(","),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=parseInt(f[0].slice(4)),G=parseInt(f[1]),B=parseInt(f[2]); | |
38661 return "rgb("+(Math.round((t-R)*p)+R)+","+(Math.round((t-G)*p)+G)+","+(Math.round((t-B)*p)+B)+")"; | |
38662 } | |
38663 | |
38664 //credits: Tupak Goliam @ http://stackoverflow.com/a/3821786 | |
38665 var drawLines = function(plot, ctx) { | |
38666 var data = plot.getData(); | |
38667 var axes = plot.getAxes(); | |
38668 var offset = plot.getPlotOffset(); | |
38669 for (var i = 0; i < data.length; i++) { | |
38670 var series = data[i]; | |
38671 var lineWidth = 1; | |
38672 | |
38673 for (var j = 0; j < series.data.length-1; j++) { | |
38674 var d = (series.data[j]); | |
38675 var d2 = (series.data[j+1]); | |
38676 | |
38677 var x = offset.left + axes.xaxis.p2c(d[0]); | |
38678 var y = offset.top + axes.yaxis.p2c(d[1]); | |
38679 | |
38680 var x2 = offset.left + axes.xaxis.p2c(d2[0]); | |
38681 var y2 = offset.top + axes.yaxis.p2c(d2[1]); | |
38682 | |
38683 //hide lines that "connect" 0 and 0 | |
38684 //essentially blanking out the 0 values | |
38685 if ((d[1]==0)&&(d2[1]==0)){ | |
38686 continue; | |
38687 } | |
38688 | |
38689 ctx.strokeStyle=series.color; | |
38690 ctx.lineWidth = lineWidth; | |
38691 ctx.beginPath(); | |
38692 ctx.moveTo(x,y); | |
38693 ctx.lineTo(x2,y2); | |
38694 | |
38695 //add shadow (esp. to make background lines more visible) | |
38696 ctx.shadowColor = shadeRGBColor(series.color,-0.3); | |
38697 ctx.shadowBlur=1; | |
38698 ctx.shadowOffsetX = 1; | |
38699 ctx.shadowOffsetY = 1; | |
38700 | |
38701 ctx.stroke(); | |
38702 } | |
38703 } | |
38704 }; | |
38705 | |
38706 var options = { | |
38707 series:{ | |
38708 //width:0 because line is drawn in own routine above | |
38709 //but everything else (data points, shadow) should be drawn | |
38710 lines:{show: true, lineWidth: 0, shadowSize: 0}, | |
38711 }, | |
38712 grid: { | |
38713 hoverable: true, | |
38714 clickable: true, | |
38715 backgroundColor: density.parent.options.backgroundColor, | |
38716 borderWidth: 0, | |
38717 minBorderMargin: 0, | |
38718 }, | |
38719 legend: { | |
38720 }, | |
38721 tooltip: true, | |
38722 tooltipOpts: { | |
38723 content: function(label, xval, yval, flotItem){ | |
38724 highlightString = moment(xval-density.singleTickCenter()).format(tooltipFormatString) + " - " + | |
38725 moment(xval+density.singleTickCenter()).format(tooltipFormatString) + " : "; | |
38726 //(max.)2 Nachkomma-Stellen von y-Wert anzeigen | |
38727 highlightString += Math.round(yval*100)/100; | |
38728 | |
38729 return highlightString; | |
38730 } | |
38731 }, | |
38732 selection: { | |
38733 mode: "x" | |
38734 }, | |
38735 xaxis: { | |
38736 mode: "time", | |
38737 timeformat:axisFormatString, | |
38738 min : density.parent.overallMin, | |
38739 max : density.parent.overallMax, | |
38740 }, | |
38741 yaxis: { | |
38742 min : density.yValMin, | |
38743 max : density.yValMax*1.05 | |
38744 }, | |
38745 hooks: { | |
38746 draw : drawLines | |
38747 }, | |
38748 }; | |
38749 if (!density.parent.options.showYAxis) | |
38750 options.yaxis.show=false; | |
38751 | |
38752 var highlight_select_plot_colors = []; | |
38753 var i = 0; | |
38754 $(highlight_select_plot).each(function(){ | |
38755 var color; | |
38756 if (i < GeoTemConfig.datasets.length){ | |
38757 var datasetColors = GeoTemConfig.getColor(i); | |
38758 if (highlight_select_plot.length>GeoTemConfig.datasets.length) | |
38759 color = "rgb("+datasetColors.r0+","+datasetColors.g0+","+datasetColors.b0+")"; | |
38760 else | |
38761 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
38762 } else { | |
38763 var datasetColors = GeoTemConfig.getColor(i-GeoTemConfig.datasets.length); | |
38764 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
38765 } | |
38766 | |
38767 highlight_select_plot_colors.push({ | |
38768 color : color, | |
38769 data : this | |
38770 }); | |
38771 i++; | |
38772 }); | |
38773 | |
38774 density.plot = $.plot($(density.div), highlight_select_plot_colors, options); | |
38775 density.parent.drawHandles(); | |
38776 | |
38777 var rangeBars = density.parent.rangeBars; | |
38778 if (typeof rangeBars !== "undefined") | |
38779 $(density.div).unbind("plothover", rangeBars.hoverFunction); | |
38780 $(density.div).unbind("plothover", density.hoverFunction); | |
38781 $(density.div).bind("plothover", density.hoverFunction); | |
38782 | |
38783 //this var prevents the execution of the plotclick event after a select event | |
38784 density.wasSelection = false; | |
38785 $(density.div).unbind("plotclick"); | |
38786 $(density.div).bind("plotclick", density.clickFunction); | |
38787 | |
38788 $(density.div).unbind("plotselected"); | |
38789 $(density.div).bind("plotselected", density.selectFuntion); | |
38790 }, | |
38791 | |
38792 hoverFunction : function (event, pos, item) { | |
38793 var hoverPoint; | |
38794 //TODO: this could be wanted (if negative weight is used) | |
38795 if ((item)&&(item.datapoint[1] != 0)) { | |
38796 //at begin and end of plot there are added 0 points | |
38797 hoverPoint = item.dataIndex-1; | |
38798 } | |
38799 //remember last point, so that we don't redraw the current state | |
38800 //that "hoverPoint" may be undefined is on purpose | |
38801 if (density.highlighted !== hoverPoint){ | |
38802 density.highlighted = hoverPoint; | |
38803 density.triggerHighlight(hoverPoint); | |
38804 } | |
38805 }, | |
38806 | |
38807 clickFunction : function (event, pos, item) { | |
38808 if (density.wasSelection) | |
38809 density.wasSelection = false; | |
38810 else { | |
38811 //remove selection handles (if there were any) | |
38812 density.parent.clearHandles(); | |
38813 | |
38814 var selectPoint; | |
38815 //that date may be undefined is on purpose | |
38816 //TODO: ==0 could be wanted (if negative weight is used) | |
38817 if ((item)&&(item.datapoint[1] != 0)) { | |
38818 //at begin and end of plot there are added 0 points | |
38819 selectPoint = item.dataIndex-1; | |
38820 } | |
38821 density.triggerSelection(selectPoint); | |
38822 } | |
38823 }, | |
38824 | |
38825 selectFuntion : function(event, ranges) { | |
38826 var spanArray = density.parent.getSpanArray(density.singleTickWidth); | |
38827 var startSpan, endSpan; | |
38828 for (var i = 0; i < spanArray.length-1; i++){ | |
38829 if ((typeof startSpan === "undefined") && (ranges.xaxis.from <= spanArray[i+1])) | |
38830 startSpan = i; | |
38831 if ((typeof endSpan === "undefined") && (ranges.xaxis.to <= spanArray[i+1])) | |
38832 endSpan = i; | |
38833 } | |
38834 | |
38835 if ((typeof startSpan !== "undefined") && (typeof endSpan !== "undefined")){ | |
38836 density.triggerSelection(startSpan, endSpan); | |
38837 density.wasSelection = true; | |
38838 | |
38839 density.parent.clearHandles(); | |
38840 var xaxis = density.plot.getAxes().xaxis; | |
38841 var x1 = density.plot.pointOffset({x:ranges.xaxis.from,y:0}).left; | |
38842 var x2 = density.plot.pointOffset({x:ranges.xaxis.to,y:0}).left; | |
38843 | |
38844 density.parent.addHandle(x1,x2); | |
38845 } | |
38846 }, | |
38847 | |
38848 selectByX : function(x1, x2){ | |
38849 density = this; | |
38850 var xaxis = density.plot.getAxes().xaxis; | |
38851 var offset = density.plot.getPlotOffset().left; | |
38852 var from = xaxis.c2p(x1-offset); | |
38853 var to = xaxis.c2p(x2-offset); | |
38854 | |
38855 var spanArray = density.parent.getSpanArray(density.singleTickWidth); | |
38856 var startSpan, endSpan; | |
38857 for (var i = 0; i < spanArray.length-1; i++){ | |
38858 if ((typeof startSpan === "undefined") && (from <= spanArray[i+1])) | |
38859 startSpan = i; | |
38860 if ((typeof endSpan === "undefined") && (to <= spanArray[i+1])) | |
38861 endSpan = i; | |
38862 } | |
38863 | |
38864 if ((typeof startSpan !== "undefined") && (typeof endSpan !== "undefined")){ | |
38865 density.triggerSelection(startSpan, endSpan); | |
38866 } | |
38867 }, | |
38868 | |
38869 drawDensityPlot : function(datasets, tickWidth) { | |
38870 var density = this; | |
38871 //calculate tick width (will be in ms) | |
38872 delete density.tickCount; | |
38873 delete density.singleTickWidth; | |
38874 delete density.highlightedDatasetsPlot; | |
38875 density.parent.zoomPlot(1); | |
38876 if (typeof tickWidth !== "undefined"){ | |
38877 density.singleTickWidth = tickWidth; | |
38878 density.tickCount = Math.ceil((density.parent.overallMax-density.parent.overallMin)/tickWidth); | |
38879 } | |
38880 if ((typeof density.tickCount === "undefined") || (density.tickCount > density.maxTickCount)){ | |
38881 density.tickCount = density.maxTickCount; | |
38882 density.singleTickWidth = (density.parent.overallMax-density.parent.overallMin)/density.tickCount; | |
38883 if (density.singleTickWidth === 0) | |
38884 density.singleTickWidth = 1; | |
38885 } | |
38886 | |
38887 var hashAndPlot = density.createUDData(datasets); | |
38888 | |
38889 density.datasetsPlot = hashAndPlot.plots; | |
38890 density.datasetsHash = hashAndPlot.hashs; | |
38891 | |
38892 density.yValMin = 0; | |
38893 density.yValMax = 0; | |
38894 | |
38895 density.combinedDatasetsPlot = []; | |
38896 for (var i = 0; i < density.datasetsPlot.length; i++){ | |
38897 for (var j = 0; j < density.datasetsPlot[i].length; j++){ | |
38898 var val = density.datasetsPlot[i][j][1]; | |
38899 | |
38900 if (val < density.yValMin) | |
38901 density.yValMin = val; | |
38902 if (val > density.yValMax) | |
38903 density.yValMax = val; | |
38904 } | |
38905 } | |
38906 | |
38907 density.showPlot(); | |
38908 }, | |
38909 | |
38910 triggerHighlight : function(hoverPoint) { | |
38911 var density = this; | |
38912 var highlightedObjects = []; | |
38913 | |
38914 | |
38915 if (typeof hoverPoint !== "undefined") { | |
38916 $(density.datasetsHash).each(function(){ | |
38917 if (typeof this[hoverPoint] !== "undefined") | |
38918 highlightedObjects.push(this[hoverPoint]); | |
38919 else | |
38920 highlightedObjects.push([]); | |
38921 }); | |
38922 } else { | |
38923 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
38924 highlightedObjects.push([]); | |
38925 } | |
38926 this.parent.core.triggerHighlight(highlightedObjects); | |
38927 }, | |
38928 | |
38929 triggerSelection : function(startPoint, endPoint) { | |
38930 var density = this; | |
38931 var selection; | |
38932 if (typeof startPoint !== "undefined") { | |
38933 if (typeof endPoint === "undefined") | |
38934 endPoint = startPoint; | |
38935 density.selected = []; | |
38936 $(density.datasetsHash).each(function(){ | |
38937 var objects = []; | |
38938 for (var i = startPoint; i <= endPoint; i++){ | |
38939 $(this[i]).each(function(){ | |
38940 if ($.inArray(this, objects) == -1){ | |
38941 objects.push(this); | |
38942 } | |
38943 }); | |
38944 } | |
38945 density.selected.push(objects); | |
38946 }); | |
38947 | |
38948 selection = new Selection(density.selected, density.parent); | |
38949 } else { | |
38950 //empty selection | |
38951 density.selected = []; | |
38952 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
38953 density.selected.push([]); | |
38954 selection = new Selection(density.selected); | |
38955 } | |
38956 | |
38957 this.parent.selectionChanged(selection); | |
38958 this.parent.core.triggerSelection(selection); | |
38959 }, | |
38960 | |
38961 highlightChanged : function(objects) { | |
38962 if( !GeoTemConfig.highlightEvents ){ | |
38963 return; | |
38964 } | |
38965 var density = this; | |
38966 var emptyHighlight = true; | |
38967 var selected_highlighted = objects; | |
38968 if (typeof density.selected !== "undefined") | |
38969 selected_highlighted = GeoTemConfig.mergeObjects(objects,density.selected); | |
38970 $(selected_highlighted).each(function(){ | |
38971 if ((this instanceof Array) && (this.length > 0)){ | |
38972 emptyHighlight = false; | |
38973 return false; | |
38974 } | |
38975 }); | |
38976 if (emptyHighlight && (typeof density.selected === "undefined")){ | |
38977 density.highlightedDatasetsPlot = []; | |
38978 } else { | |
38979 density.highlightedDatasetsPlot = density.createUDData(selected_highlighted).plots; | |
38980 } | |
38981 density.showPlot(); | |
38982 }, | |
38983 | |
38984 selectionChanged : function(objects) { | |
38985 if( !GeoTemConfig.selectionEvents ){ | |
38986 return; | |
38987 } | |
38988 var density = this; | |
38989 density.selected = objects; | |
38990 density.highlightChanged([]); | |
38991 }, | |
38992 | |
38993 deselection : function() { | |
38994 }, | |
38995 | |
38996 filtering : function() { | |
38997 }, | |
38998 | |
38999 inverseFiltering : function() { | |
39000 }, | |
39001 | |
39002 triggerRefining : function() { | |
39003 }, | |
39004 | |
39005 reset : function() { | |
39006 }, | |
39007 | |
39008 show : function() { | |
39009 }, | |
39010 | |
39011 hide : function() { | |
39012 } | |
39013 }; | |
39014 /* | |
39015 * FuzzyTimelineGui.js | |
39016 * | |
39017 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39018 * | |
39019 * This library is free software; you can redistribute it and/or | |
39020 * modify it under the terms of the GNU Lesser General Public | |
39021 * License as published by the Free Software Foundation; either | |
39022 * version 3 of the License, or (at your option) any later version. | |
39023 * | |
39024 * This library is distributed in the hope that it will be useful, | |
39025 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39027 * Lesser General Public License for more details. | |
39028 * | |
39029 * You should have received a copy of the GNU Lesser General Public | |
39030 * License along with this library; if not, write to the Free Software | |
39031 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39032 * MA 02110-1301 USA | |
39033 */ | |
39034 | |
39035 /** | |
39036 * @class FuzzyTimelineGui | |
39037 * FuzzyTimeline GUI Implementation | |
39038 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39039 * | |
39040 * @param {FuzzyTimelineWidget} parent FuzzyTimeline widget object | |
39041 * @param {HTML object} div parent div to append the FuzzyTimeline gui | |
39042 * @param {JSON} options FuzzyTimeline configuration | |
39043 */ | |
39044 function FuzzyTimelineGui(fuzzyTimelineWidget, div, options) { | |
39045 | |
39046 this.parent = fuzzyTimelineWidget; | |
39047 var fuzzyTimelineGui = this; | |
39048 | |
39049 this.fuzzyTimelineContainer = div; | |
39050 //if no height is given, draw it in a 32/9 ratio | |
39051 if ($(this.fuzzyTimelineContainer).height() === 0) | |
39052 $(this.fuzzyTimelineContainer).height($(this.fuzzyTimelineContainer).width()*9/32); | |
39053 //this.fuzzyTimelineContainer.style.position = 'relative'; | |
39054 | |
39055 this.sliderTable = document.createElement("table"); | |
39056 $(this.sliderTable).addClass("ddbToolbar"); | |
39057 $(this.sliderTable).width("100%"); | |
39058 $(this.sliderTable).height("49px"); | |
39059 div.appendChild(this.sliderTable); | |
39060 | |
39061 this.plotDIVHeight = $(this.fuzzyTimelineContainer).height()-$(this.sliderTable).height(); | |
39062 var plotScrollContainer = $("<div></div>"); | |
39063 plotScrollContainer.css("overflow-x","auto"); | |
39064 plotScrollContainer.css("overflow-y","hidden"); | |
39065 plotScrollContainer.width("100%"); | |
39066 plotScrollContainer.height(this.plotDIVHeight); | |
39067 $(div).append(plotScrollContainer); | |
39068 this.plotDiv = document.createElement("div"); | |
39069 $(this.plotDiv).width("100%"); | |
39070 $(this.plotDiv).height(this.plotDIVHeight); | |
39071 plotScrollContainer.append(this.plotDiv); | |
39072 if (this.parent.options.showRangePiechart){ | |
39073 this.rangePiechartDiv = document.createElement("div"); | |
39074 $(this.rangePiechartDiv).css("float","right"); | |
39075 //alter plot div width (leave space for piechart) | |
39076 $(this.plotDiv).width("75%"); | |
39077 $(this.rangePiechartDiv).width("25%"); | |
39078 $(this.rangePiechartDiv).height(plotDIVHeight); | |
39079 div.appendChild(this.rangePiechartDiv); | |
39080 } | |
39081 }; | |
39082 | |
39083 FuzzyTimelineGui.prototype = { | |
39084 }; | |
39085 /* | |
39086 * FuzzyTimelineRangeBars.js | |
39087 * | |
39088 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39089 * | |
39090 * This library is free software; you can redistribute it and/or | |
39091 * modify it under the terms of the GNU Lesser General Public | |
39092 * License as published by the Free Software Foundation; either | |
39093 * version 3 of the License, or (at your option) any later version. | |
39094 * | |
39095 * This library is distributed in the hope that it will be useful, | |
39096 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39097 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39098 * Lesser General Public License for more details. | |
39099 * | |
39100 * You should have received a copy of the GNU Lesser General Public | |
39101 * License along with this library; if not, write to the Free Software | |
39102 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39103 * MA 02110-1301 USA | |
39104 */ | |
39105 | |
39106 /** | |
39107 * @class FuzzyTimelineRangeBars | |
39108 * Implementation for a fuzzy time-ranges barchart | |
39109 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39110 * | |
39111 * @param {HTML object} parent div to append the FuzzyTimeline | |
39112 */ | |
39113 function FuzzyTimelineRangeBars(parent) { | |
39114 | |
39115 this.rangeBars = this; | |
39116 | |
39117 this.parent = parent; | |
39118 this.options = parent.options; | |
39119 | |
39120 this.datasets; | |
39121 //contains selected data | |
39122 this.selected = undefined; | |
39123 | |
39124 this.datasetsPlot; | |
39125 this.highlightedDatasetsPlot; | |
39126 this.yValMin; | |
39127 this.yValMax; | |
39128 this.displayType; | |
39129 | |
39130 this.plotDiv = this.parent.gui.plotDiv; | |
39131 | |
39132 this.spanWidth; | |
39133 this.tickSpans; | |
39134 this.plot; | |
39135 } | |
39136 | |
39137 FuzzyTimelineRangeBars.prototype = { | |
39138 | |
39139 initialize : function(datasets) { | |
39140 var rangeBar = this; | |
39141 | |
39142 rangeBar.datasets = datasets; | |
39143 rangeBar.selected = []; | |
39144 }, | |
39145 | |
39146 createPlot : function(datasets) { | |
39147 var rangeBar = this; | |
39148 var plots = []; | |
39149 var objectHashes = []; | |
39150 | |
39151 //-1 because last span is always empty (only there to have the ending date) | |
39152 var tickCount = rangeBar.tickSpans.length-1; | |
39153 | |
39154 $(datasets).each(function(){ | |
39155 var chartDataCounter = []; | |
39156 var objectHash = new Object(); | |
39157 | |
39158 for (var i = 0; i < tickCount; i++){ | |
39159 chartDataCounter[i]=0; | |
39160 } | |
39161 //check if we got "real" datasets, or just array of objects | |
39162 var datasetObjects = this; | |
39163 if (typeof this.objects !== "undefined") | |
39164 datasetObjects = this.objects; | |
39165 $(datasetObjects).each(function(){ | |
39166 var ticks = rangeBar.parent.getTicks(this, rangeBar.spanWidth); | |
39167 if (typeof ticks !== "undefined"){ | |
39168 var exactTickCount = | |
39169 ticks.firstTickPercentage+ | |
39170 ticks.lastTickPercentage+ | |
39171 (ticks.lastTick-ticks.firstTick-1); | |
39172 for (var i = ticks.firstTick; i <= ticks.lastTick; i++){ | |
39173 var weight = 0; | |
39174 //calculate the weight for each span, that the object overlaps | |
39175 if (rangeBar.parent.options.timelineMode == 'fuzzy'){ | |
39176 //in fuzzy mode, each span gets just a fraction of the complete weight | |
39177 if (i == ticks.firstTick) | |
39178 weight = this.weight * ticks.firstTickPercentage/exactTickCount; | |
39179 else if (i == ticks.lastTick) | |
39180 weight = this.weight * ticks.lastTickPercentage/exactTickCount; | |
39181 else | |
39182 weight = this.weight * 1/exactTickCount; | |
39183 } else if (rangeBar.parent.options.timelineMode == 'stacking'){ | |
39184 //in stacking mode each span gets the same amount. | |
39185 //(besides first and last..) | |
39186 if (i == ticks.firstTick) | |
39187 weight = this.weight * ticks.firstTickPercentage; | |
39188 else if (i == ticks.lastTick) | |
39189 weight = this.weight * ticks.lastTickPercentage; | |
39190 else | |
39191 weight = this.weight; | |
39192 | |
39193 weight = this.weight; | |
39194 } | |
39195 | |
39196 chartDataCounter[i] += weight; | |
39197 //add this object to the hash | |
39198 if (typeof objectHash[i] === "undefined") | |
39199 objectHash[i] = []; | |
39200 objectHash[i].push(this); | |
39201 } | |
39202 } | |
39203 }); | |
39204 | |
39205 //scale according to selected type | |
39206 chartDataCounter = rangeBar.parent.scaleData(chartDataCounter); | |
39207 | |
39208 //transform data so it can be passed to the flot barchart | |
39209 var plotData = []; | |
39210 for (var i = 0; i < tickCount; i++){ | |
39211 plotData[i] = []; | |
39212 plotData[i][0] = i; | |
39213 plotData[i][1] = chartDataCounter[i]; | |
39214 } | |
39215 | |
39216 //delete bars with 0 values | |
39217 for (var i = 0; i < tickCount; i++){ | |
39218 if (plotData[i][1]==0) | |
39219 delete plotData[i]; | |
39220 } | |
39221 | |
39222 plots.push(plotData); | |
39223 objectHashes.push(objectHash); | |
39224 }); | |
39225 | |
39226 return {plots:plots, hashs:objectHashes}; | |
39227 }, | |
39228 | |
39229 showPlot : function(){ | |
39230 var rangeBar = this; | |
39231 var plot = rangeBar.datasetsPlot; | |
39232 var highlight_select_plot = $.merge([],plot); | |
39233 | |
39234 //see if there are selected/highlighted values | |
39235 if (rangeBar.highlightedDatasetsPlot instanceof Array){ | |
39236 //check if plot is some other - external - graph | |
39237 if (plot === rangeBar.datasetsPlot) | |
39238 highlight_select_plot = $.merge(highlight_select_plot,rangeBar.highlightedDatasetsPlot); | |
39239 } | |
39240 | |
39241 var tickCount = rangeBar.tickSpans.length-1; | |
39242 var ticks = []; | |
39243 | |
39244 var axisFormatString = "YYYY"; | |
39245 if (rangeBar.spanWidth<60*1000){ | |
39246 axisFormatString = "YYYY/MM/DD HH:mm:ss"; | |
39247 } else if (rangeBar.spanWidth<60*60*1000) { | |
39248 axisFormatString = "YYYY/MM/DD HH:mm"; | |
39249 } else if (rangeBar.spanWidth<24*60*60*1000){ | |
39250 axisFormatString = "YYYY/MM/DD HH"; | |
39251 } else if (rangeBar.spanWidth<31*24*60*60*1000){ | |
39252 axisFormatString = "YYYY/MM/DD"; | |
39253 } else if (rangeBar.spanWidth<12*31*24*60*60*1000){ | |
39254 axisFormatString = "YYYY/MM"; | |
39255 } | |
39256 //only show ~10 labels on the x-Axis (increase if zoomed) | |
39257 var labelModulo = Math.ceil(tickCount/(10*rangeBar.parent.zoomFactor)); | |
39258 for (var i = 0; i < tickCount; i++){ | |
39259 var tickLabel = ""; | |
39260 if (i%labelModulo==0){ | |
39261 tickLabel = rangeBar.tickSpans[i].format(axisFormatString); | |
39262 } | |
39263 while ((tickLabel.length > 1) && (tickLabel.indexOf("0")==0)) | |
39264 tickLabel = tickLabel.substring(1); | |
39265 ticks[i] = [i,tickLabel]; | |
39266 } | |
39267 | |
39268 var options = { | |
39269 series:{ | |
39270 bars:{show: true} | |
39271 }, | |
39272 grid: { | |
39273 hoverable: true, | |
39274 clickable: true, | |
39275 backgroundColor: rangeBar.parent.options.backgroundColor, | |
39276 borderWidth: 0, | |
39277 minBorderMargin: 0, | |
39278 }, | |
39279 xaxis: { | |
39280 ticks: ticks, | |
39281 min : 0, | |
39282 max : tickCount, | |
39283 }, | |
39284 yaxis: { | |
39285 min : rangeBar.yValMin, | |
39286 max : rangeBar.yValMax*1.05 | |
39287 }, | |
39288 tooltip: true, | |
39289 tooltipOpts: { | |
39290 content: function(label, xval, yval, flotItem){ | |
39291 var fromLabel = rangeBar.tickSpans[xval].format(axisFormatString); | |
39292 while ((fromLabel.length > 1) && (fromLabel.indexOf("0")==0)) | |
39293 fromLabel = fromLabel.substring(1); | |
39294 var toLabel = rangeBar.tickSpans[xval+1].clone().subtract("ms",1).format(axisFormatString); | |
39295 while ((toLabel.length > 1) && (toLabel.indexOf("0")==0)) | |
39296 toLabel = toLabel.substring(1); | |
39297 highlightString = fromLabel + " - " + toLabel + " : "; | |
39298 //(max.)2 Nachkomma-Stellen von y-Wert anzeigen | |
39299 highlightString += Math.round(yval*100)/100; | |
39300 | |
39301 return highlightString; | |
39302 } | |
39303 }, | |
39304 selection: { | |
39305 mode: "x" | |
39306 } | |
39307 }; | |
39308 if (!rangeBar.parent.options.showYAxis) | |
39309 options.yaxis.show=false; | |
39310 | |
39311 var highlight_select_plot_colors = []; | |
39312 var i = 0; | |
39313 $(highlight_select_plot).each(function(){ | |
39314 var color; | |
39315 if (i < GeoTemConfig.datasets.length){ | |
39316 var datasetColors = GeoTemConfig.getColor(i); | |
39317 if (highlight_select_plot.length>GeoTemConfig.datasets.length) | |
39318 color = "rgb("+datasetColors.r0+","+datasetColors.g0+","+datasetColors.b0+")"; | |
39319 else | |
39320 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
39321 } else { | |
39322 var datasetColors = GeoTemConfig.getColor(i-GeoTemConfig.datasets.length); | |
39323 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
39324 } | |
39325 | |
39326 highlight_select_plot_colors.push({ | |
39327 color : color, | |
39328 data : this | |
39329 }); | |
39330 i++; | |
39331 }); | |
39332 | |
39333 $(rangeBar.plotDiv).unbind(); | |
39334 rangeBar.plot = $.plot($(rangeBar.plotDiv), highlight_select_plot_colors, options); | |
39335 rangeBar.parent.drawHandles(); | |
39336 | |
39337 var density = rangeBar.parent.density; | |
39338 if (typeof density !== "undefined") | |
39339 $(rangeBar.plotDiv).unbind("plothover", density.hoverFunction); | |
39340 $(rangeBar.plotDiv).unbind("plothover", rangeBar.hoverFunction); | |
39341 $(rangeBar.plotDiv).bind("plothover", $.proxy(rangeBar.hoverFunction,rangeBar)); | |
39342 | |
39343 //this var prevents the execution of the plotclick event after a select event | |
39344 rangeBar.wasSelection = false; | |
39345 $(rangeBar.plotDiv).unbind("plotclick"); | |
39346 $(rangeBar.plotDiv).bind("plotclick", $.proxy(rangeBar.clickFunction,rangeBar)); | |
39347 | |
39348 $(rangeBar.plotDiv).unbind("plotselected"); | |
39349 $(rangeBar.plotDiv).bind("plotselected", $.proxy(rangeBar.selectFunction,rangeBar)); | |
39350 }, | |
39351 | |
39352 hoverFunction : function (event, pos, item) { | |
39353 var rangeBar = this; | |
39354 var hoverBar; | |
39355 var spans; | |
39356 if (item) { | |
39357 hoverBar = item.datapoint[0]; | |
39358 } | |
39359 //remember last date, so that we don't redraw the current state | |
39360 //that date may be undefined is on purpose | |
39361 if (rangeBar.highlighted !== hoverBar){ | |
39362 rangeBar.highlighted = hoverBar; | |
39363 if (typeof hoverBar === "undefined") | |
39364 rangeBar.triggerHighlight(); | |
39365 else | |
39366 rangeBar.triggerHighlight(hoverBar); | |
39367 } | |
39368 }, | |
39369 | |
39370 clickFunction : function (event, pos, item) { | |
39371 var rangeBar = this; | |
39372 if (rangeBar.wasSelection) | |
39373 rangeBar.wasSelection = false; | |
39374 else { | |
39375 //remove selection handles (if there were any) | |
39376 rangeBar.parent.clearHandles(); | |
39377 | |
39378 var clickBar; | |
39379 if (item) { | |
39380 //contains the x-value (date) | |
39381 clickBar = item.datapoint[0]; | |
39382 } | |
39383 if (typeof clickBar === "undefined") | |
39384 rangeBar.triggerSelection(); | |
39385 else | |
39386 rangeBar.triggerSelection(clickBar); | |
39387 wasDataClick = true; | |
39388 } | |
39389 }, | |
39390 | |
39391 selectFunction : function(event, ranges) { | |
39392 var rangeBar = this; | |
39393 startBar = Math.floor(ranges.xaxis.from); | |
39394 endBar = Math.floor(ranges.xaxis.to); | |
39395 rangeBar.triggerSelection(startBar, endBar); | |
39396 rangeBar.wasSelection = true; | |
39397 | |
39398 rangeBar.parent.clearHandles(); | |
39399 var xaxis = rangeBar.plot.getAxes().xaxis; | |
39400 var x1 = rangeBar.plot.pointOffset({x:ranges.xaxis.from,y:0}).left; | |
39401 var x2 = rangeBar.plot.pointOffset({x:ranges.xaxis.to,y:0}).left; | |
39402 rangeBar.parent.addHandle(x1,x2); | |
39403 }, | |
39404 | |
39405 selectByX : function(x1, x2){ | |
39406 rangeBar = this; | |
39407 var xaxis = rangeBar.plot.getAxes().xaxis; | |
39408 var offset = rangeBar.plot.getPlotOffset().left; | |
39409 var from = Math.floor(xaxis.c2p(x1-offset)); | |
39410 var to = Math.floor(xaxis.c2p(x2-offset)); | |
39411 | |
39412 rangeBar.triggerSelection(from, to); | |
39413 }, | |
39414 | |
39415 drawRangeBarChart : function(datasets, spanWidth){ | |
39416 var rangeBar = this; | |
39417 rangeBar.spanWidth = spanWidth; | |
39418 rangeBar.tickSpans = rangeBar.parent.getSpanArray(rangeBar.spanWidth); | |
39419 //-1 because last span is always empty (only there to have the ending date) | |
39420 var tickCount = rangeBar.tickSpans.length-1; | |
39421 | |
39422 if (tickCount > rangeBar.options.maxBars){ | |
39423 var zoomFactor = tickCount / rangeBar.options.maxBars; | |
39424 rangeBar.parent.zoomPlot(zoomFactor); | |
39425 } else | |
39426 rangeBar.parent.zoomPlot(1); | |
39427 | |
39428 rangeBar.yValMin = 0; | |
39429 rangeBar.yValMax = 0; | |
39430 | |
39431 var plotAndHash = rangeBar.createPlot(datasets); | |
39432 rangeBar.datasetsPlot = plotAndHash.plots; | |
39433 rangeBar.datasetsHash = plotAndHash.hashs; | |
39434 delete rangeBar.highlightedDatasetsPlot; | |
39435 //redraw selected plot to fit (possible) new scale | |
39436 rangeBar.selectionChanged(rangeBar.selected); | |
39437 | |
39438 //get min and max values | |
39439 for (var i = 0; i < rangeBar.datasetsPlot.length; i++){ | |
39440 for (var j = 0; j < rangeBar.datasetsPlot[i].length; j++){ | |
39441 if (typeof rangeBar.datasetsPlot[i][j] !== "undefined"){ | |
39442 var val = rangeBar.datasetsPlot[i][j][1]; | |
39443 | |
39444 if (val < rangeBar.yValMin) | |
39445 rangeBar.yValMin = val; | |
39446 if (val > rangeBar.yValMax) | |
39447 rangeBar.yValMax = val; | |
39448 } | |
39449 } | |
39450 } | |
39451 | |
39452 rangeBar.showPlot(); | |
39453 }, | |
39454 | |
39455 highlightChanged : function(objects) { | |
39456 if( !GeoTemConfig.highlightEvents ){ | |
39457 return; | |
39458 } | |
39459 var rangeBar = this; | |
39460 var emptyHighlight = true; | |
39461 var selected_highlighted = objects; | |
39462 if (typeof rangeBar.selected !== "undefined") | |
39463 var selected_highlighted = GeoTemConfig.mergeObjects(objects,rangeBar.selected); | |
39464 $(selected_highlighted).each(function(){ | |
39465 if ((this instanceof Array) && (this.length > 0)){ | |
39466 emptyHighlight = false; | |
39467 return false; | |
39468 } | |
39469 }); | |
39470 if (emptyHighlight && (typeof rangeBar.selected === "undefined")){ | |
39471 rangeBar.highlightedDatasetsPlot = []; | |
39472 } else { | |
39473 rangeBar.highlightedDatasetsPlot = rangeBar.createPlot(selected_highlighted).plots; | |
39474 } | |
39475 rangeBar.showPlot(); | |
39476 }, | |
39477 | |
39478 selectionChanged : function(objects) { | |
39479 if( !GeoTemConfig.selectionEvents ){ | |
39480 return; | |
39481 } | |
39482 var rangeBar = this; | |
39483 rangeBar.selected = objects; | |
39484 rangeBar.highlightChanged([]); | |
39485 }, | |
39486 | |
39487 triggerHighlight : function(hoverPoint) { | |
39488 var rangeBar = this; | |
39489 var highlightedObjects = []; | |
39490 | |
39491 if (typeof hoverPoint !== "undefined"){ | |
39492 $(rangeBar.datasetsHash).each(function(){ | |
39493 if (typeof this[hoverPoint] !== "undefined") | |
39494 highlightedObjects.push(this[hoverPoint]); | |
39495 else | |
39496 highlightedObjects.push([]); | |
39497 }); | |
39498 } else { | |
39499 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
39500 highlightedObjects.push([]); | |
39501 } | |
39502 | |
39503 this.parent.core.triggerHighlight(highlightedObjects); | |
39504 }, | |
39505 | |
39506 triggerSelection : function(startBar, endBar) { | |
39507 var rangeBar = this; | |
39508 var selection; | |
39509 if (typeof startBar !== "undefined") { | |
39510 if (typeof endBar === "undefined") | |
39511 endBar = startBar; | |
39512 rangeBar.selected = []; | |
39513 $(rangeBar.datasetsHash).each(function(){ | |
39514 var objects = []; | |
39515 for (var i = startBar; i <= endBar; i++){ | |
39516 $(this[i]).each(function(){ | |
39517 if ($.inArray(this, objects) == -1){ | |
39518 objects.push(this); | |
39519 } | |
39520 }); | |
39521 } | |
39522 rangeBar.selected.push(objects); | |
39523 }); | |
39524 selection = new Selection(rangeBar.selected, rangeBar.parent); | |
39525 } else { | |
39526 rangeBar.selected = []; | |
39527 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
39528 rangeBar.selected.push([]); | |
39529 selection = new Selection(rangeBar.selected); | |
39530 } | |
39531 | |
39532 rangeBar.parent.selectionChanged(selection); | |
39533 rangeBar.parent.core.triggerSelection(selection); | |
39534 }, | |
39535 | |
39536 deselection : function() { | |
39537 }, | |
39538 | |
39539 filtering : function() { | |
39540 }, | |
39541 | |
39542 inverseFiltering : function() { | |
39543 }, | |
39544 | |
39545 triggerRefining : function() { | |
39546 }, | |
39547 | |
39548 reset : function() { | |
39549 }, | |
39550 | |
39551 show : function() { | |
39552 }, | |
39553 | |
39554 hide : function() { | |
39555 } | |
39556 }; | |
39557 /* | |
39558 * FuzzyTimelineRangePiechart.js | |
39559 * | |
39560 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39561 * | |
39562 * This library is free software; you can redistribute it and/or | |
39563 * modify it under the terms of the GNU Lesser General Public | |
39564 * License as published by the Free Software Foundation; either | |
39565 * version 3 of the License, or (at your option) any later version. | |
39566 * | |
39567 * This library is distributed in the hope that it will be useful, | |
39568 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39569 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39570 * Lesser General Public License for more details. | |
39571 * | |
39572 * You should have received a copy of the GNU Lesser General Public | |
39573 * License along with this library; if not, write to the Free Software | |
39574 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39575 * MA 02110-1301 USA | |
39576 */ | |
39577 | |
39578 /** | |
39579 * @class FuzzyTimelineRangePiechart | |
39580 * Implementation for a fuzzy time-ranges pie chart | |
39581 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39582 * | |
39583 * @param {HTML object} parent div to append the FuzzyTimeline | |
39584 */ | |
39585 function FuzzyTimelineRangePiechart(parent,div) { | |
39586 | |
39587 this.fuzzyTimeline = this; | |
39588 | |
39589 this.parent = parent; | |
39590 this.options = parent.options; | |
39591 | |
39592 this.div = div; | |
39593 | |
39594 this.selected = []; | |
39595 | |
39596 this.maxSlices = 10; | |
39597 } | |
39598 | |
39599 FuzzyTimelineRangePiechart.prototype = { | |
39600 | |
39601 initialize : function(datasets) { | |
39602 var piechart = this; | |
39603 if (piechart.parent.showRangePiechart){ | |
39604 piechart.datasets = datasets; | |
39605 piechart.drawPieChart(piechart.datasets); | |
39606 } | |
39607 }, | |
39608 | |
39609 drawPieChart : function(datasets){ | |
39610 var piechart = this; | |
39611 //build hashmap of spans (span length -> objects[]) | |
39612 var spans = []; | |
39613 var index = 0; | |
39614 $(datasets).each(function(){ | |
39615 var objects = this; | |
39616 //check whether we got "real" dataset or just a set of DataObjects | |
39617 if (typeof objects.objects !== "undefined") | |
39618 objects = objects.objects; | |
39619 $(objects).each(function(){ | |
39620 var dataObject = this; | |
39621 var span; | |
39622 if (dataObject.isTemporal){ | |
39623 span = SimileAjax.DateTime.MILLISECOND; | |
39624 } else if (dataObject.isFuzzyTemporal){ | |
39625 span = dataObject.TimeSpanGranularity; | |
39626 } | |
39627 | |
39628 if (typeof span === "undefined") | |
39629 return; | |
39630 | |
39631 var found = false; | |
39632 $(spans).each(function(){ | |
39633 if (this.span === span){ | |
39634 this.objects[index].push(dataObject); | |
39635 found = true; | |
39636 return false; | |
39637 } | |
39638 }); | |
39639 if (found === false){ | |
39640 var newObjectSet = []; | |
39641 for (var i = 0; i < piechart.datasets.length; i++) | |
39642 newObjectSet.push([]); | |
39643 newObjectSet[index].push(dataObject); | |
39644 spans.push({span:span,objects:newObjectSet}); | |
39645 } | |
39646 }); | |
39647 index++; | |
39648 }); | |
39649 | |
39650 //TODO: join elements of span array to keep below certain threshold | |
39651 | |
39652 //sort array by span length | |
39653 spans.sort(function(a,b){ | |
39654 return(a.span-b.span); | |
39655 }); | |
39656 | |
39657 //create chart data | |
39658 var chartData = []; | |
39659 $(spans).each(function(){ | |
39660 var spanElem = this; | |
39661 $(spanElem.objects).each(function(){ | |
39662 var label = "unknown"; | |
39663 | |
39664 if (spanElem.span === SimileAjax.DateTime.MILLENNIUM){ | |
39665 label = "millenia"; | |
39666 } else if (spanElem.span === SimileAjax.DateTime.DECADE){ | |
39667 label = "decades"; | |
39668 } else if (spanElem.span === SimileAjax.DateTime.CENTURY){ | |
39669 label = "centuries"; | |
39670 } else if (spanElem.span === SimileAjax.DateTime.YEAR){ | |
39671 label = "years"; | |
39672 } else if (spanElem.span === SimileAjax.DateTime.MONTH){ | |
39673 label = "months"; | |
39674 } else if (spanElem.span === SimileAjax.DateTime.DAY){ | |
39675 label = "days"; | |
39676 } else if (spanElem.span === SimileAjax.DateTime.HOUR){ | |
39677 label = "hours"; | |
39678 } else if (spanElem.span === SimileAjax.DateTime.MINUTE){ | |
39679 label = "minutes"; | |
39680 } else if (spanElem.span === SimileAjax.DateTime.SECOND){ | |
39681 label = "seconds"; | |
39682 } else if (spanElem.span === SimileAjax.DateTime.MILLISECOND){ | |
39683 label = "milliseconds"; | |
39684 } | |
39685 | |
39686 chartData.push({label:label,data:this.length}); | |
39687 }); | |
39688 }); | |
39689 | |
39690 $(piechart.div).unbind("plotclick"); | |
39691 $(piechart.div).unbind("plothover"); | |
39692 $(piechart.div).empty(); | |
39693 if (spans.length === 0){ | |
39694 //TODO: language specific message | |
39695 $(piechart.div).append("empty selection"); | |
39696 } else { | |
39697 $.plot($(piechart.div), chartData, | |
39698 { | |
39699 series: { | |
39700 // Make this a pie chart. | |
39701 pie: { | |
39702 show:true | |
39703 } | |
39704 }, | |
39705 legend: { show:false}, | |
39706 grid: { | |
39707 hoverable: true, | |
39708 clickable: true | |
39709 }, | |
39710 tooltip: true, | |
39711 } | |
39712 ); | |
39713 | |
39714 var lastHighlighted; | |
39715 var hoverFunction = function (event, pos, item) { | |
39716 if (item) { | |
39717 var highlightedSpan = Math.ceil(item.seriesIndex/piechart.datasets.length); | |
39718 if (lastHighlighted !== highlightedSpan){ | |
39719 var highlightedObjects = []; | |
39720 for(;highlightedSpan>=0;highlightedSpan--){ | |
39721 highlightedObjects = GeoTemConfig.mergeObjects(highlightedObjects,spans[highlightedSpan].objects); | |
39722 } | |
39723 lastHighlighted = highlightedSpan; | |
39724 } | |
39725 piechart.triggerHighlight(highlightedObjects); | |
39726 } else { | |
39727 piechart.triggerHighlight([]); | |
39728 } | |
39729 }; | |
39730 $(piechart.div).bind("plothover", hoverFunction); | |
39731 | |
39732 $(piechart.div).bind("plotclick", function (event, pos, item) { | |
39733 $(piechart.div).unbind("plothover"); | |
39734 if (item){ | |
39735 var selectedSpan = Math.ceil(item.seriesIndex/piechart.datasets.length); | |
39736 var selectedObjects = []; | |
39737 for(;selectedSpan>=0;selectedSpan--){ | |
39738 selectedObjects = GeoTemConfig.mergeObjects(selectedObjects,spans[selectedSpan].objects); | |
39739 } | |
39740 piechart.triggerSelection(selectedObjects); | |
39741 } else { | |
39742 //if it was a click outside of the pie-chart, enable highlight events | |
39743 $(piechart.div).bind("plothover", hoverFunction); | |
39744 //return to old state | |
39745 piechart.triggerSelection(piechart.selected); | |
39746 //and redraw piechart | |
39747 piechart.highlightChanged([]); | |
39748 } | |
39749 }); | |
39750 } | |
39751 }, | |
39752 | |
39753 highlightChanged : function(objects) { | |
39754 var piechart = this; | |
39755 if (piechart.parent.showRangePiechart){ | |
39756 //check if this is an empty highlight | |
39757 var emptyHighlight = true; | |
39758 $(objects).each(function(){ | |
39759 if ((this instanceof Array) && (this.length > 0)){ | |
39760 emptyHighlight = false; | |
39761 return false; | |
39762 } | |
39763 }); | |
39764 | |
39765 if (emptyHighlight === false) | |
39766 piechart.drawPieChart(GeoTemConfig.mergeObjects(piechart.selected, objects)); | |
39767 else{ | |
39768 //return to selection (or all objects, if no selection is active) | |
39769 if (piechart.selected.length > 0) | |
39770 piechart.drawPieChart(piechart.selected); | |
39771 else | |
39772 piechart.drawPieChart(piechart.datasets); | |
39773 } | |
39774 } | |
39775 }, | |
39776 | |
39777 selectionChanged : function(selection) { | |
39778 var piechart = this; | |
39779 if (piechart.parent.showRangePiechart){ | |
39780 if( !GeoTemConfig.selectionEvents ){ | |
39781 return; | |
39782 } | |
39783 piechart.selected = selection; | |
39784 piechart.highlightChanged([]); | |
39785 } | |
39786 }, | |
39787 | |
39788 triggerHighlight : function(highlightedObjects) { | |
39789 this.parent.triggerHighlight(highlightedObjects); | |
39790 }, | |
39791 | |
39792 triggerSelection : function(selectedObjects) { | |
39793 this.parent.triggerSelection(selectedObjects); | |
39794 }, | |
39795 | |
39796 deselection : function() { | |
39797 }, | |
39798 | |
39799 filtering : function() { | |
39800 }, | |
39801 | |
39802 inverseFiltering : function() { | |
39803 }, | |
39804 | |
39805 triggerRefining : function() { | |
39806 }, | |
39807 | |
39808 reset : function() { | |
39809 }, | |
39810 | |
39811 show : function() { | |
39812 }, | |
39813 | |
39814 hide : function() { | |
39815 } | |
39816 }; | |
39817 /* | |
39818 * FuzzyTimelineRangeSlider.js | |
39819 * | |
39820 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39821 * | |
39822 * This library is free software; you can redistribute it and/or | |
39823 * modify it under the terms of the GNU Lesser General Public | |
39824 * License as published by the Free Software Foundation; either | |
39825 * version 3 of the License, or (at your option) any later version. | |
39826 * | |
39827 * This library is distributed in the hope that it will be useful, | |
39828 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39829 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39830 * Lesser General Public License for more details. | |
39831 * | |
39832 * You should have received a copy of the GNU Lesser General Public | |
39833 * License along with this library; if not, write to the Free Software | |
39834 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39835 * MA 02110-1301 USA | |
39836 */ | |
39837 | |
39838 /** | |
39839 * @class FuzzyTimelineRangeSlider | |
39840 * Implementation for a fuzzy time-ranges slider | |
39841 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39842 * | |
39843 * @param {HTML object} parent div to append the FuzzyTimeline | |
39844 */ | |
39845 function FuzzyTimelineRangeSlider(parent) { | |
39846 | |
39847 var rangeSlider = this; | |
39848 | |
39849 this.parent = parent; | |
39850 this.options = parent.options; | |
39851 | |
39852 this.spans; | |
39853 | |
39854 this.datasets; | |
39855 | |
39856 this.sliderParentTable = this.parent.gui.sliderTable; | |
39857 var headerRow = $("<tr></tr>"); | |
39858 var controlsRow = $("<tr></tr>"); | |
39859 $(this.sliderParentTable).append(headerRow).append(controlsRow); | |
39860 | |
39861 headerRow.append("<td>Time start</td>"); | |
39862 this.rangeStart = document.createElement("select"); | |
39863 controlsRow.append($("<td></td>").append(this.rangeStart)); | |
39864 | |
39865 headerRow.append("<td>Time unit</td>"); | |
39866 this.rangeDropdown = document.createElement("select"); | |
39867 controlsRow.append($("<td></td>").append(this.rangeDropdown)); | |
39868 | |
39869 headerRow.append("<td>Scaling</td>"); | |
39870 this.scalingDropdown = document.createElement("select"); | |
39871 controlsRow.append($("<td></td>").append(this.scalingDropdown)); | |
39872 $(this.scalingDropdown).append("<option>normal</option>"); | |
39873 $(this.scalingDropdown).append("<option>logarithm</option>"); | |
39874 $(this.scalingDropdown).append("<option>percentage</option>"); | |
39875 $(this.scalingDropdown).change(function(eventObject){ | |
39876 var scaleMode = $(rangeSlider.scalingDropdown).find("option:selected").text(); | |
39877 rangeSlider.parent.changeScaleMode(scaleMode); | |
39878 }); | |
39879 | |
39880 headerRow.append("<td>Animation</td>"); | |
39881 this.startAnimation = document.createElement("div"); | |
39882 $(this.startAnimation).addClass("smallButton playDisabled"); | |
39883 this.pauseAnimation = document.createElement("div"); | |
39884 $(this.pauseAnimation).addClass("smallButton pauseDisabled"); | |
39885 controlsRow.append($("<td></td>").append(this.startAnimation).append(this.pauseAnimation)); | |
39886 | |
39887 headerRow.append("<td>Dated Objects</td>"); | |
39888 this.numberDatedObjects = 0; | |
39889 this.numberDatedObjectsDIV = document.createElement("div"); | |
39890 $(this.numberDatedObjectsDIV).addClass("ddbElementsCount"); | |
39891 controlsRow.append($("<td></td>").append(this.numberDatedObjectsDIV)); | |
39892 } | |
39893 | |
39894 FuzzyTimelineRangeSlider.prototype = { | |
39895 | |
39896 initialize : function(datasets) { | |
39897 var rangeSlider = this; | |
39898 rangeSlider.datasets = datasets; | |
39899 | |
39900 //reset values | |
39901 rangeSlider.spans = []; | |
39902 rangeSlider.spanHash = []; | |
39903 | |
39904 //find smallest (most accurate) time-span | |
39905 var smallestSpan; | |
39906 rangeSlider.numberDatedObjects = 0; | |
39907 $(this.datasets).each(function(){ | |
39908 $(this.objects).each(function(){ | |
39909 var dataObject = this; | |
39910 var span; | |
39911 if (dataObject.isTemporal){ | |
39912 rangeSlider.numberDatedObjects++; | |
39913 smallestSpan = moment.duration(1,'milliseconds'); | |
39914 } else if (dataObject.isFuzzyTemporal){ | |
39915 rangeSlider.numberDatedObjects++; | |
39916 span = moment.duration(dataObject.TimeSpanEnd-dataObject.TimeSpanBegin); | |
39917 if ( (typeof smallestSpan === 'undefined') || (span < smallestSpan)) | |
39918 smallestSpan = span; | |
39919 } | |
39920 }); | |
39921 if ((typeof smallestSpan !== 'undefined') && (smallestSpan.asMilliseconds() === 1)) | |
39922 return false; | |
39923 }); | |
39924 | |
39925 //show number of objects that have a time in header | |
39926 $(rangeSlider.numberDatedObjectsDIV).empty().append(rangeSlider.numberDatedObjects + " results"); | |
39927 | |
39928 if (typeof smallestSpan === 'undefined') | |
39929 return; | |
39930 | |
39931 var fixedSpans = [ | |
39932 moment.duration(1, 'seconds'), | |
39933 moment.duration(1, 'minutes'), | |
39934 moment.duration(10, 'minutes'), | |
39935 moment.duration(15, 'minutes'), | |
39936 moment.duration(30, 'minutes'), | |
39937 moment.duration(1, 'hours'), | |
39938 moment.duration(5, 'hours'), | |
39939 moment.duration(10, 'hours'), | |
39940 moment.duration(12, 'hours'), | |
39941 moment.duration(1, 'days'), | |
39942 moment.duration(7, 'days'), | |
39943 moment.duration(1, 'weeks'), | |
39944 moment.duration(2, 'weeks'), | |
39945 moment.duration(1, 'months'), | |
39946 moment.duration(2, 'months'), | |
39947 moment.duration(3, 'months'), | |
39948 moment.duration(6, 'months'), | |
39949 moment.duration(1, 'years'), | |
39950 moment.duration(5, 'years'), | |
39951 moment.duration(10, 'years'), | |
39952 moment.duration(20, 'years'), | |
39953 moment.duration(25, 'years'), | |
39954 moment.duration(50, 'years'), | |
39955 moment.duration(100, 'years'), | |
39956 moment.duration(200, 'years'), | |
39957 moment.duration(250, 'years'), | |
39958 moment.duration(500, 'years'), | |
39959 moment.duration(1000, 'years'), | |
39960 moment.duration(2000, 'years'), | |
39961 moment.duration(2500, 'years'), | |
39962 moment.duration(5000, 'years'), | |
39963 moment.duration(10000, 'years'), | |
39964 ]; | |
39965 var overallSpan = rangeSlider.parent.overallMax-rangeSlider.parent.overallMin; | |
39966 //only add spans that are not too small for the data | |
39967 for (var i = 0; i < fixedSpans.length; i++){ | |
39968 if ( (fixedSpans[i].asMilliseconds() > (smallestSpan.asMilliseconds() * 0.5)) && | |
39969 (fixedSpans[i].asMilliseconds() < overallSpan) | |
39970 && | |
39971 ( | |
39972 rangeSlider.parent.options.showAllPossibleSpans || | |
39973 ((rangeSlider.parent.overallMax-rangeSlider.parent.overallMin)/fixedSpans[i]<rangeSlider.options.maxBars) | |
39974 )) | |
39975 rangeSlider.spans.push(fixedSpans[i]); | |
39976 } | |
39977 | |
39978 $(rangeSlider.rangeDropdown).empty(); | |
39979 | |
39980 $(rangeSlider.rangeDropdown).append("<option>continuous</option>"); | |
39981 var index = 0; | |
39982 $(rangeSlider.spans).each(function(){ | |
39983 var duration = this; | |
39984 if (duration < moment.duration(1,'second')) | |
39985 humanizedSpan = duration.milliseconds() + "ms"; | |
39986 else if (duration < moment.duration(1,'minute')) | |
39987 humanizedSpan = duration.seconds() + "s"; | |
39988 else if (duration < moment.duration(1,'hour')) | |
39989 humanizedSpan = duration.minutes() + "min"; | |
39990 else if (duration < moment.duration(1,'day')) | |
39991 humanizedSpan = duration.hours() + "h"; | |
39992 else if (duration < moment.duration(1,'month')){ | |
39993 var days = duration.days(); | |
39994 humanizedSpan = days + " day"; | |
39995 if (days > 1) | |
39996 humanizedSpan += "s"; | |
39997 } else if (duration < moment.duration(1,'year')){ | |
39998 var months = duration.months(); | |
39999 humanizedSpan = months + " month"; | |
40000 if (months > 1) | |
40001 humanizedSpan += "s"; | |
40002 } else { | |
40003 var years = duration.years(); | |
40004 humanizedSpan = years + " year"; | |
40005 if (years > 1) | |
40006 humanizedSpan += "s"; | |
40007 } | |
40008 $(rangeSlider.rangeDropdown).append("<option index='"+index+"'>"+humanizedSpan+"</option>"); | |
40009 index++; | |
40010 }); | |
40011 | |
40012 $(rangeSlider.rangeDropdown).change(function( eventObject ){ | |
40013 var handlePosition = $(rangeSlider.rangeDropdown).find("option:selected").first().attr("index"); | |
40014 //if there is no index, "continuous" is selected - so the density plot will be drawn | |
40015 | |
40016 if (typeof handlePosition === "undefined"){ | |
40017 rangeSlider.parent.switchViewMode("density"); | |
40018 } else { | |
40019 rangeSlider.parent.switchViewMode("barchart"); | |
40020 } | |
40021 | |
40022 rangeSlider.parent.slidePositionChanged(rangeSlider.spans[handlePosition]); | |
40023 }); | |
40024 | |
40025 $(rangeSlider.rangeStart).empty(); | |
40026 //add start of timeline selections | |
40027 //TODO: add Months/Days/etc., atm there are only years | |
40028 var starts = []; | |
40029 var overallMin = rangeSlider.parent.overallMin; | |
40030 var last = moment(overallMin).year(); | |
40031 starts.push(last); | |
40032 for (i = 1;;i++){ | |
40033 var date = moment(overallMin).year(); | |
40034 date = date/Math.pow(10,i); | |
40035 if (Math.abs(date)<1) | |
40036 break; | |
40037 date = Math.floor(date); | |
40038 date = date*Math.pow(10,i); | |
40039 if (date != last) | |
40040 starts.push(date); | |
40041 last = date; | |
40042 } | |
40043 $(starts).each(function(){ | |
40044 $(rangeSlider.rangeStart).append("<option>"+this+"</option>"); | |
40045 }); | |
40046 | |
40047 $(rangeSlider.rangeStart).change(function( eventObject ){ | |
40048 var handlePosition = rangeSlider.rangeStart.selectedIndex; | |
40049 var start = starts[handlePosition]; | |
40050 | |
40051 rangeSlider.parent.overallMin = moment().year(start); | |
40052 $(rangeSlider.rangeDropdown).change(); | |
40053 }); | |
40054 | |
40055 $(rangeSlider.rangeDropdown).change(); | |
40056 | |
40057 $(rangeSlider.startAnimation).click(function(){ | |
40058 if ($(rangeSlider.startAnimation).hasClass("playEnabled")){ | |
40059 $(rangeSlider.startAnimation).removeClass("playEnabled").addClass("playDisabled"); | |
40060 $(rangeSlider.pauseAnimation).removeClass("pauseDisabled").addClass("pauseEnabled"); | |
40061 | |
40062 rangeSlider.parent.startAnimation(); | |
40063 } | |
40064 }); | |
40065 | |
40066 $(rangeSlider.pauseAnimation).prop('disabled', true); | |
40067 $(rangeSlider.pauseAnimation).click(function(){ | |
40068 if ($(rangeSlider.pauseAnimation).hasClass("pauseEnabled")){ | |
40069 $(rangeSlider.startAnimation).removeClass("playDisabled").addClass("playEnabled"); | |
40070 $(rangeSlider.pauseAnimation).removeClass("pauseEnabled").addClass("pauseDisabled"); | |
40071 | |
40072 rangeSlider.parent.pauseAnimation(); | |
40073 } | |
40074 }); | |
40075 }, | |
40076 | |
40077 triggerHighlight : function(columnElement) { | |
40078 | |
40079 }, | |
40080 | |
40081 triggerSelection : function(columnElement) { | |
40082 | |
40083 }, | |
40084 | |
40085 deselection : function() { | |
40086 }, | |
40087 | |
40088 filtering : function() { | |
40089 }, | |
40090 | |
40091 inverseFiltering : function() { | |
40092 }, | |
40093 | |
40094 triggerRefining : function() { | |
40095 }, | |
40096 | |
40097 reset : function() { | |
40098 }, | |
40099 | |
40100 show : function() { | |
40101 }, | |
40102 | |
40103 hide : function() { | |
40104 } | |
40105 }; | |
40106 /* | |
40107 * FuzzyTimelineWidget.js | |
40108 * | |
40109 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40110 * | |
40111 * This library is free software; you can redistribute it and/or | |
40112 * modify it under the terms of the GNU Lesser General Public | |
40113 * License as published by the Free Software Foundation; either | |
40114 * version 3 of the License, or (at your option) any later version. | |
40115 * | |
40116 * This library is distributed in the hope that it will be useful, | |
40117 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40118 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40119 * Lesser General Public License for more details. | |
40120 * | |
40121 * You should have received a copy of the GNU Lesser General Public | |
40122 * License along with this library; if not, write to the Free Software | |
40123 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40124 * MA 02110-1301 USA | |
40125 */ | |
40126 | |
40127 /** | |
40128 * @class FuzzyTimelineWidget | |
40129 * FuzzyTimelineWidget Implementation | |
40130 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40131 * | |
40132 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
40133 * @param {HTML object} div parent div to append the FuzzyTimeline widget div | |
40134 * @param {JSON} options user specified configuration that overwrites options in FuzzyTimelineConfig.js | |
40135 */ | |
40136 FuzzyTimelineWidget = function(core, div, options) { | |
40137 | |
40138 this.datasets; | |
40139 this.selected = undefined; | |
40140 this.overallMin; | |
40141 this.overallMax; | |
40142 | |
40143 this.core = core; | |
40144 this.core.setWidget(this); | |
40145 | |
40146 this.options = (new FuzzyTimelineConfig(options)).options; | |
40147 this.gui = new FuzzyTimelineGui(this, div, this.options); | |
40148 | |
40149 this.viewMode; | |
40150 this.density; | |
40151 this.rangeSlider; | |
40152 this.rangeBars; | |
40153 this.rangePiechart; | |
40154 this.spanHash = []; | |
40155 | |
40156 this.handles = []; | |
40157 this.zoomFactor = 1; | |
40158 | |
40159 this.scaleMode = "normal"; | |
40160 } | |
40161 | |
40162 FuzzyTimelineWidget.prototype = { | |
40163 | |
40164 initWidget : function(data) { | |
40165 var fuzzyTimeline = this; | |
40166 | |
40167 delete fuzzyTimeline.overallMin; | |
40168 delete fuzzyTimeline.overallMax; | |
40169 | |
40170 $(fuzzyTimeline.gui.plotDiv).empty(); | |
40171 $(fuzzyTimeline.gui.sliderTable).empty(); | |
40172 delete fuzzyTimeline.rangeSlider; | |
40173 $(fuzzyTimeline.gui.rangePiechartDiv).empty(); | |
40174 delete fuzzyTimeline.rangePiechart; | |
40175 | |
40176 fuzzyTimeline.switchViewMode("density"); | |
40177 | |
40178 if ( (data instanceof Array) && (data.length > 0) ) | |
40179 { | |
40180 fuzzyTimeline.datasets = data; | |
40181 | |
40182 $(fuzzyTimeline.datasets).each(function(){ | |
40183 $(this.objects).each(function(){ | |
40184 var datemin,datemax; | |
40185 if (this.isTemporal){ | |
40186 //TODO: allow more than one date | |
40187 datemin = moment(this.dates[0].date); | |
40188 datemax = datemin; | |
40189 } else if (this.isFuzzyTemporal){ | |
40190 //TODO: allow more than one date | |
40191 datemin = this.TimeSpanBegin; | |
40192 datemax = this.TimeSpanEnd; | |
40193 } | |
40194 | |
40195 if (typeof fuzzyTimeline.overallMin === "undefined") | |
40196 fuzzyTimeline.overallMin = datemin; | |
40197 if (typeof fuzzyTimeline.overallMax === "undefined") | |
40198 fuzzyTimeline.overallMax = datemax; | |
40199 | |
40200 if (fuzzyTimeline.overallMin > datemin) | |
40201 fuzzyTimeline.overallMin = datemin; | |
40202 if (fuzzyTimeline.overallMax < datemax) | |
40203 fuzzyTimeline.overallMax = datemax; | |
40204 }); | |
40205 }); | |
40206 | |
40207 fuzzyTimeline.rangeSlider = new FuzzyTimelineRangeSlider(fuzzyTimeline); | |
40208 fuzzyTimeline.rangeSlider.initialize(fuzzyTimeline.datasets); | |
40209 | |
40210 fuzzyTimeline.rangePiechart = new FuzzyTimelineRangePiechart(fuzzyTimeline, fuzzyTimeline.gui.rangePiechartDiv); | |
40211 fuzzyTimeline.rangePiechart.initialize(fuzzyTimeline.datasets); | |
40212 } | |
40213 }, | |
40214 | |
40215 switchViewMode : function(viewMode){ | |
40216 var fuzzyTimeline = this; | |
40217 if (viewMode !== fuzzyTimeline.viewMode){ | |
40218 $(fuzzyTimeline.gui.plotDiv).empty(); | |
40219 if (viewMode === "density"){ | |
40220 fuzzyTimeline.density = new FuzzyTimelineDensity(fuzzyTimeline,fuzzyTimeline.gui.plotDiv); | |
40221 } else if (viewMode === "barchart"){ | |
40222 fuzzyTimeline.rangeBars = new FuzzyTimelineRangeBars(fuzzyTimeline); | |
40223 } | |
40224 fuzzyTimeline.viewMode = viewMode; | |
40225 } | |
40226 }, | |
40227 | |
40228 scaleData : function(data){ | |
40229 var fuzzyTimeline = this; | |
40230 if (fuzzyTimeline.scaleMode == "normal"){ | |
40231 return data; | |
40232 } else if (fuzzyTimeline.scaleMode == "logarithm"){ | |
40233 for(var index in data){ | |
40234 var val = data[index]; | |
40235 if (val!=0){ | |
40236 var sign = 1; | |
40237 if (val<0){ | |
40238 sign = -1; | |
40239 } | |
40240 data[index] = sign*Math.log(Math.abs(data[index])+1); | |
40241 } | |
40242 } | |
40243 return data; | |
40244 } else if (fuzzyTimeline.scaleMode == "percentage"){ | |
40245 var overallCnt = 0; | |
40246 for(var index in data){ | |
40247 var val = data[index]; | |
40248 if (val > 0){ | |
40249 overallCnt += val; | |
40250 } | |
40251 } | |
40252 //make 1 = 100% | |
40253 overallCnt = overallCnt/100; | |
40254 if (overallCnt != 0){ | |
40255 for(var index in data){ | |
40256 data[index] = (data[index])/overallCnt; | |
40257 } | |
40258 } | |
40259 return data; | |
40260 } | |
40261 }, | |
40262 | |
40263 changeScaleMode : function(scaleMode) { | |
40264 var fuzzyTimeline = this; | |
40265 fuzzyTimeline.scaleMode = scaleMode; | |
40266 fuzzyTimeline.drawFuzzyTimeline(); | |
40267 }, | |
40268 | |
40269 slidePositionChanged : function(spanWidth) { | |
40270 var fuzzyTimeline = this; | |
40271 fuzzyTimeline.spanWidth = spanWidth; | |
40272 fuzzyTimeline.drawFuzzyTimeline(); | |
40273 }, | |
40274 | |
40275 drawFuzzyTimeline : function(){ | |
40276 var fuzzyTimeline = this; | |
40277 var datasets = fuzzyTimeline.datasets; | |
40278 if (fuzzyTimeline.viewMode === "density"){ | |
40279 //redraw density plot | |
40280 fuzzyTimeline.density.drawDensityPlot(datasets); | |
40281 //select currently selected data (if there is any) | |
40282 fuzzyTimeline.density.selectionChanged(fuzzyTimeline.selected); | |
40283 } else if (fuzzyTimeline.viewMode === "barchart"){ | |
40284 //redraw range plot | |
40285 fuzzyTimeline.rangeBars.drawRangeBarChart(datasets,fuzzyTimeline.spanWidth); | |
40286 //select currently selected data (if there is any) | |
40287 fuzzyTimeline.rangeBars.selectionChanged(fuzzyTimeline.selected); | |
40288 } | |
40289 }, | |
40290 | |
40291 highlightChanged : function(objects) { | |
40292 var fuzzyTimeline = this; | |
40293 if( !GeoTemConfig.highlightEvents ){ | |
40294 return; | |
40295 } | |
40296 if ( (typeof objects === "undefined") || (objects.length == 0) ){ | |
40297 return; | |
40298 } | |
40299 if (fuzzyTimeline.viewMode === "density") | |
40300 this.density.highlightChanged(objects); | |
40301 else if (fuzzyTimeline.viewMode === "barchart") | |
40302 this.rangeBars.highlightChanged(objects); | |
40303 | |
40304 fuzzyTimeline.rangePiechart.highlightChanged(objects); | |
40305 }, | |
40306 | |
40307 selectionChanged : function(selection) { | |
40308 var fuzzyTimeline = this; | |
40309 if( !GeoTemConfig.selectionEvents ){ | |
40310 return; | |
40311 } | |
40312 if (selection.valid()) | |
40313 fuzzyTimeline.selected = selection.objects; | |
40314 else | |
40315 delete fuzzyTimeline.selected; | |
40316 if (fuzzyTimeline.viewMode === "density") | |
40317 this.density.selectionChanged(fuzzyTimeline.selected); | |
40318 else if (fuzzyTimeline.viewMode === "barchart") | |
40319 this.rangeBars.selectionChanged(fuzzyTimeline.selected); | |
40320 | |
40321 if (selection.valid()) | |
40322 fuzzyTimeline.rangePiechart.selectionChanged(fuzzyTimeline.selected); | |
40323 else | |
40324 fuzzyTimeline.rangePiechart.selectionChanged([]); | |
40325 | |
40326 //selections "overwrite" each other | |
40327 if (selection.widget != fuzzyTimeline) | |
40328 fuzzyTimeline.clearHandles(); | |
40329 }, | |
40330 | |
40331 buildSpanArray : function(spanWidth) { | |
40332 var spanArray = []; | |
40333 var tickStart = moment(this.overallMin); | |
40334 do{ | |
40335 spanArray.push(moment(tickStart)); | |
40336 tickStart.add(spanWidth); | |
40337 } while (tickStart <= this.overallMax); | |
40338 spanArray.push(moment(tickStart)); | |
40339 | |
40340 this.spanHash.push({spanWidth:spanWidth,overallMin:moment(this.overallMin),spanArray:spanArray}); | |
40341 return(spanArray); | |
40342 }, | |
40343 | |
40344 getSpanArray : function(spanWidth){ | |
40345 for (var i = 0; i < this.spanHash.length; i++){ | |
40346 var element = this.spanHash[i]; | |
40347 if ( ((this.overallMin-element.overallMin)===0) && | |
40348 ((spanWidth-element.spanWidth)===0)) | |
40349 return element.spanArray; | |
40350 } | |
40351 return this.buildSpanArray(spanWidth); | |
40352 }, | |
40353 | |
40354 clearSpanArray : function(){ | |
40355 this.spanHash = []; | |
40356 }, | |
40357 | |
40358 getTicks : function(dataObject, spanWidth) { | |
40359 var datemin,datemax; | |
40360 if (dataObject.isTemporal){ | |
40361 datemin = moment(dataObject.dates[0].date); | |
40362 datemax = datemin; | |
40363 } else if (dataObject.isFuzzyTemporal){ | |
40364 datemin = dataObject.TimeSpanBegin; | |
40365 datemax = dataObject.TimeSpanEnd; | |
40366 } else{ | |
40367 return; | |
40368 } | |
40369 | |
40370 if (typeof spanWidth._data === "undefined"){ | |
40371 //This does only work with millisecond spans, as the length of years is (very) inaccurate. | |
40372 //(e.g. 100-0 = 99, 2000-1000 = 1001, 5000-0 = 5003, and so on and even more: duration(5000a) = 4932a) | |
40373 //So the time consuming loop below is needed for accurate dates, when years/months/days etc. are supplied | |
40374 var firstTick = Math.floor((datemin-this.overallMin)/spanWidth); | |
40375 var lastTick = Math.floor((datemax-this.overallMin)/spanWidth); | |
40376 //calculate how much the first (and last) tick and the time-span overlap | |
40377 var firstTickPercentage = 1; | |
40378 var lastTickPercentage = 1; | |
40379 if (firstTick != lastTick){ | |
40380 var secondTickStart = this.overallMin+(firstTick+1)*spanWidth; | |
40381 var lastTickStart = this.overallMin+lastTick*spanWidth; | |
40382 firstTickPercentage = (secondTickStart-datemin)/spanWidth; | |
40383 lastTickPercentage = (datemax-lastTickStart)/spanWidth; | |
40384 } | |
40385 if (firstTickPercentage === 0){ | |
40386 firstTick++; | |
40387 firstTickPercentage = 1; | |
40388 } | |
40389 if (lastTickPercentage === 0){ | |
40390 lastTick--; | |
40391 lastTickPercentage = 1; | |
40392 } | |
40393 } else { | |
40394 var spanArray = this.getSpanArray(spanWidth); | |
40395 var firstTick, lastTick; | |
40396 var tickCount = 0; | |
40397 var tickStart = spanArray[0]; | |
40398 var lastTickStart; | |
40399 do{ | |
40400 lastTickStart = spanArray[tickCount]; | |
40401 tickCount++; | |
40402 tickStart = spanArray[tickCount]; | |
40403 if ( (typeof firstTick === "undefined") && (datemin < tickStart) ){ | |
40404 firstTick = tickCount-1; | |
40405 firstTickPercentage = (tickStart - datemin)/spanWidth; | |
40406 } | |
40407 if ( (typeof lastTick === "undefined") && (datemax <= tickStart) ){ | |
40408 lastTick = tickCount-1; | |
40409 lastTickPercentage = (datemax - lastTickStart)/spanWidth; | |
40410 } | |
40411 } while (tickStart < datemax); | |
40412 if (firstTick == lastTick){ | |
40413 firstTickPercentage = 1; | |
40414 lastTickPercentage = 1; | |
40415 } | |
40416 } | |
40417 | |
40418 return({ firstTick:firstTick, | |
40419 lastTick:lastTick, | |
40420 firstTickPercentage:firstTickPercentage, | |
40421 lastTickPercentage:lastTickPercentage}); | |
40422 }, | |
40423 | |
40424 getObjects : function(dateStart, dateEnd) { | |
40425 var fuzzyTimeline = this; | |
40426 var searchDateStart, searchDateEnd; | |
40427 if (typeof dateStart !== "undefined") | |
40428 searchDateStart = moment(dateStart); | |
40429 if (typeof dateEnd !== "undefined") | |
40430 searchDateEnd = moment(dateEnd); | |
40431 | |
40432 var datasets = []; | |
40433 $(fuzzyTimeline.datasets).each(function(){ | |
40434 var objects = []; | |
40435 //check if we got "real" datasets, or just array of objects | |
40436 var datasetObjects = this; | |
40437 if (typeof this.objects !== "undefined") | |
40438 datasetObjects = this.objects; | |
40439 $(datasetObjects).each(function(){ | |
40440 var datemin,datemax; | |
40441 var dataObject = this; | |
40442 if (dataObject.isTemporal){ | |
40443 datemin = moment(dataObject.dates[0].date); | |
40444 datemax = datemin; | |
40445 } else if (dataObject.isFuzzyTemporal){ | |
40446 datemin = dataObject.TimeSpanBegin; | |
40447 datemax = dataObject.TimeSpanEnd; | |
40448 } else{ | |
40449 return; | |
40450 } | |
40451 | |
40452 if (typeof searchDateEnd === 'undefined'){ | |
40453 if ( (datemin <= searchDateStart) && (datemax >= searchDateStart) ) | |
40454 objects.push(this); | |
40455 } else { | |
40456 if ((datemin < searchDateEnd) && (datemax >= searchDateStart)) | |
40457 objects.push(this); | |
40458 } | |
40459 }); | |
40460 datasets.push(objects); | |
40461 }); | |
40462 | |
40463 return(datasets); | |
40464 }, | |
40465 | |
40466 triggerHighlight : function(highlightedObjects){ | |
40467 var fuzzyTimeline = this; | |
40468 if (fuzzyTimeline.viewMode === "density") | |
40469 fuzzyTimeline.density.highlightChanged(highlightedObjects); | |
40470 else if (fuzzyTimeline.viewMode === "barchart") | |
40471 fuzzyTimeline.rangeBars.highlightChanged(highlightedObjects); | |
40472 | |
40473 fuzzyTimeline.core.triggerHighlight(highlightedObjects); | |
40474 }, | |
40475 | |
40476 triggerSelection : function(selectedObjects){ | |
40477 var fuzzyTimeline = this; | |
40478 fuzzyTimeline.selected = selectedObjects; | |
40479 if (fuzzyTimeline.viewMode === "density") | |
40480 fuzzyTimeline.density.selectionChanged(selectedObjects); | |
40481 else if (fuzzyTimeline.viewMode === "barchart") | |
40482 fuzzyTimeline.rangeBars.selectionChanged(selectedObjects); | |
40483 | |
40484 selection = new Selection(selectedObjects); | |
40485 | |
40486 fuzzyTimeline.core.triggerSelection(selection); | |
40487 }, | |
40488 | |
40489 addHandle : function(x1,x2){ | |
40490 var fuzzyTimeline = this; | |
40491 //make sure the interval is ordered correctly | |
40492 if (x2<x1){ | |
40493 var temp = x1; | |
40494 x1 = x2; | |
40495 x2 = temp; | |
40496 } | |
40497 fuzzyTimeline.handles.push({x1:x1,x2:x2}); | |
40498 fuzzyTimeline.drawHandles(); | |
40499 //enabled "play" button | |
40500 $(fuzzyTimeline.rangeSlider.startAnimation).removeClass("playDisabled").addClass("playEnabled"); | |
40501 }, | |
40502 | |
40503 selectByX : function(x1,x2){ | |
40504 var fuzzyTimeline = this; | |
40505 if (fuzzyTimeline.viewMode === "density"){ | |
40506 fuzzyTimeline.density.selectByX(x1,x2); | |
40507 } else if (fuzzyTimeline.viewMode === "barchart"){ | |
40508 fuzzyTimeline.rangeBars.selectByX(x1,x2); | |
40509 } | |
40510 }, | |
40511 | |
40512 drawHandles : function(){ | |
40513 var fuzzyTimeline = this; | |
40514 | |
40515 $(fuzzyTimeline.gui.plotDiv).find(".plotHandle").remove(); | |
40516 $(fuzzyTimeline.gui.plotDiv).find(".dragTimeRangeAlt").remove(); | |
40517 $(fuzzyTimeline.gui.plotDiv).find(".plotHandleBox").remove(); | |
40518 | |
40519 var plotHeight = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).height(); | |
40520 var plotWidth = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).width(); | |
40521 //flot sends the wrong width if we extend the parent div, so scale it accordingly | |
40522 plotWidth = plotWidth*fuzzyTimeline.zoomFactor; | |
40523 var plotOffset = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).getPlotOffset().left; | |
40524 | |
40525 $(fuzzyTimeline.handles).each(function(){ | |
40526 var handle = this; | |
40527 | |
40528 var moveLeftHandle = function(){ | |
40529 leftHandle.style.left = handle.x1-$(leftHandle).width() + "px"; | |
40530 }; | |
40531 | |
40532 var moveRightHandle = function(){ | |
40533 rightHandle.style.left = handle.x2+ "px"; | |
40534 }; | |
40535 | |
40536 var resizeHandleBox = function(){ | |
40537 handleBox.style.left = handle.x1+"px"; | |
40538 $(handleBox).width(handle.x2-handle.x1); | |
40539 }; | |
40540 | |
40541 var moveDragButton = function(){ | |
40542 dragButton.style.left = (handle.x1+handle.x2)/2 - $(dragButton).width()/2 + "px"; | |
40543 }; | |
40544 | |
40545 var leftHandle = document.createElement("div"); | |
40546 leftHandle.title = GeoTemConfig.getString('leftHandle'); | |
40547 leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
40548 leftHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
40549 leftHandle.style.visibility = "visible"; | |
40550 $(fuzzyTimeline.gui.plotDiv).append(leftHandle); | |
40551 moveLeftHandle(); | |
40552 leftHandle.style.top = plotHeight/2-$(leftHandle).height()/2 + "px"; | |
40553 | |
40554 var rightHandle = document.createElement("div"); | |
40555 rightHandle.title = GeoTemConfig.getString('leftHandle'); | |
40556 rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")"; | |
40557 rightHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
40558 rightHandle.style.visibility = "visible"; | |
40559 moveRightHandle(); | |
40560 $(fuzzyTimeline.gui.plotDiv).append(rightHandle); | |
40561 | |
40562 rightHandle.style.top = plotHeight/2-$(rightHandle).height()/2 + "px"; | |
40563 | |
40564 var handleBox = document.createElement("div"); | |
40565 $(fuzzyTimeline.gui.plotDiv).append(handleBox); | |
40566 $(handleBox).addClass("plotHandleBox"); | |
40567 resizeHandleBox(); | |
40568 $(handleBox).height(plotHeight); | |
40569 | |
40570 var dragButton = document.createElement("div"); | |
40571 dragButton.title = GeoTemConfig.getString('dragTimeRange'); | |
40572 dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")"; | |
40573 dragButton.setAttribute('class', 'dragTimeRangeAlt plotHandleIcon'); | |
40574 $(fuzzyTimeline.gui.plotDiv).append(dragButton); | |
40575 moveDragButton(); | |
40576 dragButton.style.top = plotHeight + "px"; | |
40577 | |
40578 $(leftHandle).mousedown(function(){ | |
40579 $(fuzzyTimeline.gui.plotDiv).mousemove(function(eventObj){ | |
40580 var x = eventObj.clientX; | |
40581 x += $(fuzzyTimeline.gui.plotDiv).parent().scrollLeft(); | |
40582 if ((x < handle.x2) && | |
40583 (x >= plotOffset)){ | |
40584 x = x - leftHandle.offsetWidth; | |
40585 handle.x1 = x + $(leftHandle).width(); | |
40586 | |
40587 moveLeftHandle(); | |
40588 resizeHandleBox(); | |
40589 moveDragButton(); | |
40590 } | |
40591 }); | |
40592 $(fuzzyTimeline.gui.plotDiv).mouseup(function(eventObj){ | |
40593 fuzzyTimeline.selectByX(handle.x1,handle.x2); | |
40594 $(fuzzyTimeline.gui.plotDiv).unbind("mouseup"); | |
40595 $(fuzzyTimeline.gui.plotDiv).unbind("mousemove"); | |
40596 }); | |
40597 }); | |
40598 | |
40599 $(rightHandle).mousedown(function(){ | |
40600 $(fuzzyTimeline.gui.plotDiv).mousemove(function(eventObj){ | |
40601 var x = eventObj.clientX; | |
40602 x += $(fuzzyTimeline.gui.plotDiv).parent().scrollLeft(); | |
40603 x = x - rightHandle.offsetWidth; | |
40604 if ((x > handle.x1) && | |
40605 (x <= plotOffset+plotWidth)){ | |
40606 handle.x2 = x; | |
40607 | |
40608 moveRightHandle(); | |
40609 resizeHandleBox(); | |
40610 moveDragButton(); | |
40611 } | |
40612 }); | |
40613 $(fuzzyTimeline.gui.plotDiv).mouseup(function(eventObj){ | |
40614 fuzzyTimeline.selectByX(handle.x1,handle.x2); | |
40615 $(fuzzyTimeline.gui.plotDiv).unbind("mouseup"); | |
40616 $(fuzzyTimeline.gui.plotDiv).unbind("mousemove"); | |
40617 }); | |
40618 }); | |
40619 | |
40620 $(dragButton).mousedown(function(){ | |
40621 $(fuzzyTimeline.gui.plotDiv).mousemove(function(eventObj){ | |
40622 var x = eventObj.clientX; | |
40623 //TODO: for some reason we don't need the scoll offset here | |
40624 //this should be investigated? | |
40625 //x += $(fuzzyTimeline.gui.plotDiv).parent().scrollLeft(); | |
40626 var xdiff = x - $(dragButton).offset().left - $(dragButton).width()/2; | |
40627 handle.x1 = handle.x1+xdiff; | |
40628 handle.x2 = handle.x2+xdiff; | |
40629 | |
40630 moveLeftHandle(); | |
40631 moveRightHandle(); | |
40632 resizeHandleBox(); | |
40633 moveDragButton(); | |
40634 }); | |
40635 $(fuzzyTimeline.gui.plotDiv).mouseup(function(eventObj){ | |
40636 if (handle.x1 < plotOffset) | |
40637 handle.x1 = plotOffset; | |
40638 if (handle.x2 > plotOffset+plotWidth) | |
40639 handle.x2 = plotOffset+plotWidth; | |
40640 | |
40641 moveLeftHandle(); | |
40642 moveRightHandle(); | |
40643 resizeHandleBox(); | |
40644 moveDragButton(); | |
40645 | |
40646 fuzzyTimeline.selectByX(handle.x1,handle.x2); | |
40647 $(fuzzyTimeline.gui.plotDiv).unbind("mouseup"); | |
40648 $(fuzzyTimeline.gui.plotDiv).unbind("mousemove"); | |
40649 }); | |
40650 }); | |
40651 }); | |
40652 }, | |
40653 | |
40654 clearHandles : function(){ | |
40655 var fuzzyTimeline = this; | |
40656 $(fuzzyTimeline.gui.plotDiv).find(".plotHandle").remove(); | |
40657 $(fuzzyTimeline.gui.plotDiv).find(".dragTimeRangeAlt").remove(); | |
40658 $(fuzzyTimeline.gui.plotDiv).find(".plotHandleBox").remove(); | |
40659 fuzzyTimeline.handles = []; | |
40660 //disable buttons | |
40661 $(fuzzyTimeline.rangeSlider.startAnimation).removeClass("playEnabled").addClass("playDisabled"); | |
40662 $(fuzzyTimeline.rangeSlider.pauseAnimation).removeClass("pauseEnabled").addClass("pauseDisabled"); | |
40663 //stop the animation (if one was running) | |
40664 fuzzyTimeline.pauseAnimation(); | |
40665 }, | |
40666 | |
40667 startAnimation : function(){ | |
40668 var fuzzyTimeline = this; | |
40669 fuzzyTimeline.loopFunction = function(steps){ | |
40670 $(fuzzyTimeline.handles).each(function(){ | |
40671 if (typeof steps === "undefined") | |
40672 steps = 1; | |
40673 | |
40674 var handle = this; | |
40675 var x1 = handle.x1; | |
40676 var x2 = handle.x2; | |
40677 | |
40678 if (typeof handle.width === "undefined") | |
40679 handle.width = x2-x1; | |
40680 | |
40681 var plotWidth = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).width(); | |
40682 var plotOffset = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).getPlotOffset().left; | |
40683 | |
40684 var plotMax = plotWidth+plotOffset; | |
40685 | |
40686 //TODO: has to be plotMin | |
40687 if (!((x1 === plotOffset)&&(x2-x1 <= handle.width))){ | |
40688 x1 += steps; | |
40689 } | |
40690 if (x2 <= plotMax){ | |
40691 x2 += steps; | |
40692 if (x2 > plotMax) | |
40693 x2 = plotMax; | |
40694 if (x2-x1 > handle.width){ | |
40695 x1 = x2-handle.width; | |
40696 } | |
40697 } | |
40698 if (x1 >= plotMax){ | |
40699 //TODO: has to be plotMin | |
40700 x1 = plotOffset; | |
40701 x2 = plotOffset; | |
40702 } | |
40703 | |
40704 handle.x1 = x1; | |
40705 handle.x2 = x2; | |
40706 | |
40707 fuzzyTimeline.drawHandles(); | |
40708 fuzzyTimeline.selectByX(handle.x1, handle.x2); | |
40709 }); | |
40710 }; | |
40711 | |
40712 fuzzyTimeline.loopId = setInterval(function(){ | |
40713 fuzzyTimeline.loopFunction(10); | |
40714 }, 100); | |
40715 }, | |
40716 | |
40717 pauseAnimation : function(){ | |
40718 var fuzzyTimeline = this; | |
40719 clearInterval(fuzzyTimeline.loopId); | |
40720 $(fuzzyTimeline.handles).each(function(){ | |
40721 var handle = this; | |
40722 delete handle.width; | |
40723 }); | |
40724 }, | |
40725 | |
40726 //This function enlargens the plot area | |
40727 zoomPlot : function(zoomFactor){ | |
40728 var fuzzyTimeline = this; | |
40729 var oldZoomFactor = fuzzyTimeline.zoomFactor; | |
40730 fuzzyTimeline.zoomFactor = zoomFactor; | |
40731 if (zoomFactor > 1){ | |
40732 $(fuzzyTimeline.gui.plotDiv).width(zoomFactor*100+"%"); | |
40733 //leave place for the scrollbar | |
40734 $(fuzzyTimeline.gui.plotDiv).height(fuzzyTimeline.gui.plotDIVHeight-20); | |
40735 } else{ | |
40736 $(fuzzyTimeline.gui.plotDiv).width("100%"); | |
40737 $(fuzzyTimeline.gui.plotDiv).height(fuzzyTimeline.gui.plotDIVHeight); | |
40738 } | |
40739 | |
40740 //fit handles | |
40741 //this does not make much sense, as the selections are _completely_ different | |
40742 //for each scale rate, as the objects may reside in different "ticks" of the graph | |
40743 $(fuzzyTimeline.handles).each(function(){ | |
40744 var handle = this; | |
40745 handle.x1 = handle.x1 * (zoomFactor/oldZoomFactor); | |
40746 handle.x2 = handle.x2 * (zoomFactor/oldZoomFactor); | |
40747 }); | |
40748 } | |
40749 }; | |
40750 /* | |
40751 * Overlayloader.js | |
40752 * | |
40753 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40754 * | |
40755 * This library is free software; you can redistribute it and/or | |
40756 * modify it under the terms of the GNU Lesser General Public | |
40757 * License as published by the Free Software Foundation; either | |
40758 * version 3 of the License, or (at your option) any later version. | |
40759 * | |
40760 * This library is distributed in the hope that it will be useful, | |
40761 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40762 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40763 * Lesser General Public License for more details. | |
40764 * | |
40765 * You should have received a copy of the GNU Lesser General Public | |
40766 * License along with this library; if not, write to the Free Software | |
40767 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40768 * MA 02110-1301 USA | |
40769 */ | |
40770 | |
40771 /** | |
40772 * @class Overlayloader | |
40773 * Implementation for a Overlayloader UI | |
40774 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40775 * | |
40776 * @param {HTML object} parent div to append the Overlayloader | |
40777 */ | |
40778 function Overlayloader(parent) { | |
40779 | |
40780 this.overlayLoader = this; | |
40781 | |
40782 this.parent = parent; | |
40783 this.options = parent.options; | |
40784 this.attachedMapWidgets = parent.attachedMapWidgets; | |
40785 | |
40786 this.overlays = []; | |
40787 | |
40788 this.initialize(); | |
40789 } | |
40790 | |
40791 Overlayloader.prototype = { | |
40792 | |
40793 show : function() { | |
40794 this.overlayloaderDiv.style.display = "block"; | |
40795 }, | |
40796 | |
40797 hide : function() { | |
40798 this.overlayloaderDiv.style.display = "none"; | |
40799 }, | |
40800 | |
40801 initialize : function() { | |
40802 | |
40803 this.addKMLLoader(); | |
40804 this.addKMZLoader(); | |
40805 this.addArcGISWMSLoader(); | |
40806 this.addXYZLoader(); | |
40807 this.addRomanEmpireLoader(); | |
40808 this.addMapsForFreeWaterLayer(); | |
40809 this.addConfigLoader(); | |
40810 | |
40811 // trigger change event on the select so | |
40812 // that only the first loader div will be shown | |
40813 $(this.parent.gui.loaderTypeSelect).change(); | |
40814 }, | |
40815 | |
40816 distributeKML : function(kmlURL) { | |
40817 var newOverlay = new Object(); | |
40818 newOverlay.name = kmlURL; | |
40819 newOverlay.layers = []; | |
40820 | |
40821 $(this.attachedMapWidgets).each(function(){ | |
40822 var newLayer = new OpenLayers.Layer.Vector("KML", { | |
40823 projection: this.openlayersMap.displayProjection, | |
40824 strategies: [new OpenLayers.Strategy.Fixed()], | |
40825 protocol: new OpenLayers.Protocol.HTTP({ | |
40826 url: kmlURL, | |
40827 format: new OpenLayers.Format.KML({ | |
40828 extractStyles: true, | |
40829 extractAttributes: true | |
40830 }) | |
40831 }) | |
40832 }); | |
40833 | |
40834 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
40835 | |
40836 this.openlayersMap.addLayer(newLayer); | |
40837 }); | |
40838 | |
40839 this.overlays.push(newOverlay); | |
40840 this.parent.gui.refreshOverlayList(); | |
40841 }, | |
40842 | |
40843 distributeKMZ : function(kmzURL) { | |
40844 var newOverlay = new Object(); | |
40845 newOverlay.name = kmzURL; | |
40846 newOverlay.layers = []; | |
40847 | |
40848 $(this.attachedMapWidgets).each(function(){ | |
40849 var newLayer = new OpenLayers.Layer.Vector("KML", { | |
40850 projection: this.openlayersMap.displayProjection, | |
40851 strategies: [new OpenLayers.Strategy.Fixed()], | |
40852 format: OpenLayers.Format.KML, | |
40853 extractAttributes: true | |
40854 }); | |
40855 | |
40856 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
40857 | |
40858 var map = this.openlayersMap; | |
40859 | |
40860 GeoTemConfig.getKmz(kmzURL, function(kmlDoms){ | |
40861 $(kmlDoms).each(function(){ | |
40862 var kml = new OpenLayers.Format.KML().read(this); | |
40863 newLayer.addFeatures(kml); | |
40864 map.addLayer(newLayer); | |
40865 }); | |
40866 }); | |
40867 }); | |
40868 | |
40869 this.overlays.push(newOverlay); | |
40870 this.parent.gui.refreshOverlayList(); | |
40871 }, | |
40872 | |
40873 distributeArcGISWMS : function(wmsURL, wmsLayer) { | |
40874 var newOverlay = new Object(); | |
40875 newOverlay.name = wmsURL + " - " + wmsLayer; | |
40876 newOverlay.layers = []; | |
40877 | |
40878 var newLayer = new OpenLayers.Layer.WMS("ArcGIS WMS label", wmsURL, { | |
40879 layers: wmsLayer, | |
40880 format: "image/png", | |
40881 transparent: "true" | |
40882 } | |
40883 ,{ | |
40884 displayOutsideMaxExtent: true, | |
40885 isBaseLayer: false, | |
40886 projection : "EPSG:3857" | |
40887 } | |
40888 ); | |
40889 | |
40890 newLayer.setIsBaseLayer(false); | |
40891 $(this.attachedMapWidgets).each(function(){ | |
40892 this.openlayersMap.addLayer(newLayer); | |
40893 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
40894 }); | |
40895 | |
40896 this.overlays.push(newOverlay); | |
40897 this.parent.gui.refreshOverlayList(); | |
40898 }, | |
40899 | |
40900 distributeXYZ : function(xyzURL,zoomOffset) { | |
40901 var newOverlay = new Object(); | |
40902 newOverlay.name = xyzURL; | |
40903 newOverlay.layers = []; | |
40904 | |
40905 var newLayer = new OpenLayers.Layer.XYZ( | |
40906 "XYZ Layer", | |
40907 [ | |
40908 xyzURL | |
40909 ], { | |
40910 sphericalMercator: true, | |
40911 transitionEffect: "resize", | |
40912 buffer: 1, | |
40913 numZoomLevels: 12, | |
40914 transparent : true, | |
40915 isBaseLayer : false, | |
40916 zoomOffset:zoomOffset?zoomOffset:0 | |
40917 } | |
40918 ); | |
40919 | |
40920 newLayer.setIsBaseLayer(false); | |
40921 $(this.attachedMapWidgets).each(function(){ | |
40922 this.openlayersMap.addLayer(newLayer); | |
40923 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
40924 }); | |
40925 | |
40926 this.overlays.push(newOverlay); | |
40927 this.parent.gui.refreshOverlayList(); | |
40928 }, | |
40929 | |
40930 addKMLLoader : function() { | |
40931 $(this.parent.gui.loaderTypeSelect).append("<option value='KMLLoader'>KML File URL</option>"); | |
40932 | |
40933 this.KMLLoaderTab = document.createElement("div"); | |
40934 $(this.KMLLoaderTab).attr("id","KMLLoader"); | |
40935 | |
40936 this.kmlURL = document.createElement("input"); | |
40937 $(this.kmlURL).attr("type","text"); | |
40938 $(this.KMLLoaderTab).append(this.kmlURL); | |
40939 | |
40940 this.loadKMLButton = document.createElement("button"); | |
40941 $(this.loadKMLButton).text("load KML"); | |
40942 $(this.KMLLoaderTab).append(this.loadKMLButton); | |
40943 | |
40944 $(this.loadKMLButton).click($.proxy(function(){ | |
40945 var kmlURL = $(this.kmlURL).val(); | |
40946 if (kmlURL.length == 0) | |
40947 return; | |
40948 if (typeof GeoTemConfig.proxy != 'undefined') | |
40949 kmlURL = GeoTemConfig.proxy + kmlURL; | |
40950 | |
40951 this.distributeKML(kmlURL); | |
40952 },this)); | |
40953 | |
40954 $(this.parent.gui.loaders).append(this.KMLLoaderTab); | |
40955 }, | |
40956 | |
40957 addKMZLoader : function() { | |
40958 $(this.parent.gui.loaderTypeSelect).append("<option value='KMZLoader'>KMZ File URL</option>"); | |
40959 | |
40960 this.KMZLoaderTab = document.createElement("div"); | |
40961 $(this.KMZLoaderTab).attr("id","KMZLoader"); | |
40962 | |
40963 this.kmzURL = document.createElement("input"); | |
40964 $(this.kmzURL).attr("type","text"); | |
40965 $(this.KMZLoaderTab).append(this.kmzURL); | |
40966 | |
40967 this.loadKMZButton = document.createElement("button"); | |
40968 $(this.loadKMZButton).text("load KMZ"); | |
40969 $(this.KMZLoaderTab).append(this.loadKMZButton); | |
40970 | |
40971 $(this.loadKMZButton).click($.proxy(function(){ | |
40972 var kmzURL = $(this.kmzURL).val(); | |
40973 if (kmzURL.length == 0) | |
40974 return; | |
40975 if (typeof GeoTemConfig.proxy != 'undefined') | |
40976 kmzURL = GeoTemConfig.proxy + kmzURL; | |
40977 | |
40978 this.distributeKMZ(kmzURL); | |
40979 },this)); | |
40980 | |
40981 $(this.parent.gui.loaders).append(this.KMZLoaderTab); | |
40982 }, | |
40983 | |
40984 addArcGISWMSLoader : function() { | |
40985 $(this.parent.gui.loaderTypeSelect).append("<option value='ArcGISWMSLoader'>ArcGIS WMS</option>"); | |
40986 | |
40987 this.ArcGISWMSLoaderTab = document.createElement("div"); | |
40988 $(this.ArcGISWMSLoaderTab).attr("id","ArcGISWMSLoader"); | |
40989 | |
40990 $(this.ArcGISWMSLoaderTab).append("URL: "); | |
40991 | |
40992 this.wmsURL = document.createElement("input"); | |
40993 $(this.wmsURL).attr("type","text"); | |
40994 $(this.ArcGISWMSLoaderTab).append(this.wmsURL); | |
40995 | |
40996 $(this.ArcGISWMSLoaderTab).append("Layer: "); | |
40997 | |
40998 this.wmsLayer = document.createElement("input"); | |
40999 $(this.wmsLayer).attr("type","text"); | |
41000 $(this.ArcGISWMSLoaderTab).append(this.wmsLayer); | |
41001 | |
41002 this.loadArcGISWMSButton = document.createElement("button"); | |
41003 $(this.loadArcGISWMSButton).text("load Layer"); | |
41004 $(this.ArcGISWMSLoaderTab).append(this.loadArcGISWMSButton); | |
41005 | |
41006 $(this.loadArcGISWMSButton).click($.proxy(function(){ | |
41007 var wmsURL = $(this.wmsURL).val(); | |
41008 var wmsLayer = $(this.wmsLayer).val(); | |
41009 if (wmsURL.length == 0) | |
41010 return; | |
41011 | |
41012 this.distributeArcGISWMS(wmsURL, wmsLayer); | |
41013 },this)); | |
41014 | |
41015 $(this.parent.gui.loaders).append(this.ArcGISWMSLoaderTab); | |
41016 }, | |
41017 | |
41018 addXYZLoader : function() { | |
41019 $(this.parent.gui.loaderTypeSelect).append("<option value='XYZLoader'>XYZ Layer</option>"); | |
41020 | |
41021 this.XYZLoaderTab = document.createElement("div"); | |
41022 $(this.XYZLoaderTab).attr("id","XYZLoader"); | |
41023 | |
41024 $(this.XYZLoaderTab).append("URL (with x,y,z variables): "); | |
41025 | |
41026 this.xyzURL = document.createElement("input"); | |
41027 $(this.xyzURL).attr("type","text"); | |
41028 $(this.XYZLoaderTab).append(this.xyzURL); | |
41029 | |
41030 this.loadXYZButton = document.createElement("button"); | |
41031 $(this.loadXYZButton).text("load Layer"); | |
41032 $(this.XYZLoaderTab).append(this.loadXYZButton); | |
41033 | |
41034 $(this.loadXYZButton).click($.proxy(function(){ | |
41035 var xyzURL = $(this.xyzURL).val(); | |
41036 if (xyzURL.length == 0) | |
41037 return; | |
41038 | |
41039 this.distributeXYZ(xyzURL); | |
41040 },this)); | |
41041 | |
41042 $(this.parent.gui.loaders).append(this.XYZLoaderTab); | |
41043 }, | |
41044 | |
41045 addRomanEmpireLoader : function() { | |
41046 $(this.parent.gui.loaderTypeSelect).append("<option value='RomanEmpireLoader'>Roman Empire</option>"); | |
41047 | |
41048 this.RomanEmpireLoaderTab = document.createElement("div"); | |
41049 $(this.RomanEmpireLoaderTab).attr("id","RomanEmpireLoader"); | |
41050 | |
41051 this.loadRomanEmpireButton = document.createElement("button"); | |
41052 $(this.loadRomanEmpireButton).text("load Layer"); | |
41053 $(this.RomanEmpireLoaderTab).append(this.loadRomanEmpireButton); | |
41054 | |
41055 $(this.loadRomanEmpireButton).click($.proxy(function(){ | |
41056 this.distributeXYZ("http://pelagios.dme.ait.ac.at/tilesets/imperium/${z}/${x}/${y}.png",1); | |
41057 },this)); | |
41058 | |
41059 $(this.parent.gui.loaders).append(this.RomanEmpireLoaderTab); | |
41060 }, | |
41061 | |
41062 addMapsForFreeWaterLayer : function() { | |
41063 $(this.parent.gui.loaderTypeSelect).append("<option value='MapsForFreeWaterLayerLoader'>Water Layer (Maps-For-Free)</option>"); | |
41064 | |
41065 this.MapsForFreeWaterTab = document.createElement("div"); | |
41066 $(this.MapsForFreeWaterTab).attr("id","MapsForFreeWaterLayerLoader"); | |
41067 | |
41068 this.loadMapsForFreeWaterLayerButton = document.createElement("button"); | |
41069 $(this.loadMapsForFreeWaterLayerButton).text("load Layer"); | |
41070 $(this.MapsForFreeWaterTab).append(this.loadMapsForFreeWaterLayerButton); | |
41071 | |
41072 $(this.loadMapsForFreeWaterLayerButton).click($.proxy(function(){ | |
41073 this.distributeXYZ("http://maps-for-free.com/layer/water/z${z}/row${y}/${z}_${x}-${y}.gif",1); | |
41074 },this)); | |
41075 | |
41076 $(this.parent.gui.loaders).append(this.MapsForFreeWaterTab); | |
41077 }, | |
41078 | |
41079 addConfigLoader : function() { | |
41080 if ( (this.parent.options.wms_overlays instanceof Array) && | |
41081 (this.parent.options.wms_overlays.length > 0) ){ | |
41082 var overlayloader = this; | |
41083 | |
41084 $(this.parent.gui.loaderTypeSelect).append("<option value='ConfigLoader'>Other WMS maps</option>"); | |
41085 | |
41086 this.ConfigLoaderTab = document.createElement("div"); | |
41087 $(this.ConfigLoaderTab).attr("id","ConfigLoader"); | |
41088 | |
41089 this.ConfigMapSelect = document.createElement("select"); | |
41090 $(this.parent.options.wms_overlays).each(function(){ | |
41091 var name = this.name, server = this.server, layer = this.layer; | |
41092 $(overlayloader.ConfigMapSelect).append("<option layer='"+layer+"' server='"+server+"' >"+name+"</option>"); | |
41093 }); | |
41094 | |
41095 $(this.ConfigLoaderTab).append(this.ConfigMapSelect); | |
41096 | |
41097 this.loadConfigMapButton = document.createElement("button"); | |
41098 $(this.loadConfigMapButton).text("load Layer"); | |
41099 $(this.ConfigLoaderTab).append(this.loadConfigMapButton); | |
41100 | |
41101 $(this.loadConfigMapButton).click($.proxy(function(){ | |
41102 var server = $(this.ConfigMapSelect).find(":selected").attr("server"); | |
41103 var layer = $(this.ConfigMapSelect).find(":selected").attr("layer"); | |
41104 this.distributeArcGISWMS(server,layer); | |
41105 },this)); | |
41106 | |
41107 $(this.parent.gui.loaders).append(this.ConfigLoaderTab); | |
41108 } | |
41109 } | |
41110 | |
41111 }; | |
41112 /* | |
41113 * OverlayloaderConfig.js | |
41114 * | |
41115 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41116 * | |
41117 * This library is free software; you can redistribute it and/or | |
41118 * modify it under the terms of the GNU Lesser General Public | |
41119 * License as published by the Free Software Foundation; either | |
41120 * version 3 of the License, or (at your option) any later version. | |
41121 * | |
41122 * This library is distributed in the hope that it will be useful, | |
41123 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41124 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41125 * Lesser General Public License for more details. | |
41126 * | |
41127 * You should have received a copy of the GNU Lesser General Public | |
41128 * License along with this library; if not, write to the Free Software | |
41129 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41130 * MA 02110-1301 USA | |
41131 */ | |
41132 | |
41133 /** | |
41134 * @class OverlayloaderConfig | |
41135 * Overlayloader Configuration File | |
41136 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41137 */ | |
41138 function OverlayloaderConfig(options) { | |
41139 | |
41140 this.options = { | |
41141 wms_overlays : [ | |
41142 //e.g. {name:'name', server:'url', layer:'layer'}, | |
41143 ], | |
41144 }; | |
41145 if ( typeof options != 'undefined') { | |
41146 $.extend(this.options, options); | |
41147 } | |
41148 | |
41149 }; | |
41150 /* | |
41151 * OverlayloaderGui.js | |
41152 * | |
41153 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41154 * | |
41155 * This library is free software; you can redistribute it and/or | |
41156 * modify it under the terms of the GNU Lesser General Public | |
41157 * License as published by the Free Software Foundation; either | |
41158 * version 3 of the License, or (at your option) any later version. | |
41159 * | |
41160 * This library is distributed in the hope that it will be useful, | |
41161 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41162 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41163 * Lesser General Public License for more details. | |
41164 * | |
41165 * You should have received a copy of the GNU Lesser General Public | |
41166 * License along with this library; if not, write to the Free Software | |
41167 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41168 * MA 02110-1301 USA | |
41169 */ | |
41170 | |
41171 /** | |
41172 * @class OverlayloaderGui | |
41173 * Overlayloader GUI Implementation | |
41174 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41175 * | |
41176 * @param {OverlayloaderWidget} parent Overlayloader widget object | |
41177 * @param {HTML object} div parent div to append the Overlayloader gui | |
41178 * @param {JSON} options Overlayloader configuration | |
41179 */ | |
41180 function OverlayloaderGui(overlayloader, div, options) { | |
41181 | |
41182 this.parent = overlayloader; | |
41183 var overlayloaderGui = this; | |
41184 | |
41185 this.overlayloaderContainer = div; | |
41186 this.overlayloaderContainer.style.position = 'relative'; | |
41187 | |
41188 this.loaderTypeSelect = document.createElement("select"); | |
41189 div.appendChild(this.loaderTypeSelect); | |
41190 | |
41191 this.loaders = document.createElement("div"); | |
41192 div.appendChild(this.loaders); | |
41193 | |
41194 this.overlayList = document.createElement("div"); | |
41195 div.appendChild(this.overlayList); | |
41196 | |
41197 $(this.loaderTypeSelect).change(function(){ | |
41198 var activeLoader = $(this).val(); | |
41199 $(overlayloaderGui.loaders).find("div").each(function(){ | |
41200 if ($(this).attr("id") == activeLoader) | |
41201 $(this).show(); | |
41202 else | |
41203 $(this).hide(); | |
41204 }); | |
41205 }); | |
41206 | |
41207 this.refreshOverlayList = function(){ | |
41208 var overlayloaderGui = this; | |
41209 | |
41210 $(overlayloaderGui.overlayList).empty(); | |
41211 $(this.parent.overlayLoader.overlays).each(function(){ | |
41212 var overlay = this; | |
41213 $(overlayloaderGui.overlayList).append(overlay.name); | |
41214 var link = document.createElement("a"); | |
41215 $(link).text("(x)"); | |
41216 link.href=""; | |
41217 | |
41218 $(link).click($.proxy(function(){ | |
41219 $(overlay.layers).each(function(){ | |
41220 this.map.removeLayer(this.layer); | |
41221 }); | |
41222 | |
41223 var overlays = overlayloaderGui.parent.overlayLoader.overlays; | |
41224 | |
41225 overlays = $.grep(overlays, function(value) { | |
41226 return overlay != value; | |
41227 }); | |
41228 | |
41229 overlayloaderGui.parent.overlayLoader.overlays = overlays; | |
41230 | |
41231 overlayloaderGui.refreshOverlayList(); | |
41232 | |
41233 return(false); | |
41234 },{overlay:overlay,overlayloaderGui:overlayloaderGui})); | |
41235 $(overlayloaderGui.overlayList).append(link); | |
41236 }); | |
41237 }; | |
41238 }; | |
41239 /* | |
41240 * OverlayloaderWidget.js | |
41241 * | |
41242 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41243 * | |
41244 * This library is free software; you can redistribute it and/or | |
41245 * modify it under the terms of the GNU Lesser General Public | |
41246 * License as published by the Free Software Foundation; either | |
41247 * version 3 of the License, or (at your option) any later version. | |
41248 * | |
41249 * This library is distributed in the hope that it will be useful, | |
41250 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41251 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41252 * Lesser General Public License for more details. | |
41253 * | |
41254 * You should have received a copy of the GNU Lesser General Public | |
41255 * License along with this library; if not, write to the Free Software | |
41256 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41257 * MA 02110-1301 USA | |
41258 */ | |
41259 | |
41260 /** | |
41261 * @class OverlayloaderWidget | |
41262 * OverlayloaderWidget Implementation | |
41263 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41264 * | |
41265 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
41266 * @param {HTML object} div parent div to append the Overlayloader widget div | |
41267 * @param {JSON} options user specified configuration that overwrites options in OverlayloaderConfig.js | |
41268 */ | |
41269 OverlayloaderWidget = function(core, div, options) { | |
41270 | |
41271 this.core = core; | |
41272 this.core.setWidget(this); | |
41273 | |
41274 this.options = (new OverlayloaderConfig(options)).options; | |
41275 this.gui = new OverlayloaderGui(this, div, this.options); | |
41276 | |
41277 this.attachedMapWidgets = new Array(); | |
41278 | |
41279 this.overlayLoader = new Overlayloader(this); | |
41280 } | |
41281 | |
41282 OverlayloaderWidget.prototype = { | |
41283 | |
41284 initWidget : function() { | |
41285 | |
41286 var overlayloaderWidget = this; | |
41287 }, | |
41288 | |
41289 highlightChanged : function(objects) { | |
41290 if( !GeoTemConfig.highlightEvents ){ | |
41291 return; | |
41292 } | |
41293 }, | |
41294 | |
41295 selectionChanged : function(selection) { | |
41296 if( !GeoTemConfig.selectionEvents ){ | |
41297 return; | |
41298 } | |
41299 }, | |
41300 | |
41301 triggerHighlight : function(item) { | |
41302 }, | |
41303 | |
41304 tableSelection : function() { | |
41305 }, | |
41306 | |
41307 deselection : function() { | |
41308 }, | |
41309 | |
41310 filtering : function() { | |
41311 }, | |
41312 | |
41313 inverseFiltering : function() { | |
41314 }, | |
41315 | |
41316 triggerRefining : function() { | |
41317 }, | |
41318 | |
41319 reset : function() { | |
41320 }, | |
41321 | |
41322 attachMapWidget : function(widget) { | |
41323 this.attachedMapWidgets.push(widget); | |
41324 } | |
41325 }; | |
41326 /* | |
41327 * PieChart.js | |
41328 * | |
41329 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41330 * | |
41331 * This library is free software; you can redistribute it and/or | |
41332 * modify it under the terms of the GNU Lesser General Public | |
41333 * License as published by the Free Software Foundation; either | |
41334 * version 3 of the License, or (at your option) any later version. | |
41335 * | |
41336 * This library is distributed in the hope that it will be useful, | |
41337 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41338 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41339 * Lesser General Public License for more details. | |
41340 * | |
41341 * You should have received a copy of the GNU Lesser General Public | |
41342 * License along with this library; if not, write to the Free Software | |
41343 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41344 * MA 02110-1301 USA | |
41345 */ | |
41346 | |
41347 /** | |
41348 * @class PieChart | |
41349 * Implementation for a PieChart | |
41350 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41351 * | |
41352 * @param {HTML object} parent div to append the PieChart | |
41353 */ | |
41354 function PieChart(parent, watchedDataset, watchedColumn, selectionFunction) { | |
41355 | |
41356 if ((typeof selectionFunction !== "undefined") && | |
41357 (typeof selectionFunction.type !== "undefined") && | |
41358 (typeof selectionFunction.categories !== "undefined")){ | |
41359 this.type = selectionFunction.type; | |
41360 this.categories = selectionFunction.categories; | |
41361 } | |
41362 this.pieChart = this; | |
41363 this.pieChartDiv; | |
41364 this.preHighlightObjects; | |
41365 this.highlightedLabel; | |
41366 | |
41367 this.informationDIV; | |
41368 this.pieChartLabel; | |
41369 | |
41370 this.parent = parent; | |
41371 this.options = parent.options; | |
41372 | |
41373 this.watchedDatasetObject; | |
41374 this.watchedDataset = parseInt(watchedDataset); | |
41375 this.watchColumn = watchedColumn; | |
41376 if (typeof selectionFunction !== "undefined") | |
41377 this.selectionFunction = selectionFunction; | |
41378 else | |
41379 //default selectionFunction returns value (creates "distinct" piechart) | |
41380 this.selectionFunction = function(columnData){return columnData;}; | |
41381 } | |
41382 | |
41383 PieChart.prototype = { | |
41384 | |
41385 remove : function() { | |
41386 for (var i = 0; i < this.parent.pieCharts.length; i++){ | |
41387 if (this.parent.pieCharts[i] === this) | |
41388 this.parent.pieCharts[i] = null; | |
41389 } | |
41390 $(this.pieChartDiv).remove(); | |
41391 $(this.informationDIV).remove(); | |
41392 this.parent.redrawPieCharts(); | |
41393 }, | |
41394 | |
41395 refreshLabel : function(){ | |
41396 $(this.pieChartLabel).empty(); | |
41397 $(this.pieChartLabel).append(this.watchedDatasetObject.label + " - " + this.watchColumn); | |
41398 | |
41399 var c = GeoTemConfig.getColor(this.watchedDataset); | |
41400 $(this.pieChartLabel).css("color","rgb("+c.r1+","+c.g1+","+c.b1+")"); | |
41401 }, | |
41402 | |
41403 initialize : function() { | |
41404 var pieChart = this; | |
41405 | |
41406 if (typeof this.pieChartDiv === "undefined"){ | |
41407 this.informationDIV = document.createElement("div"); | |
41408 this.pieChartLabel = $("<span></span>"); | |
41409 $(this.informationDIV).append(this.pieChartLabel); | |
41410 this.refreshLabel(); | |
41411 | |
41412 var removeButton = document.createElement("button"); | |
41413 $(this.informationDIV).append(removeButton); | |
41414 $(removeButton).text("remove"); | |
41415 $(removeButton).click(function(){ | |
41416 pieChart.remove(); | |
41417 }); | |
41418 | |
41419 //only allow editing if it is a "manually" created piechart | |
41420 //automatic (with a selection function) ones, can lead to numerous problems, | |
41421 //e.g. too many categories or numeral categories threated as text ones | |
41422 if ((typeof pieChart.type !== "undefined")&& | |
41423 (typeof pieChart.categories !== "undefined")){ | |
41424 var editButton = document.createElement("button"); | |
41425 $(this.informationDIV).append(editButton); | |
41426 $(editButton).text("edit"); | |
41427 $(editButton).click(function(){ | |
41428 var chooser = new PieChartCategoryChooser( | |
41429 pieChart.parent, | |
41430 pieChart.parent.options, | |
41431 pieChart.watchedDataset, | |
41432 pieChart.watchColumn, | |
41433 pieChart.type, | |
41434 pieChart.categories); | |
41435 }); | |
41436 | |
41437 //add save button | |
41438 if (pieChart.options.allowLocalStorage){ | |
41439 var saveButton = document.createElement("button"); | |
41440 $(this.informationDIV).append(saveButton); | |
41441 $(saveButton).text("save"); | |
41442 $(saveButton).click(function(){ | |
41443 $( "<div>" + | |
41444 "pie chart name : " + | |
41445 "<input type='text' size=30 id='saveName' class='ui-widget-content ui-corner-all'></input>" + | |
41446 "</div>").dialog({ | |
41447 width:'auto', | |
41448 buttons: [ | |
41449 { | |
41450 text: "save", | |
41451 click: function(){ | |
41452 var saveName = $("#saveName").val(); | |
41453 var saveObject = new Object(); | |
41454 saveObject.type = pieChart.type; | |
41455 saveObject.categories = pieChart.categories; | |
41456 saveObject.columnName = pieChart.watchColumn; | |
41457 //save to LocalStorage | |
41458 $.remember({ | |
41459 name:pieChart.options.localStoragePrefix+saveName, | |
41460 value:saveObject, | |
41461 json:true | |
41462 }); | |
41463 $(this).dialog( "close" ); | |
41464 } | |
41465 } | |
41466 ] | |
41467 }); | |
41468 | |
41469 //set value to default (column name) | |
41470 $("#saveName").val(pieChart.watchColumn); | |
41471 //TODO: z-index has to be set, as the "tool-bars" of map (.ddbToolbar in style.css) | |
41472 //also have a z-index of 10000. z-index should be removed from all elements. | |
41473 $(".ui-dialog").css("z-index",10005); | |
41474 }); | |
41475 } | |
41476 } | |
41477 | |
41478 $(this.parent.gui.pieChartsDiv).append(this.informationDIV); | |
41479 this.pieChartDiv = document.createElement("div"); | |
41480 $(this.parent.gui.pieChartsDiv).append(this.pieChartDiv); | |
41481 | |
41482 $(this.pieChartDiv).unbind(); | |
41483 $(this.pieChartDiv).bind("plothover", function (event, pos, item) { | |
41484 var highlightedLabel; | |
41485 | |
41486 if (item) { | |
41487 highlightedLabel = item.series.label; | |
41488 } | |
41489 if (highlightedLabel !== pieChart.highlightedLabel){ | |
41490 pieChart.highlightedLabel = highlightedLabel; | |
41491 pieChart.triggerHighlight(highlightedLabel); | |
41492 } | |
41493 }); | |
41494 | |
41495 $(this.pieChartDiv).bind("plotclick", function (event, pos, item) { | |
41496 if (item) { | |
41497 //item.series.label contains the column element | |
41498 pieChart.triggerSelection(item.series.label); | |
41499 } else { | |
41500 pieChart.triggerSelection(); | |
41501 } | |
41502 }); | |
41503 } | |
41504 }, | |
41505 | |
41506 //check if dataset is still there | |
41507 checkForDataSet : function() { | |
41508 var datasets = this.parent.datasets; | |
41509 if ((typeof datasets !== "undefined") && (typeof this.watchedDatasetObject !== "undefined")){ | |
41510 //check if our data went missing | |
41511 for (var i = 0; i < datasets.length; i++){ | |
41512 if (datasets[i] === this.watchedDatasetObject){ | |
41513 //if dataset "before" this one was removed, the index changes | |
41514 if (this.watchedDataset !== i){ | |
41515 //change color to the new one (changes with index!) | |
41516 this.watchedDataset = i; | |
41517 this.refreshLabel(); | |
41518 } | |
41519 return true; | |
41520 } | |
41521 } | |
41522 } | |
41523 return false; | |
41524 }, | |
41525 | |
41526 initPieChart : function(dataSets) { | |
41527 // get dataset object (could not be there on startup, e.g. piechart defined before load completes) | |
41528 if (typeof this.watchedDatasetObject === "undefined") | |
41529 this.watchedDatasetObject = this.parent.datasets[this.watchedDataset]; | |
41530 | |
41531 this.initialize(); | |
41532 | |
41533 // if our dataset went missing, remove this piechart | |
41534 if (!this.checkForDataSet()){ | |
41535 this.remove(); | |
41536 return; | |
41537 } | |
41538 | |
41539 var objects = []; | |
41540 for (var i = 0; i < dataSets.length; i++) | |
41541 objects.push([]); | |
41542 objects[this.watchedDataset] = dataSets[this.watchedDataset].objects; | |
41543 | |
41544 this.preHighlightObjects = objects; | |
41545 this.redrawPieChart(objects); | |
41546 }, | |
41547 | |
41548 redrawPieChart : function(objects) { | |
41549 | |
41550 if (typeof objects === "undefined") | |
41551 objects = this.preHighlightObjects; | |
41552 | |
41553 if (this.checkForDataSet(objects)){ | |
41554 var pieChart = this; | |
41555 if (objects[this.watchedDataset].length === 0) | |
41556 objects = this.preHighlightObjects; | |
41557 | |
41558 var calculateSlices = function(dataObjects){ | |
41559 var chartDataCounter = new Object; | |
41560 | |
41561 $(dataObjects).each(function(){ | |
41562 var columnData = pieChart.parent.getElementData(this, pieChart.watchColumn, pieChart.selectionFunction); | |
41563 | |
41564 //disregard empty cells | |
41565 if ( (typeof columnData === "undefined") || (columnData == "") ) | |
41566 return; | |
41567 | |
41568 var weight = this.weight; | |
41569 | |
41570 if (typeof chartDataCounter[columnData] === "undefined") | |
41571 chartDataCounter[columnData] = weight; | |
41572 else | |
41573 chartDataCounter[columnData] += weight; | |
41574 }); | |
41575 | |
41576 var chartData = []; | |
41577 $.each(chartDataCounter, function(name,val){ | |
41578 //get rgb-color (24bit = 6 hex digits) from hash | |
41579 var color = '#'+hex_md5(name).substr(0,6); | |
41580 chartData.push({label:name,data:val,color:color}); | |
41581 }); | |
41582 | |
41583 //sort by count (occurances of category) | |
41584 var sortByVal = function(a,b){ | |
41585 return (b.data-a.data); | |
41586 }; | |
41587 chartData.sort(sortByVal); | |
41588 | |
41589 return chartData; | |
41590 }; | |
41591 | |
41592 var chartData = calculateSlices(objects[this.watchedDataset]); | |
41593 | |
41594 if (chartData.length>0){ | |
41595 $(this.pieChartDiv).empty(); | |
41596 | |
41597 //calculate height (flot NEEDS a height) | |
41598 var parentHeight = $(this.parent.gui.pieChartsDiv).outerHeight(true);// - $(this.parent.gui.columnSelectorDiv).outerHeight(true);//***lchang | |
41599 var pieChartCount = 0; | |
41600 $(this.parent.pieCharts).each(function(){ | |
41601 if (this instanceof PieChart) | |
41602 pieChartCount++; | |
41603 }); | |
41604 var height = (parentHeight/pieChartCount) - $(this.informationDIV).outerHeight(true); | |
41605 if (pieChart.options.restrictPieChartSize !== false) | |
41606 height = Math.min(height, /*$(window).height()*/parentHeight * pieChart.options.restrictPieChartSize);//***lchang | |
41607 if(height>300) | |
41608 height=300; | |
41609 if(height<150) | |
41610 height=150; | |
41611 $(this.pieChartDiv).height(height); | |
41612 | |
41613 $.plot($(this.pieChartDiv), chartData, | |
41614 { | |
41615 series: { | |
41616 // Make this a pie chart. | |
41617 pie: { | |
41618 show:true | |
41619 } | |
41620 }, | |
41621 legend: { show:true, position: 'se' }, | |
41622 grid: { | |
41623 hoverable: true, | |
41624 clickable: true | |
41625 }, | |
41626 tooltip: true, | |
41627 tooltipOpts: { | |
41628 content: "%s %p.1%" | |
41629 } | |
41630 } | |
41631 ); | |
41632 } | |
41633 } | |
41634 }, | |
41635 | |
41636 triggerHighlight : function(columnElement) { | |
41637 var highlightedObjects = []; | |
41638 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
41639 highlightedObjects.push([]); | |
41640 | |
41641 if (this.watchedDataset >= 0) | |
41642 highlightedObjects[this.watchedDataset] = | |
41643 this.parent.getElementsByValue(columnElement, this.watchedDataset, this.watchColumn, this.selectionFunction); | |
41644 else | |
41645 highlightedObjects[this.watchedDataset] = []; | |
41646 | |
41647 this.parent.core.triggerHighlight(highlightedObjects); | |
41648 | |
41649 var pieChart = this; | |
41650 $(this.parent.pieCharts).each(function(){ | |
41651 if (this instanceof PieChart && (this !== pieChart)){ | |
41652 if (this.watchedDataset === pieChart.watchedDataset) | |
41653 this.redrawPieChart(highlightedObjects); | |
41654 } | |
41655 }); | |
41656 }, | |
41657 | |
41658 triggerSelection : function(columnElement) { | |
41659 var selectedObjects = []; | |
41660 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
41661 selectedObjects.push([]); | |
41662 | |
41663 var selection; | |
41664 if (typeof columnElement !== "undefined"){ | |
41665 selectedObjects[this.watchedDataset] = | |
41666 this.parent.getElementsByValue(columnElement, this.watchedDataset, this.watchColumn, this.selectionFunction); | |
41667 selection = new Selection(selectedObjects, this); | |
41668 } else { | |
41669 selection = new Selection(selectedObjects); | |
41670 } | |
41671 | |
41672 this.parent.core.triggerSelection(selection); | |
41673 | |
41674 if (!selection.valid()){ | |
41675 selection.loadAllObjects(); | |
41676 //"undo" selection (click next to piechart) | |
41677 //so also redraw this dataset | |
41678 this.preHighlightObjects = selection.objects; | |
41679 this.redrawPieChart(selection.objects); | |
41680 } | |
41681 | |
41682 var pieChart = this; | |
41683 $(this.parent.pieCharts).each(function(){ | |
41684 if (this instanceof PieChart && (this !== pieChart)){ | |
41685 if (this.watchedDataset === pieChart.watchedDataset){ | |
41686 this.preHighlightObjects = selection.objects; | |
41687 this.redrawPieChart(selection.objects); | |
41688 } | |
41689 } | |
41690 }); | |
41691 }, | |
41692 | |
41693 deselection : function() { | |
41694 }, | |
41695 | |
41696 filtering : function() { | |
41697 }, | |
41698 | |
41699 inverseFiltering : function() { | |
41700 }, | |
41701 | |
41702 triggerRefining : function() { | |
41703 }, | |
41704 | |
41705 reset : function() { | |
41706 }, | |
41707 | |
41708 show : function() { | |
41709 }, | |
41710 | |
41711 hide : function() { | |
41712 } | |
41713 }; | |
41714 /* | |
41715 * PieChartCategoryChooser.js | |
41716 * | |
41717 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41718 * | |
41719 * This library is free software; you can redistribute it and/or | |
41720 * modify it under the terms of the GNU Lesser General Public | |
41721 * License as published by the Free Software Foundation; either | |
41722 * version 3 of the License, or (at your option) any later version. | |
41723 * | |
41724 * This library is distributed in the hope that it will be useful, | |
41725 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41726 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41727 * Lesser General Public License for more details. | |
41728 * | |
41729 * You should have received a copy of the GNU Lesser General Public | |
41730 * License along with this library; if not, write to the Free Software | |
41731 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41732 * MA 02110-1301 USA | |
41733 */ | |
41734 | |
41735 /** | |
41736 * @class PieChartCategoryChooser | |
41737 * PieChart dialog for category creation | |
41738 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41739 * | |
41740 * @param {PieChartWidget} parent PieChart widget object | |
41741 * @param {JSON} options PieChart configuration | |
41742 * @param {number} datasetIndex index of the dataset | |
41743 * @param {String} columnName name of the column | |
41744 */ | |
41745 | |
41746 function PieChartCategoryChooser(pieChart, options, datasetIndex, columnName, type, categories) { | |
41747 | |
41748 var pieChartCategoryChooser = this; | |
41749 | |
41750 this.parent = pieChart; | |
41751 this.options = options; | |
41752 this.datasetIndex = parseInt(datasetIndex); | |
41753 this.columnName = columnName; | |
41754 this.chartData; | |
41755 | |
41756 this.dialog = $("<div></div>"); | |
41757 this.dialog.html("").dialog({modal: true}).dialog('open'); | |
41758 | |
41759 //to asure that the dialog is above (z-index of) the toolbars | |
41760 $(".ui-front").css("z-index","20011"); | |
41761 | |
41762 var allNumeric = this.loadValues(datasetIndex, columnName); | |
41763 | |
41764 if (typeof allNumeric === "undefined") | |
41765 return; | |
41766 if (allNumeric === true){ | |
41767 this.createNumeralBasedChooser(this.chartData, categories); | |
41768 } else { | |
41769 this.createTextBasedChooser(this.chartData, categories); | |
41770 } | |
41771 }; | |
41772 | |
41773 PieChartCategoryChooser.prototype = { | |
41774 | |
41775 loadValues : function(datasetIndex, columnName){ | |
41776 var pieChartCategoryChooser = this; | |
41777 | |
41778 var allNumeric = true; | |
41779 pieChartCategoryChooser.chartData = []; | |
41780 var chartData = pieChartCategoryChooser.chartData; | |
41781 $(GeoTemConfig.datasets[datasetIndex].objects).each(function(){ | |
41782 var columnData = | |
41783 pieChartCategoryChooser.parent.getElementData(this, columnName); | |
41784 | |
41785 if (isNaN(parseFloat(columnData))) | |
41786 allNumeric = false; | |
41787 | |
41788 if ($.inArray(columnData, chartData) == -1) | |
41789 chartData.push(columnData); | |
41790 }); | |
41791 | |
41792 if (chartData.length === 0) | |
41793 return; | |
41794 else | |
41795 return allNumeric; | |
41796 }, | |
41797 | |
41798 createTextBasedChooser : function(chartData, categories){ | |
41799 var pieChartCategoryChooser = this; | |
41800 | |
41801 var addCategory = function(name,elements){ | |
41802 var newCategoryContainer = document.createElement("fieldset"); | |
41803 var newCategoryLegend = document.createElement("legend"); | |
41804 var newCategoryName = document.createElement("input"); | |
41805 $(newCategoryName).width("80%"); | |
41806 newCategoryName.type = "text"; | |
41807 newCategoryName.value = name; | |
41808 var newCategoryRemove = document.createElement("button"); | |
41809 $(newCategoryRemove).text("X"); | |
41810 $(newCategoryRemove).click(function(){ | |
41811 $(newCategoryContainer).find("li").each(function(){ | |
41812 //move all elements to unselected list | |
41813 //("unselected" is defined below) | |
41814 //prepend so the items appear on top | |
41815 $(this).prependTo(unselected); | |
41816 }); | |
41817 //and remove this category | |
41818 $(newCategoryContainer).remove(); | |
41819 }); | |
41820 $(newCategoryLegend).append(newCategoryName); | |
41821 $(newCategoryLegend).append(newCategoryRemove); | |
41822 $(newCategoryContainer).append(newCategoryLegend); | |
41823 $(newCategoryContainer).width("200px"); | |
41824 $(newCategoryContainer).css("float","left"); | |
41825 var newCategory = document.createElement("ul"); | |
41826 $(newCategory).addClass("connectedSortable"); | |
41827 $(newCategory).css("background", "#eee"); | |
41828 newCategoryContainer.appendChild(newCategory); | |
41829 $(newCategory).append("<br/>"); | |
41830 cell.appendChild(newCategoryContainer); | |
41831 //if there are pre-selected elements (e.g. "edit") | |
41832 //add them and remove them from unselected value list | |
41833 if (typeof elements !== "undefined"){ | |
41834 $(elements).each(function(){ | |
41835 var value = this; | |
41836 //add to category | |
41837 $(newCategory).append("<li>"+value+"</li>"); | |
41838 //remove from unselected list | |
41839 $(unselected).find("li").filter(function(){ | |
41840 return ($(this).text() === ""+value); | |
41841 }).remove(); | |
41842 }); | |
41843 } | |
41844 | |
41845 $( ".connectedSortable" ).sortable({ | |
41846 connectWith: ".connectedSortable" | |
41847 }).disableSelection(); | |
41848 }; | |
41849 | |
41850 var table = document.createElement("table"); | |
41851 var row = document.createElement("tr"); | |
41852 table.appendChild(row); | |
41853 var cell = document.createElement("td"); | |
41854 row.appendChild(cell); | |
41855 cell = document.createElement("td"); | |
41856 row.appendChild(cell); | |
41857 var addCategoryButton = document.createElement("button"); | |
41858 $(addCategoryButton).text("add new category"); | |
41859 cell.appendChild(addCategoryButton); | |
41860 var applyCategoryButton = document.createElement("button"); | |
41861 $(applyCategoryButton).text("apply"); | |
41862 cell.appendChild(applyCategoryButton); | |
41863 | |
41864 row = document.createElement("tr"); | |
41865 table.appendChild(row); | |
41866 cell = document.createElement("td"); | |
41867 row.appendChild(cell); | |
41868 var unselected = document.createElement("ul"); | |
41869 $(unselected).addClass("connectedSortable"); | |
41870 cell.appendChild(unselected); | |
41871 cell = document.createElement("td"); | |
41872 $(cell).attr("valign","top"); | |
41873 $(cell).width("100%"); | |
41874 row.appendChild(cell); | |
41875 | |
41876 this.dialog.append(table); | |
41877 | |
41878 $( ".connectedSortable" ).sortable({ | |
41879 connectWith: ".connectedSortable" | |
41880 }).disableSelection(); | |
41881 | |
41882 $(chartData).each(function(){ | |
41883 $(unselected).append("<li class='ui-state-default'>"+this+"</li>"); | |
41884 }); | |
41885 | |
41886 if (typeof categories !== "undefined"){ | |
41887 $(categories).each(function(){ | |
41888 var category = this; | |
41889 addCategory(category.label, category.values); | |
41890 }); | |
41891 } | |
41892 | |
41893 $(addCategoryButton).click(function(){addCategory();}); | |
41894 | |
41895 $(applyCategoryButton).click(function(){ | |
41896 var categories = []; | |
41897 $(cell).children().each(function(){ | |
41898 var label = $(this).find("legend > input").val(); | |
41899 var values = []; | |
41900 $(this).find("li").each(function(){ | |
41901 values.push($(this).text()); | |
41902 }); | |
41903 | |
41904 categories.push({label:label,values:values}); | |
41905 }); | |
41906 | |
41907 var values = []; | |
41908 $(unselected).find("li").each(function(){ | |
41909 values.push($(this).text()); | |
41910 }); | |
41911 | |
41912 categories.push({label:"other",values:values}); | |
41913 | |
41914 //create pie chart | |
41915 pieChartCategoryChooser.parent.addCategorizedPieChart( | |
41916 pieChartCategoryChooser.datasetIndex, pieChartCategoryChooser.columnName, | |
41917 "text", categories); | |
41918 | |
41919 //close dialog | |
41920 $(pieChartCategoryChooser.dialog).dialog("close"); | |
41921 }); | |
41922 | |
41923 //set dialog size | |
41924 var wWidth = $(window).width(); | |
41925 var dWidth = wWidth * 0.9; | |
41926 var wHeight = $(window).height(); | |
41927 var dHeight = wHeight * 0.9; | |
41928 $(this.dialog).dialog("option", "width", dWidth); | |
41929 $(this.dialog).dialog("option", "height", dHeight); | |
41930 }, | |
41931 | |
41932 createNumeralBasedChooser : function(chartData, existingCategories){ | |
41933 var numericChartData = []; | |
41934 for (var i = 0; i < chartData.length; i++){ | |
41935 numericChartData.push(parseFloat(chartData[i])); | |
41936 } | |
41937 chartData = numericChartData; | |
41938 chartData = chartData.sort(function sortNumber(a,b){ | |
41939 return a - b; | |
41940 }); | |
41941 | |
41942 var min = chartData[0]; | |
41943 var max = chartData[chartData.length-1]; | |
41944 //find minimum step width that is needed | |
41945 //(otherwise there could be steps that contain more than one element) | |
41946 var minStep=max-min; | |
41947 for (var i = 1; i < chartData.length; i++){ | |
41948 var thisStep = chartData[i]-chartData[i-1]; | |
41949 if ((thisStep) < minStep) | |
41950 minStep = thisStep; | |
41951 } | |
41952 | |
41953 var pieChartCategoryChooser = this; | |
41954 | |
41955 var addCategoryButton = document.createElement("button"); | |
41956 $(addCategoryButton).text("add new category"); | |
41957 this.dialog.append(addCategoryButton); | |
41958 var applyCategoryButton = document.createElement("button"); | |
41959 $(applyCategoryButton).text("apply"); | |
41960 this.dialog.append(applyCategoryButton); | |
41961 this.dialog.append("tip: use left/right arrow key for finer adjustment"); | |
41962 | |
41963 var table = document.createElement("table"); | |
41964 row = document.createElement("tr"); | |
41965 table.appendChild(row); | |
41966 cell = document.createElement("td"); | |
41967 row.appendChild(cell); | |
41968 cell.colSpan = 2; | |
41969 var slider = document.createElement("div"); | |
41970 cell.appendChild(slider); | |
41971 var handles = []; | |
41972 var categories = []; | |
41973 | |
41974 row = document.createElement("tr"); | |
41975 table.appendChild(row); | |
41976 cell = document.createElement("td"); | |
41977 $(cell).attr("valign","top"); | |
41978 row.appendChild(cell); | |
41979 var unselected = document.createElement("ul"); | |
41980 cell.appendChild(unselected); | |
41981 | |
41982 cell = document.createElement("td"); | |
41983 $(cell).attr("valign","top"); | |
41984 $(cell).width("100%"); | |
41985 row.appendChild(cell); | |
41986 | |
41987 this.dialog.append(table); | |
41988 | |
41989 $(chartData).each(function(){ | |
41990 $(unselected).append("<li class='ui-state-default'>"+this+"</li>"); | |
41991 }); | |
41992 | |
41993 var addCategory = function(boundary){ | |
41994 //check if another handle can be added | |
41995 if ((handles.length>0) && (handles[handles.length-1] === max)) | |
41996 return false; | |
41997 //destroy old slider (has to be recreated to show the new handle) | |
41998 if (handles.length>0) | |
41999 $(slider).slider("destroy"); | |
42000 | |
42001 if (typeof boundary === "undefined") | |
42002 boundary = max; | |
42003 handles.push(boundary); | |
42004 | |
42005 $(slider).slider({ | |
42006 min:min, | |
42007 max:max, | |
42008 step:minStep, | |
42009 values: handles | |
42010 }); | |
42011 | |
42012 var placeValues = function(){ | |
42013 $(unselected).find("li").remove(); | |
42014 $(cell).children().find("li").remove(); | |
42015 | |
42016 var j = 0, i = 0; | |
42017 for (; i < chartData.length; i++){ | |
42018 if (chartData[i]>handles[j]) | |
42019 j++; | |
42020 if (j == handles.length) | |
42021 break; | |
42022 $(categories[j]).append("<li class='ui-state-default'>"+chartData[i]+"</li>"); | |
42023 } | |
42024 for (; i < chartData.length; i++){ | |
42025 $(unselected).append("<li class='ui-state-default'>"+chartData[i]+"</li>"); | |
42026 } | |
42027 }; | |
42028 | |
42029 $(slider).on( "slide", function( event, ui ){ | |
42030 var last = min; | |
42031 //check whether handle values are increasing | |
42032 for(var i = 0; i < ui.values.length; i++){ | |
42033 if (ui.values[i]<last) | |
42034 return false; | |
42035 last = ui.values[i]; | |
42036 } | |
42037 handles = ui.values; | |
42038 for(var i = 0; i < handles.length; i++){ | |
42039 $(categories[i]).parent().find("legend").text("<="+handles[i]); | |
42040 } | |
42041 | |
42042 placeValues(); | |
42043 }); | |
42044 | |
42045 var newCategoryContainer = document.createElement("fieldset"); | |
42046 $(newCategoryContainer).append("<legend><="+boundary+"</legend>"); | |
42047 $(newCategoryContainer).width("188px"); | |
42048 $(newCategoryContainer).css("float","left"); | |
42049 var newCategory = document.createElement("ul"); | |
42050 $(newCategory).addClass("connectedSortable"); | |
42051 $(newCategory).css("background", "#eee"); | |
42052 newCategoryContainer.appendChild(newCategory); | |
42053 cell.appendChild(newCategoryContainer); | |
42054 categories.push(newCategory); | |
42055 | |
42056 placeValues(); | |
42057 }; | |
42058 | |
42059 $(addCategoryButton).click(function(){addCategory();}); | |
42060 | |
42061 if (typeof existingCategories !== "undefined"){ | |
42062 $(existingCategories).each(function(){ | |
42063 var boundary = this; | |
42064 addCategory(boundary); | |
42065 }); | |
42066 } | |
42067 | |
42068 $(applyCategoryButton).click(function(){ | |
42069 var categorieBoundaries = handles; | |
42070 | |
42071 //create pie chart | |
42072 pieChartCategoryChooser.parent.addCategorizedPieChart( | |
42073 pieChartCategoryChooser.datasetIndex, pieChartCategoryChooser.columnName, | |
42074 "numeral", categorieBoundaries); | |
42075 | |
42076 //close dialog | |
42077 $(pieChartCategoryChooser.dialog).dialog("close"); | |
42078 }); | |
42079 | |
42080 //set dialog size | |
42081 var wWidth = $(window).width(); | |
42082 var dWidth = wWidth * 0.9; | |
42083 var wHeight = $(window).height(); | |
42084 var dHeight = wHeight * 0.9; | |
42085 $(this.dialog).dialog("option", "width", dWidth); | |
42086 $(this.dialog).dialog("option", "height", dHeight); | |
42087 } | |
42088 }; | |
42089 /* | |
42090 * PieChartConfig.js | |
42091 * | |
42092 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42093 * | |
42094 * This library is free software; you can redistribute it and/or | |
42095 * modify it under the terms of the GNU Lesser General Public | |
42096 * License as published by the Free Software Foundation; either | |
42097 * version 3 of the License, or (at your option) any later version. | |
42098 * | |
42099 * This library is distributed in the hope that it will be useful, | |
42100 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42101 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42102 * Lesser General Public License for more details. | |
42103 * | |
42104 * You should have received a copy of the GNU Lesser General Public | |
42105 * License along with this library; if not, write to the Free Software | |
42106 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42107 * MA 02110-1301 USA | |
42108 */ | |
42109 | |
42110 /** | |
42111 * @class PieChartConfig | |
42112 * PieChart Configuration File | |
42113 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42114 */ | |
42115 function PieChartConfig(options) { | |
42116 | |
42117 this.options = { | |
42118 restrictPieChartSize : 0.8, // restrict size to percantage of window size (false for no restriction) | |
42119 localStoragePrefix : "GeoBrowser_PieChart_", // prefix for value name in LocalStorage | |
42120 allowLocalStorage : true, //whether LocalStorage save and load should be allowed (and buttons shown) | |
42121 }; | |
42122 if ( typeof options != 'undefined') { | |
42123 $.extend(this.options, options); | |
42124 } | |
42125 | |
42126 }; | |
42127 /* | |
42128 * PieChartGui.js | |
42129 * | |
42130 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42131 * | |
42132 * This library is free software; you can redistribute it and/or | |
42133 * modify it under the terms of the GNU Lesser General Public | |
42134 * License as published by the Free Software Foundation; either | |
42135 * version 3 of the License, or (at your option) any later version. | |
42136 * | |
42137 * This library is distributed in the hope that it will be useful, | |
42138 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42139 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42140 * Lesser General Public License for more details. | |
42141 * | |
42142 * You should have received a copy of the GNU Lesser General Public | |
42143 * License along with this library; if not, write to the Free Software | |
42144 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42145 * MA 02110-1301 USA | |
42146 */ | |
42147 | |
42148 /** | |
42149 * @class PieChartGui | |
42150 * PieChart GUI Implementation | |
42151 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42152 * | |
42153 * @param {PieChartWidget} parent PieChart widget object | |
42154 * @param {HTML object} div parent div to append the PieChart gui | |
42155 * @param {JSON} options PieChart configuration | |
42156 */ | |
42157 function PieChartGui(pieChart, div, options) { | |
42158 | |
42159 this.parent = pieChart; | |
42160 this.options = options; | |
42161 var pieChartGui = this; | |
42162 | |
42163 this.pieChartContainer = div; | |
42164 this.pieChartContainer.style.position = 'relative'; | |
42165 | |
42166 this.columnSelectorDiv = document.createElement("div"); | |
42167 div.appendChild(this.columnSelectorDiv); | |
42168 this.datasetSelect = document.createElement("select"); | |
42169 $(this.datasetSelect).change(function(event){ | |
42170 if (typeof pieChartGui.parent.datasets !== "undefined"){ | |
42171 var dataset = pieChartGui.parent.datasets[$(pieChartGui.datasetSelect).val()]; | |
42172 if (dataset.objects.length > 0){ | |
42173 //This implies that the dataObjects are homogenous | |
42174 var firstObject = dataset.objects[0]; | |
42175 var firstTableContent = firstObject.tableContent; | |
42176 $(pieChartGui.columnSelect).empty(); | |
42177 | |
42178 $(pieChartGui.columnSelect).append("<optgroup label='saved'>"); | |
42179 | |
42180 for(var key in localStorage){ | |
42181 //TODO: this is a somewhat bad idea, as it is used in multiple widgets. | |
42182 //A global GeoTemCo option "prefix" could be better. But still.. | |
42183 var prefix = pieChartGui.options.localStoragePrefix; | |
42184 if (key.startsWith(prefix)){ | |
42185 var saveObject = $.remember({name:key,json:true}); | |
42186 var label = key.substring(prefix.length); | |
42187 //small safety-check: if the column is not part of this dataset, don't show it | |
42188 if (typeof firstTableContent[saveObject.columnName] !== "undefined") | |
42189 $(pieChartGui.columnSelect).append("<option isSaved=1 value='"+label+"'>"+decodeURIComponent(label)+"</option>"); | |
42190 } | |
42191 } | |
42192 $(pieChartGui.columnSelect).append("</optgroup>"); | |
42193 | |
42194 $(pieChartGui.columnSelect).append("<optgroup label='new'>"); | |
42195 for (var attribute in firstTableContent) { | |
42196 $(pieChartGui.columnSelect).append("<option value='"+attribute+"'>"+attribute+"</option>"); | |
42197 } | |
42198 if (firstObject.isTemporal) | |
42199 $(pieChartGui.columnSelect).append("<option value='dates[0].date'>date</option>"); | |
42200 if (typeof firstObject.locations[0] !== "undefined"){ | |
42201 $(pieChartGui.columnSelect).append("<option value='locations[0].latitude'>lat</option>"); | |
42202 $(pieChartGui.columnSelect).append("<option value='locations[0].longitude'>lon</option>"); | |
42203 } | |
42204 $(pieChartGui.columnSelect).append("</optgroup>"); | |
42205 } | |
42206 } | |
42207 }); | |
42208 this.columnSelectorDiv.appendChild(this.datasetSelect); | |
42209 this.columnSelect = document.createElement("select"); | |
42210 this.columnSelectorDiv.appendChild(this.columnSelect); | |
42211 this.buttonNewPieChart = document.createElement("button"); | |
42212 $(this.buttonNewPieChart).text("add"); | |
42213 this.columnSelectorDiv.appendChild(this.buttonNewPieChart); | |
42214 $(this.buttonNewPieChart).click(function(){ | |
42215 //check if this is a local saved pie chart | |
42216 var isSaved=$(pieChartGui.columnSelect).find("option:selected").first().attr("isSaved"); | |
42217 if ((typeof isSaved === "undefined") || (isSaved!=1)){ | |
42218 //create new pie chart (where each value is its own category) | |
42219 pieChartGui.parent.addPieChart($(pieChartGui.datasetSelect).val(), $(pieChartGui.columnSelect).val()); | |
42220 } else { | |
42221 //is local saved, get value | |
42222 var name = pieChartGui.options.localStoragePrefix + $(pieChartGui.columnSelect).val(); | |
42223 var saveObject = $.remember({name:name,json:true}); | |
42224 if ((typeof saveObject !== "undefined") && (saveObject != null)){ | |
42225 var categories = saveObject.categories; | |
42226 var type = saveObject.type; | |
42227 var columnName = saveObject.columnName; | |
42228 | |
42229 //create pie chart | |
42230 pieChartGui.parent.addCategorizedPieChart( | |
42231 $(pieChartGui.datasetSelect).val(), columnName, | |
42232 type, categories); | |
42233 } | |
42234 } | |
42235 }); | |
42236 this.buttonPieChartCategoryChooser = document.createElement("button"); | |
42237 $(this.buttonPieChartCategoryChooser).text("categorize"); | |
42238 this.columnSelectorDiv.appendChild(this.buttonPieChartCategoryChooser); | |
42239 $(this.buttonPieChartCategoryChooser).click(function(){ | |
42240 //check if this is a local saved pie chart | |
42241 var isSaved=$(pieChartGui.columnSelect).find("option:selected").first().attr("isSaved"); | |
42242 if ((typeof isSaved === "undefined") || (isSaved!=1)){ | |
42243 var chooser = new PieChartCategoryChooser( pieChartGui.parent, | |
42244 pieChartGui.options, | |
42245 $(pieChartGui.datasetSelect).val(), | |
42246 $(pieChartGui.columnSelect).val() ); | |
42247 } else { | |
42248 alert("Saved datasets can not be categorized again. Try loading and editing instead."); | |
42249 } | |
42250 }); | |
42251 | |
42252 this.refreshColumnSelector(); | |
42253 | |
42254 this.pieChartsDiv = document.createElement("div"); | |
42255 this.pieChartsDiv.id = "pieChartsDivID"; | |
42256 div.appendChild(this.pieChartsDiv); | |
42257 $(this.pieChartsDiv).height("100%"); | |
42258 var h=$(div).height(); | |
42259 h-=30; | |
42260 $(this.pieChartsDiv).height(h); | |
42261 }; | |
42262 | |
42263 PieChartGui.prototype = { | |
42264 | |
42265 refreshColumnSelector : function(){ | |
42266 $(this.datasetSelect).empty(); | |
42267 $(this.columnSelect).empty(); | |
42268 | |
42269 if ( (typeof this.parent.datasets !== "undefined") && (this.parent.datasets.length > 0)) { | |
42270 var index = 0; | |
42271 var pieChartGui = this; | |
42272 $(this.parent.datasets).each(function(){ | |
42273 $(pieChartGui.datasetSelect).append("<option value="+index+">"+this.label+"</option>"); | |
42274 index++; | |
42275 }); | |
42276 | |
42277 $(pieChartGui.datasetSelect).change(); | |
42278 } | |
42279 } | |
42280 }; | |
42281 /* | |
42282 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message | |
42283 * Digest Algorithm, as defined in RFC 1321. | |
42284 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 | |
42285 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
42286 * Distributed under the BSD License | |
42287 * See http://pajhome.org.uk/crypt/md5 for more info. | |
42288 */ | |
42289 | |
42290 /* | |
42291 * Configurable variables. You may need to tweak these to be compatible with | |
42292 * the server-side, but the defaults work in most cases. | |
42293 */ | |
42294 var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ | |
42295 var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ | |
42296 | |
42297 /* | |
42298 * These are the functions you'll usually want to call | |
42299 * They take string arguments and return either hex or base-64 encoded strings | |
42300 */ | |
42301 function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); } | |
42302 function b64_md5(s) { return rstr2b64(rstr_md5(str2rstr_utf8(s))); } | |
42303 function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); } | |
42304 function hex_hmac_md5(k, d) | |
42305 { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } | |
42306 function b64_hmac_md5(k, d) | |
42307 { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } | |
42308 function any_hmac_md5(k, d, e) | |
42309 { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); } | |
42310 | |
42311 /* | |
42312 * Perform a simple self-test to see if the VM is working | |
42313 */ | |
42314 function md5_vm_test() | |
42315 { | |
42316 return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72"; | |
42317 } | |
42318 | |
42319 /* | |
42320 * Calculate the MD5 of a raw string | |
42321 */ | |
42322 function rstr_md5(s) | |
42323 { | |
42324 return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); | |
42325 } | |
42326 | |
42327 /* | |
42328 * Calculate the HMAC-MD5, of a key and some data (raw strings) | |
42329 */ | |
42330 function rstr_hmac_md5(key, data) | |
42331 { | |
42332 var bkey = rstr2binl(key); | |
42333 if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8); | |
42334 | |
42335 var ipad = Array(16), opad = Array(16); | |
42336 for(var i = 0; i < 16; i++) | |
42337 { | |
42338 ipad[i] = bkey[i] ^ 0x36363636; | |
42339 opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
42340 } | |
42341 | |
42342 var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); | |
42343 return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); | |
42344 } | |
42345 | |
42346 /* | |
42347 * Convert a raw string to a hex string | |
42348 */ | |
42349 function rstr2hex(input) | |
42350 { | |
42351 try { hexcase } catch(e) { hexcase=0; } | |
42352 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; | |
42353 var output = ""; | |
42354 var x; | |
42355 for(var i = 0; i < input.length; i++) | |
42356 { | |
42357 x = input.charCodeAt(i); | |
42358 output += hex_tab.charAt((x >>> 4) & 0x0F) | |
42359 + hex_tab.charAt( x & 0x0F); | |
42360 } | |
42361 return output; | |
42362 } | |
42363 | |
42364 /* | |
42365 * Convert a raw string to a base-64 string | |
42366 */ | |
42367 function rstr2b64(input) | |
42368 { | |
42369 try { b64pad } catch(e) { b64pad=''; } | |
42370 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
42371 var output = ""; | |
42372 var len = input.length; | |
42373 for(var i = 0; i < len; i += 3) | |
42374 { | |
42375 var triplet = (input.charCodeAt(i) << 16) | |
42376 | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | |
42377 | (i + 2 < len ? input.charCodeAt(i+2) : 0); | |
42378 for(var j = 0; j < 4; j++) | |
42379 { | |
42380 if(i * 8 + j * 6 > input.length * 8) output += b64pad; | |
42381 else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); | |
42382 } | |
42383 } | |
42384 return output; | |
42385 } | |
42386 | |
42387 /* | |
42388 * Convert a raw string to an arbitrary string encoding | |
42389 */ | |
42390 function rstr2any(input, encoding) | |
42391 { | |
42392 var divisor = encoding.length; | |
42393 var i, j, q, x, quotient; | |
42394 | |
42395 /* Convert to an array of 16-bit big-endian values, forming the dividend */ | |
42396 var dividend = Array(Math.ceil(input.length / 2)); | |
42397 for(i = 0; i < dividend.length; i++) | |
42398 { | |
42399 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); | |
42400 } | |
42401 | |
42402 /* | |
42403 * Repeatedly perform a long division. The binary array forms the dividend, | |
42404 * the length of the encoding is the divisor. Once computed, the quotient | |
42405 * forms the dividend for the next step. All remainders are stored for later | |
42406 * use. | |
42407 */ | |
42408 var full_length = Math.ceil(input.length * 8 / | |
42409 (Math.log(encoding.length) / Math.log(2))); | |
42410 var remainders = Array(full_length); | |
42411 for(j = 0; j < full_length; j++) | |
42412 { | |
42413 quotient = Array(); | |
42414 x = 0; | |
42415 for(i = 0; i < dividend.length; i++) | |
42416 { | |
42417 x = (x << 16) + dividend[i]; | |
42418 q = Math.floor(x / divisor); | |
42419 x -= q * divisor; | |
42420 if(quotient.length > 0 || q > 0) | |
42421 quotient[quotient.length] = q; | |
42422 } | |
42423 remainders[j] = x; | |
42424 dividend = quotient; | |
42425 } | |
42426 | |
42427 /* Convert the remainders to the output string */ | |
42428 var output = ""; | |
42429 for(i = remainders.length - 1; i >= 0; i--) | |
42430 output += encoding.charAt(remainders[i]); | |
42431 | |
42432 return output; | |
42433 } | |
42434 | |
42435 /* | |
42436 * Encode a string as utf-8. | |
42437 * For efficiency, this assumes the input is valid utf-16. | |
42438 */ | |
42439 function str2rstr_utf8(input) | |
42440 { | |
42441 var output = ""; | |
42442 var i = -1; | |
42443 var x, y; | |
42444 | |
42445 while(++i < input.length) | |
42446 { | |
42447 /* Decode utf-16 surrogate pairs */ | |
42448 x = input.charCodeAt(i); | |
42449 y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; | |
42450 if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) | |
42451 { | |
42452 x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); | |
42453 i++; | |
42454 } | |
42455 | |
42456 /* Encode output as utf-8 */ | |
42457 if(x <= 0x7F) | |
42458 output += String.fromCharCode(x); | |
42459 else if(x <= 0x7FF) | |
42460 output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), | |
42461 0x80 | ( x & 0x3F)); | |
42462 else if(x <= 0xFFFF) | |
42463 output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), | |
42464 0x80 | ((x >>> 6 ) & 0x3F), | |
42465 0x80 | ( x & 0x3F)); | |
42466 else if(x <= 0x1FFFFF) | |
42467 output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), | |
42468 0x80 | ((x >>> 12) & 0x3F), | |
42469 0x80 | ((x >>> 6 ) & 0x3F), | |
42470 0x80 | ( x & 0x3F)); | |
42471 } | |
42472 return output; | |
42473 } | |
42474 | |
42475 /* | |
42476 * Encode a string as utf-16 | |
42477 */ | |
42478 function str2rstr_utf16le(input) | |
42479 { | |
42480 var output = ""; | |
42481 for(var i = 0; i < input.length; i++) | |
42482 output += String.fromCharCode( input.charCodeAt(i) & 0xFF, | |
42483 (input.charCodeAt(i) >>> 8) & 0xFF); | |
42484 return output; | |
42485 } | |
42486 | |
42487 function str2rstr_utf16be(input) | |
42488 { | |
42489 var output = ""; | |
42490 for(var i = 0; i < input.length; i++) | |
42491 output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, | |
42492 input.charCodeAt(i) & 0xFF); | |
42493 return output; | |
42494 } | |
42495 | |
42496 /* | |
42497 * Convert a raw string to an array of little-endian words | |
42498 * Characters >255 have their high-byte silently ignored. | |
42499 */ | |
42500 function rstr2binl(input) | |
42501 { | |
42502 var output = Array(input.length >> 2); | |
42503 for(var i = 0; i < output.length; i++) | |
42504 output[i] = 0; | |
42505 for(var i = 0; i < input.length * 8; i += 8) | |
42506 output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); | |
42507 return output; | |
42508 } | |
42509 | |
42510 /* | |
42511 * Convert an array of little-endian words to a string | |
42512 */ | |
42513 function binl2rstr(input) | |
42514 { | |
42515 var output = ""; | |
42516 for(var i = 0; i < input.length * 32; i += 8) | |
42517 output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); | |
42518 return output; | |
42519 } | |
42520 | |
42521 /* | |
42522 * Calculate the MD5 of an array of little-endian words, and a bit length. | |
42523 */ | |
42524 function binl_md5(x, len) | |
42525 { | |
42526 /* append padding */ | |
42527 x[len >> 5] |= 0x80 << ((len) % 32); | |
42528 x[(((len + 64) >>> 9) << 4) + 14] = len; | |
42529 | |
42530 var a = 1732584193; | |
42531 var b = -271733879; | |
42532 var c = -1732584194; | |
42533 var d = 271733878; | |
42534 | |
42535 for(var i = 0; i < x.length; i += 16) | |
42536 { | |
42537 var olda = a; | |
42538 var oldb = b; | |
42539 var oldc = c; | |
42540 var oldd = d; | |
42541 | |
42542 a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); | |
42543 d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); | |
42544 c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); | |
42545 b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); | |
42546 a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); | |
42547 d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); | |
42548 c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); | |
42549 b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); | |
42550 a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); | |
42551 d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); | |
42552 c = md5_ff(c, d, a, b, x[i+10], 17, -42063); | |
42553 b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); | |
42554 a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); | |
42555 d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); | |
42556 c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); | |
42557 b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); | |
42558 | |
42559 a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); | |
42560 d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); | |
42561 c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); | |
42562 b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); | |
42563 a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); | |
42564 d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); | |
42565 c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); | |
42566 b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); | |
42567 a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); | |
42568 d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); | |
42569 c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); | |
42570 b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); | |
42571 a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); | |
42572 d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); | |
42573 c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); | |
42574 b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); | |
42575 | |
42576 a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); | |
42577 d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); | |
42578 c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); | |
42579 b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); | |
42580 a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); | |
42581 d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); | |
42582 c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); | |
42583 b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); | |
42584 a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); | |
42585 d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); | |
42586 c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); | |
42587 b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); | |
42588 a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); | |
42589 d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); | |
42590 c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); | |
42591 b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); | |
42592 | |
42593 a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); | |
42594 d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); | |
42595 c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); | |
42596 b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); | |
42597 a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); | |
42598 d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); | |
42599 c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); | |
42600 b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); | |
42601 a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); | |
42602 d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); | |
42603 c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); | |
42604 b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); | |
42605 a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); | |
42606 d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); | |
42607 c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); | |
42608 b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); | |
42609 | |
42610 a = safe_add(a, olda); | |
42611 b = safe_add(b, oldb); | |
42612 c = safe_add(c, oldc); | |
42613 d = safe_add(d, oldd); | |
42614 } | |
42615 return Array(a, b, c, d); | |
42616 } | |
42617 | |
42618 /* | |
42619 * These functions implement the four basic operations the algorithm uses. | |
42620 */ | |
42621 function md5_cmn(q, a, b, x, s, t) | |
42622 { | |
42623 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); | |
42624 } | |
42625 function md5_ff(a, b, c, d, x, s, t) | |
42626 { | |
42627 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); | |
42628 } | |
42629 function md5_gg(a, b, c, d, x, s, t) | |
42630 { | |
42631 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); | |
42632 } | |
42633 function md5_hh(a, b, c, d, x, s, t) | |
42634 { | |
42635 return md5_cmn(b ^ c ^ d, a, b, x, s, t); | |
42636 } | |
42637 function md5_ii(a, b, c, d, x, s, t) | |
42638 { | |
42639 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); | |
42640 } | |
42641 | |
42642 /* | |
42643 * Add integers, wrapping at 2^32. This uses 16-bit operations internally | |
42644 * to work around bugs in some JS interpreters. | |
42645 */ | |
42646 function safe_add(x, y) | |
42647 { | |
42648 var lsw = (x & 0xFFFF) + (y & 0xFFFF); | |
42649 var msw = (x >> 16) + (y >> 16) + (lsw >> 16); | |
42650 return (msw << 16) | (lsw & 0xFFFF); | |
42651 } | |
42652 | |
42653 /* | |
42654 * Bitwise rotate a 32-bit number to the left. | |
42655 */ | |
42656 function bit_rol(num, cnt) | |
42657 { | |
42658 return (num << cnt) | (num >>> (32 - cnt)); | |
42659 } | |
42660 /* | |
42661 * PieChartWidget.js | |
42662 * | |
42663 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42664 * | |
42665 * This library is free software; you can redistribute it and/or | |
42666 * modify it under the terms of the GNU Lesser General Public | |
42667 * License as published by the Free Software Foundation; either | |
42668 * version 3 of the License, or (at your option) any later version. | |
42669 * | |
42670 * This library is distributed in the hope that it will be useful, | |
42671 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42672 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42673 * Lesser General Public License for more details. | |
42674 * | |
42675 * You should have received a copy of the GNU Lesser General Public | |
42676 * License along with this library; if not, write to the Free Software | |
42677 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42678 * MA 02110-1301 USA | |
42679 */ | |
42680 | |
42681 /** | |
42682 * @class PieChartWidget | |
42683 * PieChartWidget Implementation | |
42684 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42685 * | |
42686 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
42687 * @param {HTML object} div parent div to append the PieChart widget div | |
42688 * @param {JSON} options user specified configuration that overwrites options in PieChartConfig.js | |
42689 */ | |
42690 PieChartWidget = function(core, div, options) { | |
42691 | |
42692 this.datasets; | |
42693 this.selected; | |
42694 this.core = core; | |
42695 this.core.setWidget(this); | |
42696 | |
42697 this.options = (new PieChartConfig(options)).options; | |
42698 this.gui = new PieChartGui(this, div, this.options); | |
42699 | |
42700 this.pieCharts = []; | |
42701 } | |
42702 | |
42703 PieChartWidget.prototype = { | |
42704 | |
42705 addCategorizedPieChart : function(watchedDataset, watchedColumn, type, categories){ | |
42706 var selectionFunction; | |
42707 if (type === "text"){ | |
42708 //create selection function for the pie chart | |
42709 var selectionFunction = function(columnData){ | |
42710 var categoryLabel; | |
42711 $(categories).each(function(){ | |
42712 if ($.inArray(columnData,this.values) != -1){ | |
42713 categoryLabel = this.label; | |
42714 //exit .each | |
42715 return false; | |
42716 } | |
42717 if (typeof categoryLabel !== "undefined") | |
42718 return false; | |
42719 }); | |
42720 | |
42721 if (typeof categoryLabel === "undefined") | |
42722 categoryLabel = "unknown"; | |
42723 | |
42724 return categoryLabel; | |
42725 }; | |
42726 } else if (type === "numeral"){ | |
42727 //create selection function for the pie chart | |
42728 var selectionFunction = function(columnData){ | |
42729 var categoryLabel; | |
42730 var columnDataNumeric = parseFloat(columnData); | |
42731 for (var i = 0; i < categories.length; i++){ | |
42732 if (columnDataNumeric<=categories[i]){ | |
42733 categoryLabel = pieChartCategoryChooser.columnName + "<=" + categories[i]; | |
42734 break; | |
42735 } | |
42736 } | |
42737 | |
42738 if (typeof categoryLabel === "undefined") | |
42739 categoryLabel = "unknown"; | |
42740 | |
42741 return categoryLabel; | |
42742 }; | |
42743 } else | |
42744 return; | |
42745 | |
42746 //make categories easy accessible for later usage | |
42747 selectionFunction.type = type; | |
42748 selectionFunction.categories = categories; | |
42749 | |
42750 this.addPieChart(watchedDataset, watchedColumn, selectionFunction); | |
42751 }, | |
42752 | |
42753 addPieChart : function(watchedDataset, watchedColumn, selectionFunction){ | |
42754 var newPieChart = new PieChart(this, watchedDataset, watchedColumn, selectionFunction); | |
42755 this.pieCharts.push(newPieChart); | |
42756 if ( (typeof GeoTemConfig.datasets !== "undefined") && | |
42757 (GeoTemConfig.datasets.length > watchedDataset) ) | |
42758 newPieChart.initPieChart(GeoTemConfig.datasets); | |
42759 this.redrawPieCharts(this.selected); | |
42760 }, | |
42761 | |
42762 initWidget : function(data) { | |
42763 var piechart = this; | |
42764 this.datasets = data; | |
42765 piechart.selected = []; | |
42766 $(this.datasets).each(function(){ | |
42767 piechart.selected.push(this.objects); | |
42768 }) | |
42769 | |
42770 this.gui.refreshColumnSelector(); | |
42771 | |
42772 $(this.pieCharts).each(function(){ | |
42773 if (this instanceof PieChart) | |
42774 this.initPieChart(data); | |
42775 }); | |
42776 }, | |
42777 | |
42778 redrawPieCharts : function(objects, overwrite) { | |
42779 $(this.pieCharts).each(function(){ | |
42780 if (this instanceof PieChart){ | |
42781 if ( (typeof overwrite !== "undefined") && overwrite) | |
42782 this.preHighlightObjects = objects; | |
42783 this.redrawPieChart(objects); | |
42784 } | |
42785 }); | |
42786 }, | |
42787 | |
42788 highlightChanged : function(objects) { | |
42789 if( !GeoTemConfig.highlightEvents ){ | |
42790 return; | |
42791 } | |
42792 if ( (typeof objects === "undefined") || (objects.length == 0) ){ | |
42793 return; | |
42794 } | |
42795 this.redrawPieCharts(objects, false); | |
42796 }, | |
42797 | |
42798 selectionChanged : function(selection) { | |
42799 if( !GeoTemConfig.selectionEvents ){ | |
42800 return; | |
42801 } | |
42802 if (!selection.valid()){ | |
42803 selection.loadAllObjects(); | |
42804 } | |
42805 var objects = selection.objects; | |
42806 this.selected = objects; | |
42807 this.redrawPieCharts(objects, true); | |
42808 }, | |
42809 | |
42810 getElementData : function(dataObject, watchedColumn, selectionFunction) { | |
42811 var columnData; | |
42812 if (watchedColumn.indexOf("[") === -1){ | |
42813 columnData = dataObject[watchedColumn]; | |
42814 if (typeof columnData === "undefined"){ | |
42815 columnData = dataObject.tableContent[watchedColumn]; | |
42816 }; | |
42817 } else { | |
42818 try { | |
42819 var columnName = watchedColumn.split("[")[0]; | |
42820 var IndexAndAttribute = watchedColumn.split("[")[1]; | |
42821 if (IndexAndAttribute.indexOf("]") != -1){ | |
42822 var arrayIndex = IndexAndAttribute.split("]")[0]; | |
42823 var attribute = IndexAndAttribute.split("]")[1]; | |
42824 | |
42825 if (typeof attribute === "undefined") | |
42826 columnData = dataObject[columnName][arrayIndex]; | |
42827 else{ | |
42828 attribute = attribute.split(".")[1]; | |
42829 columnData = dataObject[columnName][arrayIndex][attribute]; | |
42830 } | |
42831 } | |
42832 } catch(e) { | |
42833 if (typeof console !== undefined) | |
42834 console.error(e); | |
42835 | |
42836 delete columnData; | |
42837 } | |
42838 } | |
42839 | |
42840 if ( (typeof columnData !== "undefined") && (typeof selectionFunction !== "undefined") ) | |
42841 columnData = selectionFunction(columnData); | |
42842 | |
42843 return(columnData); | |
42844 }, | |
42845 | |
42846 getElementsByValue : function(columnValue, watchedDataset, watchedColumn, selectionFunction) { | |
42847 var elements = []; | |
42848 var pieChart = this; | |
42849 | |
42850 $(this.datasets[watchedDataset].objects).each(function(){ | |
42851 var columnData = pieChart.getElementData(this, watchedColumn, selectionFunction); | |
42852 if (columnData === columnValue) | |
42853 elements.push(this); | |
42854 }); | |
42855 | |
42856 return elements; | |
42857 }, | |
42858 }; | |
42859 /* | |
42860 * Storytelling.js | |
42861 * | |
42862 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42863 * | |
42864 * This library is free software; you can redistribute it and/or | |
42865 * modify it under the terms of the GNU Lesser General Public | |
42866 * License as published by the Free Software Foundation; either | |
42867 * version 3 of the License, or (at your option) any later version. | |
42868 * | |
42869 * This library is distributed in the hope that it will be useful, | |
42870 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42871 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42872 * Lesser General Public License for more details. | |
42873 * | |
42874 * You should have received a copy of the GNU Lesser General Public | |
42875 * License along with this library; if not, write to the Free Software | |
42876 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42877 * MA 02110-1301 USA | |
42878 */ | |
42879 | |
42880 /** | |
42881 * @class Storytelling | |
42882 * Implementation of story telling "storage" | |
42883 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42884 * | |
42885 * @param {HTML object} parent div to append the Storytelling widget | |
42886 */ | |
42887 function Storytelling(parent) { | |
42888 | |
42889 this.index; | |
42890 this.storytelling = this; | |
42891 | |
42892 this.parent = parent; | |
42893 this.options = parent.options; | |
42894 | |
42895 this.initialize(); | |
42896 } | |
42897 | |
42898 Storytelling.prototype = { | |
42899 | |
42900 remove : function() { | |
42901 }, | |
42902 | |
42903 initialize : function() { | |
42904 }, | |
42905 | |
42906 triggerHighlight : function(columnElement) { | |
42907 }, | |
42908 | |
42909 triggerSelection : function(columnElement) { | |
42910 }, | |
42911 | |
42912 deselection : function() { | |
42913 }, | |
42914 | |
42915 filtering : function() { | |
42916 }, | |
42917 | |
42918 inverseFiltering : function() { | |
42919 }, | |
42920 | |
42921 triggerRefining : function() { | |
42922 }, | |
42923 | |
42924 reset : function() { | |
42925 }, | |
42926 | |
42927 show : function() { | |
42928 }, | |
42929 | |
42930 hide : function() { | |
42931 } | |
42932 }; | |
42933 /* | |
42934 * StorytellingConfig.js | |
42935 * | |
42936 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42937 * | |
42938 * This library is free software; you can redistribute it and/or | |
42939 * modify it under the terms of the GNU Lesser General Public | |
42940 * License as published by the Free Software Foundation; either | |
42941 * version 3 of the License, or (at your option) any later version. | |
42942 * | |
42943 * This library is distributed in the hope that it will be useful, | |
42944 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42945 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42946 * Lesser General Public License for more details. | |
42947 * | |
42948 * You should have received a copy of the GNU Lesser General Public | |
42949 * License along with this library; if not, write to the Free Software | |
42950 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42951 * MA 02110-1301 USA | |
42952 */ | |
42953 | |
42954 /** | |
42955 * @class StorytellingConfig | |
42956 * Storytelling Configuration File | |
42957 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42958 */ | |
42959 function StorytellingConfig(options) { | |
42960 | |
42961 this.options = { | |
42962 dariahStorage : false, | |
42963 localStorage : true | |
42964 }; | |
42965 if ( typeof options != 'undefined') { | |
42966 $.extend(this.options, options); | |
42967 } | |
42968 | |
42969 }; | |
42970 /* | |
42971 * StorytellingGui.js | |
42972 * | |
42973 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42974 * | |
42975 * This library is free software; you can redistribute it and/or | |
42976 * modify it under the terms of the GNU Lesser General Public | |
42977 * License as published by the Free Software Foundation; either | |
42978 * version 3 of the License, or (at your option) any later version. | |
42979 * | |
42980 * This library is distributed in the hope that it will be useful, | |
42981 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42982 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42983 * Lesser General Public License for more details. | |
42984 * | |
42985 * You should have received a copy of the GNU Lesser General Public | |
42986 * License along with this library; if not, write to the Free Software | |
42987 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42988 * MA 02110-1301 USA | |
42989 */ | |
42990 | |
42991 /** | |
42992 * @class StorytellingGui | |
42993 * Storytelling GUI Implementation | |
42994 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42995 * | |
42996 * @param {StorytellingWidget} parent Storytelling widget object | |
42997 * @param {HTML object} div parent div to append the Storytelling gui | |
42998 * @param {JSON} options Storytelling configuration | |
42999 */ | |
43000 function StorytellingGui(storytelling, div, options) { | |
43001 | |
43002 this.parent = storytelling; | |
43003 var storytellingGui = this; | |
43004 | |
43005 storytellingGui.storytellingContainer = document.createElement('div'); | |
43006 $(div).append(storytellingGui.storytellingContainer); | |
43007 storytellingGui.storytellingContainer.style.position = 'relative'; | |
43008 }; | |
43009 | |
43010 StorytellingGui.prototype = { | |
43011 }; | |
43012 /* | |
43013 * StorytellingWidget.js | |
43014 * | |
43015 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
43016 * | |
43017 * This library is free software; you can redistribute it and/or | |
43018 * modify it under the terms of the GNU Lesser General Public | |
43019 * License as published by the Free Software Foundation; either | |
43020 * version 3 of the License, or (at your option) any later version. | |
43021 * | |
43022 * This library is distributed in the hope that it will be useful, | |
43023 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
43024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
43025 * Lesser General Public License for more details. | |
43026 * | |
43027 * You should have received a copy of the GNU Lesser General Public | |
43028 * License along with this library; if not, write to the Free Software | |
43029 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
43030 * MA 02110-1301 USA | |
43031 */ | |
43032 | |
43033 /** | |
43034 * @class StorytellingWidget | |
43035 * StorytellingWidget Implementation | |
43036 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
43037 * | |
43038 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
43039 * @param {HTML object} div parent div to append the Storytelling widget div | |
43040 * @param {JSON} options user specified configuration that overwrites options in StorytellingConfig.js | |
43041 */ | |
43042 StorytellingWidget = function(core, div, options) { | |
43043 | |
43044 this.datasets; | |
43045 this.core = core; | |
43046 this.core.setWidget(this); | |
43047 this.currentStatus = new Object(); | |
43048 | |
43049 this.options = (new StorytellingConfig(options)).options; | |
43050 this.gui = new StorytellingGui(this, div, this.options); | |
43051 | |
43052 this.datasetLink; | |
43053 | |
43054 Publisher.Subscribe('mapChanged', this, function(mapName) { | |
43055 this.client.currentStatus["mapChanged"] = mapName; | |
43056 this.client.createLink(); | |
43057 }); | |
43058 | |
43059 var currentStatus = $.url().param("currentStatus"); | |
43060 if (typeof currentStatus !== "undefined"){ | |
43061 this.currentStatus = $.deparam(currentStatus); | |
43062 $.each(this.currentStatus,function(action,data){ | |
43063 Publisher.Publish(action, data, this); | |
43064 }); | |
43065 } | |
43066 } | |
43067 | |
43068 StorytellingWidget.prototype = { | |
43069 | |
43070 initWidget : function(data) { | |
43071 var storytellingWidget = this; | |
43072 var gui = storytellingWidget.gui; | |
43073 | |
43074 storytellingWidget.datasets = data; | |
43075 | |
43076 $(gui.storytellingContainer).empty(); | |
43077 | |
43078 var magneticLinkParam = ""; | |
43079 var datasetIndex = 0; | |
43080 var linkCount = 1; | |
43081 $(storytellingWidget.datasets).each(function(){ | |
43082 var dataset = this; | |
43083 | |
43084 if (magneticLinkParam.length > 0) | |
43085 magneticLinkParam += "&"; | |
43086 | |
43087 var paragraph = $("<p></p>"); | |
43088 paragraph.append(dataset.label); | |
43089 if (typeof dataset.url !== "undefined"){ | |
43090 //TODO: makes only sense for KML or CSV URLs, so "type" of | |
43091 //URL should be preserved (in dataset). | |
43092 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
43093 var type="csv"; | |
43094 if (typeof dataset.type !== "undefined") | |
43095 type = dataset.type; | |
43096 else { | |
43097 if (dataset.url.toLowerCase().endsWith("kml")) | |
43098 type = "kml"; | |
43099 } | |
43100 | |
43101 magneticLinkParam += type+linkCount+"="; | |
43102 linkCount++; | |
43103 magneticLinkParam += dataset.url; | |
43104 | |
43105 var tableLinkDiv = document.createElement('a'); | |
43106 tableLinkDiv.title = dataset.url; | |
43107 tableLinkDiv.href = dataset.url; | |
43108 tableLinkDiv.target = '_'; | |
43109 tableLinkDiv.setAttribute('class', 'externalLink'); | |
43110 paragraph.append(tableLinkDiv); | |
43111 } else { | |
43112 if (storytellingWidget.options.dariahStorage){ | |
43113 var uploadToDARIAH = document.createElement('a'); | |
43114 $(uploadToDARIAH).append("Upload to DARIAH Storage"); | |
43115 uploadToDARIAH.title = ""; | |
43116 uploadToDARIAH.href = dataset.url; | |
43117 | |
43118 var localDatasetIndex = new Number(datasetIndex); | |
43119 $(uploadToDARIAH).click(function(){ | |
43120 var csv = GeoTemConfig.createCSVfromDataset(localDatasetIndex); | |
43121 // taken from dariah.storage.js | |
43122 var storageURL = "http://ref.dariah.eu/storage/" | |
43123 $.ajax({ | |
43124 url: storageURL, | |
43125 type: 'POST', | |
43126 contentType: 'text/csv', | |
43127 data: csv, | |
43128 success: function(data, status, xhr) { | |
43129 var location = xhr.getResponseHeader('Location'); | |
43130 // the dariah storage id | |
43131 dsid = location.substring(location.lastIndexOf('/')+1); | |
43132 | |
43133 //add URL to dataset | |
43134 storytellingWidget.datasets[localDatasetIndex].url = location; | |
43135 storytellingWidget.datasets[localDatasetIndex].type = "csv"; | |
43136 //refresh list | |
43137 storytellingWidget.initWidget(storytellingWidget.datasets); | |
43138 }, | |
43139 error: function (data, text, error) { | |
43140 alert('error creating new file in dariah storage because ' + text); | |
43141 console.log(data); | |
43142 console.log(text); | |
43143 console.log(error); | |
43144 } | |
43145 }); | |
43146 //discard link click-event | |
43147 return(false); | |
43148 }); | |
43149 paragraph.append(uploadToDARIAH); | |
43150 } | |
43151 // TODO: if layout is more usable, both options could be used ("else" removed) | |
43152 else if (storytellingWidget.options.localStorage){ | |
43153 var saveToLocalStorage = document.createElement('a'); | |
43154 $(saveToLocalStorage).append("Save to Local Storage"); | |
43155 saveToLocalStorage.title = ""; | |
43156 saveToLocalStorage.href = dataset.url; | |
43157 | |
43158 var localDatasetIndex = new Number(datasetIndex); | |
43159 $(saveToLocalStorage).click(function(){ | |
43160 var csv = GeoTemConfig.createCSVfromDataset(localDatasetIndex); | |
43161 | |
43162 var storageName = "GeoBrowser_dataset_"+GeoTemConfig.datasets[localDatasetIndex].label; | |
43163 $.remember({ | |
43164 name:storageName, | |
43165 value:csv | |
43166 }); | |
43167 | |
43168 //add URL to dataset | |
43169 storytellingWidget.datasets[localDatasetIndex].url = storageName; | |
43170 storytellingWidget.datasets[localDatasetIndex].type = "local"; | |
43171 //refresh list | |
43172 storytellingWidget.initWidget(storytellingWidget.datasets); | |
43173 | |
43174 //discard link click-event | |
43175 return(false); | |
43176 }); | |
43177 paragraph.append(saveToLocalStorage); | |
43178 } | |
43179 } | |
43180 | |
43181 $(gui.storytellingContainer).append(paragraph); | |
43182 datasetIndex++; | |
43183 }); | |
43184 | |
43185 this.datasetLink = magneticLinkParam; | |
43186 this.createLink(); | |
43187 }, | |
43188 | |
43189 createLink : function() { | |
43190 $(this.gui.storytellingContainer).find('.magneticLink').remove(); | |
43191 | |
43192 var magneticLink = document.createElement('a'); | |
43193 magneticLink.setAttribute('class', 'magneticLink'); | |
43194 $(magneticLink).append("Magnetic Link"); | |
43195 magneticLink.title = "Use this link to reload currently loaded (online) data."; | |
43196 magneticLink.href = "?"+this.datasetLink; | |
43197 var currentStatusParam = $.param(this.currentStatus); | |
43198 if (currentStatusParam.length > 0) | |
43199 magneticLink.href += "¤tStatus="+currentStatusParam; | |
43200 magneticLink.target = '_'; | |
43201 $(this.gui.storytellingContainer).prepend(magneticLink); | |
43202 }, | |
43203 | |
43204 highlightChanged : function(objects) { | |
43205 }, | |
43206 | |
43207 selectionChanged : function(selection) { | |
43208 }, | |
43209 }; | |
43210 /* | |
43211 * DataObject.js | |
43212 * | |
43213 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
43214 * | |
43215 * This library is free software; you can redistribute it and/or | |
43216 * modify it under the terms of the GNU Lesser General Public | |
43217 * License as published by the Free Software Foundation; either | |
43218 * version 3 of the License, or (at your option) any later version. | |
43219 * | |
43220 * This library is distributed in the hope that it will be useful, | |
43221 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
43222 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
43223 * Lesser General Public License for more details. | |
43224 * | |
43225 * You should have received a copy of the GNU Lesser General Public | |
43226 * License along with this library; if not, write to the Free Software | |
43227 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
43228 * MA 02110-1301 USA | |
43229 */ | |
43230 | |
43231 /** | |
43232 * @class DataObject | |
43233 * GeoTemCo's data object class | |
43234 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
43235 * @release 1.0 | |
43236 * @release date: 2012-07-27 | |
43237 * @version date: 2012-07-27 | |
43238 * | |
43239 * @param {String} name name of the data object | |
43240 * @param {String} description description of the data object | |
43241 * @param {JSON} locations a list of locations with longitude, latitide and place name | |
43242 * @param {JSON} dates a list of dates | |
43243 * @param {float} lon longitude value of the given place | |
43244 * @param {float} lat latitude value of the given place | |
43245 * @param {Date} timeStart start time of the data object | |
43246 * @param {Date} timeEnd end time of the data object | |
43247 * @param {int} granularity granularity of the given time | |
43248 * @param {int} weight weight of the time object | |
43249 * @param {Openlayers.Projection} projection of the coordinates (optional) | |
43250 */ | |
43251 | |
43252 DataObject = function(name, description, locations, dates, weight, tableContent, projection) { | |
43253 | |
43254 this.name = $.trim(name); | |
43255 this.description = $.trim(description); | |
43256 this.weight = weight; | |
43257 this.tableContent = new Object(); | |
43258 var objectTableContent = this.tableContent; | |
43259 for(key in tableContent){ | |
43260 value = tableContent[key]; | |
43261 objectTableContent[$.trim(key)]=$.trim(value); | |
43262 } | |
43263 | |
43264 this.percentage = 0; | |
43265 this.setPercentage = function(percentage) { | |
43266 this.percentage = percentage; | |
43267 } | |
43268 | |
43269 this.locations = []; | |
43270 var objectLocations = this.locations; | |
43271 $(locations).each(function(){ | |
43272 objectLocations.push({ | |
43273 latitude:this.latitude, | |
43274 longitude:this.longitude, | |
43275 place:$.trim(this.place) | |
43276 }); | |
43277 }); | |
43278 | |
43279 //Check if locations are valid | |
43280 if (!(projection instanceof OpenLayers.Projection)){ | |
43281 //per default GeoTemCo uses WGS84 (-90<=lat<=90, -180<=lon<=180) | |
43282 projection = new OpenLayers.Projection("EPSG:4326"); | |
43283 } | |
43284 this.projection = projection; | |
43285 | |
43286 var tempLocations = []; | |
43287 if (typeof this.locations !== "undefined"){ | |
43288 $(this.locations).each(function(){ | |
43289 //EPSG:4326 === WGS84 | |
43290 this.latitude = parseFloat(this.latitude); | |
43291 this.longitude = parseFloat(this.longitude); | |
43292 if (projection.getCode() === "EPSG:4326"){ | |
43293 if ( (typeof this.latitude === "number") && | |
43294 (this.latitude>=-90) && | |
43295 (this.latitude<=90) && | |
43296 (typeof this.longitude === "number") && | |
43297 (this.longitude>=-180) && | |
43298 (this.longitude<=180) ) | |
43299 tempLocations.push(this); | |
43300 else{ | |
43301 if ((GeoTemConfig.debug)&&(typeof console !== undefined)){ | |
43302 console.error("Object " + name + " has no valid coordinate. ("+this.latitude+","+this.longitude+")"); | |
43303 } | |
43304 } | |
43305 | |
43306 //solve lat=-90 bug | |
43307 if( this.longitude == 180 ){ | |
43308 this.longitude = 179.999; | |
43309 } | |
43310 if( this.longitude == -180 ){ | |
43311 this.longitude = -179.999; | |
43312 } | |
43313 if( this.latitude == 90 ){ | |
43314 this.latitude = 89.999; | |
43315 } | |
43316 if( this.latitude == -90 ){ | |
43317 this.latitude = -89.999; | |
43318 } | |
43319 } | |
43320 }); | |
43321 this.locations = tempLocations; | |
43322 } | |
43323 | |
43324 this.isGeospatial = false; | |
43325 if ((typeof this.locations !== "undefined") && (this.locations.length > 0)) { | |
43326 this.isGeospatial = true; | |
43327 } | |
43328 | |
43329 this.placeDetails = []; | |
43330 for (var i = 0; i < this.locations.length; i++) { | |
43331 this.placeDetails.push(this.locations[i].place.split("/")); | |
43332 } | |
43333 | |
43334 this.getLatitude = function(locationId) { | |
43335 return this.locations[locationId].latitude; | |
43336 } | |
43337 | |
43338 this.getLongitude = function(locationId) { | |
43339 return this.locations[locationId].longitude; | |
43340 } | |
43341 | |
43342 this.getPlace = function(locationId, level) { | |
43343 if (level >= this.placeDetails[locationId].length) { | |
43344 return this.placeDetails[locationId][this.placeDetails[locationId].length - 1]; | |
43345 } | |
43346 return this.placeDetails[locationId][level]; | |
43347 } | |
43348 | |
43349 this.dates = dates; | |
43350 this.isTemporal = false; | |
43351 if ((typeof this.dates !== "undefined") && (this.dates.length > 0)) { | |
43352 this.isTemporal = true; | |
43353 //test if we already have date "objects" or if we should parse the dates | |
43354 for (var i = 0; i < this.dates.length; i++){ | |
43355 if (typeof this.dates[i] === "string"){ | |
43356 var date = GeoTemConfig.getTimeData(this.dates[i]); | |
43357 //check whether we got valid dates | |
43358 if ((typeof date !== "undefined")&&(date != null)){ | |
43359 this.dates[i] = date; | |
43360 } else { | |
43361 //at least one date is invalid, so this dataObject has | |
43362 //no valid date information and is therefor not "temporal" | |
43363 this.isTemporal = false; | |
43364 break; | |
43365 } | |
43366 } | |
43367 } | |
43368 } | |
43369 | |
43370 //TODO: allow more than one timespan (as with dates/places) | |
43371 this.isFuzzyTemporal = false; | |
43372 if (this.isTemporal) { | |
43373 this.isTemporal = false; | |
43374 this.isFuzzyTemporal = true; | |
43375 | |
43376 var date = this.dates[0].date; | |
43377 var granularity = this.dates[0].granularity; | |
43378 | |
43379 this.TimeSpanGranularity = granularity; | |
43380 | |
43381 if (granularity === SimileAjax.DateTime.YEAR){ | |
43382 this.TimeSpanBegin = moment(date).startOf("year"); | |
43383 this.TimeSpanEnd = moment(date).endOf("year"); | |
43384 } else if (granularity === SimileAjax.DateTime.MONTH){ | |
43385 this.TimeSpanBegin = moment(date).startOf("month"); | |
43386 this.TimeSpanEnd = moment(date).endOf("month"); | |
43387 } else if (granularity === SimileAjax.DateTime.DAY){ | |
43388 this.TimeSpanBegin = moment(date).startOf("day"); | |
43389 this.TimeSpanEnd = moment(date).endOf("day"); | |
43390 } else if (granularity === SimileAjax.DateTime.HOUR){ | |
43391 this.TimeSpanBegin = moment(date).startOf("hour"); | |
43392 this.TimeSpanEnd = moment(date).endOf("hour"); | |
43393 } else if (granularity === SimileAjax.DateTime.MINUTE){ | |
43394 this.TimeSpanBegin = moment(date).startOf("minute"); | |
43395 this.TimeSpanEnd = moment(date).endOf("minute"); | |
43396 } else if (granularity === SimileAjax.DateTime.SECOND){ | |
43397 this.TimeSpanBegin = moment(date).startOf("second"); | |
43398 this.TimeSpanEnd = moment(date).endOf("second"); | |
43399 } else if (granularity === SimileAjax.DateTime.MILLISECOND){ | |
43400 //this is a "real" exact time | |
43401 this.isTemporal = true; | |
43402 this.isFuzzyTemporal = false; | |
43403 } | |
43404 } else if ( (typeof this.tableContent["TimeSpan:begin"] !== "undefined") && | |
43405 (typeof this.tableContent["TimeSpan:end"] !== "undefined") ){ | |
43406 //parse according to ISO 8601 | |
43407 //don't use the default "cross browser support" from moment.js | |
43408 //cause it won't work correctly with negative years | |
43409 var formats = [ "YYYYYY", | |
43410 "YYYYYY-MM", | |
43411 "YYYYYY-MM-DD", | |
43412 "YYYYYY-MM-DDTHH", | |
43413 "YYYYYY-MM-DDTHH:mm", | |
43414 "YYYYYY-MM-DDTHH:mm:ss", | |
43415 "YYYYYY-MM-DDTHH:mm:ss.SSS" | |
43416 ]; | |
43417 this.TimeSpanBegin = moment(this.tableContent["TimeSpan:begin"],formats.slice()); | |
43418 this.TimeSpanEnd = moment(this.tableContent["TimeSpan:end"],formats.slice()); | |
43419 if ((this.TimeSpanBegin instanceof Object) && this.TimeSpanBegin.isValid() && | |
43420 (this.TimeSpanEnd instanceof Object) && this.TimeSpanEnd.isValid()){ | |
43421 //check whether dates are correctly sorted | |
43422 if (this.TimeSpanBegin>this.TimeSpanEnd){ | |
43423 //dates are in the wrong order | |
43424 if ((GeoTemConfig.debug)&&(typeof console !== undefined)) | |
43425 console.error("Object " + this.name + " has wrong fuzzy dating (twisted start/end?)."); | |
43426 | |
43427 } else { | |
43428 var timeSpanBeginGranularity = formats.indexOf(this.TimeSpanBegin._f); | |
43429 var timeSpanEndGranularity = formats.indexOf(this.TimeSpanEnd._f); | |
43430 var timeSpanGranularity = Math.max( timeSpanBeginGranularity, | |
43431 timeSpanEndGranularity ); | |
43432 | |
43433 //set granularity according to formats above | |
43434 if (timeSpanGranularity === 0){ | |
43435 this.TimeSpanGranularity = SimileAjax.DateTime.YEAR; | |
43436 } else if (timeSpanGranularity === 1){ | |
43437 this.TimeSpanGranularity = SimileAjax.DateTime.MONTH; | |
43438 } else if (timeSpanGranularity === 2){ | |
43439 this.TimeSpanGranularity = SimileAjax.DateTime.DAY; | |
43440 } else if (timeSpanGranularity === 3){ | |
43441 this.TimeSpanGranularity = SimileAjax.DateTime.HOUR; | |
43442 } else if (timeSpanGranularity === 4){ | |
43443 this.TimeSpanGranularity = SimileAjax.DateTime.MINUTE; | |
43444 } else if (timeSpanGranularity === 5){ | |
43445 this.TimeSpanGranularity = SimileAjax.DateTime.SECOND; | |
43446 } else if (timeSpanGranularity === 6){ | |
43447 this.TimeSpanGranularity = SimileAjax.DateTime.MILLISECOND; | |
43448 } | |
43449 | |
43450 if (timeSpanBeginGranularity === 0){ | |
43451 this.TimeSpanBeginGranularity = SimileAjax.DateTime.YEAR; | |
43452 } else if (timeSpanBeginGranularity === 1){ | |
43453 this.TimeSpanBeginGranularity = SimileAjax.DateTime.MONTH; | |
43454 } else if (timeSpanBeginGranularity === 2){ | |
43455 this.TimeSpanBeginGranularity = SimileAjax.DateTime.DAY; | |
43456 } else if (timeSpanBeginGranularity === 3){ | |
43457 this.TimeSpanBeginGranularity = SimileAjax.DateTime.HOUR; | |
43458 } else if (timeSpanBeginGranularity === 4){ | |
43459 this.TimeSpanBeginGranularity = SimileAjax.DateTime.MINUTE; | |
43460 } else if (timeSpanBeginGranularity === 5){ | |
43461 this.TimeSpanBeginGranularity = SimileAjax.DateTime.SECOND; | |
43462 } else if (timeSpanBeginGranularity === 6){ | |
43463 this.TimeSpanBeginGranularity = SimileAjax.DateTime.MILLISECOND; | |
43464 } | |
43465 | |
43466 if (timeSpanEndGranularity === 0){ | |
43467 this.TimeSpanEndGranularity = SimileAjax.DateTime.YEAR; | |
43468 } else if (timeSpanEndGranularity === 1){ | |
43469 this.TimeSpanEndGranularity = SimileAjax.DateTime.MONTH; | |
43470 } else if (timeSpanEndGranularity === 2){ | |
43471 this.TimeSpanEndGranularity = SimileAjax.DateTime.DAY; | |
43472 } else if (timeSpanEndGranularity === 3){ | |
43473 this.TimeSpanEndGranularity = SimileAjax.DateTime.HOUR; | |
43474 } else if (timeSpanEndGranularity === 4){ | |
43475 this.TimeSpanEndGranularity = SimileAjax.DateTime.MINUTE; | |
43476 } else if (timeSpanEndGranularity === 5){ | |
43477 this.TimeSpanEndGranularity = SimileAjax.DateTime.SECOND; | |
43478 } else if (timeSpanEndGranularity === 6){ | |
43479 this.TimeSpanEndGranularity = SimileAjax.DateTime.MILLISECOND; | |
43480 } | |
43481 | |
43482 if (this.TimeSpanEnd.year()-this.TimeSpanBegin.year() >= 1000) | |
43483 this.TimeSpanGranularity = SimileAjax.DateTime.MILLENNIUM; | |
43484 else if (this.TimeSpanEnd.year()-this.TimeSpanBegin.year() >= 100) | |
43485 this.TimeSpanGranularity = SimileAjax.DateTime.CENTURY; | |
43486 else if (this.TimeSpanEnd.year()-this.TimeSpanBegin.year() >= 10) | |
43487 this.TimeSpanGranularity = SimileAjax.DateTime.DECADE; | |
43488 | |
43489 //also set upper bounds according to granularity | |
43490 //(lower bound is already correct) | |
43491 if (timeSpanEndGranularity === 0){ | |
43492 this.TimeSpanEnd.endOf("year"); | |
43493 } else if (timeSpanEndGranularity === 1){ | |
43494 this.TimeSpanEnd.endOf("month"); | |
43495 } else if (timeSpanEndGranularity === 2){ | |
43496 this.TimeSpanEnd.endOf("day"); | |
43497 } else if (timeSpanEndGranularity === 3){ | |
43498 this.TimeSpanEnd.endOf("hour"); | |
43499 } else if (timeSpanEndGranularity === 4){ | |
43500 this.TimeSpanEnd.endOf("minute"); | |
43501 } else if (timeSpanEndGranularity === 5){ | |
43502 this.TimeSpanEnd.endOf("second"); | |
43503 } else if (timeSpanEndGranularity === 6){ | |
43504 //has max accuracy, so no change needed | |
43505 } | |
43506 | |
43507 this.isFuzzyTemporal = true; | |
43508 } | |
43509 } | |
43510 } | |
43511 | |
43512 | |
43513 this.getDate = function(dateId) { | |
43514 return this.dates[dateId].date; | |
43515 } | |
43516 | |
43517 this.getTimeGranularity = function(dateId) { | |
43518 return this.dates[dateId].granularity; | |
43519 } | |
43520 | |
43521 this.setIndex = function(index) { | |
43522 this.index = index; | |
43523 } | |
43524 | |
43525 this.getTimeString = function() { | |
43526 if (this.timeStart != this.timeEnd) { | |
43527 return (SimileAjax.DateTime.getTimeString(this.granularity, this.timeStart) + " - " + SimileAjax.DateTime.getTimeString(this.granularity, this.timeEnd)); | |
43528 } else { | |
43529 return SimileAjax.DateTime.getTimeString(this.granularity, this.timeStart) + ""; | |
43530 } | |
43531 }; | |
43532 | |
43533 this.contains = function(text) { | |
43534 var allCombined = this.name + " " + this.description + " " + this.weight + " "; | |
43535 | |
43536 $.each(this.dates, function(key, value){ | |
43537 $.each(value, function(){ | |
43538 allCombined += this + " "; | |
43539 }); | |
43540 }); | |
43541 | |
43542 $.each(this.locations, function(key, value){ | |
43543 $.each(value, function(){ | |
43544 allCombined += this + " "; | |
43545 }); | |
43546 }); | |
43547 | |
43548 $.each(this.tableContent, function(key, value){ | |
43549 allCombined += value + " "; | |
43550 }); | |
43551 | |
43552 return (allCombined.indexOf(text) != -1); | |
43553 }; | |
43554 | |
43555 this.hasColorInformation = false; | |
43556 | |
43557 this.setColor = function(r0,g0,b0,r1,g1,b1) { | |
43558 this.hasColorInformation = true; | |
43559 | |
43560 this.color = new Object(); | |
43561 this.color.r0 = r0; | |
43562 this.color.g0 = g0; | |
43563 this.color.b0 = b0; | |
43564 this.color.r1 = r1; | |
43565 this.color.g1 = g1; | |
43566 this.color.b1 = b1; | |
43567 }; | |
43568 | |
43569 this.getColor = function() { | |
43570 if (!this.hasColorInformation) | |
43571 return; | |
43572 | |
43573 color = new Object(); | |
43574 color.r0 = this.r0; | |
43575 color.g0 = this.g0; | |
43576 color.b0 = this.b0; | |
43577 color.r1 = this.r1; | |
43578 color.g1 = this.g1; | |
43579 color.b1 = this.b1; | |
43580 | |
43581 return color; | |
43582 }; | |
43583 | |
43584 Publisher.Publish('dataobjectAfterCreation', this); | |
43585 }; | |
43586 | |
43587 /* | |
43588 * Dataset.js | |
43589 * | |
43590 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
43591 * | |
43592 * This library is free software; you can redistribute it and/or | |
43593 * modify it under the terms of the GNU Lesser General Public | |
43594 * License as published by the Free Software Foundation; either | |
43595 * version 3 of the License, or (at your option) any later version. | |
43596 * | |
43597 * This library is distributed in the hope that it will be useful, | |
43598 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
43599 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
43600 * Lesser General Public License for more details. | |
43601 * | |
43602 * You should have received a copy of the GNU Lesser General Public | |
43603 * License along with this library; if not, write to the Free Software | |
43604 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
43605 * MA 02110-1301 USA | |
43606 */ | |
43607 | |
43608 /** | |
43609 * @class Dataset | |
43610 * GeoTemCo's Dataset class | |
43611 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
43612 * @release 1.0 | |
43613 * @release date: 2012-07-27 | |
43614 * @version date: 2012-07-27 | |
43615 * | |
43616 * @param {Array} objects data item arrays from different datasets | |
43617 * @param {String} label label for the datasets | |
43618 */ | |
43619 Dataset = function(objects, label, url, type) { | |
43620 | |
43621 this.objects = objects; | |
43622 this.label = label; | |
43623 this.url = url; | |
43624 this.type = type; | |
43625 | |
43626 this.color; | |
43627 | |
43628 //if the user can change shapes, every dataset needs a default shape | |
43629 if (GeoTemConfig.allowUserShapeAndColorChange){ | |
43630 this.graphic={ | |
43631 shape: "circle", | |
43632 rotation: 0 | |
43633 } | |
43634 } | |
43635 | |
43636 Publisher.Publish('datasetAfterCreation', this); | |
43637 } | |
43638 /* | |
43639 * TimeDataSource.js | |
43640 * | |
43641 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
43642 * | |
43643 * This library is free software; you can redistribute it and/or | |
43644 * modify it under the terms of the GNU Lesser General Public | |
43645 * License as published by the Free Software Foundation; either | |
43646 * version 3 of the License, or (at your option) any later version. | |
43647 * | |
43648 * This library is distributed in the hope that it will be useful, | |
43649 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
43650 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
43651 * Lesser General Public License for more details. | |
43652 * | |
43653 * You should have received a copy of the GNU Lesser General Public | |
43654 * License along with this library; if not, write to the Free Software | |
43655 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
43656 * MA 02110-1301 USA | |
43657 */ | |
43658 | |
43659 /** | |
43660 * @class TimeDataSource, TimeSlice, TimeStack | |
43661 * implementation for aggregation of time items | |
43662 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
43663 * @release 1.0 | |
43664 * @release date: 2012-07-27 | |
43665 * @version date: 2012-07-27 | |
43666 * | |
43667 * @param {JSON} options time configuration | |
43668 */ | |
43669 function TimeDataSource(options) { | |
43670 | |
43671 this.options = options; | |
43672 this.timeSlices = []; | |
43673 this.unit | |
43674 this.minDate | |
43675 this.maxDate | |
43676 this.eventSources | |
43677 this.events | |
43678 this.leftSlice | |
43679 this.rightSlice | |
43680 | |
43681 this.hashMapping | |
43682 | |
43683 }; | |
43684 | |
43685 TimeDataSource.prototype = { | |
43686 | |
43687 findTimeUnits : function(granularity, timeUnit, pixels) { | |
43688 | |
43689 var time = SimileAjax.DateTime; | |
43690 this.availableUnits = []; | |
43691 var givenUnits = SimileAjax.DateTime.gregorianUnitLengths; | |
43692 for (var i = 0; i < givenUnits.length; i++) { | |
43693 if (granularity > i) { | |
43694 continue; | |
43695 } | |
43696 var slices = 0; | |
43697 var t = new Date(this.minDate.getTime()); | |
43698 do { | |
43699 time.roundDownToInterval(t, i, undefined, 1, 0); | |
43700 slices++; | |
43701 time.incrementByInterval(t, i, undefined); | |
43702 } while( t.getTime() <= this.maxDate.getTime() && slices < pixels+2 ); | |
43703 if (slices > 0 && slices <= pixels) { | |
43704 this.availableUnits.push({ | |
43705 unit : i, | |
43706 slices : slices, | |
43707 label : SimileAjax.DateTime.Strings[GeoTemConfig.language][i] | |
43708 }); | |
43709 } | |
43710 } | |
43711 var unitDiff200 = pixels + 1; | |
43712 for (var i = 0; i < this.availableUnits.length; i++) { | |
43713 var diff = Math.abs(this.availableUnits[i].slices - 200); | |
43714 if (diff < unitDiff200) { | |
43715 unitDiff200 = diff; | |
43716 this.unit = this.availableUnits[i].unit; | |
43717 } | |
43718 } | |
43719 | |
43720 }, | |
43721 | |
43722 getUnitIndex : function() { | |
43723 for (var i = 0; i < this.availableUnits.length; i++) { | |
43724 if (this.unit == this.availableUnits[i].unit) { | |
43725 return i; | |
43726 } | |
43727 } | |
43728 return 0; | |
43729 }, | |
43730 | |
43731 setTimeUnit : function(unit) { | |
43732 this.unit = unit; | |
43733 this.initializeSlices(); | |
43734 }, | |
43735 | |
43736 /** | |
43737 * initializes the TimeDataSource | |
43738 * @param {Timeplot.ColumnSource[]} dataSources the column sources corresponding to the data sets | |
43739 * @param {Timeplot.DefaultEventSource[]} eventSources the event sources corresponding to the column sources | |
43740 * @param {TimeObject[][]} timeObjects an array of time objects of different sets | |
43741 * @param {SimileAjax.DateTime} granularity the time granularity of the given data | |
43742 */ | |
43743 initialize : function(dataSources, eventSources, timeObjects, granularity, timeUnit, pixels) { | |
43744 | |
43745 this.dataSources = dataSources; | |
43746 this.eventSources = eventSources; | |
43747 this.timeObjects = timeObjects; | |
43748 | |
43749 this.minDate = undefined; | |
43750 this.maxDate = undefined; | |
43751 this.hashMapping = []; | |
43752 this.projHashMapping = []; | |
43753 | |
43754 for (var i = 0; i < timeObjects.length; i++) { | |
43755 this.hashMapping.push([]); | |
43756 this.projHashMapping.push([]); | |
43757 for (var j = 0; j < timeObjects[i].length; j++) { | |
43758 var o = timeObjects[i][j]; | |
43759 if (o.isTemporal) { | |
43760 var g = o.dates[this.options.timeIndex].granularity; | |
43761 //o.getTimeGranularity(this.options.timeIndex); | |
43762 if (g == null) { | |
43763 continue; | |
43764 } | |
43765 var time = o.dates[this.options.timeIndex].date; | |
43766 //o.getDate(this.options.timeIndex); | |
43767 if (this.minDate == undefined || time.getTime() < this.minDate.getTime()) { | |
43768 this.minDate = time; | |
43769 } | |
43770 if (this.maxDate == undefined || time.getTime() > this.maxDate.getTime()) { | |
43771 this.maxDate = time; | |
43772 } | |
43773 } | |
43774 } | |
43775 } | |
43776 | |
43777 if (this.minDate == undefined) { | |
43778 this.minDate = this.options.defaultMinDate; | |
43779 this.maxDate = this.options.defaultMaxDate; | |
43780 } | |
43781 | |
43782 this.findTimeUnits(granularity, timeUnit, pixels); | |
43783 this.initializeSlices(); | |
43784 | |
43785 }, | |
43786 | |
43787 initializeSlices : function() { | |
43788 for (var i = 0; i < this.dataSources.length; i++) { | |
43789 this.dataSources[i]._range = { | |
43790 earliestDate : null, | |
43791 latestDate : null, | |
43792 min : 0, | |
43793 max : 0 | |
43794 }; | |
43795 } | |
43796 this.timeSlices = []; | |
43797 var time = SimileAjax.DateTime; | |
43798 var t = new Date(this.minDate.getTime() - 0.9 * time.gregorianUnitLengths[this.unit]); | |
43799 do { | |
43800 time.roundDownToInterval(t, this.unit, undefined, 1, 0); | |
43801 var slice = new TimeSlice(SimileAjax.NativeDateUnit.cloneValue(t), this.timeObjects.length, this.dataSources.length); | |
43802 this.timeSlices.push(slice); | |
43803 time.incrementByInterval(t, this.unit, undefined); | |
43804 } while (t.getTime() <= this.maxDate.getTime() + 1.1 * time.gregorianUnitLengths[this.unit]); | |
43805 | |
43806 for (var i = 0; i < this.timeObjects.length; i++) { | |
43807 var projId = i; | |
43808 if( this.dataSources.length == 1 ){ | |
43809 projId = 0; | |
43810 } | |
43811 for (var j = 0; j < this.timeObjects[i].length; j++) { | |
43812 var o = this.timeObjects[i][j]; | |
43813 if (o.isTemporal) { | |
43814 var date = o.dates[this.options.timeIndex].date; | |
43815 //o.getDate(this.options.timeIndex); | |
43816 for (var k = 0; k < this.timeSlices.length - 1; k++) { | |
43817 var t1 = this.timeSlices[k].date.getTime(); | |
43818 var t2 = this.timeSlices[k + 1].date.getTime(); | |
43819 var stack = null, projStack = null; | |
43820 if (date >= t1 && date < t2) { | |
43821 stack = this.timeSlices[k].getStack(i); | |
43822 projStack = this.timeSlices[k].getProjStack(projId); | |
43823 } | |
43824 if (k == this.timeSlices.length - 2 && date >= t2) { | |
43825 stack = this.timeSlices[k + 1].getStack(i); | |
43826 projStack = this.timeSlices[k + 1].getProjStack(projId); | |
43827 } | |
43828 if (stack != null) { | |
43829 stack.addObject(o); | |
43830 projStack.addObject(o); | |
43831 this.hashMapping[i][o.index] = stack; | |
43832 this.projHashMapping[i][o.index] = projStack; | |
43833 break; | |
43834 } | |
43835 } | |
43836 } | |
43837 } | |
43838 } | |
43839 | |
43840 this.events = []; | |
43841 for (var i = 0; i < this.eventSources.length; i++) { | |
43842 var eventSet = []; | |
43843 for (var j = 0; j < this.timeSlices.length; j++) { | |
43844 var value = new Array("" + this.timeSlices[j].projStacks[i].value); | |
43845 eventSet.push({ | |
43846 date : this.timeSlices[j].date, | |
43847 value : value | |
43848 }); | |
43849 } | |
43850 this.eventSources[i].loadData(eventSet); | |
43851 this.events.push(eventSet); | |
43852 } | |
43853 | |
43854 this.leftSlice = 0; | |
43855 this.rightSlice = this.timeSlices.length - 1; | |
43856 | |
43857 }, | |
43858 | |
43859 getSliceNumber : function() { | |
43860 return this.timeSlices.length; | |
43861 }, | |
43862 | |
43863 /** | |
43864 * computes the slice index corresponding to a given time | |
43865 * @param {Date} time the given time | |
43866 * @return the corresponding slice index | |
43867 */ | |
43868 getSliceIndex : function(time) { | |
43869 for (var i = 0; i < this.timeSlices.length; i++) { | |
43870 if (time == this.timeSlices[i].date) { | |
43871 return i; | |
43872 } | |
43873 } | |
43874 }, | |
43875 | |
43876 /** | |
43877 * returns the time of a specific time slice | |
43878 * @param {int} time the given slice index | |
43879 * @return the corresponding slice date | |
43880 */ | |
43881 getSliceTime : function(index) { | |
43882 return this.timeSlices[index].date; | |
43883 }, | |
43884 | |
43885 /** | |
43886 * shifts the actual zoomed range | |
43887 * @param {int} delta the value to shift (negative for left shift, positive for right shift) | |
43888 * @return boolean value, if the range could be shifted | |
43889 */ | |
43890 setShift : function(delta) { | |
43891 if (delta == 1 && this.leftSlice != 0) { | |
43892 this.leftSlice--; | |
43893 this.rightSlice--; | |
43894 return true; | |
43895 } else if (delta == -1 && this.rightSlice != this.timeSlices.length - 1) { | |
43896 this.leftSlice++; | |
43897 this.rightSlice++; | |
43898 return true; | |
43899 } else { | |
43900 return false; | |
43901 } | |
43902 }, | |
43903 | |
43904 /** | |
43905 * zooms the actual range | |
43906 * @param {int} delta the value to zoom (negative for zoom out, positive for zoom in) | |
43907 * @param {Date} time the corresponding time of the actual mouse position on the plot | |
43908 * @param {Date} leftTime the time of the left border of a selected timerange or null | |
43909 * @param {Date} rightTime the time of the right border of a selected timerange or null | |
43910 * @return boolean value, if the range could be zoomed | |
43911 */ | |
43912 setZoom : function(delta, time, leftTime, rightTime) { | |
43913 var n1 = 0; | |
43914 var n2 = 0; | |
43915 var m = -1; | |
43916 if (delta > 0) { | |
43917 m = 1; | |
43918 if (leftTime != null) { | |
43919 n1 = this.getSliceIndex(leftTime) - this.leftSlice; | |
43920 n2 = this.rightSlice - this.getSliceIndex(rightTime); | |
43921 } else { | |
43922 slice = this.getSliceIndex(time); | |
43923 if (slice == this.leftSlice || slice == this.rightSlice) { | |
43924 return; | |
43925 } | |
43926 n1 = slice - 1 - this.leftSlice; | |
43927 n2 = this.rightSlice - slice - 1; | |
43928 } | |
43929 } else if (delta < 0) { | |
43930 | |
43931 n1 = this.leftSlice; | |
43932 n2 = this.timeSlices.length - 1 - this.rightSlice; | |
43933 } | |
43934 | |
43935 var zoomSlices = 2 * delta; | |
43936 if (Math.abs(n1 + n2) < Math.abs(zoomSlices)) { | |
43937 zoomSlices = n1 + n2; | |
43938 } | |
43939 | |
43940 if (n1 + n2 == 0) { | |
43941 return false; | |
43942 } | |
43943 | |
43944 var m1 = Math.round(n1 / (n1 + n2) * zoomSlices); | |
43945 var m2 = zoomSlices - m1; | |
43946 | |
43947 this.leftSlice += m1; | |
43948 this.rightSlice -= m2; | |
43949 | |
43950 return true; | |
43951 }, | |
43952 | |
43953 /** | |
43954 * resets the plots by loading data of actual zoomed range | |
43955 */ | |
43956 reset : function(timeGeometry) { | |
43957 for (var i = 0; i < this.eventSources.length; i++) { | |
43958 this.eventSources[i].loadData(this.events[i].slice(this.leftSlice, this.rightSlice + 1)); | |
43959 if (i + 1 < this.eventSources.length) { | |
43960 timeGeometry._earliestDate = null; | |
43961 timeGeometry._latestDate = null; | |
43962 } | |
43963 | |
43964 } | |
43965 }, | |
43966 | |
43967 /** | |
43968 * Getter for actual zoom | |
43969 * @return actual zoom value | |
43970 */ | |
43971 getZoom : function() { | |
43972 if (this.timeSlices == undefined) { | |
43973 return 0; | |
43974 } | |
43975 return Math.round((this.timeSlices.length - 3) / 2) - Math.round((this.rightSlice - this.leftSlice - 2) / 2); | |
43976 }, | |
43977 | |
43978 /** | |
43979 * Getter for date of the first timeslice | |
43980 * @return date of the first timeslice | |
43981 */ | |
43982 earliest : function() { | |
43983 return this.timeSlices[0].date; | |
43984 }, | |
43985 | |
43986 /** | |
43987 * Getter for date of the last timeslice | |
43988 * @return date of the last timeslice | |
43989 */ | |
43990 latest : function() { | |
43991 return this.timeSlices[this.timeSlices.length - 1].date; | |
43992 }, | |
43993 | |
43994 setOverlay : function(timeObjects) { | |
43995 for (var i = 0; i < this.timeSlices.length; i++) { | |
43996 this.timeSlices[i].reset(); | |
43997 } | |
43998 for (var j in timeObjects ) { | |
43999 for (var k in timeObjects[j] ) { | |
44000 var o = timeObjects[j][k]; | |
44001 if (o.isTemporal) { | |
44002 if (o.getTimeGranularity(this.options.timeIndex) == null) { | |
44003 continue; | |
44004 } | |
44005 this.hashMapping[j][o.index].overlay += o.weight; | |
44006 this.projHashMapping[j][o.index].overlay += o.weight; | |
44007 } | |
44008 } | |
44009 } | |
44010 }, | |
44011 | |
44012 size : function() { | |
44013 if (this.timeSlices.length == 0) { | |
44014 return 0; | |
44015 } | |
44016 return this.timeSlices[0].stacks.length; | |
44017 } | |
44018 }; | |
44019 | |
44020 /** | |
44021 * small class that represents a time slice of the actual timeplot. | |
44022 * it has a specific date and contains its corrsponding data objects as well | |
44023 */ | |
44024 function TimeSlice(date, rows, projRows) { | |
44025 | |
44026 this.date = date; | |
44027 this.selected = false; | |
44028 | |
44029 this.stacks = []; | |
44030 this.projStacks = []; | |
44031 for (var i = 0; i < rows; i++) { | |
44032 this.stacks.push(new TimeStack()); | |
44033 } | |
44034 for (var i = 0; i < projRows; i++) { | |
44035 this.projStacks.push(new TimeStack()); | |
44036 } | |
44037 | |
44038 this.getStack = function(row) { | |
44039 return this.stacks[row]; | |
44040 }; | |
44041 | |
44042 this.getProjStack = function(row) { | |
44043 return this.projStacks[row]; | |
44044 }; | |
44045 | |
44046 this.reset = function() { | |
44047 for (var i in this.projStacks ) { | |
44048 this.stacks[i].overlay = 0; | |
44049 this.projStacks[i].overlay = 0; | |
44050 } | |
44051 }; | |
44052 | |
44053 this.overlay = function() { | |
44054 var value = 0; | |
44055 for (var i in this.projStacks ) { | |
44056 if (this.projStacks[i].overlay > value) { | |
44057 value = this.projStacks[i].overlay; | |
44058 } | |
44059 } | |
44060 return value; | |
44061 }; | |
44062 | |
44063 }; | |
44064 | |
44065 /** | |
44066 * small class that represents a stack for a time slice which | |
44067 * holds items for different datasets for the specific time range | |
44068 */ | |
44069 function TimeStack() { | |
44070 | |
44071 this.overlay = 0; | |
44072 this.value = 0; | |
44073 this.elements = []; | |
44074 | |
44075 this.addObject = function(object) { | |
44076 this.elements.push(object); | |
44077 this.value += object.weight; | |
44078 }; | |
44079 | |
44080 }; | |
44081 /* | |
44082 * Binning.js | |
44083 * | |
44084 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
44085 * | |
44086 * This library is free software; you can redistribute it and/or | |
44087 * modify it under the terms of the GNU Lesser General Public | |
44088 * License as published by the Free Software Foundation; either | |
44089 * version 3 of the License, or (at your option) any later version. | |
44090 * | |
44091 * This library is distributed in the hope that it will be useful, | |
44092 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
44093 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
44094 * Lesser General Public License for more details. | |
44095 * | |
44096 * You should have received a copy of the GNU Lesser General Public | |
44097 * License along with this library; if not, write to the Free Software | |
44098 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
44099 * MA 02110-1301 USA | |
44100 */ | |
44101 | |
44102 /** | |
44103 * @class Binning | |
44104 * Calculates map aggregation with several binning algorithms | |
44105 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
44106 * @release 1.0 | |
44107 * @release date: 2012-07-27 | |
44108 * @version date: 2012-07-27 | |
44109 */ | |
44110 Binning = function(map, options) { | |
44111 | |
44112 this.map = map; | |
44113 this.options = options; | |
44114 this.reset(); | |
44115 | |
44116 }; | |
44117 | |
44118 Binning.prototype = { | |
44119 | |
44120 getSet : function() { | |
44121 var type = this.options.binning; | |
44122 if (!type) { | |
44123 return this.getExactBinning(); | |
44124 } else if (type == 'generic') { | |
44125 return this.getGenericBinning(); | |
44126 } else if (type == 'square') { | |
44127 return this.getSquareBinning(); | |
44128 } else if (type == 'hexagonal') { | |
44129 return this.getHexagonalBinning(); | |
44130 } else if (type == 'triangular') { | |
44131 return this.getTriangularBinning(); | |
44132 } | |
44133 }, | |
44134 | |
44135 getExactBinning : function() { | |
44136 if ( typeof this.binnings['exact'] == 'undefined') { | |
44137 this.exactBinning(); | |
44138 } | |
44139 return this.binnings['exact']; | |
44140 }, | |
44141 | |
44142 getGenericBinning : function() { | |
44143 if ( typeof this.binnings['generic'] == 'undefined') { | |
44144 this.genericBinning(); | |
44145 } | |
44146 return this.binnings['generic']; | |
44147 }, | |
44148 | |
44149 getSquareBinning : function() { | |
44150 if ( typeof this.binnings['square'] == 'undefined') { | |
44151 this.squareBinning(); | |
44152 } | |
44153 return this.binnings['square']; | |
44154 }, | |
44155 | |
44156 getHexagonalBinning : function() { | |
44157 if ( typeof this.binnings['hexagonal'] == 'undefined') { | |
44158 this.hexagonalBinning(); | |
44159 } | |
44160 return this.binnings['hexagonal']; | |
44161 }, | |
44162 | |
44163 getTriangularBinning : function() { | |
44164 if ( typeof this.binnings['triangular'] == 'undefined') { | |
44165 this.triangularBinning(); | |
44166 } | |
44167 return this.binnings['triangular']; | |
44168 }, | |
44169 | |
44170 reset : function() { | |
44171 this.zoomLevels = this.map.getNumZoomLevels(); | |
44172 this.binnings = []; | |
44173 this.minimumRadius = this.options.minimumRadius; | |
44174 this.maximumRadius = this.minimumRadius; | |
44175 this.maximumPoints = 0; | |
44176 this.minArea = 0; | |
44177 this.maxArea = 0; | |
44178 }, | |
44179 | |
44180 getMaxRadius : function(size) { | |
44181 return 4 * Math.log(size) / Math.log(2); | |
44182 }, | |
44183 | |
44184 setObjects : function(objects) { | |
44185 this.objects = objects; | |
44186 for (var i = 0; i < this.objects.length; i++) { | |
44187 var weight = 0; | |
44188 for (var j = 0; j < this.objects[i].length; j++) { | |
44189 if (this.objects[i][j].isGeospatial) { | |
44190 weight += this.objects[i][j].weight; | |
44191 } | |
44192 } | |
44193 var r = this.getMaxRadius(weight); | |
44194 if (r > this.maximumRadius) { | |
44195 this.maximumRadius = r; | |
44196 this.maximumPoints = weight; | |
44197 this.maxArea = Math.PI * this.maximumRadius * this.maximumRadius; | |
44198 this.minArea = Math.PI * this.minimumRadius * this.minimumRadius; | |
44199 } | |
44200 } | |
44201 }, | |
44202 | |
44203 dist : function(x1, y1, x2, y2) { | |
44204 return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); | |
44205 }, | |
44206 | |
44207 exactBinning : function() { | |
44208 var circleSets = []; | |
44209 var hashMaps = []; | |
44210 var selectionHashs = []; | |
44211 | |
44212 var circleAggregates = []; | |
44213 var bins = []; | |
44214 for (var i = 0; i < this.objects.length; i++) { | |
44215 bins.push([]); | |
44216 circleAggregates.push([]); | |
44217 for (var j = 0; j < this.objects[i].length; j++) { | |
44218 var o = this.objects[i][j]; | |
44219 if (o.isGeospatial) { | |
44220 if ( typeof circleAggregates[i]['' + o.getLongitude(this.options.mapIndex)] == 'undefined') { | |
44221 circleAggregates[i]['' + o.getLongitude(this.options.mapIndex)] = []; | |
44222 } | |
44223 if ( typeof circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)] == 'undefined') { | |
44224 circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)] = []; | |
44225 bins[i].push(circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)]); | |
44226 } | |
44227 circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)].push(o); | |
44228 } | |
44229 } | |
44230 } | |
44231 | |
44232 var circles = []; | |
44233 var hashMap = []; | |
44234 var selectionMap = []; | |
44235 for (var i = 0; i < bins.length; i++) { | |
44236 circles.push([]); | |
44237 hashMap.push([]); | |
44238 selectionMap.push([]); | |
44239 for (var j = 0; j < bins[i].length; j++) { | |
44240 var bin = bins[i][j]; | |
44241 var p = new OpenLayers.Geometry.Point(bin[0].getLongitude(this.options.mapIndex), bin[0].getLatitude(this.options.mapIndex), null); | |
44242 p.transform(this.map.displayProjection, this.map.projection); | |
44243 var weight = 0; | |
44244 for (var z = 0; z < bin.length; z++) { | |
44245 weight += bin[z].weight; | |
44246 } | |
44247 var radius = this.options.minimumRadius; | |
44248 if (this.options.noBinningRadii == 'dynamic') { | |
44249 radius = this.getRadius(weight); | |
44250 } | |
44251 var circle = new CircleObject(p.x, p.y, 0, 0, bin, radius, i, weight); | |
44252 circles[i].push(circle); | |
44253 for (var z = 0; z < bin.length; z++) { | |
44254 hashMap[i][bin[z].index] = circle; | |
44255 selectionMap[i][bin[z].index] = false; | |
44256 } | |
44257 } | |
44258 } | |
44259 for (var k = 0; k < this.zoomLevels; k++) { | |
44260 circleSets.push(circles); | |
44261 hashMaps.push(hashMap); | |
44262 selectionHashs.push(selectionMap); | |
44263 } | |
44264 this.binnings['exact'] = { | |
44265 circleSets : circleSets, | |
44266 hashMaps : hashMaps, | |
44267 selectionHashs : selectionHashs | |
44268 }; | |
44269 }, | |
44270 | |
44271 genericClustering : function(objects, id) { | |
44272 var binSets = []; | |
44273 var circleSets = []; | |
44274 var hashMaps = []; | |
44275 var selectionHashs = []; | |
44276 var clustering = new Clustering(-20037508.34, -20037508.34, 20037508.34, 20037508.34); | |
44277 for (var i = 0; i < objects.length; i++) { | |
44278 for (var j = 0; j < objects[i].length; j++) { | |
44279 var o = objects[i][j]; | |
44280 if (o.isGeospatial) { | |
44281 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
44282 p.transform(this.map.displayProjection, this.map.projection); | |
44283 var point = new Vertex(Math.floor(p.x), Math.floor(p.y), objects.length, this); | |
44284 point.addElement(o, o.weight, i); | |
44285 clustering.add(point); | |
44286 } | |
44287 } | |
44288 } | |
44289 | |
44290 for (var i = 0; i < this.zoomLevels; i++) { | |
44291 var bins = []; | |
44292 var circles = []; | |
44293 var hashMap = []; | |
44294 var selectionMap = []; | |
44295 for (var j = 0; j < objects.length; j++) { | |
44296 circles.push([]); | |
44297 hashMap.push([]); | |
44298 selectionMap.push([]); | |
44299 } | |
44300 var resolution = this.map.getResolutionForZoom(this.zoomLevels - i - 1); | |
44301 clustering.mergeForResolution(resolution, this.options.circleGap, this.options.circleOverlap); | |
44302 for (var j = 0; j < clustering.vertices.length; j++) { | |
44303 var point = clustering.vertices[j]; | |
44304 if (!point.legal) { | |
44305 continue; | |
44306 } | |
44307 var balls = []; | |
44308 for (var k = 0; k < point.elements.length; k++) { | |
44309 if (point.elements[k].length > 0) { | |
44310 balls.push({ | |
44311 search : k, | |
44312 elements : point.elements[k], | |
44313 radius : point.radii[k], | |
44314 weight : point.weights[k] | |
44315 }); | |
44316 } | |
44317 } | |
44318 var orderBalls = function(b1, b2) { | |
44319 if (b1.radius > b2.radius) { | |
44320 return -1; | |
44321 } | |
44322 if (b2.radius > b1.radius) { | |
44323 return 1; | |
44324 } | |
44325 return 0; | |
44326 } | |
44327 var fatherBin = { | |
44328 circles : [], | |
44329 length : 0, | |
44330 radius : point.radius / resolution, | |
44331 x : point.x, | |
44332 y : point.y | |
44333 }; | |
44334 for (var k = 0; k < objects.length; k++) { | |
44335 fatherBin.circles.push(false); | |
44336 } | |
44337 var createCircle = function(sx, sy, ball) { | |
44338 var index = id || ball.search; | |
44339 var circle = new CircleObject(point.x, point.y, sx, sy, ball.elements, ball.radius, index, ball.weight, fatherBin); | |
44340 circles[ball.search].push(circle); | |
44341 fatherBin.circles[index] = circle; | |
44342 fatherBin.length++; | |
44343 for (var k = 0; k < ball.elements.length; k++) { | |
44344 hashMap[ball.search][ball.elements[k].index] = circle; | |
44345 selectionMap[ball.search][ball.elements[k].index] = false; | |
44346 } | |
44347 } | |
44348 if (balls.length == 1) { | |
44349 createCircle(0, 0, balls[0]); | |
44350 } else if (balls.length == 2) { | |
44351 var r1 = balls[0].radius; | |
44352 var r2 = balls[1].radius; | |
44353 createCircle(-1 * r2, 0, balls[0]); | |
44354 createCircle(r1, 0, balls[1]); | |
44355 } else if (balls.length == 3) { | |
44356 balls.sort(orderBalls); | |
44357 var r1 = balls[0].radius; | |
44358 var r2 = balls[1].radius; | |
44359 var r3 = balls[2].radius; | |
44360 var d = ((2 / 3 * Math.sqrt(3) - 1) / 2) * r2; | |
44361 var delta1 = point.radius / resolution - r1 - d; | |
44362 var delta2 = r1 - delta1; | |
44363 createCircle(-delta1, 0, balls[0]); | |
44364 createCircle(delta2 + r2 - 3 * d, r2, balls[1]); | |
44365 createCircle(delta2 + r2 - 3 * d, -1 * r3, balls[2]); | |
44366 // createCircle(delta2 + r3 - (3 * d * r3 / r2), -1 * r3, balls[2]); | |
44367 } else if (balls.length == 4) { | |
44368 balls.sort(orderBalls); | |
44369 var r1 = balls[0].radius; | |
44370 var r2 = balls[1].radius; | |
44371 var r3 = balls[2].radius; | |
44372 var r4 = balls[3].radius; | |
44373 var d = (Math.sqrt(2) - 1) * r2; | |
44374 createCircle(-1 * d - r2, 0, balls[0]); | |
44375 createCircle(r1 - r2, -1 * d - r4, balls[3]); | |
44376 createCircle(r1 - r2, d + r3, balls[2]); | |
44377 createCircle(d + r1, 0, balls[1]); | |
44378 } | |
44379 if (fatherBin.length > 1) { | |
44380 bins.push(fatherBin); | |
44381 } | |
44382 } | |
44383 circleSets.push(circles); | |
44384 binSets.push(bins); | |
44385 hashMaps.push(hashMap); | |
44386 selectionHashs.push(selectionMap); | |
44387 } | |
44388 circleSets.reverse(); | |
44389 binSets.reverse(); | |
44390 hashMaps.reverse(); | |
44391 selectionHashs.reverse(); | |
44392 return { | |
44393 circleSets : circleSets, | |
44394 binSets : binSets, | |
44395 hashMaps : hashMaps, | |
44396 selectionHashs : selectionHashs | |
44397 }; | |
44398 }, | |
44399 | |
44400 genericBinning : function() { | |
44401 if (this.options.circlePackings || this.objects.length == 1) { | |
44402 this.binnings['generic'] = this.genericClustering(this.objects); | |
44403 } else { | |
44404 var circleSets = []; | |
44405 var hashMaps = []; | |
44406 var selectionHashs = []; | |
44407 for (var i = 0; i < this.objects.length; i++) { | |
44408 var sets = this.genericClustering([this.objects[i]], i); | |
44409 if (i == 0) { | |
44410 circleSets = sets.circleSets; | |
44411 hashMaps = sets.hashMaps; | |
44412 selectionHashs = sets.selectionHashs; | |
44413 } else { | |
44414 for (var j = 0; j < circleSets.length; j++) { | |
44415 circleSets[j] = circleSets[j].concat(sets.circleSets[j]); | |
44416 hashMaps[j] = hashMaps[j].concat(sets.hashMaps[j]); | |
44417 selectionHashs[j] = selectionHashs[j].concat(sets.selectionHashs[j]); | |
44418 } | |
44419 } | |
44420 } | |
44421 this.binnings['generic'] = { | |
44422 circleSets : circleSets, | |
44423 hashMaps : hashMaps, | |
44424 selectionHashs : selectionHashs | |
44425 }; | |
44426 } | |
44427 }, | |
44428 | |
44429 getRadius : function(n) { | |
44430 if (n == 0) { | |
44431 return 0; | |
44432 } | |
44433 if (n == 1) { | |
44434 return this.minimumRadius; | |
44435 } | |
44436 return Math.sqrt((this.minArea + (this.maxArea - this.minArea) / (this.maximumPoints - 1) * (n - 1) ) / Math.PI); | |
44437 }, | |
44438 | |
44439 getBinRadius : function(n, r_max, N) { | |
44440 if (n == 0) { | |
44441 return 0; | |
44442 } | |
44443 /* | |
44444 function log2(x) { | |
44445 return (Math.log(x)) / (Math.log(2)); | |
44446 } | |
44447 var r0 = this.options.minimumRadius; | |
44448 var r; | |
44449 if ( typeof r_max == 'undefined') { | |
44450 return r0 + n / Math.sqrt(this.options.maximumPoints); | |
44451 } | |
44452 return r0 + (r_max - r0 ) * log2(n) / log2(N); | |
44453 */ | |
44454 var minArea = Math.PI * this.options.minimumRadius * this.options.minimumRadius; | |
44455 var maxArea = Math.PI * r_max * r_max; | |
44456 return Math.sqrt((minArea + (maxArea - minArea) / (N - 1) * (n - 1) ) / Math.PI); | |
44457 }, | |
44458 | |
44459 shift : function(type, bin, radius, elements) { | |
44460 | |
44461 var x1 = bin.x, x2 = 0; | |
44462 var y1 = bin.y, y2 = 0; | |
44463 for (var i = 0; i < elements.length; i++) { | |
44464 x2 += elements[i].x / elements.length; | |
44465 y2 += elements[i].y / elements.length; | |
44466 } | |
44467 | |
44468 var sx = 0, sy = 0; | |
44469 | |
44470 if (type == 'square') { | |
44471 var dx = Math.abs(x2 - x1); | |
44472 var dy = Math.abs(y2 - y1); | |
44473 var m = dy / dx; | |
44474 var n = y1 - m * x1; | |
44475 if (dx > dy) { | |
44476 sx = bin.x - (x1 + bin.r - radius ); | |
44477 sy = bin.y - (m * bin.x + n ); | |
44478 } else { | |
44479 sy = bin.y - (y1 + bin.r - radius ); | |
44480 sx = bin.x - (bin.y - n) / m; | |
44481 } | |
44482 } | |
44483 | |
44484 return { | |
44485 x : sx, | |
44486 y : sy | |
44487 }; | |
44488 | |
44489 }, | |
44490 | |
44491 binSize : function(elements) { | |
44492 var size = 0; | |
44493 for (var i in elements ) { | |
44494 size += elements[i].weight; | |
44495 } | |
44496 return size; | |
44497 }, | |
44498 | |
44499 setCircleSet : function(id, binData) { | |
44500 var circleSets = []; | |
44501 var hashMaps = []; | |
44502 var selectionHashs = []; | |
44503 for (var i = 0; i < binData.length; i++) { | |
44504 var circles = []; | |
44505 var hashMap = []; | |
44506 var selectionMap = []; | |
44507 for (var j = 0; j < this.objects.length; j++) { | |
44508 circles.push([]); | |
44509 hashMap.push([]); | |
44510 selectionMap.push([]); | |
44511 } | |
44512 var points = []; | |
44513 var max = 0; | |
44514 var radius = 0; | |
44515 var resolution = this.map.getResolutionForZoom(i); | |
44516 for (var j = 0; j < binData[i].length; j++) { | |
44517 for (var k = 0; k < binData[i][j].bin.length; k++) { | |
44518 var bs = this.binSize(binData[i][j].bin[k]); | |
44519 if (bs > max) { | |
44520 max = bs; | |
44521 radius = binData[i][j].r / resolution; | |
44522 } | |
44523 } | |
44524 } | |
44525 for (var j = 0; j < binData[i].length; j++) { | |
44526 var bin = binData[i][j]; | |
44527 for (var k = 0; k < bin.bin.length; k++) { | |
44528 if (bin.bin[k].length == 0) { | |
44529 continue; | |
44530 } | |
44531 var weight = this.binSize(bin.bin[k]); | |
44532 var r = this.getBinRadius(weight, radius, max); | |
44533 var shift = this.shift(id, bin, r * resolution, bin.bin[k], i); | |
44534 var circle = new CircleObject(bin.x - shift.x, bin.y - shift.y, 0, 0, bin.bin[k], r, k, weight); | |
44535 circles[k].push(circle); | |
44536 for (var z = 0; z < bin.bin[k].length; z++) { | |
44537 hashMap[k][bin.bin[k][z].index] = circle; | |
44538 selectionMap[k][bin.bin[k][z].index] = false; | |
44539 } | |
44540 } | |
44541 } | |
44542 circleSets.push(circles); | |
44543 hashMaps.push(hashMap); | |
44544 selectionHashs.push(selectionMap); | |
44545 } | |
44546 this.binnings[id] = { | |
44547 circleSets : circleSets, | |
44548 hashMaps : hashMaps, | |
44549 selectionHashs : selectionHashs | |
44550 }; | |
44551 }, | |
44552 | |
44553 squareBinning : function() { | |
44554 | |
44555 var l = 20037508.34; | |
44556 var area0 = l * l * 4; | |
44557 var binCount = this.options.binCount; | |
44558 | |
44559 var bins = []; | |
44560 var binData = []; | |
44561 for (var k = 0; k < this.zoomLevels; k++) { | |
44562 bins.push([]); | |
44563 binData.push([]); | |
44564 } | |
44565 | |
44566 for (var i = 0; i < this.objects.length; i++) { | |
44567 for (var j = 0; j < this.objects[i].length; j++) { | |
44568 var o = this.objects[i][j]; | |
44569 if (!o.isGeospatial) { | |
44570 continue; | |
44571 } | |
44572 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
44573 p.transform(this.map.displayProjection, this.map.projection); | |
44574 o.x = p.x; | |
44575 o.y = p.y; | |
44576 for (var k = 0; k < this.zoomLevels; k++) { | |
44577 var bc = binCount * Math.pow(2, k); | |
44578 var a = 2 * l / bc; | |
44579 var binX = Math.floor((p.x + l) / (2 * l) * bc); | |
44580 var binY = Math.floor((p.y + l) / (2 * l) * bc); | |
44581 if ( typeof bins[k]['' + binX] == 'undefined') { | |
44582 bins[k]['' + binX] = []; | |
44583 } | |
44584 if ( typeof bins[k][''+binX]['' + binY] == 'undefined') { | |
44585 bins[k][''+binX]['' + binY] = []; | |
44586 for (var z = 0; z < this.objects.length; z++) { | |
44587 bins[k][''+binX]['' + binY].push([]); | |
44588 } | |
44589 var x = binX * a + a / 2 - l; | |
44590 var y = binY * a + a / 2 - l; | |
44591 binData[k].push({ | |
44592 bin : bins[k][''+binX]['' + binY], | |
44593 x : x, | |
44594 y : y, | |
44595 a : a, | |
44596 r : a / 2 | |
44597 }); | |
44598 } | |
44599 bins[k][''+binX][''+binY][i].push(o); | |
44600 } | |
44601 } | |
44602 } | |
44603 | |
44604 this.setCircleSet('square', binData); | |
44605 | |
44606 }, | |
44607 | |
44608 triangularBinning : function() { | |
44609 | |
44610 var l = 20037508.34; | |
44611 var a0 = this.options.binCount; | |
44612 var a1 = Math.sqrt(4 * a0 * a0 / Math.sqrt(3)); | |
44613 var binCount = a0 / a1 * a0; | |
44614 | |
44615 var bins = []; | |
44616 var binData = []; | |
44617 for (var k = 0; k < this.zoomLevels; k++) { | |
44618 bins.push([]); | |
44619 binData.push([]); | |
44620 } | |
44621 | |
44622 for (var i = 0; i < this.objects.length; i++) { | |
44623 for (var j = 0; j < this.objects[i].length; j++) { | |
44624 var o = this.objects[i][j]; | |
44625 if (!o.isGeospatial) { | |
44626 continue; | |
44627 } | |
44628 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
44629 p.transform(this.map.displayProjection, this.map.projection); | |
44630 o.x = p.x; | |
44631 o.y = p.y; | |
44632 for (var k = 0; k < this.zoomLevels; k++) { | |
44633 var x_bc = binCount * Math.pow(2, k); | |
44634 var y_bc = x_bc * x_bc / Math.sqrt(x_bc * x_bc - x_bc * x_bc / 4); | |
44635 var a = 2 * l / x_bc; | |
44636 var h = 2 * l / y_bc; | |
44637 var binY = Math.floor((p.y + l) / (2 * l) * y_bc); | |
44638 if ( typeof bins[k]['' + binY] == 'undefined') { | |
44639 bins[k]['' + binY] = []; | |
44640 } | |
44641 var triangleIndex; | |
44642 var partitionsX = x_bc * 2; | |
44643 var partition = Math.floor((p.x + l) / (2 * l) * partitionsX); | |
44644 var xMax = a / 2; | |
44645 var yMax = h; | |
44646 var x = p.x + l - partition * a / 2; | |
44647 var y = p.y + l - binY * h; | |
44648 if (binY % 2 == 0 && partition % 2 == 1 || binY % 2 == 1 && partition % 2 == 0) { | |
44649 if (y + yMax / xMax * x < yMax) { | |
44650 triangleIndex = partition; | |
44651 } else { | |
44652 triangleIndex = partition + 1; | |
44653 } | |
44654 } else { | |
44655 if (y > yMax / xMax * x) { | |
44656 triangleIndex = partition; | |
44657 } else { | |
44658 triangleIndex = partition + 1; | |
44659 } | |
44660 } | |
44661 if ( typeof bins[k][''+binY]['' + triangleIndex] == 'undefined') { | |
44662 bins[k][''+binY]['' + triangleIndex] = []; | |
44663 for (var z = 0; z < this.objects.length; z++) { | |
44664 bins[k][''+binY]['' + triangleIndex].push([]); | |
44665 } | |
44666 var r = Math.sqrt(3) / 6 * a; | |
44667 var x = (triangleIndex - 1) * a / 2 + a / 2 - l; | |
44668 var y; | |
44669 if (binY % 2 == 0 && triangleIndex % 2 == 0 || binY % 2 == 1 && triangleIndex % 2 == 1) { | |
44670 y = binY * h + h - r - l; | |
44671 } else { | |
44672 y = binY * h + r - l; | |
44673 } | |
44674 binData[k].push({ | |
44675 bin : bins[k][''+binY]['' + triangleIndex], | |
44676 x : x, | |
44677 y : y, | |
44678 a : a, | |
44679 r : r | |
44680 }); | |
44681 } | |
44682 bins[k][''+binY][''+triangleIndex][i].push(o); | |
44683 } | |
44684 } | |
44685 } | |
44686 | |
44687 this.setCircleSet('triangular', binData); | |
44688 | |
44689 }, | |
44690 | |
44691 hexagonalBinning : function() { | |
44692 | |
44693 var l = 20037508.34; | |
44694 var a0 = this.options.binCount; | |
44695 var a2 = Math.sqrt(4 * a0 * a0 / Math.sqrt(3)) / Math.sqrt(6); | |
44696 var binCount = a0 / a2 * a0; | |
44697 | |
44698 var bins = []; | |
44699 var binData = []; | |
44700 for (var k = 0; k < this.zoomLevels; k++) { | |
44701 bins.push([]); | |
44702 binData.push([]); | |
44703 } | |
44704 | |
44705 for (var i = 0; i < this.objects.length; i++) { | |
44706 for (var j = 0; j < this.objects[i].length; j++) { | |
44707 var o = this.objects[i][j]; | |
44708 if (!o.isGeospatial) { | |
44709 continue; | |
44710 } | |
44711 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
44712 p.transform(this.map.displayProjection, this.map.projection); | |
44713 o.x = p.x; | |
44714 o.y = p.y; | |
44715 for (var k = 0; k < this.zoomLevels; k++) { | |
44716 var x_bc = binCount * Math.pow(2, k); | |
44717 var y_bc = x_bc * x_bc / Math.sqrt(x_bc * x_bc - x_bc * x_bc / 4); | |
44718 var a = 2 * l / x_bc; | |
44719 var h = 2 * l / y_bc; | |
44720 var binY = Math.floor((p.y + l) / (2 * l) * y_bc); | |
44721 if ( typeof bins[k]['' + binY] == 'undefined') { | |
44722 bins[k]['' + binY] = []; | |
44723 } | |
44724 var triangleIndex; | |
44725 var partitionsX = x_bc * 2; | |
44726 var partition = Math.floor((p.x + l) / (2 * l) * partitionsX); | |
44727 var xMax = a / 2; | |
44728 var yMax = h; | |
44729 var x = p.x + l - partition * a / 2; | |
44730 var y = p.y + l - binY * h; | |
44731 if (binY % 2 == 0 && partition % 2 == 1 || binY % 2 == 1 && partition % 2 == 0) { | |
44732 if (y + yMax / xMax * x < yMax) { | |
44733 triangleIndex = partition; | |
44734 } else { | |
44735 triangleIndex = partition + 1; | |
44736 } | |
44737 } else { | |
44738 if (y > yMax / xMax * x) { | |
44739 triangleIndex = partition; | |
44740 } else { | |
44741 triangleIndex = partition + 1; | |
44742 } | |
44743 } | |
44744 if ( typeof bins[k][''+binY]['' + triangleIndex] == 'undefined') { | |
44745 bins[k][''+binY]['' + triangleIndex] = []; | |
44746 for (var z = 0; z < this.objects.length; z++) { | |
44747 bins[k][''+binY]['' + triangleIndex].push([]); | |
44748 } | |
44749 var r = Math.sqrt(3) / 6 * a; | |
44750 var x = (triangleIndex - 1) * a / 2 + a / 2 - l; | |
44751 var y; | |
44752 if (binY % 2 == 0 && triangleIndex % 2 == 0 || binY % 2 == 1 && triangleIndex % 2 == 1) { | |
44753 y = binY * h + h - r - l; | |
44754 } else { | |
44755 y = binY * h + r - l; | |
44756 } | |
44757 binData[k].push({ | |
44758 bin : bins[k][''+binY]['' + triangleIndex], | |
44759 x : x, | |
44760 y : y, | |
44761 a : a, | |
44762 r : r, | |
44763 h : h, | |
44764 binX : triangleIndex, | |
44765 binY : binY | |
44766 }); | |
44767 } | |
44768 bins[k][''+binY][''+triangleIndex][i].push(o); | |
44769 } | |
44770 } | |
44771 } | |
44772 | |
44773 var hexaBins = []; | |
44774 var hexaBinData = []; | |
44775 for (var k = 0; k < this.zoomLevels; k++) { | |
44776 hexaBins.push([]); | |
44777 hexaBinData.push([]); | |
44778 } | |
44779 | |
44780 for (var i = 0; i < binData.length; i++) { | |
44781 for (var j = 0; j < binData[i].length; j++) { | |
44782 var bin = binData[i][j]; | |
44783 var binY = Math.floor(bin.binY / 2); | |
44784 var binX = Math.floor(bin.binX / 3); | |
44785 var x, y; | |
44786 var a = bin.a; | |
44787 var h = bin.h; | |
44788 if (bin.binX % 6 < 3) { | |
44789 if ( typeof hexaBins[i]['' + binY] == 'undefined') { | |
44790 hexaBins[i]['' + binY] = []; | |
44791 } | |
44792 y = binY * 2 * bin.h + bin.h - l; | |
44793 x = binX * 1.5 * bin.a + a / 2 - l; | |
44794 } else { | |
44795 if (bin.binY % 2 == 1) { | |
44796 binY++; | |
44797 } | |
44798 if ( typeof hexaBins[i]['' + binY] == 'undefined') { | |
44799 hexaBins[i]['' + binY] = []; | |
44800 } | |
44801 y = binY * 2 * bin.h - l; | |
44802 x = binX * 1.5 * bin.a + a / 2 - l; | |
44803 } | |
44804 if ( typeof hexaBins[i][''+binY]['' + binX] == 'undefined') { | |
44805 hexaBins[i][''+binY]['' + binX] = []; | |
44806 for (var z = 0; z < this.objects.length; z++) { | |
44807 hexaBins[i][''+binY]['' + binX].push([]); | |
44808 } | |
44809 hexaBinData[i].push({ | |
44810 bin : hexaBins[i][''+binY]['' + binX], | |
44811 x : x, | |
44812 y : y, | |
44813 a : bin.a, | |
44814 r : bin.h | |
44815 }); | |
44816 } | |
44817 for (var k = 0; k < bin.bin.length; k++) { | |
44818 for (var m = 0; m < bin.bin[k].length; m++) { | |
44819 hexaBins[i][''+binY][''+binX][k].push(bin.bin[k][m]); | |
44820 } | |
44821 } | |
44822 } | |
44823 } | |
44824 | |
44825 this.setCircleSet('hexagonal', hexaBinData); | |
44826 | |
44827 } | |
44828 } | |
44829 | |
44830 /* | |
44831 * MapDataSource.js | |
44832 * | |
44833 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
44834 * | |
44835 * This library is free software; you can redistribute it and/or | |
44836 * modify it under the terms of the GNU Lesser General Public | |
44837 * License as published by the Free Software Foundation; either | |
44838 * version 3 of the License, or (at your option) any later version. | |
44839 * | |
44840 * This library is distributed in the hope that it will be useful, | |
44841 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
44842 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
44843 * Lesser General Public License for more details. | |
44844 * | |
44845 * You should have received a copy of the GNU Lesser General Public | |
44846 * License along with this library; if not, write to the Free Software | |
44847 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
44848 * MA 02110-1301 USA | |
44849 */ | |
44850 | |
44851 /** | |
44852 * @class MapDataSource | |
44853 * implementation for aggregation of map items | |
44854 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
44855 * @release 1.0 | |
44856 * @release date: 2012-07-27 | |
44857 * @version date: 2012-07-27 | |
44858 * | |
44859 * @param {MapWidget} parent Widget | |
44860 * @param {JSON} options map configuration | |
44861 */ | |
44862 function MapDataSource(parent, options) { | |
44863 | |
44864 this.parent = parent; | |
44865 this.olMap = parent.openlayersMap; | |
44866 this.circleSets = []; | |
44867 this.binning = new Binning(this.olMap, options); | |
44868 | |
44869 }; | |
44870 | |
44871 MapDataSource.prototype = { | |
44872 | |
44873 /** | |
44874 * initializes the MapDataSource | |
44875 * @param {MapObject[][]} mapObjects an array of map objects of different sets | |
44876 */ | |
44877 initialize : function(mapObjects) { | |
44878 | |
44879 if (mapObjects != this.mapObjects) { | |
44880 this.binning.reset(); | |
44881 this.binning.setObjects(mapObjects); | |
44882 } | |
44883 this.mapObjects = mapObjects; | |
44884 | |
44885 var set = this.binning.getSet(); | |
44886 this.circleSets = set.circleSets; | |
44887 this.binSets = set.binSets; | |
44888 this.hashMapping = set.hashMaps; | |
44889 | |
44890 }, | |
44891 | |
44892 getObjectsByZoom : function() { | |
44893 var zoom = Math.floor(this.parent.getZoom()); | |
44894 if (this.circleSets.length < zoom) { | |
44895 return null; | |
44896 } | |
44897 return this.circleSets[zoom]; | |
44898 }, | |
44899 | |
44900 getAllObjects : function() { | |
44901 if (this.circleSets.length == 0) { | |
44902 return null; | |
44903 } | |
44904 return this.circleSets; | |
44905 }, | |
44906 | |
44907 getAllBins : function() { | |
44908 if (this.binSets.length == 0) { | |
44909 return null; | |
44910 } | |
44911 return this.binSets; | |
44912 }, | |
44913 | |
44914 clearOverlay : function() { | |
44915 var zoom = Math.floor(this.parent.getZoom()); | |
44916 var circles = this.circleSets[zoom]; | |
44917 for (var i in circles ) { | |
44918 for (var j in circles[i] ) { | |
44919 circles[i][j].reset(); | |
44920 } | |
44921 } | |
44922 }, | |
44923 | |
44924 setOverlay : function(mapObjects) { | |
44925 var zoom = Math.floor(this.parent.getZoom()); | |
44926 for (var j in mapObjects ) { | |
44927 for (var k in mapObjects[j] ) { | |
44928 var o = mapObjects[j][k]; | |
44929 if (o.isGeospatial) { | |
44930 this.hashMapping[zoom][j][o.index].overlayElements.push(o); | |
44931 this.hashMapping[zoom][j][o.index].overlay += o.weight; | |
44932 } | |
44933 } | |
44934 } | |
44935 }, | |
44936 | |
44937 size : function() { | |
44938 if (this.circleSets.length == 0) { | |
44939 return 0; | |
44940 } | |
44941 return this.circleSets[0].length; | |
44942 }, | |
44943 | |
44944 getCircle : function(index, id) { | |
44945 var zoom = Math.floor(this.parent.getZoom()); | |
44946 return this.hashMapping[zoom][index][id]; | |
44947 } | |
44948 }; | |
44949 /* | |
44950 * Clustering.js | |
44951 * | |
44952 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
44953 * | |
44954 * This library is free software; you can redistribute it and/or | |
44955 * modify it under the terms of the GNU Lesser General Public | |
44956 * License as published by the Free Software Foundation; either | |
44957 * version 3 of the License, or (at your option) any later version. | |
44958 * | |
44959 * This library is distributed in the hope that it will be useful, | |
44960 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
44961 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
44962 * Lesser General Public License for more details. | |
44963 * | |
44964 * You should have received a copy of the GNU Lesser General Public | |
44965 * License along with this library; if not, write to the Free Software | |
44966 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
44967 * MA 02110-1301 USA | |
44968 */ | |
44969 | |
44970 /** | |
44971 * @class Vertex, Edge, Triangle, Clustering, BinaryHeap | |
44972 * Dynamic Delaunay clustering algorithm (see GeoTemCo paper) | |
44973 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
44974 * @release 1.0 | |
44975 * @release date: 2012-07-27 | |
44976 * @version date: 2012-07-27 | |
44977 */ | |
44978 | |
44979 function Vertex(x, y, categories, binning) { | |
44980 this.x = x; | |
44981 this.y = y; | |
44982 this.radius | |
44983 this.size = 0; | |
44984 this.elements = []; | |
44985 this.radii = []; | |
44986 this.weights = []; | |
44987 this.legal = true; | |
44988 this.binning = binning; | |
44989 if (categories != undefined) { | |
44990 for (var i = 0; i < categories; i++) { | |
44991 this.elements.push([]); | |
44992 this.weights.push(0); | |
44993 } | |
44994 } | |
44995 } | |
44996 | |
44997 Vertex.prototype.merge = function(v0, v1) { | |
44998 for (var i = 0; i < v0.elements.length; i++) { | |
44999 this.elements[i] = v0.elements[i].concat(v1.elements[i]); | |
45000 this.weights[i] = v0.weights[i] + v1.weights[i]; | |
45001 this.size += this.weights[i]; | |
45002 } | |
45003 } | |
45004 | |
45005 Vertex.prototype.CalculateRadius = function(resolution) { | |
45006 this.radii = []; | |
45007 for (i in this.elements ) { | |
45008 this.radii.push(this.binning.getRadius(this.weights[i])); | |
45009 } | |
45010 if (this.radii.length == 1) { | |
45011 this.radius = this.radii[0] * resolution; | |
45012 } else { | |
45013 var count = 0; | |
45014 var max1 = 0; | |
45015 var max2 = 0; | |
45016 for (i in this.radii ) { | |
45017 if (this.radii[i] != 0) { | |
45018 count++; | |
45019 } | |
45020 if (this.radii[i] > max1) { | |
45021 if (max1 > max2) { | |
45022 max2 = max1; | |
45023 } | |
45024 max1 = this.radii[i]; | |
45025 } else if (this.radii[i] > max2) { | |
45026 max2 = this.radii[i]; | |
45027 } | |
45028 } | |
45029 if (count == 1) { | |
45030 this.radius = max1 * resolution; | |
45031 } else if (count == 2) { | |
45032 this.radius = (max1 + max2) * resolution; | |
45033 } else if (count == 3) { | |
45034 var d = (2 / 3 * Math.sqrt(3) - 1) * max1; | |
45035 this.radius = (d + max1 + max2) * resolution; | |
45036 } else if (count == 4) { | |
45037 var d = (Math.sqrt(2) - 1) * max2; | |
45038 this.radius = (d + max1 + max2) * resolution; | |
45039 } | |
45040 } | |
45041 } | |
45042 | |
45043 Vertex.prototype.addElement = function(e, weight, index) { | |
45044 this.elements[index].push(e); | |
45045 this.size += weight; | |
45046 this.weights[index] += weight; | |
45047 } | |
45048 function Edge(v0, v1) { | |
45049 this.v0 = v0; | |
45050 this.v1 = v1; | |
45051 this.leftFace | |
45052 this.rightFace | |
45053 this.legal = true; | |
45054 this.setLength(); | |
45055 } | |
45056 | |
45057 Edge.prototype.setLength = function() { | |
45058 var dx = this.v0.x - this.v1.x; | |
45059 var dy = this.v0.y - this.v1.y; | |
45060 this.length = Math.sqrt(dx * dx + dy * dy); | |
45061 } | |
45062 | |
45063 Edge.prototype.contains = function(v) { | |
45064 if (this.v0 == v || this.v1 == v) { | |
45065 return true; | |
45066 } | |
45067 return false; | |
45068 } | |
45069 | |
45070 Edge.prototype.replaceFace = function(f_old, f_new) { | |
45071 if (this.leftFace == f_old) { | |
45072 this.leftFace = f_new; | |
45073 } else if (this.rightFace == f_old) { | |
45074 this.rightFace = f_new; | |
45075 } | |
45076 } | |
45077 | |
45078 Edge.prototype.setFace = function(f) { | |
45079 if (f.leftOf(this)) { | |
45080 this.leftFace = f; | |
45081 } else { | |
45082 this.rightFace = f; | |
45083 } | |
45084 } | |
45085 | |
45086 Edge.prototype.setFaces = function(f1, f2) { | |
45087 if (f1.leftOf(this)) { | |
45088 this.leftFace = f1; | |
45089 this.rightFace = f2; | |
45090 } else { | |
45091 this.leftFace = f2; | |
45092 this.rightFace = f1; | |
45093 } | |
45094 } | |
45095 | |
45096 Edge.prototype.removeFace = function(f) { | |
45097 if (this.leftFace == f) { | |
45098 this.leftFace = null; | |
45099 } else { | |
45100 this.rightFace = null; | |
45101 } | |
45102 } | |
45103 | |
45104 Edge.prototype.equals = function(e) { | |
45105 if (this.v0 == e.v0 && this.v1 == e.v1 || this.v0 == e.v1 && this.v1 == e.v0) { | |
45106 return true; | |
45107 } | |
45108 return false; | |
45109 } | |
45110 function Triangle(edges) { | |
45111 this.edges = edges; | |
45112 this.setVertices(); | |
45113 this.descendants = []; | |
45114 } | |
45115 | |
45116 Triangle.prototype.getTriple = function(e) { | |
45117 var i = arrayIndex(this.edges, e); | |
45118 return { | |
45119 e_s : this.edges[(i + 1) % 3], | |
45120 e_p : this.edges[(i + 2) % 3], | |
45121 u : this.vertices[(i + 2) % 3] | |
45122 }; | |
45123 } | |
45124 | |
45125 Triangle.prototype.leftOf = function(e) { | |
45126 var i = arrayIndex(this.edges, e); | |
45127 if (this.vertices[i].y != this.vertices[(i + 1) % 3].y) { | |
45128 return this.vertices[i].y > this.vertices[(i + 1) % 3].y; | |
45129 } | |
45130 return this.vertices[i].y > this.vertices[(i + 2) % 3].y; | |
45131 } | |
45132 | |
45133 Triangle.prototype.getNext = function(v) { | |
45134 var i = arrayIndex(this.vertices, v); | |
45135 return this.vertices[(i + 1) % 3]; | |
45136 } | |
45137 | |
45138 Triangle.prototype.oppositeEdge = function(v) { | |
45139 var i = arrayIndex(this.vertices, v); | |
45140 return this.edges[(i + 1) % 3]; | |
45141 } | |
45142 | |
45143 Triangle.prototype.contains = function(v) { | |
45144 return arrayIndex(this.vertices, v) != -1; | |
45145 } | |
45146 | |
45147 Triangle.prototype.replace = function(e_old, e_new) { | |
45148 this.edges[arrayIndex(this.edges, e_old)] = e_new; | |
45149 } | |
45150 | |
45151 Triangle.prototype.setVertices = function() { | |
45152 if (this.edges[1].v0 == this.edges[0].v0 || this.edges[1].v1 == this.edges[0].v0) { | |
45153 this.vertices = [this.edges[0].v1, this.edges[0].v0]; | |
45154 } else { | |
45155 this.vertices = [this.edges[0].v0, this.edges[0].v1]; | |
45156 } | |
45157 if (this.edges[2].v0 == this.vertices[0]) { | |
45158 this.vertices.push(this.edges[2].v1); | |
45159 } else { | |
45160 this.vertices.push(this.edges[2].v0); | |
45161 } | |
45162 } | |
45163 | |
45164 Triangle.prototype.replaceBy = function(triangles) { | |
45165 this.descendants = triangles; | |
45166 this.edges[0].replaceFace(this, triangles[0]); | |
45167 this.edges[1].replaceFace(this, triangles[1]); | |
45168 this.edges[2].replaceFace(this, triangles[2]); | |
45169 } | |
45170 | |
45171 Triangle.prototype.CalcCircumcircle = function() { | |
45172 var v0 = this.vertices[0]; | |
45173 var v1 = this.vertices[1]; | |
45174 var v2 = this.vertices[2]; | |
45175 var A = v1.x - v0.x; | |
45176 var B = v1.y - v0.y; | |
45177 var C = v2.x - v0.x; | |
45178 var D = v2.y - v0.y; | |
45179 var E = A * (v0.x + v1.x) + B * (v0.y + v1.y); | |
45180 var F = C * (v0.x + v2.x) + D * (v0.y + v2.y); | |
45181 var G = 2.0 * (A * (v2.y - v1.y) - B * (v2.x - v1.x)); | |
45182 var cx = (D * E - B * F) / G; | |
45183 var cy = (A * F - C * E) / G; | |
45184 this.center = new Vertex(cx, cy); | |
45185 var dx = this.center.x - v0.x; | |
45186 var dy = this.center.y - v0.y; | |
45187 this.radius_squared = dx * dx + dy * dy; | |
45188 }; | |
45189 | |
45190 Triangle.prototype.inCircumcircle = function(v) { | |
45191 if (this.radius_squared == undefined) { | |
45192 this.CalcCircumcircle(); | |
45193 } | |
45194 var dx = this.center.x - v.x; | |
45195 var dy = this.center.y - v.y; | |
45196 var dist_squared = dx * dx + dy * dy; | |
45197 return (dist_squared <= this.radius_squared ); | |
45198 }; | |
45199 | |
45200 Triangle.prototype.interior = function(v) { | |
45201 var v0 = this.vertices[0]; | |
45202 var v1 = this.vertices[1]; | |
45203 var v2 = this.vertices[2]; | |
45204 var dotAB = (v.x - v0.x ) * (v0.y - v1.y ) + (v.y - v0.y ) * (v1.x - v0.x ); | |
45205 var dotBC = (v.x - v1.x ) * (v1.y - v2.y ) + (v.y - v1.y ) * (v2.x - v1.x ); | |
45206 var dotCA = (v.x - v2.x ) * (v2.y - v0.y ) + (v.y - v2.y ) * (v0.x - v2.x ); | |
45207 if (dotAB > 0 || dotBC > 0 || dotCA > 0) { | |
45208 return null; | |
45209 } else if (dotAB < 0 && dotBC < 0 && dotCA < 0) { | |
45210 return this; | |
45211 } else if (dotAB == 0) { | |
45212 if (dotBC == 0) { | |
45213 return this.vertices[1]; | |
45214 } else if (dotCA == 0) { | |
45215 return this.vertices[0]; | |
45216 } | |
45217 return this.edges[0]; | |
45218 } else if (dotBC == 0) { | |
45219 if (dotCA == 0) { | |
45220 return this.vertices[2]; | |
45221 } | |
45222 return this.edges[1]; | |
45223 } else if (dotCA == 0) { | |
45224 return this.edges[2]; | |
45225 } | |
45226 }; | |
45227 | |
45228 function Clustering(xMin, yMin, xMax, yMax) { | |
45229 this.triangles = []; | |
45230 this.newTriangles = []; | |
45231 this.bbox = { | |
45232 x1 : xMin, | |
45233 y1 : yMin, | |
45234 x2 : xMax, | |
45235 y2 : yMax | |
45236 }; | |
45237 this.CreateBoundingTriangle(); | |
45238 this.edges = []; | |
45239 this.vertices = []; | |
45240 this.legalizes = 0; | |
45241 this.collapses = 0; | |
45242 } | |
45243 | |
45244 Clustering.prototype.locate = function(v) { | |
45245 if (this.boundingTriangle.descendants.length == 0) { | |
45246 return this.boundingTriangle; | |
45247 } | |
45248 var triangles = this.boundingTriangle.descendants; | |
45249 while (true) { | |
45250 for (var i = 0; i < triangles.length; i++) { | |
45251 var simplex = triangles[i].interior(v); | |
45252 if (simplex == null) { | |
45253 continue; | |
45254 } | |
45255 if ( simplex instanceof Vertex || this.isLeaf(triangles[i])) { | |
45256 return simplex; | |
45257 } | |
45258 triangles = triangles[i].descendants; | |
45259 break; | |
45260 } | |
45261 } | |
45262 } | |
45263 | |
45264 Clustering.prototype.legalize = function(v, e, t0_old) { | |
45265 if (!e.v0.legal && !e.v1.legal) { | |
45266 return; | |
45267 } | |
45268 this.legalizes++; | |
45269 var flip = false; | |
45270 var t1_old, tr1; | |
45271 if (e.leftFace == t0_old && e.rightFace.inCircumcircle(v)) { | |
45272 flip = true; | |
45273 t1_old = e.rightFace; | |
45274 } else if (e.rightFace == t0_old && e.leftFace.inCircumcircle(v)) { | |
45275 flip = true; | |
45276 t1_old = e.leftFace; | |
45277 } | |
45278 if (flip) { | |
45279 var tr0 = t0_old.getTriple(e); | |
45280 var tr1 = t1_old.getTriple(e); | |
45281 var e_flip = new Edge(tr0.u, tr1.u); | |
45282 var poly = []; | |
45283 poly.push(e.v0); | |
45284 poly.push(e_flip.v0); | |
45285 poly.push(e.v1); | |
45286 poly.push(e_flip.v1); | |
45287 if (!this.JordanTest(poly, e_flip)) { | |
45288 return; | |
45289 } | |
45290 e.legal = false; | |
45291 this.edges.push(e_flip); | |
45292 var t0_new = new Triangle([e_flip, tr0.e_p, tr1.e_s]); | |
45293 var t1_new = new Triangle([e_flip, tr1.e_p, tr0.e_s]); | |
45294 e_flip.setFaces(t0_new, t1_new); | |
45295 tr0.e_p.replaceFace(t0_old, t0_new); | |
45296 tr1.e_s.replaceFace(t1_old, t0_new); | |
45297 tr1.e_p.replaceFace(t1_old, t1_new); | |
45298 tr0.e_s.replaceFace(t0_old, t1_new); | |
45299 t0_old.descendants = [t0_new, t1_new]; | |
45300 t1_old.descendants = [t0_new, t1_new]; | |
45301 this.legalize(v, t0_new.edges[2], t0_new); | |
45302 this.legalize(v, t1_new.edges[1], t1_new); | |
45303 } | |
45304 } | |
45305 | |
45306 Clustering.prototype.add = function(v) { | |
45307 this.addVertex(v, this.locate(v)); | |
45308 } | |
45309 | |
45310 Clustering.prototype.addVertex = function(v, simplex) { | |
45311 if ( simplex instanceof Vertex) { | |
45312 simplex.merge(simplex, v); | |
45313 } else if ( simplex instanceof Edge) { | |
45314 this.vertices.push(v); | |
45315 simplex.legal = false; | |
45316 var tr0 = simplex.leftFace.getTriple(simplex); | |
45317 var tr1 = simplex.rightFace.getTriple(simplex); | |
45318 var e0 = new Edge(v, tr0.u); | |
45319 var e1 = new Edge(v, simplex.leftFace.getNext(tr0.u)); | |
45320 var e2 = new Edge(v, tr1.u); | |
45321 var e3 = new Edge(v, simplex.rightFace.getNext(tr1.u)); | |
45322 var t0 = new Triangle([e0, tr0.e_p, e1]); | |
45323 var t1 = new Triangle([e1, tr1.e_s, e2]); | |
45324 var t2 = new Triangle([e2, tr1.e_p, e3]); | |
45325 var t3 = new Triangle([e3, tr0.e_s, e0]); | |
45326 simplex.leftFace.descendants = [t0, t3]; | |
45327 simplex.rightFace.descendants = [t1, t2]; | |
45328 this.edges.push(e0); | |
45329 this.edges.push(e1); | |
45330 this.edges.push(e2); | |
45331 this.edges.push(e3); | |
45332 e0.setFaces(t0, t3); | |
45333 e1.setFaces(t0, t1); | |
45334 e2.setFaces(t1, t2); | |
45335 e3.setFaces(t2, t3); | |
45336 tr0.e_p.replaceFace(simplex.leftFace, t0); | |
45337 tr1.e_s.replaceFace(simplex.rightFace, t1); | |
45338 tr1.e_p.replaceFace(simplex.rightFace, t2); | |
45339 tr0.e_s.replaceFace(simplex.leftFace, t3); | |
45340 this.legalize(v, tr0.e_p, t0); | |
45341 this.legalize(v, tr1.e_s, t1); | |
45342 this.legalize(v, tr1.e_p, t2); | |
45343 this.legalize(v, tr0.e_s, t3); | |
45344 } else { | |
45345 this.vertices.push(v); | |
45346 var e_i = new Edge(simplex.vertices[0], v); | |
45347 var e_j = new Edge(simplex.vertices[1], v); | |
45348 var e_k = new Edge(simplex.vertices[2], v); | |
45349 this.edges.push(e_i); | |
45350 this.edges.push(e_j); | |
45351 this.edges.push(e_k); | |
45352 var t0 = new Triangle([e_i, simplex.edges[0], e_j]); | |
45353 var t1 = new Triangle([e_j, simplex.edges[1], e_k]); | |
45354 var t2 = new Triangle([e_k, simplex.edges[2], e_i]); | |
45355 e_i.setFaces(t0, t2); | |
45356 e_j.setFaces(t0, t1); | |
45357 e_k.setFaces(t1, t2); | |
45358 simplex.replaceBy([t0, t1, t2]); | |
45359 this.legalize(v, simplex.edges[0], t0); | |
45360 this.legalize(v, simplex.edges[1], t1); | |
45361 this.legalize(v, simplex.edges[2], t2); | |
45362 } | |
45363 } | |
45364 | |
45365 Clustering.prototype.isLeaf = function(t) { | |
45366 return t.descendants.length == 0; | |
45367 } | |
45368 | |
45369 Clustering.prototype.CreateBoundingTriangle = function() { | |
45370 var dx = (this.bbox.x2 - this.bbox.x1 ) * 10; | |
45371 var dy = (this.bbox.y2 - this.bbox.y1 ) * 10; | |
45372 var v0 = new Vertex(this.bbox.x1 - dx, this.bbox.y1 - dy * 3); | |
45373 var v1 = new Vertex(this.bbox.x2 + dx * 3, this.bbox.y2 + dy); | |
45374 var v2 = new Vertex(this.bbox.x1 - dx, this.bbox.y2 + dy); | |
45375 var e0 = new Edge(v1, v0); | |
45376 var e1 = new Edge(v0, v2); | |
45377 var e2 = new Edge(v2, v1); | |
45378 v0.legal = false; | |
45379 v1.legal = false; | |
45380 v2.legal = false; | |
45381 this.boundingTriangle = new Triangle([e0, e1, e2]); | |
45382 var inf = new Triangle([e0, e1, e2]); | |
45383 e0.setFaces(this.boundingTriangle, inf); | |
45384 e1.setFaces(this.boundingTriangle, inf); | |
45385 e2.setFaces(this.boundingTriangle, inf); | |
45386 } | |
45387 | |
45388 Clustering.prototype.mergeVertices = function(e) { | |
45389 this.collapses++; | |
45390 var s0 = e.v0.size; | |
45391 var s1 = e.v1.size; | |
45392 var x = (e.v0.x * s0 + e.v1.x * s1 ) / (s0 + s1 ); | |
45393 var y = (e.v0.y * s0 + e.v1.y * s1 ) / (s0 + s1 ); | |
45394 var v = new Vertex(x, y, e.v0.elements.length, e.v0.binning); | |
45395 v.merge(e.v0, e.v1); | |
45396 | |
45397 e.v0.legal = false; | |
45398 e.v1.legal = false; | |
45399 | |
45400 var hole = []; | |
45401 var oldFacets = []; | |
45402 e.legal = false; | |
45403 | |
45404 var vertices = []; | |
45405 var traverse = function(eLeft, eRight, triangle) { | |
45406 eLeft.legal = false; | |
45407 do { | |
45408 var triple; | |
45409 if (eLeft.leftFace == triangle) { | |
45410 triple = eLeft.rightFace.getTriple(eLeft); | |
45411 oldFacets.push(eLeft.rightFace); | |
45412 triple.e_s.removeFace(eLeft.rightFace); | |
45413 triangle = eLeft.rightFace; | |
45414 } else { | |
45415 triple = eLeft.leftFace.getTriple(eLeft); | |
45416 oldFacets.push(eLeft.leftFace); | |
45417 triple.e_s.removeFace(eLeft.leftFace); | |
45418 triangle = eLeft.leftFace; | |
45419 } | |
45420 if (arrayIndex(hole, triple.e_s) == -1) { | |
45421 hole.push(triple.e_s); | |
45422 } | |
45423 vertices.push(triple.u); | |
45424 eLeft = triple.e_p; | |
45425 eLeft.legal = false; | |
45426 } while( eLeft != eRight ); | |
45427 } | |
45428 var tr0 = e.leftFace.getTriple(e); | |
45429 var tr1 = e.rightFace.getTriple(e); | |
45430 oldFacets.push(e.leftFace); | |
45431 oldFacets.push(e.rightFace); | |
45432 traverse(tr0.e_p, tr1.e_s, e.leftFace); | |
45433 traverse(tr1.e_p, tr0.e_s, e.rightFace); | |
45434 | |
45435 var hd = new Clustering(this.bbox.x1 - 10, this.bbox.y1 - 10, this.bbox.x2 + 10, this.bbox.y2 + 10); | |
45436 var hull = []; | |
45437 for (var i in hole ) { | |
45438 if (!(hole[i].leftFace == null && hole[i].rightFace == null)) { | |
45439 hull.push(hole[i].v0); | |
45440 hull.push(hole[i].v1); | |
45441 } | |
45442 } | |
45443 var hullVertices = []; | |
45444 var distinct = []; | |
45445 for (var i in vertices ) { | |
45446 if (arrayIndex(distinct, vertices[i]) == -1) { | |
45447 hd.add(vertices[i]); | |
45448 distinct.push(vertices[i]); | |
45449 } | |
45450 if (arrayIndex(hull, vertices[i]) != -1) { | |
45451 hullVertices.push(vertices[i]); | |
45452 } | |
45453 } | |
45454 | |
45455 var newFacets = []; | |
45456 var isBoundary = function(e) { | |
45457 for (var i = 0; i < hole.length; i++) { | |
45458 if (hole[i].equals(e)) { | |
45459 return i; | |
45460 } | |
45461 } | |
45462 return -1; | |
45463 } | |
45464 var holeEdges = new Array(hole.length); | |
45465 var nonHoleEdges = []; | |
45466 | |
45467 for (var i = 0; i < hd.edges.length; i++) { | |
45468 var e = hd.edges[i]; | |
45469 var b = isBoundary(e); | |
45470 if (b != -1) { | |
45471 if (!e.legal) { | |
45472 var t1 = e.leftFace.getTriple(e); | |
45473 var t2 = e.rightFace.getTriple(e); | |
45474 var edge = new Edge(t1.u, t2.u); | |
45475 for (var j = 0; j < hd.edges.length; j++) { | |
45476 if (hd.edges[j].equals(edge) && hd.edges[j].legal) { | |
45477 hd.edges[j].legal = false; | |
45478 break; | |
45479 } | |
45480 } | |
45481 t1.e_p.setFace(e.leftFace); | |
45482 t1.e_s.setFace(e.leftFace); | |
45483 t2.e_p.setFace(e.rightFace); | |
45484 t2.e_s.setFace(e.rightFace); | |
45485 | |
45486 e.legal = true; | |
45487 } | |
45488 holeEdges[b] = e; | |
45489 } else { | |
45490 nonHoleEdges.push(e); | |
45491 } | |
45492 } | |
45493 | |
45494 for (var i = 0; i < holeEdges.length; i++) { | |
45495 var e = holeEdges[i]; | |
45496 if (hole[i].leftFace == null) { | |
45497 hole[i].leftFace = e.leftFace; | |
45498 hole[i].leftFace.replace(e, hole[i]); | |
45499 if (arrayIndex(newFacets, hole[i].leftFace) == -1) { | |
45500 newFacets.push(hole[i].leftFace); | |
45501 } | |
45502 } | |
45503 if (hole[i].rightFace == null) { | |
45504 hole[i].rightFace = e.rightFace; | |
45505 hole[i].rightFace.replace(e, hole[i]); | |
45506 if (arrayIndex(newFacets, hole[i].rightFace) == -1) { | |
45507 newFacets.push(hole[i].rightFace); | |
45508 } | |
45509 } | |
45510 } | |
45511 | |
45512 for (var i = 0; i < nonHoleEdges.length; i++) { | |
45513 var e = nonHoleEdges[i]; | |
45514 if (!e.legal) { | |
45515 continue; | |
45516 } | |
45517 if (this.JordanTest(hullVertices, e)) { | |
45518 this.edges.push(e); | |
45519 if (arrayIndex(newFacets, e.rightFace) == -1) { | |
45520 newFacets.push(e.rightFace); | |
45521 } | |
45522 if (arrayIndex(newFacets, e.leftFace) == -1) { | |
45523 newFacets.push(e.leftFace); | |
45524 } | |
45525 } | |
45526 } | |
45527 | |
45528 for (var i in oldFacets ) { | |
45529 oldFacets[i].descendants = newFacets; | |
45530 } | |
45531 | |
45532 for (var i = 0; i < newFacets.length; i++) { | |
45533 var simplex = newFacets[i].interior(v); | |
45534 if (simplex == null) { | |
45535 continue; | |
45536 } else { | |
45537 this.addVertex(v, simplex); | |
45538 break; | |
45539 } | |
45540 } | |
45541 | |
45542 return v; | |
45543 | |
45544 } | |
45545 | |
45546 Clustering.prototype.JordanTest = function(pol, e) { | |
45547 var p = new Vertex((e.v0.x + e.v1.x) * 0.5, (e.v0.y + e.v1.y) * 0.5); | |
45548 var inside = false; | |
45549 var i, j = pol.length - 1; | |
45550 for ( i = 0; i < pol.length; j = i++) { | |
45551 var p1 = pol[i]; | |
45552 var p2 = pol[j]; | |
45553 if ((((p1.y <= p.y) && (p.y < p2.y)) || ((p2.y <= p.y) && (p.y < p1.y))) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) | |
45554 inside = !inside; | |
45555 } | |
45556 return inside; | |
45557 } | |
45558 | |
45559 Clustering.prototype.mergeForResolution = function(resolution, circleGap, circleOverlap) { | |
45560 this.deleteEdges = new BinaryHeap(function(e) { | |
45561 return e.weight; | |
45562 }); | |
45563 this.weightEdges(resolution, circleGap, circleOverlap); | |
45564 var index = 0; | |
45565 while (this.deleteEdges.size() > 0) { | |
45566 var e = this.deleteEdges.pop(); | |
45567 if (e.legal) { | |
45568 var l = this.edges.length; | |
45569 var newVertex = this.mergeVertices(e); | |
45570 newVertex.CalculateRadius(resolution); | |
45571 for (var k = l; k < this.edges.length; k++) { | |
45572 var eNew = this.edges[k]; | |
45573 if (eNew.legal) { | |
45574 if( circleGap != 0 ){ | |
45575 eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius + circleGap * resolution ); | |
45576 } | |
45577 else if( circleOverlap.overlap == 0 ){ | |
45578 eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius); | |
45579 } | |
45580 else { | |
45581 var r1 = eNew.v0.radius; | |
45582 var r2 = eNew.v1.radius; | |
45583 var r = eNew.length; | |
45584 if( r < r1 + r2 ){ | |
45585 if( circleOverlap.type == 'diameter' ){ | |
45586 var ol1 = (r2-(r-r1)) / r1 / 2; | |
45587 var ol2 = (r1-(r-r2)) / r2 / 2; | |
45588 var ol = Math.max(ol1,ol2); | |
45589 eNew.weight = circleOverlap.overlap / ol; | |
45590 } | |
45591 if( circleOverlap.type == 'area' ){ | |
45592 if( !(r+r1 < r2 || r+r2 < r1) ){ | |
45593 var A = r2*r2*Math.acos((r*r+r2*r2-r1*r1)/(2*r*r2))+r1*r1*Math.acos((r*r+r1*r1-r2*r2)/(2*r*r1))-1/2*Math.sqrt((-r+r1+r2)*(r-r1+r2)*(r+r1-r2)*(r+r1+r2)); | |
45594 var ol1 = A / (Math.PI*r1*r1); | |
45595 var ol2 = A / (Math.PI*r2*r2); | |
45596 var ol = Math.max(ol1,ol2); | |
45597 eNew.weight = circleOverlap.overlap / ol; | |
45598 } | |
45599 else { | |
45600 eNew.weight = 0; | |
45601 } | |
45602 } | |
45603 } | |
45604 } | |
45605 if (eNew.weight < 1) { | |
45606 this.deleteEdges.push(eNew); | |
45607 } | |
45608 } | |
45609 } | |
45610 } | |
45611 } | |
45612 } | |
45613 | |
45614 Clustering.prototype.weightEdges = function(resolution, circleGap, circleOverlap) { | |
45615 for (var i = 0; i < this.vertices.length; i++) { | |
45616 if (this.vertices[i].legal) { | |
45617 this.vertices[i].CalculateRadius(resolution); | |
45618 } | |
45619 } | |
45620 var newEdges = []; | |
45621 for (var i = 0; i < this.edges.length; i++) { | |
45622 var e = this.edges[i]; | |
45623 if (e.legal) { | |
45624 if (!e.v0.legal || !e.v1.legal) { | |
45625 e.weight = 1; | |
45626 } else { | |
45627 if( circleGap != 0 ){ | |
45628 e.weight = e.length / (e.v0.radius + e.v1.radius + circleGap * resolution ); | |
45629 } | |
45630 else if( circleOverlap.overlap == 0 ){ | |
45631 e.weight = e.length / (e.v0.radius + e.v1.radius); | |
45632 } | |
45633 else { | |
45634 var r1 = e.v0.radius; | |
45635 var r2 = e.v1.radius; | |
45636 var r = e.length; | |
45637 if( r < r1 + r2 ){ | |
45638 if( circleOverlap.type == 'diameter' ){ | |
45639 var ol1 = (r2-(r-r1)) / r1 / 2; | |
45640 var ol2 = (r1-(r-r2)) / r2 / 2; | |
45641 var ol = Math.max(ol1,ol2); | |
45642 e.weight = circleOverlap.overlap / ol; | |
45643 } | |
45644 if( circleOverlap.type == 'area' ){ | |
45645 if( !(r+r1 < r2 || r+r2 < r1) ){ | |
45646 var A = r2*r2*Math.acos((r*r+r2*r2-r1*r1)/(2*r*r2))+r1*r1*Math.acos((r*r+r1*r1-r2*r2)/(2*r*r1))-1/2*Math.sqrt((-r+r1+r2)*(r-r1+r2)*(r+r1-r2)*(r+r1+r2)); | |
45647 var ol1 = A / (Math.PI*r1*r1); | |
45648 var ol2 = A / (Math.PI*r2*r2); | |
45649 var ol = Math.max(ol1,ol2); | |
45650 e.weight = circleOverlap.overlap / ol; | |
45651 } | |
45652 else { | |
45653 e.weight = 0; | |
45654 } | |
45655 } | |
45656 } | |
45657 } | |
45658 if (e.weight < 1) { | |
45659 this.deleteEdges.push(e); | |
45660 } | |
45661 } | |
45662 newEdges.push(e); | |
45663 } | |
45664 } | |
45665 this.edges = newEdges; | |
45666 } | |
45667 | |
45668 Clustering.prototype.ValidityTest = function() { | |
45669 console.info("Test 1: Valid Delaunay ..."); | |
45670 /* | |
45671 var leafs = []; | |
45672 var triangles = this.boundingTriangle.descendants; | |
45673 var j = 0; | |
45674 while( triangles.length > j ){ | |
45675 var t = triangles[j]; | |
45676 if( t.taken == undefined ){ | |
45677 t.taken = true; | |
45678 if( this.isLeaf(t) ){ | |
45679 leafs.push(t); | |
45680 } | |
45681 else { | |
45682 triangles = triangles.concat(t.descendants); | |
45683 } | |
45684 } | |
45685 j++; | |
45686 } | |
45687 console.info(" Number of Triangles: "+leafs.length); | |
45688 | |
45689 var c = 0; | |
45690 for( i in this.edges ){ | |
45691 if( this.edges[i].legal ){ | |
45692 c++; | |
45693 } | |
45694 } | |
45695 console.info(" Number of Edges: "+c);*/ | |
45696 /* | |
45697 | |
45698 for( var i=0; i<leafs.length; i++ ){ | |
45699 for( var j=0; j<vertices.length; j++ ){ | |
45700 if( !leafs[i].contains(vertices[j]) && leafs[i].inCircumcircle(vertices[j]) ){ | |
45701 console.info(leafs[i],vertices[j]); | |
45702 | |
45703 } | |
45704 } | |
45705 } | |
45706 */ | |
45707 | |
45708 //console.info("Test 2: Edges Facets (null) ..."); | |
45709 for (i in this.edges ) { | |
45710 var e = this.edges[i]; | |
45711 if (e.leftFace == null || e.rightFace == null) { | |
45712 console.info(e); | |
45713 alert(); | |
45714 } | |
45715 } | |
45716 | |
45717 //console.info("Test 3: Edges Facets ..."); | |
45718 var leftOf = function(v1, v2, v) { | |
45719 var x2 = v1.x - v2.x; | |
45720 var x3 = v1.x - v.x; | |
45721 var y2 = v1.y - v2.y; | |
45722 var y3 = v1.y - v.y; | |
45723 if (x2 * y3 - y2 * x3 < 0) { | |
45724 return true; | |
45725 } | |
45726 return false; | |
45727 } | |
45728 var c = 0; | |
45729 for (i in this.edges ) { | |
45730 var e = this.edges[i]; | |
45731 var t1 = e.leftFace.getTriple(e); | |
45732 var t2 = e.rightFace.getTriple(e); | |
45733 if (e.v0.y == e.v1.y) { | |
45734 if (t1.u.y > t2.u.y) { | |
45735 console.info("equal y conflict ..."); | |
45736 console.info(e); | |
45737 alert(); | |
45738 c++; | |
45739 } | |
45740 } else { | |
45741 var v1, v2; | |
45742 if (e.v0.y > e.v1.y) { | |
45743 v1 = e.v0; | |
45744 v2 = e.v1; | |
45745 } else { | |
45746 v1 = e.v1; | |
45747 v2 = e.v0; | |
45748 } | |
45749 if (!leftOf(v1, v2, t1.u)) { | |
45750 console.info("left right conflict ... left is right"); | |
45751 console.info(e); | |
45752 alert(); | |
45753 c++; | |
45754 } | |
45755 if (leftOf(v1, v2, t2.u)) { | |
45756 console.info("left right conflict ... right is left"); | |
45757 console.info(e); | |
45758 alert(); | |
45759 c++; | |
45760 } | |
45761 } | |
45762 } | |
45763 //console.info("Number of Edges: "+this.edges.length); | |
45764 //console.info("Number of Conflicts: "+c); | |
45765 | |
45766 for (i in this.edges ) { | |
45767 if (this.edges[i].legal) { | |
45768 var e = this.edges[i]; | |
45769 var tr0 = e.leftFace.getTriple(e); | |
45770 var tr1 = e.rightFace.getTriple(e); | |
45771 if (!tr0.e_p.legal || !tr0.e_s.legal || !tr1.e_p.legal || !tr1.e_s.legal) { | |
45772 console.info(e); | |
45773 console.info("conflict in edge continuity"); | |
45774 return; | |
45775 } | |
45776 } | |
45777 } | |
45778 | |
45779 } | |
45780 function BinaryHeap(scoreFunction) { | |
45781 this.content = []; | |
45782 this.scoreFunction = scoreFunction; | |
45783 } | |
45784 | |
45785 BinaryHeap.prototype = { | |
45786 push : function(element) { | |
45787 // Add the new element to the end of the array. | |
45788 this.content.push(element); | |
45789 // Allow it to bubble up. | |
45790 this.bubbleUp(this.content.length - 1); | |
45791 }, | |
45792 | |
45793 pop : function() { | |
45794 // Store the first element so we can return it later. | |
45795 var result = this.content[0]; | |
45796 // Get the element at the end of the array. | |
45797 var end = this.content.pop(); | |
45798 // If there are any elements left, put the end element at the | |
45799 // start, and let it sink down. | |
45800 if (this.content.length > 0) { | |
45801 this.content[0] = end; | |
45802 this.sinkDown(0); | |
45803 } | |
45804 return result; | |
45805 }, | |
45806 | |
45807 remove : function(node) { | |
45808 var len = this.content.length; | |
45809 // To remove a value, we must search through the array to find | |
45810 // it. | |
45811 for (var i = 0; i < len; i++) { | |
45812 if (this.content[i] == node) { | |
45813 // When it is found, the process seen in 'pop' is repeated | |
45814 // to fill up the hole. | |
45815 var end = this.content.pop(); | |
45816 if (i != len - 1) { | |
45817 this.content[i] = end; | |
45818 if (this.scoreFunction(end) < this.scoreFunction(node)) | |
45819 this.bubbleUp(i); | |
45820 else | |
45821 this.sinkDown(i); | |
45822 } | |
45823 return; | |
45824 } | |
45825 } | |
45826 throw new Error("Node not found."); | |
45827 }, | |
45828 | |
45829 size : function() { | |
45830 return this.content.length; | |
45831 }, | |
45832 | |
45833 bubbleUp : function(n) { | |
45834 // Fetch the element that has to be moved. | |
45835 var element = this.content[n]; | |
45836 // When at 0, an element can not go up any further. | |
45837 while (n > 0) { | |
45838 // Compute the parent element's index, and fetch it. | |
45839 var parentN = Math.floor((n + 1) / 2) - 1, parent = this.content[parentN]; | |
45840 // Swap the elements if the parent is greater. | |
45841 if (this.scoreFunction(element) < this.scoreFunction(parent)) { | |
45842 this.content[parentN] = element; | |
45843 this.content[n] = parent; | |
45844 // Update 'n' to continue at the new position. | |
45845 n = parentN; | |
45846 | |
45847 } | |
45848 // Found a parent that is less, no need to move it further. | |
45849 else { | |
45850 break; | |
45851 } | |
45852 } | |
45853 }, | |
45854 | |
45855 sinkDown : function(n) { | |
45856 // Look up the target element and its score. | |
45857 var length = this.content.length, element = this.content[n], elemScore = this.scoreFunction(element); | |
45858 | |
45859 while (true) { | |
45860 // Compute the indices of the child elements. | |
45861 var child2N = (n + 1) * 2, child1N = child2N - 1; | |
45862 // This is used to store the new position of the element, | |
45863 // if any. | |
45864 var swap = null; | |
45865 // If the first child exists (is inside the array)... | |
45866 if (child1N < length) { | |
45867 // Look it up and compute its score. | |
45868 var child1 = this.content[child1N], child1Score = this.scoreFunction(child1); | |
45869 // If the score is less than our element's, we need to swap. | |
45870 if (child1Score < elemScore) | |
45871 swap = child1N; | |
45872 } | |
45873 // Do the same checks for the other child. | |
45874 if (child2N < length) { | |
45875 var child2 = this.content[child2N], child2Score = this.scoreFunction(child2); | |
45876 if (child2Score < (swap == null ? elemScore : child1Score)) | |
45877 swap = child2N; | |
45878 } | |
45879 | |
45880 // If the element needs to be moved, swap it, and continue. | |
45881 if (swap != null) { | |
45882 this.content[n] = this.content[swap]; | |
45883 this.content[swap] = element; | |
45884 n = swap; | |
45885 } | |
45886 // Otherwise, we are done. | |
45887 else { | |
45888 break; | |
45889 } | |
45890 } | |
45891 } | |
45892 }; | |
45893 /* | |
45894 * Dropdown.js | |
45895 * | |
45896 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45897 * | |
45898 * This library is free software; you can redistribute it and/or | |
45899 * modify it under the terms of the GNU Lesser General Public | |
45900 * License as published by the Free Software Foundation; either | |
45901 * version 3 of the License, or (at your option) any later version. | |
45902 * | |
45903 * This library is distributed in the hope that it will be useful, | |
45904 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45905 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45906 * Lesser General Public License for more details. | |
45907 * | |
45908 * You should have received a copy of the GNU Lesser General Public | |
45909 * License along with this library; if not, write to the Free Software | |
45910 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45911 * MA 02110-1301 USA | |
45912 */ | |
45913 | |
45914 /** | |
45915 * @class Dropdown | |
45916 * Implementation for Dropdown box | |
45917 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45918 * @release 1.0 | |
45919 * @release date: 2012-07-27 | |
45920 * @version date: 2012-07-27 | |
45921 * | |
45922 * @param {HTML object} parent parent div for the dropdown box | |
45923 * @param {Array} elements list of dropdown entries | |
45924 * @param {String} title dropdown button title | |
45925 */ | |
45926 function Dropdown(parent, elements, title, maxListHeight) { | |
45927 | |
45928 var dropdown = this; | |
45929 this.visibility = false; | |
45930 this.div = document.createElement("div"); | |
45931 this.div.setAttribute('class', 'dropdown'); | |
45932 | |
45933 this.selection = document.createElement("div"); | |
45934 this.selection.setAttribute('class', 'dropdownSelection'); | |
45935 parent.appendChild(this.div); | |
45936 | |
45937 var leftBorder = document.createElement("div"); | |
45938 leftBorder.setAttribute('class', 'dropdownLeft'); | |
45939 this.div.appendChild(leftBorder); | |
45940 | |
45941 this.div.appendChild(this.selection); | |
45942 | |
45943 var dropdownButton = document.createElement("div"); | |
45944 this.div.appendChild(dropdownButton); | |
45945 if (elements.length > 1) { | |
45946 dropdownButton.setAttribute('class', 'dropdownButtonEnabled'); | |
45947 } else { | |
45948 dropdownButton.setAttribute('class', 'dropdownButtonDisabled'); | |
45949 } | |
45950 dropdownButton.onclick = function() { | |
45951 if (elements.length > 1) { | |
45952 dropdown.changeVisibility(); | |
45953 } | |
45954 } | |
45955 dropdownButton.title = title; | |
45956 | |
45957 this.getValue = function() { | |
45958 return this.selectedEntry.innerHTML; | |
45959 }; | |
45960 | |
45961 var entryMenu = document.createElement("div"); | |
45962 entryMenu.setAttribute('class', 'dropdownMenu'); | |
45963 this.div.appendChild(entryMenu); | |
45964 if (typeof maxListHeight !== "undefined") | |
45965 $(entryMenu).height(maxListHeight); | |
45966 | |
45967 var entries = document.createElement("dl"); | |
45968 var addEntry = function(e) { | |
45969 var entry = document.createElement("dt"); | |
45970 entry.setAttribute('class', 'dropdownUnselectedEntry'); | |
45971 entry.innerHTML = e.name; | |
45972 entry.onclick = function() { | |
45973 e.onclick(); | |
45974 dropdown.changeVisibility(); | |
45975 dropdown.changeEntries(e); | |
45976 } | |
45977 entries.appendChild(entry); | |
45978 e.entry = entry; | |
45979 } | |
45980 for (var i = 0; i < elements.length; i++) { | |
45981 addEntry(elements[i]); | |
45982 } | |
45983 entryMenu.appendChild(entries); | |
45984 this.selection.style.width = entryMenu.offsetWidth + "px"; | |
45985 entryMenu.style.width = (entryMenu.offsetWidth + leftBorder.offsetWidth + dropdownButton.offsetWidth - 2) + "px"; | |
45986 this.div.style.maxHeight = this.div.offsetHeight + "px"; | |
45987 | |
45988 entryMenu.style.display = 'none'; | |
45989 | |
45990 this.setEntry = function(index) { | |
45991 if ( typeof (index) == "undefined") { | |
45992 if ((elements) && elements.length > 0) { | |
45993 this.changeEntries(elements[0]); | |
45994 } | |
45995 } else { | |
45996 this.changeEntries(elements[index]); | |
45997 } | |
45998 } | |
45999 | |
46000 this.changeEntries = function(element) { | |
46001 if (this.selectedEntry) { | |
46002 this.selectedEntry.setAttribute('class', 'dropdownUnselectedEntry'); | |
46003 } | |
46004 this.selectedEntry = element.entry; | |
46005 this.selectedEntry.setAttribute('class', 'dropdownSelectedEntry'); | |
46006 this.selection.innerHTML = "<div style='display:inline-block;vertical-align:middle;'>" + element.name + "</div>"; | |
46007 } | |
46008 | |
46009 this.changeVisibility = function() { | |
46010 this.visibility = !this.visibility; | |
46011 if (this.visibility) { | |
46012 entryMenu.style.display = "block"; | |
46013 } else { | |
46014 entryMenu.style.display = "none"; | |
46015 } | |
46016 } | |
46017 } | |
46018 /* | |
46019 * MapZoomSlider.js | |
46020 * | |
46021 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
46022 * | |
46023 * This library is free software; you can redistribute it and/or | |
46024 * modify it under the terms of the GNU Lesser General Public | |
46025 * License as published by the Free Software Foundation; either | |
46026 * version 3 of the License, or (at your option) any later version. | |
46027 * | |
46028 * This library is distributed in the hope that it will be useful, | |
46029 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
46031 * Lesser General Public License for more details. | |
46032 * | |
46033 * You should have received a copy of the GNU Lesser General Public | |
46034 * License along with this library; if not, write to the Free Software | |
46035 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
46036 * MA 02110-1301 USA | |
46037 */ | |
46038 | |
46039 /** | |
46040 * @class MapZoomSlider | |
46041 * GeoTemCo style for map zoom control | |
46042 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
46043 * @release 1.0 | |
46044 * @release date: 2012-07-27 | |
46045 * @version date: 2012-07-27 | |
46046 */ | |
46047 function MapZoomSlider(parent, orientation) { | |
46048 | |
46049 this.parent = parent; | |
46050 | |
46051 var zs = this; | |
46052 this.div = document.createElement("div"); | |
46053 this.div.setAttribute('class', 'sliderStyle-' + orientation); | |
46054 | |
46055 var sliderContainer = document.createElement("div"); | |
46056 sliderContainer.setAttribute('class', 'zoomSliderContainer-' + orientation); | |
46057 var sliderDiv = document.createElement("div"); | |
46058 sliderDiv.tabIndex = 1; | |
46059 var sliderInputDiv = document.createElement("div"); | |
46060 sliderDiv.appendChild(sliderInputDiv); | |
46061 sliderContainer.appendChild(sliderDiv); | |
46062 this.slider = new Slider(sliderDiv, sliderInputDiv, orientation); | |
46063 this.div.appendChild(sliderContainer); | |
46064 | |
46065 var zoomIn = document.createElement("img"); | |
46066 zoomIn.src = GeoTemConfig.path + "zoom_in.png"; | |
46067 zoomIn.setAttribute('class', 'zoomSliderIn-' + orientation); | |
46068 zoomIn.onclick = function() { | |
46069 zs.parent.zoom(1); | |
46070 } | |
46071 this.div.appendChild(zoomIn); | |
46072 | |
46073 var zoomOut = document.createElement("img"); | |
46074 zoomOut.src = GeoTemConfig.path + "zoom_out.png"; | |
46075 zoomOut.setAttribute('class', 'zoomSliderOut-' + orientation); | |
46076 zoomOut.onclick = function() { | |
46077 zs.parent.zoom(-1); | |
46078 } | |
46079 this.div.appendChild(zoomOut); | |
46080 | |
46081 this.slider.onclick = function() { | |
46082 console.info(zs.slider.getValue()); | |
46083 } | |
46084 | |
46085 this.slider.handle.onmousedown = function() { | |
46086 var oldValue = zs.slider.getValue(); | |
46087 document.onmouseup = function() { | |
46088 if (!zs.parent.zoom((zs.slider.getValue() - oldValue) / zs.max * zs.levels)) { | |
46089 zs.setValue(oldValue); | |
46090 } | |
46091 document.onmouseup = null; | |
46092 } | |
46093 } | |
46094 | |
46095 this.setValue = function(value) { | |
46096 this.slider.setValue(value / this.levels * this.max); | |
46097 } | |
46098 | |
46099 this.setMaxAndLevels = function(max, levels) { | |
46100 this.max = max; | |
46101 this.levels = levels; | |
46102 this.slider.setMaximum(max); | |
46103 } | |
46104 // this.setMaxAndLevels(1000,parent.openlayersMap.getNumZoomLevels()); | |
46105 // this.setValue(parent.getZoom()); | |
46106 | |
46107 this.setLanguage = function() { | |
46108 zoomIn.title = GeoTemConfig.getString('zoomIn'); | |
46109 zoomOut.title = GeoTemConfig.getString('zoomOut'); | |
46110 this.slider.handle.title = GeoTemConfig.getString('zoomSlider'); | |
46111 } | |
46112 } | |
46113 /* | |
46114 * MapPopup.js | |
46115 * | |
46116 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
46117 * | |
46118 * This library is free software; you can redistribute it and/or | |
46119 * modify it under the terms of the GNU Lesser General Public | |
46120 * License as published by the Free Software Foundation; either | |
46121 * version 3 of the License, or (at your option) any later version. | |
46122 * | |
46123 * This library is distributed in the hope that it will be useful, | |
46124 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46125 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
46126 * Lesser General Public License for more details. | |
46127 * | |
46128 * You should have received a copy of the GNU Lesser General Public | |
46129 * License along with this library; if not, write to the Free Software | |
46130 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
46131 * MA 02110-1301 USA | |
46132 */ | |
46133 | |
46134 /** | |
46135 * @class MapPopup | |
46136 * map popup implementaion | |
46137 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
46138 * @release 1.0 | |
46139 * @release date: 2012-07-27 | |
46140 * @version date: 2012-07-27 | |
46141 */ | |
46142 function MapPopup(parent) { | |
46143 | |
46144 this.parentDiv = parent.gui.mapWindow; | |
46145 | |
46146 this.initialize = function(x, y, onclose) { | |
46147 | |
46148 var popup = this; | |
46149 this.x = x; | |
46150 this.y = y; | |
46151 | |
46152 this.popupDiv = document.createElement("div"); | |
46153 this.popupDiv.setAttribute('class', 'ddbPopupDiv'); | |
46154 this.parentDiv.appendChild(this.popupDiv); | |
46155 | |
46156 this.cancel = document.createElement("div"); | |
46157 this.cancel.setAttribute('class', 'ddbPopupCancel'); | |
46158 this.cancel.title = GeoTemConfig.getString('close'); | |
46159 this.cancel.onclick = function() { | |
46160 if ( typeof onclose != 'undefined') { | |
46161 onclose(); | |
46162 } | |
46163 popup.reset(); | |
46164 } | |
46165 | |
46166 this.input = document.createElement("div"); | |
46167 this.input.style.maxWidth = Math.floor(this.parentDiv.offsetWidth * 0.75) + "px"; | |
46168 this.input.style.maxHeight = Math.floor(this.parentDiv.offsetHeight * 0.75) + "px"; | |
46169 this.input.setAttribute('class', 'ddbPopupInput'); | |
46170 | |
46171 this.popupDiv.appendChild(this.input); | |
46172 this.popupDiv.appendChild(this.cancel); | |
46173 | |
46174 var peak = document.createElement("div"); | |
46175 peak.setAttribute('class', 'popupPeak'); | |
46176 this.popupDiv.appendChild(peak); | |
46177 var topRight = document.createElement("div"); | |
46178 topRight.setAttribute('class', 'popupTopRight'); | |
46179 this.popupDiv.appendChild(topRight); | |
46180 var bottomRight = document.createElement("div"); | |
46181 bottomRight.setAttribute('class', 'popupBottomRight'); | |
46182 this.popupDiv.appendChild(bottomRight); | |
46183 this.popupRight = document.createElement("div"); | |
46184 this.popupRight.setAttribute('class', 'popupRight'); | |
46185 this.popupDiv.appendChild(this.popupRight); | |
46186 this.popupBottom = document.createElement("div"); | |
46187 this.popupBottom.setAttribute('class', 'popupBottom'); | |
46188 this.popupDiv.appendChild(this.popupBottom); | |
46189 | |
46190 } | |
46191 | |
46192 this.setContent = function(content) { | |
46193 $(this.input).empty(); | |
46194 this.visible = true; | |
46195 $(this.input).append(content); | |
46196 this.decorate(); | |
46197 } | |
46198 | |
46199 this.reset = function() { | |
46200 $(this.popupDiv).remove(); | |
46201 this.visible = false; | |
46202 } | |
46203 | |
46204 this.decorate = function() { | |
46205 this.popupRight.style.height = (this.popupDiv.offsetHeight - 14) + "px"; | |
46206 this.popupBottom.style.width = (this.popupDiv.offsetWidth - 22) + "px"; | |
46207 this.left = this.x + 9; | |
46208 this.top = this.y - 10 - this.popupDiv.offsetHeight; | |
46209 this.popupDiv.style.left = this.left + "px"; | |
46210 this.popupDiv.style.top = this.top + "px"; | |
46211 var shiftX = 0, shiftY = 0; | |
46212 if (this.popupDiv.offsetTop < parent.gui.headerHeight + 10) { | |
46213 shiftY = -1 * (parent.gui.headerHeight + 10 - this.popupDiv.offsetTop); | |
46214 } | |
46215 if (this.popupDiv.offsetLeft + this.popupDiv.offsetWidth > parent.gui.headerWidth - 10) { | |
46216 shiftX = -1 * (parent.gui.headerWidth - 10 - this.popupDiv.offsetLeft - this.popupDiv.offsetWidth); | |
46217 } | |
46218 parent.shift(shiftX, shiftY); | |
46219 } | |
46220 | |
46221 this.shift = function(x, y) { | |
46222 this.left = this.left - this.x + x; | |
46223 this.top = this.top - this.y + y; | |
46224 this.x = x; | |
46225 this.y = y; | |
46226 if (this.left + this.popupDiv.offsetWidth > this.parentDiv.offsetWidth) { | |
46227 this.popupDiv.style.left = 'auto'; | |
46228 this.popupDiv.style.right = (this.parentDiv.offsetWidth - this.left - this.popupDiv.offsetWidth) + "px"; | |
46229 } else { | |
46230 this.popupDiv.style.right = 'auto'; | |
46231 this.popupDiv.style.left = this.left + "px"; | |
46232 } | |
46233 this.popupDiv.style.top = this.top + "px"; | |
46234 } | |
46235 } | |
46236 /* | |
46237 * PlacenamePopup.js | |
46238 * | |
46239 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
46240 * | |
46241 * This library is free software; you can redistribute it and/or | |
46242 * modify it under the terms of the GNU Lesser General Public | |
46243 * License as published by the Free Software Foundation; either | |
46244 * version 3 of the License, or (at your option) any later version. | |
46245 * | |
46246 * This library is distributed in the hope that it will be useful, | |
46247 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46248 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
46249 * Lesser General Public License for more details. | |
46250 * | |
46251 * You should have received a copy of the GNU Lesser General Public | |
46252 * License along with this library; if not, write to the Free Software | |
46253 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
46254 * MA 02110-1301 USA | |
46255 */ | |
46256 | |
46257 /** | |
46258 * @class PlacenamePopup | |
46259 * specific map popup for showing and interacting on placename labels | |
46260 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
46261 * @release 1.0 | |
46262 * @release date: 2012-07-27 | |
46263 * @version date: 2012-07-27 | |
46264 */ | |
46265 function PlacenamePopup(parent) { | |
46266 | |
46267 this.parentDiv = parent.gui.mapWindow; | |
46268 | |
46269 this.createPopup = function(x, y, labels) { | |
46270 this.labels = labels; | |
46271 var pnPopup = this; | |
46272 var popup = new MapPopup(parent); | |
46273 var onClose = function() { | |
46274 parent.deselection(); | |
46275 pnPopup.reset(); | |
46276 } | |
46277 popup.initialize(x, y, onClose); | |
46278 $.extend(this, popup); | |
46279 | |
46280 this.content = document.createElement("div"); | |
46281 this.inner = document.createElement("div"); | |
46282 | |
46283 this.resultsLabel = document.createElement("div"); | |
46284 this.resultsLabel.setAttribute('class', 'popupDDBResults'); | |
46285 this.content.appendChild(this.resultsLabel); | |
46286 this.backward = document.createElement("div"); | |
46287 this.backward.setAttribute('class', 'prevItem'); | |
46288 this.content.appendChild(this.backward); | |
46289 this.backward.onclick = function() { | |
46290 pnPopup.descriptionIndex--; | |
46291 pnPopup.showDescription(); | |
46292 } | |
46293 | |
46294 this.number = document.createElement("div"); | |
46295 this.content.appendChild(this.number); | |
46296 this.number.style.display = 'none'; | |
46297 this.number.style.fontSize = '13px'; | |
46298 | |
46299 this.forward = document.createElement("div"); | |
46300 this.forward.setAttribute('class', 'nextItem'); | |
46301 this.content.appendChild(this.forward); | |
46302 this.forward.onclick = function() { | |
46303 pnPopup.descriptionIndex++; | |
46304 pnPopup.showDescription(); | |
46305 } | |
46306 if (parent.options.showDescriptions) { | |
46307 this.descriptions = document.createElement("div"); | |
46308 this.descriptions.setAttribute('class', 'descriptions'); | |
46309 this.descriptions.onclick = function() { | |
46310 pnPopup.switchToDescriptionMode(); | |
46311 } | |
46312 } | |
46313 | |
46314 this.back = document.createElement("div"); | |
46315 this.back.setAttribute('class', 'back'); | |
46316 this.popupDiv.appendChild(this.back); | |
46317 this.back.onclick = function() { | |
46318 pnPopup.back.style.display = "none"; | |
46319 pnPopup.backward.style.display = "none"; | |
46320 pnPopup.forward.style.display = "none"; | |
46321 pnPopup.number.style.display = 'none'; | |
46322 pnPopup.showLabels(); | |
46323 } | |
46324 | |
46325 this.content.appendChild(this.inner); | |
46326 this.listLabels(); | |
46327 this.showLabels(); | |
46328 | |
46329 }; | |
46330 | |
46331 this.switchToDescriptionMode = function() { | |
46332 this.descriptionIndex = 0; | |
46333 this.descriptionContents = this.activeLabel.descriptions; | |
46334 this.number.style.display = 'inline-block'; | |
46335 this.inner.style.minWidth = "300px"; | |
46336 this.showDescription(); | |
46337 this.count = this.activeLabel.weight; | |
46338 this.setCount(); | |
46339 this.back.style.display = "inline-block"; | |
46340 } | |
46341 | |
46342 this.showDescription = function() { | |
46343 $(this.inner).empty(); | |
46344 this.inner.appendChild(this.descriptionContents[this.descriptionIndex]); | |
46345 this.setContent(this.content); | |
46346 if (this.descriptionContents.length == 1) { | |
46347 this.backward.style.display = "none"; | |
46348 this.forward.style.display = "none"; | |
46349 } else { | |
46350 if (this.descriptionIndex == 0) { | |
46351 this.backward.style.display = "none"; | |
46352 } else { | |
46353 this.backward.style.display = "inline-block"; | |
46354 } | |
46355 if (this.descriptionIndex == this.descriptionContents.length - 1) { | |
46356 this.forward.style.display = "none"; | |
46357 } else { | |
46358 this.forward.style.display = "inline-block"; | |
46359 } | |
46360 } | |
46361 if (this.descriptionContents.length > 1) { | |
46362 this.number.innerHTML = "#" + (this.descriptionIndex + 1); | |
46363 } else { | |
46364 this.number.style.display = 'none'; | |
46365 } | |
46366 this.decorate(); | |
46367 } | |
46368 | |
46369 this.setCount = function() { | |
46370 var c = this.count; | |
46371 if (c > 1) { | |
46372 this.resultsLabel.innerHTML = c + " " + GeoTemConfig.getString('results'); | |
46373 } else { | |
46374 this.resultsLabel.innerHTML = c + " " + GeoTemConfig.getString('result'); | |
46375 } | |
46376 } | |
46377 | |
46378 this.listLabels = function() { | |
46379 var pnPopup = this; | |
46380 this.labelDivs = []; | |
46381 this.labelCount = 0; | |
46382 this.labelsWidth = 0; | |
46383 for (var i = 0; i < this.labels.length; i++) { | |
46384 var div = document.createElement("div"); | |
46385 var content = document.createElement("div"); | |
46386 this.labels[i].allStyle += "position: relative; white-space: nowrap;"; | |
46387 content.appendChild(this.labels[i].div); | |
46388 content.setAttribute('class', 'ddbPopupLabel'); | |
46389 div.appendChild(content); | |
46390 this.labels[i].div.setAttribute('style', this.labels[i].allStyle + "" + this.labels[i].selectedStyle); | |
46391 this.input.appendChild(div); | |
46392 if (this.input.offsetWidth > this.labelsWidth) { | |
46393 this.labelsWidth = this.input.offsetWidth; | |
46394 } | |
46395 this.labels[i].div.setAttribute('style', this.labels[i].allStyle + "" + this.labels[i].unselectedStyle); | |
46396 this.labelDivs.push(div); | |
46397 var descriptions = []; | |
46398 for (var j = 0; j < this.labels[i].elements.length; j++) { | |
46399 var div = document.createElement("div"); | |
46400 div.innerHTML = this.labels[i].elements[j].description; | |
46401 descriptions.push(div); | |
46402 } | |
46403 this.labels[i].descriptions = descriptions; | |
46404 if (this.labels[i].place != "all" || i == 0) { | |
46405 this.labelCount += this.labels[i].weight; | |
46406 } | |
46407 } | |
46408 if ( typeof this.descriptions != 'undefined') { | |
46409 this.labelsWidth += 20; | |
46410 } | |
46411 } | |
46412 | |
46413 this.showLabels = function() { | |
46414 $(this.inner).empty(); | |
46415 this.count = this.labelCount; | |
46416 this.setCount(); | |
46417 for (var i = 0; i < this.labelDivs.length; i++) { | |
46418 this.inner.appendChild(this.labelDivs[i]); | |
46419 } | |
46420 this.inner.style.width = this.labelsWidth + "px"; | |
46421 this.inner.style.minWidth = this.labelsWidth + "px"; | |
46422 this.setContent(this.content); | |
46423 this.decorate(); | |
46424 } | |
46425 | |
46426 this.showLabelContent = function(label) { | |
46427 for (var i = 0; i < this.labels.length; i++) { | |
46428 if (this.labels[i] == label) { | |
46429 this.activeLabel = this.labels[i]; | |
46430 if ( typeof this.descriptions != 'undefined') { | |
46431 this.labelDivs[i].appendChild(this.descriptions); | |
46432 } | |
46433 this.decorate(); | |
46434 break; | |
46435 } | |
46436 } | |
46437 } | |
46438 | |
46439 this.setLanguage = function(language) { | |
46440 this.language = language; | |
46441 if (this.visible) { | |
46442 this.updateTexts(); | |
46443 } | |
46444 } | |
46445 }; | |
46446 /* | |
46447 * Dropdown.js | |
46448 * | |
46449 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
46450 * | |
46451 * This library is free software; you can redistribute it and/or | |
46452 * modify it under the terms of the GNU Lesser General Public | |
46453 * License as published by the Free Software Foundation; either | |
46454 * version 3 of the License, or (at your option) any later version. | |
46455 * | |
46456 * This library is distributed in the hope that it will be useful, | |
46457 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46458 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
46459 * Lesser General Public License for more details. | |
46460 * | |
46461 * You should have received a copy of the GNU Lesser General Public | |
46462 * License along with this library; if not, write to the Free Software | |
46463 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
46464 * MA 02110-1301 USA | |
46465 */ | |
46466 | |
46467 /** | |
46468 * @class Publisher | |
46469 * Publish/Subscribe mechanism | |
46470 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
46471 * @release 1.0 | |
46472 * @release date: 2012-07-27 | |
46473 * @version date: 2012-07-27 | |
46474 */ | |
46475 if ( typeof Publisher == 'undefined') { | |
46476 | |
46477 Publisher = function() { | |
46478 | |
46479 var topics = []; | |
46480 | |
46481 this.Get = function(topic) { | |
46482 var value = topics[topic]; | |
46483 if (!value || !(value instanceof Array)) { | |
46484 value = topics[topic] = []; | |
46485 } | |
46486 return value; | |
46487 }; | |
46488 | |
46489 this.Publish = function(topic, data, publisher) { | |
46490 var subscribers = this.Get(topic); | |
46491 for (var i = 0; i < subscribers.length; i++) { | |
46492 if (publisher == null || subscribers[i].client != publisher) { | |
46493 subscribers[i].callback(data); | |
46494 } | |
46495 } | |
46496 }; | |
46497 | |
46498 this.Subscribe = function(topic, subscriber, callback) { | |
46499 var subscribers = this.Get(topic); | |
46500 subscribers.push({ | |
46501 client : subscriber, | |
46502 callback : callback | |
46503 }); | |
46504 }; | |
46505 | |
46506 this.Unsubscribe = function(topic, unsubscriber) { | |
46507 var subscribers = this.Get(topic); | |
46508 for (var i = 0; i < subscribers.length; i++) { | |
46509 if (subscribers[i].client == unsubscriber) { | |
46510 subscribers.splice(i, 1); | |
46511 return; | |
46512 } | |
46513 } | |
46514 }; | |
46515 | |
46516 return this; | |
46517 | |
46518 }(); | |
46519 | |
46520 } | |
46521 /* | |
46522 * WidgetWrapper.js | |
46523 * | |
46524 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
46525 * | |
46526 * This library is free software; you can redistribute it and/or | |
46527 * modify it under the terms of the GNU Lesser General Public | |
46528 * License as published by the Free Software Foundation; either | |
46529 * version 3 of the License, or (at your option) any later version. | |
46530 * | |
46531 * This library is distributed in the hope that it will be useful, | |
46532 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46533 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
46534 * Lesser General Public License for more details. | |
46535 * | |
46536 * You should have received a copy of the GNU Lesser General Public | |
46537 * License along with this library; if not, write to the Free Software | |
46538 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
46539 * MA 02110-1301 USA | |
46540 */ | |
46541 | |
46542 /** | |
46543 * @class WidgetWrapper | |
46544 * Interface-like implementation for widgets interaction to each other; aimed to be modified for dynamic data sources | |
46545 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
46546 * @release 1.0 | |
46547 * @release date: 2012-07-27 | |
46548 * @version date: 2012-07-27 | |
46549 * | |
46550 * @param {Object} widget either a map, time or table widget | |
46551 */ | |
46552 WidgetWrapper = function() { | |
46553 | |
46554 var wrapper = this; | |
46555 | |
46556 this.setWidget = function(widget) { | |
46557 this.widget = widget; | |
46558 } | |
46559 | |
46560 this.display = function(data) { | |
46561 if ( data instanceof Array) { | |
46562 GeoTemConfig.datasets = data; | |
46563 if ( typeof wrapper.widget != 'undefined') { | |
46564 this.widget.initWidget(data); | |
46565 } | |
46566 } | |
46567 }; | |
46568 | |
46569 Publisher.Subscribe('highlight', this, function(data) { | |
46570 if (data == undefined) { | |
46571 return; | |
46572 } | |
46573 if ( typeof wrapper.widget != 'undefined') { | |
46574 wrapper.widget.highlightChanged(data); | |
46575 } | |
46576 }); | |
46577 | |
46578 Publisher.Subscribe('selection', this, function(data) { | |
46579 if ( typeof wrapper.widget != 'undefined') { | |
46580 wrapper.widget.selectionChanged(data); | |
46581 } | |
46582 }); | |
46583 | |
46584 Publisher.Subscribe('filterData', this, function(data) { | |
46585 wrapper.display(data); | |
46586 }); | |
46587 | |
46588 Publisher.Subscribe('rise', this, function(id) { | |
46589 if ( typeof wrapper.widget != 'undefined' && typeof wrapper.widget.riseLayer != 'undefined') { | |
46590 wrapper.widget.riseLayer(id); | |
46591 } | |
46592 }); | |
46593 | |
46594 Publisher.Subscribe('resizeWidget', this, function() { | |
46595 if ( typeof wrapper.widget != 'undefined' && typeof wrapper.widget.gui != 'undefined' && typeof wrapper.widget.gui.resize != 'undefined' ) { | |
46596 wrapper.widget.gui.resize(); | |
46597 } | |
46598 }); | |
46599 | |
46600 this.triggerRefining = function(datasets) { | |
46601 Publisher.Publish('filterData', datasets, null); | |
46602 }; | |
46603 | |
46604 this.triggerSelection = function(selectedObjects) { | |
46605 Publisher.Publish('selection', selectedObjects, this); | |
46606 }; | |
46607 | |
46608 this.triggerHighlight = function(highlightedObjects) { | |
46609 Publisher.Publish('highlight', highlightedObjects, this); | |
46610 }; | |
46611 | |
46612 this.triggerRise = function(id) { | |
46613 Publisher.Publish('rise', id); | |
46614 }; | |
46615 | |
46616 }; | |
46617 /* | |
46618 * final.js | |
46619 * | |
46620 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
46621 * | |
46622 * This library is free software; you can redistribute it and/or | |
46623 * modify it under the terms of the GNU Lesser General Public | |
46624 * License as published by the Free Software Foundation; either | |
46625 * version 3 of the License, or (at your option) any later version. | |
46626 * | |
46627 * This library is distributed in the hope that it will be useful, | |
46628 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
46629 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
46630 * Lesser General Public License for more details. | |
46631 * | |
46632 * You should have received a copy of the GNU Lesser General Public | |
46633 * License along with this library; if not, write to the Free Software | |
46634 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
46635 * MA 02110-1301 USA | |
46636 */ | |
46637 | |
46638 /** | |
46639 * code which is included after all other sources have been included for the minified version | |
46640 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
46641 * @release 1.0 | |
46642 * @release date: 2012-07-27 | |
46643 * @version date: 2012-07-27 | |
46644 */ | |
46645 | |
46646 OpenLayers.Util.getImagesLocation = function() { | |
46647 return GeoTemCoMinifier_urlPrefix + "lib/openlayers/img/"; | |
46648 }; | |
46649 | |
46650 OpenLayers._getScriptLocation = function() { | |
46651 return GeoTemCoMinifier_urlPrefix + "lib/openlayers/"; | |
46652 }; | |
46653 | |
46654 GeoTemConfig.configure(GeoTemCoMinifier_urlPrefix); | |
46655 })(jQuery); |