// „Gibt es schon?" — zeigt beim Anlegen eines Eintrags vorhandene Einträge mit // ähnlichem Titel an (AUSBAUSTUFEN.md 5.7). // // Agenten bekommen bei "remember" eine Rückfrage, wenn es schon einen // ähnlichen Eintrag gibt. Menschen im Formular bekommen denselben Hinweis, // nur ohne Sperre: Die Liste erscheint unter dem Titel, speichern lässt sich // trotzdem. Geprüft wird auf dem Server mit derselben Logik wie bei MCP // (internal/duplicates), damit beide Wege gleich urteilen. // // Gefragt wird erst, wenn eine Weile nicht getippt wurde (delay), nicht // bei jedem Buchstaben. Antworten, die zu spät für den aktuellen Titel // kommen, werden verworfen. (function () { "use strict"; var titleInput = document.querySelector("input[data-similar-url]"); var box = document.querySelector("[data-similar-list]"); if (!titleInput || !box) { return; } var list = box.querySelector("ul"); var slugField = document.querySelector("input[name=slug]"); var url = titleInput.getAttribute("data-similar-url"); // Die Adresse eines Eintrags: aus der Such-URL ".../entries/similar" wird // ".../e/". var entryBase = url.replace(/entries\/similar$/, "e/"); var delay = 400; // Millisekunden ohne Tippen, bevor gefragt wird var timeoutId = null; var lastQuery = ""; function show(candidates) { list.textContent = ""; candidates.forEach(function (k) { var li = document.createElement("li"); var a = document.createElement("a"); a.href = entryBase + encodeURIComponent(k.slug); a.target = "_blank"; a.rel = "noopener"; a.textContent = k.title; li.appendChild(a); // Die gemeinsamen Wörter zeigen, warum der Eintrag hier steht. // Ist es nur ein allgemeines Wort, sieht man sofort: anderes Thema. if (k.shared && k.shared.length) { var reason = document.createElement("span"); reason.className = "help"; reason.textContent = " — gemeinsam: " + k.shared.join(", "); li.appendChild(reason); } list.appendChild(li); }); box.hidden = candidates.length === 0; } function ask() { var t = titleInput.value.trim(); var s = slugField ? slugField.value.trim() : ""; var cacheKey = t + "\u0000" + s; if (cacheKey === lastQuery) { return; } lastQuery = cacheKey; if (t.length < 3) { show([]); return; } var address = url + "?title=" + encodeURIComponent(t) + "&slug=" + encodeURIComponent(s); fetch(address, { credentials: "same-origin", headers: { "Accept": "application/json" } }) .then(function (answer) { return answer.ok ? answer.json() : []; }) .then(function (candidates) { // Inzwischen weitergetippt? Dann gehört die Antwort zu einem // alten Titel. if (cacheKey === lastQuery) { show(candidates || []); } }) .catch(function () { /* nur ein Hinweis — ohne ihn geht es auch */ }); } function askLater() { clearTimeout(timeoutId); timeoutId = setTimeout(ask, delay); } titleInput.addEventListener("input", askLater); if (slugField) { slugField.addEventListener("input", askLater); } // Vorbelegter Titel (z.B. nach einem Fehler zurück im Formular). if (titleInput.value.trim() !== "") { ask(); } })();