// Dymki na kosmogramie — własne, zamiast natywnych z
(PRE-12/PRE-25).
//
// DLACZEGO NIE ZOSTAWIAMY NATYWNYCH. Rysunek niesie przy każdym obiekcie
// i każdej linii aspektu i to wystarczało, dopóki koło było statyczne. Po dodaniu
// powiększania na pełne okno dymki przestały się pokazywać — a niezależnie od tego,
// która reguła przeglądarki je tłumi, natywny dymek i tak jest tu kiepskim
// narzędziem: pojawia się po sekundzie zwłoki, nie da się go stylować, nie działa
// na dotyku i nie ma go czym wywołać z klawiatury.
//
// Sprawdzone w przeglądarce (1280×900, komplet 13 systemów): elementy z
// SĄ osiągalne kursorem — 19 z 20 trafień w hit-teście — więc nic ich nie zasłania
// i problem nie leży w geometrii ani w pointer-events.
//
// ZOSTAJE w rysunku: to nazwa dostępna dla czytników ekranu, a PDF składa
// się po stronie serwera, więc ta ścieżka jest nietknięta. Na czas najechania
// odpinamy go i wieszamy z powrotem po zejściu kursora — dzięki temu nigdy nie
// widać dwóch dymków naraz, gdyby przeglądarka jednak swój pokazała.
(function () {
'use strict';
var OFFSET = 14; // odsunięcie od kursora, żeby dymek nie siedział pod nim
var stash = null; // { owner, node } — odpięty do przywieszenia
function ready(fn) {
if (document.readyState !== 'loading') fn();
else document.addEventListener('DOMContentLoaded', fn);
}
ready(function () {
var wheels = document.querySelectorAll('svg.wheel');
if (!wheels.length) return;
var tip = document.createElement('div');
tip.className = 'wheel-tip';
tip.setAttribute('role', 'tooltip');
tip.hidden = true;
document.body.appendChild(tip);
function restore() {
if (!stash) return;
stash.owner.appendChild(stash.node);
stash = null;
}
function hide() {
tip.hidden = true;
restore();
}
// Element z własnym , licząc od celu zdarzenia w górę. Aspekty to
// cienkie linie, a glify siedzą w — oba trzymają jako dziecko.
function owner(el, root) {
while (el && el !== root) {
if (el.querySelector && el.querySelector(':scope > title')) return el;
el = el.parentNode;
}
return null;
}
function place(x, y) {
// Ustawiamy najpierw, potem mierzymy — inaczej nie znamy rozmiaru dymka.
tip.style.left = '0px';
tip.style.top = '0px';
var w = tip.offsetWidth, h = tip.offsetHeight;
var left = x + OFFSET, top = y + OFFSET;
if (left + w > window.innerWidth - 4) left = x - OFFSET - w; // odbij w lewo
if (top + h > window.innerHeight - 4) top = y - OFFSET - h; // odbij w górę
tip.style.left = Math.max(4, left) + 'px';
tip.style.top = Math.max(4, top) + 'px';
}
Array.prototype.forEach.call(wheels, function (svg) {
svg.addEventListener('mousemove', function (e) {
var el = owner(e.target, svg);
if (!el) { hide(); return; }
if (!stash || stash.owner !== el) {
restore();
var node = el.querySelector(':scope > title');
tip.textContent = node.textContent;
stash = { owner: el, node: node };
el.removeChild(node);
tip.hidden = false;
}
place(e.clientX, e.clientY);
});
svg.addEventListener('mouseleave', hide);
});
// Dymek nie może przeżyć przewinięcia ani powiększenia — zostałby wiszący
// w miejscu, w którym nic już nie ma.
window.addEventListener('scroll', hide, true);
window.addEventListener('resize', hide);
document.addEventListener('click', hide, true);
});
})();