Merge pull request #7784 from pedros007/mouseout-mouseposition

Adds option to retain MousePosition when pointer leaves viewport
This commit is contained in:
Andreas Hocevar
2018-04-23 10:44:59 +02:00
committed by GitHub
2 changed files with 107 additions and 7 deletions

View File

@@ -31,7 +31,9 @@ const COORDINATE_FORMAT = 'coordinateFormat';
* callback.
* @property {Element|string} [target] Specify a target if you want the
* control to be rendered outside of the map's viewport.
* @property {string} [undefinedHTML=''] Markup for undefined coordinates.
* @property {string} [undefinedHTML=''] Markup for undefined coordinates. If
* `undefined`, then the last pointer position is retained when the pointer
* moves outside the viewport.
*/
@@ -76,7 +78,13 @@ const MousePosition = function(opt_options) {
* @private
* @type {string}
*/
this.undefinedHTML_ = options.undefinedHTML !== undefined ? options.undefinedHTML : '';
this.undefinedHTML_ = 'undefinedHTML' in options ? options.undefinedHTML : '';
/**
* @private
* @type {boolean}
*/
this.renderOnMouseOut_ = this.undefinedHTML_ !== undefined;
/**
* @private
@@ -190,11 +198,13 @@ MousePosition.prototype.setMap = function(map) {
if (map) {
const viewport = map.getViewport();
this.listenerKeys.push(
listen(viewport, EventType.MOUSEMOVE,
this.handleMouseMove, this),
listen(viewport, EventType.MOUSEOUT,
this.handleMouseOut, this)
listen(viewport, EventType.MOUSEMOVE, this.handleMouseMove, this)
);
if (this.renderOnMouseOut_) {
this.listenerKeys.push(
listen(viewport, EventType.MOUSEOUT, this.handleMouseOut, this)
);
}
}
};
@@ -228,7 +238,7 @@ MousePosition.prototype.setProjection = function(projection) {
* @private
*/
MousePosition.prototype.updateHTML_ = function(pixel) {
let html = this.undefinedHTML_;
let html = this.undefinedHTML_ === undefined ? ' ' : this.undefinedHTML_;
if (pixel && this.mapProjection_) {
if (!this.transform_) {
const projection = this.getProjection();

View File

@@ -1,4 +1,8 @@
import Map from '../../../../src/ol/Map.js';
import MousePosition from '../../../../src/ol/control/MousePosition.js';
import View from '../../../../src/ol/View.js';
import EventType from '../../../../src/ol/events/EventType.js';
describe('ol.control.MousePosition', function() {
@@ -20,4 +24,90 @@ describe('ol.control.MousePosition', function() {
});
describe('configuration options', function() {
let target, map;
const width = 360;
const height = 180;
beforeEach(function() {
target = document.createElement('div');
const style = target.style;
style.position = 'absolute';
style.left = '-1000px';
style.top = '-1000px';
style.width = width + 'px';
style.height = height + 'px';
document.body.appendChild(target);
map = new Map({
target: target,
controls: [],
view: new View({
projection: 'EPSG:4326',
center: [0, 0],
resolution: 1
})
});
});
afterEach(function() {
map.dispose();
document.body.removeChild(target);
});
function simulateEvent(type, x, y) {
const viewport = map.getViewport();
// calculated in case body has top < 0 (test runner with small window)
const position = viewport.getBoundingClientRect();
const evt = new MouseEvent(type, {
clientX: position.left + x + width / 2,
clientY: position.top + y + height / 2
});
document.querySelector('div.ol-viewport').dispatchEvent(evt);
}
describe('undefinedHTML', function() {
it('sets div.ol-mouse-position to options.undefinedHTML when mouse moves out', function(done) {
const ctrl = new MousePosition({
undefinedHTML: 'some text'
});
ctrl.setMap(map);
map.renderSync();
const element = document.querySelector('.ol-mouse-position', map.getTarget());
expect(element.innerText).to.be('some text');
simulateEvent(EventType.MOUSEMOVE, 20, 30);
map.renderSync();
expect(element.innerText).to.be('20,-30');
map.once('postrender', function() {
expect(element.innerText).to.be('some text');
done();
});
simulateEvent(EventType.MOUSEOUT, width + 1, height + 1);
map.renderSync();
});
it('Retain mouse position in div.ol-mouse-position when options.undefinedHTML=undefined and mouse moves outside the viewport', function(done) {
const ctrl = new MousePosition({
undefinedHTML: undefined
});
ctrl.setMap(map);
map.renderSync();
const element = document.querySelector('.ol-mouse-position', map.getTarget());
expect(element.innerHTML).to.be(' ');
target.dispatchEvent(new MouseEvent('mousemove'));
simulateEvent(EventType.MOUSEMOVE, 20, 30);
map.renderSync();
map.once('postrender', function() {
expect(element.innerText).to.be('20,-30');
done();
});
simulateEvent(EventType.MOUSEOUT, width + 1, height + 1);
map.renderSync();
});
});
});
});