Version 2026.5.19 — Drag popup épinglé
[code interpolé]
This commit is contained in:
@@ -5822,16 +5822,17 @@ function splitLieu(raw) {
|
||||
ville = null;
|
||||
adresse = parts[0];
|
||||
} else {
|
||||
ville = s.substring(0, idx).trim();
|
||||
adresse = s.substring(idx + 1).trim();
|
||||
// 2+ parties : ville = 1ère, adresse = 2e, on ignore le reste
|
||||
ville = parts[0];
|
||||
adresse = parts[1];
|
||||
}
|
||||
|
||||
// Capitaliser la 1ère lettre des mots de voie (Rue, Chemin, Route, Avenue,
|
||||
// Boulevard, Place, Quai, Impasse + abréviations Av., Ch., Rte, Bd)
|
||||
if (adresse) {
|
||||
adresse = adresse.replace(
|
||||
/\b(rue|chemin|route|avenue|boulevard|place|quai|impasse|ruelle|allée|allee|passage|sentier|av\.?|ch\.?|rte\.?|bd\.?)\b/gi,
|
||||
(match) => {
|
||||
// Conserver la casse existante si déjà majuscule, sinon capitaliser
|
||||
if (/^[A-ZÉÈÀÂÎÔÛÇ]/.test(match)) return match;
|
||||
return match.charAt(0).toUpperCase() + match.slice(1).toLowerCase();
|
||||
}
|
||||
@@ -6140,6 +6141,11 @@ let bulleState = {
|
||||
};
|
||||
|
||||
function showTooltip(e, iv, rowEl) {
|
||||
// v2026.5.19 : pendant qu'un popup épinglé est en cours de drag, on ignore
|
||||
// les mouseenter sur les cartes — sinon en survolant une carte on déclenche
|
||||
// l'ouverture d'un nouveau tooltip par-dessus ce qu'on est en train de bouger.
|
||||
if (state._popupDragging) return;
|
||||
|
||||
// v4.1.15 : si la bulle est épinglée sur une autre iv, on NE REMPLACE PAS
|
||||
// son contenu (l'user veut garder la fiche épinglée même en survolant
|
||||
// d'autres cartes).
|
||||
@@ -6216,7 +6222,8 @@ function hideTooltip(opts = {}) {
|
||||
state.currentTooltipIv = null;
|
||||
currentTooltipPos = null;
|
||||
tooltipPositionMode = null; // re-détecter à la prochaine ouverture
|
||||
}, 120);
|
||||
}, 1000); // v2026.5.17 : délai 1s au lieu de 120ms pour laisser le temps
|
||||
// à l'user d'atteindre le popup depuis la carte
|
||||
}
|
||||
|
||||
// v4.2 : détecte si l'utilisateur a une sélection de texte active dans la bulle.
|
||||
@@ -6350,9 +6357,51 @@ function positionTooltipAnchored(rowEl) {
|
||||
}
|
||||
if (y < 4) y = 4;
|
||||
|
||||
// v2026.5.17 : éviter le chevauchement avec les popups épinglés existants.
|
||||
// On teste la position candidate, et si elle chevauche un popup épinglé,
|
||||
// on essaie d'autres candidats (gauche de la carte, au-dessous, au-dessus).
|
||||
const tipW = tipRect.width || 320;
|
||||
const tipH = tipRect.height || 200;
|
||||
const pinnedRects = _getPinnedPopupsViewportRects();
|
||||
if (pinnedRects.length) {
|
||||
const candidates = [
|
||||
{ x, y, label: "right" },
|
||||
{ x: rowRect.left - tipW - pad, y: rowRect.top, label: "left" },
|
||||
{ x: rowRect.left, y: rowRect.bottom + pad, label: "below" },
|
||||
{ x: rowRect.left, y: rowRect.top - tipH - pad, label: "above" }
|
||||
];
|
||||
for (const c of candidates) {
|
||||
// Borne dans le viewport
|
||||
if (c.x < 4) c.x = 4;
|
||||
if (c.x + tipW > window.innerWidth - 8) c.x = window.innerWidth - tipW - 8;
|
||||
if (c.y < 4) c.y = 4;
|
||||
if (c.y + tipH > window.innerHeight - 8) c.y = window.innerHeight - tipH - 8;
|
||||
const testRect = { left: c.x, top: c.y, right: c.x + tipW, bottom: c.y + tipH };
|
||||
const overlaps = pinnedRects.some(pr => _rectsOverlap(testRect, pr));
|
||||
if (!overlaps) {
|
||||
x = c.x; y = c.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setTooltipViewportPosition(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* v2026.5.17 : retourne les rectangles (en coords viewport) de tous les popups
|
||||
* actuellement épinglés et visibles (non réduits). Utilisé pour anti-chevauchement.
|
||||
*/
|
||||
function _getPinnedPopupsViewportRects() {
|
||||
const rects = [];
|
||||
document.querySelectorAll(".pinned-popup").forEach(p => {
|
||||
if (p.classList.contains("pinned-popup-reduced")) return; // docké, pas à l'écran
|
||||
const r = p.getBoundingClientRect();
|
||||
if (r.width > 0 && r.height > 0) rects.push(r);
|
||||
});
|
||||
return rects;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// v4.3.0 : système de popups épinglés détachés
|
||||
// ============================================================================
|
||||
@@ -6397,19 +6446,15 @@ function _rectsOverlap(a, b) {
|
||||
function _findFreePopupPosition(rowEl, w, h) {
|
||||
const pad = 14;
|
||||
const rowRect = rowEl.getBoundingClientRect();
|
||||
const viewportW = window.innerWidth;
|
||||
const viewportH = window.innerHeight;
|
||||
// v2026.5.20 : utiliser la safe area (en dessous topbar, au-dessus dock)
|
||||
const safe = _getPopupSafeArea();
|
||||
|
||||
// 4 candidats, en coords viewport
|
||||
// 4 candidats d'abord, autour de la row source (en coords viewport)
|
||||
const candidates = [
|
||||
// Droite
|
||||
{ x: rowRect.right + pad, y: rowRect.top, name: "droite" },
|
||||
// Gauche
|
||||
{ x: rowRect.left - w - pad, y: rowRect.top, name: "gauche" },
|
||||
// Dessous
|
||||
{ x: rowRect.left, y: rowRect.bottom + pad, name: "dessous" },
|
||||
// Dessus
|
||||
{ x: rowRect.left, y: rowRect.top - h - pad, name: "dessus" }
|
||||
{ x: rowRect.right + pad, y: rowRect.top, name: "droite" },
|
||||
{ x: rowRect.left - w - pad, y: rowRect.top, name: "gauche" },
|
||||
{ x: rowRect.left, y: rowRect.bottom + pad, name: "dessous" },
|
||||
{ x: rowRect.left, y: rowRect.top - h - pad, name: "dessus" }
|
||||
];
|
||||
|
||||
// Pour chaque candidat, clamper dans le viewport (marge 8px) et convertir
|
||||
|
||||
Reference in New Issue
Block a user