沖浪高手檢測機

检测微博用户的发言浓度

// ==UserScript==
// @name         沖浪高手檢測機
// @namespace    https://github.com/SomiaWhiteRing/weibo-toilet-test/
// @license      MIT
// @version      0.2
// @description  检测微博用户的发言浓度
// @author       苍旻白轮
// @match        *://weibo.com/u/*
// @match        *://www.weibo.com/u/*
// @grant        GM_addStyle
// ==/UserScript==

(function () {
  'use strict';
  // 测试模式开关
  const DEBUG_MODE = false;  // 设为 true 开启测试模式

  // 词库定义
  const STORAGE_KEY = 'weibo-toilet-words';
  const TITLE_STORAGE_KEY = 'weibo-toilet-title';

  const defaultWords = [
    "完完全全我", "女王", "这真的是我", "笑死我了", "女王一枚", "本宝", "互关", "啊啊啊啊啊这真的是我",
    "本宝宝", "我对老公", "我对室友", "态度", "心情", "熏情", "mood", "木的", "好想吃", "我帮他",
    "我真的会这样", "互关爱吃", "呃呃呃", "他/她怎么了", "就是那个谁", "那个谁真的死了", "我就长这样",
    "你长得好吗", "你不要这样说好吗", "我老了以后", "互关老了以后", "扣一下", "很好笑", "好那个", "我老公",
    "吃一下omg", "欧米茄", "天呐", "天哪", "这也太", "妈妈", "尊的是我", "长成这样我不知道我", "那里好痒",
    "本女子", "我那里有事", "湿了", "是谁", "私我", "谢谢老公", "谢谢宝宝", "嗯嘟", "我们来了",
    "我们走了", "隐隐约约听说", "我帮你", "还以为是**走了出来", "我跟你们有钱人拼了", "我要卖了",
    "穷", "焦虑", "受不了了", "fjgjdnvid", "求你们看", "这一次我一定要赢", "slau", "崩溃", "b溃了", "奔溃",
    "笑得好崩溃", "做不到这样别和我", "我老公必须这样", "我不行了", "好想鼠", "不想", "活了", "wob我不行了",
    "咋了集美", "秒了", "一秒睡了", "哭了", "喷了", "哭了", "够了", "服了", "我真的在哭", "泪流满面了",
    "我老公呢", "我的老公在哪里", "我和老公", "笑得我那里疼", "好想尖叫", "尖叫了", "wflbb", "我文化水平",
    "我做题", "我解决问题", "哎呦喂", "我求你了", "年度视频", "年度",
    "legend", "iconic", "对不起", "我下跪", "对不已", "寸不己", "已构成一种", "喂", "首页又在", "这是在干什么",
    "我真的要双了", "我真的要拉黑了", "再发一个试试呢", "好嫉妒", "好季度", "好羡慕", "好精彩", "强势围观",
    "我天呢", "没什么好说的", "封神", "好封神", "好震撼", "好美", "好米", "好难听", "概念感觉", "好丑",
    "好穷", "有点像那个谁", "这可以是我们", "闺蜜", "诡秘", "好闺蜜", "彪子", "怎么办",
    "谁能送我", "好想要", "那个了", "怎么火了", "已举办", "谁问了", "没人问", "小姐姐你", "姐妹你", "这是在干什么",
    "谁来管管", "别逼我", "我不知道这世界到底怎么了", "怎么你了", "什么意思呢", "我请问", "不认识", "nbcs", "我是",
    "换id了", "前世是", "互关帮我转转", "早就说过"
  ];

  let words; // 改为变量声明
  let activeWords; // 将 activeWords 改为变量声明

  // 修改获取或初始化词库函数
  function initializeWords() {
    let storedWords = localStorage.getItem(STORAGE_KEY);
    if (!storedWords) {
      localStorage.setItem(STORAGE_KEY, JSON.stringify(defaultWords));
      words = defaultWords;
    } else {
      words = JSON.parse(storedWords);
    }
    // 根据测试模式决定使用��词库
    activeWords = DEBUG_MODE ? words.slice(0, 10) : words;
  }

  // 在词库定义后立即执行初始化
  initializeWords();

  GM_addStyle(`
        .toilet-check-btn {
            display: inline-block;
            padding: 4px 8px;
            margin-left: 8px;
            border-radius: 4px;
            background: #ff8200;
            color: #fff;
            font-size: 12px;
            cursor: pointer;
            vertical-align: middle;
            outline: none !important;
            user-select: none;
            -webkit-tap-highlight-color: transparent;
        }

        .toilet-check-btn:focus {
            outline: none !important;
            box-shadow: none !important;
        }

        .toilet-modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            z-index: 9999;
        }

        .toilet-modal-content {
            position: relative;
            width: 600px;
            margin: 100px auto;
            padding: 20px;
            background: #fff;
            border-radius: 8px;
        }

        .toilet-dialog {
            border: none;
            border-radius: 12px;
            padding: 0;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
            display: flex;
            flex-direction: column;
        }

        .toilet-dialog:focus {
            outline: none;
        }

        .toilet-dialog::backdrop {
            background: rgba(0, 0, 0, 0.5);
        }

        .toilet-header {
            position: sticky;
            top: 0;
            padding: 16px 80px;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(10px);
            border-bottom: 1px solid rgba(0, 0, 0, 0.1);
            z-index: 1;
            border-radius: 12px 12px 0 0;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .toilet-close-btn {
            position: absolute;
            top: 16px;
            right: 16px;
            width: 28px;
            height: 28px;
            border-radius: 50%;
            background: rgba(0, 0, 0, 0.05);
            display: none;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .toilet-close-btn:hover {
            background: rgba(0, 0, 0, 0.1);
            transform: rotate(90deg);
        }

        .toilet-close-btn::before,
        .toilet-close-btn::after {
            content: '';
            position: absolute;
            width: 16px;
            height: 2px;
            background: #666;
            border-radius: 1px;
        }

        .toilet-close-btn::before {
            transform: rotate(45deg);
        }

        .toilet-close-btn::after {
            transform: rotate(-45deg);
        }

        .toilet-content {
            flex: 1;
            overflow-y: auto;
            border: none;
            scroll-behavior: smooth;
            scrollbar-width: thin;
            scrollbar-color: rgba(78, 205, 196, 0.6) transparent;
        }

        .toilet-content::-webkit-scrollbar {
            width: 8px;
        }

        .toilet-content::-webkit-scrollbar-track {
            background: transparent;
        }

        .toilet-content::-webkit-scrollbar-thumb {
            background-color: rgba(78, 205, 196, 0.6);
            border-radius: 4px;
        }

        .toilet-title {
            font-size: 32px;
            font-weight: 600;
            background: linear-gradient(45deg, #FF6B6B, #4ECDC4);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            text-align: center;
        }

        .toilet-progress-container {
            position: relative;
            width: 200px;
            height: 200px;
            margin: 24px auto;
        }

        .toilet-progress-circle {
            position: absolute;
            width: 100%;
            height: 100%;
            border-radius: 50%;
            background: conic-gradient(
                #4ECDC4 var(--progress-percent),
                #eee var(--progress-percent)
            );
            transition: all 0.3s ease;
        }

        .toilet-progress-inner {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 160px;
            height: 160px;
            background: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
            color: #333;
        }

        .toilet-result-container {
            padding: 20px;
            border-radius: 8px;
            background: rgba(245, 245, 245, 0.9);
        }

        .toilet-chart-container {
            margin-top: 24px;
            padding: 16px;
            border-radius: 8px;
            background: white;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
        }

        .toilet-keywords-cloud {
            margin-top: 24px;
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            justify-content: center;
        }

        .toilet-keyword-item {
            padding: 6px 12px;
            border-radius: 16px;
            background: rgba(78, 205, 196, 0.1);
            color: #4ECDC4;
            font-size: 14px;
            transition: all 0.3s ease;
        }

        .toilet-keyword-item:hover {
            background: rgba(78, 205, 196, 0.2);
            transform: translateY(-2px);
        }

        .github-corner {
            position: absolute;
            top: 0;
            left: 0;
            border-radius: 12px 0 8px 0;
            transform: scale(-0.7, 0.7);
            transform-origin: top left;
        }

        .github-corner svg {
            fill: #151513;
            color: #fff;
            position: absolute;
            top: 0;
            left: -80px;
            border: 0;
            outline: none !important;
        }

        .github-corner:focus-visible {
            outline: none !important;
        }

        .github-corner svg:focus-visible {
            outline: none !important;
        }

        .github-corner:hover .octo-arm {
            animation: octocat-wave 560ms ease-in-out;
        }

        @keyframes octocat-wave {
            0%, 100% { transform: rotate(0) }
            20%, 60% { transform: rotate(25deg) }
            40%, 80% { transform: rotate(-10deg) }
        }
    `);

  // 自定义日志函数
  const log = (...args) => {
    if (DEBUG_MODE) {
      console.log(...args);
    }
  };

  const error = (...args) => {
    if (DEBUG_MODE) {
      console.error(...args);
    }
  };

  // 初始化
  function init() {
    // 先找到头像元素
    const avatarMain = document.querySelector('.woo-avatar-main');
    if (avatarMain) {
      // 找到头像后面的元素中的目标容器
      const container = avatarMain.nextElementSibling?.querySelector('.woo-box-flex.woo-box-alignCenter');
      if (container) {
        addButton(container);
      }
    }
  }

  // 添加按钮
  function addButton(container) {
    // 检查按钮是否已存在
    if (!container.querySelector('.toilet-check-btn')) {
      const buttonContainer = document.createElement('div');
      buttonContainer.style.display = 'flex';
      buttonContainer.style.gap = '8px';

      // 检测按钮
      const checkButton = document.createElement('div');
      checkButton.className = 'toilet-check-btn';
      checkButton.textContent = '🚽';
      checkButton.onclick = startCheck;

      // 编辑按钮
      const editButton = document.createElement('div');
      editButton.className = 'toilet-check-btn toilet-edit-btn';
      editButton.textContent = '📝';
      editButton.style.backgroundColor = '#808080';
      editButton.onclick = openWordEditor;

      buttonContainer.appendChild(checkButton);
      buttonContainer.appendChild(editButton);
      container.appendChild(buttonContainer);
      console.log('按钮添加成功!');
    }
  }

  // 监视DOM变化
  function observeDOM() {
    const observer = new MutationObserver((mutations) => {
      const avatarMain = document.querySelector('.woo-avatar-main');
      if (avatarMain) {
        const container = avatarMain.nextElementSibling?.querySelector('.woo-box-flex.woo-box-alignCenter');
        if (container) {
          addButton(container);
        }
      }
    });

    // 监视整个文档
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }

  // 动态加载 Chart.js
  function loadChartJs() {
    return new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.src = 'https://cdn.jsdelivr.net/npm/chart.js';
      script.onload = resolve;
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }

  // 等待 Chart.js 加载完成再初始化
  loadChartJs().then(() => {
    init();
    observeDOM();
  }).catch(err => {
    console.error('加载 Chart.js 失败:', err);
  });

  // 创建并显示对话框
  function createDialog() {
    // 保存html原始的overflow值
    const originalOverflow = document.documentElement.style.overflow;
    // 设置html为hidden以防止滚动
    document.documentElement.style.overflow = 'hidden';

    const dialog = document.createElement('dialog');
    dialog.className = 'toilet-dialog';
    dialog.style.width = '80%';
    dialog.style.height = '80%';
    dialog.style.maxWidth = '1280px';
    document.body.appendChild(dialog);

    // 创建固定的头部
    const header = document.createElement('div');
    header.className = 'toilet-header';
    dialog.appendChild(header);

    // 添加 GitHub 角标
    const githubCorner = document.createElement('a');
    githubCorner.href = 'https://github.com/SomiaWhiteRing/weibo-toilet-test';  // 替换为你的 GitHub 仓库地址
    githubCorner.className = 'github-corner';
    githubCorner.setAttribute('target', '_blank');
    githubCorner.innerHTML = `
        <svg width="80" height="80" viewBox="0 0 250 250">
            <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
            <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" class="octo-arm"></path>
            <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
        </svg>
    `;
    header.appendChild(githubCorner);

    const title = document.createElement('div');
    title.className = 'toilet-title';
    title.textContent = localStorage.getItem(TITLE_STORAGE_KEY) || '廁言廁語檢測機';
    header.appendChild(title);

    // 添加关闭按钮(默认隐藏)
    const closeBtn = document.createElement('div');
    closeBtn.className = 'toilet-close-btn';
    closeBtn.onclick = () => {
      dialog.close();
      // 恢复html的overflow
      document.documentElement.style.overflow = originalOverflow;
    };
    header.appendChild(closeBtn);

    // 创建可滚动的内容区域
    const content = document.createElement('div');
    content.className = 'toilet-content';
    dialog.appendChild(content);

    const progressContainer = document.createElement('div');
    progressContainer.className = 'toilet-progress-container';
    content.appendChild(progressContainer);

    const progressCircle = document.createElement('div');
    progressCircle.className = 'toilet-progress-circle';
    progressContainer.appendChild(progressCircle);

    const progressInner = document.createElement('div');
    progressInner.className = 'toilet-progress-inner';
    progressContainer.appendChild(progressInner);

    // 监听dialog关闭事件,清理内容
    dialog.addEventListener('close', () => {
      document.documentElement.style.overflow = originalOverflow;
      // 清理内容
      content.innerHTML = '';
      dialog.remove(); // 完全移除dialog元素
    });

    dialog.showModal();
    return { dialog, progressCircle, progressInner, content, closeBtn };
  }

  // 修改 RequestPool 类
  class RequestPool {
    constructor(maxConcurrent, logFn, errorFn) {
      this.maxConcurrent = maxConcurrent;
      this.running = 0;
      this.queue = [];
      this.results = {};
      this.completedCount = 0;
      this.totalCount = 0;
      this.onProgress = null;
      this.log = logFn;
      this.error = errorFn;

      // 错误频率检测
      this.errorTimes = [];
      this.isWaiting = false;

      // 添加重试计数器
      this.retryCount = new Map();
    }

    // 检查错误频率
    checkErrorFrequency() {
      const now = Date.now();
      // 清理超过1秒的错误记录
      this.errorTimes = this.errorTimes.filter(time => now - time < 1000);
      // 添加新的错误时间
      this.errorTimes.push(now);

      // 如果1秒内错误次数超过10次
      if (this.errorTimes.length >= 10) {
        return true;
      }
      return false;
    }

    async add(task) {
      this.totalCount++;
      if (this.running >= this.maxConcurrent) {
        await new Promise(resolve => this.queue.push(resolve));
      }
      this.running++;
      try {
        const result = await task();
        this.results[result.keyword] = result.count;
      } catch (error) {
        // 获取当前任务的关键词
        const keyword = await task().catch(e => e.keyword);

        // 更新重试计数
        const currentRetries = this.retryCount.get(keyword) || 0;
        this.retryCount.set(keyword, currentRetries + 1);

        this.error(`任务失败,关键词 "${keyword}" 第 ${currentRetries + 1} 次重试:`, error);

        // 检查重试次数
        if (currentRetries < 10) {
          // 检查错误频率
          if (this.checkErrorFrequency() && !this.isWaiting) {
            this.isWaiting = true;
            this.error('检测到频繁错误,等待3秒后继续...');
            await new Promise(resolve => setTimeout(resolve, 3000));
            this.errorTimes = []; // 清空错误记录
            this.isWaiting = false;
          }

          this.add(task);
          return;
        } else {
          this.error(`关键词 "${keyword}" 已达到最大重试次数,跳过`);
          this.results[keyword] = 0; // 将结果设为0
        }
      } finally {
        this.running--;
        this.completedCount++;
        if (this.onProgress) {
          this.onProgress(this.completedCount / this.totalCount * 100);
        }
        if (this.queue.length > 0) {
          const next = this.queue.shift();
          next();
        }
      }
    }

    async waitForAll() {
      while (this.running > 0 || this.queue.length > 0) {
        await new Promise(resolve => setTimeout(resolve, 100));
      }
      return this.results;
    }
  }

  // 修改主检流程
  async function startCheck() {
    log('开始检测流程');
    const userId = location.href.match(/https:\/\/(?:www\.)?weibo\.com\/u\/(\d+)/)?.[1];
    if (!userId) {
      error('无法获取用户ID');
      alert('错误:无法从URL获取用户ID');
      return;
    }
    log(`获取到用户ID: ${userId}`);

    const { dialog, progressCircle, progressInner, content, closeBtn } = createDialog();

    // 创建请求池时传入日志函数
    const pool = new RequestPool(5, log, error);

    // 设置进度回调
    pool.onProgress = (percent) => {
      progressCircle.style.setProperty('--progress-percent', `${percent}%`);
      progressInner.textContent = `${Math.round(percent)}%`;
    };

    // 将所有任务添加到池中
    const tasks = activeWords.map(word => () => {
      // 添加随机延迟,避免请求过于集中
      const randomDelay = Math.random() * 200;
      return new Promise(resolve => setTimeout(resolve, randomDelay))
        .then(() => checkKeyword(userId, word));
    });

    // 启动所有任务
    await Promise.all(tasks.map(task => pool.add(task)));

    // 等待所有任务完成
    const wordCounts = await pool.waitForAll();

    // 绘制结果
    drawChart(dialog, wordCounts);
  }

  // 修改 checkKeyword 函数,添加关键词信息到错误对象
  async function checkKeyword(userId, keyword) {
    log(`开始检查关键词: ${keyword}`);
    try {
      const baseUrl = location.href.includes('www.weibo.com') ?
        'https://www.weibo.com' :
        'https://weibo.com';

      const response = await fetch(`${baseUrl}/ajax/statuses/searchProfile?uid=${userId}&q=${encodeURIComponent(keyword)}`);
      const data = await response.json();

      if (!response.ok || !data.data) {
        const error = new Error('请求失败');
        error.keyword = keyword;
        throw error;
      }

      return {
        keyword,
        count: data.data.total || 0
      };
    } catch (error) {
      error.keyword = keyword;
      error(`检查关键词 "${keyword}" 失败:`, error);
      throw error;
    }
  }

  // 绘制结果图表
  function drawChart(dialog, wordCounts) {
    const header = dialog.querySelector('.toilet-header');
    const content = dialog.querySelector('.toilet-content');
    const closeBtn = dialog.querySelector('.toilet-close-btn');

    // 显示关闭按钮
    closeBtn.style.display = 'flex';

    // 保留header,清空content
    content.innerHTML = '';
    header.querySelector('.toilet-title').textContent = localStorage.getItem(TITLE_STORAGE_KEY) || '廁言廁語檢測機';

    const resultContainer = document.createElement('div');
    resultContainer.className = 'toilet-result-container';
    content.appendChild(resultContainer);

    const chartContainer = document.createElement('div');
    chartContainer.className = 'toilet-chart-container';
    const canvas = document.createElement('canvas');
    chartContainer.appendChild(canvas);
    resultContainer.appendChild(chartContainer);

    // 序词频
    const sortedWords = Object.entries(wordCounts)
      .sort(([, a], [, b]) => b - a);

    // 绘制图表
    new Chart(canvas.getContext('2d'), {
      type: 'bar',
      data: {
        labels: sortedWords.slice(0, 15).map(([word]) => word),
        datasets: [{
          label: '出现次数',
          data: sortedWords.slice(0, 15).map(([, count]) => count),
          backgroundColor: 'rgba(78, 205, 196, 0.6)',
          borderColor: 'rgba(78, 205, 196, 1)',
          borderWidth: 1,
          borderRadius: 8,
        }]
      },
      options: {
        responsive: true,
        plugins: {
          legend: {
            display: false
          },
          title: {
            display: true,
            text: '高频词汇统计',
            font: {
              size: 16,
              weight: 'bold'
            }
          }
        },
        scales: {
          y: {
            beginAtZero: true,
            grid: {
              display: false
            }
          },
          x: {
            grid: {
              display: false
            }
          }
        }
      }
    });

    // 创建关键词云
    const keywordsCloud = document.createElement('div');
    keywordsCloud.className = 'toilet-keywords-cloud';
    sortedWords.slice(15).forEach(([word, count]) => {
      if (count == 0) return;
      const keywordItem = document.createElement('div');
      keywordItem.className = 'toilet-keyword-item';
      keywordItem.textContent = `${word} (${count})`;
      keywordsCloud.appendChild(keywordItem);
    });
    resultContainer.appendChild(keywordsCloud);
  }

  // 添加词库编辑器相关样式
  GM_addStyle(`
    .toilet-edit-textarea {
        width: calc(100% - 40px);
        height: 400px;
        margin: 20px;
        padding: 12px;
        border: 1px solid #ddd;
        border-radius: 8px;
        font-family: monospace;
        resize: vertical;
        box-sizing: border-box;
    }

    .toilet-title-input {
        width: 100%;
        padding: 8px;
        font-size: 24px;
        border: 1px solid rgba(0, 0, 0, 0.1);
        border-radius: 8px;
        background: transparent;
        color: inherit;
        text-align: center;
        font-weight: 600;
        background: linear-gradient(45deg, #FF6B6B, #4ECDC4);
        -webkit-background-clip: text;
        -webkit-text-fill-color: transparent;
        box-sizing: border-box;
    }

    .toilet-title-input:focus {
        outline: none;
        border-color: rgba(78, 205, 196, 0.5);
    }

    .toilet-save-btn {
        display: block;
        margin: 0 auto;
        padding: 8px 24px;
        border: none;
        border-radius: 20px;
        background: linear-gradient(45deg, #FF6B6B, #4ECDC4);
        color: white;
        font-size: 16px;
        cursor: pointer;
        transition: all 0.3s ease;
    }

    .toilet-save-btn:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    }
  `);

  // 添加词库编辑器功能
  function openWordEditor() {
    const { dialog, content } = createDialog();

    // 隐藏进度条相关元素
    content.querySelector('.toilet-progress-container')?.remove();

    // 将标题改为可编辑的输入框
    const titleElement = dialog.querySelector('.toilet-title');
    const titleInput = document.createElement('input');
    titleInput.type = 'text';
    titleInput.className = 'toilet-title-input';
    // 从 localStorage 读取标题,如果没有则使用默认标题
    titleInput.value = localStorage.getItem(TITLE_STORAGE_KEY) || '廁言廁語檢測機';
    titleInput.placeholder = '输入标题';
    titleElement.replaceWith(titleInput);

    // 创建文本区域
    const textarea = document.createElement('textarea');
    textarea.className = 'toilet-edit-textarea';
    textarea.value = JSON.parse(localStorage.getItem(STORAGE_KEY)).join('\n');
    content.appendChild(textarea);

    // 创建保存按钮
    const saveButton = document.createElement('button');
    saveButton.className = 'toilet-save-btn';
    saveButton.textContent = '保存更改';
    saveButton.onclick = () => {
      const newWords = textarea.value
        .split('\n')
        .map(word => word.trim())
        .filter(word => word);
      localStorage.setItem(STORAGE_KEY, JSON.stringify(newWords));
      localStorage.setItem(TITLE_STORAGE_KEY, titleInput.value);

      // 重新初始化词库
      initializeWords();

      dialog.close();
    };
    content.appendChild(saveButton);

    // 修改关闭按钮的处理方式
    const closeBtn = dialog.querySelector('.toilet-close-btn');
    closeBtn.style.display = 'flex';
    closeBtn.onclick = () => {
      content.innerHTML = ''; // 清理内容
      dialog.close();
      dialog.remove(); // 完全移除dialog元素
    };
  }
})();