CMS文档上传
一个小工具,实现了文档上传的功能,比较简单,感谢Claude!

某中文自媒体网站*.docx文件上传解析插件

// ==UserScript==
// @name         CKEditor DOCX Upload Helper
// @namespace    http://tampermonkey.net/
// @version      0.1.2
// @description  Adds DOCX upload functionality to CKEditor 4.4.1
// @author       Zhao-Leo
// @match        http*://example.com/*
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.4.0/mammoth.browser.min.js
// ==/UserScript==

(function () {
    'use strict';
    let initializationCount = 0;
    const DEBUG = true;
    function debugLog(...args) {
        if (DEBUG) {
            console.log('[CKEditor DOCX Helper]', ...args);
        }
    }

    // Create a MutationObserver to watch for CKEditor initialization
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            if (mutation.addedNodes && mutation.addedNodes.length > 0) {
                // Check if CKEDITOR object exists and has instances
                if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances) {
                    const instances = Object.keys(CKEDITOR.instances);
                    if (instances.length > 0) {
                        debugLog('CKEditor detected:', instances);
                        // Check if the editor is fully initialized
                        const editor = CKEDITOR.instances[instances[0]];
                        if (editor && editor.container && editor.container.$) {
                            debugLog('Editor fully initialized');
                            observer.disconnect();
                            initializeUploader(editor);
                        } else {
                            debugLog('Editor instance found but not fully initialized');
                        }
                    }
                }
            }
        });
    });

    // Start observing
    debugLog('Starting observer...');
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    function initializeUploader(editor) {
        if (initializationCount > 0) {
            debugLog('Uploader already initialized');
            return;
        }
        if (!editor || !editor.container || !editor.container.$) {
            debugLog('Editor not properly initialized');
            return;
        }

        debugLog('Initializing uploader for editor:', editor.name);
        initializationCount++;
        // Create upload button
        const button = document.createElement('button');
        button.type = 'button';
        button.textContent = '上传文档文件';
        button.style.cssText = `
            padding: 5px 10px;
            margin: 5px;
            background-color: #2196F3;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
        `;

        // Create file input
        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = '.docx';
        fileInput.style.display = 'none';

        // Insert elements before the editor
        const editorElement = editor.container.$;
        editorElement.parentNode.insertBefore(button, editorElement);
        editorElement.parentNode.insertBefore(fileInput, editorElement);

        debugLog('Upload button and file input created');

        // Handle click event
        button.onclick = (e) => {
            e.preventDefault();
            e.stopPropagation(); // 阻止事件冒泡
            debugLog('Upload button clicked');
            fileInput.click();
        };

        // Handle file selection
        fileInput.onchange = async (event) => {
            const file = event.target.files[0];
            if (!file) return;

            try {
                debugLog('Starting file processing...');
                const arrayBuffer = await file.arrayBuffer();
                const result = await mammoth.convertToHtml({ arrayBuffer });

                let html = result.value;
                const images = result.messages.filter(msg => msg.type === 'image');

                // 处理图片
                for (let i = 0; i < images.length; i++) {
                    const image = images[i];
                    const blob = new Blob([image.imageData.buffer], { type: image.mimeType });
                    const base64 = await new Promise(resolve => {
                        const reader = new FileReader();
                        reader.onloadend = () => resolve(reader.result);
                        reader.readAsDataURL(blob);
                    });

                    // 直接将base64图片插入HTML
                    html = html.replace(new RegExp(`<img[^>]*>`, 'i'), `<img src="${base64}">`);
                }

                // 清理HTML,只保留加粗格式
                // const tempDiv = document.createElement('div');
                // tempDiv.innerHTML = html;

                // const clean = (node) => {
                //     if (node.nodeType === 3) return;

                //     const isBold = node.tagName === 'STRONG' ||
                //         node.tagName === 'B' ||
                //         window.getComputedStyle(node).fontWeight === 'bold';

                //     if (isBold) {
                //         const bold = document.createElement('strong');
                //         bold.textContent = node.textContent;
                //         node.parentNode.replaceChild(bold, node);
                //     } else if (node.children && node.children.length) {
                //         Array.from(node.children).forEach(clean);
                //         if (node.tagName !== 'P' && node.tagName !== 'IMG') {
                //             while (node.firstChild) {
                //                 node.parentNode.insertBefore(node.firstChild, node);
                //             }
                //             node.parentNode.removeChild(node);
                //         }
                //     } else if (node.tagName !== 'IMG') {
                //         const text = document.createTextNode(node.textContent);
                //         node.parentNode.replaceChild(text, node);
                //     }
                // };

                // Array.from(tempDiv.children).forEach(clean);

                // // 直接设置内容到编辑器
                // editor.setData(tempDiv.innerHTML);
                editor.setData(html);
                debugLog('Content set to editor');

                // 重置文件输入
                fileInput.value = '';

            } catch (error) {
                console.error('[CKEditor DOCX Helper] Error:', error);
                alert('文档处理错误,请重试。');
            }
        };
        debugLog('Uploader initialization completed');
    }

    debugLog('Script loaded');
})();

最后修改于 2025-02-10