Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event improvements #6218

Merged
merged 9 commits into from
Feb 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## master

### ⚠️ Breaking changes

* `Evented` is no longer publicly exported, and `Evented#fire` and `Evented#listens` are now private. If you are writing a class that needs event emitting functionality, consider using [`EventEmitter`](https://nodejs.org/api/events.html#events_class_eventemitter) or similar libraries instead.

## 0.44.1

### 🐛 Bug fixes
Expand Down
2 changes: 1 addition & 1 deletion bench/lib/create_style.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow

const Style = require('../../src/style/style');
const Evented = require('../../src/util/evented');
const {Evented} = require('../../src/util/evented');

class StubMap extends Evented {
_transformRequest(url) {
Expand Down
4 changes: 2 additions & 2 deletions docs/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ toc:
- CanvasSource
- name: Events
description: |
`Evented` is Mapbox GL JS's event system. It is sometimes extended when
implementing [IControls](#IControl) and other extensions.
`Map` (and some other classes) emit events in response to user interactions or changes in state. `Evented`
is the interface used to bind and unbind listeners for these events.
- Evented
- MapMouseEvent
- MapTouchEvent
Expand Down
38 changes: 9 additions & 29 deletions docs/pages/example/drag-a-point.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@
<pre id='coordinates' class='coordinates'></pre>

<script>
// Holds mousedown state for events. if this
// flag is active, we move the point on `mousemove`.
var isDragging;

// Is the cursor over a point? if this
// flag is active, we listen for a mousedown event.
var isCursorOverPoint;

var coordinates = document.getElementById('coordinates');
var map = new mapboxgl.Map({
container: 'map',
Expand All @@ -48,21 +40,7 @@
}]
};

function mouseDown() {
if (!isCursorOverPoint) return;

isDragging = true;

// Set a cursor indicator
canvas.style.cursor = 'grab';

// Mouse events
map.on('mousemove', onMove);
map.once('mouseup', onUp);
}

function onMove(e) {
if (!isDragging) return;
var coords = e.lngLat;

// Set a UI indicator for dragging.
Expand All @@ -75,15 +53,13 @@
}

function onUp(e) {
if (!isDragging) return;
var coords = e.lngLat;

// Print the coordinates of where the point had
// finished being dragged to on the map.
coordinates.style.display = 'block';
coordinates.innerHTML = 'Longitude: ' + coords.lng + '<br />Latitude: ' + coords.lat;
canvas.style.cursor = '';
isDragging = false;

// Unbind mouse events
map.off('mousemove', onMove);
Expand Down Expand Up @@ -111,17 +87,21 @@
map.on('mouseenter', 'point', function() {
map.setPaintProperty('point', 'circle-color', '#3bb2d0');
canvas.style.cursor = 'move';
isCursorOverPoint = true;
map.dragPan.disable();
});

map.on('mouseleave', 'point', function() {
map.setPaintProperty('point', 'circle-color', '#3887be');
canvas.style.cursor = '';
isCursorOverPoint = false;
map.dragPan.enable();
});

map.on('mousedown', mouseDown);
map.on('mousedown', 'point', function(e) {
// Prevent the default map drag behavior.
e.preventDefault();

canvas.style.cursor = 'grab';

map.on('mousemove', onMove);
map.once('mouseup', onUp);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 this is such a nice simplification, and (therefore, IMO) confirms this API design.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3

});
</script>
2 changes: 0 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const Style = require('./style/style');
const LngLat = require('./geo/lng_lat');
const LngLatBounds = require('./geo/lng_lat_bounds');
const Point = require('@mapbox/point-geometry');
const Evented = require('./util/evented');
const config = require('./util/config');
const rtlTextPlugin = require('./source/rtl_text_plugin');

Expand All @@ -38,7 +37,6 @@ module.exports = {
LngLat,
LngLatBounds,
Point,
Evented,
config,

/**
Expand Down
5 changes: 3 additions & 2 deletions src/source/canvas_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ const window = require('../util/window');
const rasterBoundsAttributes = require('../data/raster_bounds_attributes');
const VertexArrayObject = require('../render/vertex_array_object');
const Texture = require('../render/texture');
const {ErrorEvent} = require('../util/evented');

import type Map from '../ui/map';
import type Dispatcher from '../util/dispatcher';
import type Evented from '../util/evented';
import type {Evented} from '../util/evented';

/**
* A data source containing the contents of an HTML canvas.
Expand Down Expand Up @@ -78,7 +79,7 @@ class CanvasSource extends ImageSource {
this.height = this.canvas.height;

if (this._hasInvalidDimensions()) {
this.fire('error', new Error('Canvas dimensions cannot be less than or equal to zero.'));
this.fire(new ErrorEvent(new Error('Canvas dimensions cannot be less than or equal to zero.')));
return;
}

Expand Down
14 changes: 7 additions & 7 deletions src/source/geojson_source.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

const Evented = require('../util/evented');
const {Event, ErrorEvent, Evented} = require('../util/evented');
const util = require('../util/util');
const window = require('../util/window');
const EXTENT = require('../data/extent');
Expand Down Expand Up @@ -137,10 +137,10 @@ class GeoJSONSource extends Evented implements Source {
}

load() {
this.fire('dataloading', {dataType: 'source'});
this.fire(new Event('dataloading', {dataType: 'source'}));
this._updateWorkerData((err) => {
if (err) {
this.fire('error', {error: err});
this.fire(new ErrorEvent(err));
return;
}

Expand All @@ -152,7 +152,7 @@ class GeoJSONSource extends Evented implements Source {

// although GeoJSON sources contain no metadata, we fire this event to let the SourceCache
// know its ok to start requesting tiles.
this.fire('data', data);
this.fire(new Event('data', data));
});
}

Expand All @@ -169,18 +169,18 @@ class GeoJSONSource extends Evented implements Source {
*/
setData(data: GeoJSON | string) {
this._data = data;
this.fire('dataloading', {dataType: 'source'});
this.fire(new Event('dataloading', {dataType: 'source'}));
this._updateWorkerData((err) => {
if (err) {
return this.fire('error', { error: err });
return this.fire(new ErrorEvent(err));
}

const data: Object = { dataType: 'source', sourceDataType: 'content' };
if (this._collectResourceTiming && this._resourceTiming && (this._resourceTiming.length > 0)) {
data.resourceTiming = this._resourceTiming;
this._resourceTiming = [];
}
this.fire('data', data);
this.fire(new Event('data', data));
});

return this;
Expand Down
10 changes: 5 additions & 5 deletions src/source/image_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const util = require('../util/util');
const {CanonicalTileID} = require('./tile_id');
const LngLat = require('../geo/lng_lat');
const Point = require('@mapbox/point-geometry');
const Evented = require('../util/evented');
const {Event, ErrorEvent, Evented} = require('../util/evented');
const ajax = require('../util/ajax');
const browser = require('../util/browser');
const EXTENT = require('../data/extent');
Expand Down Expand Up @@ -92,13 +92,13 @@ class ImageSource extends Evented implements Source {
}

load() {
this.fire('dataloading', {dataType: 'source'});
this.fire(new Event('dataloading', {dataType: 'source'}));

this.url = this.options.url;

ajax.getImage(this.map._transformRequest(this.url, ajax.ResourceType.Image), (err, image) => {
if (err) {
this.fire('error', {error: err});
this.fire(new ErrorEvent(err));
} else if (image) {
this.image = browser.getImageData(image);
this._finishLoading();
Expand All @@ -109,7 +109,7 @@ class ImageSource extends Evented implements Source {
_finishLoading() {
if (this.map) {
this.setCoordinates(this.coordinates);
this.fire('data', {dataType: 'source', sourceDataType: 'metadata'});
this.fire(new Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
}
}

Expand Down Expand Up @@ -175,7 +175,7 @@ class ImageSource extends Evented implements Source {
delete this.boundsBuffer;
}

this.fire('data', {dataType:'source', sourceDataType: 'content'});
this.fire(new Event('data', {dataType:'source', sourceDataType: 'content'}));
return this;
}

Expand Down
2 changes: 1 addition & 1 deletion src/source/raster_dem_tile_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const ajax = require('../util/ajax');
const util = require('../util/util');
const Evented = require('../util/evented');
const {Evented} = require('../util/evented');
const normalizeURL = require('../util/mapbox').normalizeTileURL;
const browser = require('../util/browser');
const {OverscaledTileID} = require('./tile_id');
Expand Down
10 changes: 5 additions & 5 deletions src/source/raster_tile_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const util = require('../util/util');
const ajax = require('../util/ajax');
const Evented = require('../util/evented');
const {Event, ErrorEvent, Evented} = require('../util/evented');
const loadTileJSON = require('./load_tilejson');
const normalizeURL = require('../util/mapbox').normalizeTileURL;
const TileBounds = require('./tile_bounds');
Expand Down Expand Up @@ -53,19 +53,19 @@ class RasterTileSource extends Evented implements Source {
}

load() {
this.fire('dataloading', {dataType: 'source'});
this.fire(new Event('dataloading', {dataType: 'source'}));
loadTileJSON(this._options, this.map._transformRequest, (err, tileJSON) => {
if (err) {
this.fire('error', err);
this.fire(new ErrorEvent(err));
} else if (tileJSON) {
util.extend(this, tileJSON);
if (tileJSON.bounds) this.tileBounds = new TileBounds(tileJSON.bounds, this.minzoom, this.maxzoom);

// `content` is included here to prevent a race condition where `Style#_updateSources` is called
// before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
// ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
this.fire('data', {dataType: 'source', sourceDataType: 'metadata'});
this.fire('data', {dataType: 'source', sourceDataType: 'content'});
this.fire(new Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
this.fire(new Event('data', {dataType: 'source', sourceDataType: 'content'}));
}
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/source/rtl_text_plugin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
const Evented = require('../util/evented');

const {Event, Evented} = require('../util/evented');

let pluginRequested = false;
let pluginURL = null;
Expand Down Expand Up @@ -32,7 +33,7 @@ module.exports.setRTLTextPlugin = function(url: string, callback: ErrorCallback)
pluginRequested = true;
pluginURL = url;
module.exports.errorCallback = callback;
module.exports.evented.fire('pluginAvailable', { pluginURL: pluginURL, errorCallback: callback });
module.exports.evented.fire(new Event('pluginAvailable', { pluginURL: pluginURL, errorCallback: callback }));
};

module.exports.applyArabicShaping = (null: ?Function);
Expand Down
4 changes: 2 additions & 2 deletions src/source/source.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const util = require('../util/util');

import type Dispatcher from '../util/dispatcher';
import type Evented from '../util/evented';
import type {Event, Evented} from '../util/evented';
import type Map from '../ui/map';
import type Tile from './tile';
import type {OverscaledTileID} from './tile_id';
Expand Down Expand Up @@ -56,7 +56,7 @@ export interface Source {

hasTransition(): boolean;

fire(type: string, data: Object): mixed;
fire(event: Event): mixed;

+onAdd?: (map: Map) => void;
+onRemove?: (map: Map) => void;
Expand Down
8 changes: 4 additions & 4 deletions src/source/source_cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const createSource = require('./source').create;
const Tile = require('./tile');
const Evented = require('../util/evented');
const {Event, ErrorEvent, Evented} = require('../util/evented');
const Cache = require('../util/lru_cache');
const Coordinate = require('../geo/coordinate');
const util = require('../util/util');
Expand Down Expand Up @@ -235,7 +235,7 @@ class SourceCache extends Evented {
_tileLoaded(tile: Tile, id: string | number, previousState: TileState, err: ?Error) {
if (err) {
tile.state = 'errored';
if (err.status !== 404) this._source.fire('error', {tile: tile, error: err});
if (err.status !== 404) this._source.fire(new ErrorEvent(err, {tile}));
// continue to try loading parent/children tiles if a tile doesn't exist (404)
else this.update(this.transform);
return;
Expand All @@ -245,7 +245,7 @@ class SourceCache extends Evented {
if (previousState === 'expired') tile.refreshedUponExpiration = true;
this._setTileReloadTimer(id, tile);
if (this.getSource().type === 'raster-dem' && tile.dem) this._backfillDEM(tile);
this._source.fire('data', {dataType: 'source', tile: tile, coord: tile.tileID});
this._source.fire(new Event('data', {dataType: 'source', tile: tile, coord: tile.tileID}));

// HACK this is necessary to fix https://github.com/mapbox/mapbox-gl-js/issues/2986
if (this.map) this.map.painter.tileExtentVAO.vao = null;
Expand Down Expand Up @@ -589,7 +589,7 @@ class SourceCache extends Evented {

tile.uses++;
this._tiles[tileID.key] = tile;
if (!cached) this._source.fire('dataloading', {tile: tile, coord: tile.tileID, dataType: 'source'});
if (!cached) this._source.fire(new Event('dataloading', {tile: tile, coord: tile.tileID, dataType: 'source'}));

return tile;
}
Expand Down
10 changes: 5 additions & 5 deletions src/source/vector_tile_source.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

const Evented = require('../util/evented');
const {Event, ErrorEvent, Evented} = require('../util/evented');
const util = require('../util/util');
const loadTileJSON = require('./load_tilejson');
const normalizeURL = require('../util/mapbox').normalizeTileURL;
Expand Down Expand Up @@ -60,20 +60,20 @@ class VectorTileSource extends Evented implements Source {
}

load() {
this.fire('dataloading', {dataType: 'source'});
this.fire(new Event('dataloading', {dataType: 'source'}));

loadTileJSON(this._options, this.map._transformRequest, (err, tileJSON) => {
if (err) {
this.fire('error', err);
this.fire(new ErrorEvent(err));
} else if (tileJSON) {
util.extend(this, tileJSON);
if (tileJSON.bounds) this.tileBounds = new TileBounds(tileJSON.bounds, this.minzoom, this.maxzoom);

// `content` is included here to prevent a race condition where `Style#_updateSources` is called
// before the TileJSON arrives. this makes sure the tiles needed are loaded once TileJSON arrives
// ref: https://github.com/mapbox/mapbox-gl-js/pull/4347#discussion_r104418088
this.fire('data', {dataType: 'source', sourceDataType: 'metadata'});
this.fire('data', {dataType: 'source', sourceDataType: 'content'});
this.fire(new Event('data', {dataType: 'source', sourceDataType: 'metadata'}));
this.fire(new Event('data', {dataType: 'source', sourceDataType: 'content'}));
}
});
}
Expand Down
Loading