Skip to content

Commit

Permalink
Refactor events
Browse files Browse the repository at this point in the history
  • Loading branch information
stepankuzmin committed Jul 30, 2024
1 parent edf6ecf commit 969486a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 21 deletions.
34 changes: 18 additions & 16 deletions src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,28 @@ const featureTypes = {
};

export default function(ctx, api) {

api.modes = Constants.modes;

// API doesn't emit events by default
const silent = ctx.options.silent !== undefined ? !!ctx.options.silent : true;

api.getFeatureIdsAt = function(point) {
const features = featuresAt.click({ point }, null, ctx);
return features.map(feature => feature.properties.id);
};

api.getSelectedIds = function () {
api.getSelectedIds = function() {
return ctx.store.getSelectedIds();
};

api.getSelected = function () {
api.getSelected = function() {
return {
type: Constants.geojsonTypes.FEATURE_COLLECTION,
features: ctx.store.getSelectedIds().map(id => ctx.store.get(id)).map(feature => feature.toGeoJSON())
};
};

api.getSelectedPoints = function () {
api.getSelectedPoints = function() {
return {
type: Constants.geojsonTypes.FEATURE_COLLECTION,
features: ctx.store.getSelectedCoordinates().map(coordinate => ({
Expand Down Expand Up @@ -72,7 +74,7 @@ export default function(ctx, api) {
return newIds;
};

api.add = function (geojson) {
api.add = function(geojson) {
const featureCollection = JSON.parse(JSON.stringify(normalize(geojson)));

const ids = featureCollection.features.map((feature) => {
Expand All @@ -89,7 +91,7 @@ export default function(ctx, api) {
throw new Error(`Invalid geometry type: ${feature.geometry.type}.`);
}
const internalFeature = new Model(ctx, feature);
ctx.store.add(internalFeature);
ctx.store.add(internalFeature, { silent });
} else {
// If a feature of that id has already been created, and we are swapping it out ...
const internalFeature = ctx.store.get(feature.id);
Expand All @@ -110,7 +112,7 @@ export default function(ctx, api) {
};


api.get = function (id) {
api.get = function(id) {
const feature = ctx.store.get(id);
if (feature) {
return feature.toGeoJSON();
Expand All @@ -125,11 +127,11 @@ export default function(ctx, api) {
};

api.delete = function(featureIds) {
ctx.store.delete(featureIds, { silent: true });
ctx.store.delete(featureIds, { silent });
// If we were in direct select mode and our selected feature no longer exists
// (because it was deleted), we need to get out of that mode.
if (api.getMode() === Constants.modes.DIRECT_SELECT && !ctx.store.getSelectedIds().length) {
ctx.events.changeMode(Constants.modes.SIMPLE_SELECT, undefined, { silent: true });
ctx.events.changeMode(Constants.modes.SIMPLE_SELECT, undefined, { silent });
} else {
ctx.store.render();
}
Expand All @@ -138,11 +140,11 @@ export default function(ctx, api) {
};

api.deleteAll = function() {
ctx.store.delete(ctx.store.getAllIds(), { silent: true });
ctx.store.delete(ctx.store.getAllIds(), { silent });
// If we were in direct select mode, now our selected feature no longer exists,
// so escape that mode.
if (api.getMode() === Constants.modes.DIRECT_SELECT) {
ctx.events.changeMode(Constants.modes.SIMPLE_SELECT, undefined, { silent: true });
ctx.events.changeMode(Constants.modes.SIMPLE_SELECT, undefined, { silent });
} else {
ctx.store.render();
}
Expand All @@ -156,7 +158,7 @@ export default function(ctx, api) {
if (stringSetsAreEqual((modeOptions.featureIds || []), ctx.store.getSelectedIds())) return api;
// And if we are changing the selection within simple_select mode, just change the selection,
// instead of stopping and re-starting the mode
ctx.store.setSelected(modeOptions.featureIds, { silent: true });
ctx.store.setSelected(modeOptions.featureIds, { silent });
ctx.store.render();
return api;
}
Expand All @@ -166,7 +168,7 @@ export default function(ctx, api) {
return api;
}

ctx.events.changeMode(mode, modeOptions, { silent: true });
ctx.events.changeMode(mode, modeOptions, { silent });
return api;
};

Expand All @@ -175,17 +177,17 @@ export default function(ctx, api) {
};

api.trash = function() {
ctx.events.trash({ silent: true });
ctx.events.trash({ silent });
return api;
};

api.combineFeatures = function() {
ctx.events.combineFeatures({ silent: true });
ctx.events.combineFeatures({ silent });
return api;
};

api.uncombineFeatures = function() {
ctx.events.uncombineFeatures({ silent: true });
ctx.events.uncombineFeatures({ silent });
return api;
};

Expand Down
4 changes: 2 additions & 2 deletions src/modes/mode_interface_accessors.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ ModeInterface.prototype.deleteFeature = function(id, opts = {}) {
* @name this.addFeature
* @param {DrawFeature} feature - the feature to add
*/
ModeInterface.prototype.addFeature = function(feature) {
return this._ctx.store.add(feature);
ModeInterface.prototype.addFeature = function(feature, opts = {}) {
return this._ctx.store.add(feature, opts);
};

/**
Expand Down
11 changes: 10 additions & 1 deletion src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,22 @@ Store.prototype.getAllIds = function() {
/**
* Adds a feature to the store.
* @param {Object} feature
* @param {Object} [options]
* @param {Object} [options.silent] - If `true`, this invocation will not fire an event.
*
* @return {Store} this
*/
Store.prototype.add = function(feature) {
Store.prototype.add = function(feature, options = {}) {
this.featureChanged(feature.id);
this._features[feature.id] = feature;
this._featureIds.add(feature.id);

if (options.silent != null && options.silent === false) {
this.ctx.map.fire(Constants.events.CREATE, {
features: [this._features[feature.id].toGeoJSON()]
});
}

return this;
};

Expand Down
4 changes: 2 additions & 2 deletions test/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,11 @@ test('Draw.set', () => {
'Draw.add called with new collection');
assert.equal(deleteSpy.callCount, 1,
'Draw.delete called');
assert.deepEqual(deleteSpy.getCall(0).args, [[
assert.deepEqual(deleteSpy.getCall(0).args[0], [
pointId,
lineId,
polygonId
]], 'Draw.delete called with old features');
], 'Draw.delete called with old features');

// Then set to another that contains a feature
// with an already-used id
Expand Down
70 changes: 70 additions & 0 deletions test/interaction_events.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -982,3 +982,73 @@ test('ensure user interactions fire right events', async (t) => {
assert.deepEqual(flushDrawEvents(), [], 'no unexpected draw events');
});
});

test('ensure API fire right events', async () => {
const container = document.createElement('div');
document.body.appendChild(container);
const map = createMap({ container });
const fireSpy = spy(map, 'fire');
const afterNextRender = setupAfterNextRender(map);
const Draw = new MapboxDraw({ silent: false });

map.addControl(Draw);
await map.on('load');

document.body.removeChild(container);

function flushDrawEvents() {
const drawEvents = [];
for (let i = 0; i < fireSpy.callCount; i++) {
const eventName = fireSpy.getCall(i).args[0];
if (typeof eventName !== 'string' || eventName.indexOf('draw.') !== 0) continue;
// Ignore draw.render events for now
if (eventName === 'draw.render') continue;
// Ignore draw.actionable events for now
if (eventName === 'draw.actionable') continue;
drawEvents.push(eventName);
}
fireSpy.resetHistory();
return drawEvents;
}

Draw.add({
type: 'Feature',
id: 'point',
properties: {},
geometry: {
type: 'Point',
coordinates: [10, 10]
}
});

Draw.deleteAll();

await afterNextRender();

Draw.add({
type: 'Feature',
id: 'line',
properties: {},
geometry: {
type: 'LineString',
coordinates: [[10, 10], [20, 20]]
}
});

await afterNextRender();

Draw.changeMode('draw_point');
Draw.changeMode('draw_line_string');
Draw.changeMode('draw_polygon');
Draw.changeMode('simple_select');

await afterNextRender();

Draw.delete('line');

await afterNextRender();

assert.deepEqual(flushDrawEvents(), [
'draw.create', 'draw.delete', 'draw.create', 'draw.modechange', 'draw.modechange', 'draw.modechange', 'draw.modechange', 'draw.delete'
], 'no unexpected draw events');
});

0 comments on commit 969486a

Please sign in to comment.