diff --git a/src/components/ProposeModal.astro b/src/components/ProposeModal.astro index d16eef1..3a3d2c9 100644 --- a/src/components/ProposeModal.astro +++ b/src/components/ProposeModal.astro @@ -103,6 +103,7 @@ const upsertLine = (text, key, value) => { const re = new RegExp(`^\\s*${esc(key)}\\s*:\\s*.*$`, "mi"); + // value vide => supprimer la ligne si elle existe if (!value) { if (!re.test(text)) return text; return ( @@ -113,8 +114,10 @@ ); } + // remplace si existe if (re.test(text)) return text.replace(re, `${key}: ${value}`); + // sinon append const sep = text && !text.endsWith("\n") ? "\n" : ""; return text + sep + `${key}: ${value}\n`; }; @@ -148,23 +151,47 @@ if (next === body) return; - const prev = u.toString(); u.searchParams.set("body", next); // garde-fou URL if (u.toString().length > URL_HARD_LIMIT) { // revert u.searchParams.set("body", body); - return; } }; + // ✅ Ouvre EN NOUVEL ONGLET sans jamais remplacer l’onglet courant + const openInNewTab = (url) => { + // 1) tente window.open + try { + const w = window.open(url, "_blank", "noopener,noreferrer"); + if (w) return true; + } catch {} + + // 2) fallback "anchor click" (souvent mieux toléré) + try { + const a = document.createElement("a"); + a.href = url; + a.target = "_blank"; + a.rel = "noopener noreferrer"; + a.style.display = "none"; + document.body.appendChild(a); + a.click(); + a.remove(); + return true; + } catch {} + + // 3) dernier recours: on ne quitte PAS la page + window.prompt("Popup bloquée. Copiez ce lien pour ouvrir le ticket :", url); + return false; + }; + const openWith = (url) => { pending = url; kind = ""; dlg.dataset.step = "1"; if (typeof dlg.showModal === "function") dlg.showModal(); - else window.open(url.toString(), "_blank", "noopener,noreferrer"); + else openInNewTab(url.toString()); }; // Intercepte UNIQUEMENT les liens marqués data-propose @@ -173,6 +200,7 @@ if (!a) return; e.preventDefault(); + e.stopPropagation(); const rawUrl = a.dataset.url || a.getAttribute("href") || ""; if (!rawUrl || rawUrl === "#") return; @@ -191,7 +219,7 @@ openWith(u); } catch { - window.open(rawUrl, "_blank", "noopener,noreferrer"); + openInNewTab(rawUrl); } }); @@ -232,14 +260,14 @@ const cat = btn.getAttribute("data-category") || ""; let body = pending.searchParams.get("body") || ""; body = upsertLine(body, "Category", cat); - pending.searchParams.set("body", body); const u = pending.toString(); dlg.close(); - const w = window.open(u, "_blank", "noopener,noreferrer"); - if (!w) window.location.href = u; + // ✅ ouvre en nouvel onglet, sans jamais remplacer l’onglet courant + openInNewTab(u); }); })(); + diff --git a/src/layouts/EditionLayout.astro b/src/layouts/EditionLayout.astro index bbd4421..a2ac6ba 100644 --- a/src/layouts/EditionLayout.astro +++ b/src/layouts/EditionLayout.astro @@ -76,6 +76,26 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? ""; history.replaceState(null, "", window.location.pathname + window.location.hash); } + // ✅ Hotfix compat citabilité : + // si l'URL pointe vers un ancien hash (#p-8-xxxxxxxx) qui n'existe plus, + // on retombe sur le paragraphe actuel du même index (#p-8-YYYYYYYY). + (function resolveLegacyParagraphHash() { + const h = window.location.hash || ""; + const m = h.match(/^#p-(\d+)-[0-9a-f]{8}$/i); + if (!m) return; + + const oldId = h.slice(1); + if (document.getElementById(oldId)) return; // l'ancre existe, rien à faire + + const idx = m[1]; + const prefix = `p-${idx}-`; + const replacement = document.querySelector(`[id^="${prefix}"]`); + if (!replacement) return; + + history.replaceState(null, "", `${window.location.pathname}#${replacement.id}`); + replacement.scrollIntoView({ block: "start" }); + })(); + const docTitle = document.body.dataset.docTitle || document.title; const docVersion = document.body.dataset.docVersion || ""; @@ -90,7 +110,7 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? ""; const quoteBlock = (s) => String(s || "") .split(/\r?\n/) - .map((l) => `> ${l}`.trimEnd()) + .map((l) => (`> ${l}`).trimEnd()) .join("\n"); function buildIssueURL(anchorId, fullText, excerpt) { @@ -128,7 +148,7 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? ""; `Texte actuel (extrait):`, quoteBlock(excerpt || ""), ``, - `Note: paragraphe long → extrait (texte complet copié au clic si possible).`, + `Note: paragraphe long → extrait (pour éviter une URL trop longue).`, ]; const footer = [ @@ -214,9 +234,6 @@ const GITEA_REPO = import.meta.env.PUBLIC_GITEA_REPO ?? ""; // la modal lit data-url en priorité (garde aussi href). propose.dataset.url = issueUrl; - // Option B : texte complet disponible au clic (presse-papier + upgrade) - propose.dataset.full = raw; - tools.appendChild(propose); }