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. */
7 * Class: OpenLayers.Popup
8 * A popup is a small div that can opened and closed on the map.
9 * Typically opened in response to clicking on a marker.
10 * See <OpenLayers.Marker>. Popup's don't require their own
11 * layer and are added the the map using the <OpenLayers.Map.addPopup>
16 * popup = new OpenLayers.Popup("chicken",
17 * new OpenLayers.LonLat(5,40),
18 * new OpenLayers.Size(200,200),
22 * map.addPopup(popup);
25 OpenLayers.Popup = OpenLayers.Class({
29 * {<OpenLayers.Events>} custom event manager
34 * {String} the unique identifier assigned to this popup.
40 * {<OpenLayers.LonLat>} the position of this popup on the map
46 * {DOMElement} the div that contains this popup.
51 * Property: contentSize
52 * {<OpenLayers.Size>} the width and height of the content.
58 * {<OpenLayers.Size>} the width and height of the popup.
63 * Property: contentHTML
64 * {String} An HTML string for this popup to display.
69 * Property: backgroundColor
70 * {String} the background color used by the popup.
76 * {float} the opacity of this popup (between 0.0 and 1.0)
82 * {String} the border size of the popup. (eg 2px)
87 * Property: contentDiv
88 * {DOMElement} a reference to the element that holds the content of
95 * {DOMElement} First and only child of 'div'. The group Div contains the
96 * 'contentDiv' and the 'closeDiv'.
102 * {DOMElement} the optional closer image
107 * APIProperty: autoSize
108 * {Boolean} Resize the popup to auto-fit the contents.
114 * APIProperty: minSize
115 * {<OpenLayers.Size>} Minimum size allowed for the popup's contents.
120 * APIProperty: maxSize
121 * {<OpenLayers.Size>} Maximum size allowed for the popup's contents.
126 * Property: displayClass
127 * {String} The CSS class of the popup.
129 displayClass: "olPopup",
132 * Property: contentDisplayClass
133 * {String} The CSS class of the popup content div.
135 contentDisplayClass: "olPopupContent",
139 * {int or <OpenLayers.Bounds>} An extra opportunity to specify internal
140 * padding of the content div inside the popup. This was originally
141 * confused with the css padding as specified in style.css's
142 * 'olPopupContent' class. We would like to get rid of this altogether,
143 * except that it does come in handy for the framed and anchoredbubble
144 * popups, who need to maintain yet another barrier between their
145 * content and the outer border of the popup itself.
147 * Note that in order to not break API, we must continue to support
148 * this property being set as an integer. Really, though, we'd like to
149 * have this specified as a Bounds object so that user can specify
150 * distinct left, top, right, bottom paddings. With the 3.0 release
151 * we can make this only a bounds.
156 * Property: disableFirefoxOverflowHack
157 * {Boolean} The hack for overflow in Firefox causes all elements
158 * to be re-drawn, which causes Flash elements to be
159 * re-initialized, which is troublesome.
160 * With this property the hack can be disabled.
162 disableFirefoxOverflowHack: false,
166 * To be removed in 3.0, this function merely helps us to deal with the
167 * case where the user may have set an integer value for padding,
168 * instead of an <OpenLayers.Bounds> object.
170 fixPadding: function() {
171 if (typeof this.padding == "number") {
172 this.padding = new OpenLayers.Bounds(
173 this.padding, this.padding, this.padding, this.padding
179 * APIProperty: panMapIfOutOfView
180 * {Boolean} When drawn, pan map such that the entire popup is visible in
181 * the current viewport (if necessary).
184 panMapIfOutOfView: false,
187 * APIProperty: keepInMap
188 * {Boolean} If panMapIfOutOfView is false, and this property is true,
189 * contrain the popup such that it always fits in the available map
190 * space. By default, this is not set on the base class. If you are
191 * creating popups that are near map edges and not allowing pannning,
192 * and especially if you have a popup which has a
193 * fixedRelativePosition, setting this to false may be a smart thing to
194 * do. Subclasses may want to override this setting.
201 * APIProperty: closeOnMove
202 * {Boolean} When map pans, close the popup.
209 * {<OpenLayers.Map>} this gets set in Map.js when the popup is added to the map
214 * Constructor: OpenLayers.Popup
218 * id - {String} a unqiue identifier for this popup. If null is passed
219 * an identifier will be automatically generated.
220 * lonlat - {<OpenLayers.LonLat>} The position on the map the popup will
222 * contentSize - {<OpenLayers.Size>} The size of the content.
223 * contentHTML - {String} An HTML string to display inside the
225 * closeBox - {Boolean} Whether to display a close box inside
227 * closeBoxCallback - {Function} Function to be called on closeBox click.
229 initialize:function(id, lonlat, contentSize, contentHTML, closeBox, closeBoxCallback) {
231 id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
235 this.lonlat = lonlat;
237 this.contentSize = (contentSize != null) ? contentSize
238 : new OpenLayers.Size(
239 OpenLayers.Popup.WIDTH,
240 OpenLayers.Popup.HEIGHT);
241 if (contentHTML != null) {
242 this.contentHTML = contentHTML;
244 this.backgroundColor = OpenLayers.Popup.COLOR;
245 this.opacity = OpenLayers.Popup.OPACITY;
246 this.border = OpenLayers.Popup.BORDER;
248 this.div = OpenLayers.Util.createDiv(this.id, null, null,
249 null, null, null, "hidden");
250 this.div.className = this.displayClass;
252 var groupDivId = this.id + "_GroupDiv";
253 this.groupDiv = OpenLayers.Util.createDiv(groupDivId, null, null,
254 null, "relative", null,
257 var id = this.div.id + "_contentDiv";
258 this.contentDiv = OpenLayers.Util.createDiv(id, null, this.contentSize.clone(),
260 this.contentDiv.className = this.contentDisplayClass;
261 this.groupDiv.appendChild(this.contentDiv);
262 this.div.appendChild(this.groupDiv);
265 this.addCloseBox(closeBoxCallback);
268 this.registerEvents();
273 * nullify references to prevent circular references and memory leaks
275 destroy: function() {
280 this.contentHTML = null;
282 this.backgroundColor = null;
286 if (this.closeOnMove && this.map) {
287 this.map.events.unregister("movestart", this, this.hide);
290 this.events.destroy();
294 OpenLayers.Event.stopObservingElement(this.closeDiv);
295 this.groupDiv.removeChild(this.closeDiv);
297 this.closeDiv = null;
299 this.div.removeChild(this.groupDiv);
300 this.groupDiv = null;
302 if (this.map != null) {
303 this.map.removePopup(this);
308 this.autoSize = null;
312 this.panMapIfOutOfView = null;
317 * Constructs the elements that make up the popup.
320 * px - {<OpenLayers.Pixel>} the position the popup in pixels.
323 * {DOMElement} Reference to a div that contains the drawn popup
327 if ((this.lonlat != null) && (this.map != null)) {
328 px = this.map.getLayerPxFromLonLat(this.lonlat);
332 // this assumes that this.map already exists, which is okay because
333 // this.draw is only called once the popup has been added to the map.
334 if (this.closeOnMove) {
335 this.map.events.register("movestart", this, this.hide);
338 //listen to movestart, moveend to disable overflow (FF bug)
339 if (!this.disableFirefoxOverflowHack && OpenLayers.Util.getBrowserName() == 'firefox') {
340 this.map.events.register("movestart", this, function() {
341 var style = document.defaultView.getComputedStyle(
342 this.contentDiv, null
344 var currentOverflow = style.getPropertyValue("overflow");
345 if (currentOverflow != "hidden") {
346 this.contentDiv._oldOverflow = currentOverflow;
347 this.contentDiv.style.overflow = "hidden";
350 this.map.events.register("moveend", this, function() {
351 var oldOverflow = this.contentDiv._oldOverflow;
353 this.contentDiv.style.overflow = oldOverflow;
354 this.contentDiv._oldOverflow = null;
360 if (!this.autoSize && !this.size) {
361 this.setSize(this.contentSize);
363 this.setBackgroundColor();
366 this.setContentHTML();
368 if (this.panMapIfOutOfView) {
376 * Method: updatePosition
377 * if the popup has a lonlat and its map members set,
378 * then have it move itself to its proper position
380 updatePosition: function() {
381 if ((this.lonlat) && (this.map)) {
382 var px = this.map.getLayerPxFromLonLat(this.lonlat);
393 * px - {<OpenLayers.Pixel>} the top and left position of the popup div.
395 moveTo: function(px) {
396 if ((px != null) && (this.div != null)) {
397 this.div.style.left = px.x + "px";
398 this.div.style.top = px.y + "px";
406 * {Boolean} Boolean indicating whether or not the popup is visible
408 visible: function() {
409 return OpenLayers.Element.visible(this.div);
414 * Toggles visibility of the popup.
417 if (this.visible()) {
426 * Makes the popup visible.
429 OpenLayers.Element.show(this.div);
431 if (this.panMapIfOutOfView) {
438 * Makes the popup invisible.
441 OpenLayers.Element.hide(this.div);
446 * Used to adjust the size of the popup.
449 * contentSize - {<OpenLayers.Size>} the new size for the popup's
450 * contents div (in pixels).
452 setSize:function(contentSize) {
453 this.size = contentSize.clone();
455 // if our contentDiv has a css 'padding' set on it by a stylesheet, we
456 // must add that to the desired "size".
457 var contentDivPadding = this.getContentDivPadding();
458 var wPadding = contentDivPadding.left + contentDivPadding.right;
459 var hPadding = contentDivPadding.top + contentDivPadding.bottom;
461 // take into account the popup's 'padding' property
463 wPadding += this.padding.left + this.padding.right;
464 hPadding += this.padding.top + this.padding.bottom;
466 // make extra space for the close div
468 var closeDivWidth = parseInt(this.closeDiv.style.width);
469 wPadding += closeDivWidth + contentDivPadding.right;
472 //increase size of the main popup div to take into account the
473 // users's desired padding and close div.
474 this.size.w += wPadding;
475 this.size.h += hPadding;
477 //now if our browser is IE, we need to actually make the contents
478 // div itself bigger to take its own padding into effect. this makes
479 // me want to shoot someone, but so it goes.
480 if (OpenLayers.Util.getBrowserName() == "msie") {
481 this.contentSize.w +=
482 contentDivPadding.left + contentDivPadding.right;
483 this.contentSize.h +=
484 contentDivPadding.bottom + contentDivPadding.top;
487 if (this.div != null) {
488 this.div.style.width = this.size.w + "px";
489 this.div.style.height = this.size.h + "px";
491 if (this.contentDiv != null){
492 this.contentDiv.style.width = contentSize.w + "px";
493 this.contentDiv.style.height = contentSize.h + "px";
498 * APIMethod: updateSize
499 * Auto size the popup so that it precisely fits its contents (as
500 * determined by this.contentDiv.innerHTML). Popup size will, of
501 * course, be limited by the available space on the current map
503 updateSize: function() {
505 // determine actual render dimensions of the contents by putting its
506 // contents into a fake contentDiv (for the CSS) and then measuring it
507 var preparedHTML = "<div class='" + this.contentDisplayClass+ "'>" +
508 this.contentDiv.innerHTML +
511 var containerElement = (this.map) ? this.map.layerContainerDiv
513 var realSize = OpenLayers.Util.getRenderedDimensions(
514 preparedHTML, null, {
515 displayClass: this.displayClass,
516 containerElement: containerElement
520 // is the "real" size of the div is safe to display in our map?
521 var safeSize = this.getSafeContentSize(realSize);
524 if (safeSize.equals(realSize)) {
525 //real size of content is small enough to fit on the map,
526 // so we use real size.
531 //make a new OL.Size object with the clipped dimensions
532 // set or null if not clipped.
533 var fixedSize = new OpenLayers.Size();
534 fixedSize.w = (safeSize.w < realSize.w) ? safeSize.w : null;
535 fixedSize.h = (safeSize.h < realSize.h) ? safeSize.h : null;
537 if (fixedSize.w && fixedSize.h) {
538 //content is too big in both directions, so we will use
539 // max popup size (safeSize), knowing well that it will
540 // overflow both ways.
543 //content is clipped in only one direction, so we need to
544 // run getRenderedDimensions() again with a fixed dimension
545 var clippedSize = OpenLayers.Util.getRenderedDimensions(
546 preparedHTML, fixedSize, {
547 displayClass: this.contentDisplayClass,
548 containerElement: containerElement
552 //if the clipped size is still the same as the safeSize,
553 // that means that our content must be fixed in the
554 // offending direction. If overflow is 'auto', this means
555 // we are going to have a scrollbar for sure, so we must
558 var currentOverflow = OpenLayers.Element.getStyle(
559 this.contentDiv, "overflow"
561 if ( (currentOverflow != "hidden") &&
562 (clippedSize.equals(safeSize)) ) {
563 var scrollBar = OpenLayers.Util.getScrollbarWidth();
565 clippedSize.h += scrollBar;
567 clippedSize.w += scrollBar;
571 newSize = this.getSafeContentSize(clippedSize);
574 this.setSize(newSize);
578 * Method: setBackgroundColor
579 * Sets the background color of the popup.
582 * color - {String} the background color. eg "#FFBBBB"
584 setBackgroundColor:function(color) {
585 if (color != undefined) {
586 this.backgroundColor = color;
589 if (this.div != null) {
590 this.div.style.backgroundColor = this.backgroundColor;
596 * Sets the opacity of the popup.
599 * opacity - {float} A value between 0.0 (transparent) and 1.0 (solid).
601 setOpacity:function(opacity) {
602 if (opacity != undefined) {
603 this.opacity = opacity;
606 if (this.div != null) {
607 // for Mozilla and Safari
608 this.div.style.opacity = this.opacity;
611 this.div.style.filter = 'alpha(opacity=' + this.opacity*100 + ')';
617 * Sets the border style of the popup.
620 * border - {String} The border style value. eg 2px
622 setBorder:function(border) {
623 if (border != undefined) {
624 this.border = border;
627 if (this.div != null) {
628 this.div.style.border = this.border;
633 * Method: setContentHTML
634 * Allows the user to set the HTML content of the popup.
637 * contentHTML - {String} HTML for the div.
639 setContentHTML:function(contentHTML) {
641 if (contentHTML != null) {
642 this.contentHTML = contentHTML;
645 if ((this.contentDiv != null) &&
646 (this.contentHTML != null) &&
647 (this.contentHTML != this.contentDiv.innerHTML)) {
649 this.contentDiv.innerHTML = this.contentHTML;
653 //if popup has images, listen for when they finish
654 // loading and resize accordingly
655 this.registerImageListeners();
657 //auto size the popup to its current contents
665 * Method: registerImageListeners
666 * Called when an image contained by the popup loaded. this function
667 * updates the popup size, then unregisters the image load listener.
669 registerImageListeners: function() {
671 // As the images load, this function will call updateSize() to
672 // resize the popup to fit the content div (which presumably is now
673 // bigger than when the image was not loaded).
675 // If the 'panMapIfOutOfView' property is set, we will pan the newly
676 // resized popup back into view.
678 // Note that this function, when called, will have 'popup' and
679 // 'img' properties in the context.
681 var onImgLoad = function() {
683 this.popup.updateSize();
685 if ( this.popup.visible() && this.popup.panMapIfOutOfView ) {
686 this.popup.panIntoView();
689 OpenLayers.Event.stopObserving(
690 this.img, "load", this.img._onImageLoad
695 //cycle through the images and if their size is 0x0, that means that
696 // they haven't been loaded yet, so we attach the listener, which
697 // will fire when the images finish loading and will resize the
698 // popup accordingly to its new size.
699 var images = this.contentDiv.getElementsByTagName("img");
700 for (var i = 0, len = images.length; i < len; i++) {
702 if (img.width == 0 || img.height == 0) {
709 //expando this function to the image itself before registering
710 // it. This way we can easily and properly unregister it.
711 img._onImgLoad = OpenLayers.Function.bind(onImgLoad, context);
713 OpenLayers.Event.observe(img, 'load', img._onImgLoad);
719 * APIMethod: getSafeContentSize
722 * size - {<OpenLayers.Size>} Desired size to make the popup.
725 * {<OpenLayers.Size>} A size to make the popup which is neither smaller
726 * than the specified minimum size, nor bigger than the maximum
727 * size (which is calculated relative to the size of the viewport).
729 getSafeContentSize: function(size) {
731 var safeContentSize = size.clone();
733 // if our contentDiv has a css 'padding' set on it by a stylesheet, we
734 // must add that to the desired "size".
735 var contentDivPadding = this.getContentDivPadding();
736 var wPadding = contentDivPadding.left + contentDivPadding.right;
737 var hPadding = contentDivPadding.top + contentDivPadding.bottom;
739 // take into account the popup's 'padding' property
741 wPadding += this.padding.left + this.padding.right;
742 hPadding += this.padding.top + this.padding.bottom;
745 var closeDivWidth = parseInt(this.closeDiv.style.width);
746 wPadding += closeDivWidth + contentDivPadding.right;
749 // prevent the popup from being smaller than a specified minimal size
751 safeContentSize.w = Math.max(safeContentSize.w,
752 (this.minSize.w - wPadding));
753 safeContentSize.h = Math.max(safeContentSize.h,
754 (this.minSize.h - hPadding));
757 // prevent the popup from being bigger than a specified maximum size
759 safeContentSize.w = Math.min(safeContentSize.w,
760 (this.maxSize.w - wPadding));
761 safeContentSize.h = Math.min(safeContentSize.h,
762 (this.maxSize.h - hPadding));
765 //make sure the desired size to set doesn't result in a popup that
766 // is bigger than the map's viewport.
768 if (this.map && this.map.size) {
770 var extraX = 0, extraY = 0;
771 if (this.keepInMap && !this.panMapIfOutOfView) {
772 var px = this.map.getPixelFromLonLat(this.lonlat);
773 switch (this.relativePosition) {
776 extraY = this.map.size.h - px.y;
779 extraX = this.map.size.w - px.x;
780 extraY = this.map.size.h - px.y;
783 extraX = this.map.size.w - px.x;
792 extraY = this.map.size.h - px.y;
797 var maxY = this.map.size.h -
798 this.map.paddingForPopups.top -
799 this.map.paddingForPopups.bottom -
802 var maxX = this.map.size.w -
803 this.map.paddingForPopups.left -
804 this.map.paddingForPopups.right -
807 safeContentSize.w = Math.min(safeContentSize.w, maxX);
808 safeContentSize.h = Math.min(safeContentSize.h, maxY);
811 return safeContentSize;
815 * Method: getContentDivPadding
816 * Glorious, oh glorious hack in order to determine the css 'padding' of
817 * the contentDiv. IE/Opera return null here unless we actually add the
818 * popup's main 'div' element (which contains contentDiv) to the DOM.
819 * So we make it invisible and then add it to the document temporarily.
821 * Once we've taken the padding readings we need, we then remove it
822 * from the DOM (it will actually get added to the DOM in
826 * {<OpenLayers.Bounds>}
828 getContentDivPadding: function() {
830 //use cached value if we have it
831 var contentDivPadding = this._contentDivPadding;
832 if (!contentDivPadding) {
834 if (this.div.parentNode == null) {
835 //make the div invisible and add it to the page
836 this.div.style.display = "none";
837 document.body.appendChild(this.div);
840 //read the padding settings from css, put them in an OL.Bounds
841 contentDivPadding = new OpenLayers.Bounds(
842 OpenLayers.Element.getStyle(this.contentDiv, "padding-left"),
843 OpenLayers.Element.getStyle(this.contentDiv, "padding-bottom"),
844 OpenLayers.Element.getStyle(this.contentDiv, "padding-right"),
845 OpenLayers.Element.getStyle(this.contentDiv, "padding-top")
849 this._contentDivPadding = contentDivPadding;
851 if (this.div.parentNode == document.body) {
852 //remove the div from the page and make it visible again
853 document.body.removeChild(this.div);
854 this.div.style.display = "";
857 return contentDivPadding;
861 * Method: addCloseBox
864 * callback - {Function} The callback to be called when the close button
867 addCloseBox: function(callback) {
869 this.closeDiv = OpenLayers.Util.createDiv(
870 this.id + "_close", null, new OpenLayers.Size(17, 17)
872 this.closeDiv.className = "olPopupCloseBox";
874 // use the content div's css padding to determine if we should
875 // padd the close div
876 var contentDivPadding = this.getContentDivPadding();
878 this.closeDiv.style.right = contentDivPadding.right + "px";
879 this.closeDiv.style.top = contentDivPadding.top + "px";
880 this.groupDiv.appendChild(this.closeDiv);
882 var closePopup = callback || function(e) {
884 OpenLayers.Event.stop(e);
886 OpenLayers.Event.observe(this.closeDiv, "click",
887 OpenLayers.Function.bindAsEventListener(closePopup, this));
891 * Method: panIntoView
892 * Pans the map such that the popup is totaly viewable (if necessary)
894 panIntoView: function() {
896 var mapSize = this.map.getSize();
898 //start with the top left corner of the popup, in px,
899 // relative to the viewport
900 var origTL = this.map.getViewPortPxFromLayerPx( new OpenLayers.Pixel(
901 parseInt(this.div.style.left),
902 parseInt(this.div.style.top)
904 var newTL = origTL.clone();
906 //new left (compare to margins, using this.size to calculate right)
907 if (origTL.x < this.map.paddingForPopups.left) {
908 newTL.x = this.map.paddingForPopups.left;
910 if ( (origTL.x + this.size.w) > (mapSize.w - this.map.paddingForPopups.right)) {
911 newTL.x = mapSize.w - this.map.paddingForPopups.right - this.size.w;
914 //new top (compare to margins, using this.size to calculate bottom)
915 if (origTL.y < this.map.paddingForPopups.top) {
916 newTL.y = this.map.paddingForPopups.top;
918 if ( (origTL.y + this.size.h) > (mapSize.h - this.map.paddingForPopups.bottom)) {
919 newTL.y = mapSize.h - this.map.paddingForPopups.bottom - this.size.h;
922 var dx = origTL.x - newTL.x;
923 var dy = origTL.y - newTL.y;
925 this.map.pan(dx, dy);
929 * Method: registerEvents
930 * Registers events on the popup.
932 * Do this in a separate function so that subclasses can
933 * choose to override it if they wish to deal differently
936 * Note in the following handler functions that some special
937 * care is needed to deal correctly with mousing and popups.
939 * Because the user might select the zoom-rectangle option and
940 * then drag it over a popup, we need a safe way to allow the
941 * mousemove and mouseup events to pass through the popup when
942 * they are initiated from outside.
944 * Otherwise, we want to essentially kill the event propagation
945 * for all other events, though we have to do so carefully,
946 * without disabling basic html functionality, like clicking on
947 * hyperlinks or drag-selecting text.
949 registerEvents:function() {
950 this.events = new OpenLayers.Events(this, this.div, null, true);
953 "mousedown": this.onmousedown,
954 "mousemove": this.onmousemove,
955 "mouseup": this.onmouseup,
956 "click": this.onclick,
957 "mouseout": this.onmouseout,
958 "dblclick": this.ondblclick,
965 * Method: onmousedown
966 * When mouse goes down within the popup, make a note of
967 * it locally, and then do not propagate the mousedown
968 * (but do so safely so that user can select text inside)
973 onmousedown: function (evt) {
974 this.mousedown = true;
975 OpenLayers.Event.stop(evt, true);
979 * Method: onmousemove
980 * If the drag was started within the popup, then
981 * do not propagate the mousemove (but do so safely
982 * so that user can select text inside)
987 onmousemove: function (evt) {
988 if (this.mousedown) {
989 OpenLayers.Event.stop(evt, true);
995 * When mouse comes up within the popup, after going down
996 * in it, reset the flag, and then (once again) do not
997 * propagate the event, but do so safely so that user can
1003 onmouseup: function (evt) {
1004 if (this.mousedown) {
1005 this.mousedown = false;
1006 OpenLayers.Event.stop(evt, true);
1012 * Ignore clicks, but allowing default browser handling
1017 onclick: function (evt) {
1018 OpenLayers.Event.stop(evt, true);
1022 * Method: onmouseout
1023 * When mouse goes out of the popup set the flag to false so that
1024 * if they let go and then drag back in, we won't be confused.
1029 onmouseout: function (evt) {
1030 this.mousedown = false;
1034 * Method: ondblclick
1035 * Ignore double-clicks, but allowing default browser handling
1040 ondblclick: function (evt) {
1041 OpenLayers.Event.stop(evt, true);
1044 CLASS_NAME: "OpenLayers.Popup"
1047 OpenLayers.Popup.WIDTH = 200;
1048 OpenLayers.Popup.HEIGHT = 200;
1049 OpenLayers.Popup.COLOR = "white";
1050 OpenLayers.Popup.OPACITY = 1;
1051 OpenLayers.Popup.BORDER = "0px";