分享一个notebooklm对话字体大小调整的油猴脚本
- 内容介绍
- 文章标签
- 相关推荐
如题,默认的字体大小有点小看着费眼,之前让ai写了一个脚本,支持调整字体大小和行高,只调整对话区
// ==UserScript==
// @name NotebookLM 对话字体大小调整
// @namespace https://tampermonkey.net/
// @version 0.4.5
// @description 优化:增大对话区字体;引用角标缩小;行内代码带背景,多行代码块保持透明。
// @author NOMELON
// @match https://notebooklm.google/*
// @match https://notebooklm.google.com/*
// @run-at document-idle
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// ==/UserScript==
(function () {
'use strict';
// --- 1. 综合配置区 ---
const CONFIG = {
fontSize: { default: 18, step: 1, min: 12, max: 36 },
lineHeight: { default: 1.7, step: 0.1, min: 1.2, max: 2.5 },
codeBlock: {
bgColor: "#b2d5f3",
textColor: "#333333",
fontFamily: '"Cascadia Code", "Consolas", "Monaco", "Courier New", "PingFang SC", "Microsoft YaHei", sans-serif'
}
};
// --- 2. 状态管理 ---
let state = {
size: Number(GM_getValue('nlm_chat_font_size', CONFIG.fontSize.default)),
lh: Number(GM_getValue('nlm_chat_line_height', CONFIG.lineHeight.default)),
menuIds: [],
styleEl: null,
toastEl: null,
toastTimer: null
};
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const round2 = (v) => Math.round(v * 100) / 100;
// --- 4. 核心 CSS 构建 ---
function buildCSS(px, lineHeight) {
return `
:root {
--nlm-chat-fs: ${px}px;
--nlm-chat-lh: ${lineHeight};
--nlm-code-bg: ${CONFIG.codeBlock.bgColor};
--nlm-code-text: ${CONFIG.codeBlock.textColor};
--nlm-code-font: ${CONFIG.codeBlock.fontFamily};
}
/* --- A. 主体字体调节 --- */
span[data-start-index],
[data-start-index].ng-star-inserted,
main .markdown-content p,
main .markdown-content li,
main .markdown-content h1,
main .markdown-content h2,
main .markdown-content h3,
main .message-content p,
main .message-content li,
.message-text-content.mat-body-medium,
.message-text-content.mat-body-medium * {
font-size: var(--nlm-chat-fs) !important;
line-height: var(--nlm-chat-lh) !important;
}
/* --- B. 引用角标 (Citation Chips) --- */
.message-text-content [aria-label*=":"],
.message-text-content button[aria-label*=":"],
.message-text-content span[aria-label*=":"] {
font-size: 12px !important;
line-height: normal !important;
height: auto !important;
min-height: unset !important;
vertical-align: super !important;
}
/* --- C. 代码区域差异化处理 --- */
/* 1. 所有代码相关元素统一字体 */
code, pre, .code, code *, pre * {
font-family: var(--nlm-code-font) !important;
font-weight: 500 !important;
}
/* 2. 行内代码:保留背景颜色 */
/* 命中:不在 pre 里的 code 标签,或者带有 .code 类的行内元素 */
code:not(pre code),
.code:not(pre *),
b.code {
background-color: var(--nlm-code-bg) !important;
color: var(--nlm-code-text) !important;
padding: 2px 4px !important;
border-radius: 4px !important;
border: none !important;
}
/* 3. 多行代码块:背景强制透明 */
/* 命中:pre 标签及其内部的所有 code 标签 */
pre,
pre code,
pre span {
background-color: transparent !important;
background: transparent !important;
display: block;
padding: 10px 0; /* 留一点上下间距 */
overflow-x: auto;
color: inherit !important; /* 维持原有的高亮颜色(如果有) */
}
/* --- D. Toast 提示 --- */
#nlm-font-toast {
position: fixed;
bottom: 80px; left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 16px; border-radius: 20px;
font-size: 14px; z-index: 9999;
pointer-events: none; opacity: 0;
transition: opacity 0.3s; font-family: sans-serif;
}
#nlm-font-toast.show { opacity: 1; }
`;
}
// --- 5. 逻辑处理 (未变动) ---
function updateStyle() {
const css = buildCSS(state.size, state.lh);
if (state.styleEl) { state.styleEl.textContent = css; }
else { state.styleEl = GM_addStyle(css); }
}
function saveState() {
GM_setValue('nlm_chat_font_size', state.size);
GM_setValue('nlm_chat_line_height', state.lh);
}
function showToast(text) {
if (!state.toastEl) {
state.toastEl = document.createElement('div');
state.toastEl.id = 'nlm-font-toast';
document.body.appendChild(state.toastEl);
}
state.toastEl.textContent = text;
state.toastEl.classList.add('show');
if (state.toastTimer) clearTimeout(state.toastTimer);
state.toastTimer = setTimeout(() => state.toastEl.classList.remove('show'), 1500);
}
function updateMenus() {
state.menuIds.forEach(id => GM_unregisterMenuCommand(id));
state.menuIds = [];
const addMenu = (text, func) => state.menuIds.push(GM_registerMenuCommand(text, func));
addMenu(`字号 + (当前 ${state.size}px)`, () => adjustSize(1));
addMenu(`字号 - (当前 ${state.size}px)`, () => adjustSize(-1));
addMenu(`行高 + (当前 ${state.lh})`, () => adjustLH(1));
addMenu(`行高 - (当前 ${state.lh})`, () => adjustLH(-1));
addMenu(`重置所有设置`, resetAll);
}
function adjustSize(dir) {
state.size = clamp(state.size + (dir * CONFIG.fontSize.step), CONFIG.fontSize.min, CONFIG.fontSize.max);
applyChanges(`字体大小: ${state.size}px`);
}
function adjustLH(dir) {
state.lh = round2(clamp(state.lh + (dir * CONFIG.lineHeight.step), CONFIG.lineHeight.min, CONFIG.lineHeight.max));
applyChanges(`行高倍数: ${state.lh}`);
}
function resetAll() {
state.size = CONFIG.fontSize.default;
state.lh = CONFIG.lineHeight.default;
applyChanges(`已重置默认设置`);
}
function applyChanges(toastText) {
updateStyle(); saveState(); updateMenus();
if (toastText) showToast(toastText);
}
function init() {
updateStyle(); updateMenus();
document.addEventListener('keydown', (e) => {
if (!e.altKey || e.ctrlKey || e.metaKey) return;
let handled = false;
if (e.key === '=' || e.key === '+') { adjustSize(1); handled = true; }
else if (e.key === '-' || e.key === '_') { adjustSize(-1); handled = true; }
else if (e.key === ']') { adjustLH(1); handled = true; }
else if (e.key === '[') { adjustLH(-1); handled = true; }
else if (e.key === '0') { resetAll(); handled = true; }
if (handled) { e.preventDefault(); e.stopPropagation(); }
}, true);
}
init();
})();
网友解答:
--【壹】--:
如题,默认的字体大小有点小看着费眼,之前让ai写了一个脚本,支持调整字体大小和行高,只调整对话区
// ==UserScript==
// @name NotebookLM 对话字体大小调整
// @namespace https://tampermonkey.net/
// @version 0.4.5
// @description 优化:增大对话区字体;引用角标缩小;行内代码带背景,多行代码块保持透明。
// @author NOMELON
// @match https://notebooklm.google/*
// @match https://notebooklm.google.com/*
// @run-at document-idle
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// ==/UserScript==
(function () {
'use strict';
// --- 1. 综合配置区 ---
const CONFIG = {
fontSize: { default: 18, step: 1, min: 12, max: 36 },
lineHeight: { default: 1.7, step: 0.1, min: 1.2, max: 2.5 },
codeBlock: {
bgColor: "#b2d5f3",
textColor: "#333333",
fontFamily: '"Cascadia Code", "Consolas", "Monaco", "Courier New", "PingFang SC", "Microsoft YaHei", sans-serif'
}
};
// --- 2. 状态管理 ---
let state = {
size: Number(GM_getValue('nlm_chat_font_size', CONFIG.fontSize.default)),
lh: Number(GM_getValue('nlm_chat_line_height', CONFIG.lineHeight.default)),
menuIds: [],
styleEl: null,
toastEl: null,
toastTimer: null
};
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const round2 = (v) => Math.round(v * 100) / 100;
// --- 4. 核心 CSS 构建 ---
function buildCSS(px, lineHeight) {
return `
:root {
--nlm-chat-fs: ${px}px;
--nlm-chat-lh: ${lineHeight};
--nlm-code-bg: ${CONFIG.codeBlock.bgColor};
--nlm-code-text: ${CONFIG.codeBlock.textColor};
--nlm-code-font: ${CONFIG.codeBlock.fontFamily};
}
/* --- A. 主体字体调节 --- */
span[data-start-index],
[data-start-index].ng-star-inserted,
main .markdown-content p,
main .markdown-content li,
main .markdown-content h1,
main .markdown-content h2,
main .markdown-content h3,
main .message-content p,
main .message-content li,
.message-text-content.mat-body-medium,
.message-text-content.mat-body-medium * {
font-size: var(--nlm-chat-fs) !important;
line-height: var(--nlm-chat-lh) !important;
}
/* --- B. 引用角标 (Citation Chips) --- */
.message-text-content [aria-label*=":"],
.message-text-content button[aria-label*=":"],
.message-text-content span[aria-label*=":"] {
font-size: 12px !important;
line-height: normal !important;
height: auto !important;
min-height: unset !important;
vertical-align: super !important;
}
/* --- C. 代码区域差异化处理 --- */
/* 1. 所有代码相关元素统一字体 */
code, pre, .code, code *, pre * {
font-family: var(--nlm-code-font) !important;
font-weight: 500 !important;
}
/* 2. 行内代码:保留背景颜色 */
/* 命中:不在 pre 里的 code 标签,或者带有 .code 类的行内元素 */
code:not(pre code),
.code:not(pre *),
b.code {
background-color: var(--nlm-code-bg) !important;
color: var(--nlm-code-text) !important;
padding: 2px 4px !important;
border-radius: 4px !important;
border: none !important;
}
/* 3. 多行代码块:背景强制透明 */
/* 命中:pre 标签及其内部的所有 code 标签 */
pre,
pre code,
pre span {
background-color: transparent !important;
background: transparent !important;
display: block;
padding: 10px 0; /* 留一点上下间距 */
overflow-x: auto;
color: inherit !important; /* 维持原有的高亮颜色(如果有) */
}
/* --- D. Toast 提示 --- */
#nlm-font-toast {
position: fixed;
bottom: 80px; left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 16px; border-radius: 20px;
font-size: 14px; z-index: 9999;
pointer-events: none; opacity: 0;
transition: opacity 0.3s; font-family: sans-serif;
}
#nlm-font-toast.show { opacity: 1; }
`;
}
// --- 5. 逻辑处理 (未变动) ---
function updateStyle() {
const css = buildCSS(state.size, state.lh);
if (state.styleEl) { state.styleEl.textContent = css; }
else { state.styleEl = GM_addStyle(css); }
}
function saveState() {
GM_setValue('nlm_chat_font_size', state.size);
GM_setValue('nlm_chat_line_height', state.lh);
}
function showToast(text) {
if (!state.toastEl) {
state.toastEl = document.createElement('div');
state.toastEl.id = 'nlm-font-toast';
document.body.appendChild(state.toastEl);
}
state.toastEl.textContent = text;
state.toastEl.classList.add('show');
if (state.toastTimer) clearTimeout(state.toastTimer);
state.toastTimer = setTimeout(() => state.toastEl.classList.remove('show'), 1500);
}
function updateMenus() {
state.menuIds.forEach(id => GM_unregisterMenuCommand(id));
state.menuIds = [];
const addMenu = (text, func) => state.menuIds.push(GM_registerMenuCommand(text, func));
addMenu(`字号 + (当前 ${state.size}px)`, () => adjustSize(1));
addMenu(`字号 - (当前 ${state.size}px)`, () => adjustSize(-1));
addMenu(`行高 + (当前 ${state.lh})`, () => adjustLH(1));
addMenu(`行高 - (当前 ${state.lh})`, () => adjustLH(-1));
addMenu(`重置所有设置`, resetAll);
}
function adjustSize(dir) {
state.size = clamp(state.size + (dir * CONFIG.fontSize.step), CONFIG.fontSize.min, CONFIG.fontSize.max);
applyChanges(`字体大小: ${state.size}px`);
}
function adjustLH(dir) {
state.lh = round2(clamp(state.lh + (dir * CONFIG.lineHeight.step), CONFIG.lineHeight.min, CONFIG.lineHeight.max));
applyChanges(`行高倍数: ${state.lh}`);
}
function resetAll() {
state.size = CONFIG.fontSize.default;
state.lh = CONFIG.lineHeight.default;
applyChanges(`已重置默认设置`);
}
function applyChanges(toastText) {
updateStyle(); saveState(); updateMenus();
if (toastText) showToast(toastText);
}
function init() {
updateStyle(); updateMenus();
document.addEventListener('keydown', (e) => {
if (!e.altKey || e.ctrlKey || e.metaKey) return;
let handled = false;
if (e.key === '=' || e.key === '+') { adjustSize(1); handled = true; }
else if (e.key === '-' || e.key === '_') { adjustSize(-1); handled = true; }
else if (e.key === ']') { adjustLH(1); handled = true; }
else if (e.key === '[') { adjustLH(-1); handled = true; }
else if (e.key === '0') { resetAll(); handled = true; }
if (handled) { e.preventDefault(); e.stopPropagation(); }
}, true);
}
init();
})();
如题,默认的字体大小有点小看着费眼,之前让ai写了一个脚本,支持调整字体大小和行高,只调整对话区
// ==UserScript==
// @name NotebookLM 对话字体大小调整
// @namespace https://tampermonkey.net/
// @version 0.4.5
// @description 优化:增大对话区字体;引用角标缩小;行内代码带背景,多行代码块保持透明。
// @author NOMELON
// @match https://notebooklm.google/*
// @match https://notebooklm.google.com/*
// @run-at document-idle
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// ==/UserScript==
(function () {
'use strict';
// --- 1. 综合配置区 ---
const CONFIG = {
fontSize: { default: 18, step: 1, min: 12, max: 36 },
lineHeight: { default: 1.7, step: 0.1, min: 1.2, max: 2.5 },
codeBlock: {
bgColor: "#b2d5f3",
textColor: "#333333",
fontFamily: '"Cascadia Code", "Consolas", "Monaco", "Courier New", "PingFang SC", "Microsoft YaHei", sans-serif'
}
};
// --- 2. 状态管理 ---
let state = {
size: Number(GM_getValue('nlm_chat_font_size', CONFIG.fontSize.default)),
lh: Number(GM_getValue('nlm_chat_line_height', CONFIG.lineHeight.default)),
menuIds: [],
styleEl: null,
toastEl: null,
toastTimer: null
};
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const round2 = (v) => Math.round(v * 100) / 100;
// --- 4. 核心 CSS 构建 ---
function buildCSS(px, lineHeight) {
return `
:root {
--nlm-chat-fs: ${px}px;
--nlm-chat-lh: ${lineHeight};
--nlm-code-bg: ${CONFIG.codeBlock.bgColor};
--nlm-code-text: ${CONFIG.codeBlock.textColor};
--nlm-code-font: ${CONFIG.codeBlock.fontFamily};
}
/* --- A. 主体字体调节 --- */
span[data-start-index],
[data-start-index].ng-star-inserted,
main .markdown-content p,
main .markdown-content li,
main .markdown-content h1,
main .markdown-content h2,
main .markdown-content h3,
main .message-content p,
main .message-content li,
.message-text-content.mat-body-medium,
.message-text-content.mat-body-medium * {
font-size: var(--nlm-chat-fs) !important;
line-height: var(--nlm-chat-lh) !important;
}
/* --- B. 引用角标 (Citation Chips) --- */
.message-text-content [aria-label*=":"],
.message-text-content button[aria-label*=":"],
.message-text-content span[aria-label*=":"] {
font-size: 12px !important;
line-height: normal !important;
height: auto !important;
min-height: unset !important;
vertical-align: super !important;
}
/* --- C. 代码区域差异化处理 --- */
/* 1. 所有代码相关元素统一字体 */
code, pre, .code, code *, pre * {
font-family: var(--nlm-code-font) !important;
font-weight: 500 !important;
}
/* 2. 行内代码:保留背景颜色 */
/* 命中:不在 pre 里的 code 标签,或者带有 .code 类的行内元素 */
code:not(pre code),
.code:not(pre *),
b.code {
background-color: var(--nlm-code-bg) !important;
color: var(--nlm-code-text) !important;
padding: 2px 4px !important;
border-radius: 4px !important;
border: none !important;
}
/* 3. 多行代码块:背景强制透明 */
/* 命中:pre 标签及其内部的所有 code 标签 */
pre,
pre code,
pre span {
background-color: transparent !important;
background: transparent !important;
display: block;
padding: 10px 0; /* 留一点上下间距 */
overflow-x: auto;
color: inherit !important; /* 维持原有的高亮颜色(如果有) */
}
/* --- D. Toast 提示 --- */
#nlm-font-toast {
position: fixed;
bottom: 80px; left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 16px; border-radius: 20px;
font-size: 14px; z-index: 9999;
pointer-events: none; opacity: 0;
transition: opacity 0.3s; font-family: sans-serif;
}
#nlm-font-toast.show { opacity: 1; }
`;
}
// --- 5. 逻辑处理 (未变动) ---
function updateStyle() {
const css = buildCSS(state.size, state.lh);
if (state.styleEl) { state.styleEl.textContent = css; }
else { state.styleEl = GM_addStyle(css); }
}
function saveState() {
GM_setValue('nlm_chat_font_size', state.size);
GM_setValue('nlm_chat_line_height', state.lh);
}
function showToast(text) {
if (!state.toastEl) {
state.toastEl = document.createElement('div');
state.toastEl.id = 'nlm-font-toast';
document.body.appendChild(state.toastEl);
}
state.toastEl.textContent = text;
state.toastEl.classList.add('show');
if (state.toastTimer) clearTimeout(state.toastTimer);
state.toastTimer = setTimeout(() => state.toastEl.classList.remove('show'), 1500);
}
function updateMenus() {
state.menuIds.forEach(id => GM_unregisterMenuCommand(id));
state.menuIds = [];
const addMenu = (text, func) => state.menuIds.push(GM_registerMenuCommand(text, func));
addMenu(`字号 + (当前 ${state.size}px)`, () => adjustSize(1));
addMenu(`字号 - (当前 ${state.size}px)`, () => adjustSize(-1));
addMenu(`行高 + (当前 ${state.lh})`, () => adjustLH(1));
addMenu(`行高 - (当前 ${state.lh})`, () => adjustLH(-1));
addMenu(`重置所有设置`, resetAll);
}
function adjustSize(dir) {
state.size = clamp(state.size + (dir * CONFIG.fontSize.step), CONFIG.fontSize.min, CONFIG.fontSize.max);
applyChanges(`字体大小: ${state.size}px`);
}
function adjustLH(dir) {
state.lh = round2(clamp(state.lh + (dir * CONFIG.lineHeight.step), CONFIG.lineHeight.min, CONFIG.lineHeight.max));
applyChanges(`行高倍数: ${state.lh}`);
}
function resetAll() {
state.size = CONFIG.fontSize.default;
state.lh = CONFIG.lineHeight.default;
applyChanges(`已重置默认设置`);
}
function applyChanges(toastText) {
updateStyle(); saveState(); updateMenus();
if (toastText) showToast(toastText);
}
function init() {
updateStyle(); updateMenus();
document.addEventListener('keydown', (e) => {
if (!e.altKey || e.ctrlKey || e.metaKey) return;
let handled = false;
if (e.key === '=' || e.key === '+') { adjustSize(1); handled = true; }
else if (e.key === '-' || e.key === '_') { adjustSize(-1); handled = true; }
else if (e.key === ']') { adjustLH(1); handled = true; }
else if (e.key === '[') { adjustLH(-1); handled = true; }
else if (e.key === '0') { resetAll(); handled = true; }
if (handled) { e.preventDefault(); e.stopPropagation(); }
}, true);
}
init();
})();
网友解答:
--【壹】--:
如题,默认的字体大小有点小看着费眼,之前让ai写了一个脚本,支持调整字体大小和行高,只调整对话区
// ==UserScript==
// @name NotebookLM 对话字体大小调整
// @namespace https://tampermonkey.net/
// @version 0.4.5
// @description 优化:增大对话区字体;引用角标缩小;行内代码带背景,多行代码块保持透明。
// @author NOMELON
// @match https://notebooklm.google/*
// @match https://notebooklm.google.com/*
// @run-at document-idle
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// ==/UserScript==
(function () {
'use strict';
// --- 1. 综合配置区 ---
const CONFIG = {
fontSize: { default: 18, step: 1, min: 12, max: 36 },
lineHeight: { default: 1.7, step: 0.1, min: 1.2, max: 2.5 },
codeBlock: {
bgColor: "#b2d5f3",
textColor: "#333333",
fontFamily: '"Cascadia Code", "Consolas", "Monaco", "Courier New", "PingFang SC", "Microsoft YaHei", sans-serif'
}
};
// --- 2. 状态管理 ---
let state = {
size: Number(GM_getValue('nlm_chat_font_size', CONFIG.fontSize.default)),
lh: Number(GM_getValue('nlm_chat_line_height', CONFIG.lineHeight.default)),
menuIds: [],
styleEl: null,
toastEl: null,
toastTimer: null
};
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
const round2 = (v) => Math.round(v * 100) / 100;
// --- 4. 核心 CSS 构建 ---
function buildCSS(px, lineHeight) {
return `
:root {
--nlm-chat-fs: ${px}px;
--nlm-chat-lh: ${lineHeight};
--nlm-code-bg: ${CONFIG.codeBlock.bgColor};
--nlm-code-text: ${CONFIG.codeBlock.textColor};
--nlm-code-font: ${CONFIG.codeBlock.fontFamily};
}
/* --- A. 主体字体调节 --- */
span[data-start-index],
[data-start-index].ng-star-inserted,
main .markdown-content p,
main .markdown-content li,
main .markdown-content h1,
main .markdown-content h2,
main .markdown-content h3,
main .message-content p,
main .message-content li,
.message-text-content.mat-body-medium,
.message-text-content.mat-body-medium * {
font-size: var(--nlm-chat-fs) !important;
line-height: var(--nlm-chat-lh) !important;
}
/* --- B. 引用角标 (Citation Chips) --- */
.message-text-content [aria-label*=":"],
.message-text-content button[aria-label*=":"],
.message-text-content span[aria-label*=":"] {
font-size: 12px !important;
line-height: normal !important;
height: auto !important;
min-height: unset !important;
vertical-align: super !important;
}
/* --- C. 代码区域差异化处理 --- */
/* 1. 所有代码相关元素统一字体 */
code, pre, .code, code *, pre * {
font-family: var(--nlm-code-font) !important;
font-weight: 500 !important;
}
/* 2. 行内代码:保留背景颜色 */
/* 命中:不在 pre 里的 code 标签,或者带有 .code 类的行内元素 */
code:not(pre code),
.code:not(pre *),
b.code {
background-color: var(--nlm-code-bg) !important;
color: var(--nlm-code-text) !important;
padding: 2px 4px !important;
border-radius: 4px !important;
border: none !important;
}
/* 3. 多行代码块:背景强制透明 */
/* 命中:pre 标签及其内部的所有 code 标签 */
pre,
pre code,
pre span {
background-color: transparent !important;
background: transparent !important;
display: block;
padding: 10px 0; /* 留一点上下间距 */
overflow-x: auto;
color: inherit !important; /* 维持原有的高亮颜色(如果有) */
}
/* --- D. Toast 提示 --- */
#nlm-font-toast {
position: fixed;
bottom: 80px; left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 16px; border-radius: 20px;
font-size: 14px; z-index: 9999;
pointer-events: none; opacity: 0;
transition: opacity 0.3s; font-family: sans-serif;
}
#nlm-font-toast.show { opacity: 1; }
`;
}
// --- 5. 逻辑处理 (未变动) ---
function updateStyle() {
const css = buildCSS(state.size, state.lh);
if (state.styleEl) { state.styleEl.textContent = css; }
else { state.styleEl = GM_addStyle(css); }
}
function saveState() {
GM_setValue('nlm_chat_font_size', state.size);
GM_setValue('nlm_chat_line_height', state.lh);
}
function showToast(text) {
if (!state.toastEl) {
state.toastEl = document.createElement('div');
state.toastEl.id = 'nlm-font-toast';
document.body.appendChild(state.toastEl);
}
state.toastEl.textContent = text;
state.toastEl.classList.add('show');
if (state.toastTimer) clearTimeout(state.toastTimer);
state.toastTimer = setTimeout(() => state.toastEl.classList.remove('show'), 1500);
}
function updateMenus() {
state.menuIds.forEach(id => GM_unregisterMenuCommand(id));
state.menuIds = [];
const addMenu = (text, func) => state.menuIds.push(GM_registerMenuCommand(text, func));
addMenu(`字号 + (当前 ${state.size}px)`, () => adjustSize(1));
addMenu(`字号 - (当前 ${state.size}px)`, () => adjustSize(-1));
addMenu(`行高 + (当前 ${state.lh})`, () => adjustLH(1));
addMenu(`行高 - (当前 ${state.lh})`, () => adjustLH(-1));
addMenu(`重置所有设置`, resetAll);
}
function adjustSize(dir) {
state.size = clamp(state.size + (dir * CONFIG.fontSize.step), CONFIG.fontSize.min, CONFIG.fontSize.max);
applyChanges(`字体大小: ${state.size}px`);
}
function adjustLH(dir) {
state.lh = round2(clamp(state.lh + (dir * CONFIG.lineHeight.step), CONFIG.lineHeight.min, CONFIG.lineHeight.max));
applyChanges(`行高倍数: ${state.lh}`);
}
function resetAll() {
state.size = CONFIG.fontSize.default;
state.lh = CONFIG.lineHeight.default;
applyChanges(`已重置默认设置`);
}
function applyChanges(toastText) {
updateStyle(); saveState(); updateMenus();
if (toastText) showToast(toastText);
}
function init() {
updateStyle(); updateMenus();
document.addEventListener('keydown', (e) => {
if (!e.altKey || e.ctrlKey || e.metaKey) return;
let handled = false;
if (e.key === '=' || e.key === '+') { adjustSize(1); handled = true; }
else if (e.key === '-' || e.key === '_') { adjustSize(-1); handled = true; }
else if (e.key === ']') { adjustLH(1); handled = true; }
else if (e.key === '[') { adjustLH(-1); handled = true; }
else if (e.key === '0') { resetAll(); handled = true; }
if (handled) { e.preventDefault(); e.stopPropagation(); }
}, true);
}
init();
})();

