2206
редагувань
Admin (обговорення | внесок) (Віджет «Повідомити про правку» (krai-feedback)) |
Admin (обговорення | внесок) (krai-feedback: мікроменю над виділенням тексту) |
||
| Рядок 368: | Рядок 368: | ||
var loadedAt = Math.floor(Date.now() / 1000); // ts фіксуємо на завантаженні (>3с завжди) | var loadedAt = Math.floor(Date.now() / 1000); // ts фіксуємо на завантаженні (>3с завжди) | ||
var overlay = null; | var overlay = null; | ||
var content = document.getElementById("mw-content-text") || document.body; | |||
var lastSelText = ""; | |||
// --- плаваюча кнопка (коли нічого не виділено) --- | |||
var btn = document.createElement("button"); | var btn = document.createElement("button"); | ||
btn.id = "krai-fb-btn"; | btn.id = "krai-fb-btn"; | ||
| Рядок 375: | Рядок 378: | ||
btn.textContent = "✏️ Повідомити про правку"; | btn.textContent = "✏️ Повідомити про правку"; | ||
document.body.appendChild(btn); | document.body.appendChild(btn); | ||
btn.addEventListener("click", function () { openModal(); }); | |||
// --- мікроменю над виділеним текстом --- | |||
var tip = document.createElement("button"); | |||
tip.id = "krai-fb-tip"; | |||
tip.type = "button"; | |||
tip.className = "krai-fb-tip"; | |||
tip.textContent = "✏️ Повідомити про правку"; | |||
tip.style.display = "none"; | |||
document.body.appendChild(tip); | |||
function selectionInContent(sel) { | |||
if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return false; | |||
return sel.anchorNode && content.contains(sel.anchorNode); | |||
} | |||
function hideTip() { tip.style.display = "none"; } | |||
function showTip() { | |||
var sel = window.getSelection(); | |||
var text = ((sel && sel.toString()) || "").trim(); | |||
if (!selectionInContent(sel) || text.length < 8) { hideTip(); return; } | |||
lastSelText = text.slice(0, 1000); | |||
var rect = sel.getRangeAt(0).getBoundingClientRect(); | |||
if (!rect || (!rect.width && !rect.height)) { hideTip(); return; } | |||
tip.style.display = "block"; | |||
var vw = document.documentElement.clientWidth; | |||
var top = rect.top + window.scrollY - tip.offsetHeight - 8; | |||
var left = rect.left + window.scrollX + (rect.width / 2) - (tip.offsetWidth / 2); | |||
left = Math.max(window.scrollX + 8, Math.min(left, window.scrollX + vw - tip.offsetWidth - 8)); | |||
if (top < window.scrollY + 4) top = rect.bottom + window.scrollY + 8; // немає місця зверху → знизу | |||
tip.style.top = top + "px"; | |||
tip.style.left = left + "px"; | |||
} | |||
document.addEventListener("mouseup", function () { setTimeout(showTip, 10); }); | |||
document.addEventListener("touchend", function () { setTimeout(showTip, 10); }); | |||
document.addEventListener("selectionchange", function () { | |||
var sel = window.getSelection(); | |||
if (!sel || sel.isCollapsed || !((sel.toString() || "").trim())) hideTip(); | |||
}); | |||
window.addEventListener("scroll", hideTip, true); | |||
window.addEventListener("resize", hideTip); | |||
tip.addEventListener("mousedown", function (e) { e.preventDefault(); }); // не втратити виділення | |||
tip.addEventListener("click", function (e) { | |||
e.preventDefault(); | |||
hideTip(); | |||
openModal(lastSelText); | |||
}); | |||
function buildModal() { | function buildModal() { | ||
| Рядок 412: | Рядок 464: | ||
} | } | ||
function openModal() { | function openModal(presetFragment) { | ||
if (!overlay) buildModal(); | if (!overlay) buildModal(); | ||
var sel = ((window.getSelection && window.getSelection().toString()) || "").trim(); | var f = overlay.querySelector('textarea[name="fragment"]'); | ||
if (sel | var sel = presetFragment || ((window.getSelection && window.getSelection().toString()) || "").trim(); | ||
if (sel && f && !f.value) f.value = sel.slice(0, 1000); | |||
overlay.classList.add("is-open"); | overlay.classList.add("is-open"); | ||
document.addEventListener("keydown", onEsc); | document.addEventListener("keydown", onEsc); | ||
| Рядок 476: | Рядок 526: | ||
.then(function () { submitBtn.disabled = false; }); | .then(function () { submitBtn.disabled = false; }); | ||
} | } | ||
}); | }); | ||
}); | }); | ||
/* === /krai-feedback === */ | /* === /krai-feedback === */ | ||