From 17b6088a79356af715354d2cd2f76ebc418720ab Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 10 Aug 2017 07:10:13 -0600 Subject: [PATCH] Allow drag and drop interaction to be configured with a source --- externs/olx.js | 13 ++++++ src/ol/interaction/draganddrop.js | 10 +++++ test/spec/ol/interaction/draganddrop.test.js | 45 +++++++++++++++++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/externs/olx.js b/externs/olx.js index ce359f09ce..523909b31e 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -2710,6 +2710,7 @@ olx.interaction.DoubleClickZoomOptions.prototype.delta; /** * @typedef {{formatConstructors: (Array.|undefined), + * source: (ol.source.Vector|undefined), * projection: ol.ProjectionLike, * target: (Element|undefined)}} */ @@ -2724,6 +2725,18 @@ olx.interaction.DragAndDropOptions; olx.interaction.DragAndDropOptions.prototype.formatConstructors; +/** + * Optional vector source where features will be added. If a source is provided + * all existing features will be removed and new features will be added when + * they are dropped on the target. If you want to add features to a vector + * source without removing the existing features (append only), instead of + * providing the source option listen for the "addfeatures" event. + * @type {ol.source.Vector|undefined} + * @api + */ +olx.interaction.DragAndDropOptions.prototype.source; + + /** * Target projection. By default, the map's view's projection is used. * @type {ol.ProjectionLike} diff --git a/src/ol/interaction/draganddrop.js b/src/ol/interaction/draganddrop.js index 7d2d44be55..4476bd42b9 100644 --- a/src/ol/interaction/draganddrop.js +++ b/src/ol/interaction/draganddrop.js @@ -49,6 +49,12 @@ ol.interaction.DragAndDrop = function(opt_options) { */ this.dropListenKeys_ = null; + /** + * @private + * @type {ol.source.Vector} + */ + this.source_ = options.source || null; + /** * @private * @type {Element} @@ -122,6 +128,10 @@ ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, event) { break; } } + if (this.source_) { + this.source_.clear(); + this.source_.addFeatures(features); + } this.dispatchEvent( new ol.interaction.DragAndDrop.Event( ol.interaction.DragAndDrop.EventType_.ADD_FEATURES, file, diff --git a/test/spec/ol/interaction/draganddrop.test.js b/test/spec/ol/interaction/draganddrop.test.js index 7e08cea6ef..8a7e76704e 100644 --- a/test/spec/ol/interaction/draganddrop.test.js +++ b/test/spec/ol/interaction/draganddrop.test.js @@ -6,7 +6,7 @@ goog.require('ol.events.Event'); goog.require('ol.events.EventTarget'); goog.require('ol.format.GeoJSON'); goog.require('ol.interaction.DragAndDrop'); - +goog.require('ol.source.Vector'); where('FileReader').describe('ol.interaction.DragAndDrop', function() { var viewport, map, interaction; @@ -37,6 +37,14 @@ where('FileReader').describe('ol.interaction.DragAndDrop', function() { expect(interaction.formatConstructors_).to.have.length(1); }); + it('accepts a source option', function() { + var source = new ol.source.Vector(); + var drop = new ol.interaction.DragAndDrop({ + formatConstructors: [ol.format.GeoJSON], + source: source + }); + expect(drop.source_).to.equal(source); + }); }); describe('#setActive()', function() { @@ -128,6 +136,41 @@ where('FileReader').describe('ol.interaction.DragAndDrop', function() { expect(event.dataTransfer.dropEffect).to.be('copy'); expect(event.propagationStopped).to.be(true); }); + + it('adds dropped features to a source', function(done) { + var source = new ol.source.Vector(); + var drop = new ol.interaction.DragAndDrop({ + formatConstructors: [ol.format.GeoJSON], + source: source + }); + drop.setMap(map); + + drop.on('addfeatures', function(evt) { + var features = source.getFeatures(); + expect(features.length).to.be(1); + done(); + }); + + var event = new ol.events.Event(); + event.dataTransfer = {}; + event.type = 'dragenter'; + viewport.dispatchEvent(event); + event.type = 'dragover'; + viewport.dispatchEvent(event); + event.type = 'drop'; + event.dataTransfer.files = { + length: 1, + item: function() { + return JSON.stringify({ + type: 'FeatureCollection', + features: [{type: 'Feature', id: '1'}] + }); + } + }; + viewport.dispatchEvent(event); + expect(event.dataTransfer.dropEffect).to.be('copy'); + expect(event.propagationStopped).to.be(true); + }); }); });