LeetCode 問題描述內容擷取器

在 LeetCode 問題頁面上,按下按鈕後直接複製描述內容到剪貼簿。

// ==UserScript==
// @name         LeetCode 問題描述內容擷取器
// @namespace    https://abc0922001.github.io/leetcode-userscripts
// @version      1.2
// @description  在 LeetCode 問題頁面上,按下按鈕後直接複製描述內容到剪貼簿。
// @author       abc0922001
// @match        https://leetcode.com/problems/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // 等待指定選取器元素出現
    function waitForElement(selector, timeout = 5000) {
        return new Promise((resolve, reject) => {
            const el = document.querySelector(selector);
            if (el) {
                return resolve(el);
            }
            const observer = new MutationObserver((mutations, obs) => {
                const el = document.querySelector(selector);
                if (el) {
                    obs.disconnect();
                    resolve(el);
                }
            });
            observer.observe(document.body, { childList: true, subtree: true });
            setTimeout(() => {
                observer.disconnect();
                reject(new Error('Timeout'));
            }, timeout);
        });
    }

    // 建立按鈕
    const btn = document.createElement('button');
    btn.textContent = '複製描述';
    btn.style.position = 'fixed';
    btn.style.top = '10px';
    btn.style.right = '10px';
    btn.style.zIndex = 1000;
    document.body.appendChild(btn);

    btn.addEventListener('click', () => {
        waitForElement('div.elfjS[data-track-load="description_content"]', 5000)
            .then(targetDiv => {
                const htmlContent = targetDiv.innerHTML;
                navigator.clipboard.writeText(htmlContent)
                    .then(() => {
                        alert('描述內容已複製到剪貼簿!');
                    })
                    .catch(err => {
                        alert('複製失敗:' + err);
                    });
            })
            .catch(err => {
                alert('找不到目標內容');
                console.error(err);
            });
    });
})();