Notebook Utility Panel

Notebook with paging + dark mode on the entire webpage (but notes stay white) + focus/adblock

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Notebook Utility Panel
// @namespace    http://tampermonkey.net/
// @version      3.4
// @description  Notebook with paging + dark mode on the entire webpage (but notes stay white) + focus/adblock
// @match        *://*/*
// @grant        GM_addStyle
// ==/UserScript==

(function () {
    'use strict';

    // --- STYLES ---
    GM_addStyle(`
      #tm-utility-btn {
        position: fixed; top: 50%; right: 0;
        transform: translateY(-50%);
        background: rgba(30,30,30,0.9);
        color: white; border: none;
        padding: 10px 14px;
        border-radius: 12px 0 0 12px;
        cursor: pointer;
        z-index: 999999;
        transition: background 0.3s ease, right 0.3s ease;
      }
      #tm-utility-btn:hover { background: rgba(50,50,50,0.95); }

      #tm-utility-panel {
        position: fixed; top: 50%; right: -380px;
        transform: translateY(-50%);
        width: 360px; height: 500px;
        background: white !important;  /* always white */
        box-shadow: -4px 0 20px rgba(0,0,0,0.2);
        border-radius: 12px 0 0 12px;
        display: flex; flex-direction: column;
        transition: right 0.4s ease;
        z-index: 999999;
        font-family: "Comic Sans MS", cursive, sans-serif;
        color: black !important;       /* always black text */
      }
      #tm-utility-panel.open { right: 0; }

      #tm-titlebar {
        display: flex; align-items: center;
        padding: 6px 8px;
        background: #f2f2f2;
        border-bottom: 1px solid #ccc;
        font-weight: bold;
        font-size: 15px;
        color: black !important;
      }
      #tm-close {
        margin-right: 8px;
        background: transparent;
        border: none;
        font-size: 16px;
        cursor: pointer;
        color: black !important;
      }

      #tm-controls {
        display: flex; gap: 6px;
        padding: 8px;
        background: #f8f8f8;
        border-bottom: 1px solid #ddd;
      }
      #tm-controls button {
        flex: 1;
        background: #fff;
        border: 1px solid #ccc;
        border-radius: 6px;
        padding: 4px 6px;
        cursor: pointer;
        font-size: 13px;
        transition: background 0.2s;
        color: black !important;
      }
      #tm-controls button:hover { background: #eee; }

      #tm-editor {
        flex: 1; padding: 12px;
        border: none; outline: none;
        font-size: 16px;
        overflow-y: auto;
        color: black !important;       /* always black text */
        background: white !important;  /* always white background */
      }

      /* Dark mode for entire page EXCEPT notes */
      .tm-dark body, .tm-dark {
        background: #121212 !important;
        color: #e0e0e0 !important;
      }
      .tm-dark * {
        background-color: transparent !important;
        color: #e0e0e0 !important;
        border-color: #333 !important;
      }
      .tm-dark a { color: #80bfff !important; }
      .tm-dark img, .tm-dark video { opacity: 0.9; }

      /* Reset dark mode styles for the notes panel */
      .tm-dark #tm-utility-panel,
      .tm-dark #tm-utility-panel * {
        background: white !important;
        color: black !important;
        border-color: #ccc !important;
      }

      #tm-paging {
        display: flex; justify-content: space-between;
        padding: 6px 8px;
        background: #f8f8f8;
        border-top: 1px solid #ddd;
      }
      #tm-paging button {
        background: #fff;
        border: 1px solid #aaa;
        border-radius: 6px;
        padding: 4px 6px;
        cursor: pointer;
        font-size: 13px;
        transition: background 0.2s;
        color: black !important;
      }
      #tm-paging button:hover { background: #eee; }

      #tm-actions {
        display: flex; gap: 6px;
        padding: 8px;
        border-top: 1px solid #ddd;
        background: #fafafa;
      }
      #tm-actions button {
        flex: 1;
        background: #0078d7; color: white !important;
        border: none; border-radius: 6px;
        padding: 6px 8px;
        cursor: pointer;
        font-size: 13px;
        transition: background 0.2s;
      }
      #tm-actions button:hover { background: #005ea6; }

      /* Focus mode hides sidebars, headers, footers, ads */
      .tm-focus aside, .tm-focus header, .tm-focus footer,
      .tm-focus nav, .tm-focus [class*="sidebar"], .tm-focus [id*="sidebar"],
      .tm-focus [id*="ad"], .tm-focus [class*="ad"], .tm-focus iframe[src*="ad"],
      .tm-focus .ytp-ad-module {
        display: none !important;
      }
    `);

    // --- BUTTON + PANEL ---
    const btn = document.createElement("button");
    btn.id = "tm-utility-btn";
    btn.textContent = "Notes";
    document.body.appendChild(btn);

    const panel = document.createElement("div");
    panel.id = "tm-utility-panel";
    panel.innerHTML = `
      <div id="tm-titlebar">
        <button id="tm-close">X</button>
        Notebook
      </div>
      <div id="tm-controls">
        <button id="bold">Bold</button>
        <button id="underline">Underline</button>
        <button id="link">Link</button>
        <button id="dark">Dark</button>
        <button id="focus">Focus</button>
      </div>
      <div id="tm-editor" contenteditable="true"></div>
      <div id="tm-paging">
        <button id="prev-page">Prev</button>
        <button id="next-page">Next</button>
      </div>
      <div id="tm-actions">
        <button id="save">Save</button>
        <button id="open">Open</button>
        <button id="clear">Delete</button>
      </div>
    `;
    document.body.appendChild(panel);

    const editor = panel.querySelector("#tm-editor");
    const closeBtn = panel.querySelector("#tm-close");

    // Notebook persistence
    const STORAGE_KEY = "tm-notebook-pages";
    let pages = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]");
    if (pages.length === 0) pages.push("");
    let currentPage = 0;

    function loadPage() {
      editor.innerHTML = pages[currentPage] || "";
    }
    function savePage() {
      pages[currentPage] = editor.innerHTML;
      localStorage.setItem(STORAGE_KEY, JSON.stringify(pages));
    }

    panel.querySelector("#next-page").onclick = () => {
      savePage();
      if (currentPage === pages.length - 1) pages.push("");
      currentPage++;
      loadPage();
    };
    panel.querySelector("#prev-page").onclick = () => {
      savePage();
      if (currentPage > 0) currentPage--;
      loadPage();
    };

    loadPage();

    btn.onclick = () => panel.classList.toggle("open");
    closeBtn.onclick = () => panel.classList.remove("open");

    // formatting
    panel.querySelector("#bold").onclick = () => document.execCommand("bold");
    panel.querySelector("#underline").onclick = () => document.execCommand("underline");
    panel.querySelector("#link").onclick = () => {
      const url = prompt("Enter link URL:");
      if (url) document.execCommand("createLink", false, url);
    };

    // dark/focus
    panel.querySelector("#dark").onclick = () => {
      document.documentElement.classList.toggle("tm-dark");
    };
    panel.querySelector("#focus").onclick = () => {
      document.documentElement.classList.toggle("tm-focus");
    };

    // save/load/delete
    panel.querySelector("#save").onclick = () => {
      savePage();
      alert("Current page saved");
    };
    panel.querySelector("#open").onclick = () => {
      const all = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]");
      if (all.length > 0) {
        pages = all; currentPage = 0; loadPage();
      }
    };
    panel.querySelector("#clear").onclick = () => {
      if (confirm("Delete all pages?")) {
        pages = [""];
        currentPage = 0;
        localStorage.setItem(STORAGE_KEY, JSON.stringify(pages));
        loadPage();
      }
    };

    window.addEventListener("beforeunload", () => savePage());
})();