chore: move tooltip to a dedicated module
This commit is contained in:
parent
8ddc570e23
commit
2ed9bc65ee
11 changed files with 191 additions and 196 deletions
|
@ -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 */
|
||||
/* *********** */
|
||||
|
|
59
umap/static/umap/css/tooltip.css
Normal file
59
umap/static/umap/css/tooltip.css
Normal file
|
@ -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;
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
116
umap/static/umap/js/modules/ui/tooltip.js
Normal file
116
umap/static/umap/js/modules/ui/tooltip.js
Normal file
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
|
@ -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 })
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
},
|
||||
})
|
|
@ -30,4 +30,5 @@
|
|||
<link rel="stylesheet" href="{% static 'umap/map.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'umap/css/panel.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'umap/css/alert.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'umap/css/tooltip.css' %}" />
|
||||
<link rel="stylesheet" href="{% static 'umap/theme.css' %}" />
|
||||
|
|
|
@ -60,5 +60,4 @@
|
|||
<script src="{% static 'umap/js/umap.importer.js' %}" defer></script>
|
||||
<script src="{% static 'umap/js/umap.share.js' %}" defer></script>
|
||||
<script src="{% static 'umap/js/umap.js' %}" defer></script>
|
||||
<script src="{% static 'umap/js/umap.ui.js' %}" defer></script>
|
||||
<script src="{% static 'umap/js/components/fragment.js' %}" defer></script>
|
||||
|
|
Loading…
Reference in a new issue