Mercurial > hg > mpiwg_geobrowser
comparison lib/GeoTemCo/platin.js~ @ 0:b57c7821382f
initial
author | Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de> |
---|---|
date | Thu, 28 May 2015 10:28:12 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:b57c7821382f |
---|---|
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-2012 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.12",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){for(var a=a.split("-"),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),f=f[g[h]];"function"== | |
1728 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){return OpenLayers.String.isNumeric(a)?parseFloat(a):a}}; | |
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}};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(){}}; | |
1731 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!= | |
1732 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+ | |
1733 ","+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())}, | |
1734 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+ | |
1735 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){var b=null;if(a){switch(a.CLASS_NAME){case "OpenLayers.LonLat":b=new OpenLayers.Bounds(a.lon,a.lat,a.lon,a.lat);break;case "OpenLayers.Geometry.Point":b=new OpenLayers.Bounds(a.x,a.y,a.x,a.y);break;case "OpenLayers.Bounds":b=a}if(b){this.centerLonLat=null;if(null==this.left||b.left<this.left)this.left= | |
1736 b.left;if(null==this.bottom||b.bottom<this.bottom)this.bottom=b.bottom;if(null==this.right||b.right>this.right)this.right=b.right;if(null==this.top||b.top>this.top)this.top=b.top}}},containsLonLat:function(a,b){"boolean"===typeof b&&(b={inclusive:b});var b=b||{},c=this.contains(a.lon,a.lat,b.inclusive),d=b.worldBounds;d&&!c&&(c=d.getWidth(),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, | |
1737 a.y,b)},contains:function(a,b,c){null==c&&(c=!0);if(null==a||null==b)return!1;var a=OpenLayers.Util.toFloat(a),b=OpenLayers.Util.toFloat(b),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={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== | |
1738 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>=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, | |
1739 {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?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= | |
1740 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,d.y);this.right=Math.max(d.x,f.x);this.top=Math.max(e.y,f.y);return this},wrapDateLine:function(a,b){var b=b||{},c=b.leftTolerance||0,d=b.rightTolerance||0,e=this.clone();if(a){for(var f= | |
1741 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"});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])}; | |
1742 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)}, | |
1743 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){var a=OpenLayers.Util.getElement(a),c=null;if(a&&a.style){c=a.style[OpenLayers.String.camelize(b)]; | |
1744 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+ | |
1745 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"}); | |
1746 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"); | |
1747 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"}; | |
1748 (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"), | |
1749 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)};"undefined"===typeof window.$&&(window.$=OpenLayers.Util.getElement); | |
1750 OpenLayers.Util.removeItem=function(a,b){for(var c=a.length-1;c>=0;c--)a[c]==b&&a.splice(c,1);return a};OpenLayers.Util.indexOf=function(a,b){if(typeof a.indexOf=="function")return a.indexOf(b);for(var c=0,d=a.length;c<d;c++)if(a[c]==b)return c;return-1}; | |
1751 OpenLayers.Util.modifyDOMElement=function(a,b,c,d,e,f,g,h){if(b)a.id=b;if(c){a.style.left=c.x+"px";a.style.top=c.y+"px"}if(d){a.style.width=d.w+"px";a.style.height=d.h+"px"}if(e)a.style.position=e;if(f)a.style.border=f;if(g)a.style.overflow=g;if(parseFloat(h)>=0&&parseFloat(h)<1){a.style.filter="alpha(opacity="+h*100+")";a.style.opacity=h}else if(parseFloat(h)==1){a.style.filter="";a.style.opacity=""}}; | |
1752 OpenLayers.Util.createDiv=function(a,b,c,d,e,f,g,h){var i=document.createElement("div");if(d)i.style.backgroundImage="url("+d+")";a||(a=OpenLayers.Util.createUniqueID("OpenLayersDiv"));e||(e="absolute");OpenLayers.Util.modifyDOMElement(i,a,b,c,e,f,g,h);return i}; | |
1753 OpenLayers.Util.createImage=function(a,b,c,d,e,f,g,h){var i=document.createElement("img");a||(a=OpenLayers.Util.createUniqueID("OpenLayersDiv"));e||(e="relative");OpenLayers.Util.modifyDOMElement(i,a,b,c,e,f,null,g);if(h){i.style.display="none";b=function(){i.style.display="";OpenLayers.Event.stopObservingElement(i)};OpenLayers.Event.observe(i,"load",b);OpenLayers.Event.observe(i,"error",b)}i.style.alt=a;i.galleryImg="no";if(d)i.src=d;return i};OpenLayers.IMAGE_RELOAD_ATTEMPTS=0; | |
1754 OpenLayers.Util.alphaHackNeeded=null;OpenLayers.Util.alphaHack=function(){if(OpenLayers.Util.alphaHackNeeded==null){var a=navigator.appVersion.split("MSIE"),a=parseFloat(a[1]),b=false;try{b=!!document.body.filters}catch(c){}OpenLayers.Util.alphaHackNeeded=b&&a>=5.5&&a<7}return OpenLayers.Util.alphaHackNeeded}; | |
1755 OpenLayers.Util.modifyAlphaImageDiv=function(a,b,c,d,e,f,g,h,i){OpenLayers.Util.modifyDOMElement(a,b,c,d,f,null,null,i);b=a.childNodes[0];if(e)b.src=e;OpenLayers.Util.modifyDOMElement(b,a.id+"_innerImage",null,d,"relative",g);if(OpenLayers.Util.alphaHack()){if(a.style.display!="none")a.style.display="inline-block";h==null&&(h="scale");a.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+b.src+"', sizingMethod='"+h+"')";if(parseFloat(a.style.opacity)>=0&&parseFloat(a.style.opacity)< | |
1756 1)a.style.filter=a.style.filter+(" alpha(opacity="+a.style.opacity*100+")");b.style.filter="alpha(opacity=0)"}};OpenLayers.Util.createAlphaImageDiv=function(a,b,c,d,e,f,g,h,i){var j=OpenLayers.Util.createDiv(),i=OpenLayers.Util.createImage(null,null,null,null,null,null,null,i);i.className="olAlphaImg";j.appendChild(i);OpenLayers.Util.modifyAlphaImageDiv(j,a,b,c,d,e,f,g,h);return j};OpenLayers.Util.upperCaseObject=function(a){var b={},c;for(c in a)b[c.toUpperCase()]=a[c];return b}; | |
1757 OpenLayers.Util.applyDefaults=function(a,b){var a=a||{},c=typeof window.Event=="function"&&b instanceof window.Event,d;for(d in b)if(a[d]===void 0||!c&&b.hasOwnProperty&&b.hasOwnProperty(d)&&!a.hasOwnProperty(d))a[d]=b[d];if(!c&&b&&b.hasOwnProperty&&b.hasOwnProperty("toString")&&!a.hasOwnProperty("toString"))a.toString=b.toString;return a}; | |
1758 OpenLayers.Util.getParameterString=function(a){var b=[],c;for(c in a){var d=a[c];if(d!=null&&typeof d!="function"){if(typeof d=="object"&&d.constructor==Array){for(var e=[],f,g=0,h=d.length;g<h;g++){f=d[g];e.push(encodeURIComponent(f===null||f===void 0?"":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}; | |
1759 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}; | |
1760 OpenLayers.Util.getXmlNodeValue=function(a){var b=null;OpenLayers.Util.Try(function(){b=a.text;if(!b)b=a.textContent;if(!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&&c!=null;)c=c.parentNode;return c!=b};OpenLayers.Util.DEFAULT_PRECISION=14; | |
1761 OpenLayers.Util.toFloat=function(a,b){if(b==null)b=OpenLayers.Util.DEFAULT_PRECISION;typeof a!=="number"&&(a=parseFloat(a));return b===0?a:parseFloat(a.toPrecision(b))};OpenLayers.Util.rad=function(a){return a*Math.PI/180};OpenLayers.Util.deg=function(a){return a*180/Math.PI};OpenLayers.Util.VincentyConstants={a:6378137,b:6356752.3142,f:1/298.257223563}; | |
1762 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))),i=Math.sin(g),g=Math.cos(g),j=Math.sin(h),h=Math.cos(h),k=f,l=2*Math.PI,m=20;Math.abs(k-l)>1.0E-12&&--m>0;){var n=Math.sin(k),o=Math.cos(k),p=Math.sqrt(h*n*h*n+(g*j-i*h*o)*(g*j-i*h*o));if(p==0)return 0;var o=i*j+g*h*o,q=Math.atan2(p,o),r=Math.asin(g* | |
1763 h*n/p),s=Math.cos(r)*Math.cos(r),n=o-2*i*j/s,t=c/16*s*(4+c*(4-3*s)),l=k,k=f+(1-t)*c*Math.sin(r)*(q+t*p*(n+t*o*(-1+2*n*n)))}if(m==0)return NaN;d=s*(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))))*(q-c*p*(n+c/4*(o*(-1+2*n*n)-c/6*n*(-3+4*p*p)*(-3+4*n*n))))).toFixed(3)/1E3}; | |
1764 OpenLayers.Util.destinationVincenty=function(a,b,c){for(var d=OpenLayers.Util,e=d.VincentyConstants,f=e.a,g=e.b,h=e.f,e=a.lon,a=a.lat,i=d.rad(b),b=Math.sin(i),i=Math.cos(i),a=(1-h)*Math.tan(d.rad(a)),j=1/Math.sqrt(1+a*a),k=a*j,l=Math.atan2(a,i),a=j*b,m=1-a*a,f=m*(f*f-g*g)/(g*g),n=1+f/16384*(4096+f*(-768+f*(320-175*f))),o=f/1024*(256+f*(-128+f*(74-47*f))),f=c/(g*n),p=2*Math.PI;Math.abs(f-p)>1.0E-12;)var q=Math.cos(2*l+f),r=Math.sin(f),s=Math.cos(f),t=o*r*(q+o/4*(s*(-1+2*q*q)-o/6*q*(-3+4*r*r)*(-3+4* | |
1765 q*q))),p=f,f=c/(g*n)+t;c=k*r-j*s*i;g=Math.atan2(k*s+j*r*i,(1-h)*Math.sqrt(a*a+c*c));b=Math.atan2(r*b,j*s-k*r*i);i=h/16*m*(4+h*(4-3*m));q=b-(1-i)*h*a*(f+i*r*(q+i*s*(-1+2*q*q)));Math.atan2(a,-c);return new OpenLayers.LonLat(e+d.deg(q),d.deg(g))}; | |
1766 OpenLayers.Util.getParameters=function(a){var a=a===null||a===void 0?window.location.href:a,b="";if(OpenLayers.String.contains(a,"?"))var b=a.indexOf("?")+1,c=OpenLayers.String.contains(a,"#")?a.indexOf("#"):a.length,b=a.substring(b,c);for(var a={},b=b.split(/[&;]/),c=0,d=b.length;c<d;++c){var e=b[c].split("=");if(e[0]){var f=e[0];try{f=decodeURIComponent(f)}catch(g){f=unescape(f)}e=(e[1]||"").replace(/\+/g," ");try{e=decodeURIComponent(e)}catch(h){e=unescape(e)}e=e.split(",");e.length==1&&(e=e[0]); | |
1767 a[f]=e}}return a};OpenLayers.Util.lastSeqID=0;OpenLayers.Util.createUniqueID=function(a){a==null&&(a="id_");OpenLayers.Util.lastSeqID=OpenLayers.Util.lastSeqID+1;return a+OpenLayers.Util.lastSeqID};OpenLayers.INCHES_PER_UNIT={inches:1,ft:12,mi:63360,m:39.3701,km:39370.1,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; | |
1768 OpenLayers.METERS_PER_INCH=0.0254000508001016; | |
1769 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, | |
1770 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/ | |
1771 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, | |
1772 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, | |
1773 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/ | |
1774 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}); | |
1775 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, | |
1776 "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 a>1?1/a:a};OpenLayers.Util.getResolutionFromScale=function(a,b){var c;if(a){b==null&&(b="degrees");c=1/(OpenLayers.Util.normalizeScale(a)*OpenLayers.INCHES_PER_UNIT[b]*OpenLayers.DOTS_PER_INCH)}return c}; | |
1777 OpenLayers.Util.getScaleFromResolution=function(a,b){b==null&&(b="degrees");return a*OpenLayers.INCHES_PER_UNIT[b]*OpenLayers.DOTS_PER_INCH}; | |
1778 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&&OpenLayers.Element.getStyle(a,"position")=="absolute"&&(a.style.top==""||a.style.left==""),e=null;if(a.getBoundingClientRect){a=a.getBoundingClientRect();e=c.scrollTop;b[0]=a.left+c.scrollLeft;b[1]=a.top+e}else if(document.getBoxObjectFor&&!d){a=document.getBoxObjectFor(a);c=document.getBoxObjectFor(c);b[0]=a.screenX-c.screenX; | |
1779 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]=b[0]+e.offsetLeft;b[1]=b[1]+e.offsetTop;e=e.offsetParent}c=OpenLayers.BROWSER_NAME;if(c=="opera"||c=="safari"&&OpenLayers.Element.getStyle(a,"position")=="absolute")b[1]=b[1]-document.body.offsetTop;for(e=a.offsetParent;e&&e!=document.body;){b[0]=b[0]-e.scrollLeft;if(c!="opera"||e.tagName!="TR")b[1]=b[1]-e.scrollTop;e=e.offsetParent}}return b}; | |
1780 OpenLayers.Util.getViewportElement=function(){var a=arguments.callee.viewportElement;if(a==void 0){a=OpenLayers.BROWSER_NAME=="msie"&&document.compatMode!="CSS1Compat"?document.body:document.documentElement;arguments.callee.viewportElement=a}return a}; | |
1781 OpenLayers.Util.isEquivalentUrl=function(a,b,c){c=c||{};OpenLayers.Util.applyDefaults(c,{ignoreCase:true,ignorePort80:true,ignoreHash:true});var a=OpenLayers.Util.createUrlObject(a,c),b=OpenLayers.Util.createUrlObject(b,c),d;for(d in a)if(d!=="args"&&a[d]!=b[d])return false;for(d in a.args){if(a.args[d]!=b.args[d])return false;delete b.args[d]}for(d in b.args)return false;return true}; | |
1782 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;if(a.indexOf("/")===0)a=d+a;else{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?c.port=="80"||c.port=="0"?"":c.port:c.port==""||c.port=="0"?"80":c.port;d.hash=b.ignoreHash|| | |
1783 c.hash==="#"?"":c.hash;var e=c.search;if(!e){e=a.indexOf("?");e=e!=-1?a.substr(e):""}d.args=OpenLayers.Util.getParameters(e);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=b==-1?c!=-1?a.substr(0,c):a:c!=-1?a.substr(0,Math.min(b,c)):a.substr(0,b)};OpenLayers.IS_GECKO=function(){var a=navigator.userAgent.toLowerCase();return a.indexOf("webkit")==-1&&a.indexOf("gecko")!=-1}(); | |
1784 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();b.indexOf("opera")!=-1?a="opera":b.indexOf("msie")!=-1?a="msie":b.indexOf("safari")!=-1?a="safari":b.indexOf("mozilla")!=-1&&(a=b.indexOf("firefox")!=-1?"firefox":"mozilla");return a}();OpenLayers.Util.getBrowserName=function(){return OpenLayers.BROWSER_NAME}; | |
1785 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=false,i=null,j=g;j&&j.tagName.toLowerCase()!="body";){var k=OpenLayers.Element.getStyle(j,"position");if(k=="absolute"){h=true;break}else if(k&&k!="static")break;j=j.parentNode}if(h&&(g.clientHeight===0||g.clientWidth===0)){i=document.createElement("div");i.style.visibility="hidden";i.style.position="absolute"; | |
1786 i.style.overflow="visible";i.style.width=document.body.clientWidth+"px";i.style.height=document.body.clientHeight+"px";i.appendChild(f)}f.style.position="absolute";if(b)if(b.w){d=b.w;f.style.width=d+"px"}else if(b.h){e=b.h;f.style.height=e+"px"}if(c&&c.displayClass)f.className=c.displayClass;b=document.createElement("div");b.innerHTML=a;b.style.overflow="visible";if(b.childNodes){a=0;for(c=b.childNodes.length;a<c;a++)if(b.childNodes[a].style)b.childNodes[a].style.overflow="visible"}f.appendChild(b); | |
1787 i?g.appendChild(i):g.appendChild(f);if(!d){d=parseInt(b.scrollWidth);f.style.width=d+"px"}e||(e=parseInt(b.scrollHeight));f.removeChild(b);if(i){i.removeChild(f);g.removeChild(i)}else g.removeChild(f);return new OpenLayers.Size(d,e)}; | |
1788 OpenLayers.Util.getScrollbarWidth=function(){var a=OpenLayers.Util._scrollbarWidth;if(a==null){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); | |
1789 OpenLayers.Util._scrollbarWidth=a-b;a=OpenLayers.Util._scrollbarWidth}return a}; | |
1790 OpenLayers.Util.getFormattedLonLat=function(a,b,c){c||(c="dms");var a=(a+540)%360-180,d=Math.abs(a),e=Math.floor(d),f=d=(d-e)/(1/60),d=Math.floor(d),f=Math.round((f-d)/(1/60)*10),f=f/10;if(f>=60){f=f-60;d=d+1;if(d>=60){d=d-60;e=e+1}}e<10&&(e="0"+e);e=e+"\u00b0";if(c.indexOf("dm")>=0){d<10&&(d="0"+d);e=e+(d+"'");if(c.indexOf("dms")>=0){f<10&&(f="0"+f);e=e+(f+'"')}}return e=b=="lon"?e+(a<0?OpenLayers.i18n("W"):OpenLayers.i18n("E")):e+(a<0?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(){throw Error("Read not implemented.");},write:function(){throw Error("Write not implemented.");},CLASS_NAME:"OpenLayers.Format"});OpenLayers.Format.CSWGetRecords=function(a){var a=OpenLayers.Util.applyDefaults(a,OpenLayers.Format.CSWGetRecords.DEFAULTS),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,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+ | |
1791 "_"))},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&& | |
1792 this.handler.setMap(a)},draw:function(a){if(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= | |
1793 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"), | |
1794 !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, | |
1795 b){b||(a.preventDefault?a.preventDefault():a.returnValue=!1);a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},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;if("keypress"==b&&(navigator.appVersion.match(/Konqueror|Safari|KHTML/)||a.attachEvent))b="keydown";this.observers||(this.observers={});if(!a._eventCacheID){var e= | |
1796 "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])},_removeElementObservers:function(a){if(a)for(var b=a.length-1;0<= | |
1797 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){var d=d||!1,a=OpenLayers.Util.getElement(a),e=a._eventCacheID;if("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 i=g[h];if(i.name==b&&i.observer==c&&i.useCapture==d){g.splice(h,1);0==g.length&&delete OpenLayers.Event.observers[e];f=!0; | |
1798 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"};OpenLayers.Event.observe(window,"unload",OpenLayers.Event.unloadCache,!1); | |
1799 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= | |
1800 {};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(){},attachToElement:function(a){this.element?OpenLayers.Event.stopObservingElement(this.element): | |
1801 (this.eventHandler=OpenLayers.Function.bindAsEventListener(this.handleBrowserEvent,this),this.clearMouseListener=OpenLayers.Function.bind(this.clearMouseCache,this));this.element=a;for(var b=0,c=this.BROWSER_EVENTS.length;b<c;b++)OpenLayers.Event.observe(a,this.BROWSER_EVENTS[b],this.eventHandler);OpenLayers.Event.observe(a,"dragstart",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&& | |
1802 !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,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== | |
1803 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=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}}, | |
1804 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=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)}},clearMouseCache:function(){this.element.scrolls=null;this.element.lefttop=null;var a=document.body;if(a&&(!(0!=a.scrollTop||0!=a.scrollLeft)||!navigator.userAgent.match(/iPhone/i)))this.element.offsets=null},getMousePosition:function(a){this.includeXY? | |
1805 this.element.hasScrollEvent||(OpenLayers.Event.observe(window,"scroll",this.clearMouseListener),this.element.hasScrollEvent=!0):this.clearMouseCache();if(!this.element.scrolls){var b=OpenLayers.Util.getViewportElement();this.element.scrolls=[b.scrollLeft,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+ | |
1806 this.element.scrolls[0]-this.element.offsets[0]-this.element.lefttop[0],a.clientY+this.element.scrolls[1]-this.element.offsets[1]-this.element.lefttop[1])},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); | |
1807 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},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",{buttonElement:c}),OpenLayers.Event.stop(a), | |
1808 b=!1}else this.startEvt&&(this.completeRegEx.test(a.type)&&(b=OpenLayers.Util.pagePosition(c),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)&&(this.startEvt=a,OpenLayers.Event.stop(a),b=!1)}else delete this.startEvt;return b}});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,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(),this.handlers.drag&&this.handlers.drag.destroy(), | |
1809 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),this.minimizeDiv=null),this.map.events.un({buttonclick:this.onButtonClick, | |
1810 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=this.displayClass+"Element";this.element.style.display="none"; | |
1811 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+"ExtentRectangle";this.element.appendChild(this.mapDiv); | |
1812 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.div.appendChild(this.maximizeDiv);a=OpenLayers.Util.getImageLocation("layer-switcher-minimize.png"); | |
1813 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.div.appendChild(this.minimizeDiv);this.minimizeControl()}this.map.getExtent()&&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", | |
1814 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()),f=this.rectPxBounds.getWidth(),c=Math.max(0,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(), | |
1815 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,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= | |
1816 "";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.style.display=a?"":"none";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.maxExtent, | |
1817 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()));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? | |
1818 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,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); | |
1819 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,"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")))? | |
1820 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},{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(){!this.handlers.drag.active&&!this.map.dragging&&this.handlers.drag.activate()}); | |
1821 this.rectEvents.register("mouseout",this,function(){this.handlers.drag.dragging||this.handlers.drag.deactivate()});if(this.ovmap.getProjection()!=this.map.getProjection()){var a=this.map.getProjectionObject().getUnits()||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=this.getRectBoundsFromMapBounds(this.ovmap.getProjection()!= | |
1822 this.map.getProjection()?this.map.getExtent().transform(this.map.getProjectionObject(),this.ovmap.getProjectionObject()):this.map.getExtent());a&&this.setRectPxBounds(a)},updateMapToRect:function(){var a=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= | |
1823 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),e=Math.max(a-c,0),f=Math.max(d-b,0);e<this.minRectSize||f<this.minRectSize?(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= | |
1824 this.minRectSize+"px"):(this.extentRectangle.className=this.displayClass+"ExtentRectangle",this.extentRectangle.style.top=Math.round(b)+"px",this.extentRectangle.style.left=Math.round(c)+"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, | |
1825 lat:a.top}),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,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= | |
1826 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.Animation=function(a){var b=!(!a.requestAnimationFrame&&!a.webkitRequestAnimationFrame&&!a.mozRequestAnimationFrame&&!a.oRequestAnimationFrame&&!a.msRequestAnimationFrame),c=function(){var b=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(b){a.setTimeout(b,16)};return function(c,d){b.apply(a,[c,d])}}(),d=0,e={};return{isNative:b,requestFrame:c,start:function(a,b,h){var b=0<b?b:Number.POSITIVE_INFINITY, | |
1827 i=++d,j=+new Date;e[i]=function(){e[i]&&+new Date-j<=b?(a(),e[i]&&c(e[i],h)):delete e[i]};c(e[i],h);return i},stop:function(a){delete e[a]}}}(window);OpenLayers.Tween=OpenLayers.Class({easing:null,begin:null,finish:null,duration:null,callbacks:null,time: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.time=0;OpenLayers.Animation.stop(this.animationId);this.animationId=null;this.callbacks&&this.callbacks.start&&this.callbacks.start.call(this,this.begin);this.animationId=OpenLayers.Animation.start(OpenLayers.Function.bind(this.play, | |
1828 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");a[b]=this.easing.apply(this,[this.time,c,d-c,this.duration])}this.time++;this.callbacks&&this.callbacks.eachStep&&this.callbacks.eachStep.call(this, | |
1829 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"}; | |
1830 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"}; | |
1831 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;window.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)),window.Proj4js&& | |
1832 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={}; | |
1833 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]}}; | |
1834 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}; | |
1835 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{var b=b.getCode(),c=c.getCode(),d=OpenLayers.Projection.transforms;if(d[b]&&d[b][c])d[b][c](a)}return a};OpenLayers.Projection.nullTransform=function(a){return a}; | |
1836 (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;a.y=Math.log(Math.tan((90+a.y)*Math.PI/360))/Math.PI*d;return a}function c(c,d){var e=OpenLayers.Projection.addTransform,f=OpenLayers.Projection.nullTransform,g,m,n,o,p;g=0;for(m=d.length;g<m;++g){n=d[g];e(c,n,b);e(n,c,a);for(p=g+1;p<m;++p)o=d[p],e(n,o,f),e(o,n,f)}}var d=2.003750834E7,e=["EPSG:900913","EPSG:3857","EPSG:102113","EPSG:102100"],f=["CRS:84","urn:ogc:def:crs:EPSG:6.6:4326", | |
1837 "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, | |
1838 maxExtent:null,minExtent:null,restrictedExtent:null,numZoomLevels:16,theme:null,displayProjection:null,fallThrough:!0,panTween:null,eventListeners:null,panMethod:OpenLayers.Easing.Expo.easeOut,panDuration:50,paddingForPopups: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,OpenLayers.Map.TILE_HEIGHT);this.paddingForPopups=new OpenLayers.Bounds(15,15,15,15);this.theme=OpenLayers._getScriptLocation()+ | |
1839 "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));this.minExtent&&!(this.minExtent instanceof OpenLayers.Bounds)&&(this.minExtent=new OpenLayers.Bounds(this.minExtent));this.restrictedExtent&& | |
1840 !(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"),this.div.style.height="1px",this.div.style.width="1px");OpenLayers.Element.addClass(this.div,"olMap");var c= | |
1841 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});c=this.id+"_OpenLayers_Container";this.layerContainerDiv=OpenLayers.Util.createDiv(c);this.layerContainerDiv.style.width="100px";this.layerContainerDiv.style.height= | |
1842 "100px";this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE.Popup-1;this.viewPortDiv.appendChild(this.layerContainerDiv);this.updateSize();if(this.eventListeners instanceof Object)this.events.on(this.eventListeners);9>parseFloat(navigator.appVersion.split("MSIE")[1])?this.events.register("resize",this,this.updateSize):(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"), | |
1843 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==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), | |
1844 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&&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, | |
1845 "unload",this.unloadDestroy);b&&b.layers&&(delete this.center,this.addLayers(b.layers),b.center&&!this.getCenter()&&this.setCenter(b.center,b.zoom))},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; | |
1846 this.panTween&&(this.panTween.stop(),this.panTween=null);OpenLayers.Event.stopObserving(window,"unload",this.unloadDestroy);this.unloadDestroy=null;this.updateSizeDestroy?OpenLayers.Event.stopObserving(window,"resize",this.updateSizeDestroy):this.events.unregister("resize",this,this.updateSize);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); | |
1847 this.layers=null}this.viewPortDiv&&this.div.removeChild(this.viewPortDiv);this.viewPortDiv=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"== | |
1848 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= | |
1849 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= | |
1850 "";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, | |
1851 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", | |
1852 {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): | |
1853 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), | |
1854 !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&& | |
1855 (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, | |
1856 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(); | |
1857 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))}}},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,a.h=this.div.offsetHeight; | |
1858 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&&this.size&&(this.center= | |
1859 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")))}}, | |
1860 panTo:function(a){if(this.panMethod&&this.getExtent().scale(this.panRatio).containsLonLat(a)){this.panTween||(this.panTween=new OpenLayers.Tween(this.panMethod));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(){this.moveTo(a); | |
1861 this.dragging=false;this.events.triggerEvent("moveend")},this)}})}}else this.setCenter(a)},setCenter:function(a,b,c,d){this.panTween&&this.panTween.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,i=0;this.restrictedExtent&&(h=c,i=d,g=!1);a=g||e<=this.maxPx.x-h&&e>=this.minPx.x+h?Math.round(a):0;b=f<=this.maxPx.y-i&&f>=this.minPx.y+i?Math.round(b):0;if(a||b){this.dragging||(this.dragging= | |
1862 !0,this.events.triggerEvent("movestart"));this.center=null;a&&(this.layerContainerDiv.style.left=parseInt(this.layerContainerDiv.style.left)-a+"px",this.minPx.x-=a,this.maxPx.x-=a);b&&(this.layerContainerDiv.style.top=parseInt(this.layerContainerDiv.style.top)-b+"px",this.minPx.y-=b,this.maxPx.y-=b);d=0;for(e=this.layers.length;d<e;++d)if(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){var b= | |
1863 this.baseLayer.resolutions,c=this.getMaxExtent().getWidth()/this.size.w;if(this.getResolutionForZoom(a)>c)for(var d=a|0,e=b.length;d<e;++d)if(b[d]<=c){a=d;break}return a},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)));if(this.baseLayer.wrapDateLine){var d=b,b=this.adjustZoom(b);b!==d&&(a=this.getCenter())}var d=c.dragging||this.dragging,e=c.forceZoomChange;!this.getCachedCenter()&& | |
1864 !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&& | |
1865 (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");f&&(!e&&this.center&&this.centerLayerContainer(a),this.center= | |
1866 a.clone());a=e?this.getResolutionForZoom(b):this.getResolution();if(e||null==this.layerContainerOrigin){this.layerContainerOrigin=this.getCachedCenter();this.layerContainerDiv.style.left="0px";this.layerContainerDiv.style.top="0px";var f=this.getMaxExtent({restricted:!0}),h=f.getCenterLonLat(),g=this.center.lon-h.lon,h=h.lat-this.center.lat,i=Math.round(f.getWidth()/a),j=Math.round(f.getHeight()/a);this.minPx={x:(this.size.w-i)/2-g/a,y:(this.size.h-j)/2-h/a};this.maxPx={x:this.minPx.x+Math.round(f.getWidth()/ | |
1867 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)if(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"})), | |
1868 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=parseInt(this.layerContainerDiv.style.left),a=parseInt(this.layerContainerDiv.style.top), | |
1869 e=Math.round(b.x-c.x),b=Math.round(b.y-c.y);this.layerContainerDiv.style.left=e+"px";this.layerContainerDiv.style.top=b+"px";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(): | |
1870 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= | |
1871 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, | |
1872 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){this.isValidZoomLevel(a)&&this.setCenter(null,a)},zoomIn:function(){this.zoomTo(this.getZoom()+1)},zoomOut:function(){this.zoomTo(this.getZoom()-1)},zoomToExtent:function(a, | |
1873 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))},zoomToMaxExtent:function(a){this.zoomToExtent(this.getMaxExtent({restricted:a?a.restricted:!0}))},zoomToScale:function(a,b){var c=OpenLayers.Util.getResolutionFromScale(a,this.baseLayer.units),d=this.size.w*c/2,c=this.size.h* | |
1874 c/2,e=this.getCachedCenter();this.zoomToExtent(new OpenLayers.Bounds(e.lon-d,e.lat-c,e.lon+d,e.lat+c),b)},getLonLatFromViewPortPx:function(a){var b=null;null!=this.baseLayer&&(b=this.baseLayer.getLonLatFromViewPortPx(a));return b},getViewPortPxFromLonLat:function(a){var b=null;null!=this.baseLayer&&(b=this.baseLayer.getViewPortPxFromLonLat(a));return b},getLonLatFromPixel:function(a){return this.getLonLatFromViewPortPx(a)},getPixelFromLonLat:function(a){a=this.getViewPortPxFromLonLat(a);a.x=Math.round(a.x); | |
1875 a.y=Math.round(a.y);return a},getGeodesicPixelSize:function(a){var b=a?this.getLonLatFromPixel(a):this.getCachedCenter()||new OpenLayers.LonLat(0,0),c=this.getResolution(),a=b.add(-c/2,0),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= | |
1876 null;if(null!=a)var b=parseInt(this.layerContainerDiv.style.left),c=parseInt(this.layerContainerDiv.style.top),b=a.add(b,c);return b},getLayerPxFromViewPortPx:function(a){var b=null;if(null!=a){var b=-parseInt(this.layerContainerDiv.style.left),c=-parseInt(this.layerContainerDiv.style.top),b=a.add(b,c);if(isNaN(b.x)||isNaN(b.y))b=null}return b},getLonLatFromLayerPx:function(a){a=this.getViewPortPxFromLayerPx(a);return this.getLonLatFromViewPortPx(a)},getLayerPxFromLonLat:function(a){return this.getLayerPxFromViewPortPx(this.getPixelFromLonLat(a))}, | |
1877 CLASS_NAME:"OpenLayers.Map"});OpenLayers.Map.TILE_WIDTH=256;OpenLayers.Map.TILE_HEIGHT=256;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, | |
1878 numZoomLevels:null,minScale:null,maxScale:null,displayOutsideMaxExtent:!1,wrapDateLine:!1,metadata:null,initialize:function(a,b){this.metadata={};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,this.div),this.eventListeners instanceof Object))this.events.on(this.eventListeners)}, | |
1879 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},getOptions:function(){var a={},b;for(b in this.options)a[b]=this[b];return a},setName:function(a){a!= | |
1880 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={});if(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 OpenLayers.Bounds)&&(a.maxExtent=new OpenLayers.Bounds(a.maxExtent)),a.minExtent&&!(a.minExtent instanceof | |
1881 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,e)){this.initResolutions();b&&this.map.baseLayer===this&&(this.map.setCenter(this.map.getCenter(), | |
1882 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(){var a=this.visibility;this.isBaseLayer||(a=a&&this.inRange);this.display(a)},moveByPx:function(){},setMap:function(a){null== | |
1883 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(),this.div.style.display=this.visibility&&this.inRange?"":"none"),this.setTileSize())},afterAdd:function(){}, | |
1884 removeMap:function(){},getImageSize:function(){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),this.redraw(),null!=this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"visibility"}), | |
1885 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=a,null!=this.map&&this.map.events.triggerEvent("changebaselayer",{layer:this}))},initResolutions:function(){var a, | |
1886 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.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<b;a++)c=this.RESOLUTION_PROPERTIES[a],d[c]=null!=this.options[c]?this.options[c]:this.map[c];null== | |
1887 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&&(g=this.options.minResolution);this.options.maxScale&&(g=OpenLayers.Util.getResolutionFromScale(this.options.maxScale, | |
1888 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=OpenLayers.Util.getScaleFromResolution(g,this.units);if(this.maxResolution=f)this.minScale=OpenLayers.Util.getScaleFromResolution(f, | |
1889 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(),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, | |
1890 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;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"!== | |
1891 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(){return this.getResolutionForZoom(this.map.getZoom())},getExtent:function(){return this.map.calculateBounds()},getZoomForExtent:function(a,b){var c=this.map.getSize();return this.getZoomForResolution(Math.max(a.getWidth()/ | |
1892 c.w,a.getHeight()/c.h),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,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< | |
1893 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!=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&& | |
1894 (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<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, | |
1895 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+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]= | |
1896 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, | |
1897 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= | |
1898 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); | |
1899 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""}, | |
1900 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, | |
1901 arguments);if(null!=this.mapObject){var d=this.map.getCenter(),e=this.map.getZoom();if(null!=d){var f=this.getOLLonLatFromMapObjectLonLat(this.getMapObjectCenter()),g=this.getOLZoomFromMapObjectZoom(this.getMapObjectZoom());if(!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, | |
1902 e,c))}}},getLonLatFromViewPortPx:function(a){var b=null;null!=this.mapObject&&null!=this.getMapObjectCenter()&&(b=this.getOLLonLatFromMapObjectLonLat(this.getMapObjectLonLatFromMapObjectPixel(this.getMapObjectPixelFromOLPixel(a))));return b},getViewPortPxFromLonLat:function(a){var b=null;null!=this.mapObject&&null!=this.getMapObjectCenter()&&(b=this.getOLPixelFromMapObjectPixel(this.getMapObjectPixelFromMapObjectLonLat(this.getMapObjectLonLatFromOLLonLat(a))));return b},getOLLonLatFromMapObjectLonLat:function(a){var b= | |
1903 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, | |
1904 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? | |
1905 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, | |
1906 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){return null!=this.resolutions?OpenLayers.Layer.prototype.getZoomForResolution.apply(this,arguments):this.getZoomForExtent(OpenLayers.Layer.prototype.getExtent.apply(this, | |
1907 []))},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], | |
1908 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, | |
1909 [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, | |
1910 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&& | |
1911 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)}},removeMap:function(a){this.visibility&&this.mapObject&&this.setGMapVisibility(!1);var b=OpenLayers.Layer.Google.cache[a.id]; | |
1912 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?(b=this.forwardMercator(b.lng(),b.lat()),a=this.forwardMercator(a.lng(),a.lat())):(b=new OpenLayers.LonLat(b.lng(),b.lat()), | |
1913 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(),a.lat()).lon:a.lng()},getLatitudeFromMapObjectLonLat:function(a){return this.sphericalMercator?this.forwardMercator(a.lng(), | |
1914 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={}; | |
1915 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= | |
1916 "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? | |
1917 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]; | |
1918 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= | |
1919 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)}, | |
1920 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, | |
1921 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&& | |
1922 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, | |
1923 b)},createTextNode:function(a){"string"!==typeof a&&(a=""+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 for(var a=a.getElementsByTagName("*"),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)("*"==b||b==e.namespaceURI)&&d.push(e);return d},getAttributeNodeNS:function(a,b,c){var d=null;if(a.getAttributeNodeNS)d=a.getAttributeNodeNS(b, | |
1924 c);else for(var a=a.attributes,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=d.nextSibling)switch(d.nodeType){case 3:case 4:c+=d.nodeValue}return c},isSimpleContent:function(a){for(var b=!0,a=a.firstChild;a;a= | |
1925 a.nextSibling)if(1===a.nodeType){b=!1;break}return b},contentType:function(a){for(var b=!1,c=!1,d=OpenLayers.Format.XML.CONTENT_TYPE.EMPTY,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},hasAttributeNS:function(a,b,c){var d=!1;return d=a.hasAttributeNS?a.hasAttributeNS(b, | |
1926 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){var b=b||{},c=b.uri||this.namespaces[b.prefix];c||(c=a.indexOf(":"),c=this.namespaces[a.substring(0,c)]);c||(c=this.namespaces[this.defaultPrefix]);c=this.createElementNS(c,a);b.attributes&&this.setAttributes(c, | |
1927 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=a.localName||a.nodeName.split(":").pop();(c=c[d]||c["*"])&&c.apply(this,[a,b])}return b},readChildNodes:function(a, | |
1928 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,b,c)},getNextEl:function(a,b,c){return a&&this.getThisOrNextEl(a.nextSibling,b,c)},getThisOrNextEl:function(a, | |
1929 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!==a.namespaceURI&&a.prefix===b){c=a.namespaceURI;break a}if(c=a.attributes.length)for(var d, | |
1930 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,b)}return c},getXMLDoc:function(){!OpenLayers.Format.XML.document&&!this.xmldom&&(document.implementation&& | |
1931 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};OpenLayers.Format.XML.lookupNamespaceURI=OpenLayers.Function.bind(OpenLayers.Format.XML.prototype.lookupNamespaceURI,OpenLayers.Format.XML.prototype); | |
1932 OpenLayers.Format.XML.document=null;OpenLayers.Format.WFST=function(a){var a=OpenLayers.Util.applyDefaults(a,OpenLayers.Format.WFST.DEFAULTS),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.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]= | |
1933 "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&& | |
1934 (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, | |
1935 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){var a=a||{},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, | |
1936 {"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){a=0;for(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", | |
1937 {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:"+ | |
1938 this.featurePrefix,this.featureNS);var c=b.modified;if(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"); | |
1939 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&& | |
1940 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){var a=OpenLayers.Util.extend({featurePrefix:this.featurePrefix,schema:this.schema},a),b=OpenLayers.Util.extend({},this.schemaLocations);a.schema&&(b[a.featurePrefix]=a.schema);var a=[],c,d;for(d in b)(c=this.namespaces[d])&& | |
1941 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, | |
1942 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,errorProperty:null,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){var a= | |
1943 a||this.defaultVersion,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)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){this.parser=this.getParser(this.getVersion(null,b));var c=this.parser.write(a,b);return!1===this.stringifyOutput?c:OpenLayers.Format.XML.prototype.write.apply(this,[c])},read:function(a,b){"string"==typeof a&& | |
1944 (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);if(null!==this.errorProperty&&void 0===d[this.errorProperty]){var e=new OpenLayers.Format.OGCExceptionReport;d.error=e.read(a)}d.version=c;return d},CLASS_NAME:"OpenLayers.Format.XML.VersionedOGC"});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&& | |
1945 (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? | |
1946 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"}; | |
1947 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= | |
1948 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|| | |
1949 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){var a="OpenLayers.LonLat"==a.CLASS_NAME?this.layer.getViewPortPxFromLonLat(a):a, | |
1950 b=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= | |
1951 a}else a==OpenLayers.State.UNKNOWN&&(this.state=a)},CLASS_NAME:"OpenLayers.Feature.Vector"}); | |
1952 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, | |
1953 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, | |
1954 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(), | |
1955 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){f=!0;g=0;for(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&& | |
1956 (b.label=""+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}), | |
1957 (!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})); | |
1958 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, | |
1959 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= | |
1960 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}; | |
1961 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(){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.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.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< | |
1962 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; | |
1963 b=!this.matchCase&&"string"==typeof a&&"string"==typeof b?a.toUpperCase()==b.toUpperCase():a==b;break;case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:b=this.value;b=!this.matchCase&&"string"==typeof a&&"string"==typeof b?a.toUpperCase()!=b.toUpperCase():a!=b;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= | |
1964 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)}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("\\"+b,"g"),".");this.value=this.value.replace(RegExp("\\"+ | |
1965 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,this)},CLASS_NAME:"OpenLayers.Filter.Comparison"}); | |
1966 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.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.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= | |
1967 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}); | |
1968 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, | |
1969 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)}, | |
1970 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))},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))},UpperBoundary:function(a,b){b.upperBoundary=OpenLayers.String.numericIf(this.readers.ogc._expression.call(this, | |
1971 a))},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(){}}},readSpatial:function(a,b,c){c=new OpenLayers.Filter.Spatial({type:c}); | |
1972 this.readChildNodes(a,c);c.value=c.components[0];delete c.components;b.filters.push(c)},writeOgcExpression:function(a,b){if(a instanceof OpenLayers.Filter.Function){var c=this.writeNode("Function",a,b);b.appendChild(c)}else this.writeNode("Literal",a,b);return b},write:function(a){return this.writers.ogc.Filter.apply(this,[a])},writeFeatureIdNodes:function(a,b){for(var c=0,d=a.fids.length;c<d;++c)this.writeNode("FeatureId",a.fids[c],b)},writers:{ogc:{Filter:function(a){var b=this.createElementNSPlus("ogc:Filter"); | |
1973 "FID"===a.type?OpenLayers.Format.Filter.v1.prototype.writeFeatureIdNodes.call(this,a,b):this.writeNode(this.getFilterType(a),a,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],"FID"===c.type?OpenLayers.Format.Filter.v1.prototype.writeFeatureIdNodes.call(this,c,b):this.writeNode(this.getFilterType(c),c,b);return b},Or:function(a){for(var b= | |
1974 this.createElementNSPlus("ogc:Or"),c,d=0,e=a.filters.length;d<e;++d)c=a.filters[d],"FID"===c.type?OpenLayers.Format.Filter.v1.prototype.writeFeatureIdNodes.call(this,c,b):this.writeNode(this.getFilterType(c),c,b);return b},Not:function(a){var b=this.createElementNSPlus("ogc:Not"),a=a.filters[0];"FID"===a.type?OpenLayers.Format.Filter.v1.prototype.writeFeatureIdNodes.call(this,a,b):this.writeNode(this.getFilterType(a),a,b);return b},PropertyIsLessThan:function(a){var b=this.createElementNSPlus("ogc:PropertyIsLessThan"); | |
1975 this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);return b},PropertyIsGreaterThan:function(a){var b=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"); | |
1976 this.writeNode("PropertyName",a,b);this.writeOgcExpression(a.value,b);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:a})},LowerBoundary:function(a){var b=this.createElementNSPlus("ogc:LowerBoundary"); | |
1977 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", | |
1978 {attributes:{units:a.distanceUnits},value:a.distance})},Function:function(a){for(var b=this.createElementNSPlus("ogc:Function",{attributes:{name:a.name}}),a=a.params,c=0,d=a.length;c<d;c++)this.writeOgcExpression(a[c],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","||":"Or","!":"Not","==":"PropertyIsEqualTo","!=":"PropertyIsNotEqualTo","<":"PropertyIsLessThan",">":"PropertyIsGreaterThan", | |
1979 "<=":"PropertyIsLessThanOrEqualTo",">=":"PropertyIsGreaterThanOrEqualTo","..":"PropertyIsBetween","~":"PropertyIsLike",BBOX:"BBOX",DWITHIN:"DWITHIN",WITHIN:"WITHIN",CONTAINS:"CONTAINS",INTERSECTS:"INTERSECTS",FID:"FeatureId"},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(); | |
1980 return this.bounds},calculateBounds:function(){},distanceTo:function(){},getVertices:function(){},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)): | |
1981 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}; | |
1982 OpenLayers.Geometry.segmentsIntersect=function(a,b,c){var d=c&&c.point,c=c&&c.tolerance,e=!1,f=a.x1-b.x1,g=a.y1-b.y1,h=a.x2-a.x1,i=a.y2-a.y1,j=b.y2-b.y1,k=b.x2-b.x1,l=j*h-k*i,j=k*g-j*f,g=h*g-i*f;0==l?0==j&&0==g&&(e=!0):(f=j/l,l=g/l,0<=f&&(1>=f&&0<=l&&1>=l)&&(d?(h=a.x1+f*h,l=a.y1+f*i,e=new OpenLayers.Geometry.Point(h,l)):e=!0));if(c)if(e){if(d){a=[a,b];b=0;a:for(;2>b;++b){f=a[b];for(i=1;3>i;++i)if(h=f["x"+i],l=f["y"+i],d=Math.sqrt(Math.pow(h-e.x,2)+Math.pow(l-e.y,2)),d<c){e.x=h;e.y=l;break a}}}}else{a= | |
1983 [a,b];b=0;a:for(;2>b;++b){h=a[b];l=a[(b+1)%2];for(i=1;3>i;++i)if(f={x:h["x"+i],y:h["y"+i]},g=OpenLayers.Geometry.distanceToSegment(f,l),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=a.x,d=a.y,e=b.x1,f=b.y1,g=b.x2,h=b.y2,i=g-e,j=h-f,k=(i*(c-e)+j*(d-f))/(Math.pow(i,2)+Math.pow(j,2));0>=k||(1<=k?(e=g,f=h):(e+=k*i,f+=k*j));return{distance:Math.sqrt(Math.pow(e-c,2)+Math.pow(f-d,2)),x:e,y:f}};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 | |
1984 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?d:{x0:e,y0:f,x1:g,y1:h,distance: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){var a= | |
1985 a*(Math.PI/180),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, | |
1986 a,b),this.bounds=null);return this},getVertices:function(){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()); | |
1987 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< | |
1988 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= | |
1989 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&& | |
1990 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 i=e=0,g=0;g<a;++g)f=c[g],h=b[g],e+=f.x*h,i+=f.y*h;return new OpenLayers.Geometry.Point(e/d,i/d)},getGeodesicLength:function(a){for(var b= | |
1991 0,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,i=this.components.length;h< | |
1992 i&&!(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)b=!1;else if(!OpenLayers.Util.isArray(a.components)||a.components.length!=this.components.length)b=!1;else for(var c=0,d=this.components.length;c<d;++c)if(!this.components[c].equals(a.components[c])){b=!1;break}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, | |
1993 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< | |
1994 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(), | |
1995 e,f,g,h,i,j,k,l=0,m=d.length;a:for(;l<m;++l){c=d[l];e=c.x1;f=c.x2;g=c.y1;h=c.y2;var n=0,o=a.length;for(;n<o;++n){i=a[n];if(i.x1>f)break;if(!(i.x2<e)&&(j=i.y1,k=i.y2,!(Math.min(j,k)>Math.max(g,h))&&!(Math.max(j,k)<Math.min(g,h))&&OpenLayers.Geometry.segmentsIntersect(c,i))){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}: | |
1996 {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=[],i=!1,j,k,l,m={point:!0,tolerance:d},n=null,o=0,p=f.length-2;o<=p;++o)if(d=f[o],g.push(d.clone()),j=f[o+1],k={x1:d.x,y1:d.y,x2:j.x,y2:j.y},k=OpenLayers.Geometry.segmentsIntersect(a,k,m),k instanceof OpenLayers.Geometry.Point&&((l=k.x===a.x1&&k.y===a.y1||k.x===a.x2&&k.y===a.y2||k.equals(d)||k.equals(j)?!0:!1)||c))k.equals(h[h.length- | |
1997 1])||h.push(k.clone()),!(0===o&&k.equals(d))&&!k.equals(j)&&(i=!0,k.equals(d)||g.push(k),e.push(new OpenLayers.Geometry.LineString(g)),g=[k.clone()]);i&&(g.push(j.clone()),e.push(new OpenLayers.Geometry.LineString(g)));if(0<h.length)var q=a.x1<a.x2?1:-1,r=a.y1<a.y2?1:-1,n={lines:e,points:h.sort(function(a,b){return q*a.x-q*b.x||r*a.y-r*b.y})};return n},split:function(a,b){var c=null,d=b&&b.mutual,e,f,g,h;if(a instanceof OpenLayers.Geometry.LineString){var i=this.getVertices(),j,k,l,m,n,o=[];g=[]; | |
1998 for(var p=0,q=i.length-2;p<=q;++p){j=i[p];k=i[p+1];l={x1:j.x,y1:j.y,x2:k.x,y2:k.y};h=h||[a];d&&o.push(j.clone());for(var r=0;r<h.length;++r)if(m=h[r].splitWithSegment(l,b))if(n=m.lines,0<n.length&&(n.unshift(r,1),Array.prototype.splice.apply(h,n),r+=n.length-2),d)for(var s=0,t=m.points.length;s<t;++s)n=m.points[s],n.equals(j)||(o.push(n),g.push(new OpenLayers.Geometry.LineString(o)),o=n.equals(k)?[]:[n.clone()])}d&&(0<g.length&&0<o.length)&&(o.push(k.clone()),g.push(new OpenLayers.Geometry.LineString(o)))}else c= | |
1999 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(), | |
2000 h=a.x,i=a.y,j,k=0,l=g.length;k<l;++k)if(j=g[k],d=OpenLayers.Geometry.distanceToSegment(a,j),d.distance<f){if(f=d.distance,e=d,0===f)break}else if(j.x2>h&&(i>j.y1&&i<j.y2||i<j.y1&&i>j.y2))break;e=c?{distance:e.distance,x0:e.x,y0:e.y,x1:h,y1:i}:e.distance}else if(a instanceof OpenLayers.Geometry.LineString){var g=this.getSortedSegments(),h=a.getSortedSegments(),m,n,o=h.length,p={point:!0},k=0,l=g.length;a:for(;k<l;++k){i=g[k];j=i.x1;n=i.y1;for(var q=0;q<o;++q)if(d=h[q],m=OpenLayers.Geometry.segmentsIntersect(i, | |
2001 d,p)){f=0;e={distance:0,x0:m.x,y0:m.y,x1:m.x,y1:m.y};break a}else d=OpenLayers.Geometry.distanceToSegment({x:j,y:n},d),d.distance<f&&(f=d.distance,e={distance:f,x0:j,y0:n,x1:d.x,y1:d.y})}c||(e=e.distance);0!==f&&i&&(d=a.distanceTo(new OpenLayers.Geometry.Point(i.x2,i.y2),b),k=c?d.distance:d,k<f&&(e=c?{distance:f,x0:d.x1,y0:d.y1,x1:d.x0,y1:d.y0}:k))}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(); | |
2002 if(3>b.length)return this;var c=function(a,b,d,i){for(var j=0,k=0,l=b,m;l<d;l++){m=a[b];var n=a[d],o=a[l],o=Math.abs(0.5*(m.x*n.y+n.x*o.y+o.x*m.y-n.x*m.y-o.x*n.y-m.x*o.y));m=Math.sqrt(Math.pow(m.x-n.x,2)+Math.pow(m.y-n.y,2));m=2*(o/m);m>j&&(j=m,k=l)}j>i&&k!=b&&(e.push(k),c(a,b,k,i),c(a,k,d,i))},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}, | |
2003 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,i=[],j=[a],k=0,l=this.components.length;k<l;++k){f=this.components[k];g=!1;for(var m=0;m<j.length;++m)if(e=f.split(j[m],b)){if(d){g=e[0];for(var n=0,o=g.length;n<o;++n)0===n&&i.length?i[i.length-1].addComponent(g[n]):i.push(new OpenLayers.Geometry.MultiLineString([g[n]]));g=!0;e=e[1]}if(e.length){e.unshift(m, | |
2004 1);Array.prototype.splice.apply(j,e);break}}g||(i.length?i[i.length-1].addComponent(f.clone()):i=[new OpenLayers.Geometry.MultiLineString(f.clone())])}i&&1<i.length?g=!0:i=[];j&&1<j.length?h=!0:j=[];if(g||h)c=d?[i,j]:j;return c},splitWith:function(a,b){var c=null,d=b&&b.mutual,e,f,g,h,i,j;if(a instanceof OpenLayers.Geometry.LineString){j=[];i=[a];for(var k=0,l=this.components.length;k<l;++k){g=!1;f=this.components[k];for(var m=0;m<i.length;++m)if(e=i[m].split(f,b)){d&&(g=e[0],g.length&&(g.unshift(m, | |
2005 1),Array.prototype.splice.apply(i,g),m+=g.length-2),e=e[1],0===e.length&&(e=[f.clone()]));g=0;for(var n=e.length;g<n;++g)0===g&&j.length?j[j.length-1].addComponent(e[g]):j.push(new OpenLayers.Geometry.MultiLineString([e[g]]));g=!0}g||(j.length?j[j.length-1].addComponent(f.clone()):j=[new OpenLayers.Geometry.MultiLineString([f.clone()])])}}else c=a.split(this);i&&1<i.length?h=!0:i=[];j&&1<j.length?g=!0:j=[];if(h||g)c=d?[i,j]:j;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();if(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, | |
2006 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, | |
2007 b);this.bounds=null}return this},getCentroid:function(){if(this.components&&2<this.components.length){for(var a=0,b=0,c=0;c<this.components.length-1;c++)var d=this.components[c],e=this.components[c+1],a=a+(d.x+e.x)*(d.x*e.y-e.x*d.y),b=b+(d.y+e.y)*(d.x*e.y-e.x*d.y);c=-1*this.getArea();return new OpenLayers.Geometry.Point(a/(6*c),b/(6*c))}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= | |
2008 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],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){for(var b=OpenLayers.Number.limitSigDigs, | |
2009 c=b(a.x,14),a=b(a.y,14),d=this.components.length-1,e,f,g,h,i,j=0,k=0;k<d;++k)if(e=this.components[k],g=b(e.x,14),e=b(e.y,14),f=this.components[k+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)){j=-1;break}}else{i=b((a-f)*((h-g)/(f-e))+h,14);if(i==c&&(e<f&&a>=e&&a<=f||e>f&&a<=e&&a>=f)){j=-1;break}i<=c||g!=h&&(i<Math.min(g,h)||i>Math.max(g,h))||(e<f&&a>=e&&a<f||e>f&&a<e&&a>=f)&&++j}return-1==j?1:!!(j&1)},intersects:function(a){var b=!1;if("OpenLayers.Geometry.Point"== | |
2010 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<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< | |
2011 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= | |
2012 this.components.length;c<d&&!(b=a.intersects(this.components[c]));++c);if(!b){c=0;for(d=a.components.length;c<d&&!(b=this.containsPoint(a.components[c]));++c);}}else{c=0;for(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, | |
2013 [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"== | |
2014 typeof a&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));for(var a=this.getElementsByTagNameNS(a.documentElement,this.gmlns,this.featureName),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, | |
2015 [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= | |
2016 g;h.gml={featureType:a.firstChild.nodeName.split(":")[1],featureNS:a.firstChild.namespaceURI,featureNSPrefix:a.firstChild.prefix};for(var a=a.firstChild,i;a&&!(1==a.nodeType&&(i=a.getAttribute("fid")||a.getAttribute("id")));)a=a.nextSibling;h.fid=i;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, | |
2017 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], | |
2018 c[0],c[2])},multipoint:function(a){var a=this.getElementsByTagNameNS(a,this.gmlns,"Point"),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")), | |
2019 g,h,i;for(c=0;c<d.length/f;++c)g=c*f,h=d[g],i=d[g+1],g=2==f?null:d[g+2],this.xy?e.push(new OpenLayers.Geometry.Point(h,i,g)):e.push(new OpenLayers.Geometry.Point(i,h,g))}if(0==d.length&&(c=this.getElementsByTagNameNS(a,this.gmlns,"coordinates"),0<c.length)){d=this.getChildValue(c[0]);d=d.replace(this.regExes.trimSpace,"");d=d.replace(this.regExes.trimComma,",");f=d.split(this.regExes.splitSpace);for(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], | |
2020 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){var a=this.getElementsByTagNameNS(a,this.gmlns,"LineString"),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){var a=this.getElementsByTagNameNS(a,this.gmlns,"LinearRing"), | |
2021 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){var a=this.getElementsByTagNameNS(a,this.gmlns,"Polygon"),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= | |
2022 [];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], | |
2023 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, | |
2024 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){for(var b={},a=a.firstChild,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,""), | |
2025 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); | |
2026 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=this.createElementNS(this.featureNS,this.featurePrefix+":"+e.substring(e.lastIndexOf(":")+1));f.appendChild(c);d.appendChild(f)}b.appendChild(d);return b},buildGeometryNode:function(a){this.externalProjection&&this.internalProjection&&(a= | |
2027 a.clone(),a.transform(this.internalProjection,this.externalProjection));var b=a.CLASS_NAME;return this.buildGeometry[b.substring(b.lastIndexOf(".")+1).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){for(var b=this.createElementNS(this.gmlns,"gml:MultiPoint"),a=a.components,c,d,e=0;e<a.length;e++)c=this.createElementNS(this.gmlns,"gml:pointMember"),d=this.buildGeometry.point.apply(this, | |
2028 [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){for(var b=this.createElementNS(this.gmlns,"gml:MultiLineString"),a=a.components,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);return b},linearring:function(a){var b=this.createElementNS(this.gmlns, | |
2029 "gml:LinearRing");b.appendChild(this.buildCoordinatesNode(a));return b},polygon:function(a){for(var b=this.createElementNS(this.gmlns,"gml:Polygon"),a=a.components,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){for(var b=this.createElementNS(this.gmlns,"gml:MultiPolygon"),a=a.components,c,d,e=0;e<a.length;++e)c=this.createElementNS(this.gmlns, | |
2030 "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"," ");var c=[];if(a instanceof OpenLayers.Bounds)c.push(a.left+","+a.bottom),c.push(a.right+","+a.top); | |
2031 else for(var a=a.components?a.components:[a],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={}); | |
2032 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?$/}, | |
2033 initialize:function(a){OpenLayers.Format.XML.prototype.initialize.apply(this,[a]);this.setGeometryTypes();a&&a.featureNS&&this.setNamespace("feature",a.featureNS);this.singleFeatureType=!a||typeof a.featureType==="string"},read:function(a){typeof a=="string"&&(a=OpenLayers.Format.XML.prototype.read.apply(this,[a]));if(a&&a.nodeType==9)a=a.documentElement;var b=[];this.readNode(a,{features:b},true);if(b.length==0){var c=this.getElementsByTagNameNS(a,this.namespaces.gml,"featureMember");if(c.length)for(var a= | |
2034 0,d=c.length;a<d;++a)this.readNode(c[a],{features:b},true);else{c=this.getElementsByTagNameNS(a,this.namespaces.gml,"featureMembers");c.length&&this.readNode(c[0],{features:b},true)}}return b},readNode:function(a,b,c){if(c===true&&this.autoConfig===true){this.featureType=null;delete this.namespaceAlias[this.featureNS];delete this.namespaces.feature;this.featureNS=null}if(!this.featureNS&&!(a.prefix in this.namespaces)&&a.parentNode.namespaceURI==this.namespaces.gml&&this.regExes.featureMember.test(a.parentNode.nodeName)){this.featureType= | |
2035 a.nodeName.split(":").pop();this.setNamespace("feature",a.namespaceURI);this.featureNS=a.namespaceURI;this.autoConfig=true}return OpenLayers.Format.XML.prototype.readNode.apply(this,[a,b])},readers:{gml:{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);if(c.components&&c.components.length>0)b.bounds=c.components[0]},Point:function(a, | |
2036 b){var c={points:[]};this.readChildNodes(a,c);if(!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,b){var c={};this.readChildNodes(a, | |
2037 c);if(!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.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.MultiPoint(c.components)]},pointMember:function(a,b){this.readChildNodes(a,b)},LineString:function(a,b){var c={};this.readChildNodes(a,c);if(!b.components)b.components=[];b.components.push(new OpenLayers.Geometry.LineString(c.points))}, | |
2038 MultiLineString:function(a,b){var c={components:[]};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.readChildNodes(a,c);c.inner.unshift(c.outer);if(!b.components)b.components=[];b.components.push(new OpenLayers.Geometry.Polygon(c.inner))},LinearRing:function(a,b){var c={};this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.LinearRing(c.points)]}, | |
2039 MultiPolygon:function(a,b){var c={components:[]};this.readChildNodes(a,c);b.components=[new OpenLayers.Geometry.MultiPolygon(c.components)]},polygonMember:function(a,b){this.readChildNodes(a,b)},GeometryCollection:function(a,b){var c={components:[]};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&& | |
2040 OpenLayers.Util.indexOf(this.featureType,d)!==-1?c="_typeName":d===this.featureType&&(c="_typeName"):a.childNodes.length==0||a.childNodes.length==1&&a.firstChild.nodeType==3?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);if(c.name)c.attributes.name=c.name;var d=new OpenLayers.Feature.Vector(c.components[0],c.attributes);if(!this.singleFeatureType){d.type=a.nodeName.split(":").pop(); | |
2041 d.namespace=a.namespaceURI}var e=a.getAttribute("fid")||this.getAttributeNS(a,this.namespaces.gml,"id");if(e)d.fid=e;this.internalProjection&&(this.externalProjection&&d.geometry)&&d.geometry.transform(this.externalProjection,this.internalProjection);if(c.bounds)d.bounds=c.bounds;b.features.push(d)},_geometry:function(a,b){if(!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); | |
2042 b.attributes[c]=d}},wfs:{FeatureCollection:function(a,b){this.readChildNodes(a,b)}}},write:function(a){a=this.writeNode("gml:"+(OpenLayers.Util.isArray(a)?"featureMembers":"featureMember"),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){for(var b= | |
2043 this.createElementNSPlus("gml:MultiPoint"),a=a.components||[a],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){for(var b=this.createElementNSPlus("gml:MultiLineString"),a=a.components||[a],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"); | |
2044 this.writeNode("LineString",a,b);return b},MultiPolygon:function(a){for(var b=this.createElementNSPlus("gml:MultiPolygon"),a=a.components||[a],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], | |
2045 b);return b},geometryMember:function(a){var b=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];d!=null&&this.writeNode("feature:_attribute",{name:c,value:d},b)}return b},_geometry:function(a){this.externalProjection&& | |
2046 this.internalProjection&&(a=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", | |
2047 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({featureMembers:function(a,b){this.readChildNodes(a,b)},Curve:function(a,b){var c={points:[]};this.readChildNodes(a,c);b.components|| | |
2048 (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),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, | |
2049 b){for(var c=this.getChildValue(a).replace(this.regExes.trimSpace,"").split(this.regExes.splitSpace),d=parseInt(a.getAttribute("dimension"))||2,e,f,g,h=Array(c.length/d),i=0,j=c.length;i<j;i+=d)e=c[i],f=c[i+1],g=2==d?void 0:c[i+2],h[i/d]=this.xy?new OpenLayers.Geometry.Point(e,f,g):new OpenLayers.Geometry.Point(f,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, | |
2050 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.readChildNodes(a,c);0<c.components.length&&(b.components=[new OpenLayers.Geometry.MultiLineString(c.components)])},curveMember:function(a,b){this.readChildNodes(a,b)},MultiSurface:function(a,b){var c={components:[]};this.readChildNodes(a,c);0<c.components.length&&(b.components=[new OpenLayers.Geometry.MultiPolygon(c.components)])}, | |
2051 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,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, | |
2052 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,[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){a=this.writeNode("gml:"+(OpenLayers.Util.isArray(a)?"featureMembers":"featureMember"),a);this.setAttributeNS(a, | |
2053 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=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+ | |
2054 " "+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");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}, | |
2055 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");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"}}); | |
2056 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],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"); | |
2057 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){for(var b=this.createElementNSPlus("gml:MultiCurve"),a=a.components||[a],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){for(var b= | |
2058 this.createElementNSPlus("gml:MultiSurface"),a=a.components||[a],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");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", | |
2059 {value:this.xy?a.left+" "+a.bottom:a.bottom+" "+a.left})},upperCorner:function(a){return this.createElementNSPlus("gml:upperCorner",{value:this.xy?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=== | |
2060 this.curve?"Curve":"LineString","OpenLayers.Geometry.MultiLineString":!1===this.multiCurve?"MultiLineString":"MultiCurve","OpenLayers.Geometry.Polygon":!0===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, | |
2061 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, | |
2062 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", | |
2063 {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", | |
2064 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})}}, | |
2065 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&& | |
2066 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){var b=this.version;b||((a=a.getAttribute("xmlns:ows"))&&"1.1"===a.substring(a.lastIndexOf("/")+1)&&(b="1.1.0"),b||(b=this.defaultVersion));return b},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)}, | |
2067 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= | |
2068 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, | |
2069 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, | |
2070 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, | |
2071 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, | |
2072 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, | |
2073 [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}, | |
2074 Language:function(a,b){b.language=this.getChildValue(a)}}},writers:{ows:{BoundingBox:function(a){var b=this.createElementNSPlus("ows:BoundingBox",{attributes:{crs:a.projection}});this.writeNode("ows:LowerCorner",a,b);this.writeNode("ows:UpperCorner",a,b);return b},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})},Identifier:function(a){return this.createElementNSPlus("ows:Identifier", | |
2075 {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}, | |
2076 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){return OpenLayers.Format.GML.v3.prototype.readNode.apply(this,[a,b])},readers:{wfs:OpenLayers.Util.applyDefaults({FeatureCollection:function(a, | |
2077 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, | |
2078 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){var a=OpenLayers.Util.extend({featureNS:this.featureNS, | |
2079 featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName},a),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", | |
2080 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(){}, | |
2081 update:function(){},"delete":function(){},commit:function(){},abort:function(){},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"}); | |
2082 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"=== | |
2083 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); | |
2084 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, | |
2085 [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(), | |
2086 "]");return c.join("")},string:function(a){var b={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\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)?""+a:"null"},"boolean":function(a){return""+a},date:function(a){function b(a){return 10>a?"0"+a:a}return'"'+a.getFullYear()+"-"+ | |
2087 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){var b=b?b:"FeatureCollection",d=null,e=null;if(e="string"==typeof a?OpenLayers.Format.JSON.prototype.read.apply(this,[a,c]):a)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=this.parseFeature(e),d.type="Feature"}catch(g){OpenLayers.Console.error(g)}break; | |
2088 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(i){d=null,OpenLayers.Console.error(i)}break;default:try{var j=this.parseGeometry(e);d.push(new OpenLayers.Feature.Vector(j))}catch(k){d=null,OpenLayers.Console.error(k)}}}}else OpenLayers.Console.error("Bad JSON: "+a);return d},isValidType:function(a, | |
2089 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||a.bbox;try{b=this.parseGeometry(a.geometry)}catch(e){throw e; | |
2090 }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);c=!0}else{if(!OpenLayers.Util.isArray(a.coordinates))throw"Geometry must have coordinates array: "+ | |
2091 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: "+a;return new OpenLayers.Geometry.Point(a[0],a[1])},multipoint:function(a){for(var b=[], | |
2092 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=this.parseCoords.linestring.apply(this,[a[d]])}catch(f){throw f;}b.push(c)}return new OpenLayers.Geometry.MultiLineString(b)}, | |
2093 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)},box:function(a){if(2!=a.length)throw"GeoJSON box coordinates must have 2 elements"; | |
2094 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=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: "+ | |
2095 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,[c,b])},createCRSObject:function(a){var a=a.layer.projection.toString(),b={};a.match(/epsg:/i)&&(a=parseInt(a.substring(a.indexOf(":")+1)),b=4326==a?{type:"name", | |
2096 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&&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, | |
2097 [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<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, | |
2098 [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=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= | |
2099 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= | |
2100 c;this.handleRead(b,a)},this));b.priv=c;return b},createRequest:function(a,b,c){var c=OpenLayers.Protocol.Script.register(c),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); | |
2101 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)}, | |
2102 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.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&& | |
2103 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, | |
2104 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]); | |
2105 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)&& | |
2106 b.deactivate();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(){return document.createElement("div")},addControlsToMap:function(a){for(var b, | |
2107 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){for(var b= | |
2108 this.controls,a=a.buttonElement,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.ZoomIn=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomIn()},CLASS_NAME:"OpenLayers.Control.ZoomIn"});OpenLayers.Control.ZoomOut=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){this.map.zoomOut()},CLASS_NAME:"OpenLayers.Control.ZoomOut"});OpenLayers.Control.ZoomToMaxExtent=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_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())); | |
2109 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, | |
2110 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= | |
2111 !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&&(b=!1!==this.events.triggerEvent("beforedraw"));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, | |
2112 {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(){},CLASS_NAME:"OpenLayers.Tile"});OpenLayers.Tile.Image=OpenLayers.Class(OpenLayers.Tile,{url:null,imgDiv:null,frame:null,imageReloadAttempts:null,layerAlphaHack:null,asyncRequestId:null,blankImageUrl:"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAQAIBRAA7",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|| | |
2113 this.layer.gutter||this.layerAlphaHack)this.frame=document.createElement("div"),this.frame.style.position="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&& | |
2114 this.layer.reproject&&(this.bounds=this.getBoundsFromBaseLayer(this.position)),this.isLoading?this._loadEvent="reload":(this.isLoading=!0,this._loadEvent="loadstart"),this.positionTile(),this.renderTile()):this.unload();return a},renderTile:function(){this.layer.div.appendChild(this.getTile());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), | |
2115 this.initImage()},positionTile:function(){var a=this.getTile().style,b=this.frame?this.size:this.layer.getImageSize(this.bounds);a.left=this.position.x+"%";a.top=this.position.y+"%";a.width=b.w+"%";a.height=b.h+"%"},clear:function(){OpenLayers.Tile.prototype.clear.apply(this,arguments);var a=this.imgDiv;if(a){OpenLayers.Event.stopObservingElement(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, | |
2116 "olImageLoadError")}this.canvasContext=null},getImage:function(){if(!this.imgDiv){this.imgDiv=document.createElement("img");this.imgDiv.className="olTileImage";this.imgDiv.galleryImg="no";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="+ | |
2117 100*this.layer.opacity+")");a.position="absolute";this.layerAlphaHack&&(a.paddingTop=a.height,a.height="0",a.width="100%");this.frame&&this.frame.appendChild(this.imgDiv)}return this.imgDiv},initImage:function(){this.events.triggerEvent(this._loadEvent);var a=this.getImage();if(this.url&&a.getAttribute("src")==this.url)this.onImageLoad();else{var b=OpenLayers.Function.bind(function(){OpenLayers.Event.stopObservingElement(a);OpenLayers.Event.observe(a,"load",OpenLayers.Function.bind(this.onImageLoad, | |
2118 this));OpenLayers.Event.observe(a,"error",OpenLayers.Function.bind(this.onImageError,this));this.imageReloadAttempts=0;this.setImgSrc(this.url)},this);a.getAttribute("src")==this.blankImageUrl?b():(OpenLayers.Event.observe(a,"load",b),OpenLayers.Event.observe(a,"error",b),this.crossOriginKeyword&&a.removeAttribute("crossorigin"),a.src=this.blankImageUrl)}},setImgSrc:function(a){var b=this.imgDiv;b.style.visibility="hidden";b.style.opacity=0;a&&(this.crossOriginKeyword&&("data:"!==a.substr(0,5)?b.setAttribute("crossorigin", | |
2119 this.crossOriginKeyword):b.removeAttribute("crossorigin")),b.src=a)},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;OpenLayers.Event.stopObservingElement(a);a.style.visibility="inherit";a.style.opacity=this.layer.opacity;this.isLoading=!1;this.canvasContext=null;this.events.triggerEvent("loadend"); | |
2120 if(7>parseFloat(navigator.appVersion.split("MSIE")[1])&&this.layer&&this.layer.div){var b=document.createElement("span");b.style.display="none";var c=this.layer.div;c.appendChild(b);window.setTimeout(function(){b.parentNode===c&&b.parentNode.removeChild(b)},0)}!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<= | |
2121 OpenLayers.IMAGE_RELOAD_ATTEMPTS?this.setImgSrc(this.layer.getURL(this.bounds)):(OpenLayers.Element.addClass(a,"olImageLoadError"),this.events.triggerEvent("loaderror"),this.onImageLoad()))},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"});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:null,numLoadingTiles:0,tileLoadingDelay:85,serverResolutions:null,moveTimerId:null,deferMoveGriddedTiles:null,tileQueueId:null,tileQueue:null,loading:!1,backBuffer:null,gridResolution:null,backBufferResolution:null,backBufferLonLat:null,backBufferTimerId:null,removeBackBufferDelay:null, | |
2122 className:null,initialize:function(a,b,c,d){OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,arguments);this.grid=[];this.tileQueue=[];null===this.removeBackBufferDelay&&(this.removeBackBufferDelay=this.singleTile?0:2500);null===this.className&&(this.className=this.singleTile?"olLayerGridSingleTile":"olLayerGrid");OpenLayers.Animation.isNative||(this.deferMoveGriddedTiles=OpenLayers.Function.bind(function(){this.moveGriddedTiles(true);this.moveTimerId=null},this))},setMap:function(a){OpenLayers.Layer.HTTPRequest.prototype.setMap.call(this, | |
2123 a);OpenLayers.Element.addClass(this.div,this.className)},removeMap:function(){null!==this.moveTimerId&&(window.clearTimeout(this.moveTimerId),this.moveTimerId=null);this.clearTileQueue();null!==this.backBufferTimerId&&(window.clearTimeout(this.backBufferTimerId),this.backBufferTimerId=null)},destroy:function(){this.removeBackBuffer();this.clearGrid();this.tileSize=this.grid=null;OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this,arguments)},clearGrid:function(){this.clearTileQueue();if(this.grid){for(var a= | |
2124 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]);this.grid=[];this.gridResolution=null}},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,[a]);null!=this.tileSize&&(a.tileSize=this.tileSize.clone());a.grid=[];a.gridResolution=null;a.backBuffer=null;a.backBufferTimerId=null;a.tileQueue=[];a.tileQueueId=null;a.loading=!1;a.moveTimerId=null; | |
2125 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(),g=this.getServerResolution(f);if(this.singleTile){if(d||!c&&!e.containsBounds(a))b&&"resize"!==this.transitionEffect&&this.removeBackBuffer(),(!b||"resize"===this.transitionEffect)&&this.applyBackBuffer(g),this.initSingleTile(a)}else(d=d||!e.intersectsBounds(a,{worldBounds:this.map.baseLayer.wrapDateLine&& | |
2126 this.map.getMaxExtent()}),f!==g?(a=this.map.calculateBounds(null,g),d&&this.transformDiv(g/f)):(this.div.style.width="100%",this.div.style.height="100%",this.div.style.left="0%",this.div.style.top="0%"),d)?(b&&"resize"===this.transitionEffect&&this.applyBackBuffer(g),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,g=this.tileSize.h,h=this.grid[0][0].bounds,i=h.left, | |
2127 h=h.top;if(c<i&&this.map.baseLayer.wrapDateLine)var j=this.map.getMaxExtent().getWidth(),k=Math.ceil((i-c)/j),c=c+j*k;c=(c-i)/(f*a);d=(h-d)/(f*g);f=Math.floor(c);i=Math.floor(d);0<=i&&i<e&&(e=this.grid[i][f])&&(b={tile:e,i:Math.floor((c-f)*a),j:Math.floor((d-i)*g)})}return b},queueTileDraw:function(a){a=a.object;~OpenLayers.Util.indexOf(this.tileQueue,a)||this.tileQueue.push(a);this.tileQueueId||(this.tileQueueId=OpenLayers.Animation.start(OpenLayers.Function.bind(this.drawTileFromQueue,this),null, | |
2128 this.div));return!1},drawTileFromQueue:function(){0===this.tileQueue.length?this.clearTileQueue():this.tileQueue.shift().draw(!0)},clearTileQueue:function(){OpenLayers.Animation.stop(this.tileQueueId);this.tileQueueId=null;this.tileQueue=[]},destroyTile:function(a){this.removeTileMonitoringHooks(a);a.destroy()},getServerResolution:function(a){a=a||this.map.getResolution();if(this.serverResolutions&&-1===OpenLayers.Util.indexOf(this.serverResolutions,a)){var b,c;for(b=this.serverResolutions.length- | |
2129 1;0<=b;b--)if(c=this.serverResolutions[b],c>a){a=c;break}if(-1===b)throw"no appropriate resolution in serverResolutions";}return a},getServerZoom:function(){var a=this.getServerResolution();return this.serverResolutions?OpenLayers.Util.indexOf(this.serverResolutions,a):this.map.getZoomForResolution(a)+(this.zoomOffset||0)},transformDiv:function(a){this.div.style.width=100*a+"%";this.div.style.height=100*a+"%";var b=this.map.getSize(),c=parseInt(this.map.layerContainerDiv.style.left,10),d=(parseInt(this.map.layerContainerDiv.style.top, | |
2130 10)-b.h/2)*(a-1);this.div.style.left=(c-b.w/2)*(a-1)+"%";this.div.style.top=d+"%"},getResolutionScale:function(){return parseInt(this.div.style.width,10)/100},applyBackBuffer:function(a){null!==this.backBufferTimerId&&this.removeBackBuffer();var b=this.backBuffer;if(!b){b=this.createBackBuffer();if(!b)return;this.div.insertBefore(b,this.div.firstChild);this.backBuffer=b;var c=this.grid[0][0].bounds;this.backBufferLonLat={lon:c.left,lat:c.top};this.backBufferResolution=this.gridResolution}var c=b.style, | |
2131 d=this.backBufferResolution/a;c.width=100*d+"%";c.height=100*d+"%";a=this.getViewPortPxFromLonLat(this.backBufferLonLat,a);c=parseInt(this.map.layerContainerDiv.style.left,10);d=parseInt(this.map.layerContainerDiv.style.top,10);b.style.left=Math.round(a.x-c)+"%";b.style.top=Math.round(a.y-d)+"%"},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";a.style.width="100%";a.style.height= | |
2132 "100%";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].createBackBuffer();f&&(f.style.top=b*this.tileSize.h+"%",f.style.left=d*this.tileSize.w+"%",a.appendChild(f))}}return a},removeBackBuffer:function(){this.backBuffer&&(this.div.removeChild(this.backBuffer),this.backBufferResolution=this.backBuffer=null,null!==this.backBufferTimerId&&(window.clearTimeout(this.backBufferTimerId),this.backBufferTimerId=null))},moveByPx:function(){this.singleTile|| | |
2133 this.moveGriddedTiles()},setTileSize:function(a){this.singleTile&&(a=this.map.getSize(),a.h=parseInt(a.h*this.ratio),a.w=parseInt(a.w*this.ratio));OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this,[a])},getTilesBounds:function(){var a=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.clearTileQueue();var b= | |
2134 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])?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=c*this.tileSize.h,e= | |
2135 a.left-b.lon,f=Math.floor(e/d)-this.buffer,e=-(e/d-f)*this.tileSize.w,f=b.lon+f*d,a=a.top-(b.lat+c),g=Math.ceil(a/c)+this.buffer;return{tilelon:d,tilelat:c,tileoffsetlon:f,tileoffsetlat:b.lat+g*c,tileoffsetx:e,tileoffsety:-(g-a/c)*this.tileSize.h}},getTileOrigin:function(){var a=this.tileOrigin;if(!a)var a=this.getMaxExtent(),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},initGriddedTiles:function(a){this.clearTileQueue(); | |
2136 var b=this.map.getSize(),c=Math.ceil(b.h/this.tileSize.h)+Math.max(1,2*this.buffer),b=Math.ceil(b.w/this.tileSize.w)+Math.max(1,2*this.buffer),d=this.getTileOrigin(),e=this.getServerResolution(),d=this.calculateGridLayout(a,d,e),e=Math.round(d.tileoffsetx),f=Math.round(d.tileoffsety),g=d.tileoffsetlon,h=d.tileoffsetlat,i=d.tilelon,j=d.tilelat,k=e,l=g,m=0,n=parseInt(this.map.layerContainerDiv.style.left),o=parseInt(this.map.layerContainerDiv.style.top),d=[],p=this.map.getCenter();do{var q=this.grid[m++]; | |
2137 q||(q=[],this.grid.push(q));var g=l,e=k,r=0;do{var s=new OpenLayers.Bounds(g,h,g+i,h+j),t=e,t=t-n,u=f,u=u-o,u=new OpenLayers.Pixel(t,u);(t=q[r++])?t.moveTo(s,u,!1):(t=this.addTile(s,u),this.addTileMonitoringHooks(t),q.push(t));s=s.getCenterLonLat();d.push({tile:t,distance:Math.pow(s.lon-p.lon,2)+Math.pow(s.lat-p.lat,2)});g+=i;e+=this.tileSize.w}while(g<=a.right+i*this.buffer||r<b);h-=j;f+=this.tileSize.h}while(h>=a.bottom-j*this.buffer||m<c);this.removeExcessTiles(m,r);this.gridResolution=this.getServerResolution(); | |
2138 d.sort(function(a,b){return a.distance-b.distance});a=0;for(c=d.length;a<c;++a)d[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);c.events.register("beforedraw",this,this.queueTileDraw);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++}; | |
2139 a.onLoadEnd=function(){this.numLoadingTiles--;this.events.triggerEvent("tileloaded",{tile:a});0===this.tileQueue.length&&0===this.numLoadingTiles&&(this.loading=!1,this.events.triggerEvent("loadend"),this.backBuffer&&(this.backBufferTimerId=window.setTimeout(OpenLayers.Function.bind(this.removeBackBuffer,this),this.removeBackBufferDelay)))};a.onLoadError=function(){this.events.triggerEvent("tileerror",{tile:a})};a.events.on({loadstart:a.onLoadStart,loadend:a.onLoadEnd,unload:a.onLoadEnd,loaderror:a.onLoadError, | |
2140 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(a){if(!a&&!OpenLayers.Animation.isNative)null!=this.moveTimerId&&window.clearTimeout(this.moveTimerId),this.moveTimerId=window.setTimeout(this.deferMoveGriddedTiles,this.tileLoadingDelay);else for(var a=this.buffer||1,b=this.getResolutionScale();;){var c=this.grid[0][0].position.x*b+parseInt(this.div.style.left, | |
2141 10)+parseInt(this.map.layerContainerDiv.style.left),d=this.grid[0][0].position.y*b+parseInt(this.div.style.top,10)+parseInt(this.map.layerContainerDiv.style.top),e=this.tileSize.w*b,f=this.tileSize.h*b;if(c>-e*(a-1))this.shiftColumn(!0);else if(c<-e*a)this.shiftColumn(!1);else if(d>-f*(a-1))this.shiftRow(!0);else if(d<-f*a)this.shiftRow(!1);else break}},shiftRow:function(a){for(var b=this.grid,c=b[a?0:this.grid.length-1],d=this.getServerResolution(),e=a?-this.tileSize.h:this.tileSize.h,d=d*-e,f=a? | |
2142 b.pop():b.shift(),g=0,h=c.length;g<h;g++){var i=c[g],j=i.bounds.clone(),i=i.position.clone();j.bottom+=d;j.top+=d;i.y+=e;f[g].moveTo(j,i)}a?b.unshift(f):b.push(f)},shiftColumn:function(a){for(var b=a?-this.tileSize.w:this.tileSize.w,c=this.getServerResolution()*b,d=0,e=this.grid.length;d<e;d++){var f=this.grid[d],g=f[a?0:f.length-1],h=g.bounds.clone(),g=g.position.clone();h.left+=c;h.right+=c;g.x+=b;var i=a?this.grid[d].pop():this.grid[d].shift();i.moveTo(h,g);a?f.unshift(i):f.push(i)}},removeExcessTiles:function(a, | |
2143 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>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+ | |
2144 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); | |
2145 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, | |
2146 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&& | |
2147 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]); | |
2148 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("", | |
2149 "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("", | |
2150 "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); | |
2151 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){d=this.createElementNS("","LAYERLIST");e.appendChild(d);for(e=0;e<a.layerlist.length;e++){var f=this.createElementNS("","LAYERDEF");d.appendChild(f); | |
2152 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", | |
2153 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 if(null!=a.get_feature&&(d=this.createElementNS("","GET_FEATURES"),d.setAttribute("outputmode", | |
2154 "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), | |
2155 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"), | |
2156 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), | |
2157 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, | |
2158 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|| | |
2159 "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&& | |
2160 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,i=0,j=h.length;i<j;i++){var k=h[i];e.symbol[k]&&g.setAttribute(k,e.symbol[k])}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= | |
2161 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", | |
2162 e.symbol.filltransparency),f.appendChild(g))}}else if("object"==typeof b.exacts){c=0;for(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&& | |
2163 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", | |
2164 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; | |
2165 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 i=e.components[g],j=this.createElementNS("","POINT");j.setAttribute("x",i.x);j.setAttribute("y", | |
2166 i.y);f.appendChild(j)}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"== | |
2167 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"), | |
2168 b.features.featurecount=c[0].getAttribute("count"),0<b.features.featurecount){c=a[0].getElementsByTagName("ENVELOPE");b.features.envelope=this.parseAttributes(c[0],"number");a=a[0].getElementsByTagName("FEATURE");for(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"); | |
2169 f=[];for(g=0;g<e.length;g++){h=[];h.push(this.parsePointGeometry(e[g]));for(var i=e[g].getElementsByTagName("HOLE"),j=0;j<i.length;j++)h.push(this.parsePointGeometry(i[j]));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): | |
2170 a.attributes[d].nodeValue;return c},parsePointGeometry:function(a){var b=[],c=a.getElementsByTagName("COORDS");if(0<c.length){a=this.getChildValue(c[0]);a=a.split(/;/);for(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"}); | |
2171 OpenLayers.Format.ArcXML.Request=OpenLayers.Class({initialize:function(){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:"", | |
2172 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"}); | |
2173 OpenLayers.Format.ArcXML.Response=OpenLayers.Class({initialize:function(){return OpenLayers.Util.extend(this,{image:{envelope:null,output:""},features:{featurecount:0,envelope:null,feature:[]},error:""})},CLASS_NAME:"OpenLayers.Format.ArcXML.Response"});OpenLayers.ProxyHost=""; | |
2174 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]==e.hostname,d=d[4], | |
2175 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):OpenLayers.Console.warn(OpenLayers.i18n("proxyNeeded"),{url:a}));return a},issue:function(a){var b=OpenLayers.Util.extend(this.DEFAULT_CONFIG,{proxy:OpenLayers.ProxyHost}),a=OpenLayers.Util.applyDefaults(a,b),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"]="XMLHttpRequest");var d=new OpenLayers.Request.XMLHttpRequest, | |
2176 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,requestUrl:e})};!1===a.async?d.send(a.data):window.setTimeout(function(){0!== | |
2177 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||200<=b.status&&300>b.status)this.events.triggerEvent("success",a),e&&e(b); | |
2178 if(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=OpenLayers.Util.extend(a,{method:"PUT"});a.headers=a.headers? | |
2179 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}, | |
2180 this.DEFAULT_PARAMS);this.options=OpenLayers.Util.applyDefaults(c,this.DEFAULT_OPTIONS);OpenLayers.Layer.Grid.prototype.initialize.apply(this,[a,b,this.params,c]);if(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", | |
2181 envelope:a.toArray(),tileSize:this.tileSize})),a=new OpenLayers.Request.POST({url:this.getFullRequestString(),data:a.write(),async:!1});if(null!=a){b=a.responseXML;if(!b||!b.documentElement)b=a.responseText;b=this.getUrlOrImage((new OpenLayers.Format.ArcXML).read(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(), | |
2182 async:!0,data:a.write(),callback:function(a){var e=a.responseXML;if(!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, | |
2183 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= | |
2184 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== | |
2185 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.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= | |
2186 !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", | |
2187 {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", | |
2188 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", | |
2189 {});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", | |
2190 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", | |
2191 {});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", | |
2192 {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.WPSExecute=OpenLayers.Class(OpenLayers.Format.XML,{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",schemaLocation:"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd", | |
2193 schemaLocationAttr:function(){},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])},writers:{wps:{Execute:function(a){var b=this.createElementNSPlus("wps:Execute",{attributes:{version:this.VERSION,service:"WPS"}});this.writeNode("ows:Identifier", | |
2194 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&&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, | |
2195 lineage:a.lineage,status:a.status}});a.output&&this.writeNode("wps:Output",a.output,b);return b},Output:function(a){var b=this.createElementNSPlus("wps:Output",{attributes:{asReference:a.asReference}});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}});this.writeNode("ows:Identifier",a.identifier, | |
2196 b);return b},DataInputs:function(a){for(var b=this.createElementNSPlus("wps:DataInputs",{}),c=0,d=a.length;c<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);return b},Data:function(a){var b=this.createElementNSPlus("wps:Data",{});a.literalData? | |
2197 this.writeNode("wps:LiteralData",a.literalData,b):a.complexData&&this.writeNode("wps:ComplexData",a.complexData,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)):b.appendChild(c);return b}, | |
2198 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},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,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, | |
2199 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},CLASS_NAME:"OpenLayers.Format.WPSExecute"});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)}, | |
2200 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", | |
2201 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); | |
2202 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(); | |
2203 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,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, | |
2204 arguments);this.map.events.register("changebaselayer",this,this.redraw)},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;this._addButton("panleft", | |
2205 "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)),this._addButton("zoomout", | |
2206 "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.getNumZoomLevels()-1-this.map.getZoom(),d=OpenLayers.Util.createAlphaImageDiv(c,a.add(-1,d*this.zoomStopHeight),{w:20,h:9},b,"absolute");d.style.cursor="move";this.slider=d;this.sliderEvents=new OpenLayers.Events(this,d,null,!0,{includeXY:!0});this.sliderEvents.on({touchstart:this.zoomBarDown, | |
2207 touchmove:this.zoomBarDrag,touchend:this.zoomBarUp,mousedown:this.zoomBarDown,mousemove:this.zoomBarDrag,mouseup:this.zoomBarUp});var e={w:this.zoomStopWidth,h:this.zoomStopHeight*this.map.getNumZoomLevels()},b=OpenLayers.Util.getImageLocation("zoombar.png"),c=null;OpenLayers.Util.alphaHack()?(c=this.id+"_"+this.map.id,c=OpenLayers.Util.createAlphaImageDiv(c,a,{w:e.w,h:this.zoomStopHeight},b,"absolute",null,"crop"),c.style.height=e.h+"px"):c=OpenLayers.Util.createDiv("OpenLayers_Control_PanZoomBar_Zoombar"+ | |
2208 this.map.id,a,e,b);c.style.cursor="pointer";c.className="olButton";this.zoombarDiv=c;this.div.appendChild(c);this.startTop=parseInt(c.style.top);this.div.appendChild(d);this.map.events.register("zoomend",this,this.moveZoomBar);return a=a.add(0,this.zoomStopHeight*this.map.getNumZoomLevels())},_removeZoomBar:function(){this.sliderEvents.un({touchstart:this.zoomBarDown,touchmove:this.zoomBarDrag,touchend:this.zoomBarUp,mousedown:this.zoomBarDown,mousemove:this.zoomBarDrag,mouseup:this.zoomBarUp});this.sliderEvents.destroy(); | |
2209 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=Math.floor(b);b=this.map.getNumZoomLevels()-1-b;b=Math.min(Math.max(b,0),this.map.getNumZoomLevels()- | |
2210 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="move",this.zoombarDiv.offsets=null,OpenLayers.Event.stop(a)},zoomBarDrag:function(a){if(null!=this.mouseDragStart){var b= | |
2211 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&&(this.slider.style.top=parseInt(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"===a.type)&&this.mouseDragStart){this.div.style.cursor="";this.map.events.un({touchmove:this.passEventToSlider,mouseup:this.passEventToSlider, | |
2212 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)}},moveZoomBar:function(){this.slider.style.top=(this.map.getNumZoomLevels()-1-this.map.getZoom())*this.zoomStopHeight+this.startTop+ | |
2213 1+"px"},CLASS_NAME:"OpenLayers.Control.PanZoomBar"});OpenLayers.Format.WFSCapabilities=OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC,{defaultVersion:"1.1.0",errorProperty:"service",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"},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,b){this.readChildNodes(a,b)}, | |
2214 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)}}},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, | |
2215 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(); | |
2216 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= | |
2217 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(){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?this.active=!0:!1},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, | |
2218 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); | |
2219 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,i=c.length;h<i;++h)if(d=c[h], | |
2220 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.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, | |
2221 [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,i=g.length;h<i;h++){var j=this.extractSegment(g[h],"trkpt");b.push(new OpenLayers.Feature.Vector(j,f))}}if(this.extractRoutes){e=a.getElementsByTagName("rte");c=0;for(d= | |
2222 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){a=a.getElementsByTagName("wpt");c=0;for(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){f=0;for(a=b.length;f< | |
2223 a;f++)b[f].geometry.transform(this.externalProjection,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){for(var b={},a=a.firstChild,c,d;a;){if(1==a.nodeType&&a.firstChild&&(c=a.firstChild,3==c.nodeType||4==c.nodeType))d=a.prefix?a.nodeName.split(":")[1]: | |
2224 a.nodeName,"trkseg"!=d&&"rtept"!=d&&(b[d]=c.nodeValue);a=a.nextSibling}return b},write:function(a,b){var a=OpenLayers.Util.isArray(a)?a:[a],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, | |
2225 [c])},buildMetadataNode:function(a){for(var b=["name","desc","author"],c=this.createElementNSPlus("gpx:metadata"),d=0;d<b.length;d++){var e=b[d];if(a[e]){var f=this.createElementNSPlus("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); | |
2226 this.appendAttributesNode(c,a);return c}c=this.createElementNSPlus("gpx:trk");this.appendAttributesNode(c,a);for(var a=this.buildTrkSegNode(b),a=OpenLayers.Util.isArray(a)?a:[a],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.createElementNSPlus("gpx:trkseg");c=0;for(d=a.components.length;c<d;c++)e=a.components[c],b.appendChild(this.buildTrkPtNode(e)); | |
2227 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.createElementNSPlus("gpx:trkpt");b.setAttribute("lon",a.x);b.setAttribute("lat",a.y);return b},buildWptNode:function(a){var b=this.createElementNSPlus("gpx:wpt");b.setAttribute("lon",a.x);b.setAttribute("lat",a.y);return b},appendAttributesNode:function(a,b){var c=this.createElementNSPlus("gpx:name");c.appendChild(this.createTextNode(b.attributes.name|| | |
2228 b.id));a.appendChild(c);c=this.createElementNSPlus("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",getVersion:function(a,b){var c=OpenLayers.Format.XML.VersionedOGC.prototype.getVersion.apply(this,arguments);if("1.1.1"==c||"1.1.0"==c)c="1.1";return c},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer"});OpenLayers.Format.WMSDescribeLayer.v1_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 a=a.documentElement.childNodes,b=[],c,d,e=0;e<a.length;++e)if(c=a[e],d=c.nodeName,"LayerDescription"==d){d=c.getAttribute("name");var f="",g="",h="";c.getAttribute("owsType")?(f=c.getAttribute("owsType"),g=c.getAttribute("owsURL")): | |
2229 ""!=c.getAttribute("wfs")?(f="WFS",g=c.getAttribute("wfs")):""!=c.getAttribute("wcs")&&(f="WCS",g=c.getAttribute("wcs"));c=c.getElementsByTagName("Query");0<c.length&&((h=c[0].getAttribute("typeName"))||(h=c[0].getAttribute("typename")));b.push({layerName:d,owsType:f,owsURL:g,typeName:h})}return b},CLASS_NAME:"OpenLayers.Format.WMSDescribeLayer.v1_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, | |
2230 [a])},getURL:function(a){var a=this.getXYZ(a),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, | |
2231 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:"Data CC-By-SA by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",sphericalMercator:!0,wrapDateLine:!0,tileOptions:null,initialize:function(a,b,c){OpenLayers.Layer.XYZ.prototype.initialize.apply(this,arguments);this.tileOptions=OpenLayers.Util.extend({crossOriginKeyword:"anonymous"}, | |
2232 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(), | |
2233 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, | |
2234 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)/ | |
2235 2)/c)*c}},drawGeometry:function(){},drawText:function(){},removeText:function(){},clear:function(){},getFeatureIdFromEvent:function(){},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(){},moveRoot:function(){},getRenderLayerId:function(){return this.container.id},applyDefaultSymbolizer:function(a){var b=OpenLayers.Util.extend({},OpenLayers.Renderer.defaultSymbolizer); | |
2236 !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"}; | |
2237 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"))}, | |
2238 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, | |
2239 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"== | |
2240 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, | |
2241 b,c){var d=new Image;b.graphicTitle&&(d.title=b.graphicTitle);var e=b.graphicWidth||b.graphicHeight,f=b.graphicHeight||b.graphicWidth,e=e?e:2*b.pointRadius,f=f?f:2*b.pointRadius,g=void 0!=b.graphicXOffset?b.graphicXOffset:-(0.5*e),h=void 0!=b.graphicYOffset?b.graphicYOffset:-(0.5*f),i=b.graphicOpacity||b.fillOpacity;d.onload=OpenLayers.Function.bind(function(){if(this.features[c]){var b=this.getLocalXY(a),k=b[0],b=b[1];if(!isNaN(k)&&!isNaN(b)){var k=k+g|0,b=b+h|0,l=this.canvas;l.globalAlpha=i;var m= | |
2242 OpenLayers.Renderer.Canvas.drawImageScaleFactor||(OpenLayers.Renderer.Canvas.drawImageScaleFactor=/android 2.1/.test(navigator.userAgent.toLowerCase())?320/window.screen.width:1);l.drawImage(d,k*m,b*m,e*m,f*m);if(this.hitDetection){this.setHitContextStyle("fill",c);this.hitContext.fillRect(k,b,e,f)}}}},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"); | |
2243 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(); | |
2244 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", | |
2245 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], | |
2246 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"=== | |
2247 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);var a="000000"+a.toString(16),b=a.length;return a="#"+a.substring(b-6,b)},setHitContextStyle:function(a,b,c,d){b=this.featureIdToHex(b); | |
2248 "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= | |
2249 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", | |
2250 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, | |
2251 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();var d=this.getLocalXY(b[0]),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){var a=a.components,d=a.length;this.drawLinearRing(a[0],b,c);for(var e=1;e< | |
2252 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"); | |
2253 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]]; | |
2254 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.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]];null==h&&(h=-0.5); | |
2255 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 i=c[0]+h*this.canvas.mozMeasureText(e[g]),j=c[1]+g*d;this.canvas.translate(i,j);this.canvas.mozDrawText(e[g]);this.canvas.translate(-i,-j)}}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;this.canvas.clearRect(0, | |
2256 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]; | |
2257 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= | |
2258 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){for(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={},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]]= | |
2259 !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]));for(var b=this.getNodes(a),c=this.getWays(a),a=Array(c.length),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]],i=new OpenLayers.Geometry.Point(h.lon,h.lat);i.osm_id=parseInt(c[d].nodes[g]); | |
2260 e[g]=i;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 j in b){h=b[j];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); | |
2261 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(j);e.fid="node."+e.osm_id;a.push(e)}h.node=null}return a},getNodes:function(a){for(var a=a.getElementsByTagName("node"),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){for(var a= | |
2262 a.getElementsByTagName("way"),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; | |
2263 a.nodes[0]==a.nodes[a.nodes.length-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, | |
2264 [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, | |
2265 "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, | |
2266 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", | |
2267 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=OpenLayers.Class({id:null,control:null,map:null,keyMask:null,active:!1,evt:null,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:0))== | |
2268 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=!1;return!0},callback:function(a,b){a&&this.callbacks[a]&&this.callbacks[a].apply(this.control,b)},register:function(a,b){this.map.events.registerPriority(a, | |
2269 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},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.Drag=OpenLayers.Class(OpenLayers.Handler,{started:!1,stopDown:!0,dragging:!1,touch:!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}})}}}, | |
2270 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.stop(a),this.oldOnselectstart||(this.oldOnselectstart=document.onselectstart?document.onselectstart:OpenLayers.Function.True),document.onselectstart=OpenLayers.Function.False,b=!this.stopDown):(this.started= | |
2271 !1,this.last=this.start=null);return b},dragmove:function(a){this.lastMoveEvt=a;if(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= | |
2272 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(){},move:function(){}, | |
2273 up:function(){},out:function(){},mousedown:function(a){return this.dragstart(a)},touchstart:function(a){this.touch||(this.touch=!0,this.map.events.un({mousedown:this.mousedown,mouseup:this.mouseup,mousemove:this.mousemove,click:this.click,scope:this}));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)}, | |
2274 touchend:function(a){a.xy=this.last;return this.dragend(a)},mouseout:function(a){if(this.started&&OpenLayers.Util.mouseLeft(a,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(){return this.start== | |
2275 this.last},activate:function(){var a=!1;OpenLayers.Handler.prototype.activate.apply(this,arguments)&&(this.dragging=!1,a=!0);return a},deactivate:function(){var a=!1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.dragging=this.started=this.touch=!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, | |
2276 "olDragDown");this.documentEvents=!0;OpenLayers.Event.observe(document,"mousemove",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.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,touch:!1,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= | |
2277 b},touchstart:function(a){this.touch||(this.touch=!0,this.map.events.un({mousedown:this.mousedown,mouseup:this.mouseup,mousemove:this.mousemove,click:this.click,dblclick:this.dblclick,scope:this}));return OpenLayers.Event.isMultiTouch(a)?!0:this.mousedown(a)},touchmove:function(a){OpenLayers.Event.stop(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)? | |
2278 !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;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"== | |
2279 b;if((this.feature=this.layer.getFeatureFromEvent(a))&&!this.feature.layer)this.feature=null;this.lastFeature&&!this.lastFeature.layer&&(this.lastFeature=null);this.feature?("touchstart"===b&&OpenLayers.Event.stop(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&& | |
2280 (d&&a||e)&&this.triggerCallback(b,"out",[this.lastFeature]),this.feature=null)):this.lastFeature&&(d||e)&&this.triggerCallback(b,"out",[this.lastFeature]);return c},triggerCallback:function(a,b,c){(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.callback(b,c))},activate:function(){var a=!1;OpenLayers.Handler.prototype.activate.apply(this,arguments)&&(this.moveLayerToTop(), | |
2281 this.map.events.on({removelayer:this.handleMapEvents,changelayer:this.handleMapEvents,scope:this}),a=!0);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.touch=!1,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()}, | |
2282 moveLayerToTop:function(){this.layer.setZIndex(Math.max(this.map.Z_INDEX_BASE.Feature-1,this.layer.getZIndex())+1)},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.Control.DragFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,onStart:function(){},onDrag:function(){},onComplete:function(){},onEnter:function(){},onLeave:function(){},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, | |
2283 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= | |
2284 !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, | |
2285 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* | |
2286 (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(){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)}, | |
2287 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.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"]= | |
2288 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, | |
2289 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();if(!this.renderer|| | |
2290 !this.renderer.supported())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(), | |
2291 this.protocol=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()));for(var a=OpenLayers.Layer.prototype.clone.apply(this,[a]),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()&& | |
2292 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, | |
2293 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(){this.drawn=!1;if(this.strategies){var a,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, | |
2294 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+parseInt(this.map.layerContainerDiv.style.left,10),e=-Math.round(e),d=d+parseInt(this.map.layerContainerDiv.style.top,10),d=-Math.round(d);this.div.style.left=e+"px";this.div.style.top= | |
2295 d+"px";d=this.renderer.setExtent(this.map.getExtent().scale(this.ratio),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){this.drawn=!0;f=0;for(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); | |
2296 var b=this.div.style.display;b!=this.renderer.root.style.display&&(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 "+ | |
2297 this.geometryType.prototype.CLASS_NAME);g.layer=this;!g.style&&this.style&&(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); | |
2298 OpenLayers.Util.isArray(a)||(a=[a]);a===this.selectedFeatures&&(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, | |
2299 e)&&OpenLayers.Util.removeItem(this.selectedFeatures,e);c&&this.events.triggerEvent("featureremoved",{feature:e})}c&&this.events.triggerEvent("featuresremoved",{features:a})}},removeAllFeatures:function(a){var a=!a||!a.silent,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(); | |
2300 this.features=[];this.unrenderedFeatures={};this.selectedFeatures=[];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, | |
2301 b);!1===c||null===c?this.unrenderedFeatures[a.id]=a:delete this.unrenderedFeatures[a.id]}},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= | |
2302 null,d=0,e=this.features.length;d<e;++d)if(this.features[d][a]==b){c=this.features[d];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(){},preFeatureInsert:function(){},getDataExtent:function(){var a=null,b=this.features; | |
2303 if(b&&0<b.length)for(var c=null,d=0,e=b.length;d<e;d++)if(c=b[d].geometry)null===a&&(a=new OpenLayers.Bounds),a.extend(c.getBounds());return a},CLASS_NAME:"OpenLayers.Layer.Vector"});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); | |
2304 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, | |
2305 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= | |
2306 {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= | |
2307 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&& | |
2308 (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){for(var b=this.layers||[this.layer],c,d,e=0;e<b.length;++e){c=b[e];for(var f=c.selectedFeatures.length-1;0<=f;--f)d=c.selectedFeatures[f],(!a||a.except!=d)&&this.unselect(d)}},clickFeature:function(a){this.hover||(-1<OpenLayers.Util.indexOf(a.layer.selectedFeatures,a)?this.toggleSelect()? | |
2309 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(){!this.hover&&this.clickout&&this.unselectAll()},overFeature:function(a){var b=a.layer;this.hover&&(this.highlightOnly? | |
2310 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})&&(a._prevHighlighter=a._lastHighlighter, | |
2311 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=this.onBeforeSelect.call(this.scope, | |
2312 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",{feature:a});this.onUnselect.call(this.scope, | |
2313 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=d.features[f];h.getVisibility()&&(null== | |
2314 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();this.deactivate();this.layers&& | |
2315 (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.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, | |
2316 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)&& | |
2317 this.callback(a.type,[a])},CLASS_NAME:"OpenLayers.Handler.Keyboard"});OpenLayers.Control.ModifyFeature=OpenLayers.Class(OpenLayers.Control,{geometryTypes:null,clickout:!0,toggle:!0,standalone:!1,layer:null,feature:null,vertices:null,virtualVertices:null,selectControl:null,dragControl: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= | |
2318 a;this.vertices=[];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=this,d={geometryTypes:this.geometryTypes,clickout:this.clickout, | |
2319 toggle:this.toggle,onBeforeSelect:this.beforeSelectFeature,onSelect:this.selectFeature,onUnselect:this.unselectFeature,scope:this};!1===this.standalone&&(this.selectControl=new OpenLayers.Control.SelectFeature(a,d));this.dragControl=new OpenLayers.Control.DragFeature(a,{geometryTypes:["OpenLayers.Geometry.Point"],onStart:function(a,b){c.dragStart.apply(c,[a,b])},onDrag:function(a,b){c.dragVertex.apply(c,[a,b])},onComplete:function(a){c.dragComplete.apply(c,[a])},featureCallbacks:{over:function(a){(c.standalone!== | |
2320 true||a._sketch||c.feature===a)&&c.dragControl.overFeature.apply(c.dragControl,[a])}}});this.handlers={keyboard:new OpenLayers.Handler.Keyboard(this,{keydown:this.handleKeypress})}},destroy:function(){this.layer=null;this.standalone||this.selectControl.destroy();this.dragControl.destroy();OpenLayers.Control.prototype.destroy.apply(this,[])},activate:function(){return(this.standalone||this.selectControl.activate())&&this.handlers.keyboard.activate()&&OpenLayers.Control.prototype.activate.apply(this, | |
2321 arguments)},deactivate:function(){var a=!1;if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)){this.layer.removeFeatures(this.vertices,{silent:!0});this.layer.removeFeatures(this.virtualVertices,{silent:!0});this.vertices=[];this.dragControl.deactivate();var b=(a=this.feature)&&a.geometry&&a.layer;!1===this.standalone?(b&&this.selectControl.unselect.apply(this.selectControl,[a]),this.selectControl.deactivate()):b&&this.unselectFeature(a);this.handlers.keyboard.deactivate();a=!0}return a}, | |
2322 beforeSelectFeature:function(a){return this.layer.events.triggerEvent("beforefeaturemodified",{feature:a})},selectFeature:function(a){if(!this.standalone||!1!==this.beforeSelectFeature(a))this.feature=a,this.modified=!1,this.resetVertices(),this.dragControl.activate(),this.onModificationStart(this.feature);var b=a.modified;if(a.geometry&&(!b||!b.geometry))this._originalGeometry=a.geometry.clone()},unselectFeature:function(a){this.layer.removeFeatures(this.vertices,{silent:!0});this.vertices=[];this.layer.destroyFeatures(this.virtualVertices, | |
2323 {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.feature=null;this.dragControl.deactivate();this.onModificationEnd(a);this.layer.events.triggerEvent("afterfeaturemodified",{feature:a,modified:this.modified});this.modified=!1},dragStart:function(a,b){if(a!=this.feature&&(!a.geometry.parent&&a!=this.dragHandle&& | |
2324 a!=this.radiusHandle)&&(!1===this.standalone&&this.feature&&this.selectControl.clickFeature.apply(this.selectControl,[this.feature]),null==this.geometryTypes||-1!=OpenLayers.Util.indexOf(this.geometryTypes,a.geometry.CLASS_NAME)))this.standalone||this.selectControl.clickFeature.apply(this.selectControl,[a]),this.dragControl.overFeature.apply(this.dragControl,[a]),this.dragControl.lastPixel=b,this.dragControl.handlers.drag.started=!0,this.dragControl.handlers.drag.start=b,this.dragControl.handlers.drag.last= | |
2325 b},dragVertex:function(a,b){this.modified=!0;"OpenLayers.Geometry.Point"==this.feature.geometry.CLASS_NAME?(this.feature!=a&&(this.feature=a),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&& | |
2326 (this.layer.destroyFeatures([this.radiusHandle],{silent:!0}),this.radiusHandle=null)):a!==this.radiusHandle&&this.layer.events.triggerEvent("vertexmodified",{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:this.selectControl.renderIntent));this.layer.drawFeature(a)},dragComplete:function(){this.resetVertices();this.setFeatureState(); | |
2327 this.onModification(this.feature);this.layer.events.triggerEvent("featuremodified",{feature:this.feature})},setFeatureState:function(){if(this.feature.state!=OpenLayers.State.INSERT&&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(){this.dragControl.feature&&this.dragControl.outFeature(this.dragControl.feature); | |
2328 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&&(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& | |
2329 OpenLayers.Control.ModifyFeature.DRAG&&this.collectDragHandle(),this.mode&(OpenLayers.Control.ModifyFeature.ROTATE|OpenLayers.Control.ModifyFeature.RESIZE)&&this.collectRadiusHandle(),this.mode&OpenLayers.Control.ModifyFeature.RESHAPE&&(this.mode&OpenLayers.Control.ModifyFeature.RESIZE||this.collectVertices()))},handleKeypress:function(a){var b=a.keyCode;if(this.feature&&-1!=OpenLayers.Util.indexOf(this.deleteCodes,b)&&(b=this.dragControl.feature)&&-1!=OpenLayers.Util.indexOf(this.vertices,b)&&!this.dragControl.handlers.drag.dragging&& | |
2330 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,this.standalone?void 0:this.selectControl.renderIntent),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"== | |
2331 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=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){d=0;for(f=c.components.length;d<f-1;++d){e=c.components[d]; | |
2332 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),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= | |
2333 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,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), | |
2334 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&OpenLayers.Control.ModifyFeature.ROTATE;b.move=function(b,c){OpenLayers.Geometry.Point.prototype.move.call(this,b,c);var j=this.x-d.x,k=this.y-d.y,l=j-b,m=k-c;if(g){var n=Math.atan2(m,l),n=Math.atan2(k,j)-n,n=n*(180/Math.PI);a.rotate(n,d)}if(e){var o;f?(k/=m,o=j/l/k):(l=Math.sqrt(l*l+m*m),k=Math.sqrt(j* | |
2335 j+k*k)/l);a.resize(k,d,o)}};c._sketch=!0;this.radiusHandle=c;this.radiusHandle.renderIntent=this.vertexRenderIntent;this.layer.addFeatures([this.radiusHandle],{silent:!0})},setMap:function(a){this.standalone||this.selectControl.setMap(a);this.dragControl.setMap(a);OpenLayers.Control.prototype.setMap.apply(this,arguments)},CLASS_NAME:"OpenLayers.Control.ModifyFeature"});OpenLayers.Control.ModifyFeature.RESHAPE=1;OpenLayers.Control.ModifyFeature.RESIZE=2;OpenLayers.Control.ModifyFeature.ROTATE=4; | |
2336 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>', | |
2337 metadata:null,type:"Road",culture:"en-US",metadataParams:null,tileOptions:null,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="_callback_"+this.id.replace(/\./g,"_");window[this._callbackId]=OpenLayers.Function.bind(OpenLayers.Layer.Bing.processMetadata, | |
2338 this);var a=OpenLayers.Util.applyDefaults({key:this.key,jsonp:this._callbackId,include:"ImageryProviders"},this.metadataParams),a="http://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)},initLayer:function(){var a=this.metadata.resourceSets[0].resources[0],b=a.imageUrl.replace("{quadkey}","${quadkey}"), | |
2339 b=b.replace("{culture}",this.culture);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)},!0)},getURL:function(a){if(this.url){for(var b=this.getXYZ(a),a=b.x,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= | |
2340 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(),new OpenLayers.Projection("EPSG:4326")),b=b.imageryProviders,d=OpenLayers.Util.indexOf(this.serverResolutions,this.getServerResolution()),e="",f,g,h,i,j,k,l;g=0;for(h=b.length;g<h;++g){f=b[g];i=0;for(j=f.coverageAreas.length;i< | |
2341 j;++i)l=f.coverageAreas[i],k=OpenLayers.Bounds.fromArray(l.bbox,!0),c.intersectsBounds(k)&&(d<=l.zoomMax&&d>=l.zoomMin)&&(e+=f.attribution+" ")}this.attribution=OpenLayers.String.format(this.attributionTemplate,{type:this.type.toLowerCase(),logo:a.brandLogoUri,copyrights:e});this.map&&this.map.events.triggerEvent("changelayer",{layer:this,property:"attribution"})}},setMap:function(){OpenLayers.Layer.XYZ.prototype.setMap.apply(this,arguments);this.updateAttribution();this.map.events.register("moveend", | |
2342 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,arguments)},CLASS_NAME:"OpenLayers.Layer.Bing"}); | |
2343 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.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, | |
2344 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(); | |
2345 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),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- | |
2346 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,i=0;i<d;++i)for(var f=e+i*this.dx,j=0;j<b;++j)h=c+j*this.dy,h=new OpenLayers.Geometry.Point(f,h),this.rotation&&h.rotate(this.rotation,a),g[i*b+j]=new OpenLayers.Feature.Vector(h);this.destroyFeatures(this.features,{silent:!0});this.addFeatures(g,{silent:!0})}},invalidBounds:function(){return!this.gridBounds|| | |
2347 !this.gridBounds.containsBounds(this.getViewBounds())},CLASS_NAME:"OpenLayers.Layer.PointGrid"});OpenLayers.Handler.MouseWheel=OpenLayers.Class(OpenLayers.Handler,{wheelListener:null,mousePosition:null,interval:0,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=!1,c=!1,d=!1,e= | |
2348 OpenLayers.Event.element(a);null!=e&&!d&&!b;){if(!b)try{var f=e.currentStyle?e.currentStyle.overflow:document.defaultView.getComputedStyle(e,null).getPropertyValue("overflow"),b=f&&"auto"==f||"scroll"==f}catch(g){}if(!c)for(var d=0,h=this.map.layers.length;d<h;d++)if(e==this.map.layers[d].div||e==this.map.layers[d].pane){c=!0;break}d=e==this.map.div;e=e.parentNode}!b&&d&&(c&&((b=0,a||(a=window.event),a.wheelDelta?(b=a.wheelDelta/120,window.opera&&9.2>window.opera.version()&&(b=-b)):a.detail&&(b=-a.detail/ | |
2349 3),this.delta+=b,this.interval)?(window.clearTimeout(this._timeoutId),this._timeoutId=window.setTimeout(OpenLayers.Function.bind(function(){this.wheelZoom(a)},this),this.interval)):this.wheelZoom(a)),OpenLayers.Event.stop(a))}},wheelZoom:function(a){var b=this.delta;this.delta=0;b&&(this.mousePosition&&(a.xy=this.mousePosition),a.xy||(a.xy=this.map.getPixelFromLonLat(this.map.getCenter())),0>b?this.callback("down",[a,this.cumulative?b:-1]):this.callback("up",[a,this.cumulative?b:1]))},mousemove:function(a){this.mousePosition= | |
2350 a.xy},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,"DOMMouseScroll",b);OpenLayers.Event.stopObserving(window,"mousewheel", | |
2351 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= | |
2352 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"== | |
2353 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({}, | |
2354 this.context);return new OpenLayers.Rule(a)},CLASS_NAME:"OpenLayers.Rule"});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= | |
2355 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.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= | |
2356 {};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){a=this.writeNode(OpenLayers.Util.isArray(a)?"wfs:FeatureCollection":"gml:featureMember",a);this.setAttributeNS(a,this.namespaces.xsi,"xsi:schemaLocation",this.schemaLocation); | |
2357 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= | |
2358 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"); | |
2359 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}, | |
2360 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, | |
2361 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, | |
2362 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", | |
2363 {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}, | |
2364 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){return OpenLayers.Format.GML.v2.prototype.readNode.apply(this,[a,b])},readers:{wfs:OpenLayers.Util.applyDefaults({WFS_TransactionResponse:function(a, | |
2365 b){b.insertIds=[];b.success=!1;this.readChildNodes(a,b)},InsertResult:function(a,b){var c={fids:[]};this.readChildNodes(a,c);b.insertIds.push(c.fids[0])},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}, | |
2366 writers:{wfs:OpenLayers.Util.applyDefaults({Query:function(a){var a=OpenLayers.Util.extend({featureNS:this.featureNS,featurePrefix:this.featurePrefix,featureType:this.featureType,srsName:this.srsName,srsNameInQuery:this.srsNameInQuery},a),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< | |
2367 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, | |
2368 0,b);this.indices[b]=this.getZIndex(a);return this.getNextElement(d)},remove:function(a){var a=a.id,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; | |
2369 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"}); | |
2370 OpenLayers.ElementsIndexer.IndexingMethods={Z_ORDER:function(a,b,c){var b=a.getZIndex(b),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}}; | |
2371 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); | |
2372 this.root.appendChild(this.textRoot);this.rendererRoot.appendChild(this.root);this.container.appendChild(this.rendererRoot);if(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&& | |
2373 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(){},drawGeometry:function(a, | |
2374 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));if(!1==e&&(b=document.getElementById(a.id)))b._style.backgroundGraphic&&(d=!0),b.parentNode.removeChild(b); | |
2375 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); | |
2376 this.postDraw(a);return b.complete},redrawBackgroundNode:function(a,b,c){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, | |
2377 b,c,null)},drawGeometryNode:function(a,b,c){var c=c||a._style,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; | |
2378 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(){},drawPoint:function(){},drawLineString:function(){},drawLinearRing:function(){},drawPolygon:function(){},drawRectangle:function(){},drawCircle:function(){},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)}, | |
2379 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 if((c=OpenLayers.Util.getElement(a.id))&&c.parentNode)if(c.geometry&& | |
2380 (c.geometry.destroy(),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(){},createNode:function(){},moveRoot:function(a){var b=this.root; | |
2381 a.root.parentNode==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){var a=a||window.location.href,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&& | |
2382 "OpenLayers.Control.ArgParser"==d.CLASS_NAME){d.displayProjection!=this.displayProjection&&(this.displayProjection=d.displayProjection);break}}if(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), | |
2383 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); | |
2384 "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)?(this.base=document.location.href,OpenLayers.Control.prototype.initialize.apply(this,[a]),null!=this.element&&(this.element=OpenLayers.Util.getElement(this.element))):(OpenLayers.Control.prototype.initialize.apply(this,[c]),this.element=OpenLayers.Util.getElement(a), | |
2385 this.base=b||document.location.href)},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!= | |
2386 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, | |
2387 changebaselayer:this.updateLink,scope:this});this.updateLink();return this.div},updateLink:function(){var a=this.anchor?"#":"?",b=this.base;-1!=b.indexOf(a)&&(b=b.substring(0,b.indexOf(a)));b+=a+OpenLayers.Util.getParameterString(this.createParams());this.anchor&&!this.element?window.location.href=b:this.element.href=b},createParams:function(a,b,c){var a=a||this.map.getCenter(),d=OpenLayers.Util.getParameters(this.base);if(a){d.zoom=b||this.map.getZoom();b=a.lat;a=a.lon;this.displayProjection&&(b= | |
2388 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;for(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){var a=this.adjustBounds(a),b=this.getServerResolution(), | |
2389 c=Math.round((a.left-this.tileOrigin.lon)/(b*this.tileSize.w)),a=Math.round((a.bottom-this.tileOrigin.lat)/(b*this.tileSize.h)),c=this.serviceVersion+"/"+this.layername+"/"+this.getServerZoom()+"/"+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.Strategy.Fixed=OpenLayers.Class(OpenLayers.Strategy,{preload:!1,activate:function(){if(OpenLayers.Strategy.prototype.activate.apply(this,arguments)){this.layer.events.on({refresh:this.load,scope:this});if(!0==this.layer.visibility||this.preload)this.load();else this.layer.events.on({visibilitychanged:this.load,scope:this});return!0}return!1},deactivate:function(){var a=OpenLayers.Strategy.prototype.deactivate.call(this);a&&this.layer.events.un({refresh:this.load,visibilitychanged:this.load, | |
2390 scope:this});return a},load:function(a){var b=this.layer;b.events.triggerEvent("loadstart");b.protocol.read(OpenLayers.Util.applyDefaults({callback:OpenLayers.Function.bind(this.merge,this,b.map.getProjectionObject()),filter:b.filter},a));b.events.un({visibilitychanged:this.load,scope:this})},merge:function(a,b){var c=this.layer;c.destroyFeatures();var d=b.features;if(d&&0<d.length){if(!a.equals(c.projection))for(var e,f=0,g=d.length;f<g;++f)(e=d[f].geometry)&&e.transform(c.projection,a);c.addFeatures(d)}c.events.triggerEvent("loadend")}, | |
2391 CLASS_NAME:"OpenLayers.Strategy.Fixed"});OpenLayers.Control.Zoom=OpenLayers.Class(OpenLayers.Control,{zoomInText:"+",zoomInId:"olZoomInLink",zoomOutText:"-",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), | |
2392 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; | |
2393 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];if(f=d.geometry){if("OpenLayers.Geometry.Point"!=f.CLASS_NAME)throw new TypeError("Only features with point geometries are supported.");}else f=d.lonlat,f=new OpenLayers.Geometry.Point(f.lon,f.lat);if(0<g){d=null!=this.dataFrom? | |
2394 a[g+this.dataFrom].data||a[g+this.dataFrom].attributes:null;var i=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,i)}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){var a=OpenLayers.Util.applyDefaults(a,OpenLayers.Protocol.WFS.DEFAULTS),b=OpenLayers.Protocol.WFS["v"+a.version.replace(/\./g,"_")];if(!b)throw"Unsupported WFS version: "+a.version;return new b(a)}; | |
2395 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;for(var a=0,b=this.markers.length;a<b;a++)this.markers[a].setOpacity(this.opacity)}},moveTo:function(a,b,c){OpenLayers.Layer.prototype.moveTo.apply(this, | |
2396 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])}, | |
2397 drawMarker:function(a){var b=this.map.getLayerPxFromLonLat(a.lonlat);null==b?a.display(!1):a.isDrawn()?a.icon&&a.icon.moveTo(b):this.div.appendChild(a.draw(b))},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,{slideFactor:50,slideRatio:null,direction:null,type:OpenLayers.Control.TYPE_BUTTON,initialize:function(a,b){this.direction=a;this.CLASS_NAME+=this.direction;OpenLayers.Control.prototype.initialize.apply(this,[b])},trigger:function(){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")); | |
2398 break;case OpenLayers.Control.Pan.SOUTH:this.map.pan(0,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){var a=OpenLayers.Util.applyDefaults(a,OpenLayers.Format.CSWGetDomain.DEFAULTS),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== | |
2399 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, | |
2400 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)}, | |
2401 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= | |
2402 this.createElementNSPlus("csw:GetDomain",{attributes:{service:"CSW",version:this.version}});if(a.PropertyName||this.PropertyName)this.writeNode("csw:PropertyName",a.PropertyName||this.PropertyName,b);else if(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", | |
2403 {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); | |
2404 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= | |
2405 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, | |
2406 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= | |
2407 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", | |
2408 {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= | |
2409 {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,i,j,k,l,m,n=this.precedence.length,o=new OpenLayers.LonLat(b.x,b.y),p=0,q=g.length;p<q;++p)if(h=g[p],h!==this.feature&&(!h._sketch&&h.state!==OpenLayers.State.DELETE&&(!a.filter||a.filter.evaluate(h)))&&h.atPoint(o,d,d))for(var r=0,s=Math.min(e.rank+ | |
2410 1,n);r<s;++r)if(i=this.precedence[r],a[i])if("edge"===i){if(j=h.geometry.distanceTo(b,{details:!0}),l=j.distance,l<=c[i]&&l<e.dist){e={rank:r,dist:l,x:j.x0,y:j.y0};f=!0;break}}else{j=h.geometry.getVertices("node"===i);m=!1;for(var t=0,u=j.length;t<u;++t)if(k=j[t],l=k.distanceTo(b),l<=c[i]&&(r<e.rank||r===e.rank&&l<e.dist))e={rank:r,dist:l,x:k.x,y:k.y},m=f=!0;if(m)break}return f?e:null},getGeoTolerance:function(a,b){b!==this.resolution&&(this.resolution=b,this.geoToleranceCache={});var c=this.geoToleranceCache[a]; | |
2411 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.Date={toISOString:function(){if("toISOString"in Date.prototype)return function(a){return a.toISOString()};var a=function(a,c){for(var d=a+"";d.length<c;)d="0"+d;return d};return function(b){return isNaN(b.getTime())?"Invalid Date":b.getUTCFullYear()+"-"+a(b.getUTCMonth()+1,2)+"-"+a(b.getUTCDate(),2)+"T"+a(b.getUTCHours(),2)+":"+a(b.getUTCMinutes(),2)+":"+a(b.getUTCSeconds(),2)+"."+a(b.getUTCMilliseconds(),3)+"Z"}}(),parse:function(a){var b;if((a=a.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))|Z)?$/))&& | |
2412 (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,b=new Date(b.getTime()+-1E3*(60*60*c+60*a)))}}else b=new Date("invalid");return b}};(function(){function a(){this._object=f&&!i?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/))&& | |
2413 (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(i){}try{a.statusText=a._object.statusText}catch(r){}}function e(a){a._object.onreadystatechange=new window.Function}var f=window.XMLHttpRequest,g=!!window.controllers,h=window.document.all&&!window.opera,i=h&&window.navigator.userAgent.match(/MSIE 7.0/); | |
2414 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,i,m,n){delete this._headers;arguments.length<3&&(i=true);this._async=i;var o= | |
2415 this,p=this.readyState,q;if(h&&i){q=function(){if(p!=b.DONE){e(o);o.abort()}};window.attachEvent("onunload",q)}b.onopen&&b.onopen.apply(this,arguments);arguments.length>4?this._object.open(a,f,i,m,n):arguments.length>3?this._object.open(a,f,i,m):this._object.open(a,f,i);this.readyState=b.OPENED;c(this);this._object.onreadystatechange=function(){if(!g||i){o.readyState=o._object.readyState;d(o);if(o._aborted)o.readyState=b.UNSENT;else{if(o.readyState==b.DONE){delete o._data;e(o);h&&i&&window.detachEvent("onunload", | |
2416 q)}p!=o.readyState&&c(o);p=o.readyState}}}};b.prototype.send=function(a){b.onsend&&b.onsend.apply(this,arguments);arguments.length||(a=null);if(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:{this._object.send(this._data);if(g&&!this._async){this.readyState=b.OPENED;for(d(this);this.readyState<b.DONE;){this.readyState++;c(this);if(this._aborted)break a}}}}; | |
2417 b.prototype.abort=function(){b.onabort&&b.onabort.apply(this,arguments);if(this.readyState>b.UNSENT)this._aborted=true;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){if(!this._headers)this._headers={};this._headers[a]=b;return this._object.setRequestHeader(a, | |
2418 b)};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];d++)if(e[0]==a&&e[1]==b&&e[2]==c)break;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(){}, | |
2419 initEvent:function(){}};a.type=="readystatechange"&&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], | |
2420 b[4]);delete a.__func});OpenLayers.Request.XMLHttpRequest=b})();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= | |
2421 {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&& | |
2422 (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, | |
2423 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= | |
2424 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= | |
2425 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 i=32*h,j=this.getElementsByTagNameNS(e,"*","Icon")[0];if(j){var k=this.parseProperty(j,"*","href");if(k){var l=this.parseProperty(j,"*","w"),m=this.parseProperty(j, | |
2426 "*","h");OpenLayers.String.startsWith(k,"http://maps.google.com/mapfiles/kml")&&(!l&&!m)&&(m=l=64,h/=2);l=l||m;m=m||l;l&&(d=parseInt(l)*h);m&&(i=parseInt(m)*h);if(m=k.match(this.regExes.kmlIconPalette))l=m[1],m=m[2],k=this.parseProperty(j,"*","x"),j=this.parseProperty(j,"*","y"),k="http://maps.google.com/mapfiles/kml/pal"+l+"/icon"+(8*(j?7-j/32:7)+(k?k/32:0))+m;b.graphicOpacity=1;b.externalGraphic=k}}if(e=this.getElementsByTagNameNS(e,"*","hotSpot")[0])k=parseFloat(e.getAttribute("x")),j=parseFloat(e.getAttribute("y")), | |
2427 l=e.getAttribute("xunits"),"pixels"==l?b.graphicXOffset=-k*h:"insetPixels"==l?b.graphicXOffset=-d+k*h:"fraction"==l&&(b.graphicXOffset=-d*k),e=e.getAttribute("yunits"),"pixels"==e?b.graphicYOffset=-i+j*h+1:"insetPixels"==e?b.graphicYOffset=-(j*h)+1:"fraction"==e&&(b.graphicYOffset=-i*(1-j)+1);b.graphicWidth=d;b.graphicHeight=i;break;case "balloonstyle":(e=OpenLayers.Util.getXmlNodeValue(e))&&(b.balloonStyle=e.replace(this.regExes.straightBracket,"${$1}"));break;case "labelstyle":if(d=this.parseProperty(e, | |
2428 "*","color"),d=this.parseKmlColor(d))b.fontColor=d.color,b.fontOpacity=d.opacity}!b.strokeColor&&b.fillColor&&(b.strokeColor=b.fillColor);if((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 i=f[g],j=this.parseProperty(i,"*","key");(i=this.parseProperty(i,"*","styleUrl"))&&"normal"==j&&(this.styles[(b.styleBaseUrl||"")+"#"+e]=this.styles[(b.styleBaseUrl|| | |
2429 "")+i])}},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];if(h&&(h=this.parseStyle(h)))g.style=OpenLayers.Util.extend(g.style,h)}if(this.extractTracks){if((f=this.getElementsByTagNameNS(f,this.namespaces.gx,"Track"))&&0<f.length)g={features:[],feature:g}, | |
2430 this.readNode(f[0],g),0<g.features.length&&c.push.apply(c,g.features)}else 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< | |
2431 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, | |
2432 i,e=0,f=c.whens.length;e<f;++e){h=b.feature.clone();h.fid=b.feature.fid||b.feature.id;i=c.points[e];h.geometry=i;"z"in i&&(h.attributes.altitude=i.z);this.internalProjection&&this.externalProjection&&h.geometry.transform(this.externalProjection,this.internalProjection);if(this.trackAttributes){i=0;for(var j=this.trackAttributes.length;i<j;++i)h.attributes[d]=c.attributes[this.trackAttributes[i]][e]}h.attributes.when=c.whens[e];h.attributes.trackId=b.feature.id;g&&(i=c.angles[e],h.attributes.heading= | |
2433 parseFloat(i[0]),h.attributes.tilt=parseFloat(i[1]),h.attributes.roll=parseFloat(i[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"], | |
2434 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")|| | |
2435 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, | |
2436 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,i=0;i<e;++i)if(g= | |
2437 d[i].split(","),h=g.length,1<h)2==g.length&&(g[2]=null),f[i]=new OpenLayers.Geometry.Point(g[0],g[1],g[2]);else throw"Bad LineString point coordinates: "+d[i];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){var a=this.getElementsByTagNameNS(a,this.internalns,"LinearRing"),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]= | |
2438 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=this.parseGeometry[(a.prefix?a.nodeName.split(":")[1]:a.nodeName).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]));for(var d,e,f,a=a.childNodes,c=0,g= | |
2439 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"); | |
2440 var h={},i=e.getElementsByTagName("value");i.length&&(h.value=this.getChildValue(i[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= | |
2441 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&& | |
2442 (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");b.appendChild(this.createTextNode(a.style&&a.style.label?a.style.label:a.attributes.name||a.id));var c=this.createElementNS(this.kmlns,"description");c.appendChild(this.createTextNode(a.attributes.description||this.placemarksDesc));var d=this.createElementNS(this.kmlns,"Placemark");null!= | |
2443 a.fid&&d.setAttribute("id",a.fid);d.appendChild(b);d.appendChild(c);b=this.buildGeometryNode(a.geometry);d.appendChild(b);a.attributes&&(a=this.buildExtendedData(a.attributes))&&d.appendChild(a);return d},buildGeometryNode:function(a){var b=a.CLASS_NAME,b=this.buildGeometry[b.substring(b.lastIndexOf(".")+1).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},multipoint:function(a){return this.buildGeometry.collection.apply(this, | |
2444 [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){for(var b=this.createElementNS(this.kmlns,"Polygon"),a=a.components,c,d,e=0,f=a.length;e<f;++e)c=0==e?"outerBoundaryIs":"innerBoundaryIs", | |
2445 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=this.createElementNS(this.kmlns,"coordinates"), | |
2446 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"),c;for(c in a)if(a[c]&&"name"!=c&&"description"!= | |
2447 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)?null:b}, | |
2448 CLASS_NAME:"OpenLayers.Format.KML"});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, | |
2449 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; | |
2450 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= | |
2451 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!= | |
2452 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; | |
2453 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= | |
2454 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), | |
2455 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, | |
2456 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= | |
2457 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= | |
2458 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._onImageLoad))},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}), | |
2459 OpenLayers.Event.observe(e,"load",e._onImgLoad)}},getSafeContentSize:function(a){var a=a.clone(),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- | |
2460 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- | |
2461 this.map.paddingForPopups.right-c-b);a.h=Math.min(a.h,d)}return a},getContentDivPadding:function(){var a=this._contentDivPadding;if(!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, | |
2462 "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, | |
2463 "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); | |
2464 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)}, | |
2465 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(){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"; | |
2466 OpenLayers.Popup.OPACITY=1;OpenLayers.Popup.BORDER="0px";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)}, | |
2467 moveTo:function(a){var b=this.relativePosition;this.relativePosition=this.calculateRelativePosition(a);a=this.calculateNewPx(a);OpenLayers.Popup.prototype.moveTo.apply(this,Array(a));this.relativePosition!=b&&this.updateRelativePosition()},setSize:function(a){OpenLayers.Popup.prototype.setSize.apply(this,arguments);this.lonlat&&this.map&&this.moveTo(this.map.getLayerPxFromLonLat(this.lonlat))},calculateRelativePosition:function(a){a=this.map.getLonLatFromLayerPx(a);a=this.map.getExtent().determineQuadrant(a); | |
2468 return OpenLayers.Bounds.oppositeQuadrant(a)},updateRelativePosition:function(){},calculateNewPx:function(a){var a=a.offset(this.anchor.offset),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"});/* | |
2469 Apache 2 | |
2470 | |
2471 Contains portions of Rico <http://openrico.org/> | |
2472 | |
2473 Copyright 2005 Sabre Airline Solutions | |
2474 | |
2475 Licensed under the Apache License, Version 2.0 (the "License"); you | |
2476 may not use this file except in compliance with the License. You | |
2477 may obtain a copy of the License at | |
2478 | |
2479 http://www.apache.org/licenses/LICENSE-2.0 | |
2480 | |
2481 Unless required by applicable law or agreed to in writing, software | |
2482 distributed under the License is distributed on an "AS IS" BASIS, | |
2483 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
2484 implied. See the License for the specific language governing | |
2485 permissions and limitations under the License. | |
2486 */ | |
2487 OpenLayers.Console.warn("OpenLayers.Rico is deprecated");OpenLayers.Rico=OpenLayers.Rico||{}; | |
2488 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)}, | |
2489 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("+ | |
2490 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()}}); | |
2491 OpenLayers.Rico.Color.createFromHex=function(a){if(4==a.length)for(var b=a,a="#",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))}; | |
2492 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, | |
2493 255,255)}; | |
2494 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{var a=6*(a-Math.floor(a)),g=a-Math.floor(a),h=c*(1-b),i=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*i+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*i+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*i+0.5}}return{r:parseInt(d),g:parseInt(e), | |
2495 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.Console.warn("OpenLayers.Rico is deprecated");OpenLayers.Rico=OpenLayers.Rico||{}; | |
2496 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="+ | |
2497 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, | |
2498 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, | |
2499 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= | |
2500 "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= | |
2501 !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")? | |
2502 "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(): | |
2503 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? | |
2504 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)); | |
2505 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.Popup.AnchoredBubble=OpenLayers.Class(OpenLayers.Popup.Anchored,{rounded:!1,initialize:function(a,b,c,d,e,f,g){OpenLayers.Console.warn("AnchoredBubble is deprecated");this.padding=new OpenLayers.Bounds(0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,0,OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);OpenLayers.Popup.Anchored.prototype.initialize.apply(this,arguments)},draw:function(a){OpenLayers.Popup.Anchored.prototype.draw.apply(this,arguments);this.setContentHTML();this.setBackgroundColor(); | |
2506 this.setOpacity();return this.div},updateRelativePosition:function(){this.setRicoCorners()},setSize:function(a){OpenLayers.Popup.Anchored.prototype.setSize.apply(this,arguments);this.setRicoCorners()},setBackgroundColor:function(a){void 0!=a&&(this.backgroundColor=a);null!=this.div&&null!=this.contentDiv&&(this.div.style.background="transparent",OpenLayers.Rico.Corner.changeColor(this.groupDiv,this.backgroundColor))},setOpacity:function(a){OpenLayers.Popup.Anchored.prototype.setOpacity.call(this, | |
2507 a);null!=this.div&&null!=this.groupDiv&&OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,this.opacity)},setBorder:function(){this.border=0},setRicoCorners:function(){var a={corners:this.getCornersToRound(this.relativePosition),color:this.backgroundColor,bgColor:"transparent",blend:!1};this.rounded?(OpenLayers.Rico.Corner.reRound(this.groupDiv,a),this.setBackgroundColor(),this.setOpacity()):(OpenLayers.Rico.Corner.round(this.div,a),this.rounded=!0)},getCornersToRound:function(){var a=["tl","tr", | |
2508 "bl","br"],b=OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);OpenLayers.Util.removeItem(a,b);return a.join(" ")},CLASS_NAME:"OpenLayers.Popup.AnchoredBubble"});OpenLayers.Popup.AnchoredBubble.CORNER_SIZE=5;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, | |
2509 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"}), | |
2510 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= | |
2511 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;if(!c||!c.documentElement)c=a.responseText;if(!c||0>=c.length)return null;c=null!==this.readFormat?this.readFormat.read(c): | |
2512 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)}); | |
2513 return c},handleCommit:function(a,b){if(b.callback){var c=a.priv,d=c.responseXML;if(!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", | |
2514 {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()}, | |
2515 CLASS_NAME:"OpenLayers.Protocol.WFS.v1"});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,touch:!1,lastTouchPx:null,initialize:function(a,b,c){if(!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, | |
2516 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(); | |
2517 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;this.touch=!1;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= | |
2518 !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(); | |
2519 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.touch||(this.touch=!0,this.map.events.un({mousedown:this.mousedown,mouseup:this.mouseup,mousemove:this.mousemove,click:this.click,dblclick:this.dblclick, | |
2520 scope:this}));this.lastTouchPx=a.xy;return this.down(a)},mousemove:function(a){return this.move(a)},touchmove:function(a){this.lastTouchPx=a.xy;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); | |
2521 return!0},up:function(a){this.mouseDown=!1;this.stoppedDown=this.stopDown;return this.checkModifiers(a)&&(!this.lastUp||!this.lastUp.equals(a.xy))&&this.lastDown&&this.passesTolerance(this.lastDown,a.xy,this.pixelTolerance)?(this.touch&&this.modifyFeature(a.xy),this.persist&&this.destroyPersistedFeature(),this.lastUp=a.xy,this.finalize(),!this.stopUp):!0},mouseout:function(a){OpenLayers.Util.mouseLeft(a,this.map.viewPortDiv)&&(this.stoppedDown=this.stopDown,this.mouseDown=!1)},passesTolerance:function(a, | |
2522 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()]); | |
2523 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, | |
2524 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.line.geometry.components[this.getCurrentPointIndex()- | |
2525 1];c&&(!isNaN(c.x)&&!isNaN(c.y))&&this.insertXY(c.x+a,c.y+b)},insertDirectionLength:function(a,b){var a=a*(Math.PI/180),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];this.insertDirectionLength(180*Math.atan2(d.y-c.y,d.x-c.x)/Math.PI+a,b)}},getCurrentPointIndex:function(){return this.line.geometry.components.length-1},undo:function(){var a= | |
2526 this.line.geometry,b=a.components,c=this.getCurrentPointIndex()-1,b=b[c];if(a=a.removeComponent(b))this.redoStack||(this.redoStack=[]),this.redoStack.push(b),this.drawFeature();return a},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&&a[this.freehandToggle]?!this.freehand:this.freehand},modifyFeature:function(a,b){this.line||this.createFeature(a); | |
2527 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=this.line&&this.line.geometry;a&&this.multi&&(a=new OpenLayers.Geometry.MultiLineString([a]));return a}, | |
2528 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,a)},down:function(a){var b=this.stopDown;this.freehandMode(a)&&(b=!0,this.touch&& | |
2529 (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===this.maxVertices?(this.removePoint(),this.finalize()):this.addPoint(a.xy), | |
2530 !1;!this.touch&&(!this.mouseDown||this.stoppedDown)&&this.modifyFeature(a.xy,!!this.lastUp);return!0},up:function(a){if(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(),this.addPoint(a.xy),this.lastUp=a.xy,this.line.geometry.components.length=== | |
2531 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){var c=c||OpenLayers.Spherical.DEFAULT_RADIUS,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))}; | |
2532 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.cache,scope:this})},removeLayer:function(a){a.layer.events.un({tileloadstart:this.makeSameOrigin, | |
2533 tileloaded:this.cache,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}},cache:function(a){if(this.active&&window.localStorage&&(a=a.tile,a instanceof OpenLayers.Tile.Image&&"data:"!==a.url.substr(0,5)))try{var b=a.getCanvasContext();if(b){var c=OpenLayers.Control.CacheWrite.urlMap; | |
2534 window.localStorage.setItem("olCache_"+(c[a.url]||a.url),b.canvas.toDataURL(this.imageFormat));delete c[a.url]}}catch(d){(b=d.name||d.message)&&this.quotaRegEx.test(b)?this.events.triggerEvent("cachefull",{tile:a}):OpenLayers.Console.error(d.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&&this.map.events.un({addlayer:this.addLayer,removeLayer:this.removeLayer,scope:this});OpenLayers.Control.prototype.destroy.apply(this, | |
2535 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, | |
2536 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, | |
2537 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){e.format=a.formats[0].value;b=0;for(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){b=0;for(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&& | |
2538 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}), | |
2539 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= | |
2540 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)); | |
2541 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"}); | |
2542 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: | |
2543 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); | |
2544 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){d=0;for(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, | |
2545 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!= | |
2546 b.layers&&delete b.layers;void 0==b.layersContext&&(b.layersContext=[]);if(void 0!=c&&OpenLayers.Util.isArray(c)){a=0;for(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:"", | |
2547 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(), | |
2548 (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:[], | |
2549 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))}, | |
2550 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"); | |
2551 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, | |
2552 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, | |
2553 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= | |
2554 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, | |
2555 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); | |
2556 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"), | |
2557 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")|| | |
2558 ""},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, | |
2559 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", | |
2560 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)); | |
2561 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)); | |
2562 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"); | |
2563 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&& | |
2564 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), | |
2565 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", | |
2566 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), | |
2567 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()))); | |
2568 return c},write_wmc_Server:function(a){var a=a.server,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)for(var b=["width","height","format"],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= | |
2569 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"}: | |
2570 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", | |
2571 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, | |
2572 !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", | |
2573 "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)])}, | |
2574 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, | |
2575 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- | |
2576 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,j=-this.deceleration*Math.pow(a, | |
2577 2)/2+c*a,k=j*d,j=j*e,l,m;l=!1;0>=-this.deceleration*a+c&&(OpenLayers.Animation.stop(this.timerId),this.timerId=null,l=!0);a=k-g;m=j-h;g=k;h=j;b(a,m,l)}},this))},CLASS_NAME:"OpenLayers.Kinetic"});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, | |
2578 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;if(!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, | |
2579 this.formatOptions);this.map&&!this.projection.equals(this.map.getProjectionObject())&&(a.externalProjection=this.projection,a.internalProjection=this.map.getProjectionObject());for(var b=(new OpenLayers.Format.GeoRSS(a)).read(b),a=0,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.",i=f.attributes.link?f.attributes.link:"",f=f.geometry.getBounds().getCenterLonLat();e.icon= | |
2580 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 j='<div class="olLayerGeoRSSClose">[x]</div>',j=j+'<div class="olLayerGeoRSSTitle">';i&&(j+='<a class="link" href="'+i+'" target="_blank">');j+=g;i&&(j+="</a>");j+="</div>";j+='<div style="" class="olLayerGeoRSSDescription">';j+=h;j+="</div>";e.popupContentHTML=j}f=new OpenLayers.Feature(this,f,e);this.features.push(f); | |
2581 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?this:null;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])}, | |
2582 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, | |
2583 graphicName:"square"},read:function(a,b){var b=OpenLayers.Util.applyDefaults(b,this.options),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= | |
2584 {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, | |
2585 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= | |
2586 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= | |
2587 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, | |
2588 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, | |
2589 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, | |
2590 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))): | |
2591 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? | |
2592 (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); | |
2593 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, | |
2594 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), | |
2595 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= | |
2596 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", | |
2597 {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&& | |
2598 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= | |
2599 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){c=0;for(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", | |
2600 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,i,j=0,k=a.rules.length;j<k;++j)if(e=a.rules[j],e.symbolizers){f={};for(var l=0,m=e.symbolizers.length;l<m;++l)g=e.symbolizers[l],h=g.zIndex,h in f||(i=e.clone(),i.symbolizers=[],f[h]=i),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()); | |
2601 d.sort();j=0;for(k=d.length;j<k;++j)e=c[d[j]],0<e.length&&(i=a.clone(),i.rules=c[d[j]],this.writeNode("FeatureTypeStyle",i,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&& | |
2602 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< | |
2603 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", | |
2604 {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"!== | |
2605 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|| | |
2606 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= | |
2607 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", | |
2608 {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", | |
2609 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"); | |
2610 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", | |
2611 {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); | |
2612 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"), | |
2613 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", | |
2614 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? | |
2615 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);this.writeNode("Format",a.graphicFormat|| | |
2616 this.getGraphicFormat(a.externalGraphic),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, | |
2617 "sld:Size",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)); | |
2618 if(!this.noMagic&&this.params.TRANSPARENT&&"true"==this.params.TRANSPARENT.toString().toLowerCase()){if(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)&& | |
2619 !(!this.yx[a]&&!OpenLayers.Projection.defaults[a].yx)},getURL:function(a){var a=this.adjustBounds(a),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(),c=this.projection&&this.projection.equals(c)? | |
2620 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.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(){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){var b=b||a._style,c=c||a._options,d=parseFloat(a.getAttributeNS(null,"r")),e=1,f;if("OpenLayers.Geometry.Point"==a._geometryClass&&d){a.style.visibility="";if(!1===b.graphic)a.style.visibility="hidden";else if(b.externalGraphic){f=this.getPosition(a);b.graphicTitle&&(a.setAttributeNS(null,"title",b.graphicTitle),d=a.getElementsByTagName("title"),0<d.length?d[0].firstChild.textContent=b.graphicTitle:(d=this.nodeFactory(null,"title"),d.textContent=b.graphicTitle,a.appendChild(d)));b.graphicWidth&& | |
2634 b.graphicHeight&&a.setAttributeNS(null,"preserveAspectRatio","none");var d=b.graphicWidth||b.graphicHeight,g=b.graphicHeight||b.graphicWidth,d=d?d:2*b.pointRadius,g=g?g:2*b.pointRadius,h=void 0!=b.graphicYOffset?b.graphicYOffset:-(0.5*g),i=b.graphicOpacity||b.fillOpacity;a.setAttributeNS(null,"x",(f.x+(void 0!=b.graphicXOffset?b.graphicXOffset:-(0.5*d))).toFixed());a.setAttributeNS(null,"y",(f.y+h).toFixed());a.setAttributeNS(null,"width",d);a.setAttributeNS(null,"height",g);a.setAttributeNS(this.xlinkns, | |
2635 "href",b.externalGraphic);a.setAttributeNS(null,"style","opacity: "+i);a.onclick=OpenLayers.Renderer.SVG.preventDefault}else if(this.isComplexSymbol(b.graphicName)){var d=3*b.pointRadius,g=2*d,j=this.importSymbol(b.graphicName);f=this.getPosition(a);e=3*this.symbolMetrics[j.id][0]/g;h=a.parentNode;i=a.nextSibling;h&&h.removeChild(a);a.firstChild&&a.removeChild(a.firstChild);a.appendChild(j.firstChild.cloneNode(!0));a.setAttributeNS(null,"viewBox",j.getAttributeNS(null,"viewBox"));a.setAttributeNS(null, | |
2636 "width",g);a.setAttributeNS(null,"height",g);a.setAttributeNS(null,"x",f.x-d);a.setAttributeNS(null,"y",f.y-d);i?h.insertBefore(a,i):h&&h.appendChild(a)}else a.setAttributeNS(null,"r",b.pointRadius);d=b.rotation;if((void 0!==d||void 0!==a._rotation)&&f)a._rotation=d,d|=0,"svg"!==a.nodeName?a.setAttributeNS(null,"transform","rotate("+d+" "+f.x+" "+f.y+")"):(f=this.symbolMetrics[j.id],a.firstChild.setAttributeNS(null,"transform","rotate("+d+" "+f[1]+" "+f[2]+")"))}c.isFilled?(a.setAttributeNS(null, | |
2637 "fill",b.fillColor),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*e),a.setAttributeNS(null,"stroke-linecap",b.strokeLinecap||"round"),a.setAttributeNS(null,"stroke-linejoin","round"),b.strokeDashstyle&&a.setAttributeNS(null,"stroke-dasharray",this.dashStyle(b,e))):a.setAttributeNS(null,"stroke", | |
2638 "none");b.pointerEvents&&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, | |
2639 ",")}},createNode:function(a,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, | |
2640 b){return this.drawCircle(a,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? | |
2641 (a.setAttributeNS(null,"points",c.path),c.complete?a:null):!1},drawPolygon:function(a,b){for(var c="",d=!0,e=!0,f,g,h=0,i=b.components.length;h<i;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, | |
2642 "x",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;delete e.labelOutlineWidth;this.drawText(a,e,c)}var f=this.getResolution(),e=(c.x-this.featureDx)/f+this.left,g=c.y/f-this.top,d=d?this.LABEL_OUTLINE_SUFFIX:this.LABEL_ID_SUFFIX, | |
2643 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,"font-size",b.fontSize);b.fontWeight&&f.setAttributeNS(null, | |
2644 "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",OpenLayers.Renderer.SVG.LABEL_ALIGN[g[1]]||"central");for(var h= | |
2645 b.label.split("\n"),i=h.length;f.childNodes.length>i;)f.removeChild(f.lastChild);for(var j=0;j<i;j++){var k=this.nodeFactory(a+d+"_tspan_"+j,"tspan");!0===b.labelSelect&&(k._featureId=a,k._geometry=c,k._geometryClass=c.CLASS_NAME);!1===OpenLayers.IS_GECKO&&k.setAttributeNS(null,"baseline-shift",OpenLayers.Renderer.SVG.LABEL_VSHIFT[g[1]]||"-35%");k.setAttribute("x",e);if(0==j){var l=OpenLayers.Renderer.SVG.LABEL_VFACTOR[g[1]];null==l&&(l=-0.5);k.setAttribute("dy",l*(i-1)+"em")}else k.setAttribute("dy", | |
2646 "1em");k.textContent=""===h[j]?" ":h[j];k.parentNode||f.appendChild(k)}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}},clipLine:function(a,b){if(b.equals(a))return"";var c=this.getResolution(), | |
2647 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,i;if(h<-d||h>d)i=(c-g)/(h-f),h=0>h?-d:d,c=g+(h-f)*i;if(c<-e||c>e)i=(h-f)/(c-g),c=0>c?-e:e,h=f+(c-g)*i;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,a)?c+","+a:!1},getPosition:function(a){return{x:parseFloat(a.getAttributeNS(null, | |
2648 "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");var a=this.nodeFactory(b,"symbol"),e=this.nodeFactory(null,"polygon");a.appendChild(e);for(var c=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0),f=[],g,h,i=0;i<d.length;i+=2)g=d[i],h=d[i+1],c.left=Math.min(c.left, | |
2649 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,arguments);b||(b=a.target, | |
2650 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){a.preventDefault&&a.preventDefault()};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");this.writeNode("gml:boundedBy",a.getDataExtent(), | |
2660 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.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"), | |
2668 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* | |
2669 a*c[b],e=1;!0===this.geodesic&&(e=(this.map.getGeodesicPixelSize().w||1.0E-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],i=d/c[g],d=this.getBarLen(h),j=this.getBarLen(i),h=d/c[b]*c[f],i=j/c[b]*c[g],b=h/a/e,a=i/a/e;"visible"==this.eBottom.style.visibility&&(this.eBottom.style.width=Math.round(a)+"px",this.eBottom.innerHTML=j+" "+g);"visible"==this.eTop.style.visibility&&(this.eTop.style.width=Math.round(b)+ | |
2670 "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, | |
2671 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, | |
2672 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)}, | |
2673 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)}, | |
2674 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, | |
2675 [a])},getURL:function(a){function b(a,b){for(var a=""+a,c=[],d=0;d<b;++d)c.push("0");return c.join("").substring(0,b-a.length)+a}var c=this.getServerResolution(),d=this.maxExtent,e=this.tileSize,f=Math.round((a.left-d.left)/(c*e.w)),a=Math.round((a.bottom-d.bottom)/(c*e.h)),c=null!=this.serverResolutions?OpenLayers.Util.indexOf(this.serverResolutions,c):this.map.getZoom(),f=[this.layername,b(c,2),b(parseInt(f/1E6),3),b(parseInt(f/1E3)%1E3,3),b(parseInt(f)%1E3,3),b(parseInt(a/1E6),3),b(parseInt(a/ | |
2676 1E3)%1E3,3),b(parseInt(a)%1E3,3)+"."+this.extension].join("/"),c=this.url;OpenLayers.Util.isArray(c)&&(c=this.selectUrl(f,c));c="/"==c.charAt(c.length-1)?c:c+"/";return c+f},CLASS_NAME:"OpenLayers.Layer.TileCache"});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){var a=this.adjustBounds(a),b=this.map.getResolution(),c=Math.round(1E4*this.map.getScale())/1E4,d=Math.round(a.left/b);return this.getFullRequestString({t:-Math.round(a.top/b),l:d,s:c})},calculateGridLayout:function(a, | |
2677 b,c){var b=c*this.tileSize.w,c=c*this.tileSize.h,d=a.left,e=Math.floor(d/b)-this.buffer,d=-(d/b-e)*this.tileSize.w,e=e*b,a=a.top,f=Math.ceil(a/c)+this.buffer;return{tilelon:b,tilelat:c,tileoffsetlon:e,tileoffsetlat:f*c,tileoffsetx:d,tileoffsety:-(f-a/c+1)*this.tileSize.h}},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,[a]);null!=this.tileSize&&(a.tileSize=this.tileSize.clone());a.grid= | |
2678 [];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.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, | |
2679 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), | |
2680 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){var b=OpenLayers.Util.applyDefaults(b,{rotation:0,scale:1,ratio:1}),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()); | |
2681 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", | |
2682 {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, | |
2683 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, | |
2684 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), | |
2685 h=new OpenLayers.Geometry.Point(d,e),f=a.center;this.rotate(-a.rotation,f);h.rotate(-a.rotation,f);var i=this.x-f.x,j=this.y-f.y,k=i-(this.x-h.x),l=j-(this.y-h.y);a.irregular&&!a._setfeature&&(i-=(this.x-h.x)/2,j-=(this.y-h.y)/2);this.x=d;this.y=e;h=1;g?(j=1.0E-5>Math.abs(l)?1:j/l,h=(1.0E-5>Math.abs(k)?1:i/k)/j):(k=Math.sqrt(k*k+l*l),j=Math.sqrt(i*i+j*j)/k);a._moving=!0;a.box.geometry.rotate(-a.rotation,f);delete a._moving;a.box.geometry.resize(j,f,h);a.box.geometry.rotate(a.rotation,f);a.transformFeature({scale:j, | |
2686 ratio:h});a.irregular&&!a._setfeature&&(i=f.clone(),i.x+=1.0E-5>Math.abs(d-f.x)?0:this.x-d,i.y+=1.0E-5>Math.abs(e-f.y)?0:this.y-e,a.box.geometry.move(this.x-d,this.y-e),a.transformFeature({center:i}))}},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,i=this.y-g.y;this.x=d;this.y=e;d=Math.atan2(i-c,h-b);d=Math.atan2(i,h)-d;d*=180/Math.PI;a._angle=(a._angle+ | |
2687 d)%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),i,j,k,l="sw s se e ne n nw w".split(" "),m=0;8>m;++m)i=this.box.geometry.components[m],j=new OpenLayers.Feature.Vector(i.clone(),{role:l[m]+"-resize"},"string"==typeof this.renderIntent?null:this.renderIntent),0==m%2&&(k=new OpenLayers.Feature.Vector(i.clone(),{role:l[m]+"-rotate"},"string"==typeof this.rotationHandleSymbolizer? | |
2688 null:this.rotationHandleSymbolizer),k.geometry.move=f,i._rotationHandle=k,h[m/2]=k),i.move=b,i.resize=c,i.rotate=d,j.geometry.move=e,i._handle=j,g[m]=j;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){b===a.box&&a.transformFeature({center:a.center})}, | |
2689 onStart:function(b){var c=!a.geometryTypes||-1!==OpenLayers.Util.indexOf(a.geometryTypes,b.geometry.CLASS_NAME),d=OpenLayers.Util.indexOf(a.handles,b),d=d+OpenLayers.Util.indexOf(a.rotationHandles,b);b!==a.feature&&(b!==a.box&&-2==d&&c)&&a.setFeature(b)},onComplete:function(){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], | |
2690 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", | |
2691 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)}, | |
2692 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= | |
2693 null)},setMap:function(a){OpenLayers.Handler.prototype.setMap.apply(this,arguments);this.dragHandler&&this.dragHandler.setMap(a)},startBox:function(){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, | |
2694 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, | |
2695 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)? | |
2696 (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, | |
2697 "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,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;if(this.out){b=Math.abs(a.right-a.left);var c=Math.abs(a.top-a.bottom);b=Math.min(this.map.size.h/c,this.map.size.w/b);var c=this.map.getExtent(),d=this.map.getLonLatFromPixel(a.getCenterPixel()),a=d.lon- | |
2698 c.getWidth()/2*b,e=d.lon+c.getWidth()/2*b,f=d.lat-c.getHeight()/2*b;b=d.lat+c.getHeight()/2*b;b=new OpenLayers.Bounds(a,f,e,b)}else b=this.map.getLonLatFromPixel({x:a.left,y:a.bottom}),c=this.map.getLonLatFromPixel({x:a.right,y:a.top}),b=new OpenLayers.Bounds(b.lon,b.lat,c.lon,c.lat);c=this.map.getZoom();this.map.zoomToExtent(b);c==this.map.getZoom()&&!0==this.alwaysZoom&&this.map.zoomTo(c+(this.out?-1:1))}else this.out?this.map.setCenter(this.map.getLonLatFromPixel(a),this.map.getZoom()-1):this.map.setCenter(this.map.getLonLatFromPixel(a), | |
2699 this.map.getZoom()+1)},CLASS_NAME:"OpenLayers.Control.ZoomBox"});OpenLayers.Control.DragPan=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_TOOL,panned:!1,interval:1,documentDrag:!1,kinetic:null,enableKinetic:!1,kineticInterval:10,draw:function(){if(this.enableKinetic){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},{interval:this.interval, | |
2700 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,f){c.map.pan(a,b,{dragging:!f, | |
2701 animate:!1})})}this.panned=!1}},CLASS_NAME:"OpenLayers.Control.DragPan"});OpenLayers.Handler.Click=OpenLayers.Class(OpenLayers.Handler,{delay:300,single:!0,"double":!1,pixelTolerance:0,dblclickTolerance:13,stopSingle:!1,stopDouble:!1,timerId:null,touch:!1,down:null,last:null,first:null,rightclickTimerId:null,touchstart:function(a){this.touch||(this.unregisterMouseListeners(),this.touch=!0);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, | |
2702 a.lastTouches=this.last.touches,this.handleSingle(a),this.down=null);return!0},unregisterMouseListeners:function(){this.map.events.un({mousedown:this.mousedown,mouseup:this.mouseup,click:this.click,dblclick:this.dblclick,scope:this})},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!= | |
2703 this.rightclickTimerId)return this.clearTimer(),this.callback("dblrightclick",[a]),!this.stopDouble;a=this["double"]?OpenLayers.Util.extend({},a):this.callback("rightclick",[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}, | |
2704 dblclick:function(a){this.handleDouble(a);return!this.stopDouble},handleDouble:function(a){this.passesDblclickTolerance(a)&&(this["double"]&&this.callback("dblclick",[a]),this.clearTimer())},handleSingle:function(a){this.passesTolerance(a)&&(null!=this.timerId?(this.last.touches&&1===this.last.touches.length&&(this["double"]&&OpenLayers.Event.stop(a),this.handleDouble(a)),(!this.last.touches||2!==this.last.touches.length)&&this.clearTimer()):(this.first=this.getEventInfo(a),this.queuePotentialClick(this.single? | |
2705 OpenLayers.Util.extend({},a):null)))},queuePotentialClick:function(a){this.timerId=window.setTimeout(OpenLayers.Function.bind(this.delayedCall,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)for(var a=0,c=this.down.touches.length;a<c;++a)if(this.getTouchDistance(this.down.touches[a],this.last.touches[a])>this.pixelTolerance){b= | |
2706 !1;break}return b},getTouchDistance:function(a,b){return Math.sqrt(Math.pow(a.clientX-b.clientX,2)+Math.pow(a.clientY-b.clientY,2))},passesDblclickTolerance:function(){var 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= | |
2707 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,e=0;e<c;e++)d=a.touches[e],b[e]={clientX:d.clientX,clientY:d.clientY}}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,this.touch=!1,a=!0);return a},CLASS_NAME:"OpenLayers.Handler.Click"});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; | |
2708 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(); | |
2709 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, | |
2710 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},this.mouseWheelOptions);OpenLayers.Control.PinchZoom&&(this.pinchZoom=new OpenLayers.Control.PinchZoom(OpenLayers.Util.extend({map:this.map},this.pinchZoomOptions)))},defaultClick:function(a){a.lastTouches&&2==a.lastTouches.length&& | |
2711 this.map.zoomOut()},defaultDblClick:function(a){this.map.setCenter(this.map.getLonLatFromViewPortPx(a.xy),this.map.zoom+1)},defaultDblRightClick:function(a){this.map.setCenter(this.map.getLonLatFromViewPortPx(a.xy),this.map.zoom-1)},wheelChange:function(a,b){var c=this.map.getZoom(),d=this.map.getZoom()+Math.round(b),d=Math.max(d,0),d=Math.min(d,this.map.getNumZoomLevels());if(d!==c){var e=this.map.getSize(),c=e.w/2-a.xy.x,e=a.xy.y-e.h/2,f=this.map.baseLayer.getResolutionForZoom(d),g=this.map.getLonLatFromPixel(a.xy); | |
2712 this.map.setCenter(new OpenLayers.LonLat(g.lon+c*f,g.lat+e*f),d)}},wheelUp:function(a,b){this.wheelChange(a,b||1)},wheelDown:function(a,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()}, | |
2713 CLASS_NAME:"OpenLayers.Control.Navigation"});OpenLayers.Control.DrawFeature=OpenLayers.Class(OpenLayers.Control,{layer:null,callbacks:null,multi:!1,featureAdded:function(){},handlerOptions:null,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= | |
2714 a;this.handlerOptions=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, | |
2715 this.callbacks,this.handlerOptions)},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, | |
2716 b){this.handler&&this.handler.line&&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, | |
2717 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", | |
2718 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){var a=a.vertex,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- | |
2719 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){d=c.length-2;a:for(;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}, | |
2720 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= | |
2721 !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]);this.addControls([new OpenLayers.Control.DrawFeature(a,OpenLayers.Handler.Point,{displayClass:"olControlDrawFeaturePoint",handlerOptions:{citeCompliant:this.citeCompliant}}),new OpenLayers.Control.DrawFeature(a,OpenLayers.Handler.Path,{displayClass:"olControlDrawFeaturePath", | |
2722 handlerOptions:{citeCompliant:this.citeCompliant}}),new OpenLayers.Control.DrawFeature(a,OpenLayers.Handler.Polygon,{displayClass:"olControlDrawFeaturePolygon",handlerOptions:{citeCompliant:this.citeCompliant}})])},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, | |
2723 scope:this});return a},update:function(a){var b=this.getMapBounds();if(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)); | |
2724 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)&& | |
2725 (this.layer.protocol.abort(this.response),this.layer.events.triggerEvent("loadend"));this.layer.events.triggerEvent("loadstart");this.response=this.layer.protocol.read(OpenLayers.Util.applyDefaults({filter:this.createFilter(),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, | |
2726 filters:[this.layer.filter,a]}));return a},merge:function(a){this.layer.destroyFeatures();if((a=a.features)&&0<a.length){var b=this.layer.projection,c=this.layer.map.getProjectionObject();if(!c.equals(b))for(var d,e=0,f=a.length;e<f;++e)(d=a[e].geometry)&&d.transform(b,c);this.layer.addFeatures(a)}this.response=null;this.layer.events.triggerEvent("loadend")},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){var a= | |
2727 this.adjustBounds(a),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){var a=OpenLayers.Util.applyDefaults(a,OpenLayers.Protocol.CSW.DEFAULTS),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){var c,d={layer:!0,matrixSet:!0},e;for(e in d)if(!(e in b))throw Error("Missing property '"+e+"' in layer configuration.");d=a.contents;e=d.tileMatrixSets[b.matrixSet];for(var f,g=0,h=d.layers.length;g<h;++g)if(d.layers[g].identifier===b.layer){f=d.layers[g];break}if(f&&e){for(var i,g=0,h=f.styles.length;g<h&&!(i=f.styles[g],i.isDefault);++g); | |
2728 c=new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults(b,{url:"REST"===b.requestEncoding&&f.resourceUrl?f.resourceUrl.tile.template:a.operationsMetadata.GetTile.dcp.http.get[0].url,name:f.title,style:i.identifier,matrixIds:e.matrixIds,tileFullExtent:e.bounds}))}return c},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):(b=this.map.viewPortDiv,a=document.createElement("div"),a.id=this.map.id+"_GMapContainer",a.style.position="absolute",a.style.width="100%",a.style.height="100%",b.appendChild(a),b=this.map.getCenter(),a=new google.maps.Map(a,{center:b?new google.maps.LatLng(b.lat, | |
2729 b.lon):new google.maps.LatLng(0,0),zoom:this.map.getZoom()||0,mapTypeId:this.type,disableDefaultUI:!0,keyboardShortcuts:!1,draggable:!1,disableDoubleClickZoom:!0,scrollwheel:!1,streetViewControl:!1}),b={mapObject:a,count:1},OpenLayers.Layer.Google.cache[this.map.id]=b,this.repositionListener=google.maps.event.addListenerOnce(a,"center_changed",OpenLayers.Function.bind(this.repositionMapElements,this)));this.mapObject=a;this.setGMapVisibility(this.visibility)},repositionMapElements:function(){google.maps.event.trigger(this.mapObject, | |
2730 "resize");var a=this.mapObject.getDiv().firstChild;if(!a||3>a.childNodes.length)return this.repositionTimer=window.setTimeout(OpenLayers.Function.bind(this.repositionMapElements,this),250),!1;for(var b=OpenLayers.Layer.Google.cache[this.map.id],c=this.map.viewPortDiv,d=a.children.length-1;0<=d;--d){if(1000001==a.children[d].style.zIndex){var e=a.children[d];c.appendChild(e);e.style.zIndex="1100";e.style.bottom="";e.className="olLayerGoogleCopyright olLayerGoogleV3";e.style.display="";b.termsOfUse= | |
2731 e}1E6==a.children[d].style.zIndex&&(e=a.children[d],c.appendChild(e),e.style.zIndex="1100",e.style.bottom="",e.className="olLayerGooglePoweredBy olLayerGoogleV3 gmnoprint",e.style.display="",b.poweredBy=e);10000002==a.children[d].style.zIndex&&c.appendChild(a.children[d])}this.setGMapVisibility(this.visibility)},onMapResize:function(){if(this.visibility)google.maps.event.trigger(this.mapObject,"resize");else{var a=OpenLayers.Layer.Google.cache[this.map.id];if(!a.resized){var b=this;google.maps.event.addListenerOnce(this.mapObject, | |
2732 "tilesloaded",function(){google.maps.event.trigger(b.mapObject,"resize");b.moveTo(b.map.getCenter(),b.map.getZoom());delete a.resized})}a.resized=!0}},setGMapVisibility:function(a){var b=OpenLayers.Layer.Google.cache[this.map.id];if(b){for(var c=this.type,d=this.map.layers,e,f=d.length-1;0<=f;--f)if(e=d[f],e instanceof OpenLayers.Layer.Google&&!0===e.visibility&&!0===e.inRange){c=e.type;a=!0;break}d=this.mapObject.getDiv();!0===a?(this.mapObject.setMapTypeId(c),d.style.left="",b.termsOfUse&&b.termsOfUse.style&& | |
2733 (b.termsOfUse.style.left="",b.termsOfUse.style.display="",b.poweredBy.style.display=""),b.displayed=this.id):(delete b.displayed,d.style.left="-9999px",b.termsOfUse&&b.termsOfUse.style&&(b.termsOfUse.style.display="none",b.termsOfUse.style.left="-9999px",b.poweredBy.style.display="none"))}},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, | |
2734 a.left),a=this.sphericalMercator?this.inverseMercator(a.top,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); | |
2735 this.wrapDateLine&&(a=a.wrapDateLine(this.maxExtent));return this.getMapObjectLonLatFromLonLat(a.lon,a.lat)},getMapObjectPixelFromMapObjectLonLat:function(a){var b=this.getLongitudeFromMapObjectLonLat(a),a=this.getLatitudeFromMapObjectLonLat(a),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, | |
2736 "idle",function(){c.style.visibility=""});c.style.visibility="hidden"}this.mapObject.setOptions({center:a,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)},destroy:function(){this.repositionListener&& | |
2737 google.maps.event.removeListener(this.repositionListener);this.repositionTimer&&window.clearTimeout(this.repositionTimer);OpenLayers.Layer.Google.prototype.destroy.apply(this,arguments)}};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, | |
2738 [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, | |
2739 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)},Input:function(a,b){var c={maxOccurs:parseInt(a.getAttribute("maxOccurs")),minOccurs:parseInt(a.getAttribute("minOccurs"))};this.readChildNodes(a,c);b.push(c)},BoundingBoxData:function(a,b){b.boundingBoxData= | |
2740 {};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)},Format:function(a,b){var c={};this.readChildNodes(a,c);b.formats||(b.formats= | |
2741 {});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.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", | |
2742 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}, | |
2743 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"== | |
2744 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|| | |
2745 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))}}, | |
2746 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, | |
2747 [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}});if(a.DistributedSearch||this.DistributedSearch)this.writeNode("csw:DistributedSearch", | |
2748 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|| | |
2749 (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", | |
2750 {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}, | |
2751 CLASS_NAME:"OpenLayers.Format.CSWGetRecords.v2_0_2"});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, | |
2752 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){for(var a=a.split("\n"),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= | |
2753 e.split("\t"),f=new OpenLayers.Geometry.Point(0,0),g={},h=this.defaultStyle?OpenLayers.Util.applyDefaults({},this.defaultStyle):null,i=!1,j=0;j<e.length;j++)if(e[j])if("point"==b[j])i=e[j].split(","),f.y=parseFloat(i[0]),f.x=parseFloat(i[1]),i=!0;else if("lat"==b[j])f.y=parseFloat(e[j]),i=!0;else if("lon"==b[j])f.x=parseFloat(e[j]),i=!0;else if("title"==b[j])g.title=e[j];else if("image"==b[j]||"icon"==b[j]&&h)h.externalGraphic=e[j];else if("iconSize"==b[j]&&h){var k=e[j].split(",");h.graphicWidth= | |
2754 parseFloat(k[0]);h.graphicHeight=parseFloat(k[1])}else"iconOffset"==b[j]&&h?(k=e[j].split(","),h.graphicXOffset=parseFloat(k[0]),h.graphicYOffset=parseFloat(k[1])):"description"==b[j]?g.description=e[j]:"overflow"==b[j]?g.overflow=e[j]:g[b[j]]=e[j];i&&(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, | |
2755 success:this.parseData,failure:function(){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){var a=a.responseText,b={};OpenLayers.Util.extend(b,this.formatOptions);this.map&&!this.projection.equals(this.map.getProjectionObject())&&(b.externalProjection=this.projection,b.internalProjection=this.map.getProjectionObject());for(var a= | |
2756 (new OpenLayers.Format.Text(b)).read(a),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(), | |
2757 null!=g&&d.icon.setSize(g));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; | |
2758 this.layer.selectedFeature=!b?this:null;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){if(!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, | |
2759 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(), | |
2760 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], | |
2761 {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();this.irregular&&(a=b.x-this.origin.x,b=b.y-this.origin.y,this.feature.geometry.resize(1, | |
2762 this.origin,0==b?a/(this.radius*Math.sqrt(2)):a/b),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(){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,this.sides,this.snapAngle)},modifyGeometry:function(){var a, | |
2763 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=Math.PI/180*this.snapAngle;this.angle= | |
2764 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){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,handlerOptions: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}, | |
2765 this.callbacks);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]; | |
2766 for(a in this.wfsCache)delete this.wfsCache[a];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, | |
2767 scope:b});this.map.addLayer(b)}return b},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 i=this.selectionSymbolizer,j=c[f];0<=j.type.indexOf("Polygon")?i={Polygon:this.selectionSymbolizer.Polygon}:0<=j.type.indexOf("LineString")?i={Line:this.selectionSymbolizer.Line}:0<=j.type.indexOf("Point")&&(i={Point:this.selectionSymbolizer.Point});d.namedLayers[h].userStyles.push({name:"default", | |
2768 rules:[new OpenLayers.Rule({symbolizer:i,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;if(!c||!c.documentElement)c=a.responseText;for(var a=b.read(c),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", | |
2769 VERSION:"1.0.0"},callback:function(a){var b=new OpenLayers.Format.WFSDescribeFeatureType,c=a.responseXML;if(!c||!c.documentElement)c=a.responseText;this.control.wfsCache[this.layer.id]=b.read(c);this.control._queue&&this.control.applySelection()},scope:this})},getGeometryAttributes:function(a){for(var b=[],a=this.wfsCache[a.id],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],i=h.type;(0<=i.indexOf("LineString")||0<=i.indexOf("GeometryAssociationType")|| | |
2770 0<=i.indexOf("GeometryPropertyType")||0<=i.indexOf("Point")||0<=i.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= | |
2771 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? | |
2772 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, | |
2773 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(), | |
2774 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 i=e[g];if(null!==i){if(!(a instanceof OpenLayers.Geometry)){var j=this.map.getLonLatFromPixel(a.xy);a=new OpenLayers.Geometry.Point(j.lon,j.lat)}i=this.createFilter(i,a);null!==i&&f.push(i)}}g=this.createSelectionLayer(d);e=this.createSLD(d,f,e);this.events.triggerEvent("selected", | |
2775 {layer:d,filters:f});g.mergeNewParams({SLD_BODY:e});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; | |
2776 if(!0===this.geodesic){if(!this.map.getUnits())return;a=OpenLayers.INCHES_PER_UNIT;a=(this.map.getGeodesicPixelSize().w||1.0E-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.Control.Button=OpenLayers.Class(OpenLayers.Control,{type:OpenLayers.Control.TYPE_BUTTON,trigger:function(){},CLASS_NAME:"OpenLayers.Control.Button"});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, | |
2777 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? | |
2778 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* | |
2779 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), | |
2780 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), | |
2781 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))* | |
2782 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},calculateGridLayout:function(a,b,c){var d=c*this.tileSize.w,c= | |
2783 c*this.tileSize.h,e=a.left-b.lon,f=Math.floor(e/d)-this.buffer,a=b.lat-a.top+c,g=Math.floor(a/c)-this.buffer;return{tilelon:d,tilelat:c,tileoffsetlon:b.lon+f*d,tileoffsetlat:b.lat-c*g,tileoffsetx:-(e/d-f)*this.tileSize.w,tileoffsety:(g-a/c)*this.tileSize.h}},CLASS_NAME:"OpenLayers.Layer.MapGuide"});OpenLayers.Control.Measure=OpenLayers.Class(OpenLayers.Control,{handlerOptions:null,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, | |
2784 this.callbacks);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&& | |
2785 this.deactivate();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)&& | |
2786 (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, | |
2787 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()), | |
2788 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, | |
2789 [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.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(){return this.relativePosition});this.contentDiv.style.position="absolute";this.contentDiv.style.zIndex=1;f&&(this.closeDiv.style.zIndex= | |
2790 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, | |
2791 arguments)},setBackgroundColor:function(){},setBorder:function(){},setOpacity:function(){},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= | |
2792 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+ | |
2793 "_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,i=isNaN(c.size.w)?this.size.w-(g+e):c.size.w,j=isNaN(c.size.h)?this.size.h-(f+ | |
2794 h):c.size.h;d.div.style.width=(0>i?0:i)+"px";d.div.style.height=(0>j?0:j)+"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, | |
2795 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", | |
2796 "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, | |
2797 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, | |
2798 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, | |
2799 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"); | |
2800 OpenLayers.Popup.Framed.prototype.initialize.apply(this,arguments);this.contentDiv.className=this.contentDisplayClass},CLASS_NAME:"OpenLayers.Popup.FramedCloud"});OpenLayers.Tile.Image.IFrame={useIFrame:null,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=null,a?(this.blankImageUrl=this._blankImageUrl,this.frame.removeChild(this.frame.firstChild)): | |
2801 (this._blankImageUrl=this.blankImageUrl,this.blankImageUrl="about:blank")}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="'+ | |
2802 a+'">'),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, | |
2803 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(); | |
2804 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)); | |
2805 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, | |
2806 [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, | |
2807 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, | |
2808 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}, | |
2809 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;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):(this.started=!1,this.last=this.start=null);OpenLayers.Event.stop(a);return b},touchmove:function(a){if(this.started&&OpenLayers.Event.isMultiTouch(a)){this.pinching= | |
2810 !0;var b=this.getPinchData(a);this.callback("move",[a,b]);this.last=b;OpenLayers.Event.stop(a)}return!0},touchend:function(a){this.started&&(this.pinching=this.started=!1,this.callback("done",[a,this.start,this.last]),this.last=this.start=null);return!0},activate:function(){var a=!1;OpenLayers.Handler.prototype.activate.apply(this,arguments)&&(this.pinching=!1,a=!0);return a},deactivate:function(){var a=!1;OpenLayers.Handler.prototype.deactivate.apply(this,arguments)&&(this.pinching=this.started= | |
2811 !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.clientX-a.clientX,2)+Math.pow(b.clientY-a.clientY,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();return a},reset:function(){!0===this.layer.visibility?this.start():this.stop()},start:function(){this.interval&&("number"=== | |
2812 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));if(this.params.TRANSPARENT&&"true"==this.params.TRANSPARENT.toString().toLowerCase()){if(null==d||!d.isBaseLayer)this.isBaseLayer=!1;"jpg"==this.params.FORMAT&& | |
2813 (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){var a=this.adjustBounds(a),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)&& | |
2814 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.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&& | |
2815 "OpenLayers.Feature.Vector"==b.CLASS_NAME)b.geometry.transform(this.externalProjection,this.internalProjection);else if(b&&"geometrycollection"!=a&&"object"==typeof b){a=0;for(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("")}, | |
2816 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]])+ | |
2817 ")");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= | |
2818 [],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(","), | |
2819 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){for(var a=OpenLayers.String.trim(a).split(","),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), | |
2820 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){for(var b,a=OpenLayers.String.trim(a).split(this.regExes.parenComma),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))}, | |
2821 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){for(var a=a.replace(/,\s*([A-Za-z])/g,"|$1"),a=OpenLayers.String.trim(a).split("|"),b=[],c=0,d=a.length;c<d;++c)b.push(OpenLayers.Format.WKT.prototype.read.apply(this,[a[c]])); | |
2822 return b}},CLASS_NAME:"OpenLayers.Format.WKT"});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}, | |
2823 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,handlerOptions: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= | |
2824 {};this.click&&(this.handlers.click=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})))}, | |
2825 activate:function(){if(!this.active)for(var a in this.handlers)this.handlers[a].activate();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= | |
2826 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);else{if(this.click)return;b=this.pixelToBounds(a)}this.setModifiers(this.handlers.box.dragHandler.evt);this.request(b)},selectHover:function(a){this.request(this.pixelToBounds(a.xy),{single:!0,hover:!0})},cancelHover:function(){this.hoverResponse&&(this.protocol.abort(this.hoverResponse),this.hoverResponse=null,OpenLayers.Element.removeClass(this.map.viewPortDiv, | |
2827 "olCursorWait"))},request:function(a,b){var b=b||{},c=new OpenLayers.Filter.Spatial({type:this.filterType,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())); | |
2828 OpenLayers.Element.removeClass(this.map.viewPortDiv,"olCursorWait")},scope:this});!0==b.hover&&(this.hoverResponse=c)},selectBestFeature:function(a,b,c){c=c||{};if(a.length){for(var b=new OpenLayers.Geometry.Point(b.lon,b.lat),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], | |
2829 toggle:this.toggle||this.toggleKey&&a[this.toggleKey]}},select:function(a){!this.modifiers.multiple&&!this.modifiers.toggle&&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, | |
2830 c.push(d),this.events.triggerEvent("featureselected",{feature:d})));this.events.triggerEvent("featuresselected",{features:c})}},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", | |
2831 {feature:a})},unselectAll:function(){for(var a in this.features)this.unselect(this.features[a])},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]= | |
2832 "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){var d=d||{},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&& | |
2833 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 "+ | |
2834 c.type);break;case "Logical":if(c.type===OpenLayers.Filter.Logical.AND){e=0;for(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), | |
2835 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- | |
2836 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(){null!=this.emptyString&&(this.element.innerHTML=this.emptyString)},formatOutput:function(a){var b=parseInt(this.numDigits);return this.prefix+a.lon.toFixed(b)+ | |
2837 this.separator+a.lat.toFixed(b)+this.suffix},CLASS_NAME:"OpenLayers.Control.MousePosition"});OpenLayers.Control.Geolocate=OpenLayers.Class(OpenLayers.Control,{geolocation:navigator.geolocation,bind:!0,watch:!1,geolocationOptions:null,destroy:function(){this.deactivate();OpenLayers.Control.prototype.destroy.apply(this,arguments)},activate:function(){return!this.geolocation?(this.events.triggerEvent("locationuncapable"),!1):OpenLayers.Control.prototype.activate.apply(this,arguments)?(this.watch?this.watchId=this.geolocation.watchPosition(OpenLayers.Function.bind(this.geolocate,this),OpenLayers.Function.bind(this.failure, | |
2838 this),this.geolocationOptions):this.getCurrentLocation(),!0):!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&&this.map.setCenter(b);this.events.triggerEvent("locationupdated",{position:a,point:new OpenLayers.Geometry.Point(b.lon, | |
2839 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, | |
2840 callback:function(a){this.isLoading=false;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=false;this.events.triggerEvent("loadend");a.status===200&&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= | |
2841 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.indexFromCharCode(this.json.grid[Math.floor(b/d)].charCodeAt(Math.floor(a/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=null}, | |
2842 CLASS_NAME:"OpenLayers.Tile.UTFGrid"});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, | |
2843 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){a&&!this.previous.active?this.previous.activate():!a&&this.previous.active&&this.previous.deactivate()}, | |
2844 onNextChange:function(a){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(), | |
2845 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], | |
2846 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()== | |
2847 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){this.previousStack.unshift(this.registry[a].apply(this, | |
2848 arguments));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,this,this.listeners[b]);a=!0;0==this.previousStack.length&& | |
2849 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.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= | |
2850 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"}); | |
2851 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){var b=OpenLayers.Util.applyDefaults(b,this.options),c=new OpenLayers.Protocol.Response({reqFeatures:a, | |
2852 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){var b=b||{},c=b.url||a.url||this.options.url+"/"+a.fid,b=OpenLayers.Util.applyDefaults(b,this.options),d=new OpenLayers.Protocol.Response({reqFeatures:a,requestType:"update"});d.priv=OpenLayers.Request[this.updateWithPOST?"POST":"PUT"]({url:c,callback:this.createCallback(this.handleUpdate, | |
2853 d,b),headers:b.headers,data:this.format.write(a)});return d},handleUpdate:function(a,b){this.handleResponse(a,b)},"delete":function(a,b){var b=b||{},c=b.url||a.url||this.options.url+"/"+a.fid,b=OpenLayers.Util.applyDefaults(b,this.options),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); | |
2854 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;if(!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= | |
2855 a.features?a.features.length:0,c=Array(b),e=0;e<b;++e)c[e]=a.features[e].fid;o.insertIds=c;d.apply(this,[a])}function d(a){this.callUserCallback(a,b);n=n&&a.success();f++;f>=m&&b.callback&&(o.code=n?OpenLayers.Protocol.Response.SUCCESS:OpenLayers.Protocol.Response.FAILURE,b.callback.apply(b.scope,[o]))}var b=OpenLayers.Util.applyDefaults(b,this.options),e=[],f=0,g={};g[OpenLayers.State.INSERT]=[];g[OpenLayers.State.UPDATE]=[];g[OpenLayers.State.DELETE]=[];for(var h,i,j=[],k=0,l=a.length;k<l;++k)if(h= | |
2856 a[k],i=g[h.state])i.push(h),j.push(h);var m=(0<g[OpenLayers.State.INSERT].length?1:0)+g[OpenLayers.State.UPDATE].length+g[OpenLayers.State.DELETE].length,n=!0,o=new OpenLayers.Protocol.Response({reqFeatures:j});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(k=h.length-1;0<=k;--k)e.push(this.update(h[k],OpenLayers.Util.applyDefaults({callback:d,scope:this},b.update)));h=g[OpenLayers.State.DELETE]; | |
2857 for(k=h.length-1;0<=k;--k)e.push(this["delete"](h[k],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,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,moveend:this.cluster, | |
2858 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.features=null},cluster:function(a){if((!a||a.zoomChanged)&&this.features)if(a=this.layer.map.getResolution(),a!=this.resolution||!this.clustersExist()){this.resolution=a;for(var a=[],b,c,d,e=0;e<this.features.length;++e)if(b=this.features[e],b.geometry){c=!1;for(var f=a.length-1;0<=f;--f)if(d=a[f],this.shouldCluster(d,b)){this.addToCluster(d, | |
2859 b);c=!0;break}c||a.push(this.createCluster(this.features[e]))}this.layer.removeAllFeatures();if(0<a.length){if(1<this.threshold){b=a.slice();a=[];e=0;for(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=!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]!= | |
2860 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=a.geometry.getBounds().getCenterLonLat(),b=new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(b.lon,b.lat),{count:1});b.cluster=[a]; | |
2861 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}); | |
2862 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(){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()), | |
2863 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){var a=OpenLayers.Util.applyDefaults(a,OpenLayers.Protocol.SOS.DEFAULTS),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,{namespaces:{xsd:"http://www.w3.org/2001/XMLSchema"},readers:{xsd:{schema:function(a,b){var c=[],d={};this.readChildNodes(a,{complexTypes:c,customTypes:d});for(var e=a.attributes,f,g,h=0,i=e.length;h<i;++h)f=e[h],g=f.name,0==g.indexOf("xmlns")?this.setNamespace(g.split(":")[1]||"",f.value):b[g]=f.value;b.featureTypes=c;b.targetPrefix=this.namespaceAlias[b.targetNamespace];h=0;for(i=c.length;h<i;++h)e=c[h],f=d[e.typeName], | |
2864 d[e.typeName]&&(e.typeName=f.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){if(b.elements){for(var c={},d=a.attributes,e,f=0,g=d.length;f<g;++f)e=d[f],c[e.name]=e.value;d=c.type;d||(d={},this.readChildNodes(a, | |
2865 d),c.restriction=d,c.type=d.base);c.localType=(d.base||d).split(":").pop();b.elements.push(c)}b.complexTypes&&(d=a.getAttribute("type"),c=d.split(":").pop(),b.customTypes[c]={name:a.getAttribute("name"),type:d})},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"), | |
2866 b[e]?("string"==typeof b[e]&&(b[e]=[b[e]]),b[e].push(d)):b[e]=d)},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.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, | |
2867 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)]; | |
2868 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< | |
2869 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)])); | |
2870 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= | |
2871 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")); | |
2872 for(var a=b.length,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"); | |
2873 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!= | |
2874 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"== | |
2875 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){for(var a=b.length,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)}, | |
2876 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); | |
2877 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)}, | |
2878 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,containerCenter:null,pinchOrigin:null,currentCenter:null,autoActivate:!0,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)},activate:function(){var a=OpenLayers.Control.prototype.activate.apply(this,arguments);a&&(this.map.events.on({moveend:this.updateContainerCenter, | |
2879 scope:this}),this.updateContainerCenter());return a},deactivate:function(){var a=OpenLayers.Control.prototype.deactivate.apply(this,arguments);this.map&&this.map.events&&this.map.events.un({moveend:this.updateContainerCenter,scope:this});return a},updateContainerCenter:function(){var a=this.map.layerContainerDiv;this.containerCenter={x:parseInt(a.style.left,10)+50,y:parseInt(a.style.top,10)+50}},pinchStart:function(a){this.currentCenter=this.pinchOrigin=a.xy},pinchMove:function(a,b){var c=b.scale, | |
2880 d=this.containerCenter,e=this.pinchOrigin,f=a.xy,g=Math.round(f.x-e.x+(c-1)*(d.x-e.x)),d=Math.round(f.y-e.y+(c-1)*(d.y-e.y));this.applyTransform("translate("+g+"px, "+d+"px) scale("+c+")");this.currentCenter=f},applyTransform:function(a){var b=this.map.layerContainerDiv.style;b["-webkit-transform"]=a;b["-moz-transform"]=a},pinchDone:function(a,b,c){this.applyTransform("");a=this.map.getZoomForResolution(this.map.getResolution()/c.scale,!0);if(a!==this.map.getZoom()||!this.currentCenter.equals(this.pinchOrigin)){var b= | |
2881 this.map.getResolutionForZoom(a),c=this.map.getLonLatFromPixel(this.pinchOrigin),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, | |
2882 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, | |
2883 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.setCenter(this.map.getLonLatFromViewPortPx(a.xy), | |
2884 this.map.zoom+1)},CLASS_NAME:"OpenLayers.Control.TouchNavigation"});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)}, | |
2885 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, | |
2886 "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:"+ | |
2887 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")); | |
2888 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()); | |
2889 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); | |
2890 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= | |
2891 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)}},OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld)},OpenLayers.Format.SLD.v1_0_0.prototype.readers), | |
2892 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},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&& | |
2893 this.writeNode("Priority",a.priority,b);return this.addVendorOptions(b,a)},PointSymbolizer:function(a){return this.addVendorOptions(OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.PointSymbolizer.apply(this,arguments),a)},LineSymbolizer:function(a){return this.addVendorOptions(OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.LineSymbolizer.apply(this,arguments),a)},PolygonSymbolizer:function(a){return this.addVendorOptions(OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld.PolygonSymbolizer.apply(this, | |
2894 arguments),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,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)}, | |
2895 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= | |
2896 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, | |
2897 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=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, | |
2898 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){var b={};b.bbox=[parseFloat(a.getAttribute("minx")),parseFloat(a.getAttribute("miny")),parseFloat(a.getAttribute("maxx")),parseFloat(a.getAttribute("maxy"))];a={x:parseFloat(a.getAttribute("resx")),y:parseFloat(a.getAttribute("resy"))};if(!isNaN(a.x)||!isNaN(a.y))b.res= | |
2899 a;return b},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, | |
2900 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, | |
2901 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, | |
2902 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:[]}; | |
2903 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? | |
2904 a.getAttribute("opaque"):null,h=a.getAttribute("noSubsets"),i=a.getAttribute("fixedWidth"),j=a.getAttribute("fixedHeight"),k=c||{},l=OpenLayers.Util.extend;c={nestedLayers:[],styles:c?[].concat(c.styles):[],srs:c?l({},k.srs):{},metadataURLs:[],bbox:c?l({},k.bbox):{},llbbox:k.llbbox,dimensions:c?l({},k.dimensions):{},authorityURLs:c?l({},k.authorityURLs):{},identifiers:{},keywords:[],queryable:f&&""!==f?"1"===f||"true"===f:k.queryable||!1,cascaded:null!==g?parseInt(g):k.cascaded||0,opaque:e?"1"=== | |
2905 e||"true"===e:k.opaque||!1,noSubsets:null!==h?"1"===h||"true"===h:k.noSubsets||!1,fixedWidth:null!=i?parseInt(i):k.fixedWidth||0,fixedHeight:null!=j?parseInt(j):k.fixedHeight||0,minScale:k.minScale,maxScale:k.maxScale,attribution:k.attribution};b.nestedLayers.push(c);c.capability=d;this.readChildNodes(a,c);delete c.capability;if(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&& | |
2906 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")};b.metadataURLs.push(c); | |
2907 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)]=!0}}}, | |
2908 CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1"});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, | |
2909 [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)}, | |
2910 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, | |
2911 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, | |
2912 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 a=a.clone(),b=new OpenLayers.Size(Math.ceil(a.w/this.standardTileSize),Math.ceil(a.h/this.standardTileSize));this.tierSizeInTiles=[b]; | |
2913 for(this.tierImageSize=[a];a.w>this.standardTileSize||a.h>this.standardTileSize;)a=new OpenLayers.Size(Math.floor(a.w/2),Math.floor(a.h/2)),b=new OpenLayers.Size(Math.ceil(a.w/this.standardTileSize),Math.ceil(a.h/this.standardTileSize)),this.tierSizeInTiles.push(b),this.tierImageSize.push(a);this.tierSizeInTiles.reverse();this.tierImageSize.reverse();this.numberOfTiers=this.tierSizeInTiles.length;this.tileCountUpToTier=[0];for(a=1;a<this.numberOfTiers;a++)this.tileCountUpToTier.push(this.tierSizeInTiles[a- | |
2914 1].w*this.tierSizeInTiles[a-1].h+this.tileCountUpToTier[a-1])},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){var a=this.adjustBounds(a),b=this.map.getResolution(),c=Math.round((a.left-this.tileOrigin.lon)/ | |
2915 (b*this.tileSize.w)),a=Math.round((this.tileOrigin.lat-a.top)/(b*this.tileSize.h)),b=this.map.getZoom(),c="TileGroup"+Math.floor((c+a*this.tierSizeInTiles[b].w+this.tileCountUpToTier[b])/256)+"/"+b+"-"+c+"-"+a+".jpg",a=this.url;OpenLayers.Util.isArray(a)&&(a=this.selectUrl(c,a));return a+c},getImageSize:function(){if(0<arguments.length){var a=this.adjustBounds(arguments[0]),b=this.map.getResolution(),c=Math.round((a.left-this.tileOrigin.lon)/(b*this.tileSize.w)),a=Math.round((this.tileOrigin.lat- | |
2916 a.top)/(b*this.tileSize.h)),b=this.map.getZoom(),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,this.map.maxExtent.top)},calculateGridLayout:function(a, | |
2917 b,c){var d=c*this.tileSize.w,c=c*this.tileSize.h,e=a.left-b.lon,f=Math.floor(e/d)-this.buffer,a=b.lat-a.top+c,g=Math.floor(a/c)-this.buffer;return{tilelon:d,tilelat:c,tileoffsetlon:b.lon+f*d,tileoffsetlat:b.lat-c*g,tileoffsetx:-(e/d-f)*this.tileSize.w,tileoffsety:(g-a/c)*this.tileSize.h}},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())); | |
2918 return a=OpenLayers.Layer.Grid.prototype.clone.apply(this,[a])},getURL:function(a){var a=this.adjustBounds(a),a=[a.left,a.bottom,a.right,a.top],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)); | |
2919 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, | |
2920 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}, | |
2921 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= | |
2922 "olv:shape"}return c},setStyle:function(a,b,c,d){var b=b||a._style,c=c||a._options,e=b.fillColor;if("OpenLayers.Geometry.Point"===a._geometryClass)if(b.externalGraphic){c.isFilled=!0;b.graphicTitle&&(a.title=b.graphicTitle);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),i=void 0!=b.graphicYOffset?b.graphicYOffset:-(0.5*f);a.style.left=((d.x-this.featureDx)/ | |
2923 g-this.offset.x+h|0)+"px";a.style.top=(d.y/g-this.offset.y-(i+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];if(c.isFilled){d|| | |
2924 (d=this.createNode("olv:fill",a.id+"_fill"));d.opacity=b.fillOpacity;if("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)}else d&&a.removeChild(d);e=b.rotation;if(void 0!==e||void 0!==a._rotation)a._rotation=e,b.externalGraphic?(this.graphicRotate(a,h,i,b),d.opacity=0):"OpenLayers.Geometry.Point"===a._geometryClass&& | |
2925 (a.style.rotation=e||0);h=a.getElementsByTagName("stroke");h=0==h.length?null:h[0];if(c.isStroked){if(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)}else 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, | |
2926 d){var d=d||a._style,e=d.rotation||0,f,g;if(!d.graphicWidth||!d.graphicHeight){var h=new Image;h.onreadystatechange=OpenLayers.Function.bind(function(){if("complete"==h.readyState||"interactive"==h.readyState)f=h.width/h.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);h.src=d.externalGraphic}else{g=Math.max(d.graphicWidth,d.graphicHeight);f=d.graphicWidth/d.graphicHeight;var i=Math.round(d.graphicWidth|| | |
2927 g*f),j=Math.round(d.graphicHeight||g);a.style.width=i+"px";a.style.height=j+"px";var k=document.getElementById(a.id+"_image");k||(k=this.createNode("olv:imagedata",a.id+"_image"),a.appendChild(k));k.style.width=i+"px";k.style.height=j+"px";k.src=d.externalGraphic;k.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='', sizingMethod='scale')";k=e*Math.PI/180;e=Math.sin(k);k=Math.cos(k);e="progid:DXImageTransform.Microsoft.Matrix(M11="+k+",M12="+-e+",M21="+e+",M22="+k+",SizingMethod='auto expand')\n"; | |
2928 (k=d.graphicOpacity||d.fillOpacity)&&1!=k&&(e+="progid:DXImageTransform.Microsoft.BasicImage(opacity="+k+")\n");a.style.filter=e;e=new OpenLayers.Geometry.Point(-b,-c);i=(new OpenLayers.Bounds(0,0,i,j)).toGeometry();i.rotate(d.rotation,e);i=i.getBounds();a.style.left=Math.round(parseInt(a.style.left)+i.left)+"px";a.style.top=Math.round(parseInt(a.style.top)-i.bottom)+"px"}},postDraw:function(a){a.style.visibility="visible";var b=a._style.fillColor,c=a._style.strokeColor;"none"==b&&a.fillcolor!=b&& | |
2929 (a.fillcolor=b);"none"==c&&a.strokecolor!=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= | |
2930 a.strokeDashstyle;switch(a){case "solid":case "dot":case "dash":case "dashdot":case "longdash":case "longdashdot":return a;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+ | |
2931 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+"_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= | |
2932 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,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,i=0;i<e;i++)g=b.components[i],h=(g.x-this.featureDx)/d-this.offset.x|0,g=g.y/d-this.offset.y|0,f[i]=" "+h+","+g+" l ";a.path="m"+f.join("")+(c?" x e":" e");return a},drawPolygon:function(a,b){this.setNodeDimension(a, | |
2933 b);var c=this.getResolution(),d=[],e,f,g,h,i,j,k,l,m,n;e=0;for(f=b.components.length;e<f;e++){d.push("m");g=b.components[e].components;h=0===e;j=i=null;k=0;for(l=g.length;k<l;k++)m=g[k],n=(m.x-this.featureDx)/c-this.offset.x|0,m=m.y/c-this.offset.y|0,n=" "+n+","+m,d.push(n),0==k&&d.push(" l"),h||(i?i!=n&&(j?j!=n&&(h=!0):j=n):i=n);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)+ | |
2934 "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+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&& | |
2935 (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=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|| | |
2936 "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=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()}, | |
2937 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");for(var a=new OpenLayers.Bounds(Number.MAX_VALUE,Number.MAX_VALUE,0,0),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; | |
2938 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"});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, | |
2939 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&& | |
2940 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= | |
2941 [];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],i=this.parseGeometry(h),h=this.parseAttributes(h),h=new OpenLayers.Feature.Vector(i.geometry,h,null);h.bounds=i.bounds;h.type=f;b.push(h)}}return b},read_FeatureInfoResponse:function(a){for(var b=[],a=this.getElementsByTagNameNS(a, | |
2942 "*","FIELDS"),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 i=e.attributes[g];f[i.nodeName]=i.nodeValue}else{e=e.childNodes;g=0;for(h=e.length;g<h;++g)i=e[g],3!=i.nodeType&&(f[i.getAttribute("name")]=i.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=g.nextSibling, | |
2943 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)for(var a=a.childNodes,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;if(0==f.length)b[e]=null;else if(1==f.length&&(f=f[0],3==f.nodeType||4==f.nodeType))f=f.nodeValue.replace(this.regExes.trimSpace,""),b[e]=f}}return b}, | |
2944 parseGeometry:function(a){this.gmlFormat||(this.gmlFormat=new OpenLayers.Format.GML);var a=this.gmlFormat.parseFeature(a),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,handlerOptions: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)); | |
2945 !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, | |
2946 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;--d)if(c=a[d],c instanceof OpenLayers.Layer.WMTS&&c.requestEncoding===this.requestEncoding&&(!this.queryVisible||c.getVisibility()))if(b.push(c),!this.drillDown||this.hover)break;return b},buildRequestOptions:function(a,b){var c=this.map.getLonLatFromPixel(b),d= | |
2947 a.getURL(new OpenLayers.Bounds(c.lon,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){var b=b||{},c=this.findLayers(); | |
2948 if(0<c.length){for(var d,e,f=0,g=c.length;f<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|| | |
2949 300<=b.status))this.events.triggerEvent("exception",{xy:a,request:b,layer:c});else{var d=b.responseXML;if(!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.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(), | |
2950 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= | |
2951 !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.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, | |
2952 this.options||{});var b=new OpenLayers.Protocol.Response({requestType:"read"}),c=this.format.write(a.params);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= | |
2953 a.responseXML;if(!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.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= | |
2954 {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")), | |
2955 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;b.maxScale=parseFloat((c/e*f*OpenLayers.DOTS_PER_INCH).toPrecision(13));b.minScale=parseFloat((d/e*f*OpenLayers.DOTS_PER_INCH).toPrecision(13))}, | |
2956 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")||"";var d=this.getChildValue(a);c.values=d.split(",")}}}, | |
2957 OpenLayers.Format.WMSCapabilities.v1.prototype.readers.wms)},CLASS_NAME:"OpenLayers.Format.WMSCapabilities.v1_1"});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]); | |
2958 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({}, | |
2959 {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, | |
2960 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= | |
2961 this.intervals[d];var h=g/2,i=f.offset({x:-h,y:-h}),h=f.offset({x:h,y:h});OpenLayers.Projection.transform(i,b,c);OpenLayers.Projection.transform(h,b,c);if((i.x-h.x)*(i.x-h.x)+(i.y-h.y)*(i.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(),j;do h=h.offset({x:0,y:g}),j=OpenLayers.Projection.transform(h.clone(),b,c),e.unshift(h);while(a.containsPixel(j)&&1E3>++d);h=f.clone();do h=h.offset({x:0,y:-g}),j=OpenLayers.Projection.transform(h.clone(),b,c),e.push(h); | |
2962 while(a.containsPixel(j)&&1E3>++d);d=0;i=[f.clone()];h=f.clone();do h=h.offset({x:-g,y:0}),j=OpenLayers.Projection.transform(h.clone(),b,c),i.unshift(h);while(a.containsPixel(j)&&1E3>++d);h=f.clone();do h=h.offset({x:g,y:0}),j=OpenLayers.Projection.transform(h.clone(),b,c),i.push(h);while(a.containsPixel(j)&&1E3>++d);g=[];for(d=0;d<i.length;++d){j=i[d].x;for(var f=[],k=null,l=Math.min(e[0].y,90),h=Math.max(e[e.length-1].y,-90),m=(l-h)/this.numPoints,l=h,h=0;h<=this.numPoints;++h){var n=new OpenLayers.Geometry.Point(j, | |
2963 l);n.transform(b,c);f.push(n);l+=m;n.y>=a.bottom&&!k&&(k=n)}this.labelled&&(k=new OpenLayers.Geometry.Point(k.x,a.bottom),j={value:j,label:this.labelled?OpenLayers.Util.getFormattedLonLat(j,"lon",this.labelFormat):"",labelAlign:"cb",xOffset:0,yOffset:2},this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(k,j)));f=new OpenLayers.Geometry.LineString(f);g.push(new OpenLayers.Feature.Vector(f))}for(h=0;h<e.length;++h)if(l=e[h].y,!(-90>l||90<l)){f=[];d=i[0].x;m=(i[i.length-1].x-d)/this.numPoints; | |
2964 j=d;k=null;for(d=0;d<=this.numPoints;++d)n=new OpenLayers.Geometry.Point(j,l),n.transform(b,c),f.push(n),j+=m,n.x<a.right&&(k=n);this.labelled&&(k=new OpenLayers.Geometry.Point(a.right,k.y),j={value:l,label:this.labelled?OpenLayers.Util.getFormattedLonLat(l,"lat",this.labelFormat):"",labelAlign:"rb",xOffset:-2,yOffset:2},this.gratLayer.addFeatures(new OpenLayers.Feature.Vector(k,j)));f=new OpenLayers.Geometry.LineString(f);g.push(new OpenLayers.Feature.Vector(f))}this.gratLayer.addFeatures(g)}},CLASS_NAME:"OpenLayers.Control.Graticule"});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)},clone:function(a){null==a&&(a=new OpenLayers.Layer.UTFGrid(this.getOptions()));return a=OpenLayers.Layer.Grid.prototype.clone.apply(this, | |
2965 [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.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, | |
2966 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= | |
2967 []: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 i=this.getContainingTileCoords(f,h.resolution);h.startTileCol=i.x;h.startTileRow=i.y;i=this.getContainingTileCoords(e,h.resolution);h.endTileCol=i.x;h.endTileRow=i.y;this.lods.push(h)}this.maxExtent=this.calculateMaxExtentWithLOD(this.lods[0]);this.serverResolutions=this.resolutions;this.overrideDPI&& | |
2968 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+ | |
2969 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){return this.getContainingTileCoords(new OpenLayers.Geometry.Point(this.maxExtent.left, | |
2970 this.maxExtent.top),a)},getLowerRightTileCoord:function(a){return this.getContainingTileCoords(new OpenLayers.Geometry.Point(this.maxExtent.right,this.maxExtent.bottom),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*a,e)},clone:function(a){null==a&&(a=new OpenLayers.Layer.ArcGISCache(this.name, | |
2971 this.url,this.options));return OpenLayers.Layer.XYZ.prototype.clone.apply(this,[a])},getMaxExtent:function(){return this.maxExtent=this.getMaxExtentForResolution(this.map.getResolution())},getTileOrigin:function(){var a=this.getMaxExtent();return new OpenLayers.LonLat(a.left,a.bottom)},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- | |
2972 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);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"+this.zeroPad(c,8,16),d="R"+this.zeroPad(d,8,16),a="L"+this.zeroPad(a,2,16),b= | |
2973 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))},zeroPad:function(a,b,c){for(a=a.toString(c||10);a.length<b;)a="0"+a;return a},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,handlerOptions: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)); | |
2974 !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, | |
2975 {})},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)if(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|| | |
2976 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())&& | |
2977 (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, | |
2978 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, | |
2979 "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, | |
2980 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;if(!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&& | |
2981 (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"== | |
2982 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);for(var a=[],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= | |
2983 {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"))); | |
2984 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})}}}, | |
2985 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", | |
2986 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, | |
2987 [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, | |
2988 "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= | |
2989 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", | |
2990 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", | |
2991 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"); | |
2992 "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", | |
2993 {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}, | |
2994 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== | |
2995 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(){},reset:function(){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 c=b(),new OpenLayers.Filter.Logical({filters:[c],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= | |
2996 b(),c=b(),new OpenLayers.Filter.Comparison({property:c,value:g,type:d[a.text.toUpperCase()]});case "VALUE":return/^'.*'$/.test(a.text)?a.text.substr(1,a.text.length-2):Number(a.text);case "SPATIAL":switch(a.text.toUpperCase()){case "BBOX":var c=b(),a=b(),g=b(),h=b(),i=b();return new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.BBOX,property:i,value:OpenLayers.Bounds.fromArray([h,g,a,c])});case "INTERSECTS":return g=b(),c=b(),new OpenLayers.Filter.Spatial({type:OpenLayers.Filter.Spatial.INTERSECTS, | |
2997 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,property:c,distance:Number(a)})}case "GEOMETRY":return OpenLayers.Geometry.fromWKT(a.text);default:return a.text}} | |
2998 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 "LOGICAL":for(var i=h[g.type];0<c.length&&h[c[c.length-1].type]<=i;)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());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 "+ | |
2999 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,COMMA:/^,/,LOGICAL:/^(AND|OR)/i,VALUE:/^('\w+'|\d+(\.\d*)?|\.\d+)/,LPAREN:/^\(/,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); | |
3000 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","BETWEEN","COMMA"],BETWEEN:["VALUE"],COMPARISON:["VALUE"],COMMA:["GEOMETRY","VALUE","PROPERTY"],VALUE:["LOGICAL","COMMA","RPAREN","END"],SPATIAL:["LPAREN"],LOGICAL:["NOT","VALUE","SPATIAL","PROPERTY","LPAREN"], | |
3001 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,">=":OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,LIKE:OpenLayers.Filter.Comparison.LIKE,BETWEEN:OpenLayers.Filter.Comparison.BETWEEN},e={},f={AND:OpenLayers.Filter.Logical.AND,OR:OpenLayers.Filter.Logical.OR}, | |
3002 g={},h={RPAREN:3,LOGICAL:2,COMPARISON:1},i;for(i in d)d.hasOwnProperty(i)&&(e[d[i]]=i);for(i in f)f.hasOwnProperty(i)&&(g[f[i]]=i);return OpenLayers.Class(OpenLayers.Format,{read:function(d){var e=d,d=[],f,g=["NOT","GEOMETRY","SPATIAL","PROPERTY","LPAREN"];do{a:{f=g;for(var h=void 0,g=void 0,i=f.length,h=0;h<i;h++){var g=f[h],p=b[g]instanceof RegExp?b[g].exec(e):(0,b[g])(e);if(p){f=p[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: "; | |
3003 for(h=0;h<i;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);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("+ | |
3004 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("+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])+ | |
3005 ")";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?a.property+" BETWEEN "+this.write(a.lowerBoundary)+" AND "+this.write(a.upperBoundary):a.property+" "+e[a.type]+" "+this.write(a.value);case void 0:if("string"===typeof a)return"'"+a+"'";if("number"===typeof a)return""+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= | |
3006 a},activate:function(){var a=OpenLayers.Control.prototype.activate.call(this);if(a)if(this.source){if(this.source.events)this.source.events.on({sketchcomplete:this.onSketchComplete,afterfeaturemodified:this.afterFeatureModified,scope:this})}else 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();return a},deactivate:function(){var a=OpenLayers.Control.prototype.deactivate.call(this); | |
3007 a&&this.source&&this.source.events&&this.layer.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}}, | |
3008 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=[],i=this.layer===this.source&&this.mutual,j={edge:this.edge,tolerance:this.tolerance,mutual:i},k=[a.geometry],l,m,n,o=0,p=d.length;o<p;++o)if(l= | |
3009 d[o],this.isEligible(l)){m=[l.geometry];for(var q=0;q<k.length;++q){n=k[q];for(var r=0;r<m.length;++r)if(e=m[r],n.getBounds().intersectsBounds(e.getBounds())&&(e=n.split(e,j)))if(f=this.events.triggerEvent("beforesplit",{source:a,target:l}),!1!==f&&(i&&(f=e[0],1<f.length&&(f.unshift(q,1),Array.prototype.splice.apply(k,f),q+=f.length-3),e=e[1]),1<e.length))e.unshift(r,1),Array.prototype.splice.apply(m,e),r+=e.length-3}m&&1<m.length&&(this.geomsToFeatures(l,m),this.events.triggerEvent("split",{original:l, | |
3010 features:m}),Array.prototype.push.apply(g,m),h.push(l),c=!0)}k&&1<k.length&&(this.geomsToFeatures(a,k),this.events.triggerEvent("split",{original:a,features:k}),Array.prototype.push.apply(g,k),h.push(a),b=!0);if(b||c){if(this.deferDelete){d=[];o=0;for(p=h.length;o<p;++o)c=h[o],c.state===OpenLayers.State.INSERT?d.push(c):(c.state=OpenLayers.State.DELETE,this.layer.drawFeature(c));this.layer.destroyFeatures(d,{silent:!0});o=0;for(p=g.length;o<p;++o)g[o].state=OpenLayers.State.INSERT}else this.layer.destroyFeatures(h, | |
3011 {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= | |
3012 {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]){b=this.matrixIds;this.matrixIds=Array(a);for(c=0;c<a;++c)this.matrixIds[c]= | |
3013 {identifier:b[c]}}},setMap:function(){OpenLayers.Layer.Grid.prototype.setMap.apply(this,arguments);this.updateMatrixProperties()},updateMatrixProperties:function(){if(this.matrix=this.getMatrix())if(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= | |
3014 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)a={identifier:this.getIdentifier()};else if("scaleDenominator"in this.matrixIds[0])for(var b= | |
3015 OpenLayers.METERS_PER_INCH*OpenLayers.INCHES_PER_UNIT[this.units]*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()];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),b=Math.floor(c),d=Math.floor(a);return{col:b, | |
3016 row:d,i:Math.floor((c-b)*this.tileSize.w),j:Math.floor((a-d)*this.tileSize.h)}},getURL:function(a){var a=this.adjustBounds(a),b="";if(!this.tileFullExtent||this.tileFullExtent.intersectsBounds(a)){var c=this.getTileInfo(a.getCenterLonLat()),a=this.dimensions;if("REST"===this.requestEncoding.toUpperCase())if(b=this.params,"string"===typeof this.url&&-1!==this.url.indexOf("{")){var d=this.url.replace(/\{/g,"${"),c={style:this.style,Style:this.style,TileMatrixSet:this.matrixSet,TileMatrix:this.matrix.identifier, | |
3017 TileRow:c.row,TileCol:c.col};if(a){var e,f;for(f=a.length-1;0<=f;--f)e=a[f],c[e]=b[e.toUpperCase()]}b=OpenLayers.String.format(d,c)}else{d=this.version+"/"+this.layer+"/"+this.style+"/";if(a)for(f=0;f<a.length;f++)b[a[f]]&&(d=d+b[a[f]]+"/");d=d+this.matrixSet+"/"+this.matrix.identifier+"/"+c.row+"/"+c.col+"."+this.formatSuffix;b=OpenLayers.Util.isArray(this.url)?this.selectUrl(d,this.url):this.url;b.match(/\/$/)||(b+="/");b+=d}else"KVP"===this.requestEncoding.toUpperCase()&&(b={SERVICE:"WMTS",REQUEST:"GetTile", | |
3018 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,[b]))}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|| | |
3019 {});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; | |
3020 b.callback.call(b.scope,a)}},parseFeatures:function(a){var b=a.responseXML;if(!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){var a=this.adjustBounds(a),b=this.map.getResolution(),c=Math.round(1E4*this.map.getScale())/1E4,d=Math.round(a.left/b),a= | |
3021 -Math.round(a.top/b),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]))}, | |
3022 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.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.Control.LayerSwitcher=OpenLayers.Class(OpenLayers.Control,{roundedCorner:!1,roundedCornerColor:"darkblue",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=[];this.roundedCorner&&OpenLayers.Console.warn("roundedCorner option is deprecated")},destroy:function(){this.clearLayersArray("base"); | |
3023 this.clearLayersArray("data");this.map.events.un({buttonclick:this.onButtonClick,addlayer:this.redraw,changelayer:this.redraw,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, | |
3024 scope:this});this.outsideViewport?(this.events.attachToElement(this.div),this.events.register("buttonclick",this,this.onButtonClick)):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=== | |
3025 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))):(a.checked=!a.checked,this.updateMap())))},clearLayersArray:function(a){this[a+"LayersDiv"].innerHTML="";this[a+"Layers"]=[]},checkRedraw:function(){var a=!1;if(!this.layerStates.length||this.map.layers.length!=this.layerStates.length)a=!0;else for(var b=0,c=this.layerStates.length;b<c;b++){var d=this.layerStates[b],e=this.map.layers[b];if(d.name!= | |
3026 e.name||d.inRange!=e.inRange||d.id!=e.id||d.visibility!=e.visibility){a=!0;break}}return a},redraw:function(){if(!this.checkRedraw())return this.div;this.clearLayersArray("base");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], | |
3027 g=e.isBaseLayer;if(e.displayInLayerSwitcher){g?b=!0:a=!0;var h=g?e==this.map.baseLayer:e.getVisibility(),i=document.createElement("input");i.id=this.id+"_input_"+e.name;i.name=g?this.id+"_baseLayers":e.name;i.type=g?"radio":"checkbox";i.value=e.name;i.checked=h;i.defaultChecked=h;i.className="olButton";i._layer=e.id;i._layerSwitcher=this.id;!g&&!e.inRange&&(i.disabled=!0);h=document.createElement("label");h["for"]=i.id;OpenLayers.Element.addClass(h,"labelSpan olButton");h._layer=e.id;h._layerSwitcher= | |
3028 this.id;!g&&!e.inRange&&(h.style.color="gray");h.innerHTML=e.name;h.style.verticalAlign=g?"bottom":"baseline";var j=document.createElement("br");(g?this.baseLayers:this.dataLayers).push({layer:e,inputElem:i,labelSpan:h});e=g?this.baseLayersDiv:this.dataLayersDiv;e.appendChild(i);e.appendChild(h);e.appendChild(j)}}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]; | |
3029 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="";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"; | |
3030 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,"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"); | |
3031 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,"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), | |
3032 this.layersDiv.appendChild(this.baseLbl),this.layersDiv.appendChild(this.baseLayersDiv));this.div.appendChild(this.layersDiv);this.roundedCorner&&(OpenLayers.Rico.Corner.round(this.div,{corners:"tl bl",bgColor:"transparent",color:this.roundedCornerColor,blend:!1}),OpenLayers.Rico.Corner.changeOpacity(this.layersDiv,0.75));var a=OpenLayers.Util.getImageLocation("layer-switcher-maximize.png");this.maximizeDiv=OpenLayers.Util.createAlphaImageDiv("OpenLayers_Control_MaximizeDiv",null,null,a,"absolute"); | |
3033 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="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})); | |
3034 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"== | |
3035 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], | |
3036 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){e=OpenLayers.Util.isArray(c.contributors)?c.contributors:[c.contributors];f=0;for(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){e=OpenLayers.Util.isArray(c.links)? | |
3037 c.links:[c.links];f=0;for(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}));if(c.summary||b.description)d.appendChild(this.createElementNSPlus("atom:summary",{value:c.summary|| | |
3038 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, | |
3039 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, | |
3040 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"); | |
3041 if(0<d.length){c={};if(e=d[0].getAttribute("type"))c.type=e;(e=d[0].getAttribute("src"))?c.src=e:(c.value="text"==c.type||"html"==c.type||null==c.type?this.getFirstChildValue(a,f,"content",null):"xhtml"==c.type||c.type.match(/(\+|\/)xml$/)?this.getChildEl(d[0]):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));for(var i=["rel", | |
3042 "type","hreflang","title","length"],g=0,h=d.length;g<h;g++){c={};c.href=d[g].getAttribute("href");for(var j=0,k=i.length;j<k;j++)(e=d[g].getAttribute(i[j]))&&(c[i[j]]=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,description:b.summary, | |
3043 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]);for(var a=0,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<f;e++)this.gmlParser.readChildNodes(d[e], | |
3044 c)}c=c.components;if((d=this.getElementsByTagNameNS(a,b,"point"))&&0<d.length){e=0;for(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 i,e=0,f=h.length;e<f;e++){d=OpenLayers.String.trim(h[e].firstChild.nodeValue).split(/\s+/);i=[];for(var j=0,k=d.length;j< | |
3045 k;j+=2)g=new OpenLayers.Geometry.Point(d[j+1],d[j]),i.push(g);c.push(new OpenLayers.Geometry.LineString(i))}if((a=this.getElementsByTagNameNS(a,b,"polygon"))&&0<a.length){e=0;for(f=a.length;e<f;e++){d=OpenLayers.String.trim(a[e].firstChild.nodeValue).split(/\s+/);i=[];j=0;for(k=d.length;j<k;j+=2)g=new OpenLayers.Geometry.Point(d[j+1],d[j]),i.push(g);c.push(new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(c)]))}}if(this.internalProjection&&this.externalProjection){e=0;for(f=c.length;e< | |
3046 f;e++)c[e]&&c[e].transform(this.externalProjection,this.internalProjection)}return c},parsePersonConstructs:function(a,b,c){for(var d=[],e=this.namespaces.atom,a=this.getElementsByTagNameNS(a,e,b),f=["uri","email"],g=0,h=a.length;g<h;g++){var i={};i.name=this.getFirstChildValue(a[g],e,"name",null);for(var j=0,k=f.length;j<k;j++){var l=this.getFirstChildValue(a[g],e,f[j],null);l&&(i[f[j]]=l)}d.push(i)}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;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,0);break;case OpenLayers.Event.KEY_UP:this.map.pan(0, | |
3047 -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();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"== | |
3048 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, | |
3049 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, | |
3050 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=!!this.yx[b.supportedCRS.replace(/urn:ogc:def:crs:(\w+):.+:(\w+)$/,"urn:ogc:def:crs:$1::$2")]);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))}, | |
3051 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||{};b.resourceUrl[a.getAttribute("resourceType")]={format:a.getAttribute("format"),template:a.getAttribute("template")}},WSDL:function(a,b){b.wsdl={};b.wsdl.href=a.getAttribute("xlink:href")},ServiceMetadataURL:function(a,b){b.serviceMetadataUrl={};b.serviceMetadataUrl.href=a.getAttribute("xlink:href")}, | |
3052 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"}); | |
3053 (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]= | |
3054 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); | |
3055 /*! | |
3056 * | |
3057 * jQuery Remember Plugin | |
3058 * Version 0.1.1 | |
3059 * | |
3060 * Copyright Nick Dreckshage, licensed GPL & MIT | |
3061 * https://github.com/ndreckshage/jquery-remember | |
3062 * | |
3063 * A fork of jQuery Cookie Plugin | |
3064 * https://github.com/carhartl/jquery-cookie | |
3065 * Copyright Klaus Hartl | |
3066 * Released under the MIT licensed | |
3067 * | |
3068 */ | |
3069 | |
3070 (function($){ | |
3071 | |
3072 // recommend changing to return function(options) { if using require.js... | |
3073 $.remember = function(options){ | |
3074 var settings, | |
3075 remember, | |
3076 controller; | |
3077 | |
3078 settings = $.extend({ | |
3079 name: null, // name/key of the cookie/localstorage item | |
3080 value: undefined, // value pair of cookie/localstorage | |
3081 getSet: false, // if true, will get if available, set if not. default is to just get OR set | |
3082 remove: false, // if true, will remove based on name/key | |
3083 use: 'default', // whether to use localstorage or cookies. default localstorage with cookie fallback. | |
3084 expires: null, // forces cookie (invalid localstorage attribue). | |
3085 path: null, // forces cookie. | |
3086 domain: null, // forces cookie. | |
3087 secure: null, // forces cookie. | |
3088 json: false, // will convert to json when set. parse with get. | |
3089 fallback: true, // whether to fallback to cookies if localstorage not available. | |
3090 raw: false, // if true, will skip uri encoding/decoding | |
3091 modernizr: false // set true if youd rather handle localstorage detection through modernizr | |
3092 }, options); | |
3093 | |
3094 remember = { | |
3095 init: function(){ | |
3096 var controller; | |
3097 | |
3098 // controls what to do with the input. set - get - set/get - erase | |
3099 // set if name exists, value exists, and not set to remove cookie. | |
3100 // get if name exists, value does not exist, and not set to remove | |
3101 // remove if remove set to true | |
3102 if (settings.name !== null && settings.value !== undefined && settings.remove !== true){ | |
3103 if (settings.getSet === true){ | |
3104 var get = this.get(); | |
3105 // if the value of get exists, return it. otherwise, set the value as specified. | |
3106 if (get === null){ | |
3107 this.set(); | |
3108 } else { | |
3109 controller = get; | |
3110 } | |
3111 } else { | |
3112 this.set(); | |
3113 } | |
3114 } else if (settings.name !== null && settings.value === undefined && settings.remove !== true){ | |
3115 controller = this.get(); | |
3116 } else if (settings.name !== null && settings.remove === true){ | |
3117 this.erase(); | |
3118 } | |
3119 | |
3120 // will return result of everything to calling js | |
3121 return controller; | |
3122 }, | |
3123 get: function(){ | |
3124 var use = this._use(), | |
3125 value = null, | |
3126 cookies, | |
3127 parts, | |
3128 name; | |
3129 | |
3130 // grab the key value pair from localstorage | |
3131 if (use === 'localstorage') { | |
3132 value = localStorage.getItem(settings.name); | |
3133 } | |
3134 | |
3135 // hit if cookie requested, and when double checking a get on an empty localstorage item | |
3136 if ((use === 'cookie') || (use === 'localstorage' && value === null && settings.fallback !== false)) { | |
3137 | |
3138 // grab all the cookies from the browser, check if set, and loop through | |
3139 cookies = document.cookie ? document.cookie : null; | |
3140 if (cookies !== null){ | |
3141 cookies = cookies.split(';'); | |
3142 for (var i = 0; i < cookies.length; i++){ | |
3143 // separate the key value pair | |
3144 parts = cookies[i].split('='); | |
3145 // set name and value to split parts, cleaning up whitespace | |
3146 name = parts.shift(); | |
3147 name = settings.raw === false ? this._trim(this._decode(name)) : this._trim(name); | |
3148 value = parts[0]; | |
3149 // break when we hit a match, or cookie is empty | |
3150 if (settings.name === name) { | |
3151 break; | |
3152 } else if (settings.fallback !== false) { | |
3153 value = localStorage.getItem(settings.name) || null; | |
3154 } else { | |
3155 value = null; | |
3156 } | |
3157 } | |
3158 } | |
3159 } | |
3160 | |
3161 // decode uri and if json is requested, parse the cookie/localstorage and return to controller | |
3162 value = (value && settings.raw === false) ? this._decode(value) : value; | |
3163 value = (value && settings.json === true) ? JSON.parse(value) : value; | |
3164 | |
3165 return value; | |
3166 }, | |
3167 set: function(){ | |
3168 var use = this._use(); | |
3169 | |
3170 // if set is hit, user has intentionally tried to set (get/set not hit) | |
3171 // clear the storage alternative, so the same value isnt stored in both | |
3172 this.erase(); | |
3173 | |
3174 // convert the value to store in json if requested | |
3175 settings.value = settings.json === true ? JSON.stringify(settings.value) : settings.value; | |
3176 | |
3177 // encode | |
3178 settings.name = settings.raw === false ? encodeURIComponent(settings.name) : settings.name; | |
3179 settings.value = settings.raw === false ? encodeURIComponent(settings.value) : settings.value; | |
3180 | |
3181 // store the key value pair in appropriate storage. set unless storage requirements failed | |
3182 if (use === 'localstorage'){ | |
3183 localStorage.setItem(settings.name, settings.value); | |
3184 } else if (use !== false){ | |
3185 // convert values that cant be stored and set | |
3186 settings.value = settings.value === null ? 'null' : settings.value; | |
3187 this._setCookie(); | |
3188 } | |
3189 }, | |
3190 erase: function(){ | |
3191 var use = this._use(); | |
3192 | |
3193 // clear localstorage and cookies by setting expiration to negative | |
3194 if (use !== 'cookie' || settings.fallback !== false){ | |
3195 localStorage.removeItem(settings.name); | |
3196 } | |
3197 if (use !== 'localstorage' || settings.fallback !== false){ | |
3198 this._setCookie('', -1); | |
3199 } | |
3200 }, | |
3201 _use: function(){ | |
3202 var use, | |
3203 localStorageSupport = this._localStorage(); | |
3204 | |
3205 // if cookie requested, or any options set that only apply to cookies | |
3206 if (settings.use === 'cookie' || settings.expires !== null || settings.path !== null || settings.domain !== null || settings.secure !== null){ | |
3207 use = 'cookie'; | |
3208 } else { | |
3209 // use local storage if available | |
3210 if (localStorageSupport){ | |
3211 use = 'localstorage'; | |
3212 } else if (settings.fallback !== false) { | |
3213 // default to cookie, unless fallback banned | |
3214 use = 'cookie'; | |
3215 } else { | |
3216 // if all this fails, nothing can be set | |
3217 use = false; | |
3218 } | |
3219 } | |
3220 | |
3221 return use; | |
3222 }, | |
3223 _setCookie: function(){ | |
3224 // allow for varying parameters with defaults. value then expires as optional params | |
3225 var value = arguments.length > 0 ? arguments[0] : settings.value, | |
3226 expires = arguments.length > 1 ? arguments[1] : settings.expires, | |
3227 expire; | |
3228 | |
3229 // set a date in the future (or negative to delete) based on expires date offset | |
3230 if (typeof expires === 'number') { | |
3231 expire = new Date(); | |
3232 expire.setDate(expire.getDate() + expires); | |
3233 } | |
3234 | |
3235 // set the cookies with all the varying settings | |
3236 document.cookie = [ | |
3237 settings.name, | |
3238 '=', | |
3239 value, | |
3240 expire ? '; expires=' + expire.toUTCString() : '', | |
3241 settings.path ? '; path=' + settings.path : '', | |
3242 settings.domain ? '; domain=' + settings.domain : '', | |
3243 settings.secure ? '; secure' : '' | |
3244 ].join(''); | |
3245 }, | |
3246 _localStorage: function(){ | |
3247 if (settings.modernizr === true && typeof Modernizr !== 'undefined'){ | |
3248 return Modernizr.localstorage; | |
3249 } else { | |
3250 // check if a browser supports localstorage with simple try catch | |
3251 try { | |
3252 localStorage.setItem('jquery-remember-test','jquery-remember-test'); | |
3253 localStorage.removeItem('jquery-remember-test'); | |
3254 return true; | |
3255 } catch(e){ | |
3256 return false; | |
3257 } | |
3258 } | |
3259 }, | |
3260 _trim: function(s){ | |
3261 // trail a strings leading/ending whitespace | |
3262 return s.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); | |
3263 }, | |
3264 _decode: function(s){ | |
3265 return decodeURIComponent(s.replace(/\+/g, ' ')); | |
3266 } | |
3267 }; | |
3268 | |
3269 return remember.init(); | |
3270 }; | |
3271 | |
3272 return $.remember; | |
3273 | |
3274 }(jQuery)); | |
3275 (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}}); | |
3276 /*! jQuery UI - v1.10.3 - 2013-05-29 | |
3277 * http://jqueryui.com | |
3278 * 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 | |
3279 * Copyright 2013 jQuery Foundation and other contributors Licensed MIT */ | |
3280 | |
3281 (function( $, undefined ) { | |
3282 | |
3283 var uuid = 0, | |
3284 runiqueId = /^ui-id-\d+$/; | |
3285 | |
3286 // $.ui might exist from components with no dependencies, e.g., $.ui.position | |
3287 $.ui = $.ui || {}; | |
3288 | |
3289 $.extend( $.ui, { | |
3290 version: "1.10.3", | |
3291 | |
3292 keyCode: { | |
3293 BACKSPACE: 8, | |
3294 COMMA: 188, | |
3295 DELETE: 46, | |
3296 DOWN: 40, | |
3297 END: 35, | |
3298 ENTER: 13, | |
3299 ESCAPE: 27, | |
3300 HOME: 36, | |
3301 LEFT: 37, | |
3302 NUMPAD_ADD: 107, | |
3303 NUMPAD_DECIMAL: 110, | |
3304 NUMPAD_DIVIDE: 111, | |
3305 NUMPAD_ENTER: 108, | |
3306 NUMPAD_MULTIPLY: 106, | |
3307 NUMPAD_SUBTRACT: 109, | |
3308 PAGE_DOWN: 34, | |
3309 PAGE_UP: 33, | |
3310 PERIOD: 190, | |
3311 RIGHT: 39, | |
3312 SPACE: 32, | |
3313 TAB: 9, | |
3314 UP: 38 | |
3315 } | |
3316 }); | |
3317 | |
3318 // plugins | |
3319 $.fn.extend({ | |
3320 focus: (function( orig ) { | |
3321 return function( delay, fn ) { | |
3322 return typeof delay === "number" ? | |
3323 this.each(function() { | |
3324 var elem = this; | |
3325 setTimeout(function() { | |
3326 $( elem ).focus(); | |
3327 if ( fn ) { | |
3328 fn.call( elem ); | |
3329 } | |
3330 }, delay ); | |
3331 }) : | |
3332 orig.apply( this, arguments ); | |
3333 }; | |
3334 })( $.fn.focus ), | |
3335 | |
3336 scrollParent: function() { | |
3337 var scrollParent; | |
3338 if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) { | |
3339 scrollParent = this.parents().filter(function() { | |
3340 return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); | |
3341 }).eq(0); | |
3342 } else { | |
3343 scrollParent = this.parents().filter(function() { | |
3344 return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x")); | |
3345 }).eq(0); | |
3346 } | |
3347 | |
3348 return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent; | |
3349 }, | |
3350 | |
3351 zIndex: function( zIndex ) { | |
3352 if ( zIndex !== undefined ) { | |
3353 return this.css( "zIndex", zIndex ); | |
3354 } | |
3355 | |
3356 if ( this.length ) { | |
3357 var elem = $( this[ 0 ] ), position, value; | |
3358 while ( elem.length && elem[ 0 ] !== document ) { | |
3359 // Ignore z-index if position is set to a value where z-index is ignored by the browser | |
3360 // This makes behavior of this function consistent across browsers | |
3361 // WebKit always returns auto if the element is positioned | |
3362 position = elem.css( "position" ); | |
3363 if ( position === "absolute" || position === "relative" || position === "fixed" ) { | |
3364 // IE returns 0 when zIndex is not specified | |
3365 // other browsers return a string | |
3366 // we ignore the case of nested elements with an explicit value of 0 | |
3367 // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> | |
3368 value = parseInt( elem.css( "zIndex" ), 10 ); | |
3369 if ( !isNaN( value ) && value !== 0 ) { | |
3370 return value; | |
3371 } | |
3372 } | |
3373 elem = elem.parent(); | |
3374 } | |
3375 } | |
3376 | |
3377 return 0; | |
3378 }, | |
3379 | |
3380 uniqueId: function() { | |
3381 return this.each(function() { | |
3382 if ( !this.id ) { | |
3383 this.id = "ui-id-" + (++uuid); | |
3384 } | |
3385 }); | |
3386 }, | |
3387 | |
3388 removeUniqueId: function() { | |
3389 return this.each(function() { | |
3390 if ( runiqueId.test( this.id ) ) { | |
3391 $( this ).removeAttr( "id" ); | |
3392 } | |
3393 }); | |
3394 } | |
3395 }); | |
3396 | |
3397 // selectors | |
3398 function focusable( element, isTabIndexNotNaN ) { | |
3399 var map, mapName, img, | |
3400 nodeName = element.nodeName.toLowerCase(); | |
3401 if ( "area" === nodeName ) { | |
3402 map = element.parentNode; | |
3403 mapName = map.name; | |
3404 if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { | |
3405 return false; | |
3406 } | |
3407 img = $( "img[usemap=#" + mapName + "]" )[0]; | |
3408 return !!img && visible( img ); | |
3409 } | |
3410 return ( /input|select|textarea|button|object/.test( nodeName ) ? | |
3411 !element.disabled : | |
3412 "a" === nodeName ? | |
3413 element.href || isTabIndexNotNaN : | |
3414 isTabIndexNotNaN) && | |
3415 // the element and all of its ancestors must be visible | |
3416 visible( element ); | |
3417 } | |
3418 | |
3419 function visible( element ) { | |
3420 return $.expr.filters.visible( element ) && | |
3421 !$( element ).parents().addBack().filter(function() { | |
3422 return $.css( this, "visibility" ) === "hidden"; | |
3423 }).length; | |
3424 } | |
3425 | |
3426 $.extend( $.expr[ ":" ], { | |
3427 data: $.expr.createPseudo ? | |
3428 $.expr.createPseudo(function( dataName ) { | |
3429 return function( elem ) { | |
3430 return !!$.data( elem, dataName ); | |
3431 }; | |
3432 }) : | |
3433 // support: jQuery <1.8 | |
3434 function( elem, i, match ) { | |
3435 return !!$.data( elem, match[ 3 ] ); | |
3436 }, | |
3437 | |
3438 focusable: function( element ) { | |
3439 return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); | |
3440 }, | |
3441 | |
3442 tabbable: function( element ) { | |
3443 var tabIndex = $.attr( element, "tabindex" ), | |
3444 isTabIndexNaN = isNaN( tabIndex ); | |
3445 return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); | |
3446 } | |
3447 }); | |
3448 | |
3449 // support: jQuery <1.8 | |
3450 if ( !$( "<a>" ).outerWidth( 1 ).jquery ) { | |
3451 $.each( [ "Width", "Height" ], function( i, name ) { | |
3452 var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], | |
3453 type = name.toLowerCase(), | |
3454 orig = { | |
3455 innerWidth: $.fn.innerWidth, | |
3456 innerHeight: $.fn.innerHeight, | |
3457 outerWidth: $.fn.outerWidth, | |
3458 outerHeight: $.fn.outerHeight | |
3459 }; | |
3460 | |
3461 function reduce( elem, size, border, margin ) { | |
3462 $.each( side, function() { | |
3463 size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; | |
3464 if ( border ) { | |
3465 size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; | |
3466 } | |
3467 if ( margin ) { | |
3468 size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; | |
3469 } | |
3470 }); | |
3471 return size; | |
3472 } | |
3473 | |
3474 $.fn[ "inner" + name ] = function( size ) { | |
3475 if ( size === undefined ) { | |
3476 return orig[ "inner" + name ].call( this ); | |
3477 } | |
3478 | |
3479 return this.each(function() { | |
3480 $( this ).css( type, reduce( this, size ) + "px" ); | |
3481 }); | |
3482 }; | |
3483 | |
3484 $.fn[ "outer" + name] = function( size, margin ) { | |
3485 if ( typeof size !== "number" ) { | |
3486 return orig[ "outer" + name ].call( this, size ); | |
3487 } | |
3488 | |
3489 return this.each(function() { | |
3490 $( this).css( type, reduce( this, size, true, margin ) + "px" ); | |
3491 }); | |
3492 }; | |
3493 }); | |
3494 } | |
3495 | |
3496 // support: jQuery <1.8 | |
3497 if ( !$.fn.addBack ) { | |
3498 $.fn.addBack = function( selector ) { | |
3499 return this.add( selector == null ? | |
3500 this.prevObject : this.prevObject.filter( selector ) | |
3501 ); | |
3502 }; | |
3503 } | |
3504 | |
3505 // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) | |
3506 if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { | |
3507 $.fn.removeData = (function( removeData ) { | |
3508 return function( key ) { | |
3509 if ( arguments.length ) { | |
3510 return removeData.call( this, $.camelCase( key ) ); | |
3511 } else { | |
3512 return removeData.call( this ); | |
3513 } | |
3514 }; | |
3515 })( $.fn.removeData ); | |
3516 } | |
3517 | |
3518 | |
3519 | |
3520 | |
3521 | |
3522 // deprecated | |
3523 $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); | |
3524 | |
3525 $.support.selectstart = "onselectstart" in document.createElement( "div" ); | |
3526 $.fn.extend({ | |
3527 disableSelection: function() { | |
3528 return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + | |
3529 ".ui-disableSelection", function( event ) { | |
3530 event.preventDefault(); | |
3531 }); | |
3532 }, | |
3533 | |
3534 enableSelection: function() { | |
3535 return this.unbind( ".ui-disableSelection" ); | |
3536 } | |
3537 }); | |
3538 | |
3539 $.extend( $.ui, { | |
3540 // $.ui.plugin is deprecated. Use $.widget() extensions instead. | |
3541 plugin: { | |
3542 add: function( module, option, set ) { | |
3543 var i, | |
3544 proto = $.ui[ module ].prototype; | |
3545 for ( i in set ) { | |
3546 proto.plugins[ i ] = proto.plugins[ i ] || []; | |
3547 proto.plugins[ i ].push( [ option, set[ i ] ] ); | |
3548 } | |
3549 }, | |
3550 call: function( instance, name, args ) { | |
3551 var i, | |
3552 set = instance.plugins[ name ]; | |
3553 if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) { | |
3554 return; | |
3555 } | |
3556 | |
3557 for ( i = 0; i < set.length; i++ ) { | |
3558 if ( instance.options[ set[ i ][ 0 ] ] ) { | |
3559 set[ i ][ 1 ].apply( instance.element, args ); | |
3560 } | |
3561 } | |
3562 } | |
3563 }, | |
3564 | |
3565 // only used by resizable | |
3566 hasScroll: function( el, a ) { | |
3567 | |
3568 //If overflow is hidden, the element might have extra content, but the user wants to hide it | |
3569 if ( $( el ).css( "overflow" ) === "hidden") { | |
3570 return false; | |
3571 } | |
3572 | |
3573 var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", | |
3574 has = false; | |
3575 | |
3576 if ( el[ scroll ] > 0 ) { | |
3577 return true; | |
3578 } | |
3579 | |
3580 // TODO: determine which cases actually cause this to happen | |
3581 // if the element doesn't have the scroll set, see if it's possible to | |
3582 // set the scroll | |
3583 el[ scroll ] = 1; | |
3584 has = ( el[ scroll ] > 0 ); | |
3585 el[ scroll ] = 0; | |
3586 return has; | |
3587 } | |
3588 }); | |
3589 | |
3590 })( jQuery ); | |
3591 (function( $, undefined ) { | |
3592 | |
3593 var uuid = 0, | |
3594 slice = Array.prototype.slice, | |
3595 _cleanData = $.cleanData; | |
3596 $.cleanData = function( elems ) { | |
3597 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
3598 try { | |
3599 $( elem ).triggerHandler( "remove" ); | |
3600 // http://bugs.jquery.com/ticket/8235 | |
3601 } catch( e ) {} | |
3602 } | |
3603 _cleanData( elems ); | |
3604 }; | |
3605 | |
3606 $.widget = function( name, base, prototype ) { | |
3607 var fullName, existingConstructor, constructor, basePrototype, | |
3608 // proxiedPrototype allows the provided prototype to remain unmodified | |
3609 // so that it can be used as a mixin for multiple widgets (#8876) | |
3610 proxiedPrototype = {}, | |
3611 namespace = name.split( "." )[ 0 ]; | |
3612 | |
3613 name = name.split( "." )[ 1 ]; | |
3614 fullName = namespace + "-" + name; | |
3615 | |
3616 if ( !prototype ) { | |
3617 prototype = base; | |
3618 base = $.Widget; | |
3619 } | |
3620 | |
3621 // create selector for plugin | |
3622 $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { | |
3623 return !!$.data( elem, fullName ); | |
3624 }; | |
3625 | |
3626 $[ namespace ] = $[ namespace ] || {}; | |
3627 existingConstructor = $[ namespace ][ name ]; | |
3628 constructor = $[ namespace ][ name ] = function( options, element ) { | |
3629 // allow instantiation without "new" keyword | |
3630 if ( !this._createWidget ) { | |
3631 return new constructor( options, element ); | |
3632 } | |
3633 | |
3634 // allow instantiation without initializing for simple inheritance | |
3635 // must use "new" keyword (the code above always passes args) | |
3636 if ( arguments.length ) { | |
3637 this._createWidget( options, element ); | |
3638 } | |
3639 }; | |
3640 // extend with the existing constructor to carry over any static properties | |
3641 $.extend( constructor, existingConstructor, { | |
3642 version: prototype.version, | |
3643 // copy the object used to create the prototype in case we need to | |
3644 // redefine the widget later | |
3645 _proto: $.extend( {}, prototype ), | |
3646 // track widgets that inherit from this widget in case this widget is | |
3647 // redefined after a widget inherits from it | |
3648 _childConstructors: [] | |
3649 }); | |
3650 | |
3651 basePrototype = new base(); | |
3652 // we need to make the options hash a property directly on the new instance | |
3653 // otherwise we'll modify the options hash on the prototype that we're | |
3654 // inheriting from | |
3655 basePrototype.options = $.widget.extend( {}, basePrototype.options ); | |
3656 $.each( prototype, function( prop, value ) { | |
3657 if ( !$.isFunction( value ) ) { | |
3658 proxiedPrototype[ prop ] = value; | |
3659 return; | |
3660 } | |
3661 proxiedPrototype[ prop ] = (function() { | |
3662 var _super = function() { | |
3663 return base.prototype[ prop ].apply( this, arguments ); | |
3664 }, | |
3665 _superApply = function( args ) { | |
3666 return base.prototype[ prop ].apply( this, args ); | |
3667 }; | |
3668 return function() { | |
3669 var __super = this._super, | |
3670 __superApply = this._superApply, | |
3671 returnValue; | |
3672 | |
3673 this._super = _super; | |
3674 this._superApply = _superApply; | |
3675 | |
3676 returnValue = value.apply( this, arguments ); | |
3677 | |
3678 this._super = __super; | |
3679 this._superApply = __superApply; | |
3680 | |
3681 return returnValue; | |
3682 }; | |
3683 })(); | |
3684 }); | |
3685 constructor.prototype = $.widget.extend( basePrototype, { | |
3686 // TODO: remove support for widgetEventPrefix | |
3687 // always use the name + a colon as the prefix, e.g., draggable:start | |
3688 // don't prefix for widgets that aren't DOM-based | |
3689 widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name | |
3690 }, proxiedPrototype, { | |
3691 constructor: constructor, | |
3692 namespace: namespace, | |
3693 widgetName: name, | |
3694 widgetFullName: fullName | |
3695 }); | |
3696 | |
3697 // If this widget is being redefined then we need to find all widgets that | |
3698 // are inheriting from it and redefine all of them so that they inherit from | |
3699 // the new version of this widget. We're essentially trying to replace one | |
3700 // level in the prototype chain. | |
3701 if ( existingConstructor ) { | |
3702 $.each( existingConstructor._childConstructors, function( i, child ) { | |
3703 var childPrototype = child.prototype; | |
3704 | |
3705 // redefine the child widget using the same prototype that was | |
3706 // originally used, but inherit from the new version of the base | |
3707 $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); | |
3708 }); | |
3709 // remove the list of existing child constructors from the old constructor | |
3710 // so the old child constructors can be garbage collected | |
3711 delete existingConstructor._childConstructors; | |
3712 } else { | |
3713 base._childConstructors.push( constructor ); | |
3714 } | |
3715 | |
3716 $.widget.bridge( name, constructor ); | |
3717 }; | |
3718 | |
3719 $.widget.extend = function( target ) { | |
3720 var input = slice.call( arguments, 1 ), | |
3721 inputIndex = 0, | |
3722 inputLength = input.length, | |
3723 key, | |
3724 value; | |
3725 for ( ; inputIndex < inputLength; inputIndex++ ) { | |
3726 for ( key in input[ inputIndex ] ) { | |
3727 value = input[ inputIndex ][ key ]; | |
3728 if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { | |
3729 // Clone objects | |
3730 if ( $.isPlainObject( value ) ) { | |
3731 target[ key ] = $.isPlainObject( target[ key ] ) ? | |
3732 $.widget.extend( {}, target[ key ], value ) : | |
3733 // Don't extend strings, arrays, etc. with objects | |
3734 $.widget.extend( {}, value ); | |
3735 // Copy everything else by reference | |
3736 } else { | |
3737 target[ key ] = value; | |
3738 } | |
3739 } | |
3740 } | |
3741 } | |
3742 return target; | |
3743 }; | |
3744 | |
3745 $.widget.bridge = function( name, object ) { | |
3746 var fullName = object.prototype.widgetFullName || name; | |
3747 $.fn[ name ] = function( options ) { | |
3748 var isMethodCall = typeof options === "string", | |
3749 args = slice.call( arguments, 1 ), | |
3750 returnValue = this; | |
3751 | |
3752 // allow multiple hashes to be passed on init | |
3753 options = !isMethodCall && args.length ? | |
3754 $.widget.extend.apply( null, [ options ].concat(args) ) : | |
3755 options; | |
3756 | |
3757 if ( isMethodCall ) { | |
3758 this.each(function() { | |
3759 var methodValue, | |
3760 instance = $.data( this, fullName ); | |
3761 if ( !instance ) { | |
3762 return $.error( "cannot call methods on " + name + " prior to initialization; " + | |
3763 "attempted to call method '" + options + "'" ); | |
3764 } | |
3765 if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { | |
3766 return $.error( "no such method '" + options + "' for " + name + " widget instance" ); | |
3767 } | |
3768 methodValue = instance[ options ].apply( instance, args ); | |
3769 if ( methodValue !== instance && methodValue !== undefined ) { | |
3770 returnValue = methodValue && methodValue.jquery ? | |
3771 returnValue.pushStack( methodValue.get() ) : | |
3772 methodValue; | |
3773 return false; | |
3774 } | |
3775 }); | |
3776 } else { | |
3777 this.each(function() { | |
3778 var instance = $.data( this, fullName ); | |
3779 if ( instance ) { | |
3780 instance.option( options || {} )._init(); | |
3781 } else { | |
3782 $.data( this, fullName, new object( options, this ) ); | |
3783 } | |
3784 }); | |
3785 } | |
3786 | |
3787 return returnValue; | |
3788 }; | |
3789 }; | |
3790 | |
3791 $.Widget = function( /* options, element */ ) {}; | |
3792 $.Widget._childConstructors = []; | |
3793 | |
3794 $.Widget.prototype = { | |
3795 widgetName: "widget", | |
3796 widgetEventPrefix: "", | |
3797 defaultElement: "<div>", | |
3798 options: { | |
3799 disabled: false, | |
3800 | |
3801 // callbacks | |
3802 create: null | |
3803 }, | |
3804 _createWidget: function( options, element ) { | |
3805 element = $( element || this.defaultElement || this )[ 0 ]; | |
3806 this.element = $( element ); | |
3807 this.uuid = uuid++; | |
3808 this.eventNamespace = "." + this.widgetName + this.uuid; | |
3809 this.options = $.widget.extend( {}, | |
3810 this.options, | |
3811 this._getCreateOptions(), | |
3812 options ); | |
3813 | |
3814 this.bindings = $(); | |
3815 this.hoverable = $(); | |
3816 this.focusable = $(); | |
3817 | |
3818 if ( element !== this ) { | |
3819 $.data( element, this.widgetFullName, this ); | |
3820 this._on( true, this.element, { | |
3821 remove: function( event ) { | |
3822 if ( event.target === element ) { | |
3823 this.destroy(); | |
3824 } | |
3825 } | |
3826 }); | |
3827 this.document = $( element.style ? | |
3828 // element within the document | |
3829 element.ownerDocument : | |
3830 // element is window or document | |
3831 element.document || element ); | |
3832 this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); | |
3833 } | |
3834 | |
3835 this._create(); | |
3836 this._trigger( "create", null, this._getCreateEventData() ); | |
3837 this._init(); | |
3838 }, | |
3839 _getCreateOptions: $.noop, | |
3840 _getCreateEventData: $.noop, | |
3841 _create: $.noop, | |
3842 _init: $.noop, | |
3843 | |
3844 destroy: function() { | |
3845 this._destroy(); | |
3846 // we can probably remove the unbind calls in 2.0 | |
3847 // all event bindings should go through this._on() | |
3848 this.element | |
3849 .unbind( this.eventNamespace ) | |
3850 // 1.9 BC for #7810 | |
3851 // TODO remove dual storage | |
3852 .removeData( this.widgetName ) | |
3853 .removeData( this.widgetFullName ) | |
3854 // support: jquery <1.6.3 | |
3855 // http://bugs.jquery.com/ticket/9413 | |
3856 .removeData( $.camelCase( this.widgetFullName ) ); | |
3857 this.widget() | |
3858 .unbind( this.eventNamespace ) | |
3859 .removeAttr( "aria-disabled" ) | |
3860 .removeClass( | |
3861 this.widgetFullName + "-disabled " + | |
3862 "ui-state-disabled" ); | |
3863 | |
3864 // clean up events and states | |
3865 this.bindings.unbind( this.eventNamespace ); | |
3866 this.hoverable.removeClass( "ui-state-hover" ); | |
3867 this.focusable.removeClass( "ui-state-focus" ); | |
3868 }, | |
3869 _destroy: $.noop, | |
3870 | |
3871 widget: function() { | |
3872 return this.element; | |
3873 }, | |
3874 | |
3875 option: function( key, value ) { | |
3876 var options = key, | |
3877 parts, | |
3878 curOption, | |
3879 i; | |
3880 | |
3881 if ( arguments.length === 0 ) { | |
3882 // don't return a reference to the internal hash | |
3883 return $.widget.extend( {}, this.options ); | |
3884 } | |
3885 | |
3886 if ( typeof key === "string" ) { | |
3887 // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } | |
3888 options = {}; | |
3889 parts = key.split( "." ); | |
3890 key = parts.shift(); | |
3891 if ( parts.length ) { | |
3892 curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); | |
3893 for ( i = 0; i < parts.length - 1; i++ ) { | |
3894 curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; | |
3895 curOption = curOption[ parts[ i ] ]; | |
3896 } | |
3897 key = parts.pop(); | |
3898 if ( value === undefined ) { | |
3899 return curOption[ key ] === undefined ? null : curOption[ key ]; | |
3900 } | |
3901 curOption[ key ] = value; | |
3902 } else { | |
3903 if ( value === undefined ) { | |
3904 return this.options[ key ] === undefined ? null : this.options[ key ]; | |
3905 } | |
3906 options[ key ] = value; | |
3907 } | |
3908 } | |
3909 | |
3910 this._setOptions( options ); | |
3911 | |
3912 return this; | |
3913 }, | |
3914 _setOptions: function( options ) { | |
3915 var key; | |
3916 | |
3917 for ( key in options ) { | |
3918 this._setOption( key, options[ key ] ); | |
3919 } | |
3920 | |
3921 return this; | |
3922 }, | |
3923 _setOption: function( key, value ) { | |
3924 this.options[ key ] = value; | |
3925 | |
3926 if ( key === "disabled" ) { | |
3927 this.widget() | |
3928 .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) | |
3929 .attr( "aria-disabled", value ); | |
3930 this.hoverable.removeClass( "ui-state-hover" ); | |
3931 this.focusable.removeClass( "ui-state-focus" ); | |
3932 } | |
3933 | |
3934 return this; | |
3935 }, | |
3936 | |
3937 enable: function() { | |
3938 return this._setOption( "disabled", false ); | |
3939 }, | |
3940 disable: function() { | |
3941 return this._setOption( "disabled", true ); | |
3942 }, | |
3943 | |
3944 _on: function( suppressDisabledCheck, element, handlers ) { | |
3945 var delegateElement, | |
3946 instance = this; | |
3947 | |
3948 // no suppressDisabledCheck flag, shuffle arguments | |
3949 if ( typeof suppressDisabledCheck !== "boolean" ) { | |
3950 handlers = element; | |
3951 element = suppressDisabledCheck; | |
3952 suppressDisabledCheck = false; | |
3953 } | |
3954 | |
3955 // no element argument, shuffle and use this.element | |
3956 if ( !handlers ) { | |
3957 handlers = element; | |
3958 element = this.element; | |
3959 delegateElement = this.widget(); | |
3960 } else { | |
3961 // accept selectors, DOM elements | |
3962 element = delegateElement = $( element ); | |
3963 this.bindings = this.bindings.add( element ); | |
3964 } | |
3965 | |
3966 $.each( handlers, function( event, handler ) { | |
3967 function handlerProxy() { | |
3968 // allow widgets to customize the disabled handling | |
3969 // - disabled as an array instead of boolean | |
3970 // - disabled class as method for disabling individual parts | |
3971 if ( !suppressDisabledCheck && | |
3972 ( instance.options.disabled === true || | |
3973 $( this ).hasClass( "ui-state-disabled" ) ) ) { | |
3974 return; | |
3975 } | |
3976 return ( typeof handler === "string" ? instance[ handler ] : handler ) | |
3977 .apply( instance, arguments ); | |
3978 } | |
3979 | |
3980 // copy the guid so direct unbinding works | |
3981 if ( typeof handler !== "string" ) { | |
3982 handlerProxy.guid = handler.guid = | |
3983 handler.guid || handlerProxy.guid || $.guid++; | |
3984 } | |
3985 | |
3986 var match = event.match( /^(\w+)\s*(.*)$/ ), | |
3987 eventName = match[1] + instance.eventNamespace, | |
3988 selector = match[2]; | |
3989 if ( selector ) { | |
3990 delegateElement.delegate( selector, eventName, handlerProxy ); | |
3991 } else { | |
3992 element.bind( eventName, handlerProxy ); | |
3993 } | |
3994 }); | |
3995 }, | |
3996 | |
3997 _off: function( element, eventName ) { | |
3998 eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; | |
3999 element.unbind( eventName ).undelegate( eventName ); | |
4000 }, | |
4001 | |
4002 _delay: function( handler, delay ) { | |
4003 function handlerProxy() { | |
4004 return ( typeof handler === "string" ? instance[ handler ] : handler ) | |
4005 .apply( instance, arguments ); | |
4006 } | |
4007 var instance = this; | |
4008 return setTimeout( handlerProxy, delay || 0 ); | |
4009 }, | |
4010 | |
4011 _hoverable: function( element ) { | |
4012 this.hoverable = this.hoverable.add( element ); | |
4013 this._on( element, { | |
4014 mouseenter: function( event ) { | |
4015 $( event.currentTarget ).addClass( "ui-state-hover" ); | |
4016 }, | |
4017 mouseleave: function( event ) { | |
4018 $( event.currentTarget ).removeClass( "ui-state-hover" ); | |
4019 } | |
4020 }); | |
4021 }, | |
4022 | |
4023 _focusable: function( element ) { | |
4024 this.focusable = this.focusable.add( element ); | |
4025 this._on( element, { | |
4026 focusin: function( event ) { | |
4027 $( event.currentTarget ).addClass( "ui-state-focus" ); | |
4028 }, | |
4029 focusout: function( event ) { | |
4030 $( event.currentTarget ).removeClass( "ui-state-focus" ); | |
4031 } | |
4032 }); | |
4033 }, | |
4034 | |
4035 _trigger: function( type, event, data ) { | |
4036 var prop, orig, | |
4037 callback = this.options[ type ]; | |
4038 | |
4039 data = data || {}; | |
4040 event = $.Event( event ); | |
4041 event.type = ( type === this.widgetEventPrefix ? | |
4042 type : | |
4043 this.widgetEventPrefix + type ).toLowerCase(); | |
4044 // the original event may come from any element | |
4045 // so we need to reset the target on the new event | |
4046 event.target = this.element[ 0 ]; | |
4047 | |
4048 // copy original event properties over to the new event | |
4049 orig = event.originalEvent; | |
4050 if ( orig ) { | |
4051 for ( prop in orig ) { | |
4052 if ( !( prop in event ) ) { | |
4053 event[ prop ] = orig[ prop ]; | |
4054 } | |
4055 } | |
4056 } | |
4057 | |
4058 this.element.trigger( event, data ); | |
4059 return !( $.isFunction( callback ) && | |
4060 callback.apply( this.element[0], [ event ].concat( data ) ) === false || | |
4061 event.isDefaultPrevented() ); | |
4062 } | |
4063 }; | |
4064 | |
4065 $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { | |
4066 $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { | |
4067 if ( typeof options === "string" ) { | |
4068 options = { effect: options }; | |
4069 } | |
4070 var hasOptions, | |
4071 effectName = !options ? | |
4072 method : | |
4073 options === true || typeof options === "number" ? | |
4074 defaultEffect : | |
4075 options.effect || defaultEffect; | |
4076 options = options || {}; | |
4077 if ( typeof options === "number" ) { | |
4078 options = { duration: options }; | |
4079 } | |
4080 hasOptions = !$.isEmptyObject( options ); | |
4081 options.complete = callback; | |
4082 if ( options.delay ) { | |
4083 element.delay( options.delay ); | |
4084 } | |
4085 if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { | |
4086 element[ method ]( options ); | |
4087 } else if ( effectName !== method && element[ effectName ] ) { | |
4088 element[ effectName ]( options.duration, options.easing, callback ); | |
4089 } else { | |
4090 element.queue(function( next ) { | |
4091 $( this )[ method ](); | |
4092 if ( callback ) { | |
4093 callback.call( element[ 0 ] ); | |
4094 } | |
4095 next(); | |
4096 }); | |
4097 } | |
4098 }; | |
4099 }); | |
4100 | |
4101 })( jQuery ); | |
4102 (function( $, undefined ) { | |
4103 | |
4104 var mouseHandled = false; | |
4105 $( document ).mouseup( function() { | |
4106 mouseHandled = false; | |
4107 }); | |
4108 | |
4109 $.widget("ui.mouse", { | |
4110 version: "1.10.3", | |
4111 options: { | |
4112 cancel: "input,textarea,button,select,option", | |
4113 distance: 1, | |
4114 delay: 0 | |
4115 }, | |
4116 _mouseInit: function() { | |
4117 var that = this; | |
4118 | |
4119 this.element | |
4120 .bind("mousedown."+this.widgetName, function(event) { | |
4121 return that._mouseDown(event); | |
4122 }) | |
4123 .bind("click."+this.widgetName, function(event) { | |
4124 if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { | |
4125 $.removeData(event.target, that.widgetName + ".preventClickEvent"); | |
4126 event.stopImmediatePropagation(); | |
4127 return false; | |
4128 } | |
4129 }); | |
4130 | |
4131 this.started = false; | |
4132 }, | |
4133 | |
4134 // TODO: make sure destroying one instance of mouse doesn't mess with | |
4135 // other instances of mouse | |
4136 _mouseDestroy: function() { | |
4137 this.element.unbind("."+this.widgetName); | |
4138 if ( this._mouseMoveDelegate ) { | |
4139 $(document) | |
4140 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) | |
4141 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); | |
4142 } | |
4143 }, | |
4144 | |
4145 _mouseDown: function(event) { | |
4146 // don't let more than one widget handle mouseStart | |
4147 if( mouseHandled ) { return; } | |
4148 | |
4149 // we may have missed mouseup (out of window) | |
4150 (this._mouseStarted && this._mouseUp(event)); | |
4151 | |
4152 this._mouseDownEvent = event; | |
4153 | |
4154 var that = this, | |
4155 btnIsLeft = (event.which === 1), | |
4156 // event.target.nodeName works around a bug in IE 8 with | |
4157 // disabled inputs (#7620) | |
4158 elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); | |
4159 if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { | |
4160 return true; | |
4161 } | |
4162 | |
4163 this.mouseDelayMet = !this.options.delay; | |
4164 if (!this.mouseDelayMet) { | |
4165 this._mouseDelayTimer = setTimeout(function() { | |
4166 that.mouseDelayMet = true; | |
4167 }, this.options.delay); | |
4168 } | |
4169 | |
4170 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { | |
4171 this._mouseStarted = (this._mouseStart(event) !== false); | |
4172 if (!this._mouseStarted) { | |
4173 event.preventDefault(); | |
4174 return true; | |
4175 } | |
4176 } | |
4177 | |
4178 // Click event may never have fired (Gecko & Opera) | |
4179 if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { | |
4180 $.removeData(event.target, this.widgetName + ".preventClickEvent"); | |
4181 } | |
4182 | |
4183 // these delegates are required to keep context | |
4184 this._mouseMoveDelegate = function(event) { | |
4185 return that._mouseMove(event); | |
4186 }; | |
4187 this._mouseUpDelegate = function(event) { | |
4188 return that._mouseUp(event); | |
4189 }; | |
4190 $(document) | |
4191 .bind("mousemove."+this.widgetName, this._mouseMoveDelegate) | |
4192 .bind("mouseup."+this.widgetName, this._mouseUpDelegate); | |
4193 | |
4194 event.preventDefault(); | |
4195 | |
4196 mouseHandled = true; | |
4197 return true; | |
4198 }, | |
4199 | |
4200 _mouseMove: function(event) { | |
4201 // IE mouseup check - mouseup happened when mouse was out of window | |
4202 if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { | |
4203 return this._mouseUp(event); | |
4204 } | |
4205 | |
4206 if (this._mouseStarted) { | |
4207 this._mouseDrag(event); | |
4208 return event.preventDefault(); | |
4209 } | |
4210 | |
4211 if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { | |
4212 this._mouseStarted = | |
4213 (this._mouseStart(this._mouseDownEvent, event) !== false); | |
4214 (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); | |
4215 } | |
4216 | |
4217 return !this._mouseStarted; | |
4218 }, | |
4219 | |
4220 _mouseUp: function(event) { | |
4221 $(document) | |
4222 .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate) | |
4223 .unbind("mouseup."+this.widgetName, this._mouseUpDelegate); | |
4224 | |
4225 if (this._mouseStarted) { | |
4226 this._mouseStarted = false; | |
4227 | |
4228 if (event.target === this._mouseDownEvent.target) { | |
4229 $.data(event.target, this.widgetName + ".preventClickEvent", true); | |
4230 } | |
4231 | |
4232 this._mouseStop(event); | |
4233 } | |
4234 | |
4235 return false; | |
4236 }, | |
4237 | |
4238 _mouseDistanceMet: function(event) { | |
4239 return (Math.max( | |
4240 Math.abs(this._mouseDownEvent.pageX - event.pageX), | |
4241 Math.abs(this._mouseDownEvent.pageY - event.pageY) | |
4242 ) >= this.options.distance | |
4243 ); | |
4244 }, | |
4245 | |
4246 _mouseDelayMet: function(/* event */) { | |
4247 return this.mouseDelayMet; | |
4248 }, | |
4249 | |
4250 // These are placeholder methods, to be overriden by extending plugin | |
4251 _mouseStart: function(/* event */) {}, | |
4252 _mouseDrag: function(/* event */) {}, | |
4253 _mouseStop: function(/* event */) {}, | |
4254 _mouseCapture: function(/* event */) { return true; } | |
4255 }); | |
4256 | |
4257 })(jQuery); | |
4258 (function( $, undefined ) { | |
4259 | |
4260 $.ui = $.ui || {}; | |
4261 | |
4262 var cachedScrollbarWidth, | |
4263 max = Math.max, | |
4264 abs = Math.abs, | |
4265 round = Math.round, | |
4266 rhorizontal = /left|center|right/, | |
4267 rvertical = /top|center|bottom/, | |
4268 roffset = /[\+\-]\d+(\.[\d]+)?%?/, | |
4269 rposition = /^\w+/, | |
4270 rpercent = /%$/, | |
4271 _position = $.fn.position; | |
4272 | |
4273 function getOffsets( offsets, width, height ) { | |
4274 return [ | |
4275 parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), | |
4276 parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) | |
4277 ]; | |
4278 } | |
4279 | |
4280 function parseCss( element, property ) { | |
4281 return parseInt( $.css( element, property ), 10 ) || 0; | |
4282 } | |
4283 | |
4284 function getDimensions( elem ) { | |
4285 var raw = elem[0]; | |
4286 if ( raw.nodeType === 9 ) { | |
4287 return { | |
4288 width: elem.width(), | |
4289 height: elem.height(), | |
4290 offset: { top: 0, left: 0 } | |
4291 }; | |
4292 } | |
4293 if ( $.isWindow( raw ) ) { | |
4294 return { | |
4295 width: elem.width(), | |
4296 height: elem.height(), | |
4297 offset: { top: elem.scrollTop(), left: elem.scrollLeft() } | |
4298 }; | |
4299 } | |
4300 if ( raw.preventDefault ) { | |
4301 return { | |
4302 width: 0, | |
4303 height: 0, | |
4304 offset: { top: raw.pageY, left: raw.pageX } | |
4305 }; | |
4306 } | |
4307 return { | |
4308 width: elem.outerWidth(), | |
4309 height: elem.outerHeight(), | |
4310 offset: elem.offset() | |
4311 }; | |
4312 } | |
4313 | |
4314 $.position = { | |
4315 scrollbarWidth: function() { | |
4316 if ( cachedScrollbarWidth !== undefined ) { | |
4317 return cachedScrollbarWidth; | |
4318 } | |
4319 var w1, w2, | |
4320 div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ), | |
4321 innerDiv = div.children()[0]; | |
4322 | |
4323 $( "body" ).append( div ); | |
4324 w1 = innerDiv.offsetWidth; | |
4325 div.css( "overflow", "scroll" ); | |
4326 | |
4327 w2 = innerDiv.offsetWidth; | |
4328 | |
4329 if ( w1 === w2 ) { | |
4330 w2 = div[0].clientWidth; | |
4331 } | |
4332 | |
4333 div.remove(); | |
4334 | |
4335 return (cachedScrollbarWidth = w1 - w2); | |
4336 }, | |
4337 getScrollInfo: function( within ) { | |
4338 var overflowX = within.isWindow ? "" : within.element.css( "overflow-x" ), | |
4339 overflowY = within.isWindow ? "" : within.element.css( "overflow-y" ), | |
4340 hasOverflowX = overflowX === "scroll" || | |
4341 ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), | |
4342 hasOverflowY = overflowY === "scroll" || | |
4343 ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); | |
4344 return { | |
4345 width: hasOverflowY ? $.position.scrollbarWidth() : 0, | |
4346 height: hasOverflowX ? $.position.scrollbarWidth() : 0 | |
4347 }; | |
4348 }, | |
4349 getWithinInfo: function( element ) { | |
4350 var withinElement = $( element || window ), | |
4351 isWindow = $.isWindow( withinElement[0] ); | |
4352 return { | |
4353 element: withinElement, | |
4354 isWindow: isWindow, | |
4355 offset: withinElement.offset() || { left: 0, top: 0 }, | |
4356 scrollLeft: withinElement.scrollLeft(), | |
4357 scrollTop: withinElement.scrollTop(), | |
4358 width: isWindow ? withinElement.width() : withinElement.outerWidth(), | |
4359 height: isWindow ? withinElement.height() : withinElement.outerHeight() | |
4360 }; | |
4361 } | |
4362 }; | |
4363 | |
4364 $.fn.position = function( options ) { | |
4365 if ( !options || !options.of ) { | |
4366 return _position.apply( this, arguments ); | |
4367 } | |
4368 | |
4369 // make a copy, we don't want to modify arguments | |
4370 options = $.extend( {}, options ); | |
4371 | |
4372 var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, | |
4373 target = $( options.of ), | |
4374 within = $.position.getWithinInfo( options.within ), | |
4375 scrollInfo = $.position.getScrollInfo( within ), | |
4376 collision = ( options.collision || "flip" ).split( " " ), | |
4377 offsets = {}; | |
4378 | |
4379 dimensions = getDimensions( target ); | |
4380 if ( target[0].preventDefault ) { | |
4381 // force left top to allow flipping | |
4382 options.at = "left top"; | |
4383 } | |
4384 targetWidth = dimensions.width; | |
4385 targetHeight = dimensions.height; | |
4386 targetOffset = dimensions.offset; | |
4387 // clone to reuse original targetOffset later | |
4388 basePosition = $.extend( {}, targetOffset ); | |
4389 | |
4390 // force my and at to have valid horizontal and vertical positions | |
4391 // if a value is missing or invalid, it will be converted to center | |
4392 $.each( [ "my", "at" ], function() { | |
4393 var pos = ( options[ this ] || "" ).split( " " ), | |
4394 horizontalOffset, | |
4395 verticalOffset; | |
4396 | |
4397 if ( pos.length === 1) { | |
4398 pos = rhorizontal.test( pos[ 0 ] ) ? | |
4399 pos.concat( [ "center" ] ) : | |
4400 rvertical.test( pos[ 0 ] ) ? | |
4401 [ "center" ].concat( pos ) : | |
4402 [ "center", "center" ]; | |
4403 } | |
4404 pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; | |
4405 pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; | |
4406 | |
4407 // calculate offsets | |
4408 horizontalOffset = roffset.exec( pos[ 0 ] ); | |
4409 verticalOffset = roffset.exec( pos[ 1 ] ); | |
4410 offsets[ this ] = [ | |
4411 horizontalOffset ? horizontalOffset[ 0 ] : 0, | |
4412 verticalOffset ? verticalOffset[ 0 ] : 0 | |
4413 ]; | |
4414 | |
4415 // reduce to just the positions without the offsets | |
4416 options[ this ] = [ | |
4417 rposition.exec( pos[ 0 ] )[ 0 ], | |
4418 rposition.exec( pos[ 1 ] )[ 0 ] | |
4419 ]; | |
4420 }); | |
4421 | |
4422 // normalize collision option | |
4423 if ( collision.length === 1 ) { | |
4424 collision[ 1 ] = collision[ 0 ]; | |
4425 } | |
4426 | |
4427 if ( options.at[ 0 ] === "right" ) { | |
4428 basePosition.left += targetWidth; | |
4429 } else if ( options.at[ 0 ] === "center" ) { | |
4430 basePosition.left += targetWidth / 2; | |
4431 } | |
4432 | |
4433 if ( options.at[ 1 ] === "bottom" ) { | |
4434 basePosition.top += targetHeight; | |
4435 } else if ( options.at[ 1 ] === "center" ) { | |
4436 basePosition.top += targetHeight / 2; | |
4437 } | |
4438 | |
4439 atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); | |
4440 basePosition.left += atOffset[ 0 ]; | |
4441 basePosition.top += atOffset[ 1 ]; | |
4442 | |
4443 return this.each(function() { | |
4444 var collisionPosition, using, | |
4445 elem = $( this ), | |
4446 elemWidth = elem.outerWidth(), | |
4447 elemHeight = elem.outerHeight(), | |
4448 marginLeft = parseCss( this, "marginLeft" ), | |
4449 marginTop = parseCss( this, "marginTop" ), | |
4450 collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, | |
4451 collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, | |
4452 position = $.extend( {}, basePosition ), | |
4453 myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); | |
4454 | |
4455 if ( options.my[ 0 ] === "right" ) { | |
4456 position.left -= elemWidth; | |
4457 } else if ( options.my[ 0 ] === "center" ) { | |
4458 position.left -= elemWidth / 2; | |
4459 } | |
4460 | |
4461 if ( options.my[ 1 ] === "bottom" ) { | |
4462 position.top -= elemHeight; | |
4463 } else if ( options.my[ 1 ] === "center" ) { | |
4464 position.top -= elemHeight / 2; | |
4465 } | |
4466 | |
4467 position.left += myOffset[ 0 ]; | |
4468 position.top += myOffset[ 1 ]; | |
4469 | |
4470 // if the browser doesn't support fractions, then round for consistent results | |
4471 if ( !$.support.offsetFractions ) { | |
4472 position.left = round( position.left ); | |
4473 position.top = round( position.top ); | |
4474 } | |
4475 | |
4476 collisionPosition = { | |
4477 marginLeft: marginLeft, | |
4478 marginTop: marginTop | |
4479 }; | |
4480 | |
4481 $.each( [ "left", "top" ], function( i, dir ) { | |
4482 if ( $.ui.position[ collision[ i ] ] ) { | |
4483 $.ui.position[ collision[ i ] ][ dir ]( position, { | |
4484 targetWidth: targetWidth, | |
4485 targetHeight: targetHeight, | |
4486 elemWidth: elemWidth, | |
4487 elemHeight: elemHeight, | |
4488 collisionPosition: collisionPosition, | |
4489 collisionWidth: collisionWidth, | |
4490 collisionHeight: collisionHeight, | |
4491 offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], | |
4492 my: options.my, | |
4493 at: options.at, | |
4494 within: within, | |
4495 elem : elem | |
4496 }); | |
4497 } | |
4498 }); | |
4499 | |
4500 if ( options.using ) { | |
4501 // adds feedback as second argument to using callback, if present | |
4502 using = function( props ) { | |
4503 var left = targetOffset.left - position.left, | |
4504 right = left + targetWidth - elemWidth, | |
4505 top = targetOffset.top - position.top, | |
4506 bottom = top + targetHeight - elemHeight, | |
4507 feedback = { | |
4508 target: { | |
4509 element: target, | |
4510 left: targetOffset.left, | |
4511 top: targetOffset.top, | |
4512 width: targetWidth, | |
4513 height: targetHeight | |
4514 }, | |
4515 element: { | |
4516 element: elem, | |
4517 left: position.left, | |
4518 top: position.top, | |
4519 width: elemWidth, | |
4520 height: elemHeight | |
4521 }, | |
4522 horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", | |
4523 vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" | |
4524 }; | |
4525 if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { | |
4526 feedback.horizontal = "center"; | |
4527 } | |
4528 if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { | |
4529 feedback.vertical = "middle"; | |
4530 } | |
4531 if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { | |
4532 feedback.important = "horizontal"; | |
4533 } else { | |
4534 feedback.important = "vertical"; | |
4535 } | |
4536 options.using.call( this, props, feedback ); | |
4537 }; | |
4538 } | |
4539 | |
4540 elem.offset( $.extend( position, { using: using } ) ); | |
4541 }); | |
4542 }; | |
4543 | |
4544 $.ui.position = { | |
4545 fit: { | |
4546 left: function( position, data ) { | |
4547 var within = data.within, | |
4548 withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, | |
4549 outerWidth = within.width, | |
4550 collisionPosLeft = position.left - data.collisionPosition.marginLeft, | |
4551 overLeft = withinOffset - collisionPosLeft, | |
4552 overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, | |
4553 newOverRight; | |
4554 | |
4555 // element is wider than within | |
4556 if ( data.collisionWidth > outerWidth ) { | |
4557 // element is initially over the left side of within | |
4558 if ( overLeft > 0 && overRight <= 0 ) { | |
4559 newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; | |
4560 position.left += overLeft - newOverRight; | |
4561 // element is initially over right side of within | |
4562 } else if ( overRight > 0 && overLeft <= 0 ) { | |
4563 position.left = withinOffset; | |
4564 // element is initially over both left and right sides of within | |
4565 } else { | |
4566 if ( overLeft > overRight ) { | |
4567 position.left = withinOffset + outerWidth - data.collisionWidth; | |
4568 } else { | |
4569 position.left = withinOffset; | |
4570 } | |
4571 } | |
4572 // too far left -> align with left edge | |
4573 } else if ( overLeft > 0 ) { | |
4574 position.left += overLeft; | |
4575 // too far right -> align with right edge | |
4576 } else if ( overRight > 0 ) { | |
4577 position.left -= overRight; | |
4578 // adjust based on position and margin | |
4579 } else { | |
4580 position.left = max( position.left - collisionPosLeft, position.left ); | |
4581 } | |
4582 }, | |
4583 top: function( position, data ) { | |
4584 var within = data.within, | |
4585 withinOffset = within.isWindow ? within.scrollTop : within.offset.top, | |
4586 outerHeight = data.within.height, | |
4587 collisionPosTop = position.top - data.collisionPosition.marginTop, | |
4588 overTop = withinOffset - collisionPosTop, | |
4589 overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, | |
4590 newOverBottom; | |
4591 | |
4592 // element is taller than within | |
4593 if ( data.collisionHeight > outerHeight ) { | |
4594 // element is initially over the top of within | |
4595 if ( overTop > 0 && overBottom <= 0 ) { | |
4596 newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; | |
4597 position.top += overTop - newOverBottom; | |
4598 // element is initially over bottom of within | |
4599 } else if ( overBottom > 0 && overTop <= 0 ) { | |
4600 position.top = withinOffset; | |
4601 // element is initially over both top and bottom of within | |
4602 } else { | |
4603 if ( overTop > overBottom ) { | |
4604 position.top = withinOffset + outerHeight - data.collisionHeight; | |
4605 } else { | |
4606 position.top = withinOffset; | |
4607 } | |
4608 } | |
4609 // too far up -> align with top | |
4610 } else if ( overTop > 0 ) { | |
4611 position.top += overTop; | |
4612 // too far down -> align with bottom edge | |
4613 } else if ( overBottom > 0 ) { | |
4614 position.top -= overBottom; | |
4615 // adjust based on position and margin | |
4616 } else { | |
4617 position.top = max( position.top - collisionPosTop, position.top ); | |
4618 } | |
4619 } | |
4620 }, | |
4621 flip: { | |
4622 left: function( position, data ) { | |
4623 var within = data.within, | |
4624 withinOffset = within.offset.left + within.scrollLeft, | |
4625 outerWidth = within.width, | |
4626 offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, | |
4627 collisionPosLeft = position.left - data.collisionPosition.marginLeft, | |
4628 overLeft = collisionPosLeft - offsetLeft, | |
4629 overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, | |
4630 myOffset = data.my[ 0 ] === "left" ? | |
4631 -data.elemWidth : | |
4632 data.my[ 0 ] === "right" ? | |
4633 data.elemWidth : | |
4634 0, | |
4635 atOffset = data.at[ 0 ] === "left" ? | |
4636 data.targetWidth : | |
4637 data.at[ 0 ] === "right" ? | |
4638 -data.targetWidth : | |
4639 0, | |
4640 offset = -2 * data.offset[ 0 ], | |
4641 newOverRight, | |
4642 newOverLeft; | |
4643 | |
4644 if ( overLeft < 0 ) { | |
4645 newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; | |
4646 if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { | |
4647 position.left += myOffset + atOffset + offset; | |
4648 } | |
4649 } | |
4650 else if ( overRight > 0 ) { | |
4651 newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; | |
4652 if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { | |
4653 position.left += myOffset + atOffset + offset; | |
4654 } | |
4655 } | |
4656 }, | |
4657 top: function( position, data ) { | |
4658 var within = data.within, | |
4659 withinOffset = within.offset.top + within.scrollTop, | |
4660 outerHeight = within.height, | |
4661 offsetTop = within.isWindow ? within.scrollTop : within.offset.top, | |
4662 collisionPosTop = position.top - data.collisionPosition.marginTop, | |
4663 overTop = collisionPosTop - offsetTop, | |
4664 overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, | |
4665 top = data.my[ 1 ] === "top", | |
4666 myOffset = top ? | |
4667 -data.elemHeight : | |
4668 data.my[ 1 ] === "bottom" ? | |
4669 data.elemHeight : | |
4670 0, | |
4671 atOffset = data.at[ 1 ] === "top" ? | |
4672 data.targetHeight : | |
4673 data.at[ 1 ] === "bottom" ? | |
4674 -data.targetHeight : | |
4675 0, | |
4676 offset = -2 * data.offset[ 1 ], | |
4677 newOverTop, | |
4678 newOverBottom; | |
4679 if ( overTop < 0 ) { | |
4680 newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; | |
4681 if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { | |
4682 position.top += myOffset + atOffset + offset; | |
4683 } | |
4684 } | |
4685 else if ( overBottom > 0 ) { | |
4686 newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; | |
4687 if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { | |
4688 position.top += myOffset + atOffset + offset; | |
4689 } | |
4690 } | |
4691 } | |
4692 }, | |
4693 flipfit: { | |
4694 left: function() { | |
4695 $.ui.position.flip.left.apply( this, arguments ); | |
4696 $.ui.position.fit.left.apply( this, arguments ); | |
4697 }, | |
4698 top: function() { | |
4699 $.ui.position.flip.top.apply( this, arguments ); | |
4700 $.ui.position.fit.top.apply( this, arguments ); | |
4701 } | |
4702 } | |
4703 }; | |
4704 | |
4705 // fraction support test | |
4706 (function () { | |
4707 var testElement, testElementParent, testElementStyle, offsetLeft, i, | |
4708 body = document.getElementsByTagName( "body" )[ 0 ], | |
4709 div = document.createElement( "div" ); | |
4710 | |
4711 //Create a "fake body" for testing based on method used in jQuery.support | |
4712 testElement = document.createElement( body ? "div" : "body" ); | |
4713 testElementStyle = { | |
4714 visibility: "hidden", | |
4715 width: 0, | |
4716 height: 0, | |
4717 border: 0, | |
4718 margin: 0, | |
4719 background: "none" | |
4720 }; | |
4721 if ( body ) { | |
4722 $.extend( testElementStyle, { | |
4723 position: "absolute", | |
4724 left: "-1000px", | |
4725 top: "-1000px" | |
4726 }); | |
4727 } | |
4728 for ( i in testElementStyle ) { | |
4729 testElement.style[ i ] = testElementStyle[ i ]; | |
4730 } | |
4731 testElement.appendChild( div ); | |
4732 testElementParent = body || document.documentElement; | |
4733 testElementParent.insertBefore( testElement, testElementParent.firstChild ); | |
4734 | |
4735 div.style.cssText = "position: absolute; left: 10.7432222px;"; | |
4736 | |
4737 offsetLeft = $( div ).offset().left; | |
4738 $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11; | |
4739 | |
4740 testElement.innerHTML = ""; | |
4741 testElementParent.removeChild( testElement ); | |
4742 })(); | |
4743 | |
4744 }( jQuery ) ); | |
4745 (function( $, undefined ) { | |
4746 | |
4747 $.widget("ui.draggable", $.ui.mouse, { | |
4748 version: "1.10.3", | |
4749 widgetEventPrefix: "drag", | |
4750 options: { | |
4751 addClasses: true, | |
4752 appendTo: "parent", | |
4753 axis: false, | |
4754 connectToSortable: false, | |
4755 containment: false, | |
4756 cursor: "auto", | |
4757 cursorAt: false, | |
4758 grid: false, | |
4759 handle: false, | |
4760 helper: "original", | |
4761 iframeFix: false, | |
4762 opacity: false, | |
4763 refreshPositions: false, | |
4764 revert: false, | |
4765 revertDuration: 500, | |
4766 scope: "default", | |
4767 scroll: true, | |
4768 scrollSensitivity: 20, | |
4769 scrollSpeed: 20, | |
4770 snap: false, | |
4771 snapMode: "both", | |
4772 snapTolerance: 20, | |
4773 stack: false, | |
4774 zIndex: false, | |
4775 | |
4776 // callbacks | |
4777 drag: null, | |
4778 start: null, | |
4779 stop: null | |
4780 }, | |
4781 _create: function() { | |
4782 | |
4783 if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) { | |
4784 this.element[0].style.position = "relative"; | |
4785 } | |
4786 if (this.options.addClasses){ | |
4787 this.element.addClass("ui-draggable"); | |
4788 } | |
4789 if (this.options.disabled){ | |
4790 this.element.addClass("ui-draggable-disabled"); | |
4791 } | |
4792 | |
4793 this._mouseInit(); | |
4794 | |
4795 }, | |
4796 | |
4797 _destroy: function() { | |
4798 this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); | |
4799 this._mouseDestroy(); | |
4800 }, | |
4801 | |
4802 _mouseCapture: function(event) { | |
4803 | |
4804 var o = this.options; | |
4805 | |
4806 // among others, prevent a drag on a resizable-handle | |
4807 if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { | |
4808 return false; | |
4809 } | |
4810 | |
4811 //Quit if we're not on a valid handle | |
4812 this.handle = this._getHandle(event); | |
4813 if (!this.handle) { | |
4814 return false; | |
4815 } | |
4816 | |
4817 $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { | |
4818 $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>") | |
4819 .css({ | |
4820 width: this.offsetWidth+"px", height: this.offsetHeight+"px", | |
4821 position: "absolute", opacity: "0.001", zIndex: 1000 | |
4822 }) | |
4823 .css($(this).offset()) | |
4824 .appendTo("body"); | |
4825 }); | |
4826 | |
4827 return true; | |
4828 | |
4829 }, | |
4830 | |
4831 _mouseStart: function(event) { | |
4832 | |
4833 var o = this.options; | |
4834 | |
4835 //Create and append the visible helper | |
4836 this.helper = this._createHelper(event); | |
4837 | |
4838 this.helper.addClass("ui-draggable-dragging"); | |
4839 | |
4840 //Cache the helper size | |
4841 this._cacheHelperProportions(); | |
4842 | |
4843 //If ddmanager is used for droppables, set the global draggable | |
4844 if($.ui.ddmanager) { | |
4845 $.ui.ddmanager.current = this; | |
4846 } | |
4847 | |
4848 /* | |
4849 * - Position generation - | |
4850 * This block generates everything position related - it's the core of draggables. | |
4851 */ | |
4852 | |
4853 //Cache the margins of the original element | |
4854 this._cacheMargins(); | |
4855 | |
4856 //Store the helper's css position | |
4857 this.cssPosition = this.helper.css( "position" ); | |
4858 this.scrollParent = this.helper.scrollParent(); | |
4859 this.offsetParent = this.helper.offsetParent(); | |
4860 this.offsetParentCssPosition = this.offsetParent.css( "position" ); | |
4861 | |
4862 //The element's absolute position on the page minus margins | |
4863 this.offset = this.positionAbs = this.element.offset(); | |
4864 this.offset = { | |
4865 top: this.offset.top - this.margins.top, | |
4866 left: this.offset.left - this.margins.left | |
4867 }; | |
4868 | |
4869 //Reset scroll cache | |
4870 this.offset.scroll = false; | |
4871 | |
4872 $.extend(this.offset, { | |
4873 click: { //Where the click happened, relative to the element | |
4874 left: event.pageX - this.offset.left, | |
4875 top: event.pageY - this.offset.top | |
4876 }, | |
4877 parent: this._getParentOffset(), | |
4878 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper | |
4879 }); | |
4880 | |
4881 //Generate the original position | |
4882 this.originalPosition = this.position = this._generatePosition(event); | |
4883 this.originalPageX = event.pageX; | |
4884 this.originalPageY = event.pageY; | |
4885 | |
4886 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied | |
4887 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); | |
4888 | |
4889 //Set a containment if given in the options | |
4890 this._setContainment(); | |
4891 | |
4892 //Trigger event + callbacks | |
4893 if(this._trigger("start", event) === false) { | |
4894 this._clear(); | |
4895 return false; | |
4896 } | |
4897 | |
4898 //Recache the helper size | |
4899 this._cacheHelperProportions(); | |
4900 | |
4901 //Prepare the droppable offsets | |
4902 if ($.ui.ddmanager && !o.dropBehaviour) { | |
4903 $.ui.ddmanager.prepareOffsets(this, event); | |
4904 } | |
4905 | |
4906 | |
4907 this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position | |
4908 | |
4909 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) | |
4910 if ( $.ui.ddmanager ) { | |
4911 $.ui.ddmanager.dragStart(this, event); | |
4912 } | |
4913 | |
4914 return true; | |
4915 }, | |
4916 | |
4917 _mouseDrag: function(event, noPropagation) { | |
4918 // reset any necessary cached properties (see #5009) | |
4919 if ( this.offsetParentCssPosition === "fixed" ) { | |
4920 this.offset.parent = this._getParentOffset(); | |
4921 } | |
4922 | |
4923 //Compute the helpers position | |
4924 this.position = this._generatePosition(event); | |
4925 this.positionAbs = this._convertPositionTo("absolute"); | |
4926 | |
4927 //Call plugins and callbacks and use the resulting position if something is returned | |
4928 if (!noPropagation) { | |
4929 var ui = this._uiHash(); | |
4930 if(this._trigger("drag", event, ui) === false) { | |
4931 this._mouseUp({}); | |
4932 return false; | |
4933 } | |
4934 this.position = ui.position; | |
4935 } | |
4936 | |
4937 if(!this.options.axis || this.options.axis !== "y") { | |
4938 this.helper[0].style.left = this.position.left+"px"; | |
4939 } | |
4940 if(!this.options.axis || this.options.axis !== "x") { | |
4941 this.helper[0].style.top = this.position.top+"px"; | |
4942 } | |
4943 if($.ui.ddmanager) { | |
4944 $.ui.ddmanager.drag(this, event); | |
4945 } | |
4946 | |
4947 return false; | |
4948 }, | |
4949 | |
4950 _mouseStop: function(event) { | |
4951 | |
4952 //If we are using droppables, inform the manager about the drop | |
4953 var that = this, | |
4954 dropped = false; | |
4955 if ($.ui.ddmanager && !this.options.dropBehaviour) { | |
4956 dropped = $.ui.ddmanager.drop(this, event); | |
4957 } | |
4958 | |
4959 //if a drop comes from outside (a sortable) | |
4960 if(this.dropped) { | |
4961 dropped = this.dropped; | |
4962 this.dropped = false; | |
4963 } | |
4964 | |
4965 //if the original element is no longer in the DOM don't bother to continue (see #8269) | |
4966 if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) { | |
4967 return false; | |
4968 } | |
4969 | |
4970 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))) { | |
4971 $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { | |
4972 if(that._trigger("stop", event) !== false) { | |
4973 that._clear(); | |
4974 } | |
4975 }); | |
4976 } else { | |
4977 if(this._trigger("stop", event) !== false) { | |
4978 this._clear(); | |
4979 } | |
4980 } | |
4981 | |
4982 return false; | |
4983 }, | |
4984 | |
4985 _mouseUp: function(event) { | |
4986 //Remove frame helpers | |
4987 $("div.ui-draggable-iframeFix").each(function() { | |
4988 this.parentNode.removeChild(this); | |
4989 }); | |
4990 | |
4991 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) | |
4992 if( $.ui.ddmanager ) { | |
4993 $.ui.ddmanager.dragStop(this, event); | |
4994 } | |
4995 | |
4996 return $.ui.mouse.prototype._mouseUp.call(this, event); | |
4997 }, | |
4998 | |
4999 cancel: function() { | |
5000 | |
5001 if(this.helper.is(".ui-draggable-dragging")) { | |
5002 this._mouseUp({}); | |
5003 } else { | |
5004 this._clear(); | |
5005 } | |
5006 | |
5007 return this; | |
5008 | |
5009 }, | |
5010 | |
5011 _getHandle: function(event) { | |
5012 return this.options.handle ? | |
5013 !!$( event.target ).closest( this.element.find( this.options.handle ) ).length : | |
5014 true; | |
5015 }, | |
5016 | |
5017 _createHelper: function(event) { | |
5018 | |
5019 var o = this.options, | |
5020 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element); | |
5021 | |
5022 if(!helper.parents("body").length) { | |
5023 helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo)); | |
5024 } | |
5025 | |
5026 if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) { | |
5027 helper.css("position", "absolute"); | |
5028 } | |
5029 | |
5030 return helper; | |
5031 | |
5032 }, | |
5033 | |
5034 _adjustOffsetFromHelper: function(obj) { | |
5035 if (typeof obj === "string") { | |
5036 obj = obj.split(" "); | |
5037 } | |
5038 if ($.isArray(obj)) { | |
5039 obj = {left: +obj[0], top: +obj[1] || 0}; | |
5040 } | |
5041 if ("left" in obj) { | |
5042 this.offset.click.left = obj.left + this.margins.left; | |
5043 } | |
5044 if ("right" in obj) { | |
5045 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; | |
5046 } | |
5047 if ("top" in obj) { | |
5048 this.offset.click.top = obj.top + this.margins.top; | |
5049 } | |
5050 if ("bottom" in obj) { | |
5051 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; | |
5052 } | |
5053 }, | |
5054 | |
5055 _getParentOffset: function() { | |
5056 | |
5057 //Get the offsetParent and cache its position | |
5058 var po = this.offsetParent.offset(); | |
5059 | |
5060 // This is a special case where we need to modify a offset calculated on start, since the following happened: | |
5061 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent | |
5062 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that | |
5063 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag | |
5064 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { | |
5065 po.left += this.scrollParent.scrollLeft(); | |
5066 po.top += this.scrollParent.scrollTop(); | |
5067 } | |
5068 | |
5069 //This needs to be actually done for all browsers, since pageX/pageY includes this information | |
5070 //Ugly IE fix | |
5071 if((this.offsetParent[0] === document.body) || | |
5072 (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { | |
5073 po = { top: 0, left: 0 }; | |
5074 } | |
5075 | |
5076 return { | |
5077 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), | |
5078 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) | |
5079 }; | |
5080 | |
5081 }, | |
5082 | |
5083 _getRelativeOffset: function() { | |
5084 | |
5085 if(this.cssPosition === "relative") { | |
5086 var p = this.element.position(); | |
5087 return { | |
5088 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), | |
5089 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() | |
5090 }; | |
5091 } else { | |
5092 return { top: 0, left: 0 }; | |
5093 } | |
5094 | |
5095 }, | |
5096 | |
5097 _cacheMargins: function() { | |
5098 this.margins = { | |
5099 left: (parseInt(this.element.css("marginLeft"),10) || 0), | |
5100 top: (parseInt(this.element.css("marginTop"),10) || 0), | |
5101 right: (parseInt(this.element.css("marginRight"),10) || 0), | |
5102 bottom: (parseInt(this.element.css("marginBottom"),10) || 0) | |
5103 }; | |
5104 }, | |
5105 | |
5106 _cacheHelperProportions: function() { | |
5107 this.helperProportions = { | |
5108 width: this.helper.outerWidth(), | |
5109 height: this.helper.outerHeight() | |
5110 }; | |
5111 }, | |
5112 | |
5113 _setContainment: function() { | |
5114 | |
5115 var over, c, ce, | |
5116 o = this.options; | |
5117 | |
5118 if ( !o.containment ) { | |
5119 this.containment = null; | |
5120 return; | |
5121 } | |
5122 | |
5123 if ( o.containment === "window" ) { | |
5124 this.containment = [ | |
5125 $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left, | |
5126 $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top, | |
5127 $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left, | |
5128 $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top | |
5129 ]; | |
5130 return; | |
5131 } | |
5132 | |
5133 if ( o.containment === "document") { | |
5134 this.containment = [ | |
5135 0, | |
5136 0, | |
5137 $( document ).width() - this.helperProportions.width - this.margins.left, | |
5138 ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top | |
5139 ]; | |
5140 return; | |
5141 } | |
5142 | |
5143 if ( o.containment.constructor === Array ) { | |
5144 this.containment = o.containment; | |
5145 return; | |
5146 } | |
5147 | |
5148 if ( o.containment === "parent" ) { | |
5149 o.containment = this.helper[ 0 ].parentNode; | |
5150 } | |
5151 | |
5152 c = $( o.containment ); | |
5153 ce = c[ 0 ]; | |
5154 | |
5155 if( !ce ) { | |
5156 return; | |
5157 } | |
5158 | |
5159 over = c.css( "overflow" ) !== "hidden"; | |
5160 | |
5161 this.containment = [ | |
5162 ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ), | |
5163 ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) , | |
5164 ( 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, | |
5165 ( 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 | |
5166 ]; | |
5167 this.relative_container = c; | |
5168 }, | |
5169 | |
5170 _convertPositionTo: function(d, pos) { | |
5171 | |
5172 if(!pos) { | |
5173 pos = this.position; | |
5174 } | |
5175 | |
5176 var mod = d === "absolute" ? 1 : -1, | |
5177 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent; | |
5178 | |
5179 //Cache the scroll | |
5180 if (!this.offset.scroll) { | |
5181 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; | |
5182 } | |
5183 | |
5184 return { | |
5185 top: ( | |
5186 pos.top + // The absolute mouse position | |
5187 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
5188 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) | |
5189 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod ) | |
5190 ), | |
5191 left: ( | |
5192 pos.left + // The absolute mouse position | |
5193 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
5194 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) | |
5195 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod ) | |
5196 ) | |
5197 }; | |
5198 | |
5199 }, | |
5200 | |
5201 _generatePosition: function(event) { | |
5202 | |
5203 var containment, co, top, left, | |
5204 o = this.options, | |
5205 scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent, | |
5206 pageX = event.pageX, | |
5207 pageY = event.pageY; | |
5208 | |
5209 //Cache the scroll | |
5210 if (!this.offset.scroll) { | |
5211 this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()}; | |
5212 } | |
5213 | |
5214 /* | |
5215 * - Position constraining - | |
5216 * Constrain the position to a mix of grid, containment. | |
5217 */ | |
5218 | |
5219 // If we are not dragging yet, we won't check for options | |
5220 if ( this.originalPosition ) { | |
5221 if ( this.containment ) { | |
5222 if ( this.relative_container ){ | |
5223 co = this.relative_container.offset(); | |
5224 containment = [ | |
5225 this.containment[ 0 ] + co.left, | |
5226 this.containment[ 1 ] + co.top, | |
5227 this.containment[ 2 ] + co.left, | |
5228 this.containment[ 3 ] + co.top | |
5229 ]; | |
5230 } | |
5231 else { | |
5232 containment = this.containment; | |
5233 } | |
5234 | |
5235 if(event.pageX - this.offset.click.left < containment[0]) { | |
5236 pageX = containment[0] + this.offset.click.left; | |
5237 } | |
5238 if(event.pageY - this.offset.click.top < containment[1]) { | |
5239 pageY = containment[1] + this.offset.click.top; | |
5240 } | |
5241 if(event.pageX - this.offset.click.left > containment[2]) { | |
5242 pageX = containment[2] + this.offset.click.left; | |
5243 } | |
5244 if(event.pageY - this.offset.click.top > containment[3]) { | |
5245 pageY = containment[3] + this.offset.click.top; | |
5246 } | |
5247 } | |
5248 | |
5249 if(o.grid) { | |
5250 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) | |
5251 top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; | |
5252 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; | |
5253 | |
5254 left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; | |
5255 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; | |
5256 } | |
5257 | |
5258 } | |
5259 | |
5260 return { | |
5261 top: ( | |
5262 pageY - // The absolute mouse position | |
5263 this.offset.click.top - // Click offset (relative to the element) | |
5264 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent | |
5265 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) | |
5266 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) | |
5267 ), | |
5268 left: ( | |
5269 pageX - // The absolute mouse position | |
5270 this.offset.click.left - // Click offset (relative to the element) | |
5271 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent | |
5272 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) | |
5273 ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) | |
5274 ) | |
5275 }; | |
5276 | |
5277 }, | |
5278 | |
5279 _clear: function() { | |
5280 this.helper.removeClass("ui-draggable-dragging"); | |
5281 if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) { | |
5282 this.helper.remove(); | |
5283 } | |
5284 this.helper = null; | |
5285 this.cancelHelperRemoval = false; | |
5286 }, | |
5287 | |
5288 // From now on bulk stuff - mainly helpers | |
5289 | |
5290 _trigger: function(type, event, ui) { | |
5291 ui = ui || this._uiHash(); | |
5292 $.ui.plugin.call(this, type, [event, ui]); | |
5293 //The absolute position has to be recalculated after plugins | |
5294 if(type === "drag") { | |
5295 this.positionAbs = this._convertPositionTo("absolute"); | |
5296 } | |
5297 return $.Widget.prototype._trigger.call(this, type, event, ui); | |
5298 }, | |
5299 | |
5300 plugins: {}, | |
5301 | |
5302 _uiHash: function() { | |
5303 return { | |
5304 helper: this.helper, | |
5305 position: this.position, | |
5306 originalPosition: this.originalPosition, | |
5307 offset: this.positionAbs | |
5308 }; | |
5309 } | |
5310 | |
5311 }); | |
5312 | |
5313 $.ui.plugin.add("draggable", "connectToSortable", { | |
5314 start: function(event, ui) { | |
5315 | |
5316 var inst = $(this).data("ui-draggable"), o = inst.options, | |
5317 uiSortable = $.extend({}, ui, { item: inst.element }); | |
5318 inst.sortables = []; | |
5319 $(o.connectToSortable).each(function() { | |
5320 var sortable = $.data(this, "ui-sortable"); | |
5321 if (sortable && !sortable.options.disabled) { | |
5322 inst.sortables.push({ | |
5323 instance: sortable, | |
5324 shouldRevert: sortable.options.revert | |
5325 }); | |
5326 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). | |
5327 sortable._trigger("activate", event, uiSortable); | |
5328 } | |
5329 }); | |
5330 | |
5331 }, | |
5332 stop: function(event, ui) { | |
5333 | |
5334 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper | |
5335 var inst = $(this).data("ui-draggable"), | |
5336 uiSortable = $.extend({}, ui, { item: inst.element }); | |
5337 | |
5338 $.each(inst.sortables, function() { | |
5339 if(this.instance.isOver) { | |
5340 | |
5341 this.instance.isOver = 0; | |
5342 | |
5343 inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance | |
5344 this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) | |
5345 | |
5346 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid" | |
5347 if(this.shouldRevert) { | |
5348 this.instance.options.revert = this.shouldRevert; | |
5349 } | |
5350 | |
5351 //Trigger the stop of the sortable | |
5352 this.instance._mouseStop(event); | |
5353 | |
5354 this.instance.options.helper = this.instance.options._helper; | |
5355 | |
5356 //If the helper has been the original item, restore properties in the sortable | |
5357 if(inst.options.helper === "original") { | |
5358 this.instance.currentItem.css({ top: "auto", left: "auto" }); | |
5359 } | |
5360 | |
5361 } else { | |
5362 this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance | |
5363 this.instance._trigger("deactivate", event, uiSortable); | |
5364 } | |
5365 | |
5366 }); | |
5367 | |
5368 }, | |
5369 drag: function(event, ui) { | |
5370 | |
5371 var inst = $(this).data("ui-draggable"), that = this; | |
5372 | |
5373 $.each(inst.sortables, function() { | |
5374 | |
5375 var innermostIntersecting = false, | |
5376 thisSortable = this; | |
5377 | |
5378 //Copy over some variables to allow calling the sortable's native _intersectsWith | |
5379 this.instance.positionAbs = inst.positionAbs; | |
5380 this.instance.helperProportions = inst.helperProportions; | |
5381 this.instance.offset.click = inst.offset.click; | |
5382 | |
5383 if(this.instance._intersectsWith(this.instance.containerCache)) { | |
5384 innermostIntersecting = true; | |
5385 $.each(inst.sortables, function () { | |
5386 this.instance.positionAbs = inst.positionAbs; | |
5387 this.instance.helperProportions = inst.helperProportions; | |
5388 this.instance.offset.click = inst.offset.click; | |
5389 if (this !== thisSortable && | |
5390 this.instance._intersectsWith(this.instance.containerCache) && | |
5391 $.contains(thisSortable.instance.element[0], this.instance.element[0]) | |
5392 ) { | |
5393 innermostIntersecting = false; | |
5394 } | |
5395 return innermostIntersecting; | |
5396 }); | |
5397 } | |
5398 | |
5399 | |
5400 if(innermostIntersecting) { | |
5401 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once | |
5402 if(!this.instance.isOver) { | |
5403 | |
5404 this.instance.isOver = 1; | |
5405 //Now we fake the start of dragging for the sortable instance, | |
5406 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem | |
5407 //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) | |
5408 this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true); | |
5409 this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it | |
5410 this.instance.options.helper = function() { return ui.helper[0]; }; | |
5411 | |
5412 event.target = this.instance.currentItem[0]; | |
5413 this.instance._mouseCapture(event, true); | |
5414 this.instance._mouseStart(event, true, true); | |
5415 | |
5416 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes | |
5417 this.instance.offset.click.top = inst.offset.click.top; | |
5418 this.instance.offset.click.left = inst.offset.click.left; | |
5419 this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; | |
5420 this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; | |
5421 | |
5422 inst._trigger("toSortable", event); | |
5423 inst.dropped = this.instance.element; //draggable revert needs that | |
5424 //hack so receive/update callbacks work (mostly) | |
5425 inst.currentItem = inst.element; | |
5426 this.instance.fromOutside = inst; | |
5427 | |
5428 } | |
5429 | |
5430 //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 | |
5431 if(this.instance.currentItem) { | |
5432 this.instance._mouseDrag(event); | |
5433 } | |
5434 | |
5435 } else { | |
5436 | |
5437 //If it doesn't intersect with the sortable, and it intersected before, | |
5438 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval | |
5439 if(this.instance.isOver) { | |
5440 | |
5441 this.instance.isOver = 0; | |
5442 this.instance.cancelHelperRemoval = true; | |
5443 | |
5444 //Prevent reverting on this forced stop | |
5445 this.instance.options.revert = false; | |
5446 | |
5447 // The out event needs to be triggered independently | |
5448 this.instance._trigger("out", event, this.instance._uiHash(this.instance)); | |
5449 | |
5450 this.instance._mouseStop(event, true); | |
5451 this.instance.options.helper = this.instance.options._helper; | |
5452 | |
5453 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size | |
5454 this.instance.currentItem.remove(); | |
5455 if(this.instance.placeholder) { | |
5456 this.instance.placeholder.remove(); | |
5457 } | |
5458 | |
5459 inst._trigger("fromSortable", event); | |
5460 inst.dropped = false; //draggable revert needs that | |
5461 } | |
5462 | |
5463 } | |
5464 | |
5465 }); | |
5466 | |
5467 } | |
5468 }); | |
5469 | |
5470 $.ui.plugin.add("draggable", "cursor", { | |
5471 start: function() { | |
5472 var t = $("body"), o = $(this).data("ui-draggable").options; | |
5473 if (t.css("cursor")) { | |
5474 o._cursor = t.css("cursor"); | |
5475 } | |
5476 t.css("cursor", o.cursor); | |
5477 }, | |
5478 stop: function() { | |
5479 var o = $(this).data("ui-draggable").options; | |
5480 if (o._cursor) { | |
5481 $("body").css("cursor", o._cursor); | |
5482 } | |
5483 } | |
5484 }); | |
5485 | |
5486 $.ui.plugin.add("draggable", "opacity", { | |
5487 start: function(event, ui) { | |
5488 var t = $(ui.helper), o = $(this).data("ui-draggable").options; | |
5489 if(t.css("opacity")) { | |
5490 o._opacity = t.css("opacity"); | |
5491 } | |
5492 t.css("opacity", o.opacity); | |
5493 }, | |
5494 stop: function(event, ui) { | |
5495 var o = $(this).data("ui-draggable").options; | |
5496 if(o._opacity) { | |
5497 $(ui.helper).css("opacity", o._opacity); | |
5498 } | |
5499 } | |
5500 }); | |
5501 | |
5502 $.ui.plugin.add("draggable", "scroll", { | |
5503 start: function() { | |
5504 var i = $(this).data("ui-draggable"); | |
5505 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { | |
5506 i.overflowOffset = i.scrollParent.offset(); | |
5507 } | |
5508 }, | |
5509 drag: function( event ) { | |
5510 | |
5511 var i = $(this).data("ui-draggable"), o = i.options, scrolled = false; | |
5512 | |
5513 if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") { | |
5514 | |
5515 if(!o.axis || o.axis !== "x") { | |
5516 if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { | |
5517 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; | |
5518 } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) { | |
5519 i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; | |
5520 } | |
5521 } | |
5522 | |
5523 if(!o.axis || o.axis !== "y") { | |
5524 if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { | |
5525 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; | |
5526 } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) { | |
5527 i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; | |
5528 } | |
5529 } | |
5530 | |
5531 } else { | |
5532 | |
5533 if(!o.axis || o.axis !== "x") { | |
5534 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { | |
5535 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); | |
5536 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { | |
5537 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); | |
5538 } | |
5539 } | |
5540 | |
5541 if(!o.axis || o.axis !== "y") { | |
5542 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { | |
5543 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); | |
5544 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { | |
5545 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); | |
5546 } | |
5547 } | |
5548 | |
5549 } | |
5550 | |
5551 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { | |
5552 $.ui.ddmanager.prepareOffsets(i, event); | |
5553 } | |
5554 | |
5555 } | |
5556 }); | |
5557 | |
5558 $.ui.plugin.add("draggable", "snap", { | |
5559 start: function() { | |
5560 | |
5561 var i = $(this).data("ui-draggable"), | |
5562 o = i.options; | |
5563 | |
5564 i.snapElements = []; | |
5565 | |
5566 $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() { | |
5567 var $t = $(this), | |
5568 $o = $t.offset(); | |
5569 if(this !== i.element[0]) { | |
5570 i.snapElements.push({ | |
5571 item: this, | |
5572 width: $t.outerWidth(), height: $t.outerHeight(), | |
5573 top: $o.top, left: $o.left | |
5574 }); | |
5575 } | |
5576 }); | |
5577 | |
5578 }, | |
5579 drag: function(event, ui) { | |
5580 | |
5581 var ts, bs, ls, rs, l, r, t, b, i, first, | |
5582 inst = $(this).data("ui-draggable"), | |
5583 o = inst.options, | |
5584 d = o.snapTolerance, | |
5585 x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, | |
5586 y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; | |
5587 | |
5588 for (i = inst.snapElements.length - 1; i >= 0; i--){ | |
5589 | |
5590 l = inst.snapElements[i].left; | |
5591 r = l + inst.snapElements[i].width; | |
5592 t = inst.snapElements[i].top; | |
5593 b = t + inst.snapElements[i].height; | |
5594 | |
5595 if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) { | |
5596 if(inst.snapElements[i].snapping) { | |
5597 (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); | |
5598 } | |
5599 inst.snapElements[i].snapping = false; | |
5600 continue; | |
5601 } | |
5602 | |
5603 if(o.snapMode !== "inner") { | |
5604 ts = Math.abs(t - y2) <= d; | |
5605 bs = Math.abs(b - y1) <= d; | |
5606 ls = Math.abs(l - x2) <= d; | |
5607 rs = Math.abs(r - x1) <= d; | |
5608 if(ts) { | |
5609 ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; | |
5610 } | |
5611 if(bs) { | |
5612 ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; | |
5613 } | |
5614 if(ls) { | |
5615 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; | |
5616 } | |
5617 if(rs) { | |
5618 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; | |
5619 } | |
5620 } | |
5621 | |
5622 first = (ts || bs || ls || rs); | |
5623 | |
5624 if(o.snapMode !== "outer") { | |
5625 ts = Math.abs(t - y1) <= d; | |
5626 bs = Math.abs(b - y2) <= d; | |
5627 ls = Math.abs(l - x1) <= d; | |
5628 rs = Math.abs(r - x2) <= d; | |
5629 if(ts) { | |
5630 ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; | |
5631 } | |
5632 if(bs) { | |
5633 ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; | |
5634 } | |
5635 if(ls) { | |
5636 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; | |
5637 } | |
5638 if(rs) { | |
5639 ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; | |
5640 } | |
5641 } | |
5642 | |
5643 if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) { | |
5644 (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); | |
5645 } | |
5646 inst.snapElements[i].snapping = (ts || bs || ls || rs || first); | |
5647 | |
5648 } | |
5649 | |
5650 } | |
5651 }); | |
5652 | |
5653 $.ui.plugin.add("draggable", "stack", { | |
5654 start: function() { | |
5655 var min, | |
5656 o = this.data("ui-draggable").options, | |
5657 group = $.makeArray($(o.stack)).sort(function(a,b) { | |
5658 return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); | |
5659 }); | |
5660 | |
5661 if (!group.length) { return; } | |
5662 | |
5663 min = parseInt($(group[0]).css("zIndex"), 10) || 0; | |
5664 $(group).each(function(i) { | |
5665 $(this).css("zIndex", min + i); | |
5666 }); | |
5667 this.css("zIndex", (min + group.length)); | |
5668 } | |
5669 }); | |
5670 | |
5671 $.ui.plugin.add("draggable", "zIndex", { | |
5672 start: function(event, ui) { | |
5673 var t = $(ui.helper), o = $(this).data("ui-draggable").options; | |
5674 if(t.css("zIndex")) { | |
5675 o._zIndex = t.css("zIndex"); | |
5676 } | |
5677 t.css("zIndex", o.zIndex); | |
5678 }, | |
5679 stop: function(event, ui) { | |
5680 var o = $(this).data("ui-draggable").options; | |
5681 if(o._zIndex) { | |
5682 $(ui.helper).css("zIndex", o._zIndex); | |
5683 } | |
5684 } | |
5685 }); | |
5686 | |
5687 })(jQuery); | |
5688 (function( $, undefined ) { | |
5689 | |
5690 function isOverAxis( x, reference, size ) { | |
5691 return ( x > reference ) && ( x < ( reference + size ) ); | |
5692 } | |
5693 | |
5694 $.widget("ui.droppable", { | |
5695 version: "1.10.3", | |
5696 widgetEventPrefix: "drop", | |
5697 options: { | |
5698 accept: "*", | |
5699 activeClass: false, | |
5700 addClasses: true, | |
5701 greedy: false, | |
5702 hoverClass: false, | |
5703 scope: "default", | |
5704 tolerance: "intersect", | |
5705 | |
5706 // callbacks | |
5707 activate: null, | |
5708 deactivate: null, | |
5709 drop: null, | |
5710 out: null, | |
5711 over: null | |
5712 }, | |
5713 _create: function() { | |
5714 | |
5715 var o = this.options, | |
5716 accept = o.accept; | |
5717 | |
5718 this.isover = false; | |
5719 this.isout = true; | |
5720 | |
5721 this.accept = $.isFunction(accept) ? accept : function(d) { | |
5722 return d.is(accept); | |
5723 }; | |
5724 | |
5725 //Store the droppable's proportions | |
5726 this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; | |
5727 | |
5728 // Add the reference and positions to the manager | |
5729 $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; | |
5730 $.ui.ddmanager.droppables[o.scope].push(this); | |
5731 | |
5732 (o.addClasses && this.element.addClass("ui-droppable")); | |
5733 | |
5734 }, | |
5735 | |
5736 _destroy: function() { | |
5737 var i = 0, | |
5738 drop = $.ui.ddmanager.droppables[this.options.scope]; | |
5739 | |
5740 for ( ; i < drop.length; i++ ) { | |
5741 if ( drop[i] === this ) { | |
5742 drop.splice(i, 1); | |
5743 } | |
5744 } | |
5745 | |
5746 this.element.removeClass("ui-droppable ui-droppable-disabled"); | |
5747 }, | |
5748 | |
5749 _setOption: function(key, value) { | |
5750 | |
5751 if(key === "accept") { | |
5752 this.accept = $.isFunction(value) ? value : function(d) { | |
5753 return d.is(value); | |
5754 }; | |
5755 } | |
5756 $.Widget.prototype._setOption.apply(this, arguments); | |
5757 }, | |
5758 | |
5759 _activate: function(event) { | |
5760 var draggable = $.ui.ddmanager.current; | |
5761 if(this.options.activeClass) { | |
5762 this.element.addClass(this.options.activeClass); | |
5763 } | |
5764 if(draggable){ | |
5765 this._trigger("activate", event, this.ui(draggable)); | |
5766 } | |
5767 }, | |
5768 | |
5769 _deactivate: function(event) { | |
5770 var draggable = $.ui.ddmanager.current; | |
5771 if(this.options.activeClass) { | |
5772 this.element.removeClass(this.options.activeClass); | |
5773 } | |
5774 if(draggable){ | |
5775 this._trigger("deactivate", event, this.ui(draggable)); | |
5776 } | |
5777 }, | |
5778 | |
5779 _over: function(event) { | |
5780 | |
5781 var draggable = $.ui.ddmanager.current; | |
5782 | |
5783 // Bail if draggable and droppable are same element | |
5784 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { | |
5785 return; | |
5786 } | |
5787 | |
5788 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5789 if(this.options.hoverClass) { | |
5790 this.element.addClass(this.options.hoverClass); | |
5791 } | |
5792 this._trigger("over", event, this.ui(draggable)); | |
5793 } | |
5794 | |
5795 }, | |
5796 | |
5797 _out: function(event) { | |
5798 | |
5799 var draggable = $.ui.ddmanager.current; | |
5800 | |
5801 // Bail if draggable and droppable are same element | |
5802 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { | |
5803 return; | |
5804 } | |
5805 | |
5806 if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5807 if(this.options.hoverClass) { | |
5808 this.element.removeClass(this.options.hoverClass); | |
5809 } | |
5810 this._trigger("out", event, this.ui(draggable)); | |
5811 } | |
5812 | |
5813 }, | |
5814 | |
5815 _drop: function(event,custom) { | |
5816 | |
5817 var draggable = custom || $.ui.ddmanager.current, | |
5818 childrenIntersection = false; | |
5819 | |
5820 // Bail if draggable and droppable are same element | |
5821 if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) { | |
5822 return false; | |
5823 } | |
5824 | |
5825 this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() { | |
5826 var inst = $.data(this, "ui-droppable"); | |
5827 if( | |
5828 inst.options.greedy && | |
5829 !inst.options.disabled && | |
5830 inst.options.scope === draggable.options.scope && | |
5831 inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && | |
5832 $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) | |
5833 ) { childrenIntersection = true; return false; } | |
5834 }); | |
5835 if(childrenIntersection) { | |
5836 return false; | |
5837 } | |
5838 | |
5839 if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5840 if(this.options.activeClass) { | |
5841 this.element.removeClass(this.options.activeClass); | |
5842 } | |
5843 if(this.options.hoverClass) { | |
5844 this.element.removeClass(this.options.hoverClass); | |
5845 } | |
5846 this._trigger("drop", event, this.ui(draggable)); | |
5847 return this.element; | |
5848 } | |
5849 | |
5850 return false; | |
5851 | |
5852 }, | |
5853 | |
5854 ui: function(c) { | |
5855 return { | |
5856 draggable: (c.currentItem || c.element), | |
5857 helper: c.helper, | |
5858 position: c.position, | |
5859 offset: c.positionAbs | |
5860 }; | |
5861 } | |
5862 | |
5863 }); | |
5864 | |
5865 $.ui.intersect = function(draggable, droppable, toleranceMode) { | |
5866 | |
5867 if (!droppable.offset) { | |
5868 return false; | |
5869 } | |
5870 | |
5871 var draggableLeft, draggableTop, | |
5872 x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, | |
5873 y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height, | |
5874 l = droppable.offset.left, r = l + droppable.proportions.width, | |
5875 t = droppable.offset.top, b = t + droppable.proportions.height; | |
5876 | |
5877 switch (toleranceMode) { | |
5878 case "fit": | |
5879 return (l <= x1 && x2 <= r && t <= y1 && y2 <= b); | |
5880 case "intersect": | |
5881 return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half | |
5882 x2 - (draggable.helperProportions.width / 2) < r && // Left Half | |
5883 t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half | |
5884 y2 - (draggable.helperProportions.height / 2) < b ); // Top Half | |
5885 case "pointer": | |
5886 draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left); | |
5887 draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top); | |
5888 return isOverAxis( draggableTop, t, droppable.proportions.height ) && isOverAxis( draggableLeft, l, droppable.proportions.width ); | |
5889 case "touch": | |
5890 return ( | |
5891 (y1 >= t && y1 <= b) || // Top edge touching | |
5892 (y2 >= t && y2 <= b) || // Bottom edge touching | |
5893 (y1 < t && y2 > b) // Surrounded vertically | |
5894 ) && ( | |
5895 (x1 >= l && x1 <= r) || // Left edge touching | |
5896 (x2 >= l && x2 <= r) || // Right edge touching | |
5897 (x1 < l && x2 > r) // Surrounded horizontally | |
5898 ); | |
5899 default: | |
5900 return false; | |
5901 } | |
5902 | |
5903 }; | |
5904 | |
5905 /* | |
5906 This manager tracks offsets of draggables and droppables | |
5907 */ | |
5908 $.ui.ddmanager = { | |
5909 current: null, | |
5910 droppables: { "default": [] }, | |
5911 prepareOffsets: function(t, event) { | |
5912 | |
5913 var i, j, | |
5914 m = $.ui.ddmanager.droppables[t.options.scope] || [], | |
5915 type = event ? event.type : null, // workaround for #2317 | |
5916 list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack(); | |
5917 | |
5918 droppablesLoop: for (i = 0; i < m.length; i++) { | |
5919 | |
5920 //No disabled and non-accepted | |
5921 if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) { | |
5922 continue; | |
5923 } | |
5924 | |
5925 // Filter out elements in the current dragged item | |
5926 for (j=0; j < list.length; j++) { | |
5927 if(list[j] === m[i].element[0]) { | |
5928 m[i].proportions.height = 0; | |
5929 continue droppablesLoop; | |
5930 } | |
5931 } | |
5932 | |
5933 m[i].visible = m[i].element.css("display") !== "none"; | |
5934 if(!m[i].visible) { | |
5935 continue; | |
5936 } | |
5937 | |
5938 //Activate the droppable if used directly from draggables | |
5939 if(type === "mousedown") { | |
5940 m[i]._activate.call(m[i], event); | |
5941 } | |
5942 | |
5943 m[i].offset = m[i].element.offset(); | |
5944 m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; | |
5945 | |
5946 } | |
5947 | |
5948 }, | |
5949 drop: function(draggable, event) { | |
5950 | |
5951 var dropped = false; | |
5952 // Create a copy of the droppables in case the list changes during the drop (#9116) | |
5953 $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() { | |
5954 | |
5955 if(!this.options) { | |
5956 return; | |
5957 } | |
5958 if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) { | |
5959 dropped = this._drop.call(this, event) || dropped; | |
5960 } | |
5961 | |
5962 if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { | |
5963 this.isout = true; | |
5964 this.isover = false; | |
5965 this._deactivate.call(this, event); | |
5966 } | |
5967 | |
5968 }); | |
5969 return dropped; | |
5970 | |
5971 }, | |
5972 dragStart: function( draggable, event ) { | |
5973 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) | |
5974 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() { | |
5975 if( !draggable.options.refreshPositions ) { | |
5976 $.ui.ddmanager.prepareOffsets( draggable, event ); | |
5977 } | |
5978 }); | |
5979 }, | |
5980 drag: function(draggable, event) { | |
5981 | |
5982 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. | |
5983 if(draggable.options.refreshPositions) { | |
5984 $.ui.ddmanager.prepareOffsets(draggable, event); | |
5985 } | |
5986 | |
5987 //Run through all droppables and check their positions based on specific tolerance options | |
5988 $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { | |
5989 | |
5990 if(this.options.disabled || this.greedyChild || !this.visible) { | |
5991 return; | |
5992 } | |
5993 | |
5994 var parentInstance, scope, parent, | |
5995 intersects = $.ui.intersect(draggable, this, this.options.tolerance), | |
5996 c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null); | |
5997 if(!c) { | |
5998 return; | |
5999 } | |
6000 | |
6001 if (this.options.greedy) { | |
6002 // find droppable parents with same scope | |
6003 scope = this.options.scope; | |
6004 parent = this.element.parents(":data(ui-droppable)").filter(function () { | |
6005 return $.data(this, "ui-droppable").options.scope === scope; | |
6006 }); | |
6007 | |
6008 if (parent.length) { | |
6009 parentInstance = $.data(parent[0], "ui-droppable"); | |
6010 parentInstance.greedyChild = (c === "isover"); | |
6011 } | |
6012 } | |
6013 | |
6014 // we just moved into a greedy child | |
6015 if (parentInstance && c === "isover") { | |
6016 parentInstance.isover = false; | |
6017 parentInstance.isout = true; | |
6018 parentInstance._out.call(parentInstance, event); | |
6019 } | |
6020 | |
6021 this[c] = true; | |
6022 this[c === "isout" ? "isover" : "isout"] = false; | |
6023 this[c === "isover" ? "_over" : "_out"].call(this, event); | |
6024 | |
6025 // we just moved out of a greedy child | |
6026 if (parentInstance && c === "isout") { | |
6027 parentInstance.isout = false; | |
6028 parentInstance.isover = true; | |
6029 parentInstance._over.call(parentInstance, event); | |
6030 } | |
6031 }); | |
6032 | |
6033 }, | |
6034 dragStop: function( draggable, event ) { | |
6035 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" ); | |
6036 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) | |
6037 if( !draggable.options.refreshPositions ) { | |
6038 $.ui.ddmanager.prepareOffsets( draggable, event ); | |
6039 } | |
6040 } | |
6041 }; | |
6042 | |
6043 })(jQuery); | |
6044 (function( $, undefined ) { | |
6045 | |
6046 function num(v) { | |
6047 return parseInt(v, 10) || 0; | |
6048 } | |
6049 | |
6050 function isNumber(value) { | |
6051 return !isNaN(parseInt(value, 10)); | |
6052 } | |
6053 | |
6054 $.widget("ui.resizable", $.ui.mouse, { | |
6055 version: "1.10.3", | |
6056 widgetEventPrefix: "resize", | |
6057 options: { | |
6058 alsoResize: false, | |
6059 animate: false, | |
6060 animateDuration: "slow", | |
6061 animateEasing: "swing", | |
6062 aspectRatio: false, | |
6063 autoHide: false, | |
6064 containment: false, | |
6065 ghost: false, | |
6066 grid: false, | |
6067 handles: "e,s,se", | |
6068 helper: false, | |
6069 maxHeight: null, | |
6070 maxWidth: null, | |
6071 minHeight: 10, | |
6072 minWidth: 10, | |
6073 // See #7960 | |
6074 zIndex: 90, | |
6075 | |
6076 // callbacks | |
6077 resize: null, | |
6078 start: null, | |
6079 stop: null | |
6080 }, | |
6081 _create: function() { | |
6082 | |
6083 var n, i, handle, axis, hname, | |
6084 that = this, | |
6085 o = this.options; | |
6086 this.element.addClass("ui-resizable"); | |
6087 | |
6088 $.extend(this, { | |
6089 _aspectRatio: !!(o.aspectRatio), | |
6090 aspectRatio: o.aspectRatio, | |
6091 originalElement: this.element, | |
6092 _proportionallyResizeElements: [], | |
6093 _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null | |
6094 }); | |
6095 | |
6096 //Wrap the element if it cannot hold child nodes | |
6097 if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { | |
6098 | |
6099 //Create a wrapper element and set the wrapper to the new current internal element | |
6100 this.element.wrap( | |
6101 $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({ | |
6102 position: this.element.css("position"), | |
6103 width: this.element.outerWidth(), | |
6104 height: this.element.outerHeight(), | |
6105 top: this.element.css("top"), | |
6106 left: this.element.css("left") | |
6107 }) | |
6108 ); | |
6109 | |
6110 //Overwrite the original this.element | |
6111 this.element = this.element.parent().data( | |
6112 "ui-resizable", this.element.data("ui-resizable") | |
6113 ); | |
6114 | |
6115 this.elementIsWrapper = true; | |
6116 | |
6117 //Move margins to the wrapper | |
6118 this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); | |
6119 this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); | |
6120 | |
6121 //Prevent Safari textarea resize | |
6122 this.originalResizeStyle = this.originalElement.css("resize"); | |
6123 this.originalElement.css("resize", "none"); | |
6124 | |
6125 //Push the actual element to our proportionallyResize internal array | |
6126 this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" })); | |
6127 | |
6128 // avoid IE jump (hard set the margin) | |
6129 this.originalElement.css({ margin: this.originalElement.css("margin") }); | |
6130 | |
6131 // fix handlers offset | |
6132 this._proportionallyResize(); | |
6133 | |
6134 } | |
6135 | |
6136 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" }); | |
6137 if(this.handles.constructor === String) { | |
6138 | |
6139 if ( this.handles === "all") { | |
6140 this.handles = "n,e,s,w,se,sw,ne,nw"; | |
6141 } | |
6142 | |
6143 n = this.handles.split(","); | |
6144 this.handles = {}; | |
6145 | |
6146 for(i = 0; i < n.length; i++) { | |
6147 | |
6148 handle = $.trim(n[i]); | |
6149 hname = "ui-resizable-"+handle; | |
6150 axis = $("<div class='ui-resizable-handle " + hname + "'></div>"); | |
6151 | |
6152 // Apply zIndex to all handles - see #7960 | |
6153 axis.css({ zIndex: o.zIndex }); | |
6154 | |
6155 //TODO : What's going on here? | |
6156 if ("se" === handle) { | |
6157 axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se"); | |
6158 } | |
6159 | |
6160 //Insert into internal handles object and append to element | |
6161 this.handles[handle] = ".ui-resizable-"+handle; | |
6162 this.element.append(axis); | |
6163 } | |
6164 | |
6165 } | |
6166 | |
6167 this._renderAxis = function(target) { | |
6168 | |
6169 var i, axis, padPos, padWrapper; | |
6170 | |
6171 target = target || this.element; | |
6172 | |
6173 for(i in this.handles) { | |
6174 | |
6175 if(this.handles[i].constructor === String) { | |
6176 this.handles[i] = $(this.handles[i], this.element).show(); | |
6177 } | |
6178 | |
6179 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) | |
6180 if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { | |
6181 | |
6182 axis = $(this.handles[i], this.element); | |
6183 | |
6184 //Checking the correct pad and border | |
6185 padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); | |
6186 | |
6187 //The padding type i have to apply... | |
6188 padPos = [ "padding", | |
6189 /ne|nw|n/.test(i) ? "Top" : | |
6190 /se|sw|s/.test(i) ? "Bottom" : | |
6191 /^e$/.test(i) ? "Right" : "Left" ].join(""); | |
6192 | |
6193 target.css(padPos, padWrapper); | |
6194 | |
6195 this._proportionallyResize(); | |
6196 | |
6197 } | |
6198 | |
6199 //TODO: What's that good for? There's not anything to be executed left | |
6200 if(!$(this.handles[i]).length) { | |
6201 continue; | |
6202 } | |
6203 } | |
6204 }; | |
6205 | |
6206 //TODO: make renderAxis a prototype function | |
6207 this._renderAxis(this.element); | |
6208 | |
6209 this._handles = $(".ui-resizable-handle", this.element) | |
6210 .disableSelection(); | |
6211 | |
6212 //Matching axis name | |
6213 this._handles.mouseover(function() { | |
6214 if (!that.resizing) { | |
6215 if (this.className) { | |
6216 axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); | |
6217 } | |
6218 //Axis, default = se | |
6219 that.axis = axis && axis[1] ? axis[1] : "se"; | |
6220 } | |
6221 }); | |
6222 | |
6223 //If we want to auto hide the elements | |
6224 if (o.autoHide) { | |
6225 this._handles.hide(); | |
6226 $(this.element) | |
6227 .addClass("ui-resizable-autohide") | |
6228 .mouseenter(function() { | |
6229 if (o.disabled) { | |
6230 return; | |
6231 } | |
6232 $(this).removeClass("ui-resizable-autohide"); | |
6233 that._handles.show(); | |
6234 }) | |
6235 .mouseleave(function(){ | |
6236 if (o.disabled) { | |
6237 return; | |
6238 } | |
6239 if (!that.resizing) { | |
6240 $(this).addClass("ui-resizable-autohide"); | |
6241 that._handles.hide(); | |
6242 } | |
6243 }); | |
6244 } | |
6245 | |
6246 //Initialize the mouse interaction | |
6247 this._mouseInit(); | |
6248 | |
6249 }, | |
6250 | |
6251 _destroy: function() { | |
6252 | |
6253 this._mouseDestroy(); | |
6254 | |
6255 var wrapper, | |
6256 _destroy = function(exp) { | |
6257 $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") | |
6258 .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove(); | |
6259 }; | |
6260 | |
6261 //TODO: Unwrap at same DOM position | |
6262 if (this.elementIsWrapper) { | |
6263 _destroy(this.element); | |
6264 wrapper = this.element; | |
6265 this.originalElement.css({ | |
6266 position: wrapper.css("position"), | |
6267 width: wrapper.outerWidth(), | |
6268 height: wrapper.outerHeight(), | |
6269 top: wrapper.css("top"), | |
6270 left: wrapper.css("left") | |
6271 }).insertAfter( wrapper ); | |
6272 wrapper.remove(); | |
6273 } | |
6274 | |
6275 this.originalElement.css("resize", this.originalResizeStyle); | |
6276 _destroy(this.originalElement); | |
6277 | |
6278 return this; | |
6279 }, | |
6280 | |
6281 _mouseCapture: function(event) { | |
6282 var i, handle, | |
6283 capture = false; | |
6284 | |
6285 for (i in this.handles) { | |
6286 handle = $(this.handles[i])[0]; | |
6287 if (handle === event.target || $.contains(handle, event.target)) { | |
6288 capture = true; | |
6289 } | |
6290 } | |
6291 | |
6292 return !this.options.disabled && capture; | |
6293 }, | |
6294 | |
6295 _mouseStart: function(event) { | |
6296 | |
6297 var curleft, curtop, cursor, | |
6298 o = this.options, | |
6299 iniPos = this.element.position(), | |
6300 el = this.element; | |
6301 | |
6302 this.resizing = true; | |
6303 | |
6304 // bugfix for http://dev.jquery.com/ticket/1749 | |
6305 if ( (/absolute/).test( el.css("position") ) ) { | |
6306 el.css({ position: "absolute", top: el.css("top"), left: el.css("left") }); | |
6307 } else if (el.is(".ui-draggable")) { | |
6308 el.css({ position: "absolute", top: iniPos.top, left: iniPos.left }); | |
6309 } | |
6310 | |
6311 this._renderProxy(); | |
6312 | |
6313 curleft = num(this.helper.css("left")); | |
6314 curtop = num(this.helper.css("top")); | |
6315 | |
6316 if (o.containment) { | |
6317 curleft += $(o.containment).scrollLeft() || 0; | |
6318 curtop += $(o.containment).scrollTop() || 0; | |
6319 } | |
6320 | |
6321 //Store needed variables | |
6322 this.offset = this.helper.offset(); | |
6323 this.position = { left: curleft, top: curtop }; | |
6324 this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; | |
6325 this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; | |
6326 this.originalPosition = { left: curleft, top: curtop }; | |
6327 this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; | |
6328 this.originalMousePosition = { left: event.pageX, top: event.pageY }; | |
6329 | |
6330 //Aspect Ratio | |
6331 this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); | |
6332 | |
6333 cursor = $(".ui-resizable-" + this.axis).css("cursor"); | |
6334 $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor); | |
6335 | |
6336 el.addClass("ui-resizable-resizing"); | |
6337 this._propagate("start", event); | |
6338 return true; | |
6339 }, | |
6340 | |
6341 _mouseDrag: function(event) { | |
6342 | |
6343 //Increase performance, avoid regex | |
6344 var data, | |
6345 el = this.helper, props = {}, | |
6346 smp = this.originalMousePosition, | |
6347 a = this.axis, | |
6348 prevTop = this.position.top, | |
6349 prevLeft = this.position.left, | |
6350 prevWidth = this.size.width, | |
6351 prevHeight = this.size.height, | |
6352 dx = (event.pageX-smp.left)||0, | |
6353 dy = (event.pageY-smp.top)||0, | |
6354 trigger = this._change[a]; | |
6355 | |
6356 if (!trigger) { | |
6357 return false; | |
6358 } | |
6359 | |
6360 // Calculate the attrs that will be change | |
6361 data = trigger.apply(this, [event, dx, dy]); | |
6362 | |
6363 // Put this in the mouseDrag handler since the user can start pressing shift while resizing | |
6364 this._updateVirtualBoundaries(event.shiftKey); | |
6365 if (this._aspectRatio || event.shiftKey) { | |
6366 data = this._updateRatio(data, event); | |
6367 } | |
6368 | |
6369 data = this._respectSize(data, event); | |
6370 | |
6371 this._updateCache(data); | |
6372 | |
6373 // plugins callbacks need to be called first | |
6374 this._propagate("resize", event); | |
6375 | |
6376 if (this.position.top !== prevTop) { | |
6377 props.top = this.position.top + "px"; | |
6378 } | |
6379 if (this.position.left !== prevLeft) { | |
6380 props.left = this.position.left + "px"; | |
6381 } | |
6382 if (this.size.width !== prevWidth) { | |
6383 props.width = this.size.width + "px"; | |
6384 } | |
6385 if (this.size.height !== prevHeight) { | |
6386 props.height = this.size.height + "px"; | |
6387 } | |
6388 el.css(props); | |
6389 | |
6390 if (!this._helper && this._proportionallyResizeElements.length) { | |
6391 this._proportionallyResize(); | |
6392 } | |
6393 | |
6394 // Call the user callback if the element was resized | |
6395 if ( ! $.isEmptyObject(props) ) { | |
6396 this._trigger("resize", event, this.ui()); | |
6397 } | |
6398 | |
6399 return false; | |
6400 }, | |
6401 | |
6402 _mouseStop: function(event) { | |
6403 | |
6404 this.resizing = false; | |
6405 var pr, ista, soffseth, soffsetw, s, left, top, | |
6406 o = this.options, that = this; | |
6407 | |
6408 if(this._helper) { | |
6409 | |
6410 pr = this._proportionallyResizeElements; | |
6411 ista = pr.length && (/textarea/i).test(pr[0].nodeName); | |
6412 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height; | |
6413 soffsetw = ista ? 0 : that.sizeDiff.width; | |
6414 | |
6415 s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) }; | |
6416 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null; | |
6417 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; | |
6418 | |
6419 if (!o.animate) { | |
6420 this.element.css($.extend(s, { top: top, left: left })); | |
6421 } | |
6422 | |
6423 that.helper.height(that.size.height); | |
6424 that.helper.width(that.size.width); | |
6425 | |
6426 if (this._helper && !o.animate) { | |
6427 this._proportionallyResize(); | |
6428 } | |
6429 } | |
6430 | |
6431 $("body").css("cursor", "auto"); | |
6432 | |
6433 this.element.removeClass("ui-resizable-resizing"); | |
6434 | |
6435 this._propagate("stop", event); | |
6436 | |
6437 if (this._helper) { | |
6438 this.helper.remove(); | |
6439 } | |
6440 | |
6441 return false; | |
6442 | |
6443 }, | |
6444 | |
6445 _updateVirtualBoundaries: function(forceAspectRatio) { | |
6446 var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b, | |
6447 o = this.options; | |
6448 | |
6449 b = { | |
6450 minWidth: isNumber(o.minWidth) ? o.minWidth : 0, | |
6451 maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, | |
6452 minHeight: isNumber(o.minHeight) ? o.minHeight : 0, | |
6453 maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity | |
6454 }; | |
6455 | |
6456 if(this._aspectRatio || forceAspectRatio) { | |
6457 // We want to create an enclosing box whose aspect ration is the requested one | |
6458 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension | |
6459 pMinWidth = b.minHeight * this.aspectRatio; | |
6460 pMinHeight = b.minWidth / this.aspectRatio; | |
6461 pMaxWidth = b.maxHeight * this.aspectRatio; | |
6462 pMaxHeight = b.maxWidth / this.aspectRatio; | |
6463 | |
6464 if(pMinWidth > b.minWidth) { | |
6465 b.minWidth = pMinWidth; | |
6466 } | |
6467 if(pMinHeight > b.minHeight) { | |
6468 b.minHeight = pMinHeight; | |
6469 } | |
6470 if(pMaxWidth < b.maxWidth) { | |
6471 b.maxWidth = pMaxWidth; | |
6472 } | |
6473 if(pMaxHeight < b.maxHeight) { | |
6474 b.maxHeight = pMaxHeight; | |
6475 } | |
6476 } | |
6477 this._vBoundaries = b; | |
6478 }, | |
6479 | |
6480 _updateCache: function(data) { | |
6481 this.offset = this.helper.offset(); | |
6482 if (isNumber(data.left)) { | |
6483 this.position.left = data.left; | |
6484 } | |
6485 if (isNumber(data.top)) { | |
6486 this.position.top = data.top; | |
6487 } | |
6488 if (isNumber(data.height)) { | |
6489 this.size.height = data.height; | |
6490 } | |
6491 if (isNumber(data.width)) { | |
6492 this.size.width = data.width; | |
6493 } | |
6494 }, | |
6495 | |
6496 _updateRatio: function( data ) { | |
6497 | |
6498 var cpos = this.position, | |
6499 csize = this.size, | |
6500 a = this.axis; | |
6501 | |
6502 if (isNumber(data.height)) { | |
6503 data.width = (data.height * this.aspectRatio); | |
6504 } else if (isNumber(data.width)) { | |
6505 data.height = (data.width / this.aspectRatio); | |
6506 } | |
6507 | |
6508 if (a === "sw") { | |
6509 data.left = cpos.left + (csize.width - data.width); | |
6510 data.top = null; | |
6511 } | |
6512 if (a === "nw") { | |
6513 data.top = cpos.top + (csize.height - data.height); | |
6514 data.left = cpos.left + (csize.width - data.width); | |
6515 } | |
6516 | |
6517 return data; | |
6518 }, | |
6519 | |
6520 _respectSize: function( data ) { | |
6521 | |
6522 var o = this._vBoundaries, | |
6523 a = this.axis, | |
6524 ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), | |
6525 isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height), | |
6526 dw = this.originalPosition.left + this.originalSize.width, | |
6527 dh = this.position.top + this.size.height, | |
6528 cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); | |
6529 if (isminw) { | |
6530 data.width = o.minWidth; | |
6531 } | |
6532 if (isminh) { | |
6533 data.height = o.minHeight; | |
6534 } | |
6535 if (ismaxw) { | |
6536 data.width = o.maxWidth; | |
6537 } | |
6538 if (ismaxh) { | |
6539 data.height = o.maxHeight; | |
6540 } | |
6541 | |
6542 if (isminw && cw) { | |
6543 data.left = dw - o.minWidth; | |
6544 } | |
6545 if (ismaxw && cw) { | |
6546 data.left = dw - o.maxWidth; | |
6547 } | |
6548 if (isminh && ch) { | |
6549 data.top = dh - o.minHeight; | |
6550 } | |
6551 if (ismaxh && ch) { | |
6552 data.top = dh - o.maxHeight; | |
6553 } | |
6554 | |
6555 // fixing jump error on top/left - bug #2330 | |
6556 if (!data.width && !data.height && !data.left && data.top) { | |
6557 data.top = null; | |
6558 } else if (!data.width && !data.height && !data.top && data.left) { | |
6559 data.left = null; | |
6560 } | |
6561 | |
6562 return data; | |
6563 }, | |
6564 | |
6565 _proportionallyResize: function() { | |
6566 | |
6567 if (!this._proportionallyResizeElements.length) { | |
6568 return; | |
6569 } | |
6570 | |
6571 var i, j, borders, paddings, prel, | |
6572 element = this.helper || this.element; | |
6573 | |
6574 for ( i=0; i < this._proportionallyResizeElements.length; i++) { | |
6575 | |
6576 prel = this._proportionallyResizeElements[i]; | |
6577 | |
6578 if (!this.borderDif) { | |
6579 this.borderDif = []; | |
6580 borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")]; | |
6581 paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")]; | |
6582 | |
6583 for ( j = 0; j < borders.length; j++ ) { | |
6584 this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 ); | |
6585 } | |
6586 } | |
6587 | |
6588 prel.css({ | |
6589 height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, | |
6590 width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 | |
6591 }); | |
6592 | |
6593 } | |
6594 | |
6595 }, | |
6596 | |
6597 _renderProxy: function() { | |
6598 | |
6599 var el = this.element, o = this.options; | |
6600 this.elementOffset = el.offset(); | |
6601 | |
6602 if(this._helper) { | |
6603 | |
6604 this.helper = this.helper || $("<div style='overflow:hidden;'></div>"); | |
6605 | |
6606 this.helper.addClass(this._helper).css({ | |
6607 width: this.element.outerWidth() - 1, | |
6608 height: this.element.outerHeight() - 1, | |
6609 position: "absolute", | |
6610 left: this.elementOffset.left +"px", | |
6611 top: this.elementOffset.top +"px", | |
6612 zIndex: ++o.zIndex //TODO: Don't modify option | |
6613 }); | |
6614 | |
6615 this.helper | |
6616 .appendTo("body") | |
6617 .disableSelection(); | |
6618 | |
6619 } else { | |
6620 this.helper = this.element; | |
6621 } | |
6622 | |
6623 }, | |
6624 | |
6625 _change: { | |
6626 e: function(event, dx) { | |
6627 return { width: this.originalSize.width + dx }; | |
6628 }, | |
6629 w: function(event, dx) { | |
6630 var cs = this.originalSize, sp = this.originalPosition; | |
6631 return { left: sp.left + dx, width: cs.width - dx }; | |
6632 }, | |
6633 n: function(event, dx, dy) { | |
6634 var cs = this.originalSize, sp = this.originalPosition; | |
6635 return { top: sp.top + dy, height: cs.height - dy }; | |
6636 }, | |
6637 s: function(event, dx, dy) { | |
6638 return { height: this.originalSize.height + dy }; | |
6639 }, | |
6640 se: function(event, dx, dy) { | |
6641 return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); | |
6642 }, | |
6643 sw: function(event, dx, dy) { | |
6644 return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); | |
6645 }, | |
6646 ne: function(event, dx, dy) { | |
6647 return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); | |
6648 }, | |
6649 nw: function(event, dx, dy) { | |
6650 return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); | |
6651 } | |
6652 }, | |
6653 | |
6654 _propagate: function(n, event) { | |
6655 $.ui.plugin.call(this, n, [event, this.ui()]); | |
6656 (n !== "resize" && this._trigger(n, event, this.ui())); | |
6657 }, | |
6658 | |
6659 plugins: {}, | |
6660 | |
6661 ui: function() { | |
6662 return { | |
6663 originalElement: this.originalElement, | |
6664 element: this.element, | |
6665 helper: this.helper, | |
6666 position: this.position, | |
6667 size: this.size, | |
6668 originalSize: this.originalSize, | |
6669 originalPosition: this.originalPosition | |
6670 }; | |
6671 } | |
6672 | |
6673 }); | |
6674 | |
6675 /* | |
6676 * Resizable Extensions | |
6677 */ | |
6678 | |
6679 $.ui.plugin.add("resizable", "animate", { | |
6680 | |
6681 stop: function( event ) { | |
6682 var that = $(this).data("ui-resizable"), | |
6683 o = that.options, | |
6684 pr = that._proportionallyResizeElements, | |
6685 ista = pr.length && (/textarea/i).test(pr[0].nodeName), | |
6686 soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height, | |
6687 soffsetw = ista ? 0 : that.sizeDiff.width, | |
6688 style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) }, | |
6689 left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null, | |
6690 top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null; | |
6691 | |
6692 that.element.animate( | |
6693 $.extend(style, top && left ? { top: top, left: left } : {}), { | |
6694 duration: o.animateDuration, | |
6695 easing: o.animateEasing, | |
6696 step: function() { | |
6697 | |
6698 var data = { | |
6699 width: parseInt(that.element.css("width"), 10), | |
6700 height: parseInt(that.element.css("height"), 10), | |
6701 top: parseInt(that.element.css("top"), 10), | |
6702 left: parseInt(that.element.css("left"), 10) | |
6703 }; | |
6704 | |
6705 if (pr && pr.length) { | |
6706 $(pr[0]).css({ width: data.width, height: data.height }); | |
6707 } | |
6708 | |
6709 // propagating resize, and updating values for each animation step | |
6710 that._updateCache(data); | |
6711 that._propagate("resize", event); | |
6712 | |
6713 } | |
6714 } | |
6715 ); | |
6716 } | |
6717 | |
6718 }); | |
6719 | |
6720 $.ui.plugin.add("resizable", "containment", { | |
6721 | |
6722 start: function() { | |
6723 var element, p, co, ch, cw, width, height, | |
6724 that = $(this).data("ui-resizable"), | |
6725 o = that.options, | |
6726 el = that.element, | |
6727 oc = o.containment, | |
6728 ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; | |
6729 | |
6730 if (!ce) { | |
6731 return; | |
6732 } | |
6733 | |
6734 that.containerElement = $(ce); | |
6735 | |
6736 if (/document/.test(oc) || oc === document) { | |
6737 that.containerOffset = { left: 0, top: 0 }; | |
6738 that.containerPosition = { left: 0, top: 0 }; | |
6739 | |
6740 that.parentData = { | |
6741 element: $(document), left: 0, top: 0, | |
6742 width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight | |
6743 }; | |
6744 } | |
6745 | |
6746 // i'm a node, so compute top, left, right, bottom | |
6747 else { | |
6748 element = $(ce); | |
6749 p = []; | |
6750 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); | |
6751 | |
6752 that.containerOffset = element.offset(); | |
6753 that.containerPosition = element.position(); | |
6754 that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; | |
6755 | |
6756 co = that.containerOffset; | |
6757 ch = that.containerSize.height; | |
6758 cw = that.containerSize.width; | |
6759 width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ); | |
6760 height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); | |
6761 | |
6762 that.parentData = { | |
6763 element: ce, left: co.left, top: co.top, width: width, height: height | |
6764 }; | |
6765 } | |
6766 }, | |
6767 | |
6768 resize: function( event ) { | |
6769 var woset, hoset, isParent, isOffsetRelative, | |
6770 that = $(this).data("ui-resizable"), | |
6771 o = that.options, | |
6772 co = that.containerOffset, cp = that.position, | |
6773 pRatio = that._aspectRatio || event.shiftKey, | |
6774 cop = { top:0, left:0 }, ce = that.containerElement; | |
6775 | |
6776 if (ce[0] !== document && (/static/).test(ce.css("position"))) { | |
6777 cop = co; | |
6778 } | |
6779 | |
6780 if (cp.left < (that._helper ? co.left : 0)) { | |
6781 that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left)); | |
6782 if (pRatio) { | |
6783 that.size.height = that.size.width / that.aspectRatio; | |
6784 } | |
6785 that.position.left = o.helper ? co.left : 0; | |
6786 } | |
6787 | |
6788 if (cp.top < (that._helper ? co.top : 0)) { | |
6789 that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top); | |
6790 if (pRatio) { | |
6791 that.size.width = that.size.height * that.aspectRatio; | |
6792 } | |
6793 that.position.top = that._helper ? co.top : 0; | |
6794 } | |
6795 | |
6796 that.offset.left = that.parentData.left+that.position.left; | |
6797 that.offset.top = that.parentData.top+that.position.top; | |
6798 | |
6799 woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width ); | |
6800 hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height ); | |
6801 | |
6802 isParent = that.containerElement.get(0) === that.element.parent().get(0); | |
6803 isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position")); | |
6804 | |
6805 if(isParent && isOffsetRelative) { | |
6806 woset -= that.parentData.left; | |
6807 } | |
6808 | |
6809 if (woset + that.size.width >= that.parentData.width) { | |
6810 that.size.width = that.parentData.width - woset; | |
6811 if (pRatio) { | |
6812 that.size.height = that.size.width / that.aspectRatio; | |
6813 } | |
6814 } | |
6815 | |
6816 if (hoset + that.size.height >= that.parentData.height) { | |
6817 that.size.height = that.parentData.height - hoset; | |
6818 if (pRatio) { | |
6819 that.size.width = that.size.height * that.aspectRatio; | |
6820 } | |
6821 } | |
6822 }, | |
6823 | |
6824 stop: function(){ | |
6825 var that = $(this).data("ui-resizable"), | |
6826 o = that.options, | |
6827 co = that.containerOffset, | |
6828 cop = that.containerPosition, | |
6829 ce = that.containerElement, | |
6830 helper = $(that.helper), | |
6831 ho = helper.offset(), | |
6832 w = helper.outerWidth() - that.sizeDiff.width, | |
6833 h = helper.outerHeight() - that.sizeDiff.height; | |
6834 | |
6835 if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) { | |
6836 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); | |
6837 } | |
6838 | |
6839 if (that._helper && !o.animate && (/static/).test(ce.css("position"))) { | |
6840 $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); | |
6841 } | |
6842 | |
6843 } | |
6844 }); | |
6845 | |
6846 $.ui.plugin.add("resizable", "alsoResize", { | |
6847 | |
6848 start: function () { | |
6849 var that = $(this).data("ui-resizable"), | |
6850 o = that.options, | |
6851 _store = function (exp) { | |
6852 $(exp).each(function() { | |
6853 var el = $(this); | |
6854 el.data("ui-resizable-alsoresize", { | |
6855 width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), | |
6856 left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10) | |
6857 }); | |
6858 }); | |
6859 }; | |
6860 | |
6861 if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) { | |
6862 if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } | |
6863 else { $.each(o.alsoResize, function (exp) { _store(exp); }); } | |
6864 }else{ | |
6865 _store(o.alsoResize); | |
6866 } | |
6867 }, | |
6868 | |
6869 resize: function (event, ui) { | |
6870 var that = $(this).data("ui-resizable"), | |
6871 o = that.options, | |
6872 os = that.originalSize, | |
6873 op = that.originalPosition, | |
6874 delta = { | |
6875 height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0, | |
6876 top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0 | |
6877 }, | |
6878 | |
6879 _alsoResize = function (exp, c) { | |
6880 $(exp).each(function() { | |
6881 var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {}, | |
6882 css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"]; | |
6883 | |
6884 $.each(css, function (i, prop) { | |
6885 var sum = (start[prop]||0) + (delta[prop]||0); | |
6886 if (sum && sum >= 0) { | |
6887 style[prop] = sum || null; | |
6888 } | |
6889 }); | |
6890 | |
6891 el.css(style); | |
6892 }); | |
6893 }; | |
6894 | |
6895 if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) { | |
6896 $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); | |
6897 }else{ | |
6898 _alsoResize(o.alsoResize); | |
6899 } | |
6900 }, | |
6901 | |
6902 stop: function () { | |
6903 $(this).removeData("resizable-alsoresize"); | |
6904 } | |
6905 }); | |
6906 | |
6907 $.ui.plugin.add("resizable", "ghost", { | |
6908 | |
6909 start: function() { | |
6910 | |
6911 var that = $(this).data("ui-resizable"), o = that.options, cs = that.size; | |
6912 | |
6913 that.ghost = that.originalElement.clone(); | |
6914 that.ghost | |
6915 .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) | |
6916 .addClass("ui-resizable-ghost") | |
6917 .addClass(typeof o.ghost === "string" ? o.ghost : ""); | |
6918 | |
6919 that.ghost.appendTo(that.helper); | |
6920 | |
6921 }, | |
6922 | |
6923 resize: function(){ | |
6924 var that = $(this).data("ui-resizable"); | |
6925 if (that.ghost) { | |
6926 that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width }); | |
6927 } | |
6928 }, | |
6929 | |
6930 stop: function() { | |
6931 var that = $(this).data("ui-resizable"); | |
6932 if (that.ghost && that.helper) { | |
6933 that.helper.get(0).removeChild(that.ghost.get(0)); | |
6934 } | |
6935 } | |
6936 | |
6937 }); | |
6938 | |
6939 $.ui.plugin.add("resizable", "grid", { | |
6940 | |
6941 resize: function() { | |
6942 var that = $(this).data("ui-resizable"), | |
6943 o = that.options, | |
6944 cs = that.size, | |
6945 os = that.originalSize, | |
6946 op = that.originalPosition, | |
6947 a = that.axis, | |
6948 grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid, | |
6949 gridX = (grid[0]||1), | |
6950 gridY = (grid[1]||1), | |
6951 ox = Math.round((cs.width - os.width) / gridX) * gridX, | |
6952 oy = Math.round((cs.height - os.height) / gridY) * gridY, | |
6953 newWidth = os.width + ox, | |
6954 newHeight = os.height + oy, | |
6955 isMaxWidth = o.maxWidth && (o.maxWidth < newWidth), | |
6956 isMaxHeight = o.maxHeight && (o.maxHeight < newHeight), | |
6957 isMinWidth = o.minWidth && (o.minWidth > newWidth), | |
6958 isMinHeight = o.minHeight && (o.minHeight > newHeight); | |
6959 | |
6960 o.grid = grid; | |
6961 | |
6962 if (isMinWidth) { | |
6963 newWidth = newWidth + gridX; | |
6964 } | |
6965 if (isMinHeight) { | |
6966 newHeight = newHeight + gridY; | |
6967 } | |
6968 if (isMaxWidth) { | |
6969 newWidth = newWidth - gridX; | |
6970 } | |
6971 if (isMaxHeight) { | |
6972 newHeight = newHeight - gridY; | |
6973 } | |
6974 | |
6975 if (/^(se|s|e)$/.test(a)) { | |
6976 that.size.width = newWidth; | |
6977 that.size.height = newHeight; | |
6978 } else if (/^(ne)$/.test(a)) { | |
6979 that.size.width = newWidth; | |
6980 that.size.height = newHeight; | |
6981 that.position.top = op.top - oy; | |
6982 } else if (/^(sw)$/.test(a)) { | |
6983 that.size.width = newWidth; | |
6984 that.size.height = newHeight; | |
6985 that.position.left = op.left - ox; | |
6986 } else { | |
6987 that.size.width = newWidth; | |
6988 that.size.height = newHeight; | |
6989 that.position.top = op.top - oy; | |
6990 that.position.left = op.left - ox; | |
6991 } | |
6992 } | |
6993 | |
6994 }); | |
6995 | |
6996 })(jQuery); | |
6997 (function( $, undefined ) { | |
6998 | |
6999 $.widget("ui.selectable", $.ui.mouse, { | |
7000 version: "1.10.3", | |
7001 options: { | |
7002 appendTo: "body", | |
7003 autoRefresh: true, | |
7004 distance: 0, | |
7005 filter: "*", | |
7006 tolerance: "touch", | |
7007 | |
7008 // callbacks | |
7009 selected: null, | |
7010 selecting: null, | |
7011 start: null, | |
7012 stop: null, | |
7013 unselected: null, | |
7014 unselecting: null | |
7015 }, | |
7016 _create: function() { | |
7017 var selectees, | |
7018 that = this; | |
7019 | |
7020 this.element.addClass("ui-selectable"); | |
7021 | |
7022 this.dragged = false; | |
7023 | |
7024 // cache selectee children based on filter | |
7025 this.refresh = function() { | |
7026 selectees = $(that.options.filter, that.element[0]); | |
7027 selectees.addClass("ui-selectee"); | |
7028 selectees.each(function() { | |
7029 var $this = $(this), | |
7030 pos = $this.offset(); | |
7031 $.data(this, "selectable-item", { | |
7032 element: this, | |
7033 $element: $this, | |
7034 left: pos.left, | |
7035 top: pos.top, | |
7036 right: pos.left + $this.outerWidth(), | |
7037 bottom: pos.top + $this.outerHeight(), | |
7038 startselected: false, | |
7039 selected: $this.hasClass("ui-selected"), | |
7040 selecting: $this.hasClass("ui-selecting"), | |
7041 unselecting: $this.hasClass("ui-unselecting") | |
7042 }); | |
7043 }); | |
7044 }; | |
7045 this.refresh(); | |
7046 | |
7047 this.selectees = selectees.addClass("ui-selectee"); | |
7048 | |
7049 this._mouseInit(); | |
7050 | |
7051 this.helper = $("<div class='ui-selectable-helper'></div>"); | |
7052 }, | |
7053 | |
7054 _destroy: function() { | |
7055 this.selectees | |
7056 .removeClass("ui-selectee") | |
7057 .removeData("selectable-item"); | |
7058 this.element | |
7059 .removeClass("ui-selectable ui-selectable-disabled"); | |
7060 this._mouseDestroy(); | |
7061 }, | |
7062 | |
7063 _mouseStart: function(event) { | |
7064 var that = this, | |
7065 options = this.options; | |
7066 | |
7067 this.opos = [event.pageX, event.pageY]; | |
7068 | |
7069 if (this.options.disabled) { | |
7070 return; | |
7071 } | |
7072 | |
7073 this.selectees = $(options.filter, this.element[0]); | |
7074 | |
7075 this._trigger("start", event); | |
7076 | |
7077 $(options.appendTo).append(this.helper); | |
7078 // position helper (lasso) | |
7079 this.helper.css({ | |
7080 "left": event.pageX, | |
7081 "top": event.pageY, | |
7082 "width": 0, | |
7083 "height": 0 | |
7084 }); | |
7085 | |
7086 if (options.autoRefresh) { | |
7087 this.refresh(); | |
7088 } | |
7089 | |
7090 this.selectees.filter(".ui-selected").each(function() { | |
7091 var selectee = $.data(this, "selectable-item"); | |
7092 selectee.startselected = true; | |
7093 if (!event.metaKey && !event.ctrlKey) { | |
7094 selectee.$element.removeClass("ui-selected"); | |
7095 selectee.selected = false; | |
7096 selectee.$element.addClass("ui-unselecting"); | |
7097 selectee.unselecting = true; | |
7098 // selectable UNSELECTING callback | |
7099 that._trigger("unselecting", event, { | |
7100 unselecting: selectee.element | |
7101 }); | |
7102 } | |
7103 }); | |
7104 | |
7105 $(event.target).parents().addBack().each(function() { | |
7106 var doSelect, | |
7107 selectee = $.data(this, "selectable-item"); | |
7108 if (selectee) { | |
7109 doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); | |
7110 selectee.$element | |
7111 .removeClass(doSelect ? "ui-unselecting" : "ui-selected") | |
7112 .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); | |
7113 selectee.unselecting = !doSelect; | |
7114 selectee.selecting = doSelect; | |
7115 selectee.selected = doSelect; | |
7116 // selectable (UN)SELECTING callback | |
7117 if (doSelect) { | |
7118 that._trigger("selecting", event, { | |
7119 selecting: selectee.element | |
7120 }); | |
7121 } else { | |
7122 that._trigger("unselecting", event, { | |
7123 unselecting: selectee.element | |
7124 }); | |
7125 } | |
7126 return false; | |
7127 } | |
7128 }); | |
7129 | |
7130 }, | |
7131 | |
7132 _mouseDrag: function(event) { | |
7133 | |
7134 this.dragged = true; | |
7135 | |
7136 if (this.options.disabled) { | |
7137 return; | |
7138 } | |
7139 | |
7140 var tmp, | |
7141 that = this, | |
7142 options = this.options, | |
7143 x1 = this.opos[0], | |
7144 y1 = this.opos[1], | |
7145 x2 = event.pageX, | |
7146 y2 = event.pageY; | |
7147 | |
7148 if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } | |
7149 if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } | |
7150 this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); | |
7151 | |
7152 this.selectees.each(function() { | |
7153 var selectee = $.data(this, "selectable-item"), | |
7154 hit = false; | |
7155 | |
7156 //prevent helper from being selected if appendTo: selectable | |
7157 if (!selectee || selectee.element === that.element[0]) { | |
7158 return; | |
7159 } | |
7160 | |
7161 if (options.tolerance === "touch") { | |
7162 hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); | |
7163 } else if (options.tolerance === "fit") { | |
7164 hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); | |
7165 } | |
7166 | |
7167 if (hit) { | |
7168 // SELECT | |
7169 if (selectee.selected) { | |
7170 selectee.$element.removeClass("ui-selected"); | |
7171 selectee.selected = false; | |
7172 } | |
7173 if (selectee.unselecting) { | |
7174 selectee.$element.removeClass("ui-unselecting"); | |
7175 selectee.unselecting = false; | |
7176 } | |
7177 if (!selectee.selecting) { | |
7178 selectee.$element.addClass("ui-selecting"); | |
7179 selectee.selecting = true; | |
7180 // selectable SELECTING callback | |
7181 that._trigger("selecting", event, { | |
7182 selecting: selectee.element | |
7183 }); | |
7184 } | |
7185 } else { | |
7186 // UNSELECT | |
7187 if (selectee.selecting) { | |
7188 if ((event.metaKey || event.ctrlKey) && selectee.startselected) { | |
7189 selectee.$element.removeClass("ui-selecting"); | |
7190 selectee.selecting = false; | |
7191 selectee.$element.addClass("ui-selected"); | |
7192 selectee.selected = true; | |
7193 } else { | |
7194 selectee.$element.removeClass("ui-selecting"); | |
7195 selectee.selecting = false; | |
7196 if (selectee.startselected) { | |
7197 selectee.$element.addClass("ui-unselecting"); | |
7198 selectee.unselecting = true; | |
7199 } | |
7200 // selectable UNSELECTING callback | |
7201 that._trigger("unselecting", event, { | |
7202 unselecting: selectee.element | |
7203 }); | |
7204 } | |
7205 } | |
7206 if (selectee.selected) { | |
7207 if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { | |
7208 selectee.$element.removeClass("ui-selected"); | |
7209 selectee.selected = false; | |
7210 | |
7211 selectee.$element.addClass("ui-unselecting"); | |
7212 selectee.unselecting = true; | |
7213 // selectable UNSELECTING callback | |
7214 that._trigger("unselecting", event, { | |
7215 unselecting: selectee.element | |
7216 }); | |
7217 } | |
7218 } | |
7219 } | |
7220 }); | |
7221 | |
7222 return false; | |
7223 }, | |
7224 | |
7225 _mouseStop: function(event) { | |
7226 var that = this; | |
7227 | |
7228 this.dragged = false; | |
7229 | |
7230 $(".ui-unselecting", this.element[0]).each(function() { | |
7231 var selectee = $.data(this, "selectable-item"); | |
7232 selectee.$element.removeClass("ui-unselecting"); | |
7233 selectee.unselecting = false; | |
7234 selectee.startselected = false; | |
7235 that._trigger("unselected", event, { | |
7236 unselected: selectee.element | |
7237 }); | |
7238 }); | |
7239 $(".ui-selecting", this.element[0]).each(function() { | |
7240 var selectee = $.data(this, "selectable-item"); | |
7241 selectee.$element.removeClass("ui-selecting").addClass("ui-selected"); | |
7242 selectee.selecting = false; | |
7243 selectee.selected = true; | |
7244 selectee.startselected = true; | |
7245 that._trigger("selected", event, { | |
7246 selected: selectee.element | |
7247 }); | |
7248 }); | |
7249 this._trigger("stop", event); | |
7250 | |
7251 this.helper.remove(); | |
7252 | |
7253 return false; | |
7254 } | |
7255 | |
7256 }); | |
7257 | |
7258 })(jQuery); | |
7259 (function( $, undefined ) { | |
7260 | |
7261 /*jshint loopfunc: true */ | |
7262 | |
7263 function isOverAxis( x, reference, size ) { | |
7264 return ( x > reference ) && ( x < ( reference + size ) ); | |
7265 } | |
7266 | |
7267 function isFloating(item) { | |
7268 return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display")); | |
7269 } | |
7270 | |
7271 $.widget("ui.sortable", $.ui.mouse, { | |
7272 version: "1.10.3", | |
7273 widgetEventPrefix: "sort", | |
7274 ready: false, | |
7275 options: { | |
7276 appendTo: "parent", | |
7277 axis: false, | |
7278 connectWith: false, | |
7279 containment: false, | |
7280 cursor: "auto", | |
7281 cursorAt: false, | |
7282 dropOnEmpty: true, | |
7283 forcePlaceholderSize: false, | |
7284 forceHelperSize: false, | |
7285 grid: false, | |
7286 handle: false, | |
7287 helper: "original", | |
7288 items: "> *", | |
7289 opacity: false, | |
7290 placeholder: false, | |
7291 revert: false, | |
7292 scroll: true, | |
7293 scrollSensitivity: 20, | |
7294 scrollSpeed: 20, | |
7295 scope: "default", | |
7296 tolerance: "intersect", | |
7297 zIndex: 1000, | |
7298 | |
7299 // callbacks | |
7300 activate: null, | |
7301 beforeStop: null, | |
7302 change: null, | |
7303 deactivate: null, | |
7304 out: null, | |
7305 over: null, | |
7306 receive: null, | |
7307 remove: null, | |
7308 sort: null, | |
7309 start: null, | |
7310 stop: null, | |
7311 update: null | |
7312 }, | |
7313 _create: function() { | |
7314 | |
7315 var o = this.options; | |
7316 this.containerCache = {}; | |
7317 this.element.addClass("ui-sortable"); | |
7318 | |
7319 //Get the items | |
7320 this.refresh(); | |
7321 | |
7322 //Let's determine if the items are being displayed horizontally | |
7323 this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false; | |
7324 | |
7325 //Let's determine the parent's offset | |
7326 this.offset = this.element.offset(); | |
7327 | |
7328 //Initialize mouse events for interaction | |
7329 this._mouseInit(); | |
7330 | |
7331 //We're ready to go | |
7332 this.ready = true; | |
7333 | |
7334 }, | |
7335 | |
7336 _destroy: function() { | |
7337 this.element | |
7338 .removeClass("ui-sortable ui-sortable-disabled"); | |
7339 this._mouseDestroy(); | |
7340 | |
7341 for ( var i = this.items.length - 1; i >= 0; i-- ) { | |
7342 this.items[i].item.removeData(this.widgetName + "-item"); | |
7343 } | |
7344 | |
7345 return this; | |
7346 }, | |
7347 | |
7348 _setOption: function(key, value){ | |
7349 if ( key === "disabled" ) { | |
7350 this.options[ key ] = value; | |
7351 | |
7352 this.widget().toggleClass( "ui-sortable-disabled", !!value ); | |
7353 } else { | |
7354 // Don't call widget base _setOption for disable as it adds ui-state-disabled class | |
7355 $.Widget.prototype._setOption.apply(this, arguments); | |
7356 } | |
7357 }, | |
7358 | |
7359 _mouseCapture: function(event, overrideHandle) { | |
7360 var currentItem = null, | |
7361 validHandle = false, | |
7362 that = this; | |
7363 | |
7364 if (this.reverting) { | |
7365 return false; | |
7366 } | |
7367 | |
7368 if(this.options.disabled || this.options.type === "static") { | |
7369 return false; | |
7370 } | |
7371 | |
7372 //We have to refresh the items data once first | |
7373 this._refreshItems(event); | |
7374 | |
7375 //Find out if the clicked node (or one of its parents) is a actual item in this.items | |
7376 $(event.target).parents().each(function() { | |
7377 if($.data(this, that.widgetName + "-item") === that) { | |
7378 currentItem = $(this); | |
7379 return false; | |
7380 } | |
7381 }); | |
7382 if($.data(event.target, that.widgetName + "-item") === that) { | |
7383 currentItem = $(event.target); | |
7384 } | |
7385 | |
7386 if(!currentItem) { | |
7387 return false; | |
7388 } | |
7389 if(this.options.handle && !overrideHandle) { | |
7390 $(this.options.handle, currentItem).find("*").addBack().each(function() { | |
7391 if(this === event.target) { | |
7392 validHandle = true; | |
7393 } | |
7394 }); | |
7395 if(!validHandle) { | |
7396 return false; | |
7397 } | |
7398 } | |
7399 | |
7400 this.currentItem = currentItem; | |
7401 this._removeCurrentsFromItems(); | |
7402 return true; | |
7403 | |
7404 }, | |
7405 | |
7406 _mouseStart: function(event, overrideHandle, noActivation) { | |
7407 | |
7408 var i, body, | |
7409 o = this.options; | |
7410 | |
7411 this.currentContainer = this; | |
7412 | |
7413 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture | |
7414 this.refreshPositions(); | |
7415 | |
7416 //Create and append the visible helper | |
7417 this.helper = this._createHelper(event); | |
7418 | |
7419 //Cache the helper size | |
7420 this._cacheHelperProportions(); | |
7421 | |
7422 /* | |
7423 * - Position generation - | |
7424 * This block generates everything position related - it's the core of draggables. | |
7425 */ | |
7426 | |
7427 //Cache the margins of the original element | |
7428 this._cacheMargins(); | |
7429 | |
7430 //Get the next scrolling parent | |
7431 this.scrollParent = this.helper.scrollParent(); | |
7432 | |
7433 //The element's absolute position on the page minus margins | |
7434 this.offset = this.currentItem.offset(); | |
7435 this.offset = { | |
7436 top: this.offset.top - this.margins.top, | |
7437 left: this.offset.left - this.margins.left | |
7438 }; | |
7439 | |
7440 $.extend(this.offset, { | |
7441 click: { //Where the click happened, relative to the element | |
7442 left: event.pageX - this.offset.left, | |
7443 top: event.pageY - this.offset.top | |
7444 }, | |
7445 parent: this._getParentOffset(), | |
7446 relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper | |
7447 }); | |
7448 | |
7449 // Only after we got the offset, we can change the helper's position to absolute | |
7450 // TODO: Still need to figure out a way to make relative sorting possible | |
7451 this.helper.css("position", "absolute"); | |
7452 this.cssPosition = this.helper.css("position"); | |
7453 | |
7454 //Generate the original position | |
7455 this.originalPosition = this._generatePosition(event); | |
7456 this.originalPageX = event.pageX; | |
7457 this.originalPageY = event.pageY; | |
7458 | |
7459 //Adjust the mouse offset relative to the helper if "cursorAt" is supplied | |
7460 (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); | |
7461 | |
7462 //Cache the former DOM position | |
7463 this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; | |
7464 | |
7465 //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 | |
7466 if(this.helper[0] !== this.currentItem[0]) { | |
7467 this.currentItem.hide(); | |
7468 } | |
7469 | |
7470 //Create the placeholder | |
7471 this._createPlaceholder(); | |
7472 | |
7473 //Set a containment if given in the options | |
7474 if(o.containment) { | |
7475 this._setContainment(); | |
7476 } | |
7477 | |
7478 if( o.cursor && o.cursor !== "auto" ) { // cursor option | |
7479 body = this.document.find( "body" ); | |
7480 | |
7481 // support: IE | |
7482 this.storedCursor = body.css( "cursor" ); | |
7483 body.css( "cursor", o.cursor ); | |
7484 | |
7485 this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body ); | |
7486 } | |
7487 | |
7488 if(o.opacity) { // opacity option | |
7489 if (this.helper.css("opacity")) { | |
7490 this._storedOpacity = this.helper.css("opacity"); | |
7491 } | |
7492 this.helper.css("opacity", o.opacity); | |
7493 } | |
7494 | |
7495 if(o.zIndex) { // zIndex option | |
7496 if (this.helper.css("zIndex")) { | |
7497 this._storedZIndex = this.helper.css("zIndex"); | |
7498 } | |
7499 this.helper.css("zIndex", o.zIndex); | |
7500 } | |
7501 | |
7502 //Prepare scrolling | |
7503 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { | |
7504 this.overflowOffset = this.scrollParent.offset(); | |
7505 } | |
7506 | |
7507 //Call callbacks | |
7508 this._trigger("start", event, this._uiHash()); | |
7509 | |
7510 //Recache the helper size | |
7511 if(!this._preserveHelperProportions) { | |
7512 this._cacheHelperProportions(); | |
7513 } | |
7514 | |
7515 | |
7516 //Post "activate" events to possible containers | |
7517 if( !noActivation ) { | |
7518 for ( i = this.containers.length - 1; i >= 0; i-- ) { | |
7519 this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) ); | |
7520 } | |
7521 } | |
7522 | |
7523 //Prepare possible droppables | |
7524 if($.ui.ddmanager) { | |
7525 $.ui.ddmanager.current = this; | |
7526 } | |
7527 | |
7528 if ($.ui.ddmanager && !o.dropBehaviour) { | |
7529 $.ui.ddmanager.prepareOffsets(this, event); | |
7530 } | |
7531 | |
7532 this.dragging = true; | |
7533 | |
7534 this.helper.addClass("ui-sortable-helper"); | |
7535 this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position | |
7536 return true; | |
7537 | |
7538 }, | |
7539 | |
7540 _mouseDrag: function(event) { | |
7541 var i, item, itemElement, intersection, | |
7542 o = this.options, | |
7543 scrolled = false; | |
7544 | |
7545 //Compute the helpers position | |
7546 this.position = this._generatePosition(event); | |
7547 this.positionAbs = this._convertPositionTo("absolute"); | |
7548 | |
7549 if (!this.lastPositionAbs) { | |
7550 this.lastPositionAbs = this.positionAbs; | |
7551 } | |
7552 | |
7553 //Do scrolling | |
7554 if(this.options.scroll) { | |
7555 if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") { | |
7556 | |
7557 if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) { | |
7558 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; | |
7559 } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) { | |
7560 this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; | |
7561 } | |
7562 | |
7563 if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) { | |
7564 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; | |
7565 } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) { | |
7566 this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; | |
7567 } | |
7568 | |
7569 } else { | |
7570 | |
7571 if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) { | |
7572 scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); | |
7573 } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) { | |
7574 scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); | |
7575 } | |
7576 | |
7577 if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) { | |
7578 scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); | |
7579 } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) { | |
7580 scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); | |
7581 } | |
7582 | |
7583 } | |
7584 | |
7585 if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { | |
7586 $.ui.ddmanager.prepareOffsets(this, event); | |
7587 } | |
7588 } | |
7589 | |
7590 //Regenerate the absolute position used for position checks | |
7591 this.positionAbs = this._convertPositionTo("absolute"); | |
7592 | |
7593 //Set the helper position | |
7594 if(!this.options.axis || this.options.axis !== "y") { | |
7595 this.helper[0].style.left = this.position.left+"px"; | |
7596 } | |
7597 if(!this.options.axis || this.options.axis !== "x") { | |
7598 this.helper[0].style.top = this.position.top+"px"; | |
7599 } | |
7600 | |
7601 //Rearrange | |
7602 for (i = this.items.length - 1; i >= 0; i--) { | |
7603 | |
7604 //Cache variables and intersection, continue if no intersection | |
7605 item = this.items[i]; | |
7606 itemElement = item.item[0]; | |
7607 intersection = this._intersectsWithPointer(item); | |
7608 if (!intersection) { | |
7609 continue; | |
7610 } | |
7611 | |
7612 // Only put the placeholder inside the current Container, skip all | |
7613 // items form other containers. This works because when moving | |
7614 // an item from one container to another the | |
7615 // currentContainer is switched before the placeholder is moved. | |
7616 // | |
7617 // Without this moving items in "sub-sortables" can cause the placeholder to jitter | |
7618 // beetween the outer and inner container. | |
7619 if (item.instance !== this.currentContainer) { | |
7620 continue; | |
7621 } | |
7622 | |
7623 // cannot intersect with itself | |
7624 // no useless actions that have been done before | |
7625 // no action if the item moved is the parent of the item checked | |
7626 if (itemElement !== this.currentItem[0] && | |
7627 this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement && | |
7628 !$.contains(this.placeholder[0], itemElement) && | |
7629 (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true) | |
7630 ) { | |
7631 | |
7632 this.direction = intersection === 1 ? "down" : "up"; | |
7633 | |
7634 if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) { | |
7635 this._rearrange(event, item); | |
7636 } else { | |
7637 break; | |
7638 } | |
7639 | |
7640 this._trigger("change", event, this._uiHash()); | |
7641 break; | |
7642 } | |
7643 } | |
7644 | |
7645 //Post events to containers | |
7646 this._contactContainers(event); | |
7647 | |
7648 //Interconnect with droppables | |
7649 if($.ui.ddmanager) { | |
7650 $.ui.ddmanager.drag(this, event); | |
7651 } | |
7652 | |
7653 //Call callbacks | |
7654 this._trigger("sort", event, this._uiHash()); | |
7655 | |
7656 this.lastPositionAbs = this.positionAbs; | |
7657 return false; | |
7658 | |
7659 }, | |
7660 | |
7661 _mouseStop: function(event, noPropagation) { | |
7662 | |
7663 if(!event) { | |
7664 return; | |
7665 } | |
7666 | |
7667 //If we are using droppables, inform the manager about the drop | |
7668 if ($.ui.ddmanager && !this.options.dropBehaviour) { | |
7669 $.ui.ddmanager.drop(this, event); | |
7670 } | |
7671 | |
7672 if(this.options.revert) { | |
7673 var that = this, | |
7674 cur = this.placeholder.offset(), | |
7675 axis = this.options.axis, | |
7676 animation = {}; | |
7677 | |
7678 if ( !axis || axis === "x" ) { | |
7679 animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft); | |
7680 } | |
7681 if ( !axis || axis === "y" ) { | |
7682 animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop); | |
7683 } | |
7684 this.reverting = true; | |
7685 $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() { | |
7686 that._clear(event); | |
7687 }); | |
7688 } else { | |
7689 this._clear(event, noPropagation); | |
7690 } | |
7691 | |
7692 return false; | |
7693 | |
7694 }, | |
7695 | |
7696 cancel: function() { | |
7697 | |
7698 if(this.dragging) { | |
7699 | |
7700 this._mouseUp({ target: null }); | |
7701 | |
7702 if(this.options.helper === "original") { | |
7703 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); | |
7704 } else { | |
7705 this.currentItem.show(); | |
7706 } | |
7707 | |
7708 //Post deactivating events to containers | |
7709 for (var i = this.containers.length - 1; i >= 0; i--){ | |
7710 this.containers[i]._trigger("deactivate", null, this._uiHash(this)); | |
7711 if(this.containers[i].containerCache.over) { | |
7712 this.containers[i]._trigger("out", null, this._uiHash(this)); | |
7713 this.containers[i].containerCache.over = 0; | |
7714 } | |
7715 } | |
7716 | |
7717 } | |
7718 | |
7719 if (this.placeholder) { | |
7720 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! | |
7721 if(this.placeholder[0].parentNode) { | |
7722 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); | |
7723 } | |
7724 if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) { | |
7725 this.helper.remove(); | |
7726 } | |
7727 | |
7728 $.extend(this, { | |
7729 helper: null, | |
7730 dragging: false, | |
7731 reverting: false, | |
7732 _noFinalSort: null | |
7733 }); | |
7734 | |
7735 if(this.domPosition.prev) { | |
7736 $(this.domPosition.prev).after(this.currentItem); | |
7737 } else { | |
7738 $(this.domPosition.parent).prepend(this.currentItem); | |
7739 } | |
7740 } | |
7741 | |
7742 return this; | |
7743 | |
7744 }, | |
7745 | |
7746 serialize: function(o) { | |
7747 | |
7748 var items = this._getItemsAsjQuery(o && o.connected), | |
7749 str = []; | |
7750 o = o || {}; | |
7751 | |
7752 $(items).each(function() { | |
7753 var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/)); | |
7754 if (res) { | |
7755 str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2])); | |
7756 } | |
7757 }); | |
7758 | |
7759 if(!str.length && o.key) { | |
7760 str.push(o.key + "="); | |
7761 } | |
7762 | |
7763 return str.join("&"); | |
7764 | |
7765 }, | |
7766 | |
7767 toArray: function(o) { | |
7768 | |
7769 var items = this._getItemsAsjQuery(o && o.connected), | |
7770 ret = []; | |
7771 | |
7772 o = o || {}; | |
7773 | |
7774 items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); }); | |
7775 return ret; | |
7776 | |
7777 }, | |
7778 | |
7779 /* Be careful with the following core functions */ | |
7780 _intersectsWith: function(item) { | |
7781 | |
7782 var x1 = this.positionAbs.left, | |
7783 x2 = x1 + this.helperProportions.width, | |
7784 y1 = this.positionAbs.top, | |
7785 y2 = y1 + this.helperProportions.height, | |
7786 l = item.left, | |
7787 r = l + item.width, | |
7788 t = item.top, | |
7789 b = t + item.height, | |
7790 dyClick = this.offset.click.top, | |
7791 dxClick = this.offset.click.left, | |
7792 isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ), | |
7793 isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ), | |
7794 isOverElement = isOverElementHeight && isOverElementWidth; | |
7795 | |
7796 if ( this.options.tolerance === "pointer" || | |
7797 this.options.forcePointerForContainers || | |
7798 (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"]) | |
7799 ) { | |
7800 return isOverElement; | |
7801 } else { | |
7802 | |
7803 return (l < x1 + (this.helperProportions.width / 2) && // Right Half | |
7804 x2 - (this.helperProportions.width / 2) < r && // Left Half | |
7805 t < y1 + (this.helperProportions.height / 2) && // Bottom Half | |
7806 y2 - (this.helperProportions.height / 2) < b ); // Top Half | |
7807 | |
7808 } | |
7809 }, | |
7810 | |
7811 _intersectsWithPointer: function(item) { | |
7812 | |
7813 var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), | |
7814 isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), | |
7815 isOverElement = isOverElementHeight && isOverElementWidth, | |
7816 verticalDirection = this._getDragVerticalDirection(), | |
7817 horizontalDirection = this._getDragHorizontalDirection(); | |
7818 | |
7819 if (!isOverElement) { | |
7820 return false; | |
7821 } | |
7822 | |
7823 return this.floating ? | |
7824 ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 ) | |
7825 : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) ); | |
7826 | |
7827 }, | |
7828 | |
7829 _intersectsWithSides: function(item) { | |
7830 | |
7831 var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), | |
7832 isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), | |
7833 verticalDirection = this._getDragVerticalDirection(), | |
7834 horizontalDirection = this._getDragHorizontalDirection(); | |
7835 | |
7836 if (this.floating && horizontalDirection) { | |
7837 return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf)); | |
7838 } else { | |
7839 return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf)); | |
7840 } | |
7841 | |
7842 }, | |
7843 | |
7844 _getDragVerticalDirection: function() { | |
7845 var delta = this.positionAbs.top - this.lastPositionAbs.top; | |
7846 return delta !== 0 && (delta > 0 ? "down" : "up"); | |
7847 }, | |
7848 | |
7849 _getDragHorizontalDirection: function() { | |
7850 var delta = this.positionAbs.left - this.lastPositionAbs.left; | |
7851 return delta !== 0 && (delta > 0 ? "right" : "left"); | |
7852 }, | |
7853 | |
7854 refresh: function(event) { | |
7855 this._refreshItems(event); | |
7856 this.refreshPositions(); | |
7857 return this; | |
7858 }, | |
7859 | |
7860 _connectWith: function() { | |
7861 var options = this.options; | |
7862 return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith; | |
7863 }, | |
7864 | |
7865 _getItemsAsjQuery: function(connected) { | |
7866 | |
7867 var i, j, cur, inst, | |
7868 items = [], | |
7869 queries = [], | |
7870 connectWith = this._connectWith(); | |
7871 | |
7872 if(connectWith && connected) { | |
7873 for (i = connectWith.length - 1; i >= 0; i--){ | |
7874 cur = $(connectWith[i]); | |
7875 for ( j = cur.length - 1; j >= 0; j--){ | |
7876 inst = $.data(cur[j], this.widgetFullName); | |
7877 if(inst && inst !== this && !inst.options.disabled) { | |
7878 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]); | |
7879 } | |
7880 } | |
7881 } | |
7882 } | |
7883 | |
7884 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]); | |
7885 | |
7886 for (i = queries.length - 1; i >= 0; i--){ | |
7887 queries[i][0].each(function() { | |
7888 items.push(this); | |
7889 }); | |
7890 } | |
7891 | |
7892 return $(items); | |
7893 | |
7894 }, | |
7895 | |
7896 _removeCurrentsFromItems: function() { | |
7897 | |
7898 var list = this.currentItem.find(":data(" + this.widgetName + "-item)"); | |
7899 | |
7900 this.items = $.grep(this.items, function (item) { | |
7901 for (var j=0; j < list.length; j++) { | |
7902 if(list[j] === item.item[0]) { | |
7903 return false; | |
7904 } | |
7905 } | |
7906 return true; | |
7907 }); | |
7908 | |
7909 }, | |
7910 | |
7911 _refreshItems: function(event) { | |
7912 | |
7913 this.items = []; | |
7914 this.containers = [this]; | |
7915 | |
7916 var i, j, cur, inst, targetData, _queries, item, queriesLength, | |
7917 items = this.items, | |
7918 queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]], | |
7919 connectWith = this._connectWith(); | |
7920 | |
7921 if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down | |
7922 for (i = connectWith.length - 1; i >= 0; i--){ | |
7923 cur = $(connectWith[i]); | |
7924 for (j = cur.length - 1; j >= 0; j--){ | |
7925 inst = $.data(cur[j], this.widgetFullName); | |
7926 if(inst && inst !== this && !inst.options.disabled) { | |
7927 queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); | |
7928 this.containers.push(inst); | |
7929 } | |
7930 } | |
7931 } | |
7932 } | |
7933 | |
7934 for (i = queries.length - 1; i >= 0; i--) { | |
7935 targetData = queries[i][1]; | |
7936 _queries = queries[i][0]; | |
7937 | |
7938 for (j=0, queriesLength = _queries.length; j < queriesLength; j++) { | |
7939 item = $(_queries[j]); | |
7940 | |
7941 item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager) | |
7942 | |
7943 items.push({ | |
7944 item: item, | |
7945 instance: targetData, | |
7946 width: 0, height: 0, | |
7947 left: 0, top: 0 | |
7948 }); | |
7949 } | |
7950 } | |
7951 | |
7952 }, | |
7953 | |
7954 refreshPositions: function(fast) { | |
7955 | |
7956 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change | |
7957 if(this.offsetParent && this.helper) { | |
7958 this.offset.parent = this._getParentOffset(); | |
7959 } | |
7960 | |
7961 var i, item, t, p; | |
7962 | |
7963 for (i = this.items.length - 1; i >= 0; i--){ | |
7964 item = this.items[i]; | |
7965 | |
7966 //We ignore calculating positions of all connected containers when we're not over them | |
7967 if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) { | |
7968 continue; | |
7969 } | |
7970 | |
7971 t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; | |
7972 | |
7973 if (!fast) { | |
7974 item.width = t.outerWidth(); | |
7975 item.height = t.outerHeight(); | |
7976 } | |
7977 | |
7978 p = t.offset(); | |
7979 item.left = p.left; | |
7980 item.top = p.top; | |
7981 } | |
7982 | |
7983 if(this.options.custom && this.options.custom.refreshContainers) { | |
7984 this.options.custom.refreshContainers.call(this); | |
7985 } else { | |
7986 for (i = this.containers.length - 1; i >= 0; i--){ | |
7987 p = this.containers[i].element.offset(); | |
7988 this.containers[i].containerCache.left = p.left; | |
7989 this.containers[i].containerCache.top = p.top; | |
7990 this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); | |
7991 this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); | |
7992 } | |
7993 } | |
7994 | |
7995 return this; | |
7996 }, | |
7997 | |
7998 _createPlaceholder: function(that) { | |
7999 that = that || this; | |
8000 var className, | |
8001 o = that.options; | |
8002 | |
8003 if(!o.placeholder || o.placeholder.constructor === String) { | |
8004 className = o.placeholder; | |
8005 o.placeholder = { | |
8006 element: function() { | |
8007 | |
8008 var nodeName = that.currentItem[0].nodeName.toLowerCase(), | |
8009 element = $( "<" + nodeName + ">", that.document[0] ) | |
8010 .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder") | |
8011 .removeClass("ui-sortable-helper"); | |
8012 | |
8013 if ( nodeName === "tr" ) { | |
8014 that.currentItem.children().each(function() { | |
8015 $( "<td> </td>", that.document[0] ) | |
8016 .attr( "colspan", $( this ).attr( "colspan" ) || 1 ) | |
8017 .appendTo( element ); | |
8018 }); | |
8019 } else if ( nodeName === "img" ) { | |
8020 element.attr( "src", that.currentItem.attr( "src" ) ); | |
8021 } | |
8022 | |
8023 if ( !className ) { | |
8024 element.css( "visibility", "hidden" ); | |
8025 } | |
8026 | |
8027 return element; | |
8028 }, | |
8029 update: function(container, p) { | |
8030 | |
8031 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that | |
8032 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified | |
8033 if(className && !o.forcePlaceholderSize) { | |
8034 return; | |
8035 } | |
8036 | |
8037 //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 | |
8038 if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); } | |
8039 if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); } | |
8040 } | |
8041 }; | |
8042 } | |
8043 | |
8044 //Create the placeholder | |
8045 that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem)); | |
8046 | |
8047 //Append it after the actual current item | |
8048 that.currentItem.after(that.placeholder); | |
8049 | |
8050 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) | |
8051 o.placeholder.update(that, that.placeholder); | |
8052 | |
8053 }, | |
8054 | |
8055 _contactContainers: function(event) { | |
8056 var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating, | |
8057 innermostContainer = null, | |
8058 innermostIndex = null; | |
8059 | |
8060 // get innermost container that intersects with item | |
8061 for (i = this.containers.length - 1; i >= 0; i--) { | |
8062 | |
8063 // never consider a container that's located within the item itself | |
8064 if($.contains(this.currentItem[0], this.containers[i].element[0])) { | |
8065 continue; | |
8066 } | |
8067 | |
8068 if(this._intersectsWith(this.containers[i].containerCache)) { | |
8069 | |
8070 // if we've already found a container and it's more "inner" than this, then continue | |
8071 if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) { | |
8072 continue; | |
8073 } | |
8074 | |
8075 innermostContainer = this.containers[i]; | |
8076 innermostIndex = i; | |
8077 | |
8078 } else { | |
8079 // container doesn't intersect. trigger "out" event if necessary | |
8080 if(this.containers[i].containerCache.over) { | |
8081 this.containers[i]._trigger("out", event, this._uiHash(this)); | |
8082 this.containers[i].containerCache.over = 0; | |
8083 } | |
8084 } | |
8085 | |
8086 } | |
8087 | |
8088 // if no intersecting containers found, return | |
8089 if(!innermostContainer) { | |
8090 return; | |
8091 } | |
8092 | |
8093 // move the item into the container if it's not there already | |
8094 if(this.containers.length === 1) { | |
8095 if (!this.containers[innermostIndex].containerCache.over) { | |
8096 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); | |
8097 this.containers[innermostIndex].containerCache.over = 1; | |
8098 } | |
8099 } else { | |
8100 | |
8101 //When entering a new container, we will find the item with the least distance and append our item near it | |
8102 dist = 10000; | |
8103 itemWithLeastDistance = null; | |
8104 floating = innermostContainer.floating || isFloating(this.currentItem); | |
8105 posProperty = floating ? "left" : "top"; | |
8106 sizeProperty = floating ? "width" : "height"; | |
8107 base = this.positionAbs[posProperty] + this.offset.click[posProperty]; | |
8108 for (j = this.items.length - 1; j >= 0; j--) { | |
8109 if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) { | |
8110 continue; | |
8111 } | |
8112 if(this.items[j].item[0] === this.currentItem[0]) { | |
8113 continue; | |
8114 } | |
8115 if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) { | |
8116 continue; | |
8117 } | |
8118 cur = this.items[j].item.offset()[posProperty]; | |
8119 nearBottom = false; | |
8120 if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){ | |
8121 nearBottom = true; | |
8122 cur += this.items[j][sizeProperty]; | |
8123 } | |
8124 | |
8125 if(Math.abs(cur - base) < dist) { | |
8126 dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; | |
8127 this.direction = nearBottom ? "up": "down"; | |
8128 } | |
8129 } | |
8130 | |
8131 //Check if dropOnEmpty is enabled | |
8132 if(!itemWithLeastDistance && !this.options.dropOnEmpty) { | |
8133 return; | |
8134 } | |
8135 | |
8136 if(this.currentContainer === this.containers[innermostIndex]) { | |
8137 return; | |
8138 } | |
8139 | |
8140 itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); | |
8141 this._trigger("change", event, this._uiHash()); | |
8142 this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); | |
8143 this.currentContainer = this.containers[innermostIndex]; | |
8144 | |
8145 //Update the placeholder | |
8146 this.options.placeholder.update(this.currentContainer, this.placeholder); | |
8147 | |
8148 this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); | |
8149 this.containers[innermostIndex].containerCache.over = 1; | |
8150 } | |
8151 | |
8152 | |
8153 }, | |
8154 | |
8155 _createHelper: function(event) { | |
8156 | |
8157 var o = this.options, | |
8158 helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem); | |
8159 | |
8160 //Add the helper to the DOM if that didn't happen already | |
8161 if(!helper.parents("body").length) { | |
8162 $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); | |
8163 } | |
8164 | |
8165 if(helper[0] === this.currentItem[0]) { | |
8166 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") }; | |
8167 } | |
8168 | |
8169 if(!helper[0].style.width || o.forceHelperSize) { | |
8170 helper.width(this.currentItem.width()); | |
8171 } | |
8172 if(!helper[0].style.height || o.forceHelperSize) { | |
8173 helper.height(this.currentItem.height()); | |
8174 } | |
8175 | |
8176 return helper; | |
8177 | |
8178 }, | |
8179 | |
8180 _adjustOffsetFromHelper: function(obj) { | |
8181 if (typeof obj === "string") { | |
8182 obj = obj.split(" "); | |
8183 } | |
8184 if ($.isArray(obj)) { | |
8185 obj = {left: +obj[0], top: +obj[1] || 0}; | |
8186 } | |
8187 if ("left" in obj) { | |
8188 this.offset.click.left = obj.left + this.margins.left; | |
8189 } | |
8190 if ("right" in obj) { | |
8191 this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; | |
8192 } | |
8193 if ("top" in obj) { | |
8194 this.offset.click.top = obj.top + this.margins.top; | |
8195 } | |
8196 if ("bottom" in obj) { | |
8197 this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; | |
8198 } | |
8199 }, | |
8200 | |
8201 _getParentOffset: function() { | |
8202 | |
8203 | |
8204 //Get the offsetParent and cache its position | |
8205 this.offsetParent = this.helper.offsetParent(); | |
8206 var po = this.offsetParent.offset(); | |
8207 | |
8208 // This is a special case where we need to modify a offset calculated on start, since the following happened: | |
8209 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent | |
8210 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that | |
8211 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag | |
8212 if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) { | |
8213 po.left += this.scrollParent.scrollLeft(); | |
8214 po.top += this.scrollParent.scrollTop(); | |
8215 } | |
8216 | |
8217 // This needs to be actually done for all browsers, since pageX/pageY includes this information | |
8218 // with an ugly IE fix | |
8219 if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) { | |
8220 po = { top: 0, left: 0 }; | |
8221 } | |
8222 | |
8223 return { | |
8224 top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), | |
8225 left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) | |
8226 }; | |
8227 | |
8228 }, | |
8229 | |
8230 _getRelativeOffset: function() { | |
8231 | |
8232 if(this.cssPosition === "relative") { | |
8233 var p = this.currentItem.position(); | |
8234 return { | |
8235 top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), | |
8236 left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() | |
8237 }; | |
8238 } else { | |
8239 return { top: 0, left: 0 }; | |
8240 } | |
8241 | |
8242 }, | |
8243 | |
8244 _cacheMargins: function() { | |
8245 this.margins = { | |
8246 left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), | |
8247 top: (parseInt(this.currentItem.css("marginTop"),10) || 0) | |
8248 }; | |
8249 }, | |
8250 | |
8251 _cacheHelperProportions: function() { | |
8252 this.helperProportions = { | |
8253 width: this.helper.outerWidth(), | |
8254 height: this.helper.outerHeight() | |
8255 }; | |
8256 }, | |
8257 | |
8258 _setContainment: function() { | |
8259 | |
8260 var ce, co, over, | |
8261 o = this.options; | |
8262 if(o.containment === "parent") { | |
8263 o.containment = this.helper[0].parentNode; | |
8264 } | |
8265 if(o.containment === "document" || o.containment === "window") { | |
8266 this.containment = [ | |
8267 0 - this.offset.relative.left - this.offset.parent.left, | |
8268 0 - this.offset.relative.top - this.offset.parent.top, | |
8269 $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left, | |
8270 ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top | |
8271 ]; | |
8272 } | |
8273 | |
8274 if(!(/^(document|window|parent)$/).test(o.containment)) { | |
8275 ce = $(o.containment)[0]; | |
8276 co = $(o.containment).offset(); | |
8277 over = ($(ce).css("overflow") !== "hidden"); | |
8278 | |
8279 this.containment = [ | |
8280 co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, | |
8281 co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, | |
8282 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, | |
8283 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 | |
8284 ]; | |
8285 } | |
8286 | |
8287 }, | |
8288 | |
8289 _convertPositionTo: function(d, pos) { | |
8290 | |
8291 if(!pos) { | |
8292 pos = this.position; | |
8293 } | |
8294 var mod = d === "absolute" ? 1 : -1, | |
8295 scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, | |
8296 scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); | |
8297 | |
8298 return { | |
8299 top: ( | |
8300 pos.top + // The absolute mouse position | |
8301 this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
8302 this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border) | |
8303 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) | |
8304 ), | |
8305 left: ( | |
8306 pos.left + // The absolute mouse position | |
8307 this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent | |
8308 this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border) | |
8309 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) | |
8310 ) | |
8311 }; | |
8312 | |
8313 }, | |
8314 | |
8315 _generatePosition: function(event) { | |
8316 | |
8317 var top, left, | |
8318 o = this.options, | |
8319 pageX = event.pageX, | |
8320 pageY = event.pageY, | |
8321 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); | |
8322 | |
8323 // This is another very weird special case that only happens for relative elements: | |
8324 // 1. If the css position is relative | |
8325 // 2. and the scroll parent is the document or similar to the offset parent | |
8326 // we have to refresh the relative offset during the scroll so there are no jumps | |
8327 if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) { | |
8328 this.offset.relative = this._getRelativeOffset(); | |
8329 } | |
8330 | |
8331 /* | |
8332 * - Position constraining - | |
8333 * Constrain the position to a mix of grid, containment. | |
8334 */ | |
8335 | |
8336 if(this.originalPosition) { //If we are not dragging yet, we won't check for options | |
8337 | |
8338 if(this.containment) { | |
8339 if(event.pageX - this.offset.click.left < this.containment[0]) { | |
8340 pageX = this.containment[0] + this.offset.click.left; | |
8341 } | |
8342 if(event.pageY - this.offset.click.top < this.containment[1]) { | |
8343 pageY = this.containment[1] + this.offset.click.top; | |
8344 } | |
8345 if(event.pageX - this.offset.click.left > this.containment[2]) { | |
8346 pageX = this.containment[2] + this.offset.click.left; | |
8347 } | |
8348 if(event.pageY - this.offset.click.top > this.containment[3]) { | |
8349 pageY = this.containment[3] + this.offset.click.top; | |
8350 } | |
8351 } | |
8352 | |
8353 if(o.grid) { | |
8354 top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; | |
8355 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; | |
8356 | |
8357 left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; | |
8358 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; | |
8359 } | |
8360 | |
8361 } | |
8362 | |
8363 return { | |
8364 top: ( | |
8365 pageY - // The absolute mouse position | |
8366 this.offset.click.top - // Click offset (relative to the element) | |
8367 this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent | |
8368 this.offset.parent.top + // The offsetParent's offset without borders (offset + border) | |
8369 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) | |
8370 ), | |
8371 left: ( | |
8372 pageX - // The absolute mouse position | |
8373 this.offset.click.left - // Click offset (relative to the element) | |
8374 this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent | |
8375 this.offset.parent.left + // The offsetParent's offset without borders (offset + border) | |
8376 ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) | |
8377 ) | |
8378 }; | |
8379 | |
8380 }, | |
8381 | |
8382 _rearrange: function(event, i, a, hardRefresh) { | |
8383 | |
8384 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)); | |
8385 | |
8386 //Various things done here to improve the performance: | |
8387 // 1. we create a setTimeout, that calls refreshPositions | |
8388 // 2. on the instance, we have a counter variable, that get's higher after every append | |
8389 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same | |
8390 // 4. this lets only the last addition to the timeout stack through | |
8391 this.counter = this.counter ? ++this.counter : 1; | |
8392 var counter = this.counter; | |
8393 | |
8394 this._delay(function() { | |
8395 if(counter === this.counter) { | |
8396 this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove | |
8397 } | |
8398 }); | |
8399 | |
8400 }, | |
8401 | |
8402 _clear: function(event, noPropagation) { | |
8403 | |
8404 this.reverting = false; | |
8405 // We delay all events that have to be triggered to after the point where the placeholder has been removed and | |
8406 // everything else normalized again | |
8407 var i, | |
8408 delayedTriggers = []; | |
8409 | |
8410 // We first have to update the dom position of the actual currentItem | |
8411 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) | |
8412 if(!this._noFinalSort && this.currentItem.parent().length) { | |
8413 this.placeholder.before(this.currentItem); | |
8414 } | |
8415 this._noFinalSort = null; | |
8416 | |
8417 if(this.helper[0] === this.currentItem[0]) { | |
8418 for(i in this._storedCSS) { | |
8419 if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") { | |
8420 this._storedCSS[i] = ""; | |
8421 } | |
8422 } | |
8423 this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); | |
8424 } else { | |
8425 this.currentItem.show(); | |
8426 } | |
8427 | |
8428 if(this.fromOutside && !noPropagation) { | |
8429 delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); | |
8430 } | |
8431 if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) { | |
8432 delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed | |
8433 } | |
8434 | |
8435 // Check if the items Container has Changed and trigger appropriate | |
8436 // events. | |
8437 if (this !== this.currentContainer) { | |
8438 if(!noPropagation) { | |
8439 delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); | |
8440 delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); | |
8441 delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer)); | |
8442 } | |
8443 } | |
8444 | |
8445 | |
8446 //Post events to containers | |
8447 for (i = this.containers.length - 1; i >= 0; i--){ | |
8448 if(!noPropagation) { | |
8449 delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); | |
8450 } | |
8451 if(this.containers[i].containerCache.over) { | |
8452 delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); | |
8453 this.containers[i].containerCache.over = 0; | |
8454 } | |
8455 } | |
8456 | |
8457 //Do what was originally in plugins | |
8458 if ( this.storedCursor ) { | |
8459 this.document.find( "body" ).css( "cursor", this.storedCursor ); | |
8460 this.storedStylesheet.remove(); | |
8461 } | |
8462 if(this._storedOpacity) { | |
8463 this.helper.css("opacity", this._storedOpacity); | |
8464 } | |
8465 if(this._storedZIndex) { | |
8466 this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex); | |
8467 } | |
8468 | |
8469 this.dragging = false; | |
8470 if(this.cancelHelperRemoval) { | |
8471 if(!noPropagation) { | |
8472 this._trigger("beforeStop", event, this._uiHash()); | |
8473 for (i=0; i < delayedTriggers.length; i++) { | |
8474 delayedTriggers[i].call(this, event); | |
8475 } //Trigger all delayed events | |
8476 this._trigger("stop", event, this._uiHash()); | |
8477 } | |
8478 | |
8479 this.fromOutside = false; | |
8480 return false; | |
8481 } | |
8482 | |
8483 if(!noPropagation) { | |
8484 this._trigger("beforeStop", event, this._uiHash()); | |
8485 } | |
8486 | |
8487 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! | |
8488 this.placeholder[0].parentNode.removeChild(this.placeholder[0]); | |
8489 | |
8490 if(this.helper[0] !== this.currentItem[0]) { | |
8491 this.helper.remove(); | |
8492 } | |
8493 this.helper = null; | |
8494 | |
8495 if(!noPropagation) { | |
8496 for (i=0; i < delayedTriggers.length; i++) { | |
8497 delayedTriggers[i].call(this, event); | |
8498 } //Trigger all delayed events | |
8499 this._trigger("stop", event, this._uiHash()); | |
8500 } | |
8501 | |
8502 this.fromOutside = false; | |
8503 return true; | |
8504 | |
8505 }, | |
8506 | |
8507 _trigger: function() { | |
8508 if ($.Widget.prototype._trigger.apply(this, arguments) === false) { | |
8509 this.cancel(); | |
8510 } | |
8511 }, | |
8512 | |
8513 _uiHash: function(_inst) { | |
8514 var inst = _inst || this; | |
8515 return { | |
8516 helper: inst.helper, | |
8517 placeholder: inst.placeholder || $([]), | |
8518 position: inst.position, | |
8519 originalPosition: inst.originalPosition, | |
8520 offset: inst.positionAbs, | |
8521 item: inst.currentItem, | |
8522 sender: _inst ? _inst.element : null | |
8523 }; | |
8524 } | |
8525 | |
8526 }); | |
8527 | |
8528 })(jQuery); | |
8529 (function( $, undefined ) { | |
8530 | |
8531 var uid = 0, | |
8532 hideProps = {}, | |
8533 showProps = {}; | |
8534 | |
8535 hideProps.height = hideProps.paddingTop = hideProps.paddingBottom = | |
8536 hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide"; | |
8537 showProps.height = showProps.paddingTop = showProps.paddingBottom = | |
8538 showProps.borderTopWidth = showProps.borderBottomWidth = "show"; | |
8539 | |
8540 $.widget( "ui.accordion", { | |
8541 version: "1.10.3", | |
8542 options: { | |
8543 active: 0, | |
8544 animate: {}, | |
8545 collapsible: false, | |
8546 event: "click", | |
8547 header: "> li > :first-child,> :not(li):even", | |
8548 heightStyle: "auto", | |
8549 icons: { | |
8550 activeHeader: "ui-icon-triangle-1-s", | |
8551 header: "ui-icon-triangle-1-e" | |
8552 }, | |
8553 | |
8554 // callbacks | |
8555 activate: null, | |
8556 beforeActivate: null | |
8557 }, | |
8558 | |
8559 _create: function() { | |
8560 var options = this.options; | |
8561 this.prevShow = this.prevHide = $(); | |
8562 this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) | |
8563 // ARIA | |
8564 .attr( "role", "tablist" ); | |
8565 | |
8566 // don't allow collapsible: false and active: false / null | |
8567 if ( !options.collapsible && (options.active === false || options.active == null) ) { | |
8568 options.active = 0; | |
8569 } | |
8570 | |
8571 this._processPanels(); | |
8572 // handle negative values | |
8573 if ( options.active < 0 ) { | |
8574 options.active += this.headers.length; | |
8575 } | |
8576 this._refresh(); | |
8577 }, | |
8578 | |
8579 _getCreateEventData: function() { | |
8580 return { | |
8581 header: this.active, | |
8582 panel: !this.active.length ? $() : this.active.next(), | |
8583 content: !this.active.length ? $() : this.active.next() | |
8584 }; | |
8585 }, | |
8586 | |
8587 _createIcons: function() { | |
8588 var icons = this.options.icons; | |
8589 if ( icons ) { | |
8590 $( "<span>" ) | |
8591 .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) | |
8592 .prependTo( this.headers ); | |
8593 this.active.children( ".ui-accordion-header-icon" ) | |
8594 .removeClass( icons.header ) | |
8595 .addClass( icons.activeHeader ); | |
8596 this.headers.addClass( "ui-accordion-icons" ); | |
8597 } | |
8598 }, | |
8599 | |
8600 _destroyIcons: function() { | |
8601 this.headers | |
8602 .removeClass( "ui-accordion-icons" ) | |
8603 .children( ".ui-accordion-header-icon" ) | |
8604 .remove(); | |
8605 }, | |
8606 | |
8607 _destroy: function() { | |
8608 var contents; | |
8609 | |
8610 // clean up main element | |
8611 this.element | |
8612 .removeClass( "ui-accordion ui-widget ui-helper-reset" ) | |
8613 .removeAttr( "role" ); | |
8614 | |
8615 // clean up headers | |
8616 this.headers | |
8617 .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" ) | |
8618 .removeAttr( "role" ) | |
8619 .removeAttr( "aria-selected" ) | |
8620 .removeAttr( "aria-controls" ) | |
8621 .removeAttr( "tabIndex" ) | |
8622 .each(function() { | |
8623 if ( /^ui-accordion/.test( this.id ) ) { | |
8624 this.removeAttribute( "id" ); | |
8625 } | |
8626 }); | |
8627 this._destroyIcons(); | |
8628 | |
8629 // clean up content panels | |
8630 contents = this.headers.next() | |
8631 .css( "display", "" ) | |
8632 .removeAttr( "role" ) | |
8633 .removeAttr( "aria-expanded" ) | |
8634 .removeAttr( "aria-hidden" ) | |
8635 .removeAttr( "aria-labelledby" ) | |
8636 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" ) | |
8637 .each(function() { | |
8638 if ( /^ui-accordion/.test( this.id ) ) { | |
8639 this.removeAttribute( "id" ); | |
8640 } | |
8641 }); | |
8642 if ( this.options.heightStyle !== "content" ) { | |
8643 contents.css( "height", "" ); | |
8644 } | |
8645 }, | |
8646 | |
8647 _setOption: function( key, value ) { | |
8648 if ( key === "active" ) { | |
8649 // _activate() will handle invalid values and update this.options | |
8650 this._activate( value ); | |
8651 return; | |
8652 } | |
8653 | |
8654 if ( key === "event" ) { | |
8655 if ( this.options.event ) { | |
8656 this._off( this.headers, this.options.event ); | |
8657 } | |
8658 this._setupEvents( value ); | |
8659 } | |
8660 | |
8661 this._super( key, value ); | |
8662 | |
8663 // setting collapsible: false while collapsed; open first panel | |
8664 if ( key === "collapsible" && !value && this.options.active === false ) { | |
8665 this._activate( 0 ); | |
8666 } | |
8667 | |
8668 if ( key === "icons" ) { | |
8669 this._destroyIcons(); | |
8670 if ( value ) { | |
8671 this._createIcons(); | |
8672 } | |
8673 } | |
8674 | |
8675 // #5332 - opacity doesn't cascade to positioned elements in IE | |
8676 // so we need to add the disabled class to the headers and panels | |
8677 if ( key === "disabled" ) { | |
8678 this.headers.add( this.headers.next() ) | |
8679 .toggleClass( "ui-state-disabled", !!value ); | |
8680 } | |
8681 }, | |
8682 | |
8683 _keydown: function( event ) { | |
8684 /*jshint maxcomplexity:15*/ | |
8685 if ( event.altKey || event.ctrlKey ) { | |
8686 return; | |
8687 } | |
8688 | |
8689 var keyCode = $.ui.keyCode, | |
8690 length = this.headers.length, | |
8691 currentIndex = this.headers.index( event.target ), | |
8692 toFocus = false; | |
8693 | |
8694 switch ( event.keyCode ) { | |
8695 case keyCode.RIGHT: | |
8696 case keyCode.DOWN: | |
8697 toFocus = this.headers[ ( currentIndex + 1 ) % length ]; | |
8698 break; | |
8699 case keyCode.LEFT: | |
8700 case keyCode.UP: | |
8701 toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; | |
8702 break; | |
8703 case keyCode.SPACE: | |
8704 case keyCode.ENTER: | |
8705 this._eventHandler( event ); | |
8706 break; | |
8707 case keyCode.HOME: | |
8708 toFocus = this.headers[ 0 ]; | |
8709 break; | |
8710 case keyCode.END: | |
8711 toFocus = this.headers[ length - 1 ]; | |
8712 break; | |
8713 } | |
8714 | |
8715 if ( toFocus ) { | |
8716 $( event.target ).attr( "tabIndex", -1 ); | |
8717 $( toFocus ).attr( "tabIndex", 0 ); | |
8718 toFocus.focus(); | |
8719 event.preventDefault(); | |
8720 } | |
8721 }, | |
8722 | |
8723 _panelKeyDown : function( event ) { | |
8724 if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { | |
8725 $( event.currentTarget ).prev().focus(); | |
8726 } | |
8727 }, | |
8728 | |
8729 refresh: function() { | |
8730 var options = this.options; | |
8731 this._processPanels(); | |
8732 | |
8733 // was collapsed or no panel | |
8734 if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { | |
8735 options.active = false; | |
8736 this.active = $(); | |
8737 // active false only when collapsible is true | |
8738 } else if ( options.active === false ) { | |
8739 this._activate( 0 ); | |
8740 // was active, but active panel is gone | |
8741 } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { | |
8742 // all remaining panel are disabled | |
8743 if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { | |
8744 options.active = false; | |
8745 this.active = $(); | |
8746 // activate previous panel | |
8747 } else { | |
8748 this._activate( Math.max( 0, options.active - 1 ) ); | |
8749 } | |
8750 // was active, active panel still exists | |
8751 } else { | |
8752 // make sure active index is correct | |
8753 options.active = this.headers.index( this.active ); | |
8754 } | |
8755 | |
8756 this._destroyIcons(); | |
8757 | |
8758 this._refresh(); | |
8759 }, | |
8760 | |
8761 _processPanels: function() { | |
8762 this.headers = this.element.find( this.options.header ) | |
8763 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ); | |
8764 | |
8765 this.headers.next() | |
8766 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) | |
8767 .filter(":not(.ui-accordion-content-active)") | |
8768 .hide(); | |
8769 }, | |
8770 | |
8771 _refresh: function() { | |
8772 var maxHeight, | |
8773 options = this.options, | |
8774 heightStyle = options.heightStyle, | |
8775 parent = this.element.parent(), | |
8776 accordionId = this.accordionId = "ui-accordion-" + | |
8777 (this.element.attr( "id" ) || ++uid); | |
8778 | |
8779 this.active = this._findActive( options.active ) | |
8780 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) | |
8781 .removeClass( "ui-corner-all" ); | |
8782 this.active.next() | |
8783 .addClass( "ui-accordion-content-active" ) | |
8784 .show(); | |
8785 | |
8786 this.headers | |
8787 .attr( "role", "tab" ) | |
8788 .each(function( i ) { | |
8789 var header = $( this ), | |
8790 headerId = header.attr( "id" ), | |
8791 panel = header.next(), | |
8792 panelId = panel.attr( "id" ); | |
8793 if ( !headerId ) { | |
8794 headerId = accordionId + "-header-" + i; | |
8795 header.attr( "id", headerId ); | |
8796 } | |
8797 if ( !panelId ) { | |
8798 panelId = accordionId + "-panel-" + i; | |
8799 panel.attr( "id", panelId ); | |
8800 } | |
8801 header.attr( "aria-controls", panelId ); | |
8802 panel.attr( "aria-labelledby", headerId ); | |
8803 }) | |
8804 .next() | |
8805 .attr( "role", "tabpanel" ); | |
8806 | |
8807 this.headers | |
8808 .not( this.active ) | |
8809 .attr({ | |
8810 "aria-selected": "false", | |
8811 tabIndex: -1 | |
8812 }) | |
8813 .next() | |
8814 .attr({ | |
8815 "aria-expanded": "false", | |
8816 "aria-hidden": "true" | |
8817 }) | |
8818 .hide(); | |
8819 | |
8820 // make sure at least one header is in the tab order | |
8821 if ( !this.active.length ) { | |
8822 this.headers.eq( 0 ).attr( "tabIndex", 0 ); | |
8823 } else { | |
8824 this.active.attr({ | |
8825 "aria-selected": "true", | |
8826 tabIndex: 0 | |
8827 }) | |
8828 .next() | |
8829 .attr({ | |
8830 "aria-expanded": "true", | |
8831 "aria-hidden": "false" | |
8832 }); | |
8833 } | |
8834 | |
8835 this._createIcons(); | |
8836 | |
8837 this._setupEvents( options.event ); | |
8838 | |
8839 if ( heightStyle === "fill" ) { | |
8840 maxHeight = parent.height(); | |
8841 this.element.siblings( ":visible" ).each(function() { | |
8842 var elem = $( this ), | |
8843 position = elem.css( "position" ); | |
8844 | |
8845 if ( position === "absolute" || position === "fixed" ) { | |
8846 return; | |
8847 } | |
8848 maxHeight -= elem.outerHeight( true ); | |
8849 }); | |
8850 | |
8851 this.headers.each(function() { | |
8852 maxHeight -= $( this ).outerHeight( true ); | |
8853 }); | |
8854 | |
8855 this.headers.next() | |
8856 .each(function() { | |
8857 $( this ).height( Math.max( 0, maxHeight - | |
8858 $( this ).innerHeight() + $( this ).height() ) ); | |
8859 }) | |
8860 .css( "overflow", "auto" ); | |
8861 } else if ( heightStyle === "auto" ) { | |
8862 maxHeight = 0; | |
8863 this.headers.next() | |
8864 .each(function() { | |
8865 maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); | |
8866 }) | |
8867 .height( maxHeight ); | |
8868 } | |
8869 }, | |
8870 | |
8871 _activate: function( index ) { | |
8872 var active = this._findActive( index )[ 0 ]; | |
8873 | |
8874 // trying to activate the already active panel | |
8875 if ( active === this.active[ 0 ] ) { | |
8876 return; | |
8877 } | |
8878 | |
8879 // trying to collapse, simulate a click on the currently active header | |
8880 active = active || this.active[ 0 ]; | |
8881 | |
8882 this._eventHandler({ | |
8883 target: active, | |
8884 currentTarget: active, | |
8885 preventDefault: $.noop | |
8886 }); | |
8887 }, | |
8888 | |
8889 _findActive: function( selector ) { | |
8890 return typeof selector === "number" ? this.headers.eq( selector ) : $(); | |
8891 }, | |
8892 | |
8893 _setupEvents: function( event ) { | |
8894 var events = { | |
8895 keydown: "_keydown" | |
8896 }; | |
8897 if ( event ) { | |
8898 $.each( event.split(" "), function( index, eventName ) { | |
8899 events[ eventName ] = "_eventHandler"; | |
8900 }); | |
8901 } | |
8902 | |
8903 this._off( this.headers.add( this.headers.next() ) ); | |
8904 this._on( this.headers, events ); | |
8905 this._on( this.headers.next(), { keydown: "_panelKeyDown" }); | |
8906 this._hoverable( this.headers ); | |
8907 this._focusable( this.headers ); | |
8908 }, | |
8909 | |
8910 _eventHandler: function( event ) { | |
8911 var options = this.options, | |
8912 active = this.active, | |
8913 clicked = $( event.currentTarget ), | |
8914 clickedIsActive = clicked[ 0 ] === active[ 0 ], | |
8915 collapsing = clickedIsActive && options.collapsible, | |
8916 toShow = collapsing ? $() : clicked.next(), | |
8917 toHide = active.next(), | |
8918 eventData = { | |
8919 oldHeader: active, | |
8920 oldPanel: toHide, | |
8921 newHeader: collapsing ? $() : clicked, | |
8922 newPanel: toShow | |
8923 }; | |
8924 | |
8925 event.preventDefault(); | |
8926 | |
8927 if ( | |
8928 // click on active header, but not collapsible | |
8929 ( clickedIsActive && !options.collapsible ) || | |
8930 // allow canceling activation | |
8931 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { | |
8932 return; | |
8933 } | |
8934 | |
8935 options.active = collapsing ? false : this.headers.index( clicked ); | |
8936 | |
8937 // when the call to ._toggle() comes after the class changes | |
8938 // it causes a very odd bug in IE 8 (see #6720) | |
8939 this.active = clickedIsActive ? $() : clicked; | |
8940 this._toggle( eventData ); | |
8941 | |
8942 // switch classes | |
8943 // corner classes on the previously active header stay after the animation | |
8944 active.removeClass( "ui-accordion-header-active ui-state-active" ); | |
8945 if ( options.icons ) { | |
8946 active.children( ".ui-accordion-header-icon" ) | |
8947 .removeClass( options.icons.activeHeader ) | |
8948 .addClass( options.icons.header ); | |
8949 } | |
8950 | |
8951 if ( !clickedIsActive ) { | |
8952 clicked | |
8953 .removeClass( "ui-corner-all" ) | |
8954 .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); | |
8955 if ( options.icons ) { | |
8956 clicked.children( ".ui-accordion-header-icon" ) | |
8957 .removeClass( options.icons.header ) | |
8958 .addClass( options.icons.activeHeader ); | |
8959 } | |
8960 | |
8961 clicked | |
8962 .next() | |
8963 .addClass( "ui-accordion-content-active" ); | |
8964 } | |
8965 }, | |
8966 | |
8967 _toggle: function( data ) { | |
8968 var toShow = data.newPanel, | |
8969 toHide = this.prevShow.length ? this.prevShow : data.oldPanel; | |
8970 | |
8971 // handle activating a panel during the animation for another activation | |
8972 this.prevShow.add( this.prevHide ).stop( true, true ); | |
8973 this.prevShow = toShow; | |
8974 this.prevHide = toHide; | |
8975 | |
8976 if ( this.options.animate ) { | |
8977 this._animate( toShow, toHide, data ); | |
8978 } else { | |
8979 toHide.hide(); | |
8980 toShow.show(); | |
8981 this._toggleComplete( data ); | |
8982 } | |
8983 | |
8984 toHide.attr({ | |
8985 "aria-expanded": "false", | |
8986 "aria-hidden": "true" | |
8987 }); | |
8988 toHide.prev().attr( "aria-selected", "false" ); | |
8989 // if we're switching panels, remove the old header from the tab order | |
8990 // if we're opening from collapsed state, remove the previous header from the tab order | |
8991 // if we're collapsing, then keep the collapsing header in the tab order | |
8992 if ( toShow.length && toHide.length ) { | |
8993 toHide.prev().attr( "tabIndex", -1 ); | |
8994 } else if ( toShow.length ) { | |
8995 this.headers.filter(function() { | |
8996 return $( this ).attr( "tabIndex" ) === 0; | |
8997 }) | |
8998 .attr( "tabIndex", -1 ); | |
8999 } | |
9000 | |
9001 toShow | |
9002 .attr({ | |
9003 "aria-expanded": "true", | |
9004 "aria-hidden": "false" | |
9005 }) | |
9006 .prev() | |
9007 .attr({ | |
9008 "aria-selected": "true", | |
9009 tabIndex: 0 | |
9010 }); | |
9011 }, | |
9012 | |
9013 _animate: function( toShow, toHide, data ) { | |
9014 var total, easing, duration, | |
9015 that = this, | |
9016 adjust = 0, | |
9017 down = toShow.length && | |
9018 ( !toHide.length || ( toShow.index() < toHide.index() ) ), | |
9019 animate = this.options.animate || {}, | |
9020 options = down && animate.down || animate, | |
9021 complete = function() { | |
9022 that._toggleComplete( data ); | |
9023 }; | |
9024 | |
9025 if ( typeof options === "number" ) { | |
9026 duration = options; | |
9027 } | |
9028 if ( typeof options === "string" ) { | |
9029 easing = options; | |
9030 } | |
9031 // fall back from options to animation in case of partial down settings | |
9032 easing = easing || options.easing || animate.easing; | |
9033 duration = duration || options.duration || animate.duration; | |
9034 | |
9035 if ( !toHide.length ) { | |
9036 return toShow.animate( showProps, duration, easing, complete ); | |
9037 } | |
9038 if ( !toShow.length ) { | |
9039 return toHide.animate( hideProps, duration, easing, complete ); | |
9040 } | |
9041 | |
9042 total = toShow.show().outerHeight(); | |
9043 toHide.animate( hideProps, { | |
9044 duration: duration, | |
9045 easing: easing, | |
9046 step: function( now, fx ) { | |
9047 fx.now = Math.round( now ); | |
9048 } | |
9049 }); | |
9050 toShow | |
9051 .hide() | |
9052 .animate( showProps, { | |
9053 duration: duration, | |
9054 easing: easing, | |
9055 complete: complete, | |
9056 step: function( now, fx ) { | |
9057 fx.now = Math.round( now ); | |
9058 if ( fx.prop !== "height" ) { | |
9059 adjust += fx.now; | |
9060 } else if ( that.options.heightStyle !== "content" ) { | |
9061 fx.now = Math.round( total - toHide.outerHeight() - adjust ); | |
9062 adjust = 0; | |
9063 } | |
9064 } | |
9065 }); | |
9066 }, | |
9067 | |
9068 _toggleComplete: function( data ) { | |
9069 var toHide = data.oldPanel; | |
9070 | |
9071 toHide | |
9072 .removeClass( "ui-accordion-content-active" ) | |
9073 .prev() | |
9074 .removeClass( "ui-corner-top" ) | |
9075 .addClass( "ui-corner-all" ); | |
9076 | |
9077 // Work around for rendering bug in IE (#5421) | |
9078 if ( toHide.length ) { | |
9079 toHide.parent()[0].className = toHide.parent()[0].className; | |
9080 } | |
9081 | |
9082 this._trigger( "activate", null, data ); | |
9083 } | |
9084 }); | |
9085 | |
9086 })( jQuery ); | |
9087 (function( $, undefined ) { | |
9088 | |
9089 // used to prevent race conditions with remote data sources | |
9090 var requestIndex = 0; | |
9091 | |
9092 $.widget( "ui.autocomplete", { | |
9093 version: "1.10.3", | |
9094 defaultElement: "<input>", | |
9095 options: { | |
9096 appendTo: null, | |
9097 autoFocus: false, | |
9098 delay: 300, | |
9099 minLength: 1, | |
9100 position: { | |
9101 my: "left top", | |
9102 at: "left bottom", | |
9103 collision: "none" | |
9104 }, | |
9105 source: null, | |
9106 | |
9107 // callbacks | |
9108 change: null, | |
9109 close: null, | |
9110 focus: null, | |
9111 open: null, | |
9112 response: null, | |
9113 search: null, | |
9114 select: null | |
9115 }, | |
9116 | |
9117 pending: 0, | |
9118 | |
9119 _create: function() { | |
9120 // Some browsers only repeat keydown events, not keypress events, | |
9121 // so we use the suppressKeyPress flag to determine if we've already | |
9122 // handled the keydown event. #7269 | |
9123 // Unfortunately the code for & in keypress is the same as the up arrow, | |
9124 // so we use the suppressKeyPressRepeat flag to avoid handling keypress | |
9125 // events when we know the keydown event was used to modify the | |
9126 // search term. #7799 | |
9127 var suppressKeyPress, suppressKeyPressRepeat, suppressInput, | |
9128 nodeName = this.element[0].nodeName.toLowerCase(), | |
9129 isTextarea = nodeName === "textarea", | |
9130 isInput = nodeName === "input"; | |
9131 | |
9132 this.isMultiLine = | |
9133 // Textareas are always multi-line | |
9134 isTextarea ? true : | |
9135 // Inputs are always single-line, even if inside a contentEditable element | |
9136 // IE also treats inputs as contentEditable | |
9137 isInput ? false : | |
9138 // All other element types are determined by whether or not they're contentEditable | |
9139 this.element.prop( "isContentEditable" ); | |
9140 | |
9141 this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ]; | |
9142 this.isNewMenu = true; | |
9143 | |
9144 this.element | |
9145 .addClass( "ui-autocomplete-input" ) | |
9146 .attr( "autocomplete", "off" ); | |
9147 | |
9148 this._on( this.element, { | |
9149 keydown: function( event ) { | |
9150 /*jshint maxcomplexity:15*/ | |
9151 if ( this.element.prop( "readOnly" ) ) { | |
9152 suppressKeyPress = true; | |
9153 suppressInput = true; | |
9154 suppressKeyPressRepeat = true; | |
9155 return; | |
9156 } | |
9157 | |
9158 suppressKeyPress = false; | |
9159 suppressInput = false; | |
9160 suppressKeyPressRepeat = false; | |
9161 var keyCode = $.ui.keyCode; | |
9162 switch( event.keyCode ) { | |
9163 case keyCode.PAGE_UP: | |
9164 suppressKeyPress = true; | |
9165 this._move( "previousPage", event ); | |
9166 break; | |
9167 case keyCode.PAGE_DOWN: | |
9168 suppressKeyPress = true; | |
9169 this._move( "nextPage", event ); | |
9170 break; | |
9171 case keyCode.UP: | |
9172 suppressKeyPress = true; | |
9173 this._keyEvent( "previous", event ); | |
9174 break; | |
9175 case keyCode.DOWN: | |
9176 suppressKeyPress = true; | |
9177 this._keyEvent( "next", event ); | |
9178 break; | |
9179 case keyCode.ENTER: | |
9180 case keyCode.NUMPAD_ENTER: | |
9181 // when menu is open and has focus | |
9182 if ( this.menu.active ) { | |
9183 // #6055 - Opera still allows the keypress to occur | |
9184 // which causes forms to submit | |
9185 suppressKeyPress = true; | |
9186 event.preventDefault(); | |
9187 this.menu.select( event ); | |
9188 } | |
9189 break; | |
9190 case keyCode.TAB: | |
9191 if ( this.menu.active ) { | |
9192 this.menu.select( event ); | |
9193 } | |
9194 break; | |
9195 case keyCode.ESCAPE: | |
9196 if ( this.menu.element.is( ":visible" ) ) { | |
9197 this._value( this.term ); | |
9198 this.close( event ); | |
9199 // Different browsers have different default behavior for escape | |
9200 // Single press can mean undo or clear | |
9201 // Double press in IE means clear the whole form | |
9202 event.preventDefault(); | |
9203 } | |
9204 break; | |
9205 default: | |
9206 suppressKeyPressRepeat = true; | |
9207 // search timeout should be triggered before the input value is changed | |
9208 this._searchTimeout( event ); | |
9209 break; | |
9210 } | |
9211 }, | |
9212 keypress: function( event ) { | |
9213 if ( suppressKeyPress ) { | |
9214 suppressKeyPress = false; | |
9215 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { | |
9216 event.preventDefault(); | |
9217 } | |
9218 return; | |
9219 } | |
9220 if ( suppressKeyPressRepeat ) { | |
9221 return; | |
9222 } | |
9223 | |
9224 // replicate some key handlers to allow them to repeat in Firefox and Opera | |
9225 var keyCode = $.ui.keyCode; | |
9226 switch( event.keyCode ) { | |
9227 case keyCode.PAGE_UP: | |
9228 this._move( "previousPage", event ); | |
9229 break; | |
9230 case keyCode.PAGE_DOWN: | |
9231 this._move( "nextPage", event ); | |
9232 break; | |
9233 case keyCode.UP: | |
9234 this._keyEvent( "previous", event ); | |
9235 break; | |
9236 case keyCode.DOWN: | |
9237 this._keyEvent( "next", event ); | |
9238 break; | |
9239 } | |
9240 }, | |
9241 input: function( event ) { | |
9242 if ( suppressInput ) { | |
9243 suppressInput = false; | |
9244 event.preventDefault(); | |
9245 return; | |
9246 } | |
9247 this._searchTimeout( event ); | |
9248 }, | |
9249 focus: function() { | |
9250 this.selectedItem = null; | |
9251 this.previous = this._value(); | |
9252 }, | |
9253 blur: function( event ) { | |
9254 if ( this.cancelBlur ) { | |
9255 delete this.cancelBlur; | |
9256 return; | |
9257 } | |
9258 | |
9259 clearTimeout( this.searching ); | |
9260 this.close( event ); | |
9261 this._change( event ); | |
9262 } | |
9263 }); | |
9264 | |
9265 this._initSource(); | |
9266 this.menu = $( "<ul>" ) | |
9267 .addClass( "ui-autocomplete ui-front" ) | |
9268 .appendTo( this._appendTo() ) | |
9269 .menu({ | |
9270 // disable ARIA support, the live region takes care of that | |
9271 role: null | |
9272 }) | |
9273 .hide() | |
9274 .data( "ui-menu" ); | |
9275 | |
9276 this._on( this.menu.element, { | |
9277 mousedown: function( event ) { | |
9278 // prevent moving focus out of the text field | |
9279 event.preventDefault(); | |
9280 | |
9281 // IE doesn't prevent moving focus even with event.preventDefault() | |
9282 // so we set a flag to know when we should ignore the blur event | |
9283 this.cancelBlur = true; | |
9284 this._delay(function() { | |
9285 delete this.cancelBlur; | |
9286 }); | |
9287 | |
9288 // clicking on the scrollbar causes focus to shift to the body | |
9289 // but we can't detect a mouseup or a click immediately afterward | |
9290 // so we have to track the next mousedown and close the menu if | |
9291 // the user clicks somewhere outside of the autocomplete | |
9292 var menuElement = this.menu.element[ 0 ]; | |
9293 if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { | |
9294 this._delay(function() { | |
9295 var that = this; | |
9296 this.document.one( "mousedown", function( event ) { | |
9297 if ( event.target !== that.element[ 0 ] && | |
9298 event.target !== menuElement && | |
9299 !$.contains( menuElement, event.target ) ) { | |
9300 that.close(); | |
9301 } | |
9302 }); | |
9303 }); | |
9304 } | |
9305 }, | |
9306 menufocus: function( event, ui ) { | |
9307 // support: Firefox | |
9308 // Prevent accidental activation of menu items in Firefox (#7024 #9118) | |
9309 if ( this.isNewMenu ) { | |
9310 this.isNewMenu = false; | |
9311 if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) { | |
9312 this.menu.blur(); | |
9313 | |
9314 this.document.one( "mousemove", function() { | |
9315 $( event.target ).trigger( event.originalEvent ); | |
9316 }); | |
9317 | |
9318 return; | |
9319 } | |
9320 } | |
9321 | |
9322 var item = ui.item.data( "ui-autocomplete-item" ); | |
9323 if ( false !== this._trigger( "focus", event, { item: item } ) ) { | |
9324 // use value to match what will end up in the input, if it was a key event | |
9325 if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) { | |
9326 this._value( item.value ); | |
9327 } | |
9328 } else { | |
9329 // Normally the input is populated with the item's value as the | |
9330 // menu is navigated, causing screen readers to notice a change and | |
9331 // announce the item. Since the focus event was canceled, this doesn't | |
9332 // happen, so we update the live region so that screen readers can | |
9333 // still notice the change and announce it. | |
9334 this.liveRegion.text( item.value ); | |
9335 } | |
9336 }, | |
9337 menuselect: function( event, ui ) { | |
9338 var item = ui.item.data( "ui-autocomplete-item" ), | |
9339 previous = this.previous; | |
9340 | |
9341 // only trigger when focus was lost (click on menu) | |
9342 if ( this.element[0] !== this.document[0].activeElement ) { | |
9343 this.element.focus(); | |
9344 this.previous = previous; | |
9345 // #6109 - IE triggers two focus events and the second | |
9346 // is asynchronous, so we need to reset the previous | |
9347 // term synchronously and asynchronously :-( | |
9348 this._delay(function() { | |
9349 this.previous = previous; | |
9350 this.selectedItem = item; | |
9351 }); | |
9352 } | |
9353 | |
9354 if ( false !== this._trigger( "select", event, { item: item } ) ) { | |
9355 this._value( item.value ); | |
9356 } | |
9357 // reset the term after the select event | |
9358 // this allows custom select handling to work properly | |
9359 this.term = this._value(); | |
9360 | |
9361 this.close( event ); | |
9362 this.selectedItem = item; | |
9363 } | |
9364 }); | |
9365 | |
9366 this.liveRegion = $( "<span>", { | |
9367 role: "status", | |
9368 "aria-live": "polite" | |
9369 }) | |
9370 .addClass( "ui-helper-hidden-accessible" ) | |
9371 .insertBefore( this.element ); | |
9372 | |
9373 // turning off autocomplete prevents the browser from remembering the | |
9374 // value when navigating through history, so we re-enable autocomplete | |
9375 // if the page is unloaded before the widget is destroyed. #7790 | |
9376 this._on( this.window, { | |
9377 beforeunload: function() { | |
9378 this.element.removeAttr( "autocomplete" ); | |
9379 } | |
9380 }); | |
9381 }, | |
9382 | |
9383 _destroy: function() { | |
9384 clearTimeout( this.searching ); | |
9385 this.element | |
9386 .removeClass( "ui-autocomplete-input" ) | |
9387 .removeAttr( "autocomplete" ); | |
9388 this.menu.element.remove(); | |
9389 this.liveRegion.remove(); | |
9390 }, | |
9391 | |
9392 _setOption: function( key, value ) { | |
9393 this._super( key, value ); | |
9394 if ( key === "source" ) { | |
9395 this._initSource(); | |
9396 } | |
9397 if ( key === "appendTo" ) { | |
9398 this.menu.element.appendTo( this._appendTo() ); | |
9399 } | |
9400 if ( key === "disabled" && value && this.xhr ) { | |
9401 this.xhr.abort(); | |
9402 } | |
9403 }, | |
9404 | |
9405 _appendTo: function() { | |
9406 var element = this.options.appendTo; | |
9407 | |
9408 if ( element ) { | |
9409 element = element.jquery || element.nodeType ? | |
9410 $( element ) : | |
9411 this.document.find( element ).eq( 0 ); | |
9412 } | |
9413 | |
9414 if ( !element ) { | |
9415 element = this.element.closest( ".ui-front" ); | |
9416 } | |
9417 | |
9418 if ( !element.length ) { | |
9419 element = this.document[0].body; | |
9420 } | |
9421 | |
9422 return element; | |
9423 }, | |
9424 | |
9425 _initSource: function() { | |
9426 var array, url, | |
9427 that = this; | |
9428 if ( $.isArray(this.options.source) ) { | |
9429 array = this.options.source; | |
9430 this.source = function( request, response ) { | |
9431 response( $.ui.autocomplete.filter( array, request.term ) ); | |
9432 }; | |
9433 } else if ( typeof this.options.source === "string" ) { | |
9434 url = this.options.source; | |
9435 this.source = function( request, response ) { | |
9436 if ( that.xhr ) { | |
9437 that.xhr.abort(); | |
9438 } | |
9439 that.xhr = $.ajax({ | |
9440 url: url, | |
9441 data: request, | |
9442 dataType: "json", | |
9443 success: function( data ) { | |
9444 response( data ); | |
9445 }, | |
9446 error: function() { | |
9447 response( [] ); | |
9448 } | |
9449 }); | |
9450 }; | |
9451 } else { | |
9452 this.source = this.options.source; | |
9453 } | |
9454 }, | |
9455 | |
9456 _searchTimeout: function( event ) { | |
9457 clearTimeout( this.searching ); | |
9458 this.searching = this._delay(function() { | |
9459 // only search if the value has changed | |
9460 if ( this.term !== this._value() ) { | |
9461 this.selectedItem = null; | |
9462 this.search( null, event ); | |
9463 } | |
9464 }, this.options.delay ); | |
9465 }, | |
9466 | |
9467 search: function( value, event ) { | |
9468 value = value != null ? value : this._value(); | |
9469 | |
9470 // always save the actual value, not the one passed as an argument | |
9471 this.term = this._value(); | |
9472 | |
9473 if ( value.length < this.options.minLength ) { | |
9474 return this.close( event ); | |
9475 } | |
9476 | |
9477 if ( this._trigger( "search", event ) === false ) { | |
9478 return; | |
9479 } | |
9480 | |
9481 return this._search( value ); | |
9482 }, | |
9483 | |
9484 _search: function( value ) { | |
9485 this.pending++; | |
9486 this.element.addClass( "ui-autocomplete-loading" ); | |
9487 this.cancelSearch = false; | |
9488 | |
9489 this.source( { term: value }, this._response() ); | |
9490 }, | |
9491 | |
9492 _response: function() { | |
9493 var that = this, | |
9494 index = ++requestIndex; | |
9495 | |
9496 return function( content ) { | |
9497 if ( index === requestIndex ) { | |
9498 that.__response( content ); | |
9499 } | |
9500 | |
9501 that.pending--; | |
9502 if ( !that.pending ) { | |
9503 that.element.removeClass( "ui-autocomplete-loading" ); | |
9504 } | |
9505 }; | |
9506 }, | |
9507 | |
9508 __response: function( content ) { | |
9509 if ( content ) { | |
9510 content = this._normalize( content ); | |
9511 } | |
9512 this._trigger( "response", null, { content: content } ); | |
9513 if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { | |
9514 this._suggest( content ); | |
9515 this._trigger( "open" ); | |
9516 } else { | |
9517 // use ._close() instead of .close() so we don't cancel future searches | |
9518 this._close(); | |
9519 } | |
9520 }, | |
9521 | |
9522 close: function( event ) { | |
9523 this.cancelSearch = true; | |
9524 this._close( event ); | |
9525 }, | |
9526 | |
9527 _close: function( event ) { | |
9528 if ( this.menu.element.is( ":visible" ) ) { | |
9529 this.menu.element.hide(); | |
9530 this.menu.blur(); | |
9531 this.isNewMenu = true; | |
9532 this._trigger( "close", event ); | |
9533 } | |
9534 }, | |
9535 | |
9536 _change: function( event ) { | |
9537 if ( this.previous !== this._value() ) { | |
9538 this._trigger( "change", event, { item: this.selectedItem } ); | |
9539 } | |
9540 }, | |
9541 | |
9542 _normalize: function( items ) { | |
9543 // assume all items have the right format when the first item is complete | |
9544 if ( items.length && items[0].label && items[0].value ) { | |
9545 return items; | |
9546 } | |
9547 return $.map( items, function( item ) { | |
9548 if ( typeof item === "string" ) { | |
9549 return { | |
9550 label: item, | |
9551 value: item | |
9552 }; | |
9553 } | |
9554 return $.extend({ | |
9555 label: item.label || item.value, | |
9556 value: item.value || item.label | |
9557 }, item ); | |
9558 }); | |
9559 }, | |
9560 | |
9561 _suggest: function( items ) { | |
9562 var ul = this.menu.element.empty(); | |
9563 this._renderMenu( ul, items ); | |
9564 this.isNewMenu = true; | |
9565 this.menu.refresh(); | |
9566 | |
9567 // size and position menu | |
9568 ul.show(); | |
9569 this._resizeMenu(); | |
9570 ul.position( $.extend({ | |
9571 of: this.element | |
9572 }, this.options.position )); | |
9573 | |
9574 if ( this.options.autoFocus ) { | |
9575 this.menu.next(); | |
9576 } | |
9577 }, | |
9578 | |
9579 _resizeMenu: function() { | |
9580 var ul = this.menu.element; | |
9581 ul.outerWidth( Math.max( | |
9582 // Firefox wraps long text (possibly a rounding bug) | |
9583 // so we add 1px to avoid the wrapping (#7513) | |
9584 ul.width( "" ).outerWidth() + 1, | |
9585 this.element.outerWidth() | |
9586 ) ); | |
9587 }, | |
9588 | |
9589 _renderMenu: function( ul, items ) { | |
9590 var that = this; | |
9591 $.each( items, function( index, item ) { | |
9592 that._renderItemData( ul, item ); | |
9593 }); | |
9594 }, | |
9595 | |
9596 _renderItemData: function( ul, item ) { | |
9597 return this._renderItem( ul, item ).data( "ui-autocomplete-item", item ); | |
9598 }, | |
9599 | |
9600 _renderItem: function( ul, item ) { | |
9601 return $( "<li>" ) | |
9602 .append( $( "<a>" ).text( item.label ) ) | |
9603 .appendTo( ul ); | |
9604 }, | |
9605 | |
9606 _move: function( direction, event ) { | |
9607 if ( !this.menu.element.is( ":visible" ) ) { | |
9608 this.search( null, event ); | |
9609 return; | |
9610 } | |
9611 if ( this.menu.isFirstItem() && /^previous/.test( direction ) || | |
9612 this.menu.isLastItem() && /^next/.test( direction ) ) { | |
9613 this._value( this.term ); | |
9614 this.menu.blur(); | |
9615 return; | |
9616 } | |
9617 this.menu[ direction ]( event ); | |
9618 }, | |
9619 | |
9620 widget: function() { | |
9621 return this.menu.element; | |
9622 }, | |
9623 | |
9624 _value: function() { | |
9625 return this.valueMethod.apply( this.element, arguments ); | |
9626 }, | |
9627 | |
9628 _keyEvent: function( keyEvent, event ) { | |
9629 if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) { | |
9630 this._move( keyEvent, event ); | |
9631 | |
9632 // prevents moving cursor to beginning/end of the text field in some browsers | |
9633 event.preventDefault(); | |
9634 } | |
9635 } | |
9636 }); | |
9637 | |
9638 $.extend( $.ui.autocomplete, { | |
9639 escapeRegex: function( value ) { | |
9640 return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); | |
9641 }, | |
9642 filter: function(array, term) { | |
9643 var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); | |
9644 return $.grep( array, function(value) { | |
9645 return matcher.test( value.label || value.value || value ); | |
9646 }); | |
9647 } | |
9648 }); | |
9649 | |
9650 | |
9651 // live region extension, adding a `messages` option | |
9652 // NOTE: This is an experimental API. We are still investigating | |
9653 // a full solution for string manipulation and internationalization. | |
9654 $.widget( "ui.autocomplete", $.ui.autocomplete, { | |
9655 options: { | |
9656 messages: { | |
9657 noResults: "No search results.", | |
9658 results: function( amount ) { | |
9659 return amount + ( amount > 1 ? " results are" : " result is" ) + | |
9660 " available, use up and down arrow keys to navigate."; | |
9661 } | |
9662 } | |
9663 }, | |
9664 | |
9665 __response: function( content ) { | |
9666 var message; | |
9667 this._superApply( arguments ); | |
9668 if ( this.options.disabled || this.cancelSearch ) { | |
9669 return; | |
9670 } | |
9671 if ( content && content.length ) { | |
9672 message = this.options.messages.results( content.length ); | |
9673 } else { | |
9674 message = this.options.messages.noResults; | |
9675 } | |
9676 this.liveRegion.text( message ); | |
9677 } | |
9678 }); | |
9679 | |
9680 }( jQuery )); | |
9681 (function( $, undefined ) { | |
9682 | |
9683 var lastActive, startXPos, startYPos, clickDragged, | |
9684 baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", | |
9685 stateClasses = "ui-state-hover ui-state-active ", | |
9686 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", | |
9687 formResetHandler = function() { | |
9688 var form = $( this ); | |
9689 setTimeout(function() { | |
9690 form.find( ":ui-button" ).button( "refresh" ); | |
9691 }, 1 ); | |
9692 }, | |
9693 radioGroup = function( radio ) { | |
9694 var name = radio.name, | |
9695 form = radio.form, | |
9696 radios = $( [] ); | |
9697 if ( name ) { | |
9698 name = name.replace( /'/g, "\\'" ); | |
9699 if ( form ) { | |
9700 radios = $( form ).find( "[name='" + name + "']" ); | |
9701 } else { | |
9702 radios = $( "[name='" + name + "']", radio.ownerDocument ) | |
9703 .filter(function() { | |
9704 return !this.form; | |
9705 }); | |
9706 } | |
9707 } | |
9708 return radios; | |
9709 }; | |
9710 | |
9711 $.widget( "ui.button", { | |
9712 version: "1.10.3", | |
9713 defaultElement: "<button>", | |
9714 options: { | |
9715 disabled: null, | |
9716 text: true, | |
9717 label: null, | |
9718 icons: { | |
9719 primary: null, | |
9720 secondary: null | |
9721 } | |
9722 }, | |
9723 _create: function() { | |
9724 this.element.closest( "form" ) | |
9725 .unbind( "reset" + this.eventNamespace ) | |
9726 .bind( "reset" + this.eventNamespace, formResetHandler ); | |
9727 | |
9728 if ( typeof this.options.disabled !== "boolean" ) { | |
9729 this.options.disabled = !!this.element.prop( "disabled" ); | |
9730 } else { | |
9731 this.element.prop( "disabled", this.options.disabled ); | |
9732 } | |
9733 | |
9734 this._determineButtonType(); | |
9735 this.hasTitle = !!this.buttonElement.attr( "title" ); | |
9736 | |
9737 var that = this, | |
9738 options = this.options, | |
9739 toggleButton = this.type === "checkbox" || this.type === "radio", | |
9740 activeClass = !toggleButton ? "ui-state-active" : "", | |
9741 focusClass = "ui-state-focus"; | |
9742 | |
9743 if ( options.label === null ) { | |
9744 options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); | |
9745 } | |
9746 | |
9747 this._hoverable( this.buttonElement ); | |
9748 | |
9749 this.buttonElement | |
9750 .addClass( baseClasses ) | |
9751 .attr( "role", "button" ) | |
9752 .bind( "mouseenter" + this.eventNamespace, function() { | |
9753 if ( options.disabled ) { | |
9754 return; | |
9755 } | |
9756 if ( this === lastActive ) { | |
9757 $( this ).addClass( "ui-state-active" ); | |
9758 } | |
9759 }) | |
9760 .bind( "mouseleave" + this.eventNamespace, function() { | |
9761 if ( options.disabled ) { | |
9762 return; | |
9763 } | |
9764 $( this ).removeClass( activeClass ); | |
9765 }) | |
9766 .bind( "click" + this.eventNamespace, function( event ) { | |
9767 if ( options.disabled ) { | |
9768 event.preventDefault(); | |
9769 event.stopImmediatePropagation(); | |
9770 } | |
9771 }); | |
9772 | |
9773 this.element | |
9774 .bind( "focus" + this.eventNamespace, function() { | |
9775 // no need to check disabled, focus won't be triggered anyway | |
9776 that.buttonElement.addClass( focusClass ); | |
9777 }) | |
9778 .bind( "blur" + this.eventNamespace, function() { | |
9779 that.buttonElement.removeClass( focusClass ); | |
9780 }); | |
9781 | |
9782 if ( toggleButton ) { | |
9783 this.element.bind( "change" + this.eventNamespace, function() { | |
9784 if ( clickDragged ) { | |
9785 return; | |
9786 } | |
9787 that.refresh(); | |
9788 }); | |
9789 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag | |
9790 // prevents issue where button state changes but checkbox/radio checked state | |
9791 // does not in Firefox (see ticket #6970) | |
9792 this.buttonElement | |
9793 .bind( "mousedown" + this.eventNamespace, function( event ) { | |
9794 if ( options.disabled ) { | |
9795 return; | |
9796 } | |
9797 clickDragged = false; | |
9798 startXPos = event.pageX; | |
9799 startYPos = event.pageY; | |
9800 }) | |
9801 .bind( "mouseup" + this.eventNamespace, function( event ) { | |
9802 if ( options.disabled ) { | |
9803 return; | |
9804 } | |
9805 if ( startXPos !== event.pageX || startYPos !== event.pageY ) { | |
9806 clickDragged = true; | |
9807 } | |
9808 }); | |
9809 } | |
9810 | |
9811 if ( this.type === "checkbox" ) { | |
9812 this.buttonElement.bind( "click" + this.eventNamespace, function() { | |
9813 if ( options.disabled || clickDragged ) { | |
9814 return false; | |
9815 } | |
9816 }); | |
9817 } else if ( this.type === "radio" ) { | |
9818 this.buttonElement.bind( "click" + this.eventNamespace, function() { | |
9819 if ( options.disabled || clickDragged ) { | |
9820 return false; | |
9821 } | |
9822 $( this ).addClass( "ui-state-active" ); | |
9823 that.buttonElement.attr( "aria-pressed", "true" ); | |
9824 | |
9825 var radio = that.element[ 0 ]; | |
9826 radioGroup( radio ) | |
9827 .not( radio ) | |
9828 .map(function() { | |
9829 return $( this ).button( "widget" )[ 0 ]; | |
9830 }) | |
9831 .removeClass( "ui-state-active" ) | |
9832 .attr( "aria-pressed", "false" ); | |
9833 }); | |
9834 } else { | |
9835 this.buttonElement | |
9836 .bind( "mousedown" + this.eventNamespace, function() { | |
9837 if ( options.disabled ) { | |
9838 return false; | |
9839 } | |
9840 $( this ).addClass( "ui-state-active" ); | |
9841 lastActive = this; | |
9842 that.document.one( "mouseup", function() { | |
9843 lastActive = null; | |
9844 }); | |
9845 }) | |
9846 .bind( "mouseup" + this.eventNamespace, function() { | |
9847 if ( options.disabled ) { | |
9848 return false; | |
9849 } | |
9850 $( this ).removeClass( "ui-state-active" ); | |
9851 }) | |
9852 .bind( "keydown" + this.eventNamespace, function(event) { | |
9853 if ( options.disabled ) { | |
9854 return false; | |
9855 } | |
9856 if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) { | |
9857 $( this ).addClass( "ui-state-active" ); | |
9858 } | |
9859 }) | |
9860 // see #8559, we bind to blur here in case the button element loses | |
9861 // focus between keydown and keyup, it would be left in an "active" state | |
9862 .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() { | |
9863 $( this ).removeClass( "ui-state-active" ); | |
9864 }); | |
9865 | |
9866 if ( this.buttonElement.is("a") ) { | |
9867 this.buttonElement.keyup(function(event) { | |
9868 if ( event.keyCode === $.ui.keyCode.SPACE ) { | |
9869 // TODO pass through original event correctly (just as 2nd argument doesn't work) | |
9870 $( this ).click(); | |
9871 } | |
9872 }); | |
9873 } | |
9874 } | |
9875 | |
9876 // TODO: pull out $.Widget's handling for the disabled option into | |
9877 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can | |
9878 // be overridden by individual plugins | |
9879 this._setOption( "disabled", options.disabled ); | |
9880 this._resetButton(); | |
9881 }, | |
9882 | |
9883 _determineButtonType: function() { | |
9884 var ancestor, labelSelector, checked; | |
9885 | |
9886 if ( this.element.is("[type=checkbox]") ) { | |
9887 this.type = "checkbox"; | |
9888 } else if ( this.element.is("[type=radio]") ) { | |
9889 this.type = "radio"; | |
9890 } else if ( this.element.is("input") ) { | |
9891 this.type = "input"; | |
9892 } else { | |
9893 this.type = "button"; | |
9894 } | |
9895 | |
9896 if ( this.type === "checkbox" || this.type === "radio" ) { | |
9897 // we don't search against the document in case the element | |
9898 // is disconnected from the DOM | |
9899 ancestor = this.element.parents().last(); | |
9900 labelSelector = "label[for='" + this.element.attr("id") + "']"; | |
9901 this.buttonElement = ancestor.find( labelSelector ); | |
9902 if ( !this.buttonElement.length ) { | |
9903 ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); | |
9904 this.buttonElement = ancestor.filter( labelSelector ); | |
9905 if ( !this.buttonElement.length ) { | |
9906 this.buttonElement = ancestor.find( labelSelector ); | |
9907 } | |
9908 } | |
9909 this.element.addClass( "ui-helper-hidden-accessible" ); | |
9910 | |
9911 checked = this.element.is( ":checked" ); | |
9912 if ( checked ) { | |
9913 this.buttonElement.addClass( "ui-state-active" ); | |
9914 } | |
9915 this.buttonElement.prop( "aria-pressed", checked ); | |
9916 } else { | |
9917 this.buttonElement = this.element; | |
9918 } | |
9919 }, | |
9920 | |
9921 widget: function() { | |
9922 return this.buttonElement; | |
9923 }, | |
9924 | |
9925 _destroy: function() { | |
9926 this.element | |
9927 .removeClass( "ui-helper-hidden-accessible" ); | |
9928 this.buttonElement | |
9929 .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) | |
9930 .removeAttr( "role" ) | |
9931 .removeAttr( "aria-pressed" ) | |
9932 .html( this.buttonElement.find(".ui-button-text").html() ); | |
9933 | |
9934 if ( !this.hasTitle ) { | |
9935 this.buttonElement.removeAttr( "title" ); | |
9936 } | |
9937 }, | |
9938 | |
9939 _setOption: function( key, value ) { | |
9940 this._super( key, value ); | |
9941 if ( key === "disabled" ) { | |
9942 if ( value ) { | |
9943 this.element.prop( "disabled", true ); | |
9944 } else { | |
9945 this.element.prop( "disabled", false ); | |
9946 } | |
9947 return; | |
9948 } | |
9949 this._resetButton(); | |
9950 }, | |
9951 | |
9952 refresh: function() { | |
9953 //See #8237 & #8828 | |
9954 var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" ); | |
9955 | |
9956 if ( isDisabled !== this.options.disabled ) { | |
9957 this._setOption( "disabled", isDisabled ); | |
9958 } | |
9959 if ( this.type === "radio" ) { | |
9960 radioGroup( this.element[0] ).each(function() { | |
9961 if ( $( this ).is( ":checked" ) ) { | |
9962 $( this ).button( "widget" ) | |
9963 .addClass( "ui-state-active" ) | |
9964 .attr( "aria-pressed", "true" ); | |
9965 } else { | |
9966 $( this ).button( "widget" ) | |
9967 .removeClass( "ui-state-active" ) | |
9968 .attr( "aria-pressed", "false" ); | |
9969 } | |
9970 }); | |
9971 } else if ( this.type === "checkbox" ) { | |
9972 if ( this.element.is( ":checked" ) ) { | |
9973 this.buttonElement | |
9974 .addClass( "ui-state-active" ) | |
9975 .attr( "aria-pressed", "true" ); | |
9976 } else { | |
9977 this.buttonElement | |
9978 .removeClass( "ui-state-active" ) | |
9979 .attr( "aria-pressed", "false" ); | |
9980 } | |
9981 } | |
9982 }, | |
9983 | |
9984 _resetButton: function() { | |
9985 if ( this.type === "input" ) { | |
9986 if ( this.options.label ) { | |
9987 this.element.val( this.options.label ); | |
9988 } | |
9989 return; | |
9990 } | |
9991 var buttonElement = this.buttonElement.removeClass( typeClasses ), | |
9992 buttonText = $( "<span></span>", this.document[0] ) | |
9993 .addClass( "ui-button-text" ) | |
9994 .html( this.options.label ) | |
9995 .appendTo( buttonElement.empty() ) | |
9996 .text(), | |
9997 icons = this.options.icons, | |
9998 multipleIcons = icons.primary && icons.secondary, | |
9999 buttonClasses = []; | |
10000 | |
10001 if ( icons.primary || icons.secondary ) { | |
10002 if ( this.options.text ) { | |
10003 buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); | |
10004 } | |
10005 | |
10006 if ( icons.primary ) { | |
10007 buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" ); | |
10008 } | |
10009 | |
10010 if ( icons.secondary ) { | |
10011 buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" ); | |
10012 } | |
10013 | |
10014 if ( !this.options.text ) { | |
10015 buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); | |
10016 | |
10017 if ( !this.hasTitle ) { | |
10018 buttonElement.attr( "title", $.trim( buttonText ) ); | |
10019 } | |
10020 } | |
10021 } else { | |
10022 buttonClasses.push( "ui-button-text-only" ); | |
10023 } | |
10024 buttonElement.addClass( buttonClasses.join( " " ) ); | |
10025 } | |
10026 }); | |
10027 | |
10028 $.widget( "ui.buttonset", { | |
10029 version: "1.10.3", | |
10030 options: { | |
10031 items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)" | |
10032 }, | |
10033 | |
10034 _create: function() { | |
10035 this.element.addClass( "ui-buttonset" ); | |
10036 }, | |
10037 | |
10038 _init: function() { | |
10039 this.refresh(); | |
10040 }, | |
10041 | |
10042 _setOption: function( key, value ) { | |
10043 if ( key === "disabled" ) { | |
10044 this.buttons.button( "option", key, value ); | |
10045 } | |
10046 | |
10047 this._super( key, value ); | |
10048 }, | |
10049 | |
10050 refresh: function() { | |
10051 var rtl = this.element.css( "direction" ) === "rtl"; | |
10052 | |
10053 this.buttons = this.element.find( this.options.items ) | |
10054 .filter( ":ui-button" ) | |
10055 .button( "refresh" ) | |
10056 .end() | |
10057 .not( ":ui-button" ) | |
10058 .button() | |
10059 .end() | |
10060 .map(function() { | |
10061 return $( this ).button( "widget" )[ 0 ]; | |
10062 }) | |
10063 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) | |
10064 .filter( ":first" ) | |
10065 .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) | |
10066 .end() | |
10067 .filter( ":last" ) | |
10068 .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) | |
10069 .end() | |
10070 .end(); | |
10071 }, | |
10072 | |
10073 _destroy: function() { | |
10074 this.element.removeClass( "ui-buttonset" ); | |
10075 this.buttons | |
10076 .map(function() { | |
10077 return $( this ).button( "widget" )[ 0 ]; | |
10078 }) | |
10079 .removeClass( "ui-corner-left ui-corner-right" ) | |
10080 .end() | |
10081 .button( "destroy" ); | |
10082 } | |
10083 }); | |
10084 | |
10085 }( jQuery ) ); | |
10086 (function( $, undefined ) { | |
10087 | |
10088 $.extend($.ui, { datepicker: { version: "1.10.3" } }); | |
10089 | |
10090 var PROP_NAME = "datepicker", | |
10091 instActive; | |
10092 | |
10093 /* Date picker manager. | |
10094 Use the singleton instance of this class, $.datepicker, to interact with the date picker. | |
10095 Settings for (groups of) date pickers are maintained in an instance object, | |
10096 allowing multiple different settings on the same page. */ | |
10097 | |
10098 function Datepicker() { | |
10099 this._curInst = null; // The current instance in use | |
10100 this._keyEvent = false; // If the last event was a key event | |
10101 this._disabledInputs = []; // List of date picker inputs that have been disabled | |
10102 this._datepickerShowing = false; // True if the popup picker is showing , false if not | |
10103 this._inDialog = false; // True if showing within a "dialog", false if not | |
10104 this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division | |
10105 this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class | |
10106 this._appendClass = "ui-datepicker-append"; // The name of the append marker class | |
10107 this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class | |
10108 this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class | |
10109 this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class | |
10110 this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class | |
10111 this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class | |
10112 this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class | |
10113 this.regional = []; // Available regional settings, indexed by language code | |
10114 this.regional[""] = { // Default regional settings | |
10115 closeText: "Done", // Display text for close link | |
10116 prevText: "Prev", // Display text for previous month link | |
10117 nextText: "Next", // Display text for next month link | |
10118 currentText: "Today", // Display text for current month link | |
10119 monthNames: ["January","February","March","April","May","June", | |
10120 "July","August","September","October","November","December"], // Names of months for drop-down and formatting | |
10121 monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting | |
10122 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting | |
10123 dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting | |
10124 dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday | |
10125 weekHeader: "Wk", // Column header for week of the year | |
10126 dateFormat: "mm/dd/yy", // See format options on parseDate | |
10127 firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... | |
10128 isRTL: false, // True if right-to-left language, false if left-to-right | |
10129 showMonthAfterYear: false, // True if the year select precedes month, false for month then year | |
10130 yearSuffix: "" // Additional text to append to the year in the month headers | |
10131 }; | |
10132 this._defaults = { // Global defaults for all the date picker instances | |
10133 showOn: "focus", // "focus" for popup on focus, | |
10134 // "button" for trigger button, or "both" for either | |
10135 showAnim: "fadeIn", // Name of jQuery animation for popup | |
10136 showOptions: {}, // Options for enhanced animations | |
10137 defaultDate: null, // Used when field is blank: actual date, | |
10138 // +/-number for offset from today, null for today | |
10139 appendText: "", // Display text following the input box, e.g. showing the format | |
10140 buttonText: "...", // Text for trigger button | |
10141 buttonImage: "", // URL for trigger button image | |
10142 buttonImageOnly: false, // True if the image appears alone, false if it appears on a button | |
10143 hideIfNoPrevNext: false, // True to hide next/previous month links | |
10144 // if not applicable, false to just disable them | |
10145 navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links | |
10146 gotoCurrent: false, // True if today link goes back to current selection instead | |
10147 changeMonth: false, // True if month can be selected directly, false if only prev/next | |
10148 changeYear: false, // True if year can be selected directly, false if only prev/next | |
10149 yearRange: "c-10:c+10", // Range of years to display in drop-down, | |
10150 // either relative to today's year (-nn:+nn), relative to currently displayed year | |
10151 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) | |
10152 showOtherMonths: false, // True to show dates in other months, false to leave blank | |
10153 selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable | |
10154 showWeek: false, // True to show week of the year, false to not show it | |
10155 calculateWeek: this.iso8601Week, // How to calculate the week of the year, | |
10156 // takes a Date and returns the number of the week for it | |
10157 shortYearCutoff: "+10", // Short year values < this are in the current century, | |
10158 // > this are in the previous century, | |
10159 // string value starting with "+" for current year + value | |
10160 minDate: null, // The earliest selectable date, or null for no limit | |
10161 maxDate: null, // The latest selectable date, or null for no limit | |
10162 duration: "fast", // Duration of display/closure | |
10163 beforeShowDay: null, // Function that takes a date and returns an array with | |
10164 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", | |
10165 // [2] = cell title (optional), e.g. $.datepicker.noWeekends | |
10166 beforeShow: null, // Function that takes an input field and | |
10167 // returns a set of custom settings for the date picker | |
10168 onSelect: null, // Define a callback function when a date is selected | |
10169 onChangeMonthYear: null, // Define a callback function when the month or year is changed | |
10170 onClose: null, // Define a callback function when the datepicker is closed | |
10171 numberOfMonths: 1, // Number of months to show at a time | |
10172 showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) | |
10173 stepMonths: 1, // Number of months to step back/forward | |
10174 stepBigMonths: 12, // Number of months to step back/forward for the big links | |
10175 altField: "", // Selector for an alternate field to store selected dates into | |
10176 altFormat: "", // The date format to use for the alternate field | |
10177 constrainInput: true, // The input is constrained by the current date format | |
10178 showButtonPanel: false, // True to show button panel, false to not show it | |
10179 autoSize: false, // True to size the input for the date format, false to leave as is | |
10180 disabled: false // The initial disabled state | |
10181 }; | |
10182 $.extend(this._defaults, this.regional[""]); | |
10183 this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")); | |
10184 } | |
10185 | |
10186 $.extend(Datepicker.prototype, { | |
10187 /* Class name added to elements to indicate already configured with a date picker. */ | |
10188 markerClassName: "hasDatepicker", | |
10189 | |
10190 //Keep track of the maximum number of rows displayed (see #7043) | |
10191 maxRows: 4, | |
10192 | |
10193 // TODO rename to "widget" when switching to widget factory | |
10194 _widgetDatepicker: function() { | |
10195 return this.dpDiv; | |
10196 }, | |
10197 | |
10198 /* Override the default settings for all instances of the date picker. | |
10199 * @param settings object - the new settings to use as defaults (anonymous object) | |
10200 * @return the manager object | |
10201 */ | |
10202 setDefaults: function(settings) { | |
10203 extendRemove(this._defaults, settings || {}); | |
10204 return this; | |
10205 }, | |
10206 | |
10207 /* Attach the date picker to a jQuery selection. | |
10208 * @param target element - the target input field or division or span | |
10209 * @param settings object - the new settings to use for this date picker instance (anonymous) | |
10210 */ | |
10211 _attachDatepicker: function(target, settings) { | |
10212 var nodeName, inline, inst; | |
10213 nodeName = target.nodeName.toLowerCase(); | |
10214 inline = (nodeName === "div" || nodeName === "span"); | |
10215 if (!target.id) { | |
10216 this.uuid += 1; | |
10217 target.id = "dp" + this.uuid; | |
10218 } | |
10219 inst = this._newInst($(target), inline); | |
10220 inst.settings = $.extend({}, settings || {}); | |
10221 if (nodeName === "input") { | |
10222 this._connectDatepicker(target, inst); | |
10223 } else if (inline) { | |
10224 this._inlineDatepicker(target, inst); | |
10225 } | |
10226 }, | |
10227 | |
10228 /* Create a new instance object. */ | |
10229 _newInst: function(target, inline) { | |
10230 var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars | |
10231 return {id: id, input: target, // associated target | |
10232 selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection | |
10233 drawMonth: 0, drawYear: 0, // month being drawn | |
10234 inline: inline, // is datepicker inline or not | |
10235 dpDiv: (!inline ? this.dpDiv : // presentation div | |
10236 bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))}; | |
10237 }, | |
10238 | |
10239 /* Attach the date picker to an input field. */ | |
10240 _connectDatepicker: function(target, inst) { | |
10241 var input = $(target); | |
10242 inst.append = $([]); | |
10243 inst.trigger = $([]); | |
10244 if (input.hasClass(this.markerClassName)) { | |
10245 return; | |
10246 } | |
10247 this._attachments(input, inst); | |
10248 input.addClass(this.markerClassName).keydown(this._doKeyDown). | |
10249 keypress(this._doKeyPress).keyup(this._doKeyUp); | |
10250 this._autoSize(inst); | |
10251 $.data(target, PROP_NAME, inst); | |
10252 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) | |
10253 if( inst.settings.disabled ) { | |
10254 this._disableDatepicker( target ); | |
10255 } | |
10256 }, | |
10257 | |
10258 /* Make attachments based on settings. */ | |
10259 _attachments: function(input, inst) { | |
10260 var showOn, buttonText, buttonImage, | |
10261 appendText = this._get(inst, "appendText"), | |
10262 isRTL = this._get(inst, "isRTL"); | |
10263 | |
10264 if (inst.append) { | |
10265 inst.append.remove(); | |
10266 } | |
10267 if (appendText) { | |
10268 inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>"); | |
10269 input[isRTL ? "before" : "after"](inst.append); | |
10270 } | |
10271 | |
10272 input.unbind("focus", this._showDatepicker); | |
10273 | |
10274 if (inst.trigger) { | |
10275 inst.trigger.remove(); | |
10276 } | |
10277 | |
10278 showOn = this._get(inst, "showOn"); | |
10279 if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field | |
10280 input.focus(this._showDatepicker); | |
10281 } | |
10282 if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked | |
10283 buttonText = this._get(inst, "buttonText"); | |
10284 buttonImage = this._get(inst, "buttonImage"); | |
10285 inst.trigger = $(this._get(inst, "buttonImageOnly") ? | |
10286 $("<img/>").addClass(this._triggerClass). | |
10287 attr({ src: buttonImage, alt: buttonText, title: buttonText }) : | |
10288 $("<button type='button'></button>").addClass(this._triggerClass). | |
10289 html(!buttonImage ? buttonText : $("<img/>").attr( | |
10290 { src:buttonImage, alt:buttonText, title:buttonText }))); | |
10291 input[isRTL ? "before" : "after"](inst.trigger); | |
10292 inst.trigger.click(function() { | |
10293 if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) { | |
10294 $.datepicker._hideDatepicker(); | |
10295 } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) { | |
10296 $.datepicker._hideDatepicker(); | |
10297 $.datepicker._showDatepicker(input[0]); | |
10298 } else { | |
10299 $.datepicker._showDatepicker(input[0]); | |
10300 } | |
10301 return false; | |
10302 }); | |
10303 } | |
10304 }, | |
10305 | |
10306 /* Apply the maximum length for the date format. */ | |
10307 _autoSize: function(inst) { | |
10308 if (this._get(inst, "autoSize") && !inst.inline) { | |
10309 var findMax, max, maxI, i, | |
10310 date = new Date(2009, 12 - 1, 20), // Ensure double digits | |
10311 dateFormat = this._get(inst, "dateFormat"); | |
10312 | |
10313 if (dateFormat.match(/[DM]/)) { | |
10314 findMax = function(names) { | |
10315 max = 0; | |
10316 maxI = 0; | |
10317 for (i = 0; i < names.length; i++) { | |
10318 if (names[i].length > max) { | |
10319 max = names[i].length; | |
10320 maxI = i; | |
10321 } | |
10322 } | |
10323 return maxI; | |
10324 }; | |
10325 date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? | |
10326 "monthNames" : "monthNamesShort")))); | |
10327 date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? | |
10328 "dayNames" : "dayNamesShort"))) + 20 - date.getDay()); | |
10329 } | |
10330 inst.input.attr("size", this._formatDate(inst, date).length); | |
10331 } | |
10332 }, | |
10333 | |
10334 /* Attach an inline date picker to a div. */ | |
10335 _inlineDatepicker: function(target, inst) { | |
10336 var divSpan = $(target); | |
10337 if (divSpan.hasClass(this.markerClassName)) { | |
10338 return; | |
10339 } | |
10340 divSpan.addClass(this.markerClassName).append(inst.dpDiv); | |
10341 $.data(target, PROP_NAME, inst); | |
10342 this._setDate(inst, this._getDefaultDate(inst), true); | |
10343 this._updateDatepicker(inst); | |
10344 this._updateAlternate(inst); | |
10345 //If disabled option is true, disable the datepicker before showing it (see ticket #5665) | |
10346 if( inst.settings.disabled ) { | |
10347 this._disableDatepicker( target ); | |
10348 } | |
10349 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements | |
10350 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height | |
10351 inst.dpDiv.css( "display", "block" ); | |
10352 }, | |
10353 | |
10354 /* Pop-up the date picker in a "dialog" box. | |
10355 * @param input element - ignored | |
10356 * @param date string or Date - the initial date to display | |
10357 * @param onSelect function - the function to call when a date is selected | |
10358 * @param settings object - update the dialog date picker instance's settings (anonymous object) | |
10359 * @param pos int[2] - coordinates for the dialog's position within the screen or | |
10360 * event - with x/y coordinates or | |
10361 * leave empty for default (screen centre) | |
10362 * @return the manager object | |
10363 */ | |
10364 _dialogDatepicker: function(input, date, onSelect, settings, pos) { | |
10365 var id, browserWidth, browserHeight, scrollX, scrollY, | |
10366 inst = this._dialogInst; // internal instance | |
10367 | |
10368 if (!inst) { | |
10369 this.uuid += 1; | |
10370 id = "dp" + this.uuid; | |
10371 this._dialogInput = $("<input type='text' id='" + id + | |
10372 "' style='position: absolute; top: -100px; width: 0px;'/>"); | |
10373 this._dialogInput.keydown(this._doKeyDown); | |
10374 $("body").append(this._dialogInput); | |
10375 inst = this._dialogInst = this._newInst(this._dialogInput, false); | |
10376 inst.settings = {}; | |
10377 $.data(this._dialogInput[0], PROP_NAME, inst); | |
10378 } | |
10379 extendRemove(inst.settings, settings || {}); | |
10380 date = (date && date.constructor === Date ? this._formatDate(inst, date) : date); | |
10381 this._dialogInput.val(date); | |
10382 | |
10383 this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); | |
10384 if (!this._pos) { | |
10385 browserWidth = document.documentElement.clientWidth; | |
10386 browserHeight = document.documentElement.clientHeight; | |
10387 scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; | |
10388 scrollY = document.documentElement.scrollTop || document.body.scrollTop; | |
10389 this._pos = // should use actual width/height below | |
10390 [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; | |
10391 } | |
10392 | |
10393 // move input on screen for focus, but hidden behind dialog | |
10394 this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px"); | |
10395 inst.settings.onSelect = onSelect; | |
10396 this._inDialog = true; | |
10397 this.dpDiv.addClass(this._dialogClass); | |
10398 this._showDatepicker(this._dialogInput[0]); | |
10399 if ($.blockUI) { | |
10400 $.blockUI(this.dpDiv); | |
10401 } | |
10402 $.data(this._dialogInput[0], PROP_NAME, inst); | |
10403 return this; | |
10404 }, | |
10405 | |
10406 /* Detach a datepicker from its control. | |
10407 * @param target element - the target input field or division or span | |
10408 */ | |
10409 _destroyDatepicker: function(target) { | |
10410 var nodeName, | |
10411 $target = $(target), | |
10412 inst = $.data(target, PROP_NAME); | |
10413 | |
10414 if (!$target.hasClass(this.markerClassName)) { | |
10415 return; | |
10416 } | |
10417 | |
10418 nodeName = target.nodeName.toLowerCase(); | |
10419 $.removeData(target, PROP_NAME); | |
10420 if (nodeName === "input") { | |
10421 inst.append.remove(); | |
10422 inst.trigger.remove(); | |
10423 $target.removeClass(this.markerClassName). | |
10424 unbind("focus", this._showDatepicker). | |
10425 unbind("keydown", this._doKeyDown). | |
10426 unbind("keypress", this._doKeyPress). | |
10427 unbind("keyup", this._doKeyUp); | |
10428 } else if (nodeName === "div" || nodeName === "span") { | |
10429 $target.removeClass(this.markerClassName).empty(); | |
10430 } | |
10431 }, | |
10432 | |
10433 /* Enable the date picker to a jQuery selection. | |
10434 * @param target element - the target input field or division or span | |
10435 */ | |
10436 _enableDatepicker: function(target) { | |
10437 var nodeName, inline, | |
10438 $target = $(target), | |
10439 inst = $.data(target, PROP_NAME); | |
10440 | |
10441 if (!$target.hasClass(this.markerClassName)) { | |
10442 return; | |
10443 } | |
10444 | |
10445 nodeName = target.nodeName.toLowerCase(); | |
10446 if (nodeName === "input") { | |
10447 target.disabled = false; | |
10448 inst.trigger.filter("button"). | |
10449 each(function() { this.disabled = false; }).end(). | |
10450 filter("img").css({opacity: "1.0", cursor: ""}); | |
10451 } else if (nodeName === "div" || nodeName === "span") { | |
10452 inline = $target.children("." + this._inlineClass); | |
10453 inline.children().removeClass("ui-state-disabled"); | |
10454 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). | |
10455 prop("disabled", false); | |
10456 } | |
10457 this._disabledInputs = $.map(this._disabledInputs, | |
10458 function(value) { return (value === target ? null : value); }); // delete entry | |
10459 }, | |
10460 | |
10461 /* Disable the date picker to a jQuery selection. | |
10462 * @param target element - the target input field or division or span | |
10463 */ | |
10464 _disableDatepicker: function(target) { | |
10465 var nodeName, inline, | |
10466 $target = $(target), | |
10467 inst = $.data(target, PROP_NAME); | |
10468 | |
10469 if (!$target.hasClass(this.markerClassName)) { | |
10470 return; | |
10471 } | |
10472 | |
10473 nodeName = target.nodeName.toLowerCase(); | |
10474 if (nodeName === "input") { | |
10475 target.disabled = true; | |
10476 inst.trigger.filter("button"). | |
10477 each(function() { this.disabled = true; }).end(). | |
10478 filter("img").css({opacity: "0.5", cursor: "default"}); | |
10479 } else if (nodeName === "div" || nodeName === "span") { | |
10480 inline = $target.children("." + this._inlineClass); | |
10481 inline.children().addClass("ui-state-disabled"); | |
10482 inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). | |
10483 prop("disabled", true); | |
10484 } | |
10485 this._disabledInputs = $.map(this._disabledInputs, | |
10486 function(value) { return (value === target ? null : value); }); // delete entry | |
10487 this._disabledInputs[this._disabledInputs.length] = target; | |
10488 }, | |
10489 | |
10490 /* Is the first field in a jQuery collection disabled as a datepicker? | |
10491 * @param target element - the target input field or division or span | |
10492 * @return boolean - true if disabled, false if enabled | |
10493 */ | |
10494 _isDisabledDatepicker: function(target) { | |
10495 if (!target) { | |
10496 return false; | |
10497 } | |
10498 for (var i = 0; i < this._disabledInputs.length; i++) { | |
10499 if (this._disabledInputs[i] === target) { | |
10500 return true; | |
10501 } | |
10502 } | |
10503 return false; | |
10504 }, | |
10505 | |
10506 /* Retrieve the instance data for the target control. | |
10507 * @param target element - the target input field or division or span | |
10508 * @return object - the associated instance data | |
10509 * @throws error if a jQuery problem getting data | |
10510 */ | |
10511 _getInst: function(target) { | |
10512 try { | |
10513 return $.data(target, PROP_NAME); | |
10514 } | |
10515 catch (err) { | |
10516 throw "Missing instance data for this datepicker"; | |
10517 } | |
10518 }, | |
10519 | |
10520 /* Update or retrieve the settings for a date picker attached to an input field or division. | |
10521 * @param target element - the target input field or division or span | |
10522 * @param name object - the new settings to update or | |
10523 * string - the name of the setting to change or retrieve, | |
10524 * when retrieving also "all" for all instance settings or | |
10525 * "defaults" for all global defaults | |
10526 * @param value any - the new value for the setting | |
10527 * (omit if above is an object or to retrieve a value) | |
10528 */ | |
10529 _optionDatepicker: function(target, name, value) { | |
10530 var settings, date, minDate, maxDate, | |
10531 inst = this._getInst(target); | |
10532 | |
10533 if (arguments.length === 2 && typeof name === "string") { | |
10534 return (name === "defaults" ? $.extend({}, $.datepicker._defaults) : | |
10535 (inst ? (name === "all" ? $.extend({}, inst.settings) : | |
10536 this._get(inst, name)) : null)); | |
10537 } | |
10538 | |
10539 settings = name || {}; | |
10540 if (typeof name === "string") { | |
10541 settings = {}; | |
10542 settings[name] = value; | |
10543 } | |
10544 | |
10545 if (inst) { | |
10546 if (this._curInst === inst) { | |
10547 this._hideDatepicker(); | |
10548 } | |
10549 | |
10550 date = this._getDateDatepicker(target, true); | |
10551 minDate = this._getMinMaxDate(inst, "min"); | |
10552 maxDate = this._getMinMaxDate(inst, "max"); | |
10553 extendRemove(inst.settings, settings); | |
10554 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided | |
10555 if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) { | |
10556 inst.settings.minDate = this._formatDate(inst, minDate); | |
10557 } | |
10558 if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) { | |
10559 inst.settings.maxDate = this._formatDate(inst, maxDate); | |
10560 } | |
10561 if ( "disabled" in settings ) { | |
10562 if ( settings.disabled ) { | |
10563 this._disableDatepicker(target); | |
10564 } else { | |
10565 this._enableDatepicker(target); | |
10566 } | |
10567 } | |
10568 this._attachments($(target), inst); | |
10569 this._autoSize(inst); | |
10570 this._setDate(inst, date); | |
10571 this._updateAlternate(inst); | |
10572 this._updateDatepicker(inst); | |
10573 } | |
10574 }, | |
10575 | |
10576 // change method deprecated | |
10577 _changeDatepicker: function(target, name, value) { | |
10578 this._optionDatepicker(target, name, value); | |
10579 }, | |
10580 | |
10581 /* Redraw the date picker attached to an input field or division. | |
10582 * @param target element - the target input field or division or span | |
10583 */ | |
10584 _refreshDatepicker: function(target) { | |
10585 var inst = this._getInst(target); | |
10586 if (inst) { | |
10587 this._updateDatepicker(inst); | |
10588 } | |
10589 }, | |
10590 | |
10591 /* Set the dates for a jQuery selection. | |
10592 * @param target element - the target input field or division or span | |
10593 * @param date Date - the new date | |
10594 */ | |
10595 _setDateDatepicker: function(target, date) { | |
10596 var inst = this._getInst(target); | |
10597 if (inst) { | |
10598 this._setDate(inst, date); | |
10599 this._updateDatepicker(inst); | |
10600 this._updateAlternate(inst); | |
10601 } | |
10602 }, | |
10603 | |
10604 /* Get the date(s) for the first entry in a jQuery selection. | |
10605 * @param target element - the target input field or division or span | |
10606 * @param noDefault boolean - true if no default date is to be used | |
10607 * @return Date - the current date | |
10608 */ | |
10609 _getDateDatepicker: function(target, noDefault) { | |
10610 var inst = this._getInst(target); | |
10611 if (inst && !inst.inline) { | |
10612 this._setDateFromField(inst, noDefault); | |
10613 } | |
10614 return (inst ? this._getDate(inst) : null); | |
10615 }, | |
10616 | |
10617 /* Handle keystrokes. */ | |
10618 _doKeyDown: function(event) { | |
10619 var onSelect, dateStr, sel, | |
10620 inst = $.datepicker._getInst(event.target), | |
10621 handled = true, | |
10622 isRTL = inst.dpDiv.is(".ui-datepicker-rtl"); | |
10623 | |
10624 inst._keyEvent = true; | |
10625 if ($.datepicker._datepickerShowing) { | |
10626 switch (event.keyCode) { | |
10627 case 9: $.datepicker._hideDatepicker(); | |
10628 handled = false; | |
10629 break; // hide on tab out | |
10630 case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." + | |
10631 $.datepicker._currentClass + ")", inst.dpDiv); | |
10632 if (sel[0]) { | |
10633 $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); | |
10634 } | |
10635 | |
10636 onSelect = $.datepicker._get(inst, "onSelect"); | |
10637 if (onSelect) { | |
10638 dateStr = $.datepicker._formatDate(inst); | |
10639 | |
10640 // trigger custom callback | |
10641 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); | |
10642 } else { | |
10643 $.datepicker._hideDatepicker(); | |
10644 } | |
10645 | |
10646 return false; // don't submit the form | |
10647 case 27: $.datepicker._hideDatepicker(); | |
10648 break; // hide on escape | |
10649 case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10650 -$.datepicker._get(inst, "stepBigMonths") : | |
10651 -$.datepicker._get(inst, "stepMonths")), "M"); | |
10652 break; // previous month/year on page up/+ ctrl | |
10653 case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10654 +$.datepicker._get(inst, "stepBigMonths") : | |
10655 +$.datepicker._get(inst, "stepMonths")), "M"); | |
10656 break; // next month/year on page down/+ ctrl | |
10657 case 35: if (event.ctrlKey || event.metaKey) { | |
10658 $.datepicker._clearDate(event.target); | |
10659 } | |
10660 handled = event.ctrlKey || event.metaKey; | |
10661 break; // clear on ctrl or command +end | |
10662 case 36: if (event.ctrlKey || event.metaKey) { | |
10663 $.datepicker._gotoToday(event.target); | |
10664 } | |
10665 handled = event.ctrlKey || event.metaKey; | |
10666 break; // current on ctrl or command +home | |
10667 case 37: if (event.ctrlKey || event.metaKey) { | |
10668 $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D"); | |
10669 } | |
10670 handled = event.ctrlKey || event.metaKey; | |
10671 // -1 day on ctrl or command +left | |
10672 if (event.originalEvent.altKey) { | |
10673 $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10674 -$.datepicker._get(inst, "stepBigMonths") : | |
10675 -$.datepicker._get(inst, "stepMonths")), "M"); | |
10676 } | |
10677 // next month/year on alt +left on Mac | |
10678 break; | |
10679 case 38: if (event.ctrlKey || event.metaKey) { | |
10680 $.datepicker._adjustDate(event.target, -7, "D"); | |
10681 } | |
10682 handled = event.ctrlKey || event.metaKey; | |
10683 break; // -1 week on ctrl or command +up | |
10684 case 39: if (event.ctrlKey || event.metaKey) { | |
10685 $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D"); | |
10686 } | |
10687 handled = event.ctrlKey || event.metaKey; | |
10688 // +1 day on ctrl or command +right | |
10689 if (event.originalEvent.altKey) { | |
10690 $.datepicker._adjustDate(event.target, (event.ctrlKey ? | |
10691 +$.datepicker._get(inst, "stepBigMonths") : | |
10692 +$.datepicker._get(inst, "stepMonths")), "M"); | |
10693 } | |
10694 // next month/year on alt +right | |
10695 break; | |
10696 case 40: if (event.ctrlKey || event.metaKey) { | |
10697 $.datepicker._adjustDate(event.target, +7, "D"); | |
10698 } | |
10699 handled = event.ctrlKey || event.metaKey; | |
10700 break; // +1 week on ctrl or command +down | |
10701 default: handled = false; | |
10702 } | |
10703 } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home | |
10704 $.datepicker._showDatepicker(this); | |
10705 } else { | |
10706 handled = false; | |
10707 } | |
10708 | |
10709 if (handled) { | |
10710 event.preventDefault(); | |
10711 event.stopPropagation(); | |
10712 } | |
10713 }, | |
10714 | |
10715 /* Filter entered characters - based on date format. */ | |
10716 _doKeyPress: function(event) { | |
10717 var chars, chr, | |
10718 inst = $.datepicker._getInst(event.target); | |
10719 | |
10720 if ($.datepicker._get(inst, "constrainInput")) { | |
10721 chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat")); | |
10722 chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode); | |
10723 return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1); | |
10724 } | |
10725 }, | |
10726 | |
10727 /* Synchronise manual entry and field/alternate field. */ | |
10728 _doKeyUp: function(event) { | |
10729 var date, | |
10730 inst = $.datepicker._getInst(event.target); | |
10731 | |
10732 if (inst.input.val() !== inst.lastVal) { | |
10733 try { | |
10734 date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), | |
10735 (inst.input ? inst.input.val() : null), | |
10736 $.datepicker._getFormatConfig(inst)); | |
10737 | |
10738 if (date) { // only if valid | |
10739 $.datepicker._setDateFromField(inst); | |
10740 $.datepicker._updateAlternate(inst); | |
10741 $.datepicker._updateDatepicker(inst); | |
10742 } | |
10743 } | |
10744 catch (err) { | |
10745 } | |
10746 } | |
10747 return true; | |
10748 }, | |
10749 | |
10750 /* Pop-up the date picker for a given input field. | |
10751 * If false returned from beforeShow event handler do not show. | |
10752 * @param input element - the input field attached to the date picker or | |
10753 * event - if triggered by focus | |
10754 */ | |
10755 _showDatepicker: function(input) { | |
10756 input = input.target || input; | |
10757 if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger | |
10758 input = $("input", input.parentNode)[0]; | |
10759 } | |
10760 | |
10761 if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here | |
10762 return; | |
10763 } | |
10764 | |
10765 var inst, beforeShow, beforeShowSettings, isFixed, | |
10766 offset, showAnim, duration; | |
10767 | |
10768 inst = $.datepicker._getInst(input); | |
10769 if ($.datepicker._curInst && $.datepicker._curInst !== inst) { | |
10770 $.datepicker._curInst.dpDiv.stop(true, true); | |
10771 if ( inst && $.datepicker._datepickerShowing ) { | |
10772 $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); | |
10773 } | |
10774 } | |
10775 | |
10776 beforeShow = $.datepicker._get(inst, "beforeShow"); | |
10777 beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; | |
10778 if(beforeShowSettings === false){ | |
10779 return; | |
10780 } | |
10781 extendRemove(inst.settings, beforeShowSettings); | |
10782 | |
10783 inst.lastVal = null; | |
10784 $.datepicker._lastInput = input; | |
10785 $.datepicker._setDateFromField(inst); | |
10786 | |
10787 if ($.datepicker._inDialog) { // hide cursor | |
10788 input.value = ""; | |
10789 } | |
10790 if (!$.datepicker._pos) { // position below input | |
10791 $.datepicker._pos = $.datepicker._findPos(input); | |
10792 $.datepicker._pos[1] += input.offsetHeight; // add the height | |
10793 } | |
10794 | |
10795 isFixed = false; | |
10796 $(input).parents().each(function() { | |
10797 isFixed |= $(this).css("position") === "fixed"; | |
10798 return !isFixed; | |
10799 }); | |
10800 | |
10801 offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; | |
10802 $.datepicker._pos = null; | |
10803 //to avoid flashes on Firefox | |
10804 inst.dpDiv.empty(); | |
10805 // determine sizing offscreen | |
10806 inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"}); | |
10807 $.datepicker._updateDatepicker(inst); | |
10808 // fix width for dynamic number of date pickers | |
10809 // and adjust position before showing | |
10810 offset = $.datepicker._checkOffset(inst, offset, isFixed); | |
10811 inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? | |
10812 "static" : (isFixed ? "fixed" : "absolute")), display: "none", | |
10813 left: offset.left + "px", top: offset.top + "px"}); | |
10814 | |
10815 if (!inst.inline) { | |
10816 showAnim = $.datepicker._get(inst, "showAnim"); | |
10817 duration = $.datepicker._get(inst, "duration"); | |
10818 inst.dpDiv.zIndex($(input).zIndex()+1); | |
10819 $.datepicker._datepickerShowing = true; | |
10820 | |
10821 if ( $.effects && $.effects.effect[ showAnim ] ) { | |
10822 inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration); | |
10823 } else { | |
10824 inst.dpDiv[showAnim || "show"](showAnim ? duration : null); | |
10825 } | |
10826 | |
10827 if ( $.datepicker._shouldFocusInput( inst ) ) { | |
10828 inst.input.focus(); | |
10829 } | |
10830 | |
10831 $.datepicker._curInst = inst; | |
10832 } | |
10833 }, | |
10834 | |
10835 /* Generate the date picker content. */ | |
10836 _updateDatepicker: function(inst) { | |
10837 this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) | |
10838 instActive = inst; // for delegate hover events | |
10839 inst.dpDiv.empty().append(this._generateHTML(inst)); | |
10840 this._attachHandlers(inst); | |
10841 inst.dpDiv.find("." + this._dayOverClass + " a").mouseover(); | |
10842 | |
10843 var origyearshtml, | |
10844 numMonths = this._getNumberOfMonths(inst), | |
10845 cols = numMonths[1], | |
10846 width = 17; | |
10847 | |
10848 inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""); | |
10849 if (cols > 1) { | |
10850 inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em"); | |
10851 } | |
10852 inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") + | |
10853 "Class"]("ui-datepicker-multi"); | |
10854 inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") + | |
10855 "Class"]("ui-datepicker-rtl"); | |
10856 | |
10857 if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { | |
10858 inst.input.focus(); | |
10859 } | |
10860 | |
10861 // deffered render of the years select (to avoid flashes on Firefox) | |
10862 if( inst.yearshtml ){ | |
10863 origyearshtml = inst.yearshtml; | |
10864 setTimeout(function(){ | |
10865 //assure that inst.yearshtml didn't change. | |
10866 if( origyearshtml === inst.yearshtml && inst.yearshtml ){ | |
10867 inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml); | |
10868 } | |
10869 origyearshtml = inst.yearshtml = null; | |
10870 }, 0); | |
10871 } | |
10872 }, | |
10873 | |
10874 // #6694 - don't focus the input if it's already focused | |
10875 // this breaks the change event in IE | |
10876 // Support: IE and jQuery <1.9 | |
10877 _shouldFocusInput: function( inst ) { | |
10878 return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); | |
10879 }, | |
10880 | |
10881 /* Check positioning to remain on screen. */ | |
10882 _checkOffset: function(inst, offset, isFixed) { | |
10883 var dpWidth = inst.dpDiv.outerWidth(), | |
10884 dpHeight = inst.dpDiv.outerHeight(), | |
10885 inputWidth = inst.input ? inst.input.outerWidth() : 0, | |
10886 inputHeight = inst.input ? inst.input.outerHeight() : 0, | |
10887 viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()), | |
10888 viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop()); | |
10889 | |
10890 offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0); | |
10891 offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0; | |
10892 offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; | |
10893 | |
10894 // now check if datepicker is showing outside window viewport - move to a better place if so. | |
10895 offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? | |
10896 Math.abs(offset.left + dpWidth - viewWidth) : 0); | |
10897 offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? | |
10898 Math.abs(dpHeight + inputHeight) : 0); | |
10899 | |
10900 return offset; | |
10901 }, | |
10902 | |
10903 /* Find an object's position on the screen. */ | |
10904 _findPos: function(obj) { | |
10905 var position, | |
10906 inst = this._getInst(obj), | |
10907 isRTL = this._get(inst, "isRTL"); | |
10908 | |
10909 while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) { | |
10910 obj = obj[isRTL ? "previousSibling" : "nextSibling"]; | |
10911 } | |
10912 | |
10913 position = $(obj).offset(); | |
10914 return [position.left, position.top]; | |
10915 }, | |
10916 | |
10917 /* Hide the date picker from view. | |
10918 * @param input element - the input field attached to the date picker | |
10919 */ | |
10920 _hideDatepicker: function(input) { | |
10921 var showAnim, duration, postProcess, onClose, | |
10922 inst = this._curInst; | |
10923 | |
10924 if (!inst || (input && inst !== $.data(input, PROP_NAME))) { | |
10925 return; | |
10926 } | |
10927 | |
10928 if (this._datepickerShowing) { | |
10929 showAnim = this._get(inst, "showAnim"); | |
10930 duration = this._get(inst, "duration"); | |
10931 postProcess = function() { | |
10932 $.datepicker._tidyDialog(inst); | |
10933 }; | |
10934 | |
10935 // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed | |
10936 if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { | |
10937 inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess); | |
10938 } else { | |
10939 inst.dpDiv[(showAnim === "slideDown" ? "slideUp" : | |
10940 (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess); | |
10941 } | |
10942 | |
10943 if (!showAnim) { | |
10944 postProcess(); | |
10945 } | |
10946 this._datepickerShowing = false; | |
10947 | |
10948 onClose = this._get(inst, "onClose"); | |
10949 if (onClose) { | |
10950 onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]); | |
10951 } | |
10952 | |
10953 this._lastInput = null; | |
10954 if (this._inDialog) { | |
10955 this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" }); | |
10956 if ($.blockUI) { | |
10957 $.unblockUI(); | |
10958 $("body").append(this.dpDiv); | |
10959 } | |
10960 } | |
10961 this._inDialog = false; | |
10962 } | |
10963 }, | |
10964 | |
10965 /* Tidy up after a dialog display. */ | |
10966 _tidyDialog: function(inst) { | |
10967 inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar"); | |
10968 }, | |
10969 | |
10970 /* Close date picker if clicked elsewhere. */ | |
10971 _checkExternalClick: function(event) { | |
10972 if (!$.datepicker._curInst) { | |
10973 return; | |
10974 } | |
10975 | |
10976 var $target = $(event.target), | |
10977 inst = $.datepicker._getInst($target[0]); | |
10978 | |
10979 if ( ( ( $target[0].id !== $.datepicker._mainDivId && | |
10980 $target.parents("#" + $.datepicker._mainDivId).length === 0 && | |
10981 !$target.hasClass($.datepicker.markerClassName) && | |
10982 !$target.closest("." + $.datepicker._triggerClass).length && | |
10983 $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || | |
10984 ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) { | |
10985 $.datepicker._hideDatepicker(); | |
10986 } | |
10987 }, | |
10988 | |
10989 /* Adjust one of the date sub-fields. */ | |
10990 _adjustDate: function(id, offset, period) { | |
10991 var target = $(id), | |
10992 inst = this._getInst(target[0]); | |
10993 | |
10994 if (this._isDisabledDatepicker(target[0])) { | |
10995 return; | |
10996 } | |
10997 this._adjustInstDate(inst, offset + | |
10998 (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning | |
10999 period); | |
11000 this._updateDatepicker(inst); | |
11001 }, | |
11002 | |
11003 /* Action for current link. */ | |
11004 _gotoToday: function(id) { | |
11005 var date, | |
11006 target = $(id), | |
11007 inst = this._getInst(target[0]); | |
11008 | |
11009 if (this._get(inst, "gotoCurrent") && inst.currentDay) { | |
11010 inst.selectedDay = inst.currentDay; | |
11011 inst.drawMonth = inst.selectedMonth = inst.currentMonth; | |
11012 inst.drawYear = inst.selectedYear = inst.currentYear; | |
11013 } else { | |
11014 date = new Date(); | |
11015 inst.selectedDay = date.getDate(); | |
11016 inst.drawMonth = inst.selectedMonth = date.getMonth(); | |
11017 inst.drawYear = inst.selectedYear = date.getFullYear(); | |
11018 } | |
11019 this._notifyChange(inst); | |
11020 this._adjustDate(target); | |
11021 }, | |
11022 | |
11023 /* Action for selecting a new month/year. */ | |
11024 _selectMonthYear: function(id, select, period) { | |
11025 var target = $(id), | |
11026 inst = this._getInst(target[0]); | |
11027 | |
11028 inst["selected" + (period === "M" ? "Month" : "Year")] = | |
11029 inst["draw" + (period === "M" ? "Month" : "Year")] = | |
11030 parseInt(select.options[select.selectedIndex].value,10); | |
11031 | |
11032 this._notifyChange(inst); | |
11033 this._adjustDate(target); | |
11034 }, | |
11035 | |
11036 /* Action for selecting a day. */ | |
11037 _selectDay: function(id, month, year, td) { | |
11038 var inst, | |
11039 target = $(id); | |
11040 | |
11041 if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { | |
11042 return; | |
11043 } | |
11044 | |
11045 inst = this._getInst(target[0]); | |
11046 inst.selectedDay = inst.currentDay = $("a", td).html(); | |
11047 inst.selectedMonth = inst.currentMonth = month; | |
11048 inst.selectedYear = inst.currentYear = year; | |
11049 this._selectDate(id, this._formatDate(inst, | |
11050 inst.currentDay, inst.currentMonth, inst.currentYear)); | |
11051 }, | |
11052 | |
11053 /* Erase the input field and hide the date picker. */ | |
11054 _clearDate: function(id) { | |
11055 var target = $(id); | |
11056 this._selectDate(target, ""); | |
11057 }, | |
11058 | |
11059 /* Update the input field with the selected date. */ | |
11060 _selectDate: function(id, dateStr) { | |
11061 var onSelect, | |
11062 target = $(id), | |
11063 inst = this._getInst(target[0]); | |
11064 | |
11065 dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); | |
11066 if (inst.input) { | |
11067 inst.input.val(dateStr); | |
11068 } | |
11069 this._updateAlternate(inst); | |
11070 | |
11071 onSelect = this._get(inst, "onSelect"); | |
11072 if (onSelect) { | |
11073 onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback | |
11074 } else if (inst.input) { | |
11075 inst.input.trigger("change"); // fire the change event | |
11076 } | |
11077 | |
11078 if (inst.inline){ | |
11079 this._updateDatepicker(inst); | |
11080 } else { | |
11081 this._hideDatepicker(); | |
11082 this._lastInput = inst.input[0]; | |
11083 if (typeof(inst.input[0]) !== "object") { | |
11084 inst.input.focus(); // restore focus | |
11085 } | |
11086 this._lastInput = null; | |
11087 } | |
11088 }, | |
11089 | |
11090 /* Update any alternate field to synchronise with the main field. */ | |
11091 _updateAlternate: function(inst) { | |
11092 var altFormat, date, dateStr, | |
11093 altField = this._get(inst, "altField"); | |
11094 | |
11095 if (altField) { // update alternate field too | |
11096 altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat"); | |
11097 date = this._getDate(inst); | |
11098 dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); | |
11099 $(altField).each(function() { $(this).val(dateStr); }); | |
11100 } | |
11101 }, | |
11102 | |
11103 /* Set as beforeShowDay function to prevent selection of weekends. | |
11104 * @param date Date - the date to customise | |
11105 * @return [boolean, string] - is this date selectable?, what is its CSS class? | |
11106 */ | |
11107 noWeekends: function(date) { | |
11108 var day = date.getDay(); | |
11109 return [(day > 0 && day < 6), ""]; | |
11110 }, | |
11111 | |
11112 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. | |
11113 * @param date Date - the date to get the week for | |
11114 * @return number - the number of the week within the year that contains this date | |
11115 */ | |
11116 iso8601Week: function(date) { | |
11117 var time, | |
11118 checkDate = new Date(date.getTime()); | |
11119 | |
11120 // Find Thursday of this week starting on Monday | |
11121 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); | |
11122 | |
11123 time = checkDate.getTime(); | |
11124 checkDate.setMonth(0); // Compare with Jan 1 | |
11125 checkDate.setDate(1); | |
11126 return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; | |
11127 }, | |
11128 | |
11129 /* Parse a string value into a date object. | |
11130 * See formatDate below for the possible formats. | |
11131 * | |
11132 * @param format string - the expected format of the date | |
11133 * @param value string - the date in the above format | |
11134 * @param settings Object - attributes include: | |
11135 * shortYearCutoff number - the cutoff year for determining the century (optional) | |
11136 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) | |
11137 * dayNames string[7] - names of the days from Sunday (optional) | |
11138 * monthNamesShort string[12] - abbreviated names of the months (optional) | |
11139 * monthNames string[12] - names of the months (optional) | |
11140 * @return Date - the extracted date value or null if value is blank | |
11141 */ | |
11142 parseDate: function (format, value, settings) { | |
11143 if (format == null || value == null) { | |
11144 throw "Invalid arguments"; | |
11145 } | |
11146 | |
11147 value = (typeof value === "object" ? value.toString() : value + ""); | |
11148 if (value === "") { | |
11149 return null; | |
11150 } | |
11151 | |
11152 var iFormat, dim, extra, | |
11153 iValue = 0, | |
11154 shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff, | |
11155 shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : | |
11156 new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)), | |
11157 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, | |
11158 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, | |
11159 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, | |
11160 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, | |
11161 year = -1, | |
11162 month = -1, | |
11163 day = -1, | |
11164 doy = -1, | |
11165 literal = false, | |
11166 date, | |
11167 // Check whether a format character is doubled | |
11168 lookAhead = function(match) { | |
11169 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); | |
11170 if (matches) { | |
11171 iFormat++; | |
11172 } | |
11173 return matches; | |
11174 }, | |
11175 // Extract a number from the string value | |
11176 getNumber = function(match) { | |
11177 var isDoubled = lookAhead(match), | |
11178 size = (match === "@" ? 14 : (match === "!" ? 20 : | |
11179 (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))), | |
11180 digits = new RegExp("^\\d{1," + size + "}"), | |
11181 num = value.substring(iValue).match(digits); | |
11182 if (!num) { | |
11183 throw "Missing number at position " + iValue; | |
11184 } | |
11185 iValue += num[0].length; | |
11186 return parseInt(num[0], 10); | |
11187 }, | |
11188 // Extract a name from the string value and convert to an index | |
11189 getName = function(match, shortNames, longNames) { | |
11190 var index = -1, | |
11191 names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { | |
11192 return [ [k, v] ]; | |
11193 }).sort(function (a, b) { | |
11194 return -(a[1].length - b[1].length); | |
11195 }); | |
11196 | |
11197 $.each(names, function (i, pair) { | |
11198 var name = pair[1]; | |
11199 if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) { | |
11200 index = pair[0]; | |
11201 iValue += name.length; | |
11202 return false; | |
11203 } | |
11204 }); | |
11205 if (index !== -1) { | |
11206 return index + 1; | |
11207 } else { | |
11208 throw "Unknown name at position " + iValue; | |
11209 } | |
11210 }, | |
11211 // Confirm that a literal character matches the string value | |
11212 checkLiteral = function() { | |
11213 if (value.charAt(iValue) !== format.charAt(iFormat)) { | |
11214 throw "Unexpected literal at position " + iValue; | |
11215 } | |
11216 iValue++; | |
11217 }; | |
11218 | |
11219 for (iFormat = 0; iFormat < format.length; iFormat++) { | |
11220 if (literal) { | |
11221 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { | |
11222 literal = false; | |
11223 } else { | |
11224 checkLiteral(); | |
11225 } | |
11226 } else { | |
11227 switch (format.charAt(iFormat)) { | |
11228 case "d": | |
11229 day = getNumber("d"); | |
11230 break; | |
11231 case "D": | |
11232 getName("D", dayNamesShort, dayNames); | |
11233 break; | |
11234 case "o": | |
11235 doy = getNumber("o"); | |
11236 break; | |
11237 case "m": | |
11238 month = getNumber("m"); | |
11239 break; | |
11240 case "M": | |
11241 month = getName("M", monthNamesShort, monthNames); | |
11242 break; | |
11243 case "y": | |
11244 year = getNumber("y"); | |
11245 break; | |
11246 case "@": | |
11247 date = new Date(getNumber("@")); | |
11248 year = date.getFullYear(); | |
11249 month = date.getMonth() + 1; | |
11250 day = date.getDate(); | |
11251 break; | |
11252 case "!": | |
11253 date = new Date((getNumber("!") - this._ticksTo1970) / 10000); | |
11254 year = date.getFullYear(); | |
11255 month = date.getMonth() + 1; | |
11256 day = date.getDate(); | |
11257 break; | |
11258 case "'": | |
11259 if (lookAhead("'")){ | |
11260 checkLiteral(); | |
11261 } else { | |
11262 literal = true; | |
11263 } | |
11264 break; | |
11265 default: | |
11266 checkLiteral(); | |
11267 } | |
11268 } | |
11269 } | |
11270 | |
11271 if (iValue < value.length){ | |
11272 extra = value.substr(iValue); | |
11273 if (!/^\s+/.test(extra)) { | |
11274 throw "Extra/unparsed characters found in date: " + extra; | |
11275 } | |
11276 } | |
11277 | |
11278 if (year === -1) { | |
11279 year = new Date().getFullYear(); | |
11280 } else if (year < 100) { | |
11281 year += new Date().getFullYear() - new Date().getFullYear() % 100 + | |
11282 (year <= shortYearCutoff ? 0 : -100); | |
11283 } | |
11284 | |
11285 if (doy > -1) { | |
11286 month = 1; | |
11287 day = doy; | |
11288 do { | |
11289 dim = this._getDaysInMonth(year, month - 1); | |
11290 if (day <= dim) { | |
11291 break; | |
11292 } | |
11293 month++; | |
11294 day -= dim; | |
11295 } while (true); | |
11296 } | |
11297 | |
11298 date = this._daylightSavingAdjust(new Date(year, month - 1, day)); | |
11299 if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) { | |
11300 throw "Invalid date"; // E.g. 31/02/00 | |
11301 } | |
11302 return date; | |
11303 }, | |
11304 | |
11305 /* Standard date formats. */ | |
11306 ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) | |
11307 COOKIE: "D, dd M yy", | |
11308 ISO_8601: "yy-mm-dd", | |
11309 RFC_822: "D, d M y", | |
11310 RFC_850: "DD, dd-M-y", | |
11311 RFC_1036: "D, d M y", | |
11312 RFC_1123: "D, d M yy", | |
11313 RFC_2822: "D, d M yy", | |
11314 RSS: "D, d M y", // RFC 822 | |
11315 TICKS: "!", | |
11316 TIMESTAMP: "@", | |
11317 W3C: "yy-mm-dd", // ISO 8601 | |
11318 | |
11319 _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + | |
11320 Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), | |
11321 | |
11322 /* Format a date object into a string value. | |
11323 * The format can be combinations of the following: | |
11324 * d - day of month (no leading zero) | |
11325 * dd - day of month (two digit) | |
11326 * o - day of year (no leading zeros) | |
11327 * oo - day of year (three digit) | |
11328 * D - day name short | |
11329 * DD - day name long | |
11330 * m - month of year (no leading zero) | |
11331 * mm - month of year (two digit) | |
11332 * M - month name short | |
11333 * MM - month name long | |
11334 * y - year (two digit) | |
11335 * yy - year (four digit) | |
11336 * @ - Unix timestamp (ms since 01/01/1970) | |
11337 * ! - Windows ticks (100ns since 01/01/0001) | |
11338 * "..." - literal text | |
11339 * '' - single quote | |
11340 * | |
11341 * @param format string - the desired format of the date | |
11342 * @param date Date - the date value to format | |
11343 * @param settings Object - attributes include: | |
11344 * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) | |
11345 * dayNames string[7] - names of the days from Sunday (optional) | |
11346 * monthNamesShort string[12] - abbreviated names of the months (optional) | |
11347 * monthNames string[12] - names of the months (optional) | |
11348 * @return string - the date in the above format | |
11349 */ | |
11350 formatDate: function (format, date, settings) { | |
11351 if (!date) { | |
11352 return ""; | |
11353 } | |
11354 | |
11355 var iFormat, | |
11356 dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort, | |
11357 dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames, | |
11358 monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort, | |
11359 monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames, | |
11360 // Check whether a format character is doubled | |
11361 lookAhead = function(match) { | |
11362 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); | |
11363 if (matches) { | |
11364 iFormat++; | |
11365 } | |
11366 return matches; | |
11367 }, | |
11368 // Format a number, with leading zero if necessary | |
11369 formatNumber = function(match, value, len) { | |
11370 var num = "" + value; | |
11371 if (lookAhead(match)) { | |
11372 while (num.length < len) { | |
11373 num = "0" + num; | |
11374 } | |
11375 } | |
11376 return num; | |
11377 }, | |
11378 // Format a name, short or long as requested | |
11379 formatName = function(match, value, shortNames, longNames) { | |
11380 return (lookAhead(match) ? longNames[value] : shortNames[value]); | |
11381 }, | |
11382 output = "", | |
11383 literal = false; | |
11384 | |
11385 if (date) { | |
11386 for (iFormat = 0; iFormat < format.length; iFormat++) { | |
11387 if (literal) { | |
11388 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { | |
11389 literal = false; | |
11390 } else { | |
11391 output += format.charAt(iFormat); | |
11392 } | |
11393 } else { | |
11394 switch (format.charAt(iFormat)) { | |
11395 case "d": | |
11396 output += formatNumber("d", date.getDate(), 2); | |
11397 break; | |
11398 case "D": | |
11399 output += formatName("D", date.getDay(), dayNamesShort, dayNames); | |
11400 break; | |
11401 case "o": | |
11402 output += formatNumber("o", | |
11403 Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); | |
11404 break; | |
11405 case "m": | |
11406 output += formatNumber("m", date.getMonth() + 1, 2); | |
11407 break; | |
11408 case "M": | |
11409 output += formatName("M", date.getMonth(), monthNamesShort, monthNames); | |
11410 break; | |
11411 case "y": | |
11412 output += (lookAhead("y") ? date.getFullYear() : | |
11413 (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100); | |
11414 break; | |
11415 case "@": | |
11416 output += date.getTime(); | |
11417 break; | |
11418 case "!": | |
11419 output += date.getTime() * 10000 + this._ticksTo1970; | |
11420 break; | |
11421 case "'": | |
11422 if (lookAhead("'")) { | |
11423 output += "'"; | |
11424 } else { | |
11425 literal = true; | |
11426 } | |
11427 break; | |
11428 default: | |
11429 output += format.charAt(iFormat); | |
11430 } | |
11431 } | |
11432 } | |
11433 } | |
11434 return output; | |
11435 }, | |
11436 | |
11437 /* Extract all possible characters from the date format. */ | |
11438 _possibleChars: function (format) { | |
11439 var iFormat, | |
11440 chars = "", | |
11441 literal = false, | |
11442 // Check whether a format character is doubled | |
11443 lookAhead = function(match) { | |
11444 var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match); | |
11445 if (matches) { | |
11446 iFormat++; | |
11447 } | |
11448 return matches; | |
11449 }; | |
11450 | |
11451 for (iFormat = 0; iFormat < format.length; iFormat++) { | |
11452 if (literal) { | |
11453 if (format.charAt(iFormat) === "'" && !lookAhead("'")) { | |
11454 literal = false; | |
11455 } else { | |
11456 chars += format.charAt(iFormat); | |
11457 } | |
11458 } else { | |
11459 switch (format.charAt(iFormat)) { | |
11460 case "d": case "m": case "y": case "@": | |
11461 chars += "0123456789"; | |
11462 break; | |
11463 case "D": case "M": | |
11464 return null; // Accept anything | |
11465 case "'": | |
11466 if (lookAhead("'")) { | |
11467 chars += "'"; | |
11468 } else { | |
11469 literal = true; | |
11470 } | |
11471 break; | |
11472 default: | |
11473 chars += format.charAt(iFormat); | |
11474 } | |
11475 } | |
11476 } | |
11477 return chars; | |
11478 }, | |
11479 | |
11480 /* Get a setting value, defaulting if necessary. */ | |
11481 _get: function(inst, name) { | |
11482 return inst.settings[name] !== undefined ? | |
11483 inst.settings[name] : this._defaults[name]; | |
11484 }, | |
11485 | |
11486 /* Parse existing date and initialise date picker. */ | |
11487 _setDateFromField: function(inst, noDefault) { | |
11488 if (inst.input.val() === inst.lastVal) { | |
11489 return; | |
11490 } | |
11491 | |
11492 var dateFormat = this._get(inst, "dateFormat"), | |
11493 dates = inst.lastVal = inst.input ? inst.input.val() : null, | |
11494 defaultDate = this._getDefaultDate(inst), | |
11495 date = defaultDate, | |
11496 settings = this._getFormatConfig(inst); | |
11497 | |
11498 try { | |
11499 date = this.parseDate(dateFormat, dates, settings) || defaultDate; | |
11500 } catch (event) { | |
11501 dates = (noDefault ? "" : dates); | |
11502 } | |
11503 inst.selectedDay = date.getDate(); | |
11504 inst.drawMonth = inst.selectedMonth = date.getMonth(); | |
11505 inst.drawYear = inst.selectedYear = date.getFullYear(); | |
11506 inst.currentDay = (dates ? date.getDate() : 0); | |
11507 inst.currentMonth = (dates ? date.getMonth() : 0); | |
11508 inst.currentYear = (dates ? date.getFullYear() : 0); | |
11509 this._adjustInstDate(inst); | |
11510 }, | |
11511 | |
11512 /* Retrieve the default date shown on opening. */ | |
11513 _getDefaultDate: function(inst) { | |
11514 return this._restrictMinMax(inst, | |
11515 this._determineDate(inst, this._get(inst, "defaultDate"), new Date())); | |
11516 }, | |
11517 | |
11518 /* A date may be specified as an exact value or a relative one. */ | |
11519 _determineDate: function(inst, date, defaultDate) { | |
11520 var offsetNumeric = function(offset) { | |
11521 var date = new Date(); | |
11522 date.setDate(date.getDate() + offset); | |
11523 return date; | |
11524 }, | |
11525 offsetString = function(offset) { | |
11526 try { | |
11527 return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"), | |
11528 offset, $.datepicker._getFormatConfig(inst)); | |
11529 } | |
11530 catch (e) { | |
11531 // Ignore | |
11532 } | |
11533 | |
11534 var date = (offset.toLowerCase().match(/^c/) ? | |
11535 $.datepicker._getDate(inst) : null) || new Date(), | |
11536 year = date.getFullYear(), | |
11537 month = date.getMonth(), | |
11538 day = date.getDate(), | |
11539 pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, | |
11540 matches = pattern.exec(offset); | |
11541 | |
11542 while (matches) { | |
11543 switch (matches[2] || "d") { | |
11544 case "d" : case "D" : | |
11545 day += parseInt(matches[1],10); break; | |
11546 case "w" : case "W" : | |
11547 day += parseInt(matches[1],10) * 7; break; | |
11548 case "m" : case "M" : | |
11549 month += parseInt(matches[1],10); | |
11550 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); | |
11551 break; | |
11552 case "y": case "Y" : | |
11553 year += parseInt(matches[1],10); | |
11554 day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); | |
11555 break; | |
11556 } | |
11557 matches = pattern.exec(offset); | |
11558 } | |
11559 return new Date(year, month, day); | |
11560 }, | |
11561 newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) : | |
11562 (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); | |
11563 | |
11564 newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate); | |
11565 if (newDate) { | |
11566 newDate.setHours(0); | |
11567 newDate.setMinutes(0); | |
11568 newDate.setSeconds(0); | |
11569 newDate.setMilliseconds(0); | |
11570 } | |
11571 return this._daylightSavingAdjust(newDate); | |
11572 }, | |
11573 | |
11574 /* Handle switch to/from daylight saving. | |
11575 * Hours may be non-zero on daylight saving cut-over: | |
11576 * > 12 when midnight changeover, but then cannot generate | |
11577 * midnight datetime, so jump to 1AM, otherwise reset. | |
11578 * @param date (Date) the date to check | |
11579 * @return (Date) the corrected date | |
11580 */ | |
11581 _daylightSavingAdjust: function(date) { | |
11582 if (!date) { | |
11583 return null; | |
11584 } | |
11585 date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); | |
11586 return date; | |
11587 }, | |
11588 | |
11589 /* Set the date(s) directly. */ | |
11590 _setDate: function(inst, date, noChange) { | |
11591 var clear = !date, | |
11592 origMonth = inst.selectedMonth, | |
11593 origYear = inst.selectedYear, | |
11594 newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); | |
11595 | |
11596 inst.selectedDay = inst.currentDay = newDate.getDate(); | |
11597 inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); | |
11598 inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); | |
11599 if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) { | |
11600 this._notifyChange(inst); | |
11601 } | |
11602 this._adjustInstDate(inst); | |
11603 if (inst.input) { | |
11604 inst.input.val(clear ? "" : this._formatDate(inst)); | |
11605 } | |
11606 }, | |
11607 | |
11608 /* Retrieve the date(s) directly. */ | |
11609 _getDate: function(inst) { | |
11610 var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null : | |
11611 this._daylightSavingAdjust(new Date( | |
11612 inst.currentYear, inst.currentMonth, inst.currentDay))); | |
11613 return startDate; | |
11614 }, | |
11615 | |
11616 /* Attach the onxxx handlers. These are declared statically so | |
11617 * they work with static code transformers like Caja. | |
11618 */ | |
11619 _attachHandlers: function(inst) { | |
11620 var stepMonths = this._get(inst, "stepMonths"), | |
11621 id = "#" + inst.id.replace( /\\\\/g, "\\" ); | |
11622 inst.dpDiv.find("[data-handler]").map(function () { | |
11623 var handler = { | |
11624 prev: function () { | |
11625 $.datepicker._adjustDate(id, -stepMonths, "M"); | |
11626 }, | |
11627 next: function () { | |
11628 $.datepicker._adjustDate(id, +stepMonths, "M"); | |
11629 }, | |
11630 hide: function () { | |
11631 $.datepicker._hideDatepicker(); | |
11632 }, | |
11633 today: function () { | |
11634 $.datepicker._gotoToday(id); | |
11635 }, | |
11636 selectDay: function () { | |
11637 $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this); | |
11638 return false; | |
11639 }, | |
11640 selectMonth: function () { | |
11641 $.datepicker._selectMonthYear(id, this, "M"); | |
11642 return false; | |
11643 }, | |
11644 selectYear: function () { | |
11645 $.datepicker._selectMonthYear(id, this, "Y"); | |
11646 return false; | |
11647 } | |
11648 }; | |
11649 $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]); | |
11650 }); | |
11651 }, | |
11652 | |
11653 /* Generate the HTML for the current state of the date picker. */ | |
11654 _generateHTML: function(inst) { | |
11655 var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, | |
11656 controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, | |
11657 monthNames, monthNamesShort, beforeShowDay, showOtherMonths, | |
11658 selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, | |
11659 cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, | |
11660 printDate, dRow, tbody, daySettings, otherMonth, unselectable, | |
11661 tempDate = new Date(), | |
11662 today = this._daylightSavingAdjust( | |
11663 new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time | |
11664 isRTL = this._get(inst, "isRTL"), | |
11665 showButtonPanel = this._get(inst, "showButtonPanel"), | |
11666 hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"), | |
11667 navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"), | |
11668 numMonths = this._getNumberOfMonths(inst), | |
11669 showCurrentAtPos = this._get(inst, "showCurrentAtPos"), | |
11670 stepMonths = this._get(inst, "stepMonths"), | |
11671 isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1), | |
11672 currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : | |
11673 new Date(inst.currentYear, inst.currentMonth, inst.currentDay))), | |
11674 minDate = this._getMinMaxDate(inst, "min"), | |
11675 maxDate = this._getMinMaxDate(inst, "max"), | |
11676 drawMonth = inst.drawMonth - showCurrentAtPos, | |
11677 drawYear = inst.drawYear; | |
11678 | |
11679 if (drawMonth < 0) { | |
11680 drawMonth += 12; | |
11681 drawYear--; | |
11682 } | |
11683 if (maxDate) { | |
11684 maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), | |
11685 maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); | |
11686 maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); | |
11687 while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { | |
11688 drawMonth--; | |
11689 if (drawMonth < 0) { | |
11690 drawMonth = 11; | |
11691 drawYear--; | |
11692 } | |
11693 } | |
11694 } | |
11695 inst.drawMonth = drawMonth; | |
11696 inst.drawYear = drawYear; | |
11697 | |
11698 prevText = this._get(inst, "prevText"); | |
11699 prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, | |
11700 this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), | |
11701 this._getFormatConfig(inst))); | |
11702 | |
11703 prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? | |
11704 "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + | |
11705 " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" : | |
11706 (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>")); | |
11707 | |
11708 nextText = this._get(inst, "nextText"); | |
11709 nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, | |
11710 this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), | |
11711 this._getFormatConfig(inst))); | |
11712 | |
11713 next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? | |
11714 "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + | |
11715 " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" : | |
11716 (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>")); | |
11717 | |
11718 currentText = this._get(inst, "currentText"); | |
11719 gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today); | |
11720 currentText = (!navigationAsDateFormat ? currentText : | |
11721 this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); | |
11722 | |
11723 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'>" + | |
11724 this._get(inst, "closeText") + "</button>" : ""); | |
11725 | |
11726 buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") + | |
11727 (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'" + | |
11728 ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : ""; | |
11729 | |
11730 firstDay = parseInt(this._get(inst, "firstDay"),10); | |
11731 firstDay = (isNaN(firstDay) ? 0 : firstDay); | |
11732 | |
11733 showWeek = this._get(inst, "showWeek"); | |
11734 dayNames = this._get(inst, "dayNames"); | |
11735 dayNamesMin = this._get(inst, "dayNamesMin"); | |
11736 monthNames = this._get(inst, "monthNames"); | |
11737 monthNamesShort = this._get(inst, "monthNamesShort"); | |
11738 beforeShowDay = this._get(inst, "beforeShowDay"); | |
11739 showOtherMonths = this._get(inst, "showOtherMonths"); | |
11740 selectOtherMonths = this._get(inst, "selectOtherMonths"); | |
11741 defaultDate = this._getDefaultDate(inst); | |
11742 html = ""; | |
11743 dow; | |
11744 for (row = 0; row < numMonths[0]; row++) { | |
11745 group = ""; | |
11746 this.maxRows = 4; | |
11747 for (col = 0; col < numMonths[1]; col++) { | |
11748 selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); | |
11749 cornerClass = " ui-corner-all"; | |
11750 calender = ""; | |
11751 if (isMultiMonth) { | |
11752 calender += "<div class='ui-datepicker-group"; | |
11753 if (numMonths[1] > 1) { | |
11754 switch (col) { | |
11755 case 0: calender += " ui-datepicker-group-first"; | |
11756 cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break; | |
11757 case numMonths[1]-1: calender += " ui-datepicker-group-last"; | |
11758 cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break; | |
11759 default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; | |
11760 } | |
11761 } | |
11762 calender += "'>"; | |
11763 } | |
11764 calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + | |
11765 (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") + | |
11766 (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") + | |
11767 this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, | |
11768 row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers | |
11769 "</div><table class='ui-datepicker-calendar'><thead>" + | |
11770 "<tr>"; | |
11771 thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : ""); | |
11772 for (dow = 0; dow < 7; dow++) { // days of the week | |
11773 day = (dow + firstDay) % 7; | |
11774 thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + | |
11775 "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>"; | |
11776 } | |
11777 calender += thead + "</tr></thead><tbody>"; | |
11778 daysInMonth = this._getDaysInMonth(drawYear, drawMonth); | |
11779 if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { | |
11780 inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); | |
11781 } | |
11782 leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; | |
11783 curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate | |
11784 numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) | |
11785 this.maxRows = numRows; | |
11786 printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); | |
11787 for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows | |
11788 calender += "<tr>"; | |
11789 tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" + | |
11790 this._get(inst, "calculateWeek")(printDate) + "</td>"); | |
11791 for (dow = 0; dow < 7; dow++) { // create date picker days | |
11792 daySettings = (beforeShowDay ? | |
11793 beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); | |
11794 otherMonth = (printDate.getMonth() !== drawMonth); | |
11795 unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || | |
11796 (minDate && printDate < minDate) || (maxDate && printDate > maxDate); | |
11797 tbody += "<td class='" + | |
11798 ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends | |
11799 (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months | |
11800 ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key | |
11801 (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ? | |
11802 // or defaultDate is current printedDate and defaultDate is selectedDate | |
11803 " " + this._dayOverClass : "") + // highlight selected day | |
11804 (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days | |
11805 (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates | |
11806 (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day | |
11807 (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different) | |
11808 ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "'") + "'" : "") + // cell title | |
11809 (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions | |
11810 (otherMonth && !showOtherMonths ? " " : // display for other months | |
11811 (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + | |
11812 (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") + | |
11813 (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day | |
11814 (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months | |
11815 "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date | |
11816 printDate.setDate(printDate.getDate() + 1); | |
11817 printDate = this._daylightSavingAdjust(printDate); | |
11818 } | |
11819 calender += tbody + "</tr>"; | |
11820 } | |
11821 drawMonth++; | |
11822 if (drawMonth > 11) { | |
11823 drawMonth = 0; | |
11824 drawYear++; | |
11825 } | |
11826 calender += "</tbody></table>" + (isMultiMonth ? "</div>" + | |
11827 ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : ""); | |
11828 group += calender; | |
11829 } | |
11830 html += group; | |
11831 } | |
11832 html += buttonPanel; | |
11833 inst._keyEvent = false; | |
11834 return html; | |
11835 }, | |
11836 | |
11837 /* Generate the month and year header. */ | |
11838 _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, | |
11839 secondary, monthNames, monthNamesShort) { | |
11840 | |
11841 var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, | |
11842 changeMonth = this._get(inst, "changeMonth"), | |
11843 changeYear = this._get(inst, "changeYear"), | |
11844 showMonthAfterYear = this._get(inst, "showMonthAfterYear"), | |
11845 html = "<div class='ui-datepicker-title'>", | |
11846 monthHtml = ""; | |
11847 | |
11848 // month selection | |
11849 if (secondary || !changeMonth) { | |
11850 monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>"; | |
11851 } else { | |
11852 inMinYear = (minDate && minDate.getFullYear() === drawYear); | |
11853 inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); | |
11854 monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; | |
11855 for ( month = 0; month < 12; month++) { | |
11856 if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) { | |
11857 monthHtml += "<option value='" + month + "'" + | |
11858 (month === drawMonth ? " selected='selected'" : "") + | |
11859 ">" + monthNamesShort[month] + "</option>"; | |
11860 } | |
11861 } | |
11862 monthHtml += "</select>"; | |
11863 } | |
11864 | |
11865 if (!showMonthAfterYear) { | |
11866 html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); | |
11867 } | |
11868 | |
11869 // year selection | |
11870 if ( !inst.yearshtml ) { | |
11871 inst.yearshtml = ""; | |
11872 if (secondary || !changeYear) { | |
11873 html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; | |
11874 } else { | |
11875 // determine range of years to display | |
11876 years = this._get(inst, "yearRange").split(":"); | |
11877 thisYear = new Date().getFullYear(); | |
11878 determineYear = function(value) { | |
11879 var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : | |
11880 (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : | |
11881 parseInt(value, 10))); | |
11882 return (isNaN(year) ? thisYear : year); | |
11883 }; | |
11884 year = determineYear(years[0]); | |
11885 endYear = Math.max(year, determineYear(years[1] || "")); | |
11886 year = (minDate ? Math.max(year, minDate.getFullYear()) : year); | |
11887 endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); | |
11888 inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; | |
11889 for (; year <= endYear; year++) { | |
11890 inst.yearshtml += "<option value='" + year + "'" + | |
11891 (year === drawYear ? " selected='selected'" : "") + | |
11892 ">" + year + "</option>"; | |
11893 } | |
11894 inst.yearshtml += "</select>"; | |
11895 | |
11896 html += inst.yearshtml; | |
11897 inst.yearshtml = null; | |
11898 } | |
11899 } | |
11900 | |
11901 html += this._get(inst, "yearSuffix"); | |
11902 if (showMonthAfterYear) { | |
11903 html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; | |
11904 } | |
11905 html += "</div>"; // Close datepicker_header | |
11906 return html; | |
11907 }, | |
11908 | |
11909 /* Adjust one of the date sub-fields. */ | |
11910 _adjustInstDate: function(inst, offset, period) { | |
11911 var year = inst.drawYear + (period === "Y" ? offset : 0), | |
11912 month = inst.drawMonth + (period === "M" ? offset : 0), | |
11913 day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), | |
11914 date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); | |
11915 | |
11916 inst.selectedDay = date.getDate(); | |
11917 inst.drawMonth = inst.selectedMonth = date.getMonth(); | |
11918 inst.drawYear = inst.selectedYear = date.getFullYear(); | |
11919 if (period === "M" || period === "Y") { | |
11920 this._notifyChange(inst); | |
11921 } | |
11922 }, | |
11923 | |
11924 /* Ensure a date is within any min/max bounds. */ | |
11925 _restrictMinMax: function(inst, date) { | |
11926 var minDate = this._getMinMaxDate(inst, "min"), | |
11927 maxDate = this._getMinMaxDate(inst, "max"), | |
11928 newDate = (minDate && date < minDate ? minDate : date); | |
11929 return (maxDate && newDate > maxDate ? maxDate : newDate); | |
11930 }, | |
11931 | |
11932 /* Notify change of month/year. */ | |
11933 _notifyChange: function(inst) { | |
11934 var onChange = this._get(inst, "onChangeMonthYear"); | |
11935 if (onChange) { | |
11936 onChange.apply((inst.input ? inst.input[0] : null), | |
11937 [inst.selectedYear, inst.selectedMonth + 1, inst]); | |
11938 } | |
11939 }, | |
11940 | |
11941 /* Determine the number of months to show. */ | |
11942 _getNumberOfMonths: function(inst) { | |
11943 var numMonths = this._get(inst, "numberOfMonths"); | |
11944 return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); | |
11945 }, | |
11946 | |
11947 /* Determine the current maximum date - ensure no time components are set. */ | |
11948 _getMinMaxDate: function(inst, minMax) { | |
11949 return this._determineDate(inst, this._get(inst, minMax + "Date"), null); | |
11950 }, | |
11951 | |
11952 /* Find the number of days in a given month. */ | |
11953 _getDaysInMonth: function(year, month) { | |
11954 return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); | |
11955 }, | |
11956 | |
11957 /* Find the day of the week of the first of a month. */ | |
11958 _getFirstDayOfMonth: function(year, month) { | |
11959 return new Date(year, month, 1).getDay(); | |
11960 }, | |
11961 | |
11962 /* Determines if we should allow a "next/prev" month display change. */ | |
11963 _canAdjustMonth: function(inst, offset, curYear, curMonth) { | |
11964 var numMonths = this._getNumberOfMonths(inst), | |
11965 date = this._daylightSavingAdjust(new Date(curYear, | |
11966 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); | |
11967 | |
11968 if (offset < 0) { | |
11969 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); | |
11970 } | |
11971 return this._isInRange(inst, date); | |
11972 }, | |
11973 | |
11974 /* Is the given date in the accepted range? */ | |
11975 _isInRange: function(inst, date) { | |
11976 var yearSplit, currentYear, | |
11977 minDate = this._getMinMaxDate(inst, "min"), | |
11978 maxDate = this._getMinMaxDate(inst, "max"), | |
11979 minYear = null, | |
11980 maxYear = null, | |
11981 years = this._get(inst, "yearRange"); | |
11982 if (years){ | |
11983 yearSplit = years.split(":"); | |
11984 currentYear = new Date().getFullYear(); | |
11985 minYear = parseInt(yearSplit[0], 10); | |
11986 maxYear = parseInt(yearSplit[1], 10); | |
11987 if ( yearSplit[0].match(/[+\-].*/) ) { | |
11988 minYear += currentYear; | |
11989 } | |
11990 if ( yearSplit[1].match(/[+\-].*/) ) { | |
11991 maxYear += currentYear; | |
11992 } | |
11993 } | |
11994 | |
11995 return ((!minDate || date.getTime() >= minDate.getTime()) && | |
11996 (!maxDate || date.getTime() <= maxDate.getTime()) && | |
11997 (!minYear || date.getFullYear() >= minYear) && | |
11998 (!maxYear || date.getFullYear() <= maxYear)); | |
11999 }, | |
12000 | |
12001 /* Provide the configuration settings for formatting/parsing. */ | |
12002 _getFormatConfig: function(inst) { | |
12003 var shortYearCutoff = this._get(inst, "shortYearCutoff"); | |
12004 shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : | |
12005 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); | |
12006 return {shortYearCutoff: shortYearCutoff, | |
12007 dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), | |
12008 monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; | |
12009 }, | |
12010 | |
12011 /* Format the given date for display. */ | |
12012 _formatDate: function(inst, day, month, year) { | |
12013 if (!day) { | |
12014 inst.currentDay = inst.selectedDay; | |
12015 inst.currentMonth = inst.selectedMonth; | |
12016 inst.currentYear = inst.selectedYear; | |
12017 } | |
12018 var date = (day ? (typeof day === "object" ? day : | |
12019 this._daylightSavingAdjust(new Date(year, month, day))) : | |
12020 this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); | |
12021 return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); | |
12022 } | |
12023 }); | |
12024 | |
12025 /* | |
12026 * Bind hover events for datepicker elements. | |
12027 * Done via delegate so the binding only occurs once in the lifetime of the parent div. | |
12028 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. | |
12029 */ | |
12030 function bindHover(dpDiv) { | |
12031 var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; | |
12032 return dpDiv.delegate(selector, "mouseout", function() { | |
12033 $(this).removeClass("ui-state-hover"); | |
12034 if (this.className.indexOf("ui-datepicker-prev") !== -1) { | |
12035 $(this).removeClass("ui-datepicker-prev-hover"); | |
12036 } | |
12037 if (this.className.indexOf("ui-datepicker-next") !== -1) { | |
12038 $(this).removeClass("ui-datepicker-next-hover"); | |
12039 } | |
12040 }) | |
12041 .delegate(selector, "mouseover", function(){ | |
12042 if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) { | |
12043 $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); | |
12044 $(this).addClass("ui-state-hover"); | |
12045 if (this.className.indexOf("ui-datepicker-prev") !== -1) { | |
12046 $(this).addClass("ui-datepicker-prev-hover"); | |
12047 } | |
12048 if (this.className.indexOf("ui-datepicker-next") !== -1) { | |
12049 $(this).addClass("ui-datepicker-next-hover"); | |
12050 } | |
12051 } | |
12052 }); | |
12053 } | |
12054 | |
12055 /* jQuery extend now ignores nulls! */ | |
12056 function extendRemove(target, props) { | |
12057 $.extend(target, props); | |
12058 for (var name in props) { | |
12059 if (props[name] == null) { | |
12060 target[name] = props[name]; | |
12061 } | |
12062 } | |
12063 return target; | |
12064 } | |
12065 | |
12066 /* Invoke the datepicker functionality. | |
12067 @param options string - a command, optionally followed by additional parameters or | |
12068 Object - settings for attaching new datepicker functionality | |
12069 @return jQuery object */ | |
12070 $.fn.datepicker = function(options){ | |
12071 | |
12072 /* Verify an empty collection wasn't passed - Fixes #6976 */ | |
12073 if ( !this.length ) { | |
12074 return this; | |
12075 } | |
12076 | |
12077 /* Initialise the date picker. */ | |
12078 if (!$.datepicker.initialized) { | |
12079 $(document).mousedown($.datepicker._checkExternalClick); | |
12080 $.datepicker.initialized = true; | |
12081 } | |
12082 | |
12083 /* Append datepicker main container to body if not exist. */ | |
12084 if ($("#"+$.datepicker._mainDivId).length === 0) { | |
12085 $("body").append($.datepicker.dpDiv); | |
12086 } | |
12087 | |
12088 var otherArgs = Array.prototype.slice.call(arguments, 1); | |
12089 if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { | |
12090 return $.datepicker["_" + options + "Datepicker"]. | |
12091 apply($.datepicker, [this[0]].concat(otherArgs)); | |
12092 } | |
12093 if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { | |
12094 return $.datepicker["_" + options + "Datepicker"]. | |
12095 apply($.datepicker, [this[0]].concat(otherArgs)); | |
12096 } | |
12097 return this.each(function() { | |
12098 typeof options === "string" ? | |
12099 $.datepicker["_" + options + "Datepicker"]. | |
12100 apply($.datepicker, [this].concat(otherArgs)) : | |
12101 $.datepicker._attachDatepicker(this, options); | |
12102 }); | |
12103 }; | |
12104 | |
12105 $.datepicker = new Datepicker(); // singleton instance | |
12106 $.datepicker.initialized = false; | |
12107 $.datepicker.uuid = new Date().getTime(); | |
12108 $.datepicker.version = "1.10.3"; | |
12109 | |
12110 })(jQuery); | |
12111 (function( $, undefined ) { | |
12112 | |
12113 var sizeRelatedOptions = { | |
12114 buttons: true, | |
12115 height: true, | |
12116 maxHeight: true, | |
12117 maxWidth: true, | |
12118 minHeight: true, | |
12119 minWidth: true, | |
12120 width: true | |
12121 }, | |
12122 resizableRelatedOptions = { | |
12123 maxHeight: true, | |
12124 maxWidth: true, | |
12125 minHeight: true, | |
12126 minWidth: true | |
12127 }; | |
12128 | |
12129 $.widget( "ui.dialog", { | |
12130 version: "1.10.3", | |
12131 options: { | |
12132 appendTo: "body", | |
12133 autoOpen: true, | |
12134 buttons: [], | |
12135 closeOnEscape: true, | |
12136 closeText: "close", | |
12137 dialogClass: "", | |
12138 draggable: true, | |
12139 hide: null, | |
12140 height: "auto", | |
12141 maxHeight: null, | |
12142 maxWidth: null, | |
12143 minHeight: 150, | |
12144 minWidth: 150, | |
12145 modal: false, | |
12146 position: { | |
12147 my: "center", | |
12148 at: "center", | |
12149 of: window, | |
12150 collision: "fit", | |
12151 // Ensure the titlebar is always visible | |
12152 using: function( pos ) { | |
12153 var topOffset = $( this ).css( pos ).offset().top; | |
12154 if ( topOffset < 0 ) { | |
12155 $( this ).css( "top", pos.top - topOffset ); | |
12156 } | |
12157 } | |
12158 }, | |
12159 resizable: true, | |
12160 show: null, | |
12161 title: null, | |
12162 width: 300, | |
12163 | |
12164 // callbacks | |
12165 beforeClose: null, | |
12166 close: null, | |
12167 drag: null, | |
12168 dragStart: null, | |
12169 dragStop: null, | |
12170 focus: null, | |
12171 open: null, | |
12172 resize: null, | |
12173 resizeStart: null, | |
12174 resizeStop: null | |
12175 }, | |
12176 | |
12177 _create: function() { | |
12178 this.originalCss = { | |
12179 display: this.element[0].style.display, | |
12180 width: this.element[0].style.width, | |
12181 minHeight: this.element[0].style.minHeight, | |
12182 maxHeight: this.element[0].style.maxHeight, | |
12183 height: this.element[0].style.height | |
12184 }; | |
12185 this.originalPosition = { | |
12186 parent: this.element.parent(), | |
12187 index: this.element.parent().children().index( this.element ) | |
12188 }; | |
12189 this.originalTitle = this.element.attr("title"); | |
12190 this.options.title = this.options.title || this.originalTitle; | |
12191 | |
12192 this._createWrapper(); | |
12193 | |
12194 this.element | |
12195 .show() | |
12196 .removeAttr("title") | |
12197 .addClass("ui-dialog-content ui-widget-content") | |
12198 .appendTo( this.uiDialog ); | |
12199 | |
12200 this._createTitlebar(); | |
12201 this._createButtonPane(); | |
12202 | |
12203 if ( this.options.draggable && $.fn.draggable ) { | |
12204 this._makeDraggable(); | |
12205 } | |
12206 if ( this.options.resizable && $.fn.resizable ) { | |
12207 this._makeResizable(); | |
12208 } | |
12209 | |
12210 this._isOpen = false; | |
12211 }, | |
12212 | |
12213 _init: function() { | |
12214 if ( this.options.autoOpen ) { | |
12215 this.open(); | |
12216 } | |
12217 }, | |
12218 | |
12219 _appendTo: function() { | |
12220 var element = this.options.appendTo; | |
12221 if ( element && (element.jquery || element.nodeType) ) { | |
12222 return $( element ); | |
12223 } | |
12224 return this.document.find( element || "body" ).eq( 0 ); | |
12225 }, | |
12226 | |
12227 _destroy: function() { | |
12228 var next, | |
12229 originalPosition = this.originalPosition; | |
12230 | |
12231 this._destroyOverlay(); | |
12232 | |
12233 this.element | |
12234 .removeUniqueId() | |
12235 .removeClass("ui-dialog-content ui-widget-content") | |
12236 .css( this.originalCss ) | |
12237 // Without detaching first, the following becomes really slow | |
12238 .detach(); | |
12239 | |
12240 this.uiDialog.stop( true, true ).remove(); | |
12241 | |
12242 if ( this.originalTitle ) { | |
12243 this.element.attr( "title", this.originalTitle ); | |
12244 } | |
12245 | |
12246 next = originalPosition.parent.children().eq( originalPosition.index ); | |
12247 // Don't try to place the dialog next to itself (#8613) | |
12248 if ( next.length && next[0] !== this.element[0] ) { | |
12249 next.before( this.element ); | |
12250 } else { | |
12251 originalPosition.parent.append( this.element ); | |
12252 } | |
12253 }, | |
12254 | |
12255 widget: function() { | |
12256 return this.uiDialog; | |
12257 }, | |
12258 | |
12259 disable: $.noop, | |
12260 enable: $.noop, | |
12261 | |
12262 close: function( event ) { | |
12263 var that = this; | |
12264 | |
12265 if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) { | |
12266 return; | |
12267 } | |
12268 | |
12269 this._isOpen = false; | |
12270 this._destroyOverlay(); | |
12271 | |
12272 if ( !this.opener.filter(":focusable").focus().length ) { | |
12273 // Hiding a focused element doesn't trigger blur in WebKit | |
12274 // so in case we have nothing to focus on, explicitly blur the active element | |
12275 // https://bugs.webkit.org/show_bug.cgi?id=47182 | |
12276 $( this.document[0].activeElement ).blur(); | |
12277 } | |
12278 | |
12279 this._hide( this.uiDialog, this.options.hide, function() { | |
12280 that._trigger( "close", event ); | |
12281 }); | |
12282 }, | |
12283 | |
12284 isOpen: function() { | |
12285 return this._isOpen; | |
12286 }, | |
12287 | |
12288 moveToTop: function() { | |
12289 this._moveToTop(); | |
12290 }, | |
12291 | |
12292 _moveToTop: function( event, silent ) { | |
12293 var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length; | |
12294 if ( moved && !silent ) { | |
12295 this._trigger( "focus", event ); | |
12296 } | |
12297 return moved; | |
12298 }, | |
12299 | |
12300 open: function() { | |
12301 var that = this; | |
12302 if ( this._isOpen ) { | |
12303 if ( this._moveToTop() ) { | |
12304 this._focusTabbable(); | |
12305 } | |
12306 return; | |
12307 } | |
12308 | |
12309 this._isOpen = true; | |
12310 this.opener = $( this.document[0].activeElement ); | |
12311 | |
12312 this._size(); | |
12313 this._position(); | |
12314 this._createOverlay(); | |
12315 this._moveToTop( null, true ); | |
12316 this._show( this.uiDialog, this.options.show, function() { | |
12317 that._focusTabbable(); | |
12318 that._trigger("focus"); | |
12319 }); | |
12320 | |
12321 this._trigger("open"); | |
12322 }, | |
12323 | |
12324 _focusTabbable: function() { | |
12325 // Set focus to the first match: | |
12326 // 1. First element inside the dialog matching [autofocus] | |
12327 // 2. Tabbable element inside the content element | |
12328 // 3. Tabbable element inside the buttonpane | |
12329 // 4. The close button | |
12330 // 5. The dialog itself | |
12331 var hasFocus = this.element.find("[autofocus]"); | |
12332 if ( !hasFocus.length ) { | |
12333 hasFocus = this.element.find(":tabbable"); | |
12334 } | |
12335 if ( !hasFocus.length ) { | |
12336 hasFocus = this.uiDialogButtonPane.find(":tabbable"); | |
12337 } | |
12338 if ( !hasFocus.length ) { | |
12339 hasFocus = this.uiDialogTitlebarClose.filter(":tabbable"); | |
12340 } | |
12341 if ( !hasFocus.length ) { | |
12342 hasFocus = this.uiDialog; | |
12343 } | |
12344 hasFocus.eq( 0 ).focus(); | |
12345 }, | |
12346 | |
12347 _keepFocus: function( event ) { | |
12348 function checkFocus() { | |
12349 var activeElement = this.document[0].activeElement, | |
12350 isActive = this.uiDialog[0] === activeElement || | |
12351 $.contains( this.uiDialog[0], activeElement ); | |
12352 if ( !isActive ) { | |
12353 this._focusTabbable(); | |
12354 } | |
12355 } | |
12356 event.preventDefault(); | |
12357 checkFocus.call( this ); | |
12358 // support: IE | |
12359 // IE <= 8 doesn't prevent moving focus even with event.preventDefault() | |
12360 // so we check again later | |
12361 this._delay( checkFocus ); | |
12362 }, | |
12363 | |
12364 _createWrapper: function() { | |
12365 this.uiDialog = $("<div>") | |
12366 .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " + | |
12367 this.options.dialogClass ) | |
12368 .hide() | |
12369 .attr({ | |
12370 // Setting tabIndex makes the div focusable | |
12371 tabIndex: -1, | |
12372 role: "dialog" | |
12373 }) | |
12374 .appendTo( this._appendTo() ); | |
12375 | |
12376 this._on( this.uiDialog, { | |
12377 keydown: function( event ) { | |
12378 if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && | |
12379 event.keyCode === $.ui.keyCode.ESCAPE ) { | |
12380 event.preventDefault(); | |
12381 this.close( event ); | |
12382 return; | |
12383 } | |
12384 | |
12385 // prevent tabbing out of dialogs | |
12386 if ( event.keyCode !== $.ui.keyCode.TAB ) { | |
12387 return; | |
12388 } | |
12389 var tabbables = this.uiDialog.find(":tabbable"), | |
12390 first = tabbables.filter(":first"), | |
12391 last = tabbables.filter(":last"); | |
12392 | |
12393 if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) { | |
12394 first.focus( 1 ); | |
12395 event.preventDefault(); | |
12396 } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) { | |
12397 last.focus( 1 ); | |
12398 event.preventDefault(); | |
12399 } | |
12400 }, | |
12401 mousedown: function( event ) { | |
12402 if ( this._moveToTop( event ) ) { | |
12403 this._focusTabbable(); | |
12404 } | |
12405 } | |
12406 }); | |
12407 | |
12408 // We assume that any existing aria-describedby attribute means | |
12409 // that the dialog content is marked up properly | |
12410 // otherwise we brute force the content as the description | |
12411 if ( !this.element.find("[aria-describedby]").length ) { | |
12412 this.uiDialog.attr({ | |
12413 "aria-describedby": this.element.uniqueId().attr("id") | |
12414 }); | |
12415 } | |
12416 }, | |
12417 | |
12418 _createTitlebar: function() { | |
12419 var uiDialogTitle; | |
12420 | |
12421 this.uiDialogTitlebar = $("<div>") | |
12422 .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix") | |
12423 .prependTo( this.uiDialog ); | |
12424 this._on( this.uiDialogTitlebar, { | |
12425 mousedown: function( event ) { | |
12426 // Don't prevent click on close button (#8838) | |
12427 // Focusing a dialog that is partially scrolled out of view | |
12428 // causes the browser to scroll it into view, preventing the click event | |
12429 if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) { | |
12430 // Dialog isn't getting focus when dragging (#8063) | |
12431 this.uiDialog.focus(); | |
12432 } | |
12433 } | |
12434 }); | |
12435 | |
12436 this.uiDialogTitlebarClose = $("<button></button>") | |
12437 .button({ | |
12438 label: this.options.closeText, | |
12439 icons: { | |
12440 primary: "ui-icon-closethick" | |
12441 }, | |
12442 text: false | |
12443 }) | |
12444 .addClass("ui-dialog-titlebar-close") | |
12445 .appendTo( this.uiDialogTitlebar ); | |
12446 this._on( this.uiDialogTitlebarClose, { | |
12447 click: function( event ) { | |
12448 event.preventDefault(); | |
12449 this.close( event ); | |
12450 } | |
12451 }); | |
12452 | |
12453 uiDialogTitle = $("<span>") | |
12454 .uniqueId() | |
12455 .addClass("ui-dialog-title") | |
12456 .prependTo( this.uiDialogTitlebar ); | |
12457 this._title( uiDialogTitle ); | |
12458 | |
12459 this.uiDialog.attr({ | |
12460 "aria-labelledby": uiDialogTitle.attr("id") | |
12461 }); | |
12462 }, | |
12463 | |
12464 _title: function( title ) { | |
12465 if ( !this.options.title ) { | |
12466 title.html(" "); | |
12467 } | |
12468 title.text( this.options.title ); | |
12469 }, | |
12470 | |
12471 _createButtonPane: function() { | |
12472 this.uiDialogButtonPane = $("<div>") | |
12473 .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"); | |
12474 | |
12475 this.uiButtonSet = $("<div>") | |
12476 .addClass("ui-dialog-buttonset") | |
12477 .appendTo( this.uiDialogButtonPane ); | |
12478 | |
12479 this._createButtons(); | |
12480 }, | |
12481 | |
12482 _createButtons: function() { | |
12483 var that = this, | |
12484 buttons = this.options.buttons; | |
12485 | |
12486 // if we already have a button pane, remove it | |
12487 this.uiDialogButtonPane.remove(); | |
12488 this.uiButtonSet.empty(); | |
12489 | |
12490 if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) { | |
12491 this.uiDialog.removeClass("ui-dialog-buttons"); | |
12492 return; | |
12493 } | |
12494 | |
12495 $.each( buttons, function( name, props ) { | |
12496 var click, buttonOptions; | |
12497 props = $.isFunction( props ) ? | |
12498 { click: props, text: name } : | |
12499 props; | |
12500 // Default to a non-submitting button | |
12501 props = $.extend( { type: "button" }, props ); | |
12502 // Change the context for the click callback to be the main element | |
12503 click = props.click; | |
12504 props.click = function() { | |
12505 click.apply( that.element[0], arguments ); | |
12506 }; | |
12507 buttonOptions = { | |
12508 icons: props.icons, | |
12509 text: props.showText | |
12510 }; | |
12511 delete props.icons; | |
12512 delete props.showText; | |
12513 $( "<button></button>", props ) | |
12514 .button( buttonOptions ) | |
12515 .appendTo( that.uiButtonSet ); | |
12516 }); | |
12517 this.uiDialog.addClass("ui-dialog-buttons"); | |
12518 this.uiDialogButtonPane.appendTo( this.uiDialog ); | |
12519 }, | |
12520 | |
12521 _makeDraggable: function() { | |
12522 var that = this, | |
12523 options = this.options; | |
12524 | |
12525 function filteredUi( ui ) { | |
12526 return { | |
12527 position: ui.position, | |
12528 offset: ui.offset | |
12529 }; | |
12530 } | |
12531 | |
12532 this.uiDialog.draggable({ | |
12533 cancel: ".ui-dialog-content, .ui-dialog-titlebar-close", | |
12534 handle: ".ui-dialog-titlebar", | |
12535 containment: "document", | |
12536 start: function( event, ui ) { | |
12537 $( this ).addClass("ui-dialog-dragging"); | |
12538 that._blockFrames(); | |
12539 that._trigger( "dragStart", event, filteredUi( ui ) ); | |
12540 }, | |
12541 drag: function( event, ui ) { | |
12542 that._trigger( "drag", event, filteredUi( ui ) ); | |
12543 }, | |
12544 stop: function( event, ui ) { | |
12545 options.position = [ | |
12546 ui.position.left - that.document.scrollLeft(), | |
12547 ui.position.top - that.document.scrollTop() | |
12548 ]; | |
12549 $( this ).removeClass("ui-dialog-dragging"); | |
12550 that._unblockFrames(); | |
12551 that._trigger( "dragStop", event, filteredUi( ui ) ); | |
12552 } | |
12553 }); | |
12554 }, | |
12555 | |
12556 _makeResizable: function() { | |
12557 var that = this, | |
12558 options = this.options, | |
12559 handles = options.resizable, | |
12560 // .ui-resizable has position: relative defined in the stylesheet | |
12561 // but dialogs have to use absolute or fixed positioning | |
12562 position = this.uiDialog.css("position"), | |
12563 resizeHandles = typeof handles === "string" ? | |
12564 handles : | |
12565 "n,e,s,w,se,sw,ne,nw"; | |
12566 | |
12567 function filteredUi( ui ) { | |
12568 return { | |
12569 originalPosition: ui.originalPosition, | |
12570 originalSize: ui.originalSize, | |
12571 position: ui.position, | |
12572 size: ui.size | |
12573 }; | |
12574 } | |
12575 | |
12576 this.uiDialog.resizable({ | |
12577 cancel: ".ui-dialog-content", | |
12578 containment: "document", | |
12579 alsoResize: this.element, | |
12580 maxWidth: options.maxWidth, | |
12581 maxHeight: options.maxHeight, | |
12582 minWidth: options.minWidth, | |
12583 minHeight: this._minHeight(), | |
12584 handles: resizeHandles, | |
12585 start: function( event, ui ) { | |
12586 $( this ).addClass("ui-dialog-resizing"); | |
12587 that._blockFrames(); | |
12588 that._trigger( "resizeStart", event, filteredUi( ui ) ); | |
12589 }, | |
12590 resize: function( event, ui ) { | |
12591 that._trigger( "resize", event, filteredUi( ui ) ); | |
12592 }, | |
12593 stop: function( event, ui ) { | |
12594 options.height = $( this ).height(); | |
12595 options.width = $( this ).width(); | |
12596 $( this ).removeClass("ui-dialog-resizing"); | |
12597 that._unblockFrames(); | |
12598 that._trigger( "resizeStop", event, filteredUi( ui ) ); | |
12599 } | |
12600 }) | |
12601 .css( "position", position ); | |
12602 }, | |
12603 | |
12604 _minHeight: function() { | |
12605 var options = this.options; | |
12606 | |
12607 return options.height === "auto" ? | |
12608 options.minHeight : | |
12609 Math.min( options.minHeight, options.height ); | |
12610 }, | |
12611 | |
12612 _position: function() { | |
12613 // Need to show the dialog to get the actual offset in the position plugin | |
12614 var isVisible = this.uiDialog.is(":visible"); | |
12615 if ( !isVisible ) { | |
12616 this.uiDialog.show(); | |
12617 } | |
12618 this.uiDialog.position( this.options.position ); | |
12619 if ( !isVisible ) { | |
12620 this.uiDialog.hide(); | |
12621 } | |
12622 }, | |
12623 | |
12624 _setOptions: function( options ) { | |
12625 var that = this, | |
12626 resize = false, | |
12627 resizableOptions = {}; | |
12628 | |
12629 $.each( options, function( key, value ) { | |
12630 that._setOption( key, value ); | |
12631 | |
12632 if ( key in sizeRelatedOptions ) { | |
12633 resize = true; | |
12634 } | |
12635 if ( key in resizableRelatedOptions ) { | |
12636 resizableOptions[ key ] = value; | |
12637 } | |
12638 }); | |
12639 | |
12640 if ( resize ) { | |
12641 this._size(); | |
12642 this._position(); | |
12643 } | |
12644 if ( this.uiDialog.is(":data(ui-resizable)") ) { | |
12645 this.uiDialog.resizable( "option", resizableOptions ); | |
12646 } | |
12647 }, | |
12648 | |
12649 _setOption: function( key, value ) { | |
12650 /*jshint maxcomplexity:15*/ | |
12651 var isDraggable, isResizable, | |
12652 uiDialog = this.uiDialog; | |
12653 | |
12654 if ( key === "dialogClass" ) { | |
12655 uiDialog | |
12656 .removeClass( this.options.dialogClass ) | |
12657 .addClass( value ); | |
12658 } | |
12659 | |
12660 if ( key === "disabled" ) { | |
12661 return; | |
12662 } | |
12663 | |
12664 this._super( key, value ); | |
12665 | |
12666 if ( key === "appendTo" ) { | |
12667 this.uiDialog.appendTo( this._appendTo() ); | |
12668 } | |
12669 | |
12670 if ( key === "buttons" ) { | |
12671 this._createButtons(); | |
12672 } | |
12673 | |
12674 if ( key === "closeText" ) { | |
12675 this.uiDialogTitlebarClose.button({ | |
12676 // Ensure that we always pass a string | |
12677 label: "" + value | |
12678 }); | |
12679 } | |
12680 | |
12681 if ( key === "draggable" ) { | |
12682 isDraggable = uiDialog.is(":data(ui-draggable)"); | |
12683 if ( isDraggable && !value ) { | |
12684 uiDialog.draggable("destroy"); | |
12685 } | |
12686 | |
12687 if ( !isDraggable && value ) { | |
12688 this._makeDraggable(); | |
12689 } | |
12690 } | |
12691 | |
12692 if ( key === "position" ) { | |
12693 this._position(); | |
12694 } | |
12695 | |
12696 if ( key === "resizable" ) { | |
12697 // currently resizable, becoming non-resizable | |
12698 isResizable = uiDialog.is(":data(ui-resizable)"); | |
12699 if ( isResizable && !value ) { | |
12700 uiDialog.resizable("destroy"); | |
12701 } | |
12702 | |
12703 // currently resizable, changing handles | |
12704 if ( isResizable && typeof value === "string" ) { | |
12705 uiDialog.resizable( "option", "handles", value ); | |
12706 } | |
12707 | |
12708 // currently non-resizable, becoming resizable | |
12709 if ( !isResizable && value !== false ) { | |
12710 this._makeResizable(); | |
12711 } | |
12712 } | |
12713 | |
12714 if ( key === "title" ) { | |
12715 this._title( this.uiDialogTitlebar.find(".ui-dialog-title") ); | |
12716 } | |
12717 }, | |
12718 | |
12719 _size: function() { | |
12720 // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content | |
12721 // divs will both have width and height set, so we need to reset them | |
12722 var nonContentHeight, minContentHeight, maxContentHeight, | |
12723 options = this.options; | |
12724 | |
12725 // Reset content sizing | |
12726 this.element.show().css({ | |
12727 width: "auto", | |
12728 minHeight: 0, | |
12729 maxHeight: "none", | |
12730 height: 0 | |
12731 }); | |
12732 | |
12733 if ( options.minWidth > options.width ) { | |
12734 options.width = options.minWidth; | |
12735 } | |
12736 | |
12737 // reset wrapper sizing | |
12738 // determine the height of all the non-content elements | |
12739 nonContentHeight = this.uiDialog.css({ | |
12740 height: "auto", | |
12741 width: options.width | |
12742 }) | |
12743 .outerHeight(); | |
12744 minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); | |
12745 maxContentHeight = typeof options.maxHeight === "number" ? | |
12746 Math.max( 0, options.maxHeight - nonContentHeight ) : | |
12747 "none"; | |
12748 | |
12749 if ( options.height === "auto" ) { | |
12750 this.element.css({ | |
12751 minHeight: minContentHeight, | |
12752 maxHeight: maxContentHeight, | |
12753 height: "auto" | |
12754 }); | |
12755 } else { | |
12756 this.element.height( Math.max( 0, options.height - nonContentHeight ) ); | |
12757 } | |
12758 | |
12759 if (this.uiDialog.is(":data(ui-resizable)") ) { | |
12760 this.uiDialog.resizable( "option", "minHeight", this._minHeight() ); | |
12761 } | |
12762 }, | |
12763 | |
12764 _blockFrames: function() { | |
12765 this.iframeBlocks = this.document.find( "iframe" ).map(function() { | |
12766 var iframe = $( this ); | |
12767 | |
12768 return $( "<div>" ) | |
12769 .css({ | |
12770 position: "absolute", | |
12771 width: iframe.outerWidth(), | |
12772 height: iframe.outerHeight() | |
12773 }) | |
12774 .appendTo( iframe.parent() ) | |
12775 .offset( iframe.offset() )[0]; | |
12776 }); | |
12777 }, | |
12778 | |
12779 _unblockFrames: function() { | |
12780 if ( this.iframeBlocks ) { | |
12781 this.iframeBlocks.remove(); | |
12782 delete this.iframeBlocks; | |
12783 } | |
12784 }, | |
12785 | |
12786 _allowInteraction: function( event ) { | |
12787 if ( $( event.target ).closest(".ui-dialog").length ) { | |
12788 return true; | |
12789 } | |
12790 | |
12791 // TODO: Remove hack when datepicker implements | |
12792 // the .ui-front logic (#8989) | |
12793 return !!$( event.target ).closest(".ui-datepicker").length; | |
12794 }, | |
12795 | |
12796 _createOverlay: function() { | |
12797 if ( !this.options.modal ) { | |
12798 return; | |
12799 } | |
12800 | |
12801 var that = this, | |
12802 widgetFullName = this.widgetFullName; | |
12803 if ( !$.ui.dialog.overlayInstances ) { | |
12804 // Prevent use of anchors and inputs. | |
12805 // We use a delay in case the overlay is created from an | |
12806 // event that we're going to be cancelling. (#2804) | |
12807 this._delay(function() { | |
12808 // Handle .dialog().dialog("close") (#4065) | |
12809 if ( $.ui.dialog.overlayInstances ) { | |
12810 this.document.bind( "focusin.dialog", function( event ) { | |
12811 if ( !that._allowInteraction( event ) ) { | |
12812 event.preventDefault(); | |
12813 $(".ui-dialog:visible:last .ui-dialog-content") | |
12814 .data( widgetFullName )._focusTabbable(); | |
12815 } | |
12816 }); | |
12817 } | |
12818 }); | |
12819 } | |
12820 | |
12821 this.overlay = $("<div>") | |
12822 .addClass("ui-widget-overlay ui-front") | |
12823 .appendTo( this._appendTo() ); | |
12824 this._on( this.overlay, { | |
12825 mousedown: "_keepFocus" | |
12826 }); | |
12827 $.ui.dialog.overlayInstances++; | |
12828 }, | |
12829 | |
12830 _destroyOverlay: function() { | |
12831 if ( !this.options.modal ) { | |
12832 return; | |
12833 } | |
12834 | |
12835 if ( this.overlay ) { | |
12836 $.ui.dialog.overlayInstances--; | |
12837 | |
12838 if ( !$.ui.dialog.overlayInstances ) { | |
12839 this.document.unbind( "focusin.dialog" ); | |
12840 } | |
12841 this.overlay.remove(); | |
12842 this.overlay = null; | |
12843 } | |
12844 } | |
12845 }); | |
12846 | |
12847 $.ui.dialog.overlayInstances = 0; | |
12848 | |
12849 // DEPRECATED | |
12850 if ( $.uiBackCompat !== false ) { | |
12851 // position option with array notation | |
12852 // just override with old implementation | |
12853 $.widget( "ui.dialog", $.ui.dialog, { | |
12854 _position: function() { | |
12855 var position = this.options.position, | |
12856 myAt = [], | |
12857 offset = [ 0, 0 ], | |
12858 isVisible; | |
12859 | |
12860 if ( position ) { | |
12861 if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) { | |
12862 myAt = position.split ? position.split(" ") : [ position[0], position[1] ]; | |
12863 if ( myAt.length === 1 ) { | |
12864 myAt[1] = myAt[0]; | |
12865 } | |
12866 | |
12867 $.each( [ "left", "top" ], function( i, offsetPosition ) { | |
12868 if ( +myAt[ i ] === myAt[ i ] ) { | |
12869 offset[ i ] = myAt[ i ]; | |
12870 myAt[ i ] = offsetPosition; | |
12871 } | |
12872 }); | |
12873 | |
12874 position = { | |
12875 my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " + | |
12876 myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]), | |
12877 at: myAt.join(" ") | |
12878 }; | |
12879 } | |
12880 | |
12881 position = $.extend( {}, $.ui.dialog.prototype.options.position, position ); | |
12882 } else { | |
12883 position = $.ui.dialog.prototype.options.position; | |
12884 } | |
12885 | |
12886 // need to show the dialog to get the actual offset in the position plugin | |
12887 isVisible = this.uiDialog.is(":visible"); | |
12888 if ( !isVisible ) { | |
12889 this.uiDialog.show(); | |
12890 } | |
12891 this.uiDialog.position( position ); | |
12892 if ( !isVisible ) { | |
12893 this.uiDialog.hide(); | |
12894 } | |
12895 } | |
12896 }); | |
12897 } | |
12898 | |
12899 }( jQuery ) ); | |
12900 (function( $, undefined ) { | |
12901 | |
12902 $.widget( "ui.menu", { | |
12903 version: "1.10.3", | |
12904 defaultElement: "<ul>", | |
12905 delay: 300, | |
12906 options: { | |
12907 icons: { | |
12908 submenu: "ui-icon-carat-1-e" | |
12909 }, | |
12910 menus: "ul", | |
12911 position: { | |
12912 my: "left top", | |
12913 at: "right top" | |
12914 }, | |
12915 role: "menu", | |
12916 | |
12917 // callbacks | |
12918 blur: null, | |
12919 focus: null, | |
12920 select: null | |
12921 }, | |
12922 | |
12923 _create: function() { | |
12924 this.activeMenu = this.element; | |
12925 // flag used to prevent firing of the click handler | |
12926 // as the event bubbles up through nested menus | |
12927 this.mouseHandled = false; | |
12928 this.element | |
12929 .uniqueId() | |
12930 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) | |
12931 .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length ) | |
12932 .attr({ | |
12933 role: this.options.role, | |
12934 tabIndex: 0 | |
12935 }) | |
12936 // need to catch all clicks on disabled menu | |
12937 // not possible through _on | |
12938 .bind( "click" + this.eventNamespace, $.proxy(function( event ) { | |
12939 if ( this.options.disabled ) { | |
12940 event.preventDefault(); | |
12941 } | |
12942 }, this )); | |
12943 | |
12944 if ( this.options.disabled ) { | |
12945 this.element | |
12946 .addClass( "ui-state-disabled" ) | |
12947 .attr( "aria-disabled", "true" ); | |
12948 } | |
12949 | |
12950 this._on({ | |
12951 // Prevent focus from sticking to links inside menu after clicking | |
12952 // them (focus should always stay on UL during navigation). | |
12953 "mousedown .ui-menu-item > a": function( event ) { | |
12954 event.preventDefault(); | |
12955 }, | |
12956 "click .ui-state-disabled > a": function( event ) { | |
12957 event.preventDefault(); | |
12958 }, | |
12959 "click .ui-menu-item:has(a)": function( event ) { | |
12960 var target = $( event.target ).closest( ".ui-menu-item" ); | |
12961 if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) { | |
12962 this.mouseHandled = true; | |
12963 | |
12964 this.select( event ); | |
12965 // Open submenu on click | |
12966 if ( target.has( ".ui-menu" ).length ) { | |
12967 this.expand( event ); | |
12968 } else if ( !this.element.is( ":focus" ) ) { | |
12969 // Redirect focus to the menu | |
12970 this.element.trigger( "focus", [ true ] ); | |
12971 | |
12972 // If the active item is on the top level, let it stay active. | |
12973 // Otherwise, blur the active item since it is no longer visible. | |
12974 if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) { | |
12975 clearTimeout( this.timer ); | |
12976 } | |
12977 } | |
12978 } | |
12979 }, | |
12980 "mouseenter .ui-menu-item": function( event ) { | |
12981 var target = $( event.currentTarget ); | |
12982 // Remove ui-state-active class from siblings of the newly focused menu item | |
12983 // to avoid a jump caused by adjacent elements both having a class with a border | |
12984 target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); | |
12985 this.focus( event, target ); | |
12986 }, | |
12987 mouseleave: "collapseAll", | |
12988 "mouseleave .ui-menu": "collapseAll", | |
12989 focus: function( event, keepActiveItem ) { | |
12990 // If there's already an active item, keep it active | |
12991 // If not, activate the first item | |
12992 var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); | |
12993 | |
12994 if ( !keepActiveItem ) { | |
12995 this.focus( event, item ); | |
12996 } | |
12997 }, | |
12998 blur: function( event ) { | |
12999 this._delay(function() { | |
13000 if ( !$.contains( this.element[0], this.document[0].activeElement ) ) { | |
13001 this.collapseAll( event ); | |
13002 } | |
13003 }); | |
13004 }, | |
13005 keydown: "_keydown" | |
13006 }); | |
13007 | |
13008 this.refresh(); | |
13009 | |
13010 // Clicks outside of a menu collapse any open menus | |
13011 this._on( this.document, { | |
13012 click: function( event ) { | |
13013 if ( !$( event.target ).closest( ".ui-menu" ).length ) { | |
13014 this.collapseAll( event ); | |
13015 } | |
13016 | |
13017 // Reset the mouseHandled flag | |
13018 this.mouseHandled = false; | |
13019 } | |
13020 }); | |
13021 }, | |
13022 | |
13023 _destroy: function() { | |
13024 // Destroy (sub)menus | |
13025 this.element | |
13026 .removeAttr( "aria-activedescendant" ) | |
13027 .find( ".ui-menu" ).addBack() | |
13028 .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" ) | |
13029 .removeAttr( "role" ) | |
13030 .removeAttr( "tabIndex" ) | |
13031 .removeAttr( "aria-labelledby" ) | |
13032 .removeAttr( "aria-expanded" ) | |
13033 .removeAttr( "aria-hidden" ) | |
13034 .removeAttr( "aria-disabled" ) | |
13035 .removeUniqueId() | |
13036 .show(); | |
13037 | |
13038 // Destroy menu items | |
13039 this.element.find( ".ui-menu-item" ) | |
13040 .removeClass( "ui-menu-item" ) | |
13041 .removeAttr( "role" ) | |
13042 .removeAttr( "aria-disabled" ) | |
13043 .children( "a" ) | |
13044 .removeUniqueId() | |
13045 .removeClass( "ui-corner-all ui-state-hover" ) | |
13046 .removeAttr( "tabIndex" ) | |
13047 .removeAttr( "role" ) | |
13048 .removeAttr( "aria-haspopup" ) | |
13049 .children().each( function() { | |
13050 var elem = $( this ); | |
13051 if ( elem.data( "ui-menu-submenu-carat" ) ) { | |
13052 elem.remove(); | |
13053 } | |
13054 }); | |
13055 | |
13056 // Destroy menu dividers | |
13057 this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); | |
13058 }, | |
13059 | |
13060 _keydown: function( event ) { | |
13061 /*jshint maxcomplexity:20*/ | |
13062 var match, prev, character, skip, regex, | |
13063 preventDefault = true; | |
13064 | |
13065 function escape( value ) { | |
13066 return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ); | |
13067 } | |
13068 | |
13069 switch ( event.keyCode ) { | |
13070 case $.ui.keyCode.PAGE_UP: | |
13071 this.previousPage( event ); | |
13072 break; | |
13073 case $.ui.keyCode.PAGE_DOWN: | |
13074 this.nextPage( event ); | |
13075 break; | |
13076 case $.ui.keyCode.HOME: | |
13077 this._move( "first", "first", event ); | |
13078 break; | |
13079 case $.ui.keyCode.END: | |
13080 this._move( "last", "last", event ); | |
13081 break; | |
13082 case $.ui.keyCode.UP: | |
13083 this.previous( event ); | |
13084 break; | |
13085 case $.ui.keyCode.DOWN: | |
13086 this.next( event ); | |
13087 break; | |
13088 case $.ui.keyCode.LEFT: | |
13089 this.collapse( event ); | |
13090 break; | |
13091 case $.ui.keyCode.RIGHT: | |
13092 if ( this.active && !this.active.is( ".ui-state-disabled" ) ) { | |
13093 this.expand( event ); | |
13094 } | |
13095 break; | |
13096 case $.ui.keyCode.ENTER: | |
13097 case $.ui.keyCode.SPACE: | |
13098 this._activate( event ); | |
13099 break; | |
13100 case $.ui.keyCode.ESCAPE: | |
13101 this.collapse( event ); | |
13102 break; | |
13103 default: | |
13104 preventDefault = false; | |
13105 prev = this.previousFilter || ""; | |
13106 character = String.fromCharCode( event.keyCode ); | |
13107 skip = false; | |
13108 | |
13109 clearTimeout( this.filterTimer ); | |
13110 | |
13111 if ( character === prev ) { | |
13112 skip = true; | |
13113 } else { | |
13114 character = prev + character; | |
13115 } | |
13116 | |
13117 regex = new RegExp( "^" + escape( character ), "i" ); | |
13118 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { | |
13119 return regex.test( $( this ).children( "a" ).text() ); | |
13120 }); | |
13121 match = skip && match.index( this.active.next() ) !== -1 ? | |
13122 this.active.nextAll( ".ui-menu-item" ) : | |
13123 match; | |
13124 | |
13125 // If no matches on the current filter, reset to the last character pressed | |
13126 // to move down the menu to the first item that starts with that character | |
13127 if ( !match.length ) { | |
13128 character = String.fromCharCode( event.keyCode ); | |
13129 regex = new RegExp( "^" + escape( character ), "i" ); | |
13130 match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { | |
13131 return regex.test( $( this ).children( "a" ).text() ); | |
13132 }); | |
13133 } | |
13134 | |
13135 if ( match.length ) { | |
13136 this.focus( event, match ); | |
13137 if ( match.length > 1 ) { | |
13138 this.previousFilter = character; | |
13139 this.filterTimer = this._delay(function() { | |
13140 delete this.previousFilter; | |
13141 }, 1000 ); | |
13142 } else { | |
13143 delete this.previousFilter; | |
13144 } | |
13145 } else { | |
13146 delete this.previousFilter; | |
13147 } | |
13148 } | |
13149 | |
13150 if ( preventDefault ) { | |
13151 event.preventDefault(); | |
13152 } | |
13153 }, | |
13154 | |
13155 _activate: function( event ) { | |
13156 if ( !this.active.is( ".ui-state-disabled" ) ) { | |
13157 if ( this.active.children( "a[aria-haspopup='true']" ).length ) { | |
13158 this.expand( event ); | |
13159 } else { | |
13160 this.select( event ); | |
13161 } | |
13162 } | |
13163 }, | |
13164 | |
13165 refresh: function() { | |
13166 var menus, | |
13167 icon = this.options.icons.submenu, | |
13168 submenus = this.element.find( this.options.menus ); | |
13169 | |
13170 // Initialize nested menus | |
13171 submenus.filter( ":not(.ui-menu)" ) | |
13172 .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) | |
13173 .hide() | |
13174 .attr({ | |
13175 role: this.options.role, | |
13176 "aria-hidden": "true", | |
13177 "aria-expanded": "false" | |
13178 }) | |
13179 .each(function() { | |
13180 var menu = $( this ), | |
13181 item = menu.prev( "a" ), | |
13182 submenuCarat = $( "<span>" ) | |
13183 .addClass( "ui-menu-icon ui-icon " + icon ) | |
13184 .data( "ui-menu-submenu-carat", true ); | |
13185 | |
13186 item | |
13187 .attr( "aria-haspopup", "true" ) | |
13188 .prepend( submenuCarat ); | |
13189 menu.attr( "aria-labelledby", item.attr( "id" ) ); | |
13190 }); | |
13191 | |
13192 menus = submenus.add( this.element ); | |
13193 | |
13194 // Don't refresh list items that are already adapted | |
13195 menus.children( ":not(.ui-menu-item):has(a)" ) | |
13196 .addClass( "ui-menu-item" ) | |
13197 .attr( "role", "presentation" ) | |
13198 .children( "a" ) | |
13199 .uniqueId() | |
13200 .addClass( "ui-corner-all" ) | |
13201 .attr({ | |
13202 tabIndex: -1, | |
13203 role: this._itemRole() | |
13204 }); | |
13205 | |
13206 // Initialize unlinked menu-items containing spaces and/or dashes only as dividers | |
13207 menus.children( ":not(.ui-menu-item)" ).each(function() { | |
13208 var item = $( this ); | |
13209 // hyphen, em dash, en dash | |
13210 if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) { | |
13211 item.addClass( "ui-widget-content ui-menu-divider" ); | |
13212 } | |
13213 }); | |
13214 | |
13215 // Add aria-disabled attribute to any disabled menu item | |
13216 menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" ); | |
13217 | |
13218 // If the active item has been removed, blur the menu | |
13219 if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { | |
13220 this.blur(); | |
13221 } | |
13222 }, | |
13223 | |
13224 _itemRole: function() { | |
13225 return { | |
13226 menu: "menuitem", | |
13227 listbox: "option" | |
13228 }[ this.options.role ]; | |
13229 }, | |
13230 | |
13231 _setOption: function( key, value ) { | |
13232 if ( key === "icons" ) { | |
13233 this.element.find( ".ui-menu-icon" ) | |
13234 .removeClass( this.options.icons.submenu ) | |
13235 .addClass( value.submenu ); | |
13236 } | |
13237 this._super( key, value ); | |
13238 }, | |
13239 | |
13240 focus: function( event, item ) { | |
13241 var nested, focused; | |
13242 this.blur( event, event && event.type === "focus" ); | |
13243 | |
13244 this._scrollIntoView( item ); | |
13245 | |
13246 this.active = item.first(); | |
13247 focused = this.active.children( "a" ).addClass( "ui-state-focus" ); | |
13248 // Only update aria-activedescendant if there's a role | |
13249 // otherwise we assume focus is managed elsewhere | |
13250 if ( this.options.role ) { | |
13251 this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); | |
13252 } | |
13253 | |
13254 // Highlight active parent menu item, if any | |
13255 this.active | |
13256 .parent() | |
13257 .closest( ".ui-menu-item" ) | |
13258 .children( "a:first" ) | |
13259 .addClass( "ui-state-active" ); | |
13260 | |
13261 if ( event && event.type === "keydown" ) { | |
13262 this._close(); | |
13263 } else { | |
13264 this.timer = this._delay(function() { | |
13265 this._close(); | |
13266 }, this.delay ); | |
13267 } | |
13268 | |
13269 nested = item.children( ".ui-menu" ); | |
13270 if ( nested.length && ( /^mouse/.test( event.type ) ) ) { | |
13271 this._startOpening(nested); | |
13272 } | |
13273 this.activeMenu = item.parent(); | |
13274 | |
13275 this._trigger( "focus", event, { item: item } ); | |
13276 }, | |
13277 | |
13278 _scrollIntoView: function( item ) { | |
13279 var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; | |
13280 if ( this._hasScroll() ) { | |
13281 borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0; | |
13282 paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0; | |
13283 offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop; | |
13284 scroll = this.activeMenu.scrollTop(); | |
13285 elementHeight = this.activeMenu.height(); | |
13286 itemHeight = item.height(); | |
13287 | |
13288 if ( offset < 0 ) { | |
13289 this.activeMenu.scrollTop( scroll + offset ); | |
13290 } else if ( offset + itemHeight > elementHeight ) { | |
13291 this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight ); | |
13292 } | |
13293 } | |
13294 }, | |
13295 | |
13296 blur: function( event, fromFocus ) { | |
13297 if ( !fromFocus ) { | |
13298 clearTimeout( this.timer ); | |
13299 } | |
13300 | |
13301 if ( !this.active ) { | |
13302 return; | |
13303 } | |
13304 | |
13305 this.active.children( "a" ).removeClass( "ui-state-focus" ); | |
13306 this.active = null; | |
13307 | |
13308 this._trigger( "blur", event, { item: this.active } ); | |
13309 }, | |
13310 | |
13311 _startOpening: function( submenu ) { | |
13312 clearTimeout( this.timer ); | |
13313 | |
13314 // Don't open if already open fixes a Firefox bug that caused a .5 pixel | |
13315 // shift in the submenu position when mousing over the carat icon | |
13316 if ( submenu.attr( "aria-hidden" ) !== "true" ) { | |
13317 return; | |
13318 } | |
13319 | |
13320 this.timer = this._delay(function() { | |
13321 this._close(); | |
13322 this._open( submenu ); | |
13323 }, this.delay ); | |
13324 }, | |
13325 | |
13326 _open: function( submenu ) { | |
13327 var position = $.extend({ | |
13328 of: this.active | |
13329 }, this.options.position ); | |
13330 | |
13331 clearTimeout( this.timer ); | |
13332 this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) | |
13333 .hide() | |
13334 .attr( "aria-hidden", "true" ); | |
13335 | |
13336 submenu | |
13337 .show() | |
13338 .removeAttr( "aria-hidden" ) | |
13339 .attr( "aria-expanded", "true" ) | |
13340 .position( position ); | |
13341 }, | |
13342 | |
13343 collapseAll: function( event, all ) { | |
13344 clearTimeout( this.timer ); | |
13345 this.timer = this._delay(function() { | |
13346 // If we were passed an event, look for the submenu that contains the event | |
13347 var currentMenu = all ? this.element : | |
13348 $( event && event.target ).closest( this.element.find( ".ui-menu" ) ); | |
13349 | |
13350 // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway | |
13351 if ( !currentMenu.length ) { | |
13352 currentMenu = this.element; | |
13353 } | |
13354 | |
13355 this._close( currentMenu ); | |
13356 | |
13357 this.blur( event ); | |
13358 this.activeMenu = currentMenu; | |
13359 }, this.delay ); | |
13360 }, | |
13361 | |
13362 // With no arguments, closes the currently active menu - if nothing is active | |
13363 // it closes all menus. If passed an argument, it will search for menus BELOW | |
13364 _close: function( startMenu ) { | |
13365 if ( !startMenu ) { | |
13366 startMenu = this.active ? this.active.parent() : this.element; | |
13367 } | |
13368 | |
13369 startMenu | |
13370 .find( ".ui-menu" ) | |
13371 .hide() | |
13372 .attr( "aria-hidden", "true" ) | |
13373 .attr( "aria-expanded", "false" ) | |
13374 .end() | |
13375 .find( "a.ui-state-active" ) | |
13376 .removeClass( "ui-state-active" ); | |
13377 }, | |
13378 | |
13379 collapse: function( event ) { | |
13380 var newItem = this.active && | |
13381 this.active.parent().closest( ".ui-menu-item", this.element ); | |
13382 if ( newItem && newItem.length ) { | |
13383 this._close(); | |
13384 this.focus( event, newItem ); | |
13385 } | |
13386 }, | |
13387 | |
13388 expand: function( event ) { | |
13389 var newItem = this.active && | |
13390 this.active | |
13391 .children( ".ui-menu " ) | |
13392 .children( ".ui-menu-item" ) | |
13393 .first(); | |
13394 | |
13395 if ( newItem && newItem.length ) { | |
13396 this._open( newItem.parent() ); | |
13397 | |
13398 // Delay so Firefox will not hide activedescendant change in expanding submenu from AT | |
13399 this._delay(function() { | |
13400 this.focus( event, newItem ); | |
13401 }); | |
13402 } | |
13403 }, | |
13404 | |
13405 next: function( event ) { | |
13406 this._move( "next", "first", event ); | |
13407 }, | |
13408 | |
13409 previous: function( event ) { | |
13410 this._move( "prev", "last", event ); | |
13411 }, | |
13412 | |
13413 isFirstItem: function() { | |
13414 return this.active && !this.active.prevAll( ".ui-menu-item" ).length; | |
13415 }, | |
13416 | |
13417 isLastItem: function() { | |
13418 return this.active && !this.active.nextAll( ".ui-menu-item" ).length; | |
13419 }, | |
13420 | |
13421 _move: function( direction, filter, event ) { | |
13422 var next; | |
13423 if ( this.active ) { | |
13424 if ( direction === "first" || direction === "last" ) { | |
13425 next = this.active | |
13426 [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ) | |
13427 .eq( -1 ); | |
13428 } else { | |
13429 next = this.active | |
13430 [ direction + "All" ]( ".ui-menu-item" ) | |
13431 .eq( 0 ); | |
13432 } | |
13433 } | |
13434 if ( !next || !next.length || !this.active ) { | |
13435 next = this.activeMenu.children( ".ui-menu-item" )[ filter ](); | |
13436 } | |
13437 | |
13438 this.focus( event, next ); | |
13439 }, | |
13440 | |
13441 nextPage: function( event ) { | |
13442 var item, base, height; | |
13443 | |
13444 if ( !this.active ) { | |
13445 this.next( event ); | |
13446 return; | |
13447 } | |
13448 if ( this.isLastItem() ) { | |
13449 return; | |
13450 } | |
13451 if ( this._hasScroll() ) { | |
13452 base = this.active.offset().top; | |
13453 height = this.element.height(); | |
13454 this.active.nextAll( ".ui-menu-item" ).each(function() { | |
13455 item = $( this ); | |
13456 return item.offset().top - base - height < 0; | |
13457 }); | |
13458 | |
13459 this.focus( event, item ); | |
13460 } else { | |
13461 this.focus( event, this.activeMenu.children( ".ui-menu-item" ) | |
13462 [ !this.active ? "first" : "last" ]() ); | |
13463 } | |
13464 }, | |
13465 | |
13466 previousPage: function( event ) { | |
13467 var item, base, height; | |
13468 if ( !this.active ) { | |
13469 this.next( event ); | |
13470 return; | |
13471 } | |
13472 if ( this.isFirstItem() ) { | |
13473 return; | |
13474 } | |
13475 if ( this._hasScroll() ) { | |
13476 base = this.active.offset().top; | |
13477 height = this.element.height(); | |
13478 this.active.prevAll( ".ui-menu-item" ).each(function() { | |
13479 item = $( this ); | |
13480 return item.offset().top - base + height > 0; | |
13481 }); | |
13482 | |
13483 this.focus( event, item ); | |
13484 } else { | |
13485 this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() ); | |
13486 } | |
13487 }, | |
13488 | |
13489 _hasScroll: function() { | |
13490 return this.element.outerHeight() < this.element.prop( "scrollHeight" ); | |
13491 }, | |
13492 | |
13493 select: function( event ) { | |
13494 // TODO: It should never be possible to not have an active item at this | |
13495 // point, but the tests don't trigger mouseenter before click. | |
13496 this.active = this.active || $( event.target ).closest( ".ui-menu-item" ); | |
13497 var ui = { item: this.active }; | |
13498 if ( !this.active.has( ".ui-menu" ).length ) { | |
13499 this.collapseAll( event, true ); | |
13500 } | |
13501 this._trigger( "select", event, ui ); | |
13502 } | |
13503 }); | |
13504 | |
13505 }( jQuery )); | |
13506 (function( $, undefined ) { | |
13507 | |
13508 $.widget( "ui.progressbar", { | |
13509 version: "1.10.3", | |
13510 options: { | |
13511 max: 100, | |
13512 value: 0, | |
13513 | |
13514 change: null, | |
13515 complete: null | |
13516 }, | |
13517 | |
13518 min: 0, | |
13519 | |
13520 _create: function() { | |
13521 // Constrain initial value | |
13522 this.oldValue = this.options.value = this._constrainedValue(); | |
13523 | |
13524 this.element | |
13525 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) | |
13526 .attr({ | |
13527 // Only set static values, aria-valuenow and aria-valuemax are | |
13528 // set inside _refreshValue() | |
13529 role: "progressbar", | |
13530 "aria-valuemin": this.min | |
13531 }); | |
13532 | |
13533 this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" ) | |
13534 .appendTo( this.element ); | |
13535 | |
13536 this._refreshValue(); | |
13537 }, | |
13538 | |
13539 _destroy: function() { | |
13540 this.element | |
13541 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) | |
13542 .removeAttr( "role" ) | |
13543 .removeAttr( "aria-valuemin" ) | |
13544 .removeAttr( "aria-valuemax" ) | |
13545 .removeAttr( "aria-valuenow" ); | |
13546 | |
13547 this.valueDiv.remove(); | |
13548 }, | |
13549 | |
13550 value: function( newValue ) { | |
13551 if ( newValue === undefined ) { | |
13552 return this.options.value; | |
13553 } | |
13554 | |
13555 this.options.value = this._constrainedValue( newValue ); | |
13556 this._refreshValue(); | |
13557 }, | |
13558 | |
13559 _constrainedValue: function( newValue ) { | |
13560 if ( newValue === undefined ) { | |
13561 newValue = this.options.value; | |
13562 } | |
13563 | |
13564 this.indeterminate = newValue === false; | |
13565 | |
13566 // sanitize value | |
13567 if ( typeof newValue !== "number" ) { | |
13568 newValue = 0; | |
13569 } | |
13570 | |
13571 return this.indeterminate ? false : | |
13572 Math.min( this.options.max, Math.max( this.min, newValue ) ); | |
13573 }, | |
13574 | |
13575 _setOptions: function( options ) { | |
13576 // Ensure "value" option is set after other values (like max) | |
13577 var value = options.value; | |
13578 delete options.value; | |
13579 | |
13580 this._super( options ); | |
13581 | |
13582 this.options.value = this._constrainedValue( value ); | |
13583 this._refreshValue(); | |
13584 }, | |
13585 | |
13586 _setOption: function( key, value ) { | |
13587 if ( key === "max" ) { | |
13588 // Don't allow a max less than min | |
13589 value = Math.max( this.min, value ); | |
13590 } | |
13591 | |
13592 this._super( key, value ); | |
13593 }, | |
13594 | |
13595 _percentage: function() { | |
13596 return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min ); | |
13597 }, | |
13598 | |
13599 _refreshValue: function() { | |
13600 var value = this.options.value, | |
13601 percentage = this._percentage(); | |
13602 | |
13603 this.valueDiv | |
13604 .toggle( this.indeterminate || value > this.min ) | |
13605 .toggleClass( "ui-corner-right", value === this.options.max ) | |
13606 .width( percentage.toFixed(0) + "%" ); | |
13607 | |
13608 this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate ); | |
13609 | |
13610 if ( this.indeterminate ) { | |
13611 this.element.removeAttr( "aria-valuenow" ); | |
13612 if ( !this.overlayDiv ) { | |
13613 this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv ); | |
13614 } | |
13615 } else { | |
13616 this.element.attr({ | |
13617 "aria-valuemax": this.options.max, | |
13618 "aria-valuenow": value | |
13619 }); | |
13620 if ( this.overlayDiv ) { | |
13621 this.overlayDiv.remove(); | |
13622 this.overlayDiv = null; | |
13623 } | |
13624 } | |
13625 | |
13626 if ( this.oldValue !== value ) { | |
13627 this.oldValue = value; | |
13628 this._trigger( "change" ); | |
13629 } | |
13630 if ( value === this.options.max ) { | |
13631 this._trigger( "complete" ); | |
13632 } | |
13633 } | |
13634 }); | |
13635 | |
13636 })( jQuery ); | |
13637 (function( $, undefined ) { | |
13638 | |
13639 // number of pages in a slider | |
13640 // (how many times can you page up/down to go through the whole range) | |
13641 var numPages = 5; | |
13642 | |
13643 $.widget( "ui.slider", $.ui.mouse, { | |
13644 version: "1.10.3", | |
13645 widgetEventPrefix: "slide", | |
13646 | |
13647 options: { | |
13648 animate: false, | |
13649 distance: 0, | |
13650 max: 100, | |
13651 min: 0, | |
13652 orientation: "horizontal", | |
13653 range: false, | |
13654 step: 1, | |
13655 value: 0, | |
13656 values: null, | |
13657 | |
13658 // callbacks | |
13659 change: null, | |
13660 slide: null, | |
13661 start: null, | |
13662 stop: null | |
13663 }, | |
13664 | |
13665 _create: function() { | |
13666 this._keySliding = false; | |
13667 this._mouseSliding = false; | |
13668 this._animateOff = true; | |
13669 this._handleIndex = null; | |
13670 this._detectOrientation(); | |
13671 this._mouseInit(); | |
13672 | |
13673 this.element | |
13674 .addClass( "ui-slider" + | |
13675 " ui-slider-" + this.orientation + | |
13676 " ui-widget" + | |
13677 " ui-widget-content" + | |
13678 " ui-corner-all"); | |
13679 | |
13680 this._refresh(); | |
13681 this._setOption( "disabled", this.options.disabled ); | |
13682 | |
13683 this._animateOff = false; | |
13684 }, | |
13685 | |
13686 _refresh: function() { | |
13687 this._createRange(); | |
13688 this._createHandles(); | |
13689 this._setupEvents(); | |
13690 this._refreshValue(); | |
13691 }, | |
13692 | |
13693 _createHandles: function() { | |
13694 var i, handleCount, | |
13695 options = this.options, | |
13696 existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), | |
13697 handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>", | |
13698 handles = []; | |
13699 | |
13700 handleCount = ( options.values && options.values.length ) || 1; | |
13701 | |
13702 if ( existingHandles.length > handleCount ) { | |
13703 existingHandles.slice( handleCount ).remove(); | |
13704 existingHandles = existingHandles.slice( 0, handleCount ); | |
13705 } | |
13706 | |
13707 for ( i = existingHandles.length; i < handleCount; i++ ) { | |
13708 handles.push( handle ); | |
13709 } | |
13710 | |
13711 this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) ); | |
13712 | |
13713 this.handle = this.handles.eq( 0 ); | |
13714 | |
13715 this.handles.each(function( i ) { | |
13716 $( this ).data( "ui-slider-handle-index", i ); | |
13717 }); | |
13718 }, | |
13719 | |
13720 _createRange: function() { | |
13721 var options = this.options, | |
13722 classes = ""; | |
13723 | |
13724 if ( options.range ) { | |
13725 if ( options.range === true ) { | |
13726 if ( !options.values ) { | |
13727 options.values = [ this._valueMin(), this._valueMin() ]; | |
13728 } else if ( options.values.length && options.values.length !== 2 ) { | |
13729 options.values = [ options.values[0], options.values[0] ]; | |
13730 } else if ( $.isArray( options.values ) ) { | |
13731 options.values = options.values.slice(0); | |
13732 } | |
13733 } | |
13734 | |
13735 if ( !this.range || !this.range.length ) { | |
13736 this.range = $( "<div></div>" ) | |
13737 .appendTo( this.element ); | |
13738 | |
13739 classes = "ui-slider-range" + | |
13740 // note: this isn't the most fittingly semantic framework class for this element, | |
13741 // but worked best visually with a variety of themes | |
13742 " ui-widget-header ui-corner-all"; | |
13743 } else { | |
13744 this.range.removeClass( "ui-slider-range-min ui-slider-range-max" ) | |
13745 // Handle range switching from true to min/max | |
13746 .css({ | |
13747 "left": "", | |
13748 "bottom": "" | |
13749 }); | |
13750 } | |
13751 | |
13752 this.range.addClass( classes + | |
13753 ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) ); | |
13754 } else { | |
13755 this.range = $([]); | |
13756 } | |
13757 }, | |
13758 | |
13759 _setupEvents: function() { | |
13760 var elements = this.handles.add( this.range ).filter( "a" ); | |
13761 this._off( elements ); | |
13762 this._on( elements, this._handleEvents ); | |
13763 this._hoverable( elements ); | |
13764 this._focusable( elements ); | |
13765 }, | |
13766 | |
13767 _destroy: function() { | |
13768 this.handles.remove(); | |
13769 this.range.remove(); | |
13770 | |
13771 this.element | |
13772 .removeClass( "ui-slider" + | |
13773 " ui-slider-horizontal" + | |
13774 " ui-slider-vertical" + | |
13775 " ui-widget" + | |
13776 " ui-widget-content" + | |
13777 " ui-corner-all" ); | |
13778 | |
13779 this._mouseDestroy(); | |
13780 }, | |
13781 | |
13782 _mouseCapture: function( event ) { | |
13783 var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle, | |
13784 that = this, | |
13785 o = this.options; | |
13786 | |
13787 if ( o.disabled ) { | |
13788 return false; | |
13789 } | |
13790 | |
13791 this.elementSize = { | |
13792 width: this.element.outerWidth(), | |
13793 height: this.element.outerHeight() | |
13794 }; | |
13795 this.elementOffset = this.element.offset(); | |
13796 | |
13797 position = { x: event.pageX, y: event.pageY }; | |
13798 normValue = this._normValueFromMouse( position ); | |
13799 distance = this._valueMax() - this._valueMin() + 1; | |
13800 this.handles.each(function( i ) { | |
13801 var thisDistance = Math.abs( normValue - that.values(i) ); | |
13802 if (( distance > thisDistance ) || | |
13803 ( distance === thisDistance && | |
13804 (i === that._lastChangedValue || that.values(i) === o.min ))) { | |
13805 distance = thisDistance; | |
13806 closestHandle = $( this ); | |
13807 index = i; | |
13808 } | |
13809 }); | |
13810 | |
13811 allowed = this._start( event, index ); | |
13812 if ( allowed === false ) { | |
13813 return false; | |
13814 } | |
13815 this._mouseSliding = true; | |
13816 | |
13817 this._handleIndex = index; | |
13818 | |
13819 closestHandle | |
13820 .addClass( "ui-state-active" ) | |
13821 .focus(); | |
13822 | |
13823 offset = closestHandle.offset(); | |
13824 mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" ); | |
13825 this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { | |
13826 left: event.pageX - offset.left - ( closestHandle.width() / 2 ), | |
13827 top: event.pageY - offset.top - | |
13828 ( closestHandle.height() / 2 ) - | |
13829 ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - | |
13830 ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + | |
13831 ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) | |
13832 }; | |
13833 | |
13834 if ( !this.handles.hasClass( "ui-state-hover" ) ) { | |
13835 this._slide( event, index, normValue ); | |
13836 } | |
13837 this._animateOff = true; | |
13838 return true; | |
13839 }, | |
13840 | |
13841 _mouseStart: function() { | |
13842 return true; | |
13843 }, | |
13844 | |
13845 _mouseDrag: function( event ) { | |
13846 var position = { x: event.pageX, y: event.pageY }, | |
13847 normValue = this._normValueFromMouse( position ); | |
13848 | |
13849 this._slide( event, this._handleIndex, normValue ); | |
13850 | |
13851 return false; | |
13852 }, | |
13853 | |
13854 _mouseStop: function( event ) { | |
13855 this.handles.removeClass( "ui-state-active" ); | |
13856 this._mouseSliding = false; | |
13857 | |
13858 this._stop( event, this._handleIndex ); | |
13859 this._change( event, this._handleIndex ); | |
13860 | |
13861 this._handleIndex = null; | |
13862 this._clickOffset = null; | |
13863 this._animateOff = false; | |
13864 | |
13865 return false; | |
13866 }, | |
13867 | |
13868 _detectOrientation: function() { | |
13869 this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; | |
13870 }, | |
13871 | |
13872 _normValueFromMouse: function( position ) { | |
13873 var pixelTotal, | |
13874 pixelMouse, | |
13875 percentMouse, | |
13876 valueTotal, | |
13877 valueMouse; | |
13878 | |
13879 if ( this.orientation === "horizontal" ) { | |
13880 pixelTotal = this.elementSize.width; | |
13881 pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); | |
13882 } else { | |
13883 pixelTotal = this.elementSize.height; | |
13884 pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); | |
13885 } | |
13886 | |
13887 percentMouse = ( pixelMouse / pixelTotal ); | |
13888 if ( percentMouse > 1 ) { | |
13889 percentMouse = 1; | |
13890 } | |
13891 if ( percentMouse < 0 ) { | |
13892 percentMouse = 0; | |
13893 } | |
13894 if ( this.orientation === "vertical" ) { | |
13895 percentMouse = 1 - percentMouse; | |
13896 } | |
13897 | |
13898 valueTotal = this._valueMax() - this._valueMin(); | |
13899 valueMouse = this._valueMin() + percentMouse * valueTotal; | |
13900 | |
13901 return this._trimAlignValue( valueMouse ); | |
13902 }, | |
13903 | |
13904 _start: function( event, index ) { | |
13905 var uiHash = { | |
13906 handle: this.handles[ index ], | |
13907 value: this.value() | |
13908 }; | |
13909 if ( this.options.values && this.options.values.length ) { | |
13910 uiHash.value = this.values( index ); | |
13911 uiHash.values = this.values(); | |
13912 } | |
13913 return this._trigger( "start", event, uiHash ); | |
13914 }, | |
13915 | |
13916 _slide: function( event, index, newVal ) { | |
13917 var otherVal, | |
13918 newValues, | |
13919 allowed; | |
13920 | |
13921 if ( this.options.values && this.options.values.length ) { | |
13922 otherVal = this.values( index ? 0 : 1 ); | |
13923 | |
13924 if ( ( this.options.values.length === 2 && this.options.range === true ) && | |
13925 ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) | |
13926 ) { | |
13927 newVal = otherVal; | |
13928 } | |
13929 | |
13930 if ( newVal !== this.values( index ) ) { | |
13931 newValues = this.values(); | |
13932 newValues[ index ] = newVal; | |
13933 // A slide can be canceled by returning false from the slide callback | |
13934 allowed = this._trigger( "slide", event, { | |
13935 handle: this.handles[ index ], | |
13936 value: newVal, | |
13937 values: newValues | |
13938 } ); | |
13939 otherVal = this.values( index ? 0 : 1 ); | |
13940 if ( allowed !== false ) { | |
13941 this.values( index, newVal, true ); | |
13942 } | |
13943 } | |
13944 } else { | |
13945 if ( newVal !== this.value() ) { | |
13946 // A slide can be canceled by returning false from the slide callback | |
13947 allowed = this._trigger( "slide", event, { | |
13948 handle: this.handles[ index ], | |
13949 value: newVal | |
13950 } ); | |
13951 if ( allowed !== false ) { | |
13952 this.value( newVal ); | |
13953 } | |
13954 } | |
13955 } | |
13956 }, | |
13957 | |
13958 _stop: function( event, index ) { | |
13959 var uiHash = { | |
13960 handle: this.handles[ index ], | |
13961 value: this.value() | |
13962 }; | |
13963 if ( this.options.values && this.options.values.length ) { | |
13964 uiHash.value = this.values( index ); | |
13965 uiHash.values = this.values(); | |
13966 } | |
13967 | |
13968 this._trigger( "stop", event, uiHash ); | |
13969 }, | |
13970 | |
13971 _change: function( event, index ) { | |
13972 if ( !this._keySliding && !this._mouseSliding ) { | |
13973 var uiHash = { | |
13974 handle: this.handles[ index ], | |
13975 value: this.value() | |
13976 }; | |
13977 if ( this.options.values && this.options.values.length ) { | |
13978 uiHash.value = this.values( index ); | |
13979 uiHash.values = this.values(); | |
13980 } | |
13981 | |
13982 //store the last changed value index for reference when handles overlap | |
13983 this._lastChangedValue = index; | |
13984 | |
13985 this._trigger( "change", event, uiHash ); | |
13986 } | |
13987 }, | |
13988 | |
13989 value: function( newValue ) { | |
13990 if ( arguments.length ) { | |
13991 this.options.value = this._trimAlignValue( newValue ); | |
13992 this._refreshValue(); | |
13993 this._change( null, 0 ); | |
13994 return; | |
13995 } | |
13996 | |
13997 return this._value(); | |
13998 }, | |
13999 | |
14000 values: function( index, newValue ) { | |
14001 var vals, | |
14002 newValues, | |
14003 i; | |
14004 | |
14005 if ( arguments.length > 1 ) { | |
14006 this.options.values[ index ] = this._trimAlignValue( newValue ); | |
14007 this._refreshValue(); | |
14008 this._change( null, index ); | |
14009 return; | |
14010 } | |
14011 | |
14012 if ( arguments.length ) { | |
14013 if ( $.isArray( arguments[ 0 ] ) ) { | |
14014 vals = this.options.values; | |
14015 newValues = arguments[ 0 ]; | |
14016 for ( i = 0; i < vals.length; i += 1 ) { | |
14017 vals[ i ] = this._trimAlignValue( newValues[ i ] ); | |
14018 this._change( null, i ); | |
14019 } | |
14020 this._refreshValue(); | |
14021 } else { | |
14022 if ( this.options.values && this.options.values.length ) { | |
14023 return this._values( index ); | |
14024 } else { | |
14025 return this.value(); | |
14026 } | |
14027 } | |
14028 } else { | |
14029 return this._values(); | |
14030 } | |
14031 }, | |
14032 | |
14033 _setOption: function( key, value ) { | |
14034 var i, | |
14035 valsLength = 0; | |
14036 | |
14037 if ( key === "range" && this.options.range === true ) { | |
14038 if ( value === "min" ) { | |
14039 this.options.value = this._values( 0 ); | |
14040 this.options.values = null; | |
14041 } else if ( value === "max" ) { | |
14042 this.options.value = this._values( this.options.values.length-1 ); | |
14043 this.options.values = null; | |
14044 } | |
14045 } | |
14046 | |
14047 if ( $.isArray( this.options.values ) ) { | |
14048 valsLength = this.options.values.length; | |
14049 } | |
14050 | |
14051 $.Widget.prototype._setOption.apply( this, arguments ); | |
14052 | |
14053 switch ( key ) { | |
14054 case "orientation": | |
14055 this._detectOrientation(); | |
14056 this.element | |
14057 .removeClass( "ui-slider-horizontal ui-slider-vertical" ) | |
14058 .addClass( "ui-slider-" + this.orientation ); | |
14059 this._refreshValue(); | |
14060 break; | |
14061 case "value": | |
14062 this._animateOff = true; | |
14063 this._refreshValue(); | |
14064 this._change( null, 0 ); | |
14065 this._animateOff = false; | |
14066 break; | |
14067 case "values": | |
14068 this._animateOff = true; | |
14069 this._refreshValue(); | |
14070 for ( i = 0; i < valsLength; i += 1 ) { | |
14071 this._change( null, i ); | |
14072 } | |
14073 this._animateOff = false; | |
14074 break; | |
14075 case "min": | |
14076 case "max": | |
14077 this._animateOff = true; | |
14078 this._refreshValue(); | |
14079 this._animateOff = false; | |
14080 break; | |
14081 case "range": | |
14082 this._animateOff = true; | |
14083 this._refresh(); | |
14084 this._animateOff = false; | |
14085 break; | |
14086 } | |
14087 }, | |
14088 | |
14089 //internal value getter | |
14090 // _value() returns value trimmed by min and max, aligned by step | |
14091 _value: function() { | |
14092 var val = this.options.value; | |
14093 val = this._trimAlignValue( val ); | |
14094 | |
14095 return val; | |
14096 }, | |
14097 | |
14098 //internal values getter | |
14099 // _values() returns array of values trimmed by min and max, aligned by step | |
14100 // _values( index ) returns single value trimmed by min and max, aligned by step | |
14101 _values: function( index ) { | |
14102 var val, | |
14103 vals, | |
14104 i; | |
14105 | |
14106 if ( arguments.length ) { | |
14107 val = this.options.values[ index ]; | |
14108 val = this._trimAlignValue( val ); | |
14109 | |
14110 return val; | |
14111 } else if ( this.options.values && this.options.values.length ) { | |
14112 // .slice() creates a copy of the array | |
14113 // this copy gets trimmed by min and max and then returned | |
14114 vals = this.options.values.slice(); | |
14115 for ( i = 0; i < vals.length; i+= 1) { | |
14116 vals[ i ] = this._trimAlignValue( vals[ i ] ); | |
14117 } | |
14118 | |
14119 return vals; | |
14120 } else { | |
14121 return []; | |
14122 } | |
14123 }, | |
14124 | |
14125 // returns the step-aligned value that val is closest to, between (inclusive) min and max | |
14126 _trimAlignValue: function( val ) { | |
14127 if ( val <= this._valueMin() ) { | |
14128 return this._valueMin(); | |
14129 } | |
14130 if ( val >= this._valueMax() ) { | |
14131 return this._valueMax(); | |
14132 } | |
14133 var step = ( this.options.step > 0 ) ? this.options.step : 1, | |
14134 valModStep = (val - this._valueMin()) % step, | |
14135 alignValue = val - valModStep; | |
14136 | |
14137 if ( Math.abs(valModStep) * 2 >= step ) { | |
14138 alignValue += ( valModStep > 0 ) ? step : ( -step ); | |
14139 } | |
14140 | |
14141 // Since JavaScript has problems with large floats, round | |
14142 // the final value to 5 digits after the decimal point (see #4124) | |
14143 return parseFloat( alignValue.toFixed(5) ); | |
14144 }, | |
14145 | |
14146 _valueMin: function() { | |
14147 return this.options.min; | |
14148 }, | |
14149 | |
14150 _valueMax: function() { | |
14151 return this.options.max; | |
14152 }, | |
14153 | |
14154 _refreshValue: function() { | |
14155 var lastValPercent, valPercent, value, valueMin, valueMax, | |
14156 oRange = this.options.range, | |
14157 o = this.options, | |
14158 that = this, | |
14159 animate = ( !this._animateOff ) ? o.animate : false, | |
14160 _set = {}; | |
14161 | |
14162 if ( this.options.values && this.options.values.length ) { | |
14163 this.handles.each(function( i ) { | |
14164 valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100; | |
14165 _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; | |
14166 $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); | |
14167 if ( that.options.range === true ) { | |
14168 if ( that.orientation === "horizontal" ) { | |
14169 if ( i === 0 ) { | |
14170 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); | |
14171 } | |
14172 if ( i === 1 ) { | |
14173 that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14174 } | |
14175 } else { | |
14176 if ( i === 0 ) { | |
14177 that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); | |
14178 } | |
14179 if ( i === 1 ) { | |
14180 that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14181 } | |
14182 } | |
14183 } | |
14184 lastValPercent = valPercent; | |
14185 }); | |
14186 } else { | |
14187 value = this.value(); | |
14188 valueMin = this._valueMin(); | |
14189 valueMax = this._valueMax(); | |
14190 valPercent = ( valueMax !== valueMin ) ? | |
14191 ( value - valueMin ) / ( valueMax - valueMin ) * 100 : | |
14192 0; | |
14193 _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; | |
14194 this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); | |
14195 | |
14196 if ( oRange === "min" && this.orientation === "horizontal" ) { | |
14197 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); | |
14198 } | |
14199 if ( oRange === "max" && this.orientation === "horizontal" ) { | |
14200 this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14201 } | |
14202 if ( oRange === "min" && this.orientation === "vertical" ) { | |
14203 this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); | |
14204 } | |
14205 if ( oRange === "max" && this.orientation === "vertical" ) { | |
14206 this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); | |
14207 } | |
14208 } | |
14209 }, | |
14210 | |
14211 _handleEvents: { | |
14212 keydown: function( event ) { | |
14213 /*jshint maxcomplexity:25*/ | |
14214 var allowed, curVal, newVal, step, | |
14215 index = $( event.target ).data( "ui-slider-handle-index" ); | |
14216 | |
14217 switch ( event.keyCode ) { | |
14218 case $.ui.keyCode.HOME: | |
14219 case $.ui.keyCode.END: | |
14220 case $.ui.keyCode.PAGE_UP: | |
14221 case $.ui.keyCode.PAGE_DOWN: | |
14222 case $.ui.keyCode.UP: | |
14223 case $.ui.keyCode.RIGHT: | |
14224 case $.ui.keyCode.DOWN: | |
14225 case $.ui.keyCode.LEFT: | |
14226 event.preventDefault(); | |
14227 if ( !this._keySliding ) { | |
14228 this._keySliding = true; | |
14229 $( event.target ).addClass( "ui-state-active" ); | |
14230 allowed = this._start( event, index ); | |
14231 if ( allowed === false ) { | |
14232 return; | |
14233 } | |
14234 } | |
14235 break; | |
14236 } | |
14237 | |
14238 step = this.options.step; | |
14239 if ( this.options.values && this.options.values.length ) { | |
14240 curVal = newVal = this.values( index ); | |
14241 } else { | |
14242 curVal = newVal = this.value(); | |
14243 } | |
14244 | |
14245 switch ( event.keyCode ) { | |
14246 case $.ui.keyCode.HOME: | |
14247 newVal = this._valueMin(); | |
14248 break; | |
14249 case $.ui.keyCode.END: | |
14250 newVal = this._valueMax(); | |
14251 break; | |
14252 case $.ui.keyCode.PAGE_UP: | |
14253 newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) ); | |
14254 break; | |
14255 case $.ui.keyCode.PAGE_DOWN: | |
14256 newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) ); | |
14257 break; | |
14258 case $.ui.keyCode.UP: | |
14259 case $.ui.keyCode.RIGHT: | |
14260 if ( curVal === this._valueMax() ) { | |
14261 return; | |
14262 } | |
14263 newVal = this._trimAlignValue( curVal + step ); | |
14264 break; | |
14265 case $.ui.keyCode.DOWN: | |
14266 case $.ui.keyCode.LEFT: | |
14267 if ( curVal === this._valueMin() ) { | |
14268 return; | |
14269 } | |
14270 newVal = this._trimAlignValue( curVal - step ); | |
14271 break; | |
14272 } | |
14273 | |
14274 this._slide( event, index, newVal ); | |
14275 }, | |
14276 click: function( event ) { | |
14277 event.preventDefault(); | |
14278 }, | |
14279 keyup: function( event ) { | |
14280 var index = $( event.target ).data( "ui-slider-handle-index" ); | |
14281 | |
14282 if ( this._keySliding ) { | |
14283 this._keySliding = false; | |
14284 this._stop( event, index ); | |
14285 this._change( event, index ); | |
14286 $( event.target ).removeClass( "ui-state-active" ); | |
14287 } | |
14288 } | |
14289 } | |
14290 | |
14291 }); | |
14292 | |
14293 }(jQuery)); | |
14294 (function( $ ) { | |
14295 | |
14296 function modifier( fn ) { | |
14297 return function() { | |
14298 var previous = this.element.val(); | |
14299 fn.apply( this, arguments ); | |
14300 this._refresh(); | |
14301 if ( previous !== this.element.val() ) { | |
14302 this._trigger( "change" ); | |
14303 } | |
14304 }; | |
14305 } | |
14306 | |
14307 $.widget( "ui.spinner", { | |
14308 version: "1.10.3", | |
14309 defaultElement: "<input>", | |
14310 widgetEventPrefix: "spin", | |
14311 options: { | |
14312 culture: null, | |
14313 icons: { | |
14314 down: "ui-icon-triangle-1-s", | |
14315 up: "ui-icon-triangle-1-n" | |
14316 }, | |
14317 incremental: true, | |
14318 max: null, | |
14319 min: null, | |
14320 numberFormat: null, | |
14321 page: 10, | |
14322 step: 1, | |
14323 | |
14324 change: null, | |
14325 spin: null, | |
14326 start: null, | |
14327 stop: null | |
14328 }, | |
14329 | |
14330 _create: function() { | |
14331 // handle string values that need to be parsed | |
14332 this._setOption( "max", this.options.max ); | |
14333 this._setOption( "min", this.options.min ); | |
14334 this._setOption( "step", this.options.step ); | |
14335 | |
14336 // format the value, but don't constrain | |
14337 this._value( this.element.val(), true ); | |
14338 | |
14339 this._draw(); | |
14340 this._on( this._events ); | |
14341 this._refresh(); | |
14342 | |
14343 // turning off autocomplete prevents the browser from remembering the | |
14344 // value when navigating through history, so we re-enable autocomplete | |
14345 // if the page is unloaded before the widget is destroyed. #7790 | |
14346 this._on( this.window, { | |
14347 beforeunload: function() { | |
14348 this.element.removeAttr( "autocomplete" ); | |
14349 } | |
14350 }); | |
14351 }, | |
14352 | |
14353 _getCreateOptions: function() { | |
14354 var options = {}, | |
14355 element = this.element; | |
14356 | |
14357 $.each( [ "min", "max", "step" ], function( i, option ) { | |
14358 var value = element.attr( option ); | |
14359 if ( value !== undefined && value.length ) { | |
14360 options[ option ] = value; | |
14361 } | |
14362 }); | |
14363 | |
14364 return options; | |
14365 }, | |
14366 | |
14367 _events: { | |
14368 keydown: function( event ) { | |
14369 if ( this._start( event ) && this._keydown( event ) ) { | |
14370 event.preventDefault(); | |
14371 } | |
14372 }, | |
14373 keyup: "_stop", | |
14374 focus: function() { | |
14375 this.previous = this.element.val(); | |
14376 }, | |
14377 blur: function( event ) { | |
14378 if ( this.cancelBlur ) { | |
14379 delete this.cancelBlur; | |
14380 return; | |
14381 } | |
14382 | |
14383 this._stop(); | |
14384 this._refresh(); | |
14385 if ( this.previous !== this.element.val() ) { | |
14386 this._trigger( "change", event ); | |
14387 } | |
14388 }, | |
14389 mousewheel: function( event, delta ) { | |
14390 if ( !delta ) { | |
14391 return; | |
14392 } | |
14393 if ( !this.spinning && !this._start( event ) ) { | |
14394 return false; | |
14395 } | |
14396 | |
14397 this._spin( (delta > 0 ? 1 : -1) * this.options.step, event ); | |
14398 clearTimeout( this.mousewheelTimer ); | |
14399 this.mousewheelTimer = this._delay(function() { | |
14400 if ( this.spinning ) { | |
14401 this._stop( event ); | |
14402 } | |
14403 }, 100 ); | |
14404 event.preventDefault(); | |
14405 }, | |
14406 "mousedown .ui-spinner-button": function( event ) { | |
14407 var previous; | |
14408 | |
14409 // We never want the buttons to have focus; whenever the user is | |
14410 // interacting with the spinner, the focus should be on the input. | |
14411 // If the input is focused then this.previous is properly set from | |
14412 // when the input first received focus. If the input is not focused | |
14413 // then we need to set this.previous based on the value before spinning. | |
14414 previous = this.element[0] === this.document[0].activeElement ? | |
14415 this.previous : this.element.val(); | |
14416 function checkFocus() { | |
14417 var isActive = this.element[0] === this.document[0].activeElement; | |
14418 if ( !isActive ) { | |
14419 this.element.focus(); | |
14420 this.previous = previous; | |
14421 // support: IE | |
14422 // IE sets focus asynchronously, so we need to check if focus | |
14423 // moved off of the input because the user clicked on the button. | |
14424 this._delay(function() { | |
14425 this.previous = previous; | |
14426 }); | |
14427 } | |
14428 } | |
14429 | |
14430 // ensure focus is on (or stays on) the text field | |
14431 event.preventDefault(); | |
14432 checkFocus.call( this ); | |
14433 | |
14434 // support: IE | |
14435 // IE doesn't prevent moving focus even with event.preventDefault() | |
14436 // so we set a flag to know when we should ignore the blur event | |
14437 // and check (again) if focus moved off of the input. | |
14438 this.cancelBlur = true; | |
14439 this._delay(function() { | |
14440 delete this.cancelBlur; | |
14441 checkFocus.call( this ); | |
14442 }); | |
14443 | |
14444 if ( this._start( event ) === false ) { | |
14445 return; | |
14446 } | |
14447 | |
14448 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); | |
14449 }, | |
14450 "mouseup .ui-spinner-button": "_stop", | |
14451 "mouseenter .ui-spinner-button": function( event ) { | |
14452 // button will add ui-state-active if mouse was down while mouseleave and kept down | |
14453 if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) { | |
14454 return; | |
14455 } | |
14456 | |
14457 if ( this._start( event ) === false ) { | |
14458 return false; | |
14459 } | |
14460 this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event ); | |
14461 }, | |
14462 // TODO: do we really want to consider this a stop? | |
14463 // shouldn't we just stop the repeater and wait until mouseup before | |
14464 // we trigger the stop event? | |
14465 "mouseleave .ui-spinner-button": "_stop" | |
14466 }, | |
14467 | |
14468 _draw: function() { | |
14469 var uiSpinner = this.uiSpinner = this.element | |
14470 .addClass( "ui-spinner-input" ) | |
14471 .attr( "autocomplete", "off" ) | |
14472 .wrap( this._uiSpinnerHtml() ) | |
14473 .parent() | |
14474 // add buttons | |
14475 .append( this._buttonHtml() ); | |
14476 | |
14477 this.element.attr( "role", "spinbutton" ); | |
14478 | |
14479 // button bindings | |
14480 this.buttons = uiSpinner.find( ".ui-spinner-button" ) | |
14481 .attr( "tabIndex", -1 ) | |
14482 .button() | |
14483 .removeClass( "ui-corner-all" ); | |
14484 | |
14485 // IE 6 doesn't understand height: 50% for the buttons | |
14486 // unless the wrapper has an explicit height | |
14487 if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) && | |
14488 uiSpinner.height() > 0 ) { | |
14489 uiSpinner.height( uiSpinner.height() ); | |
14490 } | |
14491 | |
14492 // disable spinner if element was already disabled | |
14493 if ( this.options.disabled ) { | |
14494 this.disable(); | |
14495 } | |
14496 }, | |
14497 | |
14498 _keydown: function( event ) { | |
14499 var options = this.options, | |
14500 keyCode = $.ui.keyCode; | |
14501 | |
14502 switch ( event.keyCode ) { | |
14503 case keyCode.UP: | |
14504 this._repeat( null, 1, event ); | |
14505 return true; | |
14506 case keyCode.DOWN: | |
14507 this._repeat( null, -1, event ); | |
14508 return true; | |
14509 case keyCode.PAGE_UP: | |
14510 this._repeat( null, options.page, event ); | |
14511 return true; | |
14512 case keyCode.PAGE_DOWN: | |
14513 this._repeat( null, -options.page, event ); | |
14514 return true; | |
14515 } | |
14516 | |
14517 return false; | |
14518 }, | |
14519 | |
14520 _uiSpinnerHtml: function() { | |
14521 return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"; | |
14522 }, | |
14523 | |
14524 _buttonHtml: function() { | |
14525 return "" + | |
14526 "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + | |
14527 "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + | |
14528 "</a>" + | |
14529 "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + | |
14530 "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + | |
14531 "</a>"; | |
14532 }, | |
14533 | |
14534 _start: function( event ) { | |
14535 if ( !this.spinning && this._trigger( "start", event ) === false ) { | |
14536 return false; | |
14537 } | |
14538 | |
14539 if ( !this.counter ) { | |
14540 this.counter = 1; | |
14541 } | |
14542 this.spinning = true; | |
14543 return true; | |
14544 }, | |
14545 | |
14546 _repeat: function( i, steps, event ) { | |
14547 i = i || 500; | |
14548 | |
14549 clearTimeout( this.timer ); | |
14550 this.timer = this._delay(function() { | |
14551 this._repeat( 40, steps, event ); | |
14552 }, i ); | |
14553 | |
14554 this._spin( steps * this.options.step, event ); | |
14555 }, | |
14556 | |
14557 _spin: function( step, event ) { | |
14558 var value = this.value() || 0; | |
14559 | |
14560 if ( !this.counter ) { | |
14561 this.counter = 1; | |
14562 } | |
14563 | |
14564 value = this._adjustValue( value + step * this._increment( this.counter ) ); | |
14565 | |
14566 if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) { | |
14567 this._value( value ); | |
14568 this.counter++; | |
14569 } | |
14570 }, | |
14571 | |
14572 _increment: function( i ) { | |
14573 var incremental = this.options.incremental; | |
14574 | |
14575 if ( incremental ) { | |
14576 return $.isFunction( incremental ) ? | |
14577 incremental( i ) : | |
14578 Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); | |
14579 } | |
14580 | |
14581 return 1; | |
14582 }, | |
14583 | |
14584 _precision: function() { | |
14585 var precision = this._precisionOf( this.options.step ); | |
14586 if ( this.options.min !== null ) { | |
14587 precision = Math.max( precision, this._precisionOf( this.options.min ) ); | |
14588 } | |
14589 return precision; | |
14590 }, | |
14591 | |
14592 _precisionOf: function( num ) { | |
14593 var str = num.toString(), | |
14594 decimal = str.indexOf( "." ); | |
14595 return decimal === -1 ? 0 : str.length - decimal - 1; | |
14596 }, | |
14597 | |
14598 _adjustValue: function( value ) { | |
14599 var base, aboveMin, | |
14600 options = this.options; | |
14601 | |
14602 // make sure we're at a valid step | |
14603 // - find out where we are relative to the base (min or 0) | |
14604 base = options.min !== null ? options.min : 0; | |
14605 aboveMin = value - base; | |
14606 // - round to the nearest step | |
14607 aboveMin = Math.round(aboveMin / options.step) * options.step; | |
14608 // - rounding is based on 0, so adjust back to our base | |
14609 value = base + aboveMin; | |
14610 | |
14611 // fix precision from bad JS floating point math | |
14612 value = parseFloat( value.toFixed( this._precision() ) ); | |
14613 | |
14614 // clamp the value | |
14615 if ( options.max !== null && value > options.max) { | |
14616 return options.max; | |
14617 } | |
14618 if ( options.min !== null && value < options.min ) { | |
14619 return options.min; | |
14620 } | |
14621 | |
14622 return value; | |
14623 }, | |
14624 | |
14625 _stop: function( event ) { | |
14626 if ( !this.spinning ) { | |
14627 return; | |
14628 } | |
14629 | |
14630 clearTimeout( this.timer ); | |
14631 clearTimeout( this.mousewheelTimer ); | |
14632 this.counter = 0; | |
14633 this.spinning = false; | |
14634 this._trigger( "stop", event ); | |
14635 }, | |
14636 | |
14637 _setOption: function( key, value ) { | |
14638 if ( key === "culture" || key === "numberFormat" ) { | |
14639 var prevValue = this._parse( this.element.val() ); | |
14640 this.options[ key ] = value; | |
14641 this.element.val( this._format( prevValue ) ); | |
14642 return; | |
14643 } | |
14644 | |
14645 if ( key === "max" || key === "min" || key === "step" ) { | |
14646 if ( typeof value === "string" ) { | |
14647 value = this._parse( value ); | |
14648 } | |
14649 } | |
14650 if ( key === "icons" ) { | |
14651 this.buttons.first().find( ".ui-icon" ) | |
14652 .removeClass( this.options.icons.up ) | |
14653 .addClass( value.up ); | |
14654 this.buttons.last().find( ".ui-icon" ) | |
14655 .removeClass( this.options.icons.down ) | |
14656 .addClass( value.down ); | |
14657 } | |
14658 | |
14659 this._super( key, value ); | |
14660 | |
14661 if ( key === "disabled" ) { | |
14662 if ( value ) { | |
14663 this.element.prop( "disabled", true ); | |
14664 this.buttons.button( "disable" ); | |
14665 } else { | |
14666 this.element.prop( "disabled", false ); | |
14667 this.buttons.button( "enable" ); | |
14668 } | |
14669 } | |
14670 }, | |
14671 | |
14672 _setOptions: modifier(function( options ) { | |
14673 this._super( options ); | |
14674 this._value( this.element.val() ); | |
14675 }), | |
14676 | |
14677 _parse: function( val ) { | |
14678 if ( typeof val === "string" && val !== "" ) { | |
14679 val = window.Globalize && this.options.numberFormat ? | |
14680 Globalize.parseFloat( val, 10, this.options.culture ) : +val; | |
14681 } | |
14682 return val === "" || isNaN( val ) ? null : val; | |
14683 }, | |
14684 | |
14685 _format: function( value ) { | |
14686 if ( value === "" ) { | |
14687 return ""; | |
14688 } | |
14689 return window.Globalize && this.options.numberFormat ? | |
14690 Globalize.format( value, this.options.numberFormat, this.options.culture ) : | |
14691 value; | |
14692 }, | |
14693 | |
14694 _refresh: function() { | |
14695 this.element.attr({ | |
14696 "aria-valuemin": this.options.min, | |
14697 "aria-valuemax": this.options.max, | |
14698 // TODO: what should we do with values that can't be parsed? | |
14699 "aria-valuenow": this._parse( this.element.val() ) | |
14700 }); | |
14701 }, | |
14702 | |
14703 // update the value without triggering change | |
14704 _value: function( value, allowAny ) { | |
14705 var parsed; | |
14706 if ( value !== "" ) { | |
14707 parsed = this._parse( value ); | |
14708 if ( parsed !== null ) { | |
14709 if ( !allowAny ) { | |
14710 parsed = this._adjustValue( parsed ); | |
14711 } | |
14712 value = this._format( parsed ); | |
14713 } | |
14714 } | |
14715 this.element.val( value ); | |
14716 this._refresh(); | |
14717 }, | |
14718 | |
14719 _destroy: function() { | |
14720 this.element | |
14721 .removeClass( "ui-spinner-input" ) | |
14722 .prop( "disabled", false ) | |
14723 .removeAttr( "autocomplete" ) | |
14724 .removeAttr( "role" ) | |
14725 .removeAttr( "aria-valuemin" ) | |
14726 .removeAttr( "aria-valuemax" ) | |
14727 .removeAttr( "aria-valuenow" ); | |
14728 this.uiSpinner.replaceWith( this.element ); | |
14729 }, | |
14730 | |
14731 stepUp: modifier(function( steps ) { | |
14732 this._stepUp( steps ); | |
14733 }), | |
14734 _stepUp: function( steps ) { | |
14735 if ( this._start() ) { | |
14736 this._spin( (steps || 1) * this.options.step ); | |
14737 this._stop(); | |
14738 } | |
14739 }, | |
14740 | |
14741 stepDown: modifier(function( steps ) { | |
14742 this._stepDown( steps ); | |
14743 }), | |
14744 _stepDown: function( steps ) { | |
14745 if ( this._start() ) { | |
14746 this._spin( (steps || 1) * -this.options.step ); | |
14747 this._stop(); | |
14748 } | |
14749 }, | |
14750 | |
14751 pageUp: modifier(function( pages ) { | |
14752 this._stepUp( (pages || 1) * this.options.page ); | |
14753 }), | |
14754 | |
14755 pageDown: modifier(function( pages ) { | |
14756 this._stepDown( (pages || 1) * this.options.page ); | |
14757 }), | |
14758 | |
14759 value: function( newVal ) { | |
14760 if ( !arguments.length ) { | |
14761 return this._parse( this.element.val() ); | |
14762 } | |
14763 modifier( this._value ).call( this, newVal ); | |
14764 }, | |
14765 | |
14766 widget: function() { | |
14767 return this.uiSpinner; | |
14768 } | |
14769 }); | |
14770 | |
14771 }( jQuery ) ); | |
14772 (function( $, undefined ) { | |
14773 | |
14774 var tabId = 0, | |
14775 rhash = /#.*$/; | |
14776 | |
14777 function getNextTabId() { | |
14778 return ++tabId; | |
14779 } | |
14780 | |
14781 function isLocal( anchor ) { | |
14782 return anchor.hash.length > 1 && | |
14783 decodeURIComponent( anchor.href.replace( rhash, "" ) ) === | |
14784 decodeURIComponent( location.href.replace( rhash, "" ) ); | |
14785 } | |
14786 | |
14787 $.widget( "ui.tabs", { | |
14788 version: "1.10.3", | |
14789 delay: 300, | |
14790 options: { | |
14791 active: null, | |
14792 collapsible: false, | |
14793 event: "click", | |
14794 heightStyle: "content", | |
14795 hide: null, | |
14796 show: null, | |
14797 | |
14798 // callbacks | |
14799 activate: null, | |
14800 beforeActivate: null, | |
14801 beforeLoad: null, | |
14802 load: null | |
14803 }, | |
14804 | |
14805 _create: function() { | |
14806 var that = this, | |
14807 options = this.options; | |
14808 | |
14809 this.running = false; | |
14810 | |
14811 this.element | |
14812 .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ) | |
14813 .toggleClass( "ui-tabs-collapsible", options.collapsible ) | |
14814 // Prevent users from focusing disabled tabs via click | |
14815 .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) { | |
14816 if ( $( this ).is( ".ui-state-disabled" ) ) { | |
14817 event.preventDefault(); | |
14818 } | |
14819 }) | |
14820 // support: IE <9 | |
14821 // Preventing the default action in mousedown doesn't prevent IE | |
14822 // from focusing the element, so if the anchor gets focused, blur. | |
14823 // We don't have to worry about focusing the previously focused | |
14824 // element since clicking on a non-focusable element should focus | |
14825 // the body anyway. | |
14826 .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() { | |
14827 if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) { | |
14828 this.blur(); | |
14829 } | |
14830 }); | |
14831 | |
14832 this._processTabs(); | |
14833 options.active = this._initialActive(); | |
14834 | |
14835 // Take disabling tabs via class attribute from HTML | |
14836 // into account and update option properly. | |
14837 if ( $.isArray( options.disabled ) ) { | |
14838 options.disabled = $.unique( options.disabled.concat( | |
14839 $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) { | |
14840 return that.tabs.index( li ); | |
14841 }) | |
14842 ) ).sort(); | |
14843 } | |
14844 | |
14845 // check for length avoids error when initializing empty list | |
14846 if ( this.options.active !== false && this.anchors.length ) { | |
14847 this.active = this._findActive( options.active ); | |
14848 } else { | |
14849 this.active = $(); | |
14850 } | |
14851 | |
14852 this._refresh(); | |
14853 | |
14854 if ( this.active.length ) { | |
14855 this.load( options.active ); | |
14856 } | |
14857 }, | |
14858 | |
14859 _initialActive: function() { | |
14860 var active = this.options.active, | |
14861 collapsible = this.options.collapsible, | |
14862 locationHash = location.hash.substring( 1 ); | |
14863 | |
14864 if ( active === null ) { | |
14865 // check the fragment identifier in the URL | |
14866 if ( locationHash ) { | |
14867 this.tabs.each(function( i, tab ) { | |
14868 if ( $( tab ).attr( "aria-controls" ) === locationHash ) { | |
14869 active = i; | |
14870 return false; | |
14871 } | |
14872 }); | |
14873 } | |
14874 | |
14875 // check for a tab marked active via a class | |
14876 if ( active === null ) { | |
14877 active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) ); | |
14878 } | |
14879 | |
14880 // no active tab, set to false | |
14881 if ( active === null || active === -1 ) { | |
14882 active = this.tabs.length ? 0 : false; | |
14883 } | |
14884 } | |
14885 | |
14886 // handle numbers: negative, out of range | |
14887 if ( active !== false ) { | |
14888 active = this.tabs.index( this.tabs.eq( active ) ); | |
14889 if ( active === -1 ) { | |
14890 active = collapsible ? false : 0; | |
14891 } | |
14892 } | |
14893 | |
14894 // don't allow collapsible: false and active: false | |
14895 if ( !collapsible && active === false && this.anchors.length ) { | |
14896 active = 0; | |
14897 } | |
14898 | |
14899 return active; | |
14900 }, | |
14901 | |
14902 _getCreateEventData: function() { | |
14903 return { | |
14904 tab: this.active, | |
14905 panel: !this.active.length ? $() : this._getPanelForTab( this.active ) | |
14906 }; | |
14907 }, | |
14908 | |
14909 _tabKeydown: function( event ) { | |
14910 /*jshint maxcomplexity:15*/ | |
14911 var focusedTab = $( this.document[0].activeElement ).closest( "li" ), | |
14912 selectedIndex = this.tabs.index( focusedTab ), | |
14913 goingForward = true; | |
14914 | |
14915 if ( this._handlePageNav( event ) ) { | |
14916 return; | |
14917 } | |
14918 | |
14919 switch ( event.keyCode ) { | |
14920 case $.ui.keyCode.RIGHT: | |
14921 case $.ui.keyCode.DOWN: | |
14922 selectedIndex++; | |
14923 break; | |
14924 case $.ui.keyCode.UP: | |
14925 case $.ui.keyCode.LEFT: | |
14926 goingForward = false; | |
14927 selectedIndex--; | |
14928 break; | |
14929 case $.ui.keyCode.END: | |
14930 selectedIndex = this.anchors.length - 1; | |
14931 break; | |
14932 case $.ui.keyCode.HOME: | |
14933 selectedIndex = 0; | |
14934 break; | |
14935 case $.ui.keyCode.SPACE: | |
14936 // Activate only, no collapsing | |
14937 event.preventDefault(); | |
14938 clearTimeout( this.activating ); | |
14939 this._activate( selectedIndex ); | |
14940 return; | |
14941 case $.ui.keyCode.ENTER: | |
14942 // Toggle (cancel delayed activation, allow collapsing) | |
14943 event.preventDefault(); | |
14944 clearTimeout( this.activating ); | |
14945 // Determine if we should collapse or activate | |
14946 this._activate( selectedIndex === this.options.active ? false : selectedIndex ); | |
14947 return; | |
14948 default: | |
14949 return; | |
14950 } | |
14951 | |
14952 // Focus the appropriate tab, based on which key was pressed | |
14953 event.preventDefault(); | |
14954 clearTimeout( this.activating ); | |
14955 selectedIndex = this._focusNextTab( selectedIndex, goingForward ); | |
14956 | |
14957 // Navigating with control key will prevent automatic activation | |
14958 if ( !event.ctrlKey ) { | |
14959 // Update aria-selected immediately so that AT think the tab is already selected. | |
14960 // Otherwise AT may confuse the user by stating that they need to activate the tab, | |
14961 // but the tab will already be activated by the time the announcement finishes. | |
14962 focusedTab.attr( "aria-selected", "false" ); | |
14963 this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" ); | |
14964 | |
14965 this.activating = this._delay(function() { | |
14966 this.option( "active", selectedIndex ); | |
14967 }, this.delay ); | |
14968 } | |
14969 }, | |
14970 | |
14971 _panelKeydown: function( event ) { | |
14972 if ( this._handlePageNav( event ) ) { | |
14973 return; | |
14974 } | |
14975 | |
14976 // Ctrl+up moves focus to the current tab | |
14977 if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) { | |
14978 event.preventDefault(); | |
14979 this.active.focus(); | |
14980 } | |
14981 }, | |
14982 | |
14983 // Alt+page up/down moves focus to the previous/next tab (and activates) | |
14984 _handlePageNav: function( event ) { | |
14985 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) { | |
14986 this._activate( this._focusNextTab( this.options.active - 1, false ) ); | |
14987 return true; | |
14988 } | |
14989 if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) { | |
14990 this._activate( this._focusNextTab( this.options.active + 1, true ) ); | |
14991 return true; | |
14992 } | |
14993 }, | |
14994 | |
14995 _findNextTab: function( index, goingForward ) { | |
14996 var lastTabIndex = this.tabs.length - 1; | |
14997 | |
14998 function constrain() { | |
14999 if ( index > lastTabIndex ) { | |
15000 index = 0; | |
15001 } | |
15002 if ( index < 0 ) { | |
15003 index = lastTabIndex; | |
15004 } | |
15005 return index; | |
15006 } | |
15007 | |
15008 while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) { | |
15009 index = goingForward ? index + 1 : index - 1; | |
15010 } | |
15011 | |
15012 return index; | |
15013 }, | |
15014 | |
15015 _focusNextTab: function( index, goingForward ) { | |
15016 index = this._findNextTab( index, goingForward ); | |
15017 this.tabs.eq( index ).focus(); | |
15018 return index; | |
15019 }, | |
15020 | |
15021 _setOption: function( key, value ) { | |
15022 if ( key === "active" ) { | |
15023 // _activate() will handle invalid values and update this.options | |
15024 this._activate( value ); | |
15025 return; | |
15026 } | |
15027 | |
15028 if ( key === "disabled" ) { | |
15029 // don't use the widget factory's disabled handling | |
15030 this._setupDisabled( value ); | |
15031 return; | |
15032 } | |
15033 | |
15034 this._super( key, value); | |
15035 | |
15036 if ( key === "collapsible" ) { | |
15037 this.element.toggleClass( "ui-tabs-collapsible", value ); | |
15038 // Setting collapsible: false while collapsed; open first panel | |
15039 if ( !value && this.options.active === false ) { | |
15040 this._activate( 0 ); | |
15041 } | |
15042 } | |
15043 | |
15044 if ( key === "event" ) { | |
15045 this._setupEvents( value ); | |
15046 } | |
15047 | |
15048 if ( key === "heightStyle" ) { | |
15049 this._setupHeightStyle( value ); | |
15050 } | |
15051 }, | |
15052 | |
15053 _tabId: function( tab ) { | |
15054 return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); | |
15055 }, | |
15056 | |
15057 _sanitizeSelector: function( hash ) { | |
15058 return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : ""; | |
15059 }, | |
15060 | |
15061 refresh: function() { | |
15062 var options = this.options, | |
15063 lis = this.tablist.children( ":has(a[href])" ); | |
15064 | |
15065 // get disabled tabs from class attribute from HTML | |
15066 // this will get converted to a boolean if needed in _refresh() | |
15067 options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { | |
15068 return lis.index( tab ); | |
15069 }); | |
15070 | |
15071 this._processTabs(); | |
15072 | |
15073 // was collapsed or no tabs | |
15074 if ( options.active === false || !this.anchors.length ) { | |
15075 options.active = false; | |
15076 this.active = $(); | |
15077 // was active, but active tab is gone | |
15078 } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) { | |
15079 // all remaining tabs are disabled | |
15080 if ( this.tabs.length === options.disabled.length ) { | |
15081 options.active = false; | |
15082 this.active = $(); | |
15083 // activate previous tab | |
15084 } else { | |
15085 this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) ); | |
15086 } | |
15087 // was active, active tab still exists | |
15088 } else { | |
15089 // make sure active index is correct | |
15090 options.active = this.tabs.index( this.active ); | |
15091 } | |
15092 | |
15093 this._refresh(); | |
15094 }, | |
15095 | |
15096 _refresh: function() { | |
15097 this._setupDisabled( this.options.disabled ); | |
15098 this._setupEvents( this.options.event ); | |
15099 this._setupHeightStyle( this.options.heightStyle ); | |
15100 | |
15101 this.tabs.not( this.active ).attr({ | |
15102 "aria-selected": "false", | |
15103 tabIndex: -1 | |
15104 }); | |
15105 this.panels.not( this._getPanelForTab( this.active ) ) | |
15106 .hide() | |
15107 .attr({ | |
15108 "aria-expanded": "false", | |
15109 "aria-hidden": "true" | |
15110 }); | |
15111 | |
15112 // Make sure one tab is in the tab order | |
15113 if ( !this.active.length ) { | |
15114 this.tabs.eq( 0 ).attr( "tabIndex", 0 ); | |
15115 } else { | |
15116 this.active | |
15117 .addClass( "ui-tabs-active ui-state-active" ) | |
15118 .attr({ | |
15119 "aria-selected": "true", | |
15120 tabIndex: 0 | |
15121 }); | |
15122 this._getPanelForTab( this.active ) | |
15123 .show() | |
15124 .attr({ | |
15125 "aria-expanded": "true", | |
15126 "aria-hidden": "false" | |
15127 }); | |
15128 } | |
15129 }, | |
15130 | |
15131 _processTabs: function() { | |
15132 var that = this; | |
15133 | |
15134 this.tablist = this._getList() | |
15135 .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) | |
15136 .attr( "role", "tablist" ); | |
15137 | |
15138 this.tabs = this.tablist.find( "> li:has(a[href])" ) | |
15139 .addClass( "ui-state-default ui-corner-top" ) | |
15140 .attr({ | |
15141 role: "tab", | |
15142 tabIndex: -1 | |
15143 }); | |
15144 | |
15145 this.anchors = this.tabs.map(function() { | |
15146 return $( "a", this )[ 0 ]; | |
15147 }) | |
15148 .addClass( "ui-tabs-anchor" ) | |
15149 .attr({ | |
15150 role: "presentation", | |
15151 tabIndex: -1 | |
15152 }); | |
15153 | |
15154 this.panels = $(); | |
15155 | |
15156 this.anchors.each(function( i, anchor ) { | |
15157 var selector, panel, panelId, | |
15158 anchorId = $( anchor ).uniqueId().attr( "id" ), | |
15159 tab = $( anchor ).closest( "li" ), | |
15160 originalAriaControls = tab.attr( "aria-controls" ); | |
15161 | |
15162 // inline tab | |
15163 if ( isLocal( anchor ) ) { | |
15164 selector = anchor.hash; | |
15165 panel = that.element.find( that._sanitizeSelector( selector ) ); | |
15166 // remote tab | |
15167 } else { | |
15168 panelId = that._tabId( tab ); | |
15169 selector = "#" + panelId; | |
15170 panel = that.element.find( selector ); | |
15171 if ( !panel.length ) { | |
15172 panel = that._createPanel( panelId ); | |
15173 panel.insertAfter( that.panels[ i - 1 ] || that.tablist ); | |
15174 } | |
15175 panel.attr( "aria-live", "polite" ); | |
15176 } | |
15177 | |
15178 if ( panel.length) { | |
15179 that.panels = that.panels.add( panel ); | |
15180 } | |
15181 if ( originalAriaControls ) { | |
15182 tab.data( "ui-tabs-aria-controls", originalAriaControls ); | |
15183 } | |
15184 tab.attr({ | |
15185 "aria-controls": selector.substring( 1 ), | |
15186 "aria-labelledby": anchorId | |
15187 }); | |
15188 panel.attr( "aria-labelledby", anchorId ); | |
15189 }); | |
15190 | |
15191 this.panels | |
15192 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) | |
15193 .attr( "role", "tabpanel" ); | |
15194 }, | |
15195 | |
15196 // allow overriding how to find the list for rare usage scenarios (#7715) | |
15197 _getList: function() { | |
15198 return this.element.find( "ol,ul" ).eq( 0 ); | |
15199 }, | |
15200 | |
15201 _createPanel: function( id ) { | |
15202 return $( "<div>" ) | |
15203 .attr( "id", id ) | |
15204 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) | |
15205 .data( "ui-tabs-destroy", true ); | |
15206 }, | |
15207 | |
15208 _setupDisabled: function( disabled ) { | |
15209 if ( $.isArray( disabled ) ) { | |
15210 if ( !disabled.length ) { | |
15211 disabled = false; | |
15212 } else if ( disabled.length === this.anchors.length ) { | |
15213 disabled = true; | |
15214 } | |
15215 } | |
15216 | |
15217 // disable tabs | |
15218 for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) { | |
15219 if ( disabled === true || $.inArray( i, disabled ) !== -1 ) { | |
15220 $( li ) | |
15221 .addClass( "ui-state-disabled" ) | |
15222 .attr( "aria-disabled", "true" ); | |
15223 } else { | |
15224 $( li ) | |
15225 .removeClass( "ui-state-disabled" ) | |
15226 .removeAttr( "aria-disabled" ); | |
15227 } | |
15228 } | |
15229 | |
15230 this.options.disabled = disabled; | |
15231 }, | |
15232 | |
15233 _setupEvents: function( event ) { | |
15234 var events = { | |
15235 click: function( event ) { | |
15236 event.preventDefault(); | |
15237 } | |
15238 }; | |
15239 if ( event ) { | |
15240 $.each( event.split(" "), function( index, eventName ) { | |
15241 events[ eventName ] = "_eventHandler"; | |
15242 }); | |
15243 } | |
15244 | |
15245 this._off( this.anchors.add( this.tabs ).add( this.panels ) ); | |
15246 this._on( this.anchors, events ); | |
15247 this._on( this.tabs, { keydown: "_tabKeydown" } ); | |
15248 this._on( this.panels, { keydown: "_panelKeydown" } ); | |
15249 | |
15250 this._focusable( this.tabs ); | |
15251 this._hoverable( this.tabs ); | |
15252 }, | |
15253 | |
15254 _setupHeightStyle: function( heightStyle ) { | |
15255 var maxHeight, | |
15256 parent = this.element.parent(); | |
15257 | |
15258 if ( heightStyle === "fill" ) { | |
15259 maxHeight = parent.height(); | |
15260 maxHeight -= this.element.outerHeight() - this.element.height(); | |
15261 | |
15262 this.element.siblings( ":visible" ).each(function() { | |
15263 var elem = $( this ), | |
15264 position = elem.css( "position" ); | |
15265 | |
15266 if ( position === "absolute" || position === "fixed" ) { | |
15267 return; | |
15268 } | |
15269 maxHeight -= elem.outerHeight( true ); | |
15270 }); | |
15271 | |
15272 this.element.children().not( this.panels ).each(function() { | |
15273 maxHeight -= $( this ).outerHeight( true ); | |
15274 }); | |
15275 | |
15276 this.panels.each(function() { | |
15277 $( this ).height( Math.max( 0, maxHeight - | |
15278 $( this ).innerHeight() + $( this ).height() ) ); | |
15279 }) | |
15280 .css( "overflow", "auto" ); | |
15281 } else if ( heightStyle === "auto" ) { | |
15282 maxHeight = 0; | |
15283 this.panels.each(function() { | |
15284 maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); | |
15285 }).height( maxHeight ); | |
15286 } | |
15287 }, | |
15288 | |
15289 _eventHandler: function( event ) { | |
15290 var options = this.options, | |
15291 active = this.active, | |
15292 anchor = $( event.currentTarget ), | |
15293 tab = anchor.closest( "li" ), | |
15294 clickedIsActive = tab[ 0 ] === active[ 0 ], | |
15295 collapsing = clickedIsActive && options.collapsible, | |
15296 toShow = collapsing ? $() : this._getPanelForTab( tab ), | |
15297 toHide = !active.length ? $() : this._getPanelForTab( active ), | |
15298 eventData = { | |
15299 oldTab: active, | |
15300 oldPanel: toHide, | |
15301 newTab: collapsing ? $() : tab, | |
15302 newPanel: toShow | |
15303 }; | |
15304 | |
15305 event.preventDefault(); | |
15306 | |
15307 if ( tab.hasClass( "ui-state-disabled" ) || | |
15308 // tab is already loading | |
15309 tab.hasClass( "ui-tabs-loading" ) || | |
15310 // can't switch durning an animation | |
15311 this.running || | |
15312 // click on active header, but not collapsible | |
15313 ( clickedIsActive && !options.collapsible ) || | |
15314 // allow canceling activation | |
15315 ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { | |
15316 return; | |
15317 } | |
15318 | |
15319 options.active = collapsing ? false : this.tabs.index( tab ); | |
15320 | |
15321 this.active = clickedIsActive ? $() : tab; | |
15322 if ( this.xhr ) { | |
15323 this.xhr.abort(); | |
15324 } | |
15325 | |
15326 if ( !toHide.length && !toShow.length ) { | |
15327 $.error( "jQuery UI Tabs: Mismatching fragment identifier." ); | |
15328 } | |
15329 | |
15330 if ( toShow.length ) { | |
15331 this.load( this.tabs.index( tab ), event ); | |
15332 } | |
15333 this._toggle( event, eventData ); | |
15334 }, | |
15335 | |
15336 // handles show/hide for selecting tabs | |
15337 _toggle: function( event, eventData ) { | |
15338 var that = this, | |
15339 toShow = eventData.newPanel, | |
15340 toHide = eventData.oldPanel; | |
15341 | |
15342 this.running = true; | |
15343 | |
15344 function complete() { | |
15345 that.running = false; | |
15346 that._trigger( "activate", event, eventData ); | |
15347 } | |
15348 | |
15349 function show() { | |
15350 eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" ); | |
15351 | |
15352 if ( toShow.length && that.options.show ) { | |
15353 that._show( toShow, that.options.show, complete ); | |
15354 } else { | |
15355 toShow.show(); | |
15356 complete(); | |
15357 } | |
15358 } | |
15359 | |
15360 // start out by hiding, then showing, then completing | |
15361 if ( toHide.length && this.options.hide ) { | |
15362 this._hide( toHide, this.options.hide, function() { | |
15363 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); | |
15364 show(); | |
15365 }); | |
15366 } else { | |
15367 eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" ); | |
15368 toHide.hide(); | |
15369 show(); | |
15370 } | |
15371 | |
15372 toHide.attr({ | |
15373 "aria-expanded": "false", | |
15374 "aria-hidden": "true" | |
15375 }); | |
15376 eventData.oldTab.attr( "aria-selected", "false" ); | |
15377 // If we're switching tabs, remove the old tab from the tab order. | |
15378 // If we're opening from collapsed state, remove the previous tab from the tab order. | |
15379 // If we're collapsing, then keep the collapsing tab in the tab order. | |
15380 if ( toShow.length && toHide.length ) { | |
15381 eventData.oldTab.attr( "tabIndex", -1 ); | |
15382 } else if ( toShow.length ) { | |
15383 this.tabs.filter(function() { | |
15384 return $( this ).attr( "tabIndex" ) === 0; | |
15385 }) | |
15386 .attr( "tabIndex", -1 ); | |
15387 } | |
15388 | |
15389 toShow.attr({ | |
15390 "aria-expanded": "true", | |
15391 "aria-hidden": "false" | |
15392 }); | |
15393 eventData.newTab.attr({ | |
15394 "aria-selected": "true", | |
15395 tabIndex: 0 | |
15396 }); | |
15397 }, | |
15398 | |
15399 _activate: function( index ) { | |
15400 var anchor, | |
15401 active = this._findActive( index ); | |
15402 | |
15403 // trying to activate the already active panel | |
15404 if ( active[ 0 ] === this.active[ 0 ] ) { | |
15405 return; | |
15406 } | |
15407 | |
15408 // trying to collapse, simulate a click on the current active header | |
15409 if ( !active.length ) { | |
15410 active = this.active; | |
15411 } | |
15412 | |
15413 anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; | |
15414 this._eventHandler({ | |
15415 target: anchor, | |
15416 currentTarget: anchor, | |
15417 preventDefault: $.noop | |
15418 }); | |
15419 }, | |
15420 | |
15421 _findActive: function( index ) { | |
15422 return index === false ? $() : this.tabs.eq( index ); | |
15423 }, | |
15424 | |
15425 _getIndex: function( index ) { | |
15426 // meta-function to give users option to provide a href string instead of a numerical index. | |
15427 if ( typeof index === "string" ) { | |
15428 index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); | |
15429 } | |
15430 | |
15431 return index; | |
15432 }, | |
15433 | |
15434 _destroy: function() { | |
15435 if ( this.xhr ) { | |
15436 this.xhr.abort(); | |
15437 } | |
15438 | |
15439 this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ); | |
15440 | |
15441 this.tablist | |
15442 .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) | |
15443 .removeAttr( "role" ); | |
15444 | |
15445 this.anchors | |
15446 .removeClass( "ui-tabs-anchor" ) | |
15447 .removeAttr( "role" ) | |
15448 .removeAttr( "tabIndex" ) | |
15449 .removeUniqueId(); | |
15450 | |
15451 this.tabs.add( this.panels ).each(function() { | |
15452 if ( $.data( this, "ui-tabs-destroy" ) ) { | |
15453 $( this ).remove(); | |
15454 } else { | |
15455 $( this ) | |
15456 .removeClass( "ui-state-default ui-state-active ui-state-disabled " + | |
15457 "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" ) | |
15458 .removeAttr( "tabIndex" ) | |
15459 .removeAttr( "aria-live" ) | |
15460 .removeAttr( "aria-busy" ) | |
15461 .removeAttr( "aria-selected" ) | |
15462 .removeAttr( "aria-labelledby" ) | |
15463 .removeAttr( "aria-hidden" ) | |
15464 .removeAttr( "aria-expanded" ) | |
15465 .removeAttr( "role" ); | |
15466 } | |
15467 }); | |
15468 | |
15469 this.tabs.each(function() { | |
15470 var li = $( this ), | |
15471 prev = li.data( "ui-tabs-aria-controls" ); | |
15472 if ( prev ) { | |
15473 li | |
15474 .attr( "aria-controls", prev ) | |
15475 .removeData( "ui-tabs-aria-controls" ); | |
15476 } else { | |
15477 li.removeAttr( "aria-controls" ); | |
15478 } | |
15479 }); | |
15480 | |
15481 this.panels.show(); | |
15482 | |
15483 if ( this.options.heightStyle !== "content" ) { | |
15484 this.panels.css( "height", "" ); | |
15485 } | |
15486 }, | |
15487 | |
15488 enable: function( index ) { | |
15489 var disabled = this.options.disabled; | |
15490 if ( disabled === false ) { | |
15491 return; | |
15492 } | |
15493 | |
15494 if ( index === undefined ) { | |
15495 disabled = false; | |
15496 } else { | |
15497 index = this._getIndex( index ); | |
15498 if ( $.isArray( disabled ) ) { | |
15499 disabled = $.map( disabled, function( num ) { | |
15500 return num !== index ? num : null; | |
15501 }); | |
15502 } else { | |
15503 disabled = $.map( this.tabs, function( li, num ) { | |
15504 return num !== index ? num : null; | |
15505 }); | |
15506 } | |
15507 } | |
15508 this._setupDisabled( disabled ); | |
15509 }, | |
15510 | |
15511 disable: function( index ) { | |
15512 var disabled = this.options.disabled; | |
15513 if ( disabled === true ) { | |
15514 return; | |
15515 } | |
15516 | |
15517 if ( index === undefined ) { | |
15518 disabled = true; | |
15519 } else { | |
15520 index = this._getIndex( index ); | |
15521 if ( $.inArray( index, disabled ) !== -1 ) { | |
15522 return; | |
15523 } | |
15524 if ( $.isArray( disabled ) ) { | |
15525 disabled = $.merge( [ index ], disabled ).sort(); | |
15526 } else { | |
15527 disabled = [ index ]; | |
15528 } | |
15529 } | |
15530 this._setupDisabled( disabled ); | |
15531 }, | |
15532 | |
15533 load: function( index, event ) { | |
15534 index = this._getIndex( index ); | |
15535 var that = this, | |
15536 tab = this.tabs.eq( index ), | |
15537 anchor = tab.find( ".ui-tabs-anchor" ), | |
15538 panel = this._getPanelForTab( tab ), | |
15539 eventData = { | |
15540 tab: tab, | |
15541 panel: panel | |
15542 }; | |
15543 | |
15544 // not remote | |
15545 if ( isLocal( anchor[ 0 ] ) ) { | |
15546 return; | |
15547 } | |
15548 | |
15549 this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) ); | |
15550 | |
15551 // support: jQuery <1.8 | |
15552 // jQuery <1.8 returns false if the request is canceled in beforeSend, | |
15553 // but as of 1.8, $.ajax() always returns a jqXHR object. | |
15554 if ( this.xhr && this.xhr.statusText !== "canceled" ) { | |
15555 tab.addClass( "ui-tabs-loading" ); | |
15556 panel.attr( "aria-busy", "true" ); | |
15557 | |
15558 this.xhr | |
15559 .success(function( response ) { | |
15560 // support: jQuery <1.8 | |
15561 // http://bugs.jquery.com/ticket/11778 | |
15562 setTimeout(function() { | |
15563 panel.html( response ); | |
15564 that._trigger( "load", event, eventData ); | |
15565 }, 1 ); | |
15566 }) | |
15567 .complete(function( jqXHR, status ) { | |
15568 // support: jQuery <1.8 | |
15569 // http://bugs.jquery.com/ticket/11778 | |
15570 setTimeout(function() { | |
15571 if ( status === "abort" ) { | |
15572 that.panels.stop( false, true ); | |
15573 } | |
15574 | |
15575 tab.removeClass( "ui-tabs-loading" ); | |
15576 panel.removeAttr( "aria-busy" ); | |
15577 | |
15578 if ( jqXHR === that.xhr ) { | |
15579 delete that.xhr; | |
15580 } | |
15581 }, 1 ); | |
15582 }); | |
15583 } | |
15584 }, | |
15585 | |
15586 _ajaxSettings: function( anchor, event, eventData ) { | |
15587 var that = this; | |
15588 return { | |
15589 url: anchor.attr( "href" ), | |
15590 beforeSend: function( jqXHR, settings ) { | |
15591 return that._trigger( "beforeLoad", event, | |
15592 $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) ); | |
15593 } | |
15594 }; | |
15595 }, | |
15596 | |
15597 _getPanelForTab: function( tab ) { | |
15598 var id = $( tab ).attr( "aria-controls" ); | |
15599 return this.element.find( this._sanitizeSelector( "#" + id ) ); | |
15600 } | |
15601 }); | |
15602 | |
15603 })( jQuery ); | |
15604 (function( $ ) { | |
15605 | |
15606 var increments = 0; | |
15607 | |
15608 function addDescribedBy( elem, id ) { | |
15609 var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); | |
15610 describedby.push( id ); | |
15611 elem | |
15612 .data( "ui-tooltip-id", id ) | |
15613 .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); | |
15614 } | |
15615 | |
15616 function removeDescribedBy( elem ) { | |
15617 var id = elem.data( "ui-tooltip-id" ), | |
15618 describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), | |
15619 index = $.inArray( id, describedby ); | |
15620 if ( index !== -1 ) { | |
15621 describedby.splice( index, 1 ); | |
15622 } | |
15623 | |
15624 elem.removeData( "ui-tooltip-id" ); | |
15625 describedby = $.trim( describedby.join( " " ) ); | |
15626 if ( describedby ) { | |
15627 elem.attr( "aria-describedby", describedby ); | |
15628 } else { | |
15629 elem.removeAttr( "aria-describedby" ); | |
15630 } | |
15631 } | |
15632 | |
15633 $.widget( "ui.tooltip", { | |
15634 version: "1.10.3", | |
15635 options: { | |
15636 content: function() { | |
15637 // support: IE<9, Opera in jQuery <1.7 | |
15638 // .text() can't accept undefined, so coerce to a string | |
15639 var title = $( this ).attr( "title" ) || ""; | |
15640 // Escape title, since we're going from an attribute to raw HTML | |
15641 return $( "<a>" ).text( title ).html(); | |
15642 }, | |
15643 hide: true, | |
15644 // Disabled elements have inconsistent behavior across browsers (#8661) | |
15645 items: "[title]:not([disabled])", | |
15646 position: { | |
15647 my: "left top+15", | |
15648 at: "left bottom", | |
15649 collision: "flipfit flip" | |
15650 }, | |
15651 show: true, | |
15652 tooltipClass: null, | |
15653 track: false, | |
15654 | |
15655 // callbacks | |
15656 close: null, | |
15657 open: null | |
15658 }, | |
15659 | |
15660 _create: function() { | |
15661 this._on({ | |
15662 mouseover: "open", | |
15663 focusin: "open" | |
15664 }); | |
15665 | |
15666 // IDs of generated tooltips, needed for destroy | |
15667 this.tooltips = {}; | |
15668 // IDs of parent tooltips where we removed the title attribute | |
15669 this.parents = {}; | |
15670 | |
15671 if ( this.options.disabled ) { | |
15672 this._disable(); | |
15673 } | |
15674 }, | |
15675 | |
15676 _setOption: function( key, value ) { | |
15677 var that = this; | |
15678 | |
15679 if ( key === "disabled" ) { | |
15680 this[ value ? "_disable" : "_enable" ](); | |
15681 this.options[ key ] = value; | |
15682 // disable element style changes | |
15683 return; | |
15684 } | |
15685 | |
15686 this._super( key, value ); | |
15687 | |
15688 if ( key === "content" ) { | |
15689 $.each( this.tooltips, function( id, element ) { | |
15690 that._updateContent( element ); | |
15691 }); | |
15692 } | |
15693 }, | |
15694 | |
15695 _disable: function() { | |
15696 var that = this; | |
15697 | |
15698 // close open tooltips | |
15699 $.each( this.tooltips, function( id, element ) { | |
15700 var event = $.Event( "blur" ); | |
15701 event.target = event.currentTarget = element[0]; | |
15702 that.close( event, true ); | |
15703 }); | |
15704 | |
15705 // remove title attributes to prevent native tooltips | |
15706 this.element.find( this.options.items ).addBack().each(function() { | |
15707 var element = $( this ); | |
15708 if ( element.is( "[title]" ) ) { | |
15709 element | |
15710 .data( "ui-tooltip-title", element.attr( "title" ) ) | |
15711 .attr( "title", "" ); | |
15712 } | |
15713 }); | |
15714 }, | |
15715 | |
15716 _enable: function() { | |
15717 // restore title attributes | |
15718 this.element.find( this.options.items ).addBack().each(function() { | |
15719 var element = $( this ); | |
15720 if ( element.data( "ui-tooltip-title" ) ) { | |
15721 element.attr( "title", element.data( "ui-tooltip-title" ) ); | |
15722 } | |
15723 }); | |
15724 }, | |
15725 | |
15726 open: function( event ) { | |
15727 var that = this, | |
15728 target = $( event ? event.target : this.element ) | |
15729 // we need closest here due to mouseover bubbling, | |
15730 // but always pointing at the same event target | |
15731 .closest( this.options.items ); | |
15732 | |
15733 // No element to show a tooltip for or the tooltip is already open | |
15734 if ( !target.length || target.data( "ui-tooltip-id" ) ) { | |
15735 return; | |
15736 } | |
15737 | |
15738 if ( target.attr( "title" ) ) { | |
15739 target.data( "ui-tooltip-title", target.attr( "title" ) ); | |
15740 } | |
15741 | |
15742 target.data( "ui-tooltip-open", true ); | |
15743 | |
15744 // kill parent tooltips, custom or native, for hover | |
15745 if ( event && event.type === "mouseover" ) { | |
15746 target.parents().each(function() { | |
15747 var parent = $( this ), | |
15748 blurEvent; | |
15749 if ( parent.data( "ui-tooltip-open" ) ) { | |
15750 blurEvent = $.Event( "blur" ); | |
15751 blurEvent.target = blurEvent.currentTarget = this; | |
15752 that.close( blurEvent, true ); | |
15753 } | |
15754 if ( parent.attr( "title" ) ) { | |
15755 parent.uniqueId(); | |
15756 that.parents[ this.id ] = { | |
15757 element: this, | |
15758 title: parent.attr( "title" ) | |
15759 }; | |
15760 parent.attr( "title", "" ); | |
15761 } | |
15762 }); | |
15763 } | |
15764 | |
15765 this._updateContent( target, event ); | |
15766 }, | |
15767 | |
15768 _updateContent: function( target, event ) { | |
15769 var content, | |
15770 contentOption = this.options.content, | |
15771 that = this, | |
15772 eventType = event ? event.type : null; | |
15773 | |
15774 if ( typeof contentOption === "string" ) { | |
15775 return this._open( event, target, contentOption ); | |
15776 } | |
15777 | |
15778 content = contentOption.call( target[0], function( response ) { | |
15779 // ignore async response if tooltip was closed already | |
15780 if ( !target.data( "ui-tooltip-open" ) ) { | |
15781 return; | |
15782 } | |
15783 // IE may instantly serve a cached response for ajax requests | |
15784 // delay this call to _open so the other call to _open runs first | |
15785 that._delay(function() { | |
15786 // jQuery creates a special event for focusin when it doesn't | |
15787 // exist natively. To improve performance, the native event | |
15788 // object is reused and the type is changed. Therefore, we can't | |
15789 // rely on the type being correct after the event finished | |
15790 // bubbling, so we set it back to the previous value. (#8740) | |
15791 if ( event ) { | |
15792 event.type = eventType; | |
15793 } | |
15794 this._open( event, target, response ); | |
15795 }); | |
15796 }); | |
15797 if ( content ) { | |
15798 this._open( event, target, content ); | |
15799 } | |
15800 }, | |
15801 | |
15802 _open: function( event, target, content ) { | |
15803 var tooltip, events, delayedShow, | |
15804 positionOption = $.extend( {}, this.options.position ); | |
15805 | |
15806 if ( !content ) { | |
15807 return; | |
15808 } | |
15809 | |
15810 // Content can be updated multiple times. If the tooltip already | |
15811 // exists, then just update the content and bail. | |
15812 tooltip = this._find( target ); | |
15813 if ( tooltip.length ) { | |
15814 tooltip.find( ".ui-tooltip-content" ).html( content ); | |
15815 return; | |
15816 } | |
15817 | |
15818 // if we have a title, clear it to prevent the native tooltip | |
15819 // we have to check first to avoid defining a title if none exists | |
15820 // (we don't want to cause an element to start matching [title]) | |
15821 // | |
15822 // We use removeAttr only for key events, to allow IE to export the correct | |
15823 // accessible attributes. For mouse events, set to empty string to avoid | |
15824 // native tooltip showing up (happens only when removing inside mouseover). | |
15825 if ( target.is( "[title]" ) ) { | |
15826 if ( event && event.type === "mouseover" ) { | |
15827 target.attr( "title", "" ); | |
15828 } else { | |
15829 target.removeAttr( "title" ); | |
15830 } | |
15831 } | |
15832 | |
15833 tooltip = this._tooltip( target ); | |
15834 addDescribedBy( target, tooltip.attr( "id" ) ); | |
15835 tooltip.find( ".ui-tooltip-content" ).html( content ); | |
15836 | |
15837 function position( event ) { | |
15838 positionOption.of = event; | |
15839 if ( tooltip.is( ":hidden" ) ) { | |
15840 return; | |
15841 } | |
15842 tooltip.position( positionOption ); | |
15843 } | |
15844 if ( this.options.track && event && /^mouse/.test( event.type ) ) { | |
15845 this._on( this.document, { | |
15846 mousemove: position | |
15847 }); | |
15848 // trigger once to override element-relative positioning | |
15849 position( event ); | |
15850 } else { | |
15851 tooltip.position( $.extend({ | |
15852 of: target | |
15853 }, this.options.position ) ); | |
15854 } | |
15855 | |
15856 tooltip.hide(); | |
15857 | |
15858 this._show( tooltip, this.options.show ); | |
15859 // Handle tracking tooltips that are shown with a delay (#8644). As soon | |
15860 // as the tooltip is visible, position the tooltip using the most recent | |
15861 // event. | |
15862 if ( this.options.show && this.options.show.delay ) { | |
15863 delayedShow = this.delayedShow = setInterval(function() { | |
15864 if ( tooltip.is( ":visible" ) ) { | |
15865 position( positionOption.of ); | |
15866 clearInterval( delayedShow ); | |
15867 } | |
15868 }, $.fx.interval ); | |
15869 } | |
15870 | |
15871 this._trigger( "open", event, { tooltip: tooltip } ); | |
15872 | |
15873 events = { | |
15874 keyup: function( event ) { | |
15875 if ( event.keyCode === $.ui.keyCode.ESCAPE ) { | |
15876 var fakeEvent = $.Event(event); | |
15877 fakeEvent.currentTarget = target[0]; | |
15878 this.close( fakeEvent, true ); | |
15879 } | |
15880 }, | |
15881 remove: function() { | |
15882 this._removeTooltip( tooltip ); | |
15883 } | |
15884 }; | |
15885 if ( !event || event.type === "mouseover" ) { | |
15886 events.mouseleave = "close"; | |
15887 } | |
15888 if ( !event || event.type === "focusin" ) { | |
15889 events.focusout = "close"; | |
15890 } | |
15891 this._on( true, target, events ); | |
15892 }, | |
15893 | |
15894 close: function( event ) { | |
15895 var that = this, | |
15896 target = $( event ? event.currentTarget : this.element ), | |
15897 tooltip = this._find( target ); | |
15898 | |
15899 // disabling closes the tooltip, so we need to track when we're closing | |
15900 // to avoid an infinite loop in case the tooltip becomes disabled on close | |
15901 if ( this.closing ) { | |
15902 return; | |
15903 } | |
15904 | |
15905 // Clear the interval for delayed tracking tooltips | |
15906 clearInterval( this.delayedShow ); | |
15907 | |
15908 // only set title if we had one before (see comment in _open()) | |
15909 if ( target.data( "ui-tooltip-title" ) ) { | |
15910 target.attr( "title", target.data( "ui-tooltip-title" ) ); | |
15911 } | |
15912 | |
15913 removeDescribedBy( target ); | |
15914 | |
15915 tooltip.stop( true ); | |
15916 this._hide( tooltip, this.options.hide, function() { | |
15917 that._removeTooltip( $( this ) ); | |
15918 }); | |
15919 | |
15920 target.removeData( "ui-tooltip-open" ); | |
15921 this._off( target, "mouseleave focusout keyup" ); | |
15922 // Remove 'remove' binding only on delegated targets | |
15923 if ( target[0] !== this.element[0] ) { | |
15924 this._off( target, "remove" ); | |
15925 } | |
15926 this._off( this.document, "mousemove" ); | |
15927 | |
15928 if ( event && event.type === "mouseleave" ) { | |
15929 $.each( this.parents, function( id, parent ) { | |
15930 $( parent.element ).attr( "title", parent.title ); | |
15931 delete that.parents[ id ]; | |
15932 }); | |
15933 } | |
15934 | |
15935 this.closing = true; | |
15936 this._trigger( "close", event, { tooltip: tooltip } ); | |
15937 this.closing = false; | |
15938 }, | |
15939 | |
15940 _tooltip: function( element ) { | |
15941 var id = "ui-tooltip-" + increments++, | |
15942 tooltip = $( "<div>" ) | |
15943 .attr({ | |
15944 id: id, | |
15945 role: "tooltip" | |
15946 }) | |
15947 .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " + | |
15948 ( this.options.tooltipClass || "" ) ); | |
15949 $( "<div>" ) | |
15950 .addClass( "ui-tooltip-content" ) | |
15951 .appendTo( tooltip ); | |
15952 tooltip.appendTo( this.document[0].body ); | |
15953 this.tooltips[ id ] = element; | |
15954 return tooltip; | |
15955 }, | |
15956 | |
15957 _find: function( target ) { | |
15958 var id = target.data( "ui-tooltip-id" ); | |
15959 return id ? $( "#" + id ) : $(); | |
15960 }, | |
15961 | |
15962 _removeTooltip: function( tooltip ) { | |
15963 tooltip.remove(); | |
15964 delete this.tooltips[ tooltip.attr( "id" ) ]; | |
15965 }, | |
15966 | |
15967 _destroy: function() { | |
15968 var that = this; | |
15969 | |
15970 // close open tooltips | |
15971 $.each( this.tooltips, function( id, element ) { | |
15972 // Delegate to close method to handle common cleanup | |
15973 var event = $.Event( "blur" ); | |
15974 event.target = event.currentTarget = element[0]; | |
15975 that.close( event, true ); | |
15976 | |
15977 // Remove immediately; destroying an open tooltip doesn't use the | |
15978 // hide animation | |
15979 $( "#" + id ).remove(); | |
15980 | |
15981 // Restore the title | |
15982 if ( element.data( "ui-tooltip-title" ) ) { | |
15983 element.attr( "title", element.data( "ui-tooltip-title" ) ); | |
15984 element.removeData( "ui-tooltip-title" ); | |
15985 } | |
15986 }); | |
15987 } | |
15988 }); | |
15989 | |
15990 }( jQuery ) ); | |
15991 (function($, undefined) { | |
15992 | |
15993 var dataSpace = "ui-effects-"; | |
15994 | |
15995 $.effects = { | |
15996 effect: {} | |
15997 }; | |
15998 | |
15999 /*! | |
16000 * jQuery Color Animations v2.1.2 | |
16001 * https://github.com/jquery/jquery-color | |
16002 * | |
16003 * Copyright 2013 jQuery Foundation and other contributors | |
16004 * Released under the MIT license. | |
16005 * http://jquery.org/license | |
16006 * | |
16007 * Date: Wed Jan 16 08:47:09 2013 -0600 | |
16008 */ | |
16009 (function( jQuery, undefined ) { | |
16010 | |
16011 var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", | |
16012 | |
16013 // plusequals test for += 100 -= 100 | |
16014 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, | |
16015 // a set of RE's that can match strings and generate color tuples. | |
16016 stringParsers = [{ | |
16017 re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, | |
16018 parse: function( execResult ) { | |
16019 return [ | |
16020 execResult[ 1 ], | |
16021 execResult[ 2 ], | |
16022 execResult[ 3 ], | |
16023 execResult[ 4 ] | |
16024 ]; | |
16025 } | |
16026 }, { | |
16027 re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, | |
16028 parse: function( execResult ) { | |
16029 return [ | |
16030 execResult[ 1 ] * 2.55, | |
16031 execResult[ 2 ] * 2.55, | |
16032 execResult[ 3 ] * 2.55, | |
16033 execResult[ 4 ] | |
16034 ]; | |
16035 } | |
16036 }, { | |
16037 // this regex ignores A-F because it's compared against an already lowercased string | |
16038 re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, | |
16039 parse: function( execResult ) { | |
16040 return [ | |
16041 parseInt( execResult[ 1 ], 16 ), | |
16042 parseInt( execResult[ 2 ], 16 ), | |
16043 parseInt( execResult[ 3 ], 16 ) | |
16044 ]; | |
16045 } | |
16046 }, { | |
16047 // this regex ignores A-F because it's compared against an already lowercased string | |
16048 re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, | |
16049 parse: function( execResult ) { | |
16050 return [ | |
16051 parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), | |
16052 parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), | |
16053 parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ) | |
16054 ]; | |
16055 } | |
16056 }, { | |
16057 re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, | |
16058 space: "hsla", | |
16059 parse: function( execResult ) { | |
16060 return [ | |
16061 execResult[ 1 ], | |
16062 execResult[ 2 ] / 100, | |
16063 execResult[ 3 ] / 100, | |
16064 execResult[ 4 ] | |
16065 ]; | |
16066 } | |
16067 }], | |
16068 | |
16069 // jQuery.Color( ) | |
16070 color = jQuery.Color = function( color, green, blue, alpha ) { | |
16071 return new jQuery.Color.fn.parse( color, green, blue, alpha ); | |
16072 }, | |
16073 spaces = { | |
16074 rgba: { | |
16075 props: { | |
16076 red: { | |
16077 idx: 0, | |
16078 type: "byte" | |
16079 }, | |
16080 green: { | |
16081 idx: 1, | |
16082 type: "byte" | |
16083 }, | |
16084 blue: { | |
16085 idx: 2, | |
16086 type: "byte" | |
16087 } | |
16088 } | |
16089 }, | |
16090 | |
16091 hsla: { | |
16092 props: { | |
16093 hue: { | |
16094 idx: 0, | |
16095 type: "degrees" | |
16096 }, | |
16097 saturation: { | |
16098 idx: 1, | |
16099 type: "percent" | |
16100 }, | |
16101 lightness: { | |
16102 idx: 2, | |
16103 type: "percent" | |
16104 } | |
16105 } | |
16106 } | |
16107 }, | |
16108 propTypes = { | |
16109 "byte": { | |
16110 floor: true, | |
16111 max: 255 | |
16112 }, | |
16113 "percent": { | |
16114 max: 1 | |
16115 }, | |
16116 "degrees": { | |
16117 mod: 360, | |
16118 floor: true | |
16119 } | |
16120 }, | |
16121 support = color.support = {}, | |
16122 | |
16123 // element for support tests | |
16124 supportElem = jQuery( "<p>" )[ 0 ], | |
16125 | |
16126 // colors = jQuery.Color.names | |
16127 colors, | |
16128 | |
16129 // local aliases of functions called often | |
16130 each = jQuery.each; | |
16131 | |
16132 // determine rgba support immediately | |
16133 supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; | |
16134 support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; | |
16135 | |
16136 // define cache name and alpha properties | |
16137 // for rgba and hsla spaces | |
16138 each( spaces, function( spaceName, space ) { | |
16139 space.cache = "_" + spaceName; | |
16140 space.props.alpha = { | |
16141 idx: 3, | |
16142 type: "percent", | |
16143 def: 1 | |
16144 }; | |
16145 }); | |
16146 | |
16147 function clamp( value, prop, allowEmpty ) { | |
16148 var type = propTypes[ prop.type ] || {}; | |
16149 | |
16150 if ( value == null ) { | |
16151 return (allowEmpty || !prop.def) ? null : prop.def; | |
16152 } | |
16153 | |
16154 // ~~ is an short way of doing floor for positive numbers | |
16155 value = type.floor ? ~~value : parseFloat( value ); | |
16156 | |
16157 // IE will pass in empty strings as value for alpha, | |
16158 // which will hit this case | |
16159 if ( isNaN( value ) ) { | |
16160 return prop.def; | |
16161 } | |
16162 | |
16163 if ( type.mod ) { | |
16164 // we add mod before modding to make sure that negatives values | |
16165 // get converted properly: -10 -> 350 | |
16166 return (value + type.mod) % type.mod; | |
16167 } | |
16168 | |
16169 // for now all property types without mod have min and max | |
16170 return 0 > value ? 0 : type.max < value ? type.max : value; | |
16171 } | |
16172 | |
16173 function stringParse( string ) { | |
16174 var inst = color(), | |
16175 rgba = inst._rgba = []; | |
16176 | |
16177 string = string.toLowerCase(); | |
16178 | |
16179 each( stringParsers, function( i, parser ) { | |
16180 var parsed, | |
16181 match = parser.re.exec( string ), | |
16182 values = match && parser.parse( match ), | |
16183 spaceName = parser.space || "rgba"; | |
16184 | |
16185 if ( values ) { | |
16186 parsed = inst[ spaceName ]( values ); | |
16187 | |
16188 // if this was an rgba parse the assignment might happen twice | |
16189 // oh well.... | |
16190 inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; | |
16191 rgba = inst._rgba = parsed._rgba; | |
16192 | |
16193 // exit each( stringParsers ) here because we matched | |
16194 return false; | |
16195 } | |
16196 }); | |
16197 | |
16198 // Found a stringParser that handled it | |
16199 if ( rgba.length ) { | |
16200 | |
16201 // if this came from a parsed string, force "transparent" when alpha is 0 | |
16202 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) | |
16203 if ( rgba.join() === "0,0,0,0" ) { | |
16204 jQuery.extend( rgba, colors.transparent ); | |
16205 } | |
16206 return inst; | |
16207 } | |
16208 | |
16209 // named colors | |
16210 return colors[ string ]; | |
16211 } | |
16212 | |
16213 color.fn = jQuery.extend( color.prototype, { | |
16214 parse: function( red, green, blue, alpha ) { | |
16215 if ( red === undefined ) { | |
16216 this._rgba = [ null, null, null, null ]; | |
16217 return this; | |
16218 } | |
16219 if ( red.jquery || red.nodeType ) { | |
16220 red = jQuery( red ).css( green ); | |
16221 green = undefined; | |
16222 } | |
16223 | |
16224 var inst = this, | |
16225 type = jQuery.type( red ), | |
16226 rgba = this._rgba = []; | |
16227 | |
16228 // more than 1 argument specified - assume ( red, green, blue, alpha ) | |
16229 if ( green !== undefined ) { | |
16230 red = [ red, green, blue, alpha ]; | |
16231 type = "array"; | |
16232 } | |
16233 | |
16234 if ( type === "string" ) { | |
16235 return this.parse( stringParse( red ) || colors._default ); | |
16236 } | |
16237 | |
16238 if ( type === "array" ) { | |
16239 each( spaces.rgba.props, function( key, prop ) { | |
16240 rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); | |
16241 }); | |
16242 return this; | |
16243 } | |
16244 | |
16245 if ( type === "object" ) { | |
16246 if ( red instanceof color ) { | |
16247 each( spaces, function( spaceName, space ) { | |
16248 if ( red[ space.cache ] ) { | |
16249 inst[ space.cache ] = red[ space.cache ].slice(); | |
16250 } | |
16251 }); | |
16252 } else { | |
16253 each( spaces, function( spaceName, space ) { | |
16254 var cache = space.cache; | |
16255 each( space.props, function( key, prop ) { | |
16256 | |
16257 // if the cache doesn't exist, and we know how to convert | |
16258 if ( !inst[ cache ] && space.to ) { | |
16259 | |
16260 // if the value was null, we don't need to copy it | |
16261 // if the key was alpha, we don't need to copy it either | |
16262 if ( key === "alpha" || red[ key ] == null ) { | |
16263 return; | |
16264 } | |
16265 inst[ cache ] = space.to( inst._rgba ); | |
16266 } | |
16267 | |
16268 // this is the only case where we allow nulls for ALL properties. | |
16269 // call clamp with alwaysAllowEmpty | |
16270 inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); | |
16271 }); | |
16272 | |
16273 // everything defined but alpha? | |
16274 if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { | |
16275 // use the default of 1 | |
16276 inst[ cache ][ 3 ] = 1; | |
16277 if ( space.from ) { | |
16278 inst._rgba = space.from( inst[ cache ] ); | |
16279 } | |
16280 } | |
16281 }); | |
16282 } | |
16283 return this; | |
16284 } | |
16285 }, | |
16286 is: function( compare ) { | |
16287 var is = color( compare ), | |
16288 same = true, | |
16289 inst = this; | |
16290 | |
16291 each( spaces, function( _, space ) { | |
16292 var localCache, | |
16293 isCache = is[ space.cache ]; | |
16294 if (isCache) { | |
16295 localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; | |
16296 each( space.props, function( _, prop ) { | |
16297 if ( isCache[ prop.idx ] != null ) { | |
16298 same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); | |
16299 return same; | |
16300 } | |
16301 }); | |
16302 } | |
16303 return same; | |
16304 }); | |
16305 return same; | |
16306 }, | |
16307 _space: function() { | |
16308 var used = [], | |
16309 inst = this; | |
16310 each( spaces, function( spaceName, space ) { | |
16311 if ( inst[ space.cache ] ) { | |
16312 used.push( spaceName ); | |
16313 } | |
16314 }); | |
16315 return used.pop(); | |
16316 }, | |
16317 transition: function( other, distance ) { | |
16318 var end = color( other ), | |
16319 spaceName = end._space(), | |
16320 space = spaces[ spaceName ], | |
16321 startColor = this.alpha() === 0 ? color( "transparent" ) : this, | |
16322 start = startColor[ space.cache ] || space.to( startColor._rgba ), | |
16323 result = start.slice(); | |
16324 | |
16325 end = end[ space.cache ]; | |
16326 each( space.props, function( key, prop ) { | |
16327 var index = prop.idx, | |
16328 startValue = start[ index ], | |
16329 endValue = end[ index ], | |
16330 type = propTypes[ prop.type ] || {}; | |
16331 | |
16332 // if null, don't override start value | |
16333 if ( endValue === null ) { | |
16334 return; | |
16335 } | |
16336 // if null - use end | |
16337 if ( startValue === null ) { | |
16338 result[ index ] = endValue; | |
16339 } else { | |
16340 if ( type.mod ) { | |
16341 if ( endValue - startValue > type.mod / 2 ) { | |
16342 startValue += type.mod; | |
16343 } else if ( startValue - endValue > type.mod / 2 ) { | |
16344 startValue -= type.mod; | |
16345 } | |
16346 } | |
16347 result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); | |
16348 } | |
16349 }); | |
16350 return this[ spaceName ]( result ); | |
16351 }, | |
16352 blend: function( opaque ) { | |
16353 // if we are already opaque - return ourself | |
16354 if ( this._rgba[ 3 ] === 1 ) { | |
16355 return this; | |
16356 } | |
16357 | |
16358 var rgb = this._rgba.slice(), | |
16359 a = rgb.pop(), | |
16360 blend = color( opaque )._rgba; | |
16361 | |
16362 return color( jQuery.map( rgb, function( v, i ) { | |
16363 return ( 1 - a ) * blend[ i ] + a * v; | |
16364 })); | |
16365 }, | |
16366 toRgbaString: function() { | |
16367 var prefix = "rgba(", | |
16368 rgba = jQuery.map( this._rgba, function( v, i ) { | |
16369 return v == null ? ( i > 2 ? 1 : 0 ) : v; | |
16370 }); | |
16371 | |
16372 if ( rgba[ 3 ] === 1 ) { | |
16373 rgba.pop(); | |
16374 prefix = "rgb("; | |
16375 } | |
16376 | |
16377 return prefix + rgba.join() + ")"; | |
16378 }, | |
16379 toHslaString: function() { | |
16380 var prefix = "hsla(", | |
16381 hsla = jQuery.map( this.hsla(), function( v, i ) { | |
16382 if ( v == null ) { | |
16383 v = i > 2 ? 1 : 0; | |
16384 } | |
16385 | |
16386 // catch 1 and 2 | |
16387 if ( i && i < 3 ) { | |
16388 v = Math.round( v * 100 ) + "%"; | |
16389 } | |
16390 return v; | |
16391 }); | |
16392 | |
16393 if ( hsla[ 3 ] === 1 ) { | |
16394 hsla.pop(); | |
16395 prefix = "hsl("; | |
16396 } | |
16397 return prefix + hsla.join() + ")"; | |
16398 }, | |
16399 toHexString: function( includeAlpha ) { | |
16400 var rgba = this._rgba.slice(), | |
16401 alpha = rgba.pop(); | |
16402 | |
16403 if ( includeAlpha ) { | |
16404 rgba.push( ~~( alpha * 255 ) ); | |
16405 } | |
16406 | |
16407 return "#" + jQuery.map( rgba, function( v ) { | |
16408 | |
16409 // default to 0 when nulls exist | |
16410 v = ( v || 0 ).toString( 16 ); | |
16411 return v.length === 1 ? "0" + v : v; | |
16412 }).join(""); | |
16413 }, | |
16414 toString: function() { | |
16415 return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); | |
16416 } | |
16417 }); | |
16418 color.fn.parse.prototype = color.fn; | |
16419 | |
16420 // hsla conversions adapted from: | |
16421 // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 | |
16422 | |
16423 function hue2rgb( p, q, h ) { | |
16424 h = ( h + 1 ) % 1; | |
16425 if ( h * 6 < 1 ) { | |
16426 return p + (q - p) * h * 6; | |
16427 } | |
16428 if ( h * 2 < 1) { | |
16429 return q; | |
16430 } | |
16431 if ( h * 3 < 2 ) { | |
16432 return p + (q - p) * ((2/3) - h) * 6; | |
16433 } | |
16434 return p; | |
16435 } | |
16436 | |
16437 spaces.hsla.to = function ( rgba ) { | |
16438 if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { | |
16439 return [ null, null, null, rgba[ 3 ] ]; | |
16440 } | |
16441 var r = rgba[ 0 ] / 255, | |
16442 g = rgba[ 1 ] / 255, | |
16443 b = rgba[ 2 ] / 255, | |
16444 a = rgba[ 3 ], | |
16445 max = Math.max( r, g, b ), | |
16446 min = Math.min( r, g, b ), | |
16447 diff = max - min, | |
16448 add = max + min, | |
16449 l = add * 0.5, | |
16450 h, s; | |
16451 | |
16452 if ( min === max ) { | |
16453 h = 0; | |
16454 } else if ( r === max ) { | |
16455 h = ( 60 * ( g - b ) / diff ) + 360; | |
16456 } else if ( g === max ) { | |
16457 h = ( 60 * ( b - r ) / diff ) + 120; | |
16458 } else { | |
16459 h = ( 60 * ( r - g ) / diff ) + 240; | |
16460 } | |
16461 | |
16462 // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% | |
16463 // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) | |
16464 if ( diff === 0 ) { | |
16465 s = 0; | |
16466 } else if ( l <= 0.5 ) { | |
16467 s = diff / add; | |
16468 } else { | |
16469 s = diff / ( 2 - add ); | |
16470 } | |
16471 return [ Math.round(h) % 360, s, l, a == null ? 1 : a ]; | |
16472 }; | |
16473 | |
16474 spaces.hsla.from = function ( hsla ) { | |
16475 if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { | |
16476 return [ null, null, null, hsla[ 3 ] ]; | |
16477 } | |
16478 var h = hsla[ 0 ] / 360, | |
16479 s = hsla[ 1 ], | |
16480 l = hsla[ 2 ], | |
16481 a = hsla[ 3 ], | |
16482 q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, | |
16483 p = 2 * l - q; | |
16484 | |
16485 return [ | |
16486 Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), | |
16487 Math.round( hue2rgb( p, q, h ) * 255 ), | |
16488 Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), | |
16489 a | |
16490 ]; | |
16491 }; | |
16492 | |
16493 | |
16494 each( spaces, function( spaceName, space ) { | |
16495 var props = space.props, | |
16496 cache = space.cache, | |
16497 to = space.to, | |
16498 from = space.from; | |
16499 | |
16500 // makes rgba() and hsla() | |
16501 color.fn[ spaceName ] = function( value ) { | |
16502 | |
16503 // generate a cache for this space if it doesn't exist | |
16504 if ( to && !this[ cache ] ) { | |
16505 this[ cache ] = to( this._rgba ); | |
16506 } | |
16507 if ( value === undefined ) { | |
16508 return this[ cache ].slice(); | |
16509 } | |
16510 | |
16511 var ret, | |
16512 type = jQuery.type( value ), | |
16513 arr = ( type === "array" || type === "object" ) ? value : arguments, | |
16514 local = this[ cache ].slice(); | |
16515 | |
16516 each( props, function( key, prop ) { | |
16517 var val = arr[ type === "object" ? key : prop.idx ]; | |
16518 if ( val == null ) { | |
16519 val = local[ prop.idx ]; | |
16520 } | |
16521 local[ prop.idx ] = clamp( val, prop ); | |
16522 }); | |
16523 | |
16524 if ( from ) { | |
16525 ret = color( from( local ) ); | |
16526 ret[ cache ] = local; | |
16527 return ret; | |
16528 } else { | |
16529 return color( local ); | |
16530 } | |
16531 }; | |
16532 | |
16533 // makes red() green() blue() alpha() hue() saturation() lightness() | |
16534 each( props, function( key, prop ) { | |
16535 // alpha is included in more than one space | |
16536 if ( color.fn[ key ] ) { | |
16537 return; | |
16538 } | |
16539 color.fn[ key ] = function( value ) { | |
16540 var vtype = jQuery.type( value ), | |
16541 fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), | |
16542 local = this[ fn ](), | |
16543 cur = local[ prop.idx ], | |
16544 match; | |
16545 | |
16546 if ( vtype === "undefined" ) { | |
16547 return cur; | |
16548 } | |
16549 | |
16550 if ( vtype === "function" ) { | |
16551 value = value.call( this, cur ); | |
16552 vtype = jQuery.type( value ); | |
16553 } | |
16554 if ( value == null && prop.empty ) { | |
16555 return this; | |
16556 } | |
16557 if ( vtype === "string" ) { | |
16558 match = rplusequals.exec( value ); | |
16559 if ( match ) { | |
16560 value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); | |
16561 } | |
16562 } | |
16563 local[ prop.idx ] = value; | |
16564 return this[ fn ]( local ); | |
16565 }; | |
16566 }); | |
16567 }); | |
16568 | |
16569 // add cssHook and .fx.step function for each named hook. | |
16570 // accept a space separated string of properties | |
16571 color.hook = function( hook ) { | |
16572 var hooks = hook.split( " " ); | |
16573 each( hooks, function( i, hook ) { | |
16574 jQuery.cssHooks[ hook ] = { | |
16575 set: function( elem, value ) { | |
16576 var parsed, curElem, | |
16577 backgroundColor = ""; | |
16578 | |
16579 if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { | |
16580 value = color( parsed || value ); | |
16581 if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { | |
16582 curElem = hook === "backgroundColor" ? elem.parentNode : elem; | |
16583 while ( | |
16584 (backgroundColor === "" || backgroundColor === "transparent") && | |
16585 curElem && curElem.style | |
16586 ) { | |
16587 try { | |
16588 backgroundColor = jQuery.css( curElem, "backgroundColor" ); | |
16589 curElem = curElem.parentNode; | |
16590 } catch ( e ) { | |
16591 } | |
16592 } | |
16593 | |
16594 value = value.blend( backgroundColor && backgroundColor !== "transparent" ? | |
16595 backgroundColor : | |
16596 "_default" ); | |
16597 } | |
16598 | |
16599 value = value.toRgbaString(); | |
16600 } | |
16601 try { | |
16602 elem.style[ hook ] = value; | |
16603 } catch( e ) { | |
16604 // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' | |
16605 } | |
16606 } | |
16607 }; | |
16608 jQuery.fx.step[ hook ] = function( fx ) { | |
16609 if ( !fx.colorInit ) { | |
16610 fx.start = color( fx.elem, hook ); | |
16611 fx.end = color( fx.end ); | |
16612 fx.colorInit = true; | |
16613 } | |
16614 jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); | |
16615 }; | |
16616 }); | |
16617 | |
16618 }; | |
16619 | |
16620 color.hook( stepHooks ); | |
16621 | |
16622 jQuery.cssHooks.borderColor = { | |
16623 expand: function( value ) { | |
16624 var expanded = {}; | |
16625 | |
16626 each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) { | |
16627 expanded[ "border" + part + "Color" ] = value; | |
16628 }); | |
16629 return expanded; | |
16630 } | |
16631 }; | |
16632 | |
16633 // Basic color names only. | |
16634 // Usage of any of the other color names requires adding yourself or including | |
16635 // jquery.color.svg-names.js. | |
16636 colors = jQuery.Color.names = { | |
16637 // 4.1. Basic color keywords | |
16638 aqua: "#00ffff", | |
16639 black: "#000000", | |
16640 blue: "#0000ff", | |
16641 fuchsia: "#ff00ff", | |
16642 gray: "#808080", | |
16643 green: "#008000", | |
16644 lime: "#00ff00", | |
16645 maroon: "#800000", | |
16646 navy: "#000080", | |
16647 olive: "#808000", | |
16648 purple: "#800080", | |
16649 red: "#ff0000", | |
16650 silver: "#c0c0c0", | |
16651 teal: "#008080", | |
16652 white: "#ffffff", | |
16653 yellow: "#ffff00", | |
16654 | |
16655 // 4.2.3. "transparent" color keyword | |
16656 transparent: [ null, null, null, 0 ], | |
16657 | |
16658 _default: "#ffffff" | |
16659 }; | |
16660 | |
16661 })( jQuery ); | |
16662 | |
16663 | |
16664 /******************************************************************************/ | |
16665 /****************************** CLASS ANIMATIONS ******************************/ | |
16666 /******************************************************************************/ | |
16667 (function() { | |
16668 | |
16669 var classAnimationActions = [ "add", "remove", "toggle" ], | |
16670 shorthandStyles = { | |
16671 border: 1, | |
16672 borderBottom: 1, | |
16673 borderColor: 1, | |
16674 borderLeft: 1, | |
16675 borderRight: 1, | |
16676 borderTop: 1, | |
16677 borderWidth: 1, | |
16678 margin: 1, | |
16679 padding: 1 | |
16680 }; | |
16681 | |
16682 $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { | |
16683 $.fx.step[ prop ] = function( fx ) { | |
16684 if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { | |
16685 jQuery.style( fx.elem, prop, fx.end ); | |
16686 fx.setAttr = true; | |
16687 } | |
16688 }; | |
16689 }); | |
16690 | |
16691 function getElementStyles( elem ) { | |
16692 var key, len, | |
16693 style = elem.ownerDocument.defaultView ? | |
16694 elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : | |
16695 elem.currentStyle, | |
16696 styles = {}; | |
16697 | |
16698 if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { | |
16699 len = style.length; | |
16700 while ( len-- ) { | |
16701 key = style[ len ]; | |
16702 if ( typeof style[ key ] === "string" ) { | |
16703 styles[ $.camelCase( key ) ] = style[ key ]; | |
16704 } | |
16705 } | |
16706 // support: Opera, IE <9 | |
16707 } else { | |
16708 for ( key in style ) { | |
16709 if ( typeof style[ key ] === "string" ) { | |
16710 styles[ key ] = style[ key ]; | |
16711 } | |
16712 } | |
16713 } | |
16714 | |
16715 return styles; | |
16716 } | |
16717 | |
16718 | |
16719 function styleDifference( oldStyle, newStyle ) { | |
16720 var diff = {}, | |
16721 name, value; | |
16722 | |
16723 for ( name in newStyle ) { | |
16724 value = newStyle[ name ]; | |
16725 if ( oldStyle[ name ] !== value ) { | |
16726 if ( !shorthandStyles[ name ] ) { | |
16727 if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { | |
16728 diff[ name ] = value; | |
16729 } | |
16730 } | |
16731 } | |
16732 } | |
16733 | |
16734 return diff; | |
16735 } | |
16736 | |
16737 // support: jQuery <1.8 | |
16738 if ( !$.fn.addBack ) { | |
16739 $.fn.addBack = function( selector ) { | |
16740 return this.add( selector == null ? | |
16741 this.prevObject : this.prevObject.filter( selector ) | |
16742 ); | |
16743 }; | |
16744 } | |
16745 | |
16746 $.effects.animateClass = function( value, duration, easing, callback ) { | |
16747 var o = $.speed( duration, easing, callback ); | |
16748 | |
16749 return this.queue( function() { | |
16750 var animated = $( this ), | |
16751 baseClass = animated.attr( "class" ) || "", | |
16752 applyClassChange, | |
16753 allAnimations = o.children ? animated.find( "*" ).addBack() : animated; | |
16754 | |
16755 // map the animated objects to store the original styles. | |
16756 allAnimations = allAnimations.map(function() { | |
16757 var el = $( this ); | |
16758 return { | |
16759 el: el, | |
16760 start: getElementStyles( this ) | |
16761 }; | |
16762 }); | |
16763 | |
16764 // apply class change | |
16765 applyClassChange = function() { | |
16766 $.each( classAnimationActions, function(i, action) { | |
16767 if ( value[ action ] ) { | |
16768 animated[ action + "Class" ]( value[ action ] ); | |
16769 } | |
16770 }); | |
16771 }; | |
16772 applyClassChange(); | |
16773 | |
16774 // map all animated objects again - calculate new styles and diff | |
16775 allAnimations = allAnimations.map(function() { | |
16776 this.end = getElementStyles( this.el[ 0 ] ); | |
16777 this.diff = styleDifference( this.start, this.end ); | |
16778 return this; | |
16779 }); | |
16780 | |
16781 // apply original class | |
16782 animated.attr( "class", baseClass ); | |
16783 | |
16784 // map all animated objects again - this time collecting a promise | |
16785 allAnimations = allAnimations.map(function() { | |
16786 var styleInfo = this, | |
16787 dfd = $.Deferred(), | |
16788 opts = $.extend({}, o, { | |
16789 queue: false, | |
16790 complete: function() { | |
16791 dfd.resolve( styleInfo ); | |
16792 } | |
16793 }); | |
16794 | |
16795 this.el.animate( this.diff, opts ); | |
16796 return dfd.promise(); | |
16797 }); | |
16798 | |
16799 // once all animations have completed: | |
16800 $.when.apply( $, allAnimations.get() ).done(function() { | |
16801 | |
16802 // set the final class | |
16803 applyClassChange(); | |
16804 | |
16805 // for each animated element, | |
16806 // clear all css properties that were animated | |
16807 $.each( arguments, function() { | |
16808 var el = this.el; | |
16809 $.each( this.diff, function(key) { | |
16810 el.css( key, "" ); | |
16811 }); | |
16812 }); | |
16813 | |
16814 // this is guarnteed to be there if you use jQuery.speed() | |
16815 // it also handles dequeuing the next anim... | |
16816 o.complete.call( animated[ 0 ] ); | |
16817 }); | |
16818 }); | |
16819 }; | |
16820 | |
16821 $.fn.extend({ | |
16822 addClass: (function( orig ) { | |
16823 return function( classNames, speed, easing, callback ) { | |
16824 return speed ? | |
16825 $.effects.animateClass.call( this, | |
16826 { add: classNames }, speed, easing, callback ) : | |
16827 orig.apply( this, arguments ); | |
16828 }; | |
16829 })( $.fn.addClass ), | |
16830 | |
16831 removeClass: (function( orig ) { | |
16832 return function( classNames, speed, easing, callback ) { | |
16833 return arguments.length > 1 ? | |
16834 $.effects.animateClass.call( this, | |
16835 { remove: classNames }, speed, easing, callback ) : | |
16836 orig.apply( this, arguments ); | |
16837 }; | |
16838 })( $.fn.removeClass ), | |
16839 | |
16840 toggleClass: (function( orig ) { | |
16841 return function( classNames, force, speed, easing, callback ) { | |
16842 if ( typeof force === "boolean" || force === undefined ) { | |
16843 if ( !speed ) { | |
16844 // without speed parameter | |
16845 return orig.apply( this, arguments ); | |
16846 } else { | |
16847 return $.effects.animateClass.call( this, | |
16848 (force ? { add: classNames } : { remove: classNames }), | |
16849 speed, easing, callback ); | |
16850 } | |
16851 } else { | |
16852 // without force parameter | |
16853 return $.effects.animateClass.call( this, | |
16854 { toggle: classNames }, force, speed, easing ); | |
16855 } | |
16856 }; | |
16857 })( $.fn.toggleClass ), | |
16858 | |
16859 switchClass: function( remove, add, speed, easing, callback) { | |
16860 return $.effects.animateClass.call( this, { | |
16861 add: add, | |
16862 remove: remove | |
16863 }, speed, easing, callback ); | |
16864 } | |
16865 }); | |
16866 | |
16867 })(); | |
16868 | |
16869 /******************************************************************************/ | |
16870 /*********************************** EFFECTS **********************************/ | |
16871 /******************************************************************************/ | |
16872 | |
16873 (function() { | |
16874 | |
16875 $.extend( $.effects, { | |
16876 version: "1.10.3", | |
16877 | |
16878 // Saves a set of properties in a data storage | |
16879 save: function( element, set ) { | |
16880 for( var i=0; i < set.length; i++ ) { | |
16881 if ( set[ i ] !== null ) { | |
16882 element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); | |
16883 } | |
16884 } | |
16885 }, | |
16886 | |
16887 // Restores a set of previously saved properties from a data storage | |
16888 restore: function( element, set ) { | |
16889 var val, i; | |
16890 for( i=0; i < set.length; i++ ) { | |
16891 if ( set[ i ] !== null ) { | |
16892 val = element.data( dataSpace + set[ i ] ); | |
16893 // support: jQuery 1.6.2 | |
16894 // http://bugs.jquery.com/ticket/9917 | |
16895 // jQuery 1.6.2 incorrectly returns undefined for any falsy value. | |
16896 // We can't differentiate between "" and 0 here, so we just assume | |
16897 // empty string since it's likely to be a more common value... | |
16898 if ( val === undefined ) { | |
16899 val = ""; | |
16900 } | |
16901 element.css( set[ i ], val ); | |
16902 } | |
16903 } | |
16904 }, | |
16905 | |
16906 setMode: function( el, mode ) { | |
16907 if (mode === "toggle") { | |
16908 mode = el.is( ":hidden" ) ? "show" : "hide"; | |
16909 } | |
16910 return mode; | |
16911 }, | |
16912 | |
16913 // Translates a [top,left] array into a baseline value | |
16914 // this should be a little more flexible in the future to handle a string & hash | |
16915 getBaseline: function( origin, original ) { | |
16916 var y, x; | |
16917 switch ( origin[ 0 ] ) { | |
16918 case "top": y = 0; break; | |
16919 case "middle": y = 0.5; break; | |
16920 case "bottom": y = 1; break; | |
16921 default: y = origin[ 0 ] / original.height; | |
16922 } | |
16923 switch ( origin[ 1 ] ) { | |
16924 case "left": x = 0; break; | |
16925 case "center": x = 0.5; break; | |
16926 case "right": x = 1; break; | |
16927 default: x = origin[ 1 ] / original.width; | |
16928 } | |
16929 return { | |
16930 x: x, | |
16931 y: y | |
16932 }; | |
16933 }, | |
16934 | |
16935 // Wraps the element around a wrapper that copies position properties | |
16936 createWrapper: function( element ) { | |
16937 | |
16938 // if the element is already wrapped, return it | |
16939 if ( element.parent().is( ".ui-effects-wrapper" )) { | |
16940 return element.parent(); | |
16941 } | |
16942 | |
16943 // wrap the element | |
16944 var props = { | |
16945 width: element.outerWidth(true), | |
16946 height: element.outerHeight(true), | |
16947 "float": element.css( "float" ) | |
16948 }, | |
16949 wrapper = $( "<div></div>" ) | |
16950 .addClass( "ui-effects-wrapper" ) | |
16951 .css({ | |
16952 fontSize: "100%", | |
16953 background: "transparent", | |
16954 border: "none", | |
16955 margin: 0, | |
16956 padding: 0 | |
16957 }), | |
16958 // Store the size in case width/height are defined in % - Fixes #5245 | |
16959 size = { | |
16960 width: element.width(), | |
16961 height: element.height() | |
16962 }, | |
16963 active = document.activeElement; | |
16964 | |
16965 // support: Firefox | |
16966 // Firefox incorrectly exposes anonymous content | |
16967 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 | |
16968 try { | |
16969 active.id; | |
16970 } catch( e ) { | |
16971 active = document.body; | |
16972 } | |
16973 | |
16974 element.wrap( wrapper ); | |
16975 | |
16976 // Fixes #7595 - Elements lose focus when wrapped. | |
16977 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { | |
16978 $( active ).focus(); | |
16979 } | |
16980 | |
16981 wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element | |
16982 | |
16983 // transfer positioning properties to the wrapper | |
16984 if ( element.css( "position" ) === "static" ) { | |
16985 wrapper.css({ position: "relative" }); | |
16986 element.css({ position: "relative" }); | |
16987 } else { | |
16988 $.extend( props, { | |
16989 position: element.css( "position" ), | |
16990 zIndex: element.css( "z-index" ) | |
16991 }); | |
16992 $.each([ "top", "left", "bottom", "right" ], function(i, pos) { | |
16993 props[ pos ] = element.css( pos ); | |
16994 if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { | |
16995 props[ pos ] = "auto"; | |
16996 } | |
16997 }); | |
16998 element.css({ | |
16999 position: "relative", | |
17000 top: 0, | |
17001 left: 0, | |
17002 right: "auto", | |
17003 bottom: "auto" | |
17004 }); | |
17005 } | |
17006 element.css(size); | |
17007 | |
17008 return wrapper.css( props ).show(); | |
17009 }, | |
17010 | |
17011 removeWrapper: function( element ) { | |
17012 var active = document.activeElement; | |
17013 | |
17014 if ( element.parent().is( ".ui-effects-wrapper" ) ) { | |
17015 element.parent().replaceWith( element ); | |
17016 | |
17017 // Fixes #7595 - Elements lose focus when wrapped. | |
17018 if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { | |
17019 $( active ).focus(); | |
17020 } | |
17021 } | |
17022 | |
17023 | |
17024 return element; | |
17025 }, | |
17026 | |
17027 setTransition: function( element, list, factor, value ) { | |
17028 value = value || {}; | |
17029 $.each( list, function( i, x ) { | |
17030 var unit = element.cssUnit( x ); | |
17031 if ( unit[ 0 ] > 0 ) { | |
17032 value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; | |
17033 } | |
17034 }); | |
17035 return value; | |
17036 } | |
17037 }); | |
17038 | |
17039 // return an effect options object for the given parameters: | |
17040 function _normalizeArguments( effect, options, speed, callback ) { | |
17041 | |
17042 // allow passing all options as the first parameter | |
17043 if ( $.isPlainObject( effect ) ) { | |
17044 options = effect; | |
17045 effect = effect.effect; | |
17046 } | |
17047 | |
17048 // convert to an object | |
17049 effect = { effect: effect }; | |
17050 | |
17051 // catch (effect, null, ...) | |
17052 if ( options == null ) { | |
17053 options = {}; | |
17054 } | |
17055 | |
17056 // catch (effect, callback) | |
17057 if ( $.isFunction( options ) ) { | |
17058 callback = options; | |
17059 speed = null; | |
17060 options = {}; | |
17061 } | |
17062 | |
17063 // catch (effect, speed, ?) | |
17064 if ( typeof options === "number" || $.fx.speeds[ options ] ) { | |
17065 callback = speed; | |
17066 speed = options; | |
17067 options = {}; | |
17068 } | |
17069 | |
17070 // catch (effect, options, callback) | |
17071 if ( $.isFunction( speed ) ) { | |
17072 callback = speed; | |
17073 speed = null; | |
17074 } | |
17075 | |
17076 // add options to effect | |
17077 if ( options ) { | |
17078 $.extend( effect, options ); | |
17079 } | |
17080 | |
17081 speed = speed || options.duration; | |
17082 effect.duration = $.fx.off ? 0 : | |
17083 typeof speed === "number" ? speed : | |
17084 speed in $.fx.speeds ? $.fx.speeds[ speed ] : | |
17085 $.fx.speeds._default; | |
17086 | |
17087 effect.complete = callback || options.complete; | |
17088 | |
17089 return effect; | |
17090 } | |
17091 | |
17092 function standardAnimationOption( option ) { | |
17093 // Valid standard speeds (nothing, number, named speed) | |
17094 if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { | |
17095 return true; | |
17096 } | |
17097 | |
17098 // Invalid strings - treat as "normal" speed | |
17099 if ( typeof option === "string" && !$.effects.effect[ option ] ) { | |
17100 return true; | |
17101 } | |
17102 | |
17103 // Complete callback | |
17104 if ( $.isFunction( option ) ) { | |
17105 return true; | |
17106 } | |
17107 | |
17108 // Options hash (but not naming an effect) | |
17109 if ( typeof option === "object" && !option.effect ) { | |
17110 return true; | |
17111 } | |
17112 | |
17113 // Didn't match any standard API | |
17114 return false; | |
17115 } | |
17116 | |
17117 $.fn.extend({ | |
17118 effect: function( /* effect, options, speed, callback */ ) { | |
17119 var args = _normalizeArguments.apply( this, arguments ), | |
17120 mode = args.mode, | |
17121 queue = args.queue, | |
17122 effectMethod = $.effects.effect[ args.effect ]; | |
17123 | |
17124 if ( $.fx.off || !effectMethod ) { | |
17125 // delegate to the original method (e.g., .show()) if possible | |
17126 if ( mode ) { | |
17127 return this[ mode ]( args.duration, args.complete ); | |
17128 } else { | |
17129 return this.each( function() { | |
17130 if ( args.complete ) { | |
17131 args.complete.call( this ); | |
17132 } | |
17133 }); | |
17134 } | |
17135 } | |
17136 | |
17137 function run( next ) { | |
17138 var elem = $( this ), | |
17139 complete = args.complete, | |
17140 mode = args.mode; | |
17141 | |
17142 function done() { | |
17143 if ( $.isFunction( complete ) ) { | |
17144 complete.call( elem[0] ); | |
17145 } | |
17146 if ( $.isFunction( next ) ) { | |
17147 next(); | |
17148 } | |
17149 } | |
17150 | |
17151 // If the element already has the correct final state, delegate to | |
17152 // the core methods so the internal tracking of "olddisplay" works. | |
17153 if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { | |
17154 elem[ mode ](); | |
17155 done(); | |
17156 } else { | |
17157 effectMethod.call( elem[0], args, done ); | |
17158 } | |
17159 } | |
17160 | |
17161 return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); | |
17162 }, | |
17163 | |
17164 show: (function( orig ) { | |
17165 return function( option ) { | |
17166 if ( standardAnimationOption( option ) ) { | |
17167 return orig.apply( this, arguments ); | |
17168 } else { | |
17169 var args = _normalizeArguments.apply( this, arguments ); | |
17170 args.mode = "show"; | |
17171 return this.effect.call( this, args ); | |
17172 } | |
17173 }; | |
17174 })( $.fn.show ), | |
17175 | |
17176 hide: (function( orig ) { | |
17177 return function( option ) { | |
17178 if ( standardAnimationOption( option ) ) { | |
17179 return orig.apply( this, arguments ); | |
17180 } else { | |
17181 var args = _normalizeArguments.apply( this, arguments ); | |
17182 args.mode = "hide"; | |
17183 return this.effect.call( this, args ); | |
17184 } | |
17185 }; | |
17186 })( $.fn.hide ), | |
17187 | |
17188 toggle: (function( orig ) { | |
17189 return function( option ) { | |
17190 if ( standardAnimationOption( option ) || typeof option === "boolean" ) { | |
17191 return orig.apply( this, arguments ); | |
17192 } else { | |
17193 var args = _normalizeArguments.apply( this, arguments ); | |
17194 args.mode = "toggle"; | |
17195 return this.effect.call( this, args ); | |
17196 } | |
17197 }; | |
17198 })( $.fn.toggle ), | |
17199 | |
17200 // helper functions | |
17201 cssUnit: function(key) { | |
17202 var style = this.css( key ), | |
17203 val = []; | |
17204 | |
17205 $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { | |
17206 if ( style.indexOf( unit ) > 0 ) { | |
17207 val = [ parseFloat( style ), unit ]; | |
17208 } | |
17209 }); | |
17210 return val; | |
17211 } | |
17212 }); | |
17213 | |
17214 })(); | |
17215 | |
17216 /******************************************************************************/ | |
17217 /*********************************** EASING ***********************************/ | |
17218 /******************************************************************************/ | |
17219 | |
17220 (function() { | |
17221 | |
17222 // based on easing equations from Robert Penner (http://www.robertpenner.com/easing) | |
17223 | |
17224 var baseEasings = {}; | |
17225 | |
17226 $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { | |
17227 baseEasings[ name ] = function( p ) { | |
17228 return Math.pow( p, i + 2 ); | |
17229 }; | |
17230 }); | |
17231 | |
17232 $.extend( baseEasings, { | |
17233 Sine: function ( p ) { | |
17234 return 1 - Math.cos( p * Math.PI / 2 ); | |
17235 }, | |
17236 Circ: function ( p ) { | |
17237 return 1 - Math.sqrt( 1 - p * p ); | |
17238 }, | |
17239 Elastic: function( p ) { | |
17240 return p === 0 || p === 1 ? p : | |
17241 -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 ); | |
17242 }, | |
17243 Back: function( p ) { | |
17244 return p * p * ( 3 * p - 2 ); | |
17245 }, | |
17246 Bounce: function ( p ) { | |
17247 var pow2, | |
17248 bounce = 4; | |
17249 | |
17250 while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} | |
17251 return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); | |
17252 } | |
17253 }); | |
17254 | |
17255 $.each( baseEasings, function( name, easeIn ) { | |
17256 $.easing[ "easeIn" + name ] = easeIn; | |
17257 $.easing[ "easeOut" + name ] = function( p ) { | |
17258 return 1 - easeIn( 1 - p ); | |
17259 }; | |
17260 $.easing[ "easeInOut" + name ] = function( p ) { | |
17261 return p < 0.5 ? | |
17262 easeIn( p * 2 ) / 2 : | |
17263 1 - easeIn( p * -2 + 2 ) / 2; | |
17264 }; | |
17265 }); | |
17266 | |
17267 })(); | |
17268 | |
17269 })(jQuery); | |
17270 (function( $, undefined ) { | |
17271 | |
17272 var rvertical = /up|down|vertical/, | |
17273 rpositivemotion = /up|left|vertical|horizontal/; | |
17274 | |
17275 $.effects.effect.blind = function( o, done ) { | |
17276 // Create element | |
17277 var el = $( this ), | |
17278 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17279 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17280 direction = o.direction || "up", | |
17281 vertical = rvertical.test( direction ), | |
17282 ref = vertical ? "height" : "width", | |
17283 ref2 = vertical ? "top" : "left", | |
17284 motion = rpositivemotion.test( direction ), | |
17285 animation = {}, | |
17286 show = mode === "show", | |
17287 wrapper, distance, margin; | |
17288 | |
17289 // if already wrapped, the wrapper's properties are my property. #6245 | |
17290 if ( el.parent().is( ".ui-effects-wrapper" ) ) { | |
17291 $.effects.save( el.parent(), props ); | |
17292 } else { | |
17293 $.effects.save( el, props ); | |
17294 } | |
17295 el.show(); | |
17296 wrapper = $.effects.createWrapper( el ).css({ | |
17297 overflow: "hidden" | |
17298 }); | |
17299 | |
17300 distance = wrapper[ ref ](); | |
17301 margin = parseFloat( wrapper.css( ref2 ) ) || 0; | |
17302 | |
17303 animation[ ref ] = show ? distance : 0; | |
17304 if ( !motion ) { | |
17305 el | |
17306 .css( vertical ? "bottom" : "right", 0 ) | |
17307 .css( vertical ? "top" : "left", "auto" ) | |
17308 .css({ position: "absolute" }); | |
17309 | |
17310 animation[ ref2 ] = show ? margin : distance + margin; | |
17311 } | |
17312 | |
17313 // start at 0 if we are showing | |
17314 if ( show ) { | |
17315 wrapper.css( ref, 0 ); | |
17316 if ( ! motion ) { | |
17317 wrapper.css( ref2, margin + distance ); | |
17318 } | |
17319 } | |
17320 | |
17321 // Animate | |
17322 wrapper.animate( animation, { | |
17323 duration: o.duration, | |
17324 easing: o.easing, | |
17325 queue: false, | |
17326 complete: function() { | |
17327 if ( mode === "hide" ) { | |
17328 el.hide(); | |
17329 } | |
17330 $.effects.restore( el, props ); | |
17331 $.effects.removeWrapper( el ); | |
17332 done(); | |
17333 } | |
17334 }); | |
17335 | |
17336 }; | |
17337 | |
17338 })(jQuery); | |
17339 (function( $, undefined ) { | |
17340 | |
17341 $.effects.effect.bounce = function( o, done ) { | |
17342 var el = $( this ), | |
17343 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17344 | |
17345 // defaults: | |
17346 mode = $.effects.setMode( el, o.mode || "effect" ), | |
17347 hide = mode === "hide", | |
17348 show = mode === "show", | |
17349 direction = o.direction || "up", | |
17350 distance = o.distance, | |
17351 times = o.times || 5, | |
17352 | |
17353 // number of internal animations | |
17354 anims = times * 2 + ( show || hide ? 1 : 0 ), | |
17355 speed = o.duration / anims, | |
17356 easing = o.easing, | |
17357 | |
17358 // utility: | |
17359 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", | |
17360 motion = ( direction === "up" || direction === "left" ), | |
17361 i, | |
17362 upAnim, | |
17363 downAnim, | |
17364 | |
17365 // we will need to re-assemble the queue to stack our animations in place | |
17366 queue = el.queue(), | |
17367 queuelen = queue.length; | |
17368 | |
17369 // Avoid touching opacity to prevent clearType and PNG issues in IE | |
17370 if ( show || hide ) { | |
17371 props.push( "opacity" ); | |
17372 } | |
17373 | |
17374 $.effects.save( el, props ); | |
17375 el.show(); | |
17376 $.effects.createWrapper( el ); // Create Wrapper | |
17377 | |
17378 // default distance for the BIGGEST bounce is the outer Distance / 3 | |
17379 if ( !distance ) { | |
17380 distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; | |
17381 } | |
17382 | |
17383 if ( show ) { | |
17384 downAnim = { opacity: 1 }; | |
17385 downAnim[ ref ] = 0; | |
17386 | |
17387 // if we are showing, force opacity 0 and set the initial position | |
17388 // then do the "first" animation | |
17389 el.css( "opacity", 0 ) | |
17390 .css( ref, motion ? -distance * 2 : distance * 2 ) | |
17391 .animate( downAnim, speed, easing ); | |
17392 } | |
17393 | |
17394 // start at the smallest distance if we are hiding | |
17395 if ( hide ) { | |
17396 distance = distance / Math.pow( 2, times - 1 ); | |
17397 } | |
17398 | |
17399 downAnim = {}; | |
17400 downAnim[ ref ] = 0; | |
17401 // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here | |
17402 for ( i = 0; i < times; i++ ) { | |
17403 upAnim = {}; | |
17404 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; | |
17405 | |
17406 el.animate( upAnim, speed, easing ) | |
17407 .animate( downAnim, speed, easing ); | |
17408 | |
17409 distance = hide ? distance * 2 : distance / 2; | |
17410 } | |
17411 | |
17412 // Last Bounce when Hiding | |
17413 if ( hide ) { | |
17414 upAnim = { opacity: 0 }; | |
17415 upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; | |
17416 | |
17417 el.animate( upAnim, speed, easing ); | |
17418 } | |
17419 | |
17420 el.queue(function() { | |
17421 if ( hide ) { | |
17422 el.hide(); | |
17423 } | |
17424 $.effects.restore( el, props ); | |
17425 $.effects.removeWrapper( el ); | |
17426 done(); | |
17427 }); | |
17428 | |
17429 // inject all the animations we just queued to be first in line (after "inprogress") | |
17430 if ( queuelen > 1) { | |
17431 queue.splice.apply( queue, | |
17432 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); | |
17433 } | |
17434 el.dequeue(); | |
17435 | |
17436 }; | |
17437 | |
17438 })(jQuery); | |
17439 (function( $, undefined ) { | |
17440 | |
17441 $.effects.effect.clip = function( o, done ) { | |
17442 // Create element | |
17443 var el = $( this ), | |
17444 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17445 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17446 show = mode === "show", | |
17447 direction = o.direction || "vertical", | |
17448 vert = direction === "vertical", | |
17449 size = vert ? "height" : "width", | |
17450 position = vert ? "top" : "left", | |
17451 animation = {}, | |
17452 wrapper, animate, distance; | |
17453 | |
17454 // Save & Show | |
17455 $.effects.save( el, props ); | |
17456 el.show(); | |
17457 | |
17458 // Create Wrapper | |
17459 wrapper = $.effects.createWrapper( el ).css({ | |
17460 overflow: "hidden" | |
17461 }); | |
17462 animate = ( el[0].tagName === "IMG" ) ? wrapper : el; | |
17463 distance = animate[ size ](); | |
17464 | |
17465 // Shift | |
17466 if ( show ) { | |
17467 animate.css( size, 0 ); | |
17468 animate.css( position, distance / 2 ); | |
17469 } | |
17470 | |
17471 // Create Animation Object: | |
17472 animation[ size ] = show ? distance : 0; | |
17473 animation[ position ] = show ? 0 : distance / 2; | |
17474 | |
17475 // Animate | |
17476 animate.animate( animation, { | |
17477 queue: false, | |
17478 duration: o.duration, | |
17479 easing: o.easing, | |
17480 complete: function() { | |
17481 if ( !show ) { | |
17482 el.hide(); | |
17483 } | |
17484 $.effects.restore( el, props ); | |
17485 $.effects.removeWrapper( el ); | |
17486 done(); | |
17487 } | |
17488 }); | |
17489 | |
17490 }; | |
17491 | |
17492 })(jQuery); | |
17493 (function( $, undefined ) { | |
17494 | |
17495 $.effects.effect.drop = function( o, done ) { | |
17496 | |
17497 var el = $( this ), | |
17498 props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ], | |
17499 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17500 show = mode === "show", | |
17501 direction = o.direction || "left", | |
17502 ref = ( direction === "up" || direction === "down" ) ? "top" : "left", | |
17503 motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg", | |
17504 animation = { | |
17505 opacity: show ? 1 : 0 | |
17506 }, | |
17507 distance; | |
17508 | |
17509 // Adjust | |
17510 $.effects.save( el, props ); | |
17511 el.show(); | |
17512 $.effects.createWrapper( el ); | |
17513 | |
17514 distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2; | |
17515 | |
17516 if ( show ) { | |
17517 el | |
17518 .css( "opacity", 0 ) | |
17519 .css( ref, motion === "pos" ? -distance : distance ); | |
17520 } | |
17521 | |
17522 // Animation | |
17523 animation[ ref ] = ( show ? | |
17524 ( motion === "pos" ? "+=" : "-=" ) : | |
17525 ( motion === "pos" ? "-=" : "+=" ) ) + | |
17526 distance; | |
17527 | |
17528 // Animate | |
17529 el.animate( animation, { | |
17530 queue: false, | |
17531 duration: o.duration, | |
17532 easing: o.easing, | |
17533 complete: function() { | |
17534 if ( mode === "hide" ) { | |
17535 el.hide(); | |
17536 } | |
17537 $.effects.restore( el, props ); | |
17538 $.effects.removeWrapper( el ); | |
17539 done(); | |
17540 } | |
17541 }); | |
17542 }; | |
17543 | |
17544 })(jQuery); | |
17545 (function( $, undefined ) { | |
17546 | |
17547 $.effects.effect.explode = function( o, done ) { | |
17548 | |
17549 var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3, | |
17550 cells = rows, | |
17551 el = $( this ), | |
17552 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17553 show = mode === "show", | |
17554 | |
17555 // show and then visibility:hidden the element before calculating offset | |
17556 offset = el.show().css( "visibility", "hidden" ).offset(), | |
17557 | |
17558 // width and height of a piece | |
17559 width = Math.ceil( el.outerWidth() / cells ), | |
17560 height = Math.ceil( el.outerHeight() / rows ), | |
17561 pieces = [], | |
17562 | |
17563 // loop | |
17564 i, j, left, top, mx, my; | |
17565 | |
17566 // children animate complete: | |
17567 function childComplete() { | |
17568 pieces.push( this ); | |
17569 if ( pieces.length === rows * cells ) { | |
17570 animComplete(); | |
17571 } | |
17572 } | |
17573 | |
17574 // clone the element for each row and cell. | |
17575 for( i = 0; i < rows ; i++ ) { // ===> | |
17576 top = offset.top + i * height; | |
17577 my = i - ( rows - 1 ) / 2 ; | |
17578 | |
17579 for( j = 0; j < cells ; j++ ) { // ||| | |
17580 left = offset.left + j * width; | |
17581 mx = j - ( cells - 1 ) / 2 ; | |
17582 | |
17583 // Create a clone of the now hidden main element that will be absolute positioned | |
17584 // within a wrapper div off the -left and -top equal to size of our pieces | |
17585 el | |
17586 .clone() | |
17587 .appendTo( "body" ) | |
17588 .wrap( "<div></div>" ) | |
17589 .css({ | |
17590 position: "absolute", | |
17591 visibility: "visible", | |
17592 left: -j * width, | |
17593 top: -i * height | |
17594 }) | |
17595 | |
17596 // select the wrapper - make it overflow: hidden and absolute positioned based on | |
17597 // where the original was located +left and +top equal to the size of pieces | |
17598 .parent() | |
17599 .addClass( "ui-effects-explode" ) | |
17600 .css({ | |
17601 position: "absolute", | |
17602 overflow: "hidden", | |
17603 width: width, | |
17604 height: height, | |
17605 left: left + ( show ? mx * width : 0 ), | |
17606 top: top + ( show ? my * height : 0 ), | |
17607 opacity: show ? 0 : 1 | |
17608 }).animate({ | |
17609 left: left + ( show ? 0 : mx * width ), | |
17610 top: top + ( show ? 0 : my * height ), | |
17611 opacity: show ? 1 : 0 | |
17612 }, o.duration || 500, o.easing, childComplete ); | |
17613 } | |
17614 } | |
17615 | |
17616 function animComplete() { | |
17617 el.css({ | |
17618 visibility: "visible" | |
17619 }); | |
17620 $( pieces ).remove(); | |
17621 if ( !show ) { | |
17622 el.hide(); | |
17623 } | |
17624 done(); | |
17625 } | |
17626 }; | |
17627 | |
17628 })(jQuery); | |
17629 (function( $, undefined ) { | |
17630 | |
17631 $.effects.effect.fade = function( o, done ) { | |
17632 var el = $( this ), | |
17633 mode = $.effects.setMode( el, o.mode || "toggle" ); | |
17634 | |
17635 el.animate({ | |
17636 opacity: mode | |
17637 }, { | |
17638 queue: false, | |
17639 duration: o.duration, | |
17640 easing: o.easing, | |
17641 complete: done | |
17642 }); | |
17643 }; | |
17644 | |
17645 })( jQuery ); | |
17646 (function( $, undefined ) { | |
17647 | |
17648 $.effects.effect.fold = function( o, done ) { | |
17649 | |
17650 // Create element | |
17651 var el = $( this ), | |
17652 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
17653 mode = $.effects.setMode( el, o.mode || "hide" ), | |
17654 show = mode === "show", | |
17655 hide = mode === "hide", | |
17656 size = o.size || 15, | |
17657 percent = /([0-9]+)%/.exec( size ), | |
17658 horizFirst = !!o.horizFirst, | |
17659 widthFirst = show !== horizFirst, | |
17660 ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ], | |
17661 duration = o.duration / 2, | |
17662 wrapper, distance, | |
17663 animation1 = {}, | |
17664 animation2 = {}; | |
17665 | |
17666 $.effects.save( el, props ); | |
17667 el.show(); | |
17668 | |
17669 // Create Wrapper | |
17670 wrapper = $.effects.createWrapper( el ).css({ | |
17671 overflow: "hidden" | |
17672 }); | |
17673 distance = widthFirst ? | |
17674 [ wrapper.width(), wrapper.height() ] : | |
17675 [ wrapper.height(), wrapper.width() ]; | |
17676 | |
17677 if ( percent ) { | |
17678 size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; | |
17679 } | |
17680 if ( show ) { | |
17681 wrapper.css( horizFirst ? { | |
17682 height: 0, | |
17683 width: size | |
17684 } : { | |
17685 height: size, | |
17686 width: 0 | |
17687 }); | |
17688 } | |
17689 | |
17690 // Animation | |
17691 animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size; | |
17692 animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0; | |
17693 | |
17694 // Animate | |
17695 wrapper | |
17696 .animate( animation1, duration, o.easing ) | |
17697 .animate( animation2, duration, o.easing, function() { | |
17698 if ( hide ) { | |
17699 el.hide(); | |
17700 } | |
17701 $.effects.restore( el, props ); | |
17702 $.effects.removeWrapper( el ); | |
17703 done(); | |
17704 }); | |
17705 | |
17706 }; | |
17707 | |
17708 })(jQuery); | |
17709 (function( $, undefined ) { | |
17710 | |
17711 $.effects.effect.highlight = function( o, done ) { | |
17712 var elem = $( this ), | |
17713 props = [ "backgroundImage", "backgroundColor", "opacity" ], | |
17714 mode = $.effects.setMode( elem, o.mode || "show" ), | |
17715 animation = { | |
17716 backgroundColor: elem.css( "backgroundColor" ) | |
17717 }; | |
17718 | |
17719 if (mode === "hide") { | |
17720 animation.opacity = 0; | |
17721 } | |
17722 | |
17723 $.effects.save( elem, props ); | |
17724 | |
17725 elem | |
17726 .show() | |
17727 .css({ | |
17728 backgroundImage: "none", | |
17729 backgroundColor: o.color || "#ffff99" | |
17730 }) | |
17731 .animate( animation, { | |
17732 queue: false, | |
17733 duration: o.duration, | |
17734 easing: o.easing, | |
17735 complete: function() { | |
17736 if ( mode === "hide" ) { | |
17737 elem.hide(); | |
17738 } | |
17739 $.effects.restore( elem, props ); | |
17740 done(); | |
17741 } | |
17742 }); | |
17743 }; | |
17744 | |
17745 })(jQuery); | |
17746 (function( $, undefined ) { | |
17747 | |
17748 $.effects.effect.pulsate = function( o, done ) { | |
17749 var elem = $( this ), | |
17750 mode = $.effects.setMode( elem, o.mode || "show" ), | |
17751 show = mode === "show", | |
17752 hide = mode === "hide", | |
17753 showhide = ( show || mode === "hide" ), | |
17754 | |
17755 // showing or hiding leaves of the "last" animation | |
17756 anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), | |
17757 duration = o.duration / anims, | |
17758 animateTo = 0, | |
17759 queue = elem.queue(), | |
17760 queuelen = queue.length, | |
17761 i; | |
17762 | |
17763 if ( show || !elem.is(":visible")) { | |
17764 elem.css( "opacity", 0 ).show(); | |
17765 animateTo = 1; | |
17766 } | |
17767 | |
17768 // anims - 1 opacity "toggles" | |
17769 for ( i = 1; i < anims; i++ ) { | |
17770 elem.animate({ | |
17771 opacity: animateTo | |
17772 }, duration, o.easing ); | |
17773 animateTo = 1 - animateTo; | |
17774 } | |
17775 | |
17776 elem.animate({ | |
17777 opacity: animateTo | |
17778 }, duration, o.easing); | |
17779 | |
17780 elem.queue(function() { | |
17781 if ( hide ) { | |
17782 elem.hide(); | |
17783 } | |
17784 done(); | |
17785 }); | |
17786 | |
17787 // We just queued up "anims" animations, we need to put them next in the queue | |
17788 if ( queuelen > 1 ) { | |
17789 queue.splice.apply( queue, | |
17790 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); | |
17791 } | |
17792 elem.dequeue(); | |
17793 }; | |
17794 | |
17795 })(jQuery); | |
17796 (function( $, undefined ) { | |
17797 | |
17798 $.effects.effect.puff = function( o, done ) { | |
17799 var elem = $( this ), | |
17800 mode = $.effects.setMode( elem, o.mode || "hide" ), | |
17801 hide = mode === "hide", | |
17802 percent = parseInt( o.percent, 10 ) || 150, | |
17803 factor = percent / 100, | |
17804 original = { | |
17805 height: elem.height(), | |
17806 width: elem.width(), | |
17807 outerHeight: elem.outerHeight(), | |
17808 outerWidth: elem.outerWidth() | |
17809 }; | |
17810 | |
17811 $.extend( o, { | |
17812 effect: "scale", | |
17813 queue: false, | |
17814 fade: true, | |
17815 mode: mode, | |
17816 complete: done, | |
17817 percent: hide ? percent : 100, | |
17818 from: hide ? | |
17819 original : | |
17820 { | |
17821 height: original.height * factor, | |
17822 width: original.width * factor, | |
17823 outerHeight: original.outerHeight * factor, | |
17824 outerWidth: original.outerWidth * factor | |
17825 } | |
17826 }); | |
17827 | |
17828 elem.effect( o ); | |
17829 }; | |
17830 | |
17831 $.effects.effect.scale = function( o, done ) { | |
17832 | |
17833 // Create element | |
17834 var el = $( this ), | |
17835 options = $.extend( true, {}, o ), | |
17836 mode = $.effects.setMode( el, o.mode || "effect" ), | |
17837 percent = parseInt( o.percent, 10 ) || | |
17838 ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ), | |
17839 direction = o.direction || "both", | |
17840 origin = o.origin, | |
17841 original = { | |
17842 height: el.height(), | |
17843 width: el.width(), | |
17844 outerHeight: el.outerHeight(), | |
17845 outerWidth: el.outerWidth() | |
17846 }, | |
17847 factor = { | |
17848 y: direction !== "horizontal" ? (percent / 100) : 1, | |
17849 x: direction !== "vertical" ? (percent / 100) : 1 | |
17850 }; | |
17851 | |
17852 // We are going to pass this effect to the size effect: | |
17853 options.effect = "size"; | |
17854 options.queue = false; | |
17855 options.complete = done; | |
17856 | |
17857 // Set default origin and restore for show/hide | |
17858 if ( mode !== "effect" ) { | |
17859 options.origin = origin || ["middle","center"]; | |
17860 options.restore = true; | |
17861 } | |
17862 | |
17863 options.from = o.from || ( mode === "show" ? { | |
17864 height: 0, | |
17865 width: 0, | |
17866 outerHeight: 0, | |
17867 outerWidth: 0 | |
17868 } : original ); | |
17869 options.to = { | |
17870 height: original.height * factor.y, | |
17871 width: original.width * factor.x, | |
17872 outerHeight: original.outerHeight * factor.y, | |
17873 outerWidth: original.outerWidth * factor.x | |
17874 }; | |
17875 | |
17876 // Fade option to support puff | |
17877 if ( options.fade ) { | |
17878 if ( mode === "show" ) { | |
17879 options.from.opacity = 0; | |
17880 options.to.opacity = 1; | |
17881 } | |
17882 if ( mode === "hide" ) { | |
17883 options.from.opacity = 1; | |
17884 options.to.opacity = 0; | |
17885 } | |
17886 } | |
17887 | |
17888 // Animate | |
17889 el.effect( options ); | |
17890 | |
17891 }; | |
17892 | |
17893 $.effects.effect.size = function( o, done ) { | |
17894 | |
17895 // Create element | |
17896 var original, baseline, factor, | |
17897 el = $( this ), | |
17898 props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ], | |
17899 | |
17900 // Always restore | |
17901 props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ], | |
17902 | |
17903 // Copy for children | |
17904 props2 = [ "width", "height", "overflow" ], | |
17905 cProps = [ "fontSize" ], | |
17906 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], | |
17907 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], | |
17908 | |
17909 // Set options | |
17910 mode = $.effects.setMode( el, o.mode || "effect" ), | |
17911 restore = o.restore || mode !== "effect", | |
17912 scale = o.scale || "both", | |
17913 origin = o.origin || [ "middle", "center" ], | |
17914 position = el.css( "position" ), | |
17915 props = restore ? props0 : props1, | |
17916 zero = { | |
17917 height: 0, | |
17918 width: 0, | |
17919 outerHeight: 0, | |
17920 outerWidth: 0 | |
17921 }; | |
17922 | |
17923 if ( mode === "show" ) { | |
17924 el.show(); | |
17925 } | |
17926 original = { | |
17927 height: el.height(), | |
17928 width: el.width(), | |
17929 outerHeight: el.outerHeight(), | |
17930 outerWidth: el.outerWidth() | |
17931 }; | |
17932 | |
17933 if ( o.mode === "toggle" && mode === "show" ) { | |
17934 el.from = o.to || zero; | |
17935 el.to = o.from || original; | |
17936 } else { | |
17937 el.from = o.from || ( mode === "show" ? zero : original ); | |
17938 el.to = o.to || ( mode === "hide" ? zero : original ); | |
17939 } | |
17940 | |
17941 // Set scaling factor | |
17942 factor = { | |
17943 from: { | |
17944 y: el.from.height / original.height, | |
17945 x: el.from.width / original.width | |
17946 }, | |
17947 to: { | |
17948 y: el.to.height / original.height, | |
17949 x: el.to.width / original.width | |
17950 } | |
17951 }; | |
17952 | |
17953 // Scale the css box | |
17954 if ( scale === "box" || scale === "both" ) { | |
17955 | |
17956 // Vertical props scaling | |
17957 if ( factor.from.y !== factor.to.y ) { | |
17958 props = props.concat( vProps ); | |
17959 el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from ); | |
17960 el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to ); | |
17961 } | |
17962 | |
17963 // Horizontal props scaling | |
17964 if ( factor.from.x !== factor.to.x ) { | |
17965 props = props.concat( hProps ); | |
17966 el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from ); | |
17967 el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to ); | |
17968 } | |
17969 } | |
17970 | |
17971 // Scale the content | |
17972 if ( scale === "content" || scale === "both" ) { | |
17973 | |
17974 // Vertical props scaling | |
17975 if ( factor.from.y !== factor.to.y ) { | |
17976 props = props.concat( cProps ).concat( props2 ); | |
17977 el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from ); | |
17978 el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to ); | |
17979 } | |
17980 } | |
17981 | |
17982 $.effects.save( el, props ); | |
17983 el.show(); | |
17984 $.effects.createWrapper( el ); | |
17985 el.css( "overflow", "hidden" ).css( el.from ); | |
17986 | |
17987 // Adjust | |
17988 if (origin) { // Calculate baseline shifts | |
17989 baseline = $.effects.getBaseline( origin, original ); | |
17990 el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y; | |
17991 el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x; | |
17992 el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y; | |
17993 el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x; | |
17994 } | |
17995 el.css( el.from ); // set top & left | |
17996 | |
17997 // Animate | |
17998 if ( scale === "content" || scale === "both" ) { // Scale the children | |
17999 | |
18000 // Add margins/font-size | |
18001 vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps); | |
18002 hProps = hProps.concat([ "marginLeft", "marginRight" ]); | |
18003 props2 = props0.concat(vProps).concat(hProps); | |
18004 | |
18005 el.find( "*[width]" ).each( function(){ | |
18006 var child = $( this ), | |
18007 c_original = { | |
18008 height: child.height(), | |
18009 width: child.width(), | |
18010 outerHeight: child.outerHeight(), | |
18011 outerWidth: child.outerWidth() | |
18012 }; | |
18013 if (restore) { | |
18014 $.effects.save(child, props2); | |
18015 } | |
18016 | |
18017 child.from = { | |
18018 height: c_original.height * factor.from.y, | |
18019 width: c_original.width * factor.from.x, | |
18020 outerHeight: c_original.outerHeight * factor.from.y, | |
18021 outerWidth: c_original.outerWidth * factor.from.x | |
18022 }; | |
18023 child.to = { | |
18024 height: c_original.height * factor.to.y, | |
18025 width: c_original.width * factor.to.x, | |
18026 outerHeight: c_original.height * factor.to.y, | |
18027 outerWidth: c_original.width * factor.to.x | |
18028 }; | |
18029 | |
18030 // Vertical props scaling | |
18031 if ( factor.from.y !== factor.to.y ) { | |
18032 child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from ); | |
18033 child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to ); | |
18034 } | |
18035 | |
18036 // Horizontal props scaling | |
18037 if ( factor.from.x !== factor.to.x ) { | |
18038 child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from ); | |
18039 child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to ); | |
18040 } | |
18041 | |
18042 // Animate children | |
18043 child.css( child.from ); | |
18044 child.animate( child.to, o.duration, o.easing, function() { | |
18045 | |
18046 // Restore children | |
18047 if ( restore ) { | |
18048 $.effects.restore( child, props2 ); | |
18049 } | |
18050 }); | |
18051 }); | |
18052 } | |
18053 | |
18054 // Animate | |
18055 el.animate( el.to, { | |
18056 queue: false, | |
18057 duration: o.duration, | |
18058 easing: o.easing, | |
18059 complete: function() { | |
18060 if ( el.to.opacity === 0 ) { | |
18061 el.css( "opacity", el.from.opacity ); | |
18062 } | |
18063 if( mode === "hide" ) { | |
18064 el.hide(); | |
18065 } | |
18066 $.effects.restore( el, props ); | |
18067 if ( !restore ) { | |
18068 | |
18069 // we need to calculate our new positioning based on the scaling | |
18070 if ( position === "static" ) { | |
18071 el.css({ | |
18072 position: "relative", | |
18073 top: el.to.top, | |
18074 left: el.to.left | |
18075 }); | |
18076 } else { | |
18077 $.each([ "top", "left" ], function( idx, pos ) { | |
18078 el.css( pos, function( _, str ) { | |
18079 var val = parseInt( str, 10 ), | |
18080 toRef = idx ? el.to.left : el.to.top; | |
18081 | |
18082 // if original was "auto", recalculate the new value from wrapper | |
18083 if ( str === "auto" ) { | |
18084 return toRef + "px"; | |
18085 } | |
18086 | |
18087 return val + toRef + "px"; | |
18088 }); | |
18089 }); | |
18090 } | |
18091 } | |
18092 | |
18093 $.effects.removeWrapper( el ); | |
18094 done(); | |
18095 } | |
18096 }); | |
18097 | |
18098 }; | |
18099 | |
18100 })(jQuery); | |
18101 (function( $, undefined ) { | |
18102 | |
18103 $.effects.effect.shake = function( o, done ) { | |
18104 | |
18105 var el = $( this ), | |
18106 props = [ "position", "top", "bottom", "left", "right", "height", "width" ], | |
18107 mode = $.effects.setMode( el, o.mode || "effect" ), | |
18108 direction = o.direction || "left", | |
18109 distance = o.distance || 20, | |
18110 times = o.times || 3, | |
18111 anims = times * 2 + 1, | |
18112 speed = Math.round(o.duration/anims), | |
18113 ref = (direction === "up" || direction === "down") ? "top" : "left", | |
18114 positiveMotion = (direction === "up" || direction === "left"), | |
18115 animation = {}, | |
18116 animation1 = {}, | |
18117 animation2 = {}, | |
18118 i, | |
18119 | |
18120 // we will need to re-assemble the queue to stack our animations in place | |
18121 queue = el.queue(), | |
18122 queuelen = queue.length; | |
18123 | |
18124 $.effects.save( el, props ); | |
18125 el.show(); | |
18126 $.effects.createWrapper( el ); | |
18127 | |
18128 // Animation | |
18129 animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; | |
18130 animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; | |
18131 animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; | |
18132 | |
18133 // Animate | |
18134 el.animate( animation, speed, o.easing ); | |
18135 | |
18136 // Shakes | |
18137 for ( i = 1; i < times; i++ ) { | |
18138 el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing ); | |
18139 } | |
18140 el | |
18141 .animate( animation1, speed, o.easing ) | |
18142 .animate( animation, speed / 2, o.easing ) | |
18143 .queue(function() { | |
18144 if ( mode === "hide" ) { | |
18145 el.hide(); | |
18146 } | |
18147 $.effects.restore( el, props ); | |
18148 $.effects.removeWrapper( el ); | |
18149 done(); | |
18150 }); | |
18151 | |
18152 // inject all the animations we just queued to be first in line (after "inprogress") | |
18153 if ( queuelen > 1) { | |
18154 queue.splice.apply( queue, | |
18155 [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) ); | |
18156 } | |
18157 el.dequeue(); | |
18158 | |
18159 }; | |
18160 | |
18161 })(jQuery); | |
18162 (function( $, undefined ) { | |
18163 | |
18164 $.effects.effect.slide = function( o, done ) { | |
18165 | |
18166 // Create element | |
18167 var el = $( this ), | |
18168 props = [ "position", "top", "bottom", "left", "right", "width", "height" ], | |
18169 mode = $.effects.setMode( el, o.mode || "show" ), | |
18170 show = mode === "show", | |
18171 direction = o.direction || "left", | |
18172 ref = (direction === "up" || direction === "down") ? "top" : "left", | |
18173 positiveMotion = (direction === "up" || direction === "left"), | |
18174 distance, | |
18175 animation = {}; | |
18176 | |
18177 // Adjust | |
18178 $.effects.save( el, props ); | |
18179 el.show(); | |
18180 distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ); | |
18181 | |
18182 $.effects.createWrapper( el ).css({ | |
18183 overflow: "hidden" | |
18184 }); | |
18185 | |
18186 if ( show ) { | |
18187 el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance ); | |
18188 } | |
18189 | |
18190 // Animation | |
18191 animation[ ref ] = ( show ? | |
18192 ( positiveMotion ? "+=" : "-=") : | |
18193 ( positiveMotion ? "-=" : "+=")) + | |
18194 distance; | |
18195 | |
18196 // Animate | |
18197 el.animate( animation, { | |
18198 queue: false, | |
18199 duration: o.duration, | |
18200 easing: o.easing, | |
18201 complete: function() { | |
18202 if ( mode === "hide" ) { | |
18203 el.hide(); | |
18204 } | |
18205 $.effects.restore( el, props ); | |
18206 $.effects.removeWrapper( el ); | |
18207 done(); | |
18208 } | |
18209 }); | |
18210 }; | |
18211 | |
18212 })(jQuery); | |
18213 (function( $, undefined ) { | |
18214 | |
18215 $.effects.effect.transfer = function( o, done ) { | |
18216 var elem = $( this ), | |
18217 target = $( o.to ), | |
18218 targetFixed = target.css( "position" ) === "fixed", | |
18219 body = $("body"), | |
18220 fixTop = targetFixed ? body.scrollTop() : 0, | |
18221 fixLeft = targetFixed ? body.scrollLeft() : 0, | |
18222 endPosition = target.offset(), | |
18223 animation = { | |
18224 top: endPosition.top - fixTop , | |
18225 left: endPosition.left - fixLeft , | |
18226 height: target.innerHeight(), | |
18227 width: target.innerWidth() | |
18228 }, | |
18229 startPosition = elem.offset(), | |
18230 transfer = $( "<div class='ui-effects-transfer'></div>" ) | |
18231 .appendTo( document.body ) | |
18232 .addClass( o.className ) | |
18233 .css({ | |
18234 top: startPosition.top - fixTop , | |
18235 left: startPosition.left - fixLeft , | |
18236 height: elem.innerHeight(), | |
18237 width: elem.innerWidth(), | |
18238 position: targetFixed ? "fixed" : "absolute" | |
18239 }) | |
18240 .animate( animation, o.duration, o.easing, function() { | |
18241 transfer.remove(); | |
18242 done(); | |
18243 }); | |
18244 }; | |
18245 | |
18246 })(jQuery); | |
18247 /** | |
18248 | |
18249 JSZip - A Javascript class for generating and reading zip files | |
18250 <http://stuartk.com/jszip> | |
18251 | |
18252 (c) 2009-2012 Stuart Knightley <stuart [at] stuartk.com> | |
18253 Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. | |
18254 | |
18255 Usage: | |
18256 zip = new JSZip(); | |
18257 zip.file("hello.txt", "Hello, World!").add("tempfile", "nothing"); | |
18258 zip.folder("images").file("smile.gif", base64Data, {base64: true}); | |
18259 zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")}); | |
18260 zip.remove("tempfile"); | |
18261 | |
18262 base64zip = zip.generate(); | |
18263 | |
18264 **/ | |
18265 | |
18266 /** | |
18267 * Representation a of zip file in js | |
18268 * @constructor | |
18269 * @param {String=|ArrayBuffer=|Uint8Array=} data the data to load, if any (optional). | |
18270 * @param {Object=} options the options for creating this objects (optional). | |
18271 */ | |
18272 var JSZip = function(data, options) { | |
18273 // object containing the files : | |
18274 // { | |
18275 // "folder/" : {...}, | |
18276 // "folder/data.txt" : {...} | |
18277 // } | |
18278 this.files = {}; | |
18279 | |
18280 // Where we are in the hierarchy | |
18281 this.root = ""; | |
18282 | |
18283 if (data) { | |
18284 this.load(data, options); | |
18285 } | |
18286 }; | |
18287 | |
18288 JSZip.signature = { | |
18289 LOCAL_FILE_HEADER : "\x50\x4b\x03\x04", | |
18290 CENTRAL_FILE_HEADER : "\x50\x4b\x01\x02", | |
18291 CENTRAL_DIRECTORY_END : "\x50\x4b\x05\x06", | |
18292 ZIP64_CENTRAL_DIRECTORY_LOCATOR : "\x50\x4b\x06\x07", | |
18293 ZIP64_CENTRAL_DIRECTORY_END : "\x50\x4b\x06\x06", | |
18294 DATA_DESCRIPTOR : "\x50\x4b\x07\x08" | |
18295 }; | |
18296 | |
18297 // Default properties for a new file | |
18298 JSZip.defaults = { | |
18299 base64: false, | |
18300 binary: false, | |
18301 dir: false, | |
18302 date: null | |
18303 }; | |
18304 | |
18305 | |
18306 JSZip.prototype = (function () { | |
18307 /** | |
18308 * A simple object representing a file in the zip file. | |
18309 * @constructor | |
18310 * @param {string} name the name of the file | |
18311 * @param {string} data the data | |
18312 * @param {Object} options the options of the file | |
18313 */ | |
18314 var ZipObject = function (name, data, options) { | |
18315 this.name = name; | |
18316 this.data = data; | |
18317 this.options = options; | |
18318 }; | |
18319 | |
18320 ZipObject.prototype = { | |
18321 /** | |
18322 * Return the content as UTF8 string. | |
18323 * @return {string} the UTF8 string. | |
18324 */ | |
18325 asText : function () { | |
18326 var result = this.data; | |
18327 if (result === null || typeof result === "undefined") { | |
18328 return ""; | |
18329 } | |
18330 if (this.options.base64) { | |
18331 result = JSZipBase64.decode(result); | |
18332 } | |
18333 if (this.options.binary) { | |
18334 result = JSZip.prototype.utf8decode(result); | |
18335 } | |
18336 return result; | |
18337 }, | |
18338 /** | |
18339 * Returns the binary content. | |
18340 * @return {string} the content as binary. | |
18341 */ | |
18342 asBinary : function () { | |
18343 var result = this.data; | |
18344 if (result === null || typeof result === "undefined") { | |
18345 return ""; | |
18346 } | |
18347 if (this.options.base64) { | |
18348 result = JSZipBase64.decode(result); | |
18349 } | |
18350 if (!this.options.binary) { | |
18351 result = JSZip.prototype.utf8encode(result); | |
18352 } | |
18353 return result; | |
18354 }, | |
18355 /** | |
18356 * Returns the content as an Uint8Array. | |
18357 * @return {Uint8Array} the content as an Uint8Array. | |
18358 */ | |
18359 asUint8Array : function () { | |
18360 return JSZip.utils.string2Uint8Array(this.asBinary()); | |
18361 }, | |
18362 /** | |
18363 * Returns the content as an ArrayBuffer. | |
18364 * @return {ArrayBuffer} the content as an ArrayBufer. | |
18365 */ | |
18366 asArrayBuffer : function () { | |
18367 return JSZip.utils.string2Uint8Array(this.asBinary()).buffer; | |
18368 } | |
18369 }; | |
18370 | |
18371 /** | |
18372 * Transform an integer into a string in hexadecimal. | |
18373 * @private | |
18374 * @param {number} dec the number to convert. | |
18375 * @param {number} bytes the number of bytes to generate. | |
18376 * @returns {string} the result. | |
18377 */ | |
18378 var decToHex = function(dec, bytes) { | |
18379 var hex = "", i; | |
18380 for(i = 0; i < bytes; i++) { | |
18381 hex += String.fromCharCode(dec&0xff); | |
18382 dec=dec>>>8; | |
18383 } | |
18384 return hex; | |
18385 }; | |
18386 | |
18387 /** | |
18388 * Merge the objects passed as parameters into a new one. | |
18389 * @private | |
18390 * @param {...Object} var_args All objects to merge. | |
18391 * @return {Object} a new object with the data of the others. | |
18392 */ | |
18393 var extend = function () { | |
18394 var result = {}, i, attr; | |
18395 for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers | |
18396 for (attr in arguments[i]) { | |
18397 if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { | |
18398 result[attr] = arguments[i][attr]; | |
18399 } | |
18400 } | |
18401 } | |
18402 return result; | |
18403 }; | |
18404 | |
18405 /** | |
18406 * Transforms the (incomplete) options from the user into the complete | |
18407 * set of options to create a file. | |
18408 * @private | |
18409 * @param {Object} o the options from the user. | |
18410 * @return {Object} the complete set of options. | |
18411 */ | |
18412 var prepareFileAttrs = function (o) { | |
18413 o = o || {}; | |
18414 if (o.base64 === true && o.binary == null) { | |
18415 o.binary = true; | |
18416 } | |
18417 o = extend(o, JSZip.defaults); | |
18418 o.date = o.date || new Date(); | |
18419 | |
18420 return o; | |
18421 }; | |
18422 | |
18423 /** | |
18424 * Add a file in the current folder. | |
18425 * @private | |
18426 * @param {string} name the name of the file | |
18427 * @param {String|ArrayBuffer|Uint8Array} data the data of the file | |
18428 * @param {Object} o the options of the file | |
18429 * @return {Object} the new file. | |
18430 */ | |
18431 var fileAdd = function (name, data, o) { | |
18432 // be sure sub folders exist | |
18433 var parent = parentFolder(name); | |
18434 if (parent) { | |
18435 folderAdd.call(this, parent); | |
18436 } | |
18437 | |
18438 o = prepareFileAttrs(o); | |
18439 | |
18440 if (o.dir || data === null || typeof data === "undefined") { | |
18441 o.base64 = false; | |
18442 o.binary = false; | |
18443 data = null; | |
18444 } else if (JSZip.support.uint8array && data instanceof Uint8Array) { | |
18445 o.base64 = false; | |
18446 o.binary = true; | |
18447 data = JSZip.utils.uint8Array2String(data); | |
18448 } else if (JSZip.support.arraybuffer && data instanceof ArrayBuffer) { | |
18449 o.base64 = false; | |
18450 o.binary = true; | |
18451 var bufferView = new Uint8Array(data); | |
18452 data = JSZip.utils.uint8Array2String(bufferView); | |
18453 } else if (o.binary && !o.base64) { | |
18454 // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask | |
18455 if (o.optimizedBinaryString !== true) { | |
18456 // this is a string, not in a base64 format. | |
18457 // Be sure that this is a correct "binary string" | |
18458 data = JSZip.utils.string2binary(data); | |
18459 } | |
18460 // we remove this option since it's only relevant here | |
18461 delete o.optimizedBinaryString; | |
18462 } | |
18463 | |
18464 return this.files[name] = new ZipObject(name, data, o); | |
18465 }; | |
18466 | |
18467 | |
18468 /** | |
18469 * Find the parent folder of the path. | |
18470 * @private | |
18471 * @param {string} path the path to use | |
18472 * @return {string} the parent folder, or "" | |
18473 */ | |
18474 var parentFolder = function (path) { | |
18475 if (path.slice(-1) == '/') { | |
18476 path = path.substring(0, path.length - 1); | |
18477 } | |
18478 var lastSlash = path.lastIndexOf('/'); | |
18479 return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; | |
18480 }; | |
18481 | |
18482 /** | |
18483 * Add a (sub) folder in the current folder. | |
18484 * @private | |
18485 * @param {string} name the folder's name | |
18486 * @return {Object} the new folder. | |
18487 */ | |
18488 var folderAdd = function (name) { | |
18489 // Check the name ends with a / | |
18490 if (name.slice(-1) != "/") { | |
18491 name += "/"; // IE doesn't like substr(-1) | |
18492 } | |
18493 | |
18494 // Does this folder already exist? | |
18495 if (!this.files[name]) { | |
18496 // be sure sub folders exist | |
18497 var parent = parentFolder(name); | |
18498 if (parent) { | |
18499 folderAdd.call(this, parent); | |
18500 } | |
18501 | |
18502 fileAdd.call(this, name, null, {dir:true}); | |
18503 } | |
18504 return this.files[name]; | |
18505 }; | |
18506 | |
18507 /** | |
18508 * Generate the data found in the local header of a zip file. | |
18509 * Do not create it now, as some parts are re-used later. | |
18510 * @private | |
18511 * @param {Object} file the file to use. | |
18512 * @param {string} utfEncodedFileName the file name, utf8 encoded. | |
18513 * @param {string} compressionType the compression to use. | |
18514 * @return {Object} an object containing header and compressedData. | |
18515 */ | |
18516 var prepareLocalHeaderData = function(file, utfEncodedFileName, compressionType) { | |
18517 var useUTF8 = utfEncodedFileName !== file.name, | |
18518 data = file.asBinary(), | |
18519 o = file.options, | |
18520 dosTime, | |
18521 dosDate; | |
18522 | |
18523 // date | |
18524 // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html | |
18525 // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html | |
18526 // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html | |
18527 | |
18528 dosTime = o.date.getHours(); | |
18529 dosTime = dosTime << 6; | |
18530 dosTime = dosTime | o.date.getMinutes(); | |
18531 dosTime = dosTime << 5; | |
18532 dosTime = dosTime | o.date.getSeconds() / 2; | |
18533 | |
18534 dosDate = o.date.getFullYear() - 1980; | |
18535 dosDate = dosDate << 4; | |
18536 dosDate = dosDate | (o.date.getMonth() + 1); | |
18537 dosDate = dosDate << 5; | |
18538 dosDate = dosDate | o.date.getDate(); | |
18539 | |
18540 var hasData = data !== null && data.length !== 0; | |
18541 | |
18542 var compression = JSZip.compressions[compressionType]; | |
18543 var compressedData = hasData ? compression.compress(data) : ''; | |
18544 | |
18545 var header = ""; | |
18546 | |
18547 // version needed to extract | |
18548 header += "\x0A\x00"; | |
18549 // general purpose bit flag | |
18550 // set bit 11 if utf8 | |
18551 header += useUTF8 ? "\x00\x08" : "\x00\x00"; | |
18552 // compression method | |
18553 header += hasData ? compression.magic : JSZip.compressions['STORE'].magic; | |
18554 // last mod file time | |
18555 header += decToHex(dosTime, 2); | |
18556 // last mod file date | |
18557 header += decToHex(dosDate, 2); | |
18558 // crc-32 | |
18559 header += hasData ? decToHex(this.crc32(data), 4) : '\x00\x00\x00\x00'; | |
18560 // compressed size | |
18561 header += hasData ? decToHex(compressedData.length, 4) : '\x00\x00\x00\x00'; | |
18562 // uncompressed size | |
18563 header += hasData ? decToHex(data.length, 4) : '\x00\x00\x00\x00'; | |
18564 // file name length | |
18565 header += decToHex(utfEncodedFileName.length, 2); | |
18566 // extra field length | |
18567 header += "\x00\x00"; | |
18568 | |
18569 return { | |
18570 header:header, | |
18571 compressedData:compressedData | |
18572 }; | |
18573 }; | |
18574 | |
18575 | |
18576 // return the actual prototype of JSZip | |
18577 return { | |
18578 /** | |
18579 * Read an existing zip and merge the data in the current JSZip object. | |
18580 * The implementation is in jszip-load.js, don't forget to include it. | |
18581 * @param {String|ArrayBuffer|Uint8Array} stream The stream to load | |
18582 * @param {Object} options Options for loading the stream. | |
18583 * options.base64 : is the stream in base64 ? default : false | |
18584 * @return {JSZip} the current JSZip object | |
18585 */ | |
18586 load : function (stream, options) { | |
18587 throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); | |
18588 }, | |
18589 | |
18590 /** | |
18591 * Filter nested files/folders with the specified function. | |
18592 * @param {Function} search the predicate to use : | |
18593 * function (relativePath, file) {...} | |
18594 * It takes 2 arguments : the relative path and the file. | |
18595 * @return {Array} An array of matching elements. | |
18596 */ | |
18597 filter : function (search) { | |
18598 var result = [], filename, relativePath, file, fileClone; | |
18599 for (filename in this.files) { | |
18600 if ( !this.files.hasOwnProperty(filename) ) { continue; } | |
18601 file = this.files[filename]; | |
18602 // return a new object, don't let the user mess with our internal objects :) | |
18603 fileClone = new ZipObject(file.name, file.data, extend(file.options)); | |
18604 relativePath = filename.slice(this.root.length, filename.length); | |
18605 if (filename.slice(0, this.root.length) === this.root && // the file is in the current root | |
18606 search(relativePath, fileClone)) { // and the file matches the function | |
18607 result.push(fileClone); | |
18608 } | |
18609 } | |
18610 return result; | |
18611 }, | |
18612 | |
18613 /** | |
18614 * Add a file to the zip file, or search a file. | |
18615 * @param {string|RegExp} name The name of the file to add (if data is defined), | |
18616 * the name of the file to find (if no data) or a regex to match files. | |
18617 * @param {String|ArrayBuffer|Uint8Array} data The file data, either raw or base64 encoded | |
18618 * @param {Object} o File options | |
18619 * @return {JSZip|Object|Array} this JSZip object (when adding a file), | |
18620 * a file (when searching by string) or an array of files (when searching by regex). | |
18621 */ | |
18622 file : function(name, data, o) { | |
18623 if (arguments.length === 1) { | |
18624 if (name instanceof RegExp) { | |
18625 var regexp = name; | |
18626 return this.filter(function(relativePath, file) { | |
18627 return !file.options.dir && regexp.test(relativePath); | |
18628 }); | |
18629 } else { // text | |
18630 return this.filter(function (relativePath, file) { | |
18631 return !file.options.dir && relativePath === name; | |
18632 })[0]||null; | |
18633 } | |
18634 } else { // more than one argument : we have data ! | |
18635 name = this.root+name; | |
18636 fileAdd.call(this, name, data, o); | |
18637 } | |
18638 return this; | |
18639 }, | |
18640 | |
18641 /** | |
18642 * Add a directory to the zip file, or search. | |
18643 * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. | |
18644 * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. | |
18645 */ | |
18646 folder : function(arg) { | |
18647 if (!arg) { | |
18648 return this; | |
18649 } | |
18650 | |
18651 if (arg instanceof RegExp) { | |
18652 return this.filter(function(relativePath, file) { | |
18653 return file.options.dir && arg.test(relativePath); | |
18654 }); | |
18655 } | |
18656 | |
18657 // else, name is a new folder | |
18658 var name = this.root + arg; | |
18659 var newFolder = folderAdd.call(this, name); | |
18660 | |
18661 // Allow chaining by returning a new object with this folder as the root | |
18662 var ret = this.clone(); | |
18663 ret.root = newFolder.name; | |
18664 return ret; | |
18665 }, | |
18666 | |
18667 /** | |
18668 * Delete a file, or a directory and all sub-files, from the zip | |
18669 * @param {string} name the name of the file to delete | |
18670 * @return {JSZip} this JSZip object | |
18671 */ | |
18672 remove : function(name) { | |
18673 name = this.root + name; | |
18674 var file = this.files[name]; | |
18675 if (!file) { | |
18676 // Look for any folders | |
18677 if (name.slice(-1) != "/") { | |
18678 name += "/"; | |
18679 } | |
18680 file = this.files[name]; | |
18681 } | |
18682 | |
18683 if (file) { | |
18684 if (!file.options.dir) { | |
18685 // file | |
18686 delete this.files[name]; | |
18687 } else { | |
18688 // folder | |
18689 var kids = this.filter(function (relativePath, file) { | |
18690 return file.name.slice(0, name.length) === name; | |
18691 }); | |
18692 for (var i = 0; i < kids.length; i++) { | |
18693 delete this.files[kids[i].name]; | |
18694 } | |
18695 } | |
18696 } | |
18697 | |
18698 return this; | |
18699 }, | |
18700 | |
18701 /** | |
18702 * Generate the complete zip file | |
18703 * @param {Object} options the options to generate the zip file : | |
18704 * - base64, (deprecated, use type instead) true to generate base64. | |
18705 * - compression, "STORE" by default. | |
18706 * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. | |
18707 * @return {String|Uint8Array|ArrayBuffer|Blob} the zip file | |
18708 */ | |
18709 generate : function(options) { | |
18710 options = extend(options || {}, { | |
18711 base64 : true, | |
18712 compression : "STORE", | |
18713 type : "base64" | |
18714 }); | |
18715 var compression = options.compression.toUpperCase(); | |
18716 | |
18717 // The central directory, and files data | |
18718 var directory = [], files = [], fileOffset = 0; | |
18719 | |
18720 if (!JSZip.compressions[compression]) { | |
18721 throw compression + " is not a valid compression method !"; | |
18722 } | |
18723 | |
18724 for (var name in this.files) { | |
18725 if ( !this.files.hasOwnProperty(name) ) { continue; } | |
18726 | |
18727 var file = this.files[name]; | |
18728 | |
18729 var utfEncodedFileName = this.utf8encode(file.name); | |
18730 | |
18731 var fileRecord = "", | |
18732 dirRecord = "", | |
18733 data = prepareLocalHeaderData.call(this, file, utfEncodedFileName, compression); | |
18734 fileRecord = JSZip.signature.LOCAL_FILE_HEADER + data.header + utfEncodedFileName + data.compressedData; | |
18735 | |
18736 dirRecord = JSZip.signature.CENTRAL_FILE_HEADER + | |
18737 // version made by (00: DOS) | |
18738 "\x14\x00" + | |
18739 // file header (common to file and central directory) | |
18740 data.header + | |
18741 // file comment length | |
18742 "\x00\x00" + | |
18743 // disk number start | |
18744 "\x00\x00" + | |
18745 // internal file attributes TODO | |
18746 "\x00\x00" + | |
18747 // external file attributes | |
18748 (this.files[name].options.dir===true?"\x10\x00\x00\x00":"\x00\x00\x00\x00")+ | |
18749 // relative offset of local header | |
18750 decToHex(fileOffset, 4) + | |
18751 // file name | |
18752 utfEncodedFileName; | |
18753 | |
18754 fileOffset += fileRecord.length; | |
18755 | |
18756 files.push(fileRecord); | |
18757 directory.push(dirRecord); | |
18758 } | |
18759 | |
18760 var fileData = files.join(""); | |
18761 var dirData = directory.join(""); | |
18762 | |
18763 var dirEnd = ""; | |
18764 | |
18765 // end of central dir signature | |
18766 dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END + | |
18767 // number of this disk | |
18768 "\x00\x00" + | |
18769 // number of the disk with the start of the central directory | |
18770 "\x00\x00" + | |
18771 // total number of entries in the central directory on this disk | |
18772 decToHex(files.length, 2) + | |
18773 // total number of entries in the central directory | |
18774 decToHex(files.length, 2) + | |
18775 // size of the central directory 4 bytes | |
18776 decToHex(dirData.length, 4) + | |
18777 // offset of start of central directory with respect to the starting disk number | |
18778 decToHex(fileData.length, 4) + | |
18779 // .ZIP file comment length | |
18780 "\x00\x00"; | |
18781 | |
18782 var zip = fileData + dirData + dirEnd; | |
18783 | |
18784 | |
18785 switch(options.type.toLowerCase()) { | |
18786 case "uint8array" : | |
18787 return JSZip.utils.string2Uint8Array(zip); | |
18788 case "arraybuffer" : | |
18789 return JSZip.utils.string2Uint8Array(zip).buffer; | |
18790 case "blob" : | |
18791 return JSZip.utils.string2Blob(zip); | |
18792 case "base64" : | |
18793 return (options.base64) ? JSZipBase64.encode(zip) : zip; | |
18794 default : // case "string" : | |
18795 return zip; | |
18796 } | |
18797 }, | |
18798 | |
18799 /** | |
18800 * | |
18801 * Javascript crc32 | |
18802 * http://www.webtoolkit.info/ | |
18803 * | |
18804 */ | |
18805 crc32 : function(str, crc) { | |
18806 | |
18807 if (str === "" || typeof str === "undefined") { | |
18808 return 0; | |
18809 } | |
18810 | |
18811 var table = [ | |
18812 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, | |
18813 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, | |
18814 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, | |
18815 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, | |
18816 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, | |
18817 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, | |
18818 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, | |
18819 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, | |
18820 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, | |
18821 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, | |
18822 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, | |
18823 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, | |
18824 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, | |
18825 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, | |
18826 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, | |
18827 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, | |
18828 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, | |
18829 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, | |
18830 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, | |
18831 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, | |
18832 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, | |
18833 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, | |
18834 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, | |
18835 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, | |
18836 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, | |
18837 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, | |
18838 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, | |
18839 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, | |
18840 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, | |
18841 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, | |
18842 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, | |
18843 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, | |
18844 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, | |
18845 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, | |
18846 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, | |
18847 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, | |
18848 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, | |
18849 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, | |
18850 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, | |
18851 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, | |
18852 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, | |
18853 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, | |
18854 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, | |
18855 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, | |
18856 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, | |
18857 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, | |
18858 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, | |
18859 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, | |
18860 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, | |
18861 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, | |
18862 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, | |
18863 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, | |
18864 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, | |
18865 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, | |
18866 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, | |
18867 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, | |
18868 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, | |
18869 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, | |
18870 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, | |
18871 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, | |
18872 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, | |
18873 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, | |
18874 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, | |
18875 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D | |
18876 ]; | |
18877 | |
18878 if (typeof(crc) == "undefined") { crc = 0; } | |
18879 var x = 0; | |
18880 var y = 0; | |
18881 | |
18882 crc = crc ^ (-1); | |
18883 for( var i = 0, iTop = str.length; i < iTop; i++ ) { | |
18884 y = ( crc ^ str.charCodeAt( i ) ) & 0xFF; | |
18885 x = table[y]; | |
18886 crc = ( crc >>> 8 ) ^ x; | |
18887 } | |
18888 | |
18889 return crc ^ (-1); | |
18890 }, | |
18891 | |
18892 // Inspired by http://my.opera.com/GreyWyvern/blog/show.dml/1725165 | |
18893 clone : function() { | |
18894 var newObj = new JSZip(); | |
18895 for (var i in this) { | |
18896 if (typeof this[i] !== "function") { | |
18897 newObj[i] = this[i]; | |
18898 } | |
18899 } | |
18900 return newObj; | |
18901 }, | |
18902 | |
18903 | |
18904 /** | |
18905 * http://www.webtoolkit.info/javascript-utf8.html | |
18906 */ | |
18907 utf8encode : function (string) { | |
18908 string = string.replace(/\r\n/g,"\n"); | |
18909 var utftext = ""; | |
18910 | |
18911 for (var n = 0; n < string.length; n++) { | |
18912 | |
18913 var c = string.charCodeAt(n); | |
18914 | |
18915 if (c < 128) { | |
18916 utftext += String.fromCharCode(c); | |
18917 } else if ((c > 127) && (c < 2048)) { | |
18918 utftext += String.fromCharCode((c >> 6) | 192); | |
18919 utftext += String.fromCharCode((c & 63) | 128); | |
18920 } else { | |
18921 utftext += String.fromCharCode((c >> 12) | 224); | |
18922 utftext += String.fromCharCode(((c >> 6) & 63) | 128); | |
18923 utftext += String.fromCharCode((c & 63) | 128); | |
18924 } | |
18925 | |
18926 } | |
18927 | |
18928 return utftext; | |
18929 }, | |
18930 | |
18931 /** | |
18932 * http://www.webtoolkit.info/javascript-utf8.html | |
18933 */ | |
18934 utf8decode : function (utftext) { | |
18935 var string = ""; | |
18936 var i = 0; | |
18937 var c = 0, c1 = 0, c2 = 0, c3 = 0; | |
18938 | |
18939 while ( i < utftext.length ) { | |
18940 | |
18941 c = utftext.charCodeAt(i); | |
18942 | |
18943 if (c < 128) { | |
18944 string += String.fromCharCode(c); | |
18945 i++; | |
18946 } else if ((c > 191) && (c < 224)) { | |
18947 c2 = utftext.charCodeAt(i+1); | |
18948 string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); | |
18949 i += 2; | |
18950 } else { | |
18951 c2 = utftext.charCodeAt(i+1); | |
18952 c3 = utftext.charCodeAt(i+2); | |
18953 string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); | |
18954 i += 3; | |
18955 } | |
18956 | |
18957 } | |
18958 | |
18959 return string; | |
18960 } | |
18961 }; | |
18962 }()); | |
18963 | |
18964 /* | |
18965 * Compression methods | |
18966 * This object is filled in as follow : | |
18967 * name : { | |
18968 * magic // the 2 bytes indentifying the compression method | |
18969 * compress // function, take the uncompressed content and return it compressed. | |
18970 * uncompress // function, take the compressed content and return it uncompressed. | |
18971 * } | |
18972 * | |
18973 * STORE is the default compression method, so it's included in this file. | |
18974 * Other methods should go to separated files : the user wants modularity. | |
18975 */ | |
18976 JSZip.compressions = { | |
18977 "STORE" : { | |
18978 magic : "\x00\x00", | |
18979 compress : function (content) { | |
18980 return content; // no compression | |
18981 }, | |
18982 uncompress : function (content) { | |
18983 return content; // no compression | |
18984 } | |
18985 } | |
18986 }; | |
18987 | |
18988 /* | |
18989 * List features that require a modern browser, and if the current browser support them. | |
18990 */ | |
18991 JSZip.support = { | |
18992 // contains true if JSZip can read/generate ArrayBuffer, false otherwise. | |
18993 arraybuffer : (function(){ | |
18994 return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; | |
18995 })(), | |
18996 // contains true if JSZip can read/generate Uint8Array, false otherwise. | |
18997 uint8array : (function(){ | |
18998 return typeof Uint8Array !== "undefined"; | |
18999 })(), | |
19000 // contains true if JSZip can read/generate Blob, false otherwise. | |
19001 blob : (function(){ | |
19002 // the spec started with BlobBuilder then replaced it with a construtor for Blob. | |
19003 // Result : we have browsers that : | |
19004 // * know the BlobBuilder (but with prefix) | |
19005 // * know the Blob constructor | |
19006 // * know about Blob but not about how to build them | |
19007 // About the "=== 0" test : if given the wrong type, it may be converted to a string. | |
19008 // Instead of an empty content, we will get "[object Uint8Array]" for example. | |
19009 if (typeof ArrayBuffer === "undefined") { | |
19010 return false; | |
19011 } | |
19012 var buffer = new ArrayBuffer(0); | |
19013 try { | |
19014 return new Blob([buffer], { type: "application/zip" }).size === 0; | |
19015 } | |
19016 catch(e) {} | |
19017 | |
19018 try { | |
19019 var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || | |
19020 window.MozBlobBuilder || window.MSBlobBuilder)(); | |
19021 builder.append(buffer); | |
19022 return builder.getBlob('application/zip').size === 0; | |
19023 } | |
19024 catch(e) {} | |
19025 | |
19026 return false; | |
19027 })() | |
19028 }; | |
19029 | |
19030 JSZip.utils = { | |
19031 /** | |
19032 * Convert a string to a "binary string" : a string containing only char codes between 0 and 255. | |
19033 * @param {string} str the string to transform. | |
19034 * @return {String} the binary string. | |
19035 */ | |
19036 string2binary : function (str) { | |
19037 var result = ""; | |
19038 for (var i = 0; i < str.length; i++) { | |
19039 result += String.fromCharCode(str.charCodeAt(i) & 0xff); | |
19040 } | |
19041 return result; | |
19042 }, | |
19043 /** | |
19044 * Create a Uint8Array from the string. | |
19045 * @param {string} str the string to transform. | |
19046 * @return {Uint8Array} the typed array. | |
19047 * @throws {Error} an Error if the browser doesn't support the requested feature. | |
19048 */ | |
19049 string2Uint8Array : function (str) { | |
19050 if (!JSZip.support.uint8array) { | |
19051 throw new Error("Uint8Array is not supported by this browser"); | |
19052 } | |
19053 var buffer = new ArrayBuffer(str.length); | |
19054 var bufferView = new Uint8Array(buffer); | |
19055 for(var i = 0; i < str.length; i++) { | |
19056 bufferView[i] = str.charCodeAt(i); | |
19057 } | |
19058 | |
19059 return bufferView; | |
19060 }, | |
19061 | |
19062 /** | |
19063 * Create a string from the Uint8Array. | |
19064 * @param {Uint8Array} array the array to transform. | |
19065 * @return {string} the string. | |
19066 * @throws {Error} an Error if the browser doesn't support the requested feature. | |
19067 */ | |
19068 uint8Array2String : function (array) { | |
19069 if (!JSZip.support.uint8array) { | |
19070 throw new Error("Uint8Array is not supported by this browser"); | |
19071 } | |
19072 var result = ""; | |
19073 for(var i = 0; i < array.length; i++) { | |
19074 result += String.fromCharCode(array[i]); | |
19075 } | |
19076 | |
19077 return result; | |
19078 }, | |
19079 /** | |
19080 * Create a blob from the given string. | |
19081 * @param {string} str the string to transform. | |
19082 * @return {Blob} the string. | |
19083 * @throws {Error} an Error if the browser doesn't support the requested feature. | |
19084 */ | |
19085 string2Blob : function (str) { | |
19086 if (!JSZip.support.blob) { | |
19087 throw new Error("Blob is not supported by this browser"); | |
19088 } | |
19089 | |
19090 var buffer = JSZip.utils.string2Uint8Array(str).buffer; | |
19091 try { | |
19092 // Blob constructor | |
19093 return new Blob([buffer], { type: "application/zip" }); | |
19094 } | |
19095 catch(e) {} | |
19096 | |
19097 try { | |
19098 // deprecated, browser only, old way | |
19099 var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || | |
19100 window.MozBlobBuilder || window.MSBlobBuilder)(); | |
19101 builder.append(buffer); | |
19102 return builder.getBlob('application/zip'); | |
19103 } | |
19104 catch(e) {} | |
19105 | |
19106 // well, fuck ?! | |
19107 throw new Error("Bug : can't construct the Blob."); | |
19108 } | |
19109 }; | |
19110 | |
19111 /** | |
19112 * | |
19113 * Base64 encode / decode | |
19114 * http://www.webtoolkit.info/ | |
19115 * | |
19116 * Hacked so that it doesn't utf8 en/decode everything | |
19117 **/ | |
19118 var JSZipBase64 = (function() { | |
19119 // private property | |
19120 var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; | |
19121 | |
19122 return { | |
19123 // public method for encoding | |
19124 encode : function(input, utf8) { | |
19125 var output = ""; | |
19126 var chr1, chr2, chr3, enc1, enc2, enc3, enc4; | |
19127 var i = 0; | |
19128 | |
19129 while (i < input.length) { | |
19130 | |
19131 chr1 = input.charCodeAt(i++); | |
19132 chr2 = input.charCodeAt(i++); | |
19133 chr3 = input.charCodeAt(i++); | |
19134 | |
19135 enc1 = chr1 >> 2; | |
19136 enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); | |
19137 enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); | |
19138 enc4 = chr3 & 63; | |
19139 | |
19140 if (isNaN(chr2)) { | |
19141 enc3 = enc4 = 64; | |
19142 } else if (isNaN(chr3)) { | |
19143 enc4 = 64; | |
19144 } | |
19145 | |
19146 output = output + | |
19147 _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + | |
19148 _keyStr.charAt(enc3) + _keyStr.charAt(enc4); | |
19149 | |
19150 } | |
19151 | |
19152 return output; | |
19153 }, | |
19154 | |
19155 // public method for decoding | |
19156 decode : function(input, utf8) { | |
19157 var output = ""; | |
19158 var chr1, chr2, chr3; | |
19159 var enc1, enc2, enc3, enc4; | |
19160 var i = 0; | |
19161 | |
19162 input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); | |
19163 | |
19164 while (i < input.length) { | |
19165 | |
19166 enc1 = _keyStr.indexOf(input.charAt(i++)); | |
19167 enc2 = _keyStr.indexOf(input.charAt(i++)); | |
19168 enc3 = _keyStr.indexOf(input.charAt(i++)); | |
19169 enc4 = _keyStr.indexOf(input.charAt(i++)); | |
19170 | |
19171 chr1 = (enc1 << 2) | (enc2 >> 4); | |
19172 chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); | |
19173 chr3 = ((enc3 & 3) << 6) | enc4; | |
19174 | |
19175 output = output + String.fromCharCode(chr1); | |
19176 | |
19177 if (enc3 != 64) { | |
19178 output = output + String.fromCharCode(chr2); | |
19179 } | |
19180 if (enc4 != 64) { | |
19181 output = output + String.fromCharCode(chr3); | |
19182 } | |
19183 | |
19184 } | |
19185 | |
19186 return output; | |
19187 | |
19188 } | |
19189 }; | |
19190 }()); | |
19191 | |
19192 // enforcing Stuk's coding style | |
19193 // vim: set shiftwidth=3 softtabstop=3: | |
19194 /* | |
19195 * Port of a script by Masanao Izumo. | |
19196 * | |
19197 * Only changes : wrap all the variables in a function and add the | |
19198 * main function to JSZip (DEFLATE compression method). | |
19199 * Everything else was written by M. Izumo. | |
19200 * | |
19201 * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt | |
19202 */ | |
19203 | |
19204 if(!JSZip) { | |
19205 throw "JSZip not defined"; | |
19206 } | |
19207 | |
19208 /* | |
19209 * Original: | |
19210 * http://www.onicos.com/staff/iz/amuse/javascript/expert/deflate.txt | |
19211 */ | |
19212 | |
19213 (function(){ | |
19214 | |
19215 /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp> | |
19216 * Version: 1.0.1 | |
19217 * LastModified: Dec 25 1999 | |
19218 */ | |
19219 | |
19220 /* Interface: | |
19221 * data = zip_deflate(src); | |
19222 */ | |
19223 | |
19224 /* constant parameters */ | |
19225 var zip_WSIZE = 32768; // Sliding Window size | |
19226 var zip_STORED_BLOCK = 0; | |
19227 var zip_STATIC_TREES = 1; | |
19228 var zip_DYN_TREES = 2; | |
19229 | |
19230 /* for deflate */ | |
19231 var zip_DEFAULT_LEVEL = 6; | |
19232 var zip_FULL_SEARCH = true; | |
19233 var zip_INBUFSIZ = 32768; // Input buffer size | |
19234 var zip_INBUF_EXTRA = 64; // Extra buffer | |
19235 var zip_OUTBUFSIZ = 1024 * 8; | |
19236 var zip_window_size = 2 * zip_WSIZE; | |
19237 var zip_MIN_MATCH = 3; | |
19238 var zip_MAX_MATCH = 258; | |
19239 var zip_BITS = 16; | |
19240 // for SMALL_MEM | |
19241 var zip_LIT_BUFSIZE = 0x2000; | |
19242 var zip_HASH_BITS = 13; | |
19243 // for MEDIUM_MEM | |
19244 // var zip_LIT_BUFSIZE = 0x4000; | |
19245 // var zip_HASH_BITS = 14; | |
19246 // for BIG_MEM | |
19247 // var zip_LIT_BUFSIZE = 0x8000; | |
19248 // var zip_HASH_BITS = 15; | |
19249 if(zip_LIT_BUFSIZE > zip_INBUFSIZ) | |
19250 alert("error: zip_INBUFSIZ is too small"); | |
19251 if((zip_WSIZE<<1) > (1<<zip_BITS)) | |
19252 alert("error: zip_WSIZE is too large"); | |
19253 if(zip_HASH_BITS > zip_BITS-1) | |
19254 alert("error: zip_HASH_BITS is too large"); | |
19255 if(zip_HASH_BITS < 8 || zip_MAX_MATCH != 258) | |
19256 alert("error: Code too clever"); | |
19257 var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE; | |
19258 var zip_HASH_SIZE = 1 << zip_HASH_BITS; | |
19259 var zip_HASH_MASK = zip_HASH_SIZE - 1; | |
19260 var zip_WMASK = zip_WSIZE - 1; | |
19261 var zip_NIL = 0; // Tail of hash chains | |
19262 var zip_TOO_FAR = 4096; | |
19263 var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1; | |
19264 var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD; | |
19265 var zip_SMALLEST = 1; | |
19266 var zip_MAX_BITS = 15; | |
19267 var zip_MAX_BL_BITS = 7; | |
19268 var zip_LENGTH_CODES = 29; | |
19269 var zip_LITERALS =256; | |
19270 var zip_END_BLOCK = 256; | |
19271 var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES; | |
19272 var zip_D_CODES = 30; | |
19273 var zip_BL_CODES = 19; | |
19274 var zip_REP_3_6 = 16; | |
19275 var zip_REPZ_3_10 = 17; | |
19276 var zip_REPZ_11_138 = 18; | |
19277 var zip_HEAP_SIZE = 2 * zip_L_CODES + 1; | |
19278 var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / | |
19279 zip_MIN_MATCH); | |
19280 | |
19281 /* variables */ | |
19282 var zip_free_queue; | |
19283 var zip_qhead, zip_qtail; | |
19284 var zip_initflag; | |
19285 var zip_outbuf = null; | |
19286 var zip_outcnt, zip_outoff; | |
19287 var zip_complete; | |
19288 var zip_window; | |
19289 var zip_d_buf; | |
19290 var zip_l_buf; | |
19291 var zip_prev; | |
19292 var zip_bi_buf; | |
19293 var zip_bi_valid; | |
19294 var zip_block_start; | |
19295 var zip_ins_h; | |
19296 var zip_hash_head; | |
19297 var zip_prev_match; | |
19298 var zip_match_available; | |
19299 var zip_match_length; | |
19300 var zip_prev_length; | |
19301 var zip_strstart; | |
19302 var zip_match_start; | |
19303 var zip_eofile; | |
19304 var zip_lookahead; | |
19305 var zip_max_chain_length; | |
19306 var zip_max_lazy_match; | |
19307 var zip_compr_level; | |
19308 var zip_good_match; | |
19309 var zip_nice_match; | |
19310 var zip_dyn_ltree; | |
19311 var zip_dyn_dtree; | |
19312 var zip_static_ltree; | |
19313 var zip_static_dtree; | |
19314 var zip_bl_tree; | |
19315 var zip_l_desc; | |
19316 var zip_d_desc; | |
19317 var zip_bl_desc; | |
19318 var zip_bl_count; | |
19319 var zip_heap; | |
19320 var zip_heap_len; | |
19321 var zip_heap_max; | |
19322 var zip_depth; | |
19323 var zip_length_code; | |
19324 var zip_dist_code; | |
19325 var zip_base_length; | |
19326 var zip_base_dist; | |
19327 var zip_flag_buf; | |
19328 var zip_last_lit; | |
19329 var zip_last_dist; | |
19330 var zip_last_flags; | |
19331 var zip_flags; | |
19332 var zip_flag_bit; | |
19333 var zip_opt_len; | |
19334 var zip_static_len; | |
19335 var zip_deflate_data; | |
19336 var zip_deflate_pos; | |
19337 | |
19338 /* objects (deflate) */ | |
19339 | |
19340 var zip_DeflateCT = function() { | |
19341 this.fc = 0; // frequency count or bit string | |
19342 this.dl = 0; // father node in Huffman tree or length of bit string | |
19343 } | |
19344 | |
19345 var zip_DeflateTreeDesc = function() { | |
19346 this.dyn_tree = null; // the dynamic tree | |
19347 this.static_tree = null; // corresponding static tree or NULL | |
19348 this.extra_bits = null; // extra bits for each code or NULL | |
19349 this.extra_base = 0; // base index for extra_bits | |
19350 this.elems = 0; // max number of elements in the tree | |
19351 this.max_length = 0; // max bit length for the codes | |
19352 this.max_code = 0; // largest code with non zero frequency | |
19353 } | |
19354 | |
19355 /* Values for max_lazy_match, good_match and max_chain_length, depending on | |
19356 * the desired pack level (0..9). The values given below have been tuned to | |
19357 * exclude worst case performance for pathological files. Better values may be | |
19358 * found for specific files. | |
19359 */ | |
19360 var zip_DeflateConfiguration = function(a, b, c, d) { | |
19361 this.good_length = a; // reduce lazy search above this match length | |
19362 this.max_lazy = b; // do not perform lazy search above this match length | |
19363 this.nice_length = c; // quit search above this match length | |
19364 this.max_chain = d; | |
19365 } | |
19366 | |
19367 var zip_DeflateBuffer = function() { | |
19368 this.next = null; | |
19369 this.len = 0; | |
19370 this.ptr = new Array(zip_OUTBUFSIZ); | |
19371 this.off = 0; | |
19372 } | |
19373 | |
19374 /* constant tables */ | |
19375 var zip_extra_lbits = new Array( | |
19376 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); | |
19377 var zip_extra_dbits = new Array( | |
19378 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); | |
19379 var zip_extra_blbits = new Array( | |
19380 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7); | |
19381 var zip_bl_order = new Array( | |
19382 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15); | |
19383 var zip_configuration_table = new Array( | |
19384 new zip_DeflateConfiguration(0, 0, 0, 0), | |
19385 new zip_DeflateConfiguration(4, 4, 8, 4), | |
19386 new zip_DeflateConfiguration(4, 5, 16, 8), | |
19387 new zip_DeflateConfiguration(4, 6, 32, 32), | |
19388 new zip_DeflateConfiguration(4, 4, 16, 16), | |
19389 new zip_DeflateConfiguration(8, 16, 32, 32), | |
19390 new zip_DeflateConfiguration(8, 16, 128, 128), | |
19391 new zip_DeflateConfiguration(8, 32, 128, 256), | |
19392 new zip_DeflateConfiguration(32, 128, 258, 1024), | |
19393 new zip_DeflateConfiguration(32, 258, 258, 4096)); | |
19394 | |
19395 | |
19396 /* routines (deflate) */ | |
19397 | |
19398 var zip_deflate_start = function(level) { | |
19399 var i; | |
19400 | |
19401 if(!level) | |
19402 level = zip_DEFAULT_LEVEL; | |
19403 else if(level < 1) | |
19404 level = 1; | |
19405 else if(level > 9) | |
19406 level = 9; | |
19407 | |
19408 zip_compr_level = level; | |
19409 zip_initflag = false; | |
19410 zip_eofile = false; | |
19411 if(zip_outbuf != null) | |
19412 return; | |
19413 | |
19414 zip_free_queue = zip_qhead = zip_qtail = null; | |
19415 zip_outbuf = new Array(zip_OUTBUFSIZ); | |
19416 zip_window = new Array(zip_window_size); | |
19417 zip_d_buf = new Array(zip_DIST_BUFSIZE); | |
19418 zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); | |
19419 zip_prev = new Array(1 << zip_BITS); | |
19420 zip_dyn_ltree = new Array(zip_HEAP_SIZE); | |
19421 for(i = 0; i < zip_HEAP_SIZE; i++) | |
19422 zip_dyn_ltree[i] = new zip_DeflateCT(); | |
19423 zip_dyn_dtree = new Array(2*zip_D_CODES+1); | |
19424 for(i = 0; i < 2*zip_D_CODES+1; i++) | |
19425 zip_dyn_dtree[i] = new zip_DeflateCT(); | |
19426 zip_static_ltree = new Array(zip_L_CODES+2); | |
19427 for(i = 0; i < zip_L_CODES+2; i++) | |
19428 zip_static_ltree[i] = new zip_DeflateCT(); | |
19429 zip_static_dtree = new Array(zip_D_CODES); | |
19430 for(i = 0; i < zip_D_CODES; i++) | |
19431 zip_static_dtree[i] = new zip_DeflateCT(); | |
19432 zip_bl_tree = new Array(2*zip_BL_CODES+1); | |
19433 for(i = 0; i < 2*zip_BL_CODES+1; i++) | |
19434 zip_bl_tree[i] = new zip_DeflateCT(); | |
19435 zip_l_desc = new zip_DeflateTreeDesc(); | |
19436 zip_d_desc = new zip_DeflateTreeDesc(); | |
19437 zip_bl_desc = new zip_DeflateTreeDesc(); | |
19438 zip_bl_count = new Array(zip_MAX_BITS+1); | |
19439 zip_heap = new Array(2*zip_L_CODES+1); | |
19440 zip_depth = new Array(2*zip_L_CODES+1); | |
19441 zip_length_code = new Array(zip_MAX_MATCH-zip_MIN_MATCH+1); | |
19442 zip_dist_code = new Array(512); | |
19443 zip_base_length = new Array(zip_LENGTH_CODES); | |
19444 zip_base_dist = new Array(zip_D_CODES); | |
19445 zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8)); | |
19446 } | |
19447 | |
19448 var zip_deflate_end = function() { | |
19449 zip_free_queue = zip_qhead = zip_qtail = null; | |
19450 zip_outbuf = null; | |
19451 zip_window = null; | |
19452 zip_d_buf = null; | |
19453 zip_l_buf = null; | |
19454 zip_prev = null; | |
19455 zip_dyn_ltree = null; | |
19456 zip_dyn_dtree = null; | |
19457 zip_static_ltree = null; | |
19458 zip_static_dtree = null; | |
19459 zip_bl_tree = null; | |
19460 zip_l_desc = null; | |
19461 zip_d_desc = null; | |
19462 zip_bl_desc = null; | |
19463 zip_bl_count = null; | |
19464 zip_heap = null; | |
19465 zip_depth = null; | |
19466 zip_length_code = null; | |
19467 zip_dist_code = null; | |
19468 zip_base_length = null; | |
19469 zip_base_dist = null; | |
19470 zip_flag_buf = null; | |
19471 } | |
19472 | |
19473 var zip_reuse_queue = function(p) { | |
19474 p.next = zip_free_queue; | |
19475 zip_free_queue = p; | |
19476 } | |
19477 | |
19478 var zip_new_queue = function() { | |
19479 var p; | |
19480 | |
19481 if(zip_free_queue != null) | |
19482 { | |
19483 p = zip_free_queue; | |
19484 zip_free_queue = zip_free_queue.next; | |
19485 } | |
19486 else | |
19487 p = new zip_DeflateBuffer(); | |
19488 p.next = null; | |
19489 p.len = p.off = 0; | |
19490 | |
19491 return p; | |
19492 } | |
19493 | |
19494 var zip_head1 = function(i) { | |
19495 return zip_prev[zip_WSIZE + i]; | |
19496 } | |
19497 | |
19498 var zip_head2 = function(i, val) { | |
19499 return zip_prev[zip_WSIZE + i] = val; | |
19500 } | |
19501 | |
19502 /* put_byte is used for the compressed output, put_ubyte for the | |
19503 * uncompressed output. However unlzw() uses window for its | |
19504 * suffix table instead of its output buffer, so it does not use put_ubyte | |
19505 * (to be cleaned up). | |
19506 */ | |
19507 var zip_put_byte = function(c) { | |
19508 zip_outbuf[zip_outoff + zip_outcnt++] = c; | |
19509 if(zip_outoff + zip_outcnt == zip_OUTBUFSIZ) | |
19510 zip_qoutbuf(); | |
19511 } | |
19512 | |
19513 /* Output a 16 bit value, lsb first */ | |
19514 var zip_put_short = function(w) { | |
19515 w &= 0xffff; | |
19516 if(zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { | |
19517 zip_outbuf[zip_outoff + zip_outcnt++] = (w & 0xff); | |
19518 zip_outbuf[zip_outoff + zip_outcnt++] = (w >>> 8); | |
19519 } else { | |
19520 zip_put_byte(w & 0xff); | |
19521 zip_put_byte(w >>> 8); | |
19522 } | |
19523 } | |
19524 | |
19525 /* ========================================================================== | |
19526 * Insert string s in the dictionary and set match_head to the previous head | |
19527 * of the hash chain (the most recent string with same hash key). Return | |
19528 * the previous length of the hash chain. | |
19529 * IN assertion: all calls to to INSERT_STRING are made with consecutive | |
19530 * input characters and the first MIN_MATCH bytes of s are valid | |
19531 * (except for the last MIN_MATCH-1 bytes of the input file). | |
19532 */ | |
19533 var zip_INSERT_STRING = function() { | |
19534 zip_ins_h = ((zip_ins_h << zip_H_SHIFT) | |
19535 ^ (zip_window[zip_strstart + zip_MIN_MATCH - 1] & 0xff)) | |
19536 & zip_HASH_MASK; | |
19537 zip_hash_head = zip_head1(zip_ins_h); | |
19538 zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; | |
19539 zip_head2(zip_ins_h, zip_strstart); | |
19540 } | |
19541 | |
19542 /* Send a code of the given tree. c and tree must not have side effects */ | |
19543 var zip_SEND_CODE = function(c, tree) { | |
19544 zip_send_bits(tree[c].fc, tree[c].dl); | |
19545 } | |
19546 | |
19547 /* Mapping from a distance to a distance code. dist is the distance - 1 and | |
19548 * must not have side effects. dist_code[256] and dist_code[257] are never | |
19549 * used. | |
19550 */ | |
19551 var zip_D_CODE = function(dist) { | |
19552 return (dist < 256 ? zip_dist_code[dist] | |
19553 : zip_dist_code[256 + (dist>>7)]) & 0xff; | |
19554 } | |
19555 | |
19556 /* ========================================================================== | |
19557 * Compares to subtrees, using the tree depth as tie breaker when | |
19558 * the subtrees have equal frequency. This minimizes the worst case length. | |
19559 */ | |
19560 var zip_SMALLER = function(tree, n, m) { | |
19561 return tree[n].fc < tree[m].fc || | |
19562 (tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]); | |
19563 } | |
19564 | |
19565 /* ========================================================================== | |
19566 * read string data | |
19567 */ | |
19568 var zip_read_buff = function(buff, offset, n) { | |
19569 var i; | |
19570 for(i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) | |
19571 buff[offset + i] = | |
19572 zip_deflate_data.charCodeAt(zip_deflate_pos++) & 0xff; | |
19573 return i; | |
19574 } | |
19575 | |
19576 /* ========================================================================== | |
19577 * Initialize the "longest match" routines for a new file | |
19578 */ | |
19579 var zip_lm_init = function() { | |
19580 var j; | |
19581 | |
19582 /* Initialize the hash table. */ | |
19583 for(j = 0; j < zip_HASH_SIZE; j++) | |
19584 // zip_head2(j, zip_NIL); | |
19585 zip_prev[zip_WSIZE + j] = 0; | |
19586 /* prev will be initialized on the fly */ | |
19587 | |
19588 /* Set the default configuration parameters: | |
19589 */ | |
19590 zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; | |
19591 zip_good_match = zip_configuration_table[zip_compr_level].good_length; | |
19592 if(!zip_FULL_SEARCH) | |
19593 zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; | |
19594 zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; | |
19595 | |
19596 zip_strstart = 0; | |
19597 zip_block_start = 0; | |
19598 | |
19599 zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); | |
19600 if(zip_lookahead <= 0) { | |
19601 zip_eofile = true; | |
19602 zip_lookahead = 0; | |
19603 return; | |
19604 } | |
19605 zip_eofile = false; | |
19606 /* Make sure that we always have enough lookahead. This is important | |
19607 * if input comes from a device such as a tty. | |
19608 */ | |
19609 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) | |
19610 zip_fill_window(); | |
19611 | |
19612 /* If lookahead < MIN_MATCH, ins_h is garbage, but this is | |
19613 * not important since only literal bytes will be emitted. | |
19614 */ | |
19615 zip_ins_h = 0; | |
19616 for(j = 0; j < zip_MIN_MATCH - 1; j++) { | |
19617 // UPDATE_HASH(ins_h, window[j]); | |
19618 zip_ins_h = ((zip_ins_h << zip_H_SHIFT) ^ (zip_window[j] & 0xff)) & zip_HASH_MASK; | |
19619 } | |
19620 } | |
19621 | |
19622 /* ========================================================================== | |
19623 * Set match_start to the longest match starting at the given string and | |
19624 * return its length. Matches shorter or equal to prev_length are discarded, | |
19625 * in which case the result is equal to prev_length and match_start is | |
19626 * garbage. | |
19627 * IN assertions: cur_match is the head of the hash chain for the current | |
19628 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 | |
19629 */ | |
19630 var zip_longest_match = function(cur_match) { | |
19631 var chain_length = zip_max_chain_length; // max hash chain length | |
19632 var scanp = zip_strstart; // current string | |
19633 var matchp; // matched string | |
19634 var len; // length of current match | |
19635 var best_len = zip_prev_length; // best match length so far | |
19636 | |
19637 /* Stop when cur_match becomes <= limit. To simplify the code, | |
19638 * we prevent matches with the string of window index 0. | |
19639 */ | |
19640 var limit = (zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL); | |
19641 | |
19642 var strendp = zip_strstart + zip_MAX_MATCH; | |
19643 var scan_end1 = zip_window[scanp + best_len - 1]; | |
19644 var scan_end = zip_window[scanp + best_len]; | |
19645 | |
19646 /* Do not waste too much time if we already have a good match: */ | |
19647 if(zip_prev_length >= zip_good_match) | |
19648 chain_length >>= 2; | |
19649 | |
19650 // Assert(encoder->strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); | |
19651 | |
19652 do { | |
19653 // Assert(cur_match < encoder->strstart, "no future"); | |
19654 matchp = cur_match; | |
19655 | |
19656 /* Skip to next match if the match length cannot increase | |
19657 * or if the match length is less than 2: | |
19658 */ | |
19659 if(zip_window[matchp + best_len] != scan_end || | |
19660 zip_window[matchp + best_len - 1] != scan_end1 || | |
19661 zip_window[matchp] != zip_window[scanp] || | |
19662 zip_window[++matchp] != zip_window[scanp + 1]) { | |
19663 continue; | |
19664 } | |
19665 | |
19666 /* The check at best_len-1 can be removed because it will be made | |
19667 * again later. (This heuristic is not always a win.) | |
19668 * It is not necessary to compare scan[2] and match[2] since they | |
19669 * are always equal when the other bytes match, given that | |
19670 * the hash keys are equal and that HASH_BITS >= 8. | |
19671 */ | |
19672 scanp += 2; | |
19673 matchp++; | |
19674 | |
19675 /* We check for insufficient lookahead only every 8th comparison; | |
19676 * the 256th check will be made at strstart+258. | |
19677 */ | |
19678 do { | |
19679 } while(zip_window[++scanp] == zip_window[++matchp] && | |
19680 zip_window[++scanp] == zip_window[++matchp] && | |
19681 zip_window[++scanp] == zip_window[++matchp] && | |
19682 zip_window[++scanp] == zip_window[++matchp] && | |
19683 zip_window[++scanp] == zip_window[++matchp] && | |
19684 zip_window[++scanp] == zip_window[++matchp] && | |
19685 zip_window[++scanp] == zip_window[++matchp] && | |
19686 zip_window[++scanp] == zip_window[++matchp] && | |
19687 scanp < strendp); | |
19688 | |
19689 len = zip_MAX_MATCH - (strendp - scanp); | |
19690 scanp = strendp - zip_MAX_MATCH; | |
19691 | |
19692 if(len > best_len) { | |
19693 zip_match_start = cur_match; | |
19694 best_len = len; | |
19695 if(zip_FULL_SEARCH) { | |
19696 if(len >= zip_MAX_MATCH) break; | |
19697 } else { | |
19698 if(len >= zip_nice_match) break; | |
19699 } | |
19700 | |
19701 scan_end1 = zip_window[scanp + best_len-1]; | |
19702 scan_end = zip_window[scanp + best_len]; | |
19703 } | |
19704 } while((cur_match = zip_prev[cur_match & zip_WMASK]) > limit | |
19705 && --chain_length != 0); | |
19706 | |
19707 return best_len; | |
19708 } | |
19709 | |
19710 /* ========================================================================== | |
19711 * Fill the window when the lookahead becomes insufficient. | |
19712 * Updates strstart and lookahead, and sets eofile if end of input file. | |
19713 * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 | |
19714 * OUT assertions: at least one byte has been read, or eofile is set; | |
19715 * file reads are performed for at least two bytes (required for the | |
19716 * translate_eol option). | |
19717 */ | |
19718 var zip_fill_window = function() { | |
19719 var n, m; | |
19720 | |
19721 // Amount of free space at the end of the window. | |
19722 var more = zip_window_size - zip_lookahead - zip_strstart; | |
19723 | |
19724 /* If the window is almost full and there is insufficient lookahead, | |
19725 * move the upper half to the lower one to make room in the upper half. | |
19726 */ | |
19727 if(more == -1) { | |
19728 /* Very unlikely, but possible on 16 bit machine if strstart == 0 | |
19729 * and lookahead == 1 (input done one byte at time) | |
19730 */ | |
19731 more--; | |
19732 } else if(zip_strstart >= zip_WSIZE + zip_MAX_DIST) { | |
19733 /* By the IN assertion, the window is not empty so we can't confuse | |
19734 * more == 0 with more == 64K on a 16 bit machine. | |
19735 */ | |
19736 // Assert(window_size == (ulg)2*WSIZE, "no sliding with BIG_MEM"); | |
19737 | |
19738 // System.arraycopy(window, WSIZE, window, 0, WSIZE); | |
19739 for(n = 0; n < zip_WSIZE; n++) | |
19740 zip_window[n] = zip_window[n + zip_WSIZE]; | |
19741 | |
19742 zip_match_start -= zip_WSIZE; | |
19743 zip_strstart -= zip_WSIZE; /* we now have strstart >= MAX_DIST: */ | |
19744 zip_block_start -= zip_WSIZE; | |
19745 | |
19746 for(n = 0; n < zip_HASH_SIZE; n++) { | |
19747 m = zip_head1(n); | |
19748 zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); | |
19749 } | |
19750 for(n = 0; n < zip_WSIZE; n++) { | |
19751 /* If n is not on any hash chain, prev[n] is garbage but | |
19752 * its value will never be used. | |
19753 */ | |
19754 m = zip_prev[n]; | |
19755 zip_prev[n] = (m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL); | |
19756 } | |
19757 more += zip_WSIZE; | |
19758 } | |
19759 // At this point, more >= 2 | |
19760 if(!zip_eofile) { | |
19761 n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more); | |
19762 if(n <= 0) | |
19763 zip_eofile = true; | |
19764 else | |
19765 zip_lookahead += n; | |
19766 } | |
19767 } | |
19768 | |
19769 /* ========================================================================== | |
19770 * Processes a new input file and return its compressed length. This | |
19771 * function does not perform lazy evaluationof matches and inserts | |
19772 * new strings in the dictionary only for unmatched strings or for short | |
19773 * matches. It is used only for the fast compression options. | |
19774 */ | |
19775 var zip_deflate_fast = function() { | |
19776 while(zip_lookahead != 0 && zip_qhead == null) { | |
19777 var flush; // set if current block must be flushed | |
19778 | |
19779 /* Insert the string window[strstart .. strstart+2] in the | |
19780 * dictionary, and set hash_head to the head of the hash chain: | |
19781 */ | |
19782 zip_INSERT_STRING(); | |
19783 | |
19784 /* Find the longest match, discarding those <= prev_length. | |
19785 * At this point we have always match_length < MIN_MATCH | |
19786 */ | |
19787 if(zip_hash_head != zip_NIL && | |
19788 zip_strstart - zip_hash_head <= zip_MAX_DIST) { | |
19789 /* To simplify the code, we prevent matches with the string | |
19790 * of window index 0 (in particular we have to avoid a match | |
19791 * of the string with itself at the start of the input file). | |
19792 */ | |
19793 zip_match_length = zip_longest_match(zip_hash_head); | |
19794 /* longest_match() sets match_start */ | |
19795 if(zip_match_length > zip_lookahead) | |
19796 zip_match_length = zip_lookahead; | |
19797 } | |
19798 if(zip_match_length >= zip_MIN_MATCH) { | |
19799 // check_match(strstart, match_start, match_length); | |
19800 | |
19801 flush = zip_ct_tally(zip_strstart - zip_match_start, | |
19802 zip_match_length - zip_MIN_MATCH); | |
19803 zip_lookahead -= zip_match_length; | |
19804 | |
19805 /* Insert new strings in the hash table only if the match length | |
19806 * is not too large. This saves time but degrades compression. | |
19807 */ | |
19808 if(zip_match_length <= zip_max_lazy_match) { | |
19809 zip_match_length--; // string at strstart already in hash table | |
19810 do { | |
19811 zip_strstart++; | |
19812 zip_INSERT_STRING(); | |
19813 /* strstart never exceeds WSIZE-MAX_MATCH, so there are | |
19814 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | |
19815 * these bytes are garbage, but it does not matter since | |
19816 * the next lookahead bytes will be emitted as literals. | |
19817 */ | |
19818 } while(--zip_match_length != 0); | |
19819 zip_strstart++; | |
19820 } else { | |
19821 zip_strstart += zip_match_length; | |
19822 zip_match_length = 0; | |
19823 zip_ins_h = zip_window[zip_strstart] & 0xff; | |
19824 // UPDATE_HASH(ins_h, window[strstart + 1]); | |
19825 zip_ins_h = ((zip_ins_h<<zip_H_SHIFT) ^ (zip_window[zip_strstart + 1] & 0xff)) & zip_HASH_MASK; | |
19826 | |
19827 //#if MIN_MATCH != 3 | |
19828 // Call UPDATE_HASH() MIN_MATCH-3 more times | |
19829 //#endif | |
19830 | |
19831 } | |
19832 } else { | |
19833 /* No match, output a literal byte */ | |
19834 flush = zip_ct_tally(0, zip_window[zip_strstart] & 0xff); | |
19835 zip_lookahead--; | |
19836 zip_strstart++; | |
19837 } | |
19838 if(flush) { | |
19839 zip_flush_block(0); | |
19840 zip_block_start = zip_strstart; | |
19841 } | |
19842 | |
19843 /* Make sure that we always have enough lookahead, except | |
19844 * at the end of the input file. We need MAX_MATCH bytes | |
19845 * for the next match, plus MIN_MATCH bytes to insert the | |
19846 * string following the next match. | |
19847 */ | |
19848 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) | |
19849 zip_fill_window(); | |
19850 } | |
19851 } | |
19852 | |
19853 var zip_deflate_better = function() { | |
19854 /* Process the input block. */ | |
19855 while(zip_lookahead != 0 && zip_qhead == null) { | |
19856 /* Insert the string window[strstart .. strstart+2] in the | |
19857 * dictionary, and set hash_head to the head of the hash chain: | |
19858 */ | |
19859 zip_INSERT_STRING(); | |
19860 | |
19861 /* Find the longest match, discarding those <= prev_length. | |
19862 */ | |
19863 zip_prev_length = zip_match_length; | |
19864 zip_prev_match = zip_match_start; | |
19865 zip_match_length = zip_MIN_MATCH - 1; | |
19866 | |
19867 if(zip_hash_head != zip_NIL && | |
19868 zip_prev_length < zip_max_lazy_match && | |
19869 zip_strstart - zip_hash_head <= zip_MAX_DIST) { | |
19870 /* To simplify the code, we prevent matches with the string | |
19871 * of window index 0 (in particular we have to avoid a match | |
19872 * of the string with itself at the start of the input file). | |
19873 */ | |
19874 zip_match_length = zip_longest_match(zip_hash_head); | |
19875 /* longest_match() sets match_start */ | |
19876 if(zip_match_length > zip_lookahead) | |
19877 zip_match_length = zip_lookahead; | |
19878 | |
19879 /* Ignore a length 3 match if it is too distant: */ | |
19880 if(zip_match_length == zip_MIN_MATCH && | |
19881 zip_strstart - zip_match_start > zip_TOO_FAR) { | |
19882 /* If prev_match is also MIN_MATCH, match_start is garbage | |
19883 * but we will ignore the current match anyway. | |
19884 */ | |
19885 zip_match_length--; | |
19886 } | |
19887 } | |
19888 /* If there was a match at the previous step and the current | |
19889 * match is not better, output the previous match: | |
19890 */ | |
19891 if(zip_prev_length >= zip_MIN_MATCH && | |
19892 zip_match_length <= zip_prev_length) { | |
19893 var flush; // set if current block must be flushed | |
19894 | |
19895 // check_match(strstart - 1, prev_match, prev_length); | |
19896 flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, | |
19897 zip_prev_length - zip_MIN_MATCH); | |
19898 | |
19899 /* Insert in hash table all strings up to the end of the match. | |
19900 * strstart-1 and strstart are already inserted. | |
19901 */ | |
19902 zip_lookahead -= zip_prev_length - 1; | |
19903 zip_prev_length -= 2; | |
19904 do { | |
19905 zip_strstart++; | |
19906 zip_INSERT_STRING(); | |
19907 /* strstart never exceeds WSIZE-MAX_MATCH, so there are | |
19908 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH | |
19909 * these bytes are garbage, but it does not matter since the | |
19910 * next lookahead bytes will always be emitted as literals. | |
19911 */ | |
19912 } while(--zip_prev_length != 0); | |
19913 zip_match_available = 0; | |
19914 zip_match_length = zip_MIN_MATCH - 1; | |
19915 zip_strstart++; | |
19916 if(flush) { | |
19917 zip_flush_block(0); | |
19918 zip_block_start = zip_strstart; | |
19919 } | |
19920 } else if(zip_match_available != 0) { | |
19921 /* If there was no match at the previous position, output a | |
19922 * single literal. If there was a match but the current match | |
19923 * is longer, truncate the previous match to a single literal. | |
19924 */ | |
19925 if(zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff)) { | |
19926 zip_flush_block(0); | |
19927 zip_block_start = zip_strstart; | |
19928 } | |
19929 zip_strstart++; | |
19930 zip_lookahead--; | |
19931 } else { | |
19932 /* There is no previous match to compare with, wait for | |
19933 * the next step to decide. | |
19934 */ | |
19935 zip_match_available = 1; | |
19936 zip_strstart++; | |
19937 zip_lookahead--; | |
19938 } | |
19939 | |
19940 /* Make sure that we always have enough lookahead, except | |
19941 * at the end of the input file. We need MAX_MATCH bytes | |
19942 * for the next match, plus MIN_MATCH bytes to insert the | |
19943 * string following the next match. | |
19944 */ | |
19945 while(zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) | |
19946 zip_fill_window(); | |
19947 } | |
19948 } | |
19949 | |
19950 var zip_init_deflate = function() { | |
19951 if(zip_eofile) | |
19952 return; | |
19953 zip_bi_buf = 0; | |
19954 zip_bi_valid = 0; | |
19955 zip_ct_init(); | |
19956 zip_lm_init(); | |
19957 | |
19958 zip_qhead = null; | |
19959 zip_outcnt = 0; | |
19960 zip_outoff = 0; | |
19961 | |
19962 if(zip_compr_level <= 3) | |
19963 { | |
19964 zip_prev_length = zip_MIN_MATCH - 1; | |
19965 zip_match_length = 0; | |
19966 } | |
19967 else | |
19968 { | |
19969 zip_match_length = zip_MIN_MATCH - 1; | |
19970 zip_match_available = 0; | |
19971 } | |
19972 | |
19973 zip_complete = false; | |
19974 } | |
19975 | |
19976 /* ========================================================================== | |
19977 * Same as above, but achieves better compression. We use a lazy | |
19978 * evaluation for matches: a match is finally adopted only if there is | |
19979 * no better match at the next window position. | |
19980 */ | |
19981 var zip_deflate_internal = function(buff, off, buff_size) { | |
19982 var n; | |
19983 | |
19984 if(!zip_initflag) | |
19985 { | |
19986 zip_init_deflate(); | |
19987 zip_initflag = true; | |
19988 if(zip_lookahead == 0) { // empty | |
19989 zip_complete = true; | |
19990 return 0; | |
19991 } | |
19992 } | |
19993 | |
19994 if((n = zip_qcopy(buff, off, buff_size)) == buff_size) | |
19995 return buff_size; | |
19996 | |
19997 if(zip_complete) | |
19998 return n; | |
19999 | |
20000 if(zip_compr_level <= 3) // optimized for speed | |
20001 zip_deflate_fast(); | |
20002 else | |
20003 zip_deflate_better(); | |
20004 if(zip_lookahead == 0) { | |
20005 if(zip_match_available != 0) | |
20006 zip_ct_tally(0, zip_window[zip_strstart - 1] & 0xff); | |
20007 zip_flush_block(1); | |
20008 zip_complete = true; | |
20009 } | |
20010 return n + zip_qcopy(buff, n + off, buff_size - n); | |
20011 } | |
20012 | |
20013 var zip_qcopy = function(buff, off, buff_size) { | |
20014 var n, i, j; | |
20015 | |
20016 n = 0; | |
20017 while(zip_qhead != null && n < buff_size) | |
20018 { | |
20019 i = buff_size - n; | |
20020 if(i > zip_qhead.len) | |
20021 i = zip_qhead.len; | |
20022 // System.arraycopy(qhead.ptr, qhead.off, buff, off + n, i); | |
20023 for(j = 0; j < i; j++) | |
20024 buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j]; | |
20025 | |
20026 zip_qhead.off += i; | |
20027 zip_qhead.len -= i; | |
20028 n += i; | |
20029 if(zip_qhead.len == 0) { | |
20030 var p; | |
20031 p = zip_qhead; | |
20032 zip_qhead = zip_qhead.next; | |
20033 zip_reuse_queue(p); | |
20034 } | |
20035 } | |
20036 | |
20037 if(n == buff_size) | |
20038 return n; | |
20039 | |
20040 if(zip_outoff < zip_outcnt) { | |
20041 i = buff_size - n; | |
20042 if(i > zip_outcnt - zip_outoff) | |
20043 i = zip_outcnt - zip_outoff; | |
20044 // System.arraycopy(outbuf, outoff, buff, off + n, i); | |
20045 for(j = 0; j < i; j++) | |
20046 buff[off + n + j] = zip_outbuf[zip_outoff + j]; | |
20047 zip_outoff += i; | |
20048 n += i; | |
20049 if(zip_outcnt == zip_outoff) | |
20050 zip_outcnt = zip_outoff = 0; | |
20051 } | |
20052 return n; | |
20053 } | |
20054 | |
20055 /* ========================================================================== | |
20056 * Allocate the match buffer, initialize the various tables and save the | |
20057 * location of the internal file attribute (ascii/binary) and method | |
20058 * (DEFLATE/STORE). | |
20059 */ | |
20060 var zip_ct_init = function() { | |
20061 var n; // iterates over tree elements | |
20062 var bits; // bit counter | |
20063 var length; // length value | |
20064 var code; // code value | |
20065 var dist; // distance index | |
20066 | |
20067 if(zip_static_dtree[0].dl != 0) return; // ct_init already called | |
20068 | |
20069 zip_l_desc.dyn_tree = zip_dyn_ltree; | |
20070 zip_l_desc.static_tree = zip_static_ltree; | |
20071 zip_l_desc.extra_bits = zip_extra_lbits; | |
20072 zip_l_desc.extra_base = zip_LITERALS + 1; | |
20073 zip_l_desc.elems = zip_L_CODES; | |
20074 zip_l_desc.max_length = zip_MAX_BITS; | |
20075 zip_l_desc.max_code = 0; | |
20076 | |
20077 zip_d_desc.dyn_tree = zip_dyn_dtree; | |
20078 zip_d_desc.static_tree = zip_static_dtree; | |
20079 zip_d_desc.extra_bits = zip_extra_dbits; | |
20080 zip_d_desc.extra_base = 0; | |
20081 zip_d_desc.elems = zip_D_CODES; | |
20082 zip_d_desc.max_length = zip_MAX_BITS; | |
20083 zip_d_desc.max_code = 0; | |
20084 | |
20085 zip_bl_desc.dyn_tree = zip_bl_tree; | |
20086 zip_bl_desc.static_tree = null; | |
20087 zip_bl_desc.extra_bits = zip_extra_blbits; | |
20088 zip_bl_desc.extra_base = 0; | |
20089 zip_bl_desc.elems = zip_BL_CODES; | |
20090 zip_bl_desc.max_length = zip_MAX_BL_BITS; | |
20091 zip_bl_desc.max_code = 0; | |
20092 | |
20093 // Initialize the mapping length (0..255) -> length code (0..28) | |
20094 length = 0; | |
20095 for(code = 0; code < zip_LENGTH_CODES-1; code++) { | |
20096 zip_base_length[code] = length; | |
20097 for(n = 0; n < (1<<zip_extra_lbits[code]); n++) | |
20098 zip_length_code[length++] = code; | |
20099 } | |
20100 // Assert (length == 256, "ct_init: length != 256"); | |
20101 | |
20102 /* Note that the length 255 (match length 258) can be represented | |
20103 * in two different ways: code 284 + 5 bits or code 285, so we | |
20104 * overwrite length_code[255] to use the best encoding: | |
20105 */ | |
20106 zip_length_code[length-1] = code; | |
20107 | |
20108 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ | |
20109 dist = 0; | |
20110 for(code = 0 ; code < 16; code++) { | |
20111 zip_base_dist[code] = dist; | |
20112 for(n = 0; n < (1<<zip_extra_dbits[code]); n++) { | |
20113 zip_dist_code[dist++] = code; | |
20114 } | |
20115 } | |
20116 // Assert (dist == 256, "ct_init: dist != 256"); | |
20117 dist >>= 7; // from now on, all distances are divided by 128 | |
20118 for( ; code < zip_D_CODES; code++) { | |
20119 zip_base_dist[code] = dist << 7; | |
20120 for(n = 0; n < (1<<(zip_extra_dbits[code]-7)); n++) | |
20121 zip_dist_code[256 + dist++] = code; | |
20122 } | |
20123 // Assert (dist == 256, "ct_init: 256+dist != 512"); | |
20124 | |
20125 // Construct the codes of the static literal tree | |
20126 for(bits = 0; bits <= zip_MAX_BITS; bits++) | |
20127 zip_bl_count[bits] = 0; | |
20128 n = 0; | |
20129 while(n <= 143) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } | |
20130 while(n <= 255) { zip_static_ltree[n++].dl = 9; zip_bl_count[9]++; } | |
20131 while(n <= 279) { zip_static_ltree[n++].dl = 7; zip_bl_count[7]++; } | |
20132 while(n <= 287) { zip_static_ltree[n++].dl = 8; zip_bl_count[8]++; } | |
20133 /* Codes 286 and 287 do not exist, but we must include them in the | |
20134 * tree construction to get a canonical Huffman tree (longest code | |
20135 * all ones) | |
20136 */ | |
20137 zip_gen_codes(zip_static_ltree, zip_L_CODES + 1); | |
20138 | |
20139 /* The static distance tree is trivial: */ | |
20140 for(n = 0; n < zip_D_CODES; n++) { | |
20141 zip_static_dtree[n].dl = 5; | |
20142 zip_static_dtree[n].fc = zip_bi_reverse(n, 5); | |
20143 } | |
20144 | |
20145 // Initialize the first block of the first file: | |
20146 zip_init_block(); | |
20147 } | |
20148 | |
20149 /* ========================================================================== | |
20150 * Initialize a new block. | |
20151 */ | |
20152 var zip_init_block = function() { | |
20153 var n; // iterates over tree elements | |
20154 | |
20155 // Initialize the trees. | |
20156 for(n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0; | |
20157 for(n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0; | |
20158 for(n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0; | |
20159 | |
20160 zip_dyn_ltree[zip_END_BLOCK].fc = 1; | |
20161 zip_opt_len = zip_static_len = 0; | |
20162 zip_last_lit = zip_last_dist = zip_last_flags = 0; | |
20163 zip_flags = 0; | |
20164 zip_flag_bit = 1; | |
20165 } | |
20166 | |
20167 /* ========================================================================== | |
20168 * Restore the heap property by moving down the tree starting at node k, | |
20169 * exchanging a node with the smallest of its two sons if necessary, stopping | |
20170 * when the heap property is re-established (each father smaller than its | |
20171 * two sons). | |
20172 */ | |
20173 var zip_pqdownheap = function( | |
20174 tree, // the tree to restore | |
20175 k) { // node to move down | |
20176 var v = zip_heap[k]; | |
20177 var j = k << 1; // left son of k | |
20178 | |
20179 while(j <= zip_heap_len) { | |
20180 // Set j to the smallest of the two sons: | |
20181 if(j < zip_heap_len && | |
20182 zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) | |
20183 j++; | |
20184 | |
20185 // Exit if v is smaller than both sons | |
20186 if(zip_SMALLER(tree, v, zip_heap[j])) | |
20187 break; | |
20188 | |
20189 // Exchange v with the smallest son | |
20190 zip_heap[k] = zip_heap[j]; | |
20191 k = j; | |
20192 | |
20193 // And continue down the tree, setting j to the left son of k | |
20194 j <<= 1; | |
20195 } | |
20196 zip_heap[k] = v; | |
20197 } | |
20198 | |
20199 /* ========================================================================== | |
20200 * Compute the optimal bit lengths for a tree and update the total bit length | |
20201 * for the current block. | |
20202 * IN assertion: the fields freq and dad are set, heap[heap_max] and | |
20203 * above are the tree nodes sorted by increasing frequency. | |
20204 * OUT assertions: the field len is set to the optimal bit length, the | |
20205 * array bl_count contains the frequencies for each bit length. | |
20206 * The length opt_len is updated; static_len is also updated if stree is | |
20207 * not null. | |
20208 */ | |
20209 var zip_gen_bitlen = function(desc) { // the tree descriptor | |
20210 var tree = desc.dyn_tree; | |
20211 var extra = desc.extra_bits; | |
20212 var base = desc.extra_base; | |
20213 var max_code = desc.max_code; | |
20214 var max_length = desc.max_length; | |
20215 var stree = desc.static_tree; | |
20216 var h; // heap index | |
20217 var n, m; // iterate over the tree elements | |
20218 var bits; // bit length | |
20219 var xbits; // extra bits | |
20220 var f; // frequency | |
20221 var overflow = 0; // number of elements with bit length too large | |
20222 | |
20223 for(bits = 0; bits <= zip_MAX_BITS; bits++) | |
20224 zip_bl_count[bits] = 0; | |
20225 | |
20226 /* In a first pass, compute the optimal bit lengths (which may | |
20227 * overflow in the case of the bit length tree). | |
20228 */ | |
20229 tree[zip_heap[zip_heap_max]].dl = 0; // root of the heap | |
20230 | |
20231 for(h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) { | |
20232 n = zip_heap[h]; | |
20233 bits = tree[tree[n].dl].dl + 1; | |
20234 if(bits > max_length) { | |
20235 bits = max_length; | |
20236 overflow++; | |
20237 } | |
20238 tree[n].dl = bits; | |
20239 // We overwrite tree[n].dl which is no longer needed | |
20240 | |
20241 if(n > max_code) | |
20242 continue; // not a leaf node | |
20243 | |
20244 zip_bl_count[bits]++; | |
20245 xbits = 0; | |
20246 if(n >= base) | |
20247 xbits = extra[n - base]; | |
20248 f = tree[n].fc; | |
20249 zip_opt_len += f * (bits + xbits); | |
20250 if(stree != null) | |
20251 zip_static_len += f * (stree[n].dl + xbits); | |
20252 } | |
20253 if(overflow == 0) | |
20254 return; | |
20255 | |
20256 // This happens for example on obj2 and pic of the Calgary corpus | |
20257 | |
20258 // Find the first bit length which could increase: | |
20259 do { | |
20260 bits = max_length - 1; | |
20261 while(zip_bl_count[bits] == 0) | |
20262 bits--; | |
20263 zip_bl_count[bits]--; // move one leaf down the tree | |
20264 zip_bl_count[bits + 1] += 2; // move one overflow item as its brother | |
20265 zip_bl_count[max_length]--; | |
20266 /* The brother of the overflow item also moves one step up, | |
20267 * but this does not affect bl_count[max_length] | |
20268 */ | |
20269 overflow -= 2; | |
20270 } while(overflow > 0); | |
20271 | |
20272 /* Now recompute all bit lengths, scanning in increasing frequency. | |
20273 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all | |
20274 * lengths instead of fixing only the wrong ones. This idea is taken | |
20275 * from 'ar' written by Haruhiko Okumura.) | |
20276 */ | |
20277 for(bits = max_length; bits != 0; bits--) { | |
20278 n = zip_bl_count[bits]; | |
20279 while(n != 0) { | |
20280 m = zip_heap[--h]; | |
20281 if(m > max_code) | |
20282 continue; | |
20283 if(tree[m].dl != bits) { | |
20284 zip_opt_len += (bits - tree[m].dl) * tree[m].fc; | |
20285 tree[m].fc = bits; | |
20286 } | |
20287 n--; | |
20288 } | |
20289 } | |
20290 } | |
20291 | |
20292 /* ========================================================================== | |
20293 * Generate the codes for a given tree and bit counts (which need not be | |
20294 * optimal). | |
20295 * IN assertion: the array bl_count contains the bit length statistics for | |
20296 * the given tree and the field len is set for all tree elements. | |
20297 * OUT assertion: the field code is set for all tree elements of non | |
20298 * zero code length. | |
20299 */ | |
20300 var zip_gen_codes = function(tree, // the tree to decorate | |
20301 max_code) { // largest code with non zero frequency | |
20302 var next_code = new Array(zip_MAX_BITS+1); // next code value for each bit length | |
20303 var code = 0; // running code value | |
20304 var bits; // bit index | |
20305 var n; // code index | |
20306 | |
20307 /* The distribution counts are first used to generate the code values | |
20308 * without bit reversal. | |
20309 */ | |
20310 for(bits = 1; bits <= zip_MAX_BITS; bits++) { | |
20311 code = ((code + zip_bl_count[bits-1]) << 1); | |
20312 next_code[bits] = code; | |
20313 } | |
20314 | |
20315 /* Check that the bit counts in bl_count are consistent. The last code | |
20316 * must be all ones. | |
20317 */ | |
20318 // Assert (code + encoder->bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, | |
20319 // "inconsistent bit counts"); | |
20320 // Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); | |
20321 | |
20322 for(n = 0; n <= max_code; n++) { | |
20323 var len = tree[n].dl; | |
20324 if(len == 0) | |
20325 continue; | |
20326 // Now reverse the bits | |
20327 tree[n].fc = zip_bi_reverse(next_code[len]++, len); | |
20328 | |
20329 // Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", | |
20330 // n, (isgraph(n) ? n : ' '), len, tree[n].fc, next_code[len]-1)); | |
20331 } | |
20332 } | |
20333 | |
20334 /* ========================================================================== | |
20335 * Construct one Huffman tree and assigns the code bit strings and lengths. | |
20336 * Update the total bit length for the current block. | |
20337 * IN assertion: the field freq is set for all tree elements. | |
20338 * OUT assertions: the fields len and code are set to the optimal bit length | |
20339 * and corresponding code. The length opt_len is updated; static_len is | |
20340 * also updated if stree is not null. The field max_code is set. | |
20341 */ | |
20342 var zip_build_tree = function(desc) { // the tree descriptor | |
20343 var tree = desc.dyn_tree; | |
20344 var stree = desc.static_tree; | |
20345 var elems = desc.elems; | |
20346 var n, m; // iterate over heap elements | |
20347 var max_code = -1; // largest code with non zero frequency | |
20348 var node = elems; // next internal node of the tree | |
20349 | |
20350 /* Construct the initial heap, with least frequent element in | |
20351 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. | |
20352 * heap[0] is not used. | |
20353 */ | |
20354 zip_heap_len = 0; | |
20355 zip_heap_max = zip_HEAP_SIZE; | |
20356 | |
20357 for(n = 0; n < elems; n++) { | |
20358 if(tree[n].fc != 0) { | |
20359 zip_heap[++zip_heap_len] = max_code = n; | |
20360 zip_depth[n] = 0; | |
20361 } else | |
20362 tree[n].dl = 0; | |
20363 } | |
20364 | |
20365 /* The pkzip format requires that at least one distance code exists, | |
20366 * and that at least one bit should be sent even if there is only one | |
20367 * possible code. So to avoid special checks later on we force at least | |
20368 * two codes of non zero frequency. | |
20369 */ | |
20370 while(zip_heap_len < 2) { | |
20371 var xnew = zip_heap[++zip_heap_len] = (max_code < 2 ? ++max_code : 0); | |
20372 tree[xnew].fc = 1; | |
20373 zip_depth[xnew] = 0; | |
20374 zip_opt_len--; | |
20375 if(stree != null) | |
20376 zip_static_len -= stree[xnew].dl; | |
20377 // new is 0 or 1 so it does not have extra bits | |
20378 } | |
20379 desc.max_code = max_code; | |
20380 | |
20381 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, | |
20382 * establish sub-heaps of increasing lengths: | |
20383 */ | |
20384 for(n = zip_heap_len >> 1; n >= 1; n--) | |
20385 zip_pqdownheap(tree, n); | |
20386 | |
20387 /* Construct the Huffman tree by repeatedly combining the least two | |
20388 * frequent nodes. | |
20389 */ | |
20390 do { | |
20391 n = zip_heap[zip_SMALLEST]; | |
20392 zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--]; | |
20393 zip_pqdownheap(tree, zip_SMALLEST); | |
20394 | |
20395 m = zip_heap[zip_SMALLEST]; // m = node of next least frequency | |
20396 | |
20397 // keep the nodes sorted by frequency | |
20398 zip_heap[--zip_heap_max] = n; | |
20399 zip_heap[--zip_heap_max] = m; | |
20400 | |
20401 // Create a new node father of n and m | |
20402 tree[node].fc = tree[n].fc + tree[m].fc; | |
20403 // depth[node] = (char)(MAX(depth[n], depth[m]) + 1); | |
20404 if(zip_depth[n] > zip_depth[m] + 1) | |
20405 zip_depth[node] = zip_depth[n]; | |
20406 else | |
20407 zip_depth[node] = zip_depth[m] + 1; | |
20408 tree[n].dl = tree[m].dl = node; | |
20409 | |
20410 // and insert the new node in the heap | |
20411 zip_heap[zip_SMALLEST] = node++; | |
20412 zip_pqdownheap(tree, zip_SMALLEST); | |
20413 | |
20414 } while(zip_heap_len >= 2); | |
20415 | |
20416 zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST]; | |
20417 | |
20418 /* At this point, the fields freq and dad are set. We can now | |
20419 * generate the bit lengths. | |
20420 */ | |
20421 zip_gen_bitlen(desc); | |
20422 | |
20423 // The field len is now set, we can generate the bit codes | |
20424 zip_gen_codes(tree, max_code); | |
20425 } | |
20426 | |
20427 /* ========================================================================== | |
20428 * Scan a literal or distance tree to determine the frequencies of the codes | |
20429 * in the bit length tree. Updates opt_len to take into account the repeat | |
20430 * counts. (The contribution of the bit length codes will be added later | |
20431 * during the construction of bl_tree.) | |
20432 */ | |
20433 var zip_scan_tree = function(tree,// the tree to be scanned | |
20434 max_code) { // and its largest code of non zero frequency | |
20435 var n; // iterates over all tree elements | |
20436 var prevlen = -1; // last emitted length | |
20437 var curlen; // length of current code | |
20438 var nextlen = tree[0].dl; // length of next code | |
20439 var count = 0; // repeat count of the current code | |
20440 var max_count = 7; // max repeat count | |
20441 var min_count = 4; // min repeat count | |
20442 | |
20443 if(nextlen == 0) { | |
20444 max_count = 138; | |
20445 min_count = 3; | |
20446 } | |
20447 tree[max_code + 1].dl = 0xffff; // guard | |
20448 | |
20449 for(n = 0; n <= max_code; n++) { | |
20450 curlen = nextlen; | |
20451 nextlen = tree[n + 1].dl; | |
20452 if(++count < max_count && curlen == nextlen) | |
20453 continue; | |
20454 else if(count < min_count) | |
20455 zip_bl_tree[curlen].fc += count; | |
20456 else if(curlen != 0) { | |
20457 if(curlen != prevlen) | |
20458 zip_bl_tree[curlen].fc++; | |
20459 zip_bl_tree[zip_REP_3_6].fc++; | |
20460 } else if(count <= 10) | |
20461 zip_bl_tree[zip_REPZ_3_10].fc++; | |
20462 else | |
20463 zip_bl_tree[zip_REPZ_11_138].fc++; | |
20464 count = 0; prevlen = curlen; | |
20465 if(nextlen == 0) { | |
20466 max_count = 138; | |
20467 min_count = 3; | |
20468 } else if(curlen == nextlen) { | |
20469 max_count = 6; | |
20470 min_count = 3; | |
20471 } else { | |
20472 max_count = 7; | |
20473 min_count = 4; | |
20474 } | |
20475 } | |
20476 } | |
20477 | |
20478 /* ========================================================================== | |
20479 * Send a literal or distance tree in compressed form, using the codes in | |
20480 * bl_tree. | |
20481 */ | |
20482 var zip_send_tree = function(tree, // the tree to be scanned | |
20483 max_code) { // and its largest code of non zero frequency | |
20484 var n; // iterates over all tree elements | |
20485 var prevlen = -1; // last emitted length | |
20486 var curlen; // length of current code | |
20487 var nextlen = tree[0].dl; // length of next code | |
20488 var count = 0; // repeat count of the current code | |
20489 var max_count = 7; // max repeat count | |
20490 var min_count = 4; // min repeat count | |
20491 | |
20492 /* tree[max_code+1].dl = -1; */ /* guard already set */ | |
20493 if(nextlen == 0) { | |
20494 max_count = 138; | |
20495 min_count = 3; | |
20496 } | |
20497 | |
20498 for(n = 0; n <= max_code; n++) { | |
20499 curlen = nextlen; | |
20500 nextlen = tree[n+1].dl; | |
20501 if(++count < max_count && curlen == nextlen) { | |
20502 continue; | |
20503 } else if(count < min_count) { | |
20504 do { zip_SEND_CODE(curlen, zip_bl_tree); } while(--count != 0); | |
20505 } else if(curlen != 0) { | |
20506 if(curlen != prevlen) { | |
20507 zip_SEND_CODE(curlen, zip_bl_tree); | |
20508 count--; | |
20509 } | |
20510 // Assert(count >= 3 && count <= 6, " 3_6?"); | |
20511 zip_SEND_CODE(zip_REP_3_6, zip_bl_tree); | |
20512 zip_send_bits(count - 3, 2); | |
20513 } else if(count <= 10) { | |
20514 zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree); | |
20515 zip_send_bits(count-3, 3); | |
20516 } else { | |
20517 zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree); | |
20518 zip_send_bits(count-11, 7); | |
20519 } | |
20520 count = 0; | |
20521 prevlen = curlen; | |
20522 if(nextlen == 0) { | |
20523 max_count = 138; | |
20524 min_count = 3; | |
20525 } else if(curlen == nextlen) { | |
20526 max_count = 6; | |
20527 min_count = 3; | |
20528 } else { | |
20529 max_count = 7; | |
20530 min_count = 4; | |
20531 } | |
20532 } | |
20533 } | |
20534 | |
20535 /* ========================================================================== | |
20536 * Construct the Huffman tree for the bit lengths and return the index in | |
20537 * bl_order of the last bit length code to send. | |
20538 */ | |
20539 var zip_build_bl_tree = function() { | |
20540 var max_blindex; // index of last bit length code of non zero freq | |
20541 | |
20542 // Determine the bit length frequencies for literal and distance trees | |
20543 zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code); | |
20544 zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code); | |
20545 | |
20546 // Build the bit length tree: | |
20547 zip_build_tree(zip_bl_desc); | |
20548 /* opt_len now includes the length of the tree representations, except | |
20549 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. | |
20550 */ | |
20551 | |
20552 /* Determine the number of bit length codes to send. The pkzip format | |
20553 * requires that at least 4 bit length codes be sent. (appnote.txt says | |
20554 * 3 but the actual value used is 4.) | |
20555 */ | |
20556 for(max_blindex = zip_BL_CODES-1; max_blindex >= 3; max_blindex--) { | |
20557 if(zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break; | |
20558 } | |
20559 /* Update opt_len to include the bit length tree and counts */ | |
20560 zip_opt_len += 3*(max_blindex+1) + 5+5+4; | |
20561 // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", | |
20562 // encoder->opt_len, encoder->static_len)); | |
20563 | |
20564 return max_blindex; | |
20565 } | |
20566 | |
20567 /* ========================================================================== | |
20568 * Send the header for a block using dynamic Huffman trees: the counts, the | |
20569 * lengths of the bit length codes, the literal tree and the distance tree. | |
20570 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. | |
20571 */ | |
20572 var zip_send_all_trees = function(lcodes, dcodes, blcodes) { // number of codes for each tree | |
20573 var rank; // index in bl_order | |
20574 | |
20575 // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); | |
20576 // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, | |
20577 // "too many codes"); | |
20578 // Tracev((stderr, "\nbl counts: ")); | |
20579 zip_send_bits(lcodes-257, 5); // not +255 as stated in appnote.txt | |
20580 zip_send_bits(dcodes-1, 5); | |
20581 zip_send_bits(blcodes-4, 4); // not -3 as stated in appnote.txt | |
20582 for(rank = 0; rank < blcodes; rank++) { | |
20583 // Tracev((stderr, "\nbl code %2d ", bl_order[rank])); | |
20584 zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3); | |
20585 } | |
20586 | |
20587 // send the literal tree | |
20588 zip_send_tree(zip_dyn_ltree,lcodes-1); | |
20589 | |
20590 // send the distance tree | |
20591 zip_send_tree(zip_dyn_dtree,dcodes-1); | |
20592 } | |
20593 | |
20594 /* ========================================================================== | |
20595 * Determine the best encoding for the current block: dynamic trees, static | |
20596 * trees or store, and output the encoded block to the zip file. | |
20597 */ | |
20598 var zip_flush_block = function(eof) { // true if this is the last block for a file | |
20599 var opt_lenb, static_lenb; // opt_len and static_len in bytes | |
20600 var max_blindex; // index of last bit length code of non zero freq | |
20601 var stored_len; // length of input block | |
20602 | |
20603 stored_len = zip_strstart - zip_block_start; | |
20604 zip_flag_buf[zip_last_flags] = zip_flags; // Save the flags for the last 8 items | |
20605 | |
20606 // Construct the literal and distance trees | |
20607 zip_build_tree(zip_l_desc); | |
20608 // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", | |
20609 // encoder->opt_len, encoder->static_len)); | |
20610 | |
20611 zip_build_tree(zip_d_desc); | |
20612 // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", | |
20613 // encoder->opt_len, encoder->static_len)); | |
20614 /* At this point, opt_len and static_len are the total bit lengths of | |
20615 * the compressed block data, excluding the tree representations. | |
20616 */ | |
20617 | |
20618 /* Build the bit length tree for the above two trees, and get the index | |
20619 * in bl_order of the last bit length code to send. | |
20620 */ | |
20621 max_blindex = zip_build_bl_tree(); | |
20622 | |
20623 // Determine the best encoding. Compute first the block length in bytes | |
20624 opt_lenb = (zip_opt_len +3+7)>>3; | |
20625 static_lenb = (zip_static_len+3+7)>>3; | |
20626 | |
20627 // Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", | |
20628 // opt_lenb, encoder->opt_len, | |
20629 // static_lenb, encoder->static_len, stored_len, | |
20630 // encoder->last_lit, encoder->last_dist)); | |
20631 | |
20632 if(static_lenb <= opt_lenb) | |
20633 opt_lenb = static_lenb; | |
20634 if(stored_len + 4 <= opt_lenb // 4: two words for the lengths | |
20635 && zip_block_start >= 0) { | |
20636 var i; | |
20637 | |
20638 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. | |
20639 * Otherwise we can't have processed more than WSIZE input bytes since | |
20640 * the last block flush, because compression would have been | |
20641 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to | |
20642 * transform a block into a stored block. | |
20643 */ | |
20644 zip_send_bits((zip_STORED_BLOCK<<1)+eof, 3); /* send block type */ | |
20645 zip_bi_windup(); /* align on byte boundary */ | |
20646 zip_put_short(stored_len); | |
20647 zip_put_short(~stored_len); | |
20648 | |
20649 // copy block | |
20650 /* | |
20651 p = &window[block_start]; | |
20652 for(i = 0; i < stored_len; i++) | |
20653 put_byte(p[i]); | |
20654 */ | |
20655 for(i = 0; i < stored_len; i++) | |
20656 zip_put_byte(zip_window[zip_block_start + i]); | |
20657 | |
20658 } else if(static_lenb == opt_lenb) { | |
20659 zip_send_bits((zip_STATIC_TREES<<1)+eof, 3); | |
20660 zip_compress_block(zip_static_ltree, zip_static_dtree); | |
20661 } else { | |
20662 zip_send_bits((zip_DYN_TREES<<1)+eof, 3); | |
20663 zip_send_all_trees(zip_l_desc.max_code+1, | |
20664 zip_d_desc.max_code+1, | |
20665 max_blindex+1); | |
20666 zip_compress_block(zip_dyn_ltree, zip_dyn_dtree); | |
20667 } | |
20668 | |
20669 zip_init_block(); | |
20670 | |
20671 if(eof != 0) | |
20672 zip_bi_windup(); | |
20673 } | |
20674 | |
20675 /* ========================================================================== | |
20676 * Save the match info and tally the frequency counts. Return true if | |
20677 * the current block must be flushed. | |
20678 */ | |
20679 var zip_ct_tally = function( | |
20680 dist, // distance of matched string | |
20681 lc) { // match length-MIN_MATCH or unmatched char (if dist==0) | |
20682 zip_l_buf[zip_last_lit++] = lc; | |
20683 if(dist == 0) { | |
20684 // lc is the unmatched char | |
20685 zip_dyn_ltree[lc].fc++; | |
20686 } else { | |
20687 // Here, lc is the match length - MIN_MATCH | |
20688 dist--; // dist = match distance - 1 | |
20689 // Assert((ush)dist < (ush)MAX_DIST && | |
20690 // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && | |
20691 // (ush)D_CODE(dist) < (ush)D_CODES, "ct_tally: bad match"); | |
20692 | |
20693 zip_dyn_ltree[zip_length_code[lc]+zip_LITERALS+1].fc++; | |
20694 zip_dyn_dtree[zip_D_CODE(dist)].fc++; | |
20695 | |
20696 zip_d_buf[zip_last_dist++] = dist; | |
20697 zip_flags |= zip_flag_bit; | |
20698 } | |
20699 zip_flag_bit <<= 1; | |
20700 | |
20701 // Output the flags if they fill a byte | |
20702 if((zip_last_lit & 7) == 0) { | |
20703 zip_flag_buf[zip_last_flags++] = zip_flags; | |
20704 zip_flags = 0; | |
20705 zip_flag_bit = 1; | |
20706 } | |
20707 // Try to guess if it is profitable to stop the current block here | |
20708 if(zip_compr_level > 2 && (zip_last_lit & 0xfff) == 0) { | |
20709 // Compute an upper bound for the compressed length | |
20710 var out_length = zip_last_lit * 8; | |
20711 var in_length = zip_strstart - zip_block_start; | |
20712 var dcode; | |
20713 | |
20714 for(dcode = 0; dcode < zip_D_CODES; dcode++) { | |
20715 out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]); | |
20716 } | |
20717 out_length >>= 3; | |
20718 // Trace((stderr,"\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", | |
20719 // encoder->last_lit, encoder->last_dist, in_length, out_length, | |
20720 // 100L - out_length*100L/in_length)); | |
20721 if(zip_last_dist < parseInt(zip_last_lit/2) && | |
20722 out_length < parseInt(in_length/2)) | |
20723 return true; | |
20724 } | |
20725 return (zip_last_lit == zip_LIT_BUFSIZE-1 || | |
20726 zip_last_dist == zip_DIST_BUFSIZE); | |
20727 /* We avoid equality with LIT_BUFSIZE because of wraparound at 64K | |
20728 * on 16 bit machines and because stored blocks are restricted to | |
20729 * 64K-1 bytes. | |
20730 */ | |
20731 } | |
20732 | |
20733 /* ========================================================================== | |
20734 * Send the block data compressed using the given Huffman trees | |
20735 */ | |
20736 var zip_compress_block = function( | |
20737 ltree, // literal tree | |
20738 dtree) { // distance tree | |
20739 var dist; // distance of matched string | |
20740 var lc; // match length or unmatched char (if dist == 0) | |
20741 var lx = 0; // running index in l_buf | |
20742 var dx = 0; // running index in d_buf | |
20743 var fx = 0; // running index in flag_buf | |
20744 var flag = 0; // current flags | |
20745 var code; // the code to send | |
20746 var extra; // number of extra bits to send | |
20747 | |
20748 if(zip_last_lit != 0) do { | |
20749 if((lx & 7) == 0) | |
20750 flag = zip_flag_buf[fx++]; | |
20751 lc = zip_l_buf[lx++] & 0xff; | |
20752 if((flag & 1) == 0) { | |
20753 zip_SEND_CODE(lc, ltree); /* send a literal byte */ | |
20754 // Tracecv(isgraph(lc), (stderr," '%c' ", lc)); | |
20755 } else { | |
20756 // Here, lc is the match length - MIN_MATCH | |
20757 code = zip_length_code[lc]; | |
20758 zip_SEND_CODE(code+zip_LITERALS+1, ltree); // send the length code | |
20759 extra = zip_extra_lbits[code]; | |
20760 if(extra != 0) { | |
20761 lc -= zip_base_length[code]; | |
20762 zip_send_bits(lc, extra); // send the extra length bits | |
20763 } | |
20764 dist = zip_d_buf[dx++]; | |
20765 // Here, dist is the match distance - 1 | |
20766 code = zip_D_CODE(dist); | |
20767 // Assert (code < D_CODES, "bad d_code"); | |
20768 | |
20769 zip_SEND_CODE(code, dtree); // send the distance code | |
20770 extra = zip_extra_dbits[code]; | |
20771 if(extra != 0) { | |
20772 dist -= zip_base_dist[code]; | |
20773 zip_send_bits(dist, extra); // send the extra distance bits | |
20774 } | |
20775 } // literal or match pair ? | |
20776 flag >>= 1; | |
20777 } while(lx < zip_last_lit); | |
20778 | |
20779 zip_SEND_CODE(zip_END_BLOCK, ltree); | |
20780 } | |
20781 | |
20782 /* ========================================================================== | |
20783 * Send a value on a given number of bits. | |
20784 * IN assertion: length <= 16 and value fits in length bits. | |
20785 */ | |
20786 var zip_Buf_size = 16; // bit size of bi_buf | |
20787 var zip_send_bits = function( | |
20788 value, // value to send | |
20789 length) { // number of bits | |
20790 /* If not enough room in bi_buf, use (valid) bits from bi_buf and | |
20791 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | |
20792 * unused bits in value. | |
20793 */ | |
20794 if(zip_bi_valid > zip_Buf_size - length) { | |
20795 zip_bi_buf |= (value << zip_bi_valid); | |
20796 zip_put_short(zip_bi_buf); | |
20797 zip_bi_buf = (value >> (zip_Buf_size - zip_bi_valid)); | |
20798 zip_bi_valid += length - zip_Buf_size; | |
20799 } else { | |
20800 zip_bi_buf |= value << zip_bi_valid; | |
20801 zip_bi_valid += length; | |
20802 } | |
20803 } | |
20804 | |
20805 /* ========================================================================== | |
20806 * Reverse the first len bits of a code, using straightforward code (a faster | |
20807 * method would use a table) | |
20808 * IN assertion: 1 <= len <= 15 | |
20809 */ | |
20810 var zip_bi_reverse = function( | |
20811 code, // the value to invert | |
20812 len) { // its bit length | |
20813 var res = 0; | |
20814 do { | |
20815 res |= code & 1; | |
20816 code >>= 1; | |
20817 res <<= 1; | |
20818 } while(--len > 0); | |
20819 return res >> 1; | |
20820 } | |
20821 | |
20822 /* ========================================================================== | |
20823 * Write out any remaining bits in an incomplete byte. | |
20824 */ | |
20825 var zip_bi_windup = function() { | |
20826 if(zip_bi_valid > 8) { | |
20827 zip_put_short(zip_bi_buf); | |
20828 } else if(zip_bi_valid > 0) { | |
20829 zip_put_byte(zip_bi_buf); | |
20830 } | |
20831 zip_bi_buf = 0; | |
20832 zip_bi_valid = 0; | |
20833 } | |
20834 | |
20835 var zip_qoutbuf = function() { | |
20836 if(zip_outcnt != 0) { | |
20837 var q, i; | |
20838 q = zip_new_queue(); | |
20839 if(zip_qhead == null) | |
20840 zip_qhead = zip_qtail = q; | |
20841 else | |
20842 zip_qtail = zip_qtail.next = q; | |
20843 q.len = zip_outcnt - zip_outoff; | |
20844 // System.arraycopy(zip_outbuf, zip_outoff, q.ptr, 0, q.len); | |
20845 for(i = 0; i < q.len; i++) | |
20846 q.ptr[i] = zip_outbuf[zip_outoff + i]; | |
20847 zip_outcnt = zip_outoff = 0; | |
20848 } | |
20849 } | |
20850 | |
20851 var zip_deflate = function(str, level) { | |
20852 var i, j; | |
20853 | |
20854 zip_deflate_data = str; | |
20855 zip_deflate_pos = 0; | |
20856 if(typeof level == "undefined") | |
20857 level = zip_DEFAULT_LEVEL; | |
20858 zip_deflate_start(level); | |
20859 | |
20860 var buff = new Array(1024); | |
20861 var aout = []; | |
20862 while((i = zip_deflate_internal(buff, 0, buff.length)) > 0) { | |
20863 var cbuf = new Array(i); | |
20864 for(j = 0; j < i; j++){ | |
20865 cbuf[j] = String.fromCharCode(buff[j]); | |
20866 } | |
20867 aout[aout.length] = cbuf.join(""); | |
20868 } | |
20869 zip_deflate_data = null; // G.C. | |
20870 return aout.join(""); | |
20871 } | |
20872 | |
20873 // | |
20874 // end of the script of Masanao Izumo. | |
20875 // | |
20876 | |
20877 // we add the compression method for JSZip | |
20878 if(!JSZip.compressions["DEFLATE"]) { | |
20879 JSZip.compressions["DEFLATE"] = { | |
20880 magic : "\x08\x00", | |
20881 compress : zip_deflate | |
20882 } | |
20883 } else { | |
20884 JSZip.compressions["DEFLATE"].compress = zip_deflate; | |
20885 } | |
20886 | |
20887 })(); | |
20888 | |
20889 // enforcing Stuk's coding style | |
20890 // vim: set shiftwidth=3 softtabstop=3: | |
20891 /* | |
20892 * Port of a script by Masanao Izumo. | |
20893 * | |
20894 * Only changes : wrap all the variables in a function and add the | |
20895 * main function to JSZip (DEFLATE compression method). | |
20896 * Everything else was written by M. Izumo. | |
20897 * | |
20898 * Original code can be found here: http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt | |
20899 */ | |
20900 | |
20901 if(!JSZip) { | |
20902 throw "JSZip not defined"; | |
20903 } | |
20904 | |
20905 /* | |
20906 * Original: | |
20907 * http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt | |
20908 */ | |
20909 | |
20910 (function(){ | |
20911 // the original implementation leaks a global variable. | |
20912 // Defining the variable here doesn't break anything. | |
20913 var zip_fixed_bd; | |
20914 | |
20915 /* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp> | |
20916 * Version: 1.0.0.1 | |
20917 * LastModified: Dec 25 1999 | |
20918 */ | |
20919 | |
20920 /* Interface: | |
20921 * data = zip_inflate(src); | |
20922 */ | |
20923 | |
20924 /* constant parameters */ | |
20925 var zip_WSIZE = 32768; // Sliding Window size | |
20926 var zip_STORED_BLOCK = 0; | |
20927 var zip_STATIC_TREES = 1; | |
20928 var zip_DYN_TREES = 2; | |
20929 | |
20930 /* for inflate */ | |
20931 var zip_lbits = 9; // bits in base literal/length lookup table | |
20932 var zip_dbits = 6; // bits in base distance lookup table | |
20933 var zip_INBUFSIZ = 32768; // Input buffer size | |
20934 var zip_INBUF_EXTRA = 64; // Extra buffer | |
20935 | |
20936 /* variables (inflate) */ | |
20937 var zip_slide; | |
20938 var zip_wp; // current position in slide | |
20939 var zip_fixed_tl = null; // inflate static | |
20940 var zip_fixed_td; // inflate static | |
20941 var zip_fixed_bl, fixed_bd; // inflate static | |
20942 var zip_bit_buf; // bit buffer | |
20943 var zip_bit_len; // bits in bit buffer | |
20944 var zip_method; | |
20945 var zip_eof; | |
20946 var zip_copy_leng; | |
20947 var zip_copy_dist; | |
20948 var zip_tl, zip_td; // literal/length and distance decoder tables | |
20949 var zip_bl, zip_bd; // number of bits decoded by tl and td | |
20950 | |
20951 var zip_inflate_data; | |
20952 var zip_inflate_pos; | |
20953 | |
20954 | |
20955 /* constant tables (inflate) */ | |
20956 var zip_MASK_BITS = new Array( | |
20957 0x0000, | |
20958 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | |
20959 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff); | |
20960 // Tables for deflate from PKZIP's appnote.txt. | |
20961 var zip_cplens = new Array( // Copy lengths for literal codes 257..285 | |
20962 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, | |
20963 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0); | |
20964 /* note: see note #13 above about the 258 in this list. */ | |
20965 var zip_cplext = new Array( // Extra bits for literal codes 257..285 | |
20966 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | |
20967 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid | |
20968 var zip_cpdist = new Array( // Copy offsets for distance codes 0..29 | |
20969 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, | |
20970 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, | |
20971 8193, 12289, 16385, 24577); | |
20972 var zip_cpdext = new Array( // Extra bits for distance codes | |
20973 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, | |
20974 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, | |
20975 12, 12, 13, 13); | |
20976 var zip_border = new Array( // Order of the bit length code lengths | |
20977 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); | |
20978 /* objects (inflate) */ | |
20979 | |
20980 function zip_HuftList() { | |
20981 this.next = null; | |
20982 this.list = null; | |
20983 } | |
20984 | |
20985 function zip_HuftNode() { | |
20986 this.e = 0; // number of extra bits or operation | |
20987 this.b = 0; // number of bits in this code or subcode | |
20988 | |
20989 // union | |
20990 this.n = 0; // literal, length base, or distance base | |
20991 this.t = null; // (zip_HuftNode) pointer to next level of table | |
20992 } | |
20993 | |
20994 function zip_HuftBuild(b, // code lengths in bits (all assumed <= BMAX) | |
20995 n, // number of codes (assumed <= N_MAX) | |
20996 s, // number of simple-valued codes (0..s-1) | |
20997 d, // list of base values for non-simple codes | |
20998 e, // list of extra bits for non-simple codes | |
20999 mm // maximum lookup bits | |
21000 ) { | |
21001 this.BMAX = 16; // maximum bit length of any code | |
21002 this.N_MAX = 288; // maximum number of codes in any set | |
21003 this.status = 0; // 0: success, 1: incomplete table, 2: bad input | |
21004 this.root = null; // (zip_HuftList) starting table | |
21005 this.m = 0; // maximum lookup bits, returns actual | |
21006 | |
21007 /* Given a list of code lengths and a maximum table size, make a set of | |
21008 tables to decode that set of codes. Return zero on success, one if | |
21009 the given code set is incomplete (the tables are still built in this | |
21010 case), two if the input is invalid (all zero length codes or an | |
21011 oversubscribed set of lengths), and three if not enough memory. | |
21012 The code with value 256 is special, and the tables are constructed | |
21013 so that no bits beyond that code are fetched when that code is | |
21014 decoded. */ | |
21015 { | |
21016 var a; // counter for codes of length k | |
21017 var c = new Array(this.BMAX+1); // bit length count table | |
21018 var el; // length of EOB code (value 256) | |
21019 var f; // i repeats in table every f entries | |
21020 var g; // maximum code length | |
21021 var h; // table level | |
21022 var i; // counter, current code | |
21023 var j; // counter | |
21024 var k; // number of bits in current code | |
21025 var lx = new Array(this.BMAX+1); // stack of bits per table | |
21026 var p; // pointer into c[], b[], or v[] | |
21027 var pidx; // index of p | |
21028 var q; // (zip_HuftNode) points to current table | |
21029 var r = new zip_HuftNode(); // table entry for structure assignment | |
21030 var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack | |
21031 var v = new Array(this.N_MAX); // values in order of bit length | |
21032 var w; | |
21033 var x = new Array(this.BMAX+1);// bit offsets, then code stack | |
21034 var xp; // pointer into x or c | |
21035 var y; // number of dummy codes added | |
21036 var z; // number of entries in current table | |
21037 var o; | |
21038 var tail; // (zip_HuftList) | |
21039 | |
21040 tail = this.root = null; | |
21041 for(i = 0; i < c.length; i++) | |
21042 c[i] = 0; | |
21043 for(i = 0; i < lx.length; i++) | |
21044 lx[i] = 0; | |
21045 for(i = 0; i < u.length; i++) | |
21046 u[i] = null; | |
21047 for(i = 0; i < v.length; i++) | |
21048 v[i] = 0; | |
21049 for(i = 0; i < x.length; i++) | |
21050 x[i] = 0; | |
21051 | |
21052 // Generate counts for each bit length | |
21053 el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any | |
21054 p = b; pidx = 0; | |
21055 i = n; | |
21056 do { | |
21057 c[p[pidx]]++; // assume all entries <= BMAX | |
21058 pidx++; | |
21059 } while(--i > 0); | |
21060 if(c[0] == n) { // null input--all zero length codes | |
21061 this.root = null; | |
21062 this.m = 0; | |
21063 this.status = 0; | |
21064 return; | |
21065 } | |
21066 | |
21067 // Find minimum and maximum length, bound *m by those | |
21068 for(j = 1; j <= this.BMAX; j++) | |
21069 if(c[j] != 0) | |
21070 break; | |
21071 k = j; // minimum code length | |
21072 if(mm < j) | |
21073 mm = j; | |
21074 for(i = this.BMAX; i != 0; i--) | |
21075 if(c[i] != 0) | |
21076 break; | |
21077 g = i; // maximum code length | |
21078 if(mm > i) | |
21079 mm = i; | |
21080 | |
21081 // Adjust last length count to fill out codes, if needed | |
21082 for(y = 1 << j; j < i; j++, y <<= 1) | |
21083 if((y -= c[j]) < 0) { | |
21084 this.status = 2; // bad input: more codes than bits | |
21085 this.m = mm; | |
21086 return; | |
21087 } | |
21088 if((y -= c[i]) < 0) { | |
21089 this.status = 2; | |
21090 this.m = mm; | |
21091 return; | |
21092 } | |
21093 c[i] += y; | |
21094 | |
21095 // Generate starting offsets into the value table for each length | |
21096 x[1] = j = 0; | |
21097 p = c; | |
21098 pidx = 1; | |
21099 xp = 2; | |
21100 while(--i > 0) // note that i == g from above | |
21101 x[xp++] = (j += p[pidx++]); | |
21102 | |
21103 // Make a table of values in order of bit lengths | |
21104 p = b; pidx = 0; | |
21105 i = 0; | |
21106 do { | |
21107 if((j = p[pidx++]) != 0) | |
21108 v[x[j]++] = i; | |
21109 } while(++i < n); | |
21110 n = x[g]; // set n to length of v | |
21111 | |
21112 // Generate the Huffman codes and for each, make the table entries | |
21113 x[0] = i = 0; // first Huffman code is zero | |
21114 p = v; pidx = 0; // grab values in bit order | |
21115 h = -1; // no tables yet--level -1 | |
21116 w = lx[0] = 0; // no bits decoded yet | |
21117 q = null; // ditto | |
21118 z = 0; // ditto | |
21119 | |
21120 // go through the bit lengths (k already is bits in shortest code) | |
21121 for(; k <= g; k++) { | |
21122 a = c[k]; | |
21123 while(a-- > 0) { | |
21124 // here i is the Huffman code of length k bits for value p[pidx] | |
21125 // make tables up to required level | |
21126 while(k > w + lx[1 + h]) { | |
21127 w += lx[1 + h]; // add bits already decoded | |
21128 h++; | |
21129 | |
21130 // compute minimum size table less than or equal to *m bits | |
21131 z = (z = g - w) > mm ? mm : z; // upper limit | |
21132 if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table | |
21133 // too few codes for k-w bit table | |
21134 f -= a + 1; // deduct codes from patterns left | |
21135 xp = k; | |
21136 while(++j < z) { // try smaller tables up to z bits | |
21137 if((f <<= 1) <= c[++xp]) | |
21138 break; // enough codes to use up j bits | |
21139 f -= c[xp]; // else deduct codes from patterns | |
21140 } | |
21141 } | |
21142 if(w + j > el && w < el) | |
21143 j = el - w; // make EOB code end at table | |
21144 z = 1 << j; // table entries for j-bit table | |
21145 lx[1 + h] = j; // set table size in stack | |
21146 | |
21147 // allocate and link in new table | |
21148 q = new Array(z); | |
21149 for(o = 0; o < z; o++) { | |
21150 q[o] = new zip_HuftNode(); | |
21151 } | |
21152 | |
21153 if(tail == null) | |
21154 tail = this.root = new zip_HuftList(); | |
21155 else | |
21156 tail = tail.next = new zip_HuftList(); | |
21157 tail.next = null; | |
21158 tail.list = q; | |
21159 u[h] = q; // table starts after link | |
21160 | |
21161 /* connect to last table, if there is one */ | |
21162 if(h > 0) { | |
21163 x[h] = i; // save pattern for backing up | |
21164 r.b = lx[h]; // bits to dump before this table | |
21165 r.e = 16 + j; // bits in this table | |
21166 r.t = q; // pointer to this table | |
21167 j = (i & ((1 << w) - 1)) >> (w - lx[h]); | |
21168 u[h-1][j].e = r.e; | |
21169 u[h-1][j].b = r.b; | |
21170 u[h-1][j].n = r.n; | |
21171 u[h-1][j].t = r.t; | |
21172 } | |
21173 } | |
21174 | |
21175 // set up table entry in r | |
21176 r.b = k - w; | |
21177 if(pidx >= n) | |
21178 r.e = 99; // out of values--invalid code | |
21179 else if(p[pidx] < s) { | |
21180 r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code | |
21181 r.n = p[pidx++]; // simple code is just the value | |
21182 } else { | |
21183 r.e = e[p[pidx] - s]; // non-simple--look up in lists | |
21184 r.n = d[p[pidx++] - s]; | |
21185 } | |
21186 | |
21187 // fill code-like entries with r // | |
21188 f = 1 << (k - w); | |
21189 for(j = i >> w; j < z; j += f) { | |
21190 q[j].e = r.e; | |
21191 q[j].b = r.b; | |
21192 q[j].n = r.n; | |
21193 q[j].t = r.t; | |
21194 } | |
21195 | |
21196 // backwards increment the k-bit code i | |
21197 for(j = 1 << (k - 1); (i & j) != 0; j >>= 1) | |
21198 i ^= j; | |
21199 i ^= j; | |
21200 | |
21201 // backup over finished tables | |
21202 while((i & ((1 << w) - 1)) != x[h]) { | |
21203 w -= lx[h]; // don't need to update q | |
21204 h--; | |
21205 } | |
21206 } | |
21207 } | |
21208 | |
21209 /* return actual size of base table */ | |
21210 this.m = lx[1]; | |
21211 | |
21212 /* Return true (1) if we were given an incomplete table */ | |
21213 this.status = ((y != 0 && g != 1) ? 1 : 0); | |
21214 } /* end of constructor */ | |
21215 } | |
21216 | |
21217 | |
21218 /* routines (inflate) */ | |
21219 | |
21220 function zip_GET_BYTE() { | |
21221 if(zip_inflate_data.length == zip_inflate_pos) | |
21222 return -1; | |
21223 return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff; | |
21224 } | |
21225 | |
21226 function zip_NEEDBITS(n) { | |
21227 while(zip_bit_len < n) { | |
21228 zip_bit_buf |= zip_GET_BYTE() << zip_bit_len; | |
21229 zip_bit_len += 8; | |
21230 } | |
21231 } | |
21232 | |
21233 function zip_GETBITS(n) { | |
21234 return zip_bit_buf & zip_MASK_BITS[n]; | |
21235 } | |
21236 | |
21237 function zip_DUMPBITS(n) { | |
21238 zip_bit_buf >>= n; | |
21239 zip_bit_len -= n; | |
21240 } | |
21241 | |
21242 function zip_inflate_codes(buff, off, size) { | |
21243 /* inflate (decompress) the codes in a deflated (compressed) block. | |
21244 Return an error code or zero if it all goes ok. */ | |
21245 var e; // table entry flag/number of extra bits | |
21246 var t; // (zip_HuftNode) pointer to table entry | |
21247 var n; | |
21248 | |
21249 if(size == 0) | |
21250 return 0; | |
21251 | |
21252 // inflate the coded data | |
21253 n = 0; | |
21254 for(;;) { // do until end of block | |
21255 zip_NEEDBITS(zip_bl); | |
21256 t = zip_tl.list[zip_GETBITS(zip_bl)]; | |
21257 e = t.e; | |
21258 while(e > 16) { | |
21259 if(e == 99) | |
21260 return -1; | |
21261 zip_DUMPBITS(t.b); | |
21262 e -= 16; | |
21263 zip_NEEDBITS(e); | |
21264 t = t.t[zip_GETBITS(e)]; | |
21265 e = t.e; | |
21266 } | |
21267 zip_DUMPBITS(t.b); | |
21268 | |
21269 if(e == 16) { // then it's a literal | |
21270 zip_wp &= zip_WSIZE - 1; | |
21271 buff[off + n++] = zip_slide[zip_wp++] = t.n; | |
21272 if(n == size) | |
21273 return size; | |
21274 continue; | |
21275 } | |
21276 | |
21277 // exit if end of block | |
21278 if(e == 15) | |
21279 break; | |
21280 | |
21281 // it's an EOB or a length | |
21282 | |
21283 // get length of block to copy | |
21284 zip_NEEDBITS(e); | |
21285 zip_copy_leng = t.n + zip_GETBITS(e); | |
21286 zip_DUMPBITS(e); | |
21287 | |
21288 // decode distance of block to copy | |
21289 zip_NEEDBITS(zip_bd); | |
21290 t = zip_td.list[zip_GETBITS(zip_bd)]; | |
21291 e = t.e; | |
21292 | |
21293 while(e > 16) { | |
21294 if(e == 99) | |
21295 return -1; | |
21296 zip_DUMPBITS(t.b); | |
21297 e -= 16; | |
21298 zip_NEEDBITS(e); | |
21299 t = t.t[zip_GETBITS(e)]; | |
21300 e = t.e; | |
21301 } | |
21302 zip_DUMPBITS(t.b); | |
21303 zip_NEEDBITS(e); | |
21304 zip_copy_dist = zip_wp - t.n - zip_GETBITS(e); | |
21305 zip_DUMPBITS(e); | |
21306 | |
21307 // do the copy | |
21308 while(zip_copy_leng > 0 && n < size) { | |
21309 zip_copy_leng--; | |
21310 zip_copy_dist &= zip_WSIZE - 1; | |
21311 zip_wp &= zip_WSIZE - 1; | |
21312 buff[off + n++] = zip_slide[zip_wp++] | |
21313 = zip_slide[zip_copy_dist++]; | |
21314 } | |
21315 | |
21316 if(n == size) | |
21317 return size; | |
21318 } | |
21319 | |
21320 zip_method = -1; // done | |
21321 return n; | |
21322 } | |
21323 | |
21324 function zip_inflate_stored(buff, off, size) { | |
21325 /* "decompress" an inflated type 0 (stored) block. */ | |
21326 var n; | |
21327 | |
21328 // go to byte boundary | |
21329 n = zip_bit_len & 7; | |
21330 zip_DUMPBITS(n); | |
21331 | |
21332 // get the length and its complement | |
21333 zip_NEEDBITS(16); | |
21334 n = zip_GETBITS(16); | |
21335 zip_DUMPBITS(16); | |
21336 zip_NEEDBITS(16); | |
21337 if(n != ((~zip_bit_buf) & 0xffff)) | |
21338 return -1; // error in compressed data | |
21339 zip_DUMPBITS(16); | |
21340 | |
21341 // read and output the compressed data | |
21342 zip_copy_leng = n; | |
21343 | |
21344 n = 0; | |
21345 while(zip_copy_leng > 0 && n < size) { | |
21346 zip_copy_leng--; | |
21347 zip_wp &= zip_WSIZE - 1; | |
21348 zip_NEEDBITS(8); | |
21349 buff[off + n++] = zip_slide[zip_wp++] = | |
21350 zip_GETBITS(8); | |
21351 zip_DUMPBITS(8); | |
21352 } | |
21353 | |
21354 if(zip_copy_leng == 0) | |
21355 zip_method = -1; // done | |
21356 return n; | |
21357 } | |
21358 | |
21359 function zip_inflate_fixed(buff, off, size) { | |
21360 /* decompress an inflated type 1 (fixed Huffman codes) block. We should | |
21361 either replace this with a custom decoder, or at least precompute the | |
21362 Huffman tables. */ | |
21363 | |
21364 // if first time, set up tables for fixed blocks | |
21365 if(zip_fixed_tl == null) { | |
21366 var i; // temporary variable | |
21367 var l = new Array(288); // length list for huft_build | |
21368 var h; // zip_HuftBuild | |
21369 | |
21370 // literal table | |
21371 for(i = 0; i < 144; i++) | |
21372 l[i] = 8; | |
21373 for(; i < 256; i++) | |
21374 l[i] = 9; | |
21375 for(; i < 280; i++) | |
21376 l[i] = 7; | |
21377 for(; i < 288; i++) // make a complete, but wrong code set | |
21378 l[i] = 8; | |
21379 zip_fixed_bl = 7; | |
21380 | |
21381 h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext, | |
21382 zip_fixed_bl); | |
21383 if(h.status != 0) { | |
21384 alert("HufBuild error: "+h.status); | |
21385 return -1; | |
21386 } | |
21387 zip_fixed_tl = h.root; | |
21388 zip_fixed_bl = h.m; | |
21389 | |
21390 // distance table | |
21391 for(i = 0; i < 30; i++) // make an incomplete code set | |
21392 l[i] = 5; | |
21393 zip_fixed_bd = 5; | |
21394 | |
21395 h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd); | |
21396 if(h.status > 1) { | |
21397 zip_fixed_tl = null; | |
21398 alert("HufBuild error: "+h.status); | |
21399 return -1; | |
21400 } | |
21401 zip_fixed_td = h.root; | |
21402 zip_fixed_bd = h.m; | |
21403 } | |
21404 | |
21405 zip_tl = zip_fixed_tl; | |
21406 zip_td = zip_fixed_td; | |
21407 zip_bl = zip_fixed_bl; | |
21408 zip_bd = zip_fixed_bd; | |
21409 return zip_inflate_codes(buff, off, size); | |
21410 } | |
21411 | |
21412 function zip_inflate_dynamic(buff, off, size) { | |
21413 // decompress an inflated type 2 (dynamic Huffman codes) block. | |
21414 var i; // temporary variables | |
21415 var j; | |
21416 var l; // last length | |
21417 var n; // number of lengths to get | |
21418 var t; // (zip_HuftNode) literal/length code table | |
21419 var nb; // number of bit length codes | |
21420 var nl; // number of literal/length codes | |
21421 var nd; // number of distance codes | |
21422 var ll = new Array(286+30); // literal/length and distance code lengths | |
21423 var h; // (zip_HuftBuild) | |
21424 | |
21425 for(i = 0; i < ll.length; i++) | |
21426 ll[i] = 0; | |
21427 | |
21428 // read in table lengths | |
21429 zip_NEEDBITS(5); | |
21430 nl = 257 + zip_GETBITS(5); // number of literal/length codes | |
21431 zip_DUMPBITS(5); | |
21432 zip_NEEDBITS(5); | |
21433 nd = 1 + zip_GETBITS(5); // number of distance codes | |
21434 zip_DUMPBITS(5); | |
21435 zip_NEEDBITS(4); | |
21436 nb = 4 + zip_GETBITS(4); // number of bit length codes | |
21437 zip_DUMPBITS(4); | |
21438 if(nl > 286 || nd > 30) | |
21439 return -1; // bad lengths | |
21440 | |
21441 // read in bit-length-code lengths | |
21442 for(j = 0; j < nb; j++) | |
21443 { | |
21444 zip_NEEDBITS(3); | |
21445 ll[zip_border[j]] = zip_GETBITS(3); | |
21446 zip_DUMPBITS(3); | |
21447 } | |
21448 for(; j < 19; j++) | |
21449 ll[zip_border[j]] = 0; | |
21450 | |
21451 // build decoding table for trees--single level, 7 bit lookup | |
21452 zip_bl = 7; | |
21453 h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl); | |
21454 if(h.status != 0) | |
21455 return -1; // incomplete code set | |
21456 | |
21457 zip_tl = h.root; | |
21458 zip_bl = h.m; | |
21459 | |
21460 // read in literal and distance code lengths | |
21461 n = nl + nd; | |
21462 i = l = 0; | |
21463 while(i < n) { | |
21464 zip_NEEDBITS(zip_bl); | |
21465 t = zip_tl.list[zip_GETBITS(zip_bl)]; | |
21466 j = t.b; | |
21467 zip_DUMPBITS(j); | |
21468 j = t.n; | |
21469 if(j < 16) // length of code in bits (0..15) | |
21470 ll[i++] = l = j; // save last length in l | |
21471 else if(j == 16) { // repeat last length 3 to 6 times | |
21472 zip_NEEDBITS(2); | |
21473 j = 3 + zip_GETBITS(2); | |
21474 zip_DUMPBITS(2); | |
21475 if(i + j > n) | |
21476 return -1; | |
21477 while(j-- > 0) | |
21478 ll[i++] = l; | |
21479 } else if(j == 17) { // 3 to 10 zero length codes | |
21480 zip_NEEDBITS(3); | |
21481 j = 3 + zip_GETBITS(3); | |
21482 zip_DUMPBITS(3); | |
21483 if(i + j > n) | |
21484 return -1; | |
21485 while(j-- > 0) | |
21486 ll[i++] = 0; | |
21487 l = 0; | |
21488 } else { // j == 18: 11 to 138 zero length codes | |
21489 zip_NEEDBITS(7); | |
21490 j = 11 + zip_GETBITS(7); | |
21491 zip_DUMPBITS(7); | |
21492 if(i + j > n) | |
21493 return -1; | |
21494 while(j-- > 0) | |
21495 ll[i++] = 0; | |
21496 l = 0; | |
21497 } | |
21498 } | |
21499 | |
21500 // build the decoding tables for literal/length and distance codes | |
21501 zip_bl = zip_lbits; | |
21502 h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl); | |
21503 if(zip_bl == 0) // no literals or lengths | |
21504 h.status = 1; | |
21505 if(h.status != 0) { | |
21506 if(h.status == 1) | |
21507 ;// **incomplete literal tree** | |
21508 return -1; // incomplete code set | |
21509 } | |
21510 zip_tl = h.root; | |
21511 zip_bl = h.m; | |
21512 | |
21513 for(i = 0; i < nd; i++) | |
21514 ll[i] = ll[i + nl]; | |
21515 zip_bd = zip_dbits; | |
21516 h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd); | |
21517 zip_td = h.root; | |
21518 zip_bd = h.m; | |
21519 | |
21520 if(zip_bd == 0 && nl > 257) { // lengths but no distances | |
21521 // **incomplete distance tree** | |
21522 return -1; | |
21523 } | |
21524 | |
21525 if(h.status == 1) { | |
21526 ;// **incomplete distance tree** | |
21527 } | |
21528 if(h.status != 0) | |
21529 return -1; | |
21530 | |
21531 // decompress until an end-of-block code | |
21532 return zip_inflate_codes(buff, off, size); | |
21533 } | |
21534 | |
21535 function zip_inflate_start() { | |
21536 var i; | |
21537 | |
21538 if(zip_slide == null) | |
21539 zip_slide = new Array(2 * zip_WSIZE); | |
21540 zip_wp = 0; | |
21541 zip_bit_buf = 0; | |
21542 zip_bit_len = 0; | |
21543 zip_method = -1; | |
21544 zip_eof = false; | |
21545 zip_copy_leng = zip_copy_dist = 0; | |
21546 zip_tl = null; | |
21547 } | |
21548 | |
21549 function zip_inflate_internal(buff, off, size) { | |
21550 // decompress an inflated entry | |
21551 var n, i; | |
21552 | |
21553 n = 0; | |
21554 while(n < size) { | |
21555 if(zip_eof && zip_method == -1) | |
21556 return n; | |
21557 | |
21558 if(zip_copy_leng > 0) { | |
21559 if(zip_method != zip_STORED_BLOCK) { | |
21560 // STATIC_TREES or DYN_TREES | |
21561 while(zip_copy_leng > 0 && n < size) { | |
21562 zip_copy_leng--; | |
21563 zip_copy_dist &= zip_WSIZE - 1; | |
21564 zip_wp &= zip_WSIZE - 1; | |
21565 buff[off + n++] = zip_slide[zip_wp++] = | |
21566 zip_slide[zip_copy_dist++]; | |
21567 } | |
21568 } else { | |
21569 while(zip_copy_leng > 0 && n < size) { | |
21570 zip_copy_leng--; | |
21571 zip_wp &= zip_WSIZE - 1; | |
21572 zip_NEEDBITS(8); | |
21573 buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8); | |
21574 zip_DUMPBITS(8); | |
21575 } | |
21576 if(zip_copy_leng == 0) | |
21577 zip_method = -1; // done | |
21578 } | |
21579 if(n == size) | |
21580 return n; | |
21581 } | |
21582 | |
21583 if(zip_method == -1) { | |
21584 if(zip_eof) | |
21585 break; | |
21586 | |
21587 // read in last block bit | |
21588 zip_NEEDBITS(1); | |
21589 if(zip_GETBITS(1) != 0) | |
21590 zip_eof = true; | |
21591 zip_DUMPBITS(1); | |
21592 | |
21593 // read in block type | |
21594 zip_NEEDBITS(2); | |
21595 zip_method = zip_GETBITS(2); | |
21596 zip_DUMPBITS(2); | |
21597 zip_tl = null; | |
21598 zip_copy_leng = 0; | |
21599 } | |
21600 | |
21601 switch(zip_method) { | |
21602 case 0: // zip_STORED_BLOCK | |
21603 i = zip_inflate_stored(buff, off + n, size - n); | |
21604 break; | |
21605 | |
21606 case 1: // zip_STATIC_TREES | |
21607 if(zip_tl != null) | |
21608 i = zip_inflate_codes(buff, off + n, size - n); | |
21609 else | |
21610 i = zip_inflate_fixed(buff, off + n, size - n); | |
21611 break; | |
21612 | |
21613 case 2: // zip_DYN_TREES | |
21614 if(zip_tl != null) | |
21615 i = zip_inflate_codes(buff, off + n, size - n); | |
21616 else | |
21617 i = zip_inflate_dynamic(buff, off + n, size - n); | |
21618 break; | |
21619 | |
21620 default: // error | |
21621 i = -1; | |
21622 break; | |
21623 } | |
21624 | |
21625 if(i == -1) { | |
21626 if(zip_eof) | |
21627 return 0; | |
21628 return -1; | |
21629 } | |
21630 n += i; | |
21631 } | |
21632 return n; | |
21633 } | |
21634 | |
21635 function zip_inflate(str) { | |
21636 var out, buff; | |
21637 var i, j; | |
21638 | |
21639 zip_inflate_start(); | |
21640 zip_inflate_data = str; | |
21641 zip_inflate_pos = 0; | |
21642 | |
21643 buff = new Array(1024); | |
21644 out = ""; | |
21645 while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) { | |
21646 for(j = 0; j < i; j++) | |
21647 out += String.fromCharCode(buff[j]); | |
21648 } | |
21649 zip_inflate_data = null; // G.C. | |
21650 return out; | |
21651 } | |
21652 | |
21653 // | |
21654 // end of the script of Masanao Izumo. | |
21655 // | |
21656 | |
21657 // we add the compression method for JSZip | |
21658 if(!JSZip.compressions["DEFLATE"]) { | |
21659 JSZip.compressions["DEFLATE"] = { | |
21660 magic : "\x08\x00", | |
21661 uncompress : zip_inflate | |
21662 } | |
21663 } else { | |
21664 JSZip.compressions["DEFLATE"].uncompress = zip_inflate; | |
21665 } | |
21666 | |
21667 })(); | |
21668 | |
21669 // enforcing Stuk's coding style | |
21670 // vim: set shiftwidth=3 softtabstop=3: | |
21671 /** | |
21672 | |
21673 JSZip - A Javascript class for generating and reading zip files | |
21674 <http://stuartk.com/jszip> | |
21675 | |
21676 (c) 2011 David Duponchel <d.duponchel@gmail.com> | |
21677 Dual licenced under the MIT license or GPLv3. See LICENSE.markdown. | |
21678 | |
21679 **/ | |
21680 /*global JSZip,JSZipBase64 */ | |
21681 (function () { | |
21682 | |
21683 var MAX_VALUE_16BITS = 65535; | |
21684 var MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 | |
21685 | |
21686 /** | |
21687 * Prettify a string read as binary. | |
21688 * @param {string} str the string to prettify. | |
21689 * @return {string} a pretty string. | |
21690 */ | |
21691 var pretty = function (str) { | |
21692 var res = '', code, i; | |
21693 for (i = 0; i < (str||"").length; i++) { | |
21694 code = str.charCodeAt(i); | |
21695 res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); | |
21696 } | |
21697 return res; | |
21698 }; | |
21699 | |
21700 /** | |
21701 * Find a compression registered in JSZip. | |
21702 * @param {string} compressionMethod the method magic to find. | |
21703 * @return {Object|null} the JSZip compression object, null if none found. | |
21704 */ | |
21705 var findCompression = function (compressionMethod) { | |
21706 for (var method in JSZip.compressions) { | |
21707 if( !JSZip.compressions.hasOwnProperty(method) ) { continue; } | |
21708 if (JSZip.compressions[method].magic === compressionMethod) { | |
21709 return JSZip.compressions[method]; | |
21710 } | |
21711 } | |
21712 return null; | |
21713 }; | |
21714 | |
21715 // class StreamReader {{{ | |
21716 /** | |
21717 * Read bytes from a stream. | |
21718 * Developer tip : when debugging, a watch on pretty(this.reader.stream.slice(this.reader.index)) | |
21719 * is very useful :) | |
21720 * @constructor | |
21721 * @param {String|ArrayBuffer|Uint8Array} stream the stream to read. | |
21722 */ | |
21723 function StreamReader(stream) { | |
21724 this.stream = ""; | |
21725 if (JSZip.support.uint8array && stream instanceof Uint8Array) { | |
21726 this.stream = JSZip.utils.uint8Array2String(stream); | |
21727 } else if (JSZip.support.arraybuffer && stream instanceof ArrayBuffer) { | |
21728 var bufferView = new Uint8Array(stream); | |
21729 this.stream = JSZip.utils.uint8Array2String(bufferView); | |
21730 } else { | |
21731 this.stream = JSZip.utils.string2binary(stream); | |
21732 } | |
21733 this.index = 0; | |
21734 } | |
21735 StreamReader.prototype = { | |
21736 /** | |
21737 * Check that the offset will not go too far. | |
21738 * @param {string} offset the additional offset to check. | |
21739 * @throws {Error} an Error if the offset is out of bounds. | |
21740 */ | |
21741 checkOffset : function (offset) { | |
21742 this.checkIndex(this.index + offset); | |
21743 }, | |
21744 /** | |
21745 * Check that the specifed index will not be too far. | |
21746 * @param {string} newIndex the index to check. | |
21747 * @throws {Error} an Error if the index is out of bounds. | |
21748 */ | |
21749 checkIndex : function (newIndex) { | |
21750 if (this.stream.length < newIndex || newIndex < 0) { | |
21751 throw new Error("End of stream reached (stream length = " + | |
21752 this.stream.length + ", asked index = " + | |
21753 (newIndex) + "). Corrupted zip ?"); | |
21754 } | |
21755 }, | |
21756 /** | |
21757 * Change the index. | |
21758 * @param {number} newIndex The new index. | |
21759 * @throws {Error} if the new index is out of the stream. | |
21760 */ | |
21761 setIndex : function (newIndex) { | |
21762 this.checkIndex(newIndex); | |
21763 this.index = newIndex; | |
21764 }, | |
21765 /** | |
21766 * Skip the next n bytes. | |
21767 * @param {number} n the number of bytes to skip. | |
21768 * @throws {Error} if the new index is out of the stream. | |
21769 */ | |
21770 skip : function (n) { | |
21771 this.setIndex(this.index + n); | |
21772 }, | |
21773 /** | |
21774 * Get the byte at the specified index. | |
21775 * @param {number} i the index to use. | |
21776 * @return {number} a byte. | |
21777 */ | |
21778 byteAt : function(i) { | |
21779 return this.stream.charCodeAt(i); | |
21780 }, | |
21781 /** | |
21782 * Get the next number with a given byte size. | |
21783 * @param {number} size the number of bytes to read. | |
21784 * @return {number} the corresponding number. | |
21785 */ | |
21786 readInt : function (size) { | |
21787 var result = 0, i; | |
21788 this.checkOffset(size); | |
21789 for(i = this.index + size - 1; i >= this.index; i--) { | |
21790 result = (result << 8) + this.byteAt(i); | |
21791 } | |
21792 this.index += size; | |
21793 return result; | |
21794 }, | |
21795 /** | |
21796 * Get the next string with a given byte size. | |
21797 * @param {number} size the number of bytes to read. | |
21798 * @return {string} the corresponding string. | |
21799 */ | |
21800 readString : function (size) { | |
21801 this.checkOffset(size); | |
21802 // this will work because the constructor applied the "& 0xff" mask. | |
21803 var result = this.stream.slice(this.index, this.index + size); | |
21804 this.index += size; | |
21805 return result; | |
21806 }, | |
21807 /** | |
21808 * Get the next date. | |
21809 * @return {Date} the date. | |
21810 */ | |
21811 readDate : function () { | |
21812 var dostime = this.readInt(4); | |
21813 return new Date( | |
21814 ((dostime >> 25) & 0x7f) + 1980, // year | |
21815 ((dostime >> 21) & 0x0f) - 1, // month | |
21816 (dostime >> 16) & 0x1f, // day | |
21817 (dostime >> 11) & 0x1f, // hour | |
21818 (dostime >> 5) & 0x3f, // minute | |
21819 (dostime & 0x1f) << 1); // second | |
21820 } | |
21821 }; | |
21822 // }}} end of StreamReader | |
21823 | |
21824 // class ZipEntry {{{ | |
21825 /** | |
21826 * An entry in the zip file. | |
21827 * @constructor | |
21828 * @param {Object} options Options of the current file. | |
21829 * @param {Object} loadOptions Options for loading the stream. | |
21830 */ | |
21831 function ZipEntry(options, loadOptions) { | |
21832 this.options = options; | |
21833 this.loadOptions = loadOptions; | |
21834 } | |
21835 ZipEntry.prototype = { | |
21836 /** | |
21837 * say if the file is encrypted. | |
21838 * @return {boolean} true if the file is encrypted, false otherwise. | |
21839 */ | |
21840 isEncrypted : function () { | |
21841 // bit 1 is set | |
21842 return (this.bitFlag & 0x0001) === 0x0001; | |
21843 }, | |
21844 /** | |
21845 * say if the file has utf-8 filename/comment. | |
21846 * @return {boolean} true if the filename/comment is in utf-8, false otherwise. | |
21847 */ | |
21848 useUTF8 : function () { | |
21849 // bit 11 is set | |
21850 return (this.bitFlag & 0x0800) === 0x0800; | |
21851 }, | |
21852 /** | |
21853 * Read the local part of a zip file and add the info in this object. | |
21854 * @param {StreamReader} reader the reader to use. | |
21855 */ | |
21856 readLocalPart : function(reader) { | |
21857 var compression, localExtraFieldsLength; | |
21858 | |
21859 // we already know everything from the central dir ! | |
21860 // If the central dir data are false, we are doomed. | |
21861 // On the bright side, the local part is scary : zip64, data descriptors, both, etc. | |
21862 // The less data we get here, the more reliable this should be. | |
21863 // Let's skip the whole header and dash to the data ! | |
21864 reader.skip(22); | |
21865 // in some zip created on windows, the filename stored in the central dir contains \ instead of /. | |
21866 // Strangely, the filename here is OK. | |
21867 // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes | |
21868 // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... | |
21869 // Search "unzip mismatching "local" filename continuing with "central" filename version" on | |
21870 // the internet. | |
21871 // | |
21872 // I think I see the logic here : the central directory is used to display | |
21873 // content and the local directory is used to extract the files. Mixing / and \ | |
21874 // may be used to display \ to windows users and use / when extracting the files. | |
21875 // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 | |
21876 this.fileNameLength = reader.readInt(2); | |
21877 localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir | |
21878 this.fileName = reader.readString(this.fileNameLength); | |
21879 reader.skip(localExtraFieldsLength); | |
21880 | |
21881 if (this.compressedSize == -1 || this.uncompressedSize == -1) { | |
21882 throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + | |
21883 "(compressedSize == -1 || uncompressedSize == -1)"); | |
21884 } | |
21885 this.compressedFileData = reader.readString(this.compressedSize); | |
21886 | |
21887 compression = findCompression(this.compressionMethod); | |
21888 if (compression === null) { // no compression found | |
21889 throw new Error("Corrupted zip : compression " + pretty(this.compressionMethod) + | |
21890 " unknown (inner file : " + this.fileName + ")"); | |
21891 } | |
21892 this.uncompressedFileData = compression.uncompress(this.compressedFileData); | |
21893 | |
21894 if (this.uncompressedFileData.length !== this.uncompressedSize) { | |
21895 throw new Error("Bug : uncompressed data size mismatch"); | |
21896 } | |
21897 | |
21898 if (this.loadOptions.checkCRC32 && JSZip.prototype.crc32(this.uncompressedFileData) !== this.crc32) { | |
21899 throw new Error("Corrupted zip : CRC32 mismatch"); | |
21900 } | |
21901 }, | |
21902 | |
21903 /** | |
21904 * Read the central part of a zip file and add the info in this object. | |
21905 * @param {StreamReader} reader the reader to use. | |
21906 */ | |
21907 readCentralPart : function(reader) { | |
21908 this.versionMadeBy = reader.readString(2); | |
21909 this.versionNeeded = reader.readInt(2); | |
21910 this.bitFlag = reader.readInt(2); | |
21911 this.compressionMethod = reader.readString(2); | |
21912 this.date = reader.readDate(); | |
21913 this.crc32 = reader.readInt(4); | |
21914 this.compressedSize = reader.readInt(4); | |
21915 this.uncompressedSize = reader.readInt(4); | |
21916 this.fileNameLength = reader.readInt(2); | |
21917 this.extraFieldsLength = reader.readInt(2); | |
21918 this.fileCommentLength = reader.readInt(2); | |
21919 this.diskNumberStart = reader.readInt(2); | |
21920 this.internalFileAttributes = reader.readInt(2); | |
21921 this.externalFileAttributes = reader.readInt(4); | |
21922 this.localHeaderOffset = reader.readInt(4); | |
21923 | |
21924 if (this.isEncrypted()) { | |
21925 throw new Error("Encrypted zip are not supported"); | |
21926 } | |
21927 | |
21928 this.fileName = reader.readString(this.fileNameLength); | |
21929 this.readExtraFields(reader); | |
21930 this.parseZIP64ExtraField(reader); | |
21931 this.fileComment = reader.readString(this.fileCommentLength); | |
21932 | |
21933 // warning, this is true only for zip with madeBy == DOS (plateform dependent feature) | |
21934 this.dir = this.externalFileAttributes & 0x00000010 ? true : false; | |
21935 }, | |
21936 /** | |
21937 * Parse the ZIP64 extra field and merge the info in the current ZipEntry. | |
21938 * @param {StreamReader} reader the reader to use. | |
21939 */ | |
21940 parseZIP64ExtraField : function(reader) { | |
21941 | |
21942 if(!this.extraFields[0x0001]) { | |
21943 return; | |
21944 } | |
21945 | |
21946 // should be something, preparing the extra reader | |
21947 var extraReader = new StreamReader(this.extraFields[0x0001].value); | |
21948 | |
21949 // I really hope that these 64bits integer can fit in 32 bits integer, because js | |
21950 // won't let us have more. | |
21951 if(this.uncompressedSize === MAX_VALUE_32BITS) { | |
21952 this.uncompressedSize = extraReader.readInt(8); | |
21953 } | |
21954 if(this.compressedSize === MAX_VALUE_32BITS) { | |
21955 this.compressedSize = extraReader.readInt(8); | |
21956 } | |
21957 if(this.localHeaderOffset === MAX_VALUE_32BITS) { | |
21958 this.localHeaderOffset = extraReader.readInt(8); | |
21959 } | |
21960 if(this.diskNumberStart === MAX_VALUE_32BITS) { | |
21961 this.diskNumberStart = extraReader.readInt(4); | |
21962 } | |
21963 }, | |
21964 /** | |
21965 * Read the central part of a zip file and add the info in this object. | |
21966 * @param {StreamReader} reader the reader to use. | |
21967 */ | |
21968 readExtraFields : function(reader) { | |
21969 var start = reader.index, | |
21970 extraFieldId, | |
21971 extraFieldLength, | |
21972 extraFieldValue; | |
21973 | |
21974 this.extraFields = this.extraFields || {}; | |
21975 | |
21976 while (reader.index < start + this.extraFieldsLength) { | |
21977 extraFieldId = reader.readInt(2); | |
21978 extraFieldLength = reader.readInt(2); | |
21979 extraFieldValue = reader.readString(extraFieldLength); | |
21980 | |
21981 this.extraFields[extraFieldId] = { | |
21982 id: extraFieldId, | |
21983 length: extraFieldLength, | |
21984 value: extraFieldValue | |
21985 }; | |
21986 } | |
21987 }, | |
21988 /** | |
21989 * Apply an UTF8 transformation if needed. | |
21990 */ | |
21991 handleUTF8 : function() { | |
21992 if (this.useUTF8()) { | |
21993 this.fileName = JSZip.prototype.utf8decode(this.fileName); | |
21994 this.fileComment = JSZip.prototype.utf8decode(this.fileComment); | |
21995 } | |
21996 } | |
21997 }; | |
21998 // }}} end of ZipEntry | |
21999 | |
22000 // class ZipEntries {{{ | |
22001 /** | |
22002 * All the entries in the zip file. | |
22003 * @constructor | |
22004 * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load. | |
22005 * @param {Object} loadOptions Options for loading the stream. | |
22006 */ | |
22007 function ZipEntries(data, loadOptions) { | |
22008 this.files = []; | |
22009 this.loadOptions = loadOptions; | |
22010 if (data) { | |
22011 this.load(data); | |
22012 } | |
22013 } | |
22014 ZipEntries.prototype = { | |
22015 /** | |
22016 * Check that the reader is on the speficied signature. | |
22017 * @param {string} expectedSignature the expected signature. | |
22018 * @throws {Error} if it is an other signature. | |
22019 */ | |
22020 checkSignature : function(expectedSignature) { | |
22021 var signature = this.reader.readString(4); | |
22022 if (signature !== expectedSignature) { | |
22023 throw new Error("Corrupted zip or bug : unexpected signature " + | |
22024 "(" + pretty(signature) + ", expected " + pretty(expectedSignature) + ")"); | |
22025 } | |
22026 }, | |
22027 /** | |
22028 * Read the end of the central directory. | |
22029 */ | |
22030 readBlockEndOfCentral : function () { | |
22031 this.diskNumber = this.reader.readInt(2); | |
22032 this.diskWithCentralDirStart = this.reader.readInt(2); | |
22033 this.centralDirRecordsOnThisDisk = this.reader.readInt(2); | |
22034 this.centralDirRecords = this.reader.readInt(2); | |
22035 this.centralDirSize = this.reader.readInt(4); | |
22036 this.centralDirOffset = this.reader.readInt(4); | |
22037 | |
22038 this.zipCommentLength = this.reader.readInt(2); | |
22039 this.zipComment = this.reader.readString(this.zipCommentLength); | |
22040 }, | |
22041 /** | |
22042 * Read the end of the Zip 64 central directory. | |
22043 * Not merged with the method readEndOfCentral : | |
22044 * The end of central can coexist with its Zip64 brother, | |
22045 * I don't want to read the wrong number of bytes ! | |
22046 */ | |
22047 readBlockZip64EndOfCentral : function () { | |
22048 this.zip64EndOfCentralSize = this.reader.readInt(8); | |
22049 this.versionMadeBy = this.reader.readString(2); | |
22050 this.versionNeeded = this.reader.readInt(2); | |
22051 this.diskNumber = this.reader.readInt(4); | |
22052 this.diskWithCentralDirStart = this.reader.readInt(4); | |
22053 this.centralDirRecordsOnThisDisk = this.reader.readInt(8); | |
22054 this.centralDirRecords = this.reader.readInt(8); | |
22055 this.centralDirSize = this.reader.readInt(8); | |
22056 this.centralDirOffset = this.reader.readInt(8); | |
22057 | |
22058 this.zip64ExtensibleData = {}; | |
22059 var extraDataSize = this.zip64EndOfCentralSize - 44, | |
22060 index = 0, | |
22061 extraFieldId, | |
22062 extraFieldLength, | |
22063 extraFieldValue; | |
22064 while(index < extraDataSize) { | |
22065 extraFieldId = this.reader.readInt(2); | |
22066 extraFieldLength = this.reader.readInt(4); | |
22067 extraFieldValue = this.reader.readString(extraFieldLength); | |
22068 this.zip64ExtensibleData[extraFieldId] = { | |
22069 id: extraFieldId, | |
22070 length: extraFieldLength, | |
22071 value: extraFieldValue | |
22072 }; | |
22073 } | |
22074 }, | |
22075 /** | |
22076 * Read the end of the Zip 64 central directory locator. | |
22077 */ | |
22078 readBlockZip64EndOfCentralLocator : function () { | |
22079 this.diskWithZip64CentralDirStart = this.reader.readInt(4); | |
22080 this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); | |
22081 this.disksCount = this.reader.readInt(4); | |
22082 if (this.disksCount > 1) { | |
22083 throw new Error("Multi-volumes zip are not supported"); | |
22084 } | |
22085 }, | |
22086 /** | |
22087 * Read the local files, based on the offset read in the central part. | |
22088 */ | |
22089 readLocalFiles : function() { | |
22090 var i, file; | |
22091 for(i = 0; i < this.files.length; i++) { | |
22092 file = this.files[i]; | |
22093 this.reader.setIndex(file.localHeaderOffset); | |
22094 this.checkSignature(JSZip.signature.LOCAL_FILE_HEADER); | |
22095 file.readLocalPart(this.reader); | |
22096 file.handleUTF8(); | |
22097 } | |
22098 }, | |
22099 /** | |
22100 * Read the central directory. | |
22101 */ | |
22102 readCentralDir : function() { | |
22103 var file; | |
22104 | |
22105 this.reader.setIndex(this.centralDirOffset); | |
22106 while(this.reader.readString(4) === JSZip.signature.CENTRAL_FILE_HEADER) { | |
22107 file = new ZipEntry({ | |
22108 zip64: this.zip64 | |
22109 }, this.loadOptions); | |
22110 file.readCentralPart(this.reader); | |
22111 this.files.push(file); | |
22112 } | |
22113 }, | |
22114 /** | |
22115 * Read the end of central directory. | |
22116 */ | |
22117 readEndOfCentral : function() { | |
22118 var offset = this.reader.stream.lastIndexOf(JSZip.signature.CENTRAL_DIRECTORY_END); | |
22119 if (offset === -1) { | |
22120 throw new Error("Corrupted zip : can't find end of central directory"); | |
22121 } | |
22122 this.reader.setIndex(offset); | |
22123 this.checkSignature(JSZip.signature.CENTRAL_DIRECTORY_END); | |
22124 this.readBlockEndOfCentral(); | |
22125 | |
22126 | |
22127 /* extract from the zip spec : | |
22128 4) If one of the fields in the end of central directory | |
22129 record is too small to hold required data, the field | |
22130 should be set to -1 (0xFFFF or 0xFFFFFFFF) and the | |
22131 ZIP64 format record should be created. | |
22132 5) The end of central directory record and the | |
22133 Zip64 end of central directory locator record must | |
22134 reside on the same disk when splitting or spanning | |
22135 an archive. | |
22136 */ | |
22137 if ( this.diskNumber === MAX_VALUE_16BITS | |
22138 || this.diskWithCentralDirStart === MAX_VALUE_16BITS | |
22139 || this.centralDirRecordsOnThisDisk === MAX_VALUE_16BITS | |
22140 || this.centralDirRecords === MAX_VALUE_16BITS | |
22141 || this.centralDirSize === MAX_VALUE_32BITS | |
22142 || this.centralDirOffset === MAX_VALUE_32BITS | |
22143 ) { | |
22144 this.zip64 = true; | |
22145 | |
22146 /* | |
22147 Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from | |
22148 the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents | |
22149 all numbers as 64-bit double precision IEEE 754 floating point numbers. | |
22150 So, we have 53bits for integers and bitwise operations treat everything as 32bits. | |
22151 see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators | |
22152 and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 | |
22153 */ | |
22154 | |
22155 // should look for a zip64 EOCD locator | |
22156 offset = this.reader.stream.lastIndexOf(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR); | |
22157 if (offset === -1) { | |
22158 throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator"); | |
22159 } | |
22160 this.reader.setIndex(offset); | |
22161 this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR); | |
22162 this.readBlockZip64EndOfCentralLocator(); | |
22163 | |
22164 // now the zip64 EOCD record | |
22165 this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); | |
22166 this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_END); | |
22167 this.readBlockZip64EndOfCentral(); | |
22168 } | |
22169 }, | |
22170 /** | |
22171 * Read a zip file and create ZipEntries. | |
22172 * @param {String|ArrayBuffer|Uint8Array} data the binary string representing a zip file. | |
22173 */ | |
22174 load : function(data) { | |
22175 this.reader = new StreamReader(data); | |
22176 | |
22177 this.readEndOfCentral(); | |
22178 this.readCentralDir(); | |
22179 this.readLocalFiles(); | |
22180 } | |
22181 }; | |
22182 // }}} end of ZipEntries | |
22183 | |
22184 /** | |
22185 * Implementation of the load method of JSZip. | |
22186 * It uses the above classes to decode a zip file, and load every files. | |
22187 * @param {String|ArrayBuffer|Uint8Array} data the data to load. | |
22188 * @param {Object} options Options for loading the stream. | |
22189 * options.base64 : is the stream in base64 ? default : false | |
22190 */ | |
22191 JSZip.prototype.load = function(data, options) { | |
22192 var files, zipEntries, i, input; | |
22193 options = options || {}; | |
22194 if(options.base64) { | |
22195 data = JSZipBase64.decode(data); | |
22196 } | |
22197 | |
22198 zipEntries = new ZipEntries(data, options); | |
22199 files = zipEntries.files; | |
22200 for (i = 0; i < files.length; i++) { | |
22201 input = files[i]; | |
22202 this.file(input.fileName, input.uncompressedFileData, { | |
22203 binary:true, | |
22204 optimizedBinaryString:true, | |
22205 date:input.date, | |
22206 dir:input.dir | |
22207 }); | |
22208 } | |
22209 | |
22210 return this; | |
22211 }; | |
22212 | |
22213 }()); | |
22214 // enforcing Stuk's coding style | |
22215 // vim: set shiftwidth=3 softtabstop=3 foldmethod=marker: | |
22216 //! moment.js | |
22217 //! version : 2.5.1 | |
22218 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors | |
22219 //! license : MIT | |
22220 //! momentjs.com | |
22221 | |
22222 (function (undefined) { | |
22223 | |
22224 /************************************ | |
22225 Constants | |
22226 ************************************/ | |
22227 | |
22228 var moment, | |
22229 VERSION = "2.5.1", | |
22230 global = this, | |
22231 round = Math.round, | |
22232 i, | |
22233 | |
22234 YEAR = 0, | |
22235 MONTH = 1, | |
22236 DATE = 2, | |
22237 HOUR = 3, | |
22238 MINUTE = 4, | |
22239 SECOND = 5, | |
22240 MILLISECOND = 6, | |
22241 | |
22242 // internal storage for language config files | |
22243 languages = {}, | |
22244 | |
22245 // moment internal properties | |
22246 momentProperties = { | |
22247 _isAMomentObject: null, | |
22248 _i : null, | |
22249 _f : null, | |
22250 _l : null, | |
22251 _strict : null, | |
22252 _isUTC : null, | |
22253 _offset : null, // optional. Combine with _isUTC | |
22254 _pf : null, | |
22255 _lang : null // optional | |
22256 }, | |
22257 | |
22258 // check for nodeJS | |
22259 hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'), | |
22260 | |
22261 // ASP.NET json date format regex | |
22262 aspNetJsonRegex = /^\/?Date\((\-?\d+)/i, | |
22263 aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/, | |
22264 | |
22265 // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html | |
22266 // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere | |
22267 isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/, | |
22268 | |
22269 // format tokens | |
22270 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, | |
22271 localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g, | |
22272 | |
22273 // parsing token regexes | |
22274 parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99 | |
22275 parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999 | |
22276 parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999 | |
22277 parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999 | |
22278 parseTokenDigits = /\d+/, // nonzero number of digits | |
22279 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. | |
22280 parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z | |
22281 parseTokenT = /T/i, // T (ISO separator) | |
22282 parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 | |
22283 | |
22284 //strict parsing regexes | |
22285 parseTokenOneDigit = /\d/, // 0 - 9 | |
22286 parseTokenTwoDigits = /\d\d/, // 00 - 99 | |
22287 parseTokenThreeDigits = /\d{3}/, // 000 - 999 | |
22288 parseTokenFourDigits = /\d{4}/, // 0000 - 9999 | |
22289 parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999 | |
22290 parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf | |
22291 | |
22292 // iso 8601 regex | |
22293 // 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) | |
22294 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)?)?$/, | |
22295 | |
22296 isoFormat = 'YYYY-MM-DDTHH:mm:ssZ', | |
22297 | |
22298 isoDates = [ | |
22299 ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], | |
22300 ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], | |
22301 ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], | |
22302 ['GGGG-[W]WW', /\d{4}-W\d{2}/], | |
22303 ['YYYY-DDD', /\d{4}-\d{3}/] | |
22304 ], | |
22305 | |
22306 // iso time formats and regexes | |
22307 isoTimes = [ | |
22308 ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/], | |
22309 ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], | |
22310 ['HH:mm', /(T| )\d\d:\d\d/], | |
22311 ['HH', /(T| )\d\d/] | |
22312 ], | |
22313 | |
22314 // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"] | |
22315 parseTimezoneChunker = /([\+\-]|\d\d)/gi, | |
22316 | |
22317 // getter and setter names | |
22318 proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'), | |
22319 unitMillisecondFactors = { | |
22320 'Milliseconds' : 1, | |
22321 'Seconds' : 1e3, | |
22322 'Minutes' : 6e4, | |
22323 'Hours' : 36e5, | |
22324 'Days' : 864e5, | |
22325 'Months' : 2592e6, | |
22326 'Years' : 31536e6 | |
22327 }, | |
22328 | |
22329 unitAliases = { | |
22330 ms : 'millisecond', | |
22331 s : 'second', | |
22332 m : 'minute', | |
22333 h : 'hour', | |
22334 d : 'day', | |
22335 D : 'date', | |
22336 w : 'week', | |
22337 W : 'isoWeek', | |
22338 M : 'month', | |
22339 y : 'year', | |
22340 DDD : 'dayOfYear', | |
22341 e : 'weekday', | |
22342 E : 'isoWeekday', | |
22343 gg: 'weekYear', | |
22344 GG: 'isoWeekYear' | |
22345 }, | |
22346 | |
22347 camelFunctions = { | |
22348 dayofyear : 'dayOfYear', | |
22349 isoweekday : 'isoWeekday', | |
22350 isoweek : 'isoWeek', | |
22351 weekyear : 'weekYear', | |
22352 isoweekyear : 'isoWeekYear' | |
22353 }, | |
22354 | |
22355 // format function strings | |
22356 formatFunctions = {}, | |
22357 | |
22358 // tokens to ordinalize and pad | |
22359 ordinalizeTokens = 'DDD w W M D d'.split(' '), | |
22360 paddedTokens = 'M D H h m s w W'.split(' '), | |
22361 | |
22362 formatTokenFunctions = { | |
22363 M : function () { | |
22364 return this.month() + 1; | |
22365 }, | |
22366 MMM : function (format) { | |
22367 return this.lang().monthsShort(this, format); | |
22368 }, | |
22369 MMMM : function (format) { | |
22370 return this.lang().months(this, format); | |
22371 }, | |
22372 D : function () { | |
22373 return this.date(); | |
22374 }, | |
22375 DDD : function () { | |
22376 return this.dayOfYear(); | |
22377 }, | |
22378 d : function () { | |
22379 return this.day(); | |
22380 }, | |
22381 dd : function (format) { | |
22382 return this.lang().weekdaysMin(this, format); | |
22383 }, | |
22384 ddd : function (format) { | |
22385 return this.lang().weekdaysShort(this, format); | |
22386 }, | |
22387 dddd : function (format) { | |
22388 return this.lang().weekdays(this, format); | |
22389 }, | |
22390 w : function () { | |
22391 return this.week(); | |
22392 }, | |
22393 W : function () { | |
22394 return this.isoWeek(); | |
22395 }, | |
22396 YY : function () { | |
22397 return leftZeroFill(this.year() % 100, 2); | |
22398 }, | |
22399 YYYY : function () { | |
22400 return leftZeroFill(this.year(), 4); | |
22401 }, | |
22402 YYYYY : function () { | |
22403 return leftZeroFill(this.year(), 5); | |
22404 }, | |
22405 YYYYYY : function () { | |
22406 var y = this.year(), sign = y >= 0 ? '+' : '-'; | |
22407 return sign + leftZeroFill(Math.abs(y), 6); | |
22408 }, | |
22409 gg : function () { | |
22410 return leftZeroFill(this.weekYear() % 100, 2); | |
22411 }, | |
22412 gggg : function () { | |
22413 return leftZeroFill(this.weekYear(), 4); | |
22414 }, | |
22415 ggggg : function () { | |
22416 return leftZeroFill(this.weekYear(), 5); | |
22417 }, | |
22418 GG : function () { | |
22419 return leftZeroFill(this.isoWeekYear() % 100, 2); | |
22420 }, | |
22421 GGGG : function () { | |
22422 return leftZeroFill(this.isoWeekYear(), 4); | |
22423 }, | |
22424 GGGGG : function () { | |
22425 return leftZeroFill(this.isoWeekYear(), 5); | |
22426 }, | |
22427 e : function () { | |
22428 return this.weekday(); | |
22429 }, | |
22430 E : function () { | |
22431 return this.isoWeekday(); | |
22432 }, | |
22433 a : function () { | |
22434 return this.lang().meridiem(this.hours(), this.minutes(), true); | |
22435 }, | |
22436 A : function () { | |
22437 return this.lang().meridiem(this.hours(), this.minutes(), false); | |
22438 }, | |
22439 H : function () { | |
22440 return this.hours(); | |
22441 }, | |
22442 h : function () { | |
22443 return this.hours() % 12 || 12; | |
22444 }, | |
22445 m : function () { | |
22446 return this.minutes(); | |
22447 }, | |
22448 s : function () { | |
22449 return this.seconds(); | |
22450 }, | |
22451 S : function () { | |
22452 return toInt(this.milliseconds() / 100); | |
22453 }, | |
22454 SS : function () { | |
22455 return leftZeroFill(toInt(this.milliseconds() / 10), 2); | |
22456 }, | |
22457 SSS : function () { | |
22458 return leftZeroFill(this.milliseconds(), 3); | |
22459 }, | |
22460 SSSS : function () { | |
22461 return leftZeroFill(this.milliseconds(), 3); | |
22462 }, | |
22463 Z : function () { | |
22464 var a = -this.zone(), | |
22465 b = "+"; | |
22466 if (a < 0) { | |
22467 a = -a; | |
22468 b = "-"; | |
22469 } | |
22470 return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2); | |
22471 }, | |
22472 ZZ : function () { | |
22473 var a = -this.zone(), | |
22474 b = "+"; | |
22475 if (a < 0) { | |
22476 a = -a; | |
22477 b = "-"; | |
22478 } | |
22479 return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2); | |
22480 }, | |
22481 z : function () { | |
22482 return this.zoneAbbr(); | |
22483 }, | |
22484 zz : function () { | |
22485 return this.zoneName(); | |
22486 }, | |
22487 X : function () { | |
22488 return this.unix(); | |
22489 }, | |
22490 Q : function () { | |
22491 return this.quarter(); | |
22492 } | |
22493 }, | |
22494 | |
22495 lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin']; | |
22496 | |
22497 function defaultParsingFlags() { | |
22498 // We need to deep clone this object, and es5 standard is not very | |
22499 // helpful. | |
22500 return { | |
22501 empty : false, | |
22502 unusedTokens : [], | |
22503 unusedInput : [], | |
22504 overflow : -2, | |
22505 charsLeftOver : 0, | |
22506 nullInput : false, | |
22507 invalidMonth : null, | |
22508 invalidFormat : false, | |
22509 userInvalidated : false, | |
22510 iso: false | |
22511 }; | |
22512 } | |
22513 | |
22514 function padToken(func, count) { | |
22515 return function (a) { | |
22516 return leftZeroFill(func.call(this, a), count); | |
22517 }; | |
22518 } | |
22519 function ordinalizeToken(func, period) { | |
22520 return function (a) { | |
22521 return this.lang().ordinal(func.call(this, a), period); | |
22522 }; | |
22523 } | |
22524 | |
22525 while (ordinalizeTokens.length) { | |
22526 i = ordinalizeTokens.pop(); | |
22527 formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i); | |
22528 } | |
22529 while (paddedTokens.length) { | |
22530 i = paddedTokens.pop(); | |
22531 formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2); | |
22532 } | |
22533 formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3); | |
22534 | |
22535 | |
22536 /************************************ | |
22537 Constructors | |
22538 ************************************/ | |
22539 | |
22540 function Language() { | |
22541 | |
22542 } | |
22543 | |
22544 // Moment prototype object | |
22545 function Moment(config) { | |
22546 checkOverflow(config); | |
22547 extend(this, config); | |
22548 } | |
22549 | |
22550 // Duration Constructor | |
22551 function Duration(duration) { | |
22552 var normalizedInput = normalizeObjectUnits(duration), | |
22553 years = normalizedInput.year || 0, | |
22554 months = normalizedInput.month || 0, | |
22555 weeks = normalizedInput.week || 0, | |
22556 days = normalizedInput.day || 0, | |
22557 hours = normalizedInput.hour || 0, | |
22558 minutes = normalizedInput.minute || 0, | |
22559 seconds = normalizedInput.second || 0, | |
22560 milliseconds = normalizedInput.millisecond || 0; | |
22561 | |
22562 // representation for dateAddRemove | |
22563 this._milliseconds = +milliseconds + | |
22564 seconds * 1e3 + // 1000 | |
22565 minutes * 6e4 + // 1000 * 60 | |
22566 hours * 36e5; // 1000 * 60 * 60 | |
22567 // Because of dateAddRemove treats 24 hours as different from a | |
22568 // day when working around DST, we need to store them separately | |
22569 this._days = +days + | |
22570 weeks * 7; | |
22571 // It is impossible translate months into days without knowing | |
22572 // which months you are are talking about, so we have to store | |
22573 // it separately. | |
22574 this._months = +months + | |
22575 years * 12; | |
22576 | |
22577 this._data = {}; | |
22578 | |
22579 this._bubble(); | |
22580 } | |
22581 | |
22582 /************************************ | |
22583 Helpers | |
22584 ************************************/ | |
22585 | |
22586 | |
22587 function extend(a, b) { | |
22588 for (var i in b) { | |
22589 if (b.hasOwnProperty(i)) { | |
22590 a[i] = b[i]; | |
22591 } | |
22592 } | |
22593 | |
22594 if (b.hasOwnProperty("toString")) { | |
22595 a.toString = b.toString; | |
22596 } | |
22597 | |
22598 if (b.hasOwnProperty("valueOf")) { | |
22599 a.valueOf = b.valueOf; | |
22600 } | |
22601 | |
22602 return a; | |
22603 } | |
22604 | |
22605 function cloneMoment(m) { | |
22606 var result = {}, i; | |
22607 for (i in m) { | |
22608 if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) { | |
22609 result[i] = m[i]; | |
22610 } | |
22611 } | |
22612 | |
22613 return result; | |
22614 } | |
22615 | |
22616 function absRound(number) { | |
22617 if (number < 0) { | |
22618 return Math.ceil(number); | |
22619 } else { | |
22620 return Math.floor(number); | |
22621 } | |
22622 } | |
22623 | |
22624 // left zero fill a number | |
22625 // see http://jsperf.com/left-zero-filling for performance comparison | |
22626 function leftZeroFill(number, targetLength, forceSign) { | |
22627 var output = '' + Math.abs(number), | |
22628 sign = number >= 0; | |
22629 | |
22630 while (output.length < targetLength) { | |
22631 output = '0' + output; | |
22632 } | |
22633 return (sign ? (forceSign ? '+' : '') : '-') + output; | |
22634 } | |
22635 | |
22636 // helper function for _.addTime and _.subtractTime | |
22637 function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) { | |
22638 var milliseconds = duration._milliseconds, | |
22639 days = duration._days, | |
22640 months = duration._months, | |
22641 minutes, | |
22642 hours; | |
22643 | |
22644 if (milliseconds) { | |
22645 mom._d.setTime(+mom._d + milliseconds * isAdding); | |
22646 } | |
22647 // store the minutes and hours so we can restore them | |
22648 if (days || months) { | |
22649 minutes = mom.minute(); | |
22650 hours = mom.hour(); | |
22651 } | |
22652 if (days) { | |
22653 mom.date(mom.date() + days * isAdding); | |
22654 } | |
22655 if (months) { | |
22656 mom.month(mom.month() + months * isAdding); | |
22657 } | |
22658 if (milliseconds && !ignoreUpdateOffset) { | |
22659 moment.updateOffset(mom); | |
22660 } | |
22661 // restore the minutes and hours after possibly changing dst | |
22662 if (days || months) { | |
22663 mom.minute(minutes); | |
22664 mom.hour(hours); | |
22665 } | |
22666 } | |
22667 | |
22668 // check if is an array | |
22669 function isArray(input) { | |
22670 return Object.prototype.toString.call(input) === '[object Array]'; | |
22671 } | |
22672 | |
22673 function isDate(input) { | |
22674 return Object.prototype.toString.call(input) === '[object Date]' || | |
22675 input instanceof Date; | |
22676 } | |
22677 | |
22678 // compare two arrays, return the number of differences | |
22679 function compareArrays(array1, array2, dontConvert) { | |
22680 var len = Math.min(array1.length, array2.length), | |
22681 lengthDiff = Math.abs(array1.length - array2.length), | |
22682 diffs = 0, | |
22683 i; | |
22684 for (i = 0; i < len; i++) { | |
22685 if ((dontConvert && array1[i] !== array2[i]) || | |
22686 (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { | |
22687 diffs++; | |
22688 } | |
22689 } | |
22690 return diffs + lengthDiff; | |
22691 } | |
22692 | |
22693 function normalizeUnits(units) { | |
22694 if (units) { | |
22695 var lowered = units.toLowerCase().replace(/(.)s$/, '$1'); | |
22696 units = unitAliases[units] || camelFunctions[lowered] || lowered; | |
22697 } | |
22698 return units; | |
22699 } | |
22700 | |
22701 function normalizeObjectUnits(inputObject) { | |
22702 var normalizedInput = {}, | |
22703 normalizedProp, | |
22704 prop; | |
22705 | |
22706 for (prop in inputObject) { | |
22707 if (inputObject.hasOwnProperty(prop)) { | |
22708 normalizedProp = normalizeUnits(prop); | |
22709 if (normalizedProp) { | |
22710 normalizedInput[normalizedProp] = inputObject[prop]; | |
22711 } | |
22712 } | |
22713 } | |
22714 | |
22715 return normalizedInput; | |
22716 } | |
22717 | |
22718 function makeList(field) { | |
22719 var count, setter; | |
22720 | |
22721 if (field.indexOf('week') === 0) { | |
22722 count = 7; | |
22723 setter = 'day'; | |
22724 } | |
22725 else if (field.indexOf('month') === 0) { | |
22726 count = 12; | |
22727 setter = 'month'; | |
22728 } | |
22729 else { | |
22730 return; | |
22731 } | |
22732 | |
22733 moment[field] = function (format, index) { | |
22734 var i, getter, | |
22735 method = moment.fn._lang[field], | |
22736 results = []; | |
22737 | |
22738 if (typeof format === 'number') { | |
22739 index = format; | |
22740 format = undefined; | |
22741 } | |
22742 | |
22743 getter = function (i) { | |
22744 var m = moment().utc().set(setter, i); | |
22745 return method.call(moment.fn._lang, m, format || ''); | |
22746 }; | |
22747 | |
22748 if (index != null) { | |
22749 return getter(index); | |
22750 } | |
22751 else { | |
22752 for (i = 0; i < count; i++) { | |
22753 results.push(getter(i)); | |
22754 } | |
22755 return results; | |
22756 } | |
22757 }; | |
22758 } | |
22759 | |
22760 function toInt(argumentForCoercion) { | |
22761 var coercedNumber = +argumentForCoercion, | |
22762 value = 0; | |
22763 | |
22764 if (coercedNumber !== 0 && isFinite(coercedNumber)) { | |
22765 if (coercedNumber >= 0) { | |
22766 value = Math.floor(coercedNumber); | |
22767 } else { | |
22768 value = Math.ceil(coercedNumber); | |
22769 } | |
22770 } | |
22771 | |
22772 return value; | |
22773 } | |
22774 | |
22775 function daysInMonth(year, month) { | |
22776 return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); | |
22777 } | |
22778 | |
22779 function daysInYear(year) { | |
22780 return isLeapYear(year) ? 366 : 365; | |
22781 } | |
22782 | |
22783 function isLeapYear(year) { | |
22784 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; | |
22785 } | |
22786 | |
22787 function checkOverflow(m) { | |
22788 var overflow; | |
22789 if (m._a && m._pf.overflow === -2) { | |
22790 overflow = | |
22791 m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH : | |
22792 m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE : | |
22793 m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR : | |
22794 m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE : | |
22795 m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND : | |
22796 m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND : | |
22797 -1; | |
22798 | |
22799 if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { | |
22800 overflow = DATE; | |
22801 } | |
22802 | |
22803 m._pf.overflow = overflow; | |
22804 } | |
22805 } | |
22806 | |
22807 function isValid(m) { | |
22808 if (m._isValid == null) { | |
22809 m._isValid = !isNaN(m._d.getTime()) && | |
22810 m._pf.overflow < 0 && | |
22811 !m._pf.empty && | |
22812 !m._pf.invalidMonth && | |
22813 !m._pf.nullInput && | |
22814 !m._pf.invalidFormat && | |
22815 !m._pf.userInvalidated; | |
22816 | |
22817 if (m._strict) { | |
22818 m._isValid = m._isValid && | |
22819 m._pf.charsLeftOver === 0 && | |
22820 m._pf.unusedTokens.length === 0; | |
22821 } | |
22822 } | |
22823 return m._isValid; | |
22824 } | |
22825 | |
22826 function normalizeLanguage(key) { | |
22827 return key ? key.toLowerCase().replace('_', '-') : key; | |
22828 } | |
22829 | |
22830 // Return a moment from input, that is local/utc/zone equivalent to model. | |
22831 function makeAs(input, model) { | |
22832 return model._isUTC ? moment(input).zone(model._offset || 0) : | |
22833 moment(input).local(); | |
22834 } | |
22835 | |
22836 /************************************ | |
22837 Languages | |
22838 ************************************/ | |
22839 | |
22840 | |
22841 extend(Language.prototype, { | |
22842 | |
22843 set : function (config) { | |
22844 var prop, i; | |
22845 for (i in config) { | |
22846 prop = config[i]; | |
22847 if (typeof prop === 'function') { | |
22848 this[i] = prop; | |
22849 } else { | |
22850 this['_' + i] = prop; | |
22851 } | |
22852 } | |
22853 }, | |
22854 | |
22855 _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), | |
22856 months : function (m) { | |
22857 return this._months[m.month()]; | |
22858 }, | |
22859 | |
22860 _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"), | |
22861 monthsShort : function (m) { | |
22862 return this._monthsShort[m.month()]; | |
22863 }, | |
22864 | |
22865 monthsParse : function (monthName) { | |
22866 var i, mom, regex; | |
22867 | |
22868 if (!this._monthsParse) { | |
22869 this._monthsParse = []; | |
22870 } | |
22871 | |
22872 for (i = 0; i < 12; i++) { | |
22873 // make the regex if we don't have it already | |
22874 if (!this._monthsParse[i]) { | |
22875 mom = moment.utc([2000, i]); | |
22876 regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); | |
22877 this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); | |
22878 } | |
22879 // test the regex | |
22880 if (this._monthsParse[i].test(monthName)) { | |
22881 return i; | |
22882 } | |
22883 } | |
22884 }, | |
22885 | |
22886 _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), | |
22887 weekdays : function (m) { | |
22888 return this._weekdays[m.day()]; | |
22889 }, | |
22890 | |
22891 _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"), | |
22892 weekdaysShort : function (m) { | |
22893 return this._weekdaysShort[m.day()]; | |
22894 }, | |
22895 | |
22896 _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"), | |
22897 weekdaysMin : function (m) { | |
22898 return this._weekdaysMin[m.day()]; | |
22899 }, | |
22900 | |
22901 weekdaysParse : function (weekdayName) { | |
22902 var i, mom, regex; | |
22903 | |
22904 if (!this._weekdaysParse) { | |
22905 this._weekdaysParse = []; | |
22906 } | |
22907 | |
22908 for (i = 0; i < 7; i++) { | |
22909 // make the regex if we don't have it already | |
22910 if (!this._weekdaysParse[i]) { | |
22911 mom = moment([2000, 1]).day(i); | |
22912 regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); | |
22913 this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); | |
22914 } | |
22915 // test the regex | |
22916 if (this._weekdaysParse[i].test(weekdayName)) { | |
22917 return i; | |
22918 } | |
22919 } | |
22920 }, | |
22921 | |
22922 _longDateFormat : { | |
22923 LT : "h:mm A", | |
22924 L : "MM/DD/YYYY", | |
22925 LL : "MMMM D YYYY", | |
22926 LLL : "MMMM D YYYY LT", | |
22927 LLLL : "dddd, MMMM D YYYY LT" | |
22928 }, | |
22929 longDateFormat : function (key) { | |
22930 var output = this._longDateFormat[key]; | |
22931 if (!output && this._longDateFormat[key.toUpperCase()]) { | |
22932 output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) { | |
22933 return val.slice(1); | |
22934 }); | |
22935 this._longDateFormat[key] = output; | |
22936 } | |
22937 return output; | |
22938 }, | |
22939 | |
22940 isPM : function (input) { | |
22941 // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays | |
22942 // Using charAt should be more compatible. | |
22943 return ((input + '').toLowerCase().charAt(0) === 'p'); | |
22944 }, | |
22945 | |
22946 _meridiemParse : /[ap]\.?m?\.?/i, | |
22947 meridiem : function (hours, minutes, isLower) { | |
22948 if (hours > 11) { | |
22949 return isLower ? 'pm' : 'PM'; | |
22950 } else { | |
22951 return isLower ? 'am' : 'AM'; | |
22952 } | |
22953 }, | |
22954 | |
22955 _calendar : { | |
22956 sameDay : '[Today at] LT', | |
22957 nextDay : '[Tomorrow at] LT', | |
22958 nextWeek : 'dddd [at] LT', | |
22959 lastDay : '[Yesterday at] LT', | |
22960 lastWeek : '[Last] dddd [at] LT', | |
22961 sameElse : 'L' | |
22962 }, | |
22963 calendar : function (key, mom) { | |
22964 var output = this._calendar[key]; | |
22965 return typeof output === 'function' ? output.apply(mom) : output; | |
22966 }, | |
22967 | |
22968 _relativeTime : { | |
22969 future : "in %s", | |
22970 past : "%s ago", | |
22971 s : "a few seconds", | |
22972 m : "a minute", | |
22973 mm : "%d minutes", | |
22974 h : "an hour", | |
22975 hh : "%d hours", | |
22976 d : "a day", | |
22977 dd : "%d days", | |
22978 M : "a month", | |
22979 MM : "%d months", | |
22980 y : "a year", | |
22981 yy : "%d years" | |
22982 }, | |
22983 relativeTime : function (number, withoutSuffix, string, isFuture) { | |
22984 var output = this._relativeTime[string]; | |
22985 return (typeof output === 'function') ? | |
22986 output(number, withoutSuffix, string, isFuture) : | |
22987 output.replace(/%d/i, number); | |
22988 }, | |
22989 pastFuture : function (diff, output) { | |
22990 var format = this._relativeTime[diff > 0 ? 'future' : 'past']; | |
22991 return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); | |
22992 }, | |
22993 | |
22994 ordinal : function (number) { | |
22995 return this._ordinal.replace("%d", number); | |
22996 }, | |
22997 _ordinal : "%d", | |
22998 | |
22999 preparse : function (string) { | |
23000 return string; | |
23001 }, | |
23002 | |
23003 postformat : function (string) { | |
23004 return string; | |
23005 }, | |
23006 | |
23007 week : function (mom) { | |
23008 return weekOfYear(mom, this._week.dow, this._week.doy).week; | |
23009 }, | |
23010 | |
23011 _week : { | |
23012 dow : 0, // Sunday is the first day of the week. | |
23013 doy : 6 // The week that contains Jan 1st is the first week of the year. | |
23014 }, | |
23015 | |
23016 _invalidDate: 'Invalid date', | |
23017 invalidDate: function () { | |
23018 return this._invalidDate; | |
23019 } | |
23020 }); | |
23021 | |
23022 // Loads a language definition into the `languages` cache. The function | |
23023 // takes a key and optionally values. If not in the browser and no values | |
23024 // are provided, it will load the language file module. As a convenience, | |
23025 // this function also returns the language values. | |
23026 function loadLang(key, values) { | |
23027 values.abbr = key; | |
23028 if (!languages[key]) { | |
23029 languages[key] = new Language(); | |
23030 } | |
23031 languages[key].set(values); | |
23032 return languages[key]; | |
23033 } | |
23034 | |
23035 // Remove a language from the `languages` cache. Mostly useful in tests. | |
23036 function unloadLang(key) { | |
23037 delete languages[key]; | |
23038 } | |
23039 | |
23040 // Determines which language definition to use and returns it. | |
23041 // | |
23042 // With no parameters, it will return the global language. If you | |
23043 // pass in a language key, such as 'en', it will return the | |
23044 // definition for 'en', so long as 'en' has already been loaded using | |
23045 // moment.lang. | |
23046 function getLangDefinition(key) { | |
23047 var i = 0, j, lang, next, split, | |
23048 get = function (k) { | |
23049 if (!languages[k] && hasModule) { | |
23050 try { | |
23051 require('./lang/' + k); | |
23052 } catch (e) { } | |
23053 } | |
23054 return languages[k]; | |
23055 }; | |
23056 | |
23057 if (!key) { | |
23058 return moment.fn._lang; | |
23059 } | |
23060 | |
23061 if (!isArray(key)) { | |
23062 //short-circuit everything else | |
23063 lang = get(key); | |
23064 if (lang) { | |
23065 return lang; | |
23066 } | |
23067 key = [key]; | |
23068 } | |
23069 | |
23070 //pick the language from the array | |
23071 //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each | |
23072 //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root | |
23073 while (i < key.length) { | |
23074 split = normalizeLanguage(key[i]).split('-'); | |
23075 j = split.length; | |
23076 next = normalizeLanguage(key[i + 1]); | |
23077 next = next ? next.split('-') : null; | |
23078 while (j > 0) { | |
23079 lang = get(split.slice(0, j).join('-')); | |
23080 if (lang) { | |
23081 return lang; | |
23082 } | |
23083 if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { | |
23084 //the next array item is better than a shallower substring of this one | |
23085 break; | |
23086 } | |
23087 j--; | |
23088 } | |
23089 i++; | |
23090 } | |
23091 return moment.fn._lang; | |
23092 } | |
23093 | |
23094 /************************************ | |
23095 Formatting | |
23096 ************************************/ | |
23097 | |
23098 | |
23099 function removeFormattingTokens(input) { | |
23100 if (input.match(/\[[\s\S]/)) { | |
23101 return input.replace(/^\[|\]$/g, ""); | |
23102 } | |
23103 return input.replace(/\\/g, ""); | |
23104 } | |
23105 | |
23106 function makeFormatFunction(format) { | |
23107 var array = format.match(formattingTokens), i, length; | |
23108 | |
23109 for (i = 0, length = array.length; i < length; i++) { | |
23110 if (formatTokenFunctions[array[i]]) { | |
23111 array[i] = formatTokenFunctions[array[i]]; | |
23112 } else { | |
23113 array[i] = removeFormattingTokens(array[i]); | |
23114 } | |
23115 } | |
23116 | |
23117 return function (mom) { | |
23118 var output = ""; | |
23119 for (i = 0; i < length; i++) { | |
23120 output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; | |
23121 } | |
23122 return output; | |
23123 }; | |
23124 } | |
23125 | |
23126 // format date using native date object | |
23127 function formatMoment(m, format) { | |
23128 | |
23129 if (!m.isValid()) { | |
23130 return m.lang().invalidDate(); | |
23131 } | |
23132 | |
23133 format = expandFormat(format, m.lang()); | |
23134 | |
23135 if (!formatFunctions[format]) { | |
23136 formatFunctions[format] = makeFormatFunction(format); | |
23137 } | |
23138 | |
23139 return formatFunctions[format](m); | |
23140 } | |
23141 | |
23142 function expandFormat(format, lang) { | |
23143 var i = 5; | |
23144 | |
23145 function replaceLongDateFormatTokens(input) { | |
23146 return lang.longDateFormat(input) || input; | |
23147 } | |
23148 | |
23149 localFormattingTokens.lastIndex = 0; | |
23150 while (i >= 0 && localFormattingTokens.test(format)) { | |
23151 format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); | |
23152 localFormattingTokens.lastIndex = 0; | |
23153 i -= 1; | |
23154 } | |
23155 | |
23156 return format; | |
23157 } | |
23158 | |
23159 | |
23160 /************************************ | |
23161 Parsing | |
23162 ************************************/ | |
23163 | |
23164 | |
23165 // get the regex to find the next token | |
23166 function getParseRegexForToken(token, config) { | |
23167 var a, strict = config._strict; | |
23168 switch (token) { | |
23169 case 'DDDD': | |
23170 return parseTokenThreeDigits; | |
23171 case 'YYYY': | |
23172 case 'GGGG': | |
23173 case 'gggg': | |
23174 return strict ? parseTokenFourDigits : parseTokenOneToFourDigits; | |
23175 case 'Y': | |
23176 case 'G': | |
23177 case 'g': | |
23178 return parseTokenSignedNumber; | |
23179 case 'YYYYYY': | |
23180 case 'YYYYY': | |
23181 case 'GGGGG': | |
23182 case 'ggggg': | |
23183 return strict ? parseTokenSixDigits : parseTokenOneToSixDigits; | |
23184 case 'S': | |
23185 if (strict) { return parseTokenOneDigit; } | |
23186 /* falls through */ | |
23187 case 'SS': | |
23188 if (strict) { return parseTokenTwoDigits; } | |
23189 /* falls through */ | |
23190 case 'SSS': | |
23191 if (strict) { return parseTokenThreeDigits; } | |
23192 /* falls through */ | |
23193 case 'DDD': | |
23194 return parseTokenOneToThreeDigits; | |
23195 case 'MMM': | |
23196 case 'MMMM': | |
23197 case 'dd': | |
23198 case 'ddd': | |
23199 case 'dddd': | |
23200 return parseTokenWord; | |
23201 case 'a': | |
23202 case 'A': | |
23203 return getLangDefinition(config._l)._meridiemParse; | |
23204 case 'X': | |
23205 return parseTokenTimestampMs; | |
23206 case 'Z': | |
23207 case 'ZZ': | |
23208 return parseTokenTimezone; | |
23209 case 'T': | |
23210 return parseTokenT; | |
23211 case 'SSSS': | |
23212 return parseTokenDigits; | |
23213 case 'MM': | |
23214 case 'DD': | |
23215 case 'YY': | |
23216 case 'GG': | |
23217 case 'gg': | |
23218 case 'HH': | |
23219 case 'hh': | |
23220 case 'mm': | |
23221 case 'ss': | |
23222 case 'ww': | |
23223 case 'WW': | |
23224 return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits; | |
23225 case 'M': | |
23226 case 'D': | |
23227 case 'd': | |
23228 case 'H': | |
23229 case 'h': | |
23230 case 'm': | |
23231 case 's': | |
23232 case 'w': | |
23233 case 'W': | |
23234 case 'e': | |
23235 case 'E': | |
23236 return parseTokenOneOrTwoDigits; | |
23237 default : | |
23238 a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i")); | |
23239 return a; | |
23240 } | |
23241 } | |
23242 | |
23243 function timezoneMinutesFromString(string) { | |
23244 string = string || ""; | |
23245 var possibleTzMatches = (string.match(parseTokenTimezone) || []), | |
23246 tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [], | |
23247 parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0], | |
23248 minutes = +(parts[1] * 60) + toInt(parts[2]); | |
23249 | |
23250 return parts[0] === '+' ? -minutes : minutes; | |
23251 } | |
23252 | |
23253 // function to convert string input to date | |
23254 function addTimeToArrayFromToken(token, input, config) { | |
23255 var a, datePartArray = config._a; | |
23256 | |
23257 switch (token) { | |
23258 // MONTH | |
23259 case 'M' : // fall through to MM | |
23260 case 'MM' : | |
23261 if (input != null) { | |
23262 datePartArray[MONTH] = toInt(input) - 1; | |
23263 } | |
23264 break; | |
23265 case 'MMM' : // fall through to MMMM | |
23266 case 'MMMM' : | |
23267 a = getLangDefinition(config._l).monthsParse(input); | |
23268 // if we didn't find a month name, mark the date as invalid. | |
23269 if (a != null) { | |
23270 datePartArray[MONTH] = a; | |
23271 } else { | |
23272 config._pf.invalidMonth = input; | |
23273 } | |
23274 break; | |
23275 // DAY OF MONTH | |
23276 case 'D' : // fall through to DD | |
23277 case 'DD' : | |
23278 if (input != null) { | |
23279 datePartArray[DATE] = toInt(input); | |
23280 } | |
23281 break; | |
23282 // DAY OF YEAR | |
23283 case 'DDD' : // fall through to DDDD | |
23284 case 'DDDD' : | |
23285 if (input != null) { | |
23286 config._dayOfYear = toInt(input); | |
23287 } | |
23288 | |
23289 break; | |
23290 // YEAR | |
23291 case 'YY' : | |
23292 datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000); | |
23293 break; | |
23294 case 'YYYY' : | |
23295 case 'YYYYY' : | |
23296 case 'YYYYYY' : | |
23297 datePartArray[YEAR] = toInt(input); | |
23298 break; | |
23299 // AM / PM | |
23300 case 'a' : // fall through to A | |
23301 case 'A' : | |
23302 config._isPm = getLangDefinition(config._l).isPM(input); | |
23303 break; | |
23304 // 24 HOUR | |
23305 case 'H' : // fall through to hh | |
23306 case 'HH' : // fall through to hh | |
23307 case 'h' : // fall through to hh | |
23308 case 'hh' : | |
23309 datePartArray[HOUR] = toInt(input); | |
23310 break; | |
23311 // MINUTE | |
23312 case 'm' : // fall through to mm | |
23313 case 'mm' : | |
23314 datePartArray[MINUTE] = toInt(input); | |
23315 break; | |
23316 // SECOND | |
23317 case 's' : // fall through to ss | |
23318 case 'ss' : | |
23319 datePartArray[SECOND] = toInt(input); | |
23320 break; | |
23321 // MILLISECOND | |
23322 case 'S' : | |
23323 case 'SS' : | |
23324 case 'SSS' : | |
23325 case 'SSSS' : | |
23326 datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000); | |
23327 break; | |
23328 // UNIX TIMESTAMP WITH MS | |
23329 case 'X': | |
23330 config._d = new Date(parseFloat(input) * 1000); | |
23331 break; | |
23332 // TIMEZONE | |
23333 case 'Z' : // fall through to ZZ | |
23334 case 'ZZ' : | |
23335 config._useUTC = true; | |
23336 config._tzm = timezoneMinutesFromString(input); | |
23337 break; | |
23338 case 'w': | |
23339 case 'ww': | |
23340 case 'W': | |
23341 case 'WW': | |
23342 case 'd': | |
23343 case 'dd': | |
23344 case 'ddd': | |
23345 case 'dddd': | |
23346 case 'e': | |
23347 case 'E': | |
23348 token = token.substr(0, 1); | |
23349 /* falls through */ | |
23350 case 'gg': | |
23351 case 'gggg': | |
23352 case 'GG': | |
23353 case 'GGGG': | |
23354 case 'GGGGG': | |
23355 token = token.substr(0, 2); | |
23356 if (input) { | |
23357 config._w = config._w || {}; | |
23358 config._w[token] = input; | |
23359 } | |
23360 break; | |
23361 } | |
23362 } | |
23363 | |
23364 // convert an array to a date. | |
23365 // the array should mirror the parameters below | |
23366 // note: all values past the year are optional and will default to the lowest possible value. | |
23367 // [year, month, day , hour, minute, second, millisecond] | |
23368 function dateFromConfig(config) { | |
23369 var i, date, input = [], currentDate, | |
23370 yearToUse, fixYear, w, temp, lang, weekday, week; | |
23371 | |
23372 if (config._d) { | |
23373 return; | |
23374 } | |
23375 | |
23376 currentDate = currentDateArray(config); | |
23377 | |
23378 //compute day of the year from weeks and weekdays | |
23379 if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { | |
23380 fixYear = function (val) { | |
23381 var int_val = parseInt(val, 10); | |
23382 return val ? | |
23383 (val.length < 3 ? (int_val > 68 ? 1900 + int_val : 2000 + int_val) : int_val) : | |
23384 (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]); | |
23385 }; | |
23386 | |
23387 w = config._w; | |
23388 if (w.GG != null || w.W != null || w.E != null) { | |
23389 temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1); | |
23390 } | |
23391 else { | |
23392 lang = getLangDefinition(config._l); | |
23393 weekday = w.d != null ? parseWeekday(w.d, lang) : | |
23394 (w.e != null ? parseInt(w.e, 10) + lang._week.dow : 0); | |
23395 | |
23396 week = parseInt(w.w, 10) || 1; | |
23397 | |
23398 //if we're parsing 'd', then the low day numbers may be next week | |
23399 if (w.d != null && weekday < lang._week.dow) { | |
23400 week++; | |
23401 } | |
23402 | |
23403 temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow); | |
23404 } | |
23405 | |
23406 config._a[YEAR] = temp.year; | |
23407 config._dayOfYear = temp.dayOfYear; | |
23408 } | |
23409 | |
23410 //if the day of the year is set, figure out what it is | |
23411 if (config._dayOfYear) { | |
23412 yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR]; | |
23413 | |
23414 if (config._dayOfYear > daysInYear(yearToUse)) { | |
23415 config._pf._overflowDayOfYear = true; | |
23416 } | |
23417 | |
23418 date = makeUTCDate(yearToUse, 0, config._dayOfYear); | |
23419 config._a[MONTH] = date.getUTCMonth(); | |
23420 config._a[DATE] = date.getUTCDate(); | |
23421 } | |
23422 | |
23423 // Default to current date. | |
23424 // * if no year, month, day of month are given, default to today | |
23425 // * if day of month is given, default month and year | |
23426 // * if month is given, default only year | |
23427 // * if year is given, don't default anything | |
23428 for (i = 0; i < 3 && config._a[i] == null; ++i) { | |
23429 config._a[i] = input[i] = currentDate[i]; | |
23430 } | |
23431 | |
23432 // Zero out whatever was not defaulted, including time | |
23433 for (; i < 7; i++) { | |
23434 config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; | |
23435 } | |
23436 | |
23437 // add the offsets to the time to be parsed so that we can have a clean array for checking isValid | |
23438 input[HOUR] += toInt((config._tzm || 0) / 60); | |
23439 input[MINUTE] += toInt((config._tzm || 0) % 60); | |
23440 | |
23441 config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input); | |
23442 } | |
23443 | |
23444 function dateFromObject(config) { | |
23445 var normalizedInput; | |
23446 | |
23447 if (config._d) { | |
23448 return; | |
23449 } | |
23450 | |
23451 normalizedInput = normalizeObjectUnits(config._i); | |
23452 config._a = [ | |
23453 normalizedInput.year, | |
23454 normalizedInput.month, | |
23455 normalizedInput.day, | |
23456 normalizedInput.hour, | |
23457 normalizedInput.minute, | |
23458 normalizedInput.second, | |
23459 normalizedInput.millisecond | |
23460 ]; | |
23461 | |
23462 dateFromConfig(config); | |
23463 } | |
23464 | |
23465 function currentDateArray(config) { | |
23466 var now = new Date(); | |
23467 if (config._useUTC) { | |
23468 return [ | |
23469 now.getUTCFullYear(), | |
23470 now.getUTCMonth(), | |
23471 now.getUTCDate() | |
23472 ]; | |
23473 } else { | |
23474 return [now.getFullYear(), now.getMonth(), now.getDate()]; | |
23475 } | |
23476 } | |
23477 | |
23478 // date from string and format string | |
23479 function makeDateFromStringAndFormat(config) { | |
23480 | |
23481 config._a = []; | |
23482 config._pf.empty = true; | |
23483 | |
23484 // This array is used to make a Date, either with `new Date` or `Date.UTC` | |
23485 var lang = getLangDefinition(config._l), | |
23486 string = '' + config._i, | |
23487 i, parsedInput, tokens, token, skipped, | |
23488 stringLength = string.length, | |
23489 totalParsedInputLength = 0; | |
23490 | |
23491 tokens = expandFormat(config._f, lang).match(formattingTokens) || []; | |
23492 | |
23493 for (i = 0; i < tokens.length; i++) { | |
23494 token = tokens[i]; | |
23495 parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; | |
23496 if (parsedInput) { | |
23497 skipped = string.substr(0, string.indexOf(parsedInput)); | |
23498 if (skipped.length > 0) { | |
23499 config._pf.unusedInput.push(skipped); | |
23500 } | |
23501 string = string.slice(string.indexOf(parsedInput) + parsedInput.length); | |
23502 totalParsedInputLength += parsedInput.length; | |
23503 } | |
23504 // don't parse if it's not a known token | |
23505 if (formatTokenFunctions[token]) { | |
23506 if (parsedInput) { | |
23507 config._pf.empty = false; | |
23508 } | |
23509 else { | |
23510 config._pf.unusedTokens.push(token); | |
23511 } | |
23512 addTimeToArrayFromToken(token, parsedInput, config); | |
23513 } | |
23514 else if (config._strict && !parsedInput) { | |
23515 config._pf.unusedTokens.push(token); | |
23516 } | |
23517 } | |
23518 | |
23519 // add remaining unparsed input length to the string | |
23520 config._pf.charsLeftOver = stringLength - totalParsedInputLength; | |
23521 if (string.length > 0) { | |
23522 config._pf.unusedInput.push(string); | |
23523 } | |
23524 | |
23525 // handle am pm | |
23526 if (config._isPm && config._a[HOUR] < 12) { | |
23527 config._a[HOUR] += 12; | |
23528 } | |
23529 // if is 12 am, change hours to 0 | |
23530 if (config._isPm === false && config._a[HOUR] === 12) { | |
23531 config._a[HOUR] = 0; | |
23532 } | |
23533 | |
23534 dateFromConfig(config); | |
23535 checkOverflow(config); | |
23536 } | |
23537 | |
23538 function unescapeFormat(s) { | |
23539 return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { | |
23540 return p1 || p2 || p3 || p4; | |
23541 }); | |
23542 } | |
23543 | |
23544 // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript | |
23545 function regexpEscape(s) { | |
23546 return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
23547 } | |
23548 | |
23549 // date from string and array of format strings | |
23550 function makeDateFromStringAndArray(config) { | |
23551 var tempConfig, | |
23552 bestMoment, | |
23553 | |
23554 scoreToBeat, | |
23555 i, | |
23556 currentScore; | |
23557 | |
23558 if (config._f.length === 0) { | |
23559 config._pf.invalidFormat = true; | |
23560 config._d = new Date(NaN); | |
23561 return; | |
23562 } | |
23563 | |
23564 for (i = 0; i < config._f.length; i++) { | |
23565 currentScore = 0; | |
23566 tempConfig = extend({}, config); | |
23567 tempConfig._pf = defaultParsingFlags(); | |
23568 tempConfig._f = config._f[i]; | |
23569 makeDateFromStringAndFormat(tempConfig); | |
23570 | |
23571 if (!isValid(tempConfig)) { | |
23572 continue; | |
23573 } | |
23574 | |
23575 // if there is any input that was not parsed add a penalty for that format | |
23576 currentScore += tempConfig._pf.charsLeftOver; | |
23577 | |
23578 //or tokens | |
23579 currentScore += tempConfig._pf.unusedTokens.length * 10; | |
23580 | |
23581 tempConfig._pf.score = currentScore; | |
23582 | |
23583 if (scoreToBeat == null || currentScore < scoreToBeat) { | |
23584 scoreToBeat = currentScore; | |
23585 bestMoment = tempConfig; | |
23586 } | |
23587 } | |
23588 | |
23589 extend(config, bestMoment || tempConfig); | |
23590 } | |
23591 | |
23592 // date from iso format | |
23593 function makeDateFromString(config) { | |
23594 var i, l, | |
23595 string = config._i, | |
23596 match = isoRegex.exec(string); | |
23597 | |
23598 if (match) { | |
23599 config._pf.iso = true; | |
23600 for (i = 0, l = isoDates.length; i < l; i++) { | |
23601 if (isoDates[i][1].exec(string)) { | |
23602 // match[5] should be "T" or undefined | |
23603 config._f = isoDates[i][0] + (match[6] || " "); | |
23604 break; | |
23605 } | |
23606 } | |
23607 for (i = 0, l = isoTimes.length; i < l; i++) { | |
23608 if (isoTimes[i][1].exec(string)) { | |
23609 config._f += isoTimes[i][0]; | |
23610 break; | |
23611 } | |
23612 } | |
23613 if (string.match(parseTokenTimezone)) { | |
23614 config._f += "Z"; | |
23615 } | |
23616 makeDateFromStringAndFormat(config); | |
23617 } | |
23618 else { | |
23619 config._d = new Date(string); | |
23620 } | |
23621 } | |
23622 | |
23623 function makeDateFromInput(config) { | |
23624 var input = config._i, | |
23625 matched = aspNetJsonRegex.exec(input); | |
23626 | |
23627 if (input === undefined) { | |
23628 config._d = new Date(); | |
23629 } else if (matched) { | |
23630 config._d = new Date(+matched[1]); | |
23631 } else if (typeof input === 'string') { | |
23632 makeDateFromString(config); | |
23633 } else if (isArray(input)) { | |
23634 config._a = input.slice(0); | |
23635 dateFromConfig(config); | |
23636 } else if (isDate(input)) { | |
23637 config._d = new Date(+input); | |
23638 } else if (typeof(input) === 'object') { | |
23639 dateFromObject(config); | |
23640 } else { | |
23641 config._d = new Date(input); | |
23642 } | |
23643 } | |
23644 | |
23645 function makeDate(y, m, d, h, M, s, ms) { | |
23646 //can't just apply() to create a date: | |
23647 //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply | |
23648 var date = new Date(y, m, d, h, M, s, ms); | |
23649 | |
23650 //the date constructor doesn't accept years < 1970 | |
23651 if (y < 1970) { | |
23652 date.setFullYear(y); | |
23653 } | |
23654 return date; | |
23655 } | |
23656 | |
23657 function makeUTCDate(y) { | |
23658 var date = new Date(Date.UTC.apply(null, arguments)); | |
23659 if (y < 1970) { | |
23660 date.setUTCFullYear(y); | |
23661 } | |
23662 return date; | |
23663 } | |
23664 | |
23665 function parseWeekday(input, language) { | |
23666 if (typeof input === 'string') { | |
23667 if (!isNaN(input)) { | |
23668 input = parseInt(input, 10); | |
23669 } | |
23670 else { | |
23671 input = language.weekdaysParse(input); | |
23672 if (typeof input !== 'number') { | |
23673 return null; | |
23674 } | |
23675 } | |
23676 } | |
23677 return input; | |
23678 } | |
23679 | |
23680 /************************************ | |
23681 Relative Time | |
23682 ************************************/ | |
23683 | |
23684 | |
23685 // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize | |
23686 function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) { | |
23687 return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture); | |
23688 } | |
23689 | |
23690 function relativeTime(milliseconds, withoutSuffix, lang) { | |
23691 var seconds = round(Math.abs(milliseconds) / 1000), | |
23692 minutes = round(seconds / 60), | |
23693 hours = round(minutes / 60), | |
23694 days = round(hours / 24), | |
23695 years = round(days / 365), | |
23696 args = seconds < 45 && ['s', seconds] || | |
23697 minutes === 1 && ['m'] || | |
23698 minutes < 45 && ['mm', minutes] || | |
23699 hours === 1 && ['h'] || | |
23700 hours < 22 && ['hh', hours] || | |
23701 days === 1 && ['d'] || | |
23702 days <= 25 && ['dd', days] || | |
23703 days <= 45 && ['M'] || | |
23704 days < 345 && ['MM', round(days / 30)] || | |
23705 years === 1 && ['y'] || ['yy', years]; | |
23706 args[2] = withoutSuffix; | |
23707 args[3] = milliseconds > 0; | |
23708 args[4] = lang; | |
23709 return substituteTimeAgo.apply({}, args); | |
23710 } | |
23711 | |
23712 | |
23713 /************************************ | |
23714 Week of Year | |
23715 ************************************/ | |
23716 | |
23717 | |
23718 // firstDayOfWeek 0 = sun, 6 = sat | |
23719 // the day of the week that starts the week | |
23720 // (usually sunday or monday) | |
23721 // firstDayOfWeekOfYear 0 = sun, 6 = sat | |
23722 // the first week is the week that contains the first | |
23723 // of this day of the week | |
23724 // (eg. ISO weeks use thursday (4)) | |
23725 function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { | |
23726 var end = firstDayOfWeekOfYear - firstDayOfWeek, | |
23727 daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), | |
23728 adjustedMoment; | |
23729 | |
23730 | |
23731 if (daysToDayOfWeek > end) { | |
23732 daysToDayOfWeek -= 7; | |
23733 } | |
23734 | |
23735 if (daysToDayOfWeek < end - 7) { | |
23736 daysToDayOfWeek += 7; | |
23737 } | |
23738 | |
23739 adjustedMoment = moment(mom).add('d', daysToDayOfWeek); | |
23740 return { | |
23741 week: Math.ceil(adjustedMoment.dayOfYear() / 7), | |
23742 year: adjustedMoment.year() | |
23743 }; | |
23744 } | |
23745 | |
23746 //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday | |
23747 function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { | |
23748 var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear; | |
23749 | |
23750 weekday = weekday != null ? weekday : firstDayOfWeek; | |
23751 daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0); | |
23752 dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1; | |
23753 | |
23754 return { | |
23755 year: dayOfYear > 0 ? year : year - 1, | |
23756 dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear | |
23757 }; | |
23758 } | |
23759 | |
23760 /************************************ | |
23761 Top Level Functions | |
23762 ************************************/ | |
23763 | |
23764 function makeMoment(config) { | |
23765 var input = config._i, | |
23766 format = config._f; | |
23767 | |
23768 if (input === null) { | |
23769 return moment.invalid({nullInput: true}); | |
23770 } | |
23771 | |
23772 if (typeof input === 'string') { | |
23773 config._i = input = getLangDefinition().preparse(input); | |
23774 } | |
23775 | |
23776 if (moment.isMoment(input)) { | |
23777 config = cloneMoment(input); | |
23778 | |
23779 config._d = new Date(+input._d); | |
23780 } else if (format) { | |
23781 if (isArray(format)) { | |
23782 makeDateFromStringAndArray(config); | |
23783 } else { | |
23784 makeDateFromStringAndFormat(config); | |
23785 } | |
23786 } else { | |
23787 makeDateFromInput(config); | |
23788 } | |
23789 | |
23790 return new Moment(config); | |
23791 } | |
23792 | |
23793 moment = function (input, format, lang, strict) { | |
23794 var c; | |
23795 | |
23796 if (typeof(lang) === "boolean") { | |
23797 strict = lang; | |
23798 lang = undefined; | |
23799 } | |
23800 // object construction must be done this way. | |
23801 // https://github.com/moment/moment/issues/1423 | |
23802 c = {}; | |
23803 c._isAMomentObject = true; | |
23804 c._i = input; | |
23805 c._f = format; | |
23806 c._l = lang; | |
23807 c._strict = strict; | |
23808 c._isUTC = false; | |
23809 c._pf = defaultParsingFlags(); | |
23810 | |
23811 return makeMoment(c); | |
23812 }; | |
23813 | |
23814 // creating with utc | |
23815 moment.utc = function (input, format, lang, strict) { | |
23816 var c; | |
23817 | |
23818 if (typeof(lang) === "boolean") { | |
23819 strict = lang; | |
23820 lang = undefined; | |
23821 } | |
23822 // object construction must be done this way. | |
23823 // https://github.com/moment/moment/issues/1423 | |
23824 c = {}; | |
23825 c._isAMomentObject = true; | |
23826 c._useUTC = true; | |
23827 c._isUTC = true; | |
23828 c._l = lang; | |
23829 c._i = input; | |
23830 c._f = format; | |
23831 c._strict = strict; | |
23832 c._pf = defaultParsingFlags(); | |
23833 | |
23834 return makeMoment(c).utc(); | |
23835 }; | |
23836 | |
23837 // creating with unix timestamp (in seconds) | |
23838 moment.unix = function (input) { | |
23839 return moment(input * 1000); | |
23840 }; | |
23841 | |
23842 // duration | |
23843 moment.duration = function (input, key) { | |
23844 var duration = input, | |
23845 // matching against regexp is expensive, do it on demand | |
23846 match = null, | |
23847 sign, | |
23848 ret, | |
23849 parseIso; | |
23850 | |
23851 if (moment.isDuration(input)) { | |
23852 duration = { | |
23853 ms: input._milliseconds, | |
23854 d: input._days, | |
23855 M: input._months | |
23856 }; | |
23857 } else if (typeof input === 'number') { | |
23858 duration = {}; | |
23859 if (key) { | |
23860 duration[key] = input; | |
23861 } else { | |
23862 duration.milliseconds = input; | |
23863 } | |
23864 } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) { | |
23865 sign = (match[1] === "-") ? -1 : 1; | |
23866 duration = { | |
23867 y: 0, | |
23868 d: toInt(match[DATE]) * sign, | |
23869 h: toInt(match[HOUR]) * sign, | |
23870 m: toInt(match[MINUTE]) * sign, | |
23871 s: toInt(match[SECOND]) * sign, | |
23872 ms: toInt(match[MILLISECOND]) * sign | |
23873 }; | |
23874 } else if (!!(match = isoDurationRegex.exec(input))) { | |
23875 sign = (match[1] === "-") ? -1 : 1; | |
23876 parseIso = function (inp) { | |
23877 // We'd normally use ~~inp for this, but unfortunately it also | |
23878 // converts floats to ints. | |
23879 // inp may be undefined, so careful calling replace on it. | |
23880 var res = inp && parseFloat(inp.replace(',', '.')); | |
23881 // apply sign while we're at it | |
23882 return (isNaN(res) ? 0 : res) * sign; | |
23883 }; | |
23884 duration = { | |
23885 y: parseIso(match[2]), | |
23886 M: parseIso(match[3]), | |
23887 d: parseIso(match[4]), | |
23888 h: parseIso(match[5]), | |
23889 m: parseIso(match[6]), | |
23890 s: parseIso(match[7]), | |
23891 w: parseIso(match[8]) | |
23892 }; | |
23893 } | |
23894 | |
23895 ret = new Duration(duration); | |
23896 | |
23897 if (moment.isDuration(input) && input.hasOwnProperty('_lang')) { | |
23898 ret._lang = input._lang; | |
23899 } | |
23900 | |
23901 return ret; | |
23902 }; | |
23903 | |
23904 // version number | |
23905 moment.version = VERSION; | |
23906 | |
23907 // default format | |
23908 moment.defaultFormat = isoFormat; | |
23909 | |
23910 // This function will be called whenever a moment is mutated. | |
23911 // It is intended to keep the offset in sync with the timezone. | |
23912 moment.updateOffset = function () {}; | |
23913 | |
23914 // This function will load languages and then set the global language. If | |
23915 // no arguments are passed in, it will simply return the current global | |
23916 // language key. | |
23917 moment.lang = function (key, values) { | |
23918 var r; | |
23919 if (!key) { | |
23920 return moment.fn._lang._abbr; | |
23921 } | |
23922 if (values) { | |
23923 loadLang(normalizeLanguage(key), values); | |
23924 } else if (values === null) { | |
23925 unloadLang(key); | |
23926 key = 'en'; | |
23927 } else if (!languages[key]) { | |
23928 getLangDefinition(key); | |
23929 } | |
23930 r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key); | |
23931 return r._abbr; | |
23932 }; | |
23933 | |
23934 // returns language data | |
23935 moment.langData = function (key) { | |
23936 if (key && key._lang && key._lang._abbr) { | |
23937 key = key._lang._abbr; | |
23938 } | |
23939 return getLangDefinition(key); | |
23940 }; | |
23941 | |
23942 // compare moment object | |
23943 moment.isMoment = function (obj) { | |
23944 return obj instanceof Moment || | |
23945 (obj != null && obj.hasOwnProperty('_isAMomentObject')); | |
23946 }; | |
23947 | |
23948 // for typechecking Duration objects | |
23949 moment.isDuration = function (obj) { | |
23950 return obj instanceof Duration; | |
23951 }; | |
23952 | |
23953 for (i = lists.length - 1; i >= 0; --i) { | |
23954 makeList(lists[i]); | |
23955 } | |
23956 | |
23957 moment.normalizeUnits = function (units) { | |
23958 return normalizeUnits(units); | |
23959 }; | |
23960 | |
23961 moment.invalid = function (flags) { | |
23962 var m = moment.utc(NaN); | |
23963 if (flags != null) { | |
23964 extend(m._pf, flags); | |
23965 } | |
23966 else { | |
23967 m._pf.userInvalidated = true; | |
23968 } | |
23969 | |
23970 return m; | |
23971 }; | |
23972 | |
23973 moment.parseZone = function (input) { | |
23974 return moment(input).parseZone(); | |
23975 }; | |
23976 | |
23977 /************************************ | |
23978 Moment Prototype | |
23979 ************************************/ | |
23980 | |
23981 | |
23982 extend(moment.fn = Moment.prototype, { | |
23983 | |
23984 clone : function () { | |
23985 return moment(this); | |
23986 }, | |
23987 | |
23988 valueOf : function () { | |
23989 return +this._d + ((this._offset || 0) * 60000); | |
23990 }, | |
23991 | |
23992 unix : function () { | |
23993 return Math.floor(+this / 1000); | |
23994 }, | |
23995 | |
23996 toString : function () { | |
23997 return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ"); | |
23998 }, | |
23999 | |
24000 toDate : function () { | |
24001 return this._offset ? new Date(+this) : this._d; | |
24002 }, | |
24003 | |
24004 toISOString : function () { | |
24005 var m = moment(this).utc(); | |
24006 if (0 < m.year() && m.year() <= 9999) { | |
24007 return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); | |
24008 } else { | |
24009 return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); | |
24010 } | |
24011 }, | |
24012 | |
24013 toArray : function () { | |
24014 var m = this; | |
24015 return [ | |
24016 m.year(), | |
24017 m.month(), | |
24018 m.date(), | |
24019 m.hours(), | |
24020 m.minutes(), | |
24021 m.seconds(), | |
24022 m.milliseconds() | |
24023 ]; | |
24024 }, | |
24025 | |
24026 isValid : function () { | |
24027 return isValid(this); | |
24028 }, | |
24029 | |
24030 isDSTShifted : function () { | |
24031 | |
24032 if (this._a) { | |
24033 return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0; | |
24034 } | |
24035 | |
24036 return false; | |
24037 }, | |
24038 | |
24039 parsingFlags : function () { | |
24040 return extend({}, this._pf); | |
24041 }, | |
24042 | |
24043 invalidAt: function () { | |
24044 return this._pf.overflow; | |
24045 }, | |
24046 | |
24047 utc : function () { | |
24048 return this.zone(0); | |
24049 }, | |
24050 | |
24051 local : function () { | |
24052 this.zone(0); | |
24053 this._isUTC = false; | |
24054 return this; | |
24055 }, | |
24056 | |
24057 format : function (inputString) { | |
24058 var output = formatMoment(this, inputString || moment.defaultFormat); | |
24059 return this.lang().postformat(output); | |
24060 }, | |
24061 | |
24062 add : function (input, val) { | |
24063 var dur; | |
24064 // switch args to support add('s', 1) and add(1, 's') | |
24065 if (typeof input === 'string') { | |
24066 dur = moment.duration(+val, input); | |
24067 } else { | |
24068 dur = moment.duration(input, val); | |
24069 } | |
24070 addOrSubtractDurationFromMoment(this, dur, 1); | |
24071 return this; | |
24072 }, | |
24073 | |
24074 subtract : function (input, val) { | |
24075 var dur; | |
24076 // switch args to support subtract('s', 1) and subtract(1, 's') | |
24077 if (typeof input === 'string') { | |
24078 dur = moment.duration(+val, input); | |
24079 } else { | |
24080 dur = moment.duration(input, val); | |
24081 } | |
24082 addOrSubtractDurationFromMoment(this, dur, -1); | |
24083 return this; | |
24084 }, | |
24085 | |
24086 diff : function (input, units, asFloat) { | |
24087 var that = makeAs(input, this), | |
24088 zoneDiff = (this.zone() - that.zone()) * 6e4, | |
24089 diff, output; | |
24090 | |
24091 units = normalizeUnits(units); | |
24092 | |
24093 if (units === 'year' || units === 'month') { | |
24094 // average number of days in the months in the given dates | |
24095 diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2 | |
24096 // difference in months | |
24097 output = ((this.year() - that.year()) * 12) + (this.month() - that.month()); | |
24098 // adjust by taking difference in days, average number of days | |
24099 // and dst in the given months. | |
24100 output += ((this - moment(this).startOf('month')) - | |
24101 (that - moment(that).startOf('month'))) / diff; | |
24102 // same as above but with zones, to negate all dst | |
24103 output -= ((this.zone() - moment(this).startOf('month').zone()) - | |
24104 (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff; | |
24105 if (units === 'year') { | |
24106 output = output / 12; | |
24107 } | |
24108 } else { | |
24109 diff = (this - that); | |
24110 output = units === 'second' ? diff / 1e3 : // 1000 | |
24111 units === 'minute' ? diff / 6e4 : // 1000 * 60 | |
24112 units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60 | |
24113 units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst | |
24114 units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst | |
24115 diff; | |
24116 } | |
24117 return asFloat ? output : absRound(output); | |
24118 }, | |
24119 | |
24120 from : function (time, withoutSuffix) { | |
24121 return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix); | |
24122 }, | |
24123 | |
24124 fromNow : function (withoutSuffix) { | |
24125 return this.from(moment(), withoutSuffix); | |
24126 }, | |
24127 | |
24128 calendar : function () { | |
24129 // We want to compare the start of today, vs this. | |
24130 // Getting start-of-today depends on whether we're zone'd or not. | |
24131 var sod = makeAs(moment(), this).startOf('day'), | |
24132 diff = this.diff(sod, 'days', true), | |
24133 format = diff < -6 ? 'sameElse' : | |
24134 diff < -1 ? 'lastWeek' : | |
24135 diff < 0 ? 'lastDay' : | |
24136 diff < 1 ? 'sameDay' : | |
24137 diff < 2 ? 'nextDay' : | |
24138 diff < 7 ? 'nextWeek' : 'sameElse'; | |
24139 return this.format(this.lang().calendar(format, this)); | |
24140 }, | |
24141 | |
24142 isLeapYear : function () { | |
24143 return isLeapYear(this.year()); | |
24144 }, | |
24145 | |
24146 isDST : function () { | |
24147 return (this.zone() < this.clone().month(0).zone() || | |
24148 this.zone() < this.clone().month(5).zone()); | |
24149 }, | |
24150 | |
24151 day : function (input) { | |
24152 var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); | |
24153 if (input != null) { | |
24154 input = parseWeekday(input, this.lang()); | |
24155 return this.add({ d : input - day }); | |
24156 } else { | |
24157 return day; | |
24158 } | |
24159 }, | |
24160 | |
24161 month : function (input) { | |
24162 var utc = this._isUTC ? 'UTC' : '', | |
24163 dayOfMonth; | |
24164 | |
24165 if (input != null) { | |
24166 if (typeof input === 'string') { | |
24167 input = this.lang().monthsParse(input); | |
24168 if (typeof input !== 'number') { | |
24169 return this; | |
24170 } | |
24171 } | |
24172 | |
24173 dayOfMonth = this.date(); | |
24174 this.date(1); | |
24175 this._d['set' + utc + 'Month'](input); | |
24176 this.date(Math.min(dayOfMonth, this.daysInMonth())); | |
24177 | |
24178 moment.updateOffset(this); | |
24179 return this; | |
24180 } else { | |
24181 return this._d['get' + utc + 'Month'](); | |
24182 } | |
24183 }, | |
24184 | |
24185 startOf: function (units) { | |
24186 units = normalizeUnits(units); | |
24187 // the following switch intentionally omits break keywords | |
24188 // to utilize falling through the cases. | |
24189 switch (units) { | |
24190 case 'year': | |
24191 this.month(0); | |
24192 /* falls through */ | |
24193 case 'month': | |
24194 this.date(1); | |
24195 /* falls through */ | |
24196 case 'week': | |
24197 case 'isoWeek': | |
24198 case 'day': | |
24199 this.hours(0); | |
24200 /* falls through */ | |
24201 case 'hour': | |
24202 this.minutes(0); | |
24203 /* falls through */ | |
24204 case 'minute': | |
24205 this.seconds(0); | |
24206 /* falls through */ | |
24207 case 'second': | |
24208 this.milliseconds(0); | |
24209 /* falls through */ | |
24210 } | |
24211 | |
24212 // weeks are a special case | |
24213 if (units === 'week') { | |
24214 this.weekday(0); | |
24215 } else if (units === 'isoWeek') { | |
24216 this.isoWeekday(1); | |
24217 } | |
24218 | |
24219 return this; | |
24220 }, | |
24221 | |
24222 endOf: function (units) { | |
24223 units = normalizeUnits(units); | |
24224 return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1); | |
24225 }, | |
24226 | |
24227 isAfter: function (input, units) { | |
24228 units = typeof units !== 'undefined' ? units : 'millisecond'; | |
24229 return +this.clone().startOf(units) > +moment(input).startOf(units); | |
24230 }, | |
24231 | |
24232 isBefore: function (input, units) { | |
24233 units = typeof units !== 'undefined' ? units : 'millisecond'; | |
24234 return +this.clone().startOf(units) < +moment(input).startOf(units); | |
24235 }, | |
24236 | |
24237 isSame: function (input, units) { | |
24238 units = units || 'ms'; | |
24239 return +this.clone().startOf(units) === +makeAs(input, this).startOf(units); | |
24240 }, | |
24241 | |
24242 min: function (other) { | |
24243 other = moment.apply(null, arguments); | |
24244 return other < this ? this : other; | |
24245 }, | |
24246 | |
24247 max: function (other) { | |
24248 other = moment.apply(null, arguments); | |
24249 return other > this ? this : other; | |
24250 }, | |
24251 | |
24252 zone : function (input) { | |
24253 var offset = this._offset || 0; | |
24254 if (input != null) { | |
24255 if (typeof input === "string") { | |
24256 input = timezoneMinutesFromString(input); | |
24257 } | |
24258 if (Math.abs(input) < 16) { | |
24259 input = input * 60; | |
24260 } | |
24261 this._offset = input; | |
24262 this._isUTC = true; | |
24263 if (offset !== input) { | |
24264 addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true); | |
24265 } | |
24266 } else { | |
24267 return this._isUTC ? offset : this._d.getTimezoneOffset(); | |
24268 } | |
24269 return this; | |
24270 }, | |
24271 | |
24272 zoneAbbr : function () { | |
24273 return this._isUTC ? "UTC" : ""; | |
24274 }, | |
24275 | |
24276 zoneName : function () { | |
24277 return this._isUTC ? "Coordinated Universal Time" : ""; | |
24278 }, | |
24279 | |
24280 parseZone : function () { | |
24281 if (this._tzm) { | |
24282 this.zone(this._tzm); | |
24283 } else if (typeof this._i === 'string') { | |
24284 this.zone(this._i); | |
24285 } | |
24286 return this; | |
24287 }, | |
24288 | |
24289 hasAlignedHourOffset : function (input) { | |
24290 if (!input) { | |
24291 input = 0; | |
24292 } | |
24293 else { | |
24294 input = moment(input).zone(); | |
24295 } | |
24296 | |
24297 return (this.zone() - input) % 60 === 0; | |
24298 }, | |
24299 | |
24300 daysInMonth : function () { | |
24301 return daysInMonth(this.year(), this.month()); | |
24302 }, | |
24303 | |
24304 dayOfYear : function (input) { | |
24305 var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1; | |
24306 return input == null ? dayOfYear : this.add("d", (input - dayOfYear)); | |
24307 }, | |
24308 | |
24309 quarter : function () { | |
24310 return Math.ceil((this.month() + 1.0) / 3.0); | |
24311 }, | |
24312 | |
24313 weekYear : function (input) { | |
24314 var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year; | |
24315 return input == null ? year : this.add("y", (input - year)); | |
24316 }, | |
24317 | |
24318 isoWeekYear : function (input) { | |
24319 var year = weekOfYear(this, 1, 4).year; | |
24320 return input == null ? year : this.add("y", (input - year)); | |
24321 }, | |
24322 | |
24323 week : function (input) { | |
24324 var week = this.lang().week(this); | |
24325 return input == null ? week : this.add("d", (input - week) * 7); | |
24326 }, | |
24327 | |
24328 isoWeek : function (input) { | |
24329 var week = weekOfYear(this, 1, 4).week; | |
24330 return input == null ? week : this.add("d", (input - week) * 7); | |
24331 }, | |
24332 | |
24333 weekday : function (input) { | |
24334 var weekday = (this.day() + 7 - this.lang()._week.dow) % 7; | |
24335 return input == null ? weekday : this.add("d", input - weekday); | |
24336 }, | |
24337 | |
24338 isoWeekday : function (input) { | |
24339 // behaves the same as moment#day except | |
24340 // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) | |
24341 // as a setter, sunday should belong to the previous week. | |
24342 return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); | |
24343 }, | |
24344 | |
24345 get : function (units) { | |
24346 units = normalizeUnits(units); | |
24347 return this[units](); | |
24348 }, | |
24349 | |
24350 set : function (units, value) { | |
24351 units = normalizeUnits(units); | |
24352 if (typeof this[units] === 'function') { | |
24353 this[units](value); | |
24354 } | |
24355 return this; | |
24356 }, | |
24357 | |
24358 // If passed a language key, it will set the language for this | |
24359 // instance. Otherwise, it will return the language configuration | |
24360 // variables for this instance. | |
24361 lang : function (key) { | |
24362 if (key === undefined) { | |
24363 return this._lang; | |
24364 } else { | |
24365 this._lang = getLangDefinition(key); | |
24366 return this; | |
24367 } | |
24368 } | |
24369 }); | |
24370 | |
24371 // helper for adding shortcuts | |
24372 function makeGetterAndSetter(name, key) { | |
24373 moment.fn[name] = moment.fn[name + 's'] = function (input) { | |
24374 var utc = this._isUTC ? 'UTC' : ''; | |
24375 if (input != null) { | |
24376 this._d['set' + utc + key](input); | |
24377 moment.updateOffset(this); | |
24378 return this; | |
24379 } else { | |
24380 return this._d['get' + utc + key](); | |
24381 } | |
24382 }; | |
24383 } | |
24384 | |
24385 // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds) | |
24386 for (i = 0; i < proxyGettersAndSetters.length; i ++) { | |
24387 makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]); | |
24388 } | |
24389 | |
24390 // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear') | |
24391 makeGetterAndSetter('year', 'FullYear'); | |
24392 | |
24393 // add plural methods | |
24394 moment.fn.days = moment.fn.day; | |
24395 moment.fn.months = moment.fn.month; | |
24396 moment.fn.weeks = moment.fn.week; | |
24397 moment.fn.isoWeeks = moment.fn.isoWeek; | |
24398 | |
24399 // add aliased format methods | |
24400 moment.fn.toJSON = moment.fn.toISOString; | |
24401 | |
24402 /************************************ | |
24403 Duration Prototype | |
24404 ************************************/ | |
24405 | |
24406 | |
24407 extend(moment.duration.fn = Duration.prototype, { | |
24408 | |
24409 _bubble : function () { | |
24410 var milliseconds = this._milliseconds, | |
24411 days = this._days, | |
24412 months = this._months, | |
24413 data = this._data, | |
24414 seconds, minutes, hours, years; | |
24415 | |
24416 // The following code bubbles up values, see the tests for | |
24417 // examples of what that means. | |
24418 data.milliseconds = milliseconds % 1000; | |
24419 | |
24420 seconds = absRound(milliseconds / 1000); | |
24421 data.seconds = seconds % 60; | |
24422 | |
24423 minutes = absRound(seconds / 60); | |
24424 data.minutes = minutes % 60; | |
24425 | |
24426 hours = absRound(minutes / 60); | |
24427 data.hours = hours % 24; | |
24428 | |
24429 days += absRound(hours / 24); | |
24430 data.days = days % 30; | |
24431 | |
24432 months += absRound(days / 30); | |
24433 data.months = months % 12; | |
24434 | |
24435 years = absRound(months / 12); | |
24436 data.years = years; | |
24437 }, | |
24438 | |
24439 weeks : function () { | |
24440 return absRound(this.days() / 7); | |
24441 }, | |
24442 | |
24443 valueOf : function () { | |
24444 return this._milliseconds + | |
24445 this._days * 864e5 + | |
24446 (this._months % 12) * 2592e6 + | |
24447 toInt(this._months / 12) * 31536e6; | |
24448 }, | |
24449 | |
24450 humanize : function (withSuffix) { | |
24451 var difference = +this, | |
24452 output = relativeTime(difference, !withSuffix, this.lang()); | |
24453 | |
24454 if (withSuffix) { | |
24455 output = this.lang().pastFuture(difference, output); | |
24456 } | |
24457 | |
24458 return this.lang().postformat(output); | |
24459 }, | |
24460 | |
24461 add : function (input, val) { | |
24462 // supports only 2.0-style add(1, 's') or add(moment) | |
24463 var dur = moment.duration(input, val); | |
24464 | |
24465 this._milliseconds += dur._milliseconds; | |
24466 this._days += dur._days; | |
24467 this._months += dur._months; | |
24468 | |
24469 this._bubble(); | |
24470 | |
24471 return this; | |
24472 }, | |
24473 | |
24474 subtract : function (input, val) { | |
24475 var dur = moment.duration(input, val); | |
24476 | |
24477 this._milliseconds -= dur._milliseconds; | |
24478 this._days -= dur._days; | |
24479 this._months -= dur._months; | |
24480 | |
24481 this._bubble(); | |
24482 | |
24483 return this; | |
24484 }, | |
24485 | |
24486 get : function (units) { | |
24487 units = normalizeUnits(units); | |
24488 return this[units.toLowerCase() + 's'](); | |
24489 }, | |
24490 | |
24491 as : function (units) { | |
24492 units = normalizeUnits(units); | |
24493 return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's'](); | |
24494 }, | |
24495 | |
24496 lang : moment.fn.lang, | |
24497 | |
24498 toIsoString : function () { | |
24499 // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js | |
24500 var years = Math.abs(this.years()), | |
24501 months = Math.abs(this.months()), | |
24502 days = Math.abs(this.days()), | |
24503 hours = Math.abs(this.hours()), | |
24504 minutes = Math.abs(this.minutes()), | |
24505 seconds = Math.abs(this.seconds() + this.milliseconds() / 1000); | |
24506 | |
24507 if (!this.asSeconds()) { | |
24508 // this is the same as C#'s (Noda) and python (isodate)... | |
24509 // but not other JS (goog.date) | |
24510 return 'P0D'; | |
24511 } | |
24512 | |
24513 return (this.asSeconds() < 0 ? '-' : '') + | |
24514 'P' + | |
24515 (years ? years + 'Y' : '') + | |
24516 (months ? months + 'M' : '') + | |
24517 (days ? days + 'D' : '') + | |
24518 ((hours || minutes || seconds) ? 'T' : '') + | |
24519 (hours ? hours + 'H' : '') + | |
24520 (minutes ? minutes + 'M' : '') + | |
24521 (seconds ? seconds + 'S' : ''); | |
24522 } | |
24523 }); | |
24524 | |
24525 function makeDurationGetter(name) { | |
24526 moment.duration.fn[name] = function () { | |
24527 return this._data[name]; | |
24528 }; | |
24529 } | |
24530 | |
24531 function makeDurationAsGetter(name, factor) { | |
24532 moment.duration.fn['as' + name] = function () { | |
24533 return +this / factor; | |
24534 }; | |
24535 } | |
24536 | |
24537 for (i in unitMillisecondFactors) { | |
24538 if (unitMillisecondFactors.hasOwnProperty(i)) { | |
24539 makeDurationAsGetter(i, unitMillisecondFactors[i]); | |
24540 makeDurationGetter(i.toLowerCase()); | |
24541 } | |
24542 } | |
24543 | |
24544 makeDurationAsGetter('Weeks', 6048e5); | |
24545 moment.duration.fn.asMonths = function () { | |
24546 return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12; | |
24547 }; | |
24548 | |
24549 | |
24550 /************************************ | |
24551 Default Lang | |
24552 ************************************/ | |
24553 | |
24554 | |
24555 // Set default language, other languages will inherit from English. | |
24556 moment.lang('en', { | |
24557 ordinal : function (number) { | |
24558 var b = number % 10, | |
24559 output = (toInt(number % 100 / 10) === 1) ? 'th' : | |
24560 (b === 1) ? 'st' : | |
24561 (b === 2) ? 'nd' : | |
24562 (b === 3) ? 'rd' : 'th'; | |
24563 return number + output; | |
24564 } | |
24565 }); | |
24566 | |
24567 /* EMBED_LANGUAGES */ | |
24568 | |
24569 /************************************ | |
24570 Exposing Moment | |
24571 ************************************/ | |
24572 | |
24573 function makeGlobal(deprecate) { | |
24574 var warned = false, local_moment = moment; | |
24575 /*global ender:false */ | |
24576 if (typeof ender !== 'undefined') { | |
24577 return; | |
24578 } | |
24579 // here, `this` means `window` in the browser, or `global` on the server | |
24580 // add `moment` as a global object via a string identifier, | |
24581 // for Closure Compiler "advanced" mode | |
24582 if (deprecate) { | |
24583 global.moment = function () { | |
24584 if (!warned && console && console.warn) { | |
24585 warned = true; | |
24586 console.warn( | |
24587 "Accessing Moment through the global scope is " + | |
24588 "deprecated, and will be removed in an upcoming " + | |
24589 "release."); | |
24590 } | |
24591 return local_moment.apply(null, arguments); | |
24592 }; | |
24593 extend(global.moment, local_moment); | |
24594 } else { | |
24595 global['moment'] = moment; | |
24596 } | |
24597 } | |
24598 | |
24599 // CommonJS module is defined | |
24600 if (hasModule) { | |
24601 module.exports = moment; | |
24602 makeGlobal(true); | |
24603 } else if (typeof define === "function" && define.amd) { | |
24604 define("moment", function (require, exports, module) { | |
24605 if (module.config && module.config() && module.config().noGlobal !== true) { | |
24606 // If user provided noGlobal, he is aware of global | |
24607 makeGlobal(module.config().noGlobal === undefined); | |
24608 } | |
24609 | |
24610 return moment; | |
24611 }); | |
24612 } else { | |
24613 makeGlobal(); | |
24614 } | |
24615 }).call(this); | |
24616 /*! | |
24617 * UCSV 1.1.0 | |
24618 * Provided under MIT License. | |
24619 * | |
24620 * Copyright 2010-2012, Peter Johnson | |
24621 * http://www.uselesscode.org/javascript/csv/ | |
24622 */ | |
24623 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}}()); | |
24624 /* Javascript plotting library for jQuery, version 0.8.2. | |
24625 | |
24626 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
24627 Licensed under the MIT license. | |
24628 | |
24629 */ | |
24630 | |
24631 // first an inline dependency, jquery.colorhelpers.js, we inline it here | |
24632 // for convenience | |
24633 | |
24634 /* Plugin for jQuery for working with colors. | |
24635 * | |
24636 * Version 1.1. | |
24637 * | |
24638 * Inspiration from jQuery color animation plugin by John Resig. | |
24639 * | |
24640 * Released under the MIT license by Ole Laursen, October 2009. | |
24641 * | |
24642 * Examples: | |
24643 * | |
24644 * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() | |
24645 * var c = $.color.extract($("#mydiv"), 'background-color'); | |
24646 * console.log(c.r, c.g, c.b, c.a); | |
24647 * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" | |
24648 * | |
24649 * Note that .scale() and .add() return the same modified object | |
24650 * instead of making a new one. | |
24651 * | |
24652 * V. 1.1: Fix error handling so e.g. parsing an empty string does | |
24653 * produce a color rather than just crashing. | |
24654 */ | |
24655 (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); | |
24656 | |
24657 // the actual Flot code | |
24658 (function($) { | |
24659 | |
24660 // Cache the prototype hasOwnProperty for faster access | |
24661 | |
24662 var hasOwnProperty = Object.prototype.hasOwnProperty; | |
24663 | |
24664 /////////////////////////////////////////////////////////////////////////// | |
24665 // The Canvas object is a wrapper around an HTML5 <canvas> tag. | |
24666 // | |
24667 // @constructor | |
24668 // @param {string} cls List of classes to apply to the canvas. | |
24669 // @param {element} container Element onto which to append the canvas. | |
24670 // | |
24671 // Requiring a container is a little iffy, but unfortunately canvas | |
24672 // operations don't work unless the canvas is attached to the DOM. | |
24673 | |
24674 function Canvas(cls, container) { | |
24675 | |
24676 var element = container.children("." + cls)[0]; | |
24677 | |
24678 if (element == null) { | |
24679 | |
24680 element = document.createElement("canvas"); | |
24681 element.className = cls; | |
24682 | |
24683 $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) | |
24684 .appendTo(container); | |
24685 | |
24686 // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas | |
24687 | |
24688 if (!element.getContext) { | |
24689 if (window.G_vmlCanvasManager) { | |
24690 element = window.G_vmlCanvasManager.initElement(element); | |
24691 } else { | |
24692 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."); | |
24693 } | |
24694 } | |
24695 } | |
24696 | |
24697 this.element = element; | |
24698 | |
24699 var context = this.context = element.getContext("2d"); | |
24700 | |
24701 // Determine the screen's ratio of physical to device-independent | |
24702 // pixels. This is the ratio between the canvas width that the browser | |
24703 // advertises and the number of pixels actually present in that space. | |
24704 | |
24705 // The iPhone 4, for example, has a device-independent width of 320px, | |
24706 // but its screen is actually 640px wide. It therefore has a pixel | |
24707 // ratio of 2, while most normal devices have a ratio of 1. | |
24708 | |
24709 var devicePixelRatio = window.devicePixelRatio || 1, | |
24710 backingStoreRatio = | |
24711 context.webkitBackingStorePixelRatio || | |
24712 context.mozBackingStorePixelRatio || | |
24713 context.msBackingStorePixelRatio || | |
24714 context.oBackingStorePixelRatio || | |
24715 context.backingStorePixelRatio || 1; | |
24716 | |
24717 this.pixelRatio = devicePixelRatio / backingStoreRatio; | |
24718 | |
24719 // Size the canvas to match the internal dimensions of its container | |
24720 | |
24721 this.resize(container.width(), container.height()); | |
24722 | |
24723 // Collection of HTML div layers for text overlaid onto the canvas | |
24724 | |
24725 this.textContainer = null; | |
24726 this.text = {}; | |
24727 | |
24728 // Cache of text fragments and metrics, so we can avoid expensively | |
24729 // re-calculating them when the plot is re-rendered in a loop. | |
24730 | |
24731 this._textCache = {}; | |
24732 } | |
24733 | |
24734 // Resizes the canvas to the given dimensions. | |
24735 // | |
24736 // @param {number} width New width of the canvas, in pixels. | |
24737 // @param {number} width New height of the canvas, in pixels. | |
24738 | |
24739 Canvas.prototype.resize = function(width, height) { | |
24740 | |
24741 if (width <= 0 || height <= 0) { | |
24742 throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); | |
24743 } | |
24744 | |
24745 var element = this.element, | |
24746 context = this.context, | |
24747 pixelRatio = this.pixelRatio; | |
24748 | |
24749 // Resize the canvas, increasing its density based on the display's | |
24750 // pixel ratio; basically giving it more pixels without increasing the | |
24751 // size of its element, to take advantage of the fact that retina | |
24752 // displays have that many more pixels in the same advertised space. | |
24753 | |
24754 // Resizing should reset the state (excanvas seems to be buggy though) | |
24755 | |
24756 if (this.width != width) { | |
24757 element.width = width * pixelRatio; | |
24758 element.style.width = width + "px"; | |
24759 this.width = width; | |
24760 } | |
24761 | |
24762 if (this.height != height) { | |
24763 element.height = height * pixelRatio; | |
24764 element.style.height = height + "px"; | |
24765 this.height = height; | |
24766 } | |
24767 | |
24768 // Save the context, so we can reset in case we get replotted. The | |
24769 // restore ensure that we're really back at the initial state, and | |
24770 // should be safe even if we haven't saved the initial state yet. | |
24771 | |
24772 context.restore(); | |
24773 context.save(); | |
24774 | |
24775 // Scale the coordinate space to match the display density; so even though we | |
24776 // may have twice as many pixels, we still want lines and other drawing to | |
24777 // appear at the same size; the extra pixels will just make them crisper. | |
24778 | |
24779 context.scale(pixelRatio, pixelRatio); | |
24780 }; | |
24781 | |
24782 // Clears the entire canvas area, not including any overlaid HTML text | |
24783 | |
24784 Canvas.prototype.clear = function() { | |
24785 this.context.clearRect(0, 0, this.width, this.height); | |
24786 }; | |
24787 | |
24788 // Finishes rendering the canvas, including managing the text overlay. | |
24789 | |
24790 Canvas.prototype.render = function() { | |
24791 | |
24792 var cache = this._textCache; | |
24793 | |
24794 // For each text layer, add elements marked as active that haven't | |
24795 // already been rendered, and remove those that are no longer active. | |
24796 | |
24797 for (var layerKey in cache) { | |
24798 if (hasOwnProperty.call(cache, layerKey)) { | |
24799 | |
24800 var layer = this.getTextLayer(layerKey), | |
24801 layerCache = cache[layerKey]; | |
24802 | |
24803 layer.hide(); | |
24804 | |
24805 for (var styleKey in layerCache) { | |
24806 if (hasOwnProperty.call(layerCache, styleKey)) { | |
24807 var styleCache = layerCache[styleKey]; | |
24808 for (var key in styleCache) { | |
24809 if (hasOwnProperty.call(styleCache, key)) { | |
24810 | |
24811 var positions = styleCache[key].positions; | |
24812 | |
24813 for (var i = 0, position; position = positions[i]; i++) { | |
24814 if (position.active) { | |
24815 if (!position.rendered) { | |
24816 layer.append(position.element); | |
24817 position.rendered = true; | |
24818 } | |
24819 } else { | |
24820 positions.splice(i--, 1); | |
24821 if (position.rendered) { | |
24822 position.element.detach(); | |
24823 } | |
24824 } | |
24825 } | |
24826 | |
24827 if (positions.length == 0) { | |
24828 delete styleCache[key]; | |
24829 } | |
24830 } | |
24831 } | |
24832 } | |
24833 } | |
24834 | |
24835 layer.show(); | |
24836 } | |
24837 } | |
24838 }; | |
24839 | |
24840 // Creates (if necessary) and returns the text overlay container. | |
24841 // | |
24842 // @param {string} classes String of space-separated CSS classes used to | |
24843 // uniquely identify the text layer. | |
24844 // @return {object} The jQuery-wrapped text-layer div. | |
24845 | |
24846 Canvas.prototype.getTextLayer = function(classes) { | |
24847 | |
24848 var layer = this.text[classes]; | |
24849 | |
24850 // Create the text layer if it doesn't exist | |
24851 | |
24852 if (layer == null) { | |
24853 | |
24854 // Create the text layer container, if it doesn't exist | |
24855 | |
24856 if (this.textContainer == null) { | |
24857 this.textContainer = $("<div class='flot-text'></div>") | |
24858 .css({ | |
24859 position: "absolute", | |
24860 top: 0, | |
24861 left: 0, | |
24862 bottom: 0, | |
24863 right: 0, | |
24864 'font-size': "smaller", | |
24865 color: "#545454" | |
24866 }) | |
24867 .insertAfter(this.element); | |
24868 } | |
24869 | |
24870 layer = this.text[classes] = $("<div></div>") | |
24871 .addClass(classes) | |
24872 .css({ | |
24873 position: "absolute", | |
24874 top: 0, | |
24875 left: 0, | |
24876 bottom: 0, | |
24877 right: 0 | |
24878 }) | |
24879 .appendTo(this.textContainer); | |
24880 } | |
24881 | |
24882 return layer; | |
24883 }; | |
24884 | |
24885 // Creates (if necessary) and returns a text info object. | |
24886 // | |
24887 // The object looks like this: | |
24888 // | |
24889 // { | |
24890 // width: Width of the text's wrapper div. | |
24891 // height: Height of the text's wrapper div. | |
24892 // element: The jQuery-wrapped HTML div containing the text. | |
24893 // positions: Array of positions at which this text is drawn. | |
24894 // } | |
24895 // | |
24896 // The positions array contains objects that look like this: | |
24897 // | |
24898 // { | |
24899 // active: Flag indicating whether the text should be visible. | |
24900 // rendered: Flag indicating whether the text is currently visible. | |
24901 // element: The jQuery-wrapped HTML div containing the text. | |
24902 // x: X coordinate at which to draw the text. | |
24903 // y: Y coordinate at which to draw the text. | |
24904 // } | |
24905 // | |
24906 // Each position after the first receives a clone of the original element. | |
24907 // | |
24908 // The idea is that that the width, height, and general 'identity' of the | |
24909 // text is constant no matter where it is placed; the placements are a | |
24910 // secondary property. | |
24911 // | |
24912 // Canvas maintains a cache of recently-used text info objects; getTextInfo | |
24913 // either returns the cached element or creates a new entry. | |
24914 // | |
24915 // @param {string} layer A string of space-separated CSS classes uniquely | |
24916 // identifying the layer containing this text. | |
24917 // @param {string} text Text string to retrieve info for. | |
24918 // @param {(string|object)=} font Either a string of space-separated CSS | |
24919 // classes or a font-spec object, defining the text's font and style. | |
24920 // @param {number=} angle Angle at which to rotate the text, in degrees. | |
24921 // Angle is currently unused, it will be implemented in the future. | |
24922 // @param {number=} width Maximum width of the text before it wraps. | |
24923 // @return {object} a text info object. | |
24924 | |
24925 Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { | |
24926 | |
24927 var textStyle, layerCache, styleCache, info; | |
24928 | |
24929 // Cast the value to a string, in case we were given a number or such | |
24930 | |
24931 text = "" + text; | |
24932 | |
24933 // If the font is a font-spec object, generate a CSS font definition | |
24934 | |
24935 if (typeof font === "object") { | |
24936 textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; | |
24937 } else { | |
24938 textStyle = font; | |
24939 } | |
24940 | |
24941 // Retrieve (or create) the cache for the text's layer and styles | |
24942 | |
24943 layerCache = this._textCache[layer]; | |
24944 | |
24945 if (layerCache == null) { | |
24946 layerCache = this._textCache[layer] = {}; | |
24947 } | |
24948 | |
24949 styleCache = layerCache[textStyle]; | |
24950 | |
24951 if (styleCache == null) { | |
24952 styleCache = layerCache[textStyle] = {}; | |
24953 } | |
24954 | |
24955 info = styleCache[text]; | |
24956 | |
24957 // If we can't find a matching element in our cache, create a new one | |
24958 | |
24959 if (info == null) { | |
24960 | |
24961 var element = $("<div></div>").html(text) | |
24962 .css({ | |
24963 position: "absolute", | |
24964 'max-width': width, | |
24965 top: -9999 | |
24966 }) | |
24967 .appendTo(this.getTextLayer(layer)); | |
24968 | |
24969 if (typeof font === "object") { | |
24970 element.css({ | |
24971 font: textStyle, | |
24972 color: font.color | |
24973 }); | |
24974 } else if (typeof font === "string") { | |
24975 element.addClass(font); | |
24976 } | |
24977 | |
24978 info = styleCache[text] = { | |
24979 width: element.outerWidth(true), | |
24980 height: element.outerHeight(true), | |
24981 element: element, | |
24982 positions: [] | |
24983 }; | |
24984 | |
24985 element.detach(); | |
24986 } | |
24987 | |
24988 return info; | |
24989 }; | |
24990 | |
24991 // Adds a text string to the canvas text overlay. | |
24992 // | |
24993 // The text isn't drawn immediately; it is marked as rendering, which will | |
24994 // result in its addition to the canvas on the next render pass. | |
24995 // | |
24996 // @param {string} layer A string of space-separated CSS classes uniquely | |
24997 // identifying the layer containing this text. | |
24998 // @param {number} x X coordinate at which to draw the text. | |
24999 // @param {number} y Y coordinate at which to draw the text. | |
25000 // @param {string} text Text string to draw. | |
25001 // @param {(string|object)=} font Either a string of space-separated CSS | |
25002 // classes or a font-spec object, defining the text's font and style. | |
25003 // @param {number=} angle Angle at which to rotate the text, in degrees. | |
25004 // Angle is currently unused, it will be implemented in the future. | |
25005 // @param {number=} width Maximum width of the text before it wraps. | |
25006 // @param {string=} halign Horizontal alignment of the text; either "left", | |
25007 // "center" or "right". | |
25008 // @param {string=} valign Vertical alignment of the text; either "top", | |
25009 // "middle" or "bottom". | |
25010 | |
25011 Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { | |
25012 | |
25013 var info = this.getTextInfo(layer, text, font, angle, width), | |
25014 positions = info.positions; | |
25015 | |
25016 // Tweak the div's position to match the text's alignment | |
25017 | |
25018 if (halign == "center") { | |
25019 x -= info.width / 2; | |
25020 } else if (halign == "right") { | |
25021 x -= info.width; | |
25022 } | |
25023 | |
25024 if (valign == "middle") { | |
25025 y -= info.height / 2; | |
25026 } else if (valign == "bottom") { | |
25027 y -= info.height; | |
25028 } | |
25029 | |
25030 // Determine whether this text already exists at this position. | |
25031 // If so, mark it for inclusion in the next render pass. | |
25032 | |
25033 for (var i = 0, position; position = positions[i]; i++) { | |
25034 if (position.x == x && position.y == y) { | |
25035 position.active = true; | |
25036 return; | |
25037 } | |
25038 } | |
25039 | |
25040 // If the text doesn't exist at this position, create a new entry | |
25041 | |
25042 // For the very first position we'll re-use the original element, | |
25043 // while for subsequent ones we'll clone it. | |
25044 | |
25045 position = { | |
25046 active: true, | |
25047 rendered: false, | |
25048 element: positions.length ? info.element.clone() : info.element, | |
25049 x: x, | |
25050 y: y | |
25051 }; | |
25052 | |
25053 positions.push(position); | |
25054 | |
25055 // Move the element to its final position within the container | |
25056 | |
25057 position.element.css({ | |
25058 top: Math.round(y), | |
25059 left: Math.round(x), | |
25060 'text-align': halign // In case the text wraps | |
25061 }); | |
25062 }; | |
25063 | |
25064 // Removes one or more text strings from the canvas text overlay. | |
25065 // | |
25066 // If no parameters are given, all text within the layer is removed. | |
25067 // | |
25068 // Note that the text is not immediately removed; it is simply marked as | |
25069 // inactive, which will result in its removal on the next render pass. | |
25070 // This avoids the performance penalty for 'clear and redraw' behavior, | |
25071 // where we potentially get rid of all text on a layer, but will likely | |
25072 // add back most or all of it later, as when redrawing axes, for example. | |
25073 // | |
25074 // @param {string} layer A string of space-separated CSS classes uniquely | |
25075 // identifying the layer containing this text. | |
25076 // @param {number=} x X coordinate of the text. | |
25077 // @param {number=} y Y coordinate of the text. | |
25078 // @param {string=} text Text string to remove. | |
25079 // @param {(string|object)=} font Either a string of space-separated CSS | |
25080 // classes or a font-spec object, defining the text's font and style. | |
25081 // @param {number=} angle Angle at which the text is rotated, in degrees. | |
25082 // Angle is currently unused, it will be implemented in the future. | |
25083 | |
25084 Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { | |
25085 if (text == null) { | |
25086 var layerCache = this._textCache[layer]; | |
25087 if (layerCache != null) { | |
25088 for (var styleKey in layerCache) { | |
25089 if (hasOwnProperty.call(layerCache, styleKey)) { | |
25090 var styleCache = layerCache[styleKey]; | |
25091 for (var key in styleCache) { | |
25092 if (hasOwnProperty.call(styleCache, key)) { | |
25093 var positions = styleCache[key].positions; | |
25094 for (var i = 0, position; position = positions[i]; i++) { | |
25095 position.active = false; | |
25096 } | |
25097 } | |
25098 } | |
25099 } | |
25100 } | |
25101 } | |
25102 } else { | |
25103 var positions = this.getTextInfo(layer, text, font, angle).positions; | |
25104 for (var i = 0, position; position = positions[i]; i++) { | |
25105 if (position.x == x && position.y == y) { | |
25106 position.active = false; | |
25107 } | |
25108 } | |
25109 } | |
25110 }; | |
25111 | |
25112 /////////////////////////////////////////////////////////////////////////// | |
25113 // The top-level container for the entire plot. | |
25114 | |
25115 function Plot(placeholder, data_, options_, plugins) { | |
25116 // data is on the form: | |
25117 // [ series1, series2 ... ] | |
25118 // where series is either just the data as [ [x1, y1], [x2, y2], ... ] | |
25119 // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } | |
25120 | |
25121 var series = [], | |
25122 options = { | |
25123 // the color theme used for graphs | |
25124 colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], | |
25125 legend: { | |
25126 show: true, | |
25127 noColumns: 1, // number of colums in legend table | |
25128 labelFormatter: null, // fn: string -> string | |
25129 labelBoxBorderColor: "#ccc", // border color for the little label boxes | |
25130 container: null, // container (as jQuery object) to put legend in, null means default on top of graph | |
25131 position: "ne", // position of default legend container within plot | |
25132 margin: 5, // distance from grid edge to default legend container within plot | |
25133 backgroundColor: null, // null means auto-detect | |
25134 backgroundOpacity: 0.85, // set to 0 to avoid background | |
25135 sorted: null // default to no legend sorting | |
25136 }, | |
25137 xaxis: { | |
25138 show: null, // null = auto-detect, true = always, false = never | |
25139 position: "bottom", // or "top" | |
25140 mode: null, // null or "time" | |
25141 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" } | |
25142 color: null, // base color, labels, ticks | |
25143 tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" | |
25144 transform: null, // null or f: number -> number to transform axis | |
25145 inverseTransform: null, // if transform is set, this should be the inverse function | |
25146 min: null, // min. value to show, null means set automatically | |
25147 max: null, // max. value to show, null means set automatically | |
25148 autoscaleMargin: null, // margin in % to add if auto-setting min/max | |
25149 ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks | |
25150 tickFormatter: null, // fn: number -> string | |
25151 labelWidth: null, // size of tick labels in pixels | |
25152 labelHeight: null, | |
25153 reserveSpace: null, // whether to reserve space even if axis isn't shown | |
25154 tickLength: null, // size in pixels of ticks, or "full" for whole line | |
25155 alignTicksWithAxis: null, // axis number or null for no sync | |
25156 tickDecimals: null, // no. of decimals, null means auto | |
25157 tickSize: null, // number or [number, "unit"] | |
25158 minTickSize: null // number or [number, "unit"] | |
25159 }, | |
25160 yaxis: { | |
25161 autoscaleMargin: 0.02, | |
25162 position: "left" // or "right" | |
25163 }, | |
25164 xaxes: [], | |
25165 yaxes: [], | |
25166 series: { | |
25167 points: { | |
25168 show: false, | |
25169 radius: 3, | |
25170 lineWidth: 2, // in pixels | |
25171 fill: true, | |
25172 fillColor: "#ffffff", | |
25173 symbol: "circle" // or callback | |
25174 }, | |
25175 lines: { | |
25176 // we don't put in show: false so we can see | |
25177 // whether lines were actively disabled | |
25178 lineWidth: 2, // in pixels | |
25179 fill: false, | |
25180 fillColor: null, | |
25181 steps: false | |
25182 // Omit 'zero', so we can later default its value to | |
25183 // match that of the 'fill' option. | |
25184 }, | |
25185 bars: { | |
25186 show: false, | |
25187 lineWidth: 2, // in pixels | |
25188 barWidth: 1, // in units of the x axis | |
25189 fill: true, | |
25190 fillColor: null, | |
25191 align: "left", // "left", "right", or "center" | |
25192 horizontal: false, | |
25193 zero: true | |
25194 }, | |
25195 shadowSize: 3, | |
25196 highlightColor: null | |
25197 }, | |
25198 grid: { | |
25199 show: true, | |
25200 aboveData: false, | |
25201 color: "#545454", // primary color used for outline and labels | |
25202 backgroundColor: null, // null for transparent, else color | |
25203 borderColor: null, // set if different from the grid color | |
25204 tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" | |
25205 margin: 0, // distance from the canvas edge to the grid | |
25206 labelMargin: 5, // in pixels | |
25207 axisMargin: 8, // in pixels | |
25208 borderWidth: 2, // in pixels | |
25209 minBorderMargin: null, // in pixels, null means taken from points radius | |
25210 markings: null, // array of ranges or fn: axes -> array of ranges | |
25211 markingsColor: "#f4f4f4", | |
25212 markingsLineWidth: 2, | |
25213 // interactive stuff | |
25214 clickable: false, | |
25215 hoverable: false, | |
25216 autoHighlight: true, // highlight in case mouse is near | |
25217 mouseActiveRadius: 10 // how far the mouse can be away to activate an item | |
25218 }, | |
25219 interaction: { | |
25220 redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow | |
25221 }, | |
25222 hooks: {} | |
25223 }, | |
25224 surface = null, // the canvas for the plot itself | |
25225 overlay = null, // canvas for interactive stuff on top of plot | |
25226 eventHolder = null, // jQuery object that events should be bound to | |
25227 ctx = null, octx = null, | |
25228 xaxes = [], yaxes = [], | |
25229 plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, | |
25230 plotWidth = 0, plotHeight = 0, | |
25231 hooks = { | |
25232 processOptions: [], | |
25233 processRawData: [], | |
25234 processDatapoints: [], | |
25235 processOffset: [], | |
25236 drawBackground: [], | |
25237 drawSeries: [], | |
25238 draw: [], | |
25239 bindEvents: [], | |
25240 drawOverlay: [], | |
25241 shutdown: [] | |
25242 }, | |
25243 plot = this; | |
25244 | |
25245 // public functions | |
25246 plot.setData = setData; | |
25247 plot.setupGrid = setupGrid; | |
25248 plot.draw = draw; | |
25249 plot.getPlaceholder = function() { return placeholder; }; | |
25250 plot.getCanvas = function() { return surface.element; }; | |
25251 plot.getPlotOffset = function() { return plotOffset; }; | |
25252 plot.width = function () { return plotWidth; }; | |
25253 plot.height = function () { return plotHeight; }; | |
25254 plot.offset = function () { | |
25255 var o = eventHolder.offset(); | |
25256 o.left += plotOffset.left; | |
25257 o.top += plotOffset.top; | |
25258 return o; | |
25259 }; | |
25260 plot.getData = function () { return series; }; | |
25261 plot.getAxes = function () { | |
25262 var res = {}, i; | |
25263 $.each(xaxes.concat(yaxes), function (_, axis) { | |
25264 if (axis) | |
25265 res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; | |
25266 }); | |
25267 return res; | |
25268 }; | |
25269 plot.getXAxes = function () { return xaxes; }; | |
25270 plot.getYAxes = function () { return yaxes; }; | |
25271 plot.c2p = canvasToAxisCoords; | |
25272 plot.p2c = axisToCanvasCoords; | |
25273 plot.getOptions = function () { return options; }; | |
25274 plot.highlight = highlight; | |
25275 plot.unhighlight = unhighlight; | |
25276 plot.triggerRedrawOverlay = triggerRedrawOverlay; | |
25277 plot.pointOffset = function(point) { | |
25278 return { | |
25279 left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), | |
25280 top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) | |
25281 }; | |
25282 }; | |
25283 plot.shutdown = shutdown; | |
25284 plot.destroy = function () { | |
25285 shutdown(); | |
25286 placeholder.removeData("plot").empty(); | |
25287 | |
25288 series = []; | |
25289 options = null; | |
25290 surface = null; | |
25291 overlay = null; | |
25292 eventHolder = null; | |
25293 ctx = null; | |
25294 octx = null; | |
25295 xaxes = []; | |
25296 yaxes = []; | |
25297 hooks = null; | |
25298 highlights = []; | |
25299 plot = null; | |
25300 }; | |
25301 plot.resize = function () { | |
25302 var width = placeholder.width(), | |
25303 height = placeholder.height(); | |
25304 surface.resize(width, height); | |
25305 overlay.resize(width, height); | |
25306 }; | |
25307 | |
25308 // public attributes | |
25309 plot.hooks = hooks; | |
25310 | |
25311 // initialize | |
25312 initPlugins(plot); | |
25313 parseOptions(options_); | |
25314 setupCanvases(); | |
25315 setData(data_); | |
25316 setupGrid(); | |
25317 draw(); | |
25318 bindEvents(); | |
25319 | |
25320 | |
25321 function executeHooks(hook, args) { | |
25322 args = [plot].concat(args); | |
25323 for (var i = 0; i < hook.length; ++i) | |
25324 hook[i].apply(this, args); | |
25325 } | |
25326 | |
25327 function initPlugins() { | |
25328 | |
25329 // References to key classes, allowing plugins to modify them | |
25330 | |
25331 var classes = { | |
25332 Canvas: Canvas | |
25333 }; | |
25334 | |
25335 for (var i = 0; i < plugins.length; ++i) { | |
25336 var p = plugins[i]; | |
25337 p.init(plot, classes); | |
25338 if (p.options) | |
25339 $.extend(true, options, p.options); | |
25340 } | |
25341 } | |
25342 | |
25343 function parseOptions(opts) { | |
25344 | |
25345 $.extend(true, options, opts); | |
25346 | |
25347 // $.extend merges arrays, rather than replacing them. When less | |
25348 // colors are provided than the size of the default palette, we | |
25349 // end up with those colors plus the remaining defaults, which is | |
25350 // not expected behavior; avoid it by replacing them here. | |
25351 | |
25352 if (opts && opts.colors) { | |
25353 options.colors = opts.colors; | |
25354 } | |
25355 | |
25356 if (options.xaxis.color == null) | |
25357 options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); | |
25358 if (options.yaxis.color == null) | |
25359 options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); | |
25360 | |
25361 if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility | |
25362 options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; | |
25363 if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility | |
25364 options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; | |
25365 | |
25366 if (options.grid.borderColor == null) | |
25367 options.grid.borderColor = options.grid.color; | |
25368 if (options.grid.tickColor == null) | |
25369 options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); | |
25370 | |
25371 // Fill in defaults for axis options, including any unspecified | |
25372 // font-spec fields, if a font-spec was provided. | |
25373 | |
25374 // If no x/y axis options were provided, create one of each anyway, | |
25375 // since the rest of the code assumes that they exist. | |
25376 | |
25377 var i, axisOptions, axisCount, | |
25378 fontSize = placeholder.css("font-size"), | |
25379 fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13, | |
25380 fontDefaults = { | |
25381 style: placeholder.css("font-style"), | |
25382 size: Math.round(0.8 * fontSizeDefault), | |
25383 variant: placeholder.css("font-variant"), | |
25384 weight: placeholder.css("font-weight"), | |
25385 family: placeholder.css("font-family") | |
25386 }; | |
25387 | |
25388 axisCount = options.xaxes.length || 1; | |
25389 for (i = 0; i < axisCount; ++i) { | |
25390 | |
25391 axisOptions = options.xaxes[i]; | |
25392 if (axisOptions && !axisOptions.tickColor) { | |
25393 axisOptions.tickColor = axisOptions.color; | |
25394 } | |
25395 | |
25396 axisOptions = $.extend(true, {}, options.xaxis, axisOptions); | |
25397 options.xaxes[i] = axisOptions; | |
25398 | |
25399 if (axisOptions.font) { | |
25400 axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); | |
25401 if (!axisOptions.font.color) { | |
25402 axisOptions.font.color = axisOptions.color; | |
25403 } | |
25404 if (!axisOptions.font.lineHeight) { | |
25405 axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); | |
25406 } | |
25407 } | |
25408 } | |
25409 | |
25410 axisCount = options.yaxes.length || 1; | |
25411 for (i = 0; i < axisCount; ++i) { | |
25412 | |
25413 axisOptions = options.yaxes[i]; | |
25414 if (axisOptions && !axisOptions.tickColor) { | |
25415 axisOptions.tickColor = axisOptions.color; | |
25416 } | |
25417 | |
25418 axisOptions = $.extend(true, {}, options.yaxis, axisOptions); | |
25419 options.yaxes[i] = axisOptions; | |
25420 | |
25421 if (axisOptions.font) { | |
25422 axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); | |
25423 if (!axisOptions.font.color) { | |
25424 axisOptions.font.color = axisOptions.color; | |
25425 } | |
25426 if (!axisOptions.font.lineHeight) { | |
25427 axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); | |
25428 } | |
25429 } | |
25430 } | |
25431 | |
25432 // backwards compatibility, to be removed in future | |
25433 if (options.xaxis.noTicks && options.xaxis.ticks == null) | |
25434 options.xaxis.ticks = options.xaxis.noTicks; | |
25435 if (options.yaxis.noTicks && options.yaxis.ticks == null) | |
25436 options.yaxis.ticks = options.yaxis.noTicks; | |
25437 if (options.x2axis) { | |
25438 options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); | |
25439 options.xaxes[1].position = "top"; | |
25440 } | |
25441 if (options.y2axis) { | |
25442 options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); | |
25443 options.yaxes[1].position = "right"; | |
25444 } | |
25445 if (options.grid.coloredAreas) | |
25446 options.grid.markings = options.grid.coloredAreas; | |
25447 if (options.grid.coloredAreasColor) | |
25448 options.grid.markingsColor = options.grid.coloredAreasColor; | |
25449 if (options.lines) | |
25450 $.extend(true, options.series.lines, options.lines); | |
25451 if (options.points) | |
25452 $.extend(true, options.series.points, options.points); | |
25453 if (options.bars) | |
25454 $.extend(true, options.series.bars, options.bars); | |
25455 if (options.shadowSize != null) | |
25456 options.series.shadowSize = options.shadowSize; | |
25457 if (options.highlightColor != null) | |
25458 options.series.highlightColor = options.highlightColor; | |
25459 | |
25460 // save options on axes for future reference | |
25461 for (i = 0; i < options.xaxes.length; ++i) | |
25462 getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; | |
25463 for (i = 0; i < options.yaxes.length; ++i) | |
25464 getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; | |
25465 | |
25466 // add hooks from options | |
25467 for (var n in hooks) | |
25468 if (options.hooks[n] && options.hooks[n].length) | |
25469 hooks[n] = hooks[n].concat(options.hooks[n]); | |
25470 | |
25471 executeHooks(hooks.processOptions, [options]); | |
25472 } | |
25473 | |
25474 function setData(d) { | |
25475 series = parseData(d); | |
25476 fillInSeriesOptions(); | |
25477 processData(); | |
25478 } | |
25479 | |
25480 function parseData(d) { | |
25481 var res = []; | |
25482 for (var i = 0; i < d.length; ++i) { | |
25483 var s = $.extend(true, {}, options.series); | |
25484 | |
25485 if (d[i].data != null) { | |
25486 s.data = d[i].data; // move the data instead of deep-copy | |
25487 delete d[i].data; | |
25488 | |
25489 $.extend(true, s, d[i]); | |
25490 | |
25491 d[i].data = s.data; | |
25492 } | |
25493 else | |
25494 s.data = d[i]; | |
25495 res.push(s); | |
25496 } | |
25497 | |
25498 return res; | |
25499 } | |
25500 | |
25501 function axisNumber(obj, coord) { | |
25502 var a = obj[coord + "axis"]; | |
25503 if (typeof a == "object") // if we got a real axis, extract number | |
25504 a = a.n; | |
25505 if (typeof a != "number") | |
25506 a = 1; // default to first axis | |
25507 return a; | |
25508 } | |
25509 | |
25510 function allAxes() { | |
25511 // return flat array without annoying null entries | |
25512 return $.grep(xaxes.concat(yaxes), function (a) { return a; }); | |
25513 } | |
25514 | |
25515 function canvasToAxisCoords(pos) { | |
25516 // return an object with x/y corresponding to all used axes | |
25517 var res = {}, i, axis; | |
25518 for (i = 0; i < xaxes.length; ++i) { | |
25519 axis = xaxes[i]; | |
25520 if (axis && axis.used) | |
25521 res["x" + axis.n] = axis.c2p(pos.left); | |
25522 } | |
25523 | |
25524 for (i = 0; i < yaxes.length; ++i) { | |
25525 axis = yaxes[i]; | |
25526 if (axis && axis.used) | |
25527 res["y" + axis.n] = axis.c2p(pos.top); | |
25528 } | |
25529 | |
25530 if (res.x1 !== undefined) | |
25531 res.x = res.x1; | |
25532 if (res.y1 !== undefined) | |
25533 res.y = res.y1; | |
25534 | |
25535 return res; | |
25536 } | |
25537 | |
25538 function axisToCanvasCoords(pos) { | |
25539 // get canvas coords from the first pair of x/y found in pos | |
25540 var res = {}, i, axis, key; | |
25541 | |
25542 for (i = 0; i < xaxes.length; ++i) { | |
25543 axis = xaxes[i]; | |
25544 if (axis && axis.used) { | |
25545 key = "x" + axis.n; | |
25546 if (pos[key] == null && axis.n == 1) | |
25547 key = "x"; | |
25548 | |
25549 if (pos[key] != null) { | |
25550 res.left = axis.p2c(pos[key]); | |
25551 break; | |
25552 } | |
25553 } | |
25554 } | |
25555 | |
25556 for (i = 0; i < yaxes.length; ++i) { | |
25557 axis = yaxes[i]; | |
25558 if (axis && axis.used) { | |
25559 key = "y" + axis.n; | |
25560 if (pos[key] == null && axis.n == 1) | |
25561 key = "y"; | |
25562 | |
25563 if (pos[key] != null) { | |
25564 res.top = axis.p2c(pos[key]); | |
25565 break; | |
25566 } | |
25567 } | |
25568 } | |
25569 | |
25570 return res; | |
25571 } | |
25572 | |
25573 function getOrCreateAxis(axes, number) { | |
25574 if (!axes[number - 1]) | |
25575 axes[number - 1] = { | |
25576 n: number, // save the number for future reference | |
25577 direction: axes == xaxes ? "x" : "y", | |
25578 options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) | |
25579 }; | |
25580 | |
25581 return axes[number - 1]; | |
25582 } | |
25583 | |
25584 function fillInSeriesOptions() { | |
25585 | |
25586 var neededColors = series.length, maxIndex = -1, i; | |
25587 | |
25588 // Subtract the number of series that already have fixed colors or | |
25589 // color indexes from the number that we still need to generate. | |
25590 | |
25591 for (i = 0; i < series.length; ++i) { | |
25592 var sc = series[i].color; | |
25593 if (sc != null) { | |
25594 neededColors--; | |
25595 if (typeof sc == "number" && sc > maxIndex) { | |
25596 maxIndex = sc; | |
25597 } | |
25598 } | |
25599 } | |
25600 | |
25601 // If any of the series have fixed color indexes, then we need to | |
25602 // generate at least as many colors as the highest index. | |
25603 | |
25604 if (neededColors <= maxIndex) { | |
25605 neededColors = maxIndex + 1; | |
25606 } | |
25607 | |
25608 // Generate all the colors, using first the option colors and then | |
25609 // variations on those colors once they're exhausted. | |
25610 | |
25611 var c, colors = [], colorPool = options.colors, | |
25612 colorPoolSize = colorPool.length, variation = 0; | |
25613 | |
25614 for (i = 0; i < neededColors; i++) { | |
25615 | |
25616 c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); | |
25617 | |
25618 // Each time we exhaust the colors in the pool we adjust | |
25619 // a scaling factor used to produce more variations on | |
25620 // those colors. The factor alternates negative/positive | |
25621 // to produce lighter/darker colors. | |
25622 | |
25623 // Reset the variation after every few cycles, or else | |
25624 // it will end up producing only white or black colors. | |
25625 | |
25626 if (i % colorPoolSize == 0 && i) { | |
25627 if (variation >= 0) { | |
25628 if (variation < 0.5) { | |
25629 variation = -variation - 0.2; | |
25630 } else variation = 0; | |
25631 } else variation = -variation; | |
25632 } | |
25633 | |
25634 colors[i] = c.scale('rgb', 1 + variation); | |
25635 } | |
25636 | |
25637 // Finalize the series options, filling in their colors | |
25638 | |
25639 var colori = 0, s; | |
25640 for (i = 0; i < series.length; ++i) { | |
25641 s = series[i]; | |
25642 | |
25643 // assign colors | |
25644 if (s.color == null) { | |
25645 s.color = colors[colori].toString(); | |
25646 ++colori; | |
25647 } | |
25648 else if (typeof s.color == "number") | |
25649 s.color = colors[s.color].toString(); | |
25650 | |
25651 // turn on lines automatically in case nothing is set | |
25652 if (s.lines.show == null) { | |
25653 var v, show = true; | |
25654 for (v in s) | |
25655 if (s[v] && s[v].show) { | |
25656 show = false; | |
25657 break; | |
25658 } | |
25659 if (show) | |
25660 s.lines.show = true; | |
25661 } | |
25662 | |
25663 // If nothing was provided for lines.zero, default it to match | |
25664 // lines.fill, since areas by default should extend to zero. | |
25665 | |
25666 if (s.lines.zero == null) { | |
25667 s.lines.zero = !!s.lines.fill; | |
25668 } | |
25669 | |
25670 // setup axes | |
25671 s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); | |
25672 s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); | |
25673 } | |
25674 } | |
25675 | |
25676 function processData() { | |
25677 var topSentry = Number.POSITIVE_INFINITY, | |
25678 bottomSentry = Number.NEGATIVE_INFINITY, | |
25679 fakeInfinity = Number.MAX_VALUE, | |
25680 i, j, k, m, length, | |
25681 s, points, ps, x, y, axis, val, f, p, | |
25682 data, format; | |
25683 | |
25684 function updateAxis(axis, min, max) { | |
25685 if (min < axis.datamin && min != -fakeInfinity) | |
25686 axis.datamin = min; | |
25687 if (max > axis.datamax && max != fakeInfinity) | |
25688 axis.datamax = max; | |
25689 } | |
25690 | |
25691 $.each(allAxes(), function (_, axis) { | |
25692 // init axis | |
25693 axis.datamin = topSentry; | |
25694 axis.datamax = bottomSentry; | |
25695 axis.used = false; | |
25696 }); | |
25697 | |
25698 for (i = 0; i < series.length; ++i) { | |
25699 s = series[i]; | |
25700 s.datapoints = { points: [] }; | |
25701 | |
25702 executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); | |
25703 } | |
25704 | |
25705 // first pass: clean and copy data | |
25706 for (i = 0; i < series.length; ++i) { | |
25707 s = series[i]; | |
25708 | |
25709 data = s.data; | |
25710 format = s.datapoints.format; | |
25711 | |
25712 if (!format) { | |
25713 format = []; | |
25714 // find out how to copy | |
25715 format.push({ x: true, number: true, required: true }); | |
25716 format.push({ y: true, number: true, required: true }); | |
25717 | |
25718 if (s.bars.show || (s.lines.show && s.lines.fill)) { | |
25719 var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); | |
25720 format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); | |
25721 if (s.bars.horizontal) { | |
25722 delete format[format.length - 1].y; | |
25723 format[format.length - 1].x = true; | |
25724 } | |
25725 } | |
25726 | |
25727 s.datapoints.format = format; | |
25728 } | |
25729 | |
25730 if (s.datapoints.pointsize != null) | |
25731 continue; // already filled in | |
25732 | |
25733 s.datapoints.pointsize = format.length; | |
25734 | |
25735 ps = s.datapoints.pointsize; | |
25736 points = s.datapoints.points; | |
25737 | |
25738 var insertSteps = s.lines.show && s.lines.steps; | |
25739 s.xaxis.used = s.yaxis.used = true; | |
25740 | |
25741 for (j = k = 0; j < data.length; ++j, k += ps) { | |
25742 p = data[j]; | |
25743 | |
25744 var nullify = p == null; | |
25745 if (!nullify) { | |
25746 for (m = 0; m < ps; ++m) { | |
25747 val = p[m]; | |
25748 f = format[m]; | |
25749 | |
25750 if (f) { | |
25751 if (f.number && val != null) { | |
25752 val = +val; // convert to number | |
25753 if (isNaN(val)) | |
25754 val = null; | |
25755 else if (val == Infinity) | |
25756 val = fakeInfinity; | |
25757 else if (val == -Infinity) | |
25758 val = -fakeInfinity; | |
25759 } | |
25760 | |
25761 if (val == null) { | |
25762 if (f.required) | |
25763 nullify = true; | |
25764 | |
25765 if (f.defaultValue != null) | |
25766 val = f.defaultValue; | |
25767 } | |
25768 } | |
25769 | |
25770 points[k + m] = val; | |
25771 } | |
25772 } | |
25773 | |
25774 if (nullify) { | |
25775 for (m = 0; m < ps; ++m) { | |
25776 val = points[k + m]; | |
25777 if (val != null) { | |
25778 f = format[m]; | |
25779 // extract min/max info | |
25780 if (f.autoscale !== false) { | |
25781 if (f.x) { | |
25782 updateAxis(s.xaxis, val, val); | |
25783 } | |
25784 if (f.y) { | |
25785 updateAxis(s.yaxis, val, val); | |
25786 } | |
25787 } | |
25788 } | |
25789 points[k + m] = null; | |
25790 } | |
25791 } | |
25792 else { | |
25793 // a little bit of line specific stuff that | |
25794 // perhaps shouldn't be here, but lacking | |
25795 // better means... | |
25796 if (insertSteps && k > 0 | |
25797 && points[k - ps] != null | |
25798 && points[k - ps] != points[k] | |
25799 && points[k - ps + 1] != points[k + 1]) { | |
25800 // copy the point to make room for a middle point | |
25801 for (m = 0; m < ps; ++m) | |
25802 points[k + ps + m] = points[k + m]; | |
25803 | |
25804 // middle point has same y | |
25805 points[k + 1] = points[k - ps + 1]; | |
25806 | |
25807 // we've added a point, better reflect that | |
25808 k += ps; | |
25809 } | |
25810 } | |
25811 } | |
25812 } | |
25813 | |
25814 // give the hooks a chance to run | |
25815 for (i = 0; i < series.length; ++i) { | |
25816 s = series[i]; | |
25817 | |
25818 executeHooks(hooks.processDatapoints, [ s, s.datapoints]); | |
25819 } | |
25820 | |
25821 // second pass: find datamax/datamin for auto-scaling | |
25822 for (i = 0; i < series.length; ++i) { | |
25823 s = series[i]; | |
25824 points = s.datapoints.points; | |
25825 ps = s.datapoints.pointsize; | |
25826 format = s.datapoints.format; | |
25827 | |
25828 var xmin = topSentry, ymin = topSentry, | |
25829 xmax = bottomSentry, ymax = bottomSentry; | |
25830 | |
25831 for (j = 0; j < points.length; j += ps) { | |
25832 if (points[j] == null) | |
25833 continue; | |
25834 | |
25835 for (m = 0; m < ps; ++m) { | |
25836 val = points[j + m]; | |
25837 f = format[m]; | |
25838 if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) | |
25839 continue; | |
25840 | |
25841 if (f.x) { | |
25842 if (val < xmin) | |
25843 xmin = val; | |
25844 if (val > xmax) | |
25845 xmax = val; | |
25846 } | |
25847 if (f.y) { | |
25848 if (val < ymin) | |
25849 ymin = val; | |
25850 if (val > ymax) | |
25851 ymax = val; | |
25852 } | |
25853 } | |
25854 } | |
25855 | |
25856 if (s.bars.show) { | |
25857 // make sure we got room for the bar on the dancing floor | |
25858 var delta; | |
25859 | |
25860 switch (s.bars.align) { | |
25861 case "left": | |
25862 delta = 0; | |
25863 break; | |
25864 case "right": | |
25865 delta = -s.bars.barWidth; | |
25866 break; | |
25867 default: | |
25868 delta = -s.bars.barWidth / 2; | |
25869 } | |
25870 | |
25871 if (s.bars.horizontal) { | |
25872 ymin += delta; | |
25873 ymax += delta + s.bars.barWidth; | |
25874 } | |
25875 else { | |
25876 xmin += delta; | |
25877 xmax += delta + s.bars.barWidth; | |
25878 } | |
25879 } | |
25880 | |
25881 updateAxis(s.xaxis, xmin, xmax); | |
25882 updateAxis(s.yaxis, ymin, ymax); | |
25883 } | |
25884 | |
25885 $.each(allAxes(), function (_, axis) { | |
25886 if (axis.datamin == topSentry) | |
25887 axis.datamin = null; | |
25888 if (axis.datamax == bottomSentry) | |
25889 axis.datamax = null; | |
25890 }); | |
25891 } | |
25892 | |
25893 function setupCanvases() { | |
25894 | |
25895 // Make sure the placeholder is clear of everything except canvases | |
25896 // from a previous plot in this container that we'll try to re-use. | |
25897 | |
25898 placeholder.css("padding", 0) // padding messes up the positioning | |
25899 .children().filter(function(){ | |
25900 return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base'); | |
25901 }).remove(); | |
25902 | |
25903 if (placeholder.css("position") == 'static') | |
25904 placeholder.css("position", "relative"); // for positioning labels and overlay | |
25905 | |
25906 surface = new Canvas("flot-base", placeholder); | |
25907 overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features | |
25908 | |
25909 ctx = surface.context; | |
25910 octx = overlay.context; | |
25911 | |
25912 // define which element we're listening for events on | |
25913 eventHolder = $(overlay.element).unbind(); | |
25914 | |
25915 // If we're re-using a plot object, shut down the old one | |
25916 | |
25917 var existing = placeholder.data("plot"); | |
25918 | |
25919 if (existing) { | |
25920 existing.shutdown(); | |
25921 overlay.clear(); | |
25922 } | |
25923 | |
25924 // save in case we get replotted | |
25925 placeholder.data("plot", plot); | |
25926 } | |
25927 | |
25928 function bindEvents() { | |
25929 // bind events | |
25930 if (options.grid.hoverable) { | |
25931 eventHolder.mousemove(onMouseMove); | |
25932 | |
25933 // Use bind, rather than .mouseleave, because we officially | |
25934 // still support jQuery 1.2.6, which doesn't define a shortcut | |
25935 // for mouseenter or mouseleave. This was a bug/oversight that | |
25936 // was fixed somewhere around 1.3.x. We can return to using | |
25937 // .mouseleave when we drop support for 1.2.6. | |
25938 | |
25939 eventHolder.bind("mouseleave", onMouseLeave); | |
25940 } | |
25941 | |
25942 if (options.grid.clickable) | |
25943 eventHolder.click(onClick); | |
25944 | |
25945 executeHooks(hooks.bindEvents, [eventHolder]); | |
25946 } | |
25947 | |
25948 function shutdown() { | |
25949 if (redrawTimeout) | |
25950 clearTimeout(redrawTimeout); | |
25951 | |
25952 eventHolder.unbind("mousemove", onMouseMove); | |
25953 eventHolder.unbind("mouseleave", onMouseLeave); | |
25954 eventHolder.unbind("click", onClick); | |
25955 | |
25956 executeHooks(hooks.shutdown, [eventHolder]); | |
25957 } | |
25958 | |
25959 function setTransformationHelpers(axis) { | |
25960 // set helper functions on the axis, assumes plot area | |
25961 // has been computed already | |
25962 | |
25963 function identity(x) { return x; } | |
25964 | |
25965 var s, m, t = axis.options.transform || identity, | |
25966 it = axis.options.inverseTransform; | |
25967 | |
25968 // precompute how much the axis is scaling a point | |
25969 // in canvas space | |
25970 if (axis.direction == "x") { | |
25971 s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); | |
25972 m = Math.min(t(axis.max), t(axis.min)); | |
25973 } | |
25974 else { | |
25975 s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); | |
25976 s = -s; | |
25977 m = Math.max(t(axis.max), t(axis.min)); | |
25978 } | |
25979 | |
25980 // data point to canvas coordinate | |
25981 if (t == identity) // slight optimization | |
25982 axis.p2c = function (p) { return (p - m) * s; }; | |
25983 else | |
25984 axis.p2c = function (p) { return (t(p) - m) * s; }; | |
25985 // canvas coordinate to data point | |
25986 if (!it) | |
25987 axis.c2p = function (c) { return m + c / s; }; | |
25988 else | |
25989 axis.c2p = function (c) { return it(m + c / s); }; | |
25990 } | |
25991 | |
25992 function measureTickLabels(axis) { | |
25993 | |
25994 var opts = axis.options, | |
25995 ticks = axis.ticks || [], | |
25996 labelWidth = opts.labelWidth || 0, | |
25997 labelHeight = opts.labelHeight || 0, | |
25998 maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null), | |
25999 legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", | |
26000 layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, | |
26001 font = opts.font || "flot-tick-label tickLabel"; | |
26002 | |
26003 for (var i = 0; i < ticks.length; ++i) { | |
26004 | |
26005 var t = ticks[i]; | |
26006 | |
26007 if (!t.label) | |
26008 continue; | |
26009 | |
26010 var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); | |
26011 | |
26012 labelWidth = Math.max(labelWidth, info.width); | |
26013 labelHeight = Math.max(labelHeight, info.height); | |
26014 } | |
26015 | |
26016 axis.labelWidth = opts.labelWidth || labelWidth; | |
26017 axis.labelHeight = opts.labelHeight || labelHeight; | |
26018 } | |
26019 | |
26020 function allocateAxisBoxFirstPhase(axis) { | |
26021 // find the bounding box of the axis by looking at label | |
26022 // widths/heights and ticks, make room by diminishing the | |
26023 // plotOffset; this first phase only looks at one | |
26024 // dimension per axis, the other dimension depends on the | |
26025 // other axes so will have to wait | |
26026 | |
26027 var lw = axis.labelWidth, | |
26028 lh = axis.labelHeight, | |
26029 pos = axis.options.position, | |
26030 isXAxis = axis.direction === "x", | |
26031 tickLength = axis.options.tickLength, | |
26032 axisMargin = options.grid.axisMargin, | |
26033 padding = options.grid.labelMargin, | |
26034 innermost = true, | |
26035 outermost = true, | |
26036 first = true, | |
26037 found = false; | |
26038 | |
26039 // Determine the axis's position in its direction and on its side | |
26040 | |
26041 $.each(isXAxis ? xaxes : yaxes, function(i, a) { | |
26042 if (a && a.reserveSpace) { | |
26043 if (a === axis) { | |
26044 found = true; | |
26045 } else if (a.options.position === pos) { | |
26046 if (found) { | |
26047 outermost = false; | |
26048 } else { | |
26049 innermost = false; | |
26050 } | |
26051 } | |
26052 if (!found) { | |
26053 first = false; | |
26054 } | |
26055 } | |
26056 }); | |
26057 | |
26058 // The outermost axis on each side has no margin | |
26059 | |
26060 if (outermost) { | |
26061 axisMargin = 0; | |
26062 } | |
26063 | |
26064 // The ticks for the first axis in each direction stretch across | |
26065 | |
26066 if (tickLength == null) { | |
26067 tickLength = first ? "full" : 5; | |
26068 } | |
26069 | |
26070 if (!isNaN(+tickLength)) | |
26071 padding += +tickLength; | |
26072 | |
26073 if (isXAxis) { | |
26074 lh += padding; | |
26075 | |
26076 if (pos == "bottom") { | |
26077 plotOffset.bottom += lh + axisMargin; | |
26078 axis.box = { top: surface.height - plotOffset.bottom, height: lh }; | |
26079 } | |
26080 else { | |
26081 axis.box = { top: plotOffset.top + axisMargin, height: lh }; | |
26082 plotOffset.top += lh + axisMargin; | |
26083 } | |
26084 } | |
26085 else { | |
26086 lw += padding; | |
26087 | |
26088 if (pos == "left") { | |
26089 axis.box = { left: plotOffset.left + axisMargin, width: lw }; | |
26090 plotOffset.left += lw + axisMargin; | |
26091 } | |
26092 else { | |
26093 plotOffset.right += lw + axisMargin; | |
26094 axis.box = { left: surface.width - plotOffset.right, width: lw }; | |
26095 } | |
26096 } | |
26097 | |
26098 // save for future reference | |
26099 axis.position = pos; | |
26100 axis.tickLength = tickLength; | |
26101 axis.box.padding = padding; | |
26102 axis.innermost = innermost; | |
26103 } | |
26104 | |
26105 function allocateAxisBoxSecondPhase(axis) { | |
26106 // now that all axis boxes have been placed in one | |
26107 // dimension, we can set the remaining dimension coordinates | |
26108 if (axis.direction == "x") { | |
26109 axis.box.left = plotOffset.left - axis.labelWidth / 2; | |
26110 axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; | |
26111 } | |
26112 else { | |
26113 axis.box.top = plotOffset.top - axis.labelHeight / 2; | |
26114 axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; | |
26115 } | |
26116 } | |
26117 | |
26118 function adjustLayoutForThingsStickingOut() { | |
26119 // possibly adjust plot offset to ensure everything stays | |
26120 // inside the canvas and isn't clipped off | |
26121 | |
26122 var minMargin = options.grid.minBorderMargin, | |
26123 axis, i; | |
26124 | |
26125 // check stuff from the plot (FIXME: this should just read | |
26126 // a value from the series, otherwise it's impossible to | |
26127 // customize) | |
26128 if (minMargin == null) { | |
26129 minMargin = 0; | |
26130 for (i = 0; i < series.length; ++i) | |
26131 minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); | |
26132 } | |
26133 | |
26134 var margins = { | |
26135 left: minMargin, | |
26136 right: minMargin, | |
26137 top: minMargin, | |
26138 bottom: minMargin | |
26139 }; | |
26140 | |
26141 // check axis labels, note we don't check the actual | |
26142 // labels but instead use the overall width/height to not | |
26143 // jump as much around with replots | |
26144 $.each(allAxes(), function (_, axis) { | |
26145 if (axis.reserveSpace && axis.ticks && axis.ticks.length) { | |
26146 var lastTick = axis.ticks[axis.ticks.length - 1]; | |
26147 if (axis.direction === "x") { | |
26148 margins.left = Math.max(margins.left, axis.labelWidth / 2); | |
26149 if (lastTick.v <= axis.max) { | |
26150 margins.right = Math.max(margins.right, axis.labelWidth / 2); | |
26151 } | |
26152 } else { | |
26153 margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); | |
26154 if (lastTick.v <= axis.max) { | |
26155 margins.top = Math.max(margins.top, axis.labelHeight / 2); | |
26156 } | |
26157 } | |
26158 } | |
26159 }); | |
26160 | |
26161 plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left)); | |
26162 plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right)); | |
26163 plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); | |
26164 plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); | |
26165 } | |
26166 | |
26167 function setupGrid() { | |
26168 var i, axes = allAxes(), showGrid = options.grid.show; | |
26169 | |
26170 // Initialize the plot's offset from the edge of the canvas | |
26171 | |
26172 for (var a in plotOffset) { | |
26173 var margin = options.grid.margin || 0; | |
26174 plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; | |
26175 } | |
26176 | |
26177 executeHooks(hooks.processOffset, [plotOffset]); | |
26178 | |
26179 // If the grid is visible, add its border width to the offset | |
26180 | |
26181 for (var a in plotOffset) { | |
26182 if(typeof(options.grid.borderWidth) == "object") { | |
26183 plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; | |
26184 } | |
26185 else { | |
26186 plotOffset[a] += showGrid ? options.grid.borderWidth : 0; | |
26187 } | |
26188 } | |
26189 | |
26190 // init axes | |
26191 $.each(axes, function (_, axis) { | |
26192 axis.show = axis.options.show; | |
26193 if (axis.show == null) | |
26194 axis.show = axis.used; // by default an axis is visible if it's got data | |
26195 | |
26196 axis.reserveSpace = axis.show || axis.options.reserveSpace; | |
26197 | |
26198 setRange(axis); | |
26199 }); | |
26200 | |
26201 if (showGrid) { | |
26202 | |
26203 var allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; }); | |
26204 | |
26205 $.each(allocatedAxes, function (_, axis) { | |
26206 // make the ticks | |
26207 setupTickGeneration(axis); | |
26208 setTicks(axis); | |
26209 snapRangeToTicks(axis, axis.ticks); | |
26210 // find labelWidth/Height for axis | |
26211 measureTickLabels(axis); | |
26212 }); | |
26213 | |
26214 // with all dimensions calculated, we can compute the | |
26215 // axis bounding boxes, start from the outside | |
26216 // (reverse order) | |
26217 for (i = allocatedAxes.length - 1; i >= 0; --i) | |
26218 allocateAxisBoxFirstPhase(allocatedAxes[i]); | |
26219 | |
26220 // make sure we've got enough space for things that | |
26221 // might stick out | |
26222 adjustLayoutForThingsStickingOut(); | |
26223 | |
26224 $.each(allocatedAxes, function (_, axis) { | |
26225 allocateAxisBoxSecondPhase(axis); | |
26226 }); | |
26227 } | |
26228 | |
26229 plotWidth = surface.width - plotOffset.left - plotOffset.right; | |
26230 plotHeight = surface.height - plotOffset.bottom - plotOffset.top; | |
26231 | |
26232 // now we got the proper plot dimensions, we can compute the scaling | |
26233 $.each(axes, function (_, axis) { | |
26234 setTransformationHelpers(axis); | |
26235 }); | |
26236 | |
26237 if (showGrid) { | |
26238 drawAxisLabels(); | |
26239 } | |
26240 | |
26241 insertLegend(); | |
26242 } | |
26243 | |
26244 function setRange(axis) { | |
26245 var opts = axis.options, | |
26246 min = +(opts.min != null ? opts.min : axis.datamin), | |
26247 max = +(opts.max != null ? opts.max : axis.datamax), | |
26248 delta = max - min; | |
26249 | |
26250 if (delta == 0.0) { | |
26251 // degenerate case | |
26252 var widen = max == 0 ? 1 : 0.01; | |
26253 | |
26254 if (opts.min == null) | |
26255 min -= widen; | |
26256 // always widen max if we couldn't widen min to ensure we | |
26257 // don't fall into min == max which doesn't work | |
26258 if (opts.max == null || opts.min != null) | |
26259 max += widen; | |
26260 } | |
26261 else { | |
26262 // consider autoscaling | |
26263 var margin = opts.autoscaleMargin; | |
26264 if (margin != null) { | |
26265 if (opts.min == null) { | |
26266 min -= delta * margin; | |
26267 // make sure we don't go below zero if all values | |
26268 // are positive | |
26269 if (min < 0 && axis.datamin != null && axis.datamin >= 0) | |
26270 min = 0; | |
26271 } | |
26272 if (opts.max == null) { | |
26273 max += delta * margin; | |
26274 if (max > 0 && axis.datamax != null && axis.datamax <= 0) | |
26275 max = 0; | |
26276 } | |
26277 } | |
26278 } | |
26279 axis.min = min; | |
26280 axis.max = max; | |
26281 } | |
26282 | |
26283 function setupTickGeneration(axis) { | |
26284 var opts = axis.options; | |
26285 | |
26286 // estimate number of ticks | |
26287 var noTicks; | |
26288 if (typeof opts.ticks == "number" && opts.ticks > 0) | |
26289 noTicks = opts.ticks; | |
26290 else | |
26291 // heuristic based on the model a*sqrt(x) fitted to | |
26292 // some data points that seemed reasonable | |
26293 noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); | |
26294 | |
26295 var delta = (axis.max - axis.min) / noTicks, | |
26296 dec = -Math.floor(Math.log(delta) / Math.LN10), | |
26297 maxDec = opts.tickDecimals; | |
26298 | |
26299 if (maxDec != null && dec > maxDec) { | |
26300 dec = maxDec; | |
26301 } | |
26302 | |
26303 var magn = Math.pow(10, -dec), | |
26304 norm = delta / magn, // norm is between 1.0 and 10.0 | |
26305 size; | |
26306 | |
26307 if (norm < 1.5) { | |
26308 size = 1; | |
26309 } else if (norm < 3) { | |
26310 size = 2; | |
26311 // special case for 2.5, requires an extra decimal | |
26312 if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { | |
26313 size = 2.5; | |
26314 ++dec; | |
26315 } | |
26316 } else if (norm < 7.5) { | |
26317 size = 5; | |
26318 } else { | |
26319 size = 10; | |
26320 } | |
26321 | |
26322 size *= magn; | |
26323 | |
26324 if (opts.minTickSize != null && size < opts.minTickSize) { | |
26325 size = opts.minTickSize; | |
26326 } | |
26327 | |
26328 axis.delta = delta; | |
26329 axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); | |
26330 axis.tickSize = opts.tickSize || size; | |
26331 | |
26332 // Time mode was moved to a plug-in in 0.8, but since so many people use this | |
26333 // we'll add an especially friendly make sure they remembered to include it. | |
26334 | |
26335 if (opts.mode == "time" && !axis.tickGenerator) { | |
26336 throw new Error("Time mode requires the flot.time plugin."); | |
26337 } | |
26338 | |
26339 // Flot supports base-10 axes; any other mode else is handled by a plug-in, | |
26340 // like flot.time.js. | |
26341 | |
26342 if (!axis.tickGenerator) { | |
26343 | |
26344 axis.tickGenerator = function (axis) { | |
26345 | |
26346 var ticks = [], | |
26347 start = floorInBase(axis.min, axis.tickSize), | |
26348 i = 0, | |
26349 v = Number.NaN, | |
26350 prev; | |
26351 | |
26352 do { | |
26353 prev = v; | |
26354 v = start + i * axis.tickSize; | |
26355 ticks.push(v); | |
26356 ++i; | |
26357 } while (v < axis.max && v != prev); | |
26358 return ticks; | |
26359 }; | |
26360 | |
26361 axis.tickFormatter = function (value, axis) { | |
26362 | |
26363 var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; | |
26364 var formatted = "" + Math.round(value * factor) / factor; | |
26365 | |
26366 // If tickDecimals was specified, ensure that we have exactly that | |
26367 // much precision; otherwise default to the value's own precision. | |
26368 | |
26369 if (axis.tickDecimals != null) { | |
26370 var decimal = formatted.indexOf("."); | |
26371 var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; | |
26372 if (precision < axis.tickDecimals) { | |
26373 return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); | |
26374 } | |
26375 } | |
26376 | |
26377 return formatted; | |
26378 }; | |
26379 } | |
26380 | |
26381 if ($.isFunction(opts.tickFormatter)) | |
26382 axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; | |
26383 | |
26384 if (opts.alignTicksWithAxis != null) { | |
26385 var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; | |
26386 if (otherAxis && otherAxis.used && otherAxis != axis) { | |
26387 // consider snapping min/max to outermost nice ticks | |
26388 var niceTicks = axis.tickGenerator(axis); | |
26389 if (niceTicks.length > 0) { | |
26390 if (opts.min == null) | |
26391 axis.min = Math.min(axis.min, niceTicks[0]); | |
26392 if (opts.max == null && niceTicks.length > 1) | |
26393 axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); | |
26394 } | |
26395 | |
26396 axis.tickGenerator = function (axis) { | |
26397 // copy ticks, scaled to this axis | |
26398 var ticks = [], v, i; | |
26399 for (i = 0; i < otherAxis.ticks.length; ++i) { | |
26400 v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); | |
26401 v = axis.min + v * (axis.max - axis.min); | |
26402 ticks.push(v); | |
26403 } | |
26404 return ticks; | |
26405 }; | |
26406 | |
26407 // we might need an extra decimal since forced | |
26408 // ticks don't necessarily fit naturally | |
26409 if (!axis.mode && opts.tickDecimals == null) { | |
26410 var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), | |
26411 ts = axis.tickGenerator(axis); | |
26412 | |
26413 // only proceed if the tick interval rounded | |
26414 // with an extra decimal doesn't give us a | |
26415 // zero at end | |
26416 if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) | |
26417 axis.tickDecimals = extraDec; | |
26418 } | |
26419 } | |
26420 } | |
26421 } | |
26422 | |
26423 function setTicks(axis) { | |
26424 var oticks = axis.options.ticks, ticks = []; | |
26425 if (oticks == null || (typeof oticks == "number" && oticks > 0)) | |
26426 ticks = axis.tickGenerator(axis); | |
26427 else if (oticks) { | |
26428 if ($.isFunction(oticks)) | |
26429 // generate the ticks | |
26430 ticks = oticks(axis); | |
26431 else | |
26432 ticks = oticks; | |
26433 } | |
26434 | |
26435 // clean up/labelify the supplied ticks, copy them over | |
26436 var i, v; | |
26437 axis.ticks = []; | |
26438 for (i = 0; i < ticks.length; ++i) { | |
26439 var label = null; | |
26440 var t = ticks[i]; | |
26441 if (typeof t == "object") { | |
26442 v = +t[0]; | |
26443 if (t.length > 1) | |
26444 label = t[1]; | |
26445 } | |
26446 else | |
26447 v = +t; | |
26448 if (label == null) | |
26449 label = axis.tickFormatter(v, axis); | |
26450 if (!isNaN(v)) | |
26451 axis.ticks.push({ v: v, label: label }); | |
26452 } | |
26453 } | |
26454 | |
26455 function snapRangeToTicks(axis, ticks) { | |
26456 if (axis.options.autoscaleMargin && ticks.length > 0) { | |
26457 // snap to ticks | |
26458 if (axis.options.min == null) | |
26459 axis.min = Math.min(axis.min, ticks[0].v); | |
26460 if (axis.options.max == null && ticks.length > 1) | |
26461 axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); | |
26462 } | |
26463 } | |
26464 | |
26465 function draw() { | |
26466 | |
26467 surface.clear(); | |
26468 | |
26469 executeHooks(hooks.drawBackground, [ctx]); | |
26470 | |
26471 var grid = options.grid; | |
26472 | |
26473 // draw background, if any | |
26474 if (grid.show && grid.backgroundColor) | |
26475 drawBackground(); | |
26476 | |
26477 if (grid.show && !grid.aboveData) { | |
26478 drawGrid(); | |
26479 } | |
26480 | |
26481 for (var i = 0; i < series.length; ++i) { | |
26482 executeHooks(hooks.drawSeries, [ctx, series[i]]); | |
26483 drawSeries(series[i]); | |
26484 } | |
26485 | |
26486 executeHooks(hooks.draw, [ctx]); | |
26487 | |
26488 if (grid.show && grid.aboveData) { | |
26489 drawGrid(); | |
26490 } | |
26491 | |
26492 surface.render(); | |
26493 | |
26494 // A draw implies that either the axes or data have changed, so we | |
26495 // should probably update the overlay highlights as well. | |
26496 | |
26497 triggerRedrawOverlay(); | |
26498 } | |
26499 | |
26500 function extractRange(ranges, coord) { | |
26501 var axis, from, to, key, axes = allAxes(); | |
26502 | |
26503 for (var i = 0; i < axes.length; ++i) { | |
26504 axis = axes[i]; | |
26505 if (axis.direction == coord) { | |
26506 key = coord + axis.n + "axis"; | |
26507 if (!ranges[key] && axis.n == 1) | |
26508 key = coord + "axis"; // support x1axis as xaxis | |
26509 if (ranges[key]) { | |
26510 from = ranges[key].from; | |
26511 to = ranges[key].to; | |
26512 break; | |
26513 } | |
26514 } | |
26515 } | |
26516 | |
26517 // backwards-compat stuff - to be removed in future | |
26518 if (!ranges[key]) { | |
26519 axis = coord == "x" ? xaxes[0] : yaxes[0]; | |
26520 from = ranges[coord + "1"]; | |
26521 to = ranges[coord + "2"]; | |
26522 } | |
26523 | |
26524 // auto-reverse as an added bonus | |
26525 if (from != null && to != null && from > to) { | |
26526 var tmp = from; | |
26527 from = to; | |
26528 to = tmp; | |
26529 } | |
26530 | |
26531 return { from: from, to: to, axis: axis }; | |
26532 } | |
26533 | |
26534 function drawBackground() { | |
26535 ctx.save(); | |
26536 ctx.translate(plotOffset.left, plotOffset.top); | |
26537 | |
26538 ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); | |
26539 ctx.fillRect(0, 0, plotWidth, plotHeight); | |
26540 ctx.restore(); | |
26541 } | |
26542 | |
26543 function drawGrid() { | |
26544 var i, axes, bw, bc; | |
26545 | |
26546 ctx.save(); | |
26547 ctx.translate(plotOffset.left, plotOffset.top); | |
26548 | |
26549 // draw markings | |
26550 var markings = options.grid.markings; | |
26551 if (markings) { | |
26552 if ($.isFunction(markings)) { | |
26553 axes = plot.getAxes(); | |
26554 // xmin etc. is backwards compatibility, to be | |
26555 // removed in the future | |
26556 axes.xmin = axes.xaxis.min; | |
26557 axes.xmax = axes.xaxis.max; | |
26558 axes.ymin = axes.yaxis.min; | |
26559 axes.ymax = axes.yaxis.max; | |
26560 | |
26561 markings = markings(axes); | |
26562 } | |
26563 | |
26564 for (i = 0; i < markings.length; ++i) { | |
26565 var m = markings[i], | |
26566 xrange = extractRange(m, "x"), | |
26567 yrange = extractRange(m, "y"); | |
26568 | |
26569 // fill in missing | |
26570 if (xrange.from == null) | |
26571 xrange.from = xrange.axis.min; | |
26572 if (xrange.to == null) | |
26573 xrange.to = xrange.axis.max; | |
26574 if (yrange.from == null) | |
26575 yrange.from = yrange.axis.min; | |
26576 if (yrange.to == null) | |
26577 yrange.to = yrange.axis.max; | |
26578 | |
26579 // clip | |
26580 if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || | |
26581 yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) | |
26582 continue; | |
26583 | |
26584 xrange.from = Math.max(xrange.from, xrange.axis.min); | |
26585 xrange.to = Math.min(xrange.to, xrange.axis.max); | |
26586 yrange.from = Math.max(yrange.from, yrange.axis.min); | |
26587 yrange.to = Math.min(yrange.to, yrange.axis.max); | |
26588 | |
26589 if (xrange.from == xrange.to && yrange.from == yrange.to) | |
26590 continue; | |
26591 | |
26592 // then draw | |
26593 xrange.from = xrange.axis.p2c(xrange.from); | |
26594 xrange.to = xrange.axis.p2c(xrange.to); | |
26595 yrange.from = yrange.axis.p2c(yrange.from); | |
26596 yrange.to = yrange.axis.p2c(yrange.to); | |
26597 | |
26598 if (xrange.from == xrange.to || yrange.from == yrange.to) { | |
26599 // draw line | |
26600 ctx.beginPath(); | |
26601 ctx.strokeStyle = m.color || options.grid.markingsColor; | |
26602 ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; | |
26603 ctx.moveTo(xrange.from, yrange.from); | |
26604 ctx.lineTo(xrange.to, yrange.to); | |
26605 ctx.stroke(); | |
26606 } | |
26607 else { | |
26608 // fill area | |
26609 ctx.fillStyle = m.color || options.grid.markingsColor; | |
26610 ctx.fillRect(xrange.from, yrange.to, | |
26611 xrange.to - xrange.from, | |
26612 yrange.from - yrange.to); | |
26613 } | |
26614 } | |
26615 } | |
26616 | |
26617 // draw the ticks | |
26618 axes = allAxes(); | |
26619 bw = options.grid.borderWidth; | |
26620 | |
26621 for (var j = 0; j < axes.length; ++j) { | |
26622 var axis = axes[j], box = axis.box, | |
26623 t = axis.tickLength, x, y, xoff, yoff; | |
26624 if (!axis.show || axis.ticks.length == 0) | |
26625 continue; | |
26626 | |
26627 ctx.lineWidth = 1; | |
26628 | |
26629 // find the edges | |
26630 if (axis.direction == "x") { | |
26631 x = 0; | |
26632 if (t == "full") | |
26633 y = (axis.position == "top" ? 0 : plotHeight); | |
26634 else | |
26635 y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); | |
26636 } | |
26637 else { | |
26638 y = 0; | |
26639 if (t == "full") | |
26640 x = (axis.position == "left" ? 0 : plotWidth); | |
26641 else | |
26642 x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); | |
26643 } | |
26644 | |
26645 // draw tick bar | |
26646 if (!axis.innermost) { | |
26647 ctx.strokeStyle = axis.options.color; | |
26648 ctx.beginPath(); | |
26649 xoff = yoff = 0; | |
26650 if (axis.direction == "x") | |
26651 xoff = plotWidth + 1; | |
26652 else | |
26653 yoff = plotHeight + 1; | |
26654 | |
26655 if (ctx.lineWidth == 1) { | |
26656 if (axis.direction == "x") { | |
26657 y = Math.floor(y) + 0.5; | |
26658 } else { | |
26659 x = Math.floor(x) + 0.5; | |
26660 } | |
26661 } | |
26662 | |
26663 ctx.moveTo(x, y); | |
26664 ctx.lineTo(x + xoff, y + yoff); | |
26665 ctx.stroke(); | |
26666 } | |
26667 | |
26668 // draw ticks | |
26669 | |
26670 ctx.strokeStyle = axis.options.tickColor; | |
26671 | |
26672 ctx.beginPath(); | |
26673 for (i = 0; i < axis.ticks.length; ++i) { | |
26674 var v = axis.ticks[i].v; | |
26675 | |
26676 xoff = yoff = 0; | |
26677 | |
26678 if (isNaN(v) || v < axis.min || v > axis.max | |
26679 // skip those lying on the axes if we got a border | |
26680 || (t == "full" | |
26681 && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) | |
26682 && (v == axis.min || v == axis.max))) | |
26683 continue; | |
26684 | |
26685 if (axis.direction == "x") { | |
26686 x = axis.p2c(v); | |
26687 yoff = t == "full" ? -plotHeight : t; | |
26688 | |
26689 if (axis.position == "top") | |
26690 yoff = -yoff; | |
26691 } | |
26692 else { | |
26693 y = axis.p2c(v); | |
26694 xoff = t == "full" ? -plotWidth : t; | |
26695 | |
26696 if (axis.position == "left") | |
26697 xoff = -xoff; | |
26698 } | |
26699 | |
26700 if (ctx.lineWidth == 1) { | |
26701 if (axis.direction == "x") | |
26702 x = Math.floor(x) + 0.5; | |
26703 else | |
26704 y = Math.floor(y) + 0.5; | |
26705 } | |
26706 | |
26707 ctx.moveTo(x, y); | |
26708 ctx.lineTo(x + xoff, y + yoff); | |
26709 } | |
26710 | |
26711 ctx.stroke(); | |
26712 } | |
26713 | |
26714 | |
26715 // draw border | |
26716 if (bw) { | |
26717 // If either borderWidth or borderColor is an object, then draw the border | |
26718 // line by line instead of as one rectangle | |
26719 bc = options.grid.borderColor; | |
26720 if(typeof bw == "object" || typeof bc == "object") { | |
26721 if (typeof bw !== "object") { | |
26722 bw = {top: bw, right: bw, bottom: bw, left: bw}; | |
26723 } | |
26724 if (typeof bc !== "object") { | |
26725 bc = {top: bc, right: bc, bottom: bc, left: bc}; | |
26726 } | |
26727 | |
26728 if (bw.top > 0) { | |
26729 ctx.strokeStyle = bc.top; | |
26730 ctx.lineWidth = bw.top; | |
26731 ctx.beginPath(); | |
26732 ctx.moveTo(0 - bw.left, 0 - bw.top/2); | |
26733 ctx.lineTo(plotWidth, 0 - bw.top/2); | |
26734 ctx.stroke(); | |
26735 } | |
26736 | |
26737 if (bw.right > 0) { | |
26738 ctx.strokeStyle = bc.right; | |
26739 ctx.lineWidth = bw.right; | |
26740 ctx.beginPath(); | |
26741 ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); | |
26742 ctx.lineTo(plotWidth + bw.right / 2, plotHeight); | |
26743 ctx.stroke(); | |
26744 } | |
26745 | |
26746 if (bw.bottom > 0) { | |
26747 ctx.strokeStyle = bc.bottom; | |
26748 ctx.lineWidth = bw.bottom; | |
26749 ctx.beginPath(); | |
26750 ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); | |
26751 ctx.lineTo(0, plotHeight + bw.bottom / 2); | |
26752 ctx.stroke(); | |
26753 } | |
26754 | |
26755 if (bw.left > 0) { | |
26756 ctx.strokeStyle = bc.left; | |
26757 ctx.lineWidth = bw.left; | |
26758 ctx.beginPath(); | |
26759 ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); | |
26760 ctx.lineTo(0- bw.left/2, 0); | |
26761 ctx.stroke(); | |
26762 } | |
26763 } | |
26764 else { | |
26765 ctx.lineWidth = bw; | |
26766 ctx.strokeStyle = options.grid.borderColor; | |
26767 ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); | |
26768 } | |
26769 } | |
26770 | |
26771 ctx.restore(); | |
26772 } | |
26773 | |
26774 function drawAxisLabels() { | |
26775 | |
26776 $.each(allAxes(), function (_, axis) { | |
26777 var box = axis.box, | |
26778 legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", | |
26779 layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, | |
26780 font = axis.options.font || "flot-tick-label tickLabel", | |
26781 tick, x, y, halign, valign; | |
26782 | |
26783 // Remove text before checking for axis.show and ticks.length; | |
26784 // otherwise plugins, like flot-tickrotor, that draw their own | |
26785 // tick labels will end up with both theirs and the defaults. | |
26786 | |
26787 surface.removeText(layer); | |
26788 | |
26789 if (!axis.show || axis.ticks.length == 0) | |
26790 return; | |
26791 | |
26792 for (var i = 0; i < axis.ticks.length; ++i) { | |
26793 | |
26794 tick = axis.ticks[i]; | |
26795 if (!tick.label || tick.v < axis.min || tick.v > axis.max) | |
26796 continue; | |
26797 | |
26798 if (axis.direction == "x") { | |
26799 halign = "center"; | |
26800 x = plotOffset.left + axis.p2c(tick.v); | |
26801 if (axis.position == "bottom") { | |
26802 y = box.top + box.padding; | |
26803 } else { | |
26804 y = box.top + box.height - box.padding; | |
26805 valign = "bottom"; | |
26806 } | |
26807 } else { | |
26808 valign = "middle"; | |
26809 y = plotOffset.top + axis.p2c(tick.v); | |
26810 if (axis.position == "left") { | |
26811 x = box.left + box.width - box.padding; | |
26812 halign = "right"; | |
26813 } else { | |
26814 x = box.left + box.padding; | |
26815 } | |
26816 } | |
26817 | |
26818 surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); | |
26819 } | |
26820 }); | |
26821 } | |
26822 | |
26823 function drawSeries(series) { | |
26824 if (series.lines.show) | |
26825 drawSeriesLines(series); | |
26826 if (series.bars.show) | |
26827 drawSeriesBars(series); | |
26828 if (series.points.show) | |
26829 drawSeriesPoints(series); | |
26830 } | |
26831 | |
26832 function drawSeriesLines(series) { | |
26833 function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { | |
26834 var points = datapoints.points, | |
26835 ps = datapoints.pointsize, | |
26836 prevx = null, prevy = null; | |
26837 | |
26838 ctx.beginPath(); | |
26839 for (var i = ps; i < points.length; i += ps) { | |
26840 var x1 = points[i - ps], y1 = points[i - ps + 1], | |
26841 x2 = points[i], y2 = points[i + 1]; | |
26842 | |
26843 if (x1 == null || x2 == null) | |
26844 continue; | |
26845 | |
26846 // clip with ymin | |
26847 if (y1 <= y2 && y1 < axisy.min) { | |
26848 if (y2 < axisy.min) | |
26849 continue; // line segment is outside | |
26850 // compute new intersection point | |
26851 x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26852 y1 = axisy.min; | |
26853 } | |
26854 else if (y2 <= y1 && y2 < axisy.min) { | |
26855 if (y1 < axisy.min) | |
26856 continue; | |
26857 x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26858 y2 = axisy.min; | |
26859 } | |
26860 | |
26861 // clip with ymax | |
26862 if (y1 >= y2 && y1 > axisy.max) { | |
26863 if (y2 > axisy.max) | |
26864 continue; | |
26865 x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26866 y1 = axisy.max; | |
26867 } | |
26868 else if (y2 >= y1 && y2 > axisy.max) { | |
26869 if (y1 > axisy.max) | |
26870 continue; | |
26871 x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
26872 y2 = axisy.max; | |
26873 } | |
26874 | |
26875 // clip with xmin | |
26876 if (x1 <= x2 && x1 < axisx.min) { | |
26877 if (x2 < axisx.min) | |
26878 continue; | |
26879 y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26880 x1 = axisx.min; | |
26881 } | |
26882 else if (x2 <= x1 && x2 < axisx.min) { | |
26883 if (x1 < axisx.min) | |
26884 continue; | |
26885 y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26886 x2 = axisx.min; | |
26887 } | |
26888 | |
26889 // clip with xmax | |
26890 if (x1 >= x2 && x1 > axisx.max) { | |
26891 if (x2 > axisx.max) | |
26892 continue; | |
26893 y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26894 x1 = axisx.max; | |
26895 } | |
26896 else if (x2 >= x1 && x2 > axisx.max) { | |
26897 if (x1 > axisx.max) | |
26898 continue; | |
26899 y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26900 x2 = axisx.max; | |
26901 } | |
26902 | |
26903 if (x1 != prevx || y1 != prevy) | |
26904 ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); | |
26905 | |
26906 prevx = x2; | |
26907 prevy = y2; | |
26908 ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); | |
26909 } | |
26910 ctx.stroke(); | |
26911 } | |
26912 | |
26913 function plotLineArea(datapoints, axisx, axisy) { | |
26914 var points = datapoints.points, | |
26915 ps = datapoints.pointsize, | |
26916 bottom = Math.min(Math.max(0, axisy.min), axisy.max), | |
26917 i = 0, top, areaOpen = false, | |
26918 ypos = 1, segmentStart = 0, segmentEnd = 0; | |
26919 | |
26920 // we process each segment in two turns, first forward | |
26921 // direction to sketch out top, then once we hit the | |
26922 // end we go backwards to sketch the bottom | |
26923 while (true) { | |
26924 if (ps > 0 && i > points.length + ps) | |
26925 break; | |
26926 | |
26927 i += ps; // ps is negative if going backwards | |
26928 | |
26929 var x1 = points[i - ps], | |
26930 y1 = points[i - ps + ypos], | |
26931 x2 = points[i], y2 = points[i + ypos]; | |
26932 | |
26933 if (areaOpen) { | |
26934 if (ps > 0 && x1 != null && x2 == null) { | |
26935 // at turning point | |
26936 segmentEnd = i; | |
26937 ps = -ps; | |
26938 ypos = 2; | |
26939 continue; | |
26940 } | |
26941 | |
26942 if (ps < 0 && i == segmentStart + ps) { | |
26943 // done with the reverse sweep | |
26944 ctx.fill(); | |
26945 areaOpen = false; | |
26946 ps = -ps; | |
26947 ypos = 1; | |
26948 i = segmentStart = segmentEnd + ps; | |
26949 continue; | |
26950 } | |
26951 } | |
26952 | |
26953 if (x1 == null || x2 == null) | |
26954 continue; | |
26955 | |
26956 // clip x values | |
26957 | |
26958 // clip with xmin | |
26959 if (x1 <= x2 && x1 < axisx.min) { | |
26960 if (x2 < axisx.min) | |
26961 continue; | |
26962 y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26963 x1 = axisx.min; | |
26964 } | |
26965 else if (x2 <= x1 && x2 < axisx.min) { | |
26966 if (x1 < axisx.min) | |
26967 continue; | |
26968 y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26969 x2 = axisx.min; | |
26970 } | |
26971 | |
26972 // clip with xmax | |
26973 if (x1 >= x2 && x1 > axisx.max) { | |
26974 if (x2 > axisx.max) | |
26975 continue; | |
26976 y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26977 x1 = axisx.max; | |
26978 } | |
26979 else if (x2 >= x1 && x2 > axisx.max) { | |
26980 if (x1 > axisx.max) | |
26981 continue; | |
26982 y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; | |
26983 x2 = axisx.max; | |
26984 } | |
26985 | |
26986 if (!areaOpen) { | |
26987 // open area | |
26988 ctx.beginPath(); | |
26989 ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); | |
26990 areaOpen = true; | |
26991 } | |
26992 | |
26993 // now first check the case where both is outside | |
26994 if (y1 >= axisy.max && y2 >= axisy.max) { | |
26995 ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); | |
26996 ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); | |
26997 continue; | |
26998 } | |
26999 else if (y1 <= axisy.min && y2 <= axisy.min) { | |
27000 ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); | |
27001 ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); | |
27002 continue; | |
27003 } | |
27004 | |
27005 // else it's a bit more complicated, there might | |
27006 // be a flat maxed out rectangle first, then a | |
27007 // triangular cutout or reverse; to find these | |
27008 // keep track of the current x values | |
27009 var x1old = x1, x2old = x2; | |
27010 | |
27011 // clip the y values, without shortcutting, we | |
27012 // go through all cases in turn | |
27013 | |
27014 // clip with ymin | |
27015 if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { | |
27016 x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27017 y1 = axisy.min; | |
27018 } | |
27019 else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { | |
27020 x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27021 y2 = axisy.min; | |
27022 } | |
27023 | |
27024 // clip with ymax | |
27025 if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { | |
27026 x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27027 y1 = axisy.max; | |
27028 } | |
27029 else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { | |
27030 x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; | |
27031 y2 = axisy.max; | |
27032 } | |
27033 | |
27034 // if the x value was changed we got a rectangle | |
27035 // to fill | |
27036 if (x1 != x1old) { | |
27037 ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); | |
27038 // it goes to (x1, y1), but we fill that below | |
27039 } | |
27040 | |
27041 // fill triangular section, this sometimes result | |
27042 // in redundant points if (x1, y1) hasn't changed | |
27043 // from previous line to, but we just ignore that | |
27044 ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); | |
27045 ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); | |
27046 | |
27047 // fill the other rectangle if it's there | |
27048 if (x2 != x2old) { | |
27049 ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); | |
27050 ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); | |
27051 } | |
27052 } | |
27053 } | |
27054 | |
27055 ctx.save(); | |
27056 ctx.translate(plotOffset.left, plotOffset.top); | |
27057 ctx.lineJoin = "round"; | |
27058 | |
27059 var lw = series.lines.lineWidth, | |
27060 sw = series.shadowSize; | |
27061 // FIXME: consider another form of shadow when filling is turned on | |
27062 if (lw > 0 && sw > 0) { | |
27063 // draw shadow as a thick and thin line with transparency | |
27064 ctx.lineWidth = sw; | |
27065 ctx.strokeStyle = "rgba(0,0,0,0.1)"; | |
27066 // position shadow at angle from the mid of line | |
27067 var angle = Math.PI/18; | |
27068 plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); | |
27069 ctx.lineWidth = sw/2; | |
27070 plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); | |
27071 } | |
27072 | |
27073 ctx.lineWidth = lw; | |
27074 ctx.strokeStyle = series.color; | |
27075 var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); | |
27076 if (fillStyle) { | |
27077 ctx.fillStyle = fillStyle; | |
27078 plotLineArea(series.datapoints, series.xaxis, series.yaxis); | |
27079 } | |
27080 | |
27081 if (lw > 0) | |
27082 plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); | |
27083 ctx.restore(); | |
27084 } | |
27085 | |
27086 function drawSeriesPoints(series) { | |
27087 function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { | |
27088 var points = datapoints.points, ps = datapoints.pointsize; | |
27089 | |
27090 for (var i = 0; i < points.length; i += ps) { | |
27091 var x = points[i], y = points[i + 1]; | |
27092 if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) | |
27093 continue; | |
27094 | |
27095 ctx.beginPath(); | |
27096 x = axisx.p2c(x); | |
27097 y = axisy.p2c(y) + offset; | |
27098 if (symbol == "circle") | |
27099 ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); | |
27100 else | |
27101 symbol(ctx, x, y, radius, shadow); | |
27102 ctx.closePath(); | |
27103 | |
27104 if (fillStyle) { | |
27105 ctx.fillStyle = fillStyle; | |
27106 ctx.fill(); | |
27107 } | |
27108 ctx.stroke(); | |
27109 } | |
27110 } | |
27111 | |
27112 ctx.save(); | |
27113 ctx.translate(plotOffset.left, plotOffset.top); | |
27114 | |
27115 var lw = series.points.lineWidth, | |
27116 sw = series.shadowSize, | |
27117 radius = series.points.radius, | |
27118 symbol = series.points.symbol; | |
27119 | |
27120 // If the user sets the line width to 0, we change it to a very | |
27121 // small value. A line width of 0 seems to force the default of 1. | |
27122 // Doing the conditional here allows the shadow setting to still be | |
27123 // optional even with a lineWidth of 0. | |
27124 | |
27125 if( lw == 0 ) | |
27126 lw = 0.0001; | |
27127 | |
27128 if (lw > 0 && sw > 0) { | |
27129 // draw shadow in two steps | |
27130 var w = sw / 2; | |
27131 ctx.lineWidth = w; | |
27132 ctx.strokeStyle = "rgba(0,0,0,0.1)"; | |
27133 plotPoints(series.datapoints, radius, null, w + w/2, true, | |
27134 series.xaxis, series.yaxis, symbol); | |
27135 | |
27136 ctx.strokeStyle = "rgba(0,0,0,0.2)"; | |
27137 plotPoints(series.datapoints, radius, null, w/2, true, | |
27138 series.xaxis, series.yaxis, symbol); | |
27139 } | |
27140 | |
27141 ctx.lineWidth = lw; | |
27142 ctx.strokeStyle = series.color; | |
27143 plotPoints(series.datapoints, radius, | |
27144 getFillStyle(series.points, series.color), 0, false, | |
27145 series.xaxis, series.yaxis, symbol); | |
27146 ctx.restore(); | |
27147 } | |
27148 | |
27149 function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { | |
27150 var left, right, bottom, top, | |
27151 drawLeft, drawRight, drawTop, drawBottom, | |
27152 tmp; | |
27153 | |
27154 // in horizontal mode, we start the bar from the left | |
27155 // instead of from the bottom so it appears to be | |
27156 // horizontal rather than vertical | |
27157 if (horizontal) { | |
27158 drawBottom = drawRight = drawTop = true; | |
27159 drawLeft = false; | |
27160 left = b; | |
27161 right = x; | |
27162 top = y + barLeft; | |
27163 bottom = y + barRight; | |
27164 | |
27165 // account for negative bars | |
27166 if (right < left) { | |
27167 tmp = right; | |
27168 right = left; | |
27169 left = tmp; | |
27170 drawLeft = true; | |
27171 drawRight = false; | |
27172 } | |
27173 } | |
27174 else { | |
27175 drawLeft = drawRight = drawTop = true; | |
27176 drawBottom = false; | |
27177 left = x + barLeft; | |
27178 right = x + barRight; | |
27179 bottom = b; | |
27180 top = y; | |
27181 | |
27182 // account for negative bars | |
27183 if (top < bottom) { | |
27184 tmp = top; | |
27185 top = bottom; | |
27186 bottom = tmp; | |
27187 drawBottom = true; | |
27188 drawTop = false; | |
27189 } | |
27190 } | |
27191 | |
27192 // clip | |
27193 if (right < axisx.min || left > axisx.max || | |
27194 top < axisy.min || bottom > axisy.max) | |
27195 return; | |
27196 | |
27197 if (left < axisx.min) { | |
27198 left = axisx.min; | |
27199 drawLeft = false; | |
27200 } | |
27201 | |
27202 if (right > axisx.max) { | |
27203 right = axisx.max; | |
27204 drawRight = false; | |
27205 } | |
27206 | |
27207 if (bottom < axisy.min) { | |
27208 bottom = axisy.min; | |
27209 drawBottom = false; | |
27210 } | |
27211 | |
27212 if (top > axisy.max) { | |
27213 top = axisy.max; | |
27214 drawTop = false; | |
27215 } | |
27216 | |
27217 left = axisx.p2c(left); | |
27218 bottom = axisy.p2c(bottom); | |
27219 right = axisx.p2c(right); | |
27220 top = axisy.p2c(top); | |
27221 | |
27222 // fill the bar | |
27223 if (fillStyleCallback) { | |
27224 c.fillStyle = fillStyleCallback(bottom, top); | |
27225 c.fillRect(left, top, right - left, bottom - top) | |
27226 } | |
27227 | |
27228 // draw outline | |
27229 if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { | |
27230 c.beginPath(); | |
27231 | |
27232 // FIXME: inline moveTo is buggy with excanvas | |
27233 c.moveTo(left, bottom); | |
27234 if (drawLeft) | |
27235 c.lineTo(left, top); | |
27236 else | |
27237 c.moveTo(left, top); | |
27238 if (drawTop) | |
27239 c.lineTo(right, top); | |
27240 else | |
27241 c.moveTo(right, top); | |
27242 if (drawRight) | |
27243 c.lineTo(right, bottom); | |
27244 else | |
27245 c.moveTo(right, bottom); | |
27246 if (drawBottom) | |
27247 c.lineTo(left, bottom); | |
27248 else | |
27249 c.moveTo(left, bottom); | |
27250 c.stroke(); | |
27251 } | |
27252 } | |
27253 | |
27254 function drawSeriesBars(series) { | |
27255 function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { | |
27256 var points = datapoints.points, ps = datapoints.pointsize; | |
27257 | |
27258 for (var i = 0; i < points.length; i += ps) { | |
27259 if (points[i] == null) | |
27260 continue; | |
27261 drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); | |
27262 } | |
27263 } | |
27264 | |
27265 ctx.save(); | |
27266 ctx.translate(plotOffset.left, plotOffset.top); | |
27267 | |
27268 // FIXME: figure out a way to add shadows (for instance along the right edge) | |
27269 ctx.lineWidth = series.bars.lineWidth; | |
27270 ctx.strokeStyle = series.color; | |
27271 | |
27272 var barLeft; | |
27273 | |
27274 switch (series.bars.align) { | |
27275 case "left": | |
27276 barLeft = 0; | |
27277 break; | |
27278 case "right": | |
27279 barLeft = -series.bars.barWidth; | |
27280 break; | |
27281 default: | |
27282 barLeft = -series.bars.barWidth / 2; | |
27283 } | |
27284 | |
27285 var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; | |
27286 plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); | |
27287 ctx.restore(); | |
27288 } | |
27289 | |
27290 function getFillStyle(filloptions, seriesColor, bottom, top) { | |
27291 var fill = filloptions.fill; | |
27292 if (!fill) | |
27293 return null; | |
27294 | |
27295 if (filloptions.fillColor) | |
27296 return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); | |
27297 | |
27298 var c = $.color.parse(seriesColor); | |
27299 c.a = typeof fill == "number" ? fill : 0.4; | |
27300 c.normalize(); | |
27301 return c.toString(); | |
27302 } | |
27303 | |
27304 function insertLegend() { | |
27305 | |
27306 if (options.legend.container != null) { | |
27307 $(options.legend.container).html(""); | |
27308 } else { | |
27309 placeholder.find(".legend").remove(); | |
27310 } | |
27311 | |
27312 if (!options.legend.show) { | |
27313 return; | |
27314 } | |
27315 | |
27316 var fragments = [], entries = [], rowStarted = false, | |
27317 lf = options.legend.labelFormatter, s, label; | |
27318 | |
27319 // Build a list of legend entries, with each having a label and a color | |
27320 | |
27321 for (var i = 0; i < series.length; ++i) { | |
27322 s = series[i]; | |
27323 if (s.label) { | |
27324 label = lf ? lf(s.label, s) : s.label; | |
27325 if (label) { | |
27326 entries.push({ | |
27327 label: label, | |
27328 color: s.color | |
27329 }); | |
27330 } | |
27331 } | |
27332 } | |
27333 | |
27334 // Sort the legend using either the default or a custom comparator | |
27335 | |
27336 if (options.legend.sorted) { | |
27337 if ($.isFunction(options.legend.sorted)) { | |
27338 entries.sort(options.legend.sorted); | |
27339 } else if (options.legend.sorted == "reverse") { | |
27340 entries.reverse(); | |
27341 } else { | |
27342 var ascending = options.legend.sorted != "descending"; | |
27343 entries.sort(function(a, b) { | |
27344 return a.label == b.label ? 0 : ( | |
27345 (a.label < b.label) != ascending ? 1 : -1 // Logical XOR | |
27346 ); | |
27347 }); | |
27348 } | |
27349 } | |
27350 | |
27351 // Generate markup for the list of entries, in their final order | |
27352 | |
27353 for (var i = 0; i < entries.length; ++i) { | |
27354 | |
27355 var entry = entries[i]; | |
27356 | |
27357 if (i % options.legend.noColumns == 0) { | |
27358 if (rowStarted) | |
27359 fragments.push('</tr>'); | |
27360 fragments.push('<tr>'); | |
27361 rowStarted = true; | |
27362 } | |
27363 | |
27364 fragments.push( | |
27365 '<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>' + | |
27366 '<td class="legendLabel">' + entry.label + '</td>' | |
27367 ); | |
27368 } | |
27369 | |
27370 if (rowStarted) | |
27371 fragments.push('</tr>'); | |
27372 | |
27373 if (fragments.length == 0) | |
27374 return; | |
27375 | |
27376 var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>'; | |
27377 if (options.legend.container != null) | |
27378 $(options.legend.container).html(table); | |
27379 else { | |
27380 var pos = "", | |
27381 p = options.legend.position, | |
27382 m = options.legend.margin; | |
27383 if (m[0] == null) | |
27384 m = [m, m]; | |
27385 if (p.charAt(0) == "n") | |
27386 pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; | |
27387 else if (p.charAt(0) == "s") | |
27388 pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; | |
27389 if (p.charAt(1) == "e") | |
27390 pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; | |
27391 else if (p.charAt(1) == "w") | |
27392 pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; | |
27393 var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder); | |
27394 if (options.legend.backgroundOpacity != 0.0) { | |
27395 // put in the transparent background | |
27396 // separately to avoid blended labels and | |
27397 // label boxes | |
27398 var c = options.legend.backgroundColor; | |
27399 if (c == null) { | |
27400 c = options.grid.backgroundColor; | |
27401 if (c && typeof c == "string") | |
27402 c = $.color.parse(c); | |
27403 else | |
27404 c = $.color.extract(legend, 'background-color'); | |
27405 c.a = 1; | |
27406 c = c.toString(); | |
27407 } | |
27408 var div = legend.children(); | |
27409 $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity); | |
27410 } | |
27411 } | |
27412 } | |
27413 | |
27414 | |
27415 // interactive features | |
27416 | |
27417 var highlights = [], | |
27418 redrawTimeout = null; | |
27419 | |
27420 // returns the data item the mouse is over, or null if none is found | |
27421 function findNearbyItem(mouseX, mouseY, seriesFilter) { | |
27422 var maxDistance = options.grid.mouseActiveRadius, | |
27423 smallestDistance = maxDistance * maxDistance + 1, | |
27424 item = null, foundPoint = false, i, j, ps; | |
27425 | |
27426 for (i = series.length - 1; i >= 0; --i) { | |
27427 if (!seriesFilter(series[i])) | |
27428 continue; | |
27429 | |
27430 var s = series[i], | |
27431 axisx = s.xaxis, | |
27432 axisy = s.yaxis, | |
27433 points = s.datapoints.points, | |
27434 mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster | |
27435 my = axisy.c2p(mouseY), | |
27436 maxx = maxDistance / axisx.scale, | |
27437 maxy = maxDistance / axisy.scale; | |
27438 | |
27439 ps = s.datapoints.pointsize; | |
27440 // with inverse transforms, we can't use the maxx/maxy | |
27441 // optimization, sadly | |
27442 if (axisx.options.inverseTransform) | |
27443 maxx = Number.MAX_VALUE; | |
27444 if (axisy.options.inverseTransform) | |
27445 maxy = Number.MAX_VALUE; | |
27446 | |
27447 if (s.lines.show || s.points.show) { | |
27448 for (j = 0; j < points.length; j += ps) { | |
27449 var x = points[j], y = points[j + 1]; | |
27450 if (x == null) | |
27451 continue; | |
27452 | |
27453 // For points and lines, the cursor must be within a | |
27454 // certain distance to the data point | |
27455 if (x - mx > maxx || x - mx < -maxx || | |
27456 y - my > maxy || y - my < -maxy) | |
27457 continue; | |
27458 | |
27459 // We have to calculate distances in pixels, not in | |
27460 // data units, because the scales of the axes may be different | |
27461 var dx = Math.abs(axisx.p2c(x) - mouseX), | |
27462 dy = Math.abs(axisy.p2c(y) - mouseY), | |
27463 dist = dx * dx + dy * dy; // we save the sqrt | |
27464 | |
27465 // use <= to ensure last point takes precedence | |
27466 // (last generally means on top of) | |
27467 if (dist < smallestDistance) { | |
27468 smallestDistance = dist; | |
27469 item = [i, j / ps]; | |
27470 } | |
27471 } | |
27472 } | |
27473 | |
27474 if (s.bars.show && !item) { // no other point can be nearby | |
27475 | |
27476 var barLeft, barRight; | |
27477 | |
27478 switch (s.bars.align) { | |
27479 case "left": | |
27480 barLeft = 0; | |
27481 break; | |
27482 case "right": | |
27483 barLeft = -s.bars.barWidth; | |
27484 break; | |
27485 default: | |
27486 barLeft = -s.bars.barWidth / 2; | |
27487 } | |
27488 | |
27489 barRight = barLeft + s.bars.barWidth; | |
27490 | |
27491 for (j = 0; j < points.length; j += ps) { | |
27492 var x = points[j], y = points[j + 1], b = points[j + 2]; | |
27493 if (x == null) | |
27494 continue; | |
27495 | |
27496 // for a bar graph, the cursor must be inside the bar | |
27497 if (series[i].bars.horizontal ? | |
27498 (mx <= Math.max(b, x) && mx >= Math.min(b, x) && | |
27499 my >= y + barLeft && my <= y + barRight) : | |
27500 (mx >= x + barLeft && mx <= x + barRight && | |
27501 my >= Math.min(b, y) && my <= Math.max(b, y))) | |
27502 item = [i, j / ps]; | |
27503 } | |
27504 } | |
27505 } | |
27506 | |
27507 if (item) { | |
27508 i = item[0]; | |
27509 j = item[1]; | |
27510 ps = series[i].datapoints.pointsize; | |
27511 | |
27512 return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), | |
27513 dataIndex: j, | |
27514 series: series[i], | |
27515 seriesIndex: i }; | |
27516 } | |
27517 | |
27518 return null; | |
27519 } | |
27520 | |
27521 function onMouseMove(e) { | |
27522 if (options.grid.hoverable) | |
27523 triggerClickHoverEvent("plothover", e, | |
27524 function (s) { return s["hoverable"] != false; }); | |
27525 } | |
27526 | |
27527 function onMouseLeave(e) { | |
27528 if (options.grid.hoverable) | |
27529 triggerClickHoverEvent("plothover", e, | |
27530 function (s) { return false; }); | |
27531 } | |
27532 | |
27533 function onClick(e) { | |
27534 triggerClickHoverEvent("plotclick", e, | |
27535 function (s) { return s["clickable"] != false; }); | |
27536 } | |
27537 | |
27538 // trigger click or hover event (they send the same parameters | |
27539 // so we share their code) | |
27540 function triggerClickHoverEvent(eventname, event, seriesFilter) { | |
27541 var offset = eventHolder.offset(), | |
27542 canvasX = event.pageX - offset.left - plotOffset.left, | |
27543 canvasY = event.pageY - offset.top - plotOffset.top, | |
27544 pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); | |
27545 | |
27546 pos.pageX = event.pageX; | |
27547 pos.pageY = event.pageY; | |
27548 | |
27549 var item = findNearbyItem(canvasX, canvasY, seriesFilter); | |
27550 | |
27551 if (item) { | |
27552 // fill in mouse pos for any listeners out there | |
27553 item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); | |
27554 item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); | |
27555 } | |
27556 | |
27557 if (options.grid.autoHighlight) { | |
27558 // clear auto-highlights | |
27559 for (var i = 0; i < highlights.length; ++i) { | |
27560 var h = highlights[i]; | |
27561 if (h.auto == eventname && | |
27562 !(item && h.series == item.series && | |
27563 h.point[0] == item.datapoint[0] && | |
27564 h.point[1] == item.datapoint[1])) | |
27565 unhighlight(h.series, h.point); | |
27566 } | |
27567 | |
27568 if (item) | |
27569 highlight(item.series, item.datapoint, eventname); | |
27570 } | |
27571 | |
27572 placeholder.trigger(eventname, [ pos, item ]); | |
27573 } | |
27574 | |
27575 function triggerRedrawOverlay() { | |
27576 var t = options.interaction.redrawOverlayInterval; | |
27577 if (t == -1) { // skip event queue | |
27578 drawOverlay(); | |
27579 return; | |
27580 } | |
27581 | |
27582 if (!redrawTimeout) | |
27583 redrawTimeout = setTimeout(drawOverlay, t); | |
27584 } | |
27585 | |
27586 function drawOverlay() { | |
27587 redrawTimeout = null; | |
27588 | |
27589 // draw highlights | |
27590 octx.save(); | |
27591 overlay.clear(); | |
27592 octx.translate(plotOffset.left, plotOffset.top); | |
27593 | |
27594 var i, hi; | |
27595 for (i = 0; i < highlights.length; ++i) { | |
27596 hi = highlights[i]; | |
27597 | |
27598 if (hi.series.bars.show) | |
27599 drawBarHighlight(hi.series, hi.point); | |
27600 else | |
27601 drawPointHighlight(hi.series, hi.point); | |
27602 } | |
27603 octx.restore(); | |
27604 | |
27605 executeHooks(hooks.drawOverlay, [octx]); | |
27606 } | |
27607 | |
27608 function highlight(s, point, auto) { | |
27609 if (typeof s == "number") | |
27610 s = series[s]; | |
27611 | |
27612 if (typeof point == "number") { | |
27613 var ps = s.datapoints.pointsize; | |
27614 point = s.datapoints.points.slice(ps * point, ps * (point + 1)); | |
27615 } | |
27616 | |
27617 var i = indexOfHighlight(s, point); | |
27618 if (i == -1) { | |
27619 highlights.push({ series: s, point: point, auto: auto }); | |
27620 | |
27621 triggerRedrawOverlay(); | |
27622 } | |
27623 else if (!auto) | |
27624 highlights[i].auto = false; | |
27625 } | |
27626 | |
27627 function unhighlight(s, point) { | |
27628 if (s == null && point == null) { | |
27629 highlights = []; | |
27630 triggerRedrawOverlay(); | |
27631 return; | |
27632 } | |
27633 | |
27634 if (typeof s == "number") | |
27635 s = series[s]; | |
27636 | |
27637 if (typeof point == "number") { | |
27638 var ps = s.datapoints.pointsize; | |
27639 point = s.datapoints.points.slice(ps * point, ps * (point + 1)); | |
27640 } | |
27641 | |
27642 var i = indexOfHighlight(s, point); | |
27643 if (i != -1) { | |
27644 highlights.splice(i, 1); | |
27645 | |
27646 triggerRedrawOverlay(); | |
27647 } | |
27648 } | |
27649 | |
27650 function indexOfHighlight(s, p) { | |
27651 for (var i = 0; i < highlights.length; ++i) { | |
27652 var h = highlights[i]; | |
27653 if (h.series == s && h.point[0] == p[0] | |
27654 && h.point[1] == p[1]) | |
27655 return i; | |
27656 } | |
27657 return -1; | |
27658 } | |
27659 | |
27660 function drawPointHighlight(series, point) { | |
27661 var x = point[0], y = point[1], | |
27662 axisx = series.xaxis, axisy = series.yaxis, | |
27663 highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); | |
27664 | |
27665 if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) | |
27666 return; | |
27667 | |
27668 var pointRadius = series.points.radius + series.points.lineWidth / 2; | |
27669 octx.lineWidth = pointRadius; | |
27670 octx.strokeStyle = highlightColor; | |
27671 var radius = 1.5 * pointRadius; | |
27672 x = axisx.p2c(x); | |
27673 y = axisy.p2c(y); | |
27674 | |
27675 octx.beginPath(); | |
27676 if (series.points.symbol == "circle") | |
27677 octx.arc(x, y, radius, 0, 2 * Math.PI, false); | |
27678 else | |
27679 series.points.symbol(octx, x, y, radius, false); | |
27680 octx.closePath(); | |
27681 octx.stroke(); | |
27682 } | |
27683 | |
27684 function drawBarHighlight(series, point) { | |
27685 var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), | |
27686 fillStyle = highlightColor, | |
27687 barLeft; | |
27688 | |
27689 switch (series.bars.align) { | |
27690 case "left": | |
27691 barLeft = 0; | |
27692 break; | |
27693 case "right": | |
27694 barLeft = -series.bars.barWidth; | |
27695 break; | |
27696 default: | |
27697 barLeft = -series.bars.barWidth / 2; | |
27698 } | |
27699 | |
27700 octx.lineWidth = series.bars.lineWidth; | |
27701 octx.strokeStyle = highlightColor; | |
27702 | |
27703 drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, | |
27704 function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); | |
27705 } | |
27706 | |
27707 function getColorOrGradient(spec, bottom, top, defaultColor) { | |
27708 if (typeof spec == "string") | |
27709 return spec; | |
27710 else { | |
27711 // assume this is a gradient spec; IE currently only | |
27712 // supports a simple vertical gradient properly, so that's | |
27713 // what we support too | |
27714 var gradient = ctx.createLinearGradient(0, top, 0, bottom); | |
27715 | |
27716 for (var i = 0, l = spec.colors.length; i < l; ++i) { | |
27717 var c = spec.colors[i]; | |
27718 if (typeof c != "string") { | |
27719 var co = $.color.parse(defaultColor); | |
27720 if (c.brightness != null) | |
27721 co = co.scale('rgb', c.brightness); | |
27722 if (c.opacity != null) | |
27723 co.a *= c.opacity; | |
27724 c = co.toString(); | |
27725 } | |
27726 gradient.addColorStop(i / (l - 1), c); | |
27727 } | |
27728 | |
27729 return gradient; | |
27730 } | |
27731 } | |
27732 } | |
27733 | |
27734 // Add the plot function to the top level of the jQuery object | |
27735 | |
27736 $.plot = function(placeholder, data, options) { | |
27737 //var t0 = new Date(); | |
27738 var plot = new Plot($(placeholder), data, options, $.plot.plugins); | |
27739 //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); | |
27740 return plot; | |
27741 }; | |
27742 | |
27743 $.plot.version = "0.8.2"; | |
27744 | |
27745 $.plot.plugins = []; | |
27746 | |
27747 // Also add the plot function as a chainable property | |
27748 | |
27749 $.fn.plot = function(data, options) { | |
27750 return this.each(function() { | |
27751 $.plot(this, data, options); | |
27752 }); | |
27753 }; | |
27754 | |
27755 // round to nearby lower multiple of base | |
27756 function floorInBase(n, base) { | |
27757 return base * Math.floor(n / base); | |
27758 } | |
27759 | |
27760 })(jQuery); | |
27761 /* Flot plugin for rendering pie charts. | |
27762 | |
27763 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
27764 Licensed under the MIT license. | |
27765 | |
27766 The plugin assumes that each series has a single data value, and that each | |
27767 value is a positive integer or zero. Negative numbers don't make sense for a | |
27768 pie chart, and have unpredictable results. The values do NOT need to be | |
27769 passed in as percentages; the plugin will calculate the total and per-slice | |
27770 percentages internally. | |
27771 | |
27772 * Created by Brian Medendorp | |
27773 | |
27774 * Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars | |
27775 | |
27776 The plugin supports these options: | |
27777 | |
27778 series: { | |
27779 pie: { | |
27780 show: true/false | |
27781 radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto' | |
27782 innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect | |
27783 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 | |
27784 tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show) | |
27785 offset: { | |
27786 top: integer value to move the pie up or down | |
27787 left: integer value to move the pie left or right, or 'auto' | |
27788 }, | |
27789 stroke: { | |
27790 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF') | |
27791 width: integer pixel width of the stroke | |
27792 }, | |
27793 label: { | |
27794 show: true/false, or 'auto' | |
27795 formatter: a user-defined function that modifies the text/style of the label text | |
27796 radius: 0-1 for percentage of fullsize, or a specified pixel length | |
27797 background: { | |
27798 color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000') | |
27799 opacity: 0-1 | |
27800 }, | |
27801 threshold: 0-1 for the percentage value at which to hide labels (if they're too small) | |
27802 }, | |
27803 combine: { | |
27804 threshold: 0-1 for the percentage value at which to combine slices (if they're too small) | |
27805 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 | |
27806 label: any text value of what the combined slice should be labeled | |
27807 } | |
27808 highlight: { | |
27809 opacity: 0-1 | |
27810 } | |
27811 } | |
27812 } | |
27813 | |
27814 More detail and specific examples can be found in the included HTML file. | |
27815 | |
27816 */ | |
27817 | |
27818 (function($) { | |
27819 | |
27820 // Maximum redraw attempts when fitting labels within the plot | |
27821 | |
27822 var REDRAW_ATTEMPTS = 10; | |
27823 | |
27824 // Factor by which to shrink the pie when fitting labels within the plot | |
27825 | |
27826 var REDRAW_SHRINK = 0.95; | |
27827 | |
27828 function init(plot) { | |
27829 | |
27830 var canvas = null, | |
27831 target = null, | |
27832 options = null, | |
27833 maxRadius = null, | |
27834 centerLeft = null, | |
27835 centerTop = null, | |
27836 processed = false, | |
27837 ctx = null; | |
27838 | |
27839 // interactive variables | |
27840 | |
27841 var highlights = []; | |
27842 | |
27843 // add hook to determine if pie plugin in enabled, and then perform necessary operations | |
27844 | |
27845 plot.hooks.processOptions.push(function(plot, options) { | |
27846 if (options.series.pie.show) { | |
27847 | |
27848 options.grid.show = false; | |
27849 | |
27850 // set labels.show | |
27851 | |
27852 if (options.series.pie.label.show == "auto") { | |
27853 if (options.legend.show) { | |
27854 options.series.pie.label.show = false; | |
27855 } else { | |
27856 options.series.pie.label.show = true; | |
27857 } | |
27858 } | |
27859 | |
27860 // set radius | |
27861 | |
27862 if (options.series.pie.radius == "auto") { | |
27863 if (options.series.pie.label.show) { | |
27864 options.series.pie.radius = 3/4; | |
27865 } else { | |
27866 options.series.pie.radius = 1; | |
27867 } | |
27868 } | |
27869 | |
27870 // ensure sane tilt | |
27871 | |
27872 if (options.series.pie.tilt > 1) { | |
27873 options.series.pie.tilt = 1; | |
27874 } else if (options.series.pie.tilt < 0) { | |
27875 options.series.pie.tilt = 0; | |
27876 } | |
27877 } | |
27878 }); | |
27879 | |
27880 plot.hooks.bindEvents.push(function(plot, eventHolder) { | |
27881 var options = plot.getOptions(); | |
27882 if (options.series.pie.show) { | |
27883 if (options.grid.hoverable) { | |
27884 eventHolder.unbind("mousemove").mousemove(onMouseMove); | |
27885 } | |
27886 if (options.grid.clickable) { | |
27887 eventHolder.unbind("click").click(onClick); | |
27888 } | |
27889 } | |
27890 }); | |
27891 | |
27892 plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) { | |
27893 var options = plot.getOptions(); | |
27894 if (options.series.pie.show) { | |
27895 processDatapoints(plot, series, data, datapoints); | |
27896 } | |
27897 }); | |
27898 | |
27899 plot.hooks.drawOverlay.push(function(plot, octx) { | |
27900 var options = plot.getOptions(); | |
27901 if (options.series.pie.show) { | |
27902 drawOverlay(plot, octx); | |
27903 } | |
27904 }); | |
27905 | |
27906 plot.hooks.draw.push(function(plot, newCtx) { | |
27907 var options = plot.getOptions(); | |
27908 if (options.series.pie.show) { | |
27909 draw(plot, newCtx); | |
27910 } | |
27911 }); | |
27912 | |
27913 function processDatapoints(plot, series, datapoints) { | |
27914 if (!processed) { | |
27915 processed = true; | |
27916 canvas = plot.getCanvas(); | |
27917 target = $(canvas).parent(); | |
27918 options = plot.getOptions(); | |
27919 plot.setData(combine(plot.getData())); | |
27920 } | |
27921 } | |
27922 | |
27923 function combine(data) { | |
27924 | |
27925 var total = 0, | |
27926 combined = 0, | |
27927 numCombined = 0, | |
27928 color = options.series.pie.combine.color, | |
27929 newdata = []; | |
27930 | |
27931 // Fix up the raw data from Flot, ensuring the data is numeric | |
27932 | |
27933 for (var i = 0; i < data.length; ++i) { | |
27934 | |
27935 var value = data[i].data; | |
27936 | |
27937 // If the data is an array, we'll assume that it's a standard | |
27938 // Flot x-y pair, and are concerned only with the second value. | |
27939 | |
27940 // Note how we use the original array, rather than creating a | |
27941 // new one; this is more efficient and preserves any extra data | |
27942 // that the user may have stored in higher indexes. | |
27943 | |
27944 if ($.isArray(value) && value.length == 1) { | |
27945 value = value[0]; | |
27946 } | |
27947 | |
27948 if ($.isArray(value)) { | |
27949 // Equivalent to $.isNumeric() but compatible with jQuery < 1.7 | |
27950 if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) { | |
27951 value[1] = +value[1]; | |
27952 } else { | |
27953 value[1] = 0; | |
27954 } | |
27955 } else if (!isNaN(parseFloat(value)) && isFinite(value)) { | |
27956 value = [1, +value]; | |
27957 } else { | |
27958 value = [1, 0]; | |
27959 } | |
27960 | |
27961 data[i].data = [value]; | |
27962 } | |
27963 | |
27964 // Sum up all the slices, so we can calculate percentages for each | |
27965 | |
27966 for (var i = 0; i < data.length; ++i) { | |
27967 total += data[i].data[0][1]; | |
27968 } | |
27969 | |
27970 // Count the number of slices with percentages below the combine | |
27971 // threshold; if it turns out to be just one, we won't combine. | |
27972 | |
27973 for (var i = 0; i < data.length; ++i) { | |
27974 var value = data[i].data[0][1]; | |
27975 if (value / total <= options.series.pie.combine.threshold) { | |
27976 combined += value; | |
27977 numCombined++; | |
27978 if (!color) { | |
27979 color = data[i].color; | |
27980 } | |
27981 } | |
27982 } | |
27983 | |
27984 for (var i = 0; i < data.length; ++i) { | |
27985 var value = data[i].data[0][1]; | |
27986 if (numCombined < 2 || value / total > options.series.pie.combine.threshold) { | |
27987 newdata.push({ | |
27988 data: [[1, value]], | |
27989 color: data[i].color, | |
27990 label: data[i].label, | |
27991 angle: value * Math.PI * 2 / total, | |
27992 percent: value / (total / 100) | |
27993 }); | |
27994 } | |
27995 } | |
27996 | |
27997 if (numCombined > 1) { | |
27998 newdata.push({ | |
27999 data: [[1, combined]], | |
28000 color: color, | |
28001 label: options.series.pie.combine.label, | |
28002 angle: combined * Math.PI * 2 / total, | |
28003 percent: combined / (total / 100) | |
28004 }); | |
28005 } | |
28006 | |
28007 return newdata; | |
28008 } | |
28009 | |
28010 function draw(plot, newCtx) { | |
28011 | |
28012 if (!target) { | |
28013 return; // if no series were passed | |
28014 } | |
28015 | |
28016 var canvasWidth = plot.getPlaceholder().width(), | |
28017 canvasHeight = plot.getPlaceholder().height(), | |
28018 legendWidth = target.children().filter(".legend").children().width() || 0; | |
28019 | |
28020 ctx = newCtx; | |
28021 | |
28022 // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE! | |
28023 | |
28024 // When combining smaller slices into an 'other' slice, we need to | |
28025 // add a new series. Since Flot gives plugins no way to modify the | |
28026 // list of series, the pie plugin uses a hack where the first call | |
28027 // to processDatapoints results in a call to setData with the new | |
28028 // list of series, then subsequent processDatapoints do nothing. | |
28029 | |
28030 // The plugin-global 'processed' flag is used to control this hack; | |
28031 // it starts out false, and is set to true after the first call to | |
28032 // processDatapoints. | |
28033 | |
28034 // Unfortunately this turns future setData calls into no-ops; they | |
28035 // call processDatapoints, the flag is true, and nothing happens. | |
28036 | |
28037 // To fix this we'll set the flag back to false here in draw, when | |
28038 // all series have been processed, so the next sequence of calls to | |
28039 // processDatapoints once again starts out with a slice-combine. | |
28040 // This is really a hack; in 0.9 we need to give plugins a proper | |
28041 // way to modify series before any processing begins. | |
28042 | |
28043 processed = false; | |
28044 | |
28045 // calculate maximum radius and center point | |
28046 | |
28047 maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2; | |
28048 centerTop = canvasHeight / 2 + options.series.pie.offset.top; | |
28049 centerLeft = canvasWidth / 2; | |
28050 | |
28051 if (options.series.pie.offset.left == "auto") { | |
28052 if (options.legend.position.match("w")) { | |
28053 centerLeft += legendWidth / 2; | |
28054 } else { | |
28055 centerLeft -= legendWidth / 2; | |
28056 } | |
28057 if (centerLeft < maxRadius) { | |
28058 centerLeft = maxRadius; | |
28059 } else if (centerLeft > canvasWidth - maxRadius) { | |
28060 centerLeft = canvasWidth - maxRadius; | |
28061 } | |
28062 } else { | |
28063 centerLeft += options.series.pie.offset.left; | |
28064 } | |
28065 | |
28066 var slices = plot.getData(), | |
28067 attempts = 0; | |
28068 | |
28069 // Keep shrinking the pie's radius until drawPie returns true, | |
28070 // indicating that all the labels fit, or we try too many times. | |
28071 | |
28072 do { | |
28073 if (attempts > 0) { | |
28074 maxRadius *= REDRAW_SHRINK; | |
28075 } | |
28076 attempts += 1; | |
28077 clear(); | |
28078 if (options.series.pie.tilt <= 0.8) { | |
28079 drawShadow(); | |
28080 } | |
28081 } while (!drawPie() && attempts < REDRAW_ATTEMPTS) | |
28082 | |
28083 if (attempts >= REDRAW_ATTEMPTS) { | |
28084 clear(); | |
28085 target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>"); | |
28086 } | |
28087 | |
28088 if (plot.setSeries && plot.insertLegend) { | |
28089 plot.setSeries(slices); | |
28090 plot.insertLegend(); | |
28091 } | |
28092 | |
28093 // we're actually done at this point, just defining internal functions at this point | |
28094 | |
28095 function clear() { | |
28096 ctx.clearRect(0, 0, canvasWidth, canvasHeight); | |
28097 target.children().filter(".pieLabel, .pieLabelBackground").remove(); | |
28098 } | |
28099 | |
28100 function drawShadow() { | |
28101 | |
28102 var shadowLeft = options.series.pie.shadow.left; | |
28103 var shadowTop = options.series.pie.shadow.top; | |
28104 var edge = 10; | |
28105 var alpha = options.series.pie.shadow.alpha; | |
28106 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; | |
28107 | |
28108 if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) { | |
28109 return; // shadow would be outside canvas, so don't draw it | |
28110 } | |
28111 | |
28112 ctx.save(); | |
28113 ctx.translate(shadowLeft,shadowTop); | |
28114 ctx.globalAlpha = alpha; | |
28115 ctx.fillStyle = "#000"; | |
28116 | |
28117 // center and rotate to starting position | |
28118 | |
28119 ctx.translate(centerLeft,centerTop); | |
28120 ctx.scale(1, options.series.pie.tilt); | |
28121 | |
28122 //radius -= edge; | |
28123 | |
28124 for (var i = 1; i <= edge; i++) { | |
28125 ctx.beginPath(); | |
28126 ctx.arc(0, 0, radius, 0, Math.PI * 2, false); | |
28127 ctx.fill(); | |
28128 radius -= i; | |
28129 } | |
28130 | |
28131 ctx.restore(); | |
28132 } | |
28133 | |
28134 function drawPie() { | |
28135 | |
28136 var startAngle = Math.PI * options.series.pie.startAngle; | |
28137 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; | |
28138 | |
28139 // center and rotate to starting position | |
28140 | |
28141 ctx.save(); | |
28142 ctx.translate(centerLeft,centerTop); | |
28143 ctx.scale(1, options.series.pie.tilt); | |
28144 //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera | |
28145 | |
28146 // draw slices | |
28147 | |
28148 ctx.save(); | |
28149 var currentAngle = startAngle; | |
28150 for (var i = 0; i < slices.length; ++i) { | |
28151 slices[i].startAngle = currentAngle; | |
28152 drawSlice(slices[i].angle, slices[i].color, true); | |
28153 } | |
28154 ctx.restore(); | |
28155 | |
28156 // draw slice outlines | |
28157 | |
28158 if (options.series.pie.stroke.width > 0) { | |
28159 ctx.save(); | |
28160 ctx.lineWidth = options.series.pie.stroke.width; | |
28161 currentAngle = startAngle; | |
28162 for (var i = 0; i < slices.length; ++i) { | |
28163 drawSlice(slices[i].angle, options.series.pie.stroke.color, false); | |
28164 } | |
28165 ctx.restore(); | |
28166 } | |
28167 | |
28168 // draw donut hole | |
28169 | |
28170 drawDonutHole(ctx); | |
28171 | |
28172 ctx.restore(); | |
28173 | |
28174 // Draw the labels, returning true if they fit within the plot | |
28175 | |
28176 if (options.series.pie.label.show) { | |
28177 return drawLabels(); | |
28178 } else return true; | |
28179 | |
28180 function drawSlice(angle, color, fill) { | |
28181 | |
28182 if (angle <= 0 || isNaN(angle)) { | |
28183 return; | |
28184 } | |
28185 | |
28186 if (fill) { | |
28187 ctx.fillStyle = color; | |
28188 } else { | |
28189 ctx.strokeStyle = color; | |
28190 ctx.lineJoin = "round"; | |
28191 } | |
28192 | |
28193 ctx.beginPath(); | |
28194 if (Math.abs(angle - Math.PI * 2) > 0.000000001) { | |
28195 ctx.moveTo(0, 0); // Center of the pie | |
28196 } | |
28197 | |
28198 //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera | |
28199 ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false); | |
28200 ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false); | |
28201 ctx.closePath(); | |
28202 //ctx.rotate(angle); // This doesn't work properly in Opera | |
28203 currentAngle += angle; | |
28204 | |
28205 if (fill) { | |
28206 ctx.fill(); | |
28207 } else { | |
28208 ctx.stroke(); | |
28209 } | |
28210 } | |
28211 | |
28212 function drawLabels() { | |
28213 | |
28214 var currentAngle = startAngle; | |
28215 var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius; | |
28216 | |
28217 for (var i = 0; i < slices.length; ++i) { | |
28218 if (slices[i].percent >= options.series.pie.label.threshold * 100) { | |
28219 if (!drawLabel(slices[i], currentAngle, i)) { | |
28220 return false; | |
28221 } | |
28222 } | |
28223 currentAngle += slices[i].angle; | |
28224 } | |
28225 | |
28226 return true; | |
28227 | |
28228 function drawLabel(slice, startAngle, index) { | |
28229 | |
28230 if (slice.data[0][1] == 0) { | |
28231 return true; | |
28232 } | |
28233 | |
28234 // format label text | |
28235 | |
28236 var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter; | |
28237 | |
28238 if (lf) { | |
28239 text = lf(slice.label, slice); | |
28240 } else { | |
28241 text = slice.label; | |
28242 } | |
28243 | |
28244 if (plf) { | |
28245 text = plf(text, slice); | |
28246 } | |
28247 | |
28248 var halfAngle = ((startAngle + slice.angle) + startAngle) / 2; | |
28249 var x = centerLeft + Math.round(Math.cos(halfAngle) * radius); | |
28250 var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt; | |
28251 | |
28252 var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>"; | |
28253 target.append(html); | |
28254 | |
28255 var label = target.children("#pieLabel" + index); | |
28256 var labelTop = (y - label.height() / 2); | |
28257 var labelLeft = (x - label.width() / 2); | |
28258 | |
28259 label.css("top", labelTop); | |
28260 label.css("left", labelLeft); | |
28261 | |
28262 // check to make sure that the label is not outside the canvas | |
28263 | |
28264 if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) { | |
28265 return false; | |
28266 } | |
28267 | |
28268 if (options.series.pie.label.background.opacity != 0) { | |
28269 | |
28270 // put in the transparent background separately to avoid blended labels and label boxes | |
28271 | |
28272 var c = options.series.pie.label.background.color; | |
28273 | |
28274 if (c == null) { | |
28275 c = slice.color; | |
28276 } | |
28277 | |
28278 var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;"; | |
28279 $("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>") | |
28280 .css("opacity", options.series.pie.label.background.opacity) | |
28281 .insertBefore(label); | |
28282 } | |
28283 | |
28284 return true; | |
28285 } // end individual label function | |
28286 } // end drawLabels function | |
28287 } // end drawPie function | |
28288 } // end draw function | |
28289 | |
28290 // Placed here because it needs to be accessed from multiple locations | |
28291 | |
28292 function drawDonutHole(layer) { | |
28293 if (options.series.pie.innerRadius > 0) { | |
28294 | |
28295 // subtract the center | |
28296 | |
28297 layer.save(); | |
28298 var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; | |
28299 layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color | |
28300 layer.beginPath(); | |
28301 layer.fillStyle = options.series.pie.stroke.color; | |
28302 layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); | |
28303 layer.fill(); | |
28304 layer.closePath(); | |
28305 layer.restore(); | |
28306 | |
28307 // add inner stroke | |
28308 | |
28309 layer.save(); | |
28310 layer.beginPath(); | |
28311 layer.strokeStyle = options.series.pie.stroke.color; | |
28312 layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); | |
28313 layer.stroke(); | |
28314 layer.closePath(); | |
28315 layer.restore(); | |
28316 | |
28317 // TODO: add extra shadow inside hole (with a mask) if the pie is tilted. | |
28318 } | |
28319 } | |
28320 | |
28321 //-- Additional Interactive related functions -- | |
28322 | |
28323 function isPointInPoly(poly, pt) { | |
28324 for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) | |
28325 ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1])) | |
28326 && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) | |
28327 && (c = !c); | |
28328 return c; | |
28329 } | |
28330 | |
28331 function findNearbySlice(mouseX, mouseY) { | |
28332 | |
28333 var slices = plot.getData(), | |
28334 options = plot.getOptions(), | |
28335 radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius, | |
28336 x, y; | |
28337 | |
28338 for (var i = 0; i < slices.length; ++i) { | |
28339 | |
28340 var s = slices[i]; | |
28341 | |
28342 if (s.pie.show) { | |
28343 | |
28344 ctx.save(); | |
28345 ctx.beginPath(); | |
28346 ctx.moveTo(0, 0); // Center of the pie | |
28347 //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here. | |
28348 ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false); | |
28349 ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false); | |
28350 ctx.closePath(); | |
28351 x = mouseX - centerLeft; | |
28352 y = mouseY - centerTop; | |
28353 | |
28354 if (ctx.isPointInPath) { | |
28355 if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) { | |
28356 ctx.restore(); | |
28357 return { | |
28358 datapoint: [s.percent, s.data], | |
28359 dataIndex: 0, | |
28360 series: s, | |
28361 seriesIndex: i | |
28362 }; | |
28363 } | |
28364 } else { | |
28365 | |
28366 // excanvas for IE doesn;t support isPointInPath, this is a workaround. | |
28367 | |
28368 var p1X = radius * Math.cos(s.startAngle), | |
28369 p1Y = radius * Math.sin(s.startAngle), | |
28370 p2X = radius * Math.cos(s.startAngle + s.angle / 4), | |
28371 p2Y = radius * Math.sin(s.startAngle + s.angle / 4), | |
28372 p3X = radius * Math.cos(s.startAngle + s.angle / 2), | |
28373 p3Y = radius * Math.sin(s.startAngle + s.angle / 2), | |
28374 p4X = radius * Math.cos(s.startAngle + s.angle / 1.5), | |
28375 p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5), | |
28376 p5X = radius * Math.cos(s.startAngle + s.angle), | |
28377 p5Y = radius * Math.sin(s.startAngle + s.angle), | |
28378 arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]], | |
28379 arrPoint = [x, y]; | |
28380 | |
28381 // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? | |
28382 | |
28383 if (isPointInPoly(arrPoly, arrPoint)) { | |
28384 ctx.restore(); | |
28385 return { | |
28386 datapoint: [s.percent, s.data], | |
28387 dataIndex: 0, | |
28388 series: s, | |
28389 seriesIndex: i | |
28390 }; | |
28391 } | |
28392 } | |
28393 | |
28394 ctx.restore(); | |
28395 } | |
28396 } | |
28397 | |
28398 return null; | |
28399 } | |
28400 | |
28401 function onMouseMove(e) { | |
28402 triggerClickHoverEvent("plothover", e); | |
28403 } | |
28404 | |
28405 function onClick(e) { | |
28406 triggerClickHoverEvent("plotclick", e); | |
28407 } | |
28408 | |
28409 // trigger click or hover event (they send the same parameters so we share their code) | |
28410 | |
28411 function triggerClickHoverEvent(eventname, e) { | |
28412 | |
28413 var offset = plot.offset(); | |
28414 var canvasX = parseInt(e.pageX - offset.left); | |
28415 var canvasY = parseInt(e.pageY - offset.top); | |
28416 var item = findNearbySlice(canvasX, canvasY); | |
28417 | |
28418 if (options.grid.autoHighlight) { | |
28419 | |
28420 // clear auto-highlights | |
28421 | |
28422 for (var i = 0; i < highlights.length; ++i) { | |
28423 var h = highlights[i]; | |
28424 if (h.auto == eventname && !(item && h.series == item.series)) { | |
28425 unhighlight(h.series); | |
28426 } | |
28427 } | |
28428 } | |
28429 | |
28430 // highlight the slice | |
28431 | |
28432 if (item) { | |
28433 highlight(item.series, eventname); | |
28434 } | |
28435 | |
28436 // trigger any hover bind events | |
28437 | |
28438 var pos = { pageX: e.pageX, pageY: e.pageY }; | |
28439 target.trigger(eventname, [pos, item]); | |
28440 } | |
28441 | |
28442 function highlight(s, auto) { | |
28443 //if (typeof s == "number") { | |
28444 // s = series[s]; | |
28445 //} | |
28446 | |
28447 var i = indexOfHighlight(s); | |
28448 | |
28449 if (i == -1) { | |
28450 highlights.push({ series: s, auto: auto }); | |
28451 plot.triggerRedrawOverlay(); | |
28452 } else if (!auto) { | |
28453 highlights[i].auto = false; | |
28454 } | |
28455 } | |
28456 | |
28457 function unhighlight(s) { | |
28458 if (s == null) { | |
28459 highlights = []; | |
28460 plot.triggerRedrawOverlay(); | |
28461 } | |
28462 | |
28463 //if (typeof s == "number") { | |
28464 // s = series[s]; | |
28465 //} | |
28466 | |
28467 var i = indexOfHighlight(s); | |
28468 | |
28469 if (i != -1) { | |
28470 highlights.splice(i, 1); | |
28471 plot.triggerRedrawOverlay(); | |
28472 } | |
28473 } | |
28474 | |
28475 function indexOfHighlight(s) { | |
28476 for (var i = 0; i < highlights.length; ++i) { | |
28477 var h = highlights[i]; | |
28478 if (h.series == s) | |
28479 return i; | |
28480 } | |
28481 return -1; | |
28482 } | |
28483 | |
28484 function drawOverlay(plot, octx) { | |
28485 | |
28486 var options = plot.getOptions(); | |
28487 | |
28488 var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; | |
28489 | |
28490 octx.save(); | |
28491 octx.translate(centerLeft, centerTop); | |
28492 octx.scale(1, options.series.pie.tilt); | |
28493 | |
28494 for (var i = 0; i < highlights.length; ++i) { | |
28495 drawHighlight(highlights[i].series); | |
28496 } | |
28497 | |
28498 drawDonutHole(octx); | |
28499 | |
28500 octx.restore(); | |
28501 | |
28502 function drawHighlight(series) { | |
28503 | |
28504 if (series.angle <= 0 || isNaN(series.angle)) { | |
28505 return; | |
28506 } | |
28507 | |
28508 //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString(); | |
28509 octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor | |
28510 octx.beginPath(); | |
28511 if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) { | |
28512 octx.moveTo(0, 0); // Center of the pie | |
28513 } | |
28514 octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false); | |
28515 octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false); | |
28516 octx.closePath(); | |
28517 octx.fill(); | |
28518 } | |
28519 } | |
28520 } // end init (plugin body) | |
28521 | |
28522 // define pie specific options and their default values | |
28523 | |
28524 var options = { | |
28525 series: { | |
28526 pie: { | |
28527 show: false, | |
28528 radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value) | |
28529 innerRadius: 0, /* for donut */ | |
28530 startAngle: 3/2, | |
28531 tilt: 1, | |
28532 shadow: { | |
28533 left: 5, // shadow left offset | |
28534 top: 15, // shadow top offset | |
28535 alpha: 0.02 // shadow alpha | |
28536 }, | |
28537 offset: { | |
28538 top: 0, | |
28539 left: "auto" | |
28540 }, | |
28541 stroke: { | |
28542 color: "#fff", | |
28543 width: 1 | |
28544 }, | |
28545 label: { | |
28546 show: "auto", | |
28547 formatter: function(label, slice) { | |
28548 return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>"; | |
28549 }, // formatter function | |
28550 radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value) | |
28551 background: { | |
28552 color: null, | |
28553 opacity: 0 | |
28554 }, | |
28555 threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow) | |
28556 }, | |
28557 combine: { | |
28558 threshold: -1, // percentage at which to combine little slices into one larger slice | |
28559 color: null, // color to give the new slice (auto-generated if null) | |
28560 label: "Other" // label to give the new slice | |
28561 }, | |
28562 highlight: { | |
28563 //color: "#fff", // will add this functionality once parseColor is available | |
28564 opacity: 0.5 | |
28565 } | |
28566 } | |
28567 } | |
28568 }; | |
28569 | |
28570 $.plot.plugins.push({ | |
28571 init: init, | |
28572 options: options, | |
28573 name: "pie", | |
28574 version: "1.1" | |
28575 }); | |
28576 | |
28577 })(jQuery); | |
28578 /* Flot plugin for automatically redrawing plots as the placeholder resizes. | |
28579 | |
28580 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
28581 Licensed under the MIT license. | |
28582 | |
28583 It works by listening for changes on the placeholder div (through the jQuery | |
28584 resize event plugin) - if the size changes, it will redraw the plot. | |
28585 | |
28586 There are no options. If you need to disable the plugin for some plots, you | |
28587 can just fix the size of their placeholders. | |
28588 | |
28589 */ | |
28590 | |
28591 /* Inline dependency: | |
28592 * jQuery resize event - v1.1 - 3/14/2010 | |
28593 * http://benalman.com/projects/jquery-resize-plugin/ | |
28594 * | |
28595 * Copyright (c) 2010 "Cowboy" Ben Alman | |
28596 * Dual licensed under the MIT and GPL licenses. | |
28597 * http://benalman.com/about/license/ | |
28598 */ | |
28599 | |
28600 (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); | |
28601 | |
28602 (function ($) { | |
28603 var options = { }; // no options | |
28604 | |
28605 function init(plot) { | |
28606 function onResize() { | |
28607 var placeholder = plot.getPlaceholder(); | |
28608 | |
28609 // somebody might have hidden us and we can't plot | |
28610 // when we don't have the dimensions | |
28611 if (placeholder.width() == 0 || placeholder.height() == 0) | |
28612 return; | |
28613 | |
28614 plot.resize(); | |
28615 plot.setupGrid(); | |
28616 plot.draw(); | |
28617 } | |
28618 | |
28619 function bindEvents(plot, eventHolder) { | |
28620 plot.getPlaceholder().resize(onResize); | |
28621 } | |
28622 | |
28623 function shutdown(plot, eventHolder) { | |
28624 plot.getPlaceholder().unbind("resize", onResize); | |
28625 } | |
28626 | |
28627 plot.hooks.bindEvents.push(bindEvents); | |
28628 plot.hooks.shutdown.push(shutdown); | |
28629 } | |
28630 | |
28631 $.plot.plugins.push({ | |
28632 init: init, | |
28633 options: options, | |
28634 name: 'resize', | |
28635 version: '1.0' | |
28636 }); | |
28637 })(jQuery); | |
28638 /* Flot plugin for selecting regions of a plot. | |
28639 | |
28640 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
28641 Licensed under the MIT license. | |
28642 | |
28643 The plugin supports these options: | |
28644 | |
28645 selection: { | |
28646 mode: null or "x" or "y" or "xy", | |
28647 color: color, | |
28648 shape: "round" or "miter" or "bevel", | |
28649 minSize: number of pixels | |
28650 } | |
28651 | |
28652 Selection support is enabled by setting the mode to one of "x", "y" or "xy". | |
28653 In "x" mode, the user will only be able to specify the x range, similarly for | |
28654 "y" mode. For "xy", the selection becomes a rectangle where both ranges can be | |
28655 specified. "color" is color of the selection (if you need to change the color | |
28656 later on, you can get to it with plot.getOptions().selection.color). "shape" | |
28657 is the shape of the corners of the selection. | |
28658 | |
28659 "minSize" is the minimum size a selection can be in pixels. This value can | |
28660 be customized to determine the smallest size a selection can be and still | |
28661 have the selection rectangle be displayed. When customizing this value, the | |
28662 fact that it refers to pixels, not axis units must be taken into account. | |
28663 Thus, for example, if there is a bar graph in time mode with BarWidth set to 1 | |
28664 minute, setting "minSize" to 1 will not make the minimum selection size 1 | |
28665 minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent | |
28666 "plotunselected" events from being fired when the user clicks the mouse without | |
28667 dragging. | |
28668 | |
28669 When selection support is enabled, a "plotselected" event will be emitted on | |
28670 the DOM element you passed into the plot function. The event handler gets a | |
28671 parameter with the ranges selected on the axes, like this: | |
28672 | |
28673 placeholder.bind( "plotselected", function( event, ranges ) { | |
28674 alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to) | |
28675 // similar for yaxis - with multiple axes, the extra ones are in | |
28676 // x2axis, x3axis, ... | |
28677 }); | |
28678 | |
28679 The "plotselected" event is only fired when the user has finished making the | |
28680 selection. A "plotselecting" event is fired during the process with the same | |
28681 parameters as the "plotselected" event, in case you want to know what's | |
28682 happening while it's happening, | |
28683 | |
28684 A "plotunselected" event with no arguments is emitted when the user clicks the | |
28685 mouse to remove the selection. As stated above, setting "minSize" to 0 will | |
28686 destroy this behavior. | |
28687 | |
28688 The plugin allso adds the following methods to the plot object: | |
28689 | |
28690 - setSelection( ranges, preventEvent ) | |
28691 | |
28692 Set the selection rectangle. The passed in ranges is on the same form as | |
28693 returned in the "plotselected" event. If the selection mode is "x", you | |
28694 should put in either an xaxis range, if the mode is "y" you need to put in | |
28695 an yaxis range and both xaxis and yaxis if the selection mode is "xy", like | |
28696 this: | |
28697 | |
28698 setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } }); | |
28699 | |
28700 setSelection will trigger the "plotselected" event when called. If you don't | |
28701 want that to happen, e.g. if you're inside a "plotselected" handler, pass | |
28702 true as the second parameter. If you are using multiple axes, you can | |
28703 specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of | |
28704 xaxis, the plugin picks the first one it sees. | |
28705 | |
28706 - clearSelection( preventEvent ) | |
28707 | |
28708 Clear the selection rectangle. Pass in true to avoid getting a | |
28709 "plotunselected" event. | |
28710 | |
28711 - getSelection() | |
28712 | |
28713 Returns the current selection in the same format as the "plotselected" | |
28714 event. If there's currently no selection, the function returns null. | |
28715 | |
28716 */ | |
28717 | |
28718 (function ($) { | |
28719 function init(plot) { | |
28720 var selection = { | |
28721 first: { x: -1, y: -1}, second: { x: -1, y: -1}, | |
28722 show: false, | |
28723 active: false | |
28724 }; | |
28725 | |
28726 // FIXME: The drag handling implemented here should be | |
28727 // abstracted out, there's some similar code from a library in | |
28728 // the navigation plugin, this should be massaged a bit to fit | |
28729 // the Flot cases here better and reused. Doing this would | |
28730 // make this plugin much slimmer. | |
28731 var savedhandlers = {}; | |
28732 | |
28733 var mouseUpHandler = null; | |
28734 | |
28735 function onMouseMove(e) { | |
28736 if (selection.active) { | |
28737 updateSelection(e); | |
28738 | |
28739 plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]); | |
28740 } | |
28741 } | |
28742 | |
28743 function onMouseDown(e) { | |
28744 if (e.which != 1) // only accept left-click | |
28745 return; | |
28746 | |
28747 // cancel out any text selections | |
28748 document.body.focus(); | |
28749 | |
28750 // prevent text selection and drag in old-school browsers | |
28751 if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) { | |
28752 savedhandlers.onselectstart = document.onselectstart; | |
28753 document.onselectstart = function () { return false; }; | |
28754 } | |
28755 if (document.ondrag !== undefined && savedhandlers.ondrag == null) { | |
28756 savedhandlers.ondrag = document.ondrag; | |
28757 document.ondrag = function () { return false; }; | |
28758 } | |
28759 | |
28760 setSelectionPos(selection.first, e); | |
28761 | |
28762 selection.active = true; | |
28763 | |
28764 // this is a bit silly, but we have to use a closure to be | |
28765 // able to whack the same handler again | |
28766 mouseUpHandler = function (e) { onMouseUp(e); }; | |
28767 | |
28768 $(document).one("mouseup", mouseUpHandler); | |
28769 } | |
28770 | |
28771 function onMouseUp(e) { | |
28772 mouseUpHandler = null; | |
28773 | |
28774 // revert drag stuff for old-school browsers | |
28775 if (document.onselectstart !== undefined) | |
28776 document.onselectstart = savedhandlers.onselectstart; | |
28777 if (document.ondrag !== undefined) | |
28778 document.ondrag = savedhandlers.ondrag; | |
28779 | |
28780 // no more dragging | |
28781 selection.active = false; | |
28782 updateSelection(e); | |
28783 | |
28784 if (selectionIsSane()) | |
28785 triggerSelectedEvent(); | |
28786 else { | |
28787 // this counts as a clear | |
28788 plot.getPlaceholder().trigger("plotunselected", [ ]); | |
28789 plot.getPlaceholder().trigger("plotselecting", [ null ]); | |
28790 } | |
28791 | |
28792 return false; | |
28793 } | |
28794 | |
28795 function getSelection() { | |
28796 if (!selectionIsSane()) | |
28797 return null; | |
28798 | |
28799 if (!selection.show) return null; | |
28800 | |
28801 var r = {}, c1 = selection.first, c2 = selection.second; | |
28802 $.each(plot.getAxes(), function (name, axis) { | |
28803 if (axis.used) { | |
28804 var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); | |
28805 r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) }; | |
28806 } | |
28807 }); | |
28808 return r; | |
28809 } | |
28810 | |
28811 function triggerSelectedEvent() { | |
28812 var r = getSelection(); | |
28813 | |
28814 plot.getPlaceholder().trigger("plotselected", [ r ]); | |
28815 | |
28816 // backwards-compat stuff, to be removed in future | |
28817 if (r.xaxis && r.yaxis) | |
28818 plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]); | |
28819 } | |
28820 | |
28821 function clamp(min, value, max) { | |
28822 return value < min ? min: (value > max ? max: value); | |
28823 } | |
28824 | |
28825 function setSelectionPos(pos, e) { | |
28826 var o = plot.getOptions(); | |
28827 var offset = plot.getPlaceholder().offset(); | |
28828 var plotOffset = plot.getPlotOffset(); | |
28829 pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width()); | |
28830 pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height()); | |
28831 | |
28832 if (o.selection.mode == "y") | |
28833 pos.x = pos == selection.first ? 0 : plot.width(); | |
28834 | |
28835 if (o.selection.mode == "x") | |
28836 pos.y = pos == selection.first ? 0 : plot.height(); | |
28837 } | |
28838 | |
28839 function updateSelection(pos) { | |
28840 if (pos.pageX == null) | |
28841 return; | |
28842 | |
28843 setSelectionPos(selection.second, pos); | |
28844 if (selectionIsSane()) { | |
28845 selection.show = true; | |
28846 plot.triggerRedrawOverlay(); | |
28847 } | |
28848 else | |
28849 clearSelection(true); | |
28850 } | |
28851 | |
28852 function clearSelection(preventEvent) { | |
28853 if (selection.show) { | |
28854 selection.show = false; | |
28855 plot.triggerRedrawOverlay(); | |
28856 if (!preventEvent) | |
28857 plot.getPlaceholder().trigger("plotunselected", [ ]); | |
28858 } | |
28859 } | |
28860 | |
28861 // function taken from markings support in Flot | |
28862 function extractRange(ranges, coord) { | |
28863 var axis, from, to, key, axes = plot.getAxes(); | |
28864 | |
28865 for (var k in axes) { | |
28866 axis = axes[k]; | |
28867 if (axis.direction == coord) { | |
28868 key = coord + axis.n + "axis"; | |
28869 if (!ranges[key] && axis.n == 1) | |
28870 key = coord + "axis"; // support x1axis as xaxis | |
28871 if (ranges[key]) { | |
28872 from = ranges[key].from; | |
28873 to = ranges[key].to; | |
28874 break; | |
28875 } | |
28876 } | |
28877 } | |
28878 | |
28879 // backwards-compat stuff - to be removed in future | |
28880 if (!ranges[key]) { | |
28881 axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0]; | |
28882 from = ranges[coord + "1"]; | |
28883 to = ranges[coord + "2"]; | |
28884 } | |
28885 | |
28886 // auto-reverse as an added bonus | |
28887 if (from != null && to != null && from > to) { | |
28888 var tmp = from; | |
28889 from = to; | |
28890 to = tmp; | |
28891 } | |
28892 | |
28893 return { from: from, to: to, axis: axis }; | |
28894 } | |
28895 | |
28896 function setSelection(ranges, preventEvent) { | |
28897 var axis, range, o = plot.getOptions(); | |
28898 | |
28899 if (o.selection.mode == "y") { | |
28900 selection.first.x = 0; | |
28901 selection.second.x = plot.width(); | |
28902 } | |
28903 else { | |
28904 range = extractRange(ranges, "x"); | |
28905 | |
28906 selection.first.x = range.axis.p2c(range.from); | |
28907 selection.second.x = range.axis.p2c(range.to); | |
28908 } | |
28909 | |
28910 if (o.selection.mode == "x") { | |
28911 selection.first.y = 0; | |
28912 selection.second.y = plot.height(); | |
28913 } | |
28914 else { | |
28915 range = extractRange(ranges, "y"); | |
28916 | |
28917 selection.first.y = range.axis.p2c(range.from); | |
28918 selection.second.y = range.axis.p2c(range.to); | |
28919 } | |
28920 | |
28921 selection.show = true; | |
28922 plot.triggerRedrawOverlay(); | |
28923 if (!preventEvent && selectionIsSane()) | |
28924 triggerSelectedEvent(); | |
28925 } | |
28926 | |
28927 function selectionIsSane() { | |
28928 var minSize = plot.getOptions().selection.minSize; | |
28929 return Math.abs(selection.second.x - selection.first.x) >= minSize && | |
28930 Math.abs(selection.second.y - selection.first.y) >= minSize; | |
28931 } | |
28932 | |
28933 plot.clearSelection = clearSelection; | |
28934 plot.setSelection = setSelection; | |
28935 plot.getSelection = getSelection; | |
28936 | |
28937 plot.hooks.bindEvents.push(function(plot, eventHolder) { | |
28938 var o = plot.getOptions(); | |
28939 if (o.selection.mode != null) { | |
28940 eventHolder.mousemove(onMouseMove); | |
28941 eventHolder.mousedown(onMouseDown); | |
28942 } | |
28943 }); | |
28944 | |
28945 | |
28946 plot.hooks.drawOverlay.push(function (plot, ctx) { | |
28947 // draw selection | |
28948 if (selection.show && selectionIsSane()) { | |
28949 var plotOffset = plot.getPlotOffset(); | |
28950 var o = plot.getOptions(); | |
28951 | |
28952 ctx.save(); | |
28953 ctx.translate(plotOffset.left, plotOffset.top); | |
28954 | |
28955 var c = $.color.parse(o.selection.color); | |
28956 | |
28957 ctx.strokeStyle = c.scale('a', 0.8).toString(); | |
28958 ctx.lineWidth = 1; | |
28959 ctx.lineJoin = o.selection.shape; | |
28960 ctx.fillStyle = c.scale('a', 0.4).toString(); | |
28961 | |
28962 var x = Math.min(selection.first.x, selection.second.x) + 0.5, | |
28963 y = Math.min(selection.first.y, selection.second.y) + 0.5, | |
28964 w = Math.abs(selection.second.x - selection.first.x) - 1, | |
28965 h = Math.abs(selection.second.y - selection.first.y) - 1; | |
28966 | |
28967 ctx.fillRect(x, y, w, h); | |
28968 ctx.strokeRect(x, y, w, h); | |
28969 | |
28970 ctx.restore(); | |
28971 } | |
28972 }); | |
28973 | |
28974 plot.hooks.shutdown.push(function (plot, eventHolder) { | |
28975 eventHolder.unbind("mousemove", onMouseMove); | |
28976 eventHolder.unbind("mousedown", onMouseDown); | |
28977 | |
28978 if (mouseUpHandler) | |
28979 $(document).unbind("mouseup", mouseUpHandler); | |
28980 }); | |
28981 | |
28982 } | |
28983 | |
28984 $.plot.plugins.push({ | |
28985 init: init, | |
28986 options: { | |
28987 selection: { | |
28988 mode: null, // one of null, "x", "y" or "xy" | |
28989 color: "#e8cfac", | |
28990 shape: "round", // one of "round", "miter", or "bevel" | |
28991 minSize: 5 // minimum number of pixels | |
28992 } | |
28993 }, | |
28994 name: 'selection', | |
28995 version: '1.1' | |
28996 }); | |
28997 })(jQuery); | |
28998 /* Pretty handling of time axes. | |
28999 | |
29000 Copyright (c) 2007-2013 IOLA and Ole Laursen. | |
29001 Licensed under the MIT license. | |
29002 | |
29003 Set axis.mode to "time" to enable. See the section "Time series data" in | |
29004 API.txt for details. | |
29005 | |
29006 */ | |
29007 | |
29008 (function($) { | |
29009 | |
29010 var options = { | |
29011 xaxis: { | |
29012 timezone: null, // "browser" for local to the client or timezone for timezone-js | |
29013 timeformat: null, // format string to use | |
29014 twelveHourClock: false, // 12 or 24 time in time mode | |
29015 monthNames: null // list of names of months | |
29016 } | |
29017 }; | |
29018 | |
29019 // round to nearby lower multiple of base | |
29020 | |
29021 function floorInBase(n, base) { | |
29022 return base * Math.floor(n / base); | |
29023 } | |
29024 | |
29025 // Returns a string with the date d formatted according to fmt. | |
29026 // A subset of the Open Group's strftime format is supported. | |
29027 | |
29028 function formatDate(d, fmt, monthNames, dayNames) { | |
29029 | |
29030 if (typeof d.strftime == "function") { | |
29031 return d.strftime(fmt); | |
29032 } | |
29033 | |
29034 var leftPad = function(n, pad) { | |
29035 n = "" + n; | |
29036 pad = "" + (pad == null ? "0" : pad); | |
29037 return n.length == 1 ? pad + n : n; | |
29038 }; | |
29039 | |
29040 var r = []; | |
29041 var escape = false; | |
29042 var hours = d.getHours(); | |
29043 var isAM = hours < 12; | |
29044 | |
29045 if (monthNames == null) { | |
29046 monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | |
29047 } | |
29048 | |
29049 if (dayNames == null) { | |
29050 dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; | |
29051 } | |
29052 | |
29053 var hours12; | |
29054 | |
29055 if (hours > 12) { | |
29056 hours12 = hours - 12; | |
29057 } else if (hours == 0) { | |
29058 hours12 = 12; | |
29059 } else { | |
29060 hours12 = hours; | |
29061 } | |
29062 | |
29063 for (var i = 0; i < fmt.length; ++i) { | |
29064 | |
29065 var c = fmt.charAt(i); | |
29066 | |
29067 if (escape) { | |
29068 switch (c) { | |
29069 case 'a': c = "" + dayNames[d.getDay()]; break; | |
29070 case 'b': c = "" + monthNames[d.getMonth()]; break; | |
29071 case 'd': c = leftPad(d.getDate()); break; | |
29072 case 'e': c = leftPad(d.getDate(), " "); break; | |
29073 case 'h': // For back-compat with 0.7; remove in 1.0 | |
29074 case 'H': c = leftPad(hours); break; | |
29075 case 'I': c = leftPad(hours12); break; | |
29076 case 'l': c = leftPad(hours12, " "); break; | |
29077 case 'm': c = leftPad(d.getMonth() + 1); break; | |
29078 case 'M': c = leftPad(d.getMinutes()); break; | |
29079 // quarters not in Open Group's strftime specification | |
29080 case 'q': | |
29081 c = "" + (Math.floor(d.getMonth() / 3) + 1); break; | |
29082 case 'S': c = leftPad(d.getSeconds()); break; | |
29083 case 'y': c = leftPad(d.getFullYear() % 100); break; | |
29084 case 'Y': c = "" + d.getFullYear(); break; | |
29085 case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; | |
29086 case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; | |
29087 case 'w': c = "" + d.getDay(); break; | |
29088 } | |
29089 r.push(c); | |
29090 escape = false; | |
29091 } else { | |
29092 if (c == "%") { | |
29093 escape = true; | |
29094 } else { | |
29095 r.push(c); | |
29096 } | |
29097 } | |
29098 } | |
29099 | |
29100 return r.join(""); | |
29101 } | |
29102 | |
29103 // To have a consistent view of time-based data independent of which time | |
29104 // zone the client happens to be in we need a date-like object independent | |
29105 // of time zones. This is done through a wrapper that only calls the UTC | |
29106 // versions of the accessor methods. | |
29107 | |
29108 function makeUtcWrapper(d) { | |
29109 | |
29110 function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { | |
29111 sourceObj[sourceMethod] = function() { | |
29112 return targetObj[targetMethod].apply(targetObj, arguments); | |
29113 }; | |
29114 }; | |
29115 | |
29116 var utc = { | |
29117 date: d | |
29118 }; | |
29119 | |
29120 // support strftime, if found | |
29121 | |
29122 if (d.strftime != undefined) { | |
29123 addProxyMethod(utc, "strftime", d, "strftime"); | |
29124 } | |
29125 | |
29126 addProxyMethod(utc, "getTime", d, "getTime"); | |
29127 addProxyMethod(utc, "setTime", d, "setTime"); | |
29128 | |
29129 var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; | |
29130 | |
29131 for (var p = 0; p < props.length; p++) { | |
29132 addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); | |
29133 addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); | |
29134 } | |
29135 | |
29136 return utc; | |
29137 }; | |
29138 | |
29139 // select time zone strategy. This returns a date-like object tied to the | |
29140 // desired timezone | |
29141 | |
29142 function dateGenerator(ts, opts) { | |
29143 if (opts.timezone == "browser") { | |
29144 return new Date(ts); | |
29145 } else if (!opts.timezone || opts.timezone == "utc") { | |
29146 return makeUtcWrapper(new Date(ts)); | |
29147 } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { | |
29148 var d = new timezoneJS.Date(); | |
29149 // timezone-js is fickle, so be sure to set the time zone before | |
29150 // setting the time. | |
29151 d.setTimezone(opts.timezone); | |
29152 d.setTime(ts); | |
29153 return d; | |
29154 } else { | |
29155 return makeUtcWrapper(new Date(ts)); | |
29156 } | |
29157 } | |
29158 | |
29159 // map of app. size of time units in milliseconds | |
29160 | |
29161 var timeUnitSize = { | |
29162 "second": 1000, | |
29163 "minute": 60 * 1000, | |
29164 "hour": 60 * 60 * 1000, | |
29165 "day": 24 * 60 * 60 * 1000, | |
29166 "month": 30 * 24 * 60 * 60 * 1000, | |
29167 "quarter": 3 * 30 * 24 * 60 * 60 * 1000, | |
29168 "year": 365.2425 * 24 * 60 * 60 * 1000 | |
29169 }; | |
29170 | |
29171 // the allowed tick sizes, after 1 year we use | |
29172 // an integer algorithm | |
29173 | |
29174 var baseSpec = [ | |
29175 [1, "second"], [2, "second"], [5, "second"], [10, "second"], | |
29176 [30, "second"], | |
29177 [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], | |
29178 [30, "minute"], | |
29179 [1, "hour"], [2, "hour"], [4, "hour"], | |
29180 [8, "hour"], [12, "hour"], | |
29181 [1, "day"], [2, "day"], [3, "day"], | |
29182 [0.25, "month"], [0.5, "month"], [1, "month"], | |
29183 [2, "month"] | |
29184 ]; | |
29185 | |
29186 // we don't know which variant(s) we'll need yet, but generating both is | |
29187 // cheap | |
29188 | |
29189 var specMonths = baseSpec.concat([[3, "month"], [6, "month"], | |
29190 [1, "year"]]); | |
29191 var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], | |
29192 [1, "year"]]); | |
29193 | |
29194 function init(plot) { | |
29195 plot.hooks.processOptions.push(function (plot, options) { | |
29196 $.each(plot.getAxes(), function(axisName, axis) { | |
29197 | |
29198 var opts = axis.options; | |
29199 | |
29200 if (opts.mode == "time") { | |
29201 axis.tickGenerator = function(axis) { | |
29202 | |
29203 var ticks = []; | |
29204 var d = dateGenerator(axis.min, opts); | |
29205 var minSize = 0; | |
29206 | |
29207 // make quarter use a possibility if quarters are | |
29208 // mentioned in either of these options | |
29209 | |
29210 var spec = (opts.tickSize && opts.tickSize[1] === | |
29211 "quarter") || | |
29212 (opts.minTickSize && opts.minTickSize[1] === | |
29213 "quarter") ? specQuarters : specMonths; | |
29214 | |
29215 if (opts.minTickSize != null) { | |
29216 if (typeof opts.tickSize == "number") { | |
29217 minSize = opts.tickSize; | |
29218 } else { | |
29219 minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; | |
29220 } | |
29221 } | |
29222 | |
29223 for (var i = 0; i < spec.length - 1; ++i) { | |
29224 if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] | |
29225 + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 | |
29226 && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { | |
29227 break; | |
29228 } | |
29229 } | |
29230 | |
29231 var size = spec[i][0]; | |
29232 var unit = spec[i][1]; | |
29233 | |
29234 // special-case the possibility of several years | |
29235 | |
29236 if (unit == "year") { | |
29237 | |
29238 // if given a minTickSize in years, just use it, | |
29239 // ensuring that it's an integer | |
29240 | |
29241 if (opts.minTickSize != null && opts.minTickSize[1] == "year") { | |
29242 size = Math.floor(opts.minTickSize[0]); | |
29243 } else { | |
29244 | |
29245 var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); | |
29246 var norm = (axis.delta / timeUnitSize.year) / magn; | |
29247 | |
29248 if (norm < 1.5) { | |
29249 size = 1; | |
29250 } else if (norm < 3) { | |
29251 size = 2; | |
29252 } else if (norm < 7.5) { | |
29253 size = 5; | |
29254 } else { | |
29255 size = 10; | |
29256 } | |
29257 | |
29258 size *= magn; | |
29259 } | |
29260 | |
29261 // minimum size for years is 1 | |
29262 | |
29263 if (size < 1) { | |
29264 size = 1; | |
29265 } | |
29266 } | |
29267 | |
29268 axis.tickSize = opts.tickSize || [size, unit]; | |
29269 var tickSize = axis.tickSize[0]; | |
29270 unit = axis.tickSize[1]; | |
29271 | |
29272 var step = tickSize * timeUnitSize[unit]; | |
29273 | |
29274 if (unit == "second") { | |
29275 d.setSeconds(floorInBase(d.getSeconds(), tickSize)); | |
29276 } else if (unit == "minute") { | |
29277 d.setMinutes(floorInBase(d.getMinutes(), tickSize)); | |
29278 } else if (unit == "hour") { | |
29279 d.setHours(floorInBase(d.getHours(), tickSize)); | |
29280 } else if (unit == "month") { | |
29281 d.setMonth(floorInBase(d.getMonth(), tickSize)); | |
29282 } else if (unit == "quarter") { | |
29283 d.setMonth(3 * floorInBase(d.getMonth() / 3, | |
29284 tickSize)); | |
29285 } else if (unit == "year") { | |
29286 d.setFullYear(floorInBase(d.getFullYear(), tickSize)); | |
29287 } | |
29288 | |
29289 // reset smaller components | |
29290 | |
29291 d.setMilliseconds(0); | |
29292 | |
29293 if (step >= timeUnitSize.minute) { | |
29294 d.setSeconds(0); | |
29295 } | |
29296 if (step >= timeUnitSize.hour) { | |
29297 d.setMinutes(0); | |
29298 } | |
29299 if (step >= timeUnitSize.day) { | |
29300 d.setHours(0); | |
29301 } | |
29302 if (step >= timeUnitSize.day * 4) { | |
29303 d.setDate(1); | |
29304 } | |
29305 if (step >= timeUnitSize.month * 2) { | |
29306 d.setMonth(floorInBase(d.getMonth(), 3)); | |
29307 } | |
29308 if (step >= timeUnitSize.quarter * 2) { | |
29309 d.setMonth(floorInBase(d.getMonth(), 6)); | |
29310 } | |
29311 if (step >= timeUnitSize.year) { | |
29312 d.setMonth(0); | |
29313 } | |
29314 | |
29315 var carry = 0; | |
29316 var v = Number.NaN; | |
29317 var prev; | |
29318 | |
29319 do { | |
29320 | |
29321 prev = v; | |
29322 v = d.getTime(); | |
29323 ticks.push(v); | |
29324 | |
29325 if (unit == "month" || unit == "quarter") { | |
29326 if (tickSize < 1) { | |
29327 | |
29328 // a bit complicated - we'll divide the | |
29329 // month/quarter up but we need to take | |
29330 // care of fractions so we don't end up in | |
29331 // the middle of a day | |
29332 | |
29333 d.setDate(1); | |
29334 var start = d.getTime(); | |
29335 d.setMonth(d.getMonth() + | |
29336 (unit == "quarter" ? 3 : 1)); | |
29337 var end = d.getTime(); | |
29338 d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); | |
29339 carry = d.getHours(); | |
29340 d.setHours(0); | |
29341 } else { | |
29342 d.setMonth(d.getMonth() + | |
29343 tickSize * (unit == "quarter" ? 3 : 1)); | |
29344 } | |
29345 } else if (unit == "year") { | |
29346 d.setFullYear(d.getFullYear() + tickSize); | |
29347 } else { | |
29348 d.setTime(v + step); | |
29349 } | |
29350 } while (v < axis.max && v != prev); | |
29351 | |
29352 return ticks; | |
29353 }; | |
29354 | |
29355 axis.tickFormatter = function (v, axis) { | |
29356 | |
29357 var d = dateGenerator(v, axis.options); | |
29358 | |
29359 // first check global format | |
29360 | |
29361 if (opts.timeformat != null) { | |
29362 return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); | |
29363 } | |
29364 | |
29365 // possibly use quarters if quarters are mentioned in | |
29366 // any of these places | |
29367 | |
29368 var useQuarters = (axis.options.tickSize && | |
29369 axis.options.tickSize[1] == "quarter") || | |
29370 (axis.options.minTickSize && | |
29371 axis.options.minTickSize[1] == "quarter"); | |
29372 | |
29373 var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; | |
29374 var span = axis.max - axis.min; | |
29375 var suffix = (opts.twelveHourClock) ? " %p" : ""; | |
29376 var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; | |
29377 var fmt; | |
29378 | |
29379 if (t < timeUnitSize.minute) { | |
29380 fmt = hourCode + ":%M:%S" + suffix; | |
29381 } else if (t < timeUnitSize.day) { | |
29382 if (span < 2 * timeUnitSize.day) { | |
29383 fmt = hourCode + ":%M" + suffix; | |
29384 } else { | |
29385 fmt = "%b %d " + hourCode + ":%M" + suffix; | |
29386 } | |
29387 } else if (t < timeUnitSize.month) { | |
29388 fmt = "%b %d"; | |
29389 } else if ((useQuarters && t < timeUnitSize.quarter) || | |
29390 (!useQuarters && t < timeUnitSize.year)) { | |
29391 if (span < timeUnitSize.year) { | |
29392 fmt = "%b"; | |
29393 } else { | |
29394 fmt = "%b %Y"; | |
29395 } | |
29396 } else if (useQuarters && t < timeUnitSize.year) { | |
29397 if (span < timeUnitSize.year) { | |
29398 fmt = "Q%q"; | |
29399 } else { | |
29400 fmt = "Q%q %Y"; | |
29401 } | |
29402 } else { | |
29403 fmt = "%Y"; | |
29404 } | |
29405 | |
29406 var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); | |
29407 | |
29408 return rt; | |
29409 }; | |
29410 } | |
29411 }); | |
29412 }); | |
29413 } | |
29414 | |
29415 $.plot.plugins.push({ | |
29416 init: init, | |
29417 options: options, | |
29418 name: 'time', | |
29419 version: '1.0' | |
29420 }); | |
29421 | |
29422 // Time-axis support used to be in Flot core, which exposed the | |
29423 // formatDate function on the plot object. Various plugins depend | |
29424 // on the function, so we need to re-expose it here. | |
29425 | |
29426 $.plot.formatDate = formatDate; | |
29427 | |
29428 })(jQuery); | |
29429 /* | |
29430 * jquery.flot.tooltip | |
29431 * | |
29432 * description: easy-to-use tooltips for Flot charts | |
29433 * version: 0.6.5 | |
29434 * author: Krzysztof Urbas @krzysu [myviews.pl] | |
29435 * website: https://github.com/krzysu/flot.tooltip | |
29436 * | |
29437 * build on 2014-01-23 | |
29438 * released under MIT License, 2012 | |
29439 */ | |
29440 (function ($) { | |
29441 | |
29442 // plugin options, default values | |
29443 var defaultOptions = { | |
29444 tooltip: false, | |
29445 tooltipOpts: { | |
29446 content: "%s | X: %x | Y: %y", | |
29447 // allowed templates are: | |
29448 // %s -> series label, | |
29449 // %x -> X value, | |
29450 // %y -> Y value, | |
29451 // %x.2 -> precision of X value, | |
29452 // %p -> percent | |
29453 xDateFormat: null, | |
29454 yDateFormat: null, | |
29455 monthNames: null, | |
29456 dayNames: null, | |
29457 shifts: { | |
29458 x: 10, | |
29459 y: 20 | |
29460 }, | |
29461 defaultTheme: true, | |
29462 | |
29463 // callbacks | |
29464 onHover: function(flotItem, $tooltipEl) {} | |
29465 } | |
29466 }; | |
29467 | |
29468 // object | |
29469 var FlotTooltip = function(plot) { | |
29470 | |
29471 // variables | |
29472 this.tipPosition = {x: 0, y: 0}; | |
29473 | |
29474 this.init(plot); | |
29475 }; | |
29476 | |
29477 // main plugin function | |
29478 FlotTooltip.prototype.init = function(plot) { | |
29479 | |
29480 var that = this; | |
29481 | |
29482 plot.hooks.bindEvents.push(function (plot, eventHolder) { | |
29483 | |
29484 // get plot options | |
29485 that.plotOptions = plot.getOptions(); | |
29486 | |
29487 // if not enabled return | |
29488 if (that.plotOptions.tooltip === false || typeof that.plotOptions.tooltip === 'undefined') return; | |
29489 | |
29490 // shortcut to access tooltip options | |
29491 that.tooltipOptions = that.plotOptions.tooltipOpts; | |
29492 | |
29493 // create tooltip DOM element | |
29494 var $tip = that.getDomElement(); | |
29495 | |
29496 // bind event | |
29497 $( plot.getPlaceholder() ).bind("plothover", plothover); | |
29498 | |
29499 $(eventHolder).bind('mousemove', mouseMove); | |
29500 }); | |
29501 | |
29502 plot.hooks.shutdown.push(function (plot, eventHolder){ | |
29503 $(plot.getPlaceholder()).unbind("plothover", plothover); | |
29504 $(eventHolder).unbind("mousemove", mouseMove); | |
29505 }); | |
29506 | |
29507 function mouseMove(e){ | |
29508 var pos = {}; | |
29509 pos.x = e.pageX; | |
29510 pos.y = e.pageY; | |
29511 that.updateTooltipPosition(pos); | |
29512 } | |
29513 | |
29514 function plothover(event, pos, item) { | |
29515 var $tip = that.getDomElement(); | |
29516 if (item) { | |
29517 var tipText; | |
29518 | |
29519 // convert tooltip content template to real tipText | |
29520 tipText = that.stringFormat(that.tooltipOptions.content, item); | |
29521 | |
29522 $tip.html( tipText ); | |
29523 that.updateTooltipPosition({ x: pos.pageX, y: pos.pageY }); | |
29524 $tip.css({ | |
29525 left: that.tipPosition.x + that.tooltipOptions.shifts.x, | |
29526 top: that.tipPosition.y + that.tooltipOptions.shifts.y | |
29527 }) | |
29528 .show(); | |
29529 | |
29530 // run callback | |
29531 if(typeof that.tooltipOptions.onHover === 'function') { | |
29532 that.tooltipOptions.onHover(item, $tip); | |
29533 } | |
29534 } | |
29535 else { | |
29536 $tip.hide().html(''); | |
29537 } | |
29538 } | |
29539 }; | |
29540 | |
29541 /** | |
29542 * get or create tooltip DOM element | |
29543 * @return jQuery object | |
29544 */ | |
29545 FlotTooltip.prototype.getDomElement = function() { | |
29546 var $tip; | |
29547 | |
29548 if( $('#flotTip').length > 0 ){ | |
29549 $tip = $('#flotTip'); | |
29550 } | |
29551 else { | |
29552 $tip = $('<div />').attr('id', 'flotTip'); | |
29553 $tip.appendTo('body').hide().css({position: 'absolute'}); | |
29554 | |
29555 if(this.tooltipOptions.defaultTheme) { | |
29556 $tip.css({ | |
29557 'background': '#fff', | |
29558 'z-index': '100', | |
29559 'padding': '0.4em 0.6em', | |
29560 'border-radius': '0.5em', | |
29561 'font-size': '0.8em', | |
29562 'border': '1px solid #111', | |
29563 'display': 'none', | |
29564 'white-space': 'nowrap' | |
29565 }); | |
29566 } | |
29567 } | |
29568 | |
29569 return $tip; | |
29570 }; | |
29571 | |
29572 // as the name says | |
29573 FlotTooltip.prototype.updateTooltipPosition = function(pos) { | |
29574 var totalTipWidth = $("#flotTip").outerWidth() + this.tooltipOptions.shifts.x; | |
29575 var totalTipHeight = $("#flotTip").outerHeight() + this.tooltipOptions.shifts.y; | |
29576 if ((pos.x - $(window).scrollLeft()) > ($(window).innerWidth() - totalTipWidth)) { | |
29577 pos.x -= totalTipWidth; | |
29578 } | |
29579 if ((pos.y - $(window).scrollTop()) > ($(window).innerHeight() - totalTipHeight)) { | |
29580 pos.y -= totalTipHeight; | |
29581 } | |
29582 this.tipPosition.x = pos.x; | |
29583 this.tipPosition.y = pos.y; | |
29584 }; | |
29585 | |
29586 /** | |
29587 * core function, create tooltip content | |
29588 * @param {string} content - template with tooltip content | |
29589 * @param {object} item - Flot item | |
29590 * @return {string} real tooltip content for current item | |
29591 */ | |
29592 FlotTooltip.prototype.stringFormat = function(content, item) { | |
29593 | |
29594 var percentPattern = /%p\.{0,1}(\d{0,})/; | |
29595 var seriesPattern = /%s/; | |
29596 var xPattern = /%x\.{0,1}(\d{0,})/; | |
29597 var yPattern = /%y\.{0,1}(\d{0,})/; | |
29598 var xPatternWithoutPrecision = "%x"; | |
29599 var yPatternWithoutPrecision = "%y"; | |
29600 | |
29601 var x, y; | |
29602 | |
29603 // for threshold plugin we need to read data from different place | |
29604 if (typeof item.series.threshold !== "undefined") { | |
29605 x = item.datapoint[0]; | |
29606 y = item.datapoint[1]; | |
29607 } else { | |
29608 x = item.series.data[item.dataIndex][0]; | |
29609 y = item.series.data[item.dataIndex][1]; | |
29610 } | |
29611 | |
29612 // I think this is only in case of threshold plugin | |
29613 if (item.series.label === null && item.series.originSeries) { | |
29614 item.series.label = item.series.originSeries.label; | |
29615 } | |
29616 | |
29617 // if it is a function callback get the content string | |
29618 if( typeof(content) === 'function' ) { | |
29619 content = content(item.series.label, x, y, item); | |
29620 } | |
29621 | |
29622 // percent match for pie charts | |
29623 if( typeof (item.series.percent) !== 'undefined' ) { | |
29624 content = this.adjustValPrecision(percentPattern, content, item.series.percent); | |
29625 } | |
29626 | |
29627 // series match | |
29628 if( typeof(item.series.label) !== 'undefined' ) { | |
29629 content = content.replace(seriesPattern, item.series.label); | |
29630 } | |
29631 else { | |
29632 //remove %s if label is undefined | |
29633 content = content.replace(seriesPattern, ""); | |
29634 } | |
29635 | |
29636 // time mode axes with custom dateFormat | |
29637 if(this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) { | |
29638 content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat)); | |
29639 } | |
29640 | |
29641 if(this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) { | |
29642 content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat)); | |
29643 } | |
29644 | |
29645 // set precision if defined | |
29646 if(typeof x === 'number') { | |
29647 content = this.adjustValPrecision(xPattern, content, x); | |
29648 } | |
29649 if(typeof y === 'number') { | |
29650 content = this.adjustValPrecision(yPattern, content, y); | |
29651 } | |
29652 | |
29653 // change x from number to given label, if given | |
29654 if(typeof item.series.xaxis.ticks !== 'undefined') { | |
29655 if(item.series.xaxis.ticks.length > item.dataIndex && !this.isTimeMode('xaxis', item)) | |
29656 content = content.replace(xPattern, item.series.xaxis.ticks[item.dataIndex].label); | |
29657 } | |
29658 // if no value customization, use tickFormatter by default | |
29659 if(typeof item.series.xaxis.tickFormatter !== 'undefined') { | |
29660 //escape dollar | |
29661 content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\$/g, '$$')); | |
29662 } | |
29663 if(typeof item.series.yaxis.tickFormatter !== 'undefined') { | |
29664 //escape dollar | |
29665 content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\$/g, '$$')); | |
29666 } | |
29667 | |
29668 return content; | |
29669 }; | |
29670 | |
29671 // helpers just for readability | |
29672 FlotTooltip.prototype.isTimeMode = function(axisName, item) { | |
29673 return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time'); | |
29674 }; | |
29675 | |
29676 FlotTooltip.prototype.isXDateFormat = function(item) { | |
29677 return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null); | |
29678 }; | |
29679 | |
29680 FlotTooltip.prototype.isYDateFormat = function(item) { | |
29681 return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null); | |
29682 }; | |
29683 | |
29684 // | |
29685 FlotTooltip.prototype.timestampToDate = function(tmst, dateFormat) { | |
29686 var theDate = new Date(tmst*1); | |
29687 return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames); | |
29688 }; | |
29689 | |
29690 // | |
29691 FlotTooltip.prototype.adjustValPrecision = function(pattern, content, value) { | |
29692 | |
29693 var precision; | |
29694 var matchResult = content.match(pattern); | |
29695 if( matchResult !== null ) { | |
29696 if(RegExp.$1 !== '') { | |
29697 precision = RegExp.$1; | |
29698 value = value.toFixed(precision); | |
29699 | |
29700 // only replace content if precision exists, in other case use thickformater | |
29701 content = content.replace(pattern, value); | |
29702 } | |
29703 } | |
29704 return content; | |
29705 }; | |
29706 | |
29707 // | |
29708 var init = function(plot) { | |
29709 new FlotTooltip(plot); | |
29710 }; | |
29711 | |
29712 // define Flot plugin | |
29713 $.plot.plugins.push({ | |
29714 init: init, | |
29715 options: defaultOptions, | |
29716 name: 'tooltip', | |
29717 version: '0.6.1' | |
29718 }); | |
29719 | |
29720 })(jQuery); | |
29721 // SIMILE is not used anymore (and messes with jQuery!) so it was removed | |
29722 // TimeplotLoader.load(GeoTemCoLoader.urlPrefix + 'lib/', GeoTemCoLoader.loadScripts); | |
29723 | |
29724 // ..but we still need (and use) the following defines, that where copied from there | |
29725 /* string.js */ | |
29726 String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,""); | |
29727 }; | |
29728 String.prototype.startsWith=function(A){return this.length>=A.length&&this.substr(0,A.length)==A; | |
29729 }; | |
29730 String.prototype.endsWith=function(A){return this.length>=A.length&&this.substr(this.length-A.length)==A; | |
29731 }; | |
29732 String.substitute=function(B,D){var A=""; | |
29733 var F=0; | |
29734 while(F<B.length-1){var C=B.indexOf("%",F); | |
29735 if(C<0||C==B.length-1){break; | |
29736 }else{if(C>F&&B.charAt(C-1)=="\\"){A+=B.substring(F,C-1)+"%"; | |
29737 F=C+1; | |
29738 }else{var E=parseInt(B.charAt(C+1)); | |
29739 if(isNaN(E)||E>=D.length){A+=B.substring(F,C+2); | |
29740 }else{A+=B.substring(F,C)+D[E].toString(); | |
29741 }F=C+2; | |
29742 }}}if(F<B.length){A+=B.substring(F); | |
29743 }return A; | |
29744 }; | |
29745 | |
29746 /* date-time.js */ | |
29747 SimileAjax=new Object(); | |
29748 SimileAjax.DateTime=new Object(); | |
29749 SimileAjax.DateTime.MILLISECOND=0; | |
29750 SimileAjax.DateTime.SECOND=1; | |
29751 SimileAjax.DateTime.MINUTE=2; | |
29752 SimileAjax.DateTime.HOUR=3; | |
29753 SimileAjax.DateTime.DAY=4; | |
29754 SimileAjax.DateTime.WEEK=5; | |
29755 SimileAjax.DateTime.MONTH=6; | |
29756 SimileAjax.DateTime.YEAR=7; | |
29757 SimileAjax.DateTime.DECADE=8; | |
29758 SimileAjax.DateTime.CENTURY=9; | |
29759 SimileAjax.DateTime.MILLENNIUM=10; | |
29760 SimileAjax.DateTime.EPOCH=-1; | |
29761 SimileAjax.DateTime.ERA=-2; | |
29762 | |
29763 SimileAjax.includeCssFile = function(doc, url) { | |
29764 var link = doc.createElement("link"); | |
29765 link.setAttribute("rel", "stylesheet"); | |
29766 link.setAttribute("type", "text/css"); | |
29767 link.setAttribute("href", url); | |
29768 doc.getElementsByTagName("head")[0].appendChild(link); | |
29769 }; | |
29770 /* | |
29771 * Tooltips.js | |
29772 * | |
29773 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
29774 * | |
29775 * This library is free software; you can redistribute it and/or | |
29776 * modify it under the terms of the GNU Lesser General Public | |
29777 * License as published by the Free Software Foundation; either | |
29778 * version 3 of the License, or (at your option) any later version. | |
29779 * | |
29780 * This library is distributed in the hope that it will be useful, | |
29781 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
29782 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
29783 * Lesser General Public License for more details. | |
29784 * | |
29785 * You should have received a copy of the GNU Lesser General Public | |
29786 * License along with this library; if not, write to the Free Software | |
29787 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
29788 * MA 02110-1301 USA | |
29789 */ | |
29790 | |
29791 /** | |
29792 * Tooltips JSON | |
29793 * GeoTemCo tooltips definition file | |
29794 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
29795 * @release 1.0 | |
29796 * @release date: 2012-07-27 | |
29797 * @version date: 2012-07-27 | |
29798 */ | |
29799 var Tooltips = { | |
29800 "en" : { | |
29801 "locationType" : "Location type", | |
29802 "selectLocationType" : "Select location type", | |
29803 "mapType" : "Background map", | |
29804 "selectMapType" : "Select background map", | |
29805 "selectOverlay" : "Select layer for spatial filtering", | |
29806 "overlays" : "Select layer", | |
29807 "mapSelectorTools" : "Map selector tools", | |
29808 "overlaySelector" : "Selection layer", | |
29809 "square" : "Square selection: Mouse down for the center and mouse move to set square bounds", | |
29810 "circle" : "Circle selection: Mouse down for the center and mouse move to set circle radius", | |
29811 "polygon" : "Polygon selection: Click to add vertex and double click to complete the polygon", | |
29812 "country" : "Country selection: Click inside the political borders of a country", | |
29813 "singleEntry" : "Only 1 entry available", | |
29814 "resultsLocation" : "with location information", | |
29815 "home" : "Reset map to initial view", | |
29816 "zoomIn" : "Zoom in", | |
29817 "zoomOut" : "Zoom out", | |
29818 "zoomSlider" : "Zoom slider", | |
29819 "dragSelection" : "Drag&Drop shape", | |
29820 "zoomSelection" : "Zoom into selection", | |
29821 "clearSelection" : "Clear selection", | |
29822 "contemporaryMap" : "Contemporary Map", | |
29823 "activateGeoLocation" : "Show my location", | |
29824 "deactivateGeoLocation" : "Hide my location", | |
29825 "mapOf" : "Map of", | |
29826 "close" : "Close", | |
29827 "genericBinning" : "delaunay", | |
29828 "squareBinning" : "square", | |
29829 "hexagonalBinning" : "hexagonal", | |
29830 "triangularBinning" : "triangular", | |
29831 "noBinning" : "none", | |
29832 "selectBinningType" : "Select aggregation type", | |
29833 "binningType" : "Aggregation type", | |
29834 "binningTooltip" : "Select the aggregation type for the data sources", | |
29835 "results" : "results", | |
29836 "result" : "result", | |
29837 "timeType" : "Time type", | |
29838 "timeUnit" : "Time unit:", | |
29839 "selectTimeType" : "Select time type", | |
29840 "timeAnimation" : "Animation", | |
29841 "resultsTime" : "with time information", | |
29842 "animationDisabled" : "Animation control (disabled)", | |
29843 "animationPlay" : "Animate selected time range", | |
29844 "animationPause" : "Pause animation", | |
29845 "leftHandle" : "Drag&Drop left border", | |
29846 "rightHandle" : "Drag&Drop right border", | |
29847 "dragTimeRange" : "Drag&Drop time range", | |
29848 "connectionsOn" : "Switch on time-dependent connections between map circles", | |
29849 "connectionsOff" : "Switch off time-dependent connections", | |
29850 "timeFeather" : "Adjust time range feather to smoothen map animations", | |
29851 "allResults" : "all", | |
29852 "pageInfo" : "Page PAGE_ID of PAGES_ID", | |
29853 "resultsInfo" : "RESULTS_FROM_ID-RESULTS_TO_ID of RESULTS_ID Results", | |
29854 "otherResults" : "others", | |
29855 "mapAggregation" : "Aggregation", | |
29856 "aggregation" : "Circle aggregation", | |
29857 "noAggregation" : "No circle aggregation", | |
29858 "showBoxTitle" : "Boundingbox", | |
29859 "showBbox" : "Shows given Boundingbox extension", | |
29860 "hideBbox" : "Hides given Boundingbox extension", | |
29861 "spaceHelp" : "A point on the map corresponds to one or more objects from the result list. ", | |
29862 "timeHelp" : "On the timeline are the search results sorted by year. You can choose different time-based categories as basis for the representation.", | |
29863 "selectTablePageItemsHelp" : "Click to select all rows of this page", | |
29864 "deselectTablePageItemsHelp" : "Click to deselect all rows of this page", | |
29865 "selectAllTableItemsHelp" : "Click to select all rows of the table", | |
29866 "deselectAllTableItemsHelp" : "Click to deselect all rows of the table", | |
29867 "filter" : "Filter", | |
29868 "filterSelectedItemsHelp" : "Filter the selected items", | |
29869 "inverseFilterSelectedItemsHelp" : "Apply an inverse filter on the selected items removing them from the views", | |
29870 "undoFilterSelection" : "Undo the last filter / inverse filter", | |
29871 "cancelSelection" : "Discard the current selection (all items appear as deselected)", | |
29872 "showSelectedHelp" : "Show only elements within the selection", | |
29873 "selectByTextHelp" : "Select elements that contain the given text", | |
29874 "showAllElementsHelp" : "Show all elements", | |
29875 "paginationFirsPageHelp" : "Show first page", | |
29876 "paginationPreviousPageHelp" : "Show previous page", | |
29877 "paginationNextPageHelp" : "Show next page", | |
29878 "paginationLastPageHelp" : "Show last page", | |
29879 "sortAZHelp" : "Sort table elements ascending according this column", | |
29880 "sortZAHelp" : "Sort table elements descending according this column", | |
29881 "paginationDropdownHelp" : "Select number of elements per page", | |
29882 "selectTimeUnit" : "Select Time Unit", | |
29883 "valueScale" : "Value Scale", | |
29884 "linearPlot" : "Linear Value Scale", | |
29885 "logarithmicPlot" : "Logarithmic Value Scale", | |
29886 "playButton" : "Animate Selected Range", | |
29887 "pauseButton" : "Pause Animation", | |
29888 "createNewFromSelectedHelp" : "Create new dataset from selected values", | |
29889 "removeDatasetHelp" : "Remove this dataset", | |
29890 "exportDatasetHelp" : "Export this dataset to a KML file", | |
29891 "invertSelectionHelp" : "Invert the current selection" | |
29892 }, | |
29893 "de" : { | |
29894 "locationType" : "Ortsfacette", | |
29895 "selectLocationType" : "Wähle Ortsfacette", | |
29896 "mapType" : "Kartentyp", | |
29897 "selectMapType" : "Wähle Kartentyp", | |
29898 "selectOverlay" : "Kartenauswahl für rämliches filtern", | |
29899 "overlays" : "Wähle layer", | |
29900 "mapSelectorTools" : "Bereichsauswahl", | |
29901 "overlaySelector" : "Selection layer", | |
29902 "square" : "Quadratauswahl: Maus ziehen und loslassen um Mittelpunkt und Seitenlänge des Quadrats zu bestimmen", | |
29903 "circle" : "Kreisauswahl: Maus ziehen und loslassen um Mittelpunkt und Radius des Kreises zu bestimmen", | |
29904 "polygon" : "Polygonauswahl: Mausklick zum Hinzufügen eines Eckpunktes, Doppelklick zum Fertigstellen", | |
29905 "country" : "Landauswahl: Mausklick innerhalb politischer Grenze eines Landes", | |
29906 "singleEntry" : "Nur 1 Eintrag vorhanden", | |
29907 "resultsLocation" : "mit Geoinformation", | |
29908 "home" : "Zurücksetzen zur initialen Sicht", | |
29909 "zoomIn" : "Vergrößern", | |
29910 "zoomOut" : "Verkleinern", | |
29911 "zoomSlider" : "Zoomregler", | |
29912 "dragSelection" : "Verschiebe Auswahl", | |
29913 "zoomSelection" : "Vergrößere Auswahl", | |
29914 "clearSelection" : "Entferne Auswahlbereich", | |
29915 "contemporaryMap" : "Aktuelle Weltkarte", | |
29916 "activateGeoLocation" : "Meinen Standort anzeigen", | |
29917 "deactivateGeoLocation" : "Meinen Standort ausblenden", | |
29918 "mapOf" : "Karte von", | |
29919 "close" : "Schliessen", | |
29920 "genericBinning" : "Generisch", | |
29921 "squareBinning" : "Quadrate", | |
29922 "hexagonalBinning" : "Hexagone", | |
29923 "triangularBinning" : "Dreiecke", | |
29924 "noBinning" : "Keine Bins", | |
29925 "selectBinningType" : "Wähle Binningart", | |
29926 "binningTooltip" : "W&aunl;hle die Binninart für die Datenquellen", | |
29927 "binningType" : "Binningart", | |
29928 "results" : "Resultate", | |
29929 "result" : "Resultat", | |
29930 "timeType" : "Zeitfacette", | |
29931 "timeUnit" : "Zeiteinheit", | |
29932 "selectTimeType" : "Wähle Zeitfacette", | |
29933 "timeAnimation" : "Animation", | |
29934 "resultsTime" : "mit Zeitinformation", | |
29935 "animationDisabled" : "Animationswerkzeug (deaktiviert)", | |
29936 "animationPlay" : "Animiere ausgewählten Zeitbereich", | |
29937 "animationPause" : "Animation anhalten", | |
29938 "leftHandle" : "Verschiebe linke Grenze", | |
29939 "rightHandle" : "Verschiebe rechte Grenze", | |
29940 "dragTimeRange" : "Verschiebe Zeitbereich", | |
29941 "connectionsOn" : "Aktiviere zeitabhängige Verbindungen zwischen Kreisen auf der Karte", | |
29942 "connectionsOff" : "Deaktiviere zeitabhängige Verbindungen", | |
29943 "timeFeather" : "Verändere Zeitbereichsübergänge zum Glätten der Animation", | |
29944 "pageInfo" : "Seite PAGE_ID von PAGES_ID", | |
29945 "resultsInfo" : "RESULTS_FROM_ID-RESULTS_TO_ID von RESULTS_ID Ergebnissen", | |
29946 "allResults" : "alle", | |
29947 "otherResults" : "sonstige", | |
29948 "mapAggregation" : "Aggregation", | |
29949 "aggregation" : "Kreise aggregiert", | |
29950 "noAggregation" : "Kreise nicht aggregiert", | |
29951 "showBbox" : "Geografische Ausdehnung anzeigen", | |
29952 "hideBbox" : "Geografische Ausdehnung ausblenden", | |
29953 "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 ...", | |
29954 "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 ...", | |
29955 "selectTablePageItemsHelp" : "Click to select all rows of this page", | |
29956 "deselectTablePageItemsHelp" : "Click to deselect all rows of this page", | |
29957 "selectAllTableItemsHelp" : "Click to select all rows of the table", | |
29958 "deselectAllTableItemsHelp" : "Click to deselect all rows of the table", | |
29959 "filter" : "Filter", | |
29960 "filterSelectedItemsHelp" : "Filter the selected items", | |
29961 "inverseFilterSelectedItemsHelp" : "Apply an inverse filter on the selected items removing them from the views", | |
29962 "undoFilterSelection" : "Undo the last filter / inverse filter", | |
29963 "cancelSelection" : "Discard the current selection (all items appear as deselected)", | |
29964 "showSelectedHelp" : "Show only elements within the selection", | |
29965 "selectByTextHelp" : "Select elements that contain the given text", | |
29966 "showAllElementsHelp" : "Show all elements", | |
29967 "paginationFirsPageHelp" : "Show first page", | |
29968 "paginationPreviousPageHelp" : "Show previous page", | |
29969 "paginationNextPageHelp" : "Show next page", | |
29970 "paginationLastPageHelp" : "Show last page", | |
29971 "sortAZHelp" : "Sort table elements ascending according this column", | |
29972 "sortZAHelp" : "Sort table elements descending according this column", | |
29973 "paginationDropdownHelp" : "Select number of elements per page", | |
29974 "selectTimeUnit" : "Wähle Zeitinervalle", | |
29975 "valueScale" : "Value Scale", | |
29976 "linearPlot" : "Linear Value Scale", | |
29977 "logarithmicPlot" : "Logarithmic Value Scale", | |
29978 "playButton" : "Animate Selected Range", | |
29979 "pauseButton" : "Pause Animation", | |
29980 "createNewFromSelectedHelp" : "Erstelle neuen Datensatz aus den selektierten Einträgen", | |
29981 "removeDatasetHelp" : "Diesen Datensatz entfernen", | |
29982 "exportDatasetHelp" : "Diesen Datensatz in KML Datei exportieren", | |
29983 "invertSelectionHelp" : "Jetzige Selektion umkehren" | |
29984 } | |
29985 } | |
29986 /* | |
29987 * GeoTemConfig.js | |
29988 * | |
29989 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
29990 * | |
29991 * This library is free software; you can redistribute it and/or | |
29992 * modify it under the terms of the GNU Lesser General Public | |
29993 * License as published by the Free Software Foundation; either | |
29994 * version 3 of the License, or (at your option) any later version. | |
29995 * | |
29996 * This library is distributed in the hope that it will be useful, | |
29997 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
29998 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
29999 * Lesser General Public License for more details. | |
30000 * | |
30001 * You should have received a copy of the GNU Lesser General Public | |
30002 * License along with this library; if not, write to the Free Software | |
30003 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
30004 * MA 02110-1301 USA | |
30005 */ | |
30006 | |
30007 /** | |
30008 * @class GeoTemConfig | |
30009 * Global GeoTemCo Configuration File | |
30010 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
30011 * @release 1.0 | |
30012 * @release date: 2012-07-27 | |
30013 * @version date: 2012-07-27 | |
30014 */ | |
30015 | |
30016 | |
30017 // credits: user76888, The Digital Gabeg (http://stackoverflow.com/questions/1539367) | |
30018 $.fn.cleanWhitespace = function() { | |
30019 textNodes = this.contents().filter( function() { | |
30020 return (this.nodeType == 3 && !/\S/.test(this.nodeValue)); | |
30021 }).remove(); | |
30022 return this; | |
30023 }; | |
30024 | |
30025 GeoTemConfig = { | |
30026 | |
30027 incompleteData : true, // show/hide data with either temporal or spatial metadata | |
30028 inverseFilter : true, // if inverse filtering is offered | |
30029 mouseWheelZoom : true, // enable/disable zoom with mouse wheel on map & timeplot | |
30030 language : 'en', // default language of GeoTemCo | |
30031 allowFilter : true, // if filtering should be allowed | |
30032 highlightEvents : true, // if updates after highlight events | |
30033 selectionEvents : true, // if updates after selection events | |
30034 tableExportDataset : true, // export dataset to KML | |
30035 allowCustomColoring : false, // if DataObjects can have an own color (useful for weighted coloring) | |
30036 loadColorFromDataset : false, // if DataObject color should be loaded automatically (from column "color") | |
30037 //colors for several datasets; rgb1 will be used for selected objects, rgb0 for unselected | |
30038 colors : [{ | |
30039 r1 : 255, | |
30040 g1 : 101, | |
30041 b1 : 0, | |
30042 r0 : 253, | |
30043 g0 : 229, | |
30044 b0 : 205 | |
30045 }, { | |
30046 r1 : 144, | |
30047 g1 : 26, | |
30048 b1 : 255, | |
30049 r0 : 230, | |
30050 g0 : 225, | |
30051 b0 : 255 | |
30052 }, { | |
30053 r1 : 0, | |
30054 g1 : 217, | |
30055 b1 : 0, | |
30056 r0 : 213, | |
30057 g0 : 255, | |
30058 b0 : 213 | |
30059 }, { | |
30060 r1 : 240, | |
30061 g1 : 220, | |
30062 b1 : 0, | |
30063 r0 : 247, | |
30064 g0 : 244, | |
30065 b0 : 197 | |
30066 }] | |
30067 | |
30068 } | |
30069 | |
30070 GeoTemConfig.ie = false; | |
30071 GeoTemConfig.ie8 = false; | |
30072 | |
30073 GeoTemConfig.independentMapId = 0; | |
30074 GeoTemConfig.independentTimeId = 0; | |
30075 | |
30076 if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { | |
30077 GeoTemConfig.ie = true; | |
30078 var ieversion = new Number(RegExp.$1); | |
30079 if (ieversion == 8) { | |
30080 GeoTemConfig.ie8 = true; | |
30081 } | |
30082 } | |
30083 | |
30084 GeoTemConfig.getIndependentId = function(target){ | |
30085 if( target == 'map' ){ | |
30086 return ++GeoTemConfig.independentMapId; | |
30087 } | |
30088 if( target == 'time' ){ | |
30089 return ++GeoTemConfig.independentTimeId; | |
30090 } | |
30091 return 0; | |
30092 }; | |
30093 | |
30094 GeoTemConfig.setHexColor = function(hex,index,fill){ | |
30095 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); | |
30096 if( fill ){ | |
30097 GeoTemConfig.colors[index].r0 = parseInt(result[1], 16); | |
30098 GeoTemConfig.colors[index].g0 = parseInt(result[2], 16); | |
30099 GeoTemConfig.colors[index].b0 = parseInt(result[3], 16); | |
30100 } | |
30101 else { | |
30102 GeoTemConfig.colors[index].r1 = parseInt(result[1], 16); | |
30103 GeoTemConfig.colors[index].g1 = parseInt(result[2], 16); | |
30104 GeoTemConfig.colors[index].b1 = parseInt(result[3], 16); | |
30105 } | |
30106 } | |
30107 | |
30108 GeoTemConfig.setRgbColor = function(r,g,b,index,fill){ | |
30109 if( fill ){ | |
30110 GeoTemConfig.colors[index].r0 = r; | |
30111 GeoTemConfig.colors[index].g0 = g; | |
30112 GeoTemConfig.colors[index].b0 = b; | |
30113 } | |
30114 else { | |
30115 GeoTemConfig.colors[index].r1 = r; | |
30116 GeoTemConfig.colors[index].g1 = g; | |
30117 GeoTemConfig.colors[index].b1 = b; | |
30118 } | |
30119 } | |
30120 | |
30121 GeoTemConfig.configure = function(urlPrefix) { | |
30122 GeoTemConfig.urlPrefix = urlPrefix; | |
30123 GeoTemConfig.path = GeoTemConfig.urlPrefix + "images/"; | |
30124 } | |
30125 | |
30126 GeoTemConfig.applySettings = function(settings) { | |
30127 $.extend(this, settings); | |
30128 }; | |
30129 | |
30130 //Keeps track of how many colors where assigned yet. | |
30131 GeoTemConfig.assignedColorCount = 0; | |
30132 GeoTemConfig.getColor = function(id){ | |
30133 if (typeof GeoTemConfig.datasets[id].color === "undefined"){ | |
30134 var color; | |
30135 | |
30136 while (true){ | |
30137 if( GeoTemConfig.colors.length <= GeoTemConfig.assignedColorCount ){ | |
30138 color = { | |
30139 r1 : Math.floor((Math.random()*255)+1), | |
30140 g1 : Math.floor((Math.random()*255)+1), | |
30141 b1 : Math.floor((Math.random()*255)+1), | |
30142 r0 : 230, | |
30143 g0 : 230, | |
30144 b0 : 230 | |
30145 }; | |
30146 } else | |
30147 color = GeoTemConfig.colors[GeoTemConfig.assignedColorCount]; | |
30148 | |
30149 //make sure that no other dataset has this color | |
30150 //TODO: one could also check that they are not too much alike | |
30151 var found = false; | |
30152 for (var i = 0; i < GeoTemConfig.datasets.length; i++){ | |
30153 var dataset = GeoTemConfig.datasets[i]; | |
30154 | |
30155 if (typeof dataset.color === "undefined") | |
30156 continue; | |
30157 | |
30158 if ( (dataset.color.r1 == color.r1) && | |
30159 (dataset.color.g1 == color.g1) && | |
30160 (dataset.color.b1 == color.b1) ){ | |
30161 found = true; | |
30162 break; | |
30163 } | |
30164 } | |
30165 if (found === true){ | |
30166 if( GeoTemConfig.colors.length <= GeoTemConfig.assignedColorCount ){ | |
30167 //next time skip over this color | |
30168 GeoTemConfig.assignedColorCount++; | |
30169 } | |
30170 continue; | |
30171 } else { | |
30172 GeoTemConfig.colors.push(color); | |
30173 break; | |
30174 } | |
30175 } | |
30176 GeoTemConfig.datasets[id].color = color; | |
30177 | |
30178 GeoTemConfig.assignedColorCount++; | |
30179 } | |
30180 return GeoTemConfig.datasets[id].color; | |
30181 }; | |
30182 | |
30183 GeoTemConfig.getAverageDatasetColor = function(id, objects){ | |
30184 var c = new Object(); | |
30185 var datasetColor = GeoTemConfig.getColor(id); | |
30186 c.r0 = datasetColor.r0; | |
30187 c.g0 = datasetColor.g0; | |
30188 c.b0 = datasetColor.b0; | |
30189 c.r1 = datasetColor.r1; | |
30190 c.g1 = datasetColor.g1; | |
30191 c.b1 = datasetColor.b1; | |
30192 if (!GeoTemConfig.allowCustomColoring) | |
30193 return c; | |
30194 if (objects.length == 0) | |
30195 return c; | |
30196 var avgColor = new Object(); | |
30197 avgColor.r0 = 0; | |
30198 avgColor.g0 = 0; | |
30199 avgColor.b0 = 0; | |
30200 avgColor.r1 = 0; | |
30201 avgColor.g1 = 0; | |
30202 avgColor.b1 = 0; | |
30203 | |
30204 $(objects).each(function(){ | |
30205 if (this.hasColorInformation){ | |
30206 avgColor.r0 += this.color.r0; | |
30207 avgColor.g0 += this.color.g0; | |
30208 avgColor.b0 += this.color.b0; | |
30209 avgColor.r1 += this.color.r1; | |
30210 avgColor.g1 += this.color.g1; | |
30211 avgColor.b1 += this.color.b1; | |
30212 } else { | |
30213 avgColor.r0 += datasetColor.r0; | |
30214 avgColor.g0 += datasetColor.g0; | |
30215 avgColor.b0 += datasetColor.b0; | |
30216 avgColor.r1 += datasetColor.r1; | |
30217 avgColor.g1 += datasetColor.g1; | |
30218 avgColor.b1 += datasetColor.b1; | |
30219 } | |
30220 }); | |
30221 | |
30222 c.r0 = Math.floor(avgColor.r0/objects.length); | |
30223 c.g0 = Math.floor(avgColor.g0/objects.length); | |
30224 c.b0 = Math.floor(avgColor.b0/objects.length); | |
30225 c.r1 = Math.floor(avgColor.r1/objects.length); | |
30226 c.g1 = Math.floor(avgColor.g1/objects.length); | |
30227 c.b1 = Math.floor(avgColor.b1/objects.length); | |
30228 | |
30229 return c; | |
30230 }; | |
30231 | |
30232 GeoTemConfig.getString = function(field) { | |
30233 if ( typeof Tooltips[GeoTemConfig.language] == 'undefined') { | |
30234 GeoTemConfig.language = 'en'; | |
30235 } | |
30236 return Tooltips[GeoTemConfig.language][field]; | |
30237 } | |
30238 /** | |
30239 * returns the actual mouse position | |
30240 * @param {Event} e the mouseevent | |
30241 * @return the top and left position on the screen | |
30242 */ | |
30243 GeoTemConfig.getMousePosition = function(e) { | |
30244 if (!e) { | |
30245 e = window.event; | |
30246 } | |
30247 var body = (window.document.compatMode && window.document.compatMode == "CSS1Compat") ? window.document.documentElement : window.document.body; | |
30248 return { | |
30249 top : e.pageY ? e.pageY : e.clientY, | |
30250 left : e.pageX ? e.pageX : e.clientX | |
30251 }; | |
30252 } | |
30253 /** | |
30254 * returns the json object of the file from the given url | |
30255 * @param {String} url the url of the file to load | |
30256 * @return json object of given file | |
30257 */ | |
30258 GeoTemConfig.getJson = function(url) { | |
30259 var data; | |
30260 $.ajax({ | |
30261 url : url, | |
30262 async : false, | |
30263 dataType : 'json', | |
30264 success : function(json) { | |
30265 data = json; | |
30266 } | |
30267 }); | |
30268 return data; | |
30269 } | |
30270 | |
30271 GeoTemConfig.mergeObjects = function(set1, set2) { | |
30272 var inside = []; | |
30273 var newSet = []; | |
30274 for (var i = 0; i < GeoTemConfig.datasets.length; i++){ | |
30275 inside.push([]); | |
30276 newSet.push([]); | |
30277 } | |
30278 for (var i = 0; i < set1.length; i++) { | |
30279 for (var j = 0; j < set1[i].length; j++) { | |
30280 inside[i][set1[i][j].index] = true; | |
30281 newSet[i].push(set1[i][j]); | |
30282 } | |
30283 } | |
30284 for (var i = 0; i < set2.length; i++) { | |
30285 for (var j = 0; j < set2[i].length; j++) { | |
30286 if (!inside[i][set2[i][j].index]) { | |
30287 newSet[i].push(set2[i][j]); | |
30288 } | |
30289 } | |
30290 } | |
30291 return newSet; | |
30292 }; | |
30293 | |
30294 GeoTemConfig.datasets = []; | |
30295 | |
30296 GeoTemConfig.addDataset = function(newDataset){ | |
30297 GeoTemConfig.datasets.push(newDataset); | |
30298 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
30299 }; | |
30300 | |
30301 GeoTemConfig.addDatasets = function(newDatasets){ | |
30302 $(newDatasets).each(function(){ | |
30303 GeoTemConfig.datasets.push(this); | |
30304 }); | |
30305 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
30306 }; | |
30307 | |
30308 GeoTemConfig.removeDataset = function(index){ | |
30309 GeoTemConfig.datasets.splice(index,1); | |
30310 Publisher.Publish('filterData', GeoTemConfig.datasets, null); | |
30311 }; | |
30312 | |
30313 /** | |
30314 * converts the csv-file into json-format | |
30315 * | |
30316 * @param {String} | |
30317 * text | |
30318 */ | |
30319 GeoTemConfig.convertCsv = function(text){ | |
30320 /* convert here from CSV to JSON */ | |
30321 var json = []; | |
30322 /* define expected csv table headers (first line) */ | |
30323 var expectedHeaders = new Array("Name","Address","Description","Longitude","Latitude","TimeStamp","TimeSpan:begin","TimeSpan:end","weight"); | |
30324 /* convert csv string to array of arrays using ucsv library */ | |
30325 var csvArray = CSV.csvToArray(text); | |
30326 /* get real used table headers from csv file (first line) */ | |
30327 var usedHeaders = csvArray[0]; | |
30328 /* loop outer array, begin with second line */ | |
30329 for (var i = 1; i < csvArray.length; i++) { | |
30330 var innerArray = csvArray[i]; | |
30331 var dataObject = new Object(); | |
30332 var tableContent = new Object(); | |
30333 /* exclude lines with no content */ | |
30334 var hasContent = false; | |
30335 for (var j = 0; j < innerArray.length; j++) { | |
30336 if (typeof innerArray[j] !== "undefined"){ | |
30337 if (typeof innerArray[j] === "string"){ | |
30338 if (innerArray[j].length > 0) | |
30339 hasContent = true; | |
30340 } else { | |
30341 hasContent = true; | |
30342 } | |
30343 } | |
30344 | |
30345 if (hasContent === true) | |
30346 break; | |
30347 } | |
30348 if (hasContent === false) | |
30349 continue; | |
30350 /* loop inner array */ | |
30351 for (var j = 0; j < innerArray.length; j++) { | |
30352 /* Name */ | |
30353 if (usedHeaders[j] == expectedHeaders[0]) { | |
30354 dataObject["name"] = ""+innerArray[j]; | |
30355 tableContent["name"] = ""+innerArray[j]; | |
30356 } | |
30357 /* Address */ | |
30358 else if (usedHeaders[j] == expectedHeaders[1]) { | |
30359 dataObject["place"] = ""+innerArray[j]; | |
30360 tableContent["place"] = ""+innerArray[j]; | |
30361 } | |
30362 /* Description */ | |
30363 else if (usedHeaders[j] == expectedHeaders[2]) { | |
30364 dataObject["description"] = ""+innerArray[j]; | |
30365 tableContent["description"] = ""+innerArray[j]; | |
30366 } | |
30367 /* TimeStamp */ | |
30368 else if (usedHeaders[j] == expectedHeaders[5]) { | |
30369 dataObject["time"] = ""+innerArray[j]; | |
30370 } | |
30371 /* TimeSpan:begin */ | |
30372 else if (usedHeaders[j] == expectedHeaders[6]) { | |
30373 tableContent["TimeSpan:begin"] = ""+innerArray[j]; | |
30374 } | |
30375 /* TimeSpan:end */ | |
30376 else if (usedHeaders[j] == expectedHeaders[7]) { | |
30377 tableContent["TimeSpan:end"] = ""+innerArray[j]; | |
30378 } | |
30379 /* weight */ | |
30380 else if (usedHeaders[j] == expectedHeaders[7]) { | |
30381 dataObject["weight"] = ""+innerArray[j]; | |
30382 } | |
30383 /* Longitude */ | |
30384 else if (usedHeaders[j] == expectedHeaders[3]) { | |
30385 dataObject["lon"] = parseFloat(innerArray[j]); | |
30386 } | |
30387 /* Latitude */ | |
30388 else if (usedHeaders[j] == expectedHeaders[4]) { | |
30389 dataObject["lat"] = parseFloat(innerArray[j]); | |
30390 } | |
30391 else { | |
30392 var header = new String(usedHeaders[j]); | |
30393 //remove leading and trailing Whitespace | |
30394 header = $.trim(header); | |
30395 tableContent[header] = ""+innerArray[j]; | |
30396 } | |
30397 } | |
30398 | |
30399 dataObject["tableContent"] = tableContent; | |
30400 | |
30401 json.push(dataObject); | |
30402 } | |
30403 | |
30404 return json; | |
30405 }; | |
30406 | |
30407 /** | |
30408 * returns the xml dom object of the file from the given url | |
30409 * @param {String} url the url of the file to load | |
30410 * @return xml dom object of given file | |
30411 */ | |
30412 GeoTemConfig.getKml = function(url,asyncFunc) { | |
30413 var data; | |
30414 var async = false; | |
30415 if( asyncFunc ){ | |
30416 async = true; | |
30417 } | |
30418 $.ajax({ | |
30419 url : url, | |
30420 async : async, | |
30421 dataType : 'xml', | |
30422 success : function(xml) { | |
30423 if( asyncFunc ){ | |
30424 asyncFunc(xml); | |
30425 } | |
30426 else { | |
30427 data = xml; | |
30428 } | |
30429 } | |
30430 }); | |
30431 if( !async ){ | |
30432 return data; | |
30433 } | |
30434 } | |
30435 | |
30436 /** | |
30437 * returns an array of all xml dom object of the kmls | |
30438 * found in the zip file from the given url | |
30439 * | |
30440 * can only be used with asyncFunc (because of browser | |
30441 * constraints regarding arraybuffer) | |
30442 * | |
30443 * @param {String} url the url of the file to load | |
30444 * @return xml dom object of given file | |
30445 */ | |
30446 GeoTemConfig.getKmz = function(url,asyncFunc) { | |
30447 var kmlDom = new Array(); | |
30448 | |
30449 var async = true; | |
30450 if( !asyncFunc ){ | |
30451 //if no asyncFunc is given return an empty array | |
30452 return kmlDom; | |
30453 } | |
30454 | |
30455 //use XMLHttpRequest as "arraybuffer" is not | |
30456 //supported in jQuery native $.get | |
30457 var req = new XMLHttpRequest(); | |
30458 req.open("GET",url,async); | |
30459 req.responseType = "arraybuffer"; | |
30460 req.onload = function() { | |
30461 var zip = new JSZip(); | |
30462 zip.load(req.response, {base64:false}); | |
30463 var kmlFiles = zip.file(new RegExp("kml$")); | |
30464 | |
30465 $(kmlFiles).each(function(){ | |
30466 var kml = this; | |
30467 if (kml.data != null) { | |
30468 kmlDom.push($.parseXML(kml.data)); | |
30469 } | |
30470 }); | |
30471 | |
30472 asyncFunc(kmlDom); | |
30473 }; | |
30474 req.send(); | |
30475 }; | |
30476 | |
30477 /** | |
30478 * returns the JSON "object" | |
30479 * from the csv file from the given url | |
30480 * @param {String} url the url of the file to load | |
30481 * @return xml dom object of given file | |
30482 */ | |
30483 GeoTemConfig.getCsv = function(url,asyncFunc) { | |
30484 var async = false; | |
30485 if( asyncFunc ){ | |
30486 async = true; | |
30487 } | |
30488 | |
30489 //use XMLHttpRequest as synchronous behaviour | |
30490 //is not supported in jQuery native $.get | |
30491 var req = new XMLHttpRequest(); | |
30492 req.open("GET",url,async); | |
30493 //can only be set on asynchronous now | |
30494 //req.responseType = "text"; | |
30495 var json; | |
30496 req.onload = function() { | |
30497 json = GeoTemConfig.convertCsv(req.response); | |
30498 if( asyncFunc ) | |
30499 asyncFunc(json); | |
30500 }; | |
30501 req.send(); | |
30502 | |
30503 if( !async ){ | |
30504 return json; | |
30505 } | |
30506 }; | |
30507 | |
30508 /** | |
30509 * returns a Date and a SimileAjax.DateTime granularity value for a given XML time | |
30510 * @param {String} xmlTime the XML time as String | |
30511 * @return JSON object with a Date and a SimileAjax.DateTime granularity | |
30512 */ | |
30513 GeoTemConfig.getTimeData = function(xmlTime) { | |
30514 if (!xmlTime) | |
30515 return; | |
30516 var dateData; | |
30517 try { | |
30518 var bc = false; | |
30519 if (xmlTime.startsWith("-")) { | |
30520 bc = true; | |
30521 xmlTime = xmlTime.substring(1); | |
30522 } | |
30523 var timeSplit = xmlTime.split("T"); | |
30524 var timeData = timeSplit[0].split("-"); | |
30525 for (var i = 0; i < timeData.length; i++) { | |
30526 parseInt(timeData[i]); | |
30527 } | |
30528 if (bc) { | |
30529 timeData[0] = "-" + timeData[0]; | |
30530 } | |
30531 if (timeSplit.length == 1) { | |
30532 dateData = timeData; | |
30533 } else { | |
30534 var dayData; | |
30535 if (timeSplit[1].indexOf("Z") != -1) { | |
30536 dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("Z") - 1).split(":"); | |
30537 } else { | |
30538 dayData = timeSplit[1].substring(0, timeSplit[1].indexOf("+") - 1).split(":"); | |
30539 } | |
30540 for (var i = 0; i < timeData.length; i++) { | |
30541 parseInt(dayData[i]); | |
30542 } | |
30543 dateData = timeData.concat(dayData); | |
30544 } | |
30545 } catch (exception) { | |
30546 return null; | |
30547 } | |
30548 var date, granularity; | |
30549 if (dateData.length == 6) { | |
30550 granularity = SimileAjax.DateTime.SECOND; | |
30551 date = new Date(Date.UTC(dateData[0], dateData[1] - 1, dateData[2], dateData[3], dateData[4], dateData[5])); | |
30552 } else if (dateData.length == 3) { | |
30553 granularity = SimileAjax.DateTime.DAY; | |
30554 date = new Date(Date.UTC(dateData[0], dateData[1] - 1, dateData[2])); | |
30555 } else if (dateData.length == 2) { | |
30556 granularity = SimileAjax.DateTime.MONTH; | |
30557 date = new Date(Date.UTC(dateData[0], dateData[1] - 1, 1)); | |
30558 } else if (dateData.length == 1) { | |
30559 granularity = SimileAjax.DateTime.YEAR; | |
30560 date = new Date(Date.UTC(dateData[0], 0, 1)); | |
30561 } | |
30562 if (timeData[0] && timeData[0] < 100) { | |
30563 date.setFullYear(timeData[0]); | |
30564 } | |
30565 | |
30566 //check data validity; | |
30567 var isValidDate = true; | |
30568 if ( date instanceof Date ) { | |
30569 if ( isNaN( date.getTime() ) ) | |
30570 isValidDate = false; | |
30571 } else | |
30572 isValidDate = false; | |
30573 | |
30574 if (!isValidDate){ | |
30575 if (typeof console !== "undefined") | |
30576 console.error(xmlTime + " is no valid time format"); | |
30577 return null; | |
30578 } | |
30579 | |
30580 return { | |
30581 date : date, | |
30582 granularity : granularity | |
30583 }; | |
30584 } | |
30585 /** | |
30586 * converts a JSON array into an array of data objects | |
30587 * @param {JSON} JSON a JSON array of data items | |
30588 * @return an array of data objects | |
30589 */ | |
30590 GeoTemConfig.loadJson = function(JSON) { | |
30591 var mapTimeObjects = []; | |
30592 var runningIndex = 0; | |
30593 for (var i in JSON ) { | |
30594 try { | |
30595 var item = JSON[i]; | |
30596 var index = item.index || item.id || runningIndex++; | |
30597 var name = item.name || ""; | |
30598 var description = item.description || ""; | |
30599 var tableContent = item.tableContent || []; | |
30600 var locations = []; | |
30601 if (item.location instanceof Array) { | |
30602 for (var j = 0; j < item.location.length; j++) { | |
30603 var place = item.location[j].place || "unknown"; | |
30604 var lon = item.location[j].lon; | |
30605 var lat = item.location[j].lat; | |
30606 if ((typeof lon === "undefined" || typeof lat === "undefined" || isNaN(lon) || isNaN(lat) ) && !GeoTemConfig.incompleteData) { | |
30607 throw "e"; | |
30608 } | |
30609 locations.push({ | |
30610 longitude : lon, | |
30611 latitude : lat, | |
30612 place : place | |
30613 }); | |
30614 } | |
30615 } else { | |
30616 var place = item.place || "unknown"; | |
30617 var lon = item.lon; | |
30618 var lat = item.lat; | |
30619 if ((typeof lon === "undefined" || typeof lat === "undefined" || isNaN(lon) || isNaN(lat) ) && !GeoTemConfig.incompleteData) { | |
30620 throw "e"; | |
30621 } | |
30622 locations.push({ | |
30623 longitude : lon, | |
30624 latitude : lat, | |
30625 place : place | |
30626 }); | |
30627 } | |
30628 var dates = []; | |
30629 if (item.time instanceof Array) { | |
30630 for (var j = 0; j < item.time.length; j++) { | |
30631 var time = GeoTemConfig.getTimeData(item.time[j]); | |
30632 if (time == null && !GeoTemConfig.incompleteData) { | |
30633 throw "e"; | |
30634 } | |
30635 dates.push(time); | |
30636 } | |
30637 } else { | |
30638 var time = GeoTemConfig.getTimeData(item.time); | |
30639 if (time == null && !GeoTemConfig.incompleteData) { | |
30640 throw "e"; | |
30641 } | |
30642 if (time != null) { | |
30643 dates.push(time); | |
30644 } | |
30645 } | |
30646 var weight = item.weight || 1; | |
30647 //per default GeoTemCo uses WGS84 (-90<=lat<=90, -180<=lon<=180) | |
30648 var projection = new OpenLayers.Projection("EPSG:4326"); | |
30649 var mapTimeObject = new DataObject(name, description, locations, dates, weight, tableContent, projection); | |
30650 mapTimeObject.setIndex(index); | |
30651 mapTimeObjects.push(mapTimeObject); | |
30652 } catch(e) { | |
30653 continue; | |
30654 } | |
30655 } | |
30656 | |
30657 if (GeoTemConfig.loadColorFromDataset) | |
30658 GeoTemConfig.loadDataObjectColoring(mapTimeObjects); | |
30659 | |
30660 return mapTimeObjects; | |
30661 } | |
30662 /** | |
30663 * converts a KML dom into an array of data objects | |
30664 * @param {XML dom} kml the XML dom for the KML file | |
30665 * @return an array of data objects | |
30666 */ | |
30667 GeoTemConfig.loadKml = function(kml) { | |
30668 var mapObjects = []; | |
30669 var elements = kml.getElementsByTagName("Placemark"); | |
30670 if (elements.length == 0) { | |
30671 return []; | |
30672 } | |
30673 var index = 0; | |
30674 var descriptionTableHeaders = []; | |
30675 var xmlSerializer = new XMLSerializer(); | |
30676 | |
30677 for (var i = 0; i < elements.length; i++) { | |
30678 var placemark = elements[i]; | |
30679 var name, description, place, granularity, lon, lat, tableContent = [], time = [], location = []; | |
30680 var weight = 1; | |
30681 var timeData = false, mapData = false; | |
30682 | |
30683 try { | |
30684 description = placemark.getElementsByTagName("description")[0].childNodes[0].nodeValue; | |
30685 | |
30686 //cleanWhitespace removes non-sense text-nodes (space, tab) | |
30687 //and is an addition to jquery defined above | |
30688 try { | |
30689 var descriptionDocument = $($.parseXML(description)).cleanWhitespace(); | |
30690 | |
30691 //check whether the description element contains a table | |
30692 //if yes, this data will be loaded as separate columns | |
30693 $(descriptionDocument).find("table").each(function(){ | |
30694 $(this).find("tr").each( | |
30695 function() { | |
30696 var isHeader = true; | |
30697 var lastHeader = ""; | |
30698 | |
30699 $(this).find("td").each( | |
30700 function() { | |
30701 if (isHeader) { | |
30702 lastHeader = $.trim($(this).text()); | |
30703 isHeader = false; | |
30704 } else { | |
30705 var value = ""; | |
30706 | |
30707 //if this td contains HTML, serialize all | |
30708 //it's children (the "content"!) | |
30709 $(this).children().each( | |
30710 function() { | |
30711 value += xmlSerializer.serializeToString(this); | |
30712 } | |
30713 ); | |
30714 | |
30715 //no HTML content (or no content at all) | |
30716 if (value.length == 0) | |
30717 value = $(this).text(); | |
30718 if (typeof value === "undefined") | |
30719 value = ""; | |
30720 | |
30721 if ($.inArray(lastHeader, descriptionTableHeaders) === -1) | |
30722 descriptionTableHeaders.push(lastHeader); | |
30723 | |
30724 if (tableContent[lastHeader] != null) | |
30725 //append if a field occures more than once | |
30726 tableContent[lastHeader] += "\n" + value; | |
30727 else | |
30728 tableContent[lastHeader] = value; | |
30729 | |
30730 isHeader = true; | |
30731 } | |
30732 } | |
30733 ); | |
30734 } | |
30735 ); | |
30736 }); | |
30737 } catch(e) { | |
30738 //couldn't be parsed, so it contains no html table | |
30739 //or is not in valid XHTML syntax | |
30740 } | |
30741 | |
30742 //check whether the description element contains content in the form of equations | |
30743 //e.g. someDescriptor = someValue, where these eqations are separated by <br/> | |
30744 //if yes, this data will be loaded as separate columns | |
30745 var descriptionRows = description.replace(/<\s*br\s*[\/]*\s*>/g,"<br/>"); | |
30746 $(descriptionRows.split("<br/>")).each(function(){ | |
30747 var row = this; | |
30748 | |
30749 if (typeof row === "undefined") | |
30750 return; | |
30751 | |
30752 var headerAndValue = row.split("="); | |
30753 if (headerAndValue.length != 2) | |
30754 return; | |
30755 | |
30756 var header = $.trim(headerAndValue[0]); | |
30757 var value = $.trim(headerAndValue[1]); | |
30758 | |
30759 if ($.inArray(header, descriptionTableHeaders) === -1) | |
30760 descriptionTableHeaders.push(header); | |
30761 | |
30762 if (tableContent[header] != null) | |
30763 //append if a field occures more than once | |
30764 tableContent[header] += "\n" + value; | |
30765 else | |
30766 tableContent[header] = value; | |
30767 }); | |
30768 | |
30769 tableContent["description"] = description; | |
30770 } catch(e) { | |
30771 description = ""; | |
30772 } | |
30773 | |
30774 try { | |
30775 name = placemark.getElementsByTagName("name")[0].childNodes[0].nodeValue; | |
30776 tableContent["name"] = name; | |
30777 } catch(e) { | |
30778 if (typeof tableContent["name"] !== "undefined") | |
30779 name = tableContent["name"]; | |
30780 else | |
30781 name = ""; | |
30782 } | |
30783 | |
30784 try { | |
30785 place = placemark.getElementsByTagName("address")[0].childNodes[0].nodeValue; | |
30786 tableContent["place"] = place; | |
30787 } catch(e) { | |
30788 if (typeof tableContent["place"] !== "undefined") | |
30789 place = tableContent["place"]; | |
30790 else | |
30791 place = ""; | |
30792 } | |
30793 | |
30794 try { | |
30795 var coordinates = placemark.getElementsByTagName("Point")[0].getElementsByTagName("coordinates")[0].childNodes[0].nodeValue; | |
30796 var lonlat = coordinates.split(","); | |
30797 lon = lonlat[0]; | |
30798 lat = lonlat[1]; | |
30799 if (lon == "" || lat == "" || isNaN(lon) || isNaN(lat)) { | |
30800 throw "e"; | |
30801 } | |
30802 location.push({ | |
30803 longitude : lon, | |
30804 latitude : lat, | |
30805 place : place | |
30806 }); | |
30807 } catch(e) { | |
30808 if (!GeoTemConfig.incompleteData) { | |
30809 continue; | |
30810 } | |
30811 } | |
30812 | |
30813 try { | |
30814 var tuple = GeoTemConfig.getTimeData(placemark.getElementsByTagName("TimeStamp")[0].getElementsByTagName("when")[0].childNodes[0].nodeValue); | |
30815 if (tuple != null) { | |
30816 time.push(tuple); | |
30817 timeData = true; | |
30818 } else if (!GeoTemConfig.incompleteData) { | |
30819 continue; | |
30820 } | |
30821 } catch(e) { | |
30822 try { | |
30823 if ( (typeof tableContent["TimeSpan:begin"] === "undefined") && | |
30824 (typeof tableContent["TimeSpan:end"] === "undefined") ){ | |
30825 var timeStart = $(placemark).find("TimeSpan begin").text(); | |
30826 var timeEnd = $(placemark).find("TimeSpan end").text(); | |
30827 | |
30828 if ( (timeStart != "") && (timeStart != "") ){ | |
30829 tableContent["TimeSpan:begin"] = timeStart; | |
30830 tableContent["TimeSpan:end"] = timeEnd; | |
30831 | |
30832 timeData = true; | |
30833 } | |
30834 } | |
30835 } catch(e) { | |
30836 if (!GeoTemConfig.incompleteData) { | |
30837 continue; | |
30838 } | |
30839 } | |
30840 } | |
30841 //per default GeoTemCo uses WGS84 (-90<=lat<=90, -180<=lon<=180) | |
30842 var projection = new OpenLayers.Projection("EPSG:4326"); | |
30843 var object = new DataObject(name, description, location, time, 1, tableContent, projection); | |
30844 object.setIndex(index); | |
30845 index++; | |
30846 mapObjects.push(object); | |
30847 } | |
30848 | |
30849 //make sure that all "description table" columns exists in all rows | |
30850 if (descriptionTableHeaders.length > 0){ | |
30851 $(mapObjects).each(function(){ | |
30852 var object = this; | |
30853 $(descriptionTableHeaders).each(function(){ | |
30854 if (typeof object.tableContent[this] === "undefined") | |
30855 object.tableContent[this] = ""; | |
30856 }); | |
30857 }); | |
30858 } | |
30859 | |
30860 if (GeoTemConfig.loadColorFromDataset) | |
30861 GeoTemConfig.loadDataObjectColoring(mapObjects); | |
30862 | |
30863 return mapObjects; | |
30864 }; | |
30865 | |
30866 GeoTemConfig.createKMLfromDataset = function(index){ | |
30867 var kmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document>"; | |
30868 | |
30869 //credits: Anatoly Mironov, http://stackoverflow.com/questions/2573521/how-do-i-output-an-iso-8601-formatted-string-in-javascript | |
30870 function pad(number) { | |
30871 var r = String(number); | |
30872 if ( r.length === 1 ) { | |
30873 r = '0' + r; | |
30874 } | |
30875 return r; | |
30876 } | |
30877 | |
30878 var dateToISOString = function(date, granularity) { | |
30879 var ISOString = date.getFullYear(); | |
30880 | |
30881 if (granularity <= SimileAjax.DateTime.MONTH) | |
30882 ISOString += '-' + pad( date.getMonth() + 1 ); | |
30883 if (granularity <= SimileAjax.DateTime.DAY) | |
30884 ISOString += '-' + pad( date.getDate() ); | |
30885 if (granularity <= SimileAjax.DateTime.HOUR){ | |
30886 ISOString += 'T' + pad( date.getHours() ); | |
30887 if (granularity <= SimileAjax.DateTime.MINUTE) | |
30888 ISOString += ':' + pad( date.getMinutes() ); | |
30889 if (granularity <= SimileAjax.DateTime.SECOND) | |
30890 ISOString += ':' + pad( date.getSeconds() ); | |
30891 if (granularity <= SimileAjax.DateTime.MILLISECOND) | |
30892 ISOString += '.' + String( (date.getMilliseconds()/1000).toFixed(3) ).slice( 2, 5 ); | |
30893 ISOString += 'Z'; | |
30894 } | |
30895 | |
30896 return ISOString; | |
30897 }; | |
30898 | |
30899 $(GeoTemConfig.datasets[index].objects).each(function(){ | |
30900 var name = this.name; | |
30901 var description = this.description; | |
30902 //TODO: allow multiple time/date | |
30903 var place = this.getPlace(0,0); | |
30904 var lat = this.getLatitude(0); | |
30905 var lon = this.getLongitude(0); | |
30906 | |
30907 var kmlEntry = "<Placemark>"; | |
30908 | |
30909 kmlEntry += "<name><![CDATA[" + name + "]]></name>"; | |
30910 kmlEntry += "<address><![CDATA[" + place + "]]></address>"; | |
30911 kmlEntry += "<description><![CDATA[" + description + "]]></description>"; | |
30912 kmlEntry += "<Point><coordinates>" + lon + "," + lat + "</coordinates></Point>"; | |
30913 | |
30914 if (this.isTemporal){ | |
30915 kmlEntry += "<TimeStamp><when>" + dateToISOString(this.getDate(0), this.getTimeGranularity(0)) + "</when></TimeStamp>"; | |
30916 } else if (this.isFuzzyTemporal){ | |
30917 kmlEntry += "<TimeSpan>"+ | |
30918 "<begin>" + dateToISOString(this.TimeSpanBegin.utc().toDate(), this.TimeSpanBeginGranularity) + "</begin>" + | |
30919 "<end>" + dateToISOString(this.TimeSpanEnd.utc().toDate(), this.TimeSpanEndGranularity) + "</end>" + | |
30920 "</TimeSpan>"; | |
30921 } | |
30922 | |
30923 kmlEntry += "</Placemark>"; | |
30924 | |
30925 kmlContent += kmlEntry; | |
30926 }); | |
30927 | |
30928 kmlContent += "</Document></kml>"; | |
30929 | |
30930 return(kmlContent); | |
30931 }; | |
30932 | |
30933 GeoTemConfig.createCSVfromDataset = function(index){ | |
30934 var csvContent = ""; | |
30935 var header = ["name", "description", "weight"]; | |
30936 var tableContent = []; | |
30937 | |
30938 var firstDataObject = GeoTemConfig.datasets[index].objects[0]; | |
30939 | |
30940 for(var key in firstDataObject.tableContent){ | |
30941 var found = false; | |
30942 $(header).each(function(index,val){ | |
30943 if (val === key){ | |
30944 found = true; | |
30945 return false; | |
30946 } | |
30947 }); | |
30948 if (found === true) | |
30949 continue; | |
30950 else | |
30951 tableContent.push(key); | |
30952 } | |
30953 | |
30954 var isFirst = true; | |
30955 $(header).each(function(key,val){ | |
30956 if (isFirst){ | |
30957 isFirst = false; | |
30958 } else { | |
30959 csvContent += ","; | |
30960 } | |
30961 | |
30962 //Rename according to CSV import definition | |
30963 if (val === "name") | |
30964 val = "Name"; | |
30965 else if (val === "description") | |
30966 val = "Description"; | |
30967 csvContent += "\""+val+"\""; | |
30968 }); | |
30969 $(tableContent).each(function(key,val){ | |
30970 if (isFirst){ | |
30971 isFirst = false; | |
30972 } else { | |
30973 csvContent += ","; | |
30974 } | |
30975 csvContent += "\""+val+"\""; | |
30976 }); | |
30977 //Names according to CSV import definition | |
30978 csvContent += ",\"Address\",\"Latitude\",\"Longitude\",\"TimeStamp\""; | |
30979 csvContent += "\n"; | |
30980 | |
30981 var isFirstRow = true; | |
30982 $(GeoTemConfig.datasets[index].objects).each(function(){ | |
30983 var elem = this; | |
30984 | |
30985 if (isFirstRow){ | |
30986 isFirstRow = false; | |
30987 } else { | |
30988 csvContent += "\n"; | |
30989 } | |
30990 | |
30991 var isFirst = true; | |
30992 $(header).each(function(key,val){ | |
30993 if (isFirst){ | |
30994 isFirst = false; | |
30995 } else { | |
30996 csvContent += ","; | |
30997 } | |
30998 csvContent += "\""+elem[val]+"\""; | |
30999 }); | |
31000 $(tableContent).each(function(key,val){ | |
31001 if (isFirst){ | |
31002 isFirst = false; | |
31003 } else { | |
31004 csvContent += ","; | |
31005 } | |
31006 csvContent += "\""+elem.tableContent[val]+"\""; | |
31007 }); | |
31008 | |
31009 csvContent += ","; | |
31010 csvContent += "\""; | |
31011 if (elem.isGeospatial){ | |
31012 csvContent += elem.locations[0].place; | |
31013 } | |
31014 csvContent += "\""; | |
31015 | |
31016 csvContent += ","; | |
31017 csvContent += "\""; | |
31018 if ( (elem.isGeospatial) && (typeof elem.getLatitude(0) !== "undefined") ){ | |
31019 csvContent += elem.getLatitude(0); | |
31020 } | |
31021 csvContent += "\""; | |
31022 | |
31023 csvContent += ","; | |
31024 csvContent += "\""; | |
31025 if ( (elem.isGeospatial) && (typeof elem.getLongitude(0) !== "undefined") ){ | |
31026 csvContent += elem.getLongitude(0); | |
31027 } | |
31028 csvContent += "\""; | |
31029 | |
31030 csvContent += ","; | |
31031 csvContent += "\""; | |
31032 if ( (elem.isTemporal) && (typeof elem.getDate(0) !== "undefined") ){ | |
31033 //TODO: not supported in IE8 switch to moment.js | |
31034 csvContent += elem.getDate(0).toISOString(); | |
31035 } | |
31036 csvContent += "\""; | |
31037 }); | |
31038 | |
31039 return(csvContent); | |
31040 }; | |
31041 /** | |
31042 * iterates over Datasets/DataObjects and loads color values | |
31043 * from the "color0" and "color1" elements, which contains RGB | |
31044 * values in hex (CSS style #RRGGBB) | |
31045 * @param {dataObjects} array of DataObjects | |
31046 */ | |
31047 GeoTemConfig.loadDataObjectColoring = function(dataObjects) { | |
31048 $(dataObjects).each(function(){ | |
31049 var r0,g0,b0,r1,g1,b1; | |
31050 if ( (typeof this.tableContent !== "undefined") && | |
31051 (typeof this.tableContent["color0"] !== "undefined") ){ | |
31052 var color = this.tableContent["color0"]; | |
31053 if ( (color.indexOf("#") == 0) && (color.length == 7) ){ | |
31054 r0 = parseInt("0x"+color.substr(1,2)); | |
31055 g0 = parseInt("0x"+color.substr(3,2)); | |
31056 b0 = parseInt("0x"+color.substr(5,2)); | |
31057 } | |
31058 } | |
31059 if ( (typeof this.tableContent !== "undefined") && | |
31060 (typeof this.tableContent["color1"] !== "undefined") ){ | |
31061 var color = this.tableContent["color1"]; | |
31062 if ( (color.indexOf("#") == 0) && (color.length == 7) ){ | |
31063 r1 = parseInt("0x"+color.substr(1,2)); | |
31064 g1 = parseInt("0x"+color.substr(3,2)); | |
31065 b1 = parseInt("0x"+color.substr(5,2)); | |
31066 } | |
31067 } | |
31068 | |
31069 if ( (typeof r0 !== "undefined") && (typeof g0 !== "undefined") && (typeof b0 !== "undefined") && | |
31070 (typeof r1 !== "undefined") && (typeof g1 !== "undefined") && (typeof b1 !== "undefined") ){ | |
31071 this.setColor(r0,g0,b0,r1,g1,b1); | |
31072 delete this.tableContent["color0"]; | |
31073 delete this.tableContent["color1"]; | |
31074 } else { | |
31075 if (typeof console !== undefined) | |
31076 console.error("Object '" + this.name + "' has invalid color information"); | |
31077 } | |
31078 }); | |
31079 }; | |
31080 /* | |
31081 * MapControl.js | |
31082 * | |
31083 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31084 * | |
31085 * This library is free software; you can redistribute it and/or | |
31086 * modify it under the terms of the GNU Lesser General Public | |
31087 * License as published by the Free Software Foundation; either | |
31088 * version 3 of the License, or (at your option) any later version. | |
31089 * | |
31090 * This library is distributed in the hope that it will be useful, | |
31091 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31092 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31093 * Lesser General Public License for more details. | |
31094 * | |
31095 * You should have received a copy of the GNU Lesser General Public | |
31096 * License along with this library; if not, write to the Free Software | |
31097 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31098 * MA 02110-1301 USA | |
31099 */ | |
31100 | |
31101 /** | |
31102 * @class MapControl | |
31103 * Generic map control interface | |
31104 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31105 * @release 1.0 | |
31106 * @release date: 2012-07-27 | |
31107 * @version date: 2012-07-27 | |
31108 */ | |
31109 function MapControl(map, button, label, onActivate, onDeactivate) { | |
31110 | |
31111 var control = this; | |
31112 this.button = button; | |
31113 this.enabled = true; | |
31114 this.activated = false; | |
31115 this.label = label; | |
31116 | |
31117 if (this.button != null) { | |
31118 $(this.button).addClass(label + 'Deactivated'); | |
31119 $(this.button).attr("title", GeoTemConfig.getString(GeoTemConfig.language, label)); | |
31120 //vhz | |
31121 $(this.button).click(function() { | |
31122 control.checkStatus(); | |
31123 }); | |
31124 } | |
31125 | |
31126 this.checkStatus = function() { | |
31127 if (control.enabled) { | |
31128 if ( typeof map.activeControl != 'undefined') { | |
31129 if (control.activated) { | |
31130 control.deactivate(); | |
31131 } else { | |
31132 map.activeControl.deactivate(); | |
31133 control.activate(); | |
31134 } | |
31135 } else { | |
31136 control.activate(); | |
31137 } | |
31138 } | |
31139 }; | |
31140 | |
31141 this.setButtonClass = function(removeClass, addClass) { | |
31142 if (this.button != null) { | |
31143 $(this.button).removeClass(label + removeClass); | |
31144 $(this.button).addClass(label + addClass); | |
31145 $(this.button).attr("title", GeoTemConfig.getString(GeoTemConfig.language, label)); | |
31146 } | |
31147 }; | |
31148 | |
31149 this.disable = function() { | |
31150 this.enabled = false; | |
31151 this.setButtonClass('Deactivated', 'Disabled'); | |
31152 }; | |
31153 | |
31154 this.enable = function() { | |
31155 this.enabled = true; | |
31156 this.setButtonClass('Disabled', 'Deactivated'); | |
31157 }; | |
31158 | |
31159 this.activate = function() { | |
31160 onActivate(); | |
31161 this.activated = true; | |
31162 this.setButtonClass('Deactivated', 'Activated'); | |
31163 map.activeControl = this; | |
31164 }; | |
31165 | |
31166 this.deactivate = function() { | |
31167 onDeactivate(); | |
31168 this.activated = false; | |
31169 this.setButtonClass('Activated', 'Deactivated'); | |
31170 map.activeControl = undefined; | |
31171 }; | |
31172 | |
31173 }; | |
31174 /* | |
31175 * CircleObject.js | |
31176 * | |
31177 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31178 * | |
31179 * This library is free software; you can redistribute it and/or | |
31180 * modify it under the terms of the GNU Lesser General Public | |
31181 * License as published by the Free Software Foundation; either | |
31182 * version 3 of the License, or (at your option) any later version. | |
31183 * | |
31184 * This library is distributed in the hope that it will be useful, | |
31185 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31186 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31187 * Lesser General Public License for more details. | |
31188 * | |
31189 * You should have received a copy of the GNU Lesser General Public | |
31190 * License along with this library; if not, write to the Free Software | |
31191 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31192 * MA 02110-1301 USA | |
31193 */ | |
31194 | |
31195 /** | |
31196 * @class CircleObject | |
31197 * circle object aggregate for the map | |
31198 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31199 * @release 1.0 | |
31200 * @release date: 2012-07-27 | |
31201 * @version date: 2012-07-27 | |
31202 * | |
31203 * @param {float} x the x (longitude) value for the circle | |
31204 * @param {float} y the y (latitude) value for the circle | |
31205 * @param {DataObject[]} elements array of data objects belonging to the circle | |
31206 * @param {float} radius the resulting radius (in pixel) for the circle | |
31207 * @param {int} search dataset index | |
31208 * @param {int} weight summed weight of all elements | |
31209 * @param {JSON} fatherBin bin of the circle object if its part of a circle pack | |
31210 */ | |
31211 CircleObject = function(originX, originY, shiftX, shiftY, elements, radius, search, weight, fatherBin) { | |
31212 | |
31213 this.originX = originX; | |
31214 this.originY = originY; | |
31215 this.shiftX = shiftX; | |
31216 this.shiftY = shiftY; | |
31217 this.elements = elements; | |
31218 this.radius = radius; | |
31219 this.search = search; | |
31220 this.weight = weight; | |
31221 this.overlay = 0; | |
31222 this.overlayElements = []; | |
31223 this.smoothness = 0; | |
31224 this.fatherBin = fatherBin; | |
31225 | |
31226 this.feature | |
31227 this.olFeature | |
31228 this.percentage = 0; | |
31229 this.selected = false; | |
31230 | |
31231 }; | |
31232 | |
31233 CircleObject.prototype = { | |
31234 | |
31235 /** | |
31236 * sets the OpenLayers point feature for this point object | |
31237 * @param {OpenLayers.Feature} pointFeature the point feature for this object | |
31238 */ | |
31239 setFeature : function(feature) { | |
31240 this.feature = feature; | |
31241 }, | |
31242 | |
31243 /** | |
31244 * sets the OpenLayers point feature for this point object to manage its selection status | |
31245 * @param {OpenLayers.Feature} olPointFeature the overlay point feature for this object | |
31246 */ | |
31247 setOlFeature : function(olFeature) { | |
31248 this.olFeature = olFeature; | |
31249 }, | |
31250 | |
31251 reset : function() { | |
31252 this.overlay = 0; | |
31253 this.overlayElements = []; | |
31254 this.smoothness = 0; | |
31255 }, | |
31256 | |
31257 setSelection : function(s) { | |
31258 this.selected = s; | |
31259 }, | |
31260 | |
31261 toggleSelection : function() { | |
31262 this.selected = !this.selected; | |
31263 } | |
31264 }; | |
31265 /* | |
31266 * FilterBar.js | |
31267 * | |
31268 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31269 * | |
31270 * This library is free software; you can redistribute it and/or | |
31271 * modify it under the terms of the GNU Lesser General Public | |
31272 * License as published by the Free Software Foundation; either | |
31273 * version 3 of the License, or (at your option) any later version. | |
31274 * | |
31275 * This library is distributed in the hope that it will be useful, | |
31276 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31277 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31278 * Lesser General Public License for more details. | |
31279 * | |
31280 * You should have received a copy of the GNU Lesser General Public | |
31281 * License along with this library; if not, write to the Free Software | |
31282 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31283 * MA 02110-1301 USA | |
31284 */ | |
31285 | |
31286 /** | |
31287 * @class FilterBar | |
31288 * Implementation for FilterBar Object | |
31289 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31290 * @release 1.0 | |
31291 * @release date: 2012-07-27 | |
31292 * @version date: 2012-07-27 | |
31293 * | |
31294 * @param {Object} parent parent to call filter functions | |
31295 * @param {HTML object} parentDiv div to append filter buttons | |
31296 */ | |
31297 function FilterBar(parent, parentDiv) { | |
31298 | |
31299 var bar = this; | |
31300 | |
31301 this.filter = document.createElement('div'); | |
31302 this.filter.setAttribute('class', 'smallButton filterDisabled'); | |
31303 this.filter.onclick = function() { | |
31304 parent.filtering(); | |
31305 }; | |
31306 | |
31307 this.filterInverse = document.createElement('div'); | |
31308 this.filterInverse.setAttribute('class', 'smallButton filterInverseDisabled'); | |
31309 this.filterInverse.onclick = function() { | |
31310 parent.inverseFiltering(); | |
31311 }; | |
31312 if (!GeoTemConfig.inverseFilter) { | |
31313 this.filterInverse.style.display = 'none'; | |
31314 } | |
31315 | |
31316 this.cancelSelection = document.createElement('div'); | |
31317 this.cancelSelection.setAttribute('class', 'smallButton filterCancelDisabled'); | |
31318 this.cancelSelection.onclick = function() { | |
31319 parent.deselection(); | |
31320 }; | |
31321 | |
31322 this.appendTo = function(parentDiv) { | |
31323 parentDiv.appendChild(this.filter); | |
31324 parentDiv.appendChild(this.filterInverse); | |
31325 parentDiv.appendChild(this.cancelSelection); | |
31326 } | |
31327 if ( typeof parentDiv != 'undefined') { | |
31328 this.appendTo(parentDiv); | |
31329 } | |
31330 | |
31331 this.reset = function(show) { | |
31332 if (show) { | |
31333 this.filter.setAttribute('class', 'smallButton filter'); | |
31334 this.filterInverse.setAttribute('class', 'smallButton filterInverse'); | |
31335 this.cancelSelection.setAttribute('class', 'smallButton filterCancel'); | |
31336 } else { | |
31337 this.filter.setAttribute('class', 'smallButton filterDisabled'); | |
31338 this.filterInverse.setAttribute('class', 'smallButton filterInverseDisabled'); | |
31339 this.cancelSelection.setAttribute('class', 'smallButton filterCancelDisabled'); | |
31340 } | |
31341 }; | |
31342 | |
31343 }; | |
31344 /* | |
31345 * Selection.js | |
31346 * | |
31347 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31348 * | |
31349 * This library is free software; you can redistribute it and/or | |
31350 * modify it under the terms of the GNU Lesser General Public | |
31351 * License as published by the Free Software Foundation; either | |
31352 * version 3 of the License, or (at your option) any later version. | |
31353 * | |
31354 * This library is distributed in the hope that it will be useful, | |
31355 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31356 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31357 * Lesser General Public License for more details. | |
31358 * | |
31359 * You should have received a copy of the GNU Lesser General Public | |
31360 * License along with this library; if not, write to the Free Software | |
31361 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31362 * MA 02110-1301 USA | |
31363 */ | |
31364 | |
31365 /** | |
31366 * @class Selection | |
31367 * Selection Class | |
31368 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31369 * @release 1.0 | |
31370 * @release date: 2012-07-27 | |
31371 * @version date: 2012-07-27 | |
31372 * | |
31373 * @param {Array} objects array of selected objects | |
31374 * @param {Object} widget which belongs to selection | |
31375 */ | |
31376 function Selection(objects, widget) { | |
31377 | |
31378 this.objects = objects; | |
31379 if ( typeof objects == 'undefined') { | |
31380 this.objects = []; | |
31381 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
31382 this.objects.push([]); | |
31383 } | |
31384 } | |
31385 this.widget = widget; | |
31386 | |
31387 this.getObjects = function(widget) { | |
31388 if (!this.equal(widget)) { | |
31389 return this.objects; | |
31390 } | |
31391 this.objects = []; | |
31392 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
31393 this.objects.push([]); | |
31394 } | |
31395 return this.objects; | |
31396 }; | |
31397 | |
31398 this.equal = function(widget) { | |
31399 if (this.valid() && this.widget != widget) { | |
31400 return false; | |
31401 } | |
31402 return true; | |
31403 }; | |
31404 | |
31405 this.valid = function() { | |
31406 if ( typeof this.widget != 'undefined') { | |
31407 return true; | |
31408 } | |
31409 return false; | |
31410 }; | |
31411 | |
31412 this.loadAllObjects = function() { | |
31413 allObjects = []; | |
31414 $(GeoTemConfig.datasets).each(function(){ | |
31415 var singleDatasetObjects = []; | |
31416 $(this.objects).each(function(){ | |
31417 singleDatasetObjects.push(this); | |
31418 }); | |
31419 allObjects.push(singleDatasetObjects); | |
31420 }); | |
31421 this.objects = allObjects; | |
31422 }; | |
31423 }; | |
31424 | |
31425 /* | |
31426 * PlacenameTags.js | |
31427 * | |
31428 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
31429 * | |
31430 * This library is free software; you can redistribute it and/or | |
31431 * modify it under the terms of the GNU Lesser General Public | |
31432 * License as published by the Free Software Foundation; either | |
31433 * version 3 of the License, or (at your option) any later version. | |
31434 * | |
31435 * This library is distributed in the hope that it will be useful, | |
31436 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31437 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
31438 * Lesser General Public License for more details. | |
31439 * | |
31440 * You should have received a copy of the GNU Lesser General Public | |
31441 * License along with this library; if not, write to the Free Software | |
31442 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
31443 * MA 02110-1301 USA | |
31444 */ | |
31445 | |
31446 /** | |
31447 * @class PlacenameTags | |
31448 * place labels computation for circles | |
31449 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
31450 * @release 1.0 | |
31451 * @release date: 2012-07-27 | |
31452 * @version date: 2012-07-27 | |
31453 */ | |
31454 function PlacenameTags(circle, map) { | |
31455 | |
31456 this.circle = circle; | |
31457 this.map = map; | |
31458 | |
31459 this.placeLabels | |
31460 this.selectedLabel | |
31461 | |
31462 this.allLabel | |
31463 this.othersLabel | |
31464 this.unknownLabel | |
31465 | |
31466 this.calculate = function() { | |
31467 this.calculateLabels(); | |
31468 this.calculatePlacenameTags(); | |
31469 } | |
31470 | |
31471 this.calculateLabels = function() { | |
31472 var elements = this.circle.elements; | |
31473 var k = this.circle.search; | |
31474 var weight = 0; | |
31475 var labels = []; | |
31476 | |
31477 var levelOfDetail = 0; | |
31478 if (this.map.options.placenameTagsStyle === 'zoom') | |
31479 levelOfDetail = this.map.getLevelOfDetail(); | |
31480 | |
31481 if (this.map.options.placenameTagsStyle === 'value'){ | |
31482 //find max level that _all_ elements have a value for | |
31483 var maxLevel; | |
31484 for (var i = 0; i < elements.length; i++) { | |
31485 var level = elements[i].placeDetails[this.map.options.mapIndex].length-1; | |
31486 | |
31487 if (typeof maxLevel === "undefined") | |
31488 maxLevel = level; | |
31489 if (maxLevel > level) | |
31490 maxLevel = level; | |
31491 //smallest level anyway, no need to look any further | |
31492 if (level == 0) | |
31493 break; | |
31494 } | |
31495 //search for highest level where the values differ | |
31496 for (levelOfDetail = 0; levelOfDetail < maxLevel; levelOfDetail++){ | |
31497 var differenceFound = false; | |
31498 for (var i = 0; i < (elements.length-1); i++) { | |
31499 if ( elements[i].getPlace(this.map.options.mapIndex, levelOfDetail) !== | |
31500 elements[i+1].getPlace(this.map.options.mapIndex, levelOfDetail)) | |
31501 differenceFound = true; | |
31502 } | |
31503 if (differenceFound === true) | |
31504 break; | |
31505 } | |
31506 } | |
31507 | |
31508 for (var i = 0; i < elements.length; i++) { | |
31509 weight += elements[i].weight; | |
31510 var found = false; | |
31511 var label = elements[i].getPlace(this.map.options.mapIndex, levelOfDetail); | |
31512 if (label == "") { | |
31513 label = "unknown"; | |
31514 } | |
31515 for (var j = 0; j < labels.length; j++) { | |
31516 if (labels[j].place == label) { | |
31517 labels[j].elements.push(elements[i]); | |
31518 labels[j].weight += elements[i].weight; | |
31519 found = true; | |
31520 break; | |
31521 } | |
31522 } | |
31523 if (!found) { | |
31524 labels.push({ | |
31525 id : elements[i].name, | |
31526 place : label, | |
31527 elements : new Array(elements[i]), | |
31528 weight : elements[i].weight, | |
31529 index : k | |
31530 }); | |
31531 } | |
31532 } | |
31533 var sortBySize = function(label1, label2) { | |
31534 if (label1.weight > label2.weight) { | |
31535 return -1; | |
31536 } | |
31537 return 1; | |
31538 } | |
31539 labels.sort(sortBySize); | |
31540 if (map.options.maxPlaceLabels) { | |
31541 var ml = map.options.maxPlaceLabels; | |
31542 if (ml == 1) { | |
31543 labels = []; | |
31544 labels.push({ | |
31545 place : "all", | |
31546 elements : elements, | |
31547 weight : weight, | |
31548 index : k | |
31549 }); | |
31550 } | |
31551 if (ml == 2) { | |
31552 ml++; | |
31553 } | |
31554 if (ml > 2 && labels.length + 1 > ml) { | |
31555 var c = []; | |
31556 var w = 0; | |
31557 for (var i = ml - 2; i < labels.length; i++) { | |
31558 c = c.concat(labels[i].elements); | |
31559 w += labels[i].weight; | |
31560 } | |
31561 labels = labels.slice(0, ml - 2); | |
31562 labels.push({ | |
31563 place : "others", | |
31564 elements : c, | |
31565 weight : w, | |
31566 index : k | |
31567 }); | |
31568 } | |
31569 } | |
31570 if (labels.length > 1) { | |
31571 labels.push({ | |
31572 place : "all", | |
31573 elements : elements, | |
31574 weight : weight, | |
31575 index : k | |
31576 }); | |
31577 } | |
31578 this.placeLabels = labels; | |
31579 }; | |
31580 | |
31581 this.calculatePlacenameTags = function() { | |
31582 var cloud = this; | |
31583 var c = GeoTemConfig.getColor(this.circle.search); | |
31584 if( map.options.useGraphics ){ | |
31585 c = map.config.getGraphic(this.circle.search).color; | |
31586 } | |
31587 var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
31588 var color1 = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
31589 var allStyles = "", hoverStyle = "", highlightStyle = "", selectedStyle = "", unselectedStyle = ""; | |
31590 | |
31591 if (GeoTemConfig.ie) { | |
31592 highlightStyle += map.options.ieHighlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31593 hoverStyle += map.options.ieHoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31594 selectedStyle += map.options.ieSelectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31595 unselectedStyle += map.options.ieUnselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31596 } else { | |
31597 highlightStyle += map.options.highlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31598 hoverStyle += map.options.hoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31599 selectedStyle += map.options.selectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31600 unselectedStyle += map.options.unselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31601 } | |
31602 | |
31603 var clickFunction = function(label) { | |
31604 label.div.onclick = function() { | |
31605 cloud.changeLabelSelection(label); | |
31606 } | |
31607 } | |
31608 var maxLabelSize = this.count | |
31609 for (var i = 0; i < this.placeLabels.length; i++) { | |
31610 var l = this.placeLabels[i]; | |
31611 l.selected = false; | |
31612 var div = document.createElement("div"); | |
31613 div.setAttribute('class', 'tagCloudItem'); | |
31614 var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; | |
31615 if (l.place == "all") { | |
31616 fontSize = 1; | |
31617 } | |
31618 div.style.fontSize = fontSize + "em"; | |
31619 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
31620 l.selectedStyle = selectedStyle; | |
31621 l.unselectedStyle = unselectedStyle; | |
31622 l.highlightStyle = highlightStyle; | |
31623 l.hoverStyle = hoverStyle; | |
31624 div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; | |
31625 l.div = div; | |
31626 clickFunction(l); | |
31627 } | |
31628 if (map.options.labelGrid) { | |
31629 this.showPlacelabels(); | |
31630 } else { | |
31631 for (var i = 0; i < this.placeLabels.length; i++) { | |
31632 this.placeLabels[i].div.setAttribute('style', this.placeLabels[i].allStyle + "" + this.placeLabels[i].highlightStyle); | |
31633 } | |
31634 } | |
31635 }; | |
31636 | |
31637 this.selectLabel = function(label) { | |
31638 if ( typeof label == 'undefined') { | |
31639 label = this.placeLabels[this.placeLabels.length - 1]; | |
31640 } | |
31641 if (this.map.popup) { | |
31642 this.map.popup.showLabelContent(label); | |
31643 } | |
31644 this.selectedLabel = label; | |
31645 this.selectedLabel.div.setAttribute('style', this.selectedLabel.allStyle + "" + this.selectedLabel.selectedStyle); | |
31646 this.map.mapLabelSelection(label); | |
31647 }; | |
31648 | |
31649 // changes selection between labels (click, hover) | |
31650 this.changeLabelSelection = function(label) { | |
31651 if (this.selectedLabel == label) { | |
31652 return; | |
31653 } | |
31654 if ( typeof this.selectedLabel != 'undefined') { | |
31655 this.selectedLabel.div.setAttribute('style', this.selectedLabel.allStyle + "" + this.selectedLabel.unselectedStyle); | |
31656 } | |
31657 this.selectLabel(label); | |
31658 }; | |
31659 | |
31660 this.showPlacelabels = function() { | |
31661 this.leftDiv = document.createElement("div"); | |
31662 this.leftDiv.setAttribute('class', 'tagCloudDiv'); | |
31663 this.map.gui.mapWindow.appendChild(this.leftDiv); | |
31664 this.rightDiv = document.createElement("div"); | |
31665 this.rightDiv.setAttribute('class', 'tagCloudDiv'); | |
31666 this.map.gui.mapWindow.appendChild(this.rightDiv); | |
31667 for (var i = 0; i < this.placeLabels.length; i++) { | |
31668 if (i % 2 == 0) { | |
31669 this.leftDiv.appendChild(this.placeLabels[i].div); | |
31670 } else { | |
31671 this.rightDiv.appendChild(this.placeLabels[i].div); | |
31672 } | |
31673 this.placeLabels[i].div.setAttribute('style', this.placeLabels[i].allStyle + "" + this.placeLabels[i].highlightStyle); | |
31674 } | |
31675 this.placeTagCloud(); | |
31676 }; | |
31677 | |
31678 this.placeTagCloud = function() { | |
31679 var lonlat = new OpenLayers.LonLat(this.circle.feature.geometry.x, this.circle.feature.geometry.y); | |
31680 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
31681 var radius = this.circle.feature.style.pointRadius; | |
31682 var lw = this.leftDiv.offsetWidth; | |
31683 var rw = this.rightDiv.offsetWidth; | |
31684 this.leftDiv.style.left = (pixel.x - radius - lw - 5) + "px"; | |
31685 this.rightDiv.style.left = (pixel.x + radius + 5) + "px"; | |
31686 var lh = this.leftDiv.offsetHeight; | |
31687 var rh = this.rightDiv.offsetHeight; | |
31688 var lt = pixel.y - lh / 2; | |
31689 var rt = pixel.y - rh / 2; | |
31690 this.leftDiv.style.top = lt + "px"; | |
31691 this.rightDiv.style.top = rt + "px"; | |
31692 }; | |
31693 | |
31694 this.remove = function() { | |
31695 $(this.leftDiv).remove(); | |
31696 $(this.rightDiv).remove(); | |
31697 }; | |
31698 | |
31699 }; | |
31700 | |
31701 function PackPlacenameTags(circle, map) { | |
31702 | |
31703 this.circle = circle; | |
31704 this.map = map; | |
31705 | |
31706 this.placeLabels | |
31707 this.selectedLabel | |
31708 | |
31709 this.allLabel | |
31710 this.othersLabel | |
31711 this.unknownLabel | |
31712 | |
31713 this.calculate = function() { | |
31714 this.calculateLabels(); | |
31715 this.calculatePlacenameTags(); | |
31716 } | |
31717 | |
31718 this.getLabelList = function(circle) { | |
31719 | |
31720 var elements = circle.elements; | |
31721 var k = circle.search; | |
31722 var weight = 0; | |
31723 var labels = []; | |
31724 var levelOfDetail = this.map.getLevelOfDetail(); | |
31725 for (var i = 0; i < elements.length; i++) { | |
31726 weight += elements[i].weight; | |
31727 var found = false; | |
31728 var label = elements[i].getPlace(this.map.options.mapIndex, levelOfDetail); | |
31729 if (label == "") { | |
31730 label = "unknown"; | |
31731 } | |
31732 for (var j = 0; j < labels.length; j++) { | |
31733 if (labels[j].place == label) { | |
31734 labels[j].elements.push(elements[i]); | |
31735 labels[j].weight += elements[i].weight; | |
31736 found = true; | |
31737 break; | |
31738 } | |
31739 } | |
31740 if (!found) { | |
31741 labels.push({ | |
31742 id : elements[i].name, | |
31743 place : label, | |
31744 elements : new Array(elements[i]), | |
31745 weight : elements[i].weight, | |
31746 index : k | |
31747 }); | |
31748 } | |
31749 } | |
31750 var sortBySize = function(label1, label2) { | |
31751 if (label1.weight > label2.weight) { | |
31752 return -1; | |
31753 } | |
31754 return 1; | |
31755 } | |
31756 labels.sort(sortBySize); | |
31757 var droppedLabels = []; | |
31758 if (map.options.maxPlaceLabels) { | |
31759 var ml = map.options.maxPlaceLabels; | |
31760 if (ml == 1) { | |
31761 labels = []; | |
31762 labels.push({ | |
31763 place : "all", | |
31764 elements : elements, | |
31765 weight : weight, | |
31766 index : k | |
31767 }); | |
31768 } | |
31769 if (ml == 2) { | |
31770 ml++; | |
31771 } | |
31772 if (ml > 2 && labels.length + 1 > ml) { | |
31773 var c = []; | |
31774 var w = 0; | |
31775 for (var i = ml - 2; i < labels.length; i++) { | |
31776 c = c.concat(labels[i].elements); | |
31777 w += labels[i].weight; | |
31778 droppedLabels.push(labels[i]); | |
31779 } | |
31780 labels = labels.slice(0, ml - 2); | |
31781 var ol = { | |
31782 place : "others", | |
31783 elements : c, | |
31784 weight : w, | |
31785 index : k | |
31786 }; | |
31787 labels.push(ol); | |
31788 this.othersLabels.push(ol); | |
31789 } | |
31790 } | |
31791 if (labels.length > 1) { | |
31792 labels.push({ | |
31793 place : "all", | |
31794 elements : elements, | |
31795 weight : weight, | |
31796 index : k | |
31797 }); | |
31798 } | |
31799 this.placeLabels.push(labels); | |
31800 this.droppedLabels.push(droppedLabels); | |
31801 }; | |
31802 | |
31803 this.calculateLabels = function() { | |
31804 var circles = this.circle.circles; | |
31805 this.placeLabels = []; | |
31806 this.droppedLabels = []; | |
31807 this.othersLabels = []; | |
31808 for (var i = 0; i < circles.length; i++) { | |
31809 this.getLabelList(circles[i]); | |
31810 } | |
31811 }; | |
31812 | |
31813 this.calculatePlacenameTags = function() { | |
31814 var cloud = this; | |
31815 | |
31816 var unselectedStyles = []; | |
31817 var selectedStyles = []; | |
31818 var hoverStyles = []; | |
31819 | |
31820 for (var k = 0; k < this.placeLabels.length; k++) { | |
31821 var c = GeoTemConfig.getColor(this.circle.circles[k].search); | |
31822 if( map.options.useGraphics ){ | |
31823 c = map.config.getGraphic(this.circle.circles[k].search).color; | |
31824 } | |
31825 var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
31826 var color1 = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
31827 var allStyles = "", hoverStyle = "", highlightStyle = "", selectedStyle = "", unselectedStyle = ""; | |
31828 | |
31829 if (GeoTemConfig.ie) { | |
31830 highlightStyle += map.options.ieHighlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31831 hoverStyle += map.options.ieHoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31832 selectedStyle += map.options.ieSelectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31833 unselectedStyle += map.options.ieUnselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31834 } else { | |
31835 highlightStyle += map.options.highlightLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31836 hoverStyle += map.options.hoveredLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31837 selectedStyle += map.options.selectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31838 unselectedStyle += map.options.unselectedLabel.replace(/COLOR1/g, color1).replace(/COLOR0/g, color0) + ";"; | |
31839 } | |
31840 | |
31841 allStyles += 'margin-right:5px;'; | |
31842 allStyles += 'margin-left:5px;'; | |
31843 unselectedStyles.push(unselectedStyle); | |
31844 selectedStyles.push(selectedStyle); | |
31845 hoverStyles.push(hoverStyle); | |
31846 | |
31847 var clickFunction = function(label, id) { | |
31848 label.div.onmouseover = function() { | |
31849 if (!label.opposite) { | |
31850 var oppositeLabel, oppositeLabelDiv; | |
31851 label.div.setAttribute('style', allStyles + "" + selectedStyles[id]); | |
31852 var c = GeoTemConfig.getColor(id); | |
31853 if( map.options.useGraphics ){ | |
31854 c = map.config.getGraphic(id).color; | |
31855 } | |
31856 var color0 = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
31857 if (id == 0) { | |
31858 for (var i = 0; i < cloud.droppedLabels[1].length; i++) { | |
31859 if (cloud.droppedLabels[1][i].place == label.place) { | |
31860 oppositeLabel = cloud.droppedLabels[1][i]; | |
31861 cloud.rightDiv.appendChild(oppositeLabel.div); | |
31862 cloud.drawLine(cloud.ctxOl, label.div, oppositeLabel.div); | |
31863 var olDiv = cloud.othersLabels[1].div; | |
31864 olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + (cloud.othersLabels[1].weight - oppositeLabel.weight) + ')'); | |
31865 break; | |
31866 } | |
31867 } | |
31868 } else { | |
31869 for (var i = 0; i < cloud.droppedLabels[0].length; i++) { | |
31870 if (cloud.droppedLabels[0][i].place == label.place) { | |
31871 oppositeLabel = cloud.droppedLabels[0][i]; | |
31872 cloud.leftDiv.appendChild(oppositeLabel.div); | |
31873 cloud.drawLine(cloud.ctxOl, oppositeLabel.div, label.div); | |
31874 var olDiv = cloud.othersLabels[0].div; | |
31875 olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + (cloud.othersLabels[0].weight - oppositeLabel.weight) + ')'); | |
31876 break; | |
31877 } | |
31878 } | |
31879 } | |
31880 if ( typeof oppositeLabel == 'undefined') { | |
31881 oppositeLabel = { | |
31882 div : cloud.naDiv | |
31883 }; | |
31884 if (id == 0) { | |
31885 cloud.rightDiv.appendChild(cloud.naDiv); | |
31886 cloud.drawLine(cloud.ctxOl, label.div, cloud.naDiv); | |
31887 oppositeLabel.div.setAttribute('style', allStyles + "" + selectedStyles[1]); | |
31888 } else { | |
31889 cloud.leftDiv.appendChild(cloud.naDiv); | |
31890 cloud.drawLine(cloud.ctxOl, cloud.naDiv, label.div); | |
31891 oppositeLabel.div.setAttribute('style', allStyles + "" + selectedStyles[0]); | |
31892 } | |
31893 cloud.map.mapLabelHighlight(label); | |
31894 } else { | |
31895 cloud.map.mapLabelHighlight([label, oppositeLabel]); | |
31896 } | |
31897 label.div.onmouseout = function() { | |
31898 label.div.setAttribute('style', allStyles + "" + unselectedStyles[id]); | |
31899 var olDiv = cloud.othersLabels[0].div; | |
31900 olDiv.innerHTML = olDiv.innerHTML.replace(/\(\d*\)/g, '(' + cloud.othersLabels[0].weight + ')'); | |
31901 var olDiv2 = cloud.othersLabels[1].div; | |
31902 olDiv2.innerHTML = olDiv2.innerHTML.replace(/\(\d*\)/g, '(' + cloud.othersLabels[1].weight + ')'); | |
31903 $(oppositeLabel.div).remove(); | |
31904 cloud.ctxOl.clearRect(0, 0, cloud.cvOl.width, cloud.cvOl.height); | |
31905 cloud.map.mapLabelHighlight(); | |
31906 } | |
31907 } | |
31908 } | |
31909 } | |
31910 var maxLabelSize = this.count | |
31911 for (var i = 0; i < this.placeLabels[k].length; i++) { | |
31912 var l = this.placeLabels[k][i]; | |
31913 l.selected = false; | |
31914 var div = document.createElement("div"); | |
31915 div.setAttribute('class', 'tagCloudItem'); | |
31916 var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; | |
31917 if (l.place == "all") { | |
31918 fontSize = 1; | |
31919 } | |
31920 div.style.fontSize = fontSize + "em"; | |
31921 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
31922 l.selectedStyle = selectedStyle; | |
31923 l.unselectedStyle = unselectedStyle; | |
31924 l.hoverStyle = hoverStyle; | |
31925 div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; | |
31926 l.div = div; | |
31927 clickFunction(l, k); | |
31928 } | |
31929 for (var i = 0; i < this.droppedLabels[k].length; i++) { | |
31930 var l = this.droppedLabels[k][i]; | |
31931 l.selected = false; | |
31932 var div = document.createElement("div"); | |
31933 div.setAttribute('class', 'tagCloudItem'); | |
31934 var fontSize = 1 + (l.weight - 1) / this.map.count * map.options.maxLabelIncrease; | |
31935 div.style.fontSize = fontSize + "em"; | |
31936 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
31937 l.selectedStyle = selectedStyle; | |
31938 l.unselectedStyle = unselectedStyle; | |
31939 l.hoverStyle = hoverStyle; | |
31940 div.innerHTML = l.place + "<span style='font-size:" + (1 / fontSize) + "em'> (" + l.weight + ")</span>"; | |
31941 l.div = div; | |
31942 div.setAttribute('style', allStyles + "" + selectedStyle); | |
31943 } | |
31944 } | |
31945 | |
31946 this.naDiv = document.createElement("div"); | |
31947 this.naDiv.setAttribute('class', 'tagCloudItem'); | |
31948 var fontSize = 1; | |
31949 div.style.fontSize = fontSize + "em"; | |
31950 l.allStyle = allStyles + "font-size: " + fontSize + "em;"; | |
31951 l.selectedStyle = selectedStyle; | |
31952 l.unselectedStyle = unselectedStyle; | |
31953 l.hoverStyle = hoverStyle; | |
31954 this.naDiv.innerHTML = "Not available"; | |
31955 l.div = this.naDiv; | |
31956 | |
31957 if (map.options.labelGrid) { | |
31958 this.showPlacelabels(); | |
31959 } | |
31960 }; | |
31961 | |
31962 this.showPlacelabels = function() { | |
31963 this.leftDiv = document.createElement("div"); | |
31964 this.leftDiv.setAttribute('class', 'tagCloudDiv'); | |
31965 this.leftDiv.style.textAlign = 'right'; | |
31966 this.map.gui.mapWindow.appendChild(this.leftDiv); | |
31967 this.centerDiv = document.createElement("div"); | |
31968 this.centerDiv.setAttribute('class', 'tagCloudDiv'); | |
31969 this.centerDiv.style.opacity = 0.7; | |
31970 this.map.gui.mapWindow.appendChild(this.centerDiv); | |
31971 this.centerDivOl = document.createElement("div"); | |
31972 this.centerDivOl.setAttribute('class', 'tagCloudDiv'); | |
31973 this.centerDivOl.style.opacity = 0.7; | |
31974 this.map.gui.mapWindow.appendChild(this.centerDivOl); | |
31975 this.rightDiv = document.createElement("div"); | |
31976 this.rightDiv.setAttribute('class', 'tagCloudDiv'); | |
31977 this.rightDiv.style.textAlign = 'left'; | |
31978 this.map.gui.mapWindow.appendChild(this.rightDiv); | |
31979 for (var i = 0; i < this.placeLabels.length; i++) { | |
31980 for (var j = 0; j < this.placeLabels[i].length; j++) { | |
31981 if (i == 0) { | |
31982 this.leftDiv.appendChild(this.placeLabels[i][j].div); | |
31983 } else { | |
31984 this.rightDiv.appendChild(this.placeLabels[i][j].div); | |
31985 } | |
31986 this.placeLabels[i][j].div.setAttribute('style', this.placeLabels[i][j].allStyle + "" + this.placeLabels[i][j].unselectedStyle); | |
31987 } | |
31988 } | |
31989 this.placeTagCloud(); | |
31990 this.setCanvas(); | |
31991 }; | |
31992 | |
31993 this.placeTagCloud = function() { | |
31994 var lonlat = new OpenLayers.LonLat(this.circle.feature.geometry.x, this.circle.feature.geometry.y); | |
31995 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
31996 var radius = this.circle.feature.style.pointRadius; | |
31997 var lw = this.leftDiv.offsetWidth; | |
31998 var rw = this.rightDiv.offsetWidth; | |
31999 this.leftDiv.style.left = (pixel.x - radius - lw - 5) + "px"; | |
32000 this.rightDiv.style.left = (pixel.x + radius + 5) + "px"; | |
32001 var lh = this.leftDiv.offsetHeight; | |
32002 var rh = this.rightDiv.offsetHeight; | |
32003 var lt = pixel.y - lh / 2; | |
32004 var rt = pixel.y - rh / 2; | |
32005 this.leftDiv.style.top = lt + "px"; | |
32006 this.rightDiv.style.top = rt + "px"; | |
32007 }; | |
32008 | |
32009 this.setCanvas = function() { | |
32010 var height = Math.max(this.leftDiv.offsetHeight, this.rightDiv.offsetHeight); | |
32011 var top = Math.min(this.leftDiv.offsetTop, this.rightDiv.offsetTop); | |
32012 var left = this.leftDiv.offsetLeft + this.leftDiv.offsetWidth; | |
32013 this.width = this.rightDiv.offsetLeft - left; | |
32014 this.centerDiv.style.left = left + "px"; | |
32015 this.centerDiv.style.top = top + "px"; | |
32016 this.centerDiv.style.height = height + "px"; | |
32017 this.centerDiv.style.width = this.width + "px"; | |
32018 | |
32019 this.centerDivOl.style.left = left + "px"; | |
32020 this.centerDivOl.style.top = top + "px"; | |
32021 this.centerDivOl.style.height = height + "px"; | |
32022 this.centerDivOl.style.width = this.width + "px"; | |
32023 | |
32024 var cv = document.createElement("canvas"); | |
32025 this.centerDiv.appendChild(cv); | |
32026 if (!cv.getContext && G_vmlCanvasManager) { | |
32027 cv = G_vmlCanvasManager.initElement(cv); | |
32028 } | |
32029 cv.width = this.width; | |
32030 cv.height = height; | |
32031 ctx = cv.getContext('2d'); | |
32032 | |
32033 this.cvOl = document.createElement("canvas"); | |
32034 this.centerDivOl.appendChild(this.cvOl); | |
32035 if (!this.cvOl.getContext && G_vmlCanvasManager) { | |
32036 this.cvOl = G_vmlCanvasManager.initElement(this.cvOl); | |
32037 } | |
32038 this.cvOl.width = this.width; | |
32039 this.cvOl.height = height + 50; | |
32040 this.ctxOl = this.cvOl.getContext('2d'); | |
32041 | |
32042 for (var i = 0; i < this.placeLabels[0].length; i++) { | |
32043 this.placeLabels[0][i].opposite = false; | |
32044 } | |
32045 for (var i = 0; i < this.placeLabels[1].length; i++) { | |
32046 this.placeLabels[1][i].opposite = false; | |
32047 } | |
32048 for (var i = 0; i < this.placeLabels[0].length; i++) { | |
32049 for (var j = 0; j < this.placeLabels[1].length; j++) { | |
32050 if (this.placeLabels[0][i].place == this.placeLabels[1][j].place) { | |
32051 this.drawLine(ctx, this.placeLabels[0][i].div, this.placeLabels[1][j].div); | |
32052 this.placeLabels[0][i].opposite = true; | |
32053 this.placeLabels[1][j].opposite = true; | |
32054 } | |
32055 } | |
32056 } | |
32057 } | |
32058 | |
32059 this.drawLine = function(ctx, label1, label2) { | |
32060 var x1 = 5; | |
32061 var x2 = this.width - 5; | |
32062 var y1 = label1.offsetTop + label1.offsetHeight / 2; | |
32063 var y2 = label2.offsetTop + label2.offsetHeight / 2; | |
32064 if (this.leftDiv.offsetTop > this.rightDiv.offsetTop) { | |
32065 y1 += this.leftDiv.offsetTop - this.rightDiv.offsetTop; | |
32066 } else { | |
32067 y2 += this.rightDiv.offsetTop - this.leftDiv.offsetTop; | |
32068 } | |
32069 ctx.lineCap = 'round'; | |
32070 ctx.lineWidth = 5; | |
32071 ctx.beginPath(); | |
32072 ctx.moveTo(x1, y1); | |
32073 ctx.lineTo(x2, y2); | |
32074 ctx.strokeStyle = '#555'; | |
32075 ctx.stroke(); | |
32076 } | |
32077 | |
32078 this.remove = function() { | |
32079 $(this.leftDiv).remove(); | |
32080 $(this.rightDiv).remove(); | |
32081 $(this.centerDiv).remove(); | |
32082 $(this.centerDivOl).remove(); | |
32083 }; | |
32084 | |
32085 }; | |
32086 /* | |
32087 * MapConfig.js | |
32088 * | |
32089 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
32090 * | |
32091 * This library is free software; you can redistribute it and/or | |
32092 * modify it under the terms of the GNU Lesser General Public | |
32093 * License as published by the Free Software Foundation; either | |
32094 * version 3 of the License, or (at your option) any later version. | |
32095 * | |
32096 * This library is distributed in the hope that it will be useful, | |
32097 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32098 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
32099 * Lesser General Public License for more details. | |
32100 * | |
32101 * You should have received a copy of the GNU Lesser General Public | |
32102 * License along with this library; if not, write to the Free Software | |
32103 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
32104 * MA 02110-1301 USA | |
32105 */ | |
32106 | |
32107 /** | |
32108 * @class MapConfig | |
32109 * Map Configuration File | |
32110 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
32111 * @release 1.0 | |
32112 * @release date: 2012-07-27 | |
32113 * @version date: 2012-07-27 | |
32114 */ | |
32115 function MapConfig(options) { | |
32116 | |
32117 this.options = { | |
32118 mapWidth : false, // false or desired width css definition for the map | |
32119 mapHeight : '580px', // false or desired height css definition for the map | |
32120 mapTitle : 'GeoTemCo Map View', // title will be shown in map header | |
32121 mapIndex : 0, // index = position in location array; for multiple locations the 2nd map refers to index 1 | |
32122 alternativeMap : [ | |
32123 { | |
32124 name: 'Barrington Roman Empire', | |
32125 url: 'http://pelagios.dme.ait.ac.at/tilesets/imperium/${z}/${x}/${y}.png', | |
32126 layer: 'namespace:layerName', | |
32127 type:'XYZ' | |
32128 }, | |
32129 { | |
32130 name: 'Contemporary Map (1994)', | |
32131 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32132 layer: 'historic:cntry1994' | |
32133 }, | |
32134 { | |
32135 name: 'Historical Map of 1945', | |
32136 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32137 layer: 'historic:cntry1945' | |
32138 }, | |
32139 { | |
32140 name: 'Historical Map of 1938', | |
32141 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32142 layer: 'historic:cntry1938' | |
32143 }, | |
32144 { | |
32145 name: 'Historical Map of 1920', | |
32146 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32147 layer: 'historic:cntry1920' | |
32148 }, | |
32149 { | |
32150 name: 'Historical Map of 1914', | |
32151 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32152 layer: 'historic:cntry1914' | |
32153 }, | |
32154 { | |
32155 name: 'Historical Map of 1880', | |
32156 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32157 layer: 'historic:cntry1880' | |
32158 }, | |
32159 { | |
32160 name: 'Historical Map of 1815', | |
32161 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32162 layer: 'historic:cntry1815' | |
32163 }, | |
32164 { | |
32165 name: 'Historical Map of 1783', | |
32166 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32167 layer: 'historic:cntry1783' | |
32168 }, | |
32169 { | |
32170 name: 'Historical Map of 1715', | |
32171 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32172 layer: 'historic:cntry1715' | |
32173 }, | |
32174 { | |
32175 name: 'Historical Map of 1650', | |
32176 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32177 layer: 'historic:cntry1650' | |
32178 }, | |
32179 { | |
32180 name: 'Historical Map of 1530', | |
32181 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32182 layer: 'historic:cntry1530' | |
32183 }, | |
32184 { | |
32185 name: 'Historical Map of 1492', | |
32186 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32187 layer: 'historic:cntry1492' | |
32188 }, | |
32189 { | |
32190 name: 'Historical Map of 1279', | |
32191 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32192 layer: 'historic:cntry1279' | |
32193 }, | |
32194 { | |
32195 name: 'Historical Map of 1000', | |
32196 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32197 layer: 'historic:cntry1000' | |
32198 }, | |
32199 { | |
32200 name: 'Historical Map of 800', | |
32201 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32202 layer: 'historic:cntry800' | |
32203 }, | |
32204 { | |
32205 name: 'Historical Map of 600', | |
32206 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32207 layer: 'historic:cntry600' | |
32208 }, | |
32209 { | |
32210 name: 'Historical Map of 400', | |
32211 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32212 layer: 'historic:cntry400' | |
32213 }, | |
32214 { | |
32215 name: 'Historical Map of 1 BC', | |
32216 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32217 layer: 'historic:cntry1bc' | |
32218 }, | |
32219 { | |
32220 name: 'Historical Map of 200 BC', | |
32221 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32222 layer: 'historic:cntry200bc' | |
32223 }, | |
32224 { | |
32225 name: 'Historical Map of 323 BC', | |
32226 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32227 layer: 'historic:cntry323bc' | |
32228 }, | |
32229 { | |
32230 name: 'Historical Map of 500 BC', | |
32231 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32232 layer: 'historic:cntry500bc' | |
32233 }, | |
32234 { | |
32235 name: 'Historical Map of 1000 BC', | |
32236 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32237 layer: 'historic:cntry1000bc' | |
32238 }, | |
32239 { | |
32240 name: 'Historical Map of 2000 BC', | |
32241 url: 'http://dev2.dariah.eu/geoserver/wms', | |
32242 layer: 'historic:cntry2000bc' | |
32243 }, | |
32244 ], | |
32245 legend : true, // if a legend at the bottom of the map should be shown or not | |
32246 mapMerge : false, // if the elements of distinct datasets should be merged into one set or not | |
32247 useGraphics : false, // if different graphics should represent different datasets or not | |
32248 graphics : [ | |
32249 { | |
32250 shape: "circle", | |
32251 rotation: 0 | |
32252 }, | |
32253 { | |
32254 shape: "square", | |
32255 rotation: 0 | |
32256 }, | |
32257 { | |
32258 shape: "triangle", | |
32259 rotation: 0 | |
32260 }, | |
32261 { | |
32262 shape: "square", | |
32263 rotation: 45 | |
32264 } | |
32265 ], | |
32266 googleMaps : false, // enable/disable Google maps (actually, no Google Maps API key is required) | |
32267 bingMaps : false, // enable/disable Bing maps (you need to set the Bing Maps API key below) | |
32268 bingApiKey : 'none', // bing maps api key, see informations at http://bingmapsportal.com/ | |
32269 osmMaps : true, // enable/disable OSM maps | |
32270 osmMapsMapQuest : true, // enable/disable OSM maps with MapQuest tiles | |
32271 baseLayer : 'Open Street Map', // initial layer to show (e.g. 'Google Streets') | |
32272 resetMap : true, // show/hide map reset button | |
32273 countrySelect : true, // show/hide map country selection control button | |
32274 polygonSelect : true, // show/hide map polygon selection control button | |
32275 circleSelect : true, // show/hide map circle selection control button | |
32276 squareSelect : true, // show/hide map square selection control button | |
32277 multiSelection : true, // true, if multiple polygons or multiple circles should be selectable | |
32278 popups : true, // enabled popups will show popup windows for circles on the map | |
32279 olNavigation : false, // show/hide OpenLayers navigation panel | |
32280 olLayerSwitcher : false, // show/hide OpenLayers layer switcher | |
32281 olMapOverview : false, // show/hide OpenLayers map overview | |
32282 olKeyboardDefaults : true, // (de)activate Openlayers keyboard defaults | |
32283 olScaleLine : false, // (de)activate Openlayers keyboard defaults | |
32284 geoLocation : true, // show/hide GeoLocation feature | |
32285 boundaries : { | |
32286 minLon : -29, | |
32287 minLat : 35, | |
32288 maxLon : 44, | |
32289 maxLat : 67 | |
32290 }, // initial map boundaries or 'false' for no boundaries | |
32291 mapBackground : '#bbd0ed', | |
32292 labelGrid : true, // show label grid on hover | |
32293 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) | |
32294 selectDefault : true, // true, if strongest label should be selected as default | |
32295 maxLabelIncrease : 2, // maximum increase (in em) for the font size of a label | |
32296 labelHover : false, // true, to update on label hover | |
32297 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 | |
32298 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 | |
32299 ieSelectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label in IE | |
32300 selectedLabel : "color: COLOR1; font-weight: bold;", // css code for a selected place label | |
32301 ieUnselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label in IE | |
32302 unselectedLabel : "color: COLOR1; font-weight: normal;", // css code for an unselected place label | |
32303 ieHoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label in IE | |
32304 hoveredLabel : "color: COLOR1; font-weight: bold;", // css code for a hovered place label | |
32305 circleGap : 0, // gap between the circles on the map (>=0) | |
32306 circleOverlap : { | |
32307 type: 'area', // 'area' or 'diameter' is possible | |
32308 overlap: 0 // the percentage of allowed overlap (0<=overlap<=1) | |
32309 }, // maximum allowed overlap in percent (if circleGap = 0, circleOverlap will be used) | |
32310 minimumRadius : 4, // minimum radius of a circle with mimimal weight (>0) | |
32311 circleOutline : 2, // false for no outline or a pixel value v with 0 < v | |
32312 circleOpacity : 'balloon', // 'balloon' for dynamic opacity of the circles or a value t with 0 <= t <= 1 | |
32313 minTransparency : 0.55, // maximum transparency of a circle | |
32314 maxTransparency : 0.8, // minimum transparency of a circle | |
32315 binning : 'generic', // binning algorithm for the map, possible values are: 'generic', 'square', 'hexagonal', 'triangular' or false for 'no binning' | |
32316 noBinningRadii : 'dynamic', // for 'no binning': 'static' for only minimum radii, 'dynamic' for increasing radii for increasing weights | |
32317 circlePackings : true, // if circles of multiple result sets should be displayed in circle packs, if a binning is performed | |
32318 binCount : 10, // number of bins for x and y dimension for lowest zoom level | |
32319 showDescriptions : true, // true to show descriptions of data items (must be provided by kml/json), false if not | |
32320 mapSelection : true, // show/hide select map dropdown | |
32321 binningSelection : false, // show/hide binning algorithms dropdown | |
32322 mapSelectionTools : true, // show/hide map selector tools | |
32323 dataInformation : true, // show/hide data information | |
32324 overlayVisibility : false, // initial visibility of additional overlays | |
32325 proxyHost : 'php/proxy.php?address=', //required for selectCountry feature, if the requested GeoServer and GeoTemCo are NOT on the same server | |
32326 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 | |
32327 | |
32328 }; | |
32329 if ( typeof options != 'undefined') { | |
32330 $.extend(this.options, options); | |
32331 } | |
32332 | |
32333 }; | |
32334 | |
32335 MapConfig.prototype.getGraphic = function(id){ | |
32336 var graphic = this.options.graphics[id % this.options.graphics.length]; | |
32337 return { | |
32338 shape: graphic.shape, | |
32339 rotation: graphic.rotation, | |
32340 color: GeoTemConfig.getColor(Math.floor(id/this.options.graphics.length)) | |
32341 }; | |
32342 }; | |
32343 /* | |
32344 * MapGui.js | |
32345 * | |
32346 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
32347 * | |
32348 * This library is free software; you can redistribute it and/or | |
32349 * modify it under the terms of the GNU Lesser General Public | |
32350 * License as published by the Free Software Foundation; either | |
32351 * version 3 of the License, or (at your option) any later version. | |
32352 * | |
32353 * This library is distributed in the hope that it will be useful, | |
32354 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32355 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
32356 * Lesser General Public License for more details. | |
32357 * | |
32358 * You should have received a copy of the GNU Lesser General Public | |
32359 * License along with this library; if not, write to the Free Software | |
32360 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
32361 * MA 02110-1301 USA | |
32362 */ | |
32363 | |
32364 /** | |
32365 * @class MapGui | |
32366 * Map GUI Implementation | |
32367 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
32368 * @release 1.0 | |
32369 * @release date: 2012-07-27 | |
32370 * @version date: 2012-07-27 | |
32371 * | |
32372 * @param {MapWidget} parent map widget object | |
32373 * @param {HTML object} div parent div to append the map gui | |
32374 * @param {JSON} options map configuration | |
32375 */ | |
32376 function MapGui(map, div, options, iid) { | |
32377 | |
32378 this.map = map; | |
32379 | |
32380 this.container = div; | |
32381 if (options.mapWidth) { | |
32382 this.container.style.width = options.mapWidth; | |
32383 } | |
32384 if (options.mapHeight) { | |
32385 this.container.style.height = options.mapHeight; | |
32386 } | |
32387 this.container.style.position = 'relative'; | |
32388 | |
32389 this.mapWindow = document.createElement("div"); | |
32390 this.mapWindow.setAttribute('class', 'mapWindow'); | |
32391 this.mapWindow.id = "mapWindow"+iid; | |
32392 this.mapWindow.style.background = options.mapBackground; | |
32393 this.container.appendChild(this.mapWindow); | |
32394 | |
32395 this.mapContainer = document.createElement("div"); | |
32396 this.mapContainer.setAttribute('class', 'mapContainer'); | |
32397 this.mapContainer.id = "mapContainer"+iid; | |
32398 this.mapContainer.style.position = "absolute"; | |
32399 this.mapContainer.style.zIndex = 0; | |
32400 this.mapWindow.appendChild(this.mapContainer); | |
32401 | |
32402 var toolbarTable = document.createElement("table"); | |
32403 toolbarTable.setAttribute('class', 'absoluteToolbar ddbToolbar'); | |
32404 this.container.appendChild(toolbarTable); | |
32405 this.mapToolbar = toolbarTable; | |
32406 | |
32407 var titles = document.createElement("tr"); | |
32408 toolbarTable.appendChild(titles); | |
32409 var tools = document.createElement("tr"); | |
32410 toolbarTable.appendChild(tools); | |
32411 | |
32412 if (options.mapSelection) { | |
32413 this.mapTypeTitle = document.createElement("td"); | |
32414 titles.appendChild(this.mapTypeTitle); | |
32415 this.mapTypeTitle.innerHTML = GeoTemConfig.getString('mapType'); | |
32416 this.mapTypeSelector = document.createElement("td"); | |
32417 tools.appendChild(this.mapTypeSelector); | |
32418 } | |
32419 | |
32420 if (options.mapSelectionTools) { | |
32421 this.mapSelectorTitle = document.createElement("td"); | |
32422 titles.appendChild(this.mapSelectorTitle); | |
32423 this.mapSelectorTitle.innerHTML = GeoTemConfig.getString('mapSelectorTools'); | |
32424 var mapSelectorTools = document.createElement("td"); | |
32425 var selectorTools = this.map.initSelectorTools(); | |
32426 for (var i in selectorTools ) { | |
32427 mapSelectorTools.appendChild(selectorTools[i].button); | |
32428 } | |
32429 tools.appendChild(mapSelectorTools); | |
32430 } | |
32431 | |
32432 if (options.binningSelection) { | |
32433 this.binningTitle = document.createElement("td"); | |
32434 titles.appendChild(this.binningTitle); | |
32435 this.binningTitle.innerHTML = GeoTemConfig.getString('binningType'); | |
32436 this.binningSelector = document.createElement("td"); | |
32437 tools.appendChild(this.binningSelector); | |
32438 } | |
32439 | |
32440 if (GeoTemConfig.allowFilter) { | |
32441 this.filterTitle = document.createElement("td"); | |
32442 titles.appendChild(this.filterTitle); | |
32443 this.filterTitle.innerHTML = GeoTemConfig.getString('filter'); | |
32444 this.filterOptions = document.createElement("td"); | |
32445 tools.appendChild(this.filterOptions); | |
32446 } | |
32447 | |
32448 if (options.dataInformation) { | |
32449 this.infoTitle = document.createElement("td"); | |
32450 this.infoTitle.innerHTML = options.mapTitle; | |
32451 titles.appendChild(this.infoTitle); | |
32452 var mapSum = document.createElement("td"); | |
32453 this.mapElements = document.createElement("div"); | |
32454 this.mapElements.setAttribute('class', 'ddbElementsCount'); | |
32455 mapSum.appendChild(this.mapElements); | |
32456 tools.appendChild(mapSum); | |
32457 } | |
32458 | |
32459 var gui = this; | |
32460 if (navigator.geolocation && options.geoLocation) { | |
32461 this.geoActive = false; | |
32462 this.geoLocation = document.createElement("div"); | |
32463 this.geoLocation.setAttribute('class', 'geoLocationOff'); | |
32464 this.geoLocation.title = GeoTemConfig.getString('activateGeoLocation'); | |
32465 this.container.appendChild(this.geoLocation); | |
32466 this.geoLocation.style.left = "20px"; | |
32467 this.geoLocation.onclick = function() { | |
32468 var changeStyle = function() { | |
32469 if (gui.geoActive) { | |
32470 gui.geoLocation.setAttribute('class', 'geoLocationOn'); | |
32471 gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'deactivateGeoLocation'); | |
32472 } else { | |
32473 gui.geoLocation.setAttribute('class', 'geoLocationOff'); | |
32474 gui.geoLocation.title = GeoTemConfig.getString(GeoTemConfig.language, 'activateGeoLocation'); | |
32475 } | |
32476 } | |
32477 if (!gui.geoActive) { | |
32478 if ( typeof gui.longitude == 'undefined') { | |
32479 navigator.geolocation.getCurrentPosition(function(position) { | |
32480 gui.longitude = position.coords.longitude; | |
32481 gui.latitude = position.coords.latitude; | |
32482 gui.map.setMarker(gui.longitude, gui.latitude); | |
32483 gui.geoActive = true; | |
32484 changeStyle(); | |
32485 }, function(msg) { | |
32486 console.log( typeof msg == 'string' ? msg : "error"); | |
32487 }); | |
32488 } else { | |
32489 gui.map.setMarker(gui.longitude, gui.latitude); | |
32490 gui.geoActive = true; | |
32491 changeStyle(); | |
32492 } | |
32493 } else { | |
32494 gui.map.removeMarker(); | |
32495 gui.geoActive = false; | |
32496 changeStyle(); | |
32497 } | |
32498 } | |
32499 } | |
32500 | |
32501 if (!options.olNavigation) { | |
32502 this.map.zoomSlider = new MapZoomSlider(this.map, "vertical"); | |
32503 this.container.appendChild(this.map.zoomSlider.div); | |
32504 this.map.zoomSlider.div.style.left = "20px"; | |
32505 } | |
32506 | |
32507 if (options.resetMap) { | |
32508 this.homeButton = document.createElement("div"); | |
32509 this.homeButton.setAttribute('class', 'mapHome'); | |
32510 this.homeButton.title = GeoTemConfig.getString('home'); | |
32511 this.container.appendChild(this.homeButton); | |
32512 this.homeButton.style.left = "20px"; | |
32513 this.homeButton.onclick = function() { | |
32514 if (map.mds.getAllObjects() == null){ | |
32515 map.openlayersMap.setCenter(new OpenLayers.LonLat(0, 0)); | |
32516 map.openlayersMap.zoomTo(0); | |
32517 } | |
32518 gui.map.drawObjectLayer(true); | |
32519 } | |
32520 } | |
32521 | |
32522 if (options.legend) { | |
32523 this.legendDiv = document.createElement("div"); | |
32524 this.legendDiv.setAttribute('class', 'mapLegend'); | |
32525 this.mapWindow.appendChild(this.legendDiv); | |
32526 } | |
32527 | |
32528 var linkForOsm = 'http://www.openstreetmap.org/'; | |
32529 var linkForLicense = 'http://creativecommons.org/licenses/by-sa/2.0/'; | |
32530 this.osmLink = document.createElement("div"); | |
32531 this.osmLink.setAttribute('class', 'osmLink'); | |
32532 this.osmLink.innerHTML = '(c) <a href=' + linkForOsm + '>OpenStreetMap contributors</a>, <a href=' + linkForLicense + '>CC-BY-SA</a>'; | |
32533 this.mapWindow.appendChild(this.osmLink); | |
32534 this.osmMapQuestLink = document.createElement("div"); | |
32535 this.osmMapQuestLink.setAttribute('class', 'osmLink'); | |
32536 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>'; | |
32537 this.mapWindow.appendChild(this.osmMapQuestLink); | |
32538 | |
32539 // var tooltip = document.createElement("div"); | |
32540 // tooltip.setAttribute('class','ddbTooltip'); | |
32541 // toolbarTable.appendChild(tooltip); | |
32542 | |
32543 // var tooltip = document.createElement("div"); | |
32544 // tooltip.setAttribute('class','ddbTooltip'); | |
32545 // toolbarTable.appendChild(tooltip); | |
32546 // | |
32547 // tooltip.onmouseover = function(){ | |
32548 // /* | |
32549 // Publisher.Publish('TooltipContent', { | |
32550 // content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'), | |
32551 // target: $(tooltip) | |
32552 // }); | |
32553 // */ | |
32554 // } | |
32555 // tooltip.onmouseout = function(){ | |
32556 // // Publisher.Publish('TooltipContent'); | |
32557 // } | |
32558 // //vhz tooltip on click should open a help file if defined in GeoTemConfig | |
32559 // if(GeoTemConfig.helpURL) { | |
32560 // tooltip.onclick = function () { | |
32561 // | |
32562 // } | |
32563 // } | |
32564 | |
32565 // } | |
32566 // tooltip.onmouseout = function(){ | |
32567 // Publisher.Publish('TooltipContent'); | |
32568 // } | |
32569 | |
32570 this.resize = function() { | |
32571 var w = this.container.offsetWidth; | |
32572 var h = this.container.offsetHeight; | |
32573 // this.mapWindow.style.width = w + "px"; | |
32574 this.mapWindow.style.height = h + "px"; | |
32575 // this.mapContainer.style.width = w + "px"; | |
32576 this.mapContainer.style.height = h + "px"; | |
32577 var top = toolbarTable.offsetHeight + 20; | |
32578 if (options.olLayerSwitcher) { | |
32579 var switcherDiv = $('.olControlLayerSwitcher')[0]; | |
32580 $(switcherDiv).css('top', top + "px"); | |
32581 } | |
32582 if ( typeof this.geoLocation != "undefined") { | |
32583 this.geoLocation.style.top = top + "px"; | |
32584 top += this.geoLocation.offsetHeight + 4; | |
32585 } | |
32586 if (options.olNavigation) { | |
32587 var panZoomBar = $('.olControlPanZoom')[0]; | |
32588 $(panZoomBar).css('top', top + 'px'); | |
32589 $(panZoomBar).css('left', '12px'); | |
32590 var zoomOut = document.getElementById('OpenLayers.Control.PanZoom_23_zoomout'); | |
32591 top += $(zoomOut).height() + $(zoomOut).position().top + 4; | |
32592 } else { | |
32593 this.map.zoomSlider.div.style.top = top + "px"; | |
32594 top += this.map.zoomSlider.div.offsetHeight + 2; | |
32595 } | |
32596 if (options.resetMap) { | |
32597 this.homeButton.style.top = top + "px"; | |
32598 } | |
32599 this.headerHeight = toolbarTable.offsetHeight; | |
32600 this.headerWidth = toolbarTable.offsetWidth; | |
32601 this.map.openlayersMap.updateSize(); | |
32602 this.map.drawObjectLayer(true); | |
32603 }; | |
32604 | |
32605 this.updateLegend = function(datasets){ | |
32606 $(this.legendDiv).empty(); | |
32607 var table = $('<table style="margin:10px"/>').appendTo(this.legendDiv); | |
32608 for( var i=0; i<datasets.length; i++ ){ | |
32609 var row = $('<tr/>').appendTo(table); | |
32610 if( options.useGraphics ){ | |
32611 var graphic = map.config.getGraphic(i); | |
32612 var fill = 'rgb(' + graphic.color.r0 + ',' + graphic.color.g0 + ',' + graphic.color.b0 + ')'; | |
32613 var stroke = 'rgb(' + graphic.color.r1 + ',' + graphic.color.g1 + ',' + graphic.color.b1 + ')'; | |
32614 var rot = graphic.rotation; | |
32615 var svg; | |
32616 if( graphic.shape == 'circle' ){ | |
32617 svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>'; | |
32618 } | |
32619 else if( graphic.shape == 'square' ){ | |
32620 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>'; | |
32621 } | |
32622 else if( graphic.shape == 'triangle' ){ | |
32623 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>'; | |
32624 } | |
32625 $('<td>'+svg+'</td>').appendTo(row); | |
32626 } | |
32627 else { | |
32628 var c = GeoTemConfig.getColor(i); | |
32629 var fill = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
32630 var stroke = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
32631 var svg = '<svg style="width:20px;height:20px;"><circle cx="10" cy="10" r="7" stroke="'+stroke+'" stroke-width="2" fill="'+fill+'"/></svg>'; | |
32632 $('<td>'+svg+'</td>').appendTo(row); | |
32633 } | |
32634 $('<td>'+datasets[i].label+'</td>').appendTo(row); | |
32635 } | |
32636 }; | |
32637 | |
32638 this.updateSpaceQuantity = function(count) { | |
32639 if (!options.dataInformation) { | |
32640 return; | |
32641 } | |
32642 this.mapCount = count; | |
32643 if (count != 1) { | |
32644 this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results'); | |
32645 } else { | |
32646 this.mapElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result'); | |
32647 } | |
32648 } | |
32649 | |
32650 this.setMapsDropdown = function() { | |
32651 if (!options.mapSelection) { | |
32652 return; | |
32653 } | |
32654 $(this.mapTypeSelector).empty(); | |
32655 var maps = []; | |
32656 var gui = this; | |
32657 var addMap = function(name, index) { | |
32658 var setMap = function() { | |
32659 gui.map.setMap(index); | |
32660 } | |
32661 maps.push({ | |
32662 name : name, | |
32663 onclick : setMap | |
32664 }); | |
32665 } | |
32666 for (var i = 0; i < this.map.baseLayers.length; i++) { | |
32667 addMap(this.map.baseLayers[i].name, i); | |
32668 } | |
32669 this.mapTypeDropdown = new Dropdown(this.mapTypeSelector, maps, GeoTemConfig.getString('selectMapType')); | |
32670 } | |
32671 | |
32672 this.setMap = function() { | |
32673 if (options.mapSelection) { | |
32674 this.mapTypeDropdown.setEntry(this.map.baselayerIndex); | |
32675 } | |
32676 } | |
32677 | |
32678 this.setBinningDropdown = function() { | |
32679 if (!options.binningSelection) { | |
32680 return; | |
32681 } | |
32682 $(this.binningSelector).empty(); | |
32683 var binnings = []; | |
32684 var gui = this; | |
32685 var index = 0; | |
32686 var entry; | |
32687 var addBinning = function(name, id) { | |
32688 if (options.binning == id) { | |
32689 entry = index; | |
32690 } else { | |
32691 index++; | |
32692 } | |
32693 var setBinning = function() { | |
32694 options.binning = id; | |
32695 gui.map.initWidget(gui.map.datasets, false); | |
32696 gui.map.riseLayer(); | |
32697 } | |
32698 binnings.push({ | |
32699 name : name, | |
32700 onclick : setBinning | |
32701 }); | |
32702 } | |
32703 addBinning(GeoTemConfig.getString('genericBinning'), 'generic'); | |
32704 addBinning(GeoTemConfig.getString('squareBinning'), 'square'); | |
32705 addBinning(GeoTemConfig.getString('hexagonalBinning'), 'hexagonal'); | |
32706 addBinning(GeoTemConfig.getString('triangularBinning'), 'triangular'); | |
32707 addBinning(GeoTemConfig.getString('noBinning'), false); | |
32708 var binningDropdown = new Dropdown(this.binningSelector, binnings, GeoTemConfig.getString('binningTooltip')); | |
32709 binningDropdown.setEntry(entry); | |
32710 } | |
32711 this.setBinningDropdown(); | |
32712 | |
32713 this.beautifyCount = function(count) { | |
32714 var c = count + ''; | |
32715 var p = 0; | |
32716 var l = c.length; | |
32717 while (l - p > 3) { | |
32718 p += 3; | |
32719 c = c.substring(0, l - p) + "." + c.substring(l - p); | |
32720 p++; | |
32721 l++; | |
32722 } | |
32723 return c; | |
32724 } | |
32725 | |
32726 }; | |
32727 /* | |
32728 * MapWidget.js | |
32729 * | |
32730 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
32731 * | |
32732 * This library is free software; you can redistribute it and/or | |
32733 * modify it under the terms of the GNU Lesser General Public | |
32734 * License as published by the Free Software Foundation; either | |
32735 * version 3 of the License, or (at your option) any later version. | |
32736 * | |
32737 * This library is distributed in the hope that it will be useful, | |
32738 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32739 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
32740 * Lesser General Public License for more details. | |
32741 * | |
32742 * You should have received a copy of the GNU Lesser General Public | |
32743 * License along with this library; if not, write to the Free Software | |
32744 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
32745 * MA 02110-1301 USA | |
32746 */ | |
32747 | |
32748 /** | |
32749 * @class MapWidget | |
32750 * MapWidget Implementation | |
32751 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
32752 * @release 1.0 | |
32753 * @release date: 2012-07-27 | |
32754 * @version date: 2012-07-27 | |
32755 * | |
32756 * @param {MapWrapper} core wrapper for interaction to other widgets | |
32757 * @param {HTML object} div parent div to append the map widget div | |
32758 * @param {JSON} options user specified configuration that overwrites options in MapConfig.js | |
32759 */ | |
32760 MapWidget = function(core, div, options) { | |
32761 | |
32762 this.core = core; | |
32763 this.core.setWidget(this); | |
32764 this.openlayersMap | |
32765 this.baseLayers | |
32766 this.objectLayer | |
32767 | |
32768 this.drawPolygon | |
32769 this.drawCircle | |
32770 this.selectCountry | |
32771 this.dragArea | |
32772 this.selectFeature | |
32773 this.navigation | |
32774 | |
32775 this.div = div; | |
32776 | |
32777 this.iid = GeoTemConfig.getIndependentId('map'); | |
32778 this.config = new MapConfig(options); | |
32779 this.options = this.config.options; | |
32780 this.formerCP = this.options.circlePackings; | |
32781 this.gui = new MapGui(this, this.div, this.options, this.iid); | |
32782 | |
32783 this.initialize(); | |
32784 | |
32785 } | |
32786 | |
32787 MapWidget.prototype = { | |
32788 | |
32789 /** | |
32790 * initializes the map for the Spatio Temporal Interface. | |
32791 * it includes setting up all layers of the map and defines all map specific interaction possibilities | |
32792 */ | |
32793 initialize : function() { | |
32794 | |
32795 var map = this; | |
32796 | |
32797 //OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url="; | |
32798 if (map.options.proxyHost) { | |
32799 OpenLayers.ProxyHost = map.options.proxyHost; | |
32800 } | |
32801 | |
32802 this.polygons = []; | |
32803 this.connections = []; | |
32804 this.selection = new Selection(); | |
32805 this.wmsOverlays = []; | |
32806 | |
32807 this.layerZIndex = 1; | |
32808 this.zIndices = []; | |
32809 | |
32810 var activateDrag = function() { | |
32811 map.dragArea.activate(); | |
32812 } | |
32813 var deactivateDrag = function() { | |
32814 map.dragArea.deactivate(); | |
32815 } | |
32816 this.dragControl = new MapControl(this, null, 'drag', activateDrag, deactivateDrag); | |
32817 | |
32818 /* | |
32819 this.editPolygon = document.createElement("div"); | |
32820 this.editPolygon.title = GeoTemConfig.getString('editPolygon'); | |
32821 this.editPolygon.setAttribute('class','editMapPolygon'); | |
32822 this.toolbar.appendChild(this.editPolygon); | |
32823 this.drag.onclick = function(evt){ | |
32824 if( map.activeControl == "drag" ){ | |
32825 map.deactivate("drag"); | |
32826 if( GeoTemConfig.navigate ){ | |
32827 map.activate("navigate"); | |
32828 } | |
32829 } | |
32830 else { | |
32831 map.deactivate(map.activControl); | |
32832 map.activate("drag"); | |
32833 } | |
32834 } | |
32835 map.addEditingMode(new OpenLayers.Control.EditingMode.PointArraySnapping()); | |
32836 */ | |
32837 | |
32838 this.filterBar = new FilterBar(this, this.gui.filterOptions); | |
32839 | |
32840 this.objectLayer = new OpenLayers.Layer.Vector("Data Objects", { | |
32841 projection : "EPSG:4326", | |
32842 'displayInLayerSwitcher' : false, | |
32843 rendererOptions : { | |
32844 zIndexing : true | |
32845 } | |
32846 }); | |
32847 | |
32848 this.markerLayer = new OpenLayers.Layer.Markers("Markers"); | |
32849 | |
32850 this.navigation = new OpenLayers.Control.Navigation({ | |
32851 zoomWheelEnabled : GeoTemConfig.mouseWheelZoom | |
32852 }); | |
32853 this.navigation.defaultDblClick = function(evt) { | |
32854 var newCenter = this.map.getLonLatFromViewPortPx(evt.xy); | |
32855 this.map.setCenter(newCenter, this.map.zoom + 1); | |
32856 map.drawObjectLayer(false); | |
32857 if (map.zoomSlider) { | |
32858 map.zoomSlider.setValue(map.openlayersMap.getZoom()); | |
32859 } | |
32860 } | |
32861 this.navigation.wheelUp = function(evt) { | |
32862 this.wheelChange(evt, 1); | |
32863 map.drawObjectLayer(false); | |
32864 if (map.zoomSlider) { | |
32865 map.zoomSlider.setValue(map.openlayersMap.getZoom()); | |
32866 } | |
32867 map.core.triggerHighlight([]); | |
32868 } | |
32869 this.navigation.wheelDown = function(evt) { | |
32870 this.wheelChange(evt, -1); | |
32871 map.drawObjectLayer(false); | |
32872 if (map.zoomSlider) { | |
32873 map.zoomSlider.setValue(map.openlayersMap.getZoom()); | |
32874 } | |
32875 map.core.triggerHighlight([]); | |
32876 } | |
32877 | |
32878 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]; | |
32879 | |
32880 var options = { | |
32881 controls : [this.navigation], | |
32882 projection : new OpenLayers.Projection("EPSG:900913"), | |
32883 displayProjection : new OpenLayers.Projection("EPSG:4326"), | |
32884 resolutions : this.resolutions, | |
32885 units : 'meters', | |
32886 maxExtent : new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34) | |
32887 }; | |
32888 this.openlayersMap = new OpenLayers.Map("mapContainer"+this.iid, options); | |
32889 if (map.options.navigate) { | |
32890 this.activeControl = "navigate"; | |
32891 } | |
32892 this.mds = new MapDataSource(this.openlayersMap, this.options); | |
32893 | |
32894 if (map.options.olNavigation) { | |
32895 var zoomPanel = new OpenLayers.Control.PanZoom(); | |
32896 zoomPanel.onButtonClick = function(evt) { | |
32897 var btn = evt.buttonElement; | |
32898 switch (btn.action) { | |
32899 case "panup": | |
32900 this.map.pan(0, -this.getSlideFactor("h")); | |
32901 break; | |
32902 case "pandown": | |
32903 this.map.pan(0, this.getSlideFactor("h")); | |
32904 break; | |
32905 case "panleft": | |
32906 this.map.pan(-this.getSlideFactor("w"), 0); | |
32907 break; | |
32908 case "panright": | |
32909 this.map.pan(this.getSlideFactor("w"), 0); | |
32910 break; | |
32911 case "zoomin": | |
32912 map.zoom(1); | |
32913 break; | |
32914 case "zoomout": | |
32915 map.zoom(-1); | |
32916 break; | |
32917 case "zoomworld": | |
32918 if (this.map) { | |
32919 map.zoom(this.map.zoom * -1); | |
32920 } | |
32921 break; | |
32922 } | |
32923 }; | |
32924 this.openlayersMap.addControl(zoomPanel); | |
32925 } | |
32926 | |
32927 if (map.options.popups) { | |
32928 var panMap = function() { | |
32929 if (map.selectedGlyph) { | |
32930 var lonlat = new OpenLayers.LonLat(map.selectedGlyph.lon, map.selectedGlyph.lat); | |
32931 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
32932 if (map.popup) { | |
32933 map.popup.shift(pixel.x, pixel.y); | |
32934 } | |
32935 } | |
32936 } | |
32937 this.openlayersMap.events.register("move", this.openlayersMap, panMap); | |
32938 } | |
32939 | |
32940 if (map.options.olMapOverview) { | |
32941 this.openlayersMap.addControl(new OpenLayers.Control.OverviewMap()); | |
32942 } | |
32943 if (map.options.olKeyboardDefaults) { | |
32944 var keyboardControl = new OpenLayers.Control.KeyboardDefaults(); | |
32945 keyboardControl.defaultKeyPress = function(evt) { | |
32946 switch(evt.keyCode) { | |
32947 case OpenLayers.Event.KEY_LEFT: | |
32948 this.map.pan(-this.slideFactor, 0); | |
32949 break; | |
32950 case OpenLayers.Event.KEY_RIGHT: | |
32951 this.map.pan(this.slideFactor, 0); | |
32952 break; | |
32953 case OpenLayers.Event.KEY_UP: | |
32954 this.map.pan(0, -this.slideFactor); | |
32955 break; | |
32956 case OpenLayers.Event.KEY_DOWN: | |
32957 this.map.pan(0, this.slideFactor); | |
32958 break; | |
32959 | |
32960 case 33: | |
32961 // Page Up. Same in all browsers. | |
32962 var size = this.map.getSize(); | |
32963 this.map.pan(0, -0.75 * size.h); | |
32964 break; | |
32965 case 34: | |
32966 // Page Down. Same in all browsers. | |
32967 var size = this.map.getSize(); | |
32968 this.map.pan(0, 0.75 * size.h); | |
32969 break; | |
32970 case 35: | |
32971 // End. Same in all browsers. | |
32972 var size = this.map.getSize(); | |
32973 this.map.pan(0.75 * size.w, 0); | |
32974 break; | |
32975 case 36: | |
32976 // Home. Same in all browsers. | |
32977 var size = this.map.getSize(); | |
32978 this.map.pan(-0.75 * size.w, 0); | |
32979 break; | |
32980 | |
32981 case 43: | |
32982 // +/= (ASCII), keypad + (ASCII, Opera) | |
32983 case 61: | |
32984 // +/= (Mozilla, Opera, some ASCII) | |
32985 case 187: | |
32986 // +/= (IE) | |
32987 case 107: | |
32988 // keypad + (IE, Mozilla) | |
32989 map.zoom(1); | |
32990 break; | |
32991 case 45: | |
32992 // -/_ (ASCII, Opera), keypad - (ASCII, Opera) | |
32993 case 109: | |
32994 // -/_ (Mozilla), keypad - (Mozilla, IE) | |
32995 case 189: | |
32996 // -/_ (IE) | |
32997 case 95: | |
32998 // -/_ (some ASCII) | |
32999 map.zoom(-1); | |
33000 break; | |
33001 } | |
33002 }; | |
33003 this.openlayersMap.addControl(keyboardControl); | |
33004 } | |
33005 if (map.options.olLayerSwitcher) { | |
33006 this.openlayersMap.addControl(new OpenLayers.Control.LayerSwitcher()); | |
33007 } | |
33008 if (map.options.olScaleLine) { | |
33009 this.openlayersMap.addControl(new OpenLayers.Control.ScaleLine()); | |
33010 } | |
33011 this.gui.resize(); | |
33012 this.setBaseLayers(); | |
33013 this.gui.setMapsDropdown(); | |
33014 this.gui.setMap(); | |
33015 this.openlayersMap.addLayers([this.objectLayer, this.markerLayer]); | |
33016 | |
33017 if (map.options.boundaries) { | |
33018 var boundaries = map.options.boundaries; | |
33019 var bounds = new OpenLayers.Bounds(boundaries.minLon, boundaries.minLat, boundaries.maxLon, boundaries.maxLat); | |
33020 var projectionBounds = bounds.transform(this.openlayersMap.displayProjection, this.openlayersMap.projection); | |
33021 this.openlayersMap.zoomToExtent(projectionBounds); | |
33022 } else { | |
33023 this.openlayersMap.zoomToMaxExtent(); | |
33024 } | |
33025 | |
33026 // manages selection of elements if a polygon was drawn | |
33027 this.drawnPolygonHandler = function(polygon) { | |
33028 if (map.mds.getAllObjects() == null) { | |
33029 return; | |
33030 } | |
33031 var polygonFeature; | |
33032 if ( polygon instanceof OpenLayers.Geometry.Polygon) { | |
33033 polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPolygon([polygon])); | |
33034 } else if ( polygon instanceof OpenLayers.Geometry.MultiPolygon) { | |
33035 polygonFeature = new OpenLayers.Feature.Vector(polygon); | |
33036 } | |
33037 map.polygons.push(polygonFeature); | |
33038 var style = $.extend(true, {}, OpenLayers.Feature.Vector.style['default']); | |
33039 style.graphicZIndex = 0; | |
33040 polygonFeature.style = style; | |
33041 map.objectLayer.addFeatures([polygonFeature]); | |
33042 try { | |
33043 map.activeControl.deactivate(); | |
33044 } catch(e) { | |
33045 } | |
33046 var circles = map.mds.getObjectsByZoom(); | |
33047 for (var i = 0; i < circles.length; i++) { | |
33048 for (var j = 0; j < circles[i].length; j++) { | |
33049 var c = circles[i][j]; | |
33050 if (map.inPolygon(c)) { | |
33051 if ( typeof c.fatherBin != 'undefined') { | |
33052 for (var k = 0; k < c.fatherBin.circles.length; k++) { | |
33053 if (c.fatherBin.circles[k]) { | |
33054 c.fatherBin.circles[k].setSelection(true); | |
33055 } | |
33056 } | |
33057 } else { | |
33058 c.setSelection(true); | |
33059 } | |
33060 } | |
33061 } | |
33062 } | |
33063 map.mapSelection(); | |
33064 } | |
33065 | |
33066 this.polygonDeselection = function() { | |
33067 var circles = map.mds.getObjectsByZoom(); | |
33068 for (var i = 0; i < circles.length; i++) { | |
33069 for (var j = 0; j < circles[i].length; j++) { | |
33070 var c = circles[i][j]; | |
33071 if (map.inPolygon(c)) { | |
33072 c.setSelection(false); | |
33073 } | |
33074 } | |
33075 } | |
33076 } | |
33077 this.snapper = function() { | |
33078 if (map.polygons.length == 0 || !map.options.multiSelection) { | |
33079 map.deselection(); | |
33080 } | |
33081 } | |
33082 if (map.options.polygonSelect) { | |
33083 this.drawPolygon = new OpenLayers.Control.DrawFeature(map.objectLayer, OpenLayers.Handler.Polygon, { | |
33084 displayClass : "olControlDrawFeaturePolygon", | |
33085 callbacks : { | |
33086 "done" : map.drawnPolygonHandler, | |
33087 "create" : map.snapper | |
33088 } | |
33089 }); | |
33090 this.openlayersMap.addControl(this.drawPolygon); | |
33091 } | |
33092 | |
33093 if (map.options.circleSelect) { | |
33094 this.drawCircle = new OpenLayers.Control.DrawFeature(map.objectLayer, OpenLayers.Handler.RegularPolygon, { | |
33095 displayClass : "olControlDrawFeaturePolygon", | |
33096 handlerOptions : { | |
33097 sides : 40 | |
33098 }, | |
33099 callbacks : { | |
33100 "done" : map.drawnPolygonHandler, | |
33101 "create" : map.snapper | |
33102 } | |
33103 }); | |
33104 this.openlayersMap.addControl(this.drawCircle); | |
33105 } | |
33106 | |
33107 if (map.options.squareSelect) { | |
33108 this.drawSquare = new OpenLayers.Control.DrawFeature(map.objectLayer, OpenLayers.Handler.RegularPolygon, { | |
33109 displayClass : "olControlDrawFeaturePolygon", | |
33110 handlerOptions : { | |
33111 sides : 4, | |
33112 irregular: true | |
33113 }, | |
33114 callbacks : { | |
33115 "done" : map.drawnPolygonHandler, | |
33116 "create" : map.snapper | |
33117 } | |
33118 }); | |
33119 this.openlayersMap.addControl(this.drawSquare); | |
33120 } | |
33121 | |
33122 if (map.options.polygonSelect || map.options.circleSelect || map.options.squareSelect) { | |
33123 this.dragArea = new OpenLayers.Control.DragFeature(map.objectLayer, { | |
33124 onStart : function(feature) { | |
33125 feature.style.graphicZIndex = 10000; | |
33126 map.polygonDeselection(); | |
33127 }, | |
33128 onComplete : function(feature) { | |
33129 feature.style.graphicZIndex = 0; | |
33130 map.drawnPolygonHandler(feature.geometry); | |
33131 } | |
33132 }); | |
33133 this.openlayersMap.addControl(this.dragArea); | |
33134 | |
33135 this.modifyArea = new OpenLayers.Control.ModifyFeature(map.objectLayer, { | |
33136 onStart : function(feature) { | |
33137 feature.style.graphicZIndex = 10000; | |
33138 map.polygonDeselection(); | |
33139 }, | |
33140 onComplete : function(feature) { | |
33141 feature.style.graphicZIndex = 0; | |
33142 map.drawnPolygonHandler(feature.geometry); | |
33143 } | |
33144 }); | |
33145 this.openlayersMap.addControl(this.modifyArea); | |
33146 this.modifyArea.mode = OpenLayers.Control.ModifyFeature.RESHAPE; | |
33147 | |
33148 } | |
33149 | |
33150 // calculates the tag cloud | |
33151 // manages hover selection of point objects | |
33152 var hoverSelect = function(event) { | |
33153 var object = event.feature; | |
33154 if (object.geometry instanceof OpenLayers.Geometry.Point) { | |
33155 if ( typeof map.placenameTags != 'undefined') { | |
33156 map.placenameTags.remove(); | |
33157 } | |
33158 var circle = event.feature.parent; | |
33159 if ( circle instanceof CircleObject) { | |
33160 circle.placenameTags = new PlacenameTags(circle, map); | |
33161 map.placenameTags = circle.placenameTags; | |
33162 } else { | |
33163 return; | |
33164 /* | |
33165 event.feature.style.fillOpacity = 0.2; | |
33166 event.feature.style.strokeOpacity = 1; | |
33167 map.objectLayer.drawFeature(event.feature); | |
33168 circle.placenameTags = new PackPlacenameTags(circle,map); | |
33169 */ | |
33170 } | |
33171 circle.placenameTags.calculate(); | |
33172 map.mapCircleHighlight(object.parent, false); | |
33173 if ( typeof map.featureInfo != 'undefined') { | |
33174 map.featureInfo.deactivate(); | |
33175 } | |
33176 } else { | |
33177 map.dragControl.checkStatus(); | |
33178 } | |
33179 }; | |
33180 var hoverUnselect = function(event) { | |
33181 var object = event.feature; | |
33182 if (object.geometry instanceof OpenLayers.Geometry.Point) { | |
33183 var circle = event.feature.parent; | |
33184 if (!( circle instanceof CircleObject )) { | |
33185 return; | |
33186 /* | |
33187 event.feature.style.fillOpacity = 0; | |
33188 event.feature.style.strokeOpacity = 0; | |
33189 map.objectLayer.drawFeature(event.feature); | |
33190 */ | |
33191 } | |
33192 circle.placenameTags.remove(); | |
33193 map.mapCircleHighlight(object.parent, true); | |
33194 if ( typeof map.featureInfo != 'undefined') { | |
33195 map.featureInfo.activate(); | |
33196 } | |
33197 } else { | |
33198 map.dragControl.deactivate(); | |
33199 } | |
33200 }; | |
33201 var highlightCtrl = new OpenLayers.Control.SelectFeature(this.objectLayer, { | |
33202 hover : true, | |
33203 highlightOnly : true, | |
33204 renderIntent : "temporary", | |
33205 eventListeners : { | |
33206 featurehighlighted : hoverSelect, | |
33207 featureunhighlighted : hoverUnselect | |
33208 } | |
33209 }); | |
33210 this.openlayersMap.addControl(highlightCtrl); | |
33211 highlightCtrl.activate(); | |
33212 | |
33213 this.selectFeature = new OpenLayers.Control.SelectFeature(this.objectLayer); | |
33214 | |
33215 document.onkeydown = function(e) { | |
33216 if (e.ctrlKey) { | |
33217 map.ctrlKey = true; | |
33218 } | |
33219 } | |
33220 document.onkeyup = function(e) { | |
33221 map.ctrlKey = false; | |
33222 } | |
33223 // manages click selection of point objects | |
33224 var onFeatureSelect = function(event, evt) { | |
33225 if (!(event.feature.geometry instanceof OpenLayers.Geometry.Point)) { | |
33226 return; | |
33227 } | |
33228 var circle = event.feature.parent; | |
33229 if (map.options.multiSelection && map.ctrlKey) { | |
33230 if (map.popup) { | |
33231 map.popup.reset(); | |
33232 map.selectedGlyph = false; | |
33233 } | |
33234 circle.toggleSelection(); | |
33235 map.mapSelection(); | |
33236 return; | |
33237 } | |
33238 map.reset(); | |
33239 circle.setSelection(true); | |
33240 map.objectLayer.drawFeature(circle.feature); | |
33241 if (map.options.popups) { | |
33242 if (map.popup) { | |
33243 map.popup.reset(); | |
33244 } | |
33245 var lonlat = event.feature.geometry.getBounds().getCenterLonLat(); | |
33246 var pixel = map.openlayersMap.getPixelFromLonLat(lonlat); | |
33247 map.selectedGlyph = { | |
33248 lon : lonlat.lon, | |
33249 lat : lonlat.lat | |
33250 }; | |
33251 map.popup = new PlacenamePopup(map); | |
33252 map.popup.createPopup(pixel.x, pixel.y, circle.placenameTags.placeLabels); | |
33253 if (map.options.selectDefault) { | |
33254 circle.placenameTags.selectLabel(); | |
33255 } | |
33256 } | |
33257 } | |
33258 this.objectLayer.events.on({ | |
33259 "featureselected" : onFeatureSelect | |
33260 }); | |
33261 | |
33262 this.openlayersMap.addControl(this.selectFeature); | |
33263 this.selectFeature.activate(); | |
33264 | |
33265 if (this.zoomSlider) { | |
33266 this.zoomSlider.setMaxAndLevels(1000, this.openlayersMap.getNumZoomLevels()); | |
33267 this.zoomSlider.setValue(this.openlayersMap.getZoom()); | |
33268 } | |
33269 | |
33270 Publisher.Subscribe('mapChanged', this, function(mapName) { | |
33271 this.client.setBaseLayerByName(mapName); | |
33272 this.client.gui.setMap(); | |
33273 }); | |
33274 | |
33275 }, | |
33276 | |
33277 shift : function(shiftX, shiftY) { | |
33278 this.openlayersMap.pan(shiftX, shiftY); | |
33279 }, | |
33280 | |
33281 addBaseLayers : function(layers) { | |
33282 if ( layers instanceof Array) { | |
33283 for (var i in layers ) { | |
33284 var layer; | |
33285 if (layers[i].type === "XYZ"){ | |
33286 layer = new OpenLayers.Layer.XYZ( | |
33287 layers[i].name, | |
33288 [ | |
33289 layers[i].url | |
33290 ], | |
33291 { | |
33292 sphericalMercator: true, | |
33293 transitionEffect: "resize", | |
33294 buffer: 1, | |
33295 numZoomLevels: 12, | |
33296 transparent : true | |
33297 }, | |
33298 { | |
33299 isBaseLayer : true | |
33300 } | |
33301 ); | |
33302 } else { | |
33303 layer = new OpenLayers.Layer.WMS( | |
33304 layers[i].name, layers[i].url, | |
33305 { | |
33306 projection : "EPSG:4326", | |
33307 layers : layers[i].layer, | |
33308 transparent : "true", | |
33309 format : "image/png" | |
33310 }, | |
33311 { | |
33312 isBaseLayer : true | |
33313 } | |
33314 ); | |
33315 } | |
33316 this.baseLayers.push(layer); | |
33317 this.openlayersMap.addLayers([layer]); | |
33318 } | |
33319 } | |
33320 this.gui.setMapsDropdown(); | |
33321 }, | |
33322 | |
33323 /** | |
33324 * set online available maps for Google, Bing and OSM | |
33325 */ | |
33326 setBaseLayers : function() { | |
33327 this.baseLayers = []; | |
33328 if (this.options.googleMaps) { | |
33329 // see http://openlayers.org/blog/2010/07/10/google-maps-v3-for-openlayers/ for information | |
33330 var gphy = new OpenLayers.Layer.Google("Google Physical", { | |
33331 type : google.maps.MapTypeId.TERRAIN, | |
33332 minZoomLevel : 1, | |
33333 maxZoomLevel : 19 | |
33334 }); | |
33335 var gmap = new OpenLayers.Layer.Google("Google Streets", { | |
33336 minZoomLevel : 1, | |
33337 maxZoomLevel : 19 | |
33338 }); | |
33339 var ghyb = new OpenLayers.Layer.Google("Google Hybrid", { | |
33340 type : google.maps.MapTypeId.HYBRID, | |
33341 minZoomLevel : 1, | |
33342 maxZoomLevel : 19 | |
33343 }); | |
33344 var gsat = new OpenLayers.Layer.Google("Google Satellite", { | |
33345 type : google.maps.MapTypeId.SATELLITE, | |
33346 minZoomLevel : 1, | |
33347 maxZoomLevel : 19 | |
33348 }); | |
33349 this.baseLayers.push(gphy); | |
33350 this.baseLayers.push(gmap); | |
33351 this.baseLayers.push(ghyb); | |
33352 this.baseLayers.push(gsat); | |
33353 } | |
33354 if (this.options.bingMaps) { | |
33355 // see http://openlayers.org/blog/2010/12/18/bing-tiles-for-openlayers/ for information | |
33356 var apiKey = this.options.bingApiKey; | |
33357 var road = new OpenLayers.Layer.Bing({ | |
33358 name : "Road", | |
33359 key : apiKey, | |
33360 type : "Road" | |
33361 }); | |
33362 var hybrid = new OpenLayers.Layer.Bing({ | |
33363 name : "Hybrid", | |
33364 key : apiKey, | |
33365 type : "AerialWithLabels" | |
33366 }); | |
33367 var aerial = new OpenLayers.Layer.Bing({ | |
33368 name : "Aerial", | |
33369 key : apiKey, | |
33370 type : "Aerial" | |
33371 }); | |
33372 this.baseLayers.push(road); | |
33373 this.baseLayers.push(hybrid); | |
33374 this.baseLayers.push(aerial); | |
33375 } | |
33376 if (this.options.osmMaps) { | |
33377 this.baseLayers.push(new OpenLayers.Layer.OSM('Open Street Map', '', { | |
33378 sphericalMercator : true, | |
33379 zoomOffset : 1, | |
33380 resolutions : this.resolutions | |
33381 })); | |
33382 } | |
33383 if (this.options.osmMapsMapQuest) { | |
33384 this.baseLayers.push(new OpenLayers.Layer.OSM('Open Street Map (MapQuest)', | |
33385 ["http://otile1.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png", | |
33386 "http://otile2.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png", | |
33387 "http://otile3.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png", | |
33388 "http://otile4.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png"], | |
33389 { | |
33390 sphericalMercator : true, | |
33391 zoomOffset : 1, | |
33392 resolutions : this.resolutions | |
33393 } | |
33394 )); | |
33395 } | |
33396 for (var i = 0; i < this.baseLayers.length; i++) { | |
33397 this.openlayersMap.addLayers([this.baseLayers[i]]); | |
33398 } | |
33399 if (this.options.alternativeMap) { | |
33400 if (!(this.options.alternativeMap instanceof Array)) | |
33401 this.options.alternativeMap = [this.options.alternativeMap]; | |
33402 this.addBaseLayers(this.options.alternativeMap); | |
33403 } | |
33404 this.setBaseLayerByName(this.options.baseLayer); | |
33405 }, | |
33406 | |
33407 setBaseLayerByName : function(name){ | |
33408 for (var i = 0; i < this.baseLayers.length; i++) { | |
33409 if (this.baseLayers[i].name == name) { | |
33410 this.setMap(i); | |
33411 } | |
33412 } | |
33413 }, | |
33414 | |
33415 getBaseLayerName : function() { | |
33416 return this.openlayersMap.baseLayer.name; | |
33417 }, | |
33418 | |
33419 setOverlays : function(layers) { | |
33420 var map = this; | |
33421 for (var i in this.wmsOverlays ) { | |
33422 this.openlayersMap.removeLayer(this.wmsOverlays[i]); | |
33423 } | |
33424 this.wmsOverlays = []; | |
33425 var featureInfoLayers = []; | |
33426 if ( layers instanceof Array) { | |
33427 for (var i in layers ) { | |
33428 var layer = new OpenLayers.Layer.WMS(layers[i].name, layers[i].url, { | |
33429 projection : "EPSG:4326", | |
33430 layers : layers[i].layer, | |
33431 transparent : "true", | |
33432 format : "image/png" | |
33433 }, { | |
33434 isBaseLayer : false, | |
33435 visibility : map.options.overlayVisibility | |
33436 }); | |
33437 this.wmsOverlays.push(layer); | |
33438 if (layers[i].featureInfo) { | |
33439 featureInfoLayers.push(layer); | |
33440 } | |
33441 } | |
33442 this.openlayersMap.addLayers(this.wmsOverlays); | |
33443 } | |
33444 if (this.wmsOverlays.length > 0 && map.options.overlayVisibility) { | |
33445 var map = this; | |
33446 if ( typeof this.featureInfo != 'undefined') { | |
33447 this.featureInfo.deactivate(); | |
33448 this.openlayersMap.removeControl(this.featureInfo); | |
33449 } | |
33450 this.featureInfo = new OpenLayers.Control.WMSGetFeatureInfo({ | |
33451 url : '/geoserver/wms', | |
33452 layers : featureInfoLayers, | |
33453 eventListeners : { | |
33454 getfeatureinfo : function(event) { | |
33455 if (event.text == '') { | |
33456 return; | |
33457 } | |
33458 var lonlat = map.openlayersMap.getLonLatFromPixel(new OpenLayers.Pixel(event.xy.x, event.xy.y)); | |
33459 map.selectedGlyph = { | |
33460 lon : lonlat.lon, | |
33461 lat : lonlat.lat | |
33462 }; | |
33463 if ( typeof map.popup != 'undefined') { | |
33464 map.popup.reset(); | |
33465 } | |
33466 map.popup = new MapPopup(map); | |
33467 map.popup.initialize(event.xy.x, event.xy.y); | |
33468 map.popup.setContent(event.text); | |
33469 } | |
33470 } | |
33471 }); | |
33472 this.openlayersMap.addControl(this.featureInfo); | |
33473 this.featureInfo.activate(); | |
33474 this.activateCountrySelector(this.wmsOverlays[this.wmsOverlays.length - 1]); | |
33475 } else { | |
33476 this.deactivateCountrySelector(); | |
33477 if (this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS) { | |
33478 this.activateCountrySelector(this.openlayersMap.baseLayer); | |
33479 } | |
33480 } | |
33481 }, | |
33482 | |
33483 addBaseLayer : function(layer) { | |
33484 this.baseLayers.push(layer); | |
33485 this.openlayersMap.addLayers([layer]); | |
33486 for (var i in this.baseLayers ) { | |
33487 if (this.baseLayers[i].name == this.options.baseLayer) { | |
33488 this.setMap(i); | |
33489 } | |
33490 } | |
33491 }, | |
33492 | |
33493 /** | |
33494 * draws the object layer. | |
33495 * @param {boolean} zoom if there was a zoom; if not, the new boundary of the map is calculated | |
33496 */ | |
33497 drawObjectLayer : function(zoom) { | |
33498 if ( typeof this.placenameTags != 'undefined') { | |
33499 this.placenameTags.remove(); | |
33500 } | |
33501 var points = this.mds.getAllObjects(); | |
33502 if (points == null) { | |
33503 return; | |
33504 } | |
33505 this.objectLayer.removeAllFeatures(); | |
33506 | |
33507 if (zoom) { | |
33508 var minLat, maxLat, minLon, maxLon; | |
33509 var pointsHighestZoom = points[points.length - 1]; | |
33510 for (var i = 0; i < pointsHighestZoom.length; i++) { | |
33511 for (var j = 0; j < pointsHighestZoom[i].length; j++) { | |
33512 var point = pointsHighestZoom[i][j]; | |
33513 if (minLon == null || point.originX < minLon) { | |
33514 minLon = point.originX; | |
33515 } | |
33516 if (maxLon == null || point.originX > maxLon) { | |
33517 maxLon = point.originX; | |
33518 } | |
33519 if (minLat == null || point.originY < minLat) { | |
33520 minLat = point.originY; | |
33521 } | |
33522 if (maxLat == null || point.originY > maxLat) { | |
33523 maxLat = point.originY; | |
33524 } | |
33525 } | |
33526 } | |
33527 if (minLon == maxLon && minLat == maxLat) { | |
33528 this.openlayersMap.setCenter(new OpenLayers.LonLat(minLon, minLat)); | |
33529 } else { | |
33530 var gapX = 0.1 * (maxLon - minLon ); | |
33531 var gapY1 = 0.1 * (maxLat - minLat ); | |
33532 var gapY2 = (this.gui.headerHeight / this.gui.mapWindow.offsetHeight + 0.1 ) * (maxLat - minLat ); | |
33533 this.openlayersMap.zoomToExtent(new OpenLayers.Bounds(minLon - gapX, minLat - gapY1, maxLon + gapX, maxLat + gapY2)); | |
33534 this.openlayersMap.zoomTo(Math.floor(this.openlayersMap.getZoom())); | |
33535 } | |
33536 if (this.zoomSlider) { | |
33537 this.zoomSlider.setValue(this.openlayersMap.getZoom()); | |
33538 } | |
33539 } | |
33540 var displayPoints = this.mds.getObjectsByZoom(); | |
33541 var resolution = this.openlayersMap.getResolution(); | |
33542 for (var i = 0; i < displayPoints.length; i++) { | |
33543 for (var j = 0; j < displayPoints[i].length; j++) { | |
33544 var p = displayPoints[i][j]; | |
33545 var x = p.originX + resolution * p.shiftX; | |
33546 var y = p.originY + resolution * p.shiftY; | |
33547 p.feature.geometry.x = x; | |
33548 p.feature.geometry.y = y; | |
33549 p.olFeature.geometry.x = x; | |
33550 p.olFeature.geometry.y = y; | |
33551 p.feature.style.graphicZIndex = this.zIndices[i]; | |
33552 p.olFeature.style.graphicZIndex = this.zIndices[i] + 1; | |
33553 this.objectLayer.addFeatures([p.feature]); | |
33554 this.objectLayer.addFeatures([p.olFeature]); | |
33555 } | |
33556 } | |
33557 var zoomLevel = this.openlayersMap.getZoom(); | |
33558 /* | |
33559 for (var i = 0; i < this.bins[zoomLevel].length; i++) { | |
33560 var p = this.bins[zoomLevel][i]; | |
33561 p.feature.style.graphicZIndex = 0; | |
33562 this.objectLayer.addFeatures([p.feature]); | |
33563 } | |
33564 */ | |
33565 | |
33566 var dist = function(p1, p2) { | |
33567 return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); | |
33568 } | |
33569 | |
33570 this.highlightChanged(this.selection.getObjects(this.core)); | |
33571 | |
33572 }, | |
33573 | |
33574 riseLayer : function(id) { | |
33575 this.lastId = id; | |
33576 if ( typeof id == 'undefined') { | |
33577 id = this.lastId || 0; | |
33578 } | |
33579 this.zIndices[id] = this.layerZIndex; | |
33580 this.layerZIndex += 2; | |
33581 this.drawObjectLayer(false); | |
33582 for( var i=0; i<this.polygons.length; i++ ){ | |
33583 this.objectLayer.addFeatures([this.polygons[i]]); | |
33584 } | |
33585 }, | |
33586 | |
33587 /** | |
33588 * initializes the object layer. | |
33589 * all point representations for all zoom levels are calculated and initialized | |
33590 * @param {MapObject[][]} mapObjects an array of map objects from different (1-4) sets | |
33591 */ | |
33592 initWidget : function(datasets, zoom) { | |
33593 | |
33594 this.clearMap(); | |
33595 | |
33596 this.datasets = datasets; | |
33597 var mapObjects = []; | |
33598 for (var i = 0; i < datasets.length; i++) { | |
33599 mapObjects.push(datasets[i].objects); | |
33600 } | |
33601 if (mapObjects.length > 4) { | |
33602 this.options.circlePackings = false; | |
33603 } else { | |
33604 this.options.circlePackings = this.formerCP; | |
33605 } | |
33606 | |
33607 if ( typeof mapObjects == 'undefined') { | |
33608 return; | |
33609 } | |
33610 | |
33611 this.count = 0; | |
33612 this.objectCount = 0; | |
33613 for (var i = 0; i < mapObjects.length; i++) { | |
33614 var c = 0; | |
33615 for (var j = 0; j < mapObjects[i].length; j++) { | |
33616 if (mapObjects[i][j].isGeospatial) { | |
33617 c += mapObjects[i][j].weight; | |
33618 this.objectCount++; | |
33619 } | |
33620 } | |
33621 this.count += c; | |
33622 this.zIndices.push(this.layerZIndex); | |
33623 this.layerZIndex += 2; | |
33624 } | |
33625 | |
33626 this.mds.initialize(mapObjects); | |
33627 var points = this.mds.getAllObjects(); | |
33628 if (points == null) { | |
33629 return; | |
33630 } | |
33631 | |
33632 var getArea = function(radius) { | |
33633 return Math.PI * radius * radius; | |
33634 } | |
33635 for (var i = 0; i < points.length; i++) { | |
33636 var area = 0; | |
33637 var maxRadius = 0; | |
33638 for (var j = 0; j < points[i].length; j++) { | |
33639 for (var k = 0; k < points[i][j].length; k++) { | |
33640 if (points[i][j][k].radius > maxRadius) { | |
33641 maxRadius = points[i][j][k].radius; | |
33642 area = getArea(maxRadius); | |
33643 } | |
33644 } | |
33645 } | |
33646 var minArea = getArea(this.options.minimumRadius); | |
33647 var areaDiff = area - minArea; | |
33648 for (var j = 0; j < points[i].length; j++) { | |
33649 for (var k = 0; k < points[i][j].length; k++) { | |
33650 var point = points[i][j][k]; | |
33651 var c, shape, rotation, multiplier = 1; | |
33652 if( this.options.useGraphics ){ | |
33653 var graphic = this.config.getGraphic(point.search); | |
33654 c = graphic.color; | |
33655 shape = graphic.shape; | |
33656 rotation = graphic.rotation; | |
33657 if( shape == 'square' ){ | |
33658 multiplier = 0.75; | |
33659 } | |
33660 } | |
33661 else { | |
33662 c = GeoTemConfig.getAverageDatasetColor(point.search,point.elements); | |
33663 shape = 'circle'; | |
33664 rotation = 0; | |
33665 } | |
33666 var opacity; | |
33667 if (this.options.circleOpacity == 'balloon') { | |
33668 var min = this.options.minTransparency; | |
33669 var max = this.options.maxTransparency; | |
33670 opacity = min + Math.abs(min - max) * (1 - (getArea(point.radius) - minArea) / areaDiff); | |
33671 } | |
33672 else { | |
33673 opacity = this.options.circleOpacity; | |
33674 } | |
33675 var col = false, ols = 0; | |
33676 if( this.options.circleOutline ){ | |
33677 col = true; | |
33678 ols = this.options.circleOutline; | |
33679 } | |
33680 var style = { | |
33681 graphicName: shape, | |
33682 rotation: rotation, | |
33683 fillColor : 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')', | |
33684 fillOpacity : opacity, | |
33685 strokeWidth : ols, | |
33686 strokeColor : 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')', | |
33687 stroke : col, | |
33688 pointRadius : point.radius * multiplier, | |
33689 cursor : "pointer" | |
33690 }; | |
33691 var pointGeometry = new OpenLayers.Geometry.Point(point.originX, point.originY, null); | |
33692 var feature = new OpenLayers.Feature.Vector(pointGeometry); | |
33693 feature.style = style; | |
33694 feature.parent = point; | |
33695 point.setFeature(feature); | |
33696 var olStyle = { | |
33697 graphicName: shape, | |
33698 rotation: rotation, | |
33699 fillColor : 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')', | |
33700 fillOpacity : opacity, | |
33701 stroke : false, | |
33702 pointRadius : 0, | |
33703 cursor : "pointer" | |
33704 }; | |
33705 var olPointGeometry = new OpenLayers.Geometry.Point(point.originX, point.originY, null); | |
33706 var olFeature = new OpenLayers.Feature.Vector(olPointGeometry); | |
33707 olFeature.style = olStyle; | |
33708 olFeature.parent = point; | |
33709 point.setOlFeature(olFeature); | |
33710 } | |
33711 } | |
33712 } | |
33713 | |
33714 /* | |
33715 this.bins = this.mds.getAllBins(); | |
33716 for (var i = 0; i < this.bins.length; i++) { | |
33717 for (var j = 0; j < this.bins[i].length; j++) { | |
33718 var bin = this.bins[i][j]; | |
33719 var style = { | |
33720 fillColor : 'rgb(140,140,140)', | |
33721 fillOpacity : 0, | |
33722 strokeWidth : 2, | |
33723 strokeOpacity : 0, | |
33724 strokeColor : 'rgb(140,140,140)', | |
33725 // stroke: false, | |
33726 pointRadius : bin.radius, | |
33727 cursor : "pointer" | |
33728 }; | |
33729 var pointGeometry = new OpenLayers.Geometry.Point(bin.x, bin.y, null); | |
33730 var feature = new OpenLayers.Feature.Vector(pointGeometry); | |
33731 feature.style = style; | |
33732 feature.parent = bin; | |
33733 bin.feature = feature; | |
33734 } | |
33735 } | |
33736 */ | |
33737 | |
33738 this.gui.updateLegend(datasets); | |
33739 | |
33740 if ( typeof zoom == "undefined") { | |
33741 this.drawObjectLayer(true); | |
33742 } else { | |
33743 this.drawObjectLayer(zoom); | |
33744 } | |
33745 this.gui.updateSpaceQuantity(this.count); | |
33746 | |
33747 }, | |
33748 | |
33749 /** | |
33750 * resets the map by destroying all additional elements except the point objects, which are replaced | |
33751 */ | |
33752 reset : function() { | |
33753 if ( typeof this.placenameTags != 'undefined') { | |
33754 this.placenameTags.remove(); | |
33755 } | |
33756 this.objectLayer.removeFeatures(this.polygons); | |
33757 this.polygons = []; | |
33758 this.objectLayer.removeFeatures(this.connections); | |
33759 this.connections = []; | |
33760 this.selectFeature.unselectAll(); | |
33761 this.selectedGlyph = false; | |
33762 if (this.dragControl.activated) { | |
33763 this.dragControl.deactivate(); | |
33764 } | |
33765 if (this.popup) { | |
33766 this.popup.reset(); | |
33767 } | |
33768 this.filterBar.reset(false); | |
33769 var points = this.mds.getObjectsByZoom(); | |
33770 if (points == null) { | |
33771 return; | |
33772 } | |
33773 for (var i = 0; i < points.length; i++) { | |
33774 for (var j = 0; j < points[i].length; j++) { | |
33775 points[i][j].setSelection(false); | |
33776 } | |
33777 } | |
33778 }, | |
33779 | |
33780 /** | |
33781 * resets the map by destroying all elements | |
33782 */ | |
33783 clearMap : function() { | |
33784 this.reset(); | |
33785 this.selection = new Selection(); | |
33786 this.zIndices = []; | |
33787 this.layerZIndex = 1; | |
33788 this.objectLayer.destroyFeatures(); | |
33789 }, | |
33790 | |
33791 /** | |
33792 * updates the proportional selection status of a point object | |
33793 * @param {PointObject} point the point to update | |
33794 * @param {OpenLayers.Geometry.Polygon} polygon the actual displayed map polygon | |
33795 */ | |
33796 updatePoint : function(point, polygon) { | |
33797 var olRadius = this.mds.binning.getRadius(point.overlay); | |
33798 if( this.options.useGraphics ){ | |
33799 var graphic = this.config.getGraphic(point.search); | |
33800 if( graphic.shape == 'square' ){ | |
33801 olRadius *= 0.75; | |
33802 } | |
33803 } | |
33804 point.olFeature.style.pointRadius = olRadius; | |
33805 var c = GeoTemConfig.getAverageDatasetColor(point.search, point.overlayElements); | |
33806 point.olFeature.style.fillColor = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
33807 if (polygon.containsPoint(point.feature.geometry)) { | |
33808 this.objectLayer.drawFeature(point.olFeature); | |
33809 } | |
33810 }, | |
33811 | |
33812 /** | |
33813 * updates the the object layer of the map after selections had been executed in timeplot or table or zoom level has changed | |
33814 */ | |
33815 highlightChanged : function(mapObjects) { | |
33816 if( !GeoTemConfig.highlightEvents ){ | |
33817 return; | |
33818 } | |
33819 this.mds.clearOverlay(); | |
33820 if (this.selection.valid()) { | |
33821 this.mds.setOverlay(GeoTemConfig.mergeObjects(mapObjects, this.selection.getObjects())); | |
33822 } else { | |
33823 this.mds.setOverlay(mapObjects); | |
33824 } | |
33825 var points = this.mds.getObjectsByZoom(); | |
33826 var polygon = this.openlayersMap.getExtent().toGeometry(); | |
33827 for (var i in points ) { | |
33828 for (var j in points[i] ) { | |
33829 this.updatePoint(points[i][j], polygon); | |
33830 } | |
33831 } | |
33832 this.displayConnections(); | |
33833 }, | |
33834 | |
33835 selectionChanged : function(selection) { | |
33836 if( !GeoTemConfig.selectionEvents ){ | |
33837 return; | |
33838 } | |
33839 this.reset(); | |
33840 this.selection = selection; | |
33841 this.highlightChanged(selection.objects); | |
33842 }, | |
33843 | |
33844 inPolygon : function(point) { | |
33845 for (var i = 0; i < this.polygons.length; i++) { | |
33846 var polygon = this.polygons[i].geometry; | |
33847 for (var j = 0; j < polygon.components.length; j++) { | |
33848 if (polygon.components[j].containsPoint(point.feature.geometry)) { | |
33849 return true; | |
33850 } | |
33851 } | |
33852 } | |
33853 return false; | |
33854 }, | |
33855 | |
33856 mapSelection : function() { | |
33857 var selectedObjects = []; | |
33858 for (var i = 0; i < this.mds.size(); i++) { | |
33859 selectedObjects.push([]); | |
33860 } | |
33861 var circles = this.mds.getObjectsByZoom(); | |
33862 for (var i = 0; i < circles.length; i++) { | |
33863 | |
33864 for (var j = 0; j < circles[i].length; j++) { | |
33865 var c = circles[i][j]; | |
33866 if (c.selected) { | |
33867 selectedObjects[i] = selectedObjects[i].concat(c.elements); | |
33868 } | |
33869 } | |
33870 } | |
33871 this.selection = new Selection(selectedObjects, this); | |
33872 this.highlightChanged(selectedObjects); | |
33873 this.core.triggerSelection(this.selection); | |
33874 this.filterBar.reset(true); | |
33875 }, | |
33876 | |
33877 deselection : function() { | |
33878 this.reset(); | |
33879 this.selection = new Selection(); | |
33880 this.highlightChanged([]); | |
33881 this.core.triggerSelection(this.selection); | |
33882 }, | |
33883 | |
33884 filtering : function() { | |
33885 for (var i = 0; i < this.datasets.length; i++) { | |
33886 this.datasets[i].objects = this.selection.objects[i]; | |
33887 } | |
33888 this.core.triggerRefining(this.datasets); | |
33889 }, | |
33890 | |
33891 inverseFiltering : function() { | |
33892 var selectedObjects = []; | |
33893 for (var i = 0; i < this.mds.size(); i++) { | |
33894 selectedObjects.push([]); | |
33895 } | |
33896 var circles = this.mds.getObjectsByZoom(); | |
33897 for (var i = 0; i < circles.length; i++) { | |
33898 for (var j = 0; j < circles[i].length; j++) { | |
33899 var c = circles[i][j]; | |
33900 if (!c.selected) { | |
33901 selectedObjects[i] = selectedObjects[i].concat(c.elements); | |
33902 } | |
33903 } | |
33904 } | |
33905 this.selection = new Selection(selectedObjects, this); | |
33906 this.filtering(); | |
33907 }, | |
33908 | |
33909 mapCircleHighlight : function(circle, undo) { | |
33910 if (this.polygons.length > 0 && this.inPolygon(circle)) { | |
33911 return; | |
33912 } | |
33913 var mapObjects = []; | |
33914 for (var i = 0; i < this.mds.size(); i++) { | |
33915 mapObjects.push([]); | |
33916 } | |
33917 if (!undo && !circle.selected) { | |
33918 mapObjects[circle.search] = circle.elements; | |
33919 } | |
33920 this.objectLayer.drawFeature(circle.feature); | |
33921 this.core.triggerHighlight(mapObjects); | |
33922 }, | |
33923 | |
33924 mapLabelSelection : function(label) { | |
33925 var selectedObjects = []; | |
33926 for (var i = 0; i < this.mds.size(); i++) { | |
33927 selectedObjects.push([]); | |
33928 } | |
33929 selectedObjects[label.index] = label.elements; | |
33930 this.selection = new Selection(selectedObjects, this); | |
33931 this.highlightChanged(selectedObjects); | |
33932 this.core.triggerSelection(this.selection); | |
33933 this.filterBar.reset(true); | |
33934 }, | |
33935 | |
33936 triggerMapChanged : function(mapName) { | |
33937 Publisher.Publish('mapChanged', mapName, this); | |
33938 }, | |
33939 | |
33940 /** | |
33941 * displays connections between data objects | |
33942 */ | |
33943 displayConnections : function() { | |
33944 return; | |
33945 if ( typeof this.connection != 'undefined') { | |
33946 this.objectLayer.removeFeatures(this.connections); | |
33947 this.connections = []; | |
33948 } | |
33949 if (this.options.connections) { | |
33950 var points = this.mds.getObjectsByZoom(); | |
33951 for (var i in points ) { | |
33952 for (var j in points[i] ) { | |
33953 | |
33954 } | |
33955 } | |
33956 | |
33957 var slices = this.core.timeplot.getSlices(); | |
33958 for (var i = 0; i < slices.length; i++) { | |
33959 for (var j = 0; j < slices[i].stacks.length; j++) { | |
33960 var e = slices[i].stacks[j].elements; | |
33961 if (e.length == 0) { | |
33962 continue; | |
33963 } | |
33964 var points = []; | |
33965 for (var k = 0; k < e.length; k++) { | |
33966 var point = this.mds.getCircle(j, e[k].index).feature.geometry; | |
33967 if (arrayIndex(points, point) == -1) { | |
33968 points.push(point); | |
33969 } | |
33970 } | |
33971 var matrix = new AdjMatrix(points.length); | |
33972 for (var k = 0; k < points.length - 1; k++) { | |
33973 for (var l = k + 1; l < points.length; l++) { | |
33974 matrix.setEdge(k, l, dist(points[k], points[l])); | |
33975 } | |
33976 } | |
33977 var tree = Prim(matrix); | |
33978 var lines = []; | |
33979 for (var z = 0; z < tree.length; z++) { | |
33980 lines.push(new OpenLayers.Geometry.LineString(new Array(points[tree[z].v1], points[tree[z].v2]))); | |
33981 } | |
33982 this.connections[j].push({ | |
33983 first : this.mds.getCircle(j, e[0].index).feature.geometry, | |
33984 last : this.mds.getCircle(j, e[e.length - 1].index).feature.geometry, | |
33985 lines : lines, | |
33986 time : slices[i].date | |
33987 }); | |
33988 } | |
33989 } | |
33990 var ltm = this.core.timeplot.leftFlagTime; | |
33991 var rtm = this.core.timeplot.rightFlagTime; | |
33992 if (ltm == undefined || ltm == null) { | |
33993 return; | |
33994 } else { | |
33995 ltm = ltm.getTime(); | |
33996 rtm = rtm.getTime(); | |
33997 } | |
33998 // this.connectionLayer.destroyFeatures(); | |
33999 if (thisConnections) { | |
34000 for (var i = 0; i < this.connections.length; i++) { | |
34001 var c = GeoTemConfig.colors[i]; | |
34002 var style = { | |
34003 strokeColor : 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')', | |
34004 strokeOpacity : 0.5, | |
34005 strokeWidth : 3 | |
34006 }; | |
34007 var pointsToConnect = []; | |
34008 var last = undefined; | |
34009 for (var j = 0; j < this.connections[i].length; j++) { | |
34010 var c = this.connections[i][j]; | |
34011 var ct = c.time.getTime(); | |
34012 if (ct >= ltm && ct <= rtm) { | |
34013 if (last != undefined) { | |
34014 var line = new OpenLayers.Geometry.LineString(new Array(last, c.first)); | |
34015 this.connectionLayer.addFeatures([new OpenLayers.Feature.Vector(line, null, style)]); | |
34016 } | |
34017 for (var k = 0; k < c.lines.length; k++) { | |
34018 this.connectionLayer.addFeatures([new OpenLayers.Feature.Vector(c.lines[k], null, style)]); | |
34019 } | |
34020 last = c.last; | |
34021 } | |
34022 } | |
34023 } | |
34024 // this.connectionLayer.redraw(); | |
34025 } | |
34026 } | |
34027 }, | |
34028 | |
34029 /** | |
34030 * performs a zoom on the map | |
34031 * @param {int} delta the change of zoom levels | |
34032 */ | |
34033 zoom : function(delta) { | |
34034 var zoom = this.openlayersMap.getZoom() + delta; | |
34035 if (this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS) { | |
34036 this.openlayersMap.zoomTo(zoom); | |
34037 } else { | |
34038 this.openlayersMap.zoomTo(Math.round(zoom)); | |
34039 if (this.zoomSlider) { | |
34040 this.zoomSlider.setValue(this.openlayersMap.getZoom()); | |
34041 } | |
34042 } | |
34043 this.drawObjectLayer(false); | |
34044 return true; | |
34045 }, | |
34046 | |
34047 deactivateCountrySelector : function() { | |
34048 this.openlayersMap.removeControl(this.selectCountry); | |
34049 this.selectCountry = undefined; | |
34050 }, | |
34051 | |
34052 activateCountrySelector : function(layer) { | |
34053 var map = this; | |
34054 if (this.options.countrySelect && this.options.mapSelectionTools) { | |
34055 this.selectCountry = new OpenLayers.Control.GetFeature({ | |
34056 protocol : OpenLayers.Protocol.WFS.fromWMSLayer(layer), | |
34057 click : true | |
34058 }); | |
34059 this.selectCountry.events.register("featureselected", this, function(e) { | |
34060 map.snapper(); | |
34061 map.drawnPolygonHandler(e.feature.geometry); | |
34062 }); | |
34063 this.openlayersMap.addControl(this.selectCountry); | |
34064 this.countrySelectionControl.enable(); | |
34065 } | |
34066 }, | |
34067 | |
34068 setMap : function(index) { | |
34069 this.baselayerIndex = index; | |
34070 if (this.selectCountry) { | |
34071 // if( this.wmsOverlays.length == 0 ){ | |
34072 this.deactivateCountrySelector(); | |
34073 // } | |
34074 } | |
34075 if (this.baseLayers[index] instanceof OpenLayers.Layer.WMS) { | |
34076 // if( this.wmsOverlays.length == 0 ){ | |
34077 this.activateCountrySelector(this.baseLayers[index]); | |
34078 // } | |
34079 } else { | |
34080 if (this.countrySelectionControl) { | |
34081 this.countrySelectionControl.disable(); | |
34082 } | |
34083 } | |
34084 this.openlayersMap.zoomTo(Math.floor(this.openlayersMap.getZoom())); | |
34085 this.openlayersMap.setBaseLayer(this.baseLayers[index]); | |
34086 if (this.baseLayers[index].name == 'Open Street Map') { | |
34087 this.gui.osmLink.style.visibility = 'visible'; | |
34088 } else { | |
34089 this.gui.osmLink.style.visibility = 'hidden'; | |
34090 } | |
34091 if (this.baseLayers[index].name == 'Open Street Map (MapQuest)') { | |
34092 this.gui.osmMapQuestLink.style.visibility = 'visible'; | |
34093 } else { | |
34094 this.gui.osmMapQuestLink.style.visibility = 'hidden'; | |
34095 } | |
34096 this.triggerMapChanged(this.baseLayers[index].name); | |
34097 }, | |
34098 | |
34099 //vhz added title to buttons | |
34100 initSelectorTools : function() { | |
34101 var map = this; | |
34102 this.mapControls = []; | |
34103 | |
34104 if (this.options.squareSelect) { | |
34105 var button = document.createElement("div"); | |
34106 $(button).addClass('mapControl'); | |
34107 var activate = function() { | |
34108 map.drawSquare.activate(); | |
34109 } | |
34110 var deactivate = function() { | |
34111 map.drawSquare.deactivate(); | |
34112 } | |
34113 this.mapControls.push(new MapControl(this, button, 'square', activate, deactivate)); | |
34114 } | |
34115 if (this.options.circleSelect) { | |
34116 var button = document.createElement("div"); | |
34117 $(button).addClass('mapControl'); | |
34118 var activate = function() { | |
34119 map.drawCircle.activate(); | |
34120 } | |
34121 var deactivate = function() { | |
34122 map.drawCircle.deactivate(); | |
34123 } | |
34124 this.mapControls.push(new MapControl(this, button, 'circle', activate, deactivate)); | |
34125 } | |
34126 if (this.options.polygonSelect) { | |
34127 var button = document.createElement("div"); | |
34128 $(button).addClass('mapControl'); | |
34129 var activate = function() { | |
34130 map.drawPolygon.activate(); | |
34131 } | |
34132 var deactivate = function() { | |
34133 map.drawPolygon.deactivate(); | |
34134 } | |
34135 this.mapControls.push(new MapControl(this, button, 'polygon', activate, deactivate)); | |
34136 } | |
34137 if (this.options.countrySelect) { | |
34138 var button = document.createElement("div"); | |
34139 $(button).addClass('mapControl'); | |
34140 var activate = function() { | |
34141 map.selectCountry.activate(); | |
34142 map.dragControl.disable(); | |
34143 } | |
34144 var deactivate = function() { | |
34145 map.selectCountry.deactivate(); | |
34146 map.dragControl.enable(); | |
34147 } | |
34148 this.countrySelectionControl = new MapControl(this, button, 'country', activate, deactivate); | |
34149 this.mapControls.push(this.countrySelectionControl); | |
34150 /* | |
34151 if( !(this.openlayersMap.baseLayer instanceof OpenLayers.Layer.WMS) ){ | |
34152 this.countrySelectionControl.disable(); | |
34153 } | |
34154 */ | |
34155 } | |
34156 return this.mapControls; | |
34157 }, | |
34158 | |
34159 getZoom : function() { | |
34160 return this.openlayersMap.getZoom(); | |
34161 }, | |
34162 | |
34163 setMarker : function(lon, lat) { | |
34164 var p = new OpenLayers.Geometry.Point(lon, lat, null); | |
34165 p.transform(this.openlayersMap.displayProjection, this.openlayersMap.projection); | |
34166 this.openlayersMap.setCenter(new OpenLayers.LonLat(p.x, p.y)); | |
34167 var size = new OpenLayers.Size(22, 33); | |
34168 var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h); | |
34169 var icon = new OpenLayers.Icon(GeoTemConfig.path + 'marker.png', size, offset); | |
34170 var marker = new OpenLayers.Marker(new OpenLayers.LonLat(p.x, p.y), icon); | |
34171 marker.setOpacity(0.9); | |
34172 this.markerLayer.setZIndex(parseInt(this.objectLayer.getZIndex()) + 1); | |
34173 this.markerLayer.addMarker(marker); | |
34174 // find nearest neighbor | |
34175 var nearestNeighbor; | |
34176 var points = this.mds.getAllObjects(); | |
34177 if (points == null) { | |
34178 return; | |
34179 } | |
34180 var dist = function(p1, p2) { | |
34181 return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); | |
34182 } | |
34183 var zoomLevels = this.openlayersMap.getNumZoomLevels(); | |
34184 var pointSet = points[zoomLevels - 1]; | |
34185 var closestDistance = undefined; | |
34186 var closestPoint; | |
34187 for (var i = 0; i < pointSet.length; i++) { | |
34188 for (var j = 0; j < pointSet[i].length; j++) { | |
34189 var point = pointSet[i][j].feature.geometry; | |
34190 var d = dist(point, p); | |
34191 if (!closestDistance || d < closestDistance) { | |
34192 closestDistance = d; | |
34193 closestPoint = point; | |
34194 } | |
34195 } | |
34196 } | |
34197 // find minimal zoom level | |
34198 var gap = 0; | |
34199 var x_s = this.gui.mapWindow.offsetWidth / 2 - gap; | |
34200 var y_s = this.gui.mapWindow.offsetHeight / 2 - gap; | |
34201 if (typeof closestPoint !== "undefined"){ | |
34202 var xDist = Math.abs(p.x - closestPoint.x); | |
34203 var yDist = Math.abs(p.y - closestPoint.y); | |
34204 for (var i = 0; i < zoomLevels; i++) { | |
34205 var resolution = this.openlayersMap.getResolutionForZoom(zoomLevels - i - 1); | |
34206 if (xDist / resolution < x_s && yDist / resolution < y_s) { | |
34207 this.openlayersMap.zoomTo(zoomLevels - i - 1); | |
34208 if (this.zoomSlider) { | |
34209 this.zoomSlider.setValue(this.openlayersMap.getZoom()); | |
34210 } | |
34211 this.drawObjectLayer(false); | |
34212 break; | |
34213 } | |
34214 } | |
34215 } else { | |
34216 //if there are no points on the map, zoom to max | |
34217 this.openlayersMap.zoomTo(0); | |
34218 if (this.zoomSlider) { | |
34219 this.zoomSlider.setValue(this.openlayersMap.getZoom()); | |
34220 } | |
34221 this.drawObjectLayer(false); | |
34222 } | |
34223 }, | |
34224 | |
34225 removeMarker : function() { | |
34226 this.markerLayer.removeMarker(this.markerLayer.markers[0]); | |
34227 }, | |
34228 | |
34229 getLevelOfDetail : function() { | |
34230 var zoom = Math.floor(this.openlayersMap.getZoom()); | |
34231 if (zoom <= 1) { | |
34232 return 0; | |
34233 } else if (zoom <= 3) { | |
34234 return 1; | |
34235 } else if (zoom <= 8) { | |
34236 return 2; | |
34237 } else { | |
34238 return 3; | |
34239 } | |
34240 } | |
34241 } | |
34242 /* | |
34243 * TimeConfig.js | |
34244 * | |
34245 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
34246 * | |
34247 * This library is free software; you can redistribute it and/or | |
34248 * modify it under the terms of the GNU Lesser General Public | |
34249 * License as published by the Free Software Foundation; either | |
34250 * version 3 of the License, or (at your option) any later version. | |
34251 * | |
34252 * This library is distributed in the hope that it will be useful, | |
34253 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34254 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
34255 * Lesser General Public License for more details. | |
34256 * | |
34257 * You should have received a copy of the GNU Lesser General Public | |
34258 * License along with this library; if not, write to the Free Software | |
34259 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
34260 * MA 02110-1301 USA | |
34261 */ | |
34262 | |
34263 /** | |
34264 * @class TimeConfig | |
34265 * Time Configuration File | |
34266 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
34267 * @release 1.0 | |
34268 * @release date: 2012-07-27 | |
34269 * @version date: 2012-07-27 | |
34270 */ | |
34271 function TimeConfig(options) { | |
34272 | |
34273 this.options = { | |
34274 timeTitle : 'GeoTemCo Time View', // title will be shown in timeplot header | |
34275 timeIndex : 0, // index = position in date array; for multiple dates the 2nd timeplot refers to index 1 | |
34276 timeWidth : false, // false or desired width css definition for the timeplot | |
34277 timeHeight : '100px', // false or desired height css definition for the timeplot | |
34278 defaultMinDate : new Date(2012, 0, 1), // required, when empty timelines are possible | |
34279 defaultMaxDate : new Date(), // required, when empty timelines are possible | |
34280 timeCanvasFrom : '#EEE', // time widget background gradient color top | |
34281 timeCanvasTo : '#EEE', // time widget background gradient color bottom | |
34282 rangeBoxColor : "white", // fill color for time range box | |
34283 rangeBorder : "1px solid #de7708", // border of frames | |
34284 dataInformation : true, // show/hide data information | |
34285 rangeAnimation : true, // show/hide animation buttons | |
34286 scaleSelection : true, // show/hide scale selection buttons | |
34287 linearScale : true, // true for linear value scaling, false for logarithmic | |
34288 unitSelection : true, // show/hide time unit selection dropdown | |
34289 timeUnit : -1, // minimum temporal unit (SimileAjax.DateTime or -1 if none) of the data | |
34290 timeMerge : false // if the elements of distinct datasets should be merged into one set or not | |
34291 }; | |
34292 if ( typeof options != 'undefined') { | |
34293 $.extend(this.options, options); | |
34294 } | |
34295 | |
34296 }; | |
34297 /* | |
34298 * TimeGui.js | |
34299 * | |
34300 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
34301 * | |
34302 * This library is free software; you can redistribute it and/or | |
34303 * modify it under the terms of the GNU Lesser General Public | |
34304 * License as published by the Free Software Foundation; either | |
34305 * version 3 of the License, or (at your option) any later version. | |
34306 * | |
34307 * This library is distributed in the hope that it will be useful, | |
34308 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34309 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
34310 * Lesser General Public License for more details. | |
34311 * | |
34312 * You should have received a copy of the GNU Lesser General Public | |
34313 * License along with this library; if not, write to the Free Software | |
34314 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
34315 * MA 02110-1301 USA | |
34316 */ | |
34317 | |
34318 /** | |
34319 * @class TimeGui | |
34320 * Time GUI Implementation | |
34321 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
34322 * @release 1.0 | |
34323 * @release date: 2012-07-27 | |
34324 * @version date: 2012-07-27 | |
34325 * | |
34326 * @param {TimeWidget} parent time widget object | |
34327 * @param {HTML object} div parent div to append the time gui | |
34328 * @param {JSON} options time configuration | |
34329 */ | |
34330 function TimeGui(plot, div, options, iid) { | |
34331 | |
34332 var gui = this; | |
34333 | |
34334 this.plot = plot; | |
34335 | |
34336 this.container = div; | |
34337 if (options.timeWidth) { | |
34338 this.container.style.width = options.timeWidth; | |
34339 } | |
34340 if (options.timeHeight) { | |
34341 this.container.style.height = options.timeHeight; | |
34342 } | |
34343 this.container.style.position = 'relative'; | |
34344 | |
34345 var w = this.container.offsetWidth; | |
34346 var h = this.container.offsetHeight; | |
34347 | |
34348 var toolbarTable = document.createElement("table"); | |
34349 toolbarTable.setAttribute('class', 'ddbToolbar'); | |
34350 this.container.appendChild(toolbarTable); | |
34351 | |
34352 this.plotWindow = document.createElement("div"); | |
34353 this.plotWindow.id = "plotWindow"+iid; | |
34354 this.plotWindow.setAttribute('class', 'plotWindow'); | |
34355 // this.plotWindow.style.width = w + "px"; | |
34356 | |
34357 this.plotWindow.style.height = (h + 12) + "px"; | |
34358 this.container.style.height = (h + 12) + "px"; | |
34359 | |
34360 this.plotWindow.onmousedown = function() { | |
34361 return false; | |
34362 } | |
34363 | |
34364 this.plotContainer = document.createElement("div"); | |
34365 this.plotContainer.id = "plotContainer"+iid; | |
34366 this.plotContainer.setAttribute('class', 'plotContainer'); | |
34367 // this.plotContainer.style.width = w + "px"; | |
34368 this.plotContainer.style.height = h + "px"; | |
34369 this.plotContainer.style.position = "absolute"; | |
34370 this.plotContainer.style.zIndex = 0; | |
34371 this.plotContainer.style.top = "12px"; | |
34372 this.plotWindow.appendChild(this.plotContainer); | |
34373 this.container.appendChild(this.plotWindow); | |
34374 | |
34375 this.timeplotDiv = document.createElement("div"); | |
34376 this.timeplotDiv.style.left = "16px"; | |
34377 this.timeplotDiv.style.width = (w - 32) + "px"; | |
34378 this.timeplotDiv.style.height = h + "px"; | |
34379 this.plotContainer.appendChild(this.timeplotDiv); | |
34380 | |
34381 var cv = document.createElement("canvas"); | |
34382 cv.setAttribute('class', 'plotCanvas'); | |
34383 this.plotWindow.appendChild(cv); | |
34384 if (!cv.getContext && G_vmlCanvasManager) | |
34385 cv = G_vmlCanvasManager.initElement(cv); | |
34386 var ctx = cv.getContext('2d'); | |
34387 | |
34388 var setCanvas = function(){ | |
34389 cv.width = gui.plotWindow.clientWidth; | |
34390 cv.height = gui.plotWindow.clientHeight; | |
34391 var gradient = ctx.createLinearGradient(0, 0, 0, gui.plotWindow.clientHeight); | |
34392 gradient.addColorStop(0, options.timeCanvasFrom); | |
34393 gradient.addColorStop(1, options.timeCanvasTo); | |
34394 ctx.fillStyle = gradient; | |
34395 ctx.fillRect(0, 0, gui.plotWindow.clientWidth, gui.plotWindow.clientHeight); | |
34396 } | |
34397 setCanvas(); | |
34398 | |
34399 this.resize = function(){ | |
34400 gui.timeplotDiv.style.width = (gui.container.offsetWidth - 32) + "px"; | |
34401 ctx.clearRect(0,0,gui.plotWindow.clientWidth, gui.plotWindow.clientHeight); | |
34402 if( typeof plot.datasets != "undefined" ){ | |
34403 plot.redrawPlot(); | |
34404 plot.resetOpacityPlots(); | |
34405 } | |
34406 setCanvas(); | |
34407 }; | |
34408 | |
34409 var titles = document.createElement("tr"); | |
34410 toolbarTable.appendChild(titles); | |
34411 var tools = document.createElement("tr"); | |
34412 toolbarTable.appendChild(tools); | |
34413 | |
34414 this.timeUnitTitle = document.createElement("td"); | |
34415 this.timeUnitTitle.innerHTML = GeoTemConfig.getString('timeUnit'); | |
34416 this.timeUnitSelector = document.createElement("td"); | |
34417 if (options.unitSelection) { | |
34418 tools.appendChild(this.timeUnitSelector); | |
34419 titles.appendChild(this.timeUnitTitle); | |
34420 } | |
34421 | |
34422 this.timeAnimation = document.createElement("td"); | |
34423 this.timeAnimation.innerHTML = GeoTemConfig.getString('timeAnimation'); | |
34424 var timeAnimationTools = document.createElement("td"); | |
34425 | |
34426 var status; | |
34427 this.updateAnimationButtons = function(s) { | |
34428 status = s; | |
34429 if (status == 0) { | |
34430 gui.playButton.setAttribute('class', 'smallButton playDisabled'); | |
34431 gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled'); | |
34432 } else if (status == 1) { | |
34433 gui.playButton.setAttribute('class', 'smallButton playEnabled'); | |
34434 gui.pauseButton.setAttribute('class', 'smallButton pauseDisabled'); | |
34435 } else { | |
34436 gui.playButton.setAttribute('class', 'smallButton playDisabled'); | |
34437 gui.pauseButton.setAttribute('class', 'smallButton pauseEnabled'); | |
34438 } | |
34439 }; | |
34440 this.playButton = document.createElement("div"); | |
34441 this.playButton.title = GeoTemConfig.getString('playButton'); | |
34442 timeAnimationTools.appendChild(this.playButton); | |
34443 this.playButton.onclick = function() { | |
34444 if (status == 1) { | |
34445 plot.play(); | |
34446 } | |
34447 } | |
34448 | |
34449 this.pauseButton = document.createElement("div"); | |
34450 this.pauseButton.title = GeoTemConfig.getString('pauseButton'); | |
34451 timeAnimationTools.appendChild(this.pauseButton); | |
34452 this.pauseButton.onclick = function() { | |
34453 if (status == 2) { | |
34454 plot.stop(); | |
34455 } | |
34456 } | |
34457 | |
34458 this.valueScale = document.createElement("td"); | |
34459 this.valueScale.innerHTML = GeoTemConfig.getString('valueScale'); | |
34460 var valueScaleTools = document.createElement("td"); | |
34461 | |
34462 var linearPlot; | |
34463 var setValueScale = function(linScale) { | |
34464 if (linearPlot != linScale) { | |
34465 linearPlot = linScale; | |
34466 if (linearPlot) { | |
34467 gui.linButton.setAttribute('class', 'smallButton linearPlotActivated'); | |
34468 gui.logButton.setAttribute('class', 'smallButton logarithmicPlotDeactivated'); | |
34469 plot.drawLinearPlot(); | |
34470 } else { | |
34471 gui.linButton.setAttribute('class', 'smallButton linearPlotDeactivated'); | |
34472 gui.logButton.setAttribute('class', 'smallButton logarithmicPlotActivated'); | |
34473 plot.drawLogarithmicPlot(); | |
34474 } | |
34475 } | |
34476 }; | |
34477 this.linButton = document.createElement("div"); | |
34478 this.linButton.title = GeoTemConfig.getString('linearPlot'); | |
34479 valueScaleTools.appendChild(this.linButton); | |
34480 this.linButton.onclick = function() { | |
34481 setValueScale(true); | |
34482 } | |
34483 | |
34484 this.logButton = document.createElement("div"); | |
34485 this.logButton.title = GeoTemConfig.getString('logarithmicPlot'); | |
34486 valueScaleTools.appendChild(this.logButton); | |
34487 this.logButton.onclick = function() { | |
34488 setValueScale(false); | |
34489 } | |
34490 if (options.rangeAnimation) { | |
34491 titles.appendChild(this.timeAnimation); | |
34492 tools.appendChild(timeAnimationTools); | |
34493 this.updateAnimationButtons(0); | |
34494 } | |
34495 | |
34496 if (options.scaleSelection) { | |
34497 titles.appendChild(this.valueScale); | |
34498 tools.appendChild(valueScaleTools); | |
34499 setValueScale(options.linearScale); | |
34500 } | |
34501 | |
34502 if (GeoTemConfig.allowFilter) { | |
34503 this.filterTitle = document.createElement("td"); | |
34504 titles.appendChild(this.filterTitle); | |
34505 this.filterTitle.innerHTML = GeoTemConfig.getString('filter'); | |
34506 this.filterOptions = document.createElement("td"); | |
34507 tools.appendChild(this.filterOptions); | |
34508 } | |
34509 | |
34510 if (options.dataInformation) { | |
34511 this.infoTitle = document.createElement("td"); | |
34512 this.infoTitle.innerHTML = options.timeTitle; | |
34513 titles.appendChild(this.infoTitle); | |
34514 var timeSum = document.createElement("td"); | |
34515 this.timeElements = document.createElement("div"); | |
34516 this.timeElements.setAttribute('class', 'ddbElementsCount'); | |
34517 timeSum.appendChild(this.timeElements); | |
34518 tools.appendChild(timeSum); | |
34519 } | |
34520 | |
34521 /* | |
34522 var tooltip = document.createElement("div"); | |
34523 tooltip.setAttribute('class','ddbTooltip'); | |
34524 toolbarTable.appendChild(tooltip); | |
34525 | |
34526 tooltip.onmouseover = function(){ | |
34527 /* | |
34528 getPublisher().Publish('TooltipContent', { | |
34529 content: GeoTemConfig.getString(GeoTemConfig.language,'timeHelp'), | |
34530 target: $(tooltip) | |
34531 }); | |
34532 | |
34533 } | |
34534 tooltip.onmouseout = function(){ | |
34535 //getPublisher().Publish('TooltipContent'); | |
34536 } | |
34537 */ | |
34538 | |
34539 this.setHeight = function() { | |
34540 this.container.style.height = (this.plotWindow.offsetHeight + toolbarTable.offsetHeight) + "px"; | |
34541 }; | |
34542 | |
34543 this.updateTimeQuantity = function(count) { | |
34544 if (options.dataInformation) { | |
34545 this.plotCount = count; | |
34546 if (count != 1) { | |
34547 this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('results'); | |
34548 } else { | |
34549 this.timeElements.innerHTML = this.beautifyCount(count) + " " + GeoTemConfig.getString('result'); | |
34550 } | |
34551 } | |
34552 } | |
34553 | |
34554 this.setTimeUnitDropdown = function(units) { | |
34555 $(this.timeUnitSelector).empty(); | |
34556 var gui = this; | |
34557 var timeUnits = []; | |
34558 var addUnit = function(unit, index) { | |
34559 var setUnit = function() { | |
34560 gui.plot.setTimeUnit(unit.unit); | |
34561 } | |
34562 timeUnits.push({ | |
34563 name : unit.label, | |
34564 onclick : setUnit | |
34565 }); | |
34566 } | |
34567 for (var i = 0; i < units.length; i++) { | |
34568 addUnit(units[i], i); | |
34569 } | |
34570 this.timeUnitDropdown = new Dropdown(this.timeUnitSelector, timeUnits, GeoTemConfig.getString('selectTimeUnit'), '100px'); | |
34571 this.timeUnitDropdown.setEntry(0); | |
34572 } | |
34573 this.setTimeUnitDropdown([{ | |
34574 name : 'none', | |
34575 id : -1 | |
34576 }]); | |
34577 | |
34578 this.beautifyCount = function(count) { | |
34579 var c = count + ''; | |
34580 var p = 0; | |
34581 var l = c.length; | |
34582 while (l - p > 3) { | |
34583 p += 3; | |
34584 c = c.substring(0, l - p) + "." + c.substring(l - p); | |
34585 p++; | |
34586 l++; | |
34587 } | |
34588 return c; | |
34589 } | |
34590 | |
34591 this.hideTimeUnitSelection = function() { | |
34592 this.timeUnitTitle.style.display = 'none'; | |
34593 this.timeUnitSelector.style.display = 'none'; | |
34594 } | |
34595 }; | |
34596 /* | |
34597 * TimeWidget.js | |
34598 * | |
34599 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
34600 * | |
34601 * This library is free software; you can redistribute it and/or | |
34602 * modify it under the terms of the GNU Lesser General Public | |
34603 * License as published by the Free Software Foundation; either | |
34604 * version 3 of the License, or (at your option) any later version. | |
34605 * | |
34606 * This library is distributed in the hope that it will be useful, | |
34607 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
34608 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
34609 * Lesser General Public License for more details. | |
34610 * | |
34611 * You should have received a copy of the GNU Lesser General Public | |
34612 * License along with this library; if not, write to the Free Software | |
34613 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
34614 * MA 02110-1301 USA | |
34615 */ | |
34616 | |
34617 /** | |
34618 * @class TimeWidget | |
34619 * TableWidget Implementation | |
34620 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
34621 * @release 1.0 | |
34622 * @release date: 2012-07-27 | |
34623 * @version date: 2012-07-27 | |
34624 * | |
34625 * @param {TimeWrapper} core wrapper for interaction to other widgets | |
34626 * @param {HTML object} div parent div to append the time widget div | |
34627 * @param {JSON} options user specified configuration that overwrites options in TimeConfig.js | |
34628 */ | |
34629 TimeWidget = function(core, div, options) { | |
34630 | |
34631 this.core = core; | |
34632 this.core.setWidget(this); | |
34633 this.timeplot | |
34634 this.dataSources | |
34635 this.eventSources | |
34636 this.tds | |
34637 this.timeGeometry | |
34638 this.valueGeometry | |
34639 this.canvas | |
34640 | |
34641 this.leftFlagPole | |
34642 this.rightFlagPole | |
34643 this.rangeBox | |
34644 this.leftHandle | |
34645 this.rightHandle | |
34646 | |
34647 this.leftFlagPos = null; | |
34648 this.leftFlagTime = null; | |
34649 this.rightFlagPos = null; | |
34650 this.rightFlagTime = null; | |
34651 | |
34652 this.mouseDownTime | |
34653 this.mouseUpTime | |
34654 this.mouseTempTime | |
34655 this.mouseDownPos | |
34656 this.mouseUpPos | |
34657 this.mouseTempPos | |
34658 | |
34659 this.status | |
34660 this.slider | |
34661 | |
34662 this.iid = GeoTemConfig.getIndependentId('time'); | |
34663 this.options = (new TimeConfig(options)).options; | |
34664 this.gui = new TimeGui(this, div, this.options, this.iid); | |
34665 this.initialize(); | |
34666 | |
34667 } | |
34668 | |
34669 TimeWidget.prototype = { | |
34670 | |
34671 /** | |
34672 * clears the timeplot canvas and the timeGeometry properties | |
34673 */ | |
34674 clearTimeplot : function() { | |
34675 this.timeplot._clearCanvas(); | |
34676 this.timeGeometry._earliestDate = null; | |
34677 this.timeGeometry._latestDate = null; | |
34678 this.valueGeometry._minValue = 0; | |
34679 this.valueGeometry._maxValue = 0; | |
34680 this.highlightedSlice = undefined; | |
34681 this.timeGeometry._clearLabels(); | |
34682 this.selection = new Selection(); | |
34683 }, | |
34684 | |
34685 /** | |
34686 * initializes the timeplot elements with arrays of time objects | |
34687 * @param {TimeObject[][]} timeObjects an array of time objects from different (1-4) sets | |
34688 */ | |
34689 initWidget : function(datasets) { | |
34690 this.datasets = datasets; | |
34691 var timeObjects = []; | |
34692 for (var i = 0; i < datasets.length; i++) { | |
34693 timeObjects.push(datasets[i].objects); | |
34694 } | |
34695 this.clearTimeplot(); | |
34696 this.reset(); | |
34697 for (var i = 0; i < this.timeplot._plots.length; i++) { | |
34698 this.timeplot._plots[i].dispose(); | |
34699 } | |
34700 this.dataSources = new Array(); | |
34701 this.plotInfos = new Array(); | |
34702 this.eventSources = new Array(); | |
34703 var granularity = 0; | |
34704 this.count = 0; | |
34705 for (var i = 0; i < timeObjects.length; i++) { | |
34706 if( i==0 || !this.options.timeMerge ){ | |
34707 var eventSource = new Timeplot.DefaultEventSource(); | |
34708 var dataSource = new Timeplot.ColumnSource(eventSource, 1); | |
34709 this.dataSources.push(dataSource); | |
34710 this.eventSources.push(eventSource); | |
34711 var c = GeoTemConfig.getColor(i); | |
34712 var plotInfo = Timeplot.createPlotInfo({ | |
34713 id : "plot" + i, | |
34714 dataSource : dataSource, | |
34715 timeGeometry : this.timeGeometry, | |
34716 valueGeometry : this.valueGeometry, | |
34717 fillGradient : false, | |
34718 lineColor : 'rgba(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ', 1)', | |
34719 fillColor : 'rgba(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ', 0.3)', | |
34720 showValues : true | |
34721 }); | |
34722 this.plotInfos.push(plotInfo); | |
34723 } | |
34724 for (var j = 0; j < timeObjects[i].length; j++) { | |
34725 var o = timeObjects[i][j]; | |
34726 if (o.isTemporal) { | |
34727 var g = o.dates[this.options.timeIndex].granularity; | |
34728 if (g == null) { | |
34729 continue; | |
34730 } else if (g > granularity) { | |
34731 granularity = g; | |
34732 } | |
34733 this.count += o.weight; | |
34734 } | |
34735 } | |
34736 } | |
34737 this.timeGeometry._granularity = granularity; | |
34738 this.timeGeometry._clearLabels(); | |
34739 this.timeplot.resetPlots(this.plotInfos); | |
34740 if (this.plotInfos.length == 0) { | |
34741 this.initLabels(this.timeplot.regularGrid()); | |
34742 return; | |
34743 } | |
34744 this.timeGeometry.extendedDataSource = this.tds; | |
34745 this.tds.initialize(this.dataSources, this.eventSources, timeObjects, granularity, this.options.timeUnit, this.gui.timeplotDiv.offsetWidth); | |
34746 this.gui.setTimeUnitDropdown(this.tds.availableUnits); | |
34747 this.gui.timeUnitDropdown.setEntry(this.tds.getUnitIndex()); | |
34748 var plots = this.timeplot._plots; | |
34749 for (var i = 0; i < plots.length; i++) { | |
34750 plots[i].pins = []; | |
34751 plots[i].style = this.style; | |
34752 for (var j = 0; j < this.tds.getSliceNumber(); j++) { | |
34753 plots[i].pins.push({ | |
34754 height : 0, | |
34755 count : 0 | |
34756 }); | |
34757 } | |
34758 } | |
34759 /* | |
34760 var levels = Math.round( (this.tds.timeSlices.length-3)/2 ); | |
34761 if( GeoTemConfig.timeZoom ){ | |
34762 this.zoomSlider.setMaxAndLevels(levels,levels); | |
34763 } | |
34764 */ | |
34765 this.timeplot.repaint(); | |
34766 this.timeplot._resizeCanvas(); | |
34767 // set maximum number of slider steps | |
34768 var slices = this.tds.timeSlices.length; | |
34769 var numSlices = Math.floor(slices / this.canvas.width * this.canvas.height + 0.5); | |
34770 | |
34771 this.initLabels([]); | |
34772 this.initOverview(); | |
34773 this.gui.updateTimeQuantity(this.count); | |
34774 | |
34775 }, | |
34776 | |
34777 setTimeUnit : function(unit) { | |
34778 this.clearTimeplot(); | |
34779 this.reset(); | |
34780 this.tds.setTimeUnit(unit); | |
34781 var plots = this.timeplot._plots; | |
34782 for (var i = 0; i < plots.length; i++) { | |
34783 plots[i].pins = []; | |
34784 plots[i].style = this.style; | |
34785 for (var j = 0; j < this.tds.getSliceNumber(); j++) { | |
34786 plots[i].pins.push({ | |
34787 height : 0, | |
34788 count : 0 | |
34789 }); | |
34790 } | |
34791 } | |
34792 this.initLabels([]); | |
34793 }, | |
34794 | |
34795 /** | |
34796 * initializes the timeplot for the Spatio Temporal Interface. | |
34797 * all elements (including their events) that are needed for user interaction are instantiated here, the slider element as well | |
34798 */ | |
34799 initialize : function() { | |
34800 | |
34801 this.status = 0; | |
34802 this.selection = new Selection(); | |
34803 this.paused = true; | |
34804 this.dataSources = new Array(); | |
34805 this.plotInfos = new Array(); | |
34806 this.eventSources = new Array(); | |
34807 this.timeGeometry = new Timeplot.DefaultTimeGeometry({ | |
34808 gridColor : "#000000", | |
34809 axisLabelsPlacement : "top" | |
34810 }); | |
34811 this.style = 'graph'; | |
34812 this.timeGeometry._hideLabels = true; | |
34813 this.timeGeometry._granularity = 0; | |
34814 this.valueGeometry = new Timeplot.LogarithmicValueGeometry({ | |
34815 min : 0 | |
34816 }); | |
34817 this.valueGeometry.actLinear(); | |
34818 | |
34819 var plot = this; | |
34820 | |
34821 this.timeplot = Timeplot.create(this.gui.timeplotDiv, this.plotInfos); | |
34822 this.tds = new TimeDataSource(this.options); | |
34823 | |
34824 this.canvas = this.timeplot.getCanvas(); | |
34825 | |
34826 this.leftFlagPole = this.timeplot.putDiv("leftflagpole", "timeplot-dayflag-pole"); | |
34827 this.rightFlagPole = this.timeplot.putDiv("rightflagpole", "timeplot-dayflag-pole"); | |
34828 SimileAjax.Graphics.setOpacity(this.leftFlagPole, 50); | |
34829 SimileAjax.Graphics.setOpacity(this.rightFlagPole, 50); | |
34830 | |
34831 this.rangeBox = this.timeplot.putDiv("rangebox", "range-box"); | |
34832 this.rangeBox.style.backgroundColor = plot.options.rangeBoxColor; | |
34833 this.rangeBox.style.border = plot.options.rangeBorder; | |
34834 | |
34835 this.leftHandle = document.createElement("div"); | |
34836 this.rightHandle = document.createElement("div"); | |
34837 this.gui.plotWindow.appendChild(this.leftHandle); | |
34838 this.gui.plotWindow.appendChild(this.rightHandle); | |
34839 this.leftHandle.title = GeoTemConfig.getString('leftHandle'); | |
34840 this.rightHandle.title = GeoTemConfig.getString('rightHandle'); | |
34841 | |
34842 this.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
34843 this.leftHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
34844 this.rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")"; | |
34845 this.rightHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
34846 | |
34847 this.poles = this.timeplot.putDiv("poles", "pole"); | |
34848 this.timeplot.placeDiv(this.poles, { | |
34849 left : 0, | |
34850 bottom : 0, | |
34851 width : this.canvas.width, | |
34852 height : this.canvas.height, | |
34853 display : "block" | |
34854 }); | |
34855 this.poles.appendChild(document.createElement("canvas")); | |
34856 | |
34857 this.filterBar = new FilterBar(this, this.gui.filterOptions); | |
34858 | |
34859 var plot = this; | |
34860 | |
34861 this.dragButton = document.createElement("div"); | |
34862 this.dragButton.title = GeoTemConfig.getString('dragTimeRange'); | |
34863 this.cancelButton = document.createElement("div"); | |
34864 this.cancelButton.title = GeoTemConfig.getString('clearSelection'); | |
34865 this.cancelButton.onclick = function() { | |
34866 plot.deselection(); | |
34867 } | |
34868 | |
34869 this.toolbar = document.createElement("div"); | |
34870 this.toolbar.setAttribute('class', 'plotToolbar'); | |
34871 this.toolbar.style.borderTop = plot.options.rangeBorder; | |
34872 this.toolbar.style.textAlign = "center"; | |
34873 this.gui.plotWindow.appendChild(this.toolbar); | |
34874 | |
34875 this.toolbarAbsoluteDiv = document.createElement("div"); | |
34876 this.toolbarAbsoluteDiv.setAttribute('class', 'absoluteToolbar'); | |
34877 this.toolbar.appendChild(this.toolbarAbsoluteDiv); | |
34878 | |
34879 this.dragButton.setAttribute('class', 'dragTimeRangeAlt'); | |
34880 this.dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")"; | |
34881 // this.zoomButton.setAttribute('class','zoomRangeAlt'); | |
34882 this.cancelButton.setAttribute('class', 'cancelRangeAlt'); | |
34883 this.toolbarAbsoluteDiv.appendChild(this.dragButton); | |
34884 this.toolbarAbsoluteDiv.style.width = this.dragButton.offsetWidth + "px"; | |
34885 // this.gui.plotWindow.appendChild(this.zoomButton); | |
34886 this.gui.plotWindow.appendChild(this.cancelButton); | |
34887 | |
34888 this.overview = document.createElement("div"); | |
34889 this.overview.setAttribute('class', 'timeOverview'); | |
34890 this.gui.plotWindow.appendChild(this.overview); | |
34891 | |
34892 var mousedown = false; | |
34893 this.shift = function(shift) { | |
34894 if (!mousedown) { | |
34895 return; | |
34896 } | |
34897 if (plot.tds.setShift(shift)) { | |
34898 plot.redrawPlot(); | |
34899 } | |
34900 setTimeout(function() { | |
34901 plot.shift(shift); | |
34902 }, 200); | |
34903 } | |
34904 var shiftPressed = function(shift) { | |
34905 mousedown = true; | |
34906 document.onmouseup = function() { | |
34907 mousedown = false; | |
34908 document.onmouseup = null; | |
34909 } | |
34910 plot.shift(shift); | |
34911 } | |
34912 | |
34913 this.shiftLeft = document.createElement("div"); | |
34914 this.shiftLeft.setAttribute('class', 'shiftLeft'); | |
34915 this.gui.plotWindow.appendChild(this.shiftLeft); | |
34916 this.shiftLeft.onmousedown = function() { | |
34917 shiftPressed(1); | |
34918 } | |
34919 | |
34920 this.shiftRight = document.createElement("div"); | |
34921 this.shiftRight.setAttribute('class', 'shiftRight'); | |
34922 this.gui.plotWindow.appendChild(this.shiftRight); | |
34923 this.shiftRight.onmousedown = function() { | |
34924 shiftPressed(-1); | |
34925 } | |
34926 | |
34927 this.plotLabels = document.createElement("div"); | |
34928 this.plotLabels.setAttribute('class', 'plotLabels'); | |
34929 this.gui.plotWindow.appendChild(this.plotLabels); | |
34930 | |
34931 this.initLabels(this.timeplot.regularGrid()); | |
34932 | |
34933 //Finds the time corresponding to the position x on the timeplot | |
34934 var getCorrelatedTime = function(x) { | |
34935 if (x >= plot.canvas.width) | |
34936 x = plot.canvas.width; | |
34937 if (isNaN(x) || x < 0) | |
34938 x = 0; | |
34939 var t = plot.timeGeometry.fromScreen(x); | |
34940 if (t == 0) | |
34941 return; | |
34942 return plot.dataSources[0].getClosestValidTime(t); | |
34943 } | |
34944 //Finds the position corresponding to the time t on the timeplot | |
34945 var getCorrelatedPosition = function(t) { | |
34946 var x = plot.timeGeometry.toScreen(t); | |
34947 if (x >= plot.canvas.width) | |
34948 x = plot.canvas.width; | |
34949 if (isNaN(x) || x < 0) | |
34950 x = 0; | |
34951 return x; | |
34952 } | |
34953 //Maps the 2 positions in the right order to left and right bound of the chosen timeRange | |
34954 var mapPositions = function(pos1, pos2) { | |
34955 if (pos1 > pos2) { | |
34956 plot.leftFlagPos = pos2; | |
34957 plot.rightFlagPos = pos1; | |
34958 } else { | |
34959 plot.leftFlagPos = pos1; | |
34960 plot.rightFlagPos = pos2; | |
34961 } | |
34962 plot.leftFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.leftFlagPos)); | |
34963 plot.rightFlagTime = plot.dataSources[0].getClosestValidTime(plot.timeGeometry.fromScreen(plot.rightFlagPos)); | |
34964 } | |
34965 //Sets the divs corresponding to the actual chosen timeRange | |
34966 var setRangeDivs = function() { | |
34967 plot.leftFlagPole.style.visibility = "visible"; | |
34968 plot.rightFlagPole.style.visibility = "visible"; | |
34969 plot.rangeBox.style.visibility = "visible"; | |
34970 plot.timeplot.placeDiv(plot.leftFlagPole, { | |
34971 left : plot.leftFlagPos, | |
34972 bottom : 0, | |
34973 height : plot.canvas.height, | |
34974 display : "block" | |
34975 }); | |
34976 plot.timeplot.placeDiv(plot.rightFlagPole, { | |
34977 left : plot.rightFlagPos, | |
34978 bottom : 0, | |
34979 height : plot.canvas.height, | |
34980 display : "block" | |
34981 }); | |
34982 var boxWidth = plot.rightFlagPos - plot.leftFlagPos; | |
34983 if (plot.popup) { | |
34984 plot.popupClickDiv.style.visibility = "visible"; | |
34985 plot.timeplot.placeDiv(plot.popupClickDiv, { | |
34986 left : plot.leftFlagPos, | |
34987 width : boxWidth + 1, | |
34988 height : plot.canvas.height, | |
34989 display : "block" | |
34990 }); | |
34991 } | |
34992 plot.timeplot.placeDiv(plot.rangeBox, { | |
34993 left : plot.leftFlagPos, | |
34994 width : boxWidth + 1, | |
34995 height : plot.canvas.height, | |
34996 display : "block" | |
34997 }); | |
34998 var plots = plot.timeplot._plots; | |
34999 for ( i = 0; i < plots.length; i++) { | |
35000 plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i)); | |
35001 plots[i].opacityPlot.style.visibility = "visible"; | |
35002 } | |
35003 var unit = plot.tds.unit; | |
35004 | |
35005 var top = plot.gui.plotContainer.offsetTop; | |
35006 var left = plot.gui.plotContainer.offsetLeft; | |
35007 var leftPos = plot.leftFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft; | |
35008 var rightPos = plot.rightFlagPole.offsetLeft + plot.timeplot.getElement().offsetLeft; | |
35009 var rW = rightPos - leftPos; | |
35010 var pW = plot.canvas.width; | |
35011 var pL = plot.timeplot.getElement().offsetLeft; | |
35012 | |
35013 var handleTop = top + Math.floor(plot.gui.timeplotDiv.offsetHeight / 2 - plot.leftHandle.offsetHeight / 2); | |
35014 plot.leftHandle.style.visibility = "visible"; | |
35015 plot.rightHandle.style.visibility = "visible"; | |
35016 plot.leftHandle.style.left = (leftPos - plot.leftHandle.offsetWidth / 2) + "px"; | |
35017 plot.rightHandle.style.left = (rightPos - plot.rightHandle.offsetWidth + 1 + plot.rightHandle.offsetWidth / 2) + "px"; | |
35018 plot.leftHandle.style.top = handleTop + "px"; | |
35019 plot.rightHandle.style.top = handleTop + "px"; | |
35020 if (rightPos == leftPos) { | |
35021 plot.rightHandle.style.visibility = "hidden"; | |
35022 plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "mergedHandle.png" + ")"; | |
35023 } else { | |
35024 plot.leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
35025 } | |
35026 plot.cancelButton.style.visibility = "visible"; | |
35027 plot.cancelButton.style.top = top + "px"; | |
35028 | |
35029 if (rW > plot.cancelButton.offsetWidth) { | |
35030 plot.cancelButton.style.left = (left + rightPos - plot.cancelButton.offsetWidth) + "px"; | |
35031 } else { | |
35032 plot.cancelButton.style.left = (left + rightPos) + "px"; | |
35033 } | |
35034 var tW = plot.toolbarAbsoluteDiv.offsetWidth; | |
35035 if (rW >= tW) { | |
35036 plot.toolbar.style.left = leftPos + "px"; | |
35037 plot.toolbar.style.width = (rW + 1) + "px"; | |
35038 plot.toolbarAbsoluteDiv.style.left = ((rW - tW) / 2) + "px"; | |
35039 } else { | |
35040 plot.toolbar.style.left = (pL + plot.leftFlagPos * (pW - tW) / (pW - rW)) + "px"; | |
35041 plot.toolbar.style.width = (tW + 2) + "px"; | |
35042 plot.toolbarAbsoluteDiv.style.left = "0px"; | |
35043 } | |
35044 plot.toolbar.style.top = (top + plot.timeplot.getElement().offsetHeight) + "px"; | |
35045 plot.toolbar.style.visibility = "visible"; | |
35046 plot.toolbarAbsoluteDiv.style.visibility = "visible"; | |
35047 | |
35048 } | |
35049 var getAbsoluteLeft = function(div) { | |
35050 var left = 0; | |
35051 while (div) { | |
35052 left += div.offsetLeft; | |
35053 div = div.offsetParent; | |
35054 } | |
35055 return left; | |
35056 } | |
35057 var timeplotLeft = getAbsoluteLeft(plot.timeplot.getElement()); | |
35058 | |
35059 var checkPolesForStyle = function(x) { | |
35060 if (plot.style == 'bars' && plot.leftFlagTime == plot.rightFlagTime) { | |
35061 var index = plot.tds.getSliceIndex(plot.leftFlagTime); | |
35062 var time1 = plot.leftFlagTime; | |
35063 var pos1 = plot.leftFlagPos; | |
35064 var time2, pos2; | |
35065 if (index == 0) { | |
35066 time2 = plot.tds.getSliceTime(index + 1); | |
35067 } else if (index == plot.tds.getSliceNumber() - 1) { | |
35068 time2 = plot.tds.getSliceTime(index - 1); | |
35069 } else { | |
35070 if (x < plot.leftFlagPos) { | |
35071 time2 = plot.tds.getSliceTime(index - 1); | |
35072 } else { | |
35073 time2 = plot.tds.getSliceTime(index + 1); | |
35074 } | |
35075 } | |
35076 pos2 = plot.timeGeometry.toScreen(time2); | |
35077 mapPositions(pos1, pos2, time1, time2); | |
35078 } | |
35079 } | |
35080 var startX, startY, multiplier; | |
35081 | |
35082 // mousemove function that causes moving selection of objects and toolbar divs | |
35083 var moveToolbar = function(start, actual) { | |
35084 var pixelShift = actual - start; | |
35085 if (plot.status == 2) { | |
35086 var newTime = getCorrelatedTime(startX + pixelShift); | |
35087 if (newTime == plot.mouseTempTime) { | |
35088 return; | |
35089 } | |
35090 plot.mouseTempTime = newTime; | |
35091 plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime); | |
35092 mapPositions(plot.mouseDownPos, plot.mouseTempPos); | |
35093 } else if (plot.status == 3) { | |
35094 pixelShift *= multiplier; | |
35095 var plotPos = actual - timeplotLeft; | |
35096 if (plotPos <= plot.canvas.width / 2) { | |
35097 var newTime = getCorrelatedTime(startX + pixelShift); | |
35098 if (newTime == plot.leftFlagTime) { | |
35099 return; | |
35100 } | |
35101 plot.leftFlagTime = newTime; | |
35102 var diff = plot.leftFlagPos; | |
35103 plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime); | |
35104 diff -= plot.leftFlagPos; | |
35105 plot.rightFlagTime = getCorrelatedTime(plot.rightFlagPos - diff); | |
35106 plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime); | |
35107 } else { | |
35108 var newTime = getCorrelatedTime(startY + pixelShift); | |
35109 if (newTime == plot.rightFlagTime) { | |
35110 return; | |
35111 } | |
35112 plot.rightFlagTime = newTime; | |
35113 var diff = plot.rightFlagPos; | |
35114 plot.rightFlagPos = plot.timeGeometry.toScreen(plot.rightFlagTime); | |
35115 diff -= plot.rightFlagPos; | |
35116 plot.leftFlagTime = getCorrelatedTime(plot.leftFlagPos - diff); | |
35117 plot.leftFlagPos = plot.timeGeometry.toScreen(plot.leftFlagTime); | |
35118 } | |
35119 } | |
35120 checkPolesForStyle(actual - timeplotLeft); | |
35121 setRangeDivs(); | |
35122 plot.timeSelection(); | |
35123 } | |
35124 // fakes user interaction mouse move | |
35125 var playIt = function(start, actual, reset) { | |
35126 if (!plot.paused) { | |
35127 var pixel = plot.canvas.width / (plot.tds.timeSlices.length - 1 ) / 5; | |
35128 var wait = 20 * pixel; | |
35129 if (reset) { | |
35130 actual = 0; | |
35131 } | |
35132 moveToolbar(start, actual); | |
35133 if (plot.rightFlagPos >= plot.canvas.width) { | |
35134 reset = true; | |
35135 wait = 1000; | |
35136 } else { | |
35137 reset = false; | |
35138 } | |
35139 setTimeout(function() { | |
35140 playIt(start, actual + pixel, reset) | |
35141 }, wait); | |
35142 } | |
35143 } | |
35144 var setMultiplier = function() { | |
35145 var rangeWidth = plot.rightFlagPos - plot.leftFlagPos; | |
35146 var toolbarWidth = plot.toolbarAbsoluteDiv.offsetWidth; | |
35147 var plotWidth = plot.canvas.width; | |
35148 if (rangeWidth < toolbarWidth) { | |
35149 multiplier = (plotWidth - rangeWidth) / (plotWidth - toolbarWidth); | |
35150 } else { | |
35151 multiplier = 1; | |
35152 } | |
35153 } | |
35154 /** | |
35155 * starts the animation | |
35156 */ | |
35157 this.play = function() { | |
35158 if (this.leftFlagPos == null) { | |
35159 return; | |
35160 } | |
35161 plot.paused = false; | |
35162 plot.gui.updateAnimationButtons(2); | |
35163 plot.status = 3; | |
35164 setMultiplier(); | |
35165 startX = plot.leftFlagPos; | |
35166 startY = plot.rightFlagPos; | |
35167 var position = Math.round(plot.leftFlagPos); | |
35168 playIt(position, position + 1, false); | |
35169 } | |
35170 /** | |
35171 * stops the animation | |
35172 */ | |
35173 this.stop = function() { | |
35174 plot.paused = true; | |
35175 plot.status = 0; | |
35176 plot.gui.updateAnimationButtons(1); | |
35177 } | |
35178 // triggers the mousemove function to move the range and toolbar | |
35179 var toolbarEvent = function(evt) { | |
35180 var left = GeoTemConfig.getMousePosition(evt).left; | |
35181 document.onmousemove = function(evt) { | |
35182 moveToolbar(left, GeoTemConfig.getMousePosition(evt).left); | |
35183 if (plot.popup) { | |
35184 plot.popup.reset(); | |
35185 } | |
35186 } | |
35187 } | |
35188 var initializeLeft = function() { | |
35189 plot.mouseDownTime = plot.rightFlagTime; | |
35190 plot.mouseTempTime = plot.leftFlagTime; | |
35191 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
35192 startX = plot.leftFlagPos; | |
35193 } | |
35194 var initializeRight = function() { | |
35195 plot.mouseDownTime = plot.leftFlagTime; | |
35196 plot.mouseTempTime = plot.rightFlagTime; | |
35197 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
35198 startX = plot.rightFlagPos; | |
35199 } | |
35200 var initializeDrag = function() { | |
35201 startX = plot.leftFlagPos; | |
35202 startY = plot.rightFlagPos; | |
35203 setMultiplier(); | |
35204 } | |
35205 var checkBorders = function() { | |
35206 if (plot.style == 'bars' && plot.mouseUpTime == plot.mouseDownTime) { | |
35207 var index = plot.tds.getSliceIndex(plot.mouseUpTime); | |
35208 if (index == 0) { | |
35209 plot.mouseUpTime = plot.tds.getSliceTime(index + 1); | |
35210 } else if (index == plot.tds.getSliceNumber() - 1) { | |
35211 plot.mouseUpTime = plot.tds.getSliceTime(index - 1); | |
35212 } else { | |
35213 if (plot.x < plot.leftFlagPos) { | |
35214 plot.mouseUpTime = plot.tds.getSliceTime(index - 1); | |
35215 } else { | |
35216 plot.mouseUpTime = plot.tds.getSliceTime(index + 1); | |
35217 } | |
35218 } | |
35219 } | |
35220 } | |
35221 // handles mousedown on left handle | |
35222 this.leftHandle.onmousedown = function(evt) { | |
35223 if (plot.status != 2) { | |
35224 | |
35225 initializeLeft(); | |
35226 plot.status = 2; | |
35227 toolbarEvent(evt); | |
35228 document.onmouseup = function() { | |
35229 document.onmousemove = null; | |
35230 document.onmouseup = null; | |
35231 plot.stop(); | |
35232 } | |
35233 } | |
35234 } | |
35235 // handles mousedown on right handle | |
35236 this.rightHandle.onmousedown = function(evt) { | |
35237 if (plot.status != 2) { | |
35238 initializeRight(); | |
35239 plot.status = 2; | |
35240 toolbarEvent(evt); | |
35241 document.onmouseup = function() { | |
35242 document.onmousemove = null; | |
35243 document.onmouseup = null; | |
35244 plot.stop(); | |
35245 } | |
35246 } | |
35247 } | |
35248 // handles mousedown on drag button | |
35249 this.dragButton.onmousedown = function(evt) { | |
35250 if (plot.status != 3) { | |
35251 plot.status = 3; | |
35252 initializeDrag(); | |
35253 toolbarEvent(evt); | |
35254 document.onmouseup = function() { | |
35255 document.onmousemove = null; | |
35256 document.onmouseup = null; | |
35257 plot.stop(); | |
35258 } | |
35259 } | |
35260 } | |
35261 // handles mousedown-Event on timeplot | |
35262 var mouseDownHandler = function(elmt, evt, target) { | |
35263 if (plot.dataSources.length > 0) { | |
35264 | |
35265 plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35266 if (plot.status == 0) { | |
35267 var time = getCorrelatedTime(plot.x); | |
35268 if (plot.leftFlagPos != null && plot.popup && time >= plot.leftFlagTime && time <= plot.rightFlagTime) { | |
35269 var x = plot.leftFlagPos + (plot.rightFlagPos - plot.leftFlagPos) / 2; | |
35270 var elements = []; | |
35271 for (var i = 0; i < plot.dataSources.length; i++) { | |
35272 elements.push([]); | |
35273 } | |
35274 for (var i = 0; i < plot.selectedObjects.length; i++) { | |
35275 if (plot.selectedObjects[i].value == 1) { | |
35276 for (var j = 0; j < plot.selectedObjects[i].objects.length; j++) { | |
35277 elements[j] = elements[j].concat(plot.selectedObjects[i].objects[j]); | |
35278 } | |
35279 } | |
35280 } | |
35281 var labels = []; | |
35282 for (var i = 0; i < elements.length; i++) { | |
35283 if (elements[i].length == 0) { | |
35284 continue; | |
35285 } | |
35286 var c = GeoTemConfig.getColor(i); | |
35287 var color = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
35288 var div = document.createElement("div"); | |
35289 div.setAttribute('class', 'tagCloudItem'); | |
35290 div.style.color = color; | |
35291 var label = { | |
35292 div : div, | |
35293 elements : elements[i] | |
35294 }; | |
35295 var weight = 0; | |
35296 for (j in elements[i] ) { | |
35297 weight += elements[i][j].weight; | |
35298 } | |
35299 var fs = 2 * weight / 1000; | |
35300 if (fs > 2) { | |
35301 fs = 2; | |
35302 } | |
35303 div.style.fontSize = (1 + fs) + "em"; | |
35304 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + c.hex; | |
35305 if (weight == 1) { | |
35306 div.innerHTML = weight + " object"; | |
35307 } else { | |
35308 div.innerHTML = weight + " objects"; | |
35309 } | |
35310 var appendMouseFunctions = function(label, div, color) { | |
35311 div.onclick = function() { | |
35312 plot.popup.showLabelContent(label); | |
35313 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color; | |
35314 } | |
35315 div.onmouseover = function() { | |
35316 div.style.textShadow = "0 -1px " + color + ", 1px 0 " + color + ", 0 1px " + color + ", -1px 0 " + color; | |
35317 } | |
35318 div.onmouseout = function() { | |
35319 div.style.textShadow = "0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em black, 0 0 0.4em " + color; | |
35320 } | |
35321 } | |
35322 appendMouseFunctions(label, div, c.hex); | |
35323 labels.push(label); | |
35324 } | |
35325 if (labels.length > 0) { | |
35326 plot.popup.createPopup(x + 20, 0, labels); | |
35327 } | |
35328 } else { | |
35329 plot.deselection(); | |
35330 plot.status = 1; | |
35331 plot.mouseDownTime = time; | |
35332 plot.mouseTempTime = plot.mouseDownTime; | |
35333 plot.mouseDownPos = plot.timeGeometry.toScreen(plot.mouseDownTime); | |
35334 mapPositions(plot.mouseDownPos, plot.mouseDownPos, plot.mouseDownTime, plot.mouseDownTime); | |
35335 // handles mouseup-Event on timeplot | |
35336 document.onmouseup = function() { | |
35337 if (plot.status == 1) { | |
35338 plot.mouseUpTime = plot.mouseTempTime; | |
35339 plot.mouseUpPos = plot.timeGeometry.toScreen(plot.mouseUpTime); | |
35340 mapPositions(plot.mouseDownPos, plot.mouseUpPos, plot.mouseDownTime, plot.mouseUpTime); | |
35341 checkPolesForStyle(plot.x); | |
35342 setRangeDivs(); | |
35343 plot.timeSelection(); | |
35344 plot.gui.updateAnimationButtons(1); | |
35345 document.onmouseup = null; | |
35346 plot.status = 0; | |
35347 } | |
35348 } | |
35349 } | |
35350 } | |
35351 } | |
35352 } | |
35353 // handles mousemove-Event on timeplot | |
35354 var mouseMoveHandler = function(elmt, evt, target) { | |
35355 if (plot.dataSources.length > 0) { | |
35356 plot.x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35357 if (plot.status == 1) { | |
35358 plot.mouseTempTime = getCorrelatedTime(plot.x); | |
35359 plot.mouseTempPos = plot.timeGeometry.toScreen(plot.mouseTempTime); | |
35360 mapPositions(plot.mouseDownPos, plot.mouseTempPos, plot.mouseDownTime, plot.mouseTempTime); | |
35361 checkPolesForStyle(plot.x); | |
35362 setRangeDivs(); | |
35363 } | |
35364 } | |
35365 } | |
35366 // handles mouseout-Event on timeplot | |
35367 var mouseOutHandler = function(elmt, evt, target) { | |
35368 if (plot.dataSources.length > 0) { | |
35369 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35370 var y = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).y); | |
35371 if (x > plot.canvas.width - 2 || isNaN(x) || x < 2) { | |
35372 plot.timeHighlight(true); | |
35373 plot.highlightedSlice = undefined; | |
35374 } else if (y > plot.canvas.height - 2 || isNaN(y) || y < 2) { | |
35375 plot.timeHighlight(true); | |
35376 plot.highlightedSlice = undefined; | |
35377 } | |
35378 } | |
35379 } | |
35380 // handles mouse(h)over-Event on timeplot | |
35381 var mouseHoverHandler = function(elmt, evt, target) { | |
35382 if (plot.dataSources.length > 0) { | |
35383 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35384 var time = getCorrelatedTime(x); | |
35385 if (time == undefined) { | |
35386 return; | |
35387 } | |
35388 var highlightSlice; | |
35389 var slices = plot.tds.timeSlices; | |
35390 var index = plot.tds.getSliceIndex(time); | |
35391 if (plot.style == 'graph') { | |
35392 highlightSlice = slices[index]; | |
35393 } | |
35394 if (plot.style == 'bars') { | |
35395 var pos = plot.timeGeometry.toScreen(time); | |
35396 if (x < pos && index > 0) { | |
35397 highlightSlice = slices[index - 1]; | |
35398 } else { | |
35399 highlightSlice = slices[index]; | |
35400 } | |
35401 } | |
35402 if (plot.highlightedSlice == undefined || plot.highlightedSlice != highlightSlice) { | |
35403 plot.highlightedSlice = highlightSlice; | |
35404 plot.timeHighlight(false); | |
35405 } | |
35406 } | |
35407 } | |
35408 | |
35409 this.redrawPlot = function() { | |
35410 plot.clearTimeplot(); | |
35411 plot.tds.reset(this.timeGeometry); | |
35412 plot.timeplot._prepareCanvas(); | |
35413 plot.timeplot.repaint(); | |
35414 if (plot.leftFlagPos != null) { | |
35415 plot.leftFlagPos = getCorrelatedPosition(plot.leftFlagTime); | |
35416 plot.rightFlagPos = getCorrelatedPosition(plot.rightFlagTime); | |
35417 setRangeDivs(); | |
35418 } else { | |
35419 plot.displayOverlay(); | |
35420 } | |
35421 plot.initLabels([]); | |
35422 plot.updateOverview(); | |
35423 } | |
35424 | |
35425 this.resetOpacityPlots = function() { | |
35426 var plots = plot.timeplot._plots; | |
35427 for ( var i = 0; i < plots.length; i++) { | |
35428 plots[i]._opacityCanvas.width = this.canvas.width; | |
35429 plots[i]._opacityCanvas.height = this.canvas.height; | |
35430 if( plot.leftFlagTime != null ){ | |
35431 plots[i].fullOpacityPlot(plot.leftFlagTime, plot.rightFlagTime, plot.leftFlagPos, plot.rightFlagPos, GeoTemConfig.getColor(i)); | |
35432 } | |
35433 } | |
35434 } | |
35435 | |
35436 /** | |
35437 * handles zoom of the timeplot | |
35438 * @param {int} delta the change of zoom | |
35439 * @param {Date} time a time that corresponds to a slice, that was clicked | |
35440 */ | |
35441 /* | |
35442 this.zoom = function(delta,time){ | |
35443 if( this.eventSources.length == 0 ){ | |
35444 if( GeoTemConfig.timeZoom ){ | |
35445 this.zoomSlider.setValue(0); | |
35446 } | |
35447 return false; | |
35448 } | |
35449 if( time == null ){ | |
35450 time = getCorrelatedTime(this.canvas.width/2); | |
35451 } | |
35452 if( this.tds.setZoom(delta,time,this.leftFlagTime,this.rightFlagTime) ){ | |
35453 this.redrawPlot(); | |
35454 } | |
35455 if( GeoTemConfig.timeZoom ){ | |
35456 this.zoomSlider.setValue(this.tds.getZoom()); | |
35457 } | |
35458 return true; | |
35459 } | |
35460 */ | |
35461 | |
35462 // handles mousewheel event on the timeplot | |
35463 var mouseWheelHandler = function(elmt, evt, target) { | |
35464 if (evt.preventDefault) { | |
35465 evt.preventDefault(); | |
35466 } | |
35467 if (plot.dataSources.length == 0) { | |
35468 return; | |
35469 } | |
35470 var delta = 0; | |
35471 if (!evt) | |
35472 evt = window.event; | |
35473 if (evt.wheelDelta) { | |
35474 delta = evt.wheelDelta / 120; | |
35475 if (window.opera) | |
35476 delta = -delta; | |
35477 } else if (evt.detail) { | |
35478 delta = -evt.detail / 3; | |
35479 } | |
35480 if (delta) { | |
35481 var x = Math.round(SimileAjax.DOM.getEventRelativeCoordinates(evt, plot.canvas).x); | |
35482 var time = getCorrelatedTime(x); | |
35483 plot.zoom(delta, time); | |
35484 } | |
35485 } | |
35486 var timeplotElement = this.timeplot.getElement(); | |
35487 SimileAjax.DOM.registerEvent(timeplotElement, "mousedown", mouseDownHandler); | |
35488 SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseMoveHandler); | |
35489 SimileAjax.DOM.registerEvent(timeplotElement, "mousemove", mouseHoverHandler); | |
35490 SimileAjax.DOM.registerEvent(timeplotElement, "mouseout", mouseOutHandler); | |
35491 if (GeoTemConfig.mouseWheelZoom) { | |
35492 //SimileAjax.DOM.registerEvent(timeplotElement, "mousewheel", mouseWheelHandler); | |
35493 } | |
35494 | |
35495 this.gui.setHeight(); | |
35496 | |
35497 }, | |
35498 | |
35499 resetOverlay : function() { | |
35500 this.poles.style.visibility = "hidden"; | |
35501 var plots = this.timeplot._plots; | |
35502 for (var i = 0; i < plots.length; i++) { | |
35503 for (var j = 0; j < plots[i].pins.length; j++) { | |
35504 plots[i].pins[j] = { | |
35505 height : 0, | |
35506 count : 0 | |
35507 }; | |
35508 } | |
35509 } | |
35510 }, | |
35511 | |
35512 /** | |
35513 * resets the timeplot to non selection status | |
35514 */ | |
35515 reset : function() { | |
35516 | |
35517 this.leftFlagPole.style.visibility = "hidden"; | |
35518 this.rightFlagPole.style.visibility = "hidden"; | |
35519 this.rangeBox.style.visibility = "hidden"; | |
35520 this.leftHandle.style.visibility = "hidden"; | |
35521 this.rightHandle.style.visibility = "hidden"; | |
35522 this.toolbar.style.visibility = "hidden"; | |
35523 this.toolbarAbsoluteDiv.style.visibility = "hidden"; | |
35524 this.cancelButton.style.visibility = "hidden"; | |
35525 | |
35526 var plots = this.timeplot._plots; | |
35527 for (var i = 0; i < plots.length; i++) { | |
35528 plots[i].opacityPlot.style.visibility = "hidden"; | |
35529 } | |
35530 this.resetOverlay(); | |
35531 this.filterBar.reset(false); | |
35532 | |
35533 var slices = this.tds.timeSlices; | |
35534 if (slices != undefined) { | |
35535 for (var i = 0; i < slices.length; i++) { | |
35536 slices[i].reset(); | |
35537 } | |
35538 } | |
35539 | |
35540 this.status = 0; | |
35541 this.stop(); | |
35542 this.gui.updateAnimationButtons(0); | |
35543 | |
35544 this.leftFlagPos = null; | |
35545 this.leftFlagTime = null; | |
35546 this.rightFlagPos = null; | |
35547 this.rightFlagTime = null; | |
35548 | |
35549 this.mouseDownTime = null; | |
35550 this.mouseUpTime = null; | |
35551 this.mouseTempTime = null; | |
35552 | |
35553 this.mouseDownPos = null; | |
35554 this.mouseUpPos = null; | |
35555 this.mouseTempPos = null; | |
35556 | |
35557 if (this.popup) { | |
35558 this.popup.reset(); | |
35559 this.popupClickDiv.style.visibility = "hidden"; | |
35560 } | |
35561 | |
35562 }, | |
35563 | |
35564 /** | |
35565 * sets a pole on the timeplot | |
35566 * @param {Date} time the time of the specific timeslice | |
35567 * @param {int[]} the number of selected elements per dataset | |
35568 */ | |
35569 displayOverlay : function() { | |
35570 this.poles.style.visibility = "visible"; | |
35571 var cv = this.poles.getElementsByTagName("canvas")[0]; | |
35572 cv.width = this.canvas.width; | |
35573 cv.height = this.canvas.height; | |
35574 if (!cv.getContext && G_vmlCanvasManager) { | |
35575 cv = G_vmlCanvasManager.initElement(cv); | |
35576 } | |
35577 var ctx = cv.getContext('2d'); | |
35578 ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); | |
35579 var plots = this.timeplot._plots; | |
35580 var slices = this.tds.timeSlices; | |
35581 for (var i = 0; i < slices.length; i++) { | |
35582 if (this.style == 'bars' && i + 1 == slices.length) { | |
35583 return; | |
35584 } | |
35585 if (slices[i].overlay() == 0) { | |
35586 continue; | |
35587 } | |
35588 var projStacks = slices[i].projStacks; | |
35589 var time = slices[i].date; | |
35590 var pos; | |
35591 if (this.style == 'graph') { | |
35592 pos = this.timeGeometry.toScreen(time); | |
35593 } else if (this.style == 'bars') { | |
35594 var x1 = this.timeGeometry.toScreen(time); | |
35595 var x2 = this.timeGeometry.toScreen(slices[i + 1].date); | |
35596 pos = (x1 + x2 ) / 2; | |
35597 } | |
35598 var heights = []; | |
35599 var h = 0; | |
35600 for (var j = 0; j < projStacks.length; j++) { | |
35601 var data = plots[j]._dataSource.getData(); | |
35602 for (var k = 0; k < data.times.length; k++) { | |
35603 if (data.times[k].getTime() == time.getTime()) { | |
35604 var height = plots[j]._valueGeometry.toScreen(plots[j]._dataSource.getData().values[k]) * projStacks[j].overlay / projStacks[j].value; | |
35605 heights.push(height); | |
35606 plots[j].pins[i] = { | |
35607 height : height, | |
35608 count : projStacks[j].overlay | |
35609 }; | |
35610 if (height > h) { | |
35611 h = height; | |
35612 } | |
35613 break; | |
35614 } | |
35615 } | |
35616 } | |
35617 ctx.fillStyle = "rgb(102,102,102)"; | |
35618 ctx.beginPath(); | |
35619 ctx.rect(pos - 1, this.canvas.height - h, 2, h); | |
35620 ctx.fill(); | |
35621 for (var j = 0; j < heights.length; j++) { | |
35622 if (heights[j] > 0) { | |
35623 var color = GeoTemConfig.getColor(j); | |
35624 ctx.fillStyle = "rgba(" + color.r1 + "," + color.g1 + "," + color.b1 + ",0.6)"; | |
35625 ctx.beginPath(); | |
35626 ctx.arc(pos, this.canvas.height - heights[j], 2.5, 0, Math.PI * 2, true); | |
35627 ctx.closePath(); | |
35628 ctx.fill(); | |
35629 } | |
35630 } | |
35631 } | |
35632 }, | |
35633 | |
35634 /** | |
35635 * updates the timeplot by displaying place poles, after a selection had been executed in another widget | |
35636 */ | |
35637 highlightChanged : function(timeObjects) { | |
35638 if( !GeoTemConfig.highlightEvents ){ | |
35639 return; | |
35640 } | |
35641 this.resetOverlay(); | |
35642 if (this.selection.valid()) { | |
35643 if (!this.selection.equal(this)) { | |
35644 this.tds.setOverlay(GeoTemConfig.mergeObjects(timeObjects, this.selection.getObjects(this))); | |
35645 } else { | |
35646 this.tds.setOverlay(timeObjects); | |
35647 } | |
35648 } else { | |
35649 this.tds.setOverlay(timeObjects); | |
35650 } | |
35651 this.displayOverlay(); | |
35652 }, | |
35653 | |
35654 /** | |
35655 * updates the timeplot by displaying place poles, after a selection had been executed in another widget | |
35656 */ | |
35657 selectionChanged : function(selection) { | |
35658 if( !GeoTemConfig.selectionEvents ){ | |
35659 return; | |
35660 } | |
35661 this.reset(); | |
35662 this.selection = selection; | |
35663 this.tds.setOverlay(selection.objects); | |
35664 this.displayOverlay(); | |
35665 }, | |
35666 | |
35667 /** | |
35668 * returns the approximate left position of a slice inside the overview representation | |
35669 * @param {Date} time time of the slice | |
35670 */ | |
35671 getOverviewLeft : function(time) { | |
35672 var w = this.overview.offsetWidth; | |
35673 var s = this.tds.earliest().getTime(); | |
35674 var e = this.tds.latest().getTime(); | |
35675 var t = time.getTime(); | |
35676 return Math.round(w * (t - s) / (e - s)); | |
35677 }, | |
35678 | |
35679 /** | |
35680 * visualizes the overview div (shows viewable part of zoomed timeplot) | |
35681 */ | |
35682 initOverview : function() { | |
35683 var labels = this.timeGeometry._grid; | |
35684 if (labels.length == 0) { | |
35685 var plot = this; | |
35686 setTimeout(function() { | |
35687 plot.initOverview(); | |
35688 }, 10); | |
35689 return; | |
35690 } | |
35691 | |
35692 this.overview.style.width = this.canvas.width + "px"; | |
35693 var left = this.gui.timeplotDiv.offsetLeft; | |
35694 this.overview.innerHTML = ""; | |
35695 this.overview.style.left = left + "px"; | |
35696 | |
35697 this.overviewRange = document.createElement("div"); | |
35698 this.overviewRange.setAttribute('class', 'overviewRange'); | |
35699 this.overview.appendChild(this.overviewRange); | |
35700 | |
35701 for (var i = 0; i < labels.length; i++) { | |
35702 var label = document.createElement("div"); | |
35703 label.setAttribute('class', 'overviewLabel'); | |
35704 label.innerHTML = labels[i].label; | |
35705 label.style.left = Math.floor(labels[i].x) + "px"; | |
35706 this.overview.appendChild(label); | |
35707 } | |
35708 | |
35709 this.updateOverview(); | |
35710 }, | |
35711 | |
35712 /** | |
35713 * visualizes the labels of the timeplot | |
35714 */ | |
35715 initLabels : function(labels) { | |
35716 if (labels.length == 0) { | |
35717 labels = this.timeGeometry._grid; | |
35718 if (labels.length == 0) { | |
35719 var plot = this; | |
35720 setTimeout(function() { | |
35721 plot.initLabels([]); | |
35722 }, 10); | |
35723 return; | |
35724 } | |
35725 } | |
35726 this.plotLabels.style.width = this.canvas.width + "px"; | |
35727 var left = this.gui.timeplotDiv.offsetLeft; | |
35728 this.plotLabels.style.left = left + "px"; | |
35729 this.plotLabels.innerHTML = ""; | |
35730 for (var i = 0; i < labels.length; i++) { | |
35731 var label = document.createElement("div"); | |
35732 label.setAttribute('class', 'plotLabel'); | |
35733 label.innerHTML = labels[i].label; | |
35734 label.style.left = Math.floor(labels[i].x) + "px"; | |
35735 this.plotLabels.appendChild(label); | |
35736 } | |
35737 }, | |
35738 | |
35739 /** | |
35740 * updates the overview div | |
35741 */ | |
35742 updateOverview : function() { | |
35743 if (this.tds.getZoom() > 0) { | |
35744 this.plotLabels.style.visibility = "hidden"; | |
35745 this.timeGeometry._hideLabels = false; | |
35746 this.overview.style.visibility = "visible"; | |
35747 this.shiftLeft.style.visibility = "visible"; | |
35748 this.shiftRight.style.visibility = "visible"; | |
35749 var left = this.getOverviewLeft(this.tds.timeSlices[this.tds.leftSlice].date); | |
35750 var right = this.getOverviewLeft(this.tds.timeSlices[this.tds.rightSlice].date); | |
35751 this.overviewRange.style.left = left + "px"; | |
35752 this.overviewRange.style.width = (right - left) + "px"; | |
35753 } else { | |
35754 this.timeGeometry._hideLabels = true; | |
35755 this.plotLabels.style.visibility = "visible"; | |
35756 this.overview.style.visibility = "hidden"; | |
35757 this.shiftLeft.style.visibility = "hidden"; | |
35758 this.shiftRight.style.visibility = "hidden"; | |
35759 } | |
35760 }, | |
35761 | |
35762 /** | |
35763 * returns the time slices which are created by the extended data source | |
35764 */ | |
35765 getSlices : function() { | |
35766 return this.tds.timeSlices; | |
35767 }, | |
35768 | |
35769 timeSelection : function() { | |
35770 var slices = this.tds.timeSlices; | |
35771 var ls, rs; | |
35772 for (var i = 0; i < slices.length; i++) { | |
35773 if (slices[i].date.getTime() == this.leftFlagTime.getTime()) | |
35774 ls = i; | |
35775 if (slices[i].date.getTime() == this.rightFlagTime.getTime()) { | |
35776 if (this.style == 'graph') { | |
35777 rs = i; | |
35778 } | |
35779 if (this.style == 'bars') { | |
35780 rs = i - 1; | |
35781 } | |
35782 } | |
35783 } | |
35784 var selectedObjects = []; | |
35785 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
35786 selectedObjects.push([]); | |
35787 } | |
35788 for (var i = 0; i < slices.length; i++) { | |
35789 if (i >= ls && i <= rs) { | |
35790 for (var j in slices[i].stacks ) { | |
35791 selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements); | |
35792 } | |
35793 } | |
35794 } | |
35795 this.selection = new Selection(selectedObjects, this); | |
35796 this.core.triggerSelection(this.selection); | |
35797 this.filterBar.reset(true); | |
35798 }, | |
35799 | |
35800 deselection : function() { | |
35801 this.reset(); | |
35802 this.selection = new Selection(); | |
35803 this.core.triggerSelection(this.selection); | |
35804 }, | |
35805 | |
35806 filtering : function() { | |
35807 for (var i = 0; i < this.datasets.length; i++) { | |
35808 this.datasets[i].objects = this.selection.objects[i]; | |
35809 } | |
35810 this.core.triggerRefining(this.datasets); | |
35811 }, | |
35812 | |
35813 inverseFiltering : function() { | |
35814 var slices = this.tds.timeSlices; | |
35815 var ls, rs; | |
35816 for (var i = 0; i < slices.length; i++) { | |
35817 if (slices[i].date.getTime() == this.leftFlagTime.getTime()) | |
35818 ls = i; | |
35819 if (slices[i].date.getTime() == this.rightFlagTime.getTime()) { | |
35820 if (this.style == 'graph') { | |
35821 rs = i; | |
35822 } | |
35823 if (this.style == 'bars') { | |
35824 rs = i - 1; | |
35825 } | |
35826 } | |
35827 } | |
35828 var selectedObjects = []; | |
35829 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
35830 selectedObjects.push([]); | |
35831 } | |
35832 for (var i = 0; i < slices.length; i++) { | |
35833 if (i >= ls && i <= rs) { | |
35834 continue; | |
35835 } | |
35836 for (var j in slices[i].stacks ) { | |
35837 selectedObjects[j] = selectedObjects[j].concat(slices[i].stacks[j].elements); | |
35838 } | |
35839 } | |
35840 this.selection = new Selection(selectedObjects, this); | |
35841 this.filtering(); | |
35842 }, | |
35843 | |
35844 timeHighlight : function(undo) { | |
35845 if (this.status == 0) { | |
35846 var s = this.highlightedSlice; | |
35847 var timeObjects = []; | |
35848 for (var i = 0; i < this.tds.size(); i++) { | |
35849 timeObjects.push([]); | |
35850 } | |
35851 var add = true; | |
35852 if (this.leftFlagTime != null) { | |
35853 if (this.style == 'graph' && s.date >= this.leftFlagTime && s.date <= this.rightFlagTime) { | |
35854 add = false; | |
35855 } | |
35856 if (this.style == 'bars' && s.date >= this.leftFlagTime && s.date < this.rightFlagTime) { | |
35857 add = false; | |
35858 } | |
35859 } | |
35860 if (!undo && add) { | |
35861 for (var i in s.stacks ) { | |
35862 timeObjects[i] = timeObjects[i].concat(s.stacks[i].elements); | |
35863 } | |
35864 } | |
35865 this.core.triggerHighlight(timeObjects); | |
35866 } | |
35867 }, | |
35868 | |
35869 timeRefining : function() { | |
35870 this.core.triggerRefining(this.selection.objects); | |
35871 }, | |
35872 | |
35873 setStyle : function(style) { | |
35874 this.style = style; | |
35875 }, | |
35876 | |
35877 drawLinearPlot : function() { | |
35878 if ( typeof this.valueGeometry != 'undefined') { | |
35879 this.valueGeometry.actLinear(); | |
35880 this.timeplot.repaint(); | |
35881 this.resetOpacityPlots(); | |
35882 this.displayOverlay(); | |
35883 } | |
35884 }, | |
35885 | |
35886 drawLogarithmicPlot : function() { | |
35887 if ( typeof this.valueGeometry != 'undefined') { | |
35888 this.valueGeometry.actLogarithmic(); | |
35889 this.timeplot.repaint(); | |
35890 this.resetOpacityPlots(); | |
35891 this.displayOverlay(); | |
35892 } | |
35893 } | |
35894 } | |
35895 /* | |
35896 * TableConfig.js | |
35897 * | |
35898 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
35899 * | |
35900 * This library is free software; you can redistribute it and/or | |
35901 * modify it under the terms of the GNU Lesser General Public | |
35902 * License as published by the Free Software Foundation; either | |
35903 * version 3 of the License, or (at your option) any later version. | |
35904 * | |
35905 * This library is distributed in the hope that it will be useful, | |
35906 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35907 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
35908 * Lesser General Public License for more details. | |
35909 * | |
35910 * You should have received a copy of the GNU Lesser General Public | |
35911 * License along with this library; if not, write to the Free Software | |
35912 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
35913 * MA 02110-1301 USA | |
35914 */ | |
35915 | |
35916 /** | |
35917 * @class TableConfig | |
35918 * Table Configuration File | |
35919 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
35920 * @release 1.0 | |
35921 * @release date: 2012-07-27 | |
35922 * @version date: 2012-07-27 | |
35923 */ | |
35924 function TableConfig(options) { | |
35925 | |
35926 this.options = { | |
35927 tableWidth : false, // false or desired width css definition for the table | |
35928 tableHeight : false, // false or desired height css definition for the table | |
35929 validResultsPerPage : [10, 20, 50, 100], // valid number of elements per page | |
35930 initialResultsPerPage : 10, // initial number of elements per page | |
35931 tableSorting : true, // true, if sorting of columns should be possible | |
35932 tableContentOffset : 250, // maximum display number of characters in a table cell | |
35933 tableSelectPage : true, // selection of complete table pages | |
35934 tableSelectAll : false, // selection of complete tables | |
35935 tableShowSelected : true, // show selected objects only option | |
35936 tableKeepShowSelected : true, // don't revert to show all on "reset" (e.g. selection) | |
35937 tableInvertSelection : true, // show invert selection option | |
35938 tableSelectByText : true, // select objects by full-text search | |
35939 tableCreateNewFromSelected : true, // create new dataset from selected objects | |
35940 unselectedCellColor : '#EEE', // color for an unselected row/tab | |
35941 verticalAlign : 'top', // vertical alignment of the table cells ('top','center','bottom') | |
35942 }; | |
35943 if ( typeof options != 'undefined') { | |
35944 $.extend(this.options, options); | |
35945 } | |
35946 | |
35947 }; | |
35948 /* | |
35949 * TableGui.js | |
35950 * | |
35951 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
35952 * | |
35953 * This library is free software; you can redistribute it and/or | |
35954 * modify it under the terms of the GNU Lesser General Public | |
35955 * License as published by the Free Software Foundation; either | |
35956 * version 3 of the License, or (at your option) any later version. | |
35957 * | |
35958 * This library is distributed in the hope that it will be useful, | |
35959 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
35960 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
35961 * Lesser General Public License for more details. | |
35962 * | |
35963 * You should have received a copy of the GNU Lesser General Public | |
35964 * License along with this library; if not, write to the Free Software | |
35965 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
35966 * MA 02110-1301 USA | |
35967 */ | |
35968 | |
35969 /** | |
35970 * @class TableGui | |
35971 * Table GUI Implementation | |
35972 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
35973 * @release 1.0 | |
35974 * @release date: 2012-07-27 | |
35975 * @version date: 2012-07-27 | |
35976 * | |
35977 * @param {TableWidget} parent table widget object | |
35978 * @param {HTML object} div parent div to append the table gui | |
35979 * @param {JSON} options table configuration | |
35980 */ | |
35981 function TableGui(table, div, options) { | |
35982 | |
35983 this.tableContainer = div; | |
35984 if (options.tableWidth) { | |
35985 this.tableContainer.style.width = options.tableWidth; | |
35986 } | |
35987 if (options.tableHeight) { | |
35988 this.tableContainer.style.height = options.tableHeight; | |
35989 } | |
35990 this.tableContainer.style.position = 'relative'; | |
35991 | |
35992 this.tabs = document.createElement('div'); | |
35993 this.tabs.setAttribute('class', 'tableTabs'); | |
35994 div.appendChild(this.tabs); | |
35995 | |
35996 this.input = document.createElement('div'); | |
35997 this.input.setAttribute('class', 'tableInput'); | |
35998 div.appendChild(this.input); | |
35999 | |
36000 }; | |
36001 /* | |
36002 * TableWidget.js | |
36003 * | |
36004 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
36005 * | |
36006 * This library is free software; you can redistribute it and/or | |
36007 * modify it under the terms of the GNU Lesser General Public | |
36008 * License as published by the Free Software Foundation; either | |
36009 * version 3 of the License, or (at your option) any later version. | |
36010 * | |
36011 * This library is distributed in the hope that it will be useful, | |
36012 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36014 * Lesser General Public License for more details. | |
36015 * | |
36016 * You should have received a copy of the GNU Lesser General Public | |
36017 * License along with this library; if not, write to the Free Software | |
36018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
36019 * MA 02110-1301 USA | |
36020 */ | |
36021 | |
36022 /** | |
36023 * @class TableWidget | |
36024 * TableWidget Implementation | |
36025 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
36026 * @release 1.0 | |
36027 * @release date: 2012-07-27 | |
36028 * @version date: 2012-07-27 | |
36029 * | |
36030 * @param {TableWrapper} core wrapper for interaction to other widgets | |
36031 * @param {HTML object} div parent div to append the table widget div | |
36032 * @param {JSON} options user specified configuration that overwrites options in TableConfig.js | |
36033 */ | |
36034 TableWidget = function(core, div, options) { | |
36035 | |
36036 this.core = core; | |
36037 this.core.setWidget(this); | |
36038 this.tables = []; | |
36039 this.tableTabs = []; | |
36040 this.tableElements = []; | |
36041 this.tableHash = []; | |
36042 | |
36043 this.options = (new TableConfig(options)).options; | |
36044 this.gui = new TableGui(this, div, this.options); | |
36045 this.filterBar = new FilterBar(this); | |
36046 | |
36047 } | |
36048 | |
36049 TableWidget.prototype = { | |
36050 | |
36051 initWidget : function(data) { | |
36052 this.datasets = data; | |
36053 | |
36054 $(this.gui.tabs).empty(); | |
36055 $(this.gui.input).empty(); | |
36056 this.activeTable = undefined; | |
36057 this.tables = []; | |
36058 this.tableTabs = []; | |
36059 this.tableElements = []; | |
36060 this.tableHash = []; | |
36061 this.selection = new Selection(); | |
36062 this.filterBar.reset(false); | |
36063 | |
36064 var tableWidget = this; | |
36065 var addTab = function(name, index) { | |
36066 var dataSet = GeoTemConfig.datasets[index]; | |
36067 var tableTab = document.createElement('div'); | |
36068 var tableTabTable = document.createElement('table'); | |
36069 $(tableTab).append(tableTabTable); | |
36070 var tableTabTableRow = document.createElement('tr'); | |
36071 $(tableTabTable).append(tableTabTableRow); | |
36072 tableTab.setAttribute('class', 'tableTab'); | |
36073 var c = GeoTemConfig.getColor(index); | |
36074 tableTab.style.backgroundColor = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
36075 tableTab.onclick = function() { | |
36076 tableWidget.selectTable(index); | |
36077 } | |
36078 var tableNameDiv = document.createElement('div'); | |
36079 $(tableNameDiv).append(name); | |
36080 | |
36081 if (typeof dataSet.url !== "undefined"){ | |
36082 var tableLinkDiv = document.createElement('a'); | |
36083 tableLinkDiv.title = dataSet.url; | |
36084 tableLinkDiv.href = dataSet.url; | |
36085 tableLinkDiv.target = '_'; | |
36086 tableLinkDiv.setAttribute('class', 'externalLink'); | |
36087 $(tableNameDiv).append(tableLinkDiv); | |
36088 } | |
36089 $(tableTabTableRow).append($(document.createElement('td')).append(tableNameDiv)); | |
36090 | |
36091 var removeTabDiv = document.createElement('div'); | |
36092 removeTabDiv.setAttribute('class', 'smallButton removeDataset'); | |
36093 removeTabDiv.title = GeoTemConfig.getString('removeDatasetHelp'); | |
36094 removeTabDiv.onclick = $.proxy(function(e) { | |
36095 GeoTemConfig.removeDataset(index); | |
36096 //don't let the event propagate to the DIV above | |
36097 e.stopPropagation(); | |
36098 //discard link click | |
36099 return(false); | |
36100 },{index:index}); | |
36101 $(tableTabTableRow).append($(document.createElement('td')).append(removeTabDiv)); | |
36102 | |
36103 if (GeoTemConfig.tableExportDataset){ | |
36104 var exportTabDiv = document.createElement('div'); | |
36105 exportTabDiv.setAttribute('class', 'smallButton exportDataset'); | |
36106 exportTabDiv.title = GeoTemConfig.getString('exportDatasetHelp'); | |
36107 var exportTabForm = document.createElement('form'); | |
36108 //TODO: make this configurable | |
36109 exportTabForm.action = 'php/download.php'; | |
36110 exportTabForm.method = 'post'; | |
36111 var exportTabHiddenValue = document.createElement('input'); | |
36112 exportTabHiddenValue.name = 'file'; | |
36113 exportTabHiddenValue.type = 'hidden'; | |
36114 exportTabForm.appendChild(exportTabHiddenValue); | |
36115 exportTabDiv.onclick = $.proxy(function(e) { | |
36116 $(exportTabHiddenValue).val(GeoTemConfig.createKMLfromDataset(index)); | |
36117 $(exportTabForm).submit(); | |
36118 //don't let the event propagate to the DIV | |
36119 e.stopPropagation(); | |
36120 //discard link click | |
36121 return(false); | |
36122 },{index:index}); | |
36123 exportTabDiv.appendChild(exportTabForm); | |
36124 $(tableTabTableRow).append($(document.createElement('td')).append(exportTabDiv)); | |
36125 } | |
36126 | |
36127 return tableTab; | |
36128 } | |
36129 tableWidget.addTab = addTab; | |
36130 | |
36131 for (var i in data ) { | |
36132 this.tableHash.push([]); | |
36133 var tableTab = addTab(data[i].label, i); | |
36134 this.gui.tabs.appendChild(tableTab); | |
36135 this.tableTabs.push(tableTab); | |
36136 var elements = []; | |
36137 for (var j in data[i].objects ) { | |
36138 elements.push(new TableElement(data[i].objects[j])); | |
36139 this.tableHash[i][data[i].objects[j].index] = elements[elements.length - 1]; | |
36140 } | |
36141 var table = new Table(elements, this, i); | |
36142 this.tables.push(table); | |
36143 this.tableElements.push(elements); | |
36144 } | |
36145 | |
36146 if (data.length > 0) { | |
36147 this.selectTable(0); | |
36148 } | |
36149 | |
36150 }, | |
36151 | |
36152 getHeight : function() { | |
36153 if (this.options.tableHeight) { | |
36154 return this.gui.tableContainer.offsetHeight - this.gui.tabs.offsetHeight; | |
36155 } | |
36156 return false; | |
36157 }, | |
36158 | |
36159 selectTable : function(index) { | |
36160 if (this.activeTable != index) { | |
36161 if ( typeof this.activeTable != 'undefined') { | |
36162 this.tables[this.activeTable].hide(); | |
36163 var c = GeoTemConfig.getColor(this.activeTable); | |
36164 this.tableTabs[this.activeTable].style.backgroundColor = 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'; | |
36165 } | |
36166 this.activeTable = index; | |
36167 this.tables[this.activeTable].show(); | |
36168 var c = GeoTemConfig.getColor(this.activeTable); | |
36169 this.tableTabs[this.activeTable].style.backgroundColor = 'rgb(' + c.r1 + ',' + c.g1 + ',' + c.b1 + ')'; | |
36170 this.core.triggerRise(index); | |
36171 } | |
36172 | |
36173 }, | |
36174 | |
36175 highlightChanged : function(objects) { | |
36176 if( !GeoTemConfig.highlightEvents || (typeof this.tables[this.activeTable] === "undefined")){ | |
36177 return; | |
36178 } | |
36179 if( this.tables.length > 0 ){ | |
36180 return; | |
36181 } | |
36182 for (var i = 0; i < this.tableElements.length; i++) { | |
36183 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36184 this.tableElements[i][j].highlighted = false; | |
36185 } | |
36186 } | |
36187 for (var i = 0; i < objects.length; i++) { | |
36188 for (var j = 0; j < objects[i].length; j++) { | |
36189 this.tableHash[i][objects[i][j].index].highlighted = true; | |
36190 } | |
36191 } | |
36192 this.tables[this.activeTable].update(); | |
36193 }, | |
36194 | |
36195 selectionChanged : function(selection) { | |
36196 if( !GeoTemConfig.selectionEvents || (typeof this.tables[this.activeTable] === "undefined")){ | |
36197 return; | |
36198 } | |
36199 this.reset(); | |
36200 if( this.tables.length == 0 ){ | |
36201 return; | |
36202 } | |
36203 this.selection = selection; | |
36204 for (var i = 0; i < this.tableElements.length; i++) { | |
36205 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36206 this.tableElements[i][j].selected = false; | |
36207 this.tableElements[i][j].highlighted = false; | |
36208 } | |
36209 } | |
36210 var objects = selection.getObjects(this); | |
36211 for (var i = 0; i < objects.length; i++) { | |
36212 for (var j = 0; j < objects[i].length; j++) { | |
36213 this.tableHash[i][objects[i][j].index].selected = true; | |
36214 } | |
36215 } | |
36216 this.tables[this.activeTable].reset(); | |
36217 this.tables[this.activeTable].update(); | |
36218 }, | |
36219 | |
36220 triggerHighlight : function(item) { | |
36221 var selectedObjects = []; | |
36222 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36223 selectedObjects.push([]); | |
36224 } | |
36225 if ( typeof item != 'undefined') { | |
36226 selectedObjects[this.activeTable].push(item); | |
36227 } | |
36228 this.core.triggerHighlight(selectedObjects); | |
36229 }, | |
36230 | |
36231 tableSelection : function() { | |
36232 var selectedObjects = []; | |
36233 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36234 selectedObjects.push([]); | |
36235 } | |
36236 var valid = false; | |
36237 for (var i = 0; i < this.tableElements.length; i++) { | |
36238 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36239 var e = this.tableElements[i][j]; | |
36240 if (e.selected) { | |
36241 selectedObjects[i].push(e.object); | |
36242 valid = true; | |
36243 } | |
36244 } | |
36245 } | |
36246 this.selection = new Selection(); | |
36247 if (valid) { | |
36248 this.selection = new Selection(selectedObjects, this); | |
36249 } | |
36250 this.core.triggerSelection(this.selection); | |
36251 this.filterBar.reset(true); | |
36252 }, | |
36253 | |
36254 deselection : function() { | |
36255 this.reset(); | |
36256 this.selection = new Selection(); | |
36257 this.core.triggerSelection(this.selection); | |
36258 }, | |
36259 | |
36260 filtering : function() { | |
36261 for (var i = 0; i < this.datasets.length; i++) { | |
36262 this.datasets[i].objects = this.selection.objects[i]; | |
36263 } | |
36264 this.core.triggerRefining(this.datasets); | |
36265 }, | |
36266 | |
36267 inverseFiltering : function() { | |
36268 var selectedObjects = []; | |
36269 for (var i = 0; i < GeoTemConfig.datasets.length; i++) { | |
36270 selectedObjects.push([]); | |
36271 } | |
36272 var valid = false; | |
36273 for (var i = 0; i < this.tableElements.length; i++) { | |
36274 for (var j = 0; j < this.tableElements[i].length; j++) { | |
36275 var e = this.tableElements[i][j]; | |
36276 if (!e.selected) { | |
36277 selectedObjects[i].push(e.object); | |
36278 valid = true; | |
36279 } | |
36280 } | |
36281 } | |
36282 this.selection = new Selection(); | |
36283 if (valid) { | |
36284 this.selection = new Selection(selectedObjects, this); | |
36285 } | |
36286 this.filtering(); | |
36287 }, | |
36288 | |
36289 triggerRefining : function() { | |
36290 this.core.triggerRefining(this.selection.objects); | |
36291 }, | |
36292 | |
36293 reset : function() { | |
36294 this.filterBar.reset(false); | |
36295 if( this.tables.length > 0 ){ | |
36296 this.tables[this.activeTable].resetElements(); | |
36297 this.tables[this.activeTable].reset(); | |
36298 this.tables[this.activeTable].update(); | |
36299 } | |
36300 } | |
36301 } | |
36302 /* | |
36303 * Table.js | |
36304 * | |
36305 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
36306 * | |
36307 * This library is free software; you can redistribute it and/or | |
36308 * modify it under the terms of the GNU Lesser General Public | |
36309 * License as published by the Free Software Foundation; either | |
36310 * version 3 of the License, or (at your option) any later version. | |
36311 * | |
36312 * This library is distributed in the hope that it will be useful, | |
36313 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
36314 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
36315 * Lesser General Public License for more details. | |
36316 * | |
36317 * You should have received a copy of the GNU Lesser General Public | |
36318 * License along with this library; if not, write to the Free Software | |
36319 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
36320 * MA 02110-1301 USA | |
36321 */ | |
36322 | |
36323 /** | |
36324 * @class Table | |
36325 * Implementation for a single table | |
36326 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
36327 * @release 1.0 | |
36328 * @release date: 2012-07-27 | |
36329 * @version date: 2012-07-27 | |
36330 * | |
36331 * @param {Array} elements list of data items | |
36332 * @param {HTML object} parent div to append the table | |
36333 * @param {int} id dataset index | |
36334 */ | |
36335 function Table(elements, parent, id) { | |
36336 | |
36337 this.elements = elements; | |
36338 this.showElementsLength = elements.length; | |
36339 this.parent = parent; | |
36340 this.id = id; | |
36341 this.options = parent.options; | |
36342 | |
36343 this.validResultsPerPage = [10, 20, 50, 100]; | |
36344 this.keyHeaderList = []; | |
36345 this.initialize(); | |
36346 | |
36347 } | |
36348 | |
36349 Table.prototype = { | |
36350 | |
36351 initToolbar : function() { | |
36352 | |
36353 var table = this; | |
36354 | |
36355 this.toolbar = document.createElement("table"); | |
36356 this.toolbar.setAttribute('class', 'ddbToolbar'); | |
36357 this.toolbar.style.overflow = 'auto'; | |
36358 this.tableDiv.appendChild(this.toolbar); | |
36359 | |
36360 var navigation = document.createElement("tr"); | |
36361 this.toolbar.appendChild(navigation); | |
36362 | |
36363 var selectors = document.createElement("td"); | |
36364 navigation.appendChild(selectors); | |
36365 | |
36366 if (table.options.tableSelectPage) { | |
36367 var selectPageItems = true; | |
36368 this.selectPage = document.createElement('div'); | |
36369 $(this.selectPage).css("float","left"); | |
36370 this.selectPage.setAttribute('class', 'smallButton selectPage'); | |
36371 this.selectPage.title = GeoTemConfig.getString('selectTablePageItemsHelp'); | |
36372 selectors.appendChild(this.selectPage); | |
36373 this.selectPage.onclick = function() { | |
36374 selectPageItems = !selectPageItems; | |
36375 if (selectPageItems) { | |
36376 var items = 0; | |
36377 for (var i = table.first; i < table.elements.length; i++) { | |
36378 table.elements[i].selected = false; | |
36379 items++; | |
36380 if (items == table.resultsPerPage) { | |
36381 break; | |
36382 } | |
36383 } | |
36384 table.selectPage.setAttribute('class', 'smallButton selectPage'); | |
36385 table.selectPage.title = GeoTemConfig.getString('selectTablePageItemsHelp'); | |
36386 } else { | |
36387 var items = 0; | |
36388 for (var i = table.first; i < table.elements.length; i++) { | |
36389 table.elements[i].selected = true; | |
36390 items++; | |
36391 if (items == table.resultsPerPage) { | |
36392 break; | |
36393 } | |
36394 } | |
36395 table.selectPage.setAttribute('class', 'smallButton deselectPage'); | |
36396 table.selectPage.title = GeoTemConfig.getString('deselectTablePageItemsHelp'); | |
36397 } | |
36398 table.update(); | |
36399 table.parent.tableSelection(); | |
36400 } | |
36401 } | |
36402 | |
36403 if (table.options.tableSelectAll) { | |
36404 var selectAllItems = true; | |
36405 this.selectAll = document.createElement('div'); | |
36406 this.selectAll.setAttribute('class', 'smallButton selectAll'); | |
36407 $(this.selectAll).css("float","left"); | |
36408 table.selectAll.title = GeoTemConfig.getString('selectAllTableItemsHelp'); | |
36409 selectors.appendChild(this.selectAll); | |
36410 this.selectAll.onclick = function() { | |
36411 selectAllItems = !selectAllItems; | |
36412 if (selectAllItems) { | |
36413 for (var i = 0; i < table.elements.length; i++) { | |
36414 table.elements[i].selected = false; | |
36415 } | |
36416 table.selectAll.setAttribute('class', 'smallButton selectAll'); | |
36417 table.selectAll.title = GeoTemConfig.getString('selectAllTableItemsHelp'); | |
36418 } else { | |
36419 for (var i = 0; i < table.elements.length; i++) { | |
36420 table.elements[i].selected = true; | |
36421 } | |
36422 table.selectAll.setAttribute('class', 'smallButton deselectAll'); | |
36423 table.selectAll.title = GeoTemConfig.getString('deselectAllTableItemsHelp'); | |
36424 } | |
36425 table.update(); | |
36426 table.parent.tableSelection(); | |
36427 } | |
36428 } | |
36429 | |
36430 if (table.options.tableInvertSelection) { | |
36431 this.invertSelection = document.createElement('div'); | |
36432 this.invertSelection.setAttribute('class', 'smallButton invertSelection'); | |
36433 $(this.invertSelection).css("float","left"); | |
36434 table.invertSelection.title = GeoTemConfig.getString('invertSelectionHelp'); | |
36435 selectors.appendChild(this.invertSelection); | |
36436 this.invertSelection.onclick = function() { | |
36437 for (var i = 0; i < table.elements.length; i++) { | |
36438 if (table.elements[i].selected === true) | |
36439 table.elements[i].selected = false; | |
36440 else | |
36441 table.elements[i].selected = true; | |
36442 } | |
36443 table.update(); | |
36444 table.parent.tableSelection(); | |
36445 } | |
36446 } | |
36447 | |
36448 this.showSelectedItems = false; | |
36449 if (table.options.tableShowSelected) { | |
36450 this.showSelected = document.createElement('div'); | |
36451 this.showSelected.setAttribute('class', 'smallButton showSelected'); | |
36452 $(this.showSelected).css("float","left"); | |
36453 table.showSelected.title = GeoTemConfig.getString('showSelectedHelp'); | |
36454 selectors.appendChild(this.showSelected); | |
36455 this.showSelected.onclick = function() { | |
36456 table.showSelectedItems = !table.showSelectedItems; | |
36457 if (table.showSelectedItems) { | |
36458 table.showElementsLength = 0; | |
36459 for (var i = 0; i < table.elements.length; i++) { | |
36460 if (table.elements[i].selected) { | |
36461 table.showElementsLength++; | |
36462 } | |
36463 } | |
36464 table.showSelected.setAttribute('class', 'smallButton showAll'); | |
36465 // table.selectAll.title = GeoTemConfig.getString('showAllElementsHelp'); | |
36466 } else { | |
36467 table.showElementsLength = table.elements.length; | |
36468 table.showSelected.setAttribute('class', 'smallButton showSelected'); | |
36469 // table.selectAll.title = GeoTemConfig.getString('showSelectedHelp'); | |
36470 } | |
36471 table.updateIndices(table.resultsPerPage); | |
36472 table.update(); | |
36473 } | |
36474 } | |
36475 | |
36476 if (table.options.tableSelectByText) { | |
36477 this.selectByTextDiv = document.createElement('div'); | |
36478 $(this.selectByTextDiv).css("float","left"); | |
36479 $(this.selectByTextDiv).css("vertical-align", "top"); | |
36480 //TODO: improve appearance (wrong margin) | |
36481 $(this.selectByTextDiv).css("display", "inline-block"); | |
36482 //create and append the input field | |
36483 this.selectByTextInput = document.createElement('input'); | |
36484 $(this.selectByTextInput).attr("type","text"); | |
36485 $(this.selectByTextDiv).append(this.selectByTextInput); | |
36486 //create and append the button | |
36487 this.selectByTextButton = document.createElement('input'); | |
36488 $(this.selectByTextButton).attr("type","button"); | |
36489 //TODO: add button-image | |
36490 $(this.selectByTextButton).val("search"); | |
36491 $(this.selectByTextDiv).append(this.selectByTextButton); | |
36492 | |
36493 table.selectByTextDiv.title = GeoTemConfig.getString('selectByTextHelp'); | |
36494 selectors.appendChild(this.selectByTextDiv); | |
36495 $(this.selectByTextButton).click($.proxy(function() { | |
36496 this.selectByText($(this.selectByTextInput).val()); | |
36497 },this)); | |
36498 } | |
36499 | |
36500 if (table.options.tableCreateNewFromSelected) { | |
36501 this.createNewFromSelected = document.createElement('div'); | |
36502 this.createNewFromSelected.setAttribute('class', 'smallButton createNewRefined'); | |
36503 $(this.createNewFromSelected).css("float","left"); | |
36504 this.createNewFromSelected.title = GeoTemConfig.getString('createNewFromSelectedHelp'); | |
36505 selectors.appendChild(this.createNewFromSelected); | |
36506 this.createNewFromSelected.onclick = function() { | |
36507 var copyID = table.id; | |
36508 var tableWidget = table.parent; | |
36509 | |
36510 var newObjects = []; | |
36511 $(table.elements).each(function(){ | |
36512 if (this.selected) | |
36513 newObjects.push(this.object); | |
36514 }); | |
36515 | |
36516 var newDataset = new Dataset(); | |
36517 newDataset.label = tableWidget.datasets[copyID].label + " refined"; | |
36518 newDataset.objects = newObjects; | |
36519 | |
36520 GeoTemConfig.addDataset(newDataset); | |
36521 }; | |
36522 } | |
36523 | |
36524 this.selectors = selectors; | |
36525 | |
36526 // selectors.style.width = (this.filter.offsetWidth + this.selectAll.offsetWidth + this.selectPage.offsetWidth)+"px"; | |
36527 | |
36528 var results = document.createElement("td"); | |
36529 navigation.appendChild(results); | |
36530 | |
36531 var pagination = document.createElement("td"); | |
36532 $(pagination).css('float', 'right'); | |
36533 navigation.appendChild(pagination); | |
36534 | |
36535 this.resultsInfo = document.createElement('div'); | |
36536 this.resultsInfo.setAttribute('class', 'resultsInfo'); | |
36537 results.appendChild(this.resultsInfo); | |
36538 | |
36539 this.resultsDropdown = document.createElement('div'); | |
36540 this.resultsDropdown.setAttribute('class', 'resultsDropdown'); | |
36541 pagination.appendChild(this.resultsDropdown); | |
36542 var itemNumbers = []; | |
36543 var addItemNumber = function(count, index) { | |
36544 var setItemNumber = function() { | |
36545 table.updateIndices(count); | |
36546 table.update(); | |
36547 } | |
36548 itemNumbers.push({ | |
36549 name : count, | |
36550 onclick : setItemNumber | |
36551 }); | |
36552 } | |
36553 for (var i = 0; i < table.options.validResultsPerPage.length; i++) { | |
36554 addItemNumber(table.options.validResultsPerPage[i], i); | |
36555 } | |
36556 var dropdown = new Dropdown(this.resultsDropdown, itemNumbers, GeoTemConfig.getString('paginationDropdownHelp')); | |
36557 for (var i = 0; i < table.options.validResultsPerPage.length; i++) { | |
36558 if (table.options.initialResultsPerPage == table.options.validResultsPerPage[i]) { | |
36559 dropdown.setEntry(i); | |
36560 break; | |
36561 } | |
36562 } | |
36563 dropdown.div.title = GeoTemConfig.getString('paginationDropdownHelp'); | |
36564 | |
36565 this.firstPage = document.createElement('div'); | |
36566 this.firstPage.setAttribute('class', 'paginationButton'); | |
36567 this.firstPage.title = GeoTemConfig.getString('paginationFirsPageHelp'); | |
36568 | |
36569 pagination.appendChild(this.firstPage); | |
36570 this.firstPage.onclick = function() { | |
36571 if (table.page != 0) { | |
36572 table.page = 0; | |
36573 table.update(); | |
36574 } | |
36575 } | |
36576 | |
36577 this.previousPage = document.createElement('div'); | |
36578 this.previousPage.setAttribute('class', 'paginationButton'); | |
36579 this.previousPage.title = GeoTemConfig.getString('paginationPreviousPageHelp'); | |
36580 pagination.appendChild(this.previousPage); | |
36581 this.previousPage.onclick = function() { | |
36582 if (table.page > 0) { | |
36583 table.page--; | |
36584 table.update(); | |
36585 } | |
36586 } | |
36587 | |
36588 this.pageInfo = document.createElement('div'); | |
36589 this.pageInfo.setAttribute('class', 'pageInfo'); | |
36590 pagination.appendChild(this.pageInfo); | |
36591 | |
36592 this.nextPage = document.createElement('div'); | |
36593 this.nextPage.setAttribute('class', 'paginationButton'); | |
36594 this.nextPage.title = GeoTemConfig.getString('paginationNextPageHelp'); | |
36595 pagination.appendChild(this.nextPage); | |
36596 this.nextPage.onclick = function() { | |
36597 if (table.page < table.pages - 1) { | |
36598 table.page++; | |
36599 table.update(); | |
36600 } | |
36601 } | |
36602 | |
36603 this.lastPage = document.createElement('div'); | |
36604 this.lastPage.setAttribute('class', 'paginationButton'); | |
36605 this.lastPage.title = GeoTemConfig.getString('paginationLastPageHelp'); | |
36606 pagination.appendChild(this.lastPage); | |
36607 this.lastPage.onclick = function() { | |
36608 if (table.page != table.pages - 1) { | |
36609 table.page = table.pages - 1; | |
36610 table.update(); | |
36611 } | |
36612 } | |
36613 | |
36614 this.input = document.createElement("div"); | |
36615 this.input.style.overflow = 'auto'; | |
36616 this.tableDiv.appendChild(this.input); | |
36617 | |
36618 this.elementList = document.createElement("table"); | |
36619 this.elementList.setAttribute('class', 'resultList'); | |
36620 this.input.appendChild(this.elementList); | |
36621 var height = this.parent.getHeight(); | |
36622 if (height) { | |
36623 this.input.style.height = (height - pagination.offsetHeight) + 'px'; | |
36624 this.input.style.overflowY = 'auto'; | |
36625 } | |
36626 | |
36627 this.elementListHeader = document.createElement("tr"); | |
36628 this.elementList.appendChild(this.elementListHeader); | |
36629 | |
36630 if (GeoTemConfig.allowFilter) { | |
36631 var cell = document.createElement('th'); | |
36632 this.elementListHeader.appendChild(cell); | |
36633 } | |
36634 | |
36635 //Bottom pagination elements | |
36636 this.bottomToolbar = document.createElement("table"); | |
36637 this.bottomToolbar.setAttribute('class', 'ddbToolbar'); | |
36638 this.bottomToolbar.style.overflow = 'auto'; | |
36639 this.tableDiv.appendChild(this.bottomToolbar); | |
36640 | |
36641 var bottomNavigation = document.createElement("tr"); | |
36642 this.bottomToolbar.appendChild(bottomNavigation); | |
36643 | |
36644 var bottomPagination = document.createElement("td"); | |
36645 bottomNavigation.appendChild(bottomPagination); | |
36646 | |
36647 this.bottomLastPage = document.createElement('div'); | |
36648 this.bottomLastPage.setAttribute('class', 'paginationButton'); | |
36649 this.bottomLastPage.title = GeoTemConfig.getString('paginationLastPageHelp'); | |
36650 $(this.bottomLastPage).css('float', 'right'); | |
36651 bottomPagination.appendChild(this.bottomLastPage); | |
36652 this.bottomLastPage.onclick = function() { | |
36653 if (table.page != table.pages - 1) { | |
36654 table.page = table.pages - 1; | |
36655 table.update(); | |
36656 } | |
36657 } | |
36658 | |
36659 this.bottomNextPage = document.createElement('div'); | |
36660 this.bottomNextPage.setAttribute('class', 'paginationButton'); | |
36661 this.bottomNextPage.title = GeoTemConfig.getString('paginationNextPageHelp'); | |
36662 $(this.bottomNextPage).css('float', 'right'); | |
36663 bottomPagination.appendChild(this.bottomNextPage); | |
36664 this.bottomNextPage.onclick = function() { | |
36665 if (table.page < table.pages - 1) { | |
36666 table.page++; | |
36667 table.update(); | |
36668 } | |
36669 } | |
36670 | |
36671 this.bottomPageInfo = document.createElement('div'); | |
36672 this.bottomPageInfo.setAttribute('class', 'pageInfo'); | |
36673 $(this.bottomPageInfo).css('float', 'right'); | |
36674 bottomPagination.appendChild(this.bottomPageInfo); | |
36675 | |
36676 this.bottomPreviousPage = document.createElement('div'); | |
36677 this.bottomPreviousPage.setAttribute('class', 'paginationButton'); | |
36678 this.bottomPreviousPage.title = GeoTemConfig.getString('paginationPreviousPageHelp'); | |
36679 $(this.bottomPreviousPage).css('float', 'right'); | |
36680 bottomPagination.appendChild(this.bottomPreviousPage); | |
36681 this.bottomPreviousPage.onclick = function() { | |
36682 if (table.page > 0) { | |
36683 table.page--; | |
36684 table.update(); | |
36685 } | |
36686 } | |
36687 | |
36688 this.bottomFirstPage = document.createElement('div'); | |
36689 this.bottomFirstPage.setAttribute('class', 'paginationButton'); | |
36690 this.bottomFirstPage.title = GeoTemConfig.getString('paginationFirsPageHelp'); | |
36691 $(this.bottomFirstPage).css('float', 'right'); | |
36692 bottomPagination.appendChild(this.bottomFirstPage); | |
36693 this.bottomFirstPage.onclick = function() { | |
36694 if (table.page != 0) { | |
36695 table.page = 0; | |
36696 table.update(); | |
36697 } | |
36698 } | |
36699 | |
36700 if ( typeof (this.elements[0]) == 'undefined') { | |
36701 return; | |
36702 } | |
36703 | |
36704 var ascButtons = []; | |
36705 var descButtons = []; | |
36706 var clearButtons = function() { | |
36707 for (var i in ascButtons ) { | |
36708 ascButtons[i].setAttribute('class', 'sort sortAscDeactive'); | |
36709 } | |
36710 for (var i in descButtons ) { | |
36711 descButtons[i].setAttribute('class', 'sort sortDescDeactive'); | |
36712 } | |
36713 } | |
36714 var addSortButton = function(key) { | |
36715 table.keyHeaderList.push(key); | |
36716 var cell = document.createElement('th'); | |
36717 table.elementListHeader.appendChild(cell); | |
36718 var sortAsc = document.createElement('div'); | |
36719 var sortDesc = document.createElement('div'); | |
36720 var span = document.createElement('div'); | |
36721 span.setAttribute('class', 'headerLabel'); | |
36722 span.innerHTML = key; | |
36723 cell.appendChild(sortDesc); | |
36724 cell.appendChild(span); | |
36725 cell.appendChild(sortAsc); | |
36726 sortAsc.setAttribute('class', 'sort sortAscDeactive'); | |
36727 sortAsc.title = GeoTemConfig.getString('sortAZHelp'); | |
36728 sortDesc.setAttribute('class', 'sort sortDescDeactive'); | |
36729 sortDesc.title = GeoTemConfig.getString('sortZAHelp'); | |
36730 ascButtons.push(sortAsc); | |
36731 descButtons.push(sortDesc); | |
36732 sortAsc.onclick = function() { | |
36733 clearButtons(); | |
36734 sortAsc.setAttribute('class', 'sort sortAscActive'); | |
36735 table.sortAscending(key); | |
36736 table.update(); | |
36737 } | |
36738 sortDesc.onclick = function() { | |
36739 clearButtons(); | |
36740 sortDesc.setAttribute('class', 'sort sortDescActive'); | |
36741 table.sortDescending(key); | |
36742 table.update(); | |
36743 } | |
36744 } | |
36745 for (var key in this.elements[0].object.tableContent) { | |
36746 addSortButton(key); | |
36747 } | |
36748 }, | |
36749 | |
36750 sortAscending : function(key) { | |
36751 var sortFunction = function(e1, e2) { | |
36752 if (e1.object.tableContent[key] < e2.object.tableContent[key]) { | |
36753 return -1; | |
36754 } | |
36755 return 1; | |
36756 } | |
36757 this.elements.sort(sortFunction); | |
36758 }, | |
36759 | |
36760 sortDescending : function(key) { | |
36761 var sortFunction = function(e1, e2) { | |
36762 if (e1.object.tableContent[key] > e2.object.tableContent[key]) { | |
36763 return -1; | |
36764 } | |
36765 return 1; | |
36766 } | |
36767 this.elements.sort(sortFunction); | |
36768 }, | |
36769 | |
36770 selectByText : function(text) { | |
36771 //deselect all elements | |
36772 $(this.elements).each(function(){ | |
36773 this.selected = false; | |
36774 }); | |
36775 | |
36776 var selectedCount = 0; | |
36777 $(this.elements).filter(function(index){ | |
36778 return this.object.contains(text); | |
36779 }).each(function(){ | |
36780 this.selected = true; | |
36781 selectedCount++; | |
36782 }); | |
36783 | |
36784 //only show selected elements | |
36785 this.showSelectedItems = true; | |
36786 this.showElementsLength = selectedCount; | |
36787 this.showSelected.setAttribute('class', 'smallButton showAll'); | |
36788 | |
36789 this.update(); | |
36790 this.parent.tableSelection(); | |
36791 }, | |
36792 | |
36793 setPagesText : function() { | |
36794 var infoText = GeoTemConfig.getString('pageInfo'); | |
36795 infoText = infoText.replace('PAGES_ID', this.pages); | |
36796 infoText = infoText.replace('PAGE_ID', this.page + 1); | |
36797 this.pageInfo.innerHTML = infoText; | |
36798 this.bottomPageInfo.innerHTML = infoText; | |
36799 }, | |
36800 | |
36801 setResultsText : function() { | |
36802 if (this.elements.length == 0) { | |
36803 this.resultsInfo.innerHTML = '0 Results'; | |
36804 } else { | |
36805 var infoText = GeoTemConfig.getString('resultsInfo'); | |
36806 var first = this.page * this.resultsPerPage + 1; | |
36807 var last = (this.page + 1 == this.pages ) ? this.showElementsLength : first + this.resultsPerPage - 1; | |
36808 infoText = infoText.replace('RESULTS_FROM_ID', first); | |
36809 infoText = infoText.replace('RESULTS_TO_ID', last); | |
36810 infoText = infoText.replace('RESULTS_ID', this.showElementsLength); | |
36811 this.resultsInfo.innerHTML = infoText; | |
36812 } | |
36813 }, | |
36814 | |
36815 updateIndices : function(rpp) { | |
36816 if ( typeof this.resultsPerPage == 'undefined') { | |
36817 this.page = 0; | |
36818 this.resultsPerPage = 0; | |
36819 } | |
36820 var index = this.page * this.resultsPerPage; | |
36821 this.resultsPerPage = rpp; | |
36822 if (this.showSelectedItems) { | |
36823 index = 0; | |
36824 } | |
36825 this.pages = Math.floor(this.showElementsLength / this.resultsPerPage); | |
36826 if (this.showElementsLength % this.resultsPerPage != 0) { | |
36827 this.pages++; | |
36828 } | |
36829 this.page = Math.floor(index / this.resultsPerPage); | |
36830 }, | |
36831 | |
36832 update : function() { | |
36833 var table = this; | |
36834 $(this.elementList).find("tr:gt(0)").remove(); | |
36835 if (this.page == 0) { | |
36836 this.previousPage.setAttribute('class', 'paginationButton previousPageDisabled'); | |
36837 this.firstPage.setAttribute('class', 'paginationButton firstPageDisabled'); | |
36838 this.bottomPreviousPage.setAttribute('class', 'paginationButton previousPageDisabled'); | |
36839 this.bottomFirstPage.setAttribute('class', 'paginationButton firstPageDisabled'); | |
36840 } else { | |
36841 this.previousPage.setAttribute('class', 'paginationButton previousPageEnabled'); | |
36842 this.firstPage.setAttribute('class', 'paginationButton firstPageEnabled'); | |
36843 this.bottomPreviousPage.setAttribute('class', 'paginationButton previousPageEnabled'); | |
36844 this.bottomFirstPage.setAttribute('class', 'paginationButton firstPageEnabled'); | |
36845 } | |
36846 if (this.page == this.pages - 1) { | |
36847 this.nextPage.setAttribute('class', 'paginationButton nextPageDisabled'); | |
36848 this.lastPage.setAttribute('class', 'paginationButton lastPageDisabled'); | |
36849 this.bottomNextPage.setAttribute('class', 'paginationButton nextPageDisabled'); | |
36850 this.bottomLastPage.setAttribute('class', 'paginationButton lastPageDisabled'); | |
36851 } else { | |
36852 this.nextPage.setAttribute('class', 'paginationButton nextPageEnabled'); | |
36853 this.lastPage.setAttribute('class', 'paginationButton lastPageEnabled'); | |
36854 this.bottomNextPage.setAttribute('class', 'paginationButton nextPageEnabled'); | |
36855 this.bottomLastPage.setAttribute('class', 'paginationButton lastPageEnabled'); | |
36856 } | |
36857 this.setPagesText(); | |
36858 this.setResultsText(); | |
36859 if (this.showSelectedItems) { | |
36860 var start = this.page * this.resultsPerPage; | |
36861 var items = 0; | |
36862 for (var i = 0; i < this.elements.length; i++) { | |
36863 if (items == start) { | |
36864 this.first = i; | |
36865 break; | |
36866 } | |
36867 if (this.elements[i].selected) { | |
36868 items++; | |
36869 } | |
36870 } | |
36871 } else { | |
36872 this.first = this.page * this.resultsPerPage; | |
36873 } | |
36874 //this.last = ( this.page + 1 == this.pages ) ? this.elements.length : this.first + this.resultsPerPage; | |
36875 var c = GeoTemConfig.getColor(this.id); | |
36876 var itemSet = []; | |
36877 var clearDivs = function() { | |
36878 for (var i = 0; i < itemSet.length; i++) { | |
36879 if (!itemSet[i].e.selected) { | |
36880 itemSet[i].e.highlighted = false; | |
36881 $(itemSet[i].div).css('background-color', table.options.unselectedCellColor); | |
36882 } | |
36883 } | |
36884 } | |
36885 var setHighlight = function(item, div) { | |
36886 var enter = function() { | |
36887 clearDivs(); | |
36888 if (!item.selected) { | |
36889 item.highlighted = true; | |
36890 $(div).css('background-color', 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'); | |
36891 table.parent.triggerHighlight(item.object); | |
36892 } | |
36893 } | |
36894 var leave = function() { | |
36895 clearDivs(); | |
36896 if (!item.selected) { | |
36897 table.parent.triggerHighlight(); | |
36898 } | |
36899 } | |
36900 $(div).hover(enter, leave); | |
36901 $(div).mousemove(function() { | |
36902 if (!item.selected && !item.highlighted) { | |
36903 item.highlighted = true; | |
36904 $(div).css('background-color', 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'); | |
36905 table.parent.triggerHighlight(item.object); | |
36906 } | |
36907 }); | |
36908 } | |
36909 var setSelection = function(item, div, checkbox) { | |
36910 var click = function(e) { | |
36911 var checked = $(checkbox).is(':checked'); | |
36912 if (checked) { | |
36913 item.selected = true; | |
36914 item.highlighted = false; | |
36915 } else { | |
36916 item.selected = false; | |
36917 item.highlighted = true; | |
36918 } | |
36919 //if( e.target == div ){ | |
36920 // $(checkbox).attr('checked', !checked); | |
36921 //} | |
36922 table.parent.tableSelection(); | |
36923 } | |
36924 //$(div).click(click); | |
36925 $(checkbox).click(click); | |
36926 } | |
36927 this.checkboxes = []; | |
36928 var items = 0; | |
36929 for (var i = this.first; i < this.elements.length; i++) { | |
36930 var e = this.elements[i]; | |
36931 //vhz because of an error | |
36932 if ( typeof (e) == "undefined") { | |
36933 continue; | |
36934 } | |
36935 if (this.showSelectedItems && !e.selected) { | |
36936 continue; | |
36937 } | |
36938 var itemRow = $("<tr/>").appendTo(this.elementList); | |
36939 if (GeoTemConfig.allowFilter) { | |
36940 var checkColumn = $("<td/>").appendTo(itemRow); | |
36941 var checkbox = $("<input type='checkbox'/>").appendTo(checkColumn); | |
36942 $(checkbox).attr('checked', e.selected); | |
36943 } | |
36944 var makeSubtext = function(cell, text) { | |
36945 var subtext = text.substring(0, table.options.tableContentOffset); | |
36946 subtext = subtext.substring(0, subtext.lastIndexOf(' ')); | |
36947 subtext += ' ... '; | |
36948 var textDiv = $("<div style='display:inline-block;'/>").appendTo(cell); | |
36949 $(textDiv).html(subtext); | |
36950 var show = false; | |
36951 var fullDiv = $("<div style='display:inline-block;'><a href='javascript:void(0)'>\>\></a></div>").appendTo(cell); | |
36952 $(fullDiv).click(function() { | |
36953 show = !show; | |
36954 if (show) { | |
36955 $(textDiv).html(text); | |
36956 $(fullDiv).html('<a href="javascript:void(0)">\<\<</a>'); | |
36957 } else { | |
36958 $(textDiv).html(subtext); | |
36959 $(fullDiv).html('<a href="javascript:void(0)">\>\></a>'); | |
36960 } | |
36961 }); | |
36962 } | |
36963 for (var k = 0; k < table.keyHeaderList.length; k++) { | |
36964 var key = table.keyHeaderList[k]; | |
36965 //vhz | |
36966 var text = e.object.tableContent[key]; | |
36967 if (typeof text === "undefined") | |
36968 text = ""; | |
36969 var cell = $("<td></td>").appendTo(itemRow); | |
36970 | |
36971 //align the elements (if unset: "center") | |
36972 if (typeof table.options.verticalAlign !== "undefined"){ | |
36973 if (table.options.verticalAlign === "top") | |
36974 $(cell).attr("valign","top"); | |
36975 else if (table.options.verticalAlign === "center") | |
36976 $(cell).attr("valign","center"); | |
36977 else if (table.options.verticalAlign === "bottom") | |
36978 $(cell).attr("valign","bottom"); | |
36979 } | |
36980 | |
36981 if (table.options.tableContentOffset && text.length < table.options.tableContentOffset) { | |
36982 $(cell).html(text); | |
36983 } else { | |
36984 makeSubtext(cell, text); | |
36985 } | |
36986 } | |
36987 if (e.selected || e.highlighted) { | |
36988 $(itemRow).css('background-color', 'rgb(' + c.r0 + ',' + c.g0 + ',' + c.b0 + ')'); | |
36989 } else { | |
36990 $(itemRow).css('background-color', table.options.unselectedCellColor); | |
36991 } | |
36992 itemSet.push({ | |
36993 e : e, | |
36994 div : itemRow | |
36995 }); | |
36996 setHighlight(e, itemRow); | |
36997 if (GeoTemConfig.allowFilter) { | |
36998 setSelection(e, itemRow, checkbox); | |
36999 this.checkboxes.push(checkbox); | |
37000 $(checkColumn).css('text-align', 'center'); | |
37001 } | |
37002 items++; | |
37003 if (items == this.resultsPerPage) { | |
37004 break; | |
37005 } | |
37006 } | |
37007 }, | |
37008 | |
37009 show : function() { | |
37010 if (GeoTemConfig.allowFilter) { | |
37011 this.parent.filterBar.appendTo(this.selectors); | |
37012 } | |
37013 this.tableDiv.style.display = "block"; | |
37014 }, | |
37015 | |
37016 hide : function() { | |
37017 this.tableDiv.style.display = "none"; | |
37018 }, | |
37019 | |
37020 resetElements : function() { | |
37021 for (var i = 0; i < this.elements.length; i++) { | |
37022 this.elements[i].selected = false; | |
37023 this.elements[i].highlighted = false; | |
37024 } | |
37025 }, | |
37026 | |
37027 reset : function() { | |
37028 if (!this.options.tableKeepShowSelected){ | |
37029 this.showSelectedItems = false; | |
37030 this.showElementsLength = this.elements.length; | |
37031 this.showSelected.setAttribute('class', 'smallButton showSelected'); | |
37032 } | |
37033 this.updateIndices(this.resultsPerPage); | |
37034 }, | |
37035 | |
37036 initialize : function() { | |
37037 | |
37038 this.tableDiv = document.createElement("div"); | |
37039 this.tableDiv.setAttribute('class', 'singleTable'); | |
37040 this.parent.gui.input.appendChild(this.tableDiv); | |
37041 | |
37042 this.initToolbar(); | |
37043 | |
37044 this.tableDiv.style.display = 'none'; | |
37045 this.updateIndices(this.options.initialResultsPerPage); | |
37046 | |
37047 this.update(); | |
37048 | |
37049 } | |
37050 } | |
37051 | |
37052 function TableElement(object) { | |
37053 | |
37054 this.object = object; | |
37055 this.selected = false; | |
37056 this.highlighted = false; | |
37057 | |
37058 } | |
37059 /* | |
37060 * Dataloader.js | |
37061 * | |
37062 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37063 * | |
37064 * This library is free software; you can redistribute it and/or | |
37065 * modify it under the terms of the GNU Lesser General Public | |
37066 * License as published by the Free Software Foundation; either | |
37067 * version 3 of the License, or (at your option) any later version. | |
37068 * | |
37069 * This library is distributed in the hope that it will be useful, | |
37070 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37071 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37072 * Lesser General Public License for more details. | |
37073 * | |
37074 * You should have received a copy of the GNU Lesser General Public | |
37075 * License along with this library; if not, write to the Free Software | |
37076 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37077 * MA 02110-1301 USA | |
37078 */ | |
37079 | |
37080 /** | |
37081 * @class Dataloader | |
37082 * Implementation for a Dataloader UI | |
37083 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37084 * | |
37085 * @param {HTML object} parent div to append the Dataloader | |
37086 */ | |
37087 function Dataloader(parent) { | |
37088 | |
37089 this.dataLoader = this; | |
37090 | |
37091 this.parent = parent; | |
37092 this.options = parent.options; | |
37093 | |
37094 this.initialize(); | |
37095 } | |
37096 | |
37097 Dataloader.prototype = { | |
37098 | |
37099 show : function() { | |
37100 this.dataloaderDiv.style.display = "block"; | |
37101 }, | |
37102 | |
37103 hide : function() { | |
37104 this.dataloaderDiv.style.display = "none"; | |
37105 }, | |
37106 | |
37107 initialize : function() { | |
37108 | |
37109 this.addStaticLoader(); | |
37110 this.addLocalStorageLoader(); | |
37111 this.addKMLLoader(); | |
37112 this.addKMZLoader(); | |
37113 this.addCSVLoader(); | |
37114 this.addLocalKMLLoader(); | |
37115 this.addLocalCSVLoader(); | |
37116 | |
37117 // trigger change event on the select so | |
37118 // that only the first loader div will be shown | |
37119 $(this.parent.gui.loaderTypeSelect).change(); | |
37120 }, | |
37121 | |
37122 getFileName : function(url) { | |
37123 var fileName = $.url(url).attr('file'); | |
37124 if ( (typeof fileName === "undefined") || (fileName.length === 0) ){ | |
37125 fileName = $.url(url).attr('path'); | |
37126 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
37127 while (fileName.endsWith("/")){ | |
37128 fileName = fileName.substr(0,fileName.length-1); | |
37129 } | |
37130 if (fileName.length > 1) | |
37131 fileName = fileName.substr(fileName.lastIndexOf("/")+1); | |
37132 else | |
37133 fileName = "unnamed dataset"; | |
37134 } | |
37135 return fileName; | |
37136 }, | |
37137 | |
37138 distributeDataset : function(dataSet) { | |
37139 GeoTemConfig.addDataset(dataSet); | |
37140 }, | |
37141 | |
37142 distributeDatasets : function(datasets) { | |
37143 GeoTemConfig.addDatasets(datasets); | |
37144 }, | |
37145 | |
37146 addStaticLoader : function() { | |
37147 if (this.options.staticKML.length > 0){ | |
37148 $(this.parent.gui.loaderTypeSelect).append("<option value='StaticLoader'>Static Data</option>"); | |
37149 | |
37150 this.StaticLoaderTab = document.createElement("div"); | |
37151 $(this.StaticLoaderTab).attr("id","StaticLoader"); | |
37152 | |
37153 this.staticKMLList = document.createElement("select"); | |
37154 $(this.StaticLoaderTab).append(this.staticKMLList); | |
37155 | |
37156 var staticKMLList = this.staticKMLList; | |
37157 var isFirstHeader = true; | |
37158 $(this.options.staticKML).each(function(){ | |
37159 var label = this.label; | |
37160 var url = this.url; | |
37161 var header = this.header; | |
37162 if (typeof header !== "undefined"){ | |
37163 if (!isFirstHeader) | |
37164 $(staticKMLList).append("</optgroup>"); | |
37165 $(staticKMLList).append("<optgroup label='"+header+"'>"); | |
37166 isFirstHeader = false; | |
37167 } else | |
37168 $(staticKMLList).append("<option value='"+url+"'> "+label+"</option>"); | |
37169 }); | |
37170 //close last optgroup (if there were any) | |
37171 if (!isFirstHeader) | |
37172 $(staticKMLList).append("</optgroup>"); | |
37173 | |
37174 this.loadStaticKMLButton = document.createElement("button"); | |
37175 $(this.loadStaticKMLButton).text("load"); | |
37176 $(this.StaticLoaderTab).append(this.loadStaticKMLButton); | |
37177 | |
37178 $(this.loadStaticKMLButton).click($.proxy(function(){ | |
37179 var kmlURL = $(this.staticKMLList).find(":selected").attr("value"); | |
37180 if (kmlURL.length === 0) | |
37181 return; | |
37182 var origURL = kmlURL; | |
37183 var fileName = this.getFileName(kmlURL); | |
37184 if (typeof this.options.proxy != 'undefined') | |
37185 kmlURL = this.options.proxy + kmlURL; | |
37186 var kml = GeoTemConfig.getKml(kmlURL); | |
37187 if ((typeof kml !== "undefined") && (kml != null)) { | |
37188 var dataSet = new Dataset(GeoTemConfig.loadKml(kml), fileName, origURL); | |
37189 | |
37190 if (dataSet != null) | |
37191 this.distributeDataset(dataSet); | |
37192 } else | |
37193 alert("Could not load file."); | |
37194 },this)); | |
37195 | |
37196 $(this.parent.gui.loaders).append(this.StaticLoaderTab); | |
37197 } | |
37198 }, | |
37199 | |
37200 addKMLLoader : function() { | |
37201 $(this.parent.gui.loaderTypeSelect).append("<option value='KMLLoader'>KML File URL</option>"); | |
37202 | |
37203 this.KMLLoaderTab = document.createElement("div"); | |
37204 $(this.KMLLoaderTab).attr("id","KMLLoader"); | |
37205 | |
37206 this.kmlURL = document.createElement("input"); | |
37207 $(this.kmlURL).attr("type","text"); | |
37208 $(this.KMLLoaderTab).append(this.kmlURL); | |
37209 | |
37210 this.loadKMLButton = document.createElement("button"); | |
37211 $(this.loadKMLButton).text("load KML"); | |
37212 $(this.KMLLoaderTab).append(this.loadKMLButton); | |
37213 | |
37214 $(this.loadKMLButton).click($.proxy(function(){ | |
37215 var kmlURL = $(this.kmlURL).val(); | |
37216 if (kmlURL.length === 0) | |
37217 return; | |
37218 var origURL = kmlURL; | |
37219 var fileName = this.getFileName(kmlURL); | |
37220 if (typeof this.options.proxy != 'undefined') | |
37221 kmlURL = this.options.proxy + kmlURL; | |
37222 var kml = GeoTemConfig.getKml(kmlURL); | |
37223 if ((typeof kml !== "undefined") && (kml != null)) { | |
37224 var dataSet = new Dataset(GeoTemConfig.loadKml(kml), fileName, origURL); | |
37225 | |
37226 if (dataSet != null) | |
37227 this.distributeDataset(dataSet); | |
37228 } else | |
37229 alert("Could not load file."); | |
37230 },this)); | |
37231 | |
37232 $(this.parent.gui.loaders).append(this.KMLLoaderTab); | |
37233 }, | |
37234 | |
37235 addKMZLoader : function() { | |
37236 $(this.parent.gui.loaderTypeSelect).append("<option value='KMZLoader'>KMZ File URL</option>"); | |
37237 | |
37238 this.KMZLoaderTab = document.createElement("div"); | |
37239 $(this.KMZLoaderTab).attr("id","KMZLoader"); | |
37240 | |
37241 this.kmzURL = document.createElement("input"); | |
37242 $(this.kmzURL).attr("type","text"); | |
37243 $(this.KMZLoaderTab).append(this.kmzURL); | |
37244 | |
37245 this.loadKMZButton = document.createElement("button"); | |
37246 $(this.loadKMZButton).text("load KMZ"); | |
37247 $(this.KMZLoaderTab).append(this.loadKMZButton); | |
37248 | |
37249 $(this.loadKMZButton).click($.proxy(function(){ | |
37250 | |
37251 var dataLoader = this; | |
37252 | |
37253 var kmzURL = $(this.kmzURL).val(); | |
37254 if (kmzURL.length === 0) | |
37255 return; | |
37256 var origURL = kmzURL; | |
37257 var fileName = dataLoader.getFileName(kmzURL); | |
37258 if (typeof this.options.proxy != 'undefined') | |
37259 kmzURL = this.options.proxy + kmzURL; | |
37260 | |
37261 GeoTemConfig.getKmz(kmzURL, function(kmlArray){ | |
37262 $(kmlArray).each(function(){ | |
37263 var dataSet = new Dataset(GeoTemConfig.loadKml(this), fileName, origURL); | |
37264 | |
37265 if (dataSet != null) | |
37266 dataLoader.distributeDataset(dataSet); | |
37267 }); | |
37268 }); | |
37269 },this)); | |
37270 | |
37271 $(this.parent.gui.loaders).append(this.KMZLoaderTab); | |
37272 }, | |
37273 | |
37274 addCSVLoader : function() { | |
37275 $(this.parent.gui.loaderTypeSelect).append("<option value='CSVLoader'>CSV File URL</option>"); | |
37276 | |
37277 this.CSVLoaderTab = document.createElement("div"); | |
37278 $(this.CSVLoaderTab).attr("id","CSVLoader"); | |
37279 | |
37280 this.csvURL = document.createElement("input"); | |
37281 $(this.csvURL).attr("type","text"); | |
37282 $(this.CSVLoaderTab).append(this.csvURL); | |
37283 | |
37284 this.loadCSVButton = document.createElement("button"); | |
37285 $(this.loadCSVButton).text("load CSV"); | |
37286 $(this.CSVLoaderTab).append(this.loadCSVButton); | |
37287 | |
37288 $(this.loadCSVButton).click($.proxy(function(){ | |
37289 var dataLoader = this; | |
37290 | |
37291 var csvURL = $(this.csvURL).val(); | |
37292 if (csvURL.length === 0) | |
37293 return; | |
37294 var origURL = csvURL; | |
37295 var fileName = dataLoader.getFileName(csvURL); | |
37296 if (typeof this.options.proxy != 'undefined') | |
37297 csvURL = this.options.proxy + csvURL; | |
37298 GeoTemConfig.getCsv(csvURL, function(json){ | |
37299 if ((typeof json !== "undefined") && (json.length > 0)) { | |
37300 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL); | |
37301 | |
37302 if (dataSet != null) | |
37303 dataLoader.distributeDataset(dataSet); | |
37304 } else | |
37305 alert("Could not load file."); | |
37306 }); | |
37307 },this)); | |
37308 | |
37309 $(this.parent.gui.loaders).append(this.CSVLoaderTab); | |
37310 }, | |
37311 | |
37312 addLocalKMLLoader : function() { | |
37313 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalKMLLoader'>local KML File</option>"); | |
37314 | |
37315 this.localKMLLoaderTab = document.createElement("div"); | |
37316 $(this.localKMLLoaderTab).attr("id","LocalKMLLoader"); | |
37317 | |
37318 this.kmlFile = document.createElement("input"); | |
37319 $(this.kmlFile).attr("type","file"); | |
37320 $(this.localKMLLoaderTab).append(this.kmlFile); | |
37321 | |
37322 this.loadLocalKMLButton = document.createElement("button"); | |
37323 $(this.loadLocalKMLButton).text("load KML"); | |
37324 $(this.localKMLLoaderTab).append(this.loadLocalKMLButton); | |
37325 | |
37326 $(this.loadLocalKMLButton).click($.proxy(function(){ | |
37327 var filelist = $(this.kmlFile).get(0).files; | |
37328 if (filelist.length > 0){ | |
37329 var file = filelist[0]; | |
37330 var fileName = file.name; | |
37331 var reader = new FileReader(); | |
37332 | |
37333 reader.onloadend = ($.proxy(function(theFile) { | |
37334 return function(e) { | |
37335 var dataSet = new Dataset(GeoTemConfig.loadKml($.parseXML(reader.result)), fileName); | |
37336 if (dataSet != null) | |
37337 this.distributeDataset(dataSet); | |
37338 }; | |
37339 }(file),this)); | |
37340 | |
37341 reader.readAsText(file); | |
37342 } | |
37343 },this)); | |
37344 | |
37345 $(this.parent.gui.loaders).append(this.localKMLLoaderTab); | |
37346 }, | |
37347 | |
37348 addLocalCSVLoader : function() { | |
37349 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalCSVLoader'>local CSV File</option>"); | |
37350 | |
37351 this.localCSVLoaderTab = document.createElement("div"); | |
37352 $(this.localCSVLoaderTab).attr("id","LocalCSVLoader"); | |
37353 | |
37354 this.csvFile = document.createElement("input"); | |
37355 $(this.csvFile).attr("type","file"); | |
37356 $(this.localCSVLoaderTab).append(this.csvFile); | |
37357 | |
37358 this.loadLocalCSVButton = document.createElement("button"); | |
37359 $(this.loadLocalCSVButton).text("load CSV"); | |
37360 $(this.localCSVLoaderTab).append(this.loadLocalCSVButton); | |
37361 | |
37362 $(this.loadLocalCSVButton).click($.proxy(function(){ | |
37363 var filelist = $(this.csvFile).get(0).files; | |
37364 if (filelist.length > 0){ | |
37365 var file = filelist[0]; | |
37366 var fileName = file.name; | |
37367 var reader = new FileReader(); | |
37368 | |
37369 reader.onloadend = ($.proxy(function(theFile) { | |
37370 return function(e) { | |
37371 var json = GeoTemConfig.convertCsv(reader.result); | |
37372 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName); | |
37373 if (dataSet != null) | |
37374 this.distributeDataset(dataSet); | |
37375 }; | |
37376 }(file),this)); | |
37377 | |
37378 reader.readAsText(file); | |
37379 } | |
37380 },this)); | |
37381 | |
37382 $(this.parent.gui.loaders).append(this.localCSVLoaderTab); | |
37383 }, | |
37384 | |
37385 addLocalStorageLoader : function() { | |
37386 var dataLoader = this; | |
37387 this.localStorageLoaderTab = document.createElement("div"); | |
37388 $(this.localStorageLoaderTab).attr("id","LocalStorageLoader"); | |
37389 | |
37390 var localDatasets = document.createElement("select"); | |
37391 $(this.localStorageLoaderTab).append(localDatasets); | |
37392 | |
37393 var localStorageDatasetCount = 0; | |
37394 for(var key in localStorage){ | |
37395 //TODO: this is a somewhat bad idea, as it is used in multiple widgets. | |
37396 //A global GeoTemCo option "prefix" could be better. But still.. | |
37397 if (key.startsWith("GeoBrowser_dataset_")){ | |
37398 localStorageDatasetCount++; | |
37399 var label = key.substring("GeoBrowser_dataset_".length); | |
37400 var url = key; | |
37401 $(localDatasets).append("<option value='"+url+"'>"+decodeURIComponent(label)+"</option>"); | |
37402 } | |
37403 } | |
37404 | |
37405 //only show if there are datasets | |
37406 if (localStorageDatasetCount > 0) | |
37407 $(this.parent.gui.loaderTypeSelect).append("<option value='LocalStorageLoader'>browser storage</option>"); | |
37408 | |
37409 this.loadLocalStorageButton = document.createElement("button"); | |
37410 $(this.loadLocalStorageButton).text("load"); | |
37411 $(this.localStorageLoaderTab).append(this.loadLocalStorageButton); | |
37412 | |
37413 $(this.loadLocalStorageButton).click($.proxy(function(){ | |
37414 var fileKey = $(localDatasets).find(":selected").attr("value"); | |
37415 if (fileKey.length === 0) | |
37416 return; | |
37417 var csv = $.remember({name:fileKey}); | |
37418 //TODO: this is a somewhat bad idea, as it is used in multiple widgets. | |
37419 //A global GeoTemCo option "prefix" could be better. But still.. | |
37420 var fileName = decodeURIComponent(fileKey.substring("GeoBrowser_dataset_".length)); | |
37421 var json = GeoTemConfig.convertCsv(csv); | |
37422 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, fileKey, "local"); | |
37423 if (dataSet != null) | |
37424 dataLoader.distributeDataset(dataSet); | |
37425 },this)); | |
37426 | |
37427 $(this.parent.gui.loaders).append(this.localStorageLoaderTab); | |
37428 } | |
37429 }; | |
37430 /* | |
37431 * DataloaderConfig.js | |
37432 * | |
37433 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37434 * | |
37435 * This library is free software; you can redistribute it and/or | |
37436 * modify it under the terms of the GNU Lesser General Public | |
37437 * License as published by the Free Software Foundation; either | |
37438 * version 3 of the License, or (at your option) any later version. | |
37439 * | |
37440 * This library is distributed in the hope that it will be useful, | |
37441 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37442 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37443 * Lesser General Public License for more details. | |
37444 * | |
37445 * You should have received a copy of the GNU Lesser General Public | |
37446 * License along with this library; if not, write to the Free Software | |
37447 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37448 * MA 02110-1301 USA | |
37449 */ | |
37450 | |
37451 /** | |
37452 * @class DataloaderConfig | |
37453 * Dataloader Configuration File | |
37454 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37455 */ | |
37456 function DataloaderConfig(options) { | |
37457 | |
37458 this.options = { | |
37459 proxy : 'php/proxy.php?address=', | |
37460 staticKML : [ | |
37461 // {header: "header label"}, | |
37462 // {label: "Johann Wolfgang von Goethe", url:"http://.../goethe.kml" }, | |
37463 ] | |
37464 }; | |
37465 if ( typeof options != 'undefined') { | |
37466 $.extend(this.options, options); | |
37467 } | |
37468 | |
37469 }; | |
37470 /* | |
37471 * DataloaderGui.js | |
37472 * | |
37473 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37474 * | |
37475 * This library is free software; you can redistribute it and/or | |
37476 * modify it under the terms of the GNU Lesser General Public | |
37477 * License as published by the Free Software Foundation; either | |
37478 * version 3 of the License, or (at your option) any later version. | |
37479 * | |
37480 * This library is distributed in the hope that it will be useful, | |
37481 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37482 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37483 * Lesser General Public License for more details. | |
37484 * | |
37485 * You should have received a copy of the GNU Lesser General Public | |
37486 * License along with this library; if not, write to the Free Software | |
37487 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37488 * MA 02110-1301 USA | |
37489 */ | |
37490 | |
37491 /** | |
37492 * @class DataloaderGui | |
37493 * Dataloader GUI Implementation | |
37494 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37495 * | |
37496 * @param {DataloaderWidget} parent Dataloader widget object | |
37497 * @param {HTML object} div parent div to append the Dataloader gui | |
37498 * @param {JSON} options Dataloader configuration | |
37499 */ | |
37500 function DataloaderGui(dataloader, div, options) { | |
37501 | |
37502 var dataloaderGui = this; | |
37503 | |
37504 this.dataloaderContainer = div; | |
37505 this.dataloaderContainer.style.position = 'relative'; | |
37506 | |
37507 this.loaderTypeSelect = document.createElement("select"); | |
37508 div.appendChild(this.loaderTypeSelect); | |
37509 | |
37510 this.loaders = document.createElement("div"); | |
37511 div.appendChild(this.loaders); | |
37512 | |
37513 $(this.loaderTypeSelect).change(function(){ | |
37514 var activeLoader = $(this).val(); | |
37515 $(dataloaderGui.loaders).find("div").each(function(){ | |
37516 if ($(this).attr("id") == activeLoader) | |
37517 $(this).show(); | |
37518 else | |
37519 $(this).hide(); | |
37520 }); | |
37521 }); | |
37522 }; | |
37523 /* | |
37524 * DataloaderWidget.js | |
37525 * | |
37526 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37527 * | |
37528 * This library is free software; you can redistribute it and/or | |
37529 * modify it under the terms of the GNU Lesser General Public | |
37530 * License as published by the Free Software Foundation; either | |
37531 * version 3 of the License, or (at your option) any later version. | |
37532 * | |
37533 * This library is distributed in the hope that it will be useful, | |
37534 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37535 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37536 * Lesser General Public License for more details. | |
37537 * | |
37538 * You should have received a copy of the GNU Lesser General Public | |
37539 * License along with this library; if not, write to the Free Software | |
37540 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37541 * MA 02110-1301 USA | |
37542 */ | |
37543 | |
37544 /** | |
37545 * @class DataloaderWidget | |
37546 * DataloaderWidget Implementation | |
37547 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37548 * | |
37549 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
37550 * @param {HTML object} div parent div to append the Dataloader widget div | |
37551 * @param {JSON} options user specified configuration that overwrites options in DataloaderConfig.js | |
37552 */ | |
37553 DataloaderWidget = function(core, div, options) { | |
37554 | |
37555 this.core = core; | |
37556 this.core.setWidget(this); | |
37557 | |
37558 this.options = (new DataloaderConfig(options)).options; | |
37559 this.gui = new DataloaderGui(this, div, this.options); | |
37560 | |
37561 this.dataLoader = new Dataloader(this); | |
37562 } | |
37563 | |
37564 DataloaderWidget.prototype = { | |
37565 | |
37566 initWidget : function() { | |
37567 | |
37568 var dataloaderWidget = this; | |
37569 }, | |
37570 | |
37571 highlightChanged : function(objects) { | |
37572 if( !GeoTemConfig.highlightEvents ){ | |
37573 return; | |
37574 } | |
37575 }, | |
37576 | |
37577 selectionChanged : function(selection) { | |
37578 if( !GeoTemConfig.selectionEvents ){ | |
37579 return; | |
37580 } | |
37581 }, | |
37582 | |
37583 triggerHighlight : function(item) { | |
37584 }, | |
37585 | |
37586 tableSelection : function() { | |
37587 }, | |
37588 | |
37589 deselection : function() { | |
37590 }, | |
37591 | |
37592 filtering : function() { | |
37593 }, | |
37594 | |
37595 inverseFiltering : function() { | |
37596 }, | |
37597 | |
37598 triggerRefining : function() { | |
37599 }, | |
37600 | |
37601 reset : function() { | |
37602 }, | |
37603 | |
37604 loadFromURL : function() { | |
37605 var dataLoaderWidget = this; | |
37606 //using jQuery-URL-Parser (https://github.com/skruse/jQuery-URL-Parser) | |
37607 var datasets = []; | |
37608 $.each($.url().param(),function(paramName, paramValue){ | |
37609 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
37610 var fileName = dataLoaderWidget.dataLoader.getFileName(paramValue); | |
37611 var origURL = paramValue; | |
37612 if (typeof dataLoaderWidget.options.proxy != 'undefined') | |
37613 paramValue = dataLoaderWidget.options.proxy + paramValue; | |
37614 if (paramName.toLowerCase().startsWith("kml")){ | |
37615 var kmlDoc = GeoTemConfig.getKml(paramValue); | |
37616 var dataSet = new Dataset(GeoTemConfig.loadKml(kmlDoc), fileName, origURL); | |
37617 if (dataSet != null) | |
37618 datasets.push(dataSet); | |
37619 } | |
37620 else if (paramName.toLowerCase().startsWith("csv")){ | |
37621 var json = GeoTemConfig.getCsv(paramValue); | |
37622 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL); | |
37623 if (dataSet != null) | |
37624 datasets.push(dataSet); | |
37625 } | |
37626 else if (paramName.toLowerCase().startsWith("local")){ | |
37627 var csv = $.remember({name:encodeURIComponent(origURL)}); | |
37628 //TODO: this is a bad idea and will be changed upon having a better | |
37629 //usage model for local stored data | |
37630 var fileName = origURL.substring("GeoBrowser_dataset_".length); | |
37631 var json = GeoTemConfig.convertCsv(csv); | |
37632 var dataSet = new Dataset(GeoTemConfig.loadJson(json), fileName, origURL, "local"); | |
37633 if (dataSet != null) | |
37634 datasets.push(dataSet); | |
37635 } | |
37636 }); | |
37637 //Load the (optional!) dataset colors | |
37638 $.each($.url().param(),function(paramName, paramValue){ | |
37639 if (paramName.toLowerCase().startsWith("color")){ | |
37640 //color is 1-based, index is 0-based! | |
37641 var datasetID = parseInt(paramName.substring("color".length))-1; | |
37642 if (datasets.length > datasetID){ | |
37643 if (typeof datasets[datasetID].color === "undefined"){ | |
37644 var color = new Object(); | |
37645 var colorsSelectedUnselected = paramValue.split(","); | |
37646 if (colorsSelectedUnselected.length > 2) | |
37647 return; | |
37648 | |
37649 var color1 = colorsSelectedUnselected[0]; | |
37650 if (color1.length != 6) | |
37651 return; | |
37652 | |
37653 color.r1 = parseInt(color1.substr(0,2),16); | |
37654 color.g1 = parseInt(color1.substr(2,2),16); | |
37655 color.b1 = parseInt(color1.substr(4,2),16); | |
37656 | |
37657 //check if a unselected color is given | |
37658 if (colorsSelectedUnselected.length == 2){ | |
37659 var color0 = colorsSelectedUnselected[1]; | |
37660 if (color0.length != 6) | |
37661 return; | |
37662 | |
37663 color.r0 = parseInt(color0.substr(0,2),16); | |
37664 color.g0 = parseInt(color0.substr(2,2),16); | |
37665 color.b0 = parseInt(color0.substr(4,2),16); | |
37666 } else { | |
37667 //if not: use the selected color "halved" | |
37668 color.r0 = Math.round(color.r1/2); | |
37669 color.g0 = Math.round(color.g1/2); | |
37670 color.b0 = Math.round(color.b1/2); | |
37671 } | |
37672 | |
37673 datasets[datasetID].color = color; | |
37674 } | |
37675 } | |
37676 } | |
37677 }); | |
37678 if (datasets.length > 0) | |
37679 dataLoaderWidget.dataLoader.distributeDatasets(datasets); | |
37680 } | |
37681 }; | |
37682 /* | |
37683 * FuzzyTimelineConfig.js | |
37684 * | |
37685 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37686 * | |
37687 * This library is free software; you can redistribute it and/or | |
37688 * modify it under the terms of the GNU Lesser General Public | |
37689 * License as published by the Free Software Foundation; either | |
37690 * version 3 of the License, or (at your option) any later version. | |
37691 * | |
37692 * This library is distributed in the hope that it will be useful, | |
37693 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37694 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37695 * Lesser General Public License for more details. | |
37696 * | |
37697 * You should have received a copy of the GNU Lesser General Public | |
37698 * License along with this library; if not, write to the Free Software | |
37699 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37700 * MA 02110-1301 USA | |
37701 */ | |
37702 | |
37703 /** | |
37704 * @class FuzzyTimelineConfig | |
37705 * FuzzyTimeline Configuration File | |
37706 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37707 */ | |
37708 function FuzzyTimelineConfig(options) { | |
37709 | |
37710 this.options = { | |
37711 proxy : 'php/proxy.php?address=', | |
37712 //TODO: experiment with number of ticks, 150 seems to be ok for now | |
37713 maxBars : 50, | |
37714 maxDensityTicks : 150, | |
37715 /*drawing modes: | |
37716 * fuzzy - weight is distributed over all spans an object overlaps, so that the sum remains the weight, | |
37717 * 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) | |
37718 */ | |
37719 timelineMode : 'stacking', | |
37720 showRangePiechart : false, | |
37721 backgroundColor : "#EEEEEE", | |
37722 showYAxis : true, | |
37723 //whether time-spans that "enlargen" the plot are allowed | |
37724 //if set to true, a span that creates more "bars" than fit on the screen | |
37725 //will lead to a width-increase of the chart (and a scroll bar appears) | |
37726 showAllPossibleSpans : true, | |
37727 }; | |
37728 if ( typeof options != 'undefined') { | |
37729 $.extend(this.options, options); | |
37730 } | |
37731 | |
37732 }; | |
37733 /* | |
37734 * FuzzyTimelineDensity.js | |
37735 * | |
37736 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
37737 * | |
37738 * This library is free software; you can redistribute it and/or | |
37739 * modify it under the terms of the GNU Lesser General Public | |
37740 * License as published by the Free Software Foundation; either | |
37741 * version 3 of the License, or (at your option) any later version. | |
37742 * | |
37743 * This library is distributed in the hope that it will be useful, | |
37744 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
37745 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
37746 * Lesser General Public License for more details. | |
37747 * | |
37748 * You should have received a copy of the GNU Lesser General Public | |
37749 * License along with this library; if not, write to the Free Software | |
37750 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
37751 * MA 02110-1301 USA | |
37752 */ | |
37753 | |
37754 /** | |
37755 * @class FuzzyTimelineDensity | |
37756 * Implementation for a fuzzy time-ranges density plot | |
37757 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
37758 * | |
37759 * @param {HTML object} parent div to append the FuzzyTimeline | |
37760 */ | |
37761 function FuzzyTimelineDensity(parent,div) { | |
37762 | |
37763 this.index; | |
37764 this.fuzzyTimeline = this; | |
37765 this.singleTickWidth; | |
37766 this.singleTickCenter = function(){return this.singleTickWidth/2;}; | |
37767 //contains all data | |
37768 this.datasetsPlot; | |
37769 this.datasetsHash; | |
37770 this.highlightedDatasetsPlot; | |
37771 this.yValMin; | |
37772 this.yValMax; | |
37773 this.displayType; | |
37774 //contains selected data | |
37775 this.selected = undefined; | |
37776 //contains the last selected "date" | |
37777 this.highlighted; | |
37778 | |
37779 this.parent = parent; | |
37780 this.div = div; | |
37781 this.options = parent.options; | |
37782 this.plot; | |
37783 this.maxTickCount = this.options.maxDensityTicks; | |
37784 | |
37785 this.datasets; | |
37786 } | |
37787 | |
37788 FuzzyTimelineDensity.prototype = { | |
37789 | |
37790 initialize : function(datasets) { | |
37791 var density = this; | |
37792 | |
37793 density.datasets = datasets; | |
37794 density.selected = []; | |
37795 }, | |
37796 | |
37797 createPlot : function(data){ | |
37798 density = this; | |
37799 var chartData = []; | |
37800 | |
37801 chartData.push([density.parent.overallMin,0]); | |
37802 $.each(data, function(name,val){ | |
37803 var tickCenterTime = density.parent.overallMin+name*density.singleTickWidth+density.singleTickCenter(); | |
37804 var dateObj = moment(tickCenterTime); | |
37805 chartData.push([dateObj,val]); | |
37806 }); | |
37807 var maxPlotedDate = chartData[chartData.length-1][0]; | |
37808 if (density.parent.overallMax > maxPlotedDate){ | |
37809 chartData.push([density.parent.overallMax,0]); | |
37810 } else { | |
37811 chartData.push([maxPlotedDate+1,0]); | |
37812 } | |
37813 | |
37814 | |
37815 | |
37816 return chartData; | |
37817 }, | |
37818 | |
37819 //uniform distribution (UD) | |
37820 createUDData : function(datasets) { | |
37821 var density = this; | |
37822 var plots = []; | |
37823 var objectHashes = []; | |
37824 $(datasets).each(function(){ | |
37825 var chartDataCounter = new Object(); | |
37826 var objectHash = new Object(); | |
37827 | |
37828 for (var i = 0; i < density.tickCount; i++){ | |
37829 chartDataCounter[i]=0; | |
37830 } | |
37831 //check if we got "real" datasets, or just array of objects | |
37832 var datasetObjects = this; | |
37833 if (typeof this.objects !== "undefined") | |
37834 datasetObjects = this.objects; | |
37835 $(datasetObjects).each(function(){ | |
37836 var ticks = density.parent.getTicks(this, density.singleTickWidth); | |
37837 if (typeof ticks !== "undefined"){ | |
37838 var exactTickCount = | |
37839 ticks.firstTickPercentage+ | |
37840 ticks.lastTickPercentage+ | |
37841 (ticks.lastTick-ticks.firstTick-1); | |
37842 for (var i = ticks.firstTick; i <= ticks.lastTick; i++){ | |
37843 var weight = 0; | |
37844 //calculate the weight for each span, that the object overlaps | |
37845 if (density.parent.options.timelineMode == 'fuzzy'){ | |
37846 //in fuzzy mode, each span gets just a fraction of the complete weight | |
37847 if (i == ticks.firstTick) | |
37848 weight = this.weight * ticks.firstTickPercentage/exactTickCount; | |
37849 else if (i == ticks.lastTick) | |
37850 weight = this.weight * ticks.lastTickPercentage/exactTickCount; | |
37851 else | |
37852 weight = this.weight * 1/exactTickCount; | |
37853 } else if (density.parent.options.timelineMode == 'stacking'){ | |
37854 //in stacking mode each span gets the same amount. | |
37855 //(besides first and last..) | |
37856 if (i == ticks.firstTick) | |
37857 weight = this.weight * ticks.firstTickPercentage; | |
37858 else if (i == ticks.lastTick) | |
37859 weight = this.weight * ticks.lastTickPercentage; | |
37860 else | |
37861 weight = this.weight; | |
37862 | |
37863 weight = this.weight; | |
37864 } | |
37865 | |
37866 chartDataCounter[i] += weight; | |
37867 //add this object to the hash | |
37868 if (typeof objectHash[i] === "undefined") | |
37869 objectHash[i] = []; | |
37870 objectHash[i].push(this); | |
37871 } | |
37872 } | |
37873 }); | |
37874 | |
37875 var udChartData = density.createPlot(chartDataCounter); | |
37876 if (udChartData.length > 0) | |
37877 plots.push(udChartData); | |
37878 | |
37879 objectHashes.push(objectHash); | |
37880 }); | |
37881 | |
37882 return {plots:plots, hashs:objectHashes}; | |
37883 }, | |
37884 | |
37885 showPlot : function() { | |
37886 var density = this; | |
37887 var plot = density.datasetsPlot; | |
37888 var highlight_select_plot = $.merge([],plot); | |
37889 | |
37890 //see if there are selected/highlighted values | |
37891 if (density.highlightedDatasetsPlot instanceof Array){ | |
37892 //check if plot is some other - external - graph | |
37893 if (plot === density.datasetsPlot) | |
37894 highlight_select_plot = $.merge(highlight_select_plot,density.highlightedDatasetsPlot); | |
37895 } | |
37896 | |
37897 var axisFormatString = "%Y"; | |
37898 var tooltipFormatString = "YYYY"; | |
37899 if (density.singleTickWidth<60*1000){ | |
37900 axisFormatString = "%Y/%m/%d %H:%M:%S"; | |
37901 tooltipFormatString = "YYYY/MM/DD HH:mm:ss"; | |
37902 } else if (density.singleTickWidth<60*60*1000) { | |
37903 axisFormatString = "%Y/%m/%d %H:%M"; | |
37904 tooltipFormatString = "YYYY/MM/DD HH:mm"; | |
37905 } else if (density.singleTickWidth<24*60*60*1000){ | |
37906 axisFormatString = "%Y/%m/%d %H"; | |
37907 tooltipFormatString = "YYYY/MM/DD HH"; | |
37908 } else if (density.singleTickWidth<31*24*60*60*1000){ | |
37909 axisFormatString = "%Y/%m/%d"; | |
37910 tooltipFormatString = "YYYY/MM/DD"; | |
37911 } else if (density.singleTickWidth<12*31*24*60*60*1000){ | |
37912 axisFormatString = "%Y/%m"; | |
37913 tooltipFormatString = "YYYY/MM"; | |
37914 } | |
37915 | |
37916 var options = { | |
37917 series:{ | |
37918 lines:{show: true} | |
37919 }, | |
37920 grid: { | |
37921 hoverable: true, | |
37922 clickable: true, | |
37923 backgroundColor: density.parent.options.backgroundColor, | |
37924 borderWidth: 0, | |
37925 minBorderMargin: 0, | |
37926 }, | |
37927 legend: { | |
37928 }, | |
37929 tooltip: true, | |
37930 tooltipOpts: { | |
37931 content: function(label, xval, yval, flotItem){ | |
37932 highlightString = moment(xval-density.singleTickCenter()).format(tooltipFormatString) + " - " + | |
37933 moment(xval+density.singleTickCenter()).format(tooltipFormatString) + " : "; | |
37934 //(max.)2 Nachkomma-Stellen von y-Wert anzeigen | |
37935 highlightString += Math.round(yval*100)/100; | |
37936 | |
37937 return highlightString; | |
37938 } | |
37939 }, | |
37940 selection: { | |
37941 mode: "x" | |
37942 }, | |
37943 xaxis: { | |
37944 mode: "time", | |
37945 timeformat:axisFormatString, | |
37946 min : density.parent.overallMin, | |
37947 max : density.parent.overallMax, | |
37948 }, | |
37949 yaxis: { | |
37950 min : density.yValMin, | |
37951 max : density.yValMax | |
37952 }, | |
37953 }; | |
37954 if (!density.parent.options.showYAxis) | |
37955 options.yaxis.show=false; | |
37956 | |
37957 var highlight_select_plot_colors = []; | |
37958 var i = 0; | |
37959 $(highlight_select_plot).each(function(){ | |
37960 var color; | |
37961 if (i < GeoTemConfig.datasets.length){ | |
37962 var datasetColors = GeoTemConfig.getColor(i); | |
37963 if (highlight_select_plot.length>GeoTemConfig.datasets.length) | |
37964 color = "rgb("+datasetColors.r0+","+datasetColors.g0+","+datasetColors.b0+")"; | |
37965 else | |
37966 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
37967 } else { | |
37968 var datasetColors = GeoTemConfig.getColor(i-GeoTemConfig.datasets.length); | |
37969 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
37970 } | |
37971 | |
37972 highlight_select_plot_colors.push({ | |
37973 color : color, | |
37974 data : this | |
37975 }); | |
37976 i++; | |
37977 }); | |
37978 | |
37979 density.plot = $.plot($(density.div), highlight_select_plot_colors, options); | |
37980 density.parent.drawHandles(); | |
37981 | |
37982 var rangeBars = density.parent.rangeBars; | |
37983 if (typeof rangeBars !== "undefined") | |
37984 $(density.div).unbind("plothover", rangeBars.hoverFunction); | |
37985 $(density.div).unbind("plothover", density.hoverFunction); | |
37986 $(density.div).bind("plothover", density.hoverFunction); | |
37987 | |
37988 //this var prevents the execution of the plotclick event after a select event | |
37989 density.wasSelection = false; | |
37990 $(density.div).unbind("plotclick"); | |
37991 $(density.div).bind("plotclick", density.clickFunction); | |
37992 | |
37993 $(density.div).unbind("plotselected"); | |
37994 $(density.div).bind("plotselected", density.selectFuntion); | |
37995 }, | |
37996 | |
37997 hoverFunction : function (event, pos, item) { | |
37998 var hoverPoint; | |
37999 //TODO: this could be wanted (if negative weight is used) | |
38000 if ((item)&&(item.datapoint[1] != 0)) { | |
38001 //at begin and end of plot there are added 0 points | |
38002 hoverPoint = item.dataIndex-1; | |
38003 } | |
38004 //remember last point, so that we don't redraw the current state | |
38005 //that "hoverPoint" may be undefined is on purpose | |
38006 if (density.highlighted !== hoverPoint){ | |
38007 density.highlighted = hoverPoint; | |
38008 density.triggerHighlight(hoverPoint); | |
38009 } | |
38010 }, | |
38011 | |
38012 clickFunction : function (event, pos, item) { | |
38013 if (density.wasSelection) | |
38014 density.wasSelection = false; | |
38015 else { | |
38016 //remove selection handles (if there were any) | |
38017 density.parent.clearHandles(); | |
38018 | |
38019 var selectPoint; | |
38020 //that date may be undefined is on purpose | |
38021 //TODO: ==0 could be wanted (if negative weight is used) | |
38022 if ((item)&&(item.datapoint[1] != 0)) { | |
38023 //at begin and end of plot there are added 0 points | |
38024 selectPoint = item.dataIndex-1; | |
38025 } | |
38026 density.triggerSelection(selectPoint); | |
38027 } | |
38028 }, | |
38029 | |
38030 selectFuntion : function(event, ranges) { | |
38031 var spanArray = density.parent.getSpanArray(density.singleTickWidth); | |
38032 var startSpan, endSpan; | |
38033 for (var i = 0; i < spanArray.length-1; i++){ | |
38034 if ((typeof startSpan === "undefined") && (ranges.xaxis.from <= spanArray[i+1])) | |
38035 startSpan = i; | |
38036 if ((typeof endSpan === "undefined") && (ranges.xaxis.to <= spanArray[i+1])) | |
38037 endSpan = i; | |
38038 } | |
38039 | |
38040 if ((typeof startSpan !== "undefined") && (typeof endSpan !== "undefined")){ | |
38041 density.triggerSelection(startSpan, endSpan); | |
38042 density.wasSelection = true; | |
38043 | |
38044 density.parent.clearHandles(); | |
38045 var xaxis = density.plot.getAxes().xaxis; | |
38046 var x1 = density.plot.pointOffset({x:ranges.xaxis.from,y:0}).left; | |
38047 var x2 = density.plot.pointOffset({x:ranges.xaxis.to,y:0}).left; | |
38048 | |
38049 density.parent.addHandle(x1,x2); | |
38050 } | |
38051 }, | |
38052 | |
38053 selectByX : function(x1, x2){ | |
38054 density = this; | |
38055 var xaxis = density.plot.getAxes().xaxis; | |
38056 var offset = density.plot.getPlotOffset().left; | |
38057 var from = xaxis.c2p(x1-offset); | |
38058 var to = xaxis.c2p(x2-offset); | |
38059 | |
38060 var spanArray = density.parent.getSpanArray(density.singleTickWidth); | |
38061 var startSpan, endSpan; | |
38062 for (var i = 0; i < spanArray.length-1; i++){ | |
38063 if ((typeof startSpan === "undefined") && (from <= spanArray[i+1])) | |
38064 startSpan = i; | |
38065 if ((typeof endSpan === "undefined") && (to <= spanArray[i+1])) | |
38066 endSpan = i; | |
38067 } | |
38068 | |
38069 if ((typeof startSpan !== "undefined") && (typeof endSpan !== "undefined")){ | |
38070 density.triggerSelection(startSpan, endSpan); | |
38071 } | |
38072 }, | |
38073 | |
38074 drawDensityPlot : function(datasets, tickWidth) { | |
38075 var density = this; | |
38076 //calculate tick width (will be in ms) | |
38077 delete density.tickCount; | |
38078 delete density.singleTickWidth; | |
38079 delete density.highlightedDatasetsPlot; | |
38080 density.parent.zoomPlot(1); | |
38081 if (typeof tickWidth !== "undefined"){ | |
38082 density.singleTickWidth = tickWidth; | |
38083 density.tickCount = Math.ceil((density.parent.overallMax-density.parent.overallMin)/tickWidth); | |
38084 } | |
38085 if ((typeof density.tickCount === "undefined") || (density.tickCount > density.maxTickCount)){ | |
38086 density.tickCount = density.maxTickCount; | |
38087 density.singleTickWidth = (density.parent.overallMax-density.parent.overallMin)/density.tickCount; | |
38088 if (density.singleTickWidth === 0) | |
38089 density.singleTickWidth = 1; | |
38090 } | |
38091 | |
38092 var hashAndPlot = density.createUDData(datasets); | |
38093 | |
38094 density.datasetsPlot = hashAndPlot.plots; | |
38095 density.datasetsHash = hashAndPlot.hashs; | |
38096 | |
38097 density.yValMin = 0; | |
38098 density.yValMax = 0; | |
38099 | |
38100 density.combinedDatasetsPlot = []; | |
38101 for (var i = 0; i < density.datasetsPlot.length; i++){ | |
38102 for (var j = 0; j < density.datasetsPlot[i].length; j++){ | |
38103 var val = density.datasetsPlot[i][j][1]; | |
38104 | |
38105 if (val < density.yValMin) | |
38106 density.yValMin = val; | |
38107 if (val > density.yValMax) | |
38108 density.yValMax = val; | |
38109 } | |
38110 } | |
38111 | |
38112 density.showPlot(); | |
38113 }, | |
38114 | |
38115 triggerHighlight : function(hoverPoint) { | |
38116 var density = this; | |
38117 var highlightedObjects = []; | |
38118 | |
38119 | |
38120 if (typeof hoverPoint !== "undefined") { | |
38121 $(density.datasetsHash).each(function(){ | |
38122 if (typeof this[hoverPoint] !== "undefined") | |
38123 highlightedObjects.push(this[hoverPoint]); | |
38124 else | |
38125 highlightedObjects.push([]); | |
38126 }); | |
38127 } else { | |
38128 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
38129 highlightedObjects.push([]); | |
38130 } | |
38131 this.parent.core.triggerHighlight(highlightedObjects); | |
38132 }, | |
38133 | |
38134 triggerSelection : function(startPoint, endPoint) { | |
38135 var density = this; | |
38136 var selection; | |
38137 if (typeof startPoint !== "undefined") { | |
38138 if (typeof endPoint === "undefined") | |
38139 endPoint = startPoint; | |
38140 density.selected = []; | |
38141 $(density.datasetsHash).each(function(){ | |
38142 var objects = []; | |
38143 for (var i = startPoint; i <= endPoint; i++){ | |
38144 $(this[i]).each(function(){ | |
38145 if ($.inArray(this, objects) == -1){ | |
38146 objects.push(this); | |
38147 } | |
38148 }); | |
38149 } | |
38150 density.selected.push(objects); | |
38151 }); | |
38152 | |
38153 selection = new Selection(density.selected, density.parent); | |
38154 } else { | |
38155 //empty selection | |
38156 density.selected = []; | |
38157 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
38158 density.selected.push([]); | |
38159 selection = new Selection(density.selected); | |
38160 } | |
38161 | |
38162 this.parent.selectionChanged(selection); | |
38163 this.parent.core.triggerSelection(selection); | |
38164 }, | |
38165 | |
38166 highlightChanged : function(objects) { | |
38167 if( !GeoTemConfig.highlightEvents ){ | |
38168 return; | |
38169 } | |
38170 var density = this; | |
38171 var emptyHighlight = true; | |
38172 var selected_highlighted = objects; | |
38173 if (typeof density.selected !== "undefined") | |
38174 selected_highlighted = GeoTemConfig.mergeObjects(objects,density.selected); | |
38175 $(selected_highlighted).each(function(){ | |
38176 if ((this instanceof Array) && (this.length > 0)){ | |
38177 emptyHighlight = false; | |
38178 return false; | |
38179 } | |
38180 }); | |
38181 if (emptyHighlight && (typeof density.selected === "undefined")){ | |
38182 density.highlightedDatasetsPlot = []; | |
38183 } else { | |
38184 density.highlightedDatasetsPlot = density.createUDData(selected_highlighted).plots; | |
38185 } | |
38186 density.showPlot(); | |
38187 }, | |
38188 | |
38189 selectionChanged : function(objects) { | |
38190 if( !GeoTemConfig.selectionEvents ){ | |
38191 return; | |
38192 } | |
38193 var density = this; | |
38194 density.selected = objects; | |
38195 density.highlightChanged([]); | |
38196 }, | |
38197 | |
38198 deselection : function() { | |
38199 }, | |
38200 | |
38201 filtering : function() { | |
38202 }, | |
38203 | |
38204 inverseFiltering : function() { | |
38205 }, | |
38206 | |
38207 triggerRefining : function() { | |
38208 }, | |
38209 | |
38210 reset : function() { | |
38211 }, | |
38212 | |
38213 show : function() { | |
38214 }, | |
38215 | |
38216 hide : function() { | |
38217 } | |
38218 }; | |
38219 /* | |
38220 * FuzzyTimelineGui.js | |
38221 * | |
38222 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38223 * | |
38224 * This library is free software; you can redistribute it and/or | |
38225 * modify it under the terms of the GNU Lesser General Public | |
38226 * License as published by the Free Software Foundation; either | |
38227 * version 3 of the License, or (at your option) any later version. | |
38228 * | |
38229 * This library is distributed in the hope that it will be useful, | |
38230 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38231 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38232 * Lesser General Public License for more details. | |
38233 * | |
38234 * You should have received a copy of the GNU Lesser General Public | |
38235 * License along with this library; if not, write to the Free Software | |
38236 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38237 * MA 02110-1301 USA | |
38238 */ | |
38239 | |
38240 /** | |
38241 * @class FuzzyTimelineGui | |
38242 * FuzzyTimeline GUI Implementation | |
38243 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38244 * | |
38245 * @param {FuzzyTimelineWidget} parent FuzzyTimeline widget object | |
38246 * @param {HTML object} div parent div to append the FuzzyTimeline gui | |
38247 * @param {JSON} options FuzzyTimeline configuration | |
38248 */ | |
38249 function FuzzyTimelineGui(fuzzyTimelineWidget, div, options) { | |
38250 | |
38251 this.parent = fuzzyTimelineWidget; | |
38252 var fuzzyTimelineGui = this; | |
38253 | |
38254 this.fuzzyTimelineContainer = div; | |
38255 //if no height is given, draw it in a 32/9 ratio | |
38256 if ($(this.fuzzyTimelineContainer).height() === 0) | |
38257 $(this.fuzzyTimelineContainer).height($(this.fuzzyTimelineContainer).width()*9/32); | |
38258 //this.fuzzyTimelineContainer.style.position = 'relative'; | |
38259 | |
38260 this.sliderTable = document.createElement("table"); | |
38261 $(this.sliderTable).addClass("ddbToolbar"); | |
38262 $(this.sliderTable).width("100%"); | |
38263 $(this.sliderTable).height("49px"); | |
38264 div.appendChild(this.sliderTable); | |
38265 | |
38266 this.plotDIVHeight = $(this.fuzzyTimelineContainer).height()-$(this.sliderTable).height(); | |
38267 var plotScrollContainer = $("<div></div>"); | |
38268 plotScrollContainer.css("overflow-x","auto"); | |
38269 plotScrollContainer.css("overflow-y","hidden"); | |
38270 plotScrollContainer.width("100%"); | |
38271 plotScrollContainer.height(this.plotDIVHeight); | |
38272 $(div).append(plotScrollContainer); | |
38273 this.plotDiv = document.createElement("div"); | |
38274 $(this.plotDiv).width("100%"); | |
38275 $(this.plotDiv).height(this.plotDIVHeight); | |
38276 plotScrollContainer.append(this.plotDiv); | |
38277 if (this.parent.options.showRangePiechart){ | |
38278 this.rangePiechartDiv = document.createElement("div"); | |
38279 $(this.rangePiechartDiv).css("float","right"); | |
38280 //alter plot div width (leave space for piechart) | |
38281 $(this.plotDiv).width("75%"); | |
38282 $(this.rangePiechartDiv).width("25%"); | |
38283 $(this.rangePiechartDiv).height(plotDIVHeight); | |
38284 div.appendChild(this.rangePiechartDiv); | |
38285 } | |
38286 }; | |
38287 | |
38288 FuzzyTimelineGui.prototype = { | |
38289 }; | |
38290 /* | |
38291 * FuzzyTimelineRangeBars.js | |
38292 * | |
38293 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38294 * | |
38295 * This library is free software; you can redistribute it and/or | |
38296 * modify it under the terms of the GNU Lesser General Public | |
38297 * License as published by the Free Software Foundation; either | |
38298 * version 3 of the License, or (at your option) any later version. | |
38299 * | |
38300 * This library is distributed in the hope that it will be useful, | |
38301 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38302 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38303 * Lesser General Public License for more details. | |
38304 * | |
38305 * You should have received a copy of the GNU Lesser General Public | |
38306 * License along with this library; if not, write to the Free Software | |
38307 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38308 * MA 02110-1301 USA | |
38309 */ | |
38310 | |
38311 /** | |
38312 * @class FuzzyTimelineRangeBars | |
38313 * Implementation for a fuzzy time-ranges barchart | |
38314 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38315 * | |
38316 * @param {HTML object} parent div to append the FuzzyTimeline | |
38317 */ | |
38318 function FuzzyTimelineRangeBars(parent) { | |
38319 | |
38320 this.rangeBars = this; | |
38321 | |
38322 this.parent = parent; | |
38323 this.options = parent.options; | |
38324 | |
38325 this.datasets; | |
38326 //contains selected data | |
38327 this.selected = undefined; | |
38328 | |
38329 this.datasetsPlot; | |
38330 this.highlightedDatasetsPlot; | |
38331 this.yValMin; | |
38332 this.yValMax; | |
38333 this.displayType; | |
38334 | |
38335 this.plotDiv = this.parent.gui.plotDiv; | |
38336 | |
38337 this.spanWidth; | |
38338 this.tickSpans; | |
38339 this.plot; | |
38340 } | |
38341 | |
38342 FuzzyTimelineRangeBars.prototype = { | |
38343 | |
38344 initialize : function(datasets) { | |
38345 var rangeBar = this; | |
38346 | |
38347 rangeBar.datasets = datasets; | |
38348 rangeBar.selected = []; | |
38349 }, | |
38350 | |
38351 createPlot : function(datasets) { | |
38352 var rangeBar = this; | |
38353 var plots = []; | |
38354 var objectHashes = []; | |
38355 | |
38356 //-1 because last span is always empty (only there to have the ending date) | |
38357 var tickCount = rangeBar.tickSpans.length-1; | |
38358 | |
38359 $(datasets).each(function(){ | |
38360 var chartDataCounter = []; | |
38361 var objectHash = new Object(); | |
38362 | |
38363 for (var i = 0; i < tickCount; i++){ | |
38364 chartDataCounter[i] = []; | |
38365 chartDataCounter[i][0]=i; | |
38366 chartDataCounter[i][1]=0; | |
38367 } | |
38368 //check if we got "real" datasets, or just array of objects | |
38369 var datasetObjects = this; | |
38370 if (typeof this.objects !== "undefined") | |
38371 datasetObjects = this.objects; | |
38372 $(datasetObjects).each(function(){ | |
38373 var ticks = rangeBar.parent.getTicks(this, rangeBar.spanWidth); | |
38374 if (typeof ticks !== "undefined"){ | |
38375 var exactTickCount = | |
38376 ticks.firstTickPercentage+ | |
38377 ticks.lastTickPercentage+ | |
38378 (ticks.lastTick-ticks.firstTick-1); | |
38379 for (var i = ticks.firstTick; i <= ticks.lastTick; i++){ | |
38380 var weight = 0; | |
38381 //calculate the weight for each span, that the object overlaps | |
38382 if (rangeBar.parent.options.timelineMode == 'fuzzy'){ | |
38383 //in fuzzy mode, each span gets just a fraction of the complete weight | |
38384 if (i == ticks.firstTick) | |
38385 weight = this.weight * ticks.firstTickPercentage/exactTickCount; | |
38386 else if (i == ticks.lastTick) | |
38387 weight = this.weight * ticks.lastTickPercentage/exactTickCount; | |
38388 else | |
38389 weight = this.weight * 1/exactTickCount; | |
38390 } else if (rangeBar.parent.options.timelineMode == 'stacking'){ | |
38391 //in stacking mode each span gets the same amount. | |
38392 //(besides first and last..) | |
38393 if (i == ticks.firstTick) | |
38394 weight = this.weight * ticks.firstTickPercentage; | |
38395 else if (i == ticks.lastTick) | |
38396 weight = this.weight * ticks.lastTickPercentage; | |
38397 else | |
38398 weight = this.weight; | |
38399 | |
38400 weight = this.weight; | |
38401 } | |
38402 | |
38403 chartDataCounter[i][1] += weight; | |
38404 //add this object to the hash | |
38405 if (typeof objectHash[i] === "undefined") | |
38406 objectHash[i] = []; | |
38407 objectHash[i].push(this); | |
38408 } | |
38409 } | |
38410 }); | |
38411 | |
38412 plots.push(chartDataCounter); | |
38413 objectHashes.push(objectHash); | |
38414 }); | |
38415 | |
38416 return {plots:plots, hashs:objectHashes}; | |
38417 }, | |
38418 | |
38419 showPlot : function(){ | |
38420 var rangeBar = this; | |
38421 var plot = rangeBar.datasetsPlot; | |
38422 var highlight_select_plot = $.merge([],plot); | |
38423 | |
38424 //see if there are selected/highlighted values | |
38425 if (rangeBar.highlightedDatasetsPlot instanceof Array){ | |
38426 //check if plot is some other - external - graph | |
38427 if (plot === rangeBar.datasetsPlot) | |
38428 highlight_select_plot = $.merge(highlight_select_plot,rangeBar.highlightedDatasetsPlot); | |
38429 } | |
38430 | |
38431 var tickCount = rangeBar.tickSpans.length-1; | |
38432 var ticks = []; | |
38433 | |
38434 var axisFormatString = "YYYY"; | |
38435 if (rangeBar.spanWidth<60*1000){ | |
38436 axisFormatString = "YYYY/MM/DD HH:mm:ss"; | |
38437 } else if (rangeBar.spanWidth<60*60*1000) { | |
38438 axisFormatString = "YYYY/MM/DD HH:mm"; | |
38439 } else if (rangeBar.spanWidth<24*60*60*1000){ | |
38440 axisFormatString = "YYYY/MM/DD HH"; | |
38441 } else if (rangeBar.spanWidth<31*24*60*60*1000){ | |
38442 axisFormatString = "YYYY/MM/DD"; | |
38443 } else if (rangeBar.spanWidth<12*31*24*60*60*1000){ | |
38444 axisFormatString = "YYYY/MM"; | |
38445 } | |
38446 //only show ~10 labels on the x-Axis (increase if zoomed) | |
38447 var labelModulo = Math.ceil(tickCount/(10*rangeBar.parent.zoomFactor)); | |
38448 for (var i = 0; i < tickCount; i++){ | |
38449 var tickLabel = ""; | |
38450 if (i%labelModulo==0){ | |
38451 tickLabel = rangeBar.tickSpans[i].format(axisFormatString); | |
38452 } | |
38453 while ((tickLabel.length > 1) && (tickLabel.indexOf("0")==0)) | |
38454 tickLabel = tickLabel.substring(1); | |
38455 ticks[i] = [i,tickLabel]; | |
38456 } | |
38457 | |
38458 var options = { | |
38459 series:{ | |
38460 bars:{show: true} | |
38461 }, | |
38462 grid: { | |
38463 hoverable: true, | |
38464 clickable: true, | |
38465 backgroundColor: rangeBar.parent.options.backgroundColor, | |
38466 borderWidth: 0, | |
38467 minBorderMargin: 0, | |
38468 }, | |
38469 xaxis: { | |
38470 ticks: ticks, | |
38471 min : 0, | |
38472 max : tickCount, | |
38473 }, | |
38474 yaxis: { | |
38475 min : rangeBar.yValMin, | |
38476 max : rangeBar.yValMax | |
38477 }, | |
38478 tooltip: true, | |
38479 tooltipOpts: { | |
38480 content: function(label, xval, yval, flotItem){ | |
38481 var fromLabel = rangeBar.tickSpans[xval].format(axisFormatString); | |
38482 while ((fromLabel.length > 1) && (fromLabel.indexOf("0")==0)) | |
38483 fromLabel = fromLabel.substring(1); | |
38484 var toLabel = rangeBar.tickSpans[xval+1].clone().subtract("ms",1).format(axisFormatString); | |
38485 while ((toLabel.length > 1) && (toLabel.indexOf("0")==0)) | |
38486 toLabel = toLabel.substring(1); | |
38487 highlightString = fromLabel + " - " + toLabel + " : "; | |
38488 //(max.)2 Nachkomma-Stellen von y-Wert anzeigen | |
38489 highlightString += Math.round(yval*100)/100; | |
38490 | |
38491 return highlightString; | |
38492 } | |
38493 }, | |
38494 selection: { | |
38495 mode: "x" | |
38496 } | |
38497 }; | |
38498 if (!rangeBar.parent.options.showYAxis) | |
38499 options.yaxis.show=false; | |
38500 | |
38501 var highlight_select_plot_colors = []; | |
38502 var i = 0; | |
38503 $(highlight_select_plot).each(function(){ | |
38504 var color; | |
38505 if (i < GeoTemConfig.datasets.length){ | |
38506 var datasetColors = GeoTemConfig.getColor(i); | |
38507 if (highlight_select_plot.length>GeoTemConfig.datasets.length) | |
38508 color = "rgb("+datasetColors.r0+","+datasetColors.g0+","+datasetColors.b0+")"; | |
38509 else | |
38510 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
38511 } else { | |
38512 var datasetColors = GeoTemConfig.getColor(i-GeoTemConfig.datasets.length); | |
38513 color = "rgb("+datasetColors.r1+","+datasetColors.g1+","+datasetColors.b1+")"; | |
38514 } | |
38515 | |
38516 highlight_select_plot_colors.push({ | |
38517 color : color, | |
38518 data : this | |
38519 }); | |
38520 i++; | |
38521 }); | |
38522 | |
38523 $(rangeBar.plotDiv).unbind(); | |
38524 rangeBar.plot = $.plot($(rangeBar.plotDiv), highlight_select_plot_colors, options); | |
38525 rangeBar.parent.drawHandles(); | |
38526 | |
38527 var density = rangeBar.parent.density; | |
38528 if (typeof density !== "undefined") | |
38529 $(rangeBar.plotDiv).unbind("plothover", density.hoverFunction); | |
38530 $(rangeBar.plotDiv).unbind("plothover", rangeBar.hoverFunction); | |
38531 $(rangeBar.plotDiv).bind("plothover", $.proxy(rangeBar.hoverFunction,rangeBar)); | |
38532 | |
38533 //this var prevents the execution of the plotclick event after a select event | |
38534 rangeBar.wasSelection = false; | |
38535 $(rangeBar.plotDiv).unbind("plotclick"); | |
38536 $(rangeBar.plotDiv).bind("plotclick", $.proxy(rangeBar.clickFunction,rangeBar)); | |
38537 | |
38538 $(rangeBar.plotDiv).unbind("plotselected"); | |
38539 $(rangeBar.plotDiv).bind("plotselected", $.proxy(rangeBar.selectFunction,rangeBar)); | |
38540 }, | |
38541 | |
38542 hoverFunction : function (event, pos, item) { | |
38543 var rangeBar = this; | |
38544 var hoverBar; | |
38545 var spans; | |
38546 if (item) { | |
38547 hoverBar = item.datapoint[0]; | |
38548 } | |
38549 //remember last date, so that we don't redraw the current state | |
38550 //that date may be undefined is on purpose | |
38551 if (rangeBar.highlighted !== hoverBar){ | |
38552 rangeBar.highlighted = hoverBar; | |
38553 if (typeof hoverBar === "undefined") | |
38554 rangeBar.triggerHighlight(); | |
38555 else | |
38556 rangeBar.triggerHighlight(hoverBar); | |
38557 } | |
38558 }, | |
38559 | |
38560 clickFunction : function (event, pos, item) { | |
38561 var rangeBar = this; | |
38562 if (rangeBar.wasSelection) | |
38563 rangeBar.wasSelection = false; | |
38564 else { | |
38565 //remove selection handles (if there were any) | |
38566 rangeBar.parent.clearHandles(); | |
38567 | |
38568 var clickBar; | |
38569 if (item) { | |
38570 //contains the x-value (date) | |
38571 clickBar = item.datapoint[0]; | |
38572 } | |
38573 if (typeof clickBar === "undefined") | |
38574 rangeBar.triggerSelection(); | |
38575 else | |
38576 rangeBar.triggerSelection(clickBar); | |
38577 wasDataClick = true; | |
38578 } | |
38579 }, | |
38580 | |
38581 selectFunction : function(event, ranges) { | |
38582 var rangeBar = this; | |
38583 startBar = Math.floor(ranges.xaxis.from); | |
38584 endBar = Math.floor(ranges.xaxis.to); | |
38585 rangeBar.triggerSelection(startBar, endBar); | |
38586 rangeBar.wasSelection = true; | |
38587 | |
38588 rangeBar.parent.clearHandles(); | |
38589 var xaxis = rangeBar.plot.getAxes().xaxis; | |
38590 var x1 = rangeBar.plot.pointOffset({x:ranges.xaxis.from,y:0}).left; | |
38591 var x2 = rangeBar.plot.pointOffset({x:ranges.xaxis.to,y:0}).left; | |
38592 rangeBar.parent.addHandle(x1,x2); | |
38593 }, | |
38594 | |
38595 selectByX : function(x1, x2){ | |
38596 rangeBar = this; | |
38597 var xaxis = rangeBar.plot.getAxes().xaxis; | |
38598 var offset = rangeBar.plot.getPlotOffset().left; | |
38599 var from = Math.floor(xaxis.c2p(x1-offset)); | |
38600 var to = Math.floor(xaxis.c2p(x2-offset)); | |
38601 | |
38602 rangeBar.triggerSelection(from, to); | |
38603 }, | |
38604 | |
38605 drawRangeBarChart : function(datasets, spanWidth){ | |
38606 var rangeBar = this; | |
38607 rangeBar.spanWidth = spanWidth; | |
38608 rangeBar.tickSpans = rangeBar.parent.getSpanArray(rangeBar.spanWidth); | |
38609 //-1 because last span is always empty (only there to have the ending date) | |
38610 var tickCount = rangeBar.tickSpans.length-1; | |
38611 | |
38612 if (tickCount > rangeBar.options.maxBars){ | |
38613 var zoomFactor = tickCount / rangeBar.options.maxBars; | |
38614 rangeBar.parent.zoomPlot(zoomFactor); | |
38615 } else | |
38616 rangeBar.parent.zoomPlot(1); | |
38617 | |
38618 rangeBar.yValMin = 0; | |
38619 rangeBar.yValMax = 0; | |
38620 | |
38621 var plotAndHash = rangeBar.createPlot(datasets); | |
38622 rangeBar.datasetsPlot = plotAndHash.plots; | |
38623 rangeBar.datasetsHash = plotAndHash.hashs; | |
38624 delete rangeBar.highlightedDatasetsPlot; | |
38625 //redraw selected plot to fit (possible) new scale | |
38626 rangeBar.selectionChanged(rangeBar.selected); | |
38627 | |
38628 for (var i = 0; i < rangeBar.datasetsPlot.length; i++){ | |
38629 for (var j = 0; j < rangeBar.datasetsPlot[i].length; j++){ | |
38630 var val = rangeBar.datasetsPlot[i][j][1]; | |
38631 | |
38632 if (val < rangeBar.yValMin) | |
38633 rangeBar.yValMin = val; | |
38634 if (val > rangeBar.yValMax) | |
38635 rangeBar.yValMax = val; | |
38636 } | |
38637 } | |
38638 | |
38639 rangeBar.showPlot(); | |
38640 }, | |
38641 | |
38642 highlightChanged : function(objects) { | |
38643 if( !GeoTemConfig.highlightEvents ){ | |
38644 return; | |
38645 } | |
38646 var rangeBar = this; | |
38647 var emptyHighlight = true; | |
38648 var selected_highlighted = objects; | |
38649 if (typeof rangeBar.selected !== "undefined") | |
38650 var selected_highlighted = GeoTemConfig.mergeObjects(objects,rangeBar.selected); | |
38651 $(selected_highlighted).each(function(){ | |
38652 if ((this instanceof Array) && (this.length > 0)){ | |
38653 emptyHighlight = false; | |
38654 return false; | |
38655 } | |
38656 }); | |
38657 if (emptyHighlight && (typeof rangeBar.selected === "undefined")){ | |
38658 rangeBar.highlightedDatasetsPlot = []; | |
38659 } else { | |
38660 rangeBar.highlightedDatasetsPlot = rangeBar.createPlot(selected_highlighted).plots; | |
38661 } | |
38662 rangeBar.showPlot(); | |
38663 }, | |
38664 | |
38665 selectionChanged : function(objects) { | |
38666 if( !GeoTemConfig.selectionEvents ){ | |
38667 return; | |
38668 } | |
38669 var rangeBar = this; | |
38670 rangeBar.selected = objects; | |
38671 rangeBar.highlightChanged([]); | |
38672 }, | |
38673 | |
38674 triggerHighlight : function(hoverPoint) { | |
38675 var rangeBar = this; | |
38676 var highlightedObjects = []; | |
38677 | |
38678 if (typeof hoverPoint !== "undefined"){ | |
38679 $(rangeBar.datasetsHash).each(function(){ | |
38680 if (typeof this[hoverPoint] !== "undefined") | |
38681 highlightedObjects.push(this[hoverPoint]); | |
38682 else | |
38683 highlightedObjects.push([]); | |
38684 }); | |
38685 } else { | |
38686 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
38687 highlightedObjects.push([]); | |
38688 } | |
38689 | |
38690 this.parent.core.triggerHighlight(highlightedObjects); | |
38691 }, | |
38692 | |
38693 triggerSelection : function(startBar, endBar) { | |
38694 var rangeBar = this; | |
38695 var selection; | |
38696 if (typeof startBar !== "undefined") { | |
38697 if (typeof endBar === "undefined") | |
38698 endBar = startBar; | |
38699 rangeBar.selected = []; | |
38700 $(rangeBar.datasetsHash).each(function(){ | |
38701 var objects = []; | |
38702 for (var i = startBar; i <= endBar; i++){ | |
38703 $(this[i]).each(function(){ | |
38704 if ($.inArray(this, objects) == -1){ | |
38705 objects.push(this); | |
38706 } | |
38707 }); | |
38708 } | |
38709 rangeBar.selected.push(objects); | |
38710 }); | |
38711 selection = new Selection(rangeBar.selected, rangeBar.parent); | |
38712 } else { | |
38713 rangeBar.selected = []; | |
38714 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
38715 rangeBar.selected.push([]); | |
38716 selection = new Selection(rangeBar.selected); | |
38717 } | |
38718 | |
38719 rangeBar.parent.selectionChanged(selection); | |
38720 rangeBar.parent.core.triggerSelection(selection); | |
38721 }, | |
38722 | |
38723 deselection : function() { | |
38724 }, | |
38725 | |
38726 filtering : function() { | |
38727 }, | |
38728 | |
38729 inverseFiltering : function() { | |
38730 }, | |
38731 | |
38732 triggerRefining : function() { | |
38733 }, | |
38734 | |
38735 reset : function() { | |
38736 }, | |
38737 | |
38738 show : function() { | |
38739 }, | |
38740 | |
38741 hide : function() { | |
38742 } | |
38743 }; | |
38744 /* | |
38745 * FuzzyTimelineRangePiechart.js | |
38746 * | |
38747 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
38748 * | |
38749 * This library is free software; you can redistribute it and/or | |
38750 * modify it under the terms of the GNU Lesser General Public | |
38751 * License as published by the Free Software Foundation; either | |
38752 * version 3 of the License, or (at your option) any later version. | |
38753 * | |
38754 * This library is distributed in the hope that it will be useful, | |
38755 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
38756 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
38757 * Lesser General Public License for more details. | |
38758 * | |
38759 * You should have received a copy of the GNU Lesser General Public | |
38760 * License along with this library; if not, write to the Free Software | |
38761 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
38762 * MA 02110-1301 USA | |
38763 */ | |
38764 | |
38765 /** | |
38766 * @class FuzzyTimelineRangePiechart | |
38767 * Implementation for a fuzzy time-ranges pie chart | |
38768 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
38769 * | |
38770 * @param {HTML object} parent div to append the FuzzyTimeline | |
38771 */ | |
38772 function FuzzyTimelineRangePiechart(parent,div) { | |
38773 | |
38774 this.fuzzyTimeline = this; | |
38775 | |
38776 this.parent = parent; | |
38777 this.options = parent.options; | |
38778 | |
38779 this.div = div; | |
38780 | |
38781 this.selected = []; | |
38782 | |
38783 this.maxSlices = 10; | |
38784 } | |
38785 | |
38786 FuzzyTimelineRangePiechart.prototype = { | |
38787 | |
38788 initialize : function(datasets) { | |
38789 var piechart = this; | |
38790 if (piechart.parent.showRangePiechart){ | |
38791 piechart.datasets = datasets; | |
38792 piechart.drawPieChart(piechart.datasets); | |
38793 } | |
38794 }, | |
38795 | |
38796 drawPieChart : function(datasets){ | |
38797 var piechart = this; | |
38798 //build hashmap of spans (span length -> objects[]) | |
38799 var spans = []; | |
38800 var index = 0; | |
38801 $(datasets).each(function(){ | |
38802 var objects = this; | |
38803 //check whether we got "real" dataset or just a set of DataObjects | |
38804 if (typeof objects.objects !== "undefined") | |
38805 objects = objects.objects; | |
38806 $(objects).each(function(){ | |
38807 var dataObject = this; | |
38808 var span; | |
38809 if (dataObject.isTemporal){ | |
38810 span = SimileAjax.DateTime.MILLISECOND; | |
38811 } else if (dataObject.isFuzzyTemporal){ | |
38812 span = dataObject.TimeSpanGranularity; | |
38813 } | |
38814 | |
38815 if (typeof span === "undefined") | |
38816 return; | |
38817 | |
38818 var found = false; | |
38819 $(spans).each(function(){ | |
38820 if (this.span === span){ | |
38821 this.objects[index].push(dataObject); | |
38822 found = true; | |
38823 return false; | |
38824 } | |
38825 }); | |
38826 if (found === false){ | |
38827 var newObjectSet = []; | |
38828 for (var i = 0; i < piechart.datasets.length; i++) | |
38829 newObjectSet.push([]); | |
38830 newObjectSet[index].push(dataObject); | |
38831 spans.push({span:span,objects:newObjectSet}); | |
38832 } | |
38833 }); | |
38834 index++; | |
38835 }); | |
38836 | |
38837 //TODO: join elements of span array to keep below certain threshold | |
38838 | |
38839 //sort array by span length | |
38840 spans.sort(function(a,b){ | |
38841 return(a.span-b.span); | |
38842 }); | |
38843 | |
38844 //create chart data | |
38845 var chartData = []; | |
38846 $(spans).each(function(){ | |
38847 var spanElem = this; | |
38848 $(spanElem.objects).each(function(){ | |
38849 var label = "unknown"; | |
38850 | |
38851 if (spanElem.span === SimileAjax.DateTime.MILLENNIUM){ | |
38852 label = "millenia"; | |
38853 } else if (spanElem.span === SimileAjax.DateTime.DECADE){ | |
38854 label = "decades"; | |
38855 } else if (spanElem.span === SimileAjax.DateTime.CENTURY){ | |
38856 label = "centuries"; | |
38857 } else if (spanElem.span === SimileAjax.DateTime.YEAR){ | |
38858 label = "years"; | |
38859 } else if (spanElem.span === SimileAjax.DateTime.MONTH){ | |
38860 label = "months"; | |
38861 } else if (spanElem.span === SimileAjax.DateTime.DAY){ | |
38862 label = "days"; | |
38863 } else if (spanElem.span === SimileAjax.DateTime.HOUR){ | |
38864 label = "hours"; | |
38865 } else if (spanElem.span === SimileAjax.DateTime.MINUTE){ | |
38866 label = "minutes"; | |
38867 } else if (spanElem.span === SimileAjax.DateTime.SECOND){ | |
38868 label = "seconds"; | |
38869 } else if (spanElem.span === SimileAjax.DateTime.MILLISECOND){ | |
38870 label = "milliseconds"; | |
38871 } | |
38872 | |
38873 chartData.push({label:label,data:this.length}); | |
38874 }); | |
38875 }); | |
38876 | |
38877 $(piechart.div).unbind("plotclick"); | |
38878 $(piechart.div).unbind("plothover"); | |
38879 $(piechart.div).empty(); | |
38880 if (spans.length === 0){ | |
38881 //TODO: language specific message | |
38882 $(piechart.div).append("empty selection"); | |
38883 } else { | |
38884 $.plot($(piechart.div), chartData, | |
38885 { | |
38886 series: { | |
38887 // Make this a pie chart. | |
38888 pie: { | |
38889 show:true | |
38890 } | |
38891 }, | |
38892 legend: { show:false}, | |
38893 grid: { | |
38894 hoverable: true, | |
38895 clickable: true | |
38896 }, | |
38897 tooltip: true, | |
38898 } | |
38899 ); | |
38900 | |
38901 var lastHighlighted; | |
38902 var hoverFunction = function (event, pos, item) { | |
38903 if (item) { | |
38904 var highlightedSpan = Math.ceil(item.seriesIndex/piechart.datasets.length); | |
38905 if (lastHighlighted !== highlightedSpan){ | |
38906 var highlightedObjects = []; | |
38907 for(;highlightedSpan>=0;highlightedSpan--){ | |
38908 highlightedObjects = GeoTemConfig.mergeObjects(highlightedObjects,spans[highlightedSpan].objects); | |
38909 } | |
38910 lastHighlighted = highlightedSpan; | |
38911 } | |
38912 piechart.triggerHighlight(highlightedObjects); | |
38913 } else { | |
38914 piechart.triggerHighlight([]); | |
38915 } | |
38916 }; | |
38917 $(piechart.div).bind("plothover", hoverFunction); | |
38918 | |
38919 $(piechart.div).bind("plotclick", function (event, pos, item) { | |
38920 $(piechart.div).unbind("plothover"); | |
38921 if (item){ | |
38922 var selectedSpan = Math.ceil(item.seriesIndex/piechart.datasets.length); | |
38923 var selectedObjects = []; | |
38924 for(;selectedSpan>=0;selectedSpan--){ | |
38925 selectedObjects = GeoTemConfig.mergeObjects(selectedObjects,spans[selectedSpan].objects); | |
38926 } | |
38927 piechart.triggerSelection(selectedObjects); | |
38928 } else { | |
38929 //if it was a click outside of the pie-chart, enable highlight events | |
38930 $(piechart.div).bind("plothover", hoverFunction); | |
38931 //return to old state | |
38932 piechart.triggerSelection(piechart.selected); | |
38933 //and redraw piechart | |
38934 piechart.highlightChanged([]); | |
38935 } | |
38936 }); | |
38937 } | |
38938 }, | |
38939 | |
38940 highlightChanged : function(objects) { | |
38941 var piechart = this; | |
38942 if (piechart.parent.showRangePiechart){ | |
38943 //check if this is an empty highlight | |
38944 var emptyHighlight = true; | |
38945 $(objects).each(function(){ | |
38946 if ((this instanceof Array) && (this.length > 0)){ | |
38947 emptyHighlight = false; | |
38948 return false; | |
38949 } | |
38950 }); | |
38951 | |
38952 if (emptyHighlight === false) | |
38953 piechart.drawPieChart(GeoTemConfig.mergeObjects(piechart.selected, objects)); | |
38954 else{ | |
38955 //return to selection (or all objects, if no selection is active) | |
38956 if (piechart.selected.length > 0) | |
38957 piechart.drawPieChart(piechart.selected); | |
38958 else | |
38959 piechart.drawPieChart(piechart.datasets); | |
38960 } | |
38961 } | |
38962 }, | |
38963 | |
38964 selectionChanged : function(selection) { | |
38965 var piechart = this; | |
38966 if (piechart.parent.showRangePiechart){ | |
38967 if( !GeoTemConfig.selectionEvents ){ | |
38968 return; | |
38969 } | |
38970 piechart.selected = selection; | |
38971 piechart.highlightChanged([]); | |
38972 } | |
38973 }, | |
38974 | |
38975 triggerHighlight : function(highlightedObjects) { | |
38976 this.parent.triggerHighlight(highlightedObjects); | |
38977 }, | |
38978 | |
38979 triggerSelection : function(selectedObjects) { | |
38980 this.parent.triggerSelection(selectedObjects); | |
38981 }, | |
38982 | |
38983 deselection : function() { | |
38984 }, | |
38985 | |
38986 filtering : function() { | |
38987 }, | |
38988 | |
38989 inverseFiltering : function() { | |
38990 }, | |
38991 | |
38992 triggerRefining : function() { | |
38993 }, | |
38994 | |
38995 reset : function() { | |
38996 }, | |
38997 | |
38998 show : function() { | |
38999 }, | |
39000 | |
39001 hide : function() { | |
39002 } | |
39003 }; | |
39004 /* | |
39005 * FuzzyTimelineRangeSlider.js | |
39006 * | |
39007 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39008 * | |
39009 * This library is free software; you can redistribute it and/or | |
39010 * modify it under the terms of the GNU Lesser General Public | |
39011 * License as published by the Free Software Foundation; either | |
39012 * version 3 of the License, or (at your option) any later version. | |
39013 * | |
39014 * This library is distributed in the hope that it will be useful, | |
39015 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39017 * Lesser General Public License for more details. | |
39018 * | |
39019 * You should have received a copy of the GNU Lesser General Public | |
39020 * License along with this library; if not, write to the Free Software | |
39021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39022 * MA 02110-1301 USA | |
39023 */ | |
39024 | |
39025 /** | |
39026 * @class FuzzyTimelineRangeSlider | |
39027 * Implementation for a fuzzy time-ranges slider | |
39028 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39029 * | |
39030 * @param {HTML object} parent div to append the FuzzyTimeline | |
39031 */ | |
39032 function FuzzyTimelineRangeSlider(parent) { | |
39033 | |
39034 var rangeSlider = this; | |
39035 | |
39036 this.parent = parent; | |
39037 this.options = parent.options; | |
39038 | |
39039 this.spans; | |
39040 | |
39041 this.datasets; | |
39042 | |
39043 this.sliderParentTable = this.parent.gui.sliderTable; | |
39044 var headerRow = $("<tr></tr>"); | |
39045 var controlsRow = $("<tr></tr>"); | |
39046 $(this.sliderParentTable).append(headerRow).append(controlsRow); | |
39047 | |
39048 headerRow.append("<td>Time start</td>"); | |
39049 this.rangeStart = document.createElement("select"); | |
39050 controlsRow.append($("<td></td>").append(this.rangeStart)); | |
39051 | |
39052 headerRow.append("<td>Time unit</td>"); | |
39053 this.rangeDropdown = document.createElement("select"); | |
39054 controlsRow.append($("<td></td>").append(this.rangeDropdown)); | |
39055 | |
39056 headerRow.append("<td>Animation</td>"); | |
39057 this.startAnimation = document.createElement("div"); | |
39058 $(this.startAnimation).addClass("smallButton playDisabled"); | |
39059 this.pauseAnimation = document.createElement("div"); | |
39060 $(this.pauseAnimation).addClass("smallButton pauseDisabled"); | |
39061 controlsRow.append($("<td></td>").append(this.startAnimation).append(this.pauseAnimation)); | |
39062 | |
39063 headerRow.append("<td>Dated Objects</td>"); | |
39064 this.numberDatedObjects = 0; | |
39065 this.numberDatedObjectsDIV = document.createElement("div"); | |
39066 $(this.numberDatedObjectsDIV).addClass("ddbElementsCount"); | |
39067 controlsRow.append($("<td></td>").append(this.numberDatedObjectsDIV)); | |
39068 } | |
39069 | |
39070 FuzzyTimelineRangeSlider.prototype = { | |
39071 | |
39072 initialize : function(datasets) { | |
39073 var rangeSlider = this; | |
39074 rangeSlider.datasets = datasets; | |
39075 | |
39076 //reset values | |
39077 rangeSlider.spans = []; | |
39078 rangeSlider.spanHash = []; | |
39079 | |
39080 //find smallest (most accurate) time-span | |
39081 var smallestSpan; | |
39082 rangeSlider.numberDatedObjects = 0; | |
39083 $(this.datasets).each(function(){ | |
39084 $(this.objects).each(function(){ | |
39085 var dataObject = this; | |
39086 var span; | |
39087 if (dataObject.isTemporal){ | |
39088 rangeSlider.numberDatedObjects++; | |
39089 smallestSpan = moment.duration(1,'milliseconds'); | |
39090 } else if (dataObject.isFuzzyTemporal){ | |
39091 rangeSlider.numberDatedObjects++; | |
39092 span = moment.duration(dataObject.TimeSpanEnd-dataObject.TimeSpanBegin); | |
39093 if ( (typeof smallestSpan === 'undefined') || (span < smallestSpan)) | |
39094 smallestSpan = span; | |
39095 } | |
39096 }); | |
39097 if ((typeof smallestSpan !== 'undefined') && (smallestSpan.asMilliseconds() === 1)) | |
39098 return false; | |
39099 }); | |
39100 | |
39101 //show number of objects that have a time in header | |
39102 $(rangeSlider.numberDatedObjectsDIV).empty().append(rangeSlider.numberDatedObjects + " results"); | |
39103 | |
39104 if (typeof smallestSpan === 'undefined') | |
39105 return; | |
39106 | |
39107 var fixedSpans = [ | |
39108 moment.duration(1, 'seconds'), | |
39109 moment.duration(1, 'minutes'), | |
39110 moment.duration(10, 'minutes'), | |
39111 moment.duration(15, 'minutes'), | |
39112 moment.duration(30, 'minutes'), | |
39113 moment.duration(1, 'hours'), | |
39114 moment.duration(5, 'hours'), | |
39115 moment.duration(10, 'hours'), | |
39116 moment.duration(12, 'hours'), | |
39117 moment.duration(1, 'days'), | |
39118 moment.duration(7, 'days'), | |
39119 moment.duration(1, 'weeks'), | |
39120 moment.duration(2, 'weeks'), | |
39121 moment.duration(1, 'months'), | |
39122 moment.duration(2, 'months'), | |
39123 moment.duration(3, 'months'), | |
39124 moment.duration(6, 'months'), | |
39125 moment.duration(1, 'years'), | |
39126 moment.duration(5, 'years'), | |
39127 moment.duration(10, 'years'), | |
39128 moment.duration(20, 'years'), | |
39129 moment.duration(25, 'years'), | |
39130 moment.duration(50, 'years'), | |
39131 moment.duration(100, 'years'), | |
39132 moment.duration(200, 'years'), | |
39133 moment.duration(250, 'years'), | |
39134 moment.duration(500, 'years'), | |
39135 moment.duration(1000, 'years'), | |
39136 moment.duration(2000, 'years'), | |
39137 moment.duration(2500, 'years'), | |
39138 moment.duration(5000, 'years'), | |
39139 moment.duration(10000, 'years'), | |
39140 ]; | |
39141 | |
39142 //only add spans that are not too small for the data | |
39143 for (var i = 0; i < fixedSpans.length; i++){ | |
39144 if ( (fixedSpans[i].asMilliseconds() > (smallestSpan.asMilliseconds() * 0.5)) | |
39145 && | |
39146 ( | |
39147 rangeSlider.parent.options.showAllPossibleSpans || | |
39148 ((rangeSlider.parent.overallMax-rangeSlider.parent.overallMin)/fixedSpans[i]<rangeSlider.options.maxBars) | |
39149 )) | |
39150 rangeSlider.spans.push(fixedSpans[i]); | |
39151 } | |
39152 | |
39153 $(rangeSlider.rangeDropdown).empty(); | |
39154 | |
39155 $(rangeSlider.rangeDropdown).append("<option>continuous</option>"); | |
39156 var index = 0; | |
39157 $(rangeSlider.spans).each(function(){ | |
39158 var duration = this; | |
39159 if (duration < moment.duration(1,'second')) | |
39160 humanizedSpan = duration.milliseconds() + "ms"; | |
39161 else if (duration < moment.duration(1,'minute')) | |
39162 humanizedSpan = duration.seconds() + "s"; | |
39163 else if (duration < moment.duration(1,'hour')) | |
39164 humanizedSpan = duration.minutes() + "min"; | |
39165 else if (duration < moment.duration(1,'day')) | |
39166 humanizedSpan = duration.hours() + "h"; | |
39167 else if (duration < moment.duration(1,'month')) | |
39168 humanizedSpan = duration.days() + " days"; | |
39169 else if (duration < moment.duration(1,'year')) | |
39170 humanizedSpan = duration.months() + " months"; | |
39171 else | |
39172 humanizedSpan = duration.years() + " years"; | |
39173 $(rangeSlider.rangeDropdown).append("<option index='"+index+"'>"+humanizedSpan+"</option>"); | |
39174 index++; | |
39175 }); | |
39176 | |
39177 $(rangeSlider.rangeDropdown).change(function( eventObject ){ | |
39178 var handlePosition = $(rangeSlider.rangeDropdown).find("option:selected").first().attr("index"); | |
39179 //if there is no index, "continuous" is selected - so the density plot will be drawn | |
39180 | |
39181 if (typeof handlePosition === "undefined"){ | |
39182 rangeSlider.parent.switchViewMode("density"); | |
39183 } else { | |
39184 rangeSlider.parent.switchViewMode("barchart"); | |
39185 } | |
39186 | |
39187 rangeSlider.parent.slidePositionChanged(rangeSlider.spans[handlePosition]); | |
39188 }); | |
39189 | |
39190 $(rangeSlider.rangeStart).empty(); | |
39191 //add start of timeline selections | |
39192 //TODO: add Months/Days/etc., atm there are only years | |
39193 var starts = []; | |
39194 var overallMin = rangeSlider.parent.overallMin; | |
39195 var last = moment(overallMin).year(); | |
39196 starts.push(last); | |
39197 for (i = 1;;i++){ | |
39198 var date = moment(overallMin).year(); | |
39199 date = date/Math.pow(10,i); | |
39200 if (Math.abs(date)<1) | |
39201 break; | |
39202 date = Math.floor(date); | |
39203 date = date*Math.pow(10,i); | |
39204 if (date != last) | |
39205 starts.push(date); | |
39206 last = date; | |
39207 } | |
39208 $(starts).each(function(){ | |
39209 $(rangeSlider.rangeStart).append("<option>"+this+"</option>"); | |
39210 }); | |
39211 | |
39212 $(rangeSlider.rangeStart).change(function( eventObject ){ | |
39213 var handlePosition = rangeSlider.rangeStart.selectedIndex; | |
39214 var start = starts[handlePosition]; | |
39215 | |
39216 rangeSlider.parent.overallMin = moment().year(start); | |
39217 $(rangeSlider.rangeDropdown).change(); | |
39218 }); | |
39219 | |
39220 $(rangeSlider.rangeDropdown).change(); | |
39221 | |
39222 $(rangeSlider.startAnimation).click(function(){ | |
39223 if ($(rangeSlider.startAnimation).hasClass("playEnabled")){ | |
39224 $(rangeSlider.startAnimation).removeClass("playEnabled").addClass("playDisabled"); | |
39225 $(rangeSlider.pauseAnimation).removeClass("pauseDisabled").addClass("pauseEnabled"); | |
39226 | |
39227 rangeSlider.parent.startAnimation(); | |
39228 } | |
39229 }); | |
39230 | |
39231 $(rangeSlider.pauseAnimation).prop('disabled', true); | |
39232 $(rangeSlider.pauseAnimation).click(function(){ | |
39233 if ($(rangeSlider.pauseAnimation).hasClass("pauseEnabled")){ | |
39234 $(rangeSlider.startAnimation).removeClass("playDisabled").addClass("playEnabled"); | |
39235 $(rangeSlider.pauseAnimation).removeClass("pauseEnabled").addClass("pauseDisabled"); | |
39236 | |
39237 rangeSlider.parent.pauseAnimation(); | |
39238 } | |
39239 }); | |
39240 }, | |
39241 | |
39242 triggerHighlight : function(columnElement) { | |
39243 | |
39244 }, | |
39245 | |
39246 triggerSelection : function(columnElement) { | |
39247 | |
39248 }, | |
39249 | |
39250 deselection : function() { | |
39251 }, | |
39252 | |
39253 filtering : function() { | |
39254 }, | |
39255 | |
39256 inverseFiltering : function() { | |
39257 }, | |
39258 | |
39259 triggerRefining : function() { | |
39260 }, | |
39261 | |
39262 reset : function() { | |
39263 }, | |
39264 | |
39265 show : function() { | |
39266 }, | |
39267 | |
39268 hide : function() { | |
39269 } | |
39270 }; | |
39271 /* | |
39272 * FuzzyTimelineWidget.js | |
39273 * | |
39274 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39275 * | |
39276 * This library is free software; you can redistribute it and/or | |
39277 * modify it under the terms of the GNU Lesser General Public | |
39278 * License as published by the Free Software Foundation; either | |
39279 * version 3 of the License, or (at your option) any later version. | |
39280 * | |
39281 * This library is distributed in the hope that it will be useful, | |
39282 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39283 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39284 * Lesser General Public License for more details. | |
39285 * | |
39286 * You should have received a copy of the GNU Lesser General Public | |
39287 * License along with this library; if not, write to the Free Software | |
39288 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39289 * MA 02110-1301 USA | |
39290 */ | |
39291 | |
39292 /** | |
39293 * @class FuzzyTimelineWidget | |
39294 * FuzzyTimelineWidget Implementation | |
39295 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39296 * | |
39297 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
39298 * @param {HTML object} div parent div to append the FuzzyTimeline widget div | |
39299 * @param {JSON} options user specified configuration that overwrites options in FuzzyTimelineConfig.js | |
39300 */ | |
39301 FuzzyTimelineWidget = function(core, div, options) { | |
39302 | |
39303 this.datasets; | |
39304 this.selected = undefined; | |
39305 this.overallMin; | |
39306 this.overallMax; | |
39307 | |
39308 this.core = core; | |
39309 this.core.setWidget(this); | |
39310 | |
39311 this.options = (new FuzzyTimelineConfig(options)).options; | |
39312 this.gui = new FuzzyTimelineGui(this, div, this.options); | |
39313 | |
39314 this.viewMode; | |
39315 this.density; | |
39316 this.rangeSlider; | |
39317 this.rangeBars; | |
39318 this.rangePiechart; | |
39319 this.spanHash = []; | |
39320 | |
39321 this.handles = []; | |
39322 this.zoomFactor = 1; | |
39323 } | |
39324 | |
39325 FuzzyTimelineWidget.prototype = { | |
39326 | |
39327 initWidget : function(data) { | |
39328 var fuzzyTimeline = this; | |
39329 | |
39330 delete fuzzyTimeline.overallMin; | |
39331 delete fuzzyTimeline.overallMax; | |
39332 | |
39333 $(fuzzyTimeline.gui.plotDiv).empty(); | |
39334 $(fuzzyTimeline.gui.sliderTable).empty(); | |
39335 delete fuzzyTimeline.rangeSlider; | |
39336 $(fuzzyTimeline.gui.rangePiechartDiv).empty(); | |
39337 delete fuzzyTimeline.rangePiechart; | |
39338 | |
39339 fuzzyTimeline.switchViewMode("density"); | |
39340 | |
39341 if ( (data instanceof Array) && (data.length > 0) ) | |
39342 { | |
39343 fuzzyTimeline.datasets = data; | |
39344 | |
39345 $(fuzzyTimeline.datasets).each(function(){ | |
39346 $(this.objects).each(function(){ | |
39347 var datemin,datemax; | |
39348 if (this.isTemporal){ | |
39349 //TODO: allow more than one date | |
39350 datemin = moment(this.dates[0].date); | |
39351 datemax = datemin; | |
39352 } else if (this.isFuzzyTemporal){ | |
39353 //TODO: allow more than one date | |
39354 datemin = this.TimeSpanBegin; | |
39355 datemax = this.TimeSpanEnd; | |
39356 } | |
39357 | |
39358 if (typeof fuzzyTimeline.overallMin === "undefined") | |
39359 fuzzyTimeline.overallMin = datemin; | |
39360 if (typeof fuzzyTimeline.overallMax === "undefined") | |
39361 fuzzyTimeline.overallMax = datemax; | |
39362 | |
39363 if (fuzzyTimeline.overallMin > datemin) | |
39364 fuzzyTimeline.overallMin = datemin; | |
39365 if (fuzzyTimeline.overallMax < datemax) | |
39366 fuzzyTimeline.overallMax = datemax; | |
39367 }); | |
39368 }); | |
39369 | |
39370 fuzzyTimeline.rangeSlider = new FuzzyTimelineRangeSlider(fuzzyTimeline); | |
39371 fuzzyTimeline.rangeSlider.initialize(fuzzyTimeline.datasets); | |
39372 | |
39373 fuzzyTimeline.rangePiechart = new FuzzyTimelineRangePiechart(fuzzyTimeline, fuzzyTimeline.gui.rangePiechartDiv); | |
39374 fuzzyTimeline.rangePiechart.initialize(fuzzyTimeline.datasets); | |
39375 } | |
39376 }, | |
39377 | |
39378 switchViewMode : function(viewMode){ | |
39379 var fuzzyTimeline = this; | |
39380 if (viewMode !== fuzzyTimeline.viewMode){ | |
39381 $(fuzzyTimeline.gui.plotDiv).empty(); | |
39382 if (viewMode === "density"){ | |
39383 fuzzyTimeline.density = new FuzzyTimelineDensity(fuzzyTimeline,fuzzyTimeline.gui.plotDiv); | |
39384 } else if (viewMode === "barchart"){ | |
39385 fuzzyTimeline.rangeBars = new FuzzyTimelineRangeBars(fuzzyTimeline); | |
39386 } | |
39387 fuzzyTimeline.viewMode = viewMode; | |
39388 } | |
39389 }, | |
39390 | |
39391 slidePositionChanged : function(spanWidth) { | |
39392 var fuzzyTimeline = this; | |
39393 var datasets = fuzzyTimeline.datasets; | |
39394 if (fuzzyTimeline.viewMode === "density"){ | |
39395 //redraw density plot | |
39396 fuzzyTimeline.density.drawDensityPlot(datasets); | |
39397 //select currently selected data (if there is any) | |
39398 fuzzyTimeline.density.selectionChanged(fuzzyTimeline.selected); | |
39399 } else if (fuzzyTimeline.viewMode === "barchart"){ | |
39400 //redraw range plot | |
39401 fuzzyTimeline.rangeBars.drawRangeBarChart(datasets,spanWidth); | |
39402 //select currently selected data (if there is any) | |
39403 fuzzyTimeline.rangeBars.selectionChanged(fuzzyTimeline.selected); | |
39404 } | |
39405 }, | |
39406 | |
39407 highlightChanged : function(objects) { | |
39408 var fuzzyTimeline = this; | |
39409 if( !GeoTemConfig.highlightEvents ){ | |
39410 return; | |
39411 } | |
39412 if ( (typeof objects === "undefined") || (objects.length == 0) ){ | |
39413 return; | |
39414 } | |
39415 if (fuzzyTimeline.viewMode === "density") | |
39416 this.density.highlightChanged(objects); | |
39417 else if (fuzzyTimeline.viewMode === "barchart") | |
39418 this.rangeBars.highlightChanged(objects); | |
39419 | |
39420 fuzzyTimeline.rangePiechart.highlightChanged(objects); | |
39421 }, | |
39422 | |
39423 selectionChanged : function(selection) { | |
39424 var fuzzyTimeline = this; | |
39425 if( !GeoTemConfig.selectionEvents ){ | |
39426 return; | |
39427 } | |
39428 if (selection.valid()) | |
39429 fuzzyTimeline.selected = selection.objects; | |
39430 else | |
39431 delete fuzzyTimeline.selected; | |
39432 if (fuzzyTimeline.viewMode === "density") | |
39433 this.density.selectionChanged(fuzzyTimeline.selected); | |
39434 else if (fuzzyTimeline.viewMode === "barchart") | |
39435 this.rangeBars.selectionChanged(fuzzyTimeline.selected); | |
39436 | |
39437 if (selection.valid()) | |
39438 fuzzyTimeline.rangePiechart.selectionChanged(fuzzyTimeline.selected); | |
39439 else | |
39440 fuzzyTimeline.rangePiechart.selectionChanged([]); | |
39441 | |
39442 //selections "overwrite" each other | |
39443 if (selection.widget != fuzzyTimeline) | |
39444 fuzzyTimeline.clearHandles(); | |
39445 }, | |
39446 | |
39447 buildSpanArray : function(spanWidth) { | |
39448 var spanArray = []; | |
39449 var tickStart = moment(this.overallMin); | |
39450 do{ | |
39451 spanArray.push(moment(tickStart)); | |
39452 tickStart.add(spanWidth); | |
39453 } while (tickStart <= this.overallMax); | |
39454 spanArray.push(moment(tickStart)); | |
39455 | |
39456 this.spanHash.push({spanWidth:spanWidth,overallMin:moment(this.overallMin),spanArray:spanArray}); | |
39457 return(spanArray); | |
39458 }, | |
39459 | |
39460 getSpanArray : function(spanWidth){ | |
39461 for (var i = 0; i < this.spanHash.length; i++){ | |
39462 var element = this.spanHash[i]; | |
39463 if ( ((this.overallMin-element.overallMin)===0) && | |
39464 ((spanWidth-element.spanWidth)===0)) | |
39465 return element.spanArray; | |
39466 } | |
39467 return this.buildSpanArray(spanWidth); | |
39468 }, | |
39469 | |
39470 clearSpanArray : function(){ | |
39471 this.spanHash = []; | |
39472 }, | |
39473 | |
39474 getTicks : function(dataObject, spanWidth) { | |
39475 var datemin,datemax; | |
39476 if (dataObject.isTemporal){ | |
39477 datemin = moment(dataObject.dates[0].date); | |
39478 datemax = datemin; | |
39479 } else if (dataObject.isFuzzyTemporal){ | |
39480 datemin = dataObject.TimeSpanBegin; | |
39481 datemax = dataObject.TimeSpanEnd; | |
39482 } else{ | |
39483 return; | |
39484 } | |
39485 | |
39486 if (typeof spanWidth._data === "undefined"){ | |
39487 //This does only work with millisecond spans, as the length of years is (very) inaccurate. | |
39488 //(e.g. 100-0 = 99, 2000-1000 = 1001, 5000-0 = 5003, and so on and even more: duration(5000a) = 4932a) | |
39489 //So the time consuming loop below is needed for accurate dates, when years/months/days etc. are supplied | |
39490 var firstTick = Math.floor((datemin-this.overallMin)/spanWidth); | |
39491 var lastTick = Math.floor((datemax-this.overallMin)/spanWidth); | |
39492 //calculate how much the first (and last) tick and the time-span overlap | |
39493 var firstTickPercentage = 1; | |
39494 var lastTickPercentage = 1; | |
39495 if (firstTick != lastTick){ | |
39496 var secondTickStart = this.overallMin+(firstTick+1)*spanWidth; | |
39497 var lastTickStart = this.overallMin+lastTick*spanWidth; | |
39498 firstTickPercentage = (secondTickStart-datemin)/spanWidth; | |
39499 lastTickPercentage = (datemax-lastTickStart)/spanWidth; | |
39500 } | |
39501 if (firstTickPercentage === 0){ | |
39502 firstTick++; | |
39503 firstTickPercentage = 1; | |
39504 } | |
39505 if (lastTickPercentage === 0){ | |
39506 lastTick--; | |
39507 lastTickPercentage = 1; | |
39508 } | |
39509 } else { | |
39510 var spanArray = this.getSpanArray(spanWidth); | |
39511 var firstTick, lastTick; | |
39512 var tickCount = 0; | |
39513 var tickStart = spanArray[0]; | |
39514 var lastTickStart; | |
39515 do{ | |
39516 lastTickStart = spanArray[tickCount]; | |
39517 tickCount++; | |
39518 tickStart = spanArray[tickCount]; | |
39519 if ( (typeof firstTick === "undefined") && (datemin < tickStart) ){ | |
39520 firstTick = tickCount-1; | |
39521 firstTickPercentage = (tickStart - datemin)/spanWidth; | |
39522 } | |
39523 if ( (typeof lastTick === "undefined") && (datemax <= tickStart) ){ | |
39524 lastTick = tickCount-1; | |
39525 lastTickPercentage = (datemax - lastTickStart)/spanWidth; | |
39526 } | |
39527 } while (tickStart < datemax); | |
39528 if (firstTick == lastTick){ | |
39529 firstTickPercentage = 1; | |
39530 lastTickPercentage = 1; | |
39531 } | |
39532 } | |
39533 | |
39534 return({ firstTick:firstTick, | |
39535 lastTick:lastTick, | |
39536 firstTickPercentage:firstTickPercentage, | |
39537 lastTickPercentage:lastTickPercentage}); | |
39538 }, | |
39539 | |
39540 getObjects : function(dateStart, dateEnd) { | |
39541 var fuzzyTimeline = this; | |
39542 var searchDateStart, searchDateEnd; | |
39543 if (typeof dateStart !== "undefined") | |
39544 searchDateStart = moment(dateStart); | |
39545 if (typeof dateEnd !== "undefined") | |
39546 searchDateEnd = moment(dateEnd); | |
39547 | |
39548 var datasets = []; | |
39549 $(fuzzyTimeline.datasets).each(function(){ | |
39550 var objects = []; | |
39551 //check if we got "real" datasets, or just array of objects | |
39552 var datasetObjects = this; | |
39553 if (typeof this.objects !== "undefined") | |
39554 datasetObjects = this.objects; | |
39555 $(datasetObjects).each(function(){ | |
39556 var datemin,datemax; | |
39557 var dataObject = this; | |
39558 if (dataObject.isTemporal){ | |
39559 datemin = moment(dataObject.dates[0].date); | |
39560 datemax = datemin; | |
39561 } else if (dataObject.isFuzzyTemporal){ | |
39562 datemin = dataObject.TimeSpanBegin; | |
39563 datemax = dataObject.TimeSpanEnd; | |
39564 } else{ | |
39565 return; | |
39566 } | |
39567 | |
39568 if (typeof searchDateEnd === 'undefined'){ | |
39569 if ( (datemin <= searchDateStart) && (datemax >= searchDateStart) ) | |
39570 objects.push(this); | |
39571 } else { | |
39572 if ((datemin < searchDateEnd) && (datemax >= searchDateStart)) | |
39573 objects.push(this); | |
39574 } | |
39575 }); | |
39576 datasets.push(objects); | |
39577 }); | |
39578 | |
39579 return(datasets); | |
39580 }, | |
39581 | |
39582 triggerHighlight : function(highlightedObjects){ | |
39583 var fuzzyTimeline = this; | |
39584 if (fuzzyTimeline.viewMode === "density") | |
39585 fuzzyTimeline.density.highlightChanged(highlightedObjects); | |
39586 else if (fuzzyTimeline.viewMode === "barchart") | |
39587 fuzzyTimeline.rangeBars.highlightChanged(highlightedObjects); | |
39588 | |
39589 fuzzyTimeline.core.triggerHighlight(highlightedObjects); | |
39590 }, | |
39591 | |
39592 triggerSelection : function(selectedObjects){ | |
39593 var fuzzyTimeline = this; | |
39594 fuzzyTimeline.selected = selectedObjects; | |
39595 if (fuzzyTimeline.viewMode === "density") | |
39596 fuzzyTimeline.density.selectionChanged(selectedObjects); | |
39597 else if (fuzzyTimeline.viewMode === "barchart") | |
39598 fuzzyTimeline.rangeBars.selectionChanged(selectedObjects); | |
39599 | |
39600 selection = new Selection(selectedObjects); | |
39601 | |
39602 fuzzyTimeline.core.triggerSelection(selection); | |
39603 }, | |
39604 | |
39605 addHandle : function(x1,x2){ | |
39606 var fuzzyTimeline = this; | |
39607 //make sure the interval is ordered correctly | |
39608 if (x2<x1){ | |
39609 var temp = x1; | |
39610 x1 = x2; | |
39611 x2 = temp; | |
39612 } | |
39613 fuzzyTimeline.handles.push({x1:x1,x2:x2}); | |
39614 fuzzyTimeline.drawHandles(); | |
39615 //enabled "play" button | |
39616 $(fuzzyTimeline.rangeSlider.startAnimation).removeClass("playDisabled").addClass("playEnabled"); | |
39617 }, | |
39618 | |
39619 selectByX : function(x1,x2){ | |
39620 var fuzzyTimeline = this; | |
39621 if (fuzzyTimeline.viewMode === "density"){ | |
39622 fuzzyTimeline.density.selectByX(x1,x2); | |
39623 } else if (fuzzyTimeline.viewMode === "barchart"){ | |
39624 fuzzyTimeline.rangeBars.selectByX(x1,x2); | |
39625 } | |
39626 }, | |
39627 | |
39628 drawHandles : function(){ | |
39629 var fuzzyTimeline = this; | |
39630 | |
39631 $(fuzzyTimeline.gui.plotDiv).find(".plotHandle").remove(); | |
39632 $(fuzzyTimeline.gui.plotDiv).find(".dragTimeRangeAlt").remove(); | |
39633 $(fuzzyTimeline.gui.plotDiv).find(".plotHandleBox").remove(); | |
39634 | |
39635 var plotHeight = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).height(); | |
39636 var plotWidth = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).width(); | |
39637 //flot sends the wrong width if we extend the parent div, so scale it accordingly | |
39638 plotWidth = plotWidth*fuzzyTimeline.zoomFactor; | |
39639 var plotOffset = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).getPlotOffset().left; | |
39640 | |
39641 $(fuzzyTimeline.handles).each(function(){ | |
39642 var handle = this; | |
39643 | |
39644 var moveLeftHandle = function(){ | |
39645 leftHandle.style.left = handle.x1-$(leftHandle).width() + "px"; | |
39646 }; | |
39647 | |
39648 var moveRightHandle = function(){ | |
39649 rightHandle.style.left = handle.x2+ "px"; | |
39650 }; | |
39651 | |
39652 var resizeHandleBox = function(){ | |
39653 handleBox.style.left = handle.x1+"px"; | |
39654 $(handleBox).width(handle.x2-handle.x1); | |
39655 }; | |
39656 | |
39657 var moveDragButton = function(){ | |
39658 dragButton.style.left = (handle.x1+handle.x2)/2 - $(dragButton).width()/2 + "px"; | |
39659 }; | |
39660 | |
39661 var leftHandle = document.createElement("div"); | |
39662 leftHandle.title = GeoTemConfig.getString('leftHandle'); | |
39663 leftHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "leftHandle.png" + ")"; | |
39664 leftHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
39665 leftHandle.style.visibility = "visible"; | |
39666 $(fuzzyTimeline.gui.plotDiv).append(leftHandle); | |
39667 moveLeftHandle(); | |
39668 leftHandle.style.top = plotHeight/2-$(leftHandle).height()/2 + "px"; | |
39669 | |
39670 var rightHandle = document.createElement("div"); | |
39671 rightHandle.title = GeoTemConfig.getString('leftHandle'); | |
39672 rightHandle.style.backgroundImage = "url(" + GeoTemConfig.path + "rightHandle.png" + ")"; | |
39673 rightHandle.setAttribute('class', 'plotHandle plotHandleIcon'); | |
39674 rightHandle.style.visibility = "visible"; | |
39675 moveRightHandle(); | |
39676 $(fuzzyTimeline.gui.plotDiv).append(rightHandle); | |
39677 | |
39678 rightHandle.style.top = plotHeight/2-$(rightHandle).height()/2 + "px"; | |
39679 | |
39680 var handleBox = document.createElement("div"); | |
39681 $(fuzzyTimeline.gui.plotDiv).append(handleBox); | |
39682 $(handleBox).addClass("plotHandleBox"); | |
39683 resizeHandleBox(); | |
39684 $(handleBox).height(plotHeight); | |
39685 | |
39686 var dragButton = document.createElement("div"); | |
39687 dragButton.title = GeoTemConfig.getString('dragTimeRange'); | |
39688 dragButton.style.backgroundImage = "url(" + GeoTemConfig.path + "drag.png" + ")"; | |
39689 dragButton.setAttribute('class', 'dragTimeRangeAlt plotHandleIcon'); | |
39690 $(fuzzyTimeline.gui.plotDiv).append(dragButton); | |
39691 moveDragButton(); | |
39692 dragButton.style.top = plotHeight + "px"; | |
39693 | |
39694 $(leftHandle).mousedown(function(){ | |
39695 $(fuzzyTimeline.gui.plotDiv).mousemove(function(eventObj){ | |
39696 var x = eventObj.clientX; | |
39697 x += $(fuzzyTimeline.gui.plotDiv).parent().scrollLeft(); | |
39698 if ((x < handle.x2) && | |
39699 (x >= plotOffset)){ | |
39700 x = x - leftHandle.offsetWidth; | |
39701 handle.x1 = x + $(leftHandle).width(); | |
39702 | |
39703 moveLeftHandle(); | |
39704 resizeHandleBox(); | |
39705 moveDragButton(); | |
39706 } | |
39707 }); | |
39708 $(fuzzyTimeline.gui.plotDiv).mouseup(function(eventObj){ | |
39709 fuzzyTimeline.selectByX(handle.x1,handle.x2); | |
39710 $(fuzzyTimeline.gui.plotDiv).unbind("mouseup"); | |
39711 $(fuzzyTimeline.gui.plotDiv).unbind("mousemove"); | |
39712 }); | |
39713 }); | |
39714 | |
39715 $(rightHandle).mousedown(function(){ | |
39716 $(fuzzyTimeline.gui.plotDiv).mousemove(function(eventObj){ | |
39717 var x = eventObj.clientX; | |
39718 x += $(fuzzyTimeline.gui.plotDiv).parent().scrollLeft(); | |
39719 x = x - rightHandle.offsetWidth; | |
39720 if ((x > handle.x1) && | |
39721 (x <= plotOffset+plotWidth)){ | |
39722 handle.x2 = x; | |
39723 | |
39724 moveRightHandle(); | |
39725 resizeHandleBox(); | |
39726 moveDragButton(); | |
39727 } | |
39728 }); | |
39729 $(fuzzyTimeline.gui.plotDiv).mouseup(function(eventObj){ | |
39730 fuzzyTimeline.selectByX(handle.x1,handle.x2); | |
39731 $(fuzzyTimeline.gui.plotDiv).unbind("mouseup"); | |
39732 $(fuzzyTimeline.gui.plotDiv).unbind("mousemove"); | |
39733 }); | |
39734 }); | |
39735 | |
39736 $(dragButton).mousedown(function(){ | |
39737 $(fuzzyTimeline.gui.plotDiv).mousemove(function(eventObj){ | |
39738 var x = eventObj.clientX; | |
39739 //TODO: for some reason we don't need the scoll offset here | |
39740 //this should be investigated? | |
39741 //x += $(fuzzyTimeline.gui.plotDiv).parent().scrollLeft(); | |
39742 var xdiff = x - $(dragButton).offset().left - $(dragButton).width()/2; | |
39743 handle.x1 = handle.x1+xdiff; | |
39744 handle.x2 = handle.x2+xdiff; | |
39745 | |
39746 moveLeftHandle(); | |
39747 moveRightHandle(); | |
39748 resizeHandleBox(); | |
39749 moveDragButton(); | |
39750 }); | |
39751 $(fuzzyTimeline.gui.plotDiv).mouseup(function(eventObj){ | |
39752 if (handle.x1 < plotOffset) | |
39753 handle.x1 = plotOffset; | |
39754 if (handle.x2 > plotOffset+plotWidth) | |
39755 handle.x2 = plotOffset+plotWidth; | |
39756 | |
39757 moveLeftHandle(); | |
39758 moveRightHandle(); | |
39759 resizeHandleBox(); | |
39760 moveDragButton(); | |
39761 | |
39762 fuzzyTimeline.selectByX(handle.x1,handle.x2); | |
39763 $(fuzzyTimeline.gui.plotDiv).unbind("mouseup"); | |
39764 $(fuzzyTimeline.gui.plotDiv).unbind("mousemove"); | |
39765 }); | |
39766 }); | |
39767 }); | |
39768 }, | |
39769 | |
39770 clearHandles : function(){ | |
39771 var fuzzyTimeline = this; | |
39772 $(fuzzyTimeline.gui.plotDiv).find(".plotHandle").remove(); | |
39773 $(fuzzyTimeline.gui.plotDiv).find(".dragTimeRangeAlt").remove(); | |
39774 $(fuzzyTimeline.gui.plotDiv).find(".plotHandleBox").remove(); | |
39775 fuzzyTimeline.handles = []; | |
39776 //disable buttons | |
39777 $(fuzzyTimeline.rangeSlider.startAnimation).removeClass("playEnabled").addClass("playDisabled"); | |
39778 $(fuzzyTimeline.rangeSlider.pauseAnimation).removeClass("pauseEnabled").addClass("pauseDisabled"); | |
39779 //stop the animation (if one was running) | |
39780 fuzzyTimeline.pauseAnimation(); | |
39781 }, | |
39782 | |
39783 startAnimation : function(){ | |
39784 var fuzzyTimeline = this; | |
39785 fuzzyTimeline.loopFunction = function(steps){ | |
39786 $(fuzzyTimeline.handles).each(function(){ | |
39787 if (typeof steps === "undefined") | |
39788 steps = 1; | |
39789 | |
39790 var handle = this; | |
39791 var x1 = handle.x1; | |
39792 var x2 = handle.x2; | |
39793 | |
39794 if (typeof handle.width === "undefined") | |
39795 handle.width = x2-x1; | |
39796 | |
39797 var plotWidth = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).width(); | |
39798 var plotOffset = (fuzzyTimeline.density.plot?fuzzyTimeline.density.plot:fuzzyTimeline.rangeBars.plot).getPlotOffset().left; | |
39799 | |
39800 var plotMax = plotWidth+plotOffset; | |
39801 | |
39802 //TODO: has to be plotMin | |
39803 if (!((x1 === plotOffset)&&(x2-x1 <= handle.width))){ | |
39804 x1 += steps; | |
39805 } | |
39806 if (x2 <= plotMax){ | |
39807 x2 += steps; | |
39808 if (x2 > plotMax) | |
39809 x2 = plotMax; | |
39810 if (x2-x1 > handle.width){ | |
39811 x1 = x2-handle.width; | |
39812 } | |
39813 } | |
39814 if (x1 >= plotMax){ | |
39815 //TODO: has to be plotMin | |
39816 x1 = plotOffset; | |
39817 x2 = plotOffset; | |
39818 } | |
39819 | |
39820 handle.x1 = x1; | |
39821 handle.x2 = x2; | |
39822 | |
39823 fuzzyTimeline.drawHandles(); | |
39824 fuzzyTimeline.selectByX(handle.x1, handle.x2); | |
39825 }); | |
39826 }; | |
39827 | |
39828 fuzzyTimeline.loopId = setInterval(function(){ | |
39829 fuzzyTimeline.loopFunction(10); | |
39830 }, 100); | |
39831 }, | |
39832 | |
39833 pauseAnimation : function(){ | |
39834 var fuzzyTimeline = this; | |
39835 clearInterval(fuzzyTimeline.loopId); | |
39836 $(fuzzyTimeline.handles).each(function(){ | |
39837 var handle = this; | |
39838 delete handle.width; | |
39839 }); | |
39840 }, | |
39841 | |
39842 //This function enlargens the plot area | |
39843 zoomPlot : function(zoomFactor){ | |
39844 var fuzzyTimeline = this; | |
39845 var oldZoomFactor = fuzzyTimeline.zoomFactor; | |
39846 fuzzyTimeline.zoomFactor = zoomFactor; | |
39847 if (zoomFactor > 1){ | |
39848 $(fuzzyTimeline.gui.plotDiv).width(zoomFactor*100+"%"); | |
39849 //leave place for the scrollbar | |
39850 $(fuzzyTimeline.gui.plotDiv).height(fuzzyTimeline.gui.plotDIVHeight-20); | |
39851 } else{ | |
39852 $(fuzzyTimeline.gui.plotDiv).width("100%"); | |
39853 $(fuzzyTimeline.gui.plotDiv).height(fuzzyTimeline.gui.plotDIVHeight); | |
39854 } | |
39855 | |
39856 //fit handles | |
39857 //this does not make much sense, as the selections are _completely_ different | |
39858 //for each scale rate, as the objects may reside in different "ticks" of the graph | |
39859 $(fuzzyTimeline.handles).each(function(){ | |
39860 var handle = this; | |
39861 handle.x1 = handle.x1 * (zoomFactor/oldZoomFactor); | |
39862 handle.x2 = handle.x2 * (zoomFactor/oldZoomFactor); | |
39863 }); | |
39864 } | |
39865 }; | |
39866 /* | |
39867 * Overlayloader.js | |
39868 * | |
39869 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
39870 * | |
39871 * This library is free software; you can redistribute it and/or | |
39872 * modify it under the terms of the GNU Lesser General Public | |
39873 * License as published by the Free Software Foundation; either | |
39874 * version 3 of the License, or (at your option) any later version. | |
39875 * | |
39876 * This library is distributed in the hope that it will be useful, | |
39877 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39878 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
39879 * Lesser General Public License for more details. | |
39880 * | |
39881 * You should have received a copy of the GNU Lesser General Public | |
39882 * License along with this library; if not, write to the Free Software | |
39883 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
39884 * MA 02110-1301 USA | |
39885 */ | |
39886 | |
39887 /** | |
39888 * @class Overlayloader | |
39889 * Implementation for a Overlayloader UI | |
39890 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
39891 * | |
39892 * @param {HTML object} parent div to append the Overlayloader | |
39893 */ | |
39894 function Overlayloader(parent) { | |
39895 | |
39896 this.overlayLoader = this; | |
39897 | |
39898 this.parent = parent; | |
39899 this.options = parent.options; | |
39900 this.attachedMapWidgets = parent.attachedMapWidgets; | |
39901 | |
39902 this.overlays = []; | |
39903 | |
39904 this.initialize(); | |
39905 } | |
39906 | |
39907 Overlayloader.prototype = { | |
39908 | |
39909 show : function() { | |
39910 this.overlayloaderDiv.style.display = "block"; | |
39911 }, | |
39912 | |
39913 hide : function() { | |
39914 this.overlayloaderDiv.style.display = "none"; | |
39915 }, | |
39916 | |
39917 initialize : function() { | |
39918 | |
39919 this.addKMLLoader(); | |
39920 this.addKMZLoader(); | |
39921 this.addArcGISWMSLoader(); | |
39922 this.addXYZLoader(); | |
39923 this.addRomanEmpireLoader(); | |
39924 this.addConfigLoader(); | |
39925 | |
39926 // trigger change event on the select so | |
39927 // that only the first loader div will be shown | |
39928 $(this.parent.gui.loaderTypeSelect).change(); | |
39929 }, | |
39930 | |
39931 distributeKML : function(kmlURL) { | |
39932 var newOverlay = new Object(); | |
39933 newOverlay.name = kmlURL; | |
39934 newOverlay.layers = []; | |
39935 | |
39936 $(this.attachedMapWidgets).each(function(){ | |
39937 var newLayer = new OpenLayers.Layer.Vector("KML", { | |
39938 projection: this.openlayersMap.displayProjection, | |
39939 strategies: [new OpenLayers.Strategy.Fixed()], | |
39940 protocol: new OpenLayers.Protocol.HTTP({ | |
39941 url: kmlURL, | |
39942 format: new OpenLayers.Format.KML({ | |
39943 extractStyles: true, | |
39944 extractAttributes: true | |
39945 }) | |
39946 }) | |
39947 }); | |
39948 | |
39949 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
39950 | |
39951 this.openlayersMap.addLayer(newLayer); | |
39952 }); | |
39953 | |
39954 this.overlays.push(newOverlay); | |
39955 this.parent.gui.refreshOverlayList(); | |
39956 }, | |
39957 | |
39958 distributeKMZ : function(kmzURL) { | |
39959 var newOverlay = new Object(); | |
39960 newOverlay.name = kmzURL; | |
39961 newOverlay.layers = []; | |
39962 | |
39963 $(this.attachedMapWidgets).each(function(){ | |
39964 var newLayer = new OpenLayers.Layer.Vector("KML", { | |
39965 projection: this.openlayersMap.displayProjection, | |
39966 strategies: [new OpenLayers.Strategy.Fixed()], | |
39967 format: OpenLayers.Format.KML, | |
39968 extractAttributes: true | |
39969 }); | |
39970 | |
39971 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
39972 | |
39973 var map = this.openlayersMap; | |
39974 | |
39975 GeoTemConfig.getKmz(kmzURL, function(kmlDoms){ | |
39976 $(kmlDoms).each(function(){ | |
39977 var kml = new OpenLayers.Format.KML().read(this); | |
39978 newLayer.addFeatures(kml); | |
39979 map.addLayer(newLayer); | |
39980 }); | |
39981 }); | |
39982 }); | |
39983 | |
39984 this.overlays.push(newOverlay); | |
39985 this.parent.gui.refreshOverlayList(); | |
39986 }, | |
39987 | |
39988 distributeArcGISWMS : function(wmsURL, wmsLayer) { | |
39989 var newOverlay = new Object(); | |
39990 newOverlay.name = wmsURL + " - " + wmsLayer; | |
39991 newOverlay.layers = []; | |
39992 | |
39993 var newLayer = new OpenLayers.Layer.WMS("ArcGIS WMS label", wmsURL, { | |
39994 layers: wmsLayer, | |
39995 format: "image/png", | |
39996 transparent: "true" | |
39997 } | |
39998 ,{ | |
39999 displayOutsideMaxExtent: true, | |
40000 isBaseLayer: false, | |
40001 projection : "EPSG:3857" | |
40002 } | |
40003 ); | |
40004 | |
40005 newLayer.setIsBaseLayer(false); | |
40006 $(this.attachedMapWidgets).each(function(){ | |
40007 this.openlayersMap.addLayer(newLayer); | |
40008 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
40009 }); | |
40010 | |
40011 this.overlays.push(newOverlay); | |
40012 this.parent.gui.refreshOverlayList(); | |
40013 }, | |
40014 | |
40015 distributeXYZ : function(xyzURL) { | |
40016 var newOverlay = new Object(); | |
40017 newOverlay.name = xyzURL; | |
40018 newOverlay.layers = []; | |
40019 | |
40020 var newLayer = new OpenLayers.Layer.XYZ( | |
40021 "XYZ Layer", | |
40022 [ | |
40023 xyzURL | |
40024 ], { | |
40025 sphericalMercator: true, | |
40026 transitionEffect: "resize", | |
40027 buffer: 1, | |
40028 numZoomLevels: 12, | |
40029 transparent : true | |
40030 } | |
40031 ); | |
40032 | |
40033 newLayer.setIsBaseLayer(false); | |
40034 $(this.attachedMapWidgets).each(function(){ | |
40035 this.openlayersMap.addLayer(newLayer); | |
40036 this.openlayersMap.setBaseLayer(newLayer); | |
40037 newOverlay.layers.push({map:this.openlayersMap,layer:newLayer}); | |
40038 }); | |
40039 | |
40040 this.overlays.push(newOverlay); | |
40041 this.parent.gui.refreshOverlayList(); | |
40042 }, | |
40043 | |
40044 addKMLLoader : function() { | |
40045 $(this.parent.gui.loaderTypeSelect).append("<option value='KMLLoader'>KML File URL</option>"); | |
40046 | |
40047 this.KMLLoaderTab = document.createElement("div"); | |
40048 $(this.KMLLoaderTab).attr("id","KMLLoader"); | |
40049 | |
40050 this.kmlURL = document.createElement("input"); | |
40051 $(this.kmlURL).attr("type","text"); | |
40052 $(this.KMLLoaderTab).append(this.kmlURL); | |
40053 | |
40054 this.loadKMLButton = document.createElement("button"); | |
40055 $(this.loadKMLButton).text("load KML"); | |
40056 $(this.KMLLoaderTab).append(this.loadKMLButton); | |
40057 | |
40058 $(this.loadKMLButton).click($.proxy(function(){ | |
40059 var kmlURL = $(this.kmlURL).val(); | |
40060 if (kmlURL.length == 0) | |
40061 return; | |
40062 if (typeof this.options.proxy != 'undefined') | |
40063 kmlURL = this.options.proxy + kmlURL; | |
40064 | |
40065 this.distributeKML(kmlURL); | |
40066 },this)); | |
40067 | |
40068 $(this.parent.gui.loaders).append(this.KMLLoaderTab); | |
40069 }, | |
40070 | |
40071 addKMZLoader : function() { | |
40072 $(this.parent.gui.loaderTypeSelect).append("<option value='KMZLoader'>KMZ File URL</option>"); | |
40073 | |
40074 this.KMZLoaderTab = document.createElement("div"); | |
40075 $(this.KMZLoaderTab).attr("id","KMZLoader"); | |
40076 | |
40077 this.kmzURL = document.createElement("input"); | |
40078 $(this.kmzURL).attr("type","text"); | |
40079 $(this.KMZLoaderTab).append(this.kmzURL); | |
40080 | |
40081 this.loadKMZButton = document.createElement("button"); | |
40082 $(this.loadKMZButton).text("load KMZ"); | |
40083 $(this.KMZLoaderTab).append(this.loadKMZButton); | |
40084 | |
40085 $(this.loadKMZButton).click($.proxy(function(){ | |
40086 var kmzURL = $(this.kmzURL).val(); | |
40087 if (kmzURL.length == 0) | |
40088 return; | |
40089 if (typeof this.options.proxy != 'undefined') | |
40090 kmzURL = this.options.proxy + kmzURL; | |
40091 | |
40092 this.distributeKMZ(kmzURL); | |
40093 },this)); | |
40094 | |
40095 $(this.parent.gui.loaders).append(this.KMZLoaderTab); | |
40096 }, | |
40097 | |
40098 addArcGISWMSLoader : function() { | |
40099 $(this.parent.gui.loaderTypeSelect).append("<option value='ArcGISWMSLoader'>ArcGIS WMS</option>"); | |
40100 | |
40101 this.ArcGISWMSLoaderTab = document.createElement("div"); | |
40102 $(this.ArcGISWMSLoaderTab).attr("id","ArcGISWMSLoader"); | |
40103 | |
40104 $(this.ArcGISWMSLoaderTab).append("URL: "); | |
40105 | |
40106 this.wmsURL = document.createElement("input"); | |
40107 $(this.wmsURL).attr("type","text"); | |
40108 $(this.ArcGISWMSLoaderTab).append(this.wmsURL); | |
40109 | |
40110 $(this.ArcGISWMSLoaderTab).append("Layer: "); | |
40111 | |
40112 this.wmsLayer = document.createElement("input"); | |
40113 $(this.wmsLayer).attr("type","text"); | |
40114 $(this.ArcGISWMSLoaderTab).append(this.wmsLayer); | |
40115 | |
40116 this.loadArcGISWMSButton = document.createElement("button"); | |
40117 $(this.loadArcGISWMSButton).text("load Layer"); | |
40118 $(this.ArcGISWMSLoaderTab).append(this.loadArcGISWMSButton); | |
40119 | |
40120 $(this.loadArcGISWMSButton).click($.proxy(function(){ | |
40121 var wmsURL = $(this.wmsURL).val(); | |
40122 var wmsLayer = $(this.wmsLayer).val(); | |
40123 if (wmsURL.length == 0) | |
40124 return; | |
40125 | |
40126 this.distributeArcGISWMS(wmsURL, wmsLayer); | |
40127 },this)); | |
40128 | |
40129 $(this.parent.gui.loaders).append(this.ArcGISWMSLoaderTab); | |
40130 }, | |
40131 | |
40132 addXYZLoader : function() { | |
40133 $(this.parent.gui.loaderTypeSelect).append("<option value='XYZLoader'>XYZ Layer</option>"); | |
40134 | |
40135 this.XYZLoaderTab = document.createElement("div"); | |
40136 $(this.XYZLoaderTab).attr("id","XYZLoader"); | |
40137 | |
40138 $(this.XYZLoaderTab).append("URL (with x,y,z variables): "); | |
40139 | |
40140 this.xyzURL = document.createElement("input"); | |
40141 $(this.xyzURL).attr("type","text"); | |
40142 $(this.XYZLoaderTab).append(this.xyzURL); | |
40143 | |
40144 this.loadXYZButton = document.createElement("button"); | |
40145 $(this.loadXYZButton).text("load Layer"); | |
40146 $(this.XYZLoaderTab).append(this.loadXYZButton); | |
40147 | |
40148 $(this.loadXYZButton).click($.proxy(function(){ | |
40149 var xyzURL = $(this.xyzURL).val(); | |
40150 if (xyzURL.length == 0) | |
40151 return; | |
40152 | |
40153 this.distributeXYZ(xyzURL); | |
40154 },this)); | |
40155 | |
40156 $(this.parent.gui.loaders).append(this.XYZLoaderTab); | |
40157 }, | |
40158 | |
40159 addRomanEmpireLoader : function() { | |
40160 $(this.parent.gui.loaderTypeSelect).append("<option value='RomanEmpireLoader'>Roman Empire</option>"); | |
40161 | |
40162 this.RomanEmpireLoaderTab = document.createElement("div"); | |
40163 $(this.RomanEmpireLoaderTab).attr("id","RomanEmpireLoader"); | |
40164 | |
40165 this.loadRomanEmpireButton = document.createElement("button"); | |
40166 $(this.loadRomanEmpireButton).text("load Layer"); | |
40167 $(this.RomanEmpireLoaderTab).append(this.loadRomanEmpireButton); | |
40168 | |
40169 $(this.loadRomanEmpireButton).click($.proxy(function(){ | |
40170 this.distributeXYZ("http://pelagios.dme.ait.ac.at/tilesets/imperium/${z}/${x}/${y}.png"); | |
40171 },this)); | |
40172 | |
40173 $(this.parent.gui.loaders).append(this.RomanEmpireLoaderTab); | |
40174 }, | |
40175 | |
40176 addConfigLoader : function() { | |
40177 if ( (this.parent.options.wms_overlays instanceof Array) && | |
40178 (this.parent.options.wms_overlays.length > 0) ){ | |
40179 var overlayloader = this; | |
40180 | |
40181 $(this.parent.gui.loaderTypeSelect).append("<option value='ConfigLoader'>Other WMS maps</option>"); | |
40182 | |
40183 this.ConfigLoaderTab = document.createElement("div"); | |
40184 $(this.ConfigLoaderTab).attr("id","ConfigLoader"); | |
40185 | |
40186 this.ConfigMapSelect = document.createElement("select"); | |
40187 $(this.parent.options.wms_overlays).each(function(){ | |
40188 var name = this.name, server = this.server, layer = this.layer; | |
40189 $(overlayloader.ConfigMapSelect).append("<option layer='"+layer+"' server='"+server+"' >"+name+"</option>"); | |
40190 }); | |
40191 | |
40192 $(this.ConfigLoaderTab).append(this.ConfigMapSelect); | |
40193 | |
40194 this.loadConfigMapButton = document.createElement("button"); | |
40195 $(this.loadConfigMapButton).text("load Layer"); | |
40196 $(this.ConfigLoaderTab).append(this.loadConfigMapButton); | |
40197 | |
40198 $(this.loadConfigMapButton).click($.proxy(function(){ | |
40199 var server = $(this.ConfigMapSelect).find(":selected").attr("server"); | |
40200 var layer = $(this.ConfigMapSelect).find(":selected").attr("layer"); | |
40201 this.distributeArcGISWMS(server,layer); | |
40202 },this)); | |
40203 | |
40204 $(this.parent.gui.loaders).append(this.ConfigLoaderTab); | |
40205 } | |
40206 } | |
40207 | |
40208 }; | |
40209 /* | |
40210 * OverlayloaderConfig.js | |
40211 * | |
40212 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40213 * | |
40214 * This library is free software; you can redistribute it and/or | |
40215 * modify it under the terms of the GNU Lesser General Public | |
40216 * License as published by the Free Software Foundation; either | |
40217 * version 3 of the License, or (at your option) any later version. | |
40218 * | |
40219 * This library is distributed in the hope that it will be useful, | |
40220 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40221 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40222 * Lesser General Public License for more details. | |
40223 * | |
40224 * You should have received a copy of the GNU Lesser General Public | |
40225 * License along with this library; if not, write to the Free Software | |
40226 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40227 * MA 02110-1301 USA | |
40228 */ | |
40229 | |
40230 /** | |
40231 * @class OverlayloaderConfig | |
40232 * Overlayloader Configuration File | |
40233 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40234 */ | |
40235 function OverlayloaderConfig(options) { | |
40236 | |
40237 this.options = { | |
40238 wms_overlays : [ | |
40239 //e.g. {name:'name', server:'url', layer:'layer'}, | |
40240 ], | |
40241 proxy : 'php/proxy.php?address=' | |
40242 }; | |
40243 if ( typeof options != 'undefined') { | |
40244 $.extend(this.options, options); | |
40245 } | |
40246 | |
40247 }; | |
40248 /* | |
40249 * OverlayloaderGui.js | |
40250 * | |
40251 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40252 * | |
40253 * This library is free software; you can redistribute it and/or | |
40254 * modify it under the terms of the GNU Lesser General Public | |
40255 * License as published by the Free Software Foundation; either | |
40256 * version 3 of the License, or (at your option) any later version. | |
40257 * | |
40258 * This library is distributed in the hope that it will be useful, | |
40259 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40260 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40261 * Lesser General Public License for more details. | |
40262 * | |
40263 * You should have received a copy of the GNU Lesser General Public | |
40264 * License along with this library; if not, write to the Free Software | |
40265 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40266 * MA 02110-1301 USA | |
40267 */ | |
40268 | |
40269 /** | |
40270 * @class OverlayloaderGui | |
40271 * Overlayloader GUI Implementation | |
40272 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40273 * | |
40274 * @param {OverlayloaderWidget} parent Overlayloader widget object | |
40275 * @param {HTML object} div parent div to append the Overlayloader gui | |
40276 * @param {JSON} options Overlayloader configuration | |
40277 */ | |
40278 function OverlayloaderGui(overlayloader, div, options) { | |
40279 | |
40280 this.parent = overlayloader; | |
40281 var overlayloaderGui = this; | |
40282 | |
40283 this.overlayloaderContainer = div; | |
40284 this.overlayloaderContainer.style.position = 'relative'; | |
40285 | |
40286 this.loaderTypeSelect = document.createElement("select"); | |
40287 div.appendChild(this.loaderTypeSelect); | |
40288 | |
40289 this.loaders = document.createElement("div"); | |
40290 div.appendChild(this.loaders); | |
40291 | |
40292 this.overlayList = document.createElement("div"); | |
40293 div.appendChild(this.overlayList); | |
40294 | |
40295 $(this.loaderTypeSelect).change(function(){ | |
40296 var activeLoader = $(this).val(); | |
40297 $(overlayloaderGui.loaders).find("div").each(function(){ | |
40298 if ($(this).attr("id") == activeLoader) | |
40299 $(this).show(); | |
40300 else | |
40301 $(this).hide(); | |
40302 }); | |
40303 }); | |
40304 | |
40305 this.refreshOverlayList = function(){ | |
40306 var overlayloaderGui = this; | |
40307 | |
40308 $(overlayloaderGui.overlayList).empty(); | |
40309 $(this.parent.overlayLoader.overlays).each(function(){ | |
40310 var overlay = this; | |
40311 $(overlayloaderGui.overlayList).append(overlay.name); | |
40312 var link = document.createElement("a"); | |
40313 $(link).text("(x)"); | |
40314 link.href=""; | |
40315 | |
40316 $(link).click($.proxy(function(){ | |
40317 $(overlay.layers).each(function(){ | |
40318 this.map.removeLayer(this.layer); | |
40319 }); | |
40320 | |
40321 var overlays = overlayloaderGui.parent.overlayLoader.overlays; | |
40322 | |
40323 overlays = $.grep(overlays, function(value) { | |
40324 return overlay != value; | |
40325 }); | |
40326 | |
40327 overlayloaderGui.parent.overlayLoader.overlays = overlays; | |
40328 | |
40329 overlayloaderGui.refreshOverlayList(); | |
40330 | |
40331 return(false); | |
40332 },{overlay:overlay,overlayloaderGui:overlayloaderGui})); | |
40333 $(overlayloaderGui.overlayList).append(link); | |
40334 }); | |
40335 }; | |
40336 }; | |
40337 /* | |
40338 * OverlayloaderWidget.js | |
40339 * | |
40340 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40341 * | |
40342 * This library is free software; you can redistribute it and/or | |
40343 * modify it under the terms of the GNU Lesser General Public | |
40344 * License as published by the Free Software Foundation; either | |
40345 * version 3 of the License, or (at your option) any later version. | |
40346 * | |
40347 * This library is distributed in the hope that it will be useful, | |
40348 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40349 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40350 * Lesser General Public License for more details. | |
40351 * | |
40352 * You should have received a copy of the GNU Lesser General Public | |
40353 * License along with this library; if not, write to the Free Software | |
40354 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40355 * MA 02110-1301 USA | |
40356 */ | |
40357 | |
40358 /** | |
40359 * @class OverlayloaderWidget | |
40360 * OverlayloaderWidget Implementation | |
40361 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40362 * | |
40363 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
40364 * @param {HTML object} div parent div to append the Overlayloader widget div | |
40365 * @param {JSON} options user specified configuration that overwrites options in OverlayloaderConfig.js | |
40366 */ | |
40367 OverlayloaderWidget = function(core, div, options) { | |
40368 | |
40369 this.core = core; | |
40370 this.core.setWidget(this); | |
40371 | |
40372 this.options = (new OverlayloaderConfig(options)).options; | |
40373 this.gui = new OverlayloaderGui(this, div, this.options); | |
40374 | |
40375 this.attachedMapWidgets = new Array(); | |
40376 | |
40377 this.overlayLoader = new Overlayloader(this); | |
40378 } | |
40379 | |
40380 OverlayloaderWidget.prototype = { | |
40381 | |
40382 initWidget : function() { | |
40383 | |
40384 var overlayloaderWidget = this; | |
40385 }, | |
40386 | |
40387 highlightChanged : function(objects) { | |
40388 if( !GeoTemConfig.highlightEvents ){ | |
40389 return; | |
40390 } | |
40391 }, | |
40392 | |
40393 selectionChanged : function(selection) { | |
40394 if( !GeoTemConfig.selectionEvents ){ | |
40395 return; | |
40396 } | |
40397 }, | |
40398 | |
40399 triggerHighlight : function(item) { | |
40400 }, | |
40401 | |
40402 tableSelection : function() { | |
40403 }, | |
40404 | |
40405 deselection : function() { | |
40406 }, | |
40407 | |
40408 filtering : function() { | |
40409 }, | |
40410 | |
40411 inverseFiltering : function() { | |
40412 }, | |
40413 | |
40414 triggerRefining : function() { | |
40415 }, | |
40416 | |
40417 reset : function() { | |
40418 }, | |
40419 | |
40420 attachMapWidget : function(widget) { | |
40421 this.attachedMapWidgets.push(widget); | |
40422 } | |
40423 }; | |
40424 /* | |
40425 * PieChart.js | |
40426 * | |
40427 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40428 * | |
40429 * This library is free software; you can redistribute it and/or | |
40430 * modify it under the terms of the GNU Lesser General Public | |
40431 * License as published by the Free Software Foundation; either | |
40432 * version 3 of the License, or (at your option) any later version. | |
40433 * | |
40434 * This library is distributed in the hope that it will be useful, | |
40435 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40436 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40437 * Lesser General Public License for more details. | |
40438 * | |
40439 * You should have received a copy of the GNU Lesser General Public | |
40440 * License along with this library; if not, write to the Free Software | |
40441 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40442 * MA 02110-1301 USA | |
40443 */ | |
40444 | |
40445 /** | |
40446 * @class PieChart | |
40447 * Implementation for a PieChart | |
40448 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40449 * | |
40450 * @param {HTML object} parent div to append the PieChart | |
40451 */ | |
40452 function PieChart(parent, watchedDataset, watchedColumn, selectionFunction) { | |
40453 | |
40454 if ((typeof selectionFunction !== "undefined") && | |
40455 (typeof selectionFunction.type !== "undefined") && | |
40456 (typeof selectionFunction.categories !== "undefined")){ | |
40457 this.type = selectionFunction.type; | |
40458 this.categories = selectionFunction.categories; | |
40459 } | |
40460 this.pieChart = this; | |
40461 this.pieChartDiv; | |
40462 this.preHighlightObjects; | |
40463 this.highlightedLabel; | |
40464 | |
40465 this.informationDIV; | |
40466 this.pieChartLabel; | |
40467 | |
40468 this.parent = parent; | |
40469 this.options = parent.options; | |
40470 | |
40471 this.watchedDatasetObject; | |
40472 this.watchedDataset = parseInt(watchedDataset); | |
40473 this.watchColumn = watchedColumn; | |
40474 if (typeof selectionFunction !== "undefined") | |
40475 this.selectionFunction = selectionFunction; | |
40476 else | |
40477 //default selectionFunction returns value (creates "distinct" piechart) | |
40478 this.selectionFunction = function(columnData){return columnData;}; | |
40479 } | |
40480 | |
40481 PieChart.prototype = { | |
40482 | |
40483 remove : function() { | |
40484 for (var i = 0; i < this.parent.pieCharts.length; i++){ | |
40485 if (this.parent.pieCharts[i] === this) | |
40486 this.parent.pieCharts[i] = null; | |
40487 } | |
40488 $(this.pieChartDiv).remove(); | |
40489 $(this.informationDIV).remove(); | |
40490 this.parent.redrawPieCharts(); | |
40491 }, | |
40492 | |
40493 refreshLabel : function(){ | |
40494 $(this.pieChartLabel).empty(); | |
40495 $(this.pieChartLabel).append(this.watchedDatasetObject.label + " - " + this.watchColumn); | |
40496 | |
40497 var c = GeoTemConfig.getColor(this.watchedDataset); | |
40498 $(this.pieChartLabel).css("color","rgb("+c.r1+","+c.g1+","+c.b1+")"); | |
40499 }, | |
40500 | |
40501 initialize : function() { | |
40502 var pieChart = this; | |
40503 | |
40504 if (typeof this.pieChartDiv === "undefined"){ | |
40505 this.informationDIV = document.createElement("div"); | |
40506 this.pieChartLabel = $("<span></span>"); | |
40507 $(this.informationDIV).append(this.pieChartLabel); | |
40508 this.refreshLabel(); | |
40509 | |
40510 var removeButton = document.createElement("button"); | |
40511 $(this.informationDIV).append(removeButton); | |
40512 $(removeButton).text("remove"); | |
40513 $(removeButton).click(function(){ | |
40514 pieChart.remove(); | |
40515 }); | |
40516 | |
40517 //only allow editing if it is a "manually" created piechart | |
40518 //automatic (with a selection function) ones, can lead to numerous problems, | |
40519 //e.g. too many categories or numeral categories threated as text ones | |
40520 if ((typeof pieChart.type !== "undefined")&& | |
40521 (typeof pieChart.categories !== "undefined")){ | |
40522 var editButton = document.createElement("button"); | |
40523 $(this.informationDIV).append(editButton); | |
40524 $(editButton).text("edit"); | |
40525 $(editButton).click(function(){ | |
40526 var chooser = new PieChartCategoryChooser( | |
40527 pieChart.parent, | |
40528 pieChart.parent.options, | |
40529 pieChart.watchedDataset, | |
40530 pieChart.watchColumn, | |
40531 pieChart.type, | |
40532 pieChart.categories); | |
40533 }); | |
40534 | |
40535 //add save button | |
40536 if (pieChart.options.allowLocalStorage){ | |
40537 var saveButton = document.createElement("button"); | |
40538 $(this.informationDIV).append(saveButton); | |
40539 $(saveButton).text("save"); | |
40540 $(saveButton).click(function(){ | |
40541 $( "<div>" + | |
40542 "pie chart name : " + | |
40543 "<input type='text' size=30 id='saveName' class='ui-widget-content ui-corner-all'></input>" + | |
40544 "</div>").dialog({ | |
40545 width:'auto', | |
40546 buttons: [ | |
40547 { | |
40548 text: "save", | |
40549 click: function(){ | |
40550 var saveName = $("#saveName").val(); | |
40551 var saveObject = new Object(); | |
40552 saveObject.type = pieChart.type; | |
40553 saveObject.categories = pieChart.categories; | |
40554 saveObject.columnName = pieChart.watchColumn; | |
40555 //save to LocalStorage | |
40556 $.remember({ | |
40557 name:pieChart.options.localStoragePrefix+saveName, | |
40558 value:saveObject, | |
40559 json:true | |
40560 }); | |
40561 $(this).dialog( "close" ); | |
40562 } | |
40563 } | |
40564 ] | |
40565 }); | |
40566 | |
40567 //set value to default (column name) | |
40568 $("#saveName").val(pieChart.watchColumn); | |
40569 //TODO: z-index has to be set, as the "tool-bars" of map (.ddbToolbar in style.css) | |
40570 //also have a z-index of 10000. z-index should be removed from all elements. | |
40571 $(".ui-dialog").css("z-index",10005); | |
40572 }); | |
40573 } | |
40574 } | |
40575 | |
40576 $(this.parent.gui.pieChartsDiv).append(this.informationDIV); | |
40577 this.pieChartDiv = document.createElement("div"); | |
40578 $(this.parent.gui.pieChartsDiv).append(this.pieChartDiv); | |
40579 | |
40580 $(this.pieChartDiv).unbind(); | |
40581 $(this.pieChartDiv).bind("plothover", function (event, pos, item) { | |
40582 var highlightedLabel; | |
40583 | |
40584 if (item) { | |
40585 highlightedLabel = item.series.label; | |
40586 } | |
40587 if (highlightedLabel !== pieChart.highlightedLabel){ | |
40588 pieChart.highlightedLabel = highlightedLabel; | |
40589 pieChart.triggerHighlight(highlightedLabel); | |
40590 } | |
40591 }); | |
40592 | |
40593 $(this.pieChartDiv).bind("plotclick", function (event, pos, item) { | |
40594 if (item) { | |
40595 //item.series.label contains the column element | |
40596 pieChart.triggerSelection(item.series.label); | |
40597 } else { | |
40598 pieChart.triggerSelection(); | |
40599 } | |
40600 }); | |
40601 } | |
40602 }, | |
40603 | |
40604 //check if dataset is still there | |
40605 checkForDataSet : function() { | |
40606 var datasets = this.parent.datasets; | |
40607 if ((typeof datasets !== "undefined") && (typeof this.watchedDatasetObject !== "undefined")){ | |
40608 //check if our data went missing | |
40609 for (var i = 0; i < datasets.length; i++){ | |
40610 if (datasets[i] === this.watchedDatasetObject){ | |
40611 //if dataset "before" this one was removed, the index changes | |
40612 if (this.watchedDataset !== i){ | |
40613 //change color to the new one (changes with index!) | |
40614 this.watchedDataset = i; | |
40615 this.refreshLabel(); | |
40616 } | |
40617 return true; | |
40618 } | |
40619 } | |
40620 } | |
40621 return false; | |
40622 }, | |
40623 | |
40624 initPieChart : function(dataSets) { | |
40625 // get dataset object (could not be there on startup, e.g. piechart defined before load completes) | |
40626 if (typeof this.watchedDatasetObject === "undefined") | |
40627 this.watchedDatasetObject = this.parent.datasets[this.watchedDataset]; | |
40628 | |
40629 this.initialize(); | |
40630 | |
40631 // if our dataset went missing, remove this piechart | |
40632 if (!this.checkForDataSet()){ | |
40633 this.remove(); | |
40634 return; | |
40635 } | |
40636 | |
40637 var objects = []; | |
40638 for (var i = 0; i < dataSets.length; i++) | |
40639 objects.push([]); | |
40640 objects[this.watchedDataset] = dataSets[this.watchedDataset].objects; | |
40641 | |
40642 this.preHighlightObjects = objects; | |
40643 this.redrawPieChart(objects); | |
40644 }, | |
40645 | |
40646 redrawPieChart : function(objects) { | |
40647 | |
40648 if (typeof objects === "undefined") | |
40649 objects = this.preHighlightObjects; | |
40650 | |
40651 if (this.checkForDataSet(objects)){ | |
40652 var pieChart = this; | |
40653 if (objects[this.watchedDataset].length === 0) | |
40654 objects = this.preHighlightObjects; | |
40655 | |
40656 var calculateSlices = function(dataObjects){ | |
40657 var chartDataCounter = new Object; | |
40658 | |
40659 $(dataObjects).each(function(){ | |
40660 var columnData = pieChart.parent.getElementData(this, pieChart.watchColumn, pieChart.selectionFunction); | |
40661 | |
40662 //disregard empty cells | |
40663 if ( (typeof columnData === "undefined") || (columnData == "") ) | |
40664 return; | |
40665 | |
40666 if (typeof chartDataCounter[columnData] === "undefined") | |
40667 chartDataCounter[columnData] = 1; | |
40668 else | |
40669 chartDataCounter[columnData]++; | |
40670 }); | |
40671 | |
40672 var chartData = []; | |
40673 $.each(chartDataCounter, function(name,val){ | |
40674 //get rgb-color (24bit = 6 hex digits) from hash | |
40675 var color = '#'+hex_md5(name).substr(0,6); | |
40676 chartData.push({label:name,data:val,color:color}); | |
40677 }); | |
40678 | |
40679 //sort by count (occurances of category) | |
40680 var sortByVal = function(a,b){ | |
40681 return (b.data-a.data); | |
40682 }; | |
40683 chartData.sort(sortByVal); | |
40684 | |
40685 return chartData; | |
40686 }; | |
40687 | |
40688 var chartData = calculateSlices(objects[this.watchedDataset]); | |
40689 | |
40690 if (chartData.length>0){ | |
40691 $(this.pieChartDiv).empty(); | |
40692 | |
40693 //calculate height (flot NEEDS a height) | |
40694 var parentHeight = $(this.parent.gui.pieChartsDiv).outerHeight(true) - $(this.parent.gui.columnSelectorDiv).outerHeight(true); | |
40695 var pieChartCount = 0; | |
40696 $(this.parent.pieCharts).each(function(){ | |
40697 if (this instanceof PieChart) | |
40698 pieChartCount++; | |
40699 }); | |
40700 var height = (parentHeight/pieChartCount) - $(this.informationDIV).outerHeight(true); | |
40701 if (pieChart.options.restrictPieChartSize !== false) | |
40702 height = Math.min(height, $(window).height() * pieChart.options.restrictPieChartSize); | |
40703 $(this.pieChartDiv).height(height); | |
40704 | |
40705 $.plot($(this.pieChartDiv), chartData, | |
40706 { | |
40707 series: { | |
40708 // Make this a pie chart. | |
40709 pie: { | |
40710 show:true | |
40711 } | |
40712 }, | |
40713 legend: { show:true, position: 'se' }, | |
40714 grid: { | |
40715 hoverable: true, | |
40716 clickable: true | |
40717 }, | |
40718 tooltip: true, | |
40719 tooltipOpts: { | |
40720 content: "%s %p.1%" | |
40721 } | |
40722 } | |
40723 ); | |
40724 } | |
40725 } | |
40726 }, | |
40727 | |
40728 triggerHighlight : function(columnElement) { | |
40729 var highlightedObjects = []; | |
40730 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
40731 highlightedObjects.push([]); | |
40732 | |
40733 if (this.watchedDataset >= 0) | |
40734 highlightedObjects[this.watchedDataset] = | |
40735 this.parent.getElementsByValue(columnElement, this.watchedDataset, this.watchColumn, this.selectionFunction); | |
40736 else | |
40737 highlightedObjects[this.watchedDataset] = []; | |
40738 | |
40739 this.parent.core.triggerHighlight(highlightedObjects); | |
40740 | |
40741 var pieChart = this; | |
40742 $(this.parent.pieCharts).each(function(){ | |
40743 if (this instanceof PieChart && (this !== pieChart)){ | |
40744 if (this.watchedDataset === pieChart.watchedDataset) | |
40745 this.redrawPieChart(highlightedObjects); | |
40746 } | |
40747 }); | |
40748 }, | |
40749 | |
40750 triggerSelection : function(columnElement) { | |
40751 var selectedObjects = []; | |
40752 for (var i = 0; i < GeoTemConfig.datasets.length; i++) | |
40753 selectedObjects.push([]); | |
40754 | |
40755 var selection; | |
40756 if (typeof columnElement !== "undefined"){ | |
40757 selectedObjects[this.watchedDataset] = | |
40758 this.parent.getElementsByValue(columnElement, this.watchedDataset, this.watchColumn, this.selectionFunction); | |
40759 selection = new Selection(selectedObjects, this); | |
40760 } else { | |
40761 selection = new Selection(selectedObjects); | |
40762 } | |
40763 | |
40764 this.parent.core.triggerSelection(selection); | |
40765 | |
40766 if (!selection.valid()){ | |
40767 selection.loadAllObjects(); | |
40768 //"undo" selection (click next to piechart) | |
40769 //so also redraw this dataset | |
40770 this.preHighlightObjects = selection.objects; | |
40771 this.redrawPieChart(selection.objects); | |
40772 } | |
40773 | |
40774 var pieChart = this; | |
40775 $(this.parent.pieCharts).each(function(){ | |
40776 if (this instanceof PieChart && (this !== pieChart)){ | |
40777 if (this.watchedDataset === pieChart.watchedDataset){ | |
40778 this.preHighlightObjects = selection.objects; | |
40779 this.redrawPieChart(selection.objects); | |
40780 } | |
40781 } | |
40782 }); | |
40783 }, | |
40784 | |
40785 deselection : function() { | |
40786 }, | |
40787 | |
40788 filtering : function() { | |
40789 }, | |
40790 | |
40791 inverseFiltering : function() { | |
40792 }, | |
40793 | |
40794 triggerRefining : function() { | |
40795 }, | |
40796 | |
40797 reset : function() { | |
40798 }, | |
40799 | |
40800 show : function() { | |
40801 }, | |
40802 | |
40803 hide : function() { | |
40804 } | |
40805 }; | |
40806 /* | |
40807 * PieChartCategoryChooser.js | |
40808 * | |
40809 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
40810 * | |
40811 * This library is free software; you can redistribute it and/or | |
40812 * modify it under the terms of the GNU Lesser General Public | |
40813 * License as published by the Free Software Foundation; either | |
40814 * version 3 of the License, or (at your option) any later version. | |
40815 * | |
40816 * This library is distributed in the hope that it will be useful, | |
40817 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
40818 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
40819 * Lesser General Public License for more details. | |
40820 * | |
40821 * You should have received a copy of the GNU Lesser General Public | |
40822 * License along with this library; if not, write to the Free Software | |
40823 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
40824 * MA 02110-1301 USA | |
40825 */ | |
40826 | |
40827 /** | |
40828 * @class PieChartCategoryChooser | |
40829 * PieChart dialog for category creation | |
40830 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
40831 * | |
40832 * @param {PieChartWidget} parent PieChart widget object | |
40833 * @param {JSON} options PieChart configuration | |
40834 * @param {number} datasetIndex index of the dataset | |
40835 * @param {String} columnName name of the column | |
40836 */ | |
40837 | |
40838 function PieChartCategoryChooser(pieChart, options, datasetIndex, columnName, type, categories) { | |
40839 | |
40840 var pieChartCategoryChooser = this; | |
40841 | |
40842 this.parent = pieChart; | |
40843 this.options = options; | |
40844 this.datasetIndex = parseInt(datasetIndex); | |
40845 this.columnName = columnName; | |
40846 this.chartData; | |
40847 | |
40848 this.dialog = $("<div></div>"); | |
40849 this.dialog.html("").dialog({modal: true}).dialog('open'); | |
40850 | |
40851 //to asure that the dialog is above (z-index of) the toolbars | |
40852 $(".ui-front").css("z-index","10001"); | |
40853 | |
40854 var allNumeric = this.loadValues(datasetIndex, columnName); | |
40855 | |
40856 if (typeof allNumeric === "undefined") | |
40857 return; | |
40858 if (allNumeric === true){ | |
40859 this.createNumeralBasedChooser(this.chartData, categories); | |
40860 } else { | |
40861 this.createTextBasedChooser(this.chartData, categories); | |
40862 } | |
40863 }; | |
40864 | |
40865 PieChartCategoryChooser.prototype = { | |
40866 | |
40867 loadValues : function(datasetIndex, columnName){ | |
40868 var pieChartCategoryChooser = this; | |
40869 | |
40870 var allNumeric = true; | |
40871 pieChartCategoryChooser.chartData = []; | |
40872 var chartData = pieChartCategoryChooser.chartData; | |
40873 $(GeoTemConfig.datasets[datasetIndex].objects).each(function(){ | |
40874 var columnData = | |
40875 pieChartCategoryChooser.parent.getElementData(this, columnName); | |
40876 | |
40877 if (isNaN(parseFloat(columnData))) | |
40878 allNumeric = false; | |
40879 | |
40880 if ($.inArray(columnData, chartData) == -1) | |
40881 chartData.push(columnData); | |
40882 }); | |
40883 | |
40884 if (chartData.length === 0) | |
40885 return; | |
40886 else | |
40887 return allNumeric; | |
40888 }, | |
40889 | |
40890 createTextBasedChooser : function(chartData, categories){ | |
40891 var pieChartCategoryChooser = this; | |
40892 | |
40893 var addCategory = function(name,elements){ | |
40894 var newCategoryContainer = document.createElement("fieldset"); | |
40895 var newCategoryLegend = document.createElement("legend"); | |
40896 var newCategoryName = document.createElement("input"); | |
40897 $(newCategoryName).width("80%"); | |
40898 newCategoryName.type = "text"; | |
40899 newCategoryName.value = name; | |
40900 var newCategoryRemove = document.createElement("button"); | |
40901 $(newCategoryRemove).text("X"); | |
40902 $(newCategoryRemove).click(function(){ | |
40903 $(newCategoryContainer).find("li").each(function(){ | |
40904 //move all elements to unselected list | |
40905 //("unselected" is defined below) | |
40906 //prepend so the items appear on top | |
40907 $(this).prependTo(unselected); | |
40908 }); | |
40909 //and remove this category | |
40910 $(newCategoryContainer).remove(); | |
40911 }); | |
40912 $(newCategoryLegend).append(newCategoryName); | |
40913 $(newCategoryLegend).append(newCategoryRemove); | |
40914 $(newCategoryContainer).append(newCategoryLegend); | |
40915 $(newCategoryContainer).width("200px"); | |
40916 $(newCategoryContainer).css("float","left"); | |
40917 var newCategory = document.createElement("ul"); | |
40918 $(newCategory).addClass("connectedSortable"); | |
40919 $(newCategory).css("background", "#eee"); | |
40920 newCategoryContainer.appendChild(newCategory); | |
40921 $(newCategory).append("<br/>"); | |
40922 cell.appendChild(newCategoryContainer); | |
40923 //if there are pre-selected elements (e.g. "edit") | |
40924 //add them and remove them from unselected value list | |
40925 if (typeof elements !== "undefined"){ | |
40926 $(elements).each(function(){ | |
40927 var value = this; | |
40928 //add to category | |
40929 $(newCategory).append("<li>"+value+"</li>"); | |
40930 //remove from unselected list | |
40931 $(unselected).find("li").filter(function(){ | |
40932 return ($(this).text() === ""+value); | |
40933 }).remove(); | |
40934 }); | |
40935 } | |
40936 | |
40937 $( ".connectedSortable" ).sortable({ | |
40938 connectWith: ".connectedSortable" | |
40939 }).disableSelection(); | |
40940 }; | |
40941 | |
40942 var table = document.createElement("table"); | |
40943 var row = document.createElement("tr"); | |
40944 table.appendChild(row); | |
40945 var cell = document.createElement("td"); | |
40946 row.appendChild(cell); | |
40947 cell = document.createElement("td"); | |
40948 row.appendChild(cell); | |
40949 var addCategoryButton = document.createElement("button"); | |
40950 $(addCategoryButton).text("add new category"); | |
40951 cell.appendChild(addCategoryButton); | |
40952 var applyCategoryButton = document.createElement("button"); | |
40953 $(applyCategoryButton).text("apply"); | |
40954 cell.appendChild(applyCategoryButton); | |
40955 | |
40956 row = document.createElement("tr"); | |
40957 table.appendChild(row); | |
40958 cell = document.createElement("td"); | |
40959 row.appendChild(cell); | |
40960 var unselected = document.createElement("ul"); | |
40961 $(unselected).addClass("connectedSortable"); | |
40962 cell.appendChild(unselected); | |
40963 cell = document.createElement("td"); | |
40964 $(cell).attr("valign","top"); | |
40965 $(cell).width("100%"); | |
40966 row.appendChild(cell); | |
40967 | |
40968 this.dialog.append(table); | |
40969 | |
40970 $( ".connectedSortable" ).sortable({ | |
40971 connectWith: ".connectedSortable" | |
40972 }).disableSelection(); | |
40973 | |
40974 $(chartData).each(function(){ | |
40975 $(unselected).append("<li class='ui-state-default'>"+this+"</li>"); | |
40976 }); | |
40977 | |
40978 if (typeof categories !== "undefined"){ | |
40979 $(categories).each(function(){ | |
40980 var category = this; | |
40981 addCategory(category.label, category.values); | |
40982 }); | |
40983 } | |
40984 | |
40985 $(addCategoryButton).click(function(){addCategory();}); | |
40986 | |
40987 $(applyCategoryButton).click(function(){ | |
40988 var categories = []; | |
40989 $(cell).children().each(function(){ | |
40990 var label = $(this).find("legend > input").val(); | |
40991 var values = []; | |
40992 $(this).find("li").each(function(){ | |
40993 values.push($(this).text()); | |
40994 }); | |
40995 | |
40996 categories.push({label:label,values:values}); | |
40997 }); | |
40998 | |
40999 var values = []; | |
41000 $(unselected).find("li").each(function(){ | |
41001 values.push($(this).text()); | |
41002 }); | |
41003 | |
41004 categories.push({label:"other",values:values}); | |
41005 | |
41006 //create pie chart | |
41007 pieChartCategoryChooser.parent.addCategorizedPieChart( | |
41008 pieChartCategoryChooser.datasetIndex, pieChartCategoryChooser.columnName, | |
41009 "text", categories); | |
41010 | |
41011 //close dialog | |
41012 $(pieChartCategoryChooser.dialog).dialog("close"); | |
41013 }); | |
41014 | |
41015 //set dialog size | |
41016 var wWidth = $(window).width(); | |
41017 var dWidth = wWidth * 0.9; | |
41018 var wHeight = $(window).height(); | |
41019 var dHeight = wHeight * 0.9; | |
41020 $(this.dialog).dialog("option", "width", dWidth); | |
41021 $(this.dialog).dialog("option", "height", dHeight); | |
41022 }, | |
41023 | |
41024 createNumeralBasedChooser : function(chartData, existingCategories){ | |
41025 var numericChartData = []; | |
41026 for (var i = 0; i < chartData.length; i++){ | |
41027 numericChartData.push(parseFloat(chartData[i])); | |
41028 } | |
41029 chartData = numericChartData; | |
41030 chartData = chartData.sort(function sortNumber(a,b){ | |
41031 return a - b; | |
41032 }); | |
41033 | |
41034 var min = chartData[0]; | |
41035 var max = chartData[chartData.length-1]; | |
41036 //find minimum step width that is needed | |
41037 //(otherwise there could be steps that contain more than one element) | |
41038 var minStep=max-min; | |
41039 for (var i = 1; i < chartData.length; i++){ | |
41040 var thisStep = chartData[i]-chartData[i-1]; | |
41041 if ((thisStep) < minStep) | |
41042 minStep = thisStep; | |
41043 } | |
41044 | |
41045 var pieChartCategoryChooser = this; | |
41046 | |
41047 var addCategoryButton = document.createElement("button"); | |
41048 $(addCategoryButton).text("add new category"); | |
41049 this.dialog.append(addCategoryButton); | |
41050 var applyCategoryButton = document.createElement("button"); | |
41051 $(applyCategoryButton).text("apply"); | |
41052 this.dialog.append(applyCategoryButton); | |
41053 this.dialog.append("tip: use left/right arrow key for finer adjustment"); | |
41054 | |
41055 var table = document.createElement("table"); | |
41056 row = document.createElement("tr"); | |
41057 table.appendChild(row); | |
41058 cell = document.createElement("td"); | |
41059 row.appendChild(cell); | |
41060 cell.colSpan = 2; | |
41061 var slider = document.createElement("div"); | |
41062 cell.appendChild(slider); | |
41063 var handles = []; | |
41064 var categories = []; | |
41065 | |
41066 row = document.createElement("tr"); | |
41067 table.appendChild(row); | |
41068 cell = document.createElement("td"); | |
41069 $(cell).attr("valign","top"); | |
41070 row.appendChild(cell); | |
41071 var unselected = document.createElement("ul"); | |
41072 cell.appendChild(unselected); | |
41073 | |
41074 cell = document.createElement("td"); | |
41075 $(cell).attr("valign","top"); | |
41076 $(cell).width("100%"); | |
41077 row.appendChild(cell); | |
41078 | |
41079 this.dialog.append(table); | |
41080 | |
41081 $(chartData).each(function(){ | |
41082 $(unselected).append("<li class='ui-state-default'>"+this+"</li>"); | |
41083 }); | |
41084 | |
41085 var addCategory = function(boundary){ | |
41086 //check if another handle can be added | |
41087 if ((handles.length>0) && (handles[handles.length-1] === max)) | |
41088 return false; | |
41089 //destroy old slider (has to be recreated to show the new handle) | |
41090 if (handles.length>0) | |
41091 $(slider).slider("destroy"); | |
41092 | |
41093 if (typeof boundary === "undefined") | |
41094 boundary = max; | |
41095 handles.push(boundary); | |
41096 | |
41097 $(slider).slider({ | |
41098 min:min, | |
41099 max:max, | |
41100 step:minStep, | |
41101 values: handles | |
41102 }); | |
41103 | |
41104 var placeValues = function(){ | |
41105 $(unselected).find("li").remove(); | |
41106 $(cell).children().find("li").remove(); | |
41107 | |
41108 var j = 0, i = 0; | |
41109 for (; i < chartData.length; i++){ | |
41110 if (chartData[i]>handles[j]) | |
41111 j++; | |
41112 if (j == handles.length) | |
41113 break; | |
41114 $(categories[j]).append("<li class='ui-state-default'>"+chartData[i]+"</li>"); | |
41115 } | |
41116 for (; i < chartData.length; i++){ | |
41117 $(unselected).append("<li class='ui-state-default'>"+chartData[i]+"</li>"); | |
41118 } | |
41119 }; | |
41120 | |
41121 $(slider).on( "slide", function( event, ui ){ | |
41122 var last = min; | |
41123 //check whether handle values are increasing | |
41124 for(var i = 0; i < ui.values.length; i++){ | |
41125 if (ui.values[i]<last) | |
41126 return false; | |
41127 last = ui.values[i]; | |
41128 } | |
41129 handles = ui.values; | |
41130 for(var i = 0; i < handles.length; i++){ | |
41131 $(categories[i]).parent().find("legend").text("<="+handles[i]); | |
41132 } | |
41133 | |
41134 placeValues(); | |
41135 }); | |
41136 | |
41137 var newCategoryContainer = document.createElement("fieldset"); | |
41138 $(newCategoryContainer).append("<legend><="+boundary+"</legend>"); | |
41139 $(newCategoryContainer).width("188px"); | |
41140 $(newCategoryContainer).css("float","left"); | |
41141 var newCategory = document.createElement("ul"); | |
41142 $(newCategory).addClass("connectedSortable"); | |
41143 $(newCategory).css("background", "#eee"); | |
41144 newCategoryContainer.appendChild(newCategory); | |
41145 cell.appendChild(newCategoryContainer); | |
41146 categories.push(newCategory); | |
41147 | |
41148 placeValues(); | |
41149 }; | |
41150 | |
41151 $(addCategoryButton).click(function(){addCategory();}); | |
41152 | |
41153 if (typeof existingCategories !== "undefined"){ | |
41154 $(existingCategories).each(function(){ | |
41155 var boundary = this; | |
41156 addCategory(boundary); | |
41157 }); | |
41158 } | |
41159 | |
41160 $(applyCategoryButton).click(function(){ | |
41161 var categorieBoundaries = handles; | |
41162 | |
41163 //create pie chart | |
41164 pieChartCategoryChooser.parent.addCategorizedPieChart( | |
41165 pieChartCategoryChooser.datasetIndex, pieChartCategoryChooser.columnName, | |
41166 "numeral", categorieBoundaries); | |
41167 | |
41168 //close dialog | |
41169 $(pieChartCategoryChooser.dialog).dialog("close"); | |
41170 }); | |
41171 | |
41172 //set dialog size | |
41173 var wWidth = $(window).width(); | |
41174 var dWidth = wWidth * 0.9; | |
41175 var wHeight = $(window).height(); | |
41176 var dHeight = wHeight * 0.9; | |
41177 $(this.dialog).dialog("option", "width", dWidth); | |
41178 $(this.dialog).dialog("option", "height", dHeight); | |
41179 } | |
41180 }; | |
41181 /* | |
41182 * PieChartConfig.js | |
41183 * | |
41184 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41185 * | |
41186 * This library is free software; you can redistribute it and/or | |
41187 * modify it under the terms of the GNU Lesser General Public | |
41188 * License as published by the Free Software Foundation; either | |
41189 * version 3 of the License, or (at your option) any later version. | |
41190 * | |
41191 * This library is distributed in the hope that it will be useful, | |
41192 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41193 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41194 * Lesser General Public License for more details. | |
41195 * | |
41196 * You should have received a copy of the GNU Lesser General Public | |
41197 * License along with this library; if not, write to the Free Software | |
41198 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41199 * MA 02110-1301 USA | |
41200 */ | |
41201 | |
41202 /** | |
41203 * @class PieChartConfig | |
41204 * PieChart Configuration File | |
41205 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41206 */ | |
41207 function PieChartConfig(options) { | |
41208 | |
41209 this.options = { | |
41210 proxy : 'php/proxy.php?address=', | |
41211 restrictPieChartSize : 0.25, // restrict size to percantage of window size (false for no restriction) | |
41212 localStoragePrefix : "GeoBrowser_PieChart_", // prefix for value name in LocalStorage | |
41213 allowLocalStorage : true, //whether LocalStorage save and load should be allowed (and buttons shown) | |
41214 }; | |
41215 if ( typeof options != 'undefined') { | |
41216 $.extend(this.options, options); | |
41217 } | |
41218 | |
41219 }; | |
41220 /* | |
41221 * PieChartGui.js | |
41222 * | |
41223 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41224 * | |
41225 * This library is free software; you can redistribute it and/or | |
41226 * modify it under the terms of the GNU Lesser General Public | |
41227 * License as published by the Free Software Foundation; either | |
41228 * version 3 of the License, or (at your option) any later version. | |
41229 * | |
41230 * This library is distributed in the hope that it will be useful, | |
41231 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41232 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41233 * Lesser General Public License for more details. | |
41234 * | |
41235 * You should have received a copy of the GNU Lesser General Public | |
41236 * License along with this library; if not, write to the Free Software | |
41237 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41238 * MA 02110-1301 USA | |
41239 */ | |
41240 | |
41241 /** | |
41242 * @class PieChartGui | |
41243 * PieChart GUI Implementation | |
41244 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41245 * | |
41246 * @param {PieChartWidget} parent PieChart widget object | |
41247 * @param {HTML object} div parent div to append the PieChart gui | |
41248 * @param {JSON} options PieChart configuration | |
41249 */ | |
41250 function PieChartGui(pieChart, div, options) { | |
41251 | |
41252 this.parent = pieChart; | |
41253 this.options = options; | |
41254 var pieChartGui = this; | |
41255 | |
41256 this.pieChartContainer = div; | |
41257 this.pieChartContainer.style.position = 'relative'; | |
41258 | |
41259 this.columnSelectorDiv = document.createElement("div"); | |
41260 div.appendChild(this.columnSelectorDiv); | |
41261 this.datasetSelect = document.createElement("select"); | |
41262 $(this.datasetSelect).change(function(event){ | |
41263 if (typeof pieChartGui.parent.datasets !== "undefined"){ | |
41264 var dataset = pieChartGui.parent.datasets[$(pieChartGui.datasetSelect).val()]; | |
41265 if (dataset.objects.length > 0){ | |
41266 //This implies that the dataObjects are homogenous | |
41267 var firstObject = dataset.objects[0]; | |
41268 var firstTableContent = firstObject.tableContent; | |
41269 $(pieChartGui.columnSelect).empty(); | |
41270 | |
41271 $(pieChartGui.columnSelect).append("<optgroup label='saved'>"); | |
41272 | |
41273 for(var key in localStorage){ | |
41274 //TODO: this is a somewhat bad idea, as it is used in multiple widgets. | |
41275 //A global GeoTemCo option "prefix" could be better. But still.. | |
41276 var prefix = pieChartGui.options.localStoragePrefix; | |
41277 if (key.startsWith(prefix)){ | |
41278 var saveObject = $.remember({name:key,json:true}); | |
41279 var label = key.substring(prefix.length); | |
41280 //small safety-check: if the column is not part of this dataset, don't show it | |
41281 if (typeof firstTableContent[saveObject.columnName] !== "undefined") | |
41282 $(pieChartGui.columnSelect).append("<option isSaved=1 value='"+label+"'>"+decodeURIComponent(label)+"</option>"); | |
41283 } | |
41284 } | |
41285 $(pieChartGui.columnSelect).append("</optgroup>"); | |
41286 | |
41287 $(pieChartGui.columnSelect).append("<optgroup label='new'>"); | |
41288 for (var attribute in firstTableContent) { | |
41289 $(pieChartGui.columnSelect).append("<option value='"+attribute+"'>"+attribute+"</option>"); | |
41290 } | |
41291 if (firstObject.isTemporal) | |
41292 $(pieChartGui.columnSelect).append("<option value='dates[0].date'>date</option>"); | |
41293 if (typeof firstObject.locations[0] !== "undefined"){ | |
41294 $(pieChartGui.columnSelect).append("<option value='locations[0].latitude'>lat</option>"); | |
41295 $(pieChartGui.columnSelect).append("<option value='locations[0].longitude'>lon</option>"); | |
41296 } | |
41297 $(pieChartGui.columnSelect).append("</optgroup>"); | |
41298 } | |
41299 } | |
41300 }); | |
41301 this.columnSelectorDiv.appendChild(this.datasetSelect); | |
41302 this.columnSelect = document.createElement("select"); | |
41303 this.columnSelectorDiv.appendChild(this.columnSelect); | |
41304 this.buttonNewPieChart = document.createElement("button"); | |
41305 $(this.buttonNewPieChart).text("add"); | |
41306 this.columnSelectorDiv.appendChild(this.buttonNewPieChart); | |
41307 $(this.buttonNewPieChart).click(function(){ | |
41308 //check if this is a local saved pie chart | |
41309 var isSaved=$(pieChartGui.columnSelect).find("option:selected").first().attr("isSaved"); | |
41310 if ((typeof isSaved === "undefined") || (isSaved!=1)){ | |
41311 //create new pie chart (where each value is its own category) | |
41312 pieChartGui.parent.addPieChart($(pieChartGui.datasetSelect).val(), $(pieChartGui.columnSelect).val()); | |
41313 } else { | |
41314 //is local saved, get value | |
41315 var name = pieChartGui.options.localStoragePrefix + $(pieChartGui.columnSelect).val(); | |
41316 var saveObject = $.remember({name:name,json:true}); | |
41317 if ((typeof saveObject !== "undefined") && (saveObject != null)){ | |
41318 var categories = saveObject.categories; | |
41319 var type = saveObject.type; | |
41320 var columnName = saveObject.columnName; | |
41321 | |
41322 //create pie chart | |
41323 pieChartGui.parent.addCategorizedPieChart( | |
41324 $(pieChartGui.datasetSelect).val(), columnName, | |
41325 type, categories); | |
41326 } | |
41327 } | |
41328 }); | |
41329 this.buttonPieChartCategoryChooser = document.createElement("button"); | |
41330 $(this.buttonPieChartCategoryChooser).text("categorize"); | |
41331 this.columnSelectorDiv.appendChild(this.buttonPieChartCategoryChooser); | |
41332 $(this.buttonPieChartCategoryChooser).click(function(){ | |
41333 //check if this is a local saved pie chart | |
41334 var isSaved=$(pieChartGui.columnSelect).find("option:selected").first().attr("isSaved"); | |
41335 if ((typeof isSaved === "undefined") || (isSaved!=1)){ | |
41336 var chooser = new PieChartCategoryChooser( pieChartGui.parent, | |
41337 pieChartGui.options, | |
41338 $(pieChartGui.datasetSelect).val(), | |
41339 $(pieChartGui.columnSelect).val() ); | |
41340 } else { | |
41341 alert("Saved datasets can not be categorized again. Try loading and editing instead."); | |
41342 } | |
41343 }); | |
41344 | |
41345 this.refreshColumnSelector(); | |
41346 | |
41347 this.pieChartsDiv = document.createElement("div"); | |
41348 this.pieChartsDiv.id = "pieChartsDivID"; | |
41349 div.appendChild(this.pieChartsDiv); | |
41350 $(this.pieChartsDiv).height("100%"); | |
41351 }; | |
41352 | |
41353 PieChartGui.prototype = { | |
41354 | |
41355 refreshColumnSelector : function(){ | |
41356 $(this.datasetSelect).empty(); | |
41357 $(this.columnSelect).empty(); | |
41358 | |
41359 if ( (typeof this.parent.datasets !== "undefined") && (this.parent.datasets.length > 0)) { | |
41360 var index = 0; | |
41361 var pieChartGui = this; | |
41362 $(this.parent.datasets).each(function(){ | |
41363 $(pieChartGui.datasetSelect).append("<option value="+index+">"+this.label+"</option>"); | |
41364 index++; | |
41365 }); | |
41366 | |
41367 $(pieChartGui.datasetSelect).change(); | |
41368 } | |
41369 } | |
41370 }; | |
41371 /* | |
41372 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message | |
41373 * Digest Algorithm, as defined in RFC 1321. | |
41374 * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 | |
41375 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet | |
41376 * Distributed under the BSD License | |
41377 * See http://pajhome.org.uk/crypt/md5 for more info. | |
41378 */ | |
41379 | |
41380 /* | |
41381 * Configurable variables. You may need to tweak these to be compatible with | |
41382 * the server-side, but the defaults work in most cases. | |
41383 */ | |
41384 var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ | |
41385 var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ | |
41386 | |
41387 /* | |
41388 * These are the functions you'll usually want to call | |
41389 * They take string arguments and return either hex or base-64 encoded strings | |
41390 */ | |
41391 function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); } | |
41392 function b64_md5(s) { return rstr2b64(rstr_md5(str2rstr_utf8(s))); } | |
41393 function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); } | |
41394 function hex_hmac_md5(k, d) | |
41395 { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } | |
41396 function b64_hmac_md5(k, d) | |
41397 { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); } | |
41398 function any_hmac_md5(k, d, e) | |
41399 { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); } | |
41400 | |
41401 /* | |
41402 * Perform a simple self-test to see if the VM is working | |
41403 */ | |
41404 function md5_vm_test() | |
41405 { | |
41406 return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72"; | |
41407 } | |
41408 | |
41409 /* | |
41410 * Calculate the MD5 of a raw string | |
41411 */ | |
41412 function rstr_md5(s) | |
41413 { | |
41414 return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); | |
41415 } | |
41416 | |
41417 /* | |
41418 * Calculate the HMAC-MD5, of a key and some data (raw strings) | |
41419 */ | |
41420 function rstr_hmac_md5(key, data) | |
41421 { | |
41422 var bkey = rstr2binl(key); | |
41423 if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8); | |
41424 | |
41425 var ipad = Array(16), opad = Array(16); | |
41426 for(var i = 0; i < 16; i++) | |
41427 { | |
41428 ipad[i] = bkey[i] ^ 0x36363636; | |
41429 opad[i] = bkey[i] ^ 0x5C5C5C5C; | |
41430 } | |
41431 | |
41432 var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); | |
41433 return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); | |
41434 } | |
41435 | |
41436 /* | |
41437 * Convert a raw string to a hex string | |
41438 */ | |
41439 function rstr2hex(input) | |
41440 { | |
41441 try { hexcase } catch(e) { hexcase=0; } | |
41442 var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; | |
41443 var output = ""; | |
41444 var x; | |
41445 for(var i = 0; i < input.length; i++) | |
41446 { | |
41447 x = input.charCodeAt(i); | |
41448 output += hex_tab.charAt((x >>> 4) & 0x0F) | |
41449 + hex_tab.charAt( x & 0x0F); | |
41450 } | |
41451 return output; | |
41452 } | |
41453 | |
41454 /* | |
41455 * Convert a raw string to a base-64 string | |
41456 */ | |
41457 function rstr2b64(input) | |
41458 { | |
41459 try { b64pad } catch(e) { b64pad=''; } | |
41460 var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
41461 var output = ""; | |
41462 var len = input.length; | |
41463 for(var i = 0; i < len; i += 3) | |
41464 { | |
41465 var triplet = (input.charCodeAt(i) << 16) | |
41466 | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0) | |
41467 | (i + 2 < len ? input.charCodeAt(i+2) : 0); | |
41468 for(var j = 0; j < 4; j++) | |
41469 { | |
41470 if(i * 8 + j * 6 > input.length * 8) output += b64pad; | |
41471 else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F); | |
41472 } | |
41473 } | |
41474 return output; | |
41475 } | |
41476 | |
41477 /* | |
41478 * Convert a raw string to an arbitrary string encoding | |
41479 */ | |
41480 function rstr2any(input, encoding) | |
41481 { | |
41482 var divisor = encoding.length; | |
41483 var i, j, q, x, quotient; | |
41484 | |
41485 /* Convert to an array of 16-bit big-endian values, forming the dividend */ | |
41486 var dividend = Array(Math.ceil(input.length / 2)); | |
41487 for(i = 0; i < dividend.length; i++) | |
41488 { | |
41489 dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1); | |
41490 } | |
41491 | |
41492 /* | |
41493 * Repeatedly perform a long division. The binary array forms the dividend, | |
41494 * the length of the encoding is the divisor. Once computed, the quotient | |
41495 * forms the dividend for the next step. All remainders are stored for later | |
41496 * use. | |
41497 */ | |
41498 var full_length = Math.ceil(input.length * 8 / | |
41499 (Math.log(encoding.length) / Math.log(2))); | |
41500 var remainders = Array(full_length); | |
41501 for(j = 0; j < full_length; j++) | |
41502 { | |
41503 quotient = Array(); | |
41504 x = 0; | |
41505 for(i = 0; i < dividend.length; i++) | |
41506 { | |
41507 x = (x << 16) + dividend[i]; | |
41508 q = Math.floor(x / divisor); | |
41509 x -= q * divisor; | |
41510 if(quotient.length > 0 || q > 0) | |
41511 quotient[quotient.length] = q; | |
41512 } | |
41513 remainders[j] = x; | |
41514 dividend = quotient; | |
41515 } | |
41516 | |
41517 /* Convert the remainders to the output string */ | |
41518 var output = ""; | |
41519 for(i = remainders.length - 1; i >= 0; i--) | |
41520 output += encoding.charAt(remainders[i]); | |
41521 | |
41522 return output; | |
41523 } | |
41524 | |
41525 /* | |
41526 * Encode a string as utf-8. | |
41527 * For efficiency, this assumes the input is valid utf-16. | |
41528 */ | |
41529 function str2rstr_utf8(input) | |
41530 { | |
41531 var output = ""; | |
41532 var i = -1; | |
41533 var x, y; | |
41534 | |
41535 while(++i < input.length) | |
41536 { | |
41537 /* Decode utf-16 surrogate pairs */ | |
41538 x = input.charCodeAt(i); | |
41539 y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0; | |
41540 if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) | |
41541 { | |
41542 x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF); | |
41543 i++; | |
41544 } | |
41545 | |
41546 /* Encode output as utf-8 */ | |
41547 if(x <= 0x7F) | |
41548 output += String.fromCharCode(x); | |
41549 else if(x <= 0x7FF) | |
41550 output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F), | |
41551 0x80 | ( x & 0x3F)); | |
41552 else if(x <= 0xFFFF) | |
41553 output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), | |
41554 0x80 | ((x >>> 6 ) & 0x3F), | |
41555 0x80 | ( x & 0x3F)); | |
41556 else if(x <= 0x1FFFFF) | |
41557 output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), | |
41558 0x80 | ((x >>> 12) & 0x3F), | |
41559 0x80 | ((x >>> 6 ) & 0x3F), | |
41560 0x80 | ( x & 0x3F)); | |
41561 } | |
41562 return output; | |
41563 } | |
41564 | |
41565 /* | |
41566 * Encode a string as utf-16 | |
41567 */ | |
41568 function str2rstr_utf16le(input) | |
41569 { | |
41570 var output = ""; | |
41571 for(var i = 0; i < input.length; i++) | |
41572 output += String.fromCharCode( input.charCodeAt(i) & 0xFF, | |
41573 (input.charCodeAt(i) >>> 8) & 0xFF); | |
41574 return output; | |
41575 } | |
41576 | |
41577 function str2rstr_utf16be(input) | |
41578 { | |
41579 var output = ""; | |
41580 for(var i = 0; i < input.length; i++) | |
41581 output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF, | |
41582 input.charCodeAt(i) & 0xFF); | |
41583 return output; | |
41584 } | |
41585 | |
41586 /* | |
41587 * Convert a raw string to an array of little-endian words | |
41588 * Characters >255 have their high-byte silently ignored. | |
41589 */ | |
41590 function rstr2binl(input) | |
41591 { | |
41592 var output = Array(input.length >> 2); | |
41593 for(var i = 0; i < output.length; i++) | |
41594 output[i] = 0; | |
41595 for(var i = 0; i < input.length * 8; i += 8) | |
41596 output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32); | |
41597 return output; | |
41598 } | |
41599 | |
41600 /* | |
41601 * Convert an array of little-endian words to a string | |
41602 */ | |
41603 function binl2rstr(input) | |
41604 { | |
41605 var output = ""; | |
41606 for(var i = 0; i < input.length * 32; i += 8) | |
41607 output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF); | |
41608 return output; | |
41609 } | |
41610 | |
41611 /* | |
41612 * Calculate the MD5 of an array of little-endian words, and a bit length. | |
41613 */ | |
41614 function binl_md5(x, len) | |
41615 { | |
41616 /* append padding */ | |
41617 x[len >> 5] |= 0x80 << ((len) % 32); | |
41618 x[(((len + 64) >>> 9) << 4) + 14] = len; | |
41619 | |
41620 var a = 1732584193; | |
41621 var b = -271733879; | |
41622 var c = -1732584194; | |
41623 var d = 271733878; | |
41624 | |
41625 for(var i = 0; i < x.length; i += 16) | |
41626 { | |
41627 var olda = a; | |
41628 var oldb = b; | |
41629 var oldc = c; | |
41630 var oldd = d; | |
41631 | |
41632 a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); | |
41633 d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); | |
41634 c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); | |
41635 b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); | |
41636 a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); | |
41637 d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); | |
41638 c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); | |
41639 b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); | |
41640 a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); | |
41641 d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); | |
41642 c = md5_ff(c, d, a, b, x[i+10], 17, -42063); | |
41643 b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); | |
41644 a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); | |
41645 d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); | |
41646 c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); | |
41647 b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); | |
41648 | |
41649 a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); | |
41650 d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); | |
41651 c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); | |
41652 b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); | |
41653 a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); | |
41654 d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); | |
41655 c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); | |
41656 b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); | |
41657 a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); | |
41658 d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); | |
41659 c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); | |
41660 b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); | |
41661 a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); | |
41662 d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); | |
41663 c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); | |
41664 b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); | |
41665 | |
41666 a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); | |
41667 d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); | |
41668 c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); | |
41669 b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); | |
41670 a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); | |
41671 d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); | |
41672 c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); | |
41673 b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); | |
41674 a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); | |
41675 d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); | |
41676 c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); | |
41677 b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); | |
41678 a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); | |
41679 d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); | |
41680 c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); | |
41681 b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); | |
41682 | |
41683 a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); | |
41684 d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); | |
41685 c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); | |
41686 b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); | |
41687 a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); | |
41688 d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); | |
41689 c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); | |
41690 b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); | |
41691 a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); | |
41692 d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); | |
41693 c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); | |
41694 b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); | |
41695 a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); | |
41696 d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); | |
41697 c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); | |
41698 b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); | |
41699 | |
41700 a = safe_add(a, olda); | |
41701 b = safe_add(b, oldb); | |
41702 c = safe_add(c, oldc); | |
41703 d = safe_add(d, oldd); | |
41704 } | |
41705 return Array(a, b, c, d); | |
41706 } | |
41707 | |
41708 /* | |
41709 * These functions implement the four basic operations the algorithm uses. | |
41710 */ | |
41711 function md5_cmn(q, a, b, x, s, t) | |
41712 { | |
41713 return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); | |
41714 } | |
41715 function md5_ff(a, b, c, d, x, s, t) | |
41716 { | |
41717 return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); | |
41718 } | |
41719 function md5_gg(a, b, c, d, x, s, t) | |
41720 { | |
41721 return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); | |
41722 } | |
41723 function md5_hh(a, b, c, d, x, s, t) | |
41724 { | |
41725 return md5_cmn(b ^ c ^ d, a, b, x, s, t); | |
41726 } | |
41727 function md5_ii(a, b, c, d, x, s, t) | |
41728 { | |
41729 return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); | |
41730 } | |
41731 | |
41732 /* | |
41733 * Add integers, wrapping at 2^32. This uses 16-bit operations internally | |
41734 * to work around bugs in some JS interpreters. | |
41735 */ | |
41736 function safe_add(x, y) | |
41737 { | |
41738 var lsw = (x & 0xFFFF) + (y & 0xFFFF); | |
41739 var msw = (x >> 16) + (y >> 16) + (lsw >> 16); | |
41740 return (msw << 16) | (lsw & 0xFFFF); | |
41741 } | |
41742 | |
41743 /* | |
41744 * Bitwise rotate a 32-bit number to the left. | |
41745 */ | |
41746 function bit_rol(num, cnt) | |
41747 { | |
41748 return (num << cnt) | (num >>> (32 - cnt)); | |
41749 } | |
41750 /* | |
41751 * PieChartWidget.js | |
41752 * | |
41753 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41754 * | |
41755 * This library is free software; you can redistribute it and/or | |
41756 * modify it under the terms of the GNU Lesser General Public | |
41757 * License as published by the Free Software Foundation; either | |
41758 * version 3 of the License, or (at your option) any later version. | |
41759 * | |
41760 * This library is distributed in the hope that it will be useful, | |
41761 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41762 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41763 * Lesser General Public License for more details. | |
41764 * | |
41765 * You should have received a copy of the GNU Lesser General Public | |
41766 * License along with this library; if not, write to the Free Software | |
41767 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41768 * MA 02110-1301 USA | |
41769 */ | |
41770 | |
41771 /** | |
41772 * @class PieChartWidget | |
41773 * PieChartWidget Implementation | |
41774 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41775 * | |
41776 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
41777 * @param {HTML object} div parent div to append the PieChart widget div | |
41778 * @param {JSON} options user specified configuration that overwrites options in PieChartConfig.js | |
41779 */ | |
41780 PieChartWidget = function(core, div, options) { | |
41781 | |
41782 this.datasets; | |
41783 this.selected; | |
41784 this.core = core; | |
41785 this.core.setWidget(this); | |
41786 | |
41787 this.options = (new PieChartConfig(options)).options; | |
41788 this.gui = new PieChartGui(this, div, this.options); | |
41789 | |
41790 this.pieCharts = []; | |
41791 } | |
41792 | |
41793 PieChartWidget.prototype = { | |
41794 | |
41795 addCategorizedPieChart : function(watchedDataset, watchedColumn, type, categories){ | |
41796 var selectionFunction; | |
41797 if (type === "text"){ | |
41798 //create selection function for the pie chart | |
41799 var selectionFunction = function(columnData){ | |
41800 var categoryLabel; | |
41801 $(categories).each(function(){ | |
41802 if ($.inArray(columnData,this.values) != -1){ | |
41803 categoryLabel = this.label; | |
41804 //exit .each | |
41805 return false; | |
41806 } | |
41807 if (typeof categoryLabel !== "undefined") | |
41808 return false; | |
41809 }); | |
41810 | |
41811 if (typeof categoryLabel === "undefined") | |
41812 categoryLabel = "unknown"; | |
41813 | |
41814 return categoryLabel; | |
41815 }; | |
41816 } else if (type === "numeral"){ | |
41817 //create selection function for the pie chart | |
41818 var selectionFunction = function(columnData){ | |
41819 var categoryLabel; | |
41820 var columnDataNumeric = parseFloat(columnData); | |
41821 for (var i = 0; i < categories.length; i++){ | |
41822 if (columnDataNumeric<=categories[i]){ | |
41823 categoryLabel = pieChartCategoryChooser.columnName + "<=" + categories[i]; | |
41824 break; | |
41825 } | |
41826 } | |
41827 | |
41828 if (typeof categoryLabel === "undefined") | |
41829 categoryLabel = "unknown"; | |
41830 | |
41831 return categoryLabel; | |
41832 }; | |
41833 } else | |
41834 return; | |
41835 | |
41836 //make categories easy accessible for later usage | |
41837 selectionFunction.type = type; | |
41838 selectionFunction.categories = categories; | |
41839 | |
41840 this.addPieChart(watchedDataset, watchedColumn, selectionFunction); | |
41841 }, | |
41842 | |
41843 addPieChart : function(watchedDataset, watchedColumn, selectionFunction){ | |
41844 var newPieChart = new PieChart(this, watchedDataset, watchedColumn, selectionFunction); | |
41845 this.pieCharts.push(newPieChart); | |
41846 if ( (typeof GeoTemConfig.datasets !== "undefined") && | |
41847 (GeoTemConfig.datasets.length > watchedDataset) ) | |
41848 newPieChart.initPieChart(GeoTemConfig.datasets); | |
41849 this.redrawPieCharts(this.selected); | |
41850 }, | |
41851 | |
41852 initWidget : function(data) { | |
41853 var piechart = this; | |
41854 this.datasets = data; | |
41855 piechart.selected = []; | |
41856 $(this.datasets).each(function(){ | |
41857 piechart.selected.push(this.objects); | |
41858 }) | |
41859 | |
41860 this.gui.refreshColumnSelector(); | |
41861 | |
41862 $(this.pieCharts).each(function(){ | |
41863 if (this instanceof PieChart) | |
41864 this.initPieChart(data); | |
41865 }); | |
41866 }, | |
41867 | |
41868 redrawPieCharts : function(objects, overwrite) { | |
41869 $(this.pieCharts).each(function(){ | |
41870 if (this instanceof PieChart){ | |
41871 if ( (typeof overwrite !== "undefined") && overwrite) | |
41872 this.preHighlightObjects = objects; | |
41873 this.redrawPieChart(objects); | |
41874 } | |
41875 }); | |
41876 }, | |
41877 | |
41878 highlightChanged : function(objects) { | |
41879 if( !GeoTemConfig.highlightEvents ){ | |
41880 return; | |
41881 } | |
41882 if ( (typeof objects === "undefined") || (objects.length == 0) ){ | |
41883 return; | |
41884 } | |
41885 this.redrawPieCharts(objects, false); | |
41886 }, | |
41887 | |
41888 selectionChanged : function(selection) { | |
41889 if( !GeoTemConfig.selectionEvents ){ | |
41890 return; | |
41891 } | |
41892 if (!selection.valid()){ | |
41893 selection.loadAllObjects(); | |
41894 } | |
41895 var objects = selection.objects; | |
41896 this.selected = objects; | |
41897 this.redrawPieCharts(objects, true); | |
41898 }, | |
41899 | |
41900 getElementData : function(dataObject, watchedColumn, selectionFunction) { | |
41901 var columnData; | |
41902 if (watchedColumn.indexOf("[") === -1){ | |
41903 columnData = dataObject[watchedColumn]; | |
41904 if (typeof columnData === "undefined"){ | |
41905 columnData = dataObject.tableContent[watchedColumn]; | |
41906 }; | |
41907 } else { | |
41908 try { | |
41909 var columnName = watchedColumn.split("[")[0]; | |
41910 var IndexAndAttribute = watchedColumn.split("[")[1]; | |
41911 if (IndexAndAttribute.indexOf("]") != -1){ | |
41912 var arrayIndex = IndexAndAttribute.split("]")[0]; | |
41913 var attribute = IndexAndAttribute.split("]")[1]; | |
41914 | |
41915 if (typeof attribute === "undefined") | |
41916 columnData = dataObject[columnName][arrayIndex]; | |
41917 else{ | |
41918 attribute = attribute.split(".")[1]; | |
41919 columnData = dataObject[columnName][arrayIndex][attribute]; | |
41920 } | |
41921 } | |
41922 } catch(e) { | |
41923 if (typeof console !== undefined) | |
41924 console.error(e); | |
41925 | |
41926 delete columnData; | |
41927 } | |
41928 } | |
41929 | |
41930 if ( (typeof columnData !== "undefined") && (typeof selectionFunction !== "undefined") ) | |
41931 columnData = selectionFunction(columnData); | |
41932 | |
41933 return(columnData); | |
41934 }, | |
41935 | |
41936 getElementsByValue : function(columnValue, watchedDataset, watchedColumn, selectionFunction) { | |
41937 var elements = []; | |
41938 var pieChart = this; | |
41939 | |
41940 $(this.datasets[watchedDataset].objects).each(function(){ | |
41941 var columnData = pieChart.getElementData(this, watchedColumn, selectionFunction); | |
41942 if (columnData === columnValue) | |
41943 elements.push(this); | |
41944 }); | |
41945 | |
41946 return elements; | |
41947 }, | |
41948 }; | |
41949 /* | |
41950 * Storytelling.js | |
41951 * | |
41952 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
41953 * | |
41954 * This library is free software; you can redistribute it and/or | |
41955 * modify it under the terms of the GNU Lesser General Public | |
41956 * License as published by the Free Software Foundation; either | |
41957 * version 3 of the License, or (at your option) any later version. | |
41958 * | |
41959 * This library is distributed in the hope that it will be useful, | |
41960 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
41961 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41962 * Lesser General Public License for more details. | |
41963 * | |
41964 * You should have received a copy of the GNU Lesser General Public | |
41965 * License along with this library; if not, write to the Free Software | |
41966 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
41967 * MA 02110-1301 USA | |
41968 */ | |
41969 | |
41970 /** | |
41971 * @class Storytelling | |
41972 * Implementation of story telling "storage" | |
41973 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
41974 * | |
41975 * @param {HTML object} parent div to append the Storytelling widget | |
41976 */ | |
41977 function Storytelling(parent) { | |
41978 | |
41979 this.index; | |
41980 this.storytelling = this; | |
41981 | |
41982 this.parent = parent; | |
41983 this.options = parent.options; | |
41984 | |
41985 this.initialize(); | |
41986 } | |
41987 | |
41988 Storytelling.prototype = { | |
41989 | |
41990 remove : function() { | |
41991 }, | |
41992 | |
41993 initialize : function() { | |
41994 }, | |
41995 | |
41996 triggerHighlight : function(columnElement) { | |
41997 }, | |
41998 | |
41999 triggerSelection : function(columnElement) { | |
42000 }, | |
42001 | |
42002 deselection : function() { | |
42003 }, | |
42004 | |
42005 filtering : function() { | |
42006 }, | |
42007 | |
42008 inverseFiltering : function() { | |
42009 }, | |
42010 | |
42011 triggerRefining : function() { | |
42012 }, | |
42013 | |
42014 reset : function() { | |
42015 }, | |
42016 | |
42017 show : function() { | |
42018 }, | |
42019 | |
42020 hide : function() { | |
42021 } | |
42022 }; | |
42023 /* | |
42024 * StorytellingConfig.js | |
42025 * | |
42026 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42027 * | |
42028 * This library is free software; you can redistribute it and/or | |
42029 * modify it under the terms of the GNU Lesser General Public | |
42030 * License as published by the Free Software Foundation; either | |
42031 * version 3 of the License, or (at your option) any later version. | |
42032 * | |
42033 * This library is distributed in the hope that it will be useful, | |
42034 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42035 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42036 * Lesser General Public License for more details. | |
42037 * | |
42038 * You should have received a copy of the GNU Lesser General Public | |
42039 * License along with this library; if not, write to the Free Software | |
42040 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42041 * MA 02110-1301 USA | |
42042 */ | |
42043 | |
42044 /** | |
42045 * @class StorytellingConfig | |
42046 * Storytelling Configuration File | |
42047 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42048 */ | |
42049 function StorytellingConfig(options) { | |
42050 | |
42051 this.options = { | |
42052 proxy : 'php/proxy.php?address=', | |
42053 dariahStorage : false, | |
42054 localStorage : true | |
42055 }; | |
42056 if ( typeof options != 'undefined') { | |
42057 $.extend(this.options, options); | |
42058 } | |
42059 | |
42060 }; | |
42061 /* | |
42062 * StorytellingGui.js | |
42063 * | |
42064 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42065 * | |
42066 * This library is free software; you can redistribute it and/or | |
42067 * modify it under the terms of the GNU Lesser General Public | |
42068 * License as published by the Free Software Foundation; either | |
42069 * version 3 of the License, or (at your option) any later version. | |
42070 * | |
42071 * This library is distributed in the hope that it will be useful, | |
42072 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42073 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42074 * Lesser General Public License for more details. | |
42075 * | |
42076 * You should have received a copy of the GNU Lesser General Public | |
42077 * License along with this library; if not, write to the Free Software | |
42078 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42079 * MA 02110-1301 USA | |
42080 */ | |
42081 | |
42082 /** | |
42083 * @class StorytellingGui | |
42084 * Storytelling GUI Implementation | |
42085 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42086 * | |
42087 * @param {StorytellingWidget} parent Storytelling widget object | |
42088 * @param {HTML object} div parent div to append the Storytelling gui | |
42089 * @param {JSON} options Storytelling configuration | |
42090 */ | |
42091 function StorytellingGui(storytelling, div, options) { | |
42092 | |
42093 this.parent = storytelling; | |
42094 var storytellingGui = this; | |
42095 | |
42096 storytellingGui.storytellingContainer = document.createElement('div'); | |
42097 $(div).append(storytellingGui.storytellingContainer); | |
42098 storytellingGui.storytellingContainer.style.position = 'relative'; | |
42099 }; | |
42100 | |
42101 StorytellingGui.prototype = { | |
42102 }; | |
42103 /* | |
42104 * StorytellingWidget.js | |
42105 * | |
42106 * Copyright (c) 2013, Sebastian Kruse. All rights reserved. | |
42107 * | |
42108 * This library is free software; you can redistribute it and/or | |
42109 * modify it under the terms of the GNU Lesser General Public | |
42110 * License as published by the Free Software Foundation; either | |
42111 * version 3 of the License, or (at your option) any later version. | |
42112 * | |
42113 * This library is distributed in the hope that it will be useful, | |
42114 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42115 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42116 * Lesser General Public License for more details. | |
42117 * | |
42118 * You should have received a copy of the GNU Lesser General Public | |
42119 * License along with this library; if not, write to the Free Software | |
42120 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42121 * MA 02110-1301 USA | |
42122 */ | |
42123 | |
42124 /** | |
42125 * @class StorytellingWidget | |
42126 * StorytellingWidget Implementation | |
42127 * @author Sebastian Kruse (skruse@mpiwg-berlin.mpg.de) | |
42128 * | |
42129 * @param {WidgetWrapper} core wrapper for interaction to other widgets | |
42130 * @param {HTML object} div parent div to append the Storytelling widget div | |
42131 * @param {JSON} options user specified configuration that overwrites options in StorytellingConfig.js | |
42132 */ | |
42133 StorytellingWidget = function(core, div, options) { | |
42134 | |
42135 this.datasets; | |
42136 this.core = core; | |
42137 this.core.setWidget(this); | |
42138 this.currentStatus = new Object(); | |
42139 | |
42140 this.options = (new StorytellingConfig(options)).options; | |
42141 this.gui = new StorytellingGui(this, div, this.options); | |
42142 | |
42143 this.datasetLink; | |
42144 | |
42145 Publisher.Subscribe('mapChanged', this, function(mapName) { | |
42146 this.client.currentStatus["mapChanged"] = mapName; | |
42147 this.client.createLink(); | |
42148 }); | |
42149 | |
42150 var currentStatus = $.url().param("currentStatus"); | |
42151 if (typeof currentStatus !== "undefined"){ | |
42152 this.currentStatus = $.deparam(currentStatus); | |
42153 $.each(this.currentStatus,function(action,data){ | |
42154 Publisher.Publish(action, data, this); | |
42155 }); | |
42156 } | |
42157 } | |
42158 | |
42159 StorytellingWidget.prototype = { | |
42160 | |
42161 initWidget : function(data) { | |
42162 var storytellingWidget = this; | |
42163 var gui = storytellingWidget.gui; | |
42164 | |
42165 storytellingWidget.datasets = data; | |
42166 | |
42167 $(gui.storytellingContainer).empty(); | |
42168 | |
42169 var magneticLinkParam = ""; | |
42170 var datasetIndex = 0; | |
42171 var linkCount = 1; | |
42172 $(storytellingWidget.datasets).each(function(){ | |
42173 var dataset = this; | |
42174 | |
42175 if (magneticLinkParam.length > 0) | |
42176 magneticLinkParam += "&"; | |
42177 | |
42178 var paragraph = $("<p></p>"); | |
42179 paragraph.append(dataset.label); | |
42180 if (typeof dataset.url !== "undefined"){ | |
42181 //TODO: makes only sense for KML or CSV URLs, so "type" of | |
42182 //URL should be preserved (in dataset). | |
42183 //startsWith and endsWith defined in SIMILE Ajax (string.js) | |
42184 var type="csv"; | |
42185 if (typeof dataset.type !== "undefined") | |
42186 type = dataset.type; | |
42187 else { | |
42188 if (dataset.url.toLowerCase().endsWith("kml")) | |
42189 type = "kml"; | |
42190 } | |
42191 | |
42192 magneticLinkParam += type+linkCount+"="; | |
42193 linkCount++; | |
42194 magneticLinkParam += dataset.url; | |
42195 | |
42196 var tableLinkDiv = document.createElement('a'); | |
42197 tableLinkDiv.title = dataset.url; | |
42198 tableLinkDiv.href = dataset.url; | |
42199 tableLinkDiv.target = '_'; | |
42200 tableLinkDiv.setAttribute('class', 'externalLink'); | |
42201 paragraph.append(tableLinkDiv); | |
42202 } else { | |
42203 if (storytellingWidget.options.dariahStorage){ | |
42204 var uploadToDARIAH = document.createElement('a'); | |
42205 $(uploadToDARIAH).append("Upload to DARIAH Storage"); | |
42206 uploadToDARIAH.title = ""; | |
42207 uploadToDARIAH.href = dataset.url; | |
42208 | |
42209 var localDatasetIndex = new Number(datasetIndex); | |
42210 $(uploadToDARIAH).click(function(){ | |
42211 var csv = GeoTemConfig.createCSVfromDataset(localDatasetIndex); | |
42212 // taken from dariah.storage.js | |
42213 var storageURL = "http://ref.dariah.eu/storage/" | |
42214 $.ajax({ | |
42215 url: storageURL, | |
42216 type: 'POST', | |
42217 contentType: 'text/csv', | |
42218 data: csv, | |
42219 success: function(data, status, xhr) { | |
42220 var location = xhr.getResponseHeader('Location'); | |
42221 // the dariah storage id | |
42222 dsid = location.substring(location.lastIndexOf('/')+1); | |
42223 | |
42224 //add URL to dataset | |
42225 storytellingWidget.datasets[localDatasetIndex].url = location; | |
42226 storytellingWidget.datasets[localDatasetIndex].type = "csv"; | |
42227 //refresh list | |
42228 storytellingWidget.initWidget(storytellingWidget.datasets); | |
42229 }, | |
42230 error: function (data, text, error) { | |
42231 alert('error creating new file in dariah storage because ' + text); | |
42232 console.log(data); | |
42233 console.log(text); | |
42234 console.log(error); | |
42235 } | |
42236 }); | |
42237 //discard link click-event | |
42238 return(false); | |
42239 }); | |
42240 paragraph.append(uploadToDARIAH); | |
42241 } | |
42242 // TODO: if layout is more usable, both options could be used ("else" removed) | |
42243 else if (storytellingWidget.options.localStorage){ | |
42244 var saveToLocalStorage = document.createElement('a'); | |
42245 $(saveToLocalStorage).append("Save to Local Storage"); | |
42246 saveToLocalStorage.title = ""; | |
42247 saveToLocalStorage.href = dataset.url; | |
42248 | |
42249 var localDatasetIndex = new Number(datasetIndex); | |
42250 $(saveToLocalStorage).click(function(){ | |
42251 var csv = GeoTemConfig.createCSVfromDataset(localDatasetIndex); | |
42252 | |
42253 var storageName = "GeoBrowser_dataset_"+GeoTemConfig.datasets[localDatasetIndex].label; | |
42254 $.remember({ | |
42255 name:storageName, | |
42256 value:csv | |
42257 }); | |
42258 | |
42259 //add URL to dataset | |
42260 storytellingWidget.datasets[localDatasetIndex].url = storageName; | |
42261 storytellingWidget.datasets[localDatasetIndex].type = "local"; | |
42262 //refresh list | |
42263 storytellingWidget.initWidget(storytellingWidget.datasets); | |
42264 | |
42265 //discard link click-event | |
42266 return(false); | |
42267 }); | |
42268 paragraph.append(saveToLocalStorage); | |
42269 } | |
42270 } | |
42271 | |
42272 $(gui.storytellingContainer).append(paragraph); | |
42273 datasetIndex++; | |
42274 }); | |
42275 | |
42276 this.datasetLink = magneticLinkParam; | |
42277 this.createLink(); | |
42278 }, | |
42279 | |
42280 createLink : function() { | |
42281 $(this.gui.storytellingContainer).find('.magneticLink').remove(); | |
42282 | |
42283 var magneticLink = document.createElement('a'); | |
42284 magneticLink.setAttribute('class', 'magneticLink'); | |
42285 $(magneticLink).append("Magnetic Link"); | |
42286 magneticLink.title = "Use this link to reload currently loaded (online) data."; | |
42287 magneticLink.href = "?"+this.datasetLink; | |
42288 var currentStatusParam = $.param(this.currentStatus); | |
42289 if (currentStatusParam.length > 0) | |
42290 magneticLink.href += "¤tStatus="+currentStatusParam; | |
42291 magneticLink.target = '_'; | |
42292 $(this.gui.storytellingContainer).prepend(magneticLink); | |
42293 }, | |
42294 | |
42295 highlightChanged : function(objects) { | |
42296 }, | |
42297 | |
42298 selectionChanged : function(selection) { | |
42299 }, | |
42300 }; | |
42301 /* | |
42302 * DataObject.js | |
42303 * | |
42304 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
42305 * | |
42306 * This library is free software; you can redistribute it and/or | |
42307 * modify it under the terms of the GNU Lesser General Public | |
42308 * License as published by the Free Software Foundation; either | |
42309 * version 3 of the License, or (at your option) any later version. | |
42310 * | |
42311 * This library is distributed in the hope that it will be useful, | |
42312 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42314 * Lesser General Public License for more details. | |
42315 * | |
42316 * You should have received a copy of the GNU Lesser General Public | |
42317 * License along with this library; if not, write to the Free Software | |
42318 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42319 * MA 02110-1301 USA | |
42320 */ | |
42321 | |
42322 /** | |
42323 * @class DataObject | |
42324 * GeoTemCo's data object class | |
42325 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
42326 * @release 1.0 | |
42327 * @release date: 2012-07-27 | |
42328 * @version date: 2012-07-27 | |
42329 * | |
42330 * @param {String} name name of the data object | |
42331 * @param {String} description description of the data object | |
42332 * @param {JSON} locations a list of locations with longitude, latitide and place name | |
42333 * @param {JSON} dates a list of dates | |
42334 * @param {float} lon longitude value of the given place | |
42335 * @param {float} lat latitude value of the given place | |
42336 * @param {Date} timeStart start time of the data object | |
42337 * @param {Date} timeEnd end time of the data object | |
42338 * @param {int} granularity granularity of the given time | |
42339 * @param {int} weight weight of the time object | |
42340 * @param {Openlayers.Projection} projection of the coordinates (optional) | |
42341 */ | |
42342 | |
42343 DataObject = function(name, description, locations, dates, weight, tableContent, projection) { | |
42344 | |
42345 this.name = $.trim(name); | |
42346 this.description = $.trim(description); | |
42347 this.weight = weight; | |
42348 this.tableContent = new Object(); | |
42349 var objectTableContent = this.tableContent; | |
42350 for(key in tableContent){ | |
42351 value = tableContent[key]; | |
42352 objectTableContent[$.trim(key)]=$.trim(value); | |
42353 } | |
42354 | |
42355 this.percentage = 0; | |
42356 this.setPercentage = function(percentage) { | |
42357 this.percentage = percentage; | |
42358 } | |
42359 | |
42360 this.locations = []; | |
42361 var objectLocations = this.locations; | |
42362 $(locations).each(function(){ | |
42363 objectLocations.push({ | |
42364 latitude:this.latitude, | |
42365 longitude:this.longitude, | |
42366 place:$.trim(this.place) | |
42367 }); | |
42368 }); | |
42369 | |
42370 //Check if locations are valid | |
42371 if (projection instanceof OpenLayers.Projection){ | |
42372 var tempLocations = []; | |
42373 $(this.locations).each(function(){ | |
42374 //EPSG:4326 === WGS84 | |
42375 this.latitude = parseFloat(this.latitude); | |
42376 this.longitude = parseFloat(this.longitude); | |
42377 if (projection.getCode() === "EPSG:4326"){ | |
42378 if ( (typeof this.latitude === "number") && | |
42379 (this.latitude>=-90) && | |
42380 (this.latitude<=90) && | |
42381 (typeof this.longitude === "number") && | |
42382 (this.longitude>=-180) && | |
42383 (this.longitude<=180) ) | |
42384 tempLocations.push(this); | |
42385 else{ | |
42386 if (typeof console !== "undefined") | |
42387 console.error("Object " + name + " has no valid coordinate. ("+this.latitude+","+this.longitude+")"); | |
42388 } | |
42389 } | |
42390 }); | |
42391 this.locations = tempLocations; | |
42392 } | |
42393 | |
42394 this.isGeospatial = false; | |
42395 if ((typeof this.locations !== "undefined") && (this.locations.length > 0)) { | |
42396 this.isGeospatial = true; | |
42397 } | |
42398 | |
42399 this.placeDetails = []; | |
42400 for (var i = 0; i < this.locations.length; i++) { | |
42401 this.placeDetails.push(this.locations[i].place.split("/")); | |
42402 } | |
42403 | |
42404 this.getLatitude = function(locationId) { | |
42405 return this.locations[locationId].latitude; | |
42406 } | |
42407 | |
42408 this.getLongitude = function(locationId) { | |
42409 return this.locations[locationId].longitude; | |
42410 } | |
42411 | |
42412 this.getPlace = function(locationId, level) { | |
42413 if (level >= this.placeDetails[locationId].length) { | |
42414 return this.placeDetails[locationId][this.placeDetails[locationId].length - 1]; | |
42415 } | |
42416 return this.placeDetails[locationId][level]; | |
42417 } | |
42418 | |
42419 this.dates = dates; | |
42420 this.isTemporal = false; | |
42421 if ((typeof this.dates !== "undefined") && (this.dates.length > 0)) { | |
42422 this.isTemporal = true; | |
42423 } | |
42424 | |
42425 //TODO: allow more than one timespan (as with dates/places) | |
42426 this.isFuzzyTemporal = false; | |
42427 if (this.isTemporal) { | |
42428 this.isTemporal = false; | |
42429 this.isFuzzyTemporal = true; | |
42430 | |
42431 var date = this.dates[0].date; | |
42432 var granularity = this.dates[0].granularity; | |
42433 | |
42434 this.TimeSpanGranularity = granularity; | |
42435 | |
42436 if (granularity === SimileAjax.DateTime.YEAR){ | |
42437 this.TimeSpanBegin = moment(date).startOf("year"); | |
42438 this.TimeSpanEnd = moment(date).endOf("year"); | |
42439 } else if (granularity === SimileAjax.DateTime.MONTH){ | |
42440 this.TimeSpanBegin = moment(date).startOf("month"); | |
42441 this.TimeSpanEnd = moment(date).endOf("month"); | |
42442 } else if (granularity === SimileAjax.DateTime.DAY){ | |
42443 this.TimeSpanBegin = moment(date).startOf("day"); | |
42444 this.TimeSpanEnd = moment(date).endOf("day"); | |
42445 } else if (granularity === SimileAjax.DateTime.HOUR){ | |
42446 this.TimeSpanBegin = moment(date).startOf("hour"); | |
42447 this.TimeSpanEnd = moment(date).endOf("hour"); | |
42448 } else if (granularity === SimileAjax.DateTime.MINUTE){ | |
42449 this.TimeSpanBegin = moment(date).startOf("minute"); | |
42450 this.TimeSpanEnd = moment(date).endOf("minute"); | |
42451 } else if (granularity === SimileAjax.DateTime.SECOND){ | |
42452 this.TimeSpanBegin = moment(date).startOf("second"); | |
42453 this.TimeSpanEnd = moment(date).endOf("second"); | |
42454 } else if (granularity === SimileAjax.DateTime.MILLISECOND){ | |
42455 //this is a "real" exact time | |
42456 this.isTemporal = true; | |
42457 this.isFuzzyTemporal = false; | |
42458 } | |
42459 } else if ( (typeof this.tableContent["TimeSpan:begin"] !== "undefined") && | |
42460 (typeof this.tableContent["TimeSpan:end"] !== "undefined") ){ | |
42461 //parse according to ISO 8601 | |
42462 //don't use the default "cross browser support" from moment.js | |
42463 //cause it won't work correctly with negative years | |
42464 var formats = [ "YYYYYY", | |
42465 "YYYYYY-MM", | |
42466 "YYYYYY-MM-DD", | |
42467 "YYYYYY-MM-DDTHH", | |
42468 "YYYYYY-MM-DDTHH:mm", | |
42469 "YYYYYY-MM-DDTHH:mm:ss", | |
42470 "YYYYYY-MM-DDTHH:mm:ss.SSS" | |
42471 ]; | |
42472 this.TimeSpanBegin = moment(this.tableContent["TimeSpan:begin"],formats.slice()); | |
42473 this.TimeSpanEnd = moment(this.tableContent["TimeSpan:end"],formats.slice()); | |
42474 if ((this.TimeSpanBegin instanceof Object) && this.TimeSpanBegin.isValid() && | |
42475 (this.TimeSpanEnd instanceof Object) && this.TimeSpanEnd.isValid()){ | |
42476 //check whether dates are correctly sorted | |
42477 if (this.TimeSpanBegin>this.TimeSpanEnd){ | |
42478 //dates are in the wrong order | |
42479 if (typeof console !== "undefined") | |
42480 console.error("Object " + this.name + " has wrong fuzzy dating (twisted start/end?)."); | |
42481 | |
42482 } else { | |
42483 var timeSpanBeginGranularity = formats.indexOf(this.TimeSpanBegin._f); | |
42484 var timeSpanEndGranularity = formats.indexOf(this.TimeSpanEnd._f); | |
42485 var timeSpanGranularity = Math.max( timeSpanBeginGranularity, | |
42486 timeSpanEndGranularity ); | |
42487 | |
42488 //set granularity according to formats above | |
42489 if (timeSpanGranularity === 0){ | |
42490 this.TimeSpanGranularity = SimileAjax.DateTime.YEAR; | |
42491 } else if (timeSpanGranularity === 1){ | |
42492 this.TimeSpanGranularity = SimileAjax.DateTime.MONTH; | |
42493 } else if (timeSpanGranularity === 2){ | |
42494 this.TimeSpanGranularity = SimileAjax.DateTime.DAY; | |
42495 } else if (timeSpanGranularity === 3){ | |
42496 this.TimeSpanGranularity = SimileAjax.DateTime.HOUR; | |
42497 } else if (timeSpanGranularity === 4){ | |
42498 this.TimeSpanGranularity = SimileAjax.DateTime.MINUTE; | |
42499 } else if (timeSpanGranularity === 5){ | |
42500 this.TimeSpanGranularity = SimileAjax.DateTime.SECOND; | |
42501 } else if (timeSpanGranularity === 6){ | |
42502 this.TimeSpanGranularity = SimileAjax.DateTime.MILLISECOND; | |
42503 } | |
42504 | |
42505 if (timeSpanBeginGranularity === 0){ | |
42506 this.TimeSpanBeginGranularity = SimileAjax.DateTime.YEAR; | |
42507 } else if (timeSpanBeginGranularity === 1){ | |
42508 this.TimeSpanBeginGranularity = SimileAjax.DateTime.MONTH; | |
42509 } else if (timeSpanBeginGranularity === 2){ | |
42510 this.TimeSpanBeginGranularity = SimileAjax.DateTime.DAY; | |
42511 } else if (timeSpanBeginGranularity === 3){ | |
42512 this.TimeSpanBeginGranularity = SimileAjax.DateTime.HOUR; | |
42513 } else if (timeSpanBeginGranularity === 4){ | |
42514 this.TimeSpanBeginGranularity = SimileAjax.DateTime.MINUTE; | |
42515 } else if (timeSpanBeginGranularity === 5){ | |
42516 this.TimeSpanBeginGranularity = SimileAjax.DateTime.SECOND; | |
42517 } else if (timeSpanBeginGranularity === 6){ | |
42518 this.TimeSpanBeginGranularity = SimileAjax.DateTime.MILLISECOND; | |
42519 } | |
42520 | |
42521 if (timeSpanEndGranularity === 0){ | |
42522 this.TimeSpanEndGranularity = SimileAjax.DateTime.YEAR; | |
42523 } else if (timeSpanEndGranularity === 1){ | |
42524 this.TimeSpanEndGranularity = SimileAjax.DateTime.MONTH; | |
42525 } else if (timeSpanEndGranularity === 2){ | |
42526 this.TimeSpanEndGranularity = SimileAjax.DateTime.DAY; | |
42527 } else if (timeSpanEndGranularity === 3){ | |
42528 this.TimeSpanEndGranularity = SimileAjax.DateTime.HOUR; | |
42529 } else if (timeSpanEndGranularity === 4){ | |
42530 this.TimeSpanEndGranularity = SimileAjax.DateTime.MINUTE; | |
42531 } else if (timeSpanEndGranularity === 5){ | |
42532 this.TimeSpanEndGranularity = SimileAjax.DateTime.SECOND; | |
42533 } else if (timeSpanEndGranularity === 6){ | |
42534 this.TimeSpanEndGranularity = SimileAjax.DateTime.MILLISECOND; | |
42535 } | |
42536 | |
42537 if (this.TimeSpanEnd.year()-this.TimeSpanBegin.year() >= 1000) | |
42538 this.TimeSpanGranularity = SimileAjax.DateTime.MILLENNIUM; | |
42539 else if (this.TimeSpanEnd.year()-this.TimeSpanBegin.year() >= 100) | |
42540 this.TimeSpanGranularity = SimileAjax.DateTime.CENTURY; | |
42541 else if (this.TimeSpanEnd.year()-this.TimeSpanBegin.year() >= 10) | |
42542 this.TimeSpanGranularity = SimileAjax.DateTime.DECADE; | |
42543 | |
42544 //also set upper bounds according to granularity | |
42545 //(lower bound is already correct) | |
42546 if (timeSpanEndGranularity === 0){ | |
42547 this.TimeSpanEnd.endOf("year"); | |
42548 } else if (timeSpanEndGranularity === 1){ | |
42549 this.TimeSpanEnd.endOf("month"); | |
42550 } else if (timeSpanEndGranularity === 2){ | |
42551 this.TimeSpanEnd.endOf("day"); | |
42552 } else if (timeSpanEndGranularity === 3){ | |
42553 this.TimeSpanEnd.endOf("hour"); | |
42554 } else if (timeSpanEndGranularity === 4){ | |
42555 this.TimeSpanEnd.endOf("minute"); | |
42556 } else if (timeSpanEndGranularity === 5){ | |
42557 this.TimeSpanEnd.endOf("second"); | |
42558 } else if (timeSpanEndGranularity === 6){ | |
42559 //has max accuracy, so no change needed | |
42560 } | |
42561 | |
42562 this.isFuzzyTemporal = true; | |
42563 } | |
42564 } | |
42565 } | |
42566 | |
42567 | |
42568 this.getDate = function(dateId) { | |
42569 return this.dates[dateId].date; | |
42570 } | |
42571 | |
42572 this.getTimeGranularity = function(dateId) { | |
42573 return this.dates[dateId].granularity; | |
42574 } | |
42575 | |
42576 this.setIndex = function(index) { | |
42577 this.index = index; | |
42578 } | |
42579 | |
42580 this.getTimeString = function() { | |
42581 if (this.timeStart != this.timeEnd) { | |
42582 return (SimileAjax.DateTime.getTimeString(this.granularity, this.timeStart) + " - " + SimileAjax.DateTime.getTimeString(this.granularity, this.timeEnd)); | |
42583 } else { | |
42584 return SimileAjax.DateTime.getTimeString(this.granularity, this.timeStart) + ""; | |
42585 } | |
42586 }; | |
42587 | |
42588 this.contains = function(text) { | |
42589 var allCombined = this.name + " " + this.description + " " + this.weight + " "; | |
42590 | |
42591 $.each(this.dates, function(key, value){ | |
42592 $.each(value, function(){ | |
42593 allCombined += this + " "; | |
42594 }); | |
42595 }); | |
42596 | |
42597 $.each(this.locations, function(key, value){ | |
42598 $.each(value, function(){ | |
42599 allCombined += this + " "; | |
42600 }); | |
42601 }); | |
42602 | |
42603 $.each(this.tableContent, function(key, value){ | |
42604 allCombined += value + " "; | |
42605 }); | |
42606 | |
42607 return (allCombined.indexOf(text) != -1); | |
42608 }; | |
42609 | |
42610 this.hasColorInformation = false; | |
42611 | |
42612 this.setColor = function(r0,g0,b0,r1,g1,b1) { | |
42613 this.hasColorInformation = true; | |
42614 | |
42615 this.color = new Object(); | |
42616 this.color.r0 = r0; | |
42617 this.color.g0 = g0; | |
42618 this.color.b0 = b0; | |
42619 this.color.r1 = r1; | |
42620 this.color.g1 = g1; | |
42621 this.color.b1 = b1; | |
42622 }; | |
42623 | |
42624 this.getColor = function() { | |
42625 if (!this.hasColorInformation) | |
42626 return; | |
42627 | |
42628 color = new Object(); | |
42629 color.r0 = this.r0; | |
42630 color.g0 = this.g0; | |
42631 color.b0 = this.b0; | |
42632 color.r1 = this.r1; | |
42633 color.g1 = this.g1; | |
42634 color.b1 = this.b1; | |
42635 | |
42636 return color; | |
42637 }; | |
42638 | |
42639 Publisher.Publish('dataobjectAfterCreation', this); | |
42640 }; | |
42641 | |
42642 /* | |
42643 * Dataset.js | |
42644 * | |
42645 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
42646 * | |
42647 * This library is free software; you can redistribute it and/or | |
42648 * modify it under the terms of the GNU Lesser General Public | |
42649 * License as published by the Free Software Foundation; either | |
42650 * version 3 of the License, or (at your option) any later version. | |
42651 * | |
42652 * This library is distributed in the hope that it will be useful, | |
42653 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42654 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42655 * Lesser General Public License for more details. | |
42656 * | |
42657 * You should have received a copy of the GNU Lesser General Public | |
42658 * License along with this library; if not, write to the Free Software | |
42659 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42660 * MA 02110-1301 USA | |
42661 */ | |
42662 | |
42663 /** | |
42664 * @class Dataset | |
42665 * GeoTemCo's Dataset class | |
42666 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
42667 * @release 1.0 | |
42668 * @release date: 2012-07-27 | |
42669 * @version date: 2012-07-27 | |
42670 * | |
42671 * @param {Array} objects data item arrays from different datasets | |
42672 * @param {String} label label for the datasets | |
42673 */ | |
42674 Dataset = function(objects, label, url, type) { | |
42675 | |
42676 this.objects = objects; | |
42677 this.label = label; | |
42678 this.url = url; | |
42679 this.type = type; | |
42680 | |
42681 this.color; | |
42682 | |
42683 Publisher.Publish('datasetAfterCreation', this); | |
42684 } | |
42685 /* | |
42686 * TimeDataSource.js | |
42687 * | |
42688 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
42689 * | |
42690 * This library is free software; you can redistribute it and/or | |
42691 * modify it under the terms of the GNU Lesser General Public | |
42692 * License as published by the Free Software Foundation; either | |
42693 * version 3 of the License, or (at your option) any later version. | |
42694 * | |
42695 * This library is distributed in the hope that it will be useful, | |
42696 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
42697 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42698 * Lesser General Public License for more details. | |
42699 * | |
42700 * You should have received a copy of the GNU Lesser General Public | |
42701 * License along with this library; if not, write to the Free Software | |
42702 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
42703 * MA 02110-1301 USA | |
42704 */ | |
42705 | |
42706 /** | |
42707 * @class TimeDataSource, TimeSlice, TimeStack | |
42708 * implementation for aggregation of time items | |
42709 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
42710 * @release 1.0 | |
42711 * @release date: 2012-07-27 | |
42712 * @version date: 2012-07-27 | |
42713 * | |
42714 * @param {JSON} options time configuration | |
42715 */ | |
42716 function TimeDataSource(options) { | |
42717 | |
42718 this.options = options; | |
42719 this.timeSlices = []; | |
42720 this.unit | |
42721 this.minDate | |
42722 this.maxDate | |
42723 this.eventSources | |
42724 this.events | |
42725 this.leftSlice | |
42726 this.rightSlice | |
42727 | |
42728 this.hashMapping | |
42729 | |
42730 }; | |
42731 | |
42732 TimeDataSource.prototype = { | |
42733 | |
42734 findTimeUnits : function(granularity, timeUnit, pixels) { | |
42735 | |
42736 var time = SimileAjax.DateTime; | |
42737 this.availableUnits = []; | |
42738 var givenUnits = SimileAjax.DateTime.gregorianUnitLengths; | |
42739 for (var i = 0; i < givenUnits.length; i++) { | |
42740 if (granularity > i) { | |
42741 continue; | |
42742 } | |
42743 var slices = 0; | |
42744 var t = new Date(this.minDate.getTime()); | |
42745 do { | |
42746 time.roundDownToInterval(t, i, undefined, 1, 0); | |
42747 slices++; | |
42748 time.incrementByInterval(t, i, undefined); | |
42749 } while( t.getTime() <= this.maxDate.getTime() && slices < pixels+2 ); | |
42750 if (slices > 0 && slices <= pixels) { | |
42751 this.availableUnits.push({ | |
42752 unit : i, | |
42753 slices : slices, | |
42754 label : SimileAjax.DateTime.Strings[GeoTemConfig.language][i] | |
42755 }); | |
42756 } | |
42757 } | |
42758 var unitDiff200 = pixels + 1; | |
42759 for (var i = 0; i < this.availableUnits.length; i++) { | |
42760 var diff = Math.abs(this.availableUnits[i].slices - 200); | |
42761 if (diff < unitDiff200) { | |
42762 unitDiff200 = diff; | |
42763 this.unit = this.availableUnits[i].unit; | |
42764 } | |
42765 } | |
42766 | |
42767 }, | |
42768 | |
42769 getUnitIndex : function() { | |
42770 for (var i = 0; i < this.availableUnits.length; i++) { | |
42771 if (this.unit == this.availableUnits[i].unit) { | |
42772 return i; | |
42773 } | |
42774 } | |
42775 return 0; | |
42776 }, | |
42777 | |
42778 setTimeUnit : function(unit) { | |
42779 this.unit = unit; | |
42780 this.initializeSlices(); | |
42781 }, | |
42782 | |
42783 /** | |
42784 * initializes the TimeDataSource | |
42785 * @param {Timeplot.ColumnSource[]} dataSources the column sources corresponding to the data sets | |
42786 * @param {Timeplot.DefaultEventSource[]} eventSources the event sources corresponding to the column sources | |
42787 * @param {TimeObject[][]} timeObjects an array of time objects of different sets | |
42788 * @param {SimileAjax.DateTime} granularity the time granularity of the given data | |
42789 */ | |
42790 initialize : function(dataSources, eventSources, timeObjects, granularity, timeUnit, pixels) { | |
42791 | |
42792 this.dataSources = dataSources; | |
42793 this.eventSources = eventSources; | |
42794 this.timeObjects = timeObjects; | |
42795 | |
42796 this.minDate = undefined; | |
42797 this.maxDate = undefined; | |
42798 this.hashMapping = []; | |
42799 this.projHashMapping = []; | |
42800 | |
42801 for (var i = 0; i < timeObjects.length; i++) { | |
42802 this.hashMapping.push([]); | |
42803 this.projHashMapping.push([]); | |
42804 for (var j = 0; j < timeObjects[i].length; j++) { | |
42805 var o = timeObjects[i][j]; | |
42806 if (o.isTemporal) { | |
42807 var g = o.dates[this.options.timeIndex].granularity; | |
42808 //o.getTimeGranularity(this.options.timeIndex); | |
42809 if (g == null) { | |
42810 continue; | |
42811 } | |
42812 var time = o.dates[this.options.timeIndex].date; | |
42813 //o.getDate(this.options.timeIndex); | |
42814 if (this.minDate == undefined || time.getTime() < this.minDate.getTime()) { | |
42815 this.minDate = time; | |
42816 } | |
42817 if (this.maxDate == undefined || time.getTime() > this.maxDate.getTime()) { | |
42818 this.maxDate = time; | |
42819 } | |
42820 } | |
42821 } | |
42822 } | |
42823 | |
42824 if (this.minDate == undefined) { | |
42825 this.minDate = this.options.defaultMinDate; | |
42826 this.maxDate = this.options.defaultMaxDate; | |
42827 } | |
42828 | |
42829 this.findTimeUnits(granularity, timeUnit, pixels); | |
42830 this.initializeSlices(); | |
42831 | |
42832 }, | |
42833 | |
42834 initializeSlices : function() { | |
42835 for (var i = 0; i < this.dataSources.length; i++) { | |
42836 this.dataSources[i]._range = { | |
42837 earliestDate : null, | |
42838 latestDate : null, | |
42839 min : 0, | |
42840 max : 0 | |
42841 }; | |
42842 } | |
42843 this.timeSlices = []; | |
42844 var time = SimileAjax.DateTime; | |
42845 var t = new Date(this.minDate.getTime() - 0.9 * time.gregorianUnitLengths[this.unit]); | |
42846 do { | |
42847 time.roundDownToInterval(t, this.unit, undefined, 1, 0); | |
42848 var slice = new TimeSlice(SimileAjax.NativeDateUnit.cloneValue(t), this.timeObjects.length, this.dataSources.length); | |
42849 this.timeSlices.push(slice); | |
42850 time.incrementByInterval(t, this.unit, undefined); | |
42851 } while (t.getTime() <= this.maxDate.getTime() + 1.1 * time.gregorianUnitLengths[this.unit]); | |
42852 | |
42853 for (var i = 0; i < this.timeObjects.length; i++) { | |
42854 var projId = i; | |
42855 if( this.dataSources.length == 1 ){ | |
42856 projId = 0; | |
42857 } | |
42858 for (var j = 0; j < this.timeObjects[i].length; j++) { | |
42859 var o = this.timeObjects[i][j]; | |
42860 if (o.isTemporal) { | |
42861 var date = o.dates[this.options.timeIndex].date; | |
42862 //o.getDate(this.options.timeIndex); | |
42863 for (var k = 0; k < this.timeSlices.length - 1; k++) { | |
42864 var t1 = this.timeSlices[k].date.getTime(); | |
42865 var t2 = this.timeSlices[k + 1].date.getTime(); | |
42866 var stack = null, projStack = null; | |
42867 if (date >= t1 && date < t2) { | |
42868 stack = this.timeSlices[k].getStack(i); | |
42869 projStack = this.timeSlices[k].getProjStack(projId); | |
42870 } | |
42871 if (k == this.timeSlices.length - 2 && date >= t2) { | |
42872 stack = this.timeSlices[k + 1].getStack(i); | |
42873 projStack = this.timeSlices[k + 1].getProjStack(projId); | |
42874 } | |
42875 if (stack != null) { | |
42876 stack.addObject(o); | |
42877 projStack.addObject(o); | |
42878 this.hashMapping[i][o.index] = stack; | |
42879 this.projHashMapping[i][o.index] = projStack; | |
42880 break; | |
42881 } | |
42882 } | |
42883 } | |
42884 } | |
42885 } | |
42886 | |
42887 this.events = []; | |
42888 for (var i = 0; i < this.eventSources.length; i++) { | |
42889 var eventSet = []; | |
42890 for (var j = 0; j < this.timeSlices.length; j++) { | |
42891 var value = new Array("" + this.timeSlices[j].projStacks[i].value); | |
42892 eventSet.push({ | |
42893 date : this.timeSlices[j].date, | |
42894 value : value | |
42895 }); | |
42896 } | |
42897 this.eventSources[i].loadData(eventSet); | |
42898 this.events.push(eventSet); | |
42899 } | |
42900 | |
42901 this.leftSlice = 0; | |
42902 this.rightSlice = this.timeSlices.length - 1; | |
42903 | |
42904 }, | |
42905 | |
42906 getSliceNumber : function() { | |
42907 return this.timeSlices.length; | |
42908 }, | |
42909 | |
42910 /** | |
42911 * computes the slice index corresponding to a given time | |
42912 * @param {Date} time the given time | |
42913 * @return the corresponding slice index | |
42914 */ | |
42915 getSliceIndex : function(time) { | |
42916 for (var i = 0; i < this.timeSlices.length; i++) { | |
42917 if (time == this.timeSlices[i].date) { | |
42918 return i; | |
42919 } | |
42920 } | |
42921 }, | |
42922 | |
42923 /** | |
42924 * returns the time of a specific time slice | |
42925 * @param {int} time the given slice index | |
42926 * @return the corresponding slice date | |
42927 */ | |
42928 getSliceTime : function(index) { | |
42929 return this.timeSlices[index].date; | |
42930 }, | |
42931 | |
42932 /** | |
42933 * shifts the actual zoomed range | |
42934 * @param {int} delta the value to shift (negative for left shift, positive for right shift) | |
42935 * @return boolean value, if the range could be shifted | |
42936 */ | |
42937 setShift : function(delta) { | |
42938 if (delta == 1 && this.leftSlice != 0) { | |
42939 this.leftSlice--; | |
42940 this.rightSlice--; | |
42941 return true; | |
42942 } else if (delta == -1 && this.rightSlice != this.timeSlices.length - 1) { | |
42943 this.leftSlice++; | |
42944 this.rightSlice++; | |
42945 return true; | |
42946 } else { | |
42947 return false; | |
42948 } | |
42949 }, | |
42950 | |
42951 /** | |
42952 * zooms the actual range | |
42953 * @param {int} delta the value to zoom (negative for zoom out, positive for zoom in) | |
42954 * @param {Date} time the corresponding time of the actual mouse position on the plot | |
42955 * @param {Date} leftTime the time of the left border of a selected timerange or null | |
42956 * @param {Date} rightTime the time of the right border of a selected timerange or null | |
42957 * @return boolean value, if the range could be zoomed | |
42958 */ | |
42959 setZoom : function(delta, time, leftTime, rightTime) { | |
42960 var n1 = 0; | |
42961 var n2 = 0; | |
42962 var m = -1; | |
42963 if (delta > 0) { | |
42964 m = 1; | |
42965 if (leftTime != null) { | |
42966 n1 = this.getSliceIndex(leftTime) - this.leftSlice; | |
42967 n2 = this.rightSlice - this.getSliceIndex(rightTime); | |
42968 } else { | |
42969 slice = this.getSliceIndex(time); | |
42970 if (slice == this.leftSlice || slice == this.rightSlice) { | |
42971 return; | |
42972 } | |
42973 n1 = slice - 1 - this.leftSlice; | |
42974 n2 = this.rightSlice - slice - 1; | |
42975 } | |
42976 } else if (delta < 0) { | |
42977 | |
42978 n1 = this.leftSlice; | |
42979 n2 = this.timeSlices.length - 1 - this.rightSlice; | |
42980 } | |
42981 | |
42982 var zoomSlices = 2 * delta; | |
42983 if (Math.abs(n1 + n2) < Math.abs(zoomSlices)) { | |
42984 zoomSlices = n1 + n2; | |
42985 } | |
42986 | |
42987 if (n1 + n2 == 0) { | |
42988 return false; | |
42989 } | |
42990 | |
42991 var m1 = Math.round(n1 / (n1 + n2) * zoomSlices); | |
42992 var m2 = zoomSlices - m1; | |
42993 | |
42994 this.leftSlice += m1; | |
42995 this.rightSlice -= m2; | |
42996 | |
42997 return true; | |
42998 }, | |
42999 | |
43000 /** | |
43001 * resets the plots by loading data of actual zoomed range | |
43002 */ | |
43003 reset : function(timeGeometry) { | |
43004 for (var i = 0; i < this.eventSources.length; i++) { | |
43005 this.eventSources[i].loadData(this.events[i].slice(this.leftSlice, this.rightSlice + 1)); | |
43006 if (i + 1 < this.eventSources.length) { | |
43007 timeGeometry._earliestDate = null; | |
43008 timeGeometry._latestDate = null; | |
43009 } | |
43010 | |
43011 } | |
43012 }, | |
43013 | |
43014 /** | |
43015 * Getter for actual zoom | |
43016 * @return actual zoom value | |
43017 */ | |
43018 getZoom : function() { | |
43019 if (this.timeSlices == undefined) { | |
43020 return 0; | |
43021 } | |
43022 return Math.round((this.timeSlices.length - 3) / 2) - Math.round((this.rightSlice - this.leftSlice - 2) / 2); | |
43023 }, | |
43024 | |
43025 /** | |
43026 * Getter for date of the first timeslice | |
43027 * @return date of the first timeslice | |
43028 */ | |
43029 earliest : function() { | |
43030 return this.timeSlices[0].date; | |
43031 }, | |
43032 | |
43033 /** | |
43034 * Getter for date of the last timeslice | |
43035 * @return date of the last timeslice | |
43036 */ | |
43037 latest : function() { | |
43038 return this.timeSlices[this.timeSlices.length - 1].date; | |
43039 }, | |
43040 | |
43041 setOverlay : function(timeObjects) { | |
43042 for (var i = 0; i < this.timeSlices.length; i++) { | |
43043 this.timeSlices[i].reset(); | |
43044 } | |
43045 for (var j in timeObjects ) { | |
43046 for (var k in timeObjects[j] ) { | |
43047 var o = timeObjects[j][k]; | |
43048 if (o.isTemporal) { | |
43049 if (o.getTimeGranularity(this.options.timeIndex) == null) { | |
43050 continue; | |
43051 } | |
43052 this.hashMapping[j][o.index].overlay += o.weight; | |
43053 this.projHashMapping[j][o.index].overlay += o.weight; | |
43054 } | |
43055 } | |
43056 } | |
43057 }, | |
43058 | |
43059 size : function() { | |
43060 if (this.timeSlices.length == 0) { | |
43061 return 0; | |
43062 } | |
43063 return this.timeSlices[0].stacks.length; | |
43064 } | |
43065 }; | |
43066 | |
43067 /** | |
43068 * small class that represents a time slice of the actual timeplot. | |
43069 * it has a specific date and contains its corrsponding data objects as well | |
43070 */ | |
43071 function TimeSlice(date, rows, projRows) { | |
43072 | |
43073 this.date = date; | |
43074 this.selected = false; | |
43075 | |
43076 this.stacks = []; | |
43077 this.projStacks = []; | |
43078 for (var i = 0; i < rows; i++) { | |
43079 this.stacks.push(new TimeStack()); | |
43080 } | |
43081 for (var i = 0; i < projRows; i++) { | |
43082 this.projStacks.push(new TimeStack()); | |
43083 } | |
43084 | |
43085 this.getStack = function(row) { | |
43086 return this.stacks[row]; | |
43087 }; | |
43088 | |
43089 this.getProjStack = function(row) { | |
43090 return this.projStacks[row]; | |
43091 }; | |
43092 | |
43093 this.reset = function() { | |
43094 for (var i in this.projStacks ) { | |
43095 this.stacks[i].overlay = 0; | |
43096 this.projStacks[i].overlay = 0; | |
43097 } | |
43098 }; | |
43099 | |
43100 this.overlay = function() { | |
43101 var value = 0; | |
43102 for (var i in this.projStacks ) { | |
43103 if (this.projStacks[i].overlay > value) { | |
43104 value = this.projStacks[i].overlay; | |
43105 } | |
43106 } | |
43107 return value; | |
43108 }; | |
43109 | |
43110 }; | |
43111 | |
43112 /** | |
43113 * small class that represents a stack for a time slice which | |
43114 * holds items for different datasets for the specific time range | |
43115 */ | |
43116 function TimeStack() { | |
43117 | |
43118 this.overlay = 0; | |
43119 this.value = 0; | |
43120 this.elements = []; | |
43121 | |
43122 this.addObject = function(object) { | |
43123 this.elements.push(object); | |
43124 this.value += object.weight; | |
43125 }; | |
43126 | |
43127 }; | |
43128 /* | |
43129 * Binning.js | |
43130 * | |
43131 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
43132 * | |
43133 * This library is free software; you can redistribute it and/or | |
43134 * modify it under the terms of the GNU Lesser General Public | |
43135 * License as published by the Free Software Foundation; either | |
43136 * version 3 of the License, or (at your option) any later version. | |
43137 * | |
43138 * This library is distributed in the hope that it will be useful, | |
43139 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
43140 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
43141 * Lesser General Public License for more details. | |
43142 * | |
43143 * You should have received a copy of the GNU Lesser General Public | |
43144 * License along with this library; if not, write to the Free Software | |
43145 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
43146 * MA 02110-1301 USA | |
43147 */ | |
43148 | |
43149 /** | |
43150 * @class Binning | |
43151 * Calculates map aggregation with several binning algorithms | |
43152 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
43153 * @release 1.0 | |
43154 * @release date: 2012-07-27 | |
43155 * @version date: 2012-07-27 | |
43156 */ | |
43157 Binning = function(map, options) { | |
43158 | |
43159 this.map = map; | |
43160 this.options = options; | |
43161 this.reset(); | |
43162 | |
43163 }; | |
43164 | |
43165 Binning.prototype = { | |
43166 | |
43167 getSet : function() { | |
43168 var type = this.options.binning; | |
43169 if (!type) { | |
43170 return this.getExactBinning(); | |
43171 } else if (type == 'generic') { | |
43172 return this.getGenericBinning(); | |
43173 } else if (type == 'square') { | |
43174 return this.getSquareBinning(); | |
43175 } else if (type == 'hexagonal') { | |
43176 return this.getHexagonalBinning(); | |
43177 } else if (type == 'triangular') { | |
43178 return this.getTriangularBinning(); | |
43179 } | |
43180 }, | |
43181 | |
43182 getExactBinning : function() { | |
43183 if ( typeof this.binnings['exact'] == 'undefined') { | |
43184 this.exactBinning(); | |
43185 } | |
43186 return this.binnings['exact']; | |
43187 }, | |
43188 | |
43189 getGenericBinning : function() { | |
43190 if ( typeof this.binnings['generic'] == 'undefined') { | |
43191 this.genericBinning(); | |
43192 } | |
43193 return this.binnings['generic']; | |
43194 }, | |
43195 | |
43196 getSquareBinning : function() { | |
43197 if ( typeof this.binnings['square'] == 'undefined') { | |
43198 this.squareBinning(); | |
43199 } | |
43200 return this.binnings['square']; | |
43201 }, | |
43202 | |
43203 getHexagonalBinning : function() { | |
43204 if ( typeof this.binnings['hexagonal'] == 'undefined') { | |
43205 this.hexagonalBinning(); | |
43206 } | |
43207 return this.binnings['hexagonal']; | |
43208 }, | |
43209 | |
43210 getTriangularBinning : function() { | |
43211 if ( typeof this.binnings['triangular'] == 'undefined') { | |
43212 this.triangularBinning(); | |
43213 } | |
43214 return this.binnings['triangular']; | |
43215 }, | |
43216 | |
43217 reset : function() { | |
43218 this.zoomLevels = this.map.getNumZoomLevels(); | |
43219 this.binnings = []; | |
43220 this.minimumRadius = this.options.minimumRadius; | |
43221 this.maximumRadius = this.minimumRadius; | |
43222 this.maximumPoints = 0; | |
43223 this.minArea = 0; | |
43224 this.maxArea = 0; | |
43225 }, | |
43226 | |
43227 getMaxRadius : function(size) { | |
43228 return 4 * Math.log(size) / Math.log(2); | |
43229 }, | |
43230 | |
43231 setObjects : function(objects) { | |
43232 this.objects = objects; | |
43233 for (var i = 0; i < this.objects.length; i++) { | |
43234 var weight = 0; | |
43235 for (var j = 0; j < this.objects[i].length; j++) { | |
43236 if (this.objects[i][j].isGeospatial) { | |
43237 weight += this.objects[i][j].weight; | |
43238 } | |
43239 } | |
43240 var r = this.getMaxRadius(weight); | |
43241 if (r > this.maximumRadius) { | |
43242 this.maximumRadius = r; | |
43243 this.maximumPoints = weight; | |
43244 this.maxArea = Math.PI * this.maximumRadius * this.maximumRadius; | |
43245 this.minArea = Math.PI * this.minimumRadius * this.minimumRadius; | |
43246 } | |
43247 } | |
43248 }, | |
43249 | |
43250 dist : function(x1, y1, x2, y2) { | |
43251 return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); | |
43252 }, | |
43253 | |
43254 exactBinning : function() { | |
43255 var circleSets = []; | |
43256 var hashMaps = []; | |
43257 var selectionHashs = []; | |
43258 | |
43259 var circleAggregates = []; | |
43260 var bins = []; | |
43261 for (var i = 0; i < this.objects.length; i++) { | |
43262 bins.push([]); | |
43263 circleAggregates.push([]); | |
43264 for (var j = 0; j < this.objects[i].length; j++) { | |
43265 var o = this.objects[i][j]; | |
43266 if (o.isGeospatial) { | |
43267 if ( typeof circleAggregates[i]['' + o.getLongitude(this.options.mapIndex)] == 'undefined') { | |
43268 circleAggregates[i]['' + o.getLongitude(this.options.mapIndex)] = []; | |
43269 } | |
43270 if ( typeof circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)] == 'undefined') { | |
43271 circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)] = []; | |
43272 bins[i].push(circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)]); | |
43273 } | |
43274 circleAggregates[i][''+o.getLongitude(this.options.mapIndex)]['' + o.getLatitude(this.options.mapIndex)].push(o); | |
43275 } | |
43276 } | |
43277 } | |
43278 | |
43279 var circles = []; | |
43280 var hashMap = []; | |
43281 var selectionMap = []; | |
43282 for (var i = 0; i < bins.length; i++) { | |
43283 circles.push([]); | |
43284 hashMap.push([]); | |
43285 selectionMap.push([]); | |
43286 for (var j = 0; j < bins[i].length; j++) { | |
43287 var bin = bins[i][j]; | |
43288 var p = new OpenLayers.Geometry.Point(bin[0].getLongitude(this.options.mapIndex), bin[0].getLatitude(this.options.mapIndex), null); | |
43289 p.transform(this.map.displayProjection, this.map.projection); | |
43290 var weight = 0; | |
43291 for (var z = 0; z < bin.length; z++) { | |
43292 weight += bin[z].weight; | |
43293 } | |
43294 var radius = this.options.minimumRadius; | |
43295 if (this.options.noBinningRadii == 'dynamic') { | |
43296 radius = this.getRadius(weight); | |
43297 } | |
43298 var circle = new CircleObject(p.x, p.y, 0, 0, bin, radius, i, weight); | |
43299 circles[i].push(circle); | |
43300 for (var z = 0; z < bin.length; z++) { | |
43301 hashMap[i][bin[z].index] = circle; | |
43302 selectionMap[i][bin[z].index] = false; | |
43303 } | |
43304 } | |
43305 } | |
43306 for (var k = 0; k < this.zoomLevels; k++) { | |
43307 circleSets.push(circles); | |
43308 hashMaps.push(hashMap); | |
43309 selectionHashs.push(selectionMap); | |
43310 } | |
43311 this.binnings['exact'] = { | |
43312 circleSets : circleSets, | |
43313 hashMaps : hashMaps, | |
43314 selectionHashs : selectionHashs | |
43315 }; | |
43316 }, | |
43317 | |
43318 genericClustering : function(objects, id) { | |
43319 var binSets = []; | |
43320 var circleSets = []; | |
43321 var hashMaps = []; | |
43322 var selectionHashs = []; | |
43323 var clustering = new Clustering(-20037508.34, -20037508.34, 20037508.34, 20037508.34); | |
43324 for (var i = 0; i < objects.length; i++) { | |
43325 for (var j = 0; j < objects[i].length; j++) { | |
43326 var o = objects[i][j]; | |
43327 if (o.isGeospatial) { | |
43328 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
43329 p.transform(this.map.displayProjection, this.map.projection); | |
43330 var point = new Vertex(Math.floor(p.x), Math.floor(p.y), objects.length, this); | |
43331 point.addElement(o, o.weight, i); | |
43332 clustering.add(point); | |
43333 } | |
43334 } | |
43335 } | |
43336 | |
43337 for (var i = 0; i < this.zoomLevels; i++) { | |
43338 var bins = []; | |
43339 var circles = []; | |
43340 var hashMap = []; | |
43341 var selectionMap = []; | |
43342 for (var j = 0; j < objects.length; j++) { | |
43343 circles.push([]); | |
43344 hashMap.push([]); | |
43345 selectionMap.push([]); | |
43346 } | |
43347 var resolution = this.map.getResolutionForZoom(this.zoomLevels - i - 1); | |
43348 clustering.mergeForResolution(resolution, this.options.circleGap, this.options.circleOverlap); | |
43349 for (var j = 0; j < clustering.vertices.length; j++) { | |
43350 var point = clustering.vertices[j]; | |
43351 if (!point.legal) { | |
43352 continue; | |
43353 } | |
43354 var balls = []; | |
43355 for (var k = 0; k < point.elements.length; k++) { | |
43356 if (point.elements[k].length > 0) { | |
43357 balls.push({ | |
43358 search : k, | |
43359 elements : point.elements[k], | |
43360 radius : point.radii[k], | |
43361 weight : point.weights[k] | |
43362 }); | |
43363 } | |
43364 } | |
43365 var orderBalls = function(b1, b2) { | |
43366 if (b1.radius > b2.radius) { | |
43367 return -1; | |
43368 } | |
43369 if (b2.radius > b1.radius) { | |
43370 return 1; | |
43371 } | |
43372 return 0; | |
43373 } | |
43374 var fatherBin = { | |
43375 circles : [], | |
43376 length : 0, | |
43377 radius : point.radius / resolution, | |
43378 x : point.x, | |
43379 y : point.y | |
43380 }; | |
43381 for (var k = 0; k < objects.length; k++) { | |
43382 fatherBin.circles.push(false); | |
43383 } | |
43384 var createCircle = function(sx, sy, ball) { | |
43385 var index = id || ball.search; | |
43386 var circle = new CircleObject(point.x, point.y, sx, sy, ball.elements, ball.radius, index, ball.weight, fatherBin); | |
43387 circles[ball.search].push(circle); | |
43388 fatherBin.circles[index] = circle; | |
43389 fatherBin.length++; | |
43390 for (var k = 0; k < ball.elements.length; k++) { | |
43391 hashMap[ball.search][ball.elements[k].index] = circle; | |
43392 selectionMap[ball.search][ball.elements[k].index] = false; | |
43393 } | |
43394 } | |
43395 if (balls.length == 1) { | |
43396 createCircle(0, 0, balls[0]); | |
43397 } else if (balls.length == 2) { | |
43398 var r1 = balls[0].radius; | |
43399 var r2 = balls[1].radius; | |
43400 createCircle(-1 * r2, 0, balls[0]); | |
43401 createCircle(r1, 0, balls[1]); | |
43402 } else if (balls.length == 3) { | |
43403 balls.sort(orderBalls); | |
43404 var r1 = balls[0].radius; | |
43405 var r2 = balls[1].radius; | |
43406 var r3 = balls[2].radius; | |
43407 var d = ((2 / 3 * Math.sqrt(3) - 1) / 2) * r2; | |
43408 var delta1 = point.radius / resolution - r1 - d; | |
43409 var delta2 = r1 - delta1; | |
43410 createCircle(-delta1, 0, balls[0]); | |
43411 createCircle(delta2 + r2 - 3 * d, r2, balls[1]); | |
43412 createCircle(delta2 + r2 - 3 * d, -1 * r3, balls[2]); | |
43413 // createCircle(delta2 + r3 - (3 * d * r3 / r2), -1 * r3, balls[2]); | |
43414 } else if (balls.length == 4) { | |
43415 balls.sort(orderBalls); | |
43416 var r1 = balls[0].radius; | |
43417 var r2 = balls[1].radius; | |
43418 var r3 = balls[2].radius; | |
43419 var r4 = balls[3].radius; | |
43420 var d = (Math.sqrt(2) - 1) * r2; | |
43421 createCircle(-1 * d - r2, 0, balls[0]); | |
43422 createCircle(r1 - r2, -1 * d - r4, balls[3]); | |
43423 createCircle(r1 - r2, d + r3, balls[2]); | |
43424 createCircle(d + r1, 0, balls[1]); | |
43425 } | |
43426 if (fatherBin.length > 1) { | |
43427 bins.push(fatherBin); | |
43428 } | |
43429 } | |
43430 circleSets.push(circles); | |
43431 binSets.push(bins); | |
43432 hashMaps.push(hashMap); | |
43433 selectionHashs.push(selectionMap); | |
43434 } | |
43435 circleSets.reverse(); | |
43436 binSets.reverse(); | |
43437 hashMaps.reverse(); | |
43438 selectionHashs.reverse(); | |
43439 return { | |
43440 circleSets : circleSets, | |
43441 binSets : binSets, | |
43442 hashMaps : hashMaps, | |
43443 selectionHashs : selectionHashs | |
43444 }; | |
43445 }, | |
43446 | |
43447 genericBinning : function() { | |
43448 if (this.options.circlePackings || this.objects.length == 1) { | |
43449 this.binnings['generic'] = this.genericClustering(this.objects); | |
43450 } else { | |
43451 var circleSets = []; | |
43452 var hashMaps = []; | |
43453 var selectionHashs = []; | |
43454 for (var i = 0; i < this.objects.length; i++) { | |
43455 var sets = this.genericClustering([this.objects[i]], i); | |
43456 if (i == 0) { | |
43457 circleSets = sets.circleSets; | |
43458 hashMaps = sets.hashMaps; | |
43459 selectionHashs = sets.selectionHashs; | |
43460 } else { | |
43461 for (var j = 0; j < circleSets.length; j++) { | |
43462 circleSets[j] = circleSets[j].concat(sets.circleSets[j]); | |
43463 hashMaps[j] = hashMaps[j].concat(sets.hashMaps[j]); | |
43464 selectionHashs[j] = selectionHashs[j].concat(sets.selectionHashs[j]); | |
43465 } | |
43466 } | |
43467 } | |
43468 this.binnings['generic'] = { | |
43469 circleSets : circleSets, | |
43470 hashMaps : hashMaps, | |
43471 selectionHashs : selectionHashs | |
43472 }; | |
43473 } | |
43474 }, | |
43475 | |
43476 getRadius : function(n) { | |
43477 if (n == 0) { | |
43478 return 0; | |
43479 } | |
43480 if (n == 1) { | |
43481 return this.minimumRadius; | |
43482 } | |
43483 return Math.sqrt((this.minArea + (this.maxArea - this.minArea) / (this.maximumPoints - 1) * (n - 1) ) / Math.PI); | |
43484 }, | |
43485 | |
43486 getBinRadius : function(n, r_max, N) { | |
43487 if (n == 0) { | |
43488 return 0; | |
43489 } | |
43490 /* | |
43491 function log2(x) { | |
43492 return (Math.log(x)) / (Math.log(2)); | |
43493 } | |
43494 var r0 = this.options.minimumRadius; | |
43495 var r; | |
43496 if ( typeof r_max == 'undefined') { | |
43497 return r0 + n / Math.sqrt(this.options.maximumPoints); | |
43498 } | |
43499 return r0 + (r_max - r0 ) * log2(n) / log2(N); | |
43500 */ | |
43501 var minArea = Math.PI * this.options.minimumRadius * this.options.minimumRadius; | |
43502 var maxArea = Math.PI * r_max * r_max; | |
43503 return Math.sqrt((minArea + (maxArea - minArea) / (N - 1) * (n - 1) ) / Math.PI); | |
43504 }, | |
43505 | |
43506 shift : function(type, bin, radius, elements) { | |
43507 | |
43508 var x1 = bin.x, x2 = 0; | |
43509 var y1 = bin.y, y2 = 0; | |
43510 for (var i = 0; i < elements.length; i++) { | |
43511 x2 += elements[i].x / elements.length; | |
43512 y2 += elements[i].y / elements.length; | |
43513 } | |
43514 | |
43515 var sx = 0, sy = 0; | |
43516 | |
43517 if (type == 'square') { | |
43518 var dx = Math.abs(x2 - x1); | |
43519 var dy = Math.abs(y2 - y1); | |
43520 var m = dy / dx; | |
43521 var n = y1 - m * x1; | |
43522 if (dx > dy) { | |
43523 sx = bin.x - (x1 + bin.r - radius ); | |
43524 sy = bin.y - (m * bin.x + n ); | |
43525 } else { | |
43526 sy = bin.y - (y1 + bin.r - radius ); | |
43527 sx = bin.x - (bin.y - n) / m; | |
43528 } | |
43529 } | |
43530 | |
43531 return { | |
43532 x : sx, | |
43533 y : sy | |
43534 }; | |
43535 | |
43536 }, | |
43537 | |
43538 binSize : function(elements) { | |
43539 var size = 0; | |
43540 for (var i in elements ) { | |
43541 size += elements[i].weight; | |
43542 } | |
43543 return size; | |
43544 }, | |
43545 | |
43546 setCircleSet : function(id, binData) { | |
43547 var circleSets = []; | |
43548 var hashMaps = []; | |
43549 var selectionHashs = []; | |
43550 for (var i = 0; i < binData.length; i++) { | |
43551 var circles = []; | |
43552 var hashMap = []; | |
43553 var selectionMap = []; | |
43554 for (var j = 0; j < this.objects.length; j++) { | |
43555 circles.push([]); | |
43556 hashMap.push([]); | |
43557 selectionMap.push([]); | |
43558 } | |
43559 var points = []; | |
43560 var max = 0; | |
43561 var radius = 0; | |
43562 var resolution = this.map.getResolutionForZoom(i); | |
43563 for (var j = 0; j < binData[i].length; j++) { | |
43564 for (var k = 0; k < binData[i][j].bin.length; k++) { | |
43565 var bs = this.binSize(binData[i][j].bin[k]); | |
43566 if (bs > max) { | |
43567 max = bs; | |
43568 radius = binData[i][j].r / resolution; | |
43569 } | |
43570 } | |
43571 } | |
43572 for (var j = 0; j < binData[i].length; j++) { | |
43573 var bin = binData[i][j]; | |
43574 for (var k = 0; k < bin.bin.length; k++) { | |
43575 if (bin.bin[k].length == 0) { | |
43576 continue; | |
43577 } | |
43578 var weight = this.binSize(bin.bin[k]); | |
43579 var r = this.getBinRadius(weight, radius, max); | |
43580 var shift = this.shift(id, bin, r * resolution, bin.bin[k], i); | |
43581 var circle = new CircleObject(bin.x - shift.x, bin.y - shift.y, 0, 0, bin.bin[k], r, k, weight); | |
43582 circles[k].push(circle); | |
43583 for (var z = 0; z < bin.bin[k].length; z++) { | |
43584 hashMap[k][bin.bin[k][z].index] = circle; | |
43585 selectionMap[k][bin.bin[k][z].index] = false; | |
43586 } | |
43587 } | |
43588 } | |
43589 circleSets.push(circles); | |
43590 hashMaps.push(hashMap); | |
43591 selectionHashs.push(selectionMap); | |
43592 } | |
43593 this.binnings[id] = { | |
43594 circleSets : circleSets, | |
43595 hashMaps : hashMaps, | |
43596 selectionHashs : selectionHashs | |
43597 }; | |
43598 }, | |
43599 | |
43600 squareBinning : function() { | |
43601 | |
43602 var l = 20037508.34; | |
43603 var area0 = l * l * 4; | |
43604 var binCount = this.options.binCount; | |
43605 | |
43606 var bins = []; | |
43607 var binData = []; | |
43608 for (var k = 0; k < this.zoomLevels; k++) { | |
43609 bins.push([]); | |
43610 binData.push([]); | |
43611 } | |
43612 | |
43613 for (var i = 0; i < this.objects.length; i++) { | |
43614 for (var j = 0; j < this.objects[i].length; j++) { | |
43615 var o = this.objects[i][j]; | |
43616 if (!o.isGeospatial) { | |
43617 continue; | |
43618 } | |
43619 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
43620 p.transform(this.map.displayProjection, this.map.projection); | |
43621 o.x = p.x; | |
43622 o.y = p.y; | |
43623 for (var k = 0; k < this.zoomLevels; k++) { | |
43624 var bc = binCount * Math.pow(2, k); | |
43625 var a = 2 * l / bc; | |
43626 var binX = Math.floor((p.x + l) / (2 * l) * bc); | |
43627 var binY = Math.floor((p.y + l) / (2 * l) * bc); | |
43628 if ( typeof bins[k]['' + binX] == 'undefined') { | |
43629 bins[k]['' + binX] = []; | |
43630 } | |
43631 if ( typeof bins[k][''+binX]['' + binY] == 'undefined') { | |
43632 bins[k][''+binX]['' + binY] = []; | |
43633 for (var z = 0; z < this.objects.length; z++) { | |
43634 bins[k][''+binX]['' + binY].push([]); | |
43635 } | |
43636 var x = binX * a + a / 2 - l; | |
43637 var y = binY * a + a / 2 - l; | |
43638 binData[k].push({ | |
43639 bin : bins[k][''+binX]['' + binY], | |
43640 x : x, | |
43641 y : y, | |
43642 a : a, | |
43643 r : a / 2 | |
43644 }); | |
43645 } | |
43646 bins[k][''+binX][''+binY][i].push(o); | |
43647 } | |
43648 } | |
43649 } | |
43650 | |
43651 this.setCircleSet('square', binData); | |
43652 | |
43653 }, | |
43654 | |
43655 triangularBinning : function() { | |
43656 | |
43657 var l = 20037508.34; | |
43658 var a0 = this.options.binCount; | |
43659 var a1 = Math.sqrt(4 * a0 * a0 / Math.sqrt(3)); | |
43660 var binCount = a0 / a1 * a0; | |
43661 | |
43662 var bins = []; | |
43663 var binData = []; | |
43664 for (var k = 0; k < this.zoomLevels; k++) { | |
43665 bins.push([]); | |
43666 binData.push([]); | |
43667 } | |
43668 | |
43669 for (var i = 0; i < this.objects.length; i++) { | |
43670 for (var j = 0; j < this.objects[i].length; j++) { | |
43671 var o = this.objects[i][j]; | |
43672 if (!o.isGeospatial) { | |
43673 continue; | |
43674 } | |
43675 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
43676 p.transform(this.map.displayProjection, this.map.projection); | |
43677 o.x = p.x; | |
43678 o.y = p.y; | |
43679 for (var k = 0; k < this.zoomLevels; k++) { | |
43680 var x_bc = binCount * Math.pow(2, k); | |
43681 var y_bc = x_bc * x_bc / Math.sqrt(x_bc * x_bc - x_bc * x_bc / 4); | |
43682 var a = 2 * l / x_bc; | |
43683 var h = 2 * l / y_bc; | |
43684 var binY = Math.floor((p.y + l) / (2 * l) * y_bc); | |
43685 if ( typeof bins[k]['' + binY] == 'undefined') { | |
43686 bins[k]['' + binY] = []; | |
43687 } | |
43688 var triangleIndex; | |
43689 var partitionsX = x_bc * 2; | |
43690 var partition = Math.floor((p.x + l) / (2 * l) * partitionsX); | |
43691 var xMax = a / 2; | |
43692 var yMax = h; | |
43693 var x = p.x + l - partition * a / 2; | |
43694 var y = p.y + l - binY * h; | |
43695 if (binY % 2 == 0 && partition % 2 == 1 || binY % 2 == 1 && partition % 2 == 0) { | |
43696 if (y + yMax / xMax * x < yMax) { | |
43697 triangleIndex = partition; | |
43698 } else { | |
43699 triangleIndex = partition + 1; | |
43700 } | |
43701 } else { | |
43702 if (y > yMax / xMax * x) { | |
43703 triangleIndex = partition; | |
43704 } else { | |
43705 triangleIndex = partition + 1; | |
43706 } | |
43707 } | |
43708 if ( typeof bins[k][''+binY]['' + triangleIndex] == 'undefined') { | |
43709 bins[k][''+binY]['' + triangleIndex] = []; | |
43710 for (var z = 0; z < this.objects.length; z++) { | |
43711 bins[k][''+binY]['' + triangleIndex].push([]); | |
43712 } | |
43713 var r = Math.sqrt(3) / 6 * a; | |
43714 var x = (triangleIndex - 1) * a / 2 + a / 2 - l; | |
43715 var y; | |
43716 if (binY % 2 == 0 && triangleIndex % 2 == 0 || binY % 2 == 1 && triangleIndex % 2 == 1) { | |
43717 y = binY * h + h - r - l; | |
43718 } else { | |
43719 y = binY * h + r - l; | |
43720 } | |
43721 binData[k].push({ | |
43722 bin : bins[k][''+binY]['' + triangleIndex], | |
43723 x : x, | |
43724 y : y, | |
43725 a : a, | |
43726 r : r | |
43727 }); | |
43728 } | |
43729 bins[k][''+binY][''+triangleIndex][i].push(o); | |
43730 } | |
43731 } | |
43732 } | |
43733 | |
43734 this.setCircleSet('triangular', binData); | |
43735 | |
43736 }, | |
43737 | |
43738 hexagonalBinning : function() { | |
43739 | |
43740 var l = 20037508.34; | |
43741 var a0 = this.options.binCount; | |
43742 var a2 = Math.sqrt(4 * a0 * a0 / Math.sqrt(3)) / Math.sqrt(6); | |
43743 var binCount = a0 / a2 * a0; | |
43744 | |
43745 var bins = []; | |
43746 var binData = []; | |
43747 for (var k = 0; k < this.zoomLevels; k++) { | |
43748 bins.push([]); | |
43749 binData.push([]); | |
43750 } | |
43751 | |
43752 for (var i = 0; i < this.objects.length; i++) { | |
43753 for (var j = 0; j < this.objects[i].length; j++) { | |
43754 var o = this.objects[i][j]; | |
43755 if (!o.isGeospatial) { | |
43756 continue; | |
43757 } | |
43758 var p = new OpenLayers.Geometry.Point(o.getLongitude(this.options.mapIndex), o.getLatitude(this.options.mapIndex), null); | |
43759 p.transform(this.map.displayProjection, this.map.projection); | |
43760 o.x = p.x; | |
43761 o.y = p.y; | |
43762 for (var k = 0; k < this.zoomLevels; k++) { | |
43763 var x_bc = binCount * Math.pow(2, k); | |
43764 var y_bc = x_bc * x_bc / Math.sqrt(x_bc * x_bc - x_bc * x_bc / 4); | |
43765 var a = 2 * l / x_bc; | |
43766 var h = 2 * l / y_bc; | |
43767 var binY = Math.floor((p.y + l) / (2 * l) * y_bc); | |
43768 if ( typeof bins[k]['' + binY] == 'undefined') { | |
43769 bins[k]['' + binY] = []; | |
43770 } | |
43771 var triangleIndex; | |
43772 var partitionsX = x_bc * 2; | |
43773 var partition = Math.floor((p.x + l) / (2 * l) * partitionsX); | |
43774 var xMax = a / 2; | |
43775 var yMax = h; | |
43776 var x = p.x + l - partition * a / 2; | |
43777 var y = p.y + l - binY * h; | |
43778 if (binY % 2 == 0 && partition % 2 == 1 || binY % 2 == 1 && partition % 2 == 0) { | |
43779 if (y + yMax / xMax * x < yMax) { | |
43780 triangleIndex = partition; | |
43781 } else { | |
43782 triangleIndex = partition + 1; | |
43783 } | |
43784 } else { | |
43785 if (y > yMax / xMax * x) { | |
43786 triangleIndex = partition; | |
43787 } else { | |
43788 triangleIndex = partition + 1; | |
43789 } | |
43790 } | |
43791 if ( typeof bins[k][''+binY]['' + triangleIndex] == 'undefined') { | |
43792 bins[k][''+binY]['' + triangleIndex] = []; | |
43793 for (var z = 0; z < this.objects.length; z++) { | |
43794 bins[k][''+binY]['' + triangleIndex].push([]); | |
43795 } | |
43796 var r = Math.sqrt(3) / 6 * a; | |
43797 var x = (triangleIndex - 1) * a / 2 + a / 2 - l; | |
43798 var y; | |
43799 if (binY % 2 == 0 && triangleIndex % 2 == 0 || binY % 2 == 1 && triangleIndex % 2 == 1) { | |
43800 y = binY * h + h - r - l; | |
43801 } else { | |
43802 y = binY * h + r - l; | |
43803 } | |
43804 binData[k].push({ | |
43805 bin : bins[k][''+binY]['' + triangleIndex], | |
43806 x : x, | |
43807 y : y, | |
43808 a : a, | |
43809 r : r, | |
43810 h : h, | |
43811 binX : triangleIndex, | |
43812 binY : binY | |
43813 }); | |
43814 } | |
43815 bins[k][''+binY][''+triangleIndex][i].push(o); | |
43816 } | |
43817 } | |
43818 } | |
43819 | |
43820 var hexaBins = []; | |
43821 var hexaBinData = []; | |
43822 for (var k = 0; k < this.zoomLevels; k++) { | |
43823 hexaBins.push([]); | |
43824 hexaBinData.push([]); | |
43825 } | |
43826 | |
43827 for (var i = 0; i < binData.length; i++) { | |
43828 for (var j = 0; j < binData[i].length; j++) { | |
43829 var bin = binData[i][j]; | |
43830 var binY = Math.floor(bin.binY / 2); | |
43831 var binX = Math.floor(bin.binX / 3); | |
43832 var x, y; | |
43833 var a = bin.a; | |
43834 var h = bin.h; | |
43835 if (bin.binX % 6 < 3) { | |
43836 if ( typeof hexaBins[i]['' + binY] == 'undefined') { | |
43837 hexaBins[i]['' + binY] = []; | |
43838 } | |
43839 y = binY * 2 * bin.h + bin.h - l; | |
43840 x = binX * 1.5 * bin.a + a / 2 - l; | |
43841 } else { | |
43842 if (bin.binY % 2 == 1) { | |
43843 binY++; | |
43844 } | |
43845 if ( typeof hexaBins[i]['' + binY] == 'undefined') { | |
43846 hexaBins[i]['' + binY] = []; | |
43847 } | |
43848 y = binY * 2 * bin.h - l; | |
43849 x = binX * 1.5 * bin.a + a / 2 - l; | |
43850 } | |
43851 if ( typeof hexaBins[i][''+binY]['' + binX] == 'undefined') { | |
43852 hexaBins[i][''+binY]['' + binX] = []; | |
43853 for (var z = 0; z < this.objects.length; z++) { | |
43854 hexaBins[i][''+binY]['' + binX].push([]); | |
43855 } | |
43856 hexaBinData[i].push({ | |
43857 bin : hexaBins[i][''+binY]['' + binX], | |
43858 x : x, | |
43859 y : y, | |
43860 a : bin.a, | |
43861 r : bin.h | |
43862 }); | |
43863 } | |
43864 for (var k = 0; k < bin.bin.length; k++) { | |
43865 for (var m = 0; m < bin.bin[k].length; m++) { | |
43866 hexaBins[i][''+binY][''+binX][k].push(bin.bin[k][m]); | |
43867 } | |
43868 } | |
43869 } | |
43870 } | |
43871 | |
43872 this.setCircleSet('hexagonal', hexaBinData); | |
43873 | |
43874 } | |
43875 } | |
43876 | |
43877 /* | |
43878 * MapDataSource.js | |
43879 * | |
43880 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
43881 * | |
43882 * This library is free software; you can redistribute it and/or | |
43883 * modify it under the terms of the GNU Lesser General Public | |
43884 * License as published by the Free Software Foundation; either | |
43885 * version 3 of the License, or (at your option) any later version. | |
43886 * | |
43887 * This library is distributed in the hope that it will be useful, | |
43888 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
43889 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
43890 * Lesser General Public License for more details. | |
43891 * | |
43892 * You should have received a copy of the GNU Lesser General Public | |
43893 * License along with this library; if not, write to the Free Software | |
43894 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
43895 * MA 02110-1301 USA | |
43896 */ | |
43897 | |
43898 /** | |
43899 * @class MapDataSource | |
43900 * implementation for aggregation of map items | |
43901 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
43902 * @release 1.0 | |
43903 * @release date: 2012-07-27 | |
43904 * @version date: 2012-07-27 | |
43905 * | |
43906 * @param {OpenLayers.Map} olMap openlayers map object of the map widget | |
43907 * @param {JSON} options map configuration | |
43908 */ | |
43909 function MapDataSource(olMap, options) { | |
43910 | |
43911 this.olMap = olMap; | |
43912 this.circleSets = []; | |
43913 this.binning = new Binning(olMap, options); | |
43914 | |
43915 }; | |
43916 | |
43917 MapDataSource.prototype = { | |
43918 | |
43919 /** | |
43920 * initializes the MapDataSource | |
43921 * @param {MapObject[][]} mapObjects an array of map objects of different sets | |
43922 */ | |
43923 initialize : function(mapObjects) { | |
43924 | |
43925 if (mapObjects != this.mapObjects) { | |
43926 this.binning.reset(); | |
43927 this.binning.setObjects(mapObjects); | |
43928 } | |
43929 this.mapObjects = mapObjects; | |
43930 | |
43931 var set = this.binning.getSet(); | |
43932 this.circleSets = set.circleSets; | |
43933 this.binSets = set.binSets; | |
43934 this.hashMapping = set.hashMaps; | |
43935 | |
43936 }, | |
43937 | |
43938 getObjectsByZoom : function() { | |
43939 var zoom = Math.floor(this.olMap.getZoom()); | |
43940 if (this.circleSets.length < zoom) { | |
43941 return null; | |
43942 } | |
43943 return this.circleSets[zoom]; | |
43944 }, | |
43945 | |
43946 getAllObjects : function() { | |
43947 if (this.circleSets.length == 0) { | |
43948 return null; | |
43949 } | |
43950 return this.circleSets; | |
43951 }, | |
43952 | |
43953 getAllBins : function() { | |
43954 if (this.binSets.length == 0) { | |
43955 return null; | |
43956 } | |
43957 return this.binSets; | |
43958 }, | |
43959 | |
43960 clearOverlay : function() { | |
43961 var zoom = Math.floor(this.olMap.getZoom()); | |
43962 var circles = this.circleSets[zoom]; | |
43963 for (var i in circles ) { | |
43964 for (var j in circles[i] ) { | |
43965 circles[i][j].reset(); | |
43966 } | |
43967 } | |
43968 }, | |
43969 | |
43970 setOverlay : function(mapObjects) { | |
43971 var zoom = Math.floor(this.olMap.getZoom()); | |
43972 for (var j in mapObjects ) { | |
43973 for (var k in mapObjects[j] ) { | |
43974 var o = mapObjects[j][k]; | |
43975 if (o.isGeospatial) { | |
43976 this.hashMapping[zoom][j][o.index].overlayElements.push(o); | |
43977 this.hashMapping[zoom][j][o.index].overlay += o.weight; | |
43978 } | |
43979 } | |
43980 } | |
43981 }, | |
43982 | |
43983 size : function() { | |
43984 if (this.circleSets.length == 0) { | |
43985 return 0; | |
43986 } | |
43987 return this.circleSets[0].length; | |
43988 }, | |
43989 | |
43990 getCircle : function(index, id) { | |
43991 var zoom = Math.floor(this.olMap.getZoom()); | |
43992 return this.hashMapping[zoom][index][id]; | |
43993 } | |
43994 }; | |
43995 /* | |
43996 * Clustering.js | |
43997 * | |
43998 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
43999 * | |
44000 * This library is free software; you can redistribute it and/or | |
44001 * modify it under the terms of the GNU Lesser General Public | |
44002 * License as published by the Free Software Foundation; either | |
44003 * version 3 of the License, or (at your option) any later version. | |
44004 * | |
44005 * This library is distributed in the hope that it will be useful, | |
44006 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
44007 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
44008 * Lesser General Public License for more details. | |
44009 * | |
44010 * You should have received a copy of the GNU Lesser General Public | |
44011 * License along with this library; if not, write to the Free Software | |
44012 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
44013 * MA 02110-1301 USA | |
44014 */ | |
44015 | |
44016 /** | |
44017 * @class Vertex, Edge, Triangle, Clustering, BinaryHeap | |
44018 * Dynamic Delaunay clustering algorithm (see GeoTemCo paper) | |
44019 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
44020 * @release 1.0 | |
44021 * @release date: 2012-07-27 | |
44022 * @version date: 2012-07-27 | |
44023 */ | |
44024 | |
44025 function Vertex(x, y, categories, binning) { | |
44026 this.x = x; | |
44027 this.y = y; | |
44028 this.radius | |
44029 this.size = 0; | |
44030 this.elements = []; | |
44031 this.radii = []; | |
44032 this.weights = []; | |
44033 this.legal = true; | |
44034 this.binning = binning; | |
44035 if (categories != undefined) { | |
44036 for (var i = 0; i < categories; i++) { | |
44037 this.elements.push([]); | |
44038 this.weights.push(0); | |
44039 } | |
44040 } | |
44041 } | |
44042 | |
44043 Vertex.prototype.merge = function(v0, v1) { | |
44044 for (var i = 0; i < v0.elements.length; i++) { | |
44045 this.elements[i] = v0.elements[i].concat(v1.elements[i]); | |
44046 this.weights[i] = v0.weights[i] + v1.weights[i]; | |
44047 this.size += this.weights[i]; | |
44048 } | |
44049 } | |
44050 | |
44051 Vertex.prototype.CalculateRadius = function(resolution) { | |
44052 this.radii = []; | |
44053 for (i in this.elements ) { | |
44054 this.radii.push(this.binning.getRadius(this.weights[i])); | |
44055 } | |
44056 if (this.radii.length == 1) { | |
44057 this.radius = this.radii[0] * resolution; | |
44058 } else { | |
44059 var count = 0; | |
44060 var max1 = 0; | |
44061 var max2 = 0; | |
44062 for (i in this.radii ) { | |
44063 if (this.radii[i] != 0) { | |
44064 count++; | |
44065 } | |
44066 if (this.radii[i] > max1) { | |
44067 if (max1 > max2) { | |
44068 max2 = max1; | |
44069 } | |
44070 max1 = this.radii[i]; | |
44071 } else if (this.radii[i] > max2) { | |
44072 max2 = this.radii[i]; | |
44073 } | |
44074 } | |
44075 if (count == 1) { | |
44076 this.radius = max1 * resolution; | |
44077 } else if (count == 2) { | |
44078 this.radius = (max1 + max2) * resolution; | |
44079 } else if (count == 3) { | |
44080 var d = (2 / 3 * Math.sqrt(3) - 1) * max1; | |
44081 this.radius = (d + max1 + max2) * resolution; | |
44082 } else if (count == 4) { | |
44083 var d = (Math.sqrt(2) - 1) * max2; | |
44084 this.radius = (d + max1 + max2) * resolution; | |
44085 } | |
44086 } | |
44087 } | |
44088 | |
44089 Vertex.prototype.addElement = function(e, weight, index) { | |
44090 this.elements[index].push(e); | |
44091 this.size += weight; | |
44092 this.weights[index] += weight; | |
44093 } | |
44094 function Edge(v0, v1) { | |
44095 this.v0 = v0; | |
44096 this.v1 = v1; | |
44097 this.leftFace | |
44098 this.rightFace | |
44099 this.legal = true; | |
44100 this.setLength(); | |
44101 } | |
44102 | |
44103 Edge.prototype.setLength = function() { | |
44104 var dx = this.v0.x - this.v1.x; | |
44105 var dy = this.v0.y - this.v1.y; | |
44106 this.length = Math.sqrt(dx * dx + dy * dy); | |
44107 } | |
44108 | |
44109 Edge.prototype.contains = function(v) { | |
44110 if (this.v0 == v || this.v1 == v) { | |
44111 return true; | |
44112 } | |
44113 return false; | |
44114 } | |
44115 | |
44116 Edge.prototype.replaceFace = function(f_old, f_new) { | |
44117 if (this.leftFace == f_old) { | |
44118 this.leftFace = f_new; | |
44119 } else if (this.rightFace == f_old) { | |
44120 this.rightFace = f_new; | |
44121 } | |
44122 } | |
44123 | |
44124 Edge.prototype.setFace = function(f) { | |
44125 if (f.leftOf(this)) { | |
44126 this.leftFace = f; | |
44127 } else { | |
44128 this.rightFace = f; | |
44129 } | |
44130 } | |
44131 | |
44132 Edge.prototype.setFaces = function(f1, f2) { | |
44133 if (f1.leftOf(this)) { | |
44134 this.leftFace = f1; | |
44135 this.rightFace = f2; | |
44136 } else { | |
44137 this.leftFace = f2; | |
44138 this.rightFace = f1; | |
44139 } | |
44140 } | |
44141 | |
44142 Edge.prototype.removeFace = function(f) { | |
44143 if (this.leftFace == f) { | |
44144 this.leftFace = null; | |
44145 } else { | |
44146 this.rightFace = null; | |
44147 } | |
44148 } | |
44149 | |
44150 Edge.prototype.equals = function(e) { | |
44151 if (this.v0 == e.v0 && this.v1 == e.v1 || this.v0 == e.v1 && this.v1 == e.v0) { | |
44152 return true; | |
44153 } | |
44154 return false; | |
44155 } | |
44156 function Triangle(edges) { | |
44157 this.edges = edges; | |
44158 this.setVertices(); | |
44159 this.descendants = []; | |
44160 } | |
44161 | |
44162 Triangle.prototype.getTriple = function(e) { | |
44163 var i = arrayIndex(this.edges, e); | |
44164 return { | |
44165 e_s : this.edges[(i + 1) % 3], | |
44166 e_p : this.edges[(i + 2) % 3], | |
44167 u : this.vertices[(i + 2) % 3] | |
44168 }; | |
44169 } | |
44170 | |
44171 Triangle.prototype.leftOf = function(e) { | |
44172 var i = arrayIndex(this.edges, e); | |
44173 if (this.vertices[i].y != this.vertices[(i + 1) % 3].y) { | |
44174 return this.vertices[i].y > this.vertices[(i + 1) % 3].y; | |
44175 } | |
44176 return this.vertices[i].y > this.vertices[(i + 2) % 3].y; | |
44177 } | |
44178 | |
44179 Triangle.prototype.getNext = function(v) { | |
44180 var i = arrayIndex(this.vertices, v); | |
44181 return this.vertices[(i + 1) % 3]; | |
44182 } | |
44183 | |
44184 Triangle.prototype.oppositeEdge = function(v) { | |
44185 var i = arrayIndex(this.vertices, v); | |
44186 return this.edges[(i + 1) % 3]; | |
44187 } | |
44188 | |
44189 Triangle.prototype.contains = function(v) { | |
44190 return arrayIndex(this.vertices, v) != -1; | |
44191 } | |
44192 | |
44193 Triangle.prototype.replace = function(e_old, e_new) { | |
44194 this.edges[arrayIndex(this.edges, e_old)] = e_new; | |
44195 } | |
44196 | |
44197 Triangle.prototype.setVertices = function() { | |
44198 if (this.edges[1].v0 == this.edges[0].v0 || this.edges[1].v1 == this.edges[0].v0) { | |
44199 this.vertices = [this.edges[0].v1, this.edges[0].v0]; | |
44200 } else { | |
44201 this.vertices = [this.edges[0].v0, this.edges[0].v1]; | |
44202 } | |
44203 if (this.edges[2].v0 == this.vertices[0]) { | |
44204 this.vertices.push(this.edges[2].v1); | |
44205 } else { | |
44206 this.vertices.push(this.edges[2].v0); | |
44207 } | |
44208 } | |
44209 | |
44210 Triangle.prototype.replaceBy = function(triangles) { | |
44211 this.descendants = triangles; | |
44212 this.edges[0].replaceFace(this, triangles[0]); | |
44213 this.edges[1].replaceFace(this, triangles[1]); | |
44214 this.edges[2].replaceFace(this, triangles[2]); | |
44215 } | |
44216 | |
44217 Triangle.prototype.CalcCircumcircle = function() { | |
44218 var v0 = this.vertices[0]; | |
44219 var v1 = this.vertices[1]; | |
44220 var v2 = this.vertices[2]; | |
44221 var A = v1.x - v0.x; | |
44222 var B = v1.y - v0.y; | |
44223 var C = v2.x - v0.x; | |
44224 var D = v2.y - v0.y; | |
44225 var E = A * (v0.x + v1.x) + B * (v0.y + v1.y); | |
44226 var F = C * (v0.x + v2.x) + D * (v0.y + v2.y); | |
44227 var G = 2.0 * (A * (v2.y - v1.y) - B * (v2.x - v1.x)); | |
44228 var cx = (D * E - B * F) / G; | |
44229 var cy = (A * F - C * E) / G; | |
44230 this.center = new Vertex(cx, cy); | |
44231 var dx = this.center.x - v0.x; | |
44232 var dy = this.center.y - v0.y; | |
44233 this.radius_squared = dx * dx + dy * dy; | |
44234 }; | |
44235 | |
44236 Triangle.prototype.inCircumcircle = function(v) { | |
44237 if (this.radius_squared == undefined) { | |
44238 this.CalcCircumcircle(); | |
44239 } | |
44240 var dx = this.center.x - v.x; | |
44241 var dy = this.center.y - v.y; | |
44242 var dist_squared = dx * dx + dy * dy; | |
44243 return (dist_squared <= this.radius_squared ); | |
44244 }; | |
44245 | |
44246 Triangle.prototype.interior = function(v) { | |
44247 var v0 = this.vertices[0]; | |
44248 var v1 = this.vertices[1]; | |
44249 var v2 = this.vertices[2]; | |
44250 var dotAB = (v.x - v0.x ) * (v0.y - v1.y ) + (v.y - v0.y ) * (v1.x - v0.x ); | |
44251 var dotBC = (v.x - v1.x ) * (v1.y - v2.y ) + (v.y - v1.y ) * (v2.x - v1.x ); | |
44252 var dotCA = (v.x - v2.x ) * (v2.y - v0.y ) + (v.y - v2.y ) * (v0.x - v2.x ); | |
44253 if (dotAB > 0 || dotBC > 0 || dotCA > 0) { | |
44254 return null; | |
44255 } else if (dotAB < 0 && dotBC < 0 && dotCA < 0) { | |
44256 return this; | |
44257 } else if (dotAB == 0) { | |
44258 if (dotBC == 0) { | |
44259 return this.vertices[1]; | |
44260 } else if (dotCA == 0) { | |
44261 return this.vertices[0]; | |
44262 } | |
44263 return this.edges[0]; | |
44264 } else if (dotBC == 0) { | |
44265 if (dotCA == 0) { | |
44266 return this.vertices[2]; | |
44267 } | |
44268 return this.edges[1]; | |
44269 } else if (dotCA == 0) { | |
44270 return this.edges[2]; | |
44271 } | |
44272 }; | |
44273 | |
44274 function Clustering(xMin, yMin, xMax, yMax) { | |
44275 this.triangles = []; | |
44276 this.newTriangles = []; | |
44277 this.bbox = { | |
44278 x1 : xMin, | |
44279 y1 : yMin, | |
44280 x2 : xMax, | |
44281 y2 : yMax | |
44282 }; | |
44283 this.CreateBoundingTriangle(); | |
44284 this.edges = []; | |
44285 this.vertices = []; | |
44286 this.legalizes = 0; | |
44287 this.collapses = 0; | |
44288 } | |
44289 | |
44290 Clustering.prototype.locate = function(v) { | |
44291 if (this.boundingTriangle.descendants.length == 0) { | |
44292 return this.boundingTriangle; | |
44293 } | |
44294 var triangles = this.boundingTriangle.descendants; | |
44295 while (true) { | |
44296 for (var i = 0; i < triangles.length; i++) { | |
44297 var simplex = triangles[i].interior(v); | |
44298 if (simplex == null) { | |
44299 continue; | |
44300 } | |
44301 if ( simplex instanceof Vertex || this.isLeaf(triangles[i])) { | |
44302 return simplex; | |
44303 } | |
44304 triangles = triangles[i].descendants; | |
44305 break; | |
44306 } | |
44307 } | |
44308 } | |
44309 | |
44310 Clustering.prototype.legalize = function(v, e, t0_old) { | |
44311 if (!e.v0.legal && !e.v1.legal) { | |
44312 return; | |
44313 } | |
44314 this.legalizes++; | |
44315 var flip = false; | |
44316 var t1_old, tr1; | |
44317 if (e.leftFace == t0_old && e.rightFace.inCircumcircle(v)) { | |
44318 flip = true; | |
44319 t1_old = e.rightFace; | |
44320 } else if (e.rightFace == t0_old && e.leftFace.inCircumcircle(v)) { | |
44321 flip = true; | |
44322 t1_old = e.leftFace; | |
44323 } | |
44324 if (flip) { | |
44325 var tr0 = t0_old.getTriple(e); | |
44326 var tr1 = t1_old.getTriple(e); | |
44327 var e_flip = new Edge(tr0.u, tr1.u); | |
44328 var poly = []; | |
44329 poly.push(e.v0); | |
44330 poly.push(e_flip.v0); | |
44331 poly.push(e.v1); | |
44332 poly.push(e_flip.v1); | |
44333 if (!this.JordanTest(poly, e_flip)) { | |
44334 return; | |
44335 } | |
44336 e.legal = false; | |
44337 this.edges.push(e_flip); | |
44338 var t0_new = new Triangle([e_flip, tr0.e_p, tr1.e_s]); | |
44339 var t1_new = new Triangle([e_flip, tr1.e_p, tr0.e_s]); | |
44340 e_flip.setFaces(t0_new, t1_new); | |
44341 tr0.e_p.replaceFace(t0_old, t0_new); | |
44342 tr1.e_s.replaceFace(t1_old, t0_new); | |
44343 tr1.e_p.replaceFace(t1_old, t1_new); | |
44344 tr0.e_s.replaceFace(t0_old, t1_new); | |
44345 t0_old.descendants = [t0_new, t1_new]; | |
44346 t1_old.descendants = [t0_new, t1_new]; | |
44347 this.legalize(v, t0_new.edges[2], t0_new); | |
44348 this.legalize(v, t1_new.edges[1], t1_new); | |
44349 } | |
44350 } | |
44351 | |
44352 Clustering.prototype.add = function(v) { | |
44353 this.addVertex(v, this.locate(v)); | |
44354 } | |
44355 | |
44356 Clustering.prototype.addVertex = function(v, simplex) { | |
44357 if ( simplex instanceof Vertex) { | |
44358 simplex.merge(simplex, v); | |
44359 } else if ( simplex instanceof Edge) { | |
44360 this.vertices.push(v); | |
44361 simplex.legal = false; | |
44362 var tr0 = simplex.leftFace.getTriple(simplex); | |
44363 var tr1 = simplex.rightFace.getTriple(simplex); | |
44364 var e0 = new Edge(v, tr0.u); | |
44365 var e1 = new Edge(v, simplex.leftFace.getNext(tr0.u)); | |
44366 var e2 = new Edge(v, tr1.u); | |
44367 var e3 = new Edge(v, simplex.rightFace.getNext(tr1.u)); | |
44368 var t0 = new Triangle([e0, tr0.e_p, e1]); | |
44369 var t1 = new Triangle([e1, tr1.e_s, e2]); | |
44370 var t2 = new Triangle([e2, tr1.e_p, e3]); | |
44371 var t3 = new Triangle([e3, tr0.e_s, e0]); | |
44372 simplex.leftFace.descendants = [t0, t3]; | |
44373 simplex.rightFace.descendants = [t1, t2]; | |
44374 this.edges.push(e0); | |
44375 this.edges.push(e1); | |
44376 this.edges.push(e2); | |
44377 this.edges.push(e3); | |
44378 e0.setFaces(t0, t3); | |
44379 e1.setFaces(t0, t1); | |
44380 e2.setFaces(t1, t2); | |
44381 e3.setFaces(t2, t3); | |
44382 tr0.e_p.replaceFace(simplex.leftFace, t0); | |
44383 tr1.e_s.replaceFace(simplex.rightFace, t1); | |
44384 tr1.e_p.replaceFace(simplex.rightFace, t2); | |
44385 tr0.e_s.replaceFace(simplex.leftFace, t3); | |
44386 this.legalize(v, tr0.e_p, t0); | |
44387 this.legalize(v, tr1.e_s, t1); | |
44388 this.legalize(v, tr1.e_p, t2); | |
44389 this.legalize(v, tr0.e_s, t3); | |
44390 } else { | |
44391 this.vertices.push(v); | |
44392 var e_i = new Edge(simplex.vertices[0], v); | |
44393 var e_j = new Edge(simplex.vertices[1], v); | |
44394 var e_k = new Edge(simplex.vertices[2], v); | |
44395 this.edges.push(e_i); | |
44396 this.edges.push(e_j); | |
44397 this.edges.push(e_k); | |
44398 var t0 = new Triangle([e_i, simplex.edges[0], e_j]); | |
44399 var t1 = new Triangle([e_j, simplex.edges[1], e_k]); | |
44400 var t2 = new Triangle([e_k, simplex.edges[2], e_i]); | |
44401 e_i.setFaces(t0, t2); | |
44402 e_j.setFaces(t0, t1); | |
44403 e_k.setFaces(t1, t2); | |
44404 simplex.replaceBy([t0, t1, t2]); | |
44405 this.legalize(v, simplex.edges[0], t0); | |
44406 this.legalize(v, simplex.edges[1], t1); | |
44407 this.legalize(v, simplex.edges[2], t2); | |
44408 } | |
44409 } | |
44410 | |
44411 Clustering.prototype.isLeaf = function(t) { | |
44412 return t.descendants.length == 0; | |
44413 } | |
44414 | |
44415 Clustering.prototype.CreateBoundingTriangle = function() { | |
44416 var dx = (this.bbox.x2 - this.bbox.x1 ) * 10; | |
44417 var dy = (this.bbox.y2 - this.bbox.y1 ) * 10; | |
44418 var v0 = new Vertex(this.bbox.x1 - dx, this.bbox.y1 - dy * 3); | |
44419 var v1 = new Vertex(this.bbox.x2 + dx * 3, this.bbox.y2 + dy); | |
44420 var v2 = new Vertex(this.bbox.x1 - dx, this.bbox.y2 + dy); | |
44421 var e0 = new Edge(v1, v0); | |
44422 var e1 = new Edge(v0, v2); | |
44423 var e2 = new Edge(v2, v1); | |
44424 v0.legal = false; | |
44425 v1.legal = false; | |
44426 v2.legal = false; | |
44427 this.boundingTriangle = new Triangle([e0, e1, e2]); | |
44428 var inf = new Triangle([e0, e1, e2]); | |
44429 e0.setFaces(this.boundingTriangle, inf); | |
44430 e1.setFaces(this.boundingTriangle, inf); | |
44431 e2.setFaces(this.boundingTriangle, inf); | |
44432 } | |
44433 | |
44434 Clustering.prototype.mergeVertices = function(e) { | |
44435 this.collapses++; | |
44436 var s0 = e.v0.size; | |
44437 var s1 = e.v1.size; | |
44438 var x = (e.v0.x * s0 + e.v1.x * s1 ) / (s0 + s1 ); | |
44439 var y = (e.v0.y * s0 + e.v1.y * s1 ) / (s0 + s1 ); | |
44440 var v = new Vertex(x, y, e.v0.elements.length, e.v0.binning); | |
44441 v.merge(e.v0, e.v1); | |
44442 | |
44443 e.v0.legal = false; | |
44444 e.v1.legal = false; | |
44445 | |
44446 var hole = []; | |
44447 var oldFacets = []; | |
44448 e.legal = false; | |
44449 | |
44450 var vertices = []; | |
44451 var traverse = function(eLeft, eRight, triangle) { | |
44452 eLeft.legal = false; | |
44453 do { | |
44454 var triple; | |
44455 if (eLeft.leftFace == triangle) { | |
44456 triple = eLeft.rightFace.getTriple(eLeft); | |
44457 oldFacets.push(eLeft.rightFace); | |
44458 triple.e_s.removeFace(eLeft.rightFace); | |
44459 triangle = eLeft.rightFace; | |
44460 } else { | |
44461 triple = eLeft.leftFace.getTriple(eLeft); | |
44462 oldFacets.push(eLeft.leftFace); | |
44463 triple.e_s.removeFace(eLeft.leftFace); | |
44464 triangle = eLeft.leftFace; | |
44465 } | |
44466 if (arrayIndex(hole, triple.e_s) == -1) { | |
44467 hole.push(triple.e_s); | |
44468 } | |
44469 vertices.push(triple.u); | |
44470 eLeft = triple.e_p; | |
44471 eLeft.legal = false; | |
44472 } while( eLeft != eRight ); | |
44473 } | |
44474 var tr0 = e.leftFace.getTriple(e); | |
44475 var tr1 = e.rightFace.getTriple(e); | |
44476 oldFacets.push(e.leftFace); | |
44477 oldFacets.push(e.rightFace); | |
44478 traverse(tr0.e_p, tr1.e_s, e.leftFace); | |
44479 traverse(tr1.e_p, tr0.e_s, e.rightFace); | |
44480 | |
44481 var hd = new Clustering(this.bbox.x1 - 10, this.bbox.y1 - 10, this.bbox.x2 + 10, this.bbox.y2 + 10); | |
44482 var hull = []; | |
44483 for (var i in hole ) { | |
44484 if (!(hole[i].leftFace == null && hole[i].rightFace == null)) { | |
44485 hull.push(hole[i].v0); | |
44486 hull.push(hole[i].v1); | |
44487 } | |
44488 } | |
44489 var hullVertices = []; | |
44490 var distinct = []; | |
44491 for (var i in vertices ) { | |
44492 if (arrayIndex(distinct, vertices[i]) == -1) { | |
44493 hd.add(vertices[i]); | |
44494 distinct.push(vertices[i]); | |
44495 } | |
44496 if (arrayIndex(hull, vertices[i]) != -1) { | |
44497 hullVertices.push(vertices[i]); | |
44498 } | |
44499 } | |
44500 | |
44501 var newFacets = []; | |
44502 var isBoundary = function(e) { | |
44503 for (var i = 0; i < hole.length; i++) { | |
44504 if (hole[i].equals(e)) { | |
44505 return i; | |
44506 } | |
44507 } | |
44508 return -1; | |
44509 } | |
44510 var holeEdges = new Array(hole.length); | |
44511 var nonHoleEdges = []; | |
44512 | |
44513 for (var i = 0; i < hd.edges.length; i++) { | |
44514 var e = hd.edges[i]; | |
44515 var b = isBoundary(e); | |
44516 if (b != -1) { | |
44517 if (!e.legal) { | |
44518 var t1 = e.leftFace.getTriple(e); | |
44519 var t2 = e.rightFace.getTriple(e); | |
44520 var edge = new Edge(t1.u, t2.u); | |
44521 for (var j = 0; j < hd.edges.length; j++) { | |
44522 if (hd.edges[j].equals(edge) && hd.edges[j].legal) { | |
44523 hd.edges[j].legal = false; | |
44524 break; | |
44525 } | |
44526 } | |
44527 t1.e_p.setFace(e.leftFace); | |
44528 t1.e_s.setFace(e.leftFace); | |
44529 t2.e_p.setFace(e.rightFace); | |
44530 t2.e_s.setFace(e.rightFace); | |
44531 | |
44532 e.legal = true; | |
44533 } | |
44534 holeEdges[b] = e; | |
44535 } else { | |
44536 nonHoleEdges.push(e); | |
44537 } | |
44538 } | |
44539 | |
44540 for (var i = 0; i < holeEdges.length; i++) { | |
44541 var e = holeEdges[i]; | |
44542 if (hole[i].leftFace == null) { | |
44543 hole[i].leftFace = e.leftFace; | |
44544 hole[i].leftFace.replace(e, hole[i]); | |
44545 if (arrayIndex(newFacets, hole[i].leftFace) == -1) { | |
44546 newFacets.push(hole[i].leftFace); | |
44547 } | |
44548 } | |
44549 if (hole[i].rightFace == null) { | |
44550 hole[i].rightFace = e.rightFace; | |
44551 hole[i].rightFace.replace(e, hole[i]); | |
44552 if (arrayIndex(newFacets, hole[i].rightFace) == -1) { | |
44553 newFacets.push(hole[i].rightFace); | |
44554 } | |
44555 } | |
44556 } | |
44557 | |
44558 for (var i = 0; i < nonHoleEdges.length; i++) { | |
44559 var e = nonHoleEdges[i]; | |
44560 if (!e.legal) { | |
44561 continue; | |
44562 } | |
44563 if (this.JordanTest(hullVertices, e)) { | |
44564 this.edges.push(e); | |
44565 if (arrayIndex(newFacets, e.rightFace) == -1) { | |
44566 newFacets.push(e.rightFace); | |
44567 } | |
44568 if (arrayIndex(newFacets, e.leftFace) == -1) { | |
44569 newFacets.push(e.leftFace); | |
44570 } | |
44571 } | |
44572 } | |
44573 | |
44574 for (var i in oldFacets ) { | |
44575 oldFacets[i].descendants = newFacets; | |
44576 } | |
44577 | |
44578 for (var i = 0; i < newFacets.length; i++) { | |
44579 var simplex = newFacets[i].interior(v); | |
44580 if (simplex == null) { | |
44581 continue; | |
44582 } else { | |
44583 this.addVertex(v, simplex); | |
44584 break; | |
44585 } | |
44586 } | |
44587 | |
44588 return v; | |
44589 | |
44590 } | |
44591 | |
44592 Clustering.prototype.JordanTest = function(pol, e) { | |
44593 var p = new Vertex((e.v0.x + e.v1.x) * 0.5, (e.v0.y + e.v1.y) * 0.5); | |
44594 var inside = false; | |
44595 var i, j = pol.length - 1; | |
44596 for ( i = 0; i < pol.length; j = i++) { | |
44597 var p1 = pol[i]; | |
44598 var p2 = pol[j]; | |
44599 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)) | |
44600 inside = !inside; | |
44601 } | |
44602 return inside; | |
44603 } | |
44604 | |
44605 Clustering.prototype.mergeForResolution = function(resolution, circleGap, circleOverlap) { | |
44606 this.deleteEdges = new BinaryHeap(function(e) { | |
44607 return e.weight; | |
44608 }); | |
44609 this.weightEdges(resolution, circleGap, circleOverlap); | |
44610 var index = 0; | |
44611 while (this.deleteEdges.size() > 0) { | |
44612 var e = this.deleteEdges.pop(); | |
44613 if (e.legal) { | |
44614 var l = this.edges.length; | |
44615 var newVertex = this.mergeVertices(e); | |
44616 newVertex.CalculateRadius(resolution); | |
44617 for (var k = l; k < this.edges.length; k++) { | |
44618 var eNew = this.edges[k]; | |
44619 if (eNew.legal) { | |
44620 if( circleGap != 0 ){ | |
44621 eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius + circleGap * resolution ); | |
44622 } | |
44623 else if( circleOverlap.overlap == 0 ){ | |
44624 eNew.weight = eNew.length / (eNew.v0.radius + eNew.v1.radius); | |
44625 } | |
44626 else { | |
44627 var r1 = eNew.v0.radius; | |
44628 var r2 = eNew.v1.radius; | |
44629 var r = eNew.length; | |
44630 if( r < r1 + r2 ){ | |
44631 if( circleOverlap.type == 'diameter' ){ | |
44632 var ol1 = (r2-(r-r1)) / r1 / 2; | |
44633 var ol2 = (r1-(r-r2)) / r2 / 2; | |
44634 var ol = Math.max(ol1,ol2); | |
44635 eNew.weight = circleOverlap.overlap / ol; | |
44636 } | |
44637 if( circleOverlap.type == 'area' ){ | |
44638 if( !(r+r1 < r2 || r+r2 < r1) ){ | |
44639 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)); | |
44640 var ol1 = A / (Math.PI*r1*r1); | |
44641 var ol2 = A / (Math.PI*r2*r2); | |
44642 var ol = Math.max(ol1,ol2); | |
44643 eNew.weight = circleOverlap.overlap / ol; | |
44644 } | |
44645 else { | |
44646 eNew.weight = 0; | |
44647 } | |
44648 } | |
44649 } | |
44650 } | |
44651 if (eNew.weight < 1) { | |
44652 this.deleteEdges.push(eNew); | |
44653 } | |
44654 } | |
44655 } | |
44656 } | |
44657 } | |
44658 } | |
44659 | |
44660 Clustering.prototype.weightEdges = function(resolution, circleGap, circleOverlap) { | |
44661 for (var i = 0; i < this.vertices.length; i++) { | |
44662 if (this.vertices[i].legal) { | |
44663 this.vertices[i].CalculateRadius(resolution); | |
44664 } | |
44665 } | |
44666 var newEdges = []; | |
44667 for (var i = 0; i < this.edges.length; i++) { | |
44668 var e = this.edges[i]; | |
44669 if (e.legal) { | |
44670 if (!e.v0.legal || !e.v1.legal) { | |
44671 e.weight = 1; | |
44672 } else { | |
44673 if( circleGap != 0 ){ | |
44674 e.weight = e.length / (e.v0.radius + e.v1.radius + circleGap * resolution ); | |
44675 } | |
44676 else if( circleOverlap.overlap == 0 ){ | |
44677 e.weight = e.length / (e.v0.radius + e.v1.radius); | |
44678 } | |
44679 else { | |
44680 var r1 = e.v0.radius; | |
44681 var r2 = e.v1.radius; | |
44682 var r = e.length; | |
44683 if( r < r1 + r2 ){ | |
44684 if( circleOverlap.type == 'diameter' ){ | |
44685 var ol1 = (r2-(r-r1)) / r1 / 2; | |
44686 var ol2 = (r1-(r-r2)) / r2 / 2; | |
44687 var ol = Math.max(ol1,ol2); | |
44688 e.weight = circleOverlap.overlap / ol; | |
44689 } | |
44690 if( circleOverlap.type == 'area' ){ | |
44691 if( !(r+r1 < r2 || r+r2 < r1) ){ | |
44692 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)); | |
44693 var ol1 = A / (Math.PI*r1*r1); | |
44694 var ol2 = A / (Math.PI*r2*r2); | |
44695 var ol = Math.max(ol1,ol2); | |
44696 e.weight = circleOverlap.overlap / ol; | |
44697 } | |
44698 else { | |
44699 e.weight = 0; | |
44700 } | |
44701 } | |
44702 } | |
44703 } | |
44704 if (e.weight < 1) { | |
44705 this.deleteEdges.push(e); | |
44706 } | |
44707 } | |
44708 newEdges.push(e); | |
44709 } | |
44710 } | |
44711 this.edges = newEdges; | |
44712 } | |
44713 | |
44714 Clustering.prototype.ValidityTest = function() { | |
44715 console.info("Test 1: Valid Delaunay ..."); | |
44716 /* | |
44717 var leafs = []; | |
44718 var triangles = this.boundingTriangle.descendants; | |
44719 var j = 0; | |
44720 while( triangles.length > j ){ | |
44721 var t = triangles[j]; | |
44722 if( t.taken == undefined ){ | |
44723 t.taken = true; | |
44724 if( this.isLeaf(t) ){ | |
44725 leafs.push(t); | |
44726 } | |
44727 else { | |
44728 triangles = triangles.concat(t.descendants); | |
44729 } | |
44730 } | |
44731 j++; | |
44732 } | |
44733 console.info(" Number of Triangles: "+leafs.length); | |
44734 | |
44735 var c = 0; | |
44736 for( i in this.edges ){ | |
44737 if( this.edges[i].legal ){ | |
44738 c++; | |
44739 } | |
44740 } | |
44741 console.info(" Number of Edges: "+c);*/ | |
44742 /* | |
44743 | |
44744 for( var i=0; i<leafs.length; i++ ){ | |
44745 for( var j=0; j<vertices.length; j++ ){ | |
44746 if( !leafs[i].contains(vertices[j]) && leafs[i].inCircumcircle(vertices[j]) ){ | |
44747 console.info(leafs[i],vertices[j]); | |
44748 | |
44749 } | |
44750 } | |
44751 } | |
44752 */ | |
44753 | |
44754 //console.info("Test 2: Edges Facets (null) ..."); | |
44755 for (i in this.edges ) { | |
44756 var e = this.edges[i]; | |
44757 if (e.leftFace == null || e.rightFace == null) { | |
44758 console.info(e); | |
44759 alert(); | |
44760 } | |
44761 } | |
44762 | |
44763 //console.info("Test 3: Edges Facets ..."); | |
44764 var leftOf = function(v1, v2, v) { | |
44765 var x2 = v1.x - v2.x; | |
44766 var x3 = v1.x - v.x; | |
44767 var y2 = v1.y - v2.y; | |
44768 var y3 = v1.y - v.y; | |
44769 if (x2 * y3 - y2 * x3 < 0) { | |
44770 return true; | |
44771 } | |
44772 return false; | |
44773 } | |
44774 var c = 0; | |
44775 for (i in this.edges ) { | |
44776 var e = this.edges[i]; | |
44777 var t1 = e.leftFace.getTriple(e); | |
44778 var t2 = e.rightFace.getTriple(e); | |
44779 if (e.v0.y == e.v1.y) { | |
44780 if (t1.u.y > t2.u.y) { | |
44781 console.info("equal y conflict ..."); | |
44782 console.info(e); | |
44783 alert(); | |
44784 c++; | |
44785 } | |
44786 } else { | |
44787 var v1, v2; | |
44788 if (e.v0.y > e.v1.y) { | |
44789 v1 = e.v0; | |
44790 v2 = e.v1; | |
44791 } else { | |
44792 v1 = e.v1; | |
44793 v2 = e.v0; | |
44794 } | |
44795 if (!leftOf(v1, v2, t1.u)) { | |
44796 console.info("left right conflict ... left is right"); | |
44797 console.info(e); | |
44798 alert(); | |
44799 c++; | |
44800 } | |
44801 if (leftOf(v1, v2, t2.u)) { | |
44802 console.info("left right conflict ... right is left"); | |
44803 console.info(e); | |
44804 alert(); | |
44805 c++; | |
44806 } | |
44807 } | |
44808 } | |
44809 //console.info("Number of Edges: "+this.edges.length); | |
44810 //console.info("Number of Conflicts: "+c); | |
44811 | |
44812 for (i in this.edges ) { | |
44813 if (this.edges[i].legal) { | |
44814 var e = this.edges[i]; | |
44815 var tr0 = e.leftFace.getTriple(e); | |
44816 var tr1 = e.rightFace.getTriple(e); | |
44817 if (!tr0.e_p.legal || !tr0.e_s.legal || !tr1.e_p.legal || !tr1.e_s.legal) { | |
44818 console.info(e); | |
44819 console.info("conflict in edge continuity"); | |
44820 return; | |
44821 } | |
44822 } | |
44823 } | |
44824 | |
44825 } | |
44826 function BinaryHeap(scoreFunction) { | |
44827 this.content = []; | |
44828 this.scoreFunction = scoreFunction; | |
44829 } | |
44830 | |
44831 BinaryHeap.prototype = { | |
44832 push : function(element) { | |
44833 // Add the new element to the end of the array. | |
44834 this.content.push(element); | |
44835 // Allow it to bubble up. | |
44836 this.bubbleUp(this.content.length - 1); | |
44837 }, | |
44838 | |
44839 pop : function() { | |
44840 // Store the first element so we can return it later. | |
44841 var result = this.content[0]; | |
44842 // Get the element at the end of the array. | |
44843 var end = this.content.pop(); | |
44844 // If there are any elements left, put the end element at the | |
44845 // start, and let it sink down. | |
44846 if (this.content.length > 0) { | |
44847 this.content[0] = end; | |
44848 this.sinkDown(0); | |
44849 } | |
44850 return result; | |
44851 }, | |
44852 | |
44853 remove : function(node) { | |
44854 var len = this.content.length; | |
44855 // To remove a value, we must search through the array to find | |
44856 // it. | |
44857 for (var i = 0; i < len; i++) { | |
44858 if (this.content[i] == node) { | |
44859 // When it is found, the process seen in 'pop' is repeated | |
44860 // to fill up the hole. | |
44861 var end = this.content.pop(); | |
44862 if (i != len - 1) { | |
44863 this.content[i] = end; | |
44864 if (this.scoreFunction(end) < this.scoreFunction(node)) | |
44865 this.bubbleUp(i); | |
44866 else | |
44867 this.sinkDown(i); | |
44868 } | |
44869 return; | |
44870 } | |
44871 } | |
44872 throw new Error("Node not found."); | |
44873 }, | |
44874 | |
44875 size : function() { | |
44876 return this.content.length; | |
44877 }, | |
44878 | |
44879 bubbleUp : function(n) { | |
44880 // Fetch the element that has to be moved. | |
44881 var element = this.content[n]; | |
44882 // When at 0, an element can not go up any further. | |
44883 while (n > 0) { | |
44884 // Compute the parent element's index, and fetch it. | |
44885 var parentN = Math.floor((n + 1) / 2) - 1, parent = this.content[parentN]; | |
44886 // Swap the elements if the parent is greater. | |
44887 if (this.scoreFunction(element) < this.scoreFunction(parent)) { | |
44888 this.content[parentN] = element; | |
44889 this.content[n] = parent; | |
44890 // Update 'n' to continue at the new position. | |
44891 n = parentN; | |
44892 | |
44893 } | |
44894 // Found a parent that is less, no need to move it further. | |
44895 else { | |
44896 break; | |
44897 } | |
44898 } | |
44899 }, | |
44900 | |
44901 sinkDown : function(n) { | |
44902 // Look up the target element and its score. | |
44903 var length = this.content.length, element = this.content[n], elemScore = this.scoreFunction(element); | |
44904 | |
44905 while (true) { | |
44906 // Compute the indices of the child elements. | |
44907 var child2N = (n + 1) * 2, child1N = child2N - 1; | |
44908 // This is used to store the new position of the element, | |
44909 // if any. | |
44910 var swap = null; | |
44911 // If the first child exists (is inside the array)... | |
44912 if (child1N < length) { | |
44913 // Look it up and compute its score. | |
44914 var child1 = this.content[child1N], child1Score = this.scoreFunction(child1); | |
44915 // If the score is less than our element's, we need to swap. | |
44916 if (child1Score < elemScore) | |
44917 swap = child1N; | |
44918 } | |
44919 // Do the same checks for the other child. | |
44920 if (child2N < length) { | |
44921 var child2 = this.content[child2N], child2Score = this.scoreFunction(child2); | |
44922 if (child2Score < (swap == null ? elemScore : child1Score)) | |
44923 swap = child2N; | |
44924 } | |
44925 | |
44926 // If the element needs to be moved, swap it, and continue. | |
44927 if (swap != null) { | |
44928 this.content[n] = this.content[swap]; | |
44929 this.content[swap] = element; | |
44930 n = swap; | |
44931 } | |
44932 // Otherwise, we are done. | |
44933 else { | |
44934 break; | |
44935 } | |
44936 } | |
44937 } | |
44938 }; | |
44939 /* | |
44940 * Dropdown.js | |
44941 * | |
44942 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
44943 * | |
44944 * This library is free software; you can redistribute it and/or | |
44945 * modify it under the terms of the GNU Lesser General Public | |
44946 * License as published by the Free Software Foundation; either | |
44947 * version 3 of the License, or (at your option) any later version. | |
44948 * | |
44949 * This library is distributed in the hope that it will be useful, | |
44950 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
44951 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
44952 * Lesser General Public License for more details. | |
44953 * | |
44954 * You should have received a copy of the GNU Lesser General Public | |
44955 * License along with this library; if not, write to the Free Software | |
44956 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
44957 * MA 02110-1301 USA | |
44958 */ | |
44959 | |
44960 /** | |
44961 * @class Dropdown | |
44962 * Implementation for Dropdown box | |
44963 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
44964 * @release 1.0 | |
44965 * @release date: 2012-07-27 | |
44966 * @version date: 2012-07-27 | |
44967 * | |
44968 * @param {HTML object} parent parent div for the dropdown box | |
44969 * @param {Array} elements list of dropdown entries | |
44970 * @param {String} title dropdown button title | |
44971 */ | |
44972 function Dropdown(parent, elements, title, maxListHeight) { | |
44973 | |
44974 var dropdown = this; | |
44975 this.visibility = false; | |
44976 this.div = document.createElement("div"); | |
44977 this.div.setAttribute('class', 'dropdown'); | |
44978 | |
44979 this.selection = document.createElement("div"); | |
44980 this.selection.setAttribute('class', 'dropdownSelection'); | |
44981 parent.appendChild(this.div); | |
44982 | |
44983 var leftBorder = document.createElement("div"); | |
44984 leftBorder.setAttribute('class', 'dropdownLeft'); | |
44985 this.div.appendChild(leftBorder); | |
44986 | |
44987 this.div.appendChild(this.selection); | |
44988 | |
44989 var dropdownButton = document.createElement("div"); | |
44990 this.div.appendChild(dropdownButton); | |
44991 if (elements.length > 1) { | |
44992 dropdownButton.setAttribute('class', 'dropdownButtonEnabled'); | |
44993 } else { | |
44994 dropdownButton.setAttribute('class', 'dropdownButtonDisabled'); | |
44995 } | |
44996 dropdownButton.onclick = function() { | |
44997 if (elements.length > 1) { | |
44998 dropdown.changeVisibility(); | |
44999 } | |
45000 } | |
45001 dropdownButton.title = title; | |
45002 | |
45003 this.getValue = function() { | |
45004 return this.selectedEntry.innerHTML; | |
45005 }; | |
45006 | |
45007 var entryMenu = document.createElement("div"); | |
45008 entryMenu.setAttribute('class', 'dropdownMenu'); | |
45009 this.div.appendChild(entryMenu); | |
45010 if (typeof maxListHeight !== "undefined") | |
45011 $(entryMenu).height(maxListHeight); | |
45012 | |
45013 var entries = document.createElement("dl"); | |
45014 var addEntry = function(e) { | |
45015 var entry = document.createElement("dt"); | |
45016 entry.setAttribute('class', 'dropdownUnselectedEntry'); | |
45017 entry.innerHTML = e.name; | |
45018 entry.onclick = function() { | |
45019 e.onclick(); | |
45020 dropdown.changeVisibility(); | |
45021 dropdown.changeEntries(e); | |
45022 } | |
45023 entries.appendChild(entry); | |
45024 e.entry = entry; | |
45025 } | |
45026 for (var i = 0; i < elements.length; i++) { | |
45027 addEntry(elements[i]); | |
45028 } | |
45029 entryMenu.appendChild(entries); | |
45030 this.selection.style.width = entryMenu.offsetWidth + "px"; | |
45031 entryMenu.style.width = (entryMenu.offsetWidth + leftBorder.offsetWidth + dropdownButton.offsetWidth - 2) + "px"; | |
45032 this.div.style.maxHeight = this.div.offsetHeight + "px"; | |
45033 | |
45034 entryMenu.style.display = 'none'; | |
45035 | |
45036 this.setEntry = function(index) { | |
45037 if ( typeof (index) == "undefined") { | |
45038 if ((elements) && elements.length > 0) { | |
45039 this.changeEntries(elements[0]); | |
45040 } | |
45041 } else { | |
45042 this.changeEntries(elements[index]); | |
45043 } | |
45044 } | |
45045 | |
45046 this.changeEntries = function(element) { | |
45047 if (this.selectedEntry) { | |
45048 this.selectedEntry.setAttribute('class', 'dropdownUnselectedEntry'); | |
45049 } | |
45050 this.selectedEntry = element.entry; | |
45051 this.selectedEntry.setAttribute('class', 'dropdownSelectedEntry'); | |
45052 this.selection.innerHTML = "<div style='display:inline-block;vertical-align:middle;'>" + element.name + "</div>"; | |
45053 } | |
45054 | |
45055 this.changeVisibility = function() { | |
45056 this.visibility = !this.visibility; | |
45057 if (this.visibility) { | |
45058 entryMenu.style.display = "block"; | |
45059 } else { | |
45060 entryMenu.style.display = "none"; | |
45061 } | |
45062 } | |
45063 } | |
45064 /* | |
45065 * MapZoomSlider.js | |
45066 * | |
45067 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45068 * | |
45069 * This library is free software; you can redistribute it and/or | |
45070 * modify it under the terms of the GNU Lesser General Public | |
45071 * License as published by the Free Software Foundation; either | |
45072 * version 3 of the License, or (at your option) any later version. | |
45073 * | |
45074 * This library is distributed in the hope that it will be useful, | |
45075 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45076 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45077 * Lesser General Public License for more details. | |
45078 * | |
45079 * You should have received a copy of the GNU Lesser General Public | |
45080 * License along with this library; if not, write to the Free Software | |
45081 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45082 * MA 02110-1301 USA | |
45083 */ | |
45084 | |
45085 /** | |
45086 * @class MapZoomSlider | |
45087 * GeoTemCo style for map zoom control | |
45088 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45089 * @release 1.0 | |
45090 * @release date: 2012-07-27 | |
45091 * @version date: 2012-07-27 | |
45092 */ | |
45093 function MapZoomSlider(parent, orientation) { | |
45094 | |
45095 this.parent = parent; | |
45096 | |
45097 var zs = this; | |
45098 this.div = document.createElement("div"); | |
45099 this.div.setAttribute('class', 'sliderStyle-' + orientation); | |
45100 | |
45101 var sliderContainer = document.createElement("div"); | |
45102 sliderContainer.setAttribute('class', 'zoomSliderContainer-' + orientation); | |
45103 var sliderDiv = document.createElement("div"); | |
45104 sliderDiv.tabIndex = 1; | |
45105 var sliderInputDiv = document.createElement("div"); | |
45106 sliderDiv.appendChild(sliderInputDiv); | |
45107 sliderContainer.appendChild(sliderDiv); | |
45108 this.slider = new Slider(sliderDiv, sliderInputDiv, orientation); | |
45109 this.div.appendChild(sliderContainer); | |
45110 | |
45111 var zoomIn = document.createElement("img"); | |
45112 zoomIn.src = GeoTemConfig.path + "zoom_in.png"; | |
45113 zoomIn.setAttribute('class', 'zoomSliderIn-' + orientation); | |
45114 zoomIn.onclick = function() { | |
45115 zs.parent.zoom(1); | |
45116 } | |
45117 this.div.appendChild(zoomIn); | |
45118 | |
45119 var zoomOut = document.createElement("img"); | |
45120 zoomOut.src = GeoTemConfig.path + "zoom_out.png"; | |
45121 zoomOut.setAttribute('class', 'zoomSliderOut-' + orientation); | |
45122 zoomOut.onclick = function() { | |
45123 zs.parent.zoom(-1); | |
45124 } | |
45125 this.div.appendChild(zoomOut); | |
45126 | |
45127 this.slider.onclick = function() { | |
45128 console.info(zs.slider.getValue()); | |
45129 } | |
45130 | |
45131 this.slider.handle.onmousedown = function() { | |
45132 var oldValue = zs.slider.getValue(); | |
45133 document.onmouseup = function() { | |
45134 if (!zs.parent.zoom((zs.slider.getValue() - oldValue) / zs.max * zs.levels)) { | |
45135 zs.setValue(oldValue); | |
45136 } | |
45137 document.onmouseup = null; | |
45138 } | |
45139 } | |
45140 | |
45141 this.setValue = function(value) { | |
45142 this.slider.setValue(value / this.levels * this.max); | |
45143 } | |
45144 | |
45145 this.setMaxAndLevels = function(max, levels) { | |
45146 this.max = max; | |
45147 this.levels = levels; | |
45148 this.slider.setMaximum(max); | |
45149 } | |
45150 // this.setMaxAndLevels(1000,parent.openlayersMap.getNumZoomLevels()); | |
45151 // this.setValue(parent.openlayersMap.getZoom()); | |
45152 | |
45153 this.setLanguage = function() { | |
45154 zoomIn.title = GeoTemConfig.getString('zoomIn'); | |
45155 zoomOut.title = GeoTemConfig.getString('zoomOut'); | |
45156 this.slider.handle.title = GeoTemConfig.getString('zoomSlider'); | |
45157 } | |
45158 } | |
45159 /* | |
45160 * MapPopup.js | |
45161 * | |
45162 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45163 * | |
45164 * This library is free software; you can redistribute it and/or | |
45165 * modify it under the terms of the GNU Lesser General Public | |
45166 * License as published by the Free Software Foundation; either | |
45167 * version 3 of the License, or (at your option) any later version. | |
45168 * | |
45169 * This library is distributed in the hope that it will be useful, | |
45170 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45171 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45172 * Lesser General Public License for more details. | |
45173 * | |
45174 * You should have received a copy of the GNU Lesser General Public | |
45175 * License along with this library; if not, write to the Free Software | |
45176 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45177 * MA 02110-1301 USA | |
45178 */ | |
45179 | |
45180 /** | |
45181 * @class MapPopup | |
45182 * map popup implementaion | |
45183 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45184 * @release 1.0 | |
45185 * @release date: 2012-07-27 | |
45186 * @version date: 2012-07-27 | |
45187 */ | |
45188 function MapPopup(parent) { | |
45189 | |
45190 this.parentDiv = parent.gui.mapWindow; | |
45191 | |
45192 this.initialize = function(x, y, onclose) { | |
45193 | |
45194 var popup = this; | |
45195 this.x = x; | |
45196 this.y = y; | |
45197 | |
45198 this.popupDiv = document.createElement("div"); | |
45199 this.popupDiv.setAttribute('class', 'ddbPopupDiv'); | |
45200 this.parentDiv.appendChild(this.popupDiv); | |
45201 | |
45202 this.cancel = document.createElement("div"); | |
45203 this.cancel.setAttribute('class', 'ddbPopupCancel'); | |
45204 this.cancel.title = GeoTemConfig.getString('close'); | |
45205 this.cancel.onclick = function() { | |
45206 if ( typeof onclose != 'undefined') { | |
45207 onclose(); | |
45208 } | |
45209 popup.reset(); | |
45210 } | |
45211 | |
45212 this.input = document.createElement("div"); | |
45213 this.input.style.maxWidth = Math.floor(this.parentDiv.offsetWidth * 0.75) + "px"; | |
45214 this.input.style.maxHeight = Math.floor(this.parentDiv.offsetHeight * 0.75) + "px"; | |
45215 this.input.setAttribute('class', 'ddbPopupInput'); | |
45216 | |
45217 this.popupDiv.appendChild(this.input); | |
45218 this.popupDiv.appendChild(this.cancel); | |
45219 | |
45220 var peak = document.createElement("div"); | |
45221 peak.setAttribute('class', 'popupPeak'); | |
45222 this.popupDiv.appendChild(peak); | |
45223 var topRight = document.createElement("div"); | |
45224 topRight.setAttribute('class', 'popupTopRight'); | |
45225 this.popupDiv.appendChild(topRight); | |
45226 var bottomRight = document.createElement("div"); | |
45227 bottomRight.setAttribute('class', 'popupBottomRight'); | |
45228 this.popupDiv.appendChild(bottomRight); | |
45229 this.popupRight = document.createElement("div"); | |
45230 this.popupRight.setAttribute('class', 'popupRight'); | |
45231 this.popupDiv.appendChild(this.popupRight); | |
45232 this.popupBottom = document.createElement("div"); | |
45233 this.popupBottom.setAttribute('class', 'popupBottom'); | |
45234 this.popupDiv.appendChild(this.popupBottom); | |
45235 | |
45236 } | |
45237 | |
45238 this.setContent = function(content) { | |
45239 $(this.input).empty(); | |
45240 this.visible = true; | |
45241 $(this.input).append(content); | |
45242 this.decorate(); | |
45243 } | |
45244 | |
45245 this.reset = function() { | |
45246 $(this.popupDiv).remove(); | |
45247 this.visible = false; | |
45248 } | |
45249 | |
45250 this.decorate = function() { | |
45251 this.popupRight.style.height = (this.popupDiv.offsetHeight - 14) + "px"; | |
45252 this.popupBottom.style.width = (this.popupDiv.offsetWidth - 22) + "px"; | |
45253 this.left = this.x + 9; | |
45254 this.top = this.y - 10 - this.popupDiv.offsetHeight; | |
45255 this.popupDiv.style.left = this.left + "px"; | |
45256 this.popupDiv.style.top = this.top + "px"; | |
45257 var shiftX = 0, shiftY = 0; | |
45258 if (this.popupDiv.offsetTop < parent.gui.headerHeight + 10) { | |
45259 shiftY = -1 * (parent.gui.headerHeight + 10 - this.popupDiv.offsetTop); | |
45260 } | |
45261 if (this.popupDiv.offsetLeft + this.popupDiv.offsetWidth > parent.gui.headerWidth - 10) { | |
45262 shiftX = -1 * (parent.gui.headerWidth - 10 - this.popupDiv.offsetLeft - this.popupDiv.offsetWidth); | |
45263 } | |
45264 parent.shift(shiftX, shiftY); | |
45265 } | |
45266 | |
45267 this.shift = function(x, y) { | |
45268 this.left = this.left - this.x + x; | |
45269 this.top = this.top - this.y + y; | |
45270 this.x = x; | |
45271 this.y = y; | |
45272 if (this.left + this.popupDiv.offsetWidth > this.parentDiv.offsetWidth) { | |
45273 this.popupDiv.style.left = 'auto'; | |
45274 this.popupDiv.style.right = (this.parentDiv.offsetWidth - this.left - this.popupDiv.offsetWidth) + "px"; | |
45275 } else { | |
45276 this.popupDiv.style.right = 'auto'; | |
45277 this.popupDiv.style.left = this.left + "px"; | |
45278 } | |
45279 this.popupDiv.style.top = this.top + "px"; | |
45280 } | |
45281 } | |
45282 /* | |
45283 * PlacenamePopup.js | |
45284 * | |
45285 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45286 * | |
45287 * This library is free software; you can redistribute it and/or | |
45288 * modify it under the terms of the GNU Lesser General Public | |
45289 * License as published by the Free Software Foundation; either | |
45290 * version 3 of the License, or (at your option) any later version. | |
45291 * | |
45292 * This library is distributed in the hope that it will be useful, | |
45293 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45294 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45295 * Lesser General Public License for more details. | |
45296 * | |
45297 * You should have received a copy of the GNU Lesser General Public | |
45298 * License along with this library; if not, write to the Free Software | |
45299 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45300 * MA 02110-1301 USA | |
45301 */ | |
45302 | |
45303 /** | |
45304 * @class PlacenamePopup | |
45305 * specific map popup for showing and interacting on placename labels | |
45306 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45307 * @release 1.0 | |
45308 * @release date: 2012-07-27 | |
45309 * @version date: 2012-07-27 | |
45310 */ | |
45311 function PlacenamePopup(parent) { | |
45312 | |
45313 this.parentDiv = parent.gui.mapWindow; | |
45314 | |
45315 this.createPopup = function(x, y, labels) { | |
45316 this.labels = labels; | |
45317 var pnPopup = this; | |
45318 var popup = new MapPopup(parent); | |
45319 var onClose = function() { | |
45320 parent.deselection(); | |
45321 pnPopup.reset(); | |
45322 } | |
45323 popup.initialize(x, y, onClose); | |
45324 $.extend(this, popup); | |
45325 | |
45326 this.content = document.createElement("div"); | |
45327 this.inner = document.createElement("div"); | |
45328 | |
45329 this.resultsLabel = document.createElement("div"); | |
45330 this.resultsLabel.setAttribute('class', 'popupDDBResults'); | |
45331 this.content.appendChild(this.resultsLabel); | |
45332 this.backward = document.createElement("div"); | |
45333 this.backward.setAttribute('class', 'prevItem'); | |
45334 this.content.appendChild(this.backward); | |
45335 this.backward.onclick = function() { | |
45336 pnPopup.descriptionIndex--; | |
45337 pnPopup.showDescription(); | |
45338 } | |
45339 | |
45340 this.number = document.createElement("div"); | |
45341 this.content.appendChild(this.number); | |
45342 this.number.style.display = 'none'; | |
45343 this.number.style.fontSize = '13px'; | |
45344 | |
45345 this.forward = document.createElement("div"); | |
45346 this.forward.setAttribute('class', 'nextItem'); | |
45347 this.content.appendChild(this.forward); | |
45348 this.forward.onclick = function() { | |
45349 pnPopup.descriptionIndex++; | |
45350 pnPopup.showDescription(); | |
45351 } | |
45352 if (parent.options.showDescriptions) { | |
45353 this.descriptions = document.createElement("div"); | |
45354 this.descriptions.setAttribute('class', 'descriptions'); | |
45355 this.descriptions.onclick = function() { | |
45356 pnPopup.switchToDescriptionMode(); | |
45357 } | |
45358 } | |
45359 | |
45360 this.back = document.createElement("div"); | |
45361 this.back.setAttribute('class', 'back'); | |
45362 this.popupDiv.appendChild(this.back); | |
45363 this.back.onclick = function() { | |
45364 pnPopup.back.style.display = "none"; | |
45365 pnPopup.backward.style.display = "none"; | |
45366 pnPopup.forward.style.display = "none"; | |
45367 pnPopup.number.style.display = 'none'; | |
45368 pnPopup.showLabels(); | |
45369 } | |
45370 | |
45371 this.content.appendChild(this.inner); | |
45372 this.listLabels(); | |
45373 this.showLabels(); | |
45374 | |
45375 }; | |
45376 | |
45377 this.switchToDescriptionMode = function() { | |
45378 this.descriptionIndex = 0; | |
45379 this.descriptionContents = this.activeLabel.descriptions; | |
45380 this.number.style.display = 'inline-block'; | |
45381 this.inner.style.minWidth = "300px"; | |
45382 this.showDescription(); | |
45383 this.count = this.activeLabel.weight; | |
45384 this.setCount(); | |
45385 this.back.style.display = "inline-block"; | |
45386 } | |
45387 | |
45388 this.showDescription = function() { | |
45389 $(this.inner).empty(); | |
45390 this.inner.appendChild(this.descriptionContents[this.descriptionIndex]); | |
45391 this.setContent(this.content); | |
45392 if (this.descriptionContents.length == 1) { | |
45393 this.backward.style.display = "none"; | |
45394 this.forward.style.display = "none"; | |
45395 } else { | |
45396 if (this.descriptionIndex == 0) { | |
45397 this.backward.style.display = "none"; | |
45398 } else { | |
45399 this.backward.style.display = "inline-block"; | |
45400 } | |
45401 if (this.descriptionIndex == this.descriptionContents.length - 1) { | |
45402 this.forward.style.display = "none"; | |
45403 } else { | |
45404 this.forward.style.display = "inline-block"; | |
45405 } | |
45406 } | |
45407 if (this.descriptionContents.length > 1) { | |
45408 this.number.innerHTML = "#" + (this.descriptionIndex + 1); | |
45409 } else { | |
45410 this.number.style.display = 'none'; | |
45411 } | |
45412 this.decorate(); | |
45413 } | |
45414 | |
45415 this.setCount = function() { | |
45416 var c = this.count; | |
45417 if (c > 1) { | |
45418 this.resultsLabel.innerHTML = c + " " + GeoTemConfig.getString('results'); | |
45419 } else { | |
45420 this.resultsLabel.innerHTML = c + " " + GeoTemConfig.getString('result'); | |
45421 } | |
45422 } | |
45423 | |
45424 this.listLabels = function() { | |
45425 var pnPopup = this; | |
45426 this.labelDivs = []; | |
45427 this.labelCount = 0; | |
45428 this.labelsWidth = 0; | |
45429 for (var i = 0; i < this.labels.length; i++) { | |
45430 var div = document.createElement("div"); | |
45431 var content = document.createElement("div"); | |
45432 this.labels[i].allStyle += "position: relative; white-space: nowrap;"; | |
45433 content.appendChild(this.labels[i].div); | |
45434 content.setAttribute('class', 'ddbPopupLabel'); | |
45435 div.appendChild(content); | |
45436 this.labels[i].div.setAttribute('style', this.labels[i].allStyle + "" + this.labels[i].selectedStyle); | |
45437 this.input.appendChild(div); | |
45438 if (this.input.offsetWidth > this.labelsWidth) { | |
45439 this.labelsWidth = this.input.offsetWidth; | |
45440 } | |
45441 this.labels[i].div.setAttribute('style', this.labels[i].allStyle + "" + this.labels[i].unselectedStyle); | |
45442 this.labelDivs.push(div); | |
45443 var descriptions = []; | |
45444 for (var j = 0; j < this.labels[i].elements.length; j++) { | |
45445 var div = document.createElement("div"); | |
45446 div.innerHTML = this.labels[i].elements[j].description; | |
45447 descriptions.push(div); | |
45448 } | |
45449 this.labels[i].descriptions = descriptions; | |
45450 if (this.labels[i].place != "all" || i == 0) { | |
45451 this.labelCount += this.labels[i].weight; | |
45452 } | |
45453 } | |
45454 if ( typeof this.descriptions != 'undefined') { | |
45455 this.labelsWidth += 20; | |
45456 } | |
45457 } | |
45458 | |
45459 this.showLabels = function() { | |
45460 $(this.inner).empty(); | |
45461 this.count = this.labelCount; | |
45462 this.setCount(); | |
45463 for (var i = 0; i < this.labelDivs.length; i++) { | |
45464 this.inner.appendChild(this.labelDivs[i]); | |
45465 } | |
45466 this.inner.style.width = this.labelsWidth + "px"; | |
45467 this.inner.style.minWidth = this.labelsWidth + "px"; | |
45468 this.setContent(this.content); | |
45469 this.decorate(); | |
45470 } | |
45471 | |
45472 this.showLabelContent = function(label) { | |
45473 for (var i = 0; i < this.labels.length; i++) { | |
45474 if (this.labels[i] == label) { | |
45475 this.activeLabel = this.labels[i]; | |
45476 if ( typeof this.descriptions != 'undefined') { | |
45477 this.labelDivs[i].appendChild(this.descriptions); | |
45478 } | |
45479 this.decorate(); | |
45480 break; | |
45481 } | |
45482 } | |
45483 } | |
45484 | |
45485 this.setLanguage = function(language) { | |
45486 this.language = language; | |
45487 if (this.visible) { | |
45488 this.updateTexts(); | |
45489 } | |
45490 } | |
45491 }; | |
45492 /* | |
45493 * Dropdown.js | |
45494 * | |
45495 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45496 * | |
45497 * This library is free software; you can redistribute it and/or | |
45498 * modify it under the terms of the GNU Lesser General Public | |
45499 * License as published by the Free Software Foundation; either | |
45500 * version 3 of the License, or (at your option) any later version. | |
45501 * | |
45502 * This library is distributed in the hope that it will be useful, | |
45503 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45504 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45505 * Lesser General Public License for more details. | |
45506 * | |
45507 * You should have received a copy of the GNU Lesser General Public | |
45508 * License along with this library; if not, write to the Free Software | |
45509 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45510 * MA 02110-1301 USA | |
45511 */ | |
45512 | |
45513 /** | |
45514 * @class Publisher | |
45515 * Publish/Subscribe mechanism | |
45516 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45517 * @release 1.0 | |
45518 * @release date: 2012-07-27 | |
45519 * @version date: 2012-07-27 | |
45520 */ | |
45521 if ( typeof Publisher == 'undefined') { | |
45522 | |
45523 Publisher = function() { | |
45524 | |
45525 var topics = []; | |
45526 | |
45527 this.Get = function(topic) { | |
45528 var value = topics[topic]; | |
45529 if (!value || !(value instanceof Array)) { | |
45530 value = topics[topic] = []; | |
45531 } | |
45532 return value; | |
45533 }; | |
45534 | |
45535 this.Publish = function(topic, data, publisher) { | |
45536 var subscribers = this.Get(topic); | |
45537 for (var i = 0; i < subscribers.length; i++) { | |
45538 if (publisher == null || subscribers[i].client != publisher) { | |
45539 subscribers[i].callback(data); | |
45540 } | |
45541 } | |
45542 }; | |
45543 | |
45544 this.Subscribe = function(topic, subscriber, callback) { | |
45545 var subscribers = this.Get(topic); | |
45546 subscribers.push({ | |
45547 client : subscriber, | |
45548 callback : callback | |
45549 }); | |
45550 }; | |
45551 | |
45552 this.Unsubscribe = function(topic, unsubscriber) { | |
45553 var subscribers = this.Get(topic); | |
45554 for (var i = 0; i < subscribers.length; i++) { | |
45555 if (subscribers[i].client == unsubscriber) { | |
45556 subscribers.splice(i, 1); | |
45557 return; | |
45558 } | |
45559 } | |
45560 }; | |
45561 | |
45562 return this; | |
45563 | |
45564 }(); | |
45565 | |
45566 } | |
45567 /* | |
45568 * WidgetWrapper.js | |
45569 * | |
45570 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45571 * | |
45572 * This library is free software; you can redistribute it and/or | |
45573 * modify it under the terms of the GNU Lesser General Public | |
45574 * License as published by the Free Software Foundation; either | |
45575 * version 3 of the License, or (at your option) any later version. | |
45576 * | |
45577 * This library is distributed in the hope that it will be useful, | |
45578 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45579 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45580 * Lesser General Public License for more details. | |
45581 * | |
45582 * You should have received a copy of the GNU Lesser General Public | |
45583 * License along with this library; if not, write to the Free Software | |
45584 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45585 * MA 02110-1301 USA | |
45586 */ | |
45587 | |
45588 /** | |
45589 * @class WidgetWrapper | |
45590 * Interface-like implementation for widgets interaction to each other; aimed to be modified for dynamic data sources | |
45591 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45592 * @release 1.0 | |
45593 * @release date: 2012-07-27 | |
45594 * @version date: 2012-07-27 | |
45595 * | |
45596 * @param {Object} widget either a map, time or table widget | |
45597 */ | |
45598 WidgetWrapper = function() { | |
45599 | |
45600 var wrapper = this; | |
45601 | |
45602 this.setWidget = function(widget) { | |
45603 this.widget = widget; | |
45604 } | |
45605 | |
45606 this.display = function(data) { | |
45607 if ( data instanceof Array) { | |
45608 GeoTemConfig.datasets = data; | |
45609 if ( typeof wrapper.widget != 'undefined') { | |
45610 this.widget.initWidget(data); | |
45611 } | |
45612 } | |
45613 }; | |
45614 | |
45615 Publisher.Subscribe('highlight', this, function(data) { | |
45616 if (data == undefined) { | |
45617 return; | |
45618 } | |
45619 if ( typeof wrapper.widget != 'undefined') { | |
45620 wrapper.widget.highlightChanged(data); | |
45621 } | |
45622 }); | |
45623 | |
45624 Publisher.Subscribe('selection', this, function(data) { | |
45625 if ( typeof wrapper.widget != 'undefined') { | |
45626 wrapper.widget.selectionChanged(data); | |
45627 } | |
45628 }); | |
45629 | |
45630 Publisher.Subscribe('filterData', this, function(data) { | |
45631 wrapper.display(data); | |
45632 }); | |
45633 | |
45634 Publisher.Subscribe('rise', this, function(id) { | |
45635 if ( typeof wrapper.widget != 'undefined' && typeof wrapper.widget.riseLayer != 'undefined') { | |
45636 wrapper.widget.riseLayer(id); | |
45637 } | |
45638 }); | |
45639 | |
45640 Publisher.Subscribe('resizeWidget', this, function() { | |
45641 if ( typeof wrapper.widget != 'undefined' && typeof wrapper.widget.gui != 'undefined' && typeof wrapper.widget.gui.resize != 'undefined' ) { | |
45642 wrapper.widget.gui.resize(); | |
45643 } | |
45644 }); | |
45645 | |
45646 this.triggerRefining = function(datasets) { | |
45647 Publisher.Publish('filterData', datasets, null); | |
45648 }; | |
45649 | |
45650 this.triggerSelection = function(selectedObjects) { | |
45651 Publisher.Publish('selection', selectedObjects, this); | |
45652 }; | |
45653 | |
45654 this.triggerHighlight = function(highlightedObjects) { | |
45655 Publisher.Publish('highlight', highlightedObjects, this); | |
45656 }; | |
45657 | |
45658 this.triggerRise = function(id) { | |
45659 Publisher.Publish('rise', id); | |
45660 }; | |
45661 | |
45662 }; | |
45663 /* | |
45664 * final.js | |
45665 * | |
45666 * Copyright (c) 2012, Stefan Jänicke. All rights reserved. | |
45667 * | |
45668 * This library is free software; you can redistribute it and/or | |
45669 * modify it under the terms of the GNU Lesser General Public | |
45670 * License as published by the Free Software Foundation; either | |
45671 * version 3 of the License, or (at your option) any later version. | |
45672 * | |
45673 * This library is distributed in the hope that it will be useful, | |
45674 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
45675 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
45676 * Lesser General Public License for more details. | |
45677 * | |
45678 * You should have received a copy of the GNU Lesser General Public | |
45679 * License along with this library; if not, write to the Free Software | |
45680 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | |
45681 * MA 02110-1301 USA | |
45682 */ | |
45683 | |
45684 /** | |
45685 * code which is included after all other sources have been included for the minified version | |
45686 * @author Stefan Jänicke (stjaenicke@informatik.uni-leipzig.de) | |
45687 * @release 1.0 | |
45688 * @release date: 2012-07-27 | |
45689 * @version date: 2012-07-27 | |
45690 */ | |
45691 | |
45692 OpenLayers.Util.getImagesLocation = function() { | |
45693 return GeoTemCoMinifier_urlPrefix + "lib/openlayers/img/"; | |
45694 }; | |
45695 | |
45696 OpenLayers._getScriptLocation = function() { | |
45697 return GeoTemCoMinifier_urlPrefix + "lib/openlayers/"; | |
45698 }; | |
45699 | |
45700 GeoTemConfig.configure(GeoTemCoMinifier_urlPrefix); | |
45701 })(jQuery); |