diff --git a/docs-users/requirements.txt b/docs-users/requirements.txt index f1bc6509d..6052f3fd7 100644 --- a/docs-users/requirements.txt +++ b/docs-users/requirements.txt @@ -1,5 +1,5 @@ # Force rtfd to use a recent version of mkdocs mkdocs==1.6.1 -pymdown-extensions==10.12 +pymdown-extensions==10.13 mkdocs-material==9.5.48 mkdocs-static-i18n==1.2.3 diff --git a/docs/requirements.txt b/docs/requirements.txt index f1bc6509d..6052f3fd7 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ # Force rtfd to use a recent version of mkdocs mkdocs==1.6.1 -pymdown-extensions==10.12 +pymdown-extensions==10.13 mkdocs-material==9.5.48 mkdocs-static-i18n==1.2.3 diff --git a/pyproject.toml b/pyproject.toml index cf36d0a74..b380ab0c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,14 +43,14 @@ dependencies = [ [project.optional-dependencies] dev = [ - "hatch==1.13.0", + "hatch==1.14.0", "ruff==0.8.4", "djlint==1.36.3", "mkdocs==1.6.1", "mkdocs-material==9.5.48", "mkdocs-static-i18n==1.2.3", "vermin==1.6.0", - "pymdown-extensions==10.12", + "pymdown-extensions==10.13", "isort==5.13.2", ] test = [ @@ -61,7 +61,7 @@ test = [ "pytest-playwright==0.6.2", "pytest-rerunfailures==15.0", "pytest-xdist>=3.5.0,<4", - "moto[s3]==5.0.21" + "moto[s3]==5.0.24" ] docker = [ "uwsgi==2.0.28", diff --git a/umap/static/umap/js/modules/drop.js b/umap/static/umap/js/modules/drop.js new file mode 100644 index 000000000..a757a6f05 --- /dev/null +++ b/umap/static/umap/js/modules/drop.js @@ -0,0 +1,55 @@ +export default class DropControl { + constructor(umap, leafletMap, dropzone) { + this._umap = umap + this._leafletMap = leafletMap + this.dropzone = dropzone + } + + enable() { + this.controller = new AbortController() + this.dropzone.addEventListener('dragenter', (e) => this.dragenter(e), { + signal: this.controller.signal, + }) + this.dropzone.addEventListener('dragover', (e) => this.dragover(e), { + signal: this.controller.signal, + }) + this.dropzone.addEventListener('drop', (e) => this.drop(e), { + signal: this.controller.signal, + }) + this.dropzone.addEventListener('dragleave', (e) => this.dragleave(e), { + signal: this.controller.signal, + }) + } + + disable() { + this.controller.abort() + } + + dragenter(event) { + event.stopPropagation() + event.preventDefault() + this._leafletMap.scrollWheelZoom.disable() + this.dropzone.classList.add('umap-dragover') + } + + dragover(event) { + event.stopPropagation() + event.preventDefault() + } + + drop(event) { + this._leafletMap.scrollWheelZoom.enable() + this.dropzone.classList.remove('umap-dragover') + event.stopPropagation() + event.preventDefault() + const importer = this._umap.importer + importer.build() + importer.files = event.dataTransfer.files + importer.submit() + } + + dragleave() { + this._leafletMap.scrollWheelZoom.enable() + this.dropzone.classList.remove('umap-dragover') + } +} diff --git a/umap/static/umap/js/modules/importer.js b/umap/static/umap/js/modules/importer.js index 9d1d6180f..268b1d15e 100644 --- a/umap/static/umap/js/modules/importer.js +++ b/umap/static/umap/js/modules/importer.js @@ -124,6 +124,11 @@ export default class Importer extends Utils.WithTemplate { return this.qs('[type=file]').files } + set files(files) { + this.qs('[type=file]').files = files + this.onFileChange() + } + get raw() { return this.qs('textarea').value } @@ -213,11 +218,11 @@ export default class Importer extends Utils.WithTemplate { this.qs('[name=submit').toggleAttribute('disabled', !this.canSubmit()) } - onFileChange(e) { + onFileChange() { let type = '' let newType - for (const file of e.target.files) { - newType = U.Utils.detectFileType(file) + for (const file of this.files) { + newType = Utils.detectFileType(file) if (!type && newType) type = newType if (type && newType !== type) { type = '' diff --git a/umap/static/umap/js/modules/rendering/map.js b/umap/static/umap/js/modules/rendering/map.js index ae92c6845..b969c5ed8 100644 --- a/umap/static/umap/js/modules/rendering/map.js +++ b/umap/static/umap/js/modules/rendering/map.js @@ -12,6 +12,7 @@ import { translate } from '../i18n.js' import { uMapAlert as Alert } from '../../components/alerts/alert.js' import * as Utils from '../utils.js' import * as Icon from './icon.js' +import DropControl from '../drop.js' // Those options are not saved on the server, so they can live here // instead of in umap.properties @@ -96,7 +97,7 @@ const ControlsMixin = { this._controls.more = new U.MoreControls() this._controls.scale = L.control.scale() this._controls.permanentCredit = new U.PermanentCreditsControl(this) - this._umap.drop = new U.DropControl(this) + this._umap.drop = new DropControl(this._umap, this, this._container) this._controls.tilelayers = new U.TileLayerControl(this) }, diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 4cdcc15cc..f402d81c4 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -337,52 +337,6 @@ U.DrawToolbar = L.Toolbar.Control.extend({ }, }) -U.DropControl = L.Class.extend({ - initialize: function (map) { - this.map = map - this.dropzone = map._container - }, - - enable: function () { - L.DomEvent.on(this.dropzone, 'dragenter', this.dragenter, this) - L.DomEvent.on(this.dropzone, 'dragover', this.dragover, this) - L.DomEvent.on(this.dropzone, 'drop', this.drop, this) - L.DomEvent.on(this.dropzone, 'dragleave', this.dragleave, this) - }, - - disable: function () { - L.DomEvent.off(this.dropzone, 'dragenter', this.dragenter, this) - L.DomEvent.off(this.dropzone, 'dragover', this.dragover, this) - L.DomEvent.off(this.dropzone, 'drop', this.drop, this) - L.DomEvent.off(this.dropzone, 'dragleave', this.dragleave, this) - }, - - dragenter: function (event) { - L.DomEvent.stop(event) - this.map.scrollWheelZoom.disable() - this.dropzone.classList.add('umap-dragover') - }, - - dragover: (event) => { - L.DomEvent.stop(event) - }, - - drop: function (event) { - this.map.scrollWheelZoom.enable() - this.dropzone.classList.remove('umap-dragover') - L.DomEvent.stop(event) - for (const file of event.dataTransfer.files) { - this.map._umap.processFileToImport(file) - } - this.map._umap.onceDataLoaded(this.map._umap.fitDataBounds) - }, - - dragleave: function () { - this.map.scrollWheelZoom.enable() - this.dropzone.classList.remove('umap-dragover') - }, -}) - U.EditControl = L.Control.extend({ options: { position: 'topright',