diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css
index 7d2f1984..85fa2fbc 100644
--- a/umap/static/umap/base.css
+++ b/umap/static/umap/base.css
@@ -735,6 +735,7 @@ input:invalid {
.umap-alert input {
padding: 5px;
border-radius: 4px;
+ width: 100%;
}
/* *********** */
@@ -771,6 +772,20 @@ input:invalid {
border-width: 11px;
margin-left: calc(-50% + 21px);
}
+#umap-tooltip-container.tooltip-bottom:before {
+ top: -22px;
+ left: calc(50% - 11px);
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ border-top-color: rgba(30, 30, 30, 0.7);
+ border-width: 11px;
+ margin-left: calc(-50% + 21px);
+ transform: rotate(180deg);
+}
#umap-tooltip-container.tooltip.tooltip-left:after {
left: 100%;
top: 50%;
@@ -816,10 +831,22 @@ input:invalid {
color: #fff;
float: right;
padding-right: 10px;
+ width: 100px;
+ line-height: 1;
+ margin: .5rem;
+ background-color: #666;
+ font-size: .7rem;
}
#umap-alert-container .umap-close-icon {
background-position: -74px -55px;
}
+#umap-alert-container .umap-alert-actions {
+ display: flex;
+ margin: 1rem;
+}
+#umap-alert-container .umap-alert-actions .umap-action {
+ margin-bottom: 0;
+}
/* *********** */
diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js
index 5f6e0637..e8c89ba5 100644
--- a/umap/static/umap/js/umap.controls.js
+++ b/umap/static/umap/js/umap.controls.js
@@ -320,13 +320,28 @@ L.U.EditControl = L.Control.extend({
onAdd: function (map) {
const container = L.DomUtil.create('div', 'leaflet-control-edit-enable')
- L.DomUtil.createButton(
+ const enableEditing = L.DomUtil.createButton(
'',
container,
- `${L._('Enable editing')} (Ctrl+E)`,
+ L._('Enable editing'),
map.enableEdit,
map
)
+ L.DomEvent.on(
+ enableEditing,
+ 'mouseover',
+ function () {
+ map.ui.tooltip({
+ content: `${L._('Edit map')} (Ctrl+E)`,
+ anchor: enableEditing,
+ position: 'bottom',
+ delay: 750,
+ duration: 5000,
+ })
+ },
+ this
+ )
+
return container
},
})
@@ -864,22 +879,52 @@ L.U.Map.include({
'umap-main-edit-toolbox with-transition dark',
this._controlContainer
)
- const logo = L.DomUtil.create('div', 'logo', container)
+ const leftContainer = L.DomUtil.create('div', 'umap-left-edit-toolbox', container)
+ const rightContainer = L.DomUtil.create('div', 'umap-right-edit-toolbox', container)
+ const logo = L.DomUtil.create('div', 'logo', leftContainer)
L.DomUtil.createLink('', logo, 'uMap', '/', null, L._('Go to the homepage'))
const nameButton = L.DomUtil.createButton(
'map-name',
- container,
+ leftContainer,
'',
this.edit,
this
)
+ L.DomEvent.on(
+ nameButton,
+ 'mouseover',
+ function () {
+ this.ui.tooltip({
+ content: L._('Edit the title of the map'),
+ anchor: nameButton,
+ position: 'bottom',
+ delay: 500,
+ duration: 5000,
+ })
+ },
+ this
+ )
const shareStatusButton = L.DomUtil.createButton(
'share-status',
- container,
+ leftContainer,
'',
this.permissions.edit,
this.permissions
)
+ L.DomEvent.on(
+ shareStatusButton,
+ 'mouseover',
+ function () {
+ this.ui.tooltip({
+ content: L._('Update who can see and edit the map'),
+ anchor: shareStatusButton,
+ position: 'bottom',
+ delay: 500,
+ duration: 5000,
+ })
+ },
+ this
+ )
const update = () => {
const status = this.permissions.getShareStatusDisplay()
nameButton.textContent = this.getDisplayName()
@@ -897,39 +942,81 @@ L.U.Map.include({
L.DomEvent.on(shareStatusButton, 'click', this.permissions.edit, this.permissions)
}
this.on('postsync', L.bind(update, this))
- L.DomUtil.createButton(
- 'leaflet-control-edit-save button',
- container,
- `${L._('Save current edits')} (Ctrl+S)`,
- this.save,
- this
- )
- L.DomUtil.createButton(
+ if (this.options.user) {
+ L.DomUtil.createLink(
+ 'umap-user',
+ rightContainer,
+ L._(`My Dashboard ({username})`, { username: this.options.user.name }),
+ this.options.user.url
+ )
+ }
+ this.help.link(rightContainer, 'edit')
+ const controlEditCancel = L.DomUtil.createButton(
'leaflet-control-edit-cancel',
- container,
- `${L._('Cancel edits')} (Ctrl+Z)`,
+ rightContainer,
+ L._('Cancel edits'),
this.askForReset,
this
)
- L.DomUtil.createButton(
+ L.DomEvent.on(
+ controlEditCancel,
+ 'mouseover',
+ function () {
+ this.ui.tooltip({
+ content: `${L._('Cancel')} (Ctrl+Z)`,
+ anchor: controlEditCancel,
+ position: 'bottom',
+ delay: 500,
+ duration: 5000,
+ })
+ },
+ this
+ )
+ const controlEditDisable = L.DomUtil.createButton(
'leaflet-control-edit-disable',
- container,
- `${L._('Disable editing')} (Ctrl+E)`,
+ rightContainer,
+ L.DomUtil.add('span', '', null, L._('Disable editing')),
function (e) {
this.disableEdit(e)
this.ui.closePanel()
},
this
)
- this.help.link(container, 'edit')
- if (this.options.user) {
- L.DomUtil.createLink(
- 'umap-user',
- container,
- L._(`My Dashboard ({username})`, { username: this.options.user.name }),
- this.options.user.url
- )
- }
+ L.DomEvent.on(
+ controlEditDisable,
+ 'mouseover',
+ function () {
+ this.ui.tooltip({
+ content: `${L._('Disable editing')} (Ctrl+E)`,
+ anchor: controlEditDisable,
+ position: 'bottom',
+ delay: 500,
+ duration: 5000,
+ })
+ },
+ this
+ )
+ const controlEditSave = L.DomUtil.createButton(
+ 'leaflet-control-edit-save button',
+ rightContainer,
+ L.DomUtil.add('span', '', null, L._('Save current edits')),
+ this.save,
+ this
+ )
+ L.DomEvent.on(
+ controlEditSave,
+ 'mouseover',
+ function () {
+ this.ui.tooltip({
+ content: `${L._('Save')} (Ctrl+S)`,
+ anchor: controlEditSave,
+ position: 'bottom',
+ delay: 500,
+ duration: 5000,
+ })
+ },
+ this
+ )
},
renderShareBox: function () {
diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js
index 7141f183..5958598b 100644
--- a/umap/static/umap/js/umap.core.js
+++ b/umap/static/umap/js/umap.core.js
@@ -261,32 +261,31 @@ L.Util.hasVar = (value) => {
}
L.Util.copyToClipboard = function (textToCopy) {
- // https://stackoverflow.com/a/65996386
- // Navigator clipboard api needs a secure context (https)
- if (navigator.clipboard && window.isSecureContext) {
- navigator.clipboard.writeText(textToCopy)
- } else {
- // Use the 'out of viewport hidden text area' trick
- const textArea = document.createElement('textarea')
- textArea.value = textToCopy
+ // https://stackoverflow.com/a/65996386
+ // Navigator clipboard api needs a secure context (https)
+ if (navigator.clipboard && window.isSecureContext) {
+ navigator.clipboard.writeText(textToCopy)
+ } else {
+ // Use the 'out of viewport hidden text area' trick
+ const textArea = document.createElement('textarea')
+ textArea.value = textToCopy
- // Move textarea out of the viewport so it's not visible
- textArea.style.position = 'absolute'
- textArea.style.left = '-999999px'
+ // Move textarea out of the viewport so it's not visible
+ textArea.style.position = 'absolute'
+ textArea.style.left = '-999999px'
- document.body.prepend(textArea)
- textArea.select()
+ document.body.prepend(textArea)
+ textArea.select()
- try {
- document.execCommand('copy')
- } catch (error) {
- console.error(error)
- } finally {
- textArea.remove()
- }
- }
+ try {
+ document.execCommand('copy')
+ } catch (error) {
+ console.error(error)
+ } finally {
+ textArea.remove()
}
-
+ }
+}
L.DomUtil.add = (tagName, className, container, content) => {
const el = L.DomUtil.create(tagName, className, container)
@@ -317,9 +316,6 @@ L.DomUtil.createFieldset = (container, legend, options) => {
}
L.DomUtil.createButton = (className, container, content, callback, context) => {
- // TODO: actually switch to buttons’ elements.
- // const el = L.DomUtil.add('a', className, container, content)
- // el.href = '#'
const el = L.DomUtil.add('button', className, container, content)
el.type = 'button'
if (callback) {
diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js
index abe99542..c8e9133c 100644
--- a/umap/static/umap/js/umap.ui.js
+++ b/umap/static/umap/js/umap.ui.js
@@ -106,18 +106,19 @@ L.U.UI = L.Evented.extend({
L.DomUtil.add('div', '', this._alert, e.content)
if (e.actions) {
let action, el, input
+ const form = L.DomUtil.add('div', 'umap-alert-actions', this._alert)
for (let i = 0; i < e.actions.length; i++) {
action = e.actions[i]
if (action.input) {
input = L.DomUtil.element(
'input',
{ className: 'umap-alert-input', placeholder: action.input },
- this._alert
+ form
)
}
el = L.DomUtil.createButton(
- { className: 'umap-action' },
- this._alert,
+ 'umap-action',
+ form,
action.label,
action.callback,
action.callbackContext || this.map
@@ -133,20 +134,32 @@ L.U.UI = L.Evented.extend({
}
},
- tooltip: function (e) {
+ tooltip: function (opts) {
this.TOOLTIP_ID = Math.random()
const id = this.TOOLTIP_ID
- L.DomUtil.addClass(this.parent, 'umap-tooltip')
- if (e.anchor && e.position === 'top') this.anchorTooltipTop(e.anchor)
- else if (e.anchor && e.position === 'left') this.anchorTooltipLeft(e.anchor)
- else this.anchorTooltipAbsolute()
- this._tooltip.innerHTML = e.content
+ function showIt() {
+ if (opts.anchor && opts.position === 'top') {
+ this.anchorTooltipTop(opts.anchor)
+ } else if (opts.anchor && opts.position === 'left') {
+ this.anchorTooltipLeft(opts.anchor)
+ } else if (opts.anchor && opts.position === 'bottom') {
+ this.anchorTooltipBottom(opts.anchor)
+ } else {
+ this.anchorTooltipAbsolute()
+ }
+ L.DomUtil.addClass(this.parent, 'umap-tooltip')
+ this._tooltip.innerHTML = opts.content
+ }
function closeIt() {
this.closeTooltip(id)
}
- if (e.anchor) L.DomEvent.once(e.anchor, 'mouseout', closeIt, this)
- if (e.duration !== Infinity)
- window.setTimeout(L.bind(closeIt, this), e.duration || 3000)
+ window.setTimeout(L.bind(showIt, this), opts.delay || 0)
+ if (opts.anchor) {
+ L.DomEvent.once(opts.anchor, 'mouseout', closeIt, this)
+ }
+ if (opts.duration !== Infinity) {
+ window.setTimeout(L.bind(closeIt, this), opts.duration || 3000)
+ }
},
anchorTooltipAbsolute: function () {
@@ -168,6 +181,15 @@ L.U.UI = L.Evented.extend({
})
},
+ anchorTooltipBottom: function (el) {
+ this._tooltip.className = 'tooltip-bottom'
+ const coords = this.getPosition(el)
+ this.setTooltipPosition({
+ left: coords.left + 30,
+ bottom: this.getDocHeight() - coords.top - 76,
+ })
+ },
+
anchorTooltipLeft: function (el) {
this._tooltip.className = 'tooltip-left'
const coords = this.getPosition(el)
@@ -179,7 +201,9 @@ L.U.UI = L.Evented.extend({
closeTooltip: function (id) {
if (id && id !== this.TOOLTIP_ID) return
+ this._tooltip.className = ''
this._tooltip.innerHTML = ''
+ this.setTooltipPosition({})
L.DomUtil.removeClass(this.parent, 'umap-tooltip')
},
diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css
index 0b18ef2e..71d8c584 100644
--- a/umap/static/umap/map.css
+++ b/umap/static/umap/map.css
@@ -379,10 +379,6 @@ ul.photon-autocomplete {
.dark .umap-help-button {
background-image: url('./img/16-white.svg');
}
-.umap-help-link {
- float: right;
- margin-right: 20px;
-}
.umap-help-on .umap-help-box {
visibility: visible;
top: 100px;
@@ -423,27 +419,37 @@ ul.photon-autocomplete {
/* ********************************* */
/* Edit main toolbox */
/* ********************************* */
+.umap-main-edit-toolbox [type="button"] {
+ color: #fff;
+ font-size: 1.2em;
+ border: none;
+ background-color: #323737;
+ width: auto;
+ margin-bottom: 0;
+}
+.umap-main-edit-toolbox [type="button"]:hover {
+ text-decoration: underline;
+}
-.leaflet-container a.leaflet-control-edit-save,
-.leaflet-container a.leaflet-control-edit-cancel,
-.leaflet-container a.leaflet-control-edit-disable {
+.leaflet-container .umap-help-link {
+ font-size: 12px;
+}
+.leaflet-container .leaflet-control-edit-save,
+.leaflet-container .leaflet-control-edit-cancel,
+.leaflet-container .leaflet-control-edit-disable {
display: block;
border: none;
- font-size: 11px;
- margin-left: 10px;
- float: right;
+ font-size: 12px;
border-radius: 20px;
color: #f8f8f8;
- width: auto;
height: 36px;
line-height: 36px;
min-height: 36px;
padding: 0 20px;
- min-width: 100px;
}
-.leaflet-container a.leaflet-control-edit-disable:before,
-.leaflet-container a.leaflet-control-edit-save:before,
-.leaflet-container a.leaflet-control-edit-cancel:before {
+.leaflet-container .leaflet-control-edit-disable:before,
+.leaflet-container .leaflet-control-edit-save:before,
+.leaflet-container .leaflet-control-edit-cancel:before {
display: inline-block;
width: 24px;
height: 24px;
@@ -453,37 +459,37 @@ ul.photon-autocomplete {
vertical-align: middle;
content: ' ';
}
-.leaflet-container a.leaflet-control-edit-save:before {
+.leaflet-container .leaflet-control-edit-save:before {
background-position: -2px -25px;
}
-.leaflet-container a.leaflet-control-edit-disable:before {
+.leaflet-container .leaflet-control-edit-disable:before {
background-position: -26px -1px;
}
-.leaflet-container a.leaflet-control-edit-cancel,
-.leaflet-container a.leaflet-control-edit-disable {
+.leaflet-container .leaflet-control-edit-cancel,
+.leaflet-container .leaflet-control-edit-disable {
border: 1px solid #555;
}
-.leaflet-container a.leaflet-control-edit-save {
+.leaflet-container .leaflet-control-edit-save {
opacity: 0.5;
cursor: not-allowed;
background-color: #215d9c;
}
-.umap-is-dirty a.leaflet-control-edit-save {
+.umap-is-dirty .leaflet-control-edit-save {
opacity: 1;
cursor: pointer;
}
-.leaflet-container a.leaflet-control-edit-save,
-.leaflet-container a.leaflet-control-edit-cancel,
-.leaflet-container a.leaflet-control-edit-disable,
+.leaflet-container .leaflet-control-edit-save,
+.leaflet-container .leaflet-control-edit-cancel,
+.leaflet-container .leaflet-control-edit-disable,
.umap-edit-enabled .leaflet-control-edit-enable {
display: none;
}
-.umap-edit-enabled a.leaflet-control-edit-save,
-.umap-edit-enabled a.leaflet-control-edit-disable,
-.umap-edit-enabled .umap-is-dirty a.leaflet-control-edit-cancel {
+.umap-edit-enabled .leaflet-control-edit-save,
+.umap-edit-enabled .leaflet-control-edit-disable,
+.umap-edit-enabled .umap-is-dirty .leaflet-control-edit-cancel {
display: inline-block;
}
-.umap-is-dirty a.leaflet-control-edit-disable {
+.umap-is-dirty .leaflet-control-edit-disable {
display: none;
}
.umap-caption-bar {
@@ -506,7 +512,17 @@ ul.photon-autocomplete {
opacity: 0.98;
color: #fff;
display: flex;
+ justify-content: space-between;
}
+.umap-left-edit-toolbox,
+.umap-right-edit-toolbox {
+ display: flex;
+ column-gap: 10px;
+}
+.umap-right-edit-toolbox {
+ align-items: baseline;
+}
+
.umap-main-edit-toolbox .logo {
width: 39px;
height: 100%;
@@ -521,24 +537,21 @@ ul.photon-autocomplete {
vertical-align: middle;
text-indent: -9999px;
}
-.umap-main-edit-toolbox [type="button"] {
- color: #fff;
- font-size: 1.2em;
- border: none;
- background-color: #323737;
-}
-.umap-main-edit-toolbox [type="button"]:hover {
- text-decoration: underline;
-}
.umap-main-edit-toolbox .map-name {
display: inline-block;
- max-width: 200px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
- margin-right: 5px;
font-weight: bold;
+ text-align: left;
}
+.umap-main-edit-toolbox .share-status {
+ font-size: 1em;
+ font-style: italic;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
.map-name:after {
content: '\00a0';
padding-left: 3px;
@@ -548,9 +561,6 @@ ul.photon-autocomplete {
.umap-is-dirty .map-name:after {
content: '*';
}
-.umap-main-edit-toolbox .share-status {
- margin: 0 20px;
-}
.umap-edit-enabled .umap-main-edit-toolbox {
top: 0;
}
@@ -1532,14 +1542,11 @@ a.add-datalayer:hover,
@media all and (max-width: 980px) {
- .leaflet-container a.leaflet-control-edit-save,
- .leaflet-container a.leaflet-control-edit-disable,
- .leaflet-container a.leaflet-control-edit-cancel {
- text-indent: calc(100% - 10px);
- width: 35px;
- min-width: initial;
+ .leaflet-container .leaflet-control-edit-save span,
+ .leaflet-container .leaflet-control-edit-disable span,
+ .leaflet-container .leaflet-control-edit-cancel span {
+ display: none;
}
-
.umap-main-edit-toolbox .umap-help-button {
display: none;
}
@@ -1549,7 +1556,11 @@ a.add-datalayer:hover,
.umap-main-edit-toolbox .umap-user:after {
display: none;
}
-
+}
+@media all and (max-width: 640px) {
+ .umap-main-edit-toolbox .map-name {
+ max-width: 150px;
+ }
}
@media all and (max-width: 480px) {
diff --git a/umap/static/umap/test/_pre.js b/umap/static/umap/test/_pre.js
index dda0c79e..836a3c91 100644
--- a/umap/static/umap/test/_pre.js
+++ b/umap/static/umap/test/_pre.js
@@ -47,10 +47,10 @@ var enableEdit = function () {
happen.click(qs('div.leaflet-control-edit-enable a'))
}
var disableEdit = function () {
- happen.click(qs('a.leaflet-control-edit-disable'))
+ happen.click(qs('.leaflet-control-edit-disable'))
}
var clickSave = function () {
- happen.click(qs('a.leaflet-control-edit-save'))
+ happen.click(qs('.leaflet-control-edit-save'))
}
var clickCancel = function () {
var _confirm = window.confirm