77 lines
3.1 KiB
JavaScript
77 lines
3.1 KiB
JavaScript
"use strict";
|
|
|
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
Veskslop UI polish — progressive enhancement, no markup edits.
|
|
|
|
Three things CSS cannot reach:
|
|
· close buttons that are the letter "X"
|
|
· the play control that is a ▶ character at 44px
|
|
· help text trapped in a native title tooltip
|
|
|
|
Each fix is idempotent and runs again on DOM changes, so it survives the
|
|
Media and Bot tabs rebuilding their trees. Load AFTER icons.js.
|
|
───────────────────────────────────────────────────────────────────────── */
|
|
|
|
(function () {
|
|
const VK = window.VK;
|
|
if (!VK || !VK.icon) return;
|
|
|
|
const GLYPH_CLOSE = /^[xX✕✖×]$/;
|
|
const GLYPH_PLAY = /^[▶►▸]$/;
|
|
|
|
function polish(root) {
|
|
if (!root || root.nodeType !== 1) return;
|
|
|
|
/* Text-glyph close buttons → the x icon, with a real label. */
|
|
root.querySelectorAll("button, .vk-chip").forEach((el) => {
|
|
const text = (el.textContent || "").trim();
|
|
if (GLYPH_CLOSE.test(text)) {
|
|
el.innerHTML = VK.icon("x", 13);
|
|
el.classList.add("vk-icon-btn");
|
|
if (!el.getAttribute("aria-label")) el.setAttribute("aria-label", "Close");
|
|
} else if (GLYPH_PLAY.test(text)) {
|
|
el.innerHTML = VK.icon("play", 22);
|
|
if (!el.getAttribute("aria-label")) el.setAttribute("aria-label", "Play");
|
|
}
|
|
});
|
|
|
|
/* .vk-media-play is a ▶ character styled at 44px. */
|
|
root.querySelectorAll(".vk-media-play").forEach((el) => {
|
|
if (el.querySelector("svg")) return;
|
|
el.innerHTML = VK.icon("play", 22);
|
|
if (!el.getAttribute("aria-label")) el.setAttribute("aria-label", "Play");
|
|
});
|
|
|
|
/* Help marks: move title → data-tip so the styled tooltip is the only
|
|
one that fires, and keep the text reachable for screen readers. */
|
|
root.querySelectorAll(".vk-info").forEach((el) => {
|
|
const tip = el.getAttribute("title");
|
|
if (tip) {
|
|
el.dataset.tip = tip;
|
|
el.removeAttribute("title");
|
|
el.setAttribute("aria-label", tip);
|
|
}
|
|
if (!el.textContent.trim()) el.textContent = "i";
|
|
if (!el.hasAttribute("tabindex")) el.tabIndex = 0;
|
|
el.setAttribute("role", "note");
|
|
});
|
|
|
|
if (VK.hydrateIcons) VK.hydrateIcons(root);
|
|
}
|
|
|
|
function run() {
|
|
polish(document.body);
|
|
new MutationObserver((records) => {
|
|
for (const r of records) {
|
|
r.addedNodes.forEach((n) => polish(n));
|
|
}
|
|
}).observe(document.body, { childList: true, subtree: true });
|
|
}
|
|
|
|
if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", run);
|
|
} else {
|
|
run();
|
|
}
|
|
})();
|