| | 1 | /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD |
|---|
| | 2 | * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
|---|
| | 3 | * full text of the license. */ |
|---|
| | 4 | |
|---|
| | 5 | OpenLayers.Position = { |
|---|
| | 6 | TOP_LEFT: "top-left", |
|---|
| | 7 | TOP_RIGHT: "top-right", |
|---|
| | 8 | BOTTOM_LEFT: "bottom-left", |
|---|
| | 9 | BOTTOM_RIGHT: "bottom-right" |
|---|
| | 10 | }; |
|---|
| | 11 | |
|---|
| | 12 | /** |
|---|
| | 13 | * Class: OpenLayers.Popup.FramedBubble |
|---|
| | 14 | */ |
|---|
| | 15 | OpenLayers.Popup.FramedBubble = OpenLayers.Class({ |
|---|
| | 16 | |
|---|
| | 17 | /** |
|---|
| | 18 | * Property: bubble |
|---|
| | 19 | * hash of properties for the bubble decoration |
|---|
| | 20 | */ |
|---|
| | 21 | bubble: { |
|---|
| | 22 | /** |
|---|
| | 23 | * src - {String} url to the global popup image |
|---|
| | 24 | * size - {<OpenLayers.Size>} size of the global popup image |
|---|
| | 25 | */ |
|---|
| | 26 | image: { |
|---|
| | 27 | src: OpenLayers.Util.getImagesLocation() + 'popup.png', |
|---|
| | 28 | size: new OpenLayers.Size(676, 736) |
|---|
| | 29 | }, |
|---|
| | 30 | /** |
|---|
| | 31 | * popup minimum size |
|---|
| | 32 | */ |
|---|
| | 33 | minSize: new OpenLayers.Size(105, 10), |
|---|
| | 34 | /** |
|---|
| | 35 | * outside margin of the popup including bubble decoration |
|---|
| | 36 | * usefull to prevent the popup to be too close to the map border |
|---|
| | 37 | */ |
|---|
| | 38 | margin: new OpenLayers.Bounds(5, 5, 5, 5), |
|---|
| | 39 | /** |
|---|
| | 40 | * inside padding of the bubble |
|---|
| | 41 | * usefull for the contentDiv |
|---|
| | 42 | */ |
|---|
| | 43 | padding: [15, 32, 61, 15], |
|---|
| | 44 | /** |
|---|
| | 45 | * Relative position in the lower right corner |
|---|
| | 46 | */ |
|---|
| | 47 | relativePosition: OpenLayers.Position.BOTTOM_RIGHT, |
|---|
| | 48 | /** |
|---|
| | 49 | * The x and y offset needed position the stem image over the marker. |
|---|
| | 50 | */ |
|---|
| | 51 | offset: new OpenLayers.Pixel(55, -10), |
|---|
| | 52 | /** |
|---|
| | 53 | * size - {Array} width and height of the clipping div (accepts 'auto' values) |
|---|
| | 54 | * anchor - {Array} top, right, bottom, left values to position the clipping div |
|---|
| | 55 | * position - {<OpenLayers.Pixel>} left and top position of the image, |
|---|
| | 56 | * in order to show a specific part of the global popup image |
|---|
| | 57 | */ |
|---|
| | 58 | blocks: [ |
|---|
| | 59 | { // top-left |
|---|
| | 60 | size: ['auto', 'auto'], |
|---|
| | 61 | anchor: [0, 38, 68, 0], |
|---|
| | 62 | position: new OpenLayers.Pixel(0, 0) |
|---|
| | 63 | }, |
|---|
| | 64 | { //top-right |
|---|
| | 65 | size: [38, 'auto'], |
|---|
| | 66 | anchor: [0, 0, 68, null], |
|---|
| | 67 | position: new OpenLayers.Pixel(-638, 0) |
|---|
| | 68 | }, |
|---|
| | 69 | { //bottom-left |
|---|
| | 70 | size: ['auto', 39], |
|---|
| | 71 | anchor: [null, 97, 29, 0], |
|---|
| | 72 | position: new OpenLayers.Pixel(0, -629) |
|---|
| | 73 | }, |
|---|
| | 74 | { // stem |
|---|
| | 75 | size: [97, 68], |
|---|
| | 76 | anchor: [null, 0, 0, null], |
|---|
| | 77 | position: new OpenLayers.Pixel(0, -668) |
|---|
| | 78 | } |
|---|
| | 79 | ] |
|---|
| | 80 | }, |
|---|
| | 81 | |
|---|
| | 82 | div: null, |
|---|
| | 83 | contentDiv: null, |
|---|
| | 84 | |
|---|
| | 85 | /** |
|---|
| | 86 | * APIMethod: onLoad |
|---|
| | 87 | * {Function} Optional function to be called when the popup is fully drawn. |
|---|
| | 88 | */ |
|---|
| | 89 | onLoad: function() {}, |
|---|
| | 90 | |
|---|
| | 91 | /** |
|---|
| | 92 | * APIMethod: onClose |
|---|
| | 93 | * {Function} Optional function to be called when close button is clicked. |
|---|
| | 94 | */ |
|---|
| | 95 | onClose: function() {}, |
|---|
| | 96 | |
|---|
| | 97 | /** |
|---|
| | 98 | * Property: decorated |
|---|
| | 99 | * {Boolean} tells if popup is already decorated, if true decorate() only updates sizes |
|---|
| | 100 | */ |
|---|
| | 101 | decorated: false, |
|---|
| | 102 | |
|---|
| | 103 | /** |
|---|
| | 104 | * Constructor: OpenLayers.Popup.FramedBubble |
|---|
| | 105 | * |
|---|
| | 106 | * Parameters: |
|---|
| | 107 | * id - {String} |
|---|
| | 108 | * lonlat - {<OpenLayers.LonLat>} |
|---|
| | 109 | * size - {<OpenLayers.Size>} |
|---|
| | 110 | * contentHTML - {String} |
|---|
| | 111 | * anchor - {Object} Object to which we'll anchor the popup. Must expose |
|---|
| | 112 | * a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>) |
|---|
| | 113 | * (Note that this is generally an <OpenLayers.Icon>). |
|---|
| | 114 | * closeBox - {Boolean} |
|---|
| | 115 | * closeBoxCallback - {Function} Function to be called on closeBox click. |
|---|
| | 116 | */ |
|---|
| | 117 | initialize:function(id, lonlat, size, contentHTML, anchor, closeBox, |
|---|
| | 118 | closeBoxCallback) { |
|---|
| | 119 | |
|---|
| | 120 | if (id == null) { |
|---|
| | 121 | id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); |
|---|
| | 122 | } |
|---|
| | 123 | |
|---|
| | 124 | this.id = id; |
|---|
| | 125 | this.lonlat = lonlat; |
|---|
| | 126 | this.size = (size != null) ? size |
|---|
| | 127 | : new OpenLayers.Size( |
|---|
| | 128 | OpenLayers.Popup.WIDTH, |
|---|
| | 129 | OpenLayers.Popup.HEIGHT); |
|---|
| | 130 | |
|---|
| | 131 | if (contentHTML != null) { |
|---|
| | 132 | this.contentHTML = contentHTML; |
|---|
| | 133 | } |
|---|
| | 134 | |
|---|
| | 135 | // compute the div size (ie. popup with bubble) |
|---|
| | 136 | |
|---|
| | 137 | this.div = OpenLayers.Util.createDiv(this.id + "Frame", null, null, |
|---|
| | 138 | null, "absolute"); |
|---|
| | 139 | this.div.className = "olBubbleFrame"; |
|---|
| | 140 | |
|---|
| | 141 | this.contentDiv = OpenLayers.Util.createDiv(id, null, null, |
|---|
| | 142 | null, "absolute", null, |
|---|
| | 143 | "hidden"); |
|---|
| | 144 | // TODO: when popup is created by a feature using createPopup(), the overflow |
|---|
| | 145 | // is reset to auto, which causes display flickr when popup is outside the map viewport |
|---|
| | 146 | this.contentDiv.className = 'olPopupContent'; |
|---|
| | 147 | |
|---|
| | 148 | // determine actual render dimensions |
|---|
| | 149 | this.size = this.getRenderedDimensions(); |
|---|
| | 150 | |
|---|
| | 151 | this.contentDiv.style.left = this.bubble.padding[3] + "px"; |
|---|
| | 152 | this.contentDiv.style.top = this.bubble.padding[0] + "px"; |
|---|
| | 153 | |
|---|
| | 154 | if (closeBox) { |
|---|
| | 155 | // TODO : we should probably use the bubble properties |
|---|
| | 156 | |
|---|
| | 157 | // close icon |
|---|
| | 158 | var oBtnClose = document.createElement("A"); |
|---|
| | 159 | oBtnClose.id = "olPopupCloseButton"; |
|---|
| | 160 | oBtnClose.className = "close"; |
|---|
| | 161 | oBtnClose.style.position = "absolute"; |
|---|
| | 162 | oBtnClose.title = "close popup"; |
|---|
| | 163 | oBtnClose.href = "#"; |
|---|
| | 164 | this.div.appendChild(oBtnClose); |
|---|
| | 165 | |
|---|
| | 166 | var closePopup = closeBoxCallback || |
|---|
| | 167 | function(e){ |
|---|
| | 168 | this.hide(); |
|---|
| | 169 | OpenLayers.Event.stop(e); |
|---|
| | 170 | }; |
|---|
| | 171 | OpenLayers.Event.observe(oBtnClose, "click", |
|---|
| | 172 | OpenLayers.Function.bindAsEventListener(closePopup, this)); |
|---|
| | 173 | } |
|---|
| | 174 | }, |
|---|
| | 175 | |
|---|
| | 176 | /** |
|---|
| | 177 | * APIMethod: destroy |
|---|
| | 178 | * nullify references to prevent circular references and memory leaks |
|---|
| | 179 | */ |
|---|
| | 180 | destroy: function() { |
|---|
| | 181 | if (this.map != null) { |
|---|
| | 182 | this.map.removePopup(this); |
|---|
| | 183 | } |
|---|
| | 184 | this.div = null; |
|---|
| | 185 | this.contentDiv = null; |
|---|
| | 186 | this.map = null; |
|---|
| | 187 | }, |
|---|
| | 188 | |
|---|
| | 189 | /** |
|---|
| | 190 | * Method: draw |
|---|
| | 191 | * |
|---|
| | 192 | * Parameters: |
|---|
| | 193 | * px - {<OpenLayers.Pixel>} |
|---|
| | 194 | * |
|---|
| | 195 | * Returns: |
|---|
| | 196 | * {DOMElement} Reference to a div that contains the drawn popup. |
|---|
| | 197 | */ |
|---|
| | 198 | draw: function(px) { |
|---|
| | 199 | this.setSize(this.size); |
|---|
| | 200 | this.setContentHTML(); |
|---|
| | 201 | |
|---|
| | 202 | this.onLoad(); |
|---|
| | 203 | |
|---|
| | 204 | /* |
|---|
| | 205 | * by Pierre GIRAUD: I would prefer something like if (!viewable) { .. doSomething .. } |
|---|
| | 206 | */ |
|---|
| | 207 | this.shiftMapIfNotViewable(); |
|---|
| | 208 | |
|---|
| | 209 | return this.div; |
|---|
| | 210 | }, |
|---|
| | 211 | |
|---|
| | 212 | /** |
|---|
| | 213 | * Method: moveTo |
|---|
| | 214 | * |
|---|
| | 215 | * Parameters: |
|---|
| | 216 | * px - {<OpenLayers.Pixel>} the top and left position of the popup div. |
|---|
| | 217 | */ |
|---|
| | 218 | moveTo: function(px) { |
|---|
| | 219 | px = this.calculateRelativePosition(px); |
|---|
| | 220 | |
|---|
| | 221 | this.div.style.left = px.x + "px"; |
|---|
| | 222 | this.div.style.top = px.y + "px"; |
|---|
| | 223 | }, |
|---|
| | 224 | |
|---|
| | 225 | /** |
|---|
| | 226 | * Method: updatePosition |
|---|
| | 227 | * if the popup has a lonlat and its map member set, |
|---|
| | 228 | * then have it move itself to its proper position |
|---|
| | 229 | */ |
|---|
| | 230 | updatePosition: function() { |
|---|
| | 231 | this.shiftMapIfNotViewable(); |
|---|
| | 232 | |
|---|
| | 233 | if ((this.lonlat) && (this.map)) { |
|---|
| | 234 | var px = this.map.getLayerPxFromLonLat(this.lonlat); |
|---|
| | 235 | if (px) { |
|---|
| | 236 | this.moveTo(px); |
|---|
| | 237 | } |
|---|
| | 238 | } |
|---|
| | 239 | }, |
|---|
| | 240 | |
|---|
| | 241 | /** |
|---|
| | 242 | * APIMethod: Set the size of the popup. |
|---|
| | 243 | * Given size is intended to be used for the content. |
|---|
| | 244 | * This function also makes sure the popup does not get sized larger than |
|---|
| | 245 | * the viewport. |
|---|
| | 246 | * |
|---|
| | 247 | * Parameters: |
|---|
| | 248 | * size {OpenLayers.Size} - size of the content of the popup |
|---|
| | 249 | */ |
|---|
| | 250 | setSize: function(size) { |
|---|
| | 251 | size = this.constrainSizeToViewPort(size); |
|---|
| | 252 | |
|---|
| | 253 | // pgiraud: to my point of view, the popup given size correspond |
|---|
| | 254 | // to the size of the content, it's easier to user to set this size |
|---|
| | 255 | // (to show an image in the popup for example) |
|---|
| | 256 | |
|---|
| | 257 | // first set the contentDiv style with the given size |
|---|
| | 258 | this.contentDiv.style.width = size.w + "px"; |
|---|
| | 259 | this.contentDiv.style.height = size.h + "px"; |
|---|
| | 260 | |
|---|
| | 261 | // then compute the size of the frame using the bubble properties |
|---|
| | 262 | var w = size.w + this.bubble.padding[1] + this.bubble.padding[3]; |
|---|
| | 263 | var h = size.h + this.bubble.padding[0] + this.bubble.padding[2]; |
|---|
| | 264 | size.w = w; |
|---|
| | 265 | size.h = h; |
|---|
| | 266 | this.frameSize = size; |
|---|
| | 267 | |
|---|
| | 268 | this.div.style.width = this.frameSize.w + "px"; |
|---|
| | 269 | this.div.style.height = this.frameSize.h + "px"; |
|---|
| | 270 | |
|---|
| | 271 | this.updatePosition(); |
|---|
| | 272 | |
|---|
| | 273 | this.decorate(); |
|---|
| | 274 | }, |
|---|
| | 275 | |
|---|
| | 276 | /** |
|---|
| | 277 | * Method: getRenderedDimensions |
|---|
| | 278 | * Renders the contentHTML offscreen to determine actual dimensions for |
|---|
| | 279 | * popup sizing. As we need layout to determine dimensions the content |
|---|
| | 280 | * is rendered -9999px to the left and absolute to ensure the scrollbars do not flicker |
|---|
| | 281 | * |
|---|
| | 282 | * Returns: |
|---|
| | 283 | * {OpenLayers.Size} |
|---|
| | 284 | */ |
|---|
| | 285 | getRenderedDimensions : function() { |
|---|
| | 286 | |
|---|
| | 287 | // create temp container div with restricted size |
|---|
| | 288 | var container = document.createElement("div"); |
|---|
| | 289 | container.className = 'olBubbleFrame'; |
|---|
| | 290 | container.style.overflow=""; |
|---|
| | 291 | container.style.position = "absolute"; |
|---|
| | 292 | container.style.left="-9999px"; |
|---|
| | 293 | |
|---|
| | 294 | // create temp content div and assign content |
|---|
| | 295 | var content = document.createElement("div"); |
|---|
| | 296 | content.innerHTML = this.contentHTML; |
|---|
| | 297 | content.className = 'olPopupContent'; |
|---|
| | 298 | |
|---|
| | 299 | // add content to restricted container |
|---|
| | 300 | container.appendChild(content); |
|---|
| | 301 | |
|---|
| | 302 | // append container to body for rendering |
|---|
| | 303 | document.body.appendChild(container); |
|---|
| | 304 | |
|---|
| | 305 | // calculate scroll width of content and add corners and shadow width |
|---|
| | 306 | var w = parseInt(content.scrollWidth);// |
|---|
| | 307 | |
|---|
| | 308 | // update container width to allow height to adjust |
|---|
| | 309 | container.style.width = w + "px"; |
|---|
| | 310 | |
|---|
| | 311 | // capture height and add shadow and corner image widths |
|---|
| | 312 | var h = parseInt(content.scrollHeight);// |
|---|
| | 313 | |
|---|
| | 314 | // remove elements |
|---|
| | 315 | document.body.removeChild(container); |
|---|
| | 316 | |
|---|
| | 317 | // cleanup |
|---|
| | 318 | container = null; |
|---|
| | 319 | content = null; |
|---|
| | 320 | |
|---|
| | 321 | // prevent the popup from being smaller than a given minimal size |
|---|
| | 322 | if (w < this.bubble.minSize.w) { |
|---|
| | 323 | w = this.bubble.minSize.w; |
|---|
| | 324 | } |
|---|
| | 325 | if (h < this.bubble.minSize.h) { |
|---|
| | 326 | h = this.bubble.minSize.h; |
|---|
| | 327 | } |
|---|
| | 328 | |
|---|
| | 329 | return new OpenLayers.Size(w, h); |
|---|
| | 330 | }, |
|---|
| | 331 | |
|---|
| | 332 | /** |
|---|
| | 333 | * Method: constrainSizeToViewPort |
|---|
| | 334 | * Ensure that popup size doesn't get larger than the map viewport size |
|---|
| | 335 | * |
|---|
| | 336 | * Returns: |
|---|
| | 337 | * {OpenLayers.Size} |
|---|
| | 338 | */ |
|---|
| | 339 | constrainSizeToViewPort: function(size) { |
|---|
| | 340 | size = size.clone(); |
|---|
| | 341 | |
|---|
| | 342 | // Restrict the size if it's greater than the map's viewport. |
|---|
| | 343 | var mapSize = this.map.size; |
|---|
| | 344 | |
|---|
| | 345 | // Calculate the difference between the container and the content |
|---|
| | 346 | // and scale the content accordingly. |
|---|
| | 347 | var heightDifference = size.h - |
|---|
| | 348 | (mapSize.h - |
|---|
| | 349 | this.bubble.margin.top - |
|---|
| | 350 | this.bubble.margin.bottom); |
|---|
| | 351 | |
|---|
| | 352 | if (heightDifference > 0) { |
|---|
| | 353 | size.h -= heightDifference; |
|---|
| | 354 | } |
|---|
| | 355 | |
|---|
| | 356 | var widthDifference = size.w - |
|---|
| | 357 | (mapSize.w - |
|---|
| | 358 | this.bubble.margin.left - |
|---|
| | 359 | this.bubble.margin.right + |
|---|
| | 360 | OpenLayers.Popup.SCROLL_BAR_WIDTH); |
|---|
| | 361 | |
|---|
| | 362 | if (widthDifference > 0) { |
|---|
| | 363 | size.w -= widthDifference; |
|---|
| | 364 | } else if (size.w + OpenLayers.Popup.SCROLL_BAR_WIDTH < mapSize.w){ |
|---|
| | 365 | size.w += OpenLayers.Popup.SCROLL_BAR_WIDTH; |
|---|
| | 366 | } |
|---|
| | 367 | |
|---|
| | 368 | return size; |
|---|
| | 369 | }, |
|---|
| | 370 | |
|---|
| | 371 | /** |
|---|
| | 372 | * Method: shiftMapIfNotViewable |
|---|
| | 373 | * Shifts the map (pan) if the popup isn't totaly viewable (includes bubble.margin) |
|---|
| | 374 | * TODO use the panTo (animated method) |
|---|
| | 375 | */ |
|---|
| | 376 | shiftMapIfNotViewable : function() { |
|---|
| | 377 | |
|---|
| | 378 | var mapSize = this.map.getSize(); |
|---|
| | 379 | var popupPosition = this.calculateRelativePosition(this.map.getViewPortPxFromLonLat(this.lonlat), this.frameSize); |
|---|
| | 380 | |
|---|
| | 381 | // Get the current center before any shift. |
|---|
| | 382 | var center = this.map.getViewPortPxFromLonLat(this.map.getCenter()); |
|---|
| | 383 | var newCenter = center.clone(); |
|---|
| | 384 | |
|---|
| | 385 | var top = popupPosition.y; |
|---|
| | 386 | var right = popupPosition.x + this.frameSize.w; |
|---|
| | 387 | var bottom = popupPosition.y + this.frameSize.h; |
|---|
| | 388 | var left = popupPosition.x; |
|---|
| | 389 | |
|---|
| | 390 | // TODO: check race condition |
|---|
| | 391 | // what if left is not visible and right is not visible ? |
|---|
| | 392 | |
|---|
| | 393 | // If left is not visible... |
|---|
| | 394 | if (left < this.bubble.margin.left) { |
|---|
| | 395 | newCenter.x += left - this.bubble.margin.left; |
|---|
| | 396 | } |
|---|
| | 397 | |
|---|
| | 398 | // If right is not visible... |
|---|
| | 399 | if (right > mapSize.w - this.bubble.margin.right) { |
|---|
| | 400 | newCenter.x += parseInt(right - mapSize.w + this.bubble.margin.right); |
|---|
| | 401 | } |
|---|
| | 402 | |
|---|
| | 403 | // If top is not visible... |
|---|
| | 404 | if (top < this.bubble.margin.top) { |
|---|
| | 405 | newCenter.y += top - this.bubble.margin.top; |
|---|
| | 406 | } |
|---|
| | 407 | |
|---|
| | 408 | // If bottom is not visible... |
|---|
| | 409 | if (bottom > mapSize.h - this.bubble.margin.bottom) { |
|---|
| | 410 | newCenter.y += parseInt(bottom - mapSize.h + this.bubble.margin.bottom); |
|---|
| | 411 | } |
|---|
| | 412 | |
|---|
| | 413 | // this.map.shiftToViewPortPx(newCenter); |
|---|
| | 414 | var dx = newCenter.x - center.x; |
|---|
| | 415 | var dy = newCenter.y - center.y; |
|---|
| | 416 | |
|---|
| | 417 | // TODO: this will be the place to call panTo (animated panning) |
|---|
| | 418 | this.map.pan(dx, dy); |
|---|
| | 419 | }, |
|---|
| | 420 | |
|---|
| | 421 | /** |
|---|
| | 422 | * Method: calculateRelativePosition |
|---|
| | 423 | * |
|---|
| | 424 | * Calculate the position of the popup (or what the popup should be) |
|---|
| | 425 | * given a starting pixel position and a size value. |
|---|
| | 426 | * |
|---|
| | 427 | * Parameters: |
|---|
| | 428 | * px - {<OpenLayers.Pixel>} The top and left position of the popup div. |
|---|
| | 429 | * |
|---|
| | 430 | * Returns: |
|---|
| | 431 | * {<OpenLayers.Pixel>} The new top and left position of the popup div. |
|---|
| | 432 | */ |
|---|
| | 433 | calculateRelativePosition: function(px) { |
|---|
| | 434 | px = px.clone(); |
|---|
| | 435 | |
|---|
| | 436 | px.x += this.bubble.offset.x; |
|---|
| | 437 | px.y += this.bubble.offset.y; |
|---|
| | 438 | |
|---|
| | 439 | if (this.bubble.relativePosition == OpenLayers.Position.TOP_RIGHT || |
|---|
| | 440 | this.bubble.relativePosition == OpenLayers.Position.BOTTOM_RIGHT) { |
|---|
| | 441 | px.x -= this.frameSize.w; |
|---|
| | 442 | } |
|---|
| | 443 | |
|---|
| | 444 | if (this.bubble.relativePosition == OpenLayers.Position.BOTTOM_LEFT || |
|---|
| | 445 | this.bubble.relativePosition == OpenLayers.Position.BOTTOM_RIGHT) { |
|---|
| | 446 | px.y -= this.frameSize.h; |
|---|
| | 447 | } |
|---|
| | 448 | |
|---|
| | 449 | return px; |
|---|
| | 450 | }, |
|---|
| | 451 | |
|---|
| | 452 | /** |
|---|
| | 453 | * Method: setContentHTML |
|---|
| | 454 | * Allows the user to set the HTML content of the popup. |
|---|
| | 455 | * |
|---|
| | 456 | * Parameters: |
|---|
| | 457 | * contentHTML - {String} HTML for the div. |
|---|
| | 458 | */ |
|---|
| | 459 | setContentHTML:function(contentHTML) { |
|---|
| | 460 | if (contentHTML != null) { |
|---|
| | 461 | this.contentHTML = contentHTML; |
|---|
| | 462 | } |
|---|
| | 463 | |
|---|
| | 464 | if (this.contentDiv != null) { |
|---|
| | 465 | this.contentDiv.innerHTML = this.contentHTML; |
|---|
| | 466 | } |
|---|
| | 467 | }, |
|---|
| | 468 | |
|---|
| | 469 | /**************************** |
|---|
| | 470 | * Styling * |
|---|
| | 471 | ****************************/ |
|---|
| | 472 | |
|---|
| | 473 | /** |
|---|
| | 474 | * Method: decorate |
|---|
| | 475 | * Append the bubble images (corners) to the frame |
|---|
| | 476 | */ |
|---|
| | 477 | decorate: function() { |
|---|
| | 478 | var src = this.bubble.image.src; |
|---|
| | 479 | var blocks = this.bubble.blocks; |
|---|
| | 480 | for (var i in blocks) { |
|---|
| | 481 | var block = blocks[i]; |
|---|
| | 482 | var divId = this.id + '_FrameDecorationDiv_' + i; |
|---|
| | 483 | var imgId = this.id + '_FrameDecorationImg_' + i; |
|---|
| | 484 | |
|---|
| | 485 | var div, image; |
|---|
| | 486 | if (this.decorated) { |
|---|
| | 487 | div = OpenLayers.Util.getElement(divId); |
|---|
| | 488 | image = OpenLayers.Util.getElement(imgId); |
|---|
| | 489 | } else { |
|---|
| | 490 | div = OpenLayers.Util.createDiv(divId, null, null, null, "absolute", null, "hidden", null); |
|---|
| | 491 | image = OpenLayers.Util.createAlphaImageDiv(imgId, null, this.bubble.image.size, src, "absolute", null, null, null); |
|---|
| | 492 | div.appendChild(image); |
|---|
| | 493 | this.div.appendChild(div); |
|---|
| | 494 | } |
|---|
| | 495 | |
|---|
| | 496 | // adjust sizes |
|---|
| | 497 | var t = block.anchor[0]; |
|---|
| | 498 | var r = block.anchor[1]; |
|---|
| | 499 | var b = block.anchor[2]; |
|---|
| | 500 | var l = block.anchor[3]; |
|---|
| | 501 | |
|---|
| | 502 | var w = (block.size[0] == 'auto') ? |
|---|
| | 503 | this.frameSize.w - (r + l) : block.size[0]; |
|---|
| | 504 | var h = (block.size[1] == 'auto') ? |
|---|
| | 505 | this.frameSize.h - (b + t) : block.size[1]; |
|---|
| | 506 | |
|---|
| | 507 | div.style.width = parseInt(w) + 'px'; |
|---|
| | 508 | |
|---|
| | 509 | div.style.height = h + 'px'; |
|---|
| | 510 | |
|---|
| | 511 | div.style.top = (t != null) ? t + 'px' : ''; |
|---|
| | 512 | div.style.right = (r != null) ? r + 'px' : ''; |
|---|
| | 513 | div.style.bottom = (b != null) ? b + 'px' : ''; |
|---|
| | 514 | div.style.left = (l != null) ? l + 'px' : ''; |
|---|
| | 515 | |
|---|
| | 516 | image.style.left = block.position.x + 'px'; |
|---|
| | 517 | image.style.top = block.position.y + 'px'; |
|---|
| | 518 | |
|---|
| | 519 | } |
|---|
| | 520 | this.div.appendChild(this.contentDiv); |
|---|
| | 521 | this.decorated = true; |
|---|
| | 522 | }, |
|---|
| | 523 | |
|---|
| | 524 | /** |
|---|
| | 525 | * APIMethod: visible |
|---|
| | 526 | * |
|---|
| | 527 | * Returns: |
|---|
| | 528 | * {Boolean} Boolean indicating whether or not the popup is visible |
|---|
| | 529 | */ |
|---|
| | 530 | visible: function() { |
|---|
| | 531 | return OpenLayers.Element.visible(this.div); |
|---|
| | 532 | }, |
|---|
| | 533 | |
|---|
| | 534 | /** |
|---|
| | 535 | * APIMethod: toggle |
|---|
| | 536 | * Toggles visibility of the popup. |
|---|
| | 537 | */ |
|---|
| | 538 | toggle: function() { |
|---|
| | 539 | OpenLayers.Element.toggle(this.div); |
|---|
| | 540 | }, |
|---|
| | 541 | |
|---|
| | 542 | /** |
|---|
| | 543 | * APIMethod: show |
|---|
| | 544 | * Makes the popup visible. |
|---|
| | 545 | */ |
|---|
| | 546 | show: function() { |
|---|
| | 547 | OpenLayers.Element.show(this.div); |
|---|
| | 548 | }, |
|---|
| | 549 | |
|---|
| | 550 | /** |
|---|
| | 551 | * APIMethod: hide |
|---|
| | 552 | * Makes the popup invisible. |
|---|
| | 553 | */ |
|---|
| | 554 | hide: function() { |
|---|
| | 555 | if (this.map) { |
|---|
| | 556 | this.map.removePopup(this); |
|---|
| | 557 | } |
|---|
| | 558 | OpenLayers.Element.hide(this.div); |
|---|
| | 559 | this.onClose(); |
|---|
| | 560 | }, |
|---|
| | 561 | |
|---|
| | 562 | /** |
|---|
| | 563 | * APIMethod: setBackgroundColor |
|---|
| | 564 | * Kept here for compatibility with possible old application code |
|---|
| | 565 | */ |
|---|
| | 566 | setBackgroundColor:function(color) {}, |
|---|
| | 567 | |
|---|
| | 568 | /** |
|---|
| | 569 | * APIMethod: setOpacity |
|---|
| | 570 | * Sets the opacity of the popup. |
|---|
| | 571 | * |
|---|
| | 572 | * Parameters: |
|---|
| | 573 | * opacity - {float} A value between 0.0 (transparent) and 1.0 (solid). |
|---|
| | 574 | */ |
|---|
| | 575 | setOpacity:function(opacity) { |
|---|
| | 576 | if (opacity != undefined) { |
|---|
| | 577 | this.opacity = opacity; |
|---|
| | 578 | } |
|---|
| | 579 | |
|---|
| | 580 | if (this.div != null) { |
|---|
| | 581 | // for Mozilla and Safari |
|---|
| | 582 | this.div.style.opacity = this.opacity; |
|---|
| | 583 | |
|---|
| | 584 | // for IE |
|---|
| | 585 | this.div.style.filter = 'alpha(opacity=' + this.opacity*100 + ')'; |
|---|
| | 586 | } |
|---|
| | 587 | }, |
|---|
| | 588 | |
|---|
| | 589 | /** |
|---|
| | 590 | * Method: setBorder |
|---|
| | 591 | * Kept here for compatibility with possible old application code |
|---|
| | 592 | */ |
|---|
| | 593 | setBorder:function() {}, |
|---|
| | 594 | |
|---|
| | 595 | CLASS_NAME: "OpenLayers.Popup.FramedBubble" |
|---|
| | 596 | }); |