Notebook-style notes with close, paging, dark/focus modes
当前为
// ==UserScript==
// @name Notebook Utility Panel
// @namespace http://tampermonkey.net/
// @version 3.1
// @description Notebook-style notes with close, paging, dark/focus modes
// @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: rgba(250,250,250,0.98);
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;
}
#tm-utility-panel.open { right: 0; }
#tm-close {
position: absolute; top: 6px; left: 6px;
background: transparent;
border: none;
font-size: 18px;
cursor: pointer;
color: inherit; /* makes it black in light mode, white in dark */
}
#tm-controls {
display: flex; gap: 6px;
padding: 8px 28px 8px 36px; /* extra left space for X */
background: #f0f0f0;
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;
}
#tm-controls button:hover { background: #eee; }
#tm-editor {
flex: 1; padding: 12px;
border: none; outline: none;
font-size: 16px;
overflow-y: auto;
color: black;
background: #fff;
}
.tm-dark #tm-editor {
color: white !important;
background: #222 !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 = `
<button id="tm-close">✖️</button>
<div id="tm-controls">
<button id="bold">B</button>
<button id="underline">U</button>
<button id="link">🔗</button>
<button id="dark">🌙</button>
<button id="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");
// localStorage notebook handling
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");
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);
};
panel.querySelector("#dark").onclick = () => {
document.body.classList.toggle("tm-dark");
};
panel.querySelector("#focus").onclick = () => {
document.body.classList.toggle("tm-focus");
};
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());
})();