// ==UserScript==
// @name AI Chat Window Enhancer Pro
// @name:zh-CN AI对话窗口增强专业版
// @namespace http://tampermonkey.net/
// @version 0.3.4
// @description Enhanced chat window for various AI platforms: ChatGPT, Claude, Kimi, Tongyi, ChatGLM, Tiangong, Deepseek, Gemini
// @description:zh-CN 为主流AI平台优化对话窗口体验:支持ChatGPT、Claude、Kimi、通义千问、智谱GLM、天工、Deepseek、Gemini
// @author Claude
// @match *://chatgpt.com/*
// @match *://new.oaifree.com/*
// @match *://shared.oaifree.com/*
// @match *://www.aicnn.cn/oaifree/*
// @match *://chat.aicnn.xyz/*
// @match *://plus.aivvm.com/*
// @match *://kimi.moonshot.cn/*
// @match *://tongyi.aliyun.com/qianwen*
// @match *://www.tiangong.cn/*
// @match *://chatglm.cn/*
// @match *://claude.ai/*
// @match *://chat.deepseek.com/*
// @include *://*claude*/*
// @match *://chat.kelaode.ai/*
// @match *://gemini.google.com/*
// @icon data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHJlY3Qgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiByeD0iNSIgcnk9IjUiIGZpbGw9IiM2YmIiLz4KICA8cGF0aCBkPSJtMTcgMTMuNyA0LTQtNC00bS0xMCA4LTQtNCA0LTRtMTMuOTk5IDMuODI1SDMuMjE1Ii8+CiAgPHBhdGggZD0iTTE5IDE2aC0yLjVhLjk5LjkgMCAwIDAtLjc3NS4zNzVsLTIuOSAzLjY1Yy0uNC41LTEuMTYyLjUtMS41NjMgMGwtMi45MjUtMy42NUEuOTkuOSAwIDAgMCA3LjUgMTZINWMtMS42NjMgMC0zLTEuMzM4LTMtM1Y2YzAtMS42NjIgMS4zNS0zIDMtM2gxNGEzIDMgMCAwIDEgMyAzdjdjMCAxLjY2Mi0xLjM1IDMtMyAzWiIgZmlsbC1vcGFjaXR5PSIuMTYiIHN0cm9rZT0iI0VFRSIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8L3N2Zz4K
// @license AGPL-3.0
// @grant GM_addStyle
// @noframes
// ==/UserScript==
(function() {
'use strict';
// 统一的样式配置
const STYLE_CONFIG = {
maxWidth: '95%',
maxViewportWidth: '90vw',
scrollbarWidth: 'thin',
scrollbarThumbColor: '#aaaa',
scrollbarTrackColor: '#1111',
codeBlockScrollbarHeight: '8px',
codeBlockScrollbarThumbColor: '#666',
codeBlockScrollbarTrackColor: '#f1f1f1',
// 代码块选中样式
codeSelectionBgColor: 'rgba(70, 130, 180, 0.5)', // 深色主题选中背景色
codeSelectionTextColor: 'white', // 深色主题选中文本色
lightCodeSelectionBgColor: 'rgba(0, 120, 215, 0.3)', // 浅色主题选中背景色
lightCodeSelectionTextColor: 'black' // 浅色主题选中文本色
};
// 通用代码块样式
const CODE_BLOCK_STYLES = `
/* 代码块样式优化 */
pre > div.rounded-md,
.code-block__code {
min-height: 1.5em;
height: auto !important;
}
/* 保持代码块的水平滚动,移除纵向限制 */
pre > div.rounded-md > div.overflow-y-auto,
.code-block__code {
max-height: none !important;
height: auto !important;
overflow-y: visible !important;
overflow-x: auto !important;
}
/* 移除代码块的折叠按钮 */
button[class*="code-block-collapse-button"],
div[class*="code-block-collapse"] {
display: none !important;
}
/* 确保代码块始终展开 */
div[class*="code-block-wrapper"].collapsed {
max-height: none !important;
height: auto !important;
}
/* 优化代码块滚动条样式 */
pre > div.rounded-md > div.overflow-y-auto::-webkit-scrollbar,
.code-block__code::-webkit-scrollbar {
height: ${STYLE_CONFIG.codeBlockScrollbarHeight};
width: ${STYLE_CONFIG.codeBlockScrollbarHeight};
}
pre > div.rounded-md > div.overflow-y-auto::-webkit-scrollbar-thumb,
.code-block__code::-webkit-scrollbar-thumb {
background: ${STYLE_CONFIG.codeBlockScrollbarThumbColor};
border-radius: 4px;
}
pre > div.rounded-md > div.overflow-y-auto::-webkit-scrollbar-track,
.code-block__code::-webkit-scrollbar-track {
background: ${STYLE_CONFIG.codeBlockScrollbarTrackColor};
}
/* 代码块文本选中样式 - 适用于深色背景 */
pre code::selection,
.code-block__code code::selection,
pre div::selection,
.code-block__code div::selection,
pre span::selection,
.code-block__code span::selection,
div[class*="codeBlockContainer"] *::selection,
div[class*="code-block"] *::selection {
background-color: ${STYLE_CONFIG.codeSelectionBgColor} !important;
color: ${STYLE_CONFIG.codeSelectionTextColor} !important;
}
/* 浅色背景代码块的选中样式 */
pre.bg-white code::selection,
pre.bg-gray-50 code::selection,
pre.bg-slate-50 code::selection,
.light-theme pre code::selection,
.light pre code::selection {
background-color: ${STYLE_CONFIG.lightCodeSelectionBgColor} !important;
color: ${STYLE_CONFIG.lightCodeSelectionTextColor} !important;
}
/* 提升代码块hover时的可识别性 */
pre:hover,
.code-block__code:hover,
div[class*="codeBlockContainer"]:hover,
div[class*="code-block"]:hover {
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1);
transition: box-shadow 0.2s ease-in-out;
}
`;
// 平台特定的样式定义
const PLATFORM_STYLES = {
kimi: `
div[data-testid] div[data-index] div.MuiBox-root {
max-width: 100% !important;
}
div[class^=mainContent] div.MuiBox-root > div[class^=chatBottom_] {
max-width: calc(100% - 100px);
}
div[class^=mainContent] div[class^=chatInput_] div[class^=inputInner_] div[class^=editor] {
max-height: 360px;
}
#scroll-list div[class^=chatItemBox_].MuiBox-root {
max-width: 100%;
}
div.MuiBox-root[class^=homepage] div[class^=mainContent] div[class^=chatInput_] div[class^=inputInner_] div[class^=editor] {
max-height: 600px;
}
#root > div > div[class*=mainContent] > div[class*=layoutContent] > div.MuiBox-root > div.MuiBox-root[class*=homepage] > div.MuiContainer-root.MuiContainer-maxWidthMd {
max-width: calc(100% - 100px);
}
${CODE_BLOCK_STYLES}
`,
deepseek: `
div:has(> #latest-context-divider) {
width: ${STYLE_CONFIG.maxWidth} !important;
}
div:has(> div > #chat-input) {
width: ${STYLE_CONFIG.maxWidth} !important;
max-width: ${STYLE_CONFIG.maxViewportWidth};
}
${CODE_BLOCK_STYLES}
`,
tongyi: `
div[class^=mainContent] div[class^=questionItem--],
div[class^=mainContent] div[class^=answerItem--] {
width: 90% !important;
max-width: ${STYLE_CONFIG.maxViewportWidth};
}
${CODE_BLOCK_STYLES}
`,
tiangong: `
#app > div > div > main > div.overflow-y-scroll.w-full > div.search-content.relative.flex.w-full.flex-row.justify-center,
#app > div > div > main > div.overflow-y-scroll.w-full > div.search-content.relative.flex.w-full.flex-row.justify-center > label.w-full.cursor-default.select-auto,
label.w-full {
max-width: calc(100% - 100px);
--search-max-width: calc(100% - 100px);
}
:root {
--search-max-width: calc(100% - 100px);
}
${CODE_BLOCK_STYLES}
`,
chatglm: `
div.conversation-inner.dialogue > div.conversation-list.detail > div.item.conversation-item,
.markdown-body.md-body {
max-width: ${STYLE_CONFIG.maxViewportWidth} !important;
}
${CODE_BLOCK_STYLES}
`,
gemini: `
#chat-history > infinite-scroller > div,
#app-root > main > side-navigation-v2 > bard-sidenav-container > bard-sidenav-content > div > div > div.content-container > chat-window > div.chat-container.ng-star-inserted > div.bottom-container.response-optimization.ng-star-inserted,
#app-root > main > side-navigation-v2 > bard-sidenav-container > bard-sidenav-content > div > div > div.content-container > chat-window > div.chat-container.ng-star-inserted > div.bottom-container.response-optimization.ng-star-inserted > div.input-area-container.ng-star-inserted {
max-width: calc(100% - 20px);
}
${CODE_BLOCK_STYLES}
`,
default: `
.xl\\:max-w-\\[48rem\\] {
width: ${STYLE_CONFIG.maxWidth} !important;
max-width: 96% !important;
}
div.mx-auto.md\\:max-w-3xl,
div.mx-auto.flex {
max-width: calc(100% - 10px);
}
${CODE_BLOCK_STYLES}
.ProseMirror.break-words.ProseMirror-focused {
max-width: 100%;
}
body > div.flex.min-h-screen.w-full div.flex.flex-col div.flex.gap-2 div.mt-1.max-h-96.w-full.overflow-y-auto.break-words > div.ProseMirror.break-words {
max-width: 90%;
}
main > div.composer-parent article > div.text-base > div.mx-auto,
main article > div.text-base > div.mx-auto {
max-width: ${STYLE_CONFIG.maxWidth};
}
body > div.flex.min-h-screen.w-full > div > main > div.top-5.z-10.mx-auto.w-full.max-w-2xl.md,
body > div.flex.min-h-screen.w-full > div > main > div.mx-auto.w-full.max-w-2xl.px-1.md {
max-width: 100%;
}
body > div.flex.min-h-screen.w-full > div > main.max-w-7xl {
max-width: 90rem;
}
`
};
// 平台映射配置
const PLATFORM_MAP = {
'kimi.moonshot.cn': 'kimi',
'chat.deepseek.com': 'deepseek',
'tongyi.aliyun.com': 'tongyi',
'tiangong.cn': 'tiangong',
'chatglm.cn': 'chatglm',
'gemini.google.com': 'gemini'
};
// 检测当前平台并应用相应样式
function applyPlatformStyles() {
try {
const host = window.location.hostname;
let platformKey = 'default';
// 使用平台映射检测当前平台
for (const [domain, key] of Object.entries(PLATFORM_MAP)) {
if (host.includes(domain)) {
platformKey = key;
break;
}
}
// 应用对应平台的样式
const styleToApply = PLATFORM_STYLES[platformKey] || PLATFORM_STYLES.default;
GM_addStyle(styleToApply);
console.log(`[AI Chat Enhancer] Applied styles for platform: ${platformKey}`);
} catch (error) {
console.error('[AI Chat Enhancer] Error applying styles:', error);
}
}
// 优化链接处理
function enhanceLinks() {
// 使用防抖避免频繁调用
if (enhanceLinks.timer) {
clearTimeout(enhanceLinks.timer);
}
try {
const links = document.querySelectorAll('div[data-message-id] a[rel="noreferrer"]');
if (links.length > 0) {
links.forEach(link => {
if (!link.href && link.innerText && link.innerText.trim()) {
const linkText = link.innerText.trim();
// 仅处理有效链接文本
if (linkText.startsWith('http') || linkText.includes('www.')) {
link.href = linkText;
link.target = "_blank";
link.rel = "noopener noreferrer";
}
}
});
}
} catch (error) {
console.error('[AI Chat Enhancer] Error enhancing links:', error);
}
// 使用MutationObserver替代递归调用,降低性能消耗
enhanceLinks.timer = setTimeout(() => {
if (!enhanceLinks.observer) {
// 创建观察器,监听DOM变化
enhanceLinks.observer = new MutationObserver((mutations) => {
const shouldProcess = mutations.some(mutation =>
mutation.addedNodes.length > 0 ||
(mutation.type === 'attributes' && mutation.attributeName === 'href')
);
if (shouldProcess) {
enhanceLinks();
}
});
// 开始观察文档变化
enhanceLinks.observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['href']
});
}
}, 2000);
}
// 初始化
function init() {
// 在DOMContentLoaded后执行
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
applyPlatformStyles();
enhanceLinks();
});
} else {
// 文档已经加载完成
applyPlatformStyles();
enhanceLinks();
}
// 监听页面变化,适应单页应用
window.addEventListener('popstate', applyPlatformStyles);
window.addEventListener('pushstate', applyPlatformStyles);
window.addEventListener('replacestate', applyPlatformStyles);
}
// 启动脚本
init();
})();