diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css
index 6079a78b..ded44fc6 100644
--- a/umap/static/umap/base.css
+++ b/umap/static/umap/base.css
@@ -756,69 +756,6 @@ input[type=hidden].blur + [type="button"] {
}
-/* *********** */
-/* Tooltip */
-/* *********** */
-#umap-tooltip-container {
- line-height: 20px;
- padding: 5px 10px;
- width: auto;
- position: absolute;
- box-shadow: 0 1px 7px #999999;
- display: none;
- background-color: rgba(40, 40, 40, 0.8);
- color: #eeeeec;
- font-size: 0.8em;
- border-radius: 2px;
- z-index: 1011;
- font-weight: normal;
- max-width: 300px;
-}
-.umap-tooltip #umap-tooltip-container {
- display: block;
-}
-#umap-tooltip-container.tooltip-top:after {
- top: 100%;
- 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.8);
- 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;
- transform: rotate(180deg);
-}
-#umap-tooltip-container.tooltip.tooltip-left:after {
- left: 100%;
- top: 50%;
- border: solid transparent;
- content: " ";
- height: 0;
- width: 0;
- position: absolute;
- pointer-events: none;
- border-color: rgba(136, 183, 213, 0);
- border-left-color: #333;
- border-width: 11px;
- margin-top: -10px;
-}
-
-
/* *********** */
/* Various */
/* *********** */
diff --git a/umap/static/umap/css/tooltip.css b/umap/static/umap/css/tooltip.css
new file mode 100644
index 00000000..caa475eb
--- /dev/null
+++ b/umap/static/umap/css/tooltip.css
@@ -0,0 +1,59 @@
+#umap-tooltip-container {
+ line-height: 20px;
+ padding: 5px 10px;
+ width: auto;
+ position: absolute;
+ box-shadow: 0 1px 7px #999999;
+ display: none;
+ background-color: rgba(40, 40, 40, 0.8);
+ color: #eeeeec;
+ font-size: 0.8em;
+ border-radius: 2px;
+ z-index: 1011;
+ font-weight: normal;
+ max-width: 300px;
+}
+.umap-tooltip #umap-tooltip-container {
+ display: block;
+}
+#umap-tooltip-container.tooltip-top:after {
+ top: 100%;
+ 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.8);
+ 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;
+ transform: rotate(180deg);
+}
+#umap-tooltip-container.tooltip.tooltip-left:after {
+ left: 100%;
+ top: 50%;
+ border: solid transparent;
+ content: " ";
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ border-color: rgba(136, 183, 213, 0);
+ border-left-color: #333;
+ border-width: 11px;
+ margin-top: -10px;
+}
+
diff --git a/umap/static/umap/js/modules/global.js b/umap/static/umap/js/modules/global.js
index 83bc9b1f..924854f9 100644
--- a/umap/static/umap/js/modules/global.js
+++ b/umap/static/umap/js/modules/global.js
@@ -4,6 +4,7 @@ import Facets from './facets.js'
import Caption from './caption.js'
import { Panel, EditPanel, FullPanel } from './panel.js'
import Alert from './ui/alert.js'
+import Tooltip from './ui/tooltip.js'
import * as Utils from './utils.js'
import { SCHEMA } from './schema.js'
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
@@ -23,6 +24,7 @@ window.U = {
Facets,
Panel,
Alert,
+ Tooltip,
EditPanel,
FullPanel,
Utils,
diff --git a/umap/static/umap/js/modules/ui/tooltip.js b/umap/static/umap/js/modules/ui/tooltip.js
new file mode 100644
index 00000000..6573421d
--- /dev/null
+++ b/umap/static/umap/js/modules/ui/tooltip.js
@@ -0,0 +1,116 @@
+import { DomUtil, DomEvent } from '../../../vendors/leaflet/leaflet-src.esm.js'
+import { translate } from '../i18n.js'
+
+export default class Tooltip {
+ constructor(parent) {
+ this.parent = parent
+ this.container = DomUtil.create('div', 'with-transition', this.parent)
+ this.container.id = 'umap-tooltip-container'
+ DomEvent.disableClickPropagation(this.container)
+ DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu.
+ DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation)
+ DomEvent.on(this.container, 'MozMousePixelScroll', DomEvent.stopPropagation)
+ }
+
+ open(opts) {
+ function showIt() {
+ if (opts.anchor && opts.position === 'top') {
+ this.anchorTop(opts.anchor)
+ } else if (opts.anchor && opts.position === 'left') {
+ this.anchorLeft(opts.anchor)
+ } else if (opts.anchor && opts.position === 'bottom') {
+ this.anchorBottom(opts.anchor)
+ } else {
+ this.anchorAbsolute()
+ }
+ L.DomUtil.addClass(this.parent, 'umap-tooltip')
+ this.container.innerHTML = U.Utils.escapeHTML(opts.content)
+ }
+ this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
+ const id = this.TOOLTIP_ID
+ const closeIt = () => {
+ this.close(id)
+ }
+ if (opts.anchor) {
+ L.DomEvent.once(opts.anchor, 'mouseout', closeIt)
+ }
+ if (opts.duration !== Infinity) {
+ window.setTimeout(closeIt, opts.duration || 3000)
+ }
+ }
+
+ anchorAbsolute() {
+ this.container.className = ''
+ const left =
+ this.parent.offsetLeft +
+ this.parent.clientWidth / 2 -
+ this.container.clientWidth / 2,
+ top = this.parent.offsetTop + 75
+ this.setPosition({ top: top, left: left })
+ }
+
+ anchorTop(el) {
+ this.container.className = 'tooltip-top'
+ const coords = this.getPosition(el)
+ this.setPosition({
+ left: coords.left - 10,
+ bottom: this.getDocHeight() - coords.top + 11,
+ })
+ }
+
+ anchorBottom(el) {
+ this.container.className = 'tooltip-bottom'
+ const coords = this.getPosition(el)
+ this.setPosition({
+ left: coords.left,
+ top: coords.bottom + 11,
+ })
+ }
+
+ anchorLeft(el) {
+ this.container.className = 'tooltip-left'
+ const coords = this.getPosition(el)
+ this.setPosition({
+ top: coords.top,
+ right: document.documentElement.offsetWidth - coords.left + 11,
+ })
+ }
+
+ close(id) {
+ // Clear timetout even if a new tooltip has been added
+ // in the meantime. Eg. after a mouseout from the anchor.
+ window.clearTimeout(id)
+ if (id && id !== this.TOOLTIP_ID) return
+ this.container.className = ''
+ this.container.innerHTML = ''
+ this.setPosition({})
+ L.DomUtil.removeClass(this.parent, 'umap-tooltip')
+ }
+
+ getPosition(el) {
+ return el.getBoundingClientRect()
+ }
+
+ setPosition(coords) {
+ if (coords.left) this.container.style.left = `${coords.left}px`
+ else this.container.style.left = 'initial'
+ if (coords.right) this.container.style.right = `${coords.right}px`
+ else this.container.style.right = 'initial'
+ if (coords.top) this.container.style.top = `${coords.top}px`
+ else this.container.style.top = 'initial'
+ if (coords.bottom) this.container.style.bottom = `${coords.bottom}px`
+ else this.container.style.bottom = 'initial'
+ }
+
+ getDocHeight() {
+ const D = document
+ return Math.max(
+ D.body.scrollHeight,
+ D.documentElement.scrollHeight,
+ D.body.offsetHeight,
+ D.documentElement.offsetHeight,
+ D.body.clientHeight,
+ D.documentElement.clientHeight
+ )
+ }
+}
diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js
index f7f09711..4ae4ffbc 100644
--- a/umap/static/umap/js/umap.controls.js
+++ b/umap/static/umap/js/umap.controls.js
@@ -394,7 +394,7 @@ U.EditControl = L.Control.extend({
enableEditing,
'mouseover',
function () {
- map.ui.tooltip({
+ map.tooltip.open({
content: map.help.displayLabel('TOGGLE_EDIT'),
anchor: enableEditing,
position: 'bottom',
@@ -693,7 +693,7 @@ const ControlsMixin = {
nameButton,
'mouseover',
function () {
- this.ui.tooltip({
+ this.tooltip.open({
content: L._('Edit the title of the map'),
anchor: nameButton,
position: 'bottom',
@@ -714,7 +714,7 @@ const ControlsMixin = {
shareStatusButton,
'mouseover',
function () {
- this.ui.tooltip({
+ this.tooltip.open({
content: L._('Update who can see and edit the map'),
anchor: shareStatusButton,
position: 'bottom',
@@ -763,7 +763,7 @@ const ControlsMixin = {
controlEditCancel,
'mouseover',
function () {
- this.ui.tooltip({
+ this.tooltip.open({
content: this.help.displayLabel('CANCEL'),
anchor: controlEditCancel,
position: 'bottom',
@@ -784,7 +784,7 @@ const ControlsMixin = {
controlEditDisable,
'mouseover',
function () {
- this.ui.tooltip({
+ this.tooltip.open({
content: this.help.displayLabel('PREVIEW'),
anchor: controlEditDisable,
position: 'bottom',
@@ -805,7 +805,7 @@ const ControlsMixin = {
controlEditSave,
'mouseover',
function () {
- this.ui.tooltip({
+ this.tooltip.open({
content: this.help.displayLabel('SAVE'),
anchor: controlEditSave,
position: 'bottom',
@@ -1249,7 +1249,7 @@ U.Editable = L.Editable.extend({
L.Editable.prototype.initialize.call(this, map, options)
this.on('editable:drawing:click editable:drawing:move', this.drawingTooltip)
this.on('editable:drawing:end', (e) => {
- this.closeTooltip()
+ this.map.tooltip.close()
// Leaflet.Editable will delete the drawn shape if invalid
// (eg. line has only one drawn point)
// So let's check if the layer has no more shape
@@ -1313,7 +1313,7 @@ U.Editable = L.Editable.extend({
drawingTooltip: function (e) {
if (e.layer instanceof L.Marker && e.type == 'editable:drawing:start') {
- this.map.ui.tooltip({ content: L._('Click to add a marker') })
+ this.map.tooltip.open({ content: L._('Click to add a marker') })
}
if (!(e.layer instanceof L.Polyline)) {
// only continue with Polylines and Polygons
@@ -1356,7 +1356,7 @@ U.Editable = L.Editable.extend({
}
}
if (content) {
- this.map.ui.tooltip({ content: content })
+ this.map.tooltip.open({ content: content })
}
},
diff --git a/umap/static/umap/js/umap.features.js b/umap/static/umap/js/umap.features.js
index 3ab590b8..27c835e7 100644
--- a/umap/static/umap/js/umap.features.js
+++ b/umap/static/umap/js/umap.features.js
@@ -878,9 +878,9 @@ U.PathMixin = {
_onMouseOver: function () {
if (this.map.measureTools && this.map.measureTools.enabled()) {
- this.map.ui.tooltip({ content: this.getMeasure(), anchor: this })
+ this.map.tooltip.open({ content: this.getMeasure(), anchor: this })
} else if (this.map.editEnabled && !this.map.editedFeature) {
- this.map.ui.tooltip({ content: L._('Click to edit'), anchor: this })
+ this.map.tooltip.open({ content: L._('Click to edit'), anchor: this })
}
},
diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js
index c52ad146..4915dfb3 100644
--- a/umap/static/umap/js/umap.forms.js
+++ b/umap/static/umap/js/umap.forms.js
@@ -78,7 +78,7 @@ L.FormBuilder.Element.include({
info,
'mouseover',
function () {
- this.builder.map.ui.tooltip({
+ this.builder.map.tooltip.open({
anchor: info,
content: this.options.helpTooltip,
position: 'top',
diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js
index c8f3f3bb..5dda78d1 100644
--- a/umap/static/umap/js/umap.js
+++ b/umap/static/umap/js/umap.js
@@ -58,11 +58,11 @@ U.Map = L.Map.extend({
this.panel = new U.Panel(this)
this.alert = new U.Alert(this._controlContainer)
+ this.tooltip = new U.Tooltip(this._controlContainer)
if (this.hasEditMode()) {
this.editPanel = new U.EditPanel(this)
this.fullPanel = new U.FullPanel(this)
}
- this.ui = new U.UI(this._container)
L.DomEvent.on(document.body, 'dataloading', (e) => this.fire('dataloading', e))
L.DomEvent.on(document.body, 'dataload', (e) => this.fire('dataload', e))
this.server = new U.ServerRequest(this.alert)
diff --git a/umap/static/umap/js/umap.ui.js b/umap/static/umap/js/umap.ui.js
deleted file mode 100644
index 9e0a2f4e..00000000
--- a/umap/static/umap/js/umap.ui.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Modals
- */
-U.UI = L.Evented.extend({
- TOOLTIP_ID: null,
-
- initialize: function (parent) {
- this.parent = parent
- this.container = L.DomUtil.create('div', 'leaflet-ui-container', this.parent)
- L.DomEvent.disableClickPropagation(this.container)
- L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation) // Do not activate our custom context menu.
- L.DomEvent.on(this.container, 'wheel', L.DomEvent.stopPropagation)
- L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation)
- this._tooltip = L.DomUtil.create('div', '', this.container)
- this._tooltip.id = 'umap-tooltip-container'
- },
-
- tooltip: function (opts) {
- 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 = U.Utils.escapeHTML(opts.content)
- }
- this.TOOLTIP_ID = window.setTimeout(L.bind(showIt, this), opts.delay || 0)
- const id = this.TOOLTIP_ID
- function closeIt() {
- this.closeTooltip(id)
- }
- 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 () {
- this._tooltip.className = ''
- const left =
- this.parent.offsetLeft +
- this.parent.clientWidth / 2 -
- this._tooltip.clientWidth / 2,
- top = this.parent.offsetTop + 75
- this.setTooltipPosition({ top: top, left: left })
- },
-
- anchorTooltipTop: function (el) {
- this._tooltip.className = 'tooltip-top'
- const coords = this.getPosition(el)
- this.setTooltipPosition({
- left: coords.left - 10,
- bottom: this.getDocHeight() - coords.top + 11,
- })
- },
-
- anchorTooltipBottom: function (el) {
- this._tooltip.className = 'tooltip-bottom'
- const coords = this.getPosition(el)
- this.setTooltipPosition({
- left: coords.left,
- top: coords.bottom + 11,
- })
- },
-
- anchorTooltipLeft: function (el) {
- this._tooltip.className = 'tooltip-left'
- const coords = this.getPosition(el)
- this.setTooltipPosition({
- top: coords.top,
- right: document.documentElement.offsetWidth - coords.left + 11,
- })
- },
-
- closeTooltip: function (id) {
- // Clear timetout even if a new tooltip has been added
- // in the meantime. Eg. after a mouseout from the anchor.
- window.clearTimeout(id)
- if (id && id !== this.TOOLTIP_ID) return
- this._tooltip.className = ''
- this._tooltip.innerHTML = ''
- this.setTooltipPosition({})
- L.DomUtil.removeClass(this.parent, 'umap-tooltip')
- },
-
- getPosition: function (el) {
- return el.getBoundingClientRect()
- },
-
- setTooltipPosition: function (coords) {
- if (coords.left) this._tooltip.style.left = `${coords.left}px`
- else this._tooltip.style.left = 'initial'
- if (coords.right) this._tooltip.style.right = `${coords.right}px`
- else this._tooltip.style.right = 'initial'
- if (coords.top) this._tooltip.style.top = `${coords.top}px`
- else this._tooltip.style.top = 'initial'
- if (coords.bottom) this._tooltip.style.bottom = `${coords.bottom}px`
- else this._tooltip.style.bottom = 'initial'
- },
-
- getDocHeight: function () {
- const D = document
- return Math.max(
- D.body.scrollHeight,
- D.documentElement.scrollHeight,
- D.body.offsetHeight,
- D.documentElement.offsetHeight,
- D.body.clientHeight,
- D.documentElement.clientHeight
- )
- },
-})
diff --git a/umap/templates/umap/css.html b/umap/templates/umap/css.html
index f9faa516..4e12a22d 100644
--- a/umap/templates/umap/css.html
+++ b/umap/templates/umap/css.html
@@ -30,4 +30,5 @@
+
diff --git a/umap/templates/umap/js.html b/umap/templates/umap/js.html
index 8c8c206e..966ed8d2 100644
--- a/umap/templates/umap/js.html
+++ b/umap/templates/umap/js.html
@@ -60,5 +60,4 @@
-