From 49db1f9aaa3b69d8fe3dccf27602caa205c5ae9e Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 5 Jul 2024 10:10:18 +0200 Subject: [PATCH] chore: move share to modules --- umap/static/umap/js/modules/formatter.js | 36 ++++- umap/static/umap/js/modules/global.js | 4 +- .../js/{umap.share.js => modules/share.js} | 151 +++++++----------- umap/templates/umap/js.html | 1 - 4 files changed, 94 insertions(+), 98 deletions(-) rename umap/static/umap/js/{umap.share.js => modules/share.js} (70%) diff --git a/umap/static/umap/js/modules/formatter.js b/umap/static/umap/js/modules/formatter.js index 7efea950..64ac5e2b 100644 --- a/umap/static/umap/js/modules/formatter.js +++ b/umap/static/umap/js/modules/formatter.js @@ -1,7 +1,41 @@ /* Uses globals for: csv2geojson, osmtogeojson, GeoRSSToGeoJSON (not available as ESM) */ import { translate } from './i18n.js' -export default class Formatter { +export const EXPORT_FORMATS = { + geojson: { + formatter: async (map) => JSON.stringify(map.toGeoJSON(), null, 2), + ext: '.geojson', + filetype: 'application/json', + }, + gpx: { + formatter: async (map) => await map.formatter.toGPX(map.toGeoJSON()), + ext: '.gpx', + filetype: 'application/gpx+xml', + }, + kml: { + formatter: async (map) => await map.formatter.toKML(map.toGeoJSON()), + ext: '.kml', + filetype: 'application/vnd.google-earth.kml+xml', + }, + csv: { + formatter: async (map) => { + const table = [] + map.eachFeature((feature) => { + const row = feature.toGeoJSON().properties + const center = feature.getCenter() + delete row._umap_options + row.Latitude = center.lat + row.Longitude = center.lng + table.push(row) + }) + return csv2geojson.dsv.csvFormat(table) + }, + ext: '.csv', + filetype: 'text/csv', + }, +} + +export class Formatter { async fromGPX(str) { const togeojson = await import('../../vendors/togeojson/togeojson.es.js') return togeojson.gpx(this.toDom(str)) diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js index f49786e3..11b62b2b 100644 --- a/umap/static/umap/js/modules/global.js +++ b/umap/static/umap/js/modules/global.js @@ -7,13 +7,14 @@ import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js' import Browser from './browser.js' import Caption from './caption.js' import Facets from './facets.js' -import Formatter from './formatter.js' +import { Formatter } from './formatter.js' import Help from './help.js' import Importer from './importer.js' import Orderable from './orderable.js' import { HTTPError, NOKError, Request, RequestError, ServerRequest } from './request.js' import Rules from './rules.js' import { SCHEMA } from './schema.js' +import Share from './share.js' import Slideshow from './slideshow.js' import { SyncEngine } from './sync/engine.js' import Dialog from './ui/dialog.js' @@ -50,6 +51,7 @@ window.U = { Rules, SCHEMA, ServerRequest, + Share, Slideshow, SyncEngine, Tooltip, diff --git a/umap/static/umap/js/umap.share.js b/umap/static/umap/js/modules/share.js similarity index 70% rename from umap/static/umap/js/umap.share.js rename to umap/static/umap/js/modules/share.js index 21207255..363066ae 100644 --- a/umap/static/umap/js/umap.share.js +++ b/umap/static/umap/js/modules/share.js @@ -1,43 +1,11 @@ -U.Share = L.Class.extend({ - EXPORT_TYPES: { - geojson: { - formatter: async (map) => JSON.stringify(map.toGeoJSON(), null, 2), - ext: '.geojson', - filetype: 'application/json', - }, - gpx: { - formatter: async (map) => await map.formatter.toGPX(map.toGeoJSON()), - ext: '.gpx', - filetype: 'application/gpx+xml', - }, - kml: { - formatter: async (map) => await map.formatter.toKML(map.toGeoJSON()), - ext: '.kml', - filetype: 'application/vnd.google-earth.kml+xml', - }, - csv: { - formatter: async (map) => { - const table = [] - map.eachFeature((feature) => { - const row = feature.toGeoJSON().properties - const center = feature.getCenter() - delete row._umap_options - row.Latitude = center.lat - row.Longitude = center.lng - table.push(row) - }) - return csv2geojson.dsv.csvFormat(table) - }, - ext: '.csv', - filetype: 'text/csv', - }, - }, +import { EXPORT_FORMATS } from './formatter.js' - initialize: function (map) { +export default class Share { + constructor(map) { this.map = map - }, + } - build: function () { + build() { this.container = L.DomUtil.create('div', '') this.title = L.DomUtil.createTitle( this.container, @@ -63,16 +31,10 @@ U.Share = L.Class.extend({ L.DomUtil.add('h4', '', this.container, L._('Download')) L.DomUtil.add('small', 'label', this.container, L._("Only visible layers' data")) - for (const key in this.EXPORT_TYPES) { - if (this.EXPORT_TYPES.hasOwnProperty(key)) { - L.DomUtil.createButton( - 'download-file', - this.container, - this.EXPORT_TYPES[key].name || key, - () => this.download(key), - this - ) - } + for (const format of Object.keys(EXPORT_FORMATS)) { + L.DomUtil.createButton('download-file', this.container, format, () => + this.download(format) + ) } L.DomUtil.create('div', 'vspace', this.container) L.DomUtil.add( @@ -135,7 +97,7 @@ U.Share = L.Class.extend({ for (let i = 0; i < this.map.HIDDABLE_CONTROLS.length; i++) { UIFields.push(`queryString.${this.map.HIDDABLE_CONTROLS[i]}Control`) } - const iframeExporter = new U.IframeExporter(this.map) + const iframeExporter = new IframeExporter(this.map) const buildIframeCode = () => { iframe.textContent = iframeExporter.build() exportUrl.value = window.location.protocol + iframeExporter.buildUrl() @@ -149,23 +111,23 @@ U.Share = L.Class.extend({ L._('Embed and link options') ) iframeOptions.appendChild(builder.build()) - }, + } - open: function () { + open() { if (!this.container) this.build() this.map.panel.open({ content: this.container }) - }, + } - format: async function (mode) { - const type = this.EXPORT_TYPES[mode] + async format(mode) { + const type = EXPORT_FORMATS[mode] const content = await type.formatter(this.map) let name = this.map.options.name || 'data' name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase() const filename = name + type.ext return { content, filetype: type.filetype, filename } - }, + } - download: async function (mode) { + async download(mode) { const { content, filetype, filename } = await this.format(mode) const blob = new Blob([content], { type: filetype }) window.URL = window.URL || window.webkitURL @@ -176,50 +138,49 @@ U.Share = L.Class.extend({ document.body.appendChild(el) el.click() document.body.removeChild(el) - }, -}) + } +} -U.IframeExporter = L.Evented.extend({ - options: { - includeFullScreenLink: true, - currentView: false, - keepCurrentDatalayers: false, - viewCurrentFeature: false, - }, - - queryString: { - scaleControl: false, - miniMap: false, - scrollWheelZoom: false, - zoomControl: true, - editMode: 'disabled', - moreControl: true, - searchControl: null, - tilelayersControl: null, - embedControl: null, - datalayersControl: true, - onLoadPanel: 'none', - captionBar: false, - captionMenus: true, - }, - - dimensions: { - width: '100%', - height: '300px', - }, - - initialize: function (map) { +class IframeExporter { + constructor(map) { this.map = map this.baseUrl = U.Utils.getBaseUrl() + this.options = { + includeFullScreenLink: true, + currentView: false, + keepCurrentDatalayers: false, + viewCurrentFeature: false, + } + + this.queryString = { + scaleControl: false, + miniMap: false, + scrollWheelZoom: false, + zoomControl: true, + editMode: 'disabled', + moreControl: true, + searchControl: null, + tilelayersControl: null, + embedControl: null, + datalayersControl: true, + onLoadPanel: 'none', + captionBar: false, + captionMenus: true, + } + + this.dimensions = { + width: '100%', + height: '300px', + } // Use map default, not generic default this.queryString.onLoadPanel = this.map.getOption('onLoadPanel') - }, + } - getMap: function () { + getMap() { return this.map - }, + } - buildUrl: function (options) { + buildUrl(options) { const datalayers = [] if (this.options.viewCurrentFeature && this.map.currentFeature) { this.queryString.feature = this.map.currentFeature.getSlug() @@ -239,9 +200,9 @@ U.IframeExporter = L.Evented.extend({ const currentView = this.options.currentView ? window.location.hash : '' const queryString = L.extend({}, this.queryString, options) return `${this.baseUrl}?${U.Utils.buildQueryString(queryString)}${currentView}` - }, + } - build: function () { + build() { const iframeUrl = this.buildUrl() let code = `` if (this.options.includeFullScreenLink) { @@ -249,5 +210,5 @@ U.IframeExporter = L.Evented.extend({ code += `

${L._('See full screen')}

` } return code - }, -}) + } +} diff --git a/umap/templates/umap/js.html b/umap/templates/umap/js.html index 7e2c0037..9659b547 100644 --- a/umap/templates/umap/js.html +++ b/umap/templates/umap/js.html @@ -52,6 +52,5 @@ -