diff --git a/umap/static/umap/js/modules/caption.js b/umap/static/umap/js/modules/caption.js
new file mode 100644
index 00000000..9ebe01ce
--- /dev/null
+++ b/umap/static/umap/js/modules/caption.js
@@ -0,0 +1,108 @@
+import { DomUtil } from '../../vendors/leaflet/leaflet-src.esm.js'
+import { translate } from './i18n.js'
+import * as Utils from './utils.js'
+
+export default class Caption {
+ constructor(map) {
+ this.map = map
+ }
+
+ open() {
+ const container = DomUtil.create('div', 'umap-caption')
+ DomUtil.createTitle(container, this.map.options.name, 'icon-caption')
+ this.map.permissions.addOwnerLink('h5', container)
+ if (this.map.options.description) {
+ const description = DomUtil.element({
+ tagName: 'div',
+ className: 'umap-map-description',
+ safeHTML: Utils.toHTML(this.map.options.description),
+ parent: container,
+ })
+ }
+ const datalayerContainer = DomUtil.create('div', 'datalayer-container', container)
+ this.map.eachDataLayer((datalayer) => this.addDataLayer(datalayer, datalayerContainer))
+ const creditsContainer = DomUtil.create('div', 'credits-container', container)
+ this.addCredits(creditsContainer)
+ this.map.panel.open({ content: container })
+ }
+
+ addDataLayer(datalayer, container) {
+ if (!datalayer.options.inCaption) return
+ const p = DomUtil.create('p', 'datalayer-legend', container),
+ legend = DomUtil.create('span', '', p),
+ headline = DomUtil.create('strong', '', p)
+ datalayer.onceLoaded(() => {
+ datalayer.renderLegend(legend)
+ if (datalayer.options.description) {
+ DomUtil.element({
+ tagName: 'span',
+ parent: p,
+ safeHTML: Utils.toHTML(datalayer.options.description),
+ })
+ }
+ })
+ datalayer.renderToolbox(headline)
+ DomUtil.add('span', '', headline, `${datalayer.options.name} `)
+ }
+
+ addCredits(container) {
+ const credits = DomUtil.createFieldset(container, translate('Credits'))
+ let title = DomUtil.add('h5', '', credits, translate('User content credits'))
+ if (this.map.options.shortCredit || this.map.options.longCredit) {
+ DomUtil.element({
+ tagName: 'p',
+ parent: credits,
+ safeHTML: Utils.toHTML(
+ this.map.options.longCredit || this.map.options.shortCredit
+ ),
+ })
+ }
+ if (this.map.options.licence) {
+ const licence = DomUtil.add(
+ 'p',
+ '',
+ credits,
+ `${translate('Map user content has been published under licence')} `
+ )
+ DomUtil.createLink(
+ '',
+ licence,
+ this.map.options.licence.name,
+ this.map.options.licence.url
+ )
+ } else {
+ DomUtil.add('p', '', credits, translate('No licence has been set'))
+ }
+ title = DomUtil.create('h5', '', credits)
+ title.textContent = translate('Map background credits')
+ const tilelayerCredit = DomUtil.create('p', '', credits)
+ DomUtil.element({
+ tagName: 'strong',
+ parent: tilelayerCredit,
+ textContent: `${this.map.selected_tilelayer.options.name} `,
+ })
+ DomUtil.element({
+ tagName: 'span',
+ parent: tilelayerCredit,
+ safeHTML: this.map.selected_tilelayer.getAttribution(),
+ })
+ const urls = {
+ leaflet: 'http://leafletjs.com',
+ django: 'https://www.djangoproject.com',
+ umap: 'https://umap-project.org/',
+ changelog: 'https://docs.umap-project.org/en/master/changelog/',
+ version: this.map.options.umap_version,
+ }
+ const creditHTML = translate(
+ `
+ Powered by Leaflet and
+ Django,
+ glued by uMap project
+ (version {version}).
+ `,
+ urls
+ )
+ DomUtil.element({ tagName: 'p', innerHTML: creditHTML, parent: credits })
+
+ }
+}
diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js
index 16742508..f665ef52 100644
--- a/umap/static/umap/js/modules/global.js
+++ b/umap/static/umap/js/modules/global.js
@@ -1,6 +1,7 @@
import URLs from './urls.js'
import Browser from './browser.js'
import Facets from './facets.js'
+import Caption from './caption.js'
import { Panel, EditPanel, FullPanel } from './panel.js'
import * as Utils from './utils.js'
import { SCHEMA } from './schema.js'
@@ -25,4 +26,5 @@ window.U = {
Utils,
SCHEMA,
Orderable,
+ Caption,
}
diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js
index 770bcda5..e019fb7b 100644
--- a/umap/static/umap/js/umap.controls.js
+++ b/umap/static/umap/js/umap.controls.js
@@ -530,7 +530,7 @@ U.CaptionControl = L.Control.Button.extend({
},
onClick: function () {
- this.map.displayCaption()
+ this.map.openCaption()
},
})
@@ -671,96 +671,6 @@ const ControlsMixin = {
'tilelayers',
],
- displayCaption: function () {
- const container = L.DomUtil.create('div', 'umap-caption')
- L.DomUtil.createTitle(container, this.options.name, 'icon-caption')
- this.permissions.addOwnerLink('h5', container)
- if (this.options.description) {
- const description = L.DomUtil.element({
- tagName: 'div',
- className: 'umap-map-description',
- safeHTML: U.Utils.toHTML(this.options.description),
- parent: container,
- })
- }
- const datalayerContainer = L.DomUtil.create('div', 'datalayer-container', container)
- this.eachVisibleDataLayer((datalayer) => {
- if (!datalayer.options.inCaption) return
- const p = L.DomUtil.create('p', 'datalayer-legend', datalayerContainer),
- legend = L.DomUtil.create('span', '', p),
- headline = L.DomUtil.create('strong', '', p)
- datalayer.onceLoaded(function () {
- datalayer.renderLegend(legend)
- if (datalayer.options.description) {
- L.DomUtil.element({
- tagName: 'span',
- parent: p,
- safeHTML: U.Utils.toHTML(datalayer.options.description),
- })
- }
- })
- datalayer.renderToolbox(headline)
- L.DomUtil.add('span', '', headline, `${datalayer.options.name} `)
- })
- const creditsContainer = L.DomUtil.create('div', 'credits-container', container),
- credits = L.DomUtil.createFieldset(creditsContainer, L._('Credits'))
- title = L.DomUtil.add('h5', '', credits, L._('User content credits'))
- if (this.options.shortCredit || this.options.longCredit) {
- L.DomUtil.element({
- tagName: 'p',
- parent: credits,
- safeHTML: U.Utils.toHTML(this.options.longCredit || this.options.shortCredit),
- })
- }
- if (this.options.licence) {
- const licence = L.DomUtil.add(
- 'p',
- '',
- credits,
- `${L._('Map user content has been published under licence')} `
- )
- L.DomUtil.createLink(
- '',
- licence,
- this.options.licence.name,
- this.options.licence.url
- )
- } else {
- L.DomUtil.add('p', '', credits, L._('No licence has been set'))
- }
- title = L.DomUtil.create('h5', '', credits)
- title.textContent = L._('Map background credits')
- const tilelayerCredit = L.DomUtil.create('p', '', credits)
- L.DomUtil.element({
- tagName: 'strong',
- parent: tilelayerCredit,
- textContent: `${this.selected_tilelayer.options.name} `,
- })
- L.DomUtil.element({
- tagName: 'span',
- parent: tilelayerCredit,
- safeHTML: this.selected_tilelayer.getAttribution(),
- })
- const urls = {
- leaflet: 'http://leafletjs.com',
- django: 'https://www.djangoproject.com',
- umap: 'http://wiki.openstreetmap.org/wiki/UMap',
- changelog: 'https://umap-project.readthedocs.io/en/master/changelog/',
- version: this.options.umap_version,
- }
- const creditHTML = L._(
- `
- Powered by Leaflet and
- Django,
- glued by uMap project
- (version {version}).
- `,
- urls
- )
- L.DomUtil.element({ tagName: 'p', innerHTML: creditHTML, parent: credits })
- this.panel.open({ content: container })
- },
-
renderEditToolbar: function () {
const container = L.DomUtil.create(
'div',
@@ -1077,7 +987,7 @@ U.AttributionControl = L.Control.Attribution.extend({
if (captionMenus) {
const link = L.DomUtil.add('a', '', container, ` — ${L._('About')}`)
L.DomEvent.on(link, 'click', L.DomEvent.stop)
- .on(link, 'click', this._map.displayCaption, this._map)
+ .on(link, 'click', this._map.openCaption, this._map)
.on(link, 'dblclick', L.DomEvent.stop)
}
if (window.top === window.self && captionMenus) {
diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js
index b37767a5..8bc9ac21 100644
--- a/umap/static/umap/js/umap.js
+++ b/umap/static/umap/js/umap.js
@@ -222,7 +222,7 @@ U.Map = L.Map.extend({
this.openBrowser('filters')
} else if (this.options.onLoadPanel === 'caption') {
this.panel.mode = 'condensed'
- this.displayCaption()
+ this.openCaption()
}
if (L.Util.queryString('edit')) {
if (this.hasEditMode()) this.enableEdit()
@@ -382,6 +382,7 @@ U.Map = L.Map.extend({
else this.scrollWheelZoom.disable()
this.browser = new U.Browser(this)
this.facets = new U.Facets(this)
+ this.caption = new U.Caption(this)
this.importer = new U.Importer(this)
this.drop = new U.DropControl(this)
this.share = new U.Share(this)
@@ -911,9 +912,11 @@ U.Map = L.Map.extend({
},
openBrowser: function (mode) {
- this.onceDatalayersLoaded(function () {
- this.browser.open(mode)
- })
+ this.onceDatalayersLoaded(() => this.browser.open(mode))
+ },
+
+ openCaption: function () {
+ this.onceDatalayersLoaded(() => this.caption.open())
},
eachDataLayer: function (method, context) {
@@ -1591,7 +1594,7 @@ U.Map = L.Map.extend({
'umap-about-link flat',
container,
L._('About'),
- this.displayCaption,
+ this.openCaption,
this
)
L.DomUtil.createButton(
@@ -1758,7 +1761,7 @@ U.Map = L.Map.extend({
items.push(
{
text: L._('About'),
- callback: this.displayCaption,
+ callback: this.openCaption,
},
{
text: this.help.displayLabel('SEARCH'),
diff --git a/umap/tests/base.py b/umap/tests/base.py
index 62f948eb..e1abba32 100644
--- a/umap/tests/base.py
+++ b/umap/tests/base.py
@@ -125,6 +125,7 @@ class DataLayerFactory(factory.django.DjangoModelFactory):
**kwargs["settings"],
}
data.setdefault("_umap_options", {})
+ kwargs["settings"]["name"] = kwargs["name"]
data["_umap_options"]["name"] = kwargs["name"]
kwargs["geojson"] = ContentFile(json.dumps(data), "foo.json")
return kwargs
diff --git a/umap/tests/integration/test_caption.py b/umap/tests/integration/test_caption.py
new file mode 100644
index 00000000..2936d65c
--- /dev/null
+++ b/umap/tests/integration/test_caption.py
@@ -0,0 +1,24 @@
+import pytest
+from playwright.sync_api import expect
+
+from ..base import DataLayerFactory
+
+pytestmark = pytest.mark.django_db
+
+
+def test_caption(live_server, page, map):
+ map.settings["properties"]["onLoadPanel"] = "caption"
+ map.save()
+ basic = DataLayerFactory(map=map, name="Basic layer")
+ non_loaded = DataLayerFactory(
+ map=map, name="Non loaded", settings={"displayOnLoad": False}
+ )
+ hidden = DataLayerFactory(map=map, name="Hidden", settings={"inCaption": False})
+ page.goto(f"{live_server.url}{map.get_absolute_url()}")
+ panel = page.locator(".umap-caption")
+ expect(panel).to_be_visible()
+ expect(panel.locator(".datalayer-legend").get_by_text(basic.name)).to_be_visible()
+ expect(
+ panel.locator(".datalayer-legend .off").get_by_text(non_loaded.name)
+ ).to_be_visible()
+ expect(panel.locator(".datalayer-legend").get_by_text(hidden.name)).to_be_hidden()
diff --git a/umap/tests/integration/test_map.py b/umap/tests/integration/test_map.py
index 87c673eb..5bbc128f 100644
--- a/umap/tests/integration/test_map.py
+++ b/umap/tests/integration/test_map.py
@@ -188,21 +188,6 @@ def test_remote_layer_should_not_be_used_as_datalayer_for_created_features(
expect(layers).to_have_count(2)
-def test_can_hide_datalayer_from_caption(openmap, live_server, datalayer, page):
- # Add another DataLayer
- other = DataLayerFactory(map=openmap, name="Hidden", settings={"inCaption": False})
- page.goto(f"{live_server.url}{openmap.get_absolute_url()}")
- toggle = page.get_by_text("About").first
- expect(toggle).to_be_visible()
- toggle.click()
- layers = page.locator(".umap-caption .datalayer-legend")
- expect(layers).to_have_count(1)
- found = page.locator(".panel.left.on").get_by_text(datalayer.name)
- expect(found).to_be_visible()
- hidden = page.locator(".panel.left.on").get_by_text(other.name)
- expect(hidden).to_be_hidden()
-
-
def test_minimap_on_load(map, live_server, datalayer, page):
page.goto(f"{live_server.url}{map.get_absolute_url()}")
expect(page.locator(".leaflet-control-minimap")).to_be_hidden()