Перейти до вмісту

MediaWiki:Common.js: відмінності між версіями

krai-feedback: мікроменю над виділенням тексту
(Віджет «Повідомити про правку» (krai-feedback))
(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();
        var f = overlay.querySelector('textarea[name="fragment"]');
       if (sel && f && !f.value) f.value = sel.slice(0, 1000);
        if (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; });
     }
     }
    btn.addEventListener("click", openModal);
   });
   });
});
});
/* === /krai-feedback === */
/* === /krai-feedback === */