(function () { let settings = DEFAULT_SETTINGS; const elementState = new WeakMap(); const CLICK_COOLDOWN_MS = 1500; function isSkipIntroButton(text) { return text.indexOf("skip intro") !== -1; } function isSkipCreditsButton(text) { return text.indexOf("skip credit") !== -1; } function isVisible(el) { const style = window.getComputedStyle(el); return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0"; } function getDelayMs(type) { const seconds = type === "intro" ? settings.introDelaySeconds : settings.creditsDelaySeconds; return clampDelaySeconds(seconds) * 1000; } function isStillEligible(el, type) { if (!document.body.contains(el)) return false; if (!isVisible(el)) return false; if (type === "intro" && !settings.skipIntro) return false; if (type === "credits" && !settings.skipCredits) return false; if (!hostMatchesConfig(window.location.hostname, settings.plexUrl)) return false; const text = (el.innerText || el.textContent || "").trim().toLowerCase(); return type === "intro" ? isSkipIntroButton(text) : isSkipCreditsButton(text); } function performClick(el) { const state = elementState.get(el) || {}; state.timer = null; state.lastClickAt = Date.now(); elementState.set(el, state); el.click(); } function scheduleClick(el, type) { const state = elementState.get(el) || {}; if (state.timer) return; if (state.lastClickAt && Date.now() - state.lastClickAt < CLICK_COOLDOWN_MS) return; const delayMs = getDelayMs(type); if (delayMs <= 0) { performClick(el); return; } state.timer = setTimeout(() => { const current = elementState.get(el) || {}; current.timer = null; elementState.set(el, current); if (isStillEligible(el, type)) performClick(el); }, delayMs); elementState.set(el, state); } function scanAndClick() { if (!settings.skipIntro && !settings.skipCredits) return; if (!hostMatchesConfig(window.location.hostname, settings.plexUrl)) return; const nodes = document.querySelectorAll('button, [role="button"]'); nodes.forEach((el) => { const text = (el.innerText || el.textContent || "").trim().toLowerCase(); if (!text) return; if (!isVisible(el)) return; if (settings.skipIntro && isSkipIntroButton(text)) { scheduleClick(el, "intro"); } else if (settings.skipCredits && isSkipCreditsButton(text)) { scheduleClick(el, "credits"); } }); } function start() { const observer = new MutationObserver(scanAndClick); observer.observe(document.documentElement, { childList: true, subtree: true }); scanAndClick(); } chrome.storage.sync.get(DEFAULT_SETTINGS, (loaded) => { settings = loaded; start(); }); chrome.storage.onChanged.addListener((changes, area) => { if (area !== "sync") return; Object.keys(changes).forEach((key) => { settings[key] = changes[key].newValue; }); }); })();