MediaWiki:Common.js: Difference between revisions
MediaWiki interface page
More actions
No edit summary |
No edit summary |
||
| Line 358: | Line 358: | ||
var activeEl = null; | var activeEl = null; | ||
var pinned = false; | var pinned = false; | ||
var lastPoint = null; // {x,y} for | var lastPoint = null; // {x,y} for point positioning | ||
function qTipText(el) { | function qTipText(el) { | ||
| Line 380: | Line 380: | ||
// Minimal inline styling so it works even without CSS. | // Minimal inline styling so it works even without CSS. | ||
tipEl.style.position = "fixed"; | tipEl.style.position = "fixed"; | ||
tipEl.style.zIndex = "99999"; | tipEl.style.zIndex = "99999"; | ||
| Line 392: | Line 391: | ||
tipEl.style.lineHeight = "1.25"; | tipEl.style.lineHeight = "1.25"; | ||
tipEl.style.boxShadow = "0 8px 24px rgba(0,0,0,0.35)"; | tipEl.style.boxShadow = "0 8px 24px rgba(0,0,0,0.35)"; | ||
tipEl.style.pointerEvents = "none"; // toggled | tipEl.style.pointerEvents = "none"; // toggled when pinned | ||
tipInner = document.createElement("div"); | tipInner = document.createElement("div"); | ||
| Line 402: | Line 401: | ||
function suppressTitle(el) { | function suppressTitle(el) { | ||
if (!el) return; | if (!el) return; | ||
var t = el.getAttribute("title"); | var t = el.getAttribute("title"); | ||
| Line 429: | Line 427: | ||
var r = el.getBoundingClientRect(); | var r = el.getBoundingClientRect(); | ||
tipEl.style.left = "0px"; | tipEl.style.left = "0px"; | ||
tipEl.style.top = "0px"; | tipEl.style.top = "0px"; | ||
| Line 452: | Line 449: | ||
} | } | ||
// Position relative to a screen point ( | // Position relative to a screen point (preferred on touch + desktop hover) | ||
function positionTipPoint(clientX, clientY) { | function positionTipPoint(clientX, clientY) { | ||
if (!tipEl) return; | if (!tipEl) return; | ||
tipEl.style.left = "0px"; | tipEl.style.left = "0px"; | ||
tipEl.style.top = "0px"; | tipEl.style.top = "0px"; | ||
| Line 471: | Line 467: | ||
// Prefer ABOVE the finger/cursor | // Prefer ABOVE the finger/cursor | ||
var y = clientY - tr.height - gap; | var y = clientY - tr.height - gap; | ||
// If not enough room above, drop below | // If not enough room above, drop below | ||
if (y < pad) { | if (y < pad) { | ||
| Line 496: | Line 493: | ||
suppressTitle(el); | suppressTitle(el); | ||
// | // default positioning (can be overridden by point positioning) | ||
positionTip(el); | positionTip(el); | ||
} | } | ||
| Line 522: | Line 519: | ||
} | } | ||
// Hover in/out (desktop) | // Hover in/out (desktop) — position ABOVE cursor | ||
document.addEventListener( | document.addEventListener( | ||
"mouseover", | "mouseover", | ||
| Line 532: | Line 529: | ||
if (activeEl === el) return; | if (activeEl === el) return; | ||
show(el); | show(el); | ||
positionTipPoint(e.clientX, e.clientY); | |||
}, | |||
true | |||
); | |||
document.addEventListener( | |||
"mousemove", | |||
function (e) { | |||
if (pinned) return; | |||
if (!activeEl) return; | |||
var el = closestDef(e.target); | |||
if (!el || el !== activeEl) return; | |||
positionTipPoint(e.clientX, e.clientY); | |||
}, | }, | ||
true | true | ||
| Line 549: | Line 559: | ||
// Touch: pin tooltip and position ABOVE the finger press point. | // Touch: pin tooltip and position ABOVE the finger press point. | ||
document.addEventListener( | document.addEventListener( | ||
"pointerdown", | "pointerdown", | ||
| Line 558: | Line 567: | ||
if (e.pointerType !== "touch") return; | if (e.pointerType !== "touch") return; | ||
// If we have a | // If we have a link, let navigation happen. | ||
if (qLink(el)) return; | if (qLink(el)) return; | ||
| Line 568: | Line 577: | ||
positionTipPoint(e.clientX, e.clientY); | positionTipPoint(e.clientX, e.clientY); | ||
// Prevent | // Prevent follow-up click from toggling it off immediately. | ||
e.preventDefault(); | e.preventDefault(); | ||
e.stopPropagation(); | e.stopPropagation(); | ||
| Line 575: | Line 584: | ||
); | ); | ||
// | // Click behavior: | ||
// - If data-sv-def-link is set, navigate (future-ready). | // - If data-sv-def-link is set, navigate (future-ready). | ||
// - Otherwise toggle a pinned tooltip | // - Otherwise toggle a pinned tooltip. | ||
document.addEventListener( | document.addEventListener( | ||
"click", | "click", | ||
| Line 598: | Line 607: | ||
if (!txt) return; | if (!txt) return; | ||
e.preventDefault(); | e.preventDefault(); | ||
e.stopPropagation(); | e.stopPropagation(); | ||
| Line 610: | Line 618: | ||
show(el); | show(el); | ||
// For | // For mouse clicks, anchor to the click point (feels better than element-anchor) | ||
positionTipPoint(e.clientX, e.clientY); | |||
}, | }, | ||
true | true | ||
| Line 633: | Line 640: | ||
function () { | function () { | ||
if (tipEl && tipEl.style.display === "block") { | if (tipEl && tipEl.style.display === "block") { | ||
if ( | if (lastPoint) positionTipPoint(lastPoint.x, lastPoint.y); | ||
else if (activeEl) positionTip(activeEl); | else if (activeEl) positionTip(activeEl); | ||
} | } | ||
| Line 640: | Line 647: | ||
); | ); | ||
window.addEventListener( | window.addEventListener( | ||
"scroll", | "scroll", | ||
function () { | function () { | ||
if (tipEl && tipEl.style.display === "block") { | if (tipEl && tipEl.style.display === "block") { | ||
if ( | if (lastPoint) positionTipPoint(lastPoint.x, lastPoint.y); | ||
else if (activeEl) positionTip(activeEl); | else if (activeEl) positionTip(activeEl); | ||
} | } | ||
| Line 652: | Line 658: | ||
); | ); | ||
mw.hook("wikipage.content").add(function () { | mw.hook("wikipage.content").add(function () { | ||
// No-op: event delegation already covers new content. | // No-op: event delegation already covers new content. | ||
}); | }); | ||
})(window.mw); | })(window.mw); | ||