// ==UserScript==
// @name 太美了
// @namespace http://tampermonkey.net/
// @version 1.1
// @description 美化文档格式,添加标题序号,调整样式等
// @author weihao2293
// @match *://*.km.sankuai.com/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 添加 iconfont 样式
function addIconFont() {
const style = document.createElement('style');
style.textContent = `
@font-face {
font-family: "iconfont";
src: url('//at.alicdn.com/t/font_1444750_kz0d4j05q4.eot');
src: url('//at.alicdn.com/t/font_1444750_kz0d4j05q4.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1444750_kz0d4j05q4.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1444750_kz0d4j05q4.woff') format('woff'),
url('//at.alicdn.com/t/font_1444750_kz0d4j05q4.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1444750_kz0d4j05q4.svg#iconfont') format('svg');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.ct-icon-ai:before {
content: "\\e65b"; /* 这是一个示例,需要替换为正确的图标编码 */
}
/* 添加折叠图标样式 */
.heading-collapse-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
margin-right: 5px;
cursor: pointer;
transition: transform 0.3s;
user-select: none;
position: relative;
top: -1px;
vertical-align: middle;
}
.heading-collapse-btn::before {
content: '▼';
font-size: 12px;
color: #666;
line-height: 1;
}
.heading-collapse-btn.collapsed::before {
content: '▶';
}
.content-collapsed {
display: none !important;
}
`;
document.head.appendChild(style);
}
// 创建并添加按钮
function createBeautifyButton() {
const button = document.createElement('button');
button.textContent = '太美了';
button.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
z-index: 9999;
padding: 8px 20px;
font-size: 13px;
font-weight: 500;
color: white;
background: linear-gradient(90deg,
#6631FF 0%,
#A431FF 50%,
#EE89FF 100%
);
border: none;
border-radius: 100px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 0 5px rgba(156, 111, 228, 0.2);
`;
// 添加动画关键帧到文档
const style = document.createElement('style');
style.textContent = `
@keyframes glowing {
from {
box-shadow: 0 0 5px rgba(156, 111, 228, 0.2),
0 0 0.5px #fff,
0 0 2px #fff,
0 0 8px rgba(164, 49, 255, 0.5),
0 0 12px rgba(102, 49, 255, 0.3);
}
to {
box-shadow: 0 0 8px rgba(156, 111, 228, 0.2),
0 0 1px #fff,
0 0 3px #fff,
0 0 15px rgba(164, 49, 255, 0.4),
0 0 25px rgba(102, 49, 255, 0.2);
}
}
`;
document.head.appendChild(style);
// 添加悬停效果
button.onmouseenter = () => {
button.style.transform = 'translateY(-2px) scale(1.05)';
button.style.filter = 'brightness(1.2)';
button.style.animation = 'glowing 1.5s ease-in-out infinite alternate';
};
button.onmouseleave = () => {
button.style.transform = 'translateY(0) scale(1)';
button.style.filter = 'brightness(1)';
button.style.animation = 'none';
button.style.boxShadow = '0 0 5px rgba(156, 111, 228, 0.2)';
};
document.body.appendChild(button);
return button;
}
// 设置标准宽度
function setStandardWidth() {
window.widthType = 1;
}
// 处理标题
function processHeadings() {
const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
let currentNumbers = [0, 0, 0, 0, 0, 0]; // 用于跟踪每个级别的编号
// 找到最高级别和最低级别的标题
let highestLevel = 6;
let lowestLevel = 1;
headings.forEach(heading => {
const level = parseInt(heading.tagName[1]);
highestLevel = Math.min(highestLevel, level);
lowestLevel = Math.max(lowestLevel, level);
});
// 添加新序号和分隔线
headings.forEach((heading, index) => {
// 移除已有的序号
heading.innerHTML = heading.innerHTML.replace(/^[\d\.]+\s+/, '');
// 为除第一个标题外的所有标题添加分隔线,但只在没有分隔线时添加
if (index > 0 && !heading.previousElementSibling?.matches('hr.ct-node-view-dom')) {
const hr = document.createElement('hr');
hr.className = 'ct-node-view-dom';
hr.setAttribute('contenteditable', 'false');
hr.style.display = 'block';
heading.parentNode.insertBefore(hr, heading);
}
// 处理标题内的所有 span 元素
const spans = heading.querySelectorAll('span');
spans.forEach(span => {
// 移除背景色
if (span.classList.contains('text-background-color')) {
span.style.setProperty('background-color', 'transparent', 'important');
span.classList.remove('text-background-color');
}
// 设置文字颜色为黑色
span.style.setProperty('color', '#000000', 'important');
});
// 获取标题文本内容(保留原有的 HTML 结构)
const originalContent = heading.innerHTML;
// 计算相对级别(从1开始)
const absoluteLevel = parseInt(heading.tagName[1]);
const relativeLevel = absoluteLevel - highestLevel + 1;
const totalLevels = lowestLevel - highestLevel + 1; // 总共有几级标题
// 生成序号
let number = '';
if (relativeLevel === 1) {
// 最高级标题使用两位数字
currentNumbers[0]++;
// 重置所有子级编号
for (let i = 1; i < totalLevels; i++) {
currentNumbers[i] = 0;
}
number = String(currentNumbers[0]).padStart(2, '0');
} else {
// 子级标题
currentNumbers[relativeLevel - 1]++;
// 重置所有更低级别的编号
for (let i = relativeLevel; i < totalLevels; i++) {
currentNumbers[i] = 0;
}
// 生成序号:去掉前导零,然后添加子级序号
number = currentNumbers[0] + currentNumbers.slice(1, relativeLevel)
.map(num => '.' + num)
.join('');
}
// 添加序号
heading.innerHTML = number + ' ' + originalContent;
// 添加折叠按钮
const collapseBtn = document.createElement('span');
collapseBtn.className = 'heading-collapse-btn';
heading.insertBefore(collapseBtn, heading.firstChild);
// 添加点击事件
collapseBtn.addEventListener('click', (e) => {
e.stopPropagation();
const currentLevel = parseInt(heading.tagName[1]);
let element = heading.nextElementSibling;
const isCollapsed = collapseBtn.classList.toggle('collapsed');
while (element) {
// 如果遇到更高级别的标题,停止折叠
if (element.tagName && /^H[1-6]$/.test(element.tagName)) {
const elementLevel = parseInt(element.tagName[1]);
if (elementLevel <= currentLevel) {
break;
}
}
// 折叠或展开内容
element.classList.toggle('content-collapsed', isCollapsed);
element = element.nextElementSibling;
}
});
});
}
// 处理段落 - 只处理图片和状态标签相关的逻辑,不添加空行
function processParagraphs() {
const paragraphs = document.querySelectorAll('p');
paragraphs.forEach(p => {
// 跳过包含图片的段落和图片前面的段落
if (p.querySelector('.pk-image') ||
(p.nextElementSibling && p.nextElementSibling.querySelector('.pk-image'))) {
return;
}
// 跳过包含 pk-status 的段落
if (p.querySelector('.pk-status') ||
(p.nextElementSibling && p.nextElementSibling.querySelector('.pk-status'))) {
return;
}
});
}
// 主函数
function beautifyDocument() {
setStandardWidth();
processHeadings();
processParagraphs();
// 移除所有已有的折叠状态
document.querySelectorAll('.content-collapsed').forEach(el => {
el.classList.remove('content-collapsed');
});
}
// 初始化
addIconFont();
const beautifyButton = createBeautifyButton();
beautifyButton.addEventListener('click', beautifyDocument);
})();