MediaWiki:Common.js: Difference between revisions
MediaWiki interface page
More actions
No edit summary |
No edit summary |
||
| Line 18: | Line 18: | ||
var SERIES_SEL = "[data-series]"; | var SERIES_SEL = "[data-series]"; | ||
// Popups (Phase 4.1 markup: span toggles + div popovers | // Popups (Phase 4.1 markup: span toggles + div popovers) | ||
var POPUP_WRAP_SEL = ".sv-tip, .sv-disclose"; | var POPUP_WRAP_SEL = ".sv-tip, .sv-disclose"; | ||
var POPUP_BTN_SEL = | var POPUP_BTN_SEL = | ||
".sv-tip-btn[data-sv-toggle='1'], .sv-disclose-btn[data-sv-toggle='1']"; | ".sv-tip-btn[data-sv-toggle='1'], .sv-disclose-btn[data-sv-toggle='1']"; | ||
var POPUP_POP_SEL = ".sv-tip-pop, .sv-disclose-pop"; | var POPUP_POP_SEL = ".sv-tip-pop, .sv-disclose-pop"; | ||
var POPUP_HEAD_SEL = ".sv-tip-pop-head, .sv-disclose-pop-head"; | |||
var POPUP_HIDDEN_CLASS = "sv-hidden"; | var POPUP_HIDDEN_CLASS = "sv-hidden"; | ||
| Line 230: | Line 230: | ||
/* ------------------------------------------------------------------ */ | /* ------------------------------------------------------------------ */ | ||
/* Popup (Phase 4.1: span toggles + | /* Popup (Phase 4.1: span toggles + div popovers) */ | ||
/* ------------------------------------------------------------------ */ | /* ------------------------------------------------------------------ */ | ||
| Line 236: | Line 236: | ||
if (!pop) return; | if (!pop) return; | ||
if (pop.classList) pop.classList.add(POPUP_HIDDEN_CLASS); | if (pop.classList) pop.classList.add(POPUP_HIDDEN_CLASS); | ||
pop.setAttribute("hidden", "hidden"); | pop.setAttribute("hidden", "hidden"); | ||
} | } | ||
| Line 251: | Line 250: | ||
if (!id) return null; | if (!id) return null; | ||
// Prefer scoping to | var pop = document.getElementById(id); | ||
if (!pop) return null; | |||
// Prefer scoping to wrapper; prevents collisions if IDs ever repeat. | |||
var wrap = closest(btn, POPUP_WRAP_SEL); | var wrap = closest(btn, POPUP_WRAP_SEL); | ||
if (wrap | if (wrap && !wrap.contains(pop)) return null; | ||
return | return pop; | ||
} | } | ||
| Line 300: | Line 299: | ||
} | } | ||
} | } | ||
function normalizeBtnPopups(container) { | function normalizeBtnPopups(container) { | ||
var root = container || document; | var root = container || document; | ||
// Ensure | // Ensure pop divs with sv-hidden are also [hidden] so they start hidden. | ||
var pops = root.querySelectorAll(POPUP_POP_SEL); | var pops = root.querySelectorAll(POPUP_POP_SEL); | ||
for (var i = 0; i < pops.length; i++) { | for (var i = 0; i < pops.length; i++) { | ||
| Line 354: | Line 324: | ||
} | } | ||
/ | // Click handling (delegated): | ||
// - clicking popup header closes | |||
// | // - clicking toggle button toggles | ||
// - clicking outside any wrapper closes all | |||
document.addEventListener( | document.addEventListener( | ||
"click", | "click", | ||
function (e) { | function (e) { | ||
var t = e.target; | |||
if (!t) return; | |||
// 1) Header click closes its popup | |||
var head = t.closest ? t.closest(POPUP_HEAD_SEL) : null; | |||
if (head) { | |||
var wrap = closest(head, POPUP_WRAP_SEL); | |||
if (wrap) { | |||
var btn = wrap.querySelector(POPUP_BTN_SEL); | |||
if (btn) closeBtnPopup(btn); | |||
} | |||
e.preventDefault(); | |||
return; | |||
} | |||
// 2) Button click toggles | |||
var btn = | var btn = | ||
t.closest && t.closest(POPUP_BTN_SEL) ? t.closest(POPUP_BTN_SEL) : null; | |||
if ( | if (btn) { | ||
e.preventDefault(); | |||
if (isBtnExpanded(btn)) { | |||
closeBtnPopup(btn); | |||
return; | |||
} | |||
closeOtherBtnPopupsWithinCard(btn); | |||
openBtnPopup(btn); | |||
return; | return; | ||
} | } | ||
// 3) Click outside wrappers closes all | |||
if (!closest(t, POPUP_WRAP_SEL)) { | |||
closeAllBtnPopups(document); | |||
} | |||
}, | }, | ||
true | true | ||
); | ); | ||
// Keyboard toggle (Enter/Space) | // Keyboard toggle (Enter/Space) + Escape closes all | ||
document.addEventListener( | document.addEventListener( | ||
"keydown", | "keydown", | ||
function (e) { | function (e) { | ||
if (e.key === "Escape") { | |||
closeAllBtnPopups(document); | |||
return; | |||
} | |||
if (!(e.key === "Enter" || e.key === " " || e.key === "Spacebar")) | if (!(e.key === "Enter" || e.key === " " || e.key === "Spacebar")) | ||
return; | return; | ||
| Line 397: | Line 395: | ||
openBtnPopup(btn); | openBtnPopup(btn); | ||
} | } | ||
}, | }, | ||
true | true | ||
| Line 477: | Line 424: | ||
if (!uid) { | if (!uid) { | ||
_tabsUidCounter++; | _tabsUidCounter++; | ||
uid = (root.getAttribute("data-tabs-root") || "svgi-tabs") + "-" + _tabsUidCounter; | uid = | ||
(root.getAttribute("data-tabs-root") || "svgi-tabs") + | |||
"-" + | |||
_tabsUidCounter; | |||
root.setAttribute("data-tabs-uid", uid); | root.setAttribute("data-tabs-uid", uid); | ||
} | } | ||
| Line 651: | Line 601: | ||
initLevels(root); | initLevels(root); | ||
initTabs(root); | initTabs(root); | ||
// Normalize Phase 4.1 span-popups | // Normalize Phase 4.1 span-popups | ||
normalizeBtnPopups( | normalizeBtnPopups(root || document); | ||
} | } | ||