Merge branch 'master' of https://github.com/openlayers/ol3
This commit is contained in:
BIN
css/img/close.gif
Normal file
BIN
css/img/close.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
120
css/ol.css
120
css/ol.css
@@ -1,2 +1,120 @@
|
||||
.ol-viewport { width:100%; height:100%; position:relative; left:0; top:0; }
|
||||
.ol-renderer-webgl-canvas { width:100%; height:100%; }
|
||||
.ol-renderer-webgl-canvas { width:100%;height:100%; }
|
||||
|
||||
/**
|
||||
* arrow implementation from http://cssarrowplease.com/ for ol-popup
|
||||
*/
|
||||
|
||||
.ol-popup {
|
||||
position: absolute;
|
||||
background: #88b7d5;
|
||||
border: 4px solid #c2e1f5;
|
||||
}
|
||||
|
||||
/**
|
||||
* FIXME
|
||||
*/
|
||||
.ol-popup-close {
|
||||
background: url("img/close.gif") no-repeat;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.ol-popup-top {}
|
||||
.ol-popup-top:after, .ol-popup-top:before {
|
||||
bottom: 100%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ol-popup-top:after {
|
||||
border-bottom-color: #88b7d5;
|
||||
border-width: 30px;
|
||||
left: 50%;
|
||||
margin-left: -30px;
|
||||
}
|
||||
|
||||
.ol-popup-top:before {
|
||||
border-bottom-color: #c2e1f5;
|
||||
border-width: 36px;
|
||||
left: 50%;
|
||||
margin-left: -36px;
|
||||
}
|
||||
|
||||
.ol-popup-bottom {}
|
||||
.ol-popup-bottom:after, .ol-popup-bottom:before {
|
||||
top: 100%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ol-popup-bottom:after {
|
||||
border-top-color: #88b7d5;
|
||||
border-width: 30px;
|
||||
left: 50%;
|
||||
margin-left: -30px;
|
||||
}
|
||||
.ol-popup-bottom:before {
|
||||
border-top-color: #c2e1f5;
|
||||
border-width: 36px;
|
||||
left: 50%;
|
||||
margin-left: -36px;
|
||||
}
|
||||
.ol-popup-right {}
|
||||
.ol-popup-right:after, .ol-popup-right:before {
|
||||
left: 100%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ol-popup-right:after {
|
||||
border-left-color: #88b7d5;
|
||||
border-width: 30px;
|
||||
top: 50%;
|
||||
margin-top: -30px;
|
||||
}
|
||||
.ol-popup-right:before {
|
||||
border-left-color: #c2e1f5;
|
||||
border-width: 36px;
|
||||
top: 50%;
|
||||
margin-top: -36px;
|
||||
}
|
||||
.ol-popup-left {}
|
||||
.ol-popup-left:after, .ol-popup-left:before {
|
||||
right: 100%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ol-popup-left:after {
|
||||
border-right-color: #88b7d5;
|
||||
border-width: 30px;
|
||||
top: 50%;
|
||||
margin-top: -30px;
|
||||
}
|
||||
.ol-popup-left:before {
|
||||
border-right-color: #c2e1f5;
|
||||
border-width: 36px;
|
||||
top: 50%;
|
||||
margin-top: -36px;
|
||||
}
|
||||
|
||||
|
||||
130
src/api/popup.js
Normal file
130
src/api/popup.js
Normal file
@@ -0,0 +1,130 @@
|
||||
goog.provide('ol.popup');
|
||||
|
||||
goog.require('ol.Popup');
|
||||
goog.require('ol.map');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {ol.Popup|Object} popup
|
||||
*/
|
||||
ol.PopupLike;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @param {ol.PopupLike} opt_arg popup object literal.
|
||||
* @return {ol.Popup} the popup.
|
||||
*/
|
||||
ol.popup = function(opt_arg){
|
||||
|
||||
if (opt_arg instanceof ol.Popup) {
|
||||
return opt_arg;
|
||||
}
|
||||
|
||||
/** @type {ol.Map} */
|
||||
var map;
|
||||
|
||||
/** @type {ol.Loc|ol.Feature|undefined} */
|
||||
var anchor;
|
||||
|
||||
/** @type {string|undefined} */
|
||||
var placement;
|
||||
|
||||
/** @type {string|undefined} */
|
||||
var content;
|
||||
|
||||
/** @type {string|undefined} */
|
||||
var template;
|
||||
|
||||
if (arguments.length == 1 && goog.isDef(opt_arg)) {
|
||||
if (goog.isObject(opt_arg)) {
|
||||
map = opt_arg['map'];
|
||||
anchor = opt_arg['anchor'];
|
||||
placement = opt_arg['placement'];
|
||||
content = opt_arg['content'];
|
||||
template = opt_arg['template'];
|
||||
}
|
||||
}
|
||||
|
||||
var popup = new ol.Popup(map, anchor);
|
||||
|
||||
if (goog.isDef(anchor)) {
|
||||
popup.setAnchor(anchor);
|
||||
}
|
||||
if (goog.isDef(placement)) {
|
||||
popup.setPlacement(placement);
|
||||
}
|
||||
if (goog.isDef(content)) {
|
||||
popup.setContent(content);
|
||||
}
|
||||
if (goog.isDef(template)) {
|
||||
popup.setTemplate(template);
|
||||
}
|
||||
|
||||
return popup;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @param {ol.Loc|ol.Feature=} opt_arg a feature or a location.
|
||||
* @return {ol.Popup|ol.Feature|ol.Loc|undefined} Result.
|
||||
*/
|
||||
ol.Popup.prototype.anchor = function(opt_arg){
|
||||
if (arguments.length == 1 && goog.isDef(opt_arg)) {
|
||||
this.setAnchor(opt_arg);
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
return this.getAnchor();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @param {ol.Map=} opt_arg the map .
|
||||
* @return {ol.Popup|ol.Map|undefined} the map or the popup.
|
||||
*/
|
||||
ol.Popup.prototype.map = function(opt_arg){
|
||||
if (arguments.length == 1 && goog.isDef(opt_arg)) {
|
||||
this.setMap(opt_arg);
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
return this.getMap();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @param {string=} opt_arg the content for the map (HTML makrkup)
|
||||
* @return {ol.Popup|string|undefined} the content or the popup.
|
||||
*/
|
||||
ol.Popup.prototype.content = function(opt_arg){
|
||||
if (arguments.length == 1 && goog.isDef(opt_arg)) {
|
||||
this.setContent(opt_arg);
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
return this.getContent();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @param {string=} opt_arg the template to be used to generate the content
|
||||
* @return {ol.Popup|string|undefined} the template or the popup.
|
||||
*/
|
||||
ol.Popup.prototype.template = function(opt_arg){
|
||||
if (arguments.length == 1 && goog.isDef(opt_arg)) {
|
||||
this.setTemplate(opt_arg);
|
||||
return this;
|
||||
}
|
||||
else {
|
||||
return this.getTemplate();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ goog.require("ol.feature");
|
||||
goog.require("ol.projection");
|
||||
goog.require("ol.layer.xyz");
|
||||
goog.require("ol.layer.osm");
|
||||
goog.require("ol.popup");
|
||||
goog.require("ol.Tile");
|
||||
goog.require("ol.TileSet");
|
||||
goog.require("ol.TileCache");
|
||||
|
||||
@@ -385,6 +385,25 @@ ol.Map.prototype.moveByPx = function(dx, dy) {
|
||||
// call moveByPx on renderers
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {ol.Loc} loc the location being requested
|
||||
* @returns {Object} the
|
||||
*/
|
||||
ol.Map.prototype.getViewportPosition = function(loc) {
|
||||
//TODO: delegate this to the renderers
|
||||
//stub for now to get popups working
|
||||
return {x: 200, y: 300};
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {Element} the map overlay element
|
||||
*/
|
||||
ol.Map.prototype.getMapOverlay = function() {
|
||||
//TODO: delegate this to the renderers
|
||||
//stub for now to get popups working
|
||||
return this.mapOverlay_
|
||||
};
|
||||
|
||||
/**
|
||||
* @export
|
||||
*/
|
||||
|
||||
281
src/ol/Popup.js
Normal file
281
src/ol/Popup.js
Normal file
@@ -0,0 +1,281 @@
|
||||
goog.provide('ol.Popup');
|
||||
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.Loc');
|
||||
goog.require('ol.Feature');
|
||||
//goog.require('goog.dom');
|
||||
//goog.require('goog.style');
|
||||
|
||||
|
||||
/**
|
||||
* @export
|
||||
* @constructor
|
||||
* @param {ol.Map} map the map on which the popup is placed.
|
||||
* @param {ol.Loc|ol.Feature=} opt_anchor the anchor object for the popup.
|
||||
* @param {string=} opt_placement the placement of the arrow on the popup.
|
||||
* @param {boolean=} opt_close include a close button on the popup
|
||||
*/
|
||||
ol.Popup = function(map, opt_anchor, opt_placement, opt_close) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Map}
|
||||
*/
|
||||
this.map_ = map;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Loc|ol.Feature|undefined}
|
||||
*/
|
||||
this.anchor_ = opt_anchor;
|
||||
|
||||
/**
|
||||
* can be 'top','bottom','right','left','auto'
|
||||
* TODO: 'auto' not yet implemented
|
||||
* @private
|
||||
* @type {!string}
|
||||
*/
|
||||
this.placement_ = goog.isDefAndNotNull(opt_placement)?opt_placement:'top';
|
||||
|
||||
/**
|
||||
* include a close button on the popup - defaults to true.
|
||||
* @private
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.closeButton_ = goog.isDefAndNotNull(opt_close) ? opt_close : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.content_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.template_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Element}
|
||||
*/
|
||||
this.container_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.arrowOffset_ = 32; //FIXME: set this from CSS dynamically somehow?
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
*/
|
||||
ol.Popup.CLASS_NAME = 'ol-popup';
|
||||
|
||||
/**
|
||||
* @return {ol.Map} Projection.
|
||||
*/
|
||||
ol.Popup.prototype.getMap = function() {
|
||||
return this.map_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {ol.Map} map the map object to hold this popup.
|
||||
*/
|
||||
ol.Popup.prototype.setMap = function(map) {
|
||||
this.map_ = map;
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {ol.Feature|ol.Loc|undefined} the anchor .
|
||||
*/
|
||||
ol.Popup.prototype.getAnchor = function() {
|
||||
return this.anchor_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {ol.Feature|ol.Loc} anchor the anchor location to place this popup.
|
||||
*/
|
||||
ol.Popup.prototype.setAnchor = function(anchor) {
|
||||
this.anchor_ = anchor;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string|undefined} the placement value relative to the anchor.
|
||||
*/
|
||||
ol.Popup.prototype.getPlacement = function() {
|
||||
return this.placement_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} placement where to place this popup relative to the anchor.
|
||||
*/
|
||||
ol.Popup.prototype.setPlacement = function(placement) {
|
||||
if (!goog.isNull(this.container_)) {
|
||||
goog.dom.classes.remove(this.container_,
|
||||
ol.Popup.CLASS_NAME+'-'+this.placement_);
|
||||
goog.dom.classes.add(this.container_,ol.Popup.CLASS_NAME+'-'+placement);
|
||||
}
|
||||
this.placement_ = placement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string|undefined} static content to be displayed in the popup (HTML)
|
||||
*/
|
||||
ol.Popup.prototype.getContent = function() {
|
||||
return this.content_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} content the content to be displayed this popup.
|
||||
*/
|
||||
ol.Popup.prototype.setContent = function(content) {
|
||||
this.content_ = content;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @returns {string} generates the content
|
||||
*/
|
||||
ol.Popup.prototype.generateContent_ = function() {
|
||||
//set the content
|
||||
if ( goog.isDefAndNotNull(this.content_) ) {
|
||||
return this.content_;
|
||||
} else {
|
||||
if ( goog.isDefAndNotNull(this.template_) &&
|
||||
(this.anchor_ instanceof ol.Feature)) {
|
||||
//set content from feature attributes on the template
|
||||
//TODO: this.setContent(template.apply(this.anchor.getAttributes()));
|
||||
return this.template_; //stub to return something
|
||||
} else {
|
||||
return '<br>';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string|undefined} the anchor .
|
||||
*/
|
||||
ol.Popup.prototype.getTemplate = function() {
|
||||
return this.template_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} template the map object to hold this popup.
|
||||
*/
|
||||
ol.Popup.prototype.setTemplate = function(template) {
|
||||
this.template_ = template;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open the popup.
|
||||
* @export
|
||||
* @param {ol.Feature|ol.Loc} opt_arg feature or location for the anchor
|
||||
*/
|
||||
ol.Popup.prototype.open = function(opt_arg) {
|
||||
if (goog.isDef(opt_arg)) {
|
||||
this.setAnchor(opt_arg);
|
||||
}
|
||||
|
||||
//create popup container if it's not created already
|
||||
if (goog.isNull(this.container_)) {
|
||||
this.container_ = goog.dom.createElement('div');
|
||||
goog.dom.classes.add(this.container_,
|
||||
ol.Popup.CLASS_NAME, ol.Popup.CLASS_NAME+'-'+this.placement_);
|
||||
|
||||
if (this.closeButton_) {
|
||||
var closeButton = goog.dom.createElement('div');
|
||||
goog.dom.appendChild(this.container_, closeButton);
|
||||
goog.dom.classes.add(closeButton, ol.Popup.CLASS_NAME+'-close');
|
||||
}
|
||||
this.map_.getEvents().register('click', this.clickHandler, this);
|
||||
goog.dom.appendChild(this.map_.getMapOverlay(), this.container_);
|
||||
}
|
||||
|
||||
this.childContent_=goog.dom.htmlToDocumentFragment(this.generateContent_());
|
||||
goog.dom.appendChild(this.container_, this.childContent_);
|
||||
|
||||
//position the element
|
||||
if (this.anchor_ instanceof ol.Feature) {
|
||||
this.pos_ = this.anchor_.getGeometry().getCentroid();
|
||||
} else {
|
||||
this.pos_ = this.anchor_;
|
||||
}
|
||||
var popupPosPx = this.map_.getViewportPosition(this.pos_);
|
||||
var popupSize = goog.style.getSize(this.container_);
|
||||
|
||||
switch(this.placement_) {
|
||||
default:
|
||||
case 'auto':
|
||||
//TODO: switch based on map quadrant
|
||||
break;
|
||||
case 'top':
|
||||
case 'bottom':
|
||||
popupPosPx.x -= popupSize.width / 2.0;
|
||||
|
||||
if (this.placement_ == "bottom") {
|
||||
popupPosPx.y -= popupSize.height + this.arrowOffset_;
|
||||
} else {
|
||||
popupPosPx.y += this.arrowOffset_;
|
||||
}
|
||||
break;
|
||||
case 'left':
|
||||
case 'right':
|
||||
popupPosPx.y -= popupSize.height / 2.0;
|
||||
|
||||
if (this.placement_ == "right") {
|
||||
popupPosPx.x -= popupSize.width + this.arrowOffset_;
|
||||
} else {
|
||||
popupPosPx.x += this.arrowOffset_;
|
||||
}
|
||||
break;
|
||||
};
|
||||
this.moveTo_(popupPosPx);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @param px - {goog.} the top and left position of the popup div.
|
||||
*/
|
||||
ol.Popup.prototype.moveTo_ = function(px) {
|
||||
if (goog.isDefAndNotNull(px)) {
|
||||
goog.style.setPosition(this.container_, px.x, px.y);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Click handler
|
||||
* @param {Event} evt the event generated by a click
|
||||
*/
|
||||
ol.Popup.prototype.clickHandler = function(evt) {
|
||||
var target = /** @type {Node} */ evt.target;
|
||||
if (goog.dom.classes.has(target,ol.Popup.CLASS_NAME+'-close')) {
|
||||
this.close();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clean up.
|
||||
* @export
|
||||
*/
|
||||
ol.Popup.prototype.close = function() {
|
||||
goog.dom.removeChildren(this.container_);
|
||||
goog.dom.removeNode(this.container_);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clean up.
|
||||
* @export
|
||||
*/
|
||||
ol.Popup.prototype.destroy = function() {
|
||||
for (var key in this) {
|
||||
delete this[key];
|
||||
}
|
||||
};
|
||||
@@ -12,13 +12,19 @@ goog.require('goog.functions');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Element} target The element that will be dragged.
|
||||
* @param {ol.event.Events} target The Events instance that handles events.
|
||||
* @extends {goog.fx.Dragger}
|
||||
* @implements {ol.event.ISequence}
|
||||
* @export
|
||||
*/
|
||||
ol.event.Drag = function(target) {
|
||||
goog.base(this, target);
|
||||
goog.base(this, target.getElement());
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.event.Events}
|
||||
*/
|
||||
this.target_ = target;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -47,6 +53,7 @@ ol.event.Drag.prototype.dispatchEvent = function(e) {
|
||||
e.type = ol.event.Drag.EventType.DRAGEND;
|
||||
}
|
||||
}
|
||||
this.target_.dispatchEvent(/** @type {Event} */ (e));
|
||||
return goog.base(this, 'dispatchEvent', e);
|
||||
};
|
||||
|
||||
@@ -67,11 +74,6 @@ ol.event.Drag.prototype.doDrag = function(e, x, y, dragFromScroll) {
|
||||
/** @override */
|
||||
ol.event.Drag.prototype.defaultAction = function(x, y) {};
|
||||
|
||||
/** @inheritDoc */
|
||||
ol.event.Drag.prototype.getEventTypes = function() {
|
||||
return ol.event.Drag.EventType;
|
||||
};
|
||||
|
||||
/** @inheritDoc */
|
||||
ol.event.Drag.prototype.destroy = ol.event.Drag.prototype.dispose;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ ol.event.isMultiTouch = function(evt) {
|
||||
* @constructor
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @param {Object} object The object we are creating this instance for.
|
||||
* @param {!EventTarget=} opt_element An optional element that we want to
|
||||
* @param {!Element=} opt_element An optional element that we want to
|
||||
* listen to browser events on.
|
||||
* @param {boolean=} opt_includeXY Should the 'xy' property automatically be
|
||||
* created for browser pointer events? In general, this should be false. If
|
||||
@@ -71,7 +71,7 @@ ol.event.Events = function(object, opt_element, opt_includeXY, opt_sequences) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {EventTarget}
|
||||
* @type {Element}
|
||||
* The element that this instance listens to mouse events on.
|
||||
*/
|
||||
this.element_ = null;
|
||||
@@ -115,7 +115,7 @@ ol.event.Events.prototype.setIncludeXY = function(includeXY) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {EventTarget} The element that this instance currently
|
||||
* @return {Element} The element that this instance currently
|
||||
* listens to browser events on.
|
||||
*/
|
||||
ol.event.Events.prototype.getElement = function() {
|
||||
@@ -126,18 +126,17 @@ ol.event.Events.prototype.getElement = function() {
|
||||
* Attach this instance to a DOM element. When called, all browser events fired
|
||||
* on the provided element will be relayed by this instance.
|
||||
*
|
||||
* @param {EventTarget} element A DOM element to attach
|
||||
* @param {Element} element A DOM element to attach
|
||||
* browser events to. If called without this argument, all browser events
|
||||
* will be detached from the element they are currently attached to.
|
||||
*/
|
||||
ol.event.Events.prototype.setElement = function(element) {
|
||||
var types, t;
|
||||
var types = goog.events.EventType, t;
|
||||
if (this.element_) {
|
||||
types = this.getBrowserEventTypes();
|
||||
for (t in types) {
|
||||
// register the event cross-browser
|
||||
goog.events.unlisten(
|
||||
this.element_, types[t], this.handleBrowserEvent, false, this
|
||||
this.element_, types[t], this.dispatchEvent, true, this
|
||||
);
|
||||
}
|
||||
this.destroySequences();
|
||||
@@ -145,25 +144,21 @@ ol.event.Events.prototype.setElement = function(element) {
|
||||
}
|
||||
this.element_ = element || null;
|
||||
if (goog.isDefAndNotNull(element)) {
|
||||
this.createSequences(element);
|
||||
types = this.getBrowserEventTypes();
|
||||
this.createSequences();
|
||||
for (t in types) {
|
||||
// register the event cross-browser
|
||||
goog.events.listen(
|
||||
element, types[t], this.handleBrowserEvent, false, this
|
||||
element, types[t], this.dispatchEvent, true, this
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {EventTarget} target
|
||||
*/
|
||||
ol.event.Events.prototype.createSequences = function(target) {
|
||||
ol.event.Events.prototype.createSequences = function() {
|
||||
for (var i=0, ii=this.sequenceProviders_.length; i<ii; ++i) {
|
||||
this.sequences_.push(
|
||||
new ol.event.SEQUENCE_PROVIDER_MAP[this.sequenceProviders_[i]](
|
||||
target
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -176,18 +171,6 @@ ol.event.Events.prototype.destroySequences = function() {
|
||||
this.sequences_ = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {Object.<string, string>}
|
||||
*/
|
||||
ol.event.Events.prototype.getBrowserEventTypes = function() {
|
||||
var types = {};
|
||||
goog.object.extend(types, goog.events.EventType);
|
||||
for (var i=this.sequences_.length-1; i>=0; --i) {
|
||||
goog.object.extend(types, this.sequences_[i].getEventTypes());
|
||||
}
|
||||
return types;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a listener for an event.
|
||||
*
|
||||
@@ -257,39 +240,40 @@ ol.event.Events.prototype.triggerEvent = function(type, opt_evt) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Basically just a wrapper to the triggerEvent() function, but takes
|
||||
* care to set a property 'xy' on the event with the current mouse position.
|
||||
* Basically just a wrapper to the parent's dispatchEvent() function, but takes
|
||||
* care to set a property 'xy' on the event with the current mouse position and
|
||||
* normalize clientX and clientY for multi-touch events.
|
||||
*
|
||||
* @param {Event} evt
|
||||
* @param {Event} evt Event object.
|
||||
* @return {boolean} If anyone called preventDefault on the event object (or
|
||||
* if any of the handlers returns false this will also return false.
|
||||
*/
|
||||
ol.event.Events.prototype.handleBrowserEvent = function(evt) {
|
||||
ol.event.Events.prototype.dispatchEvent = function(evt) {
|
||||
var type = evt.type,
|
||||
listeners = goog.events.getListeners(this.element_, type, false)
|
||||
.concat(goog.events.getListeners(this.element_, type, true));
|
||||
if (!listeners || listeners.length === 0) {
|
||||
if (listeners && listeners.length > 0) {
|
||||
// noone's listening, bail out
|
||||
return;
|
||||
}
|
||||
// add clientX & clientY to all events - corresponds to average x, y
|
||||
var touches = evt.touches;
|
||||
if (touches && touches[0]) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var num = touches.length;
|
||||
var touch;
|
||||
for (var i=0; i<num; ++i) {
|
||||
touch = touches[i];
|
||||
x += touch.clientX;
|
||||
y += touch.clientY;
|
||||
// add clientX & clientY to all events - corresponds to average x, y
|
||||
var touches = evt.touches;
|
||||
if (touches && touches[0]) {
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var num = touches.length;
|
||||
var touch;
|
||||
for (var i=0; i<num; ++i) {
|
||||
touch = touches[i];
|
||||
x += touch.clientX;
|
||||
y += touch.clientY;
|
||||
}
|
||||
evt.clientX = x / num;
|
||||
evt.clientY = y / num;
|
||||
}
|
||||
if (this.includeXY_) {
|
||||
evt.xy = goog.style.getRelativePosition(evt, this.element_);
|
||||
}
|
||||
evt.clientX = x / num;
|
||||
evt.clientY = y / num;
|
||||
}
|
||||
if (this.includeXY_) {
|
||||
var element = /** @type {!Element} */ this.element_;
|
||||
evt.xy = goog.style.getRelativePosition(evt, element);
|
||||
}
|
||||
this.dispatchEvent(evt);
|
||||
return goog.base(this, 'dispatchEvent', evt);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
goog.provide('ol.event.ISequence');
|
||||
|
||||
/**
|
||||
* Interface for event sequences
|
||||
* Interface for event sequences. Event sequences map sequences of native
|
||||
* browser events to high level events that the sequence provides.
|
||||
*
|
||||
* Implementations are expected to call dispatchEvent on the {@code target} to
|
||||
* to fire their high level events.
|
||||
*
|
||||
* Implementations can expect the {@code target}'s {@code getElement()} method
|
||||
* to return an {Element} at construction time.
|
||||
*
|
||||
* @interface
|
||||
* @param {Element} target The element that will be listened to for browser
|
||||
* events.
|
||||
* @param {ol.event.Events} target The Events instance that receives the
|
||||
* sequence's events.
|
||||
*/
|
||||
ol.event.ISequence = function(target) {};
|
||||
|
||||
/**
|
||||
* @return {Object.<string, string>} element
|
||||
*/
|
||||
ol.event.ISequence.prototype.getEventTypes = function() {};
|
||||
|
||||
/**
|
||||
* Destroys the sequence
|
||||
*/
|
||||
|
||||
@@ -32,3 +32,12 @@ ol.geom.Geometry.prototype.setBounds = function(bounds) {
|
||||
this.bounds_ = bounds;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns ol.Loc
|
||||
*/
|
||||
ol.geom.Geometry.prototype.getCentroid = function() {
|
||||
//FIXME: stub only to get popups working
|
||||
return new ol.Loc(-76,45);
|
||||
};
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
<script type="text/javascript" src="spec/api/layer/xyz.test.js"></script>
|
||||
<script type="text/javascript" src="spec/api/layer/osm.test.js"></script>
|
||||
<script type="text/javascript" src="spec/api/feature.test.js"></script>
|
||||
<script type="text/javascript" src="spec/api/popup.test.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
<script type="text/javascript" src="spec/ol/Feature.test.js"></script>
|
||||
<script type="text/javascript" src="spec/ol/renderer/WebGL.test.js"></script>
|
||||
<script type="text/javascript" src="spec/ol/renderer/TileLayerRenderer.test.js"></script>
|
||||
<script type="text/javascript" src="spec/ol/Popup.test.js"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
280
test/spec/api/popup.test.js
Normal file
280
test/spec/api/popup.test.js
Normal file
@@ -0,0 +1,280 @@
|
||||
describe("ol.popup", function() {
|
||||
|
||||
it("should be able to add it to a map", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.map()).toBeA(ol.Map);
|
||||
});
|
||||
|
||||
it("should be able to place it at a specific location", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
anchor: ol.loc([10,20])
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.anchor()).toBeA(ol.Loc);
|
||||
expect(popup.anchor().x()).toBe(10);
|
||||
expect(popup.anchor().y()).toBe(20);
|
||||
});
|
||||
|
||||
it("should be able to anchor it with a feature", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var feat = ol.feature();
|
||||
var point = ol.geom.point([21, 4]);
|
||||
feat.geometry(point);
|
||||
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
anchor: feat
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.anchor()).toBeA(ol.Feature);
|
||||
expect(popup.anchor().geometry().x()).toBe(21);
|
||||
expect(popup.anchor().geometry().y()).toBe(4);
|
||||
});
|
||||
|
||||
it("should be able to anchor it with a feature", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var feat = ol.feature();
|
||||
var point = ol.geom.point([21, 4]);
|
||||
feat.geometry(point);
|
||||
|
||||
var popup = ol.popup({
|
||||
map: map
|
||||
}).anchor(feat);
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.anchor()).toBeA(ol.Feature);
|
||||
expect(popup.anchor().geometry().x()).toBe(21);
|
||||
expect(popup.anchor().geometry().y()).toBe(4);
|
||||
});
|
||||
|
||||
it("should be able to associate it with a feature", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var feat = ol.feature();
|
||||
var point = ol.geom.point([21, 4]);
|
||||
feat.geometry(point);
|
||||
var popup = ol.popup({
|
||||
map: map
|
||||
});
|
||||
popup.anchor(feat);
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.anchor()).toBeA(ol.Feature);
|
||||
expect(popup.anchor().geometry().x()).toBe(21);
|
||||
expect(popup.anchor().geometry().y()).toBe(4);
|
||||
});
|
||||
|
||||
/*
|
||||
* not yet implemented
|
||||
it("should be able to set the placement automatically", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
anchor: ol.loc([10,20]),
|
||||
placement: 'auto'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
//expect?
|
||||
});
|
||||
*/
|
||||
|
||||
it("should be able to set the placement top of the location", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
anchor: ol.loc([10,20]),
|
||||
placement: 'top'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
//expect?
|
||||
});
|
||||
|
||||
it("should be able to set the placement right of the location", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
anchor: ol.loc([10,20]),
|
||||
placement: 'right'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
//expect?
|
||||
});
|
||||
|
||||
/*
|
||||
it("should be able to open and close a popup", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
anchor: ol.loc([10,20]),
|
||||
content: 'test'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open();
|
||||
var elems = goog.dom.getElementsByClass('ol-popup');
|
||||
expect(elems.length).toBe(1);
|
||||
expect(elems[0].innerHTML.indexOf('test')).toBe(0);
|
||||
|
||||
popup.close();
|
||||
//expect(popup.container()).toBeNull();
|
||||
|
||||
});
|
||||
|
||||
it("should be able to open and close a popup with a feature argument", function() {
|
||||
|
||||
var point = ol.geom.point([21, 4]);
|
||||
var feat = ol.feature().geometry(point).set('name','foo');
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
template: '<p>{{name}}</p>'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open(feat);
|
||||
|
||||
expect(popup.anchor()).toBeA(ol.Feature);
|
||||
expect(popup.anchor().geometry().x()).toBe(21);
|
||||
expect(popup.anchor().geometry().y()).toBe(4);
|
||||
//expect?
|
||||
|
||||
popup.close();
|
||||
//expect?
|
||||
|
||||
});
|
||||
|
||||
it("should be able to open with a new feature and the popup updates", function() {
|
||||
|
||||
var point = ol.geom.point([21, 4]);
|
||||
var feat = ol.feature().geometry(point).set('name','foo');
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
template: '<p>{{name}}</p>'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open(feat);
|
||||
|
||||
expect(popup.anchor()).toBeA(ol.Feature);
|
||||
expect(popup.anchor().geometry().x()).toBe(21);
|
||||
expect(popup.anchor().geometry().y()).toBe(4);
|
||||
//expect?
|
||||
|
||||
var feat2 = ol.feature().geometry(ol.geom.point([-67,-80])).set('name','bar');
|
||||
popup.open(feat2)
|
||||
expect(popup.anchor().geometry().x()).toBe(-67);
|
||||
expect(popup.anchor().geometry().y()).toBe(-80);
|
||||
|
||||
popup.close();
|
||||
//expect?
|
||||
|
||||
});
|
||||
|
||||
it("should be able to open and close a popup with a loc argument", function() {
|
||||
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
content: 'test'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open(ol.loc([15,3]));
|
||||
|
||||
expect(popup.anchor()).toBeA(ol.Loc);
|
||||
expect(popup.anchor().x()).toBe(15);
|
||||
expect(popup.anchor().y()).toBe(3);
|
||||
|
||||
popup.close();
|
||||
//expect?
|
||||
|
||||
});
|
||||
|
||||
it("should be able to set content in the popup", function() {
|
||||
|
||||
var point = ol.geom.point([21, 4]);
|
||||
var feat = ol.feature().geometry(point);
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
content: '<p>hello popup! #ol3</p>'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open();
|
||||
//expect?
|
||||
|
||||
popup.content('<p>content changed! #ol3</p>');
|
||||
//expect?
|
||||
|
||||
popup.close();
|
||||
//expect?
|
||||
|
||||
});
|
||||
|
||||
it("should be able to set content based on a template and feature attributes", function() {
|
||||
|
||||
var point = ol.geom.point([21, 4]);
|
||||
var feat = ol.feature().geometry(point).set('name', 'foo');
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
template: '<p>hello popup template! #ol3 feature name: {{name}}</p>'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open(feat);
|
||||
//expect?
|
||||
|
||||
popup.template();
|
||||
|
||||
popup.close();
|
||||
//expect?
|
||||
|
||||
});
|
||||
|
||||
it("should be able to use a user provided container", function() {
|
||||
|
||||
var point = ol.geom.point([21, 4]);
|
||||
var feat = ol.feature().geometry(point).set('name', 'foo');
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
template: '<p>hello popup template! #ol3 feature name: {{name}}</p>'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open(feat);
|
||||
//expect?
|
||||
|
||||
popup.template();
|
||||
|
||||
popup.close();
|
||||
//expect?
|
||||
|
||||
});
|
||||
*/
|
||||
|
||||
});
|
||||
|
||||
@@ -123,38 +123,35 @@ describe("ol.event.Events", function() {
|
||||
events.destroy();
|
||||
});
|
||||
|
||||
it("can be extended with event sequences", function() {
|
||||
var element = document.createElement("div"),
|
||||
events = new ol.event.Events("foo", element, false, ["drag"]),
|
||||
mockEvt;
|
||||
it("can be extended with sequences implementing ol.event.ISequence", function() {
|
||||
var sequence;
|
||||
var Sequence = function(target) {
|
||||
sequence = this;
|
||||
this.target = target;
|
||||
};
|
||||
Sequence.prototype.fire = function() {
|
||||
this.target.dispatchEvent("myevent");
|
||||
};
|
||||
Sequence.prototype.destroy = function() {
|
||||
this.destroyed = true;
|
||||
};
|
||||
ol.event.addSequenceProvider("myseq", Sequence);
|
||||
|
||||
var element = document.createElement("div");
|
||||
events = new ol.event.Events("foo", undefined, false, ["myseq"]);
|
||||
|
||||
// mock dom object
|
||||
goog.object.extend(element, new goog.events.EventTarget());
|
||||
expect(sequence).toBeUndefined();
|
||||
|
||||
log = [];
|
||||
events.register('dragstart', logFn);
|
||||
events.register('drag', logFn);
|
||||
events.register('dragend', logFn);
|
||||
events.setElement(element);
|
||||
events.register('myevent', logFn);
|
||||
sequence.fire();
|
||||
|
||||
mockEvt = new goog.events.BrowserEvent({
|
||||
type: "dragstart", button: null
|
||||
});
|
||||
element.dispatchEvent(mockEvt);
|
||||
mockEvt = new goog.events.BrowserEvent({
|
||||
type: "drag", button: null
|
||||
});
|
||||
element.dispatchEvent(mockEvt);
|
||||
mockEvt = new goog.events.BrowserEvent({
|
||||
type: "dragend", button: null
|
||||
});
|
||||
element.dispatchEvent(mockEvt);
|
||||
|
||||
expect(log.length).toBe(3);
|
||||
expect(log[0].evt.type).toBe("dragstart");
|
||||
expect(log[1].evt.type).toBe("drag");
|
||||
expect(log[2].evt.type).toBe("dragend");
|
||||
expect(log.length).toBe(1);
|
||||
expect(log[0].evt.type).toBe("myevent");
|
||||
|
||||
events.destroy();
|
||||
expect(sequence.destroyed).toBe(true);
|
||||
});
|
||||
|
||||
it("provides an isSingleTouch() function", function() {
|
||||
|
||||
96
test/spec/ol/Popup.test.js
Normal file
96
test/spec/ol/Popup.test.js
Normal file
@@ -0,0 +1,96 @@
|
||||
describe("ol.Popup", function() {
|
||||
|
||||
it("should be able to add it to a map", function() {
|
||||
|
||||
var map = new ol.Map();
|
||||
var popup = new ol.Popup(map);
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.getMap()).toBeA(ol.Map);
|
||||
});
|
||||
|
||||
it("should be able to place it at a specific location", function() {
|
||||
|
||||
var map = new ol.Map();
|
||||
var popup = new ol.Popup(map, new ol.Loc(10,20));
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
expect(popup.getAnchor()).toBeA(ol.Loc);
|
||||
expect(popup.getAnchor().x()).toBe(10);
|
||||
expect(popup.getAnchor().y()).toBe(20);
|
||||
});
|
||||
|
||||
it("should be able to anchor it with a feature", function() {
|
||||
|
||||
var feat = new ol.Feature();
|
||||
feat.setGeometry(new ol.geom.Point(21, 4));
|
||||
var map = new ol.Map();
|
||||
var popup = new ol.Popup(map, feat);
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
var anchor = popup.getAnchor();
|
||||
expect(anchor).toBeA(ol.Feature);
|
||||
var geom = anchor.getGeometry();
|
||||
expect(geom.getX()).toBe(21);
|
||||
expect(geom.getY()).toBe(4);
|
||||
});
|
||||
|
||||
/*
|
||||
it("should be able to set the placement top of the location", function() {
|
||||
|
||||
var map = new ol.Map();
|
||||
var popup = new ol.Popup(map, new ol.Loc(10,20),'top');
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open();
|
||||
var elems = goog.dom.getElementsByClass('ol-popup-top');
|
||||
expect(elems.length).toBe(1);
|
||||
elems = goog.dom.getElementsByClass('ol-popup-close');
|
||||
expect(elems.length).toBe(1);
|
||||
popup.close();
|
||||
});
|
||||
|
||||
it("should be able to change the placement", function() {
|
||||
|
||||
var map = new ol.Map();
|
||||
var popup = new ol.Popup(map, new ol.Loc(10,20),'top',false);
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open();
|
||||
var elems = goog.dom.getElementsByClass('ol-popup-top');
|
||||
expect(elems.length).toBe(1);
|
||||
elems = goog.dom.getElementsByClass('ol-popup-close');
|
||||
expect(elems.length).toBe(0);
|
||||
|
||||
popup.setPlacement('right');
|
||||
elems = goog.dom.getElementsByClass('ol-popup-top');
|
||||
expect(elems.length).toBe(0);
|
||||
elems = goog.dom.getElementsByClass('ol-popup-right');
|
||||
expect(elems.length).toBe(1);
|
||||
|
||||
popup.close();
|
||||
});
|
||||
|
||||
it("should be able to use a user provided container", function() {
|
||||
|
||||
var point = ol.geom.point([21, 4]);
|
||||
var feat = ol.feature().geometry(point).set('name', 'foo');
|
||||
var map = ol.map();
|
||||
var popup = ol.popup({
|
||||
map: map,
|
||||
template: '<p>hello popup template! #ol3 feature name: {{name}}</p>'
|
||||
});
|
||||
|
||||
expect(popup).toBeA(ol.Popup);
|
||||
popup.open(feat);
|
||||
//expect?
|
||||
|
||||
pop.template();
|
||||
|
||||
popup.close();
|
||||
expect(goog.dom.getElementsByClass('ol-popup')).toBeNull();
|
||||
});
|
||||
*/
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user