nascent / Clean TheOldReader

// ==UserScript==
// @name         Clean TheOldReader
// @namespace    https://theoldreader.com/
// @version      0.4
// @description  Removes unused features and sponsorships from TheOldReader
// @author       nascent
// @match        https://theoldreader.com/*
// @run-at       document-start
// @license      GPL-3.0-or-later
// @grant        none
// @icon         https://www.google.com/s2/favicons?domain=theoldreader.com&sz=128
// ==/UserScript==

/* ------------------ CONFIG ------------------ */

// CSS selectors to hide globally
const HIDE_SELECTORS = [
  '.btn-star',
  '.btn-share',
  '.btn-like',
  '.dropdown-toggle',
  '.btn-group',
  '.dl-horizontal',
  '.sponsorship',
];

// Selectors to hide only on the homepage
const HOMEPAGE_SELECTORS = [];

// Keyboard shortcuts to block (by key name, case-insensitive)
const BLOCKED_KEYS = ['c', 'f', 'l', 's'];

/* ------------------ CSS INJECTION ------------------ */

const isHomepage = /^\/?(#.*)?$/.test(location.pathname);

const hiddenSelectors = isHomepage
  ? HIDE_SELECTORS.concat(HOMEPAGE_SELECTORS)
  : HIDE_SELECTORS;

const style = document.createElement('style');
style.textContent = hiddenSelectors
  .map(s => `${s} { display: none !important; }`)
  .join('\n');
document.documentElement.appendChild(style);

/* ------------------ KEYBOARD SHORTCUT BLOCKING ------------------ */

document.addEventListener('keydown', function (e) {
  if (/^(input|textarea|select)$/i.test(e.target.tagName)) return;
  if (BLOCKED_KEYS.includes(e.key.toLowerCase())) {
    e.stopImmediatePropagation();
    e.preventDefault();
  }
}, true);

/* ------------------ DYNAMIC CONTENT (PJAX) ------------------ */

// TheOldReader uses pjax for navigation, so the page doesn't fully reload.
// Watch for sponsorship elements injected after navigation.
let debounceTimer;
const observer = new MutationObserver(() => {
  clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => {
    document.querySelectorAll('.sponsorship').forEach(el => el.remove());
  }, 100);
});

if (document.body) {
  observer.observe(document.body, { childList: true, subtree: true });
} else {
  document.addEventListener('DOMContentLoaded', () => {
    observer.observe(document.body, { childList: true, subtree: true });
  });
}