Leaflet/src/layer/Popup.js

272 lines
6.6 KiB
JavaScript
Raw Normal View History

/*
* L.Popup is used for displaying popups on the map.
*/
2010-12-16 01:55:57 +08:00
2012-03-03 23:02:20 +08:00
L.Map.mergeOptions({
closePopupOnClick: true
});
2010-12-16 01:55:57 +08:00
L.Popup = L.Class.extend({
includes: L.Mixin.Events,
2010-12-16 01:55:57 +08:00
options: {
minWidth: 50,
2011-01-11 21:45:06 +08:00
maxWidth: 300,
maxHeight: null,
2011-01-11 21:45:06 +08:00
autoPan: true,
closeButton: true,
offset: new L.Point(0, 6),
2012-01-06 18:16:24 +08:00
autoPanPadding: new L.Point(5, 5),
className: '',
zoomAnimation: true
2010-12-16 01:55:57 +08:00
},
2011-12-13 23:34:56 +08:00
initialize: function (options, source) {
L.setOptions(this, options);
2011-12-13 23:34:56 +08:00
2011-11-22 23:45:43 +08:00
this._source = source;
this._animated = L.Browser.any3d && this.options.zoomAnimation;
2010-12-16 01:55:57 +08:00
},
2011-12-09 22:51:31 +08:00
onAdd: function (map) {
2010-12-16 01:55:57 +08:00
this._map = map;
2012-02-15 19:17:25 +08:00
2010-12-16 01:55:57 +08:00
if (!this._container) {
this._initLayout();
}
2011-04-27 18:52:23 +08:00
this._updateContent();
var animFade = map.options.fadeAnimation;
if (animFade) {
L.DomUtil.setOpacity(this._container, 0);
}
2012-02-15 19:17:25 +08:00
map._panes.popupPane.appendChild(this._container);
2012-02-15 19:17:25 +08:00
map.on('viewreset', this._updatePosition, this);
2012-06-19 21:38:40 +08:00
if (this._animated) {
2012-06-19 21:38:40 +08:00
map.on('zoomanim', this._zoomAnimation, this);
}
2012-02-15 19:17:25 +08:00
if (map.options.closePopupOnClick) {
map.on('preclick', this._close, this);
2011-04-12 21:51:42 +08:00
}
2011-12-13 23:34:56 +08:00
this._update();
if (animFade) {
L.DomUtil.setOpacity(this._container, 1);
}
2010-12-16 01:55:57 +08:00
},
addTo: function (map) {
map.addLayer(this);
return this;
},
2012-07-12 20:46:52 +08:00
openOn: function (map) {
map.openPopup(this);
return this;
},
2011-12-09 22:51:31 +08:00
onRemove: function (map) {
2010-12-16 01:55:57 +08:00
map._panes.popupPane.removeChild(this._container);
2012-02-15 19:17:25 +08:00
L.Util.falseFn(this._container.offsetWidth); // force reflow
map.off({
viewreset: this._updatePosition,
preclick: this._close,
zoomanim: this._zoomAnimation
}, this);
if (map.options.fadeAnimation) {
L.DomUtil.setOpacity(this._container, 0);
}
2012-02-15 19:17:25 +08:00
this._map = null;
},
2011-12-09 22:51:31 +08:00
setLatLng: function (latlng) {
2012-07-03 22:06:44 +08:00
this._latlng = L.latLng(latlng);
2012-02-15 19:17:25 +08:00
this._update();
2011-04-27 23:02:58 +08:00
return this;
},
2011-12-09 22:51:31 +08:00
setContent: function (content) {
this._content = content;
2012-02-15 19:17:25 +08:00
this._update();
2011-04-27 23:02:58 +08:00
return this;
2010-12-16 01:55:57 +08:00
},
2011-12-09 22:51:31 +08:00
_close: function () {
2012-03-04 06:42:50 +08:00
var map = this._map;
if (map) {
map._popup = null;
map
2012-11-08 00:46:59 +08:00
.removeLayer(this)
.fire('popupclose', {popup: this});
}
2010-12-16 01:55:57 +08:00
},
2011-12-09 22:51:31 +08:00
_initLayout: function () {
var prefix = 'leaflet-popup',
containerClass = prefix + ' ' + this.options.className + ' leaflet-zoom-' +
(this._animated ? 'animated' : 'hide'),
2012-11-08 00:46:59 +08:00
container = this._container = L.DomUtil.create('div', containerClass),
closeButton;
if (this.options.closeButton) {
2012-11-08 00:46:59 +08:00
closeButton = this._closeButton =
L.DomUtil.create('a', prefix + '-close-button', container);
closeButton.href = '#close';
2012-07-13 07:47:19 +08:00
closeButton.innerHTML = '×';
2013-03-20 22:24:47 +08:00
L.DomEvent.disableClickPropagation(closeButton);
L.DomEvent.on(closeButton, 'click', this._onCloseButtonClick, this);
2011-06-21 15:06:47 +08:00
}
2012-11-08 00:46:59 +08:00
var wrapper = this._wrapper =
L.DomUtil.create('div', prefix + '-content-wrapper', container);
L.DomEvent.disableClickPropagation(wrapper);
this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper);
L.DomEvent.on(this._contentNode, 'mousewheel', L.DomEvent.stopPropagation);
this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container', container);
this._tip = L.DomUtil.create('div', prefix + '-tip', this._tipContainer);
2010-12-16 01:55:57 +08:00
},
2011-12-09 22:51:31 +08:00
_update: function () {
if (!this._map) { return; }
2012-02-15 19:17:25 +08:00
this._container.style.visibility = 'hidden';
2011-06-03 17:55:06 +08:00
this._updateContent();
this._updateLayout();
this._updatePosition();
this._container.style.visibility = '';
this._adjustPan();
},
2011-12-09 22:51:31 +08:00
_updateContent: function () {
if (!this._content) { return; }
if (typeof this._content === 'string') {
this._contentNode.innerHTML = this._content;
} else {
2012-02-08 06:16:05 +08:00
while (this._contentNode.hasChildNodes()) {
this._contentNode.removeChild(this._contentNode.firstChild);
}
this._contentNode.appendChild(this._content);
}
this.fire('contentupdate');
},
2011-12-09 22:51:31 +08:00
_updateLayout: function () {
var container = this._contentNode,
2012-11-08 00:46:59 +08:00
style = container.style;
2010-12-16 01:55:57 +08:00
style.width = '';
style.whiteSpace = 'nowrap';
2012-02-15 19:17:25 +08:00
var width = container.offsetWidth;
width = Math.min(width, this.options.maxWidth);
width = Math.max(width, this.options.minWidth);
style.width = (width + 1) + 'px';
style.whiteSpace = '';
2012-02-15 19:17:25 +08:00
style.height = '';
var height = container.offsetHeight,
2012-11-08 00:46:59 +08:00
maxHeight = this.options.maxHeight,
scrolledClass = 'leaflet-popup-scrolled';
if (maxHeight && height > maxHeight) {
style.height = maxHeight + 'px';
L.DomUtil.addClass(container, scrolledClass);
} else {
L.DomUtil.removeClass(container, scrolledClass);
}
this._containerWidth = this._container.offsetWidth;
2010-12-16 01:55:57 +08:00
},
2011-12-09 22:51:31 +08:00
_updatePosition: function () {
if (!this._map) { return; }
2012-06-25 16:42:51 +08:00
var pos = this._map.latLngToLayerPoint(this._latlng),
animated = this._animated,
2012-11-08 00:46:59 +08:00
offset = this.options.offset;
2012-06-25 16:42:51 +08:00
if (animated) {
2012-06-25 16:42:51 +08:00
L.DomUtil.setPosition(this._container, pos);
}
this._containerBottom = -offset.y - (animated ? 0 : pos.y);
this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x + (animated ? 0 : pos.x);
2012-06-26 05:06:23 +08:00
//Bottom position the popup in case the height of the popup changes (images loading etc)
2011-01-11 21:45:06 +08:00
this._container.style.bottom = this._containerBottom + 'px';
this._container.style.left = this._containerLeft + 'px';
2010-12-16 02:58:07 +08:00
},
2012-07-03 22:06:44 +08:00
_zoomAnimation: function (opt) {
var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center);
L.DomUtil.setPosition(this._container, pos);
},
2011-12-09 22:51:31 +08:00
_adjustPan: function () {
if (!this.options.autoPan) { return; }
2012-02-15 19:17:25 +08:00
var map = this._map,
2012-11-08 00:46:59 +08:00
containerHeight = this._container.offsetHeight,
containerWidth = this._containerWidth,
2012-02-15 19:17:25 +08:00
2012-11-08 00:46:59 +08:00
layerPos = new L.Point(this._containerLeft, -containerHeight - this._containerBottom);
2012-06-25 16:42:51 +08:00
if (this._animated) {
2012-06-25 16:42:51 +08:00
layerPos._add(L.DomUtil.getPosition(this._container));
}
2012-02-15 19:17:25 +08:00
2012-06-25 16:42:51 +08:00
var containerPos = map.layerPointToContainerPoint(layerPos),
2012-11-08 00:46:59 +08:00
padding = this.options.autoPanPadding,
size = map.getSize(),
dx = 0,
dy = 0;
2011-01-11 21:45:06 +08:00
if (containerPos.x < 0) {
2012-06-25 16:42:51 +08:00
dx = containerPos.x - padding.x;
2011-01-11 21:45:06 +08:00
}
2012-02-15 19:17:25 +08:00
if (containerPos.x + containerWidth > size.x) {
2012-06-25 16:42:51 +08:00
dx = containerPos.x + containerWidth - size.x + padding.x;
2011-01-11 21:45:06 +08:00
}
if (containerPos.y < 0) {
2012-06-25 16:42:51 +08:00
dy = containerPos.y - padding.y;
2011-01-11 21:45:06 +08:00
}
if (containerPos.y + containerHeight > size.y) {
2012-06-25 16:42:51 +08:00
dy = containerPos.y + containerHeight - size.y + padding.y;
2011-01-11 21:45:06 +08:00
}
2012-06-25 16:42:51 +08:00
if (dx || dy) {
map.panBy(new L.Point(dx, dy));
2011-01-11 21:45:06 +08:00
}
},
2011-12-09 22:51:31 +08:00
_onCloseButtonClick: function (e) {
this._close();
L.DomEvent.stop(e);
2010-12-16 01:55:57 +08:00
}
});
2012-07-05 19:45:06 +08:00
L.popup = function (options, source) {
return new L.Popup(options, source);
};