1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
// ==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');
})();
|