Skip to content

Commit

Permalink
refactor shareBox into separate class
Browse files Browse the repository at this point in the history
download() and format() functions as well as dialog itself and
IFrameExporter helper moved into new file umap.share.js
  • Loading branch information
jschleic committed Dec 15, 2023
1 parent 670c56d commit 06ce5b4
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 269 deletions.
239 changes: 2 additions & 237 deletions umap/static/umap/js/umap.controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ L.Control.Embed = L.Control.extend({
'',
container,
L._('Share, download and embed this map'),
map.renderShareBox,
map
map.share.open,
map.share
)
L.DomEvent.on(shareButton, 'dblclick', L.DomEvent.stopPropagation)
return container
Expand Down Expand Up @@ -888,46 +888,6 @@ L.U.Map.include({
this.ui.openPanel({ data: { html: container }, actions: actions })
},

EXPORT_TYPES: {
geojson: {
formatter: function (map) {
return JSON.stringify(map.toGeoJSON(), null, 2)
},
ext: '.geojson',
filetype: 'application/json',
},
gpx: {
formatter: function (map) {
return togpx(map.toGeoJSON())
},
ext: '.gpx',
filetype: 'application/gpx+xml',
},
kml: {
formatter: function (map) {
return tokml(map.toGeoJSON())
},
ext: '.kml',
filetype: 'application/vnd.google-earth.kml+xml',
},
csv: {
formatter: function (map) {
const table = []
map.eachFeature((feature) => {
const row = feature.toGeoJSON()['properties'],
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',
},
},

renderEditToolbar: function () {
const container = L.DomUtil.create(
'div',
Expand Down Expand Up @@ -1075,130 +1035,6 @@ L.U.Map.include({
this
)
},

renderShareBox: function () {
const container = L.DomUtil.create('div', 'umap-share')
const title = L.DomUtil.create('h3', '', container)
title.textContent = L._('Share, download and embed this map')
if (this.options.shortUrl) {
L.DomUtil.createButton(
'button copy-button',
container,
L._('copy'),
() => navigator.clipboard.writeText(this.options.shortUrl),
this
)
L.DomUtil.add('h4', '', container, L._('Short URL'))
const shortUrlLabel = L.DomUtil.create('label', '', container)
shortUrlLabel.textContent = L._('Share this link to view the map')
const shortUrl = L.DomUtil.create('input', 'umap-short-url', container)
shortUrl.type = 'text'
shortUrl.value = this.options.shortUrl
L.DomUtil.create('hr', '', container)
}

L.DomUtil.add('h4', '', container, L._('Download data'))
const downloadLabel = L.DomUtil.create('label', '', container)
downloadLabel.textContent = L._('Choose the format of the data to export')
const exportCaveat = L.DomUtil.add(
'small',
'help-text',
container,
L._('Only visible features will be downloaded.')
)
console.log(this.EXPORT_TYPES)
const typeInput = L.DomUtil.create(
'div',
`button-bar by${Object.keys(this.EXPORT_TYPES).length}`,
container
)
let option
for (const key in this.EXPORT_TYPES) {
if (this.EXPORT_TYPES.hasOwnProperty(key)) {
L.DomUtil.createButton(
'button',
typeInput,
this.EXPORT_TYPES[key].name || key,
() => this.download(key),
this
)
}
}
L.DomUtil.create('hr', '', container)

L.DomUtil.add('h4', '', container, L._('Backup data'))
const backupLabel = L.DomUtil.create('label', '', container)
backupLabel.textContent = L._('Download all data and settings of the map')
const downloadUrl = L.Util.template(this.options.urls.map_download, {
map_id: this.options.umap_id,
})
const link = L.DomUtil.createLink(
'button',
container,
L._('Download full backup'),
downloadUrl
)
let name = this.options.name || 'data'
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
link.setAttribute('download', `${name}.umap`)
L.DomUtil.create('hr', '', container)

const embedTitle = L.DomUtil.add('h4', '', container, L._('Embed the map'))
const iframe = L.DomUtil.create('textarea', 'umap-share-iframe', container)
const urlTitle = L.DomUtil.add('h4', '', container, L._('Direct link'))
const shortUrlLabel = L.DomUtil.create('label', '', container)
shortUrlLabel.textContent = L._(
'Share this link to open a customized map view'
)
const exportUrl = L.DomUtil.create('input', 'umap-share-url', container)
exportUrl.type = 'text'
const UIFields = [
['dimensions.width', { handler: 'Input', label: L._('width') }],
['dimensions.height', { handler: 'Input', label: L._('height') }],
[
'options.includeFullScreenLink',
{ handler: 'Switch', label: L._('Include full screen link?') },
],
[
'options.currentView',
{ handler: 'Switch', label: L._('Current view instead of default map view?') },
],
[
'options.keepCurrentDatalayers',
{ handler: 'Switch', label: L._('Keep current visible layers') },
],
[
'options.viewCurrentFeature',
{ handler: 'Switch', label: L._('Open current feature on load') },
],
'queryString.moreControl',
'queryString.scrollWheelZoom',
'queryString.miniMap',
'queryString.scaleControl',
'queryString.onLoadPanel',
'queryString.captionBar',
'queryString.captionMenus',
]
for (let i = 0; i < this.HIDDABLE_CONTROLS.length; i++) {
UIFields.push(`queryString.${this.HIDDABLE_CONTROLS[i]}Control`)
}
const iframeExporter = new L.U.IframeExporter(this)
const buildIframeCode = () => {
iframe.innerHTML = iframeExporter.build()
exportUrl.value = window.location.protocol + iframeExporter.buildUrl()
}
buildIframeCode()
const builder = new L.U.FormBuilder(iframeExporter, UIFields, {
callback: buildIframeCode,
})
const iframeOptions = L.DomUtil.createFieldset(
container,
L._('Embed and link options')
)
iframeOptions.appendChild(builder.build())

this.ui.openPanel({ data: { html: container } })
},
})

L.U.TileLayerControl = L.Control.extend({
Expand Down Expand Up @@ -1488,77 +1324,6 @@ L.U.ContextMenu = L.Map.ContextMenu.extend({
},
})

L.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) {
this.map = map
this.baseUrl = L.Util.getBaseUrl()
// Use map default, not generic default
this.queryString.onLoadPanel = this.map.options.onLoadPanel
},

getMap: function () {
return this.map
},

buildUrl: function (options) {
const datalayers = []
if (this.options.viewCurrentFeature && this.map.currentFeature) {
this.queryString.feature = this.map.currentFeature.getSlug()
}
if (this.options.keepCurrentDatalayers) {
this.map.eachDataLayer((datalayer) => {
if (datalayer.isVisible() && datalayer.umap_id) {
datalayers.push(datalayer.umap_id)
}
})
this.queryString.datalayers = datalayers.join(',')
} else {
delete this.queryString.datalayers
}
const currentView = this.options.currentView ? window.location.hash : ''
const queryString = L.extend({}, this.queryString, options)
return `${this.baseUrl}?${L.Util.buildQueryString(queryString)}${currentView}`
},

build: function () {
const iframeUrl = this.buildUrl()
let code = `<iframe width="${this.dimensions.width}" height="${this.dimensions.height}" frameborder="0" allowfullscreen allow="geolocation" src="${iframeUrl}"></iframe>`
if (this.options.includeFullScreenLink) {
const fullUrl = this.buildUrl({ scrollWheelZoom: true })
code += `<p><a href="${fullUrl}">${L._('See full screen')}</a></p>`
}
return code
},
})

L.U.Editable = L.Editable.extend({
initialize: function (map, options) {
L.Editable.prototype.initialize.call(this, map, options)
Expand Down
31 changes: 5 additions & 26 deletions umap/static/umap/js/umap.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ L.U.Map.include({
}
this.initShortcuts()
this.onceDatalayersLoaded(function () {
if (L.Util.queryString('share')) this.renderShareBox()
if (L.Util.queryString('share')) this.share.open()
else if (this.options.onLoadPanel === 'databrowser') this.openBrowser()
else if (this.options.onLoadPanel === 'caption') this.displayCaption()
else if (
Expand Down Expand Up @@ -345,6 +345,7 @@ L.U.Map.include({
this.browser = new L.U.Browser(this)
this.importer = new L.U.Importer(this)
this.drop = new L.U.DropControl(this)
this.share = new L.U.Share(this)
this.renderControls()
},

Expand Down Expand Up @@ -844,28 +845,6 @@ L.U.Map.include({
})
},

format: function (mode) {
const type = this.EXPORT_TYPES[mode]
const content = type.formatter(this)
let name = this.options.name || 'data'
name = name.replace(/[^a-z0-9]/gi, '_').toLowerCase()
const filename = name + type.ext
return { content, filetype: type.filetype, filename }
},

download: function (mode) {
const { content, filetype, filename } = this.format(mode)
const blob = new Blob([content], { type: filetype })
window.URL = window.URL || window.webkitURL
const el = document.createElement('a')
el.download = filename
el.href = window.URL.createObjectURL(blob)
el.style.display = 'none'
document.body.appendChild(el)
el.click()
document.body.removeChild(el)
},

processFileToImport: function (file, layer, type) {
type = type || L.Util.detectFileType(file)
if (!type) {
Expand Down Expand Up @@ -1698,9 +1677,9 @@ L.U.Map.include({
L.DomUtil.createButton(
'button umap-download',
advancedButtons,
L._('Open download panel'),
this.renderShareBox,
this
L._('Open share & download panel'),
this.share.open,
this.share
)
},

Expand Down
Loading

0 comments on commit 06ce5b4

Please sign in to comment.