|
|
@@ -814,16 +814,15 @@ export default {
|
|
|
|
|
|
// 如果成功获取到内容,则执行插入操作
|
|
|
if (text || htmlContent) {
|
|
|
- // 如果有HTML内容,先处理HTML以清理超链接样式
|
|
|
- if (htmlContent && htmlContent.trim()) {
|
|
|
- console.log('Processing HTML content from clipboard');
|
|
|
- const processedHtml = this.processPastedHtml(htmlContent);
|
|
|
- // 使用处理后的HTML内容
|
|
|
- this.editorRef.command.executeSetHTML({ main: processedHtml });
|
|
|
- } else if (text && text.trim()) {
|
|
|
- console.log('Processing plain text from clipboard');
|
|
|
- // 使用纯文本
|
|
|
- this.editorRef.command.executeInsertText(text);
|
|
|
+ // 统一按纯文本在光标处插入,避免覆盖整篇文档
|
|
|
+ let toInsert = text && text.trim() ? text : '';
|
|
|
+ if (!toInsert && htmlContent && htmlContent.trim()) {
|
|
|
+ const tempDiv = document.createElement('div');
|
|
|
+ tempDiv.innerHTML = htmlContent;
|
|
|
+ toInsert = tempDiv.textContent || tempDiv.innerText || '';
|
|
|
+ }
|
|
|
+ if (toInsert) {
|
|
|
+ this.editorRef.command.executeInsertText(toInsert);
|
|
|
} else {
|
|
|
console.warn('Both HTML and text content are empty or invalid.');
|
|
|
}
|
|
|
@@ -1013,165 +1012,14 @@ export default {
|
|
|
return originalExecuteSetHTML.call(instance.command, htmlData);
|
|
|
};
|
|
|
|
|
|
- // 添加全局粘贴事件监听器,确保所有粘贴操作都经过处理
|
|
|
+ // 仅在编辑区域挂载本地粘贴监听,避免拦截系统/浏览器菜单功能
|
|
|
const editorElement = document.querySelector(".canvas-editor");
|
|
|
if (editorElement) {
|
|
|
- // 创建事件处理器引用
|
|
|
this.eventHandlers = {
|
|
|
- paste: this.handlePaste.bind(this),
|
|
|
- keydown: (e) => {
|
|
|
- if ((e.ctrlKey || e.metaKey) && e.key === 'v') {
|
|
|
- e.preventDefault();
|
|
|
- this.handlePaste(e);
|
|
|
- }
|
|
|
- },
|
|
|
- contextmenu: (e) => {
|
|
|
- // 使用MutationObserver监听动态创建的右键菜单
|
|
|
- const observer = new MutationObserver((mutations) => {
|
|
|
- mutations.forEach((mutation) => {
|
|
|
- mutation.addedNodes.forEach((node) => {
|
|
|
- if (node.nodeType === Node.ELEMENT_NODE) {
|
|
|
- // 查找所有菜单项
|
|
|
- const allMenuItems = node.querySelectorAll ?
|
|
|
- node.querySelectorAll('*') : [];
|
|
|
-
|
|
|
- // 也检查节点本身
|
|
|
- const allItems = [...allMenuItems, node];
|
|
|
-
|
|
|
- allItems.forEach(item => {
|
|
|
- // 为所有菜单项添加点击事件监听器
|
|
|
- if (item.textContent && (
|
|
|
- item.textContent.includes('粘贴') ||
|
|
|
- item.textContent.includes('剪切') ||
|
|
|
- item.textContent.includes('全选') ||
|
|
|
- item.textContent.includes('打印') ||
|
|
|
- item.textContent.includes('签名') ||
|
|
|
- item.textContent.includes('格式整理')
|
|
|
- )) {
|
|
|
- console.log('Found menu item:', item.textContent);
|
|
|
- item.addEventListener('click', (e) => {
|
|
|
- e.preventDefault();
|
|
|
- e.stopPropagation();
|
|
|
- console.log('Menu item clicked:', item.textContent);
|
|
|
-
|
|
|
- // 处理特定功能
|
|
|
- if (item.textContent.includes('粘贴')) {
|
|
|
- this.handlePaste(e);
|
|
|
- }
|
|
|
-
|
|
|
- // 点击菜单项后关闭菜单
|
|
|
- setTimeout(() => {
|
|
|
- this.closeAllContextMenus();
|
|
|
- }, 100);
|
|
|
- }, true);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- // 开始观察文档变化
|
|
|
- observer.observe(document.body, {
|
|
|
- childList: true,
|
|
|
- subtree: true
|
|
|
- });
|
|
|
-
|
|
|
- // 5秒后停止观察(避免内存泄漏)
|
|
|
- setTimeout(() => {
|
|
|
- observer.disconnect();
|
|
|
- }, 5000);
|
|
|
- },
|
|
|
- documentPaste: (e) => {
|
|
|
- // 检查是否在编辑器区域内
|
|
|
- const editorElement = document.querySelector(".canvas-editor");
|
|
|
- if (editorElement && editorElement.contains(e.target)) {
|
|
|
- e.preventDefault();
|
|
|
- this.handlePaste(e);
|
|
|
- }
|
|
|
- }
|
|
|
+ paste: this.handlePaste.bind(this)
|
|
|
};
|
|
|
-
|
|
|
- // 监听所有可能的粘贴事件
|
|
|
editorElement.addEventListener('paste', this.eventHandlers.paste, true);
|
|
|
-
|
|
|
- // 监听键盘粘贴事件
|
|
|
- editorElement.addEventListener('keydown', this.eventHandlers.keydown, true);
|
|
|
-
|
|
|
- // 监听右键菜单粘贴(如果存在)
|
|
|
- editorElement.addEventListener('contextmenu', this.eventHandlers.contextmenu, true);
|
|
|
- }
|
|
|
-
|
|
|
- // 监听整个文档的粘贴事件作为备用
|
|
|
- if (this.eventHandlers) {
|
|
|
- document.addEventListener('paste', this.eventHandlers.documentPaste, true);
|
|
|
}
|
|
|
-
|
|
|
- // 添加全局的粘贴拦截,确保所有粘贴操作都被拦截
|
|
|
- const globalPasteHandler = (e) => {
|
|
|
- const editorElement = document.querySelector(".canvas-editor");
|
|
|
- if (editorElement && editorElement.contains(e.target)) {
|
|
|
- console.log('Global paste intercepted');
|
|
|
- e.preventDefault();
|
|
|
- e.stopPropagation();
|
|
|
- this.handlePaste(e);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // 监听所有可能的粘贴事件
|
|
|
- document.addEventListener('paste', globalPasteHandler, true);
|
|
|
- window.addEventListener('paste', globalPasteHandler, true);
|
|
|
-
|
|
|
- // 保存处理器引用以便清理
|
|
|
- this.globalPasteHandler = globalPasteHandler;
|
|
|
-
|
|
|
- // 添加全局点击事件监听器,用于关闭右键菜单
|
|
|
- this.globalClickHandler = (e) => {
|
|
|
- // 检查点击的元素是否是右键菜单
|
|
|
- const contextMenus = document.querySelectorAll('.ce-contextmenu, [class*="contextmenu"], [class*="context-menu"]');
|
|
|
- let isClickOnMenu = false;
|
|
|
- let clickedMenuItem = false;
|
|
|
-
|
|
|
- contextMenus.forEach(menu => {
|
|
|
- if (menu.contains(e.target)) {
|
|
|
- isClickOnMenu = true;
|
|
|
- // 检查是否点击的是菜单项(按钮)
|
|
|
- const menuItems = menu.querySelectorAll('li, div[role="menuitem"], button, a, span');
|
|
|
- menuItems.forEach(item => {
|
|
|
- if (item.contains(e.target) && item !== menu) {
|
|
|
- clickedMenuItem = true;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 如果点击的是菜单项或者不是菜单,则关闭所有右键菜单
|
|
|
- if (clickedMenuItem || !isClickOnMenu) {
|
|
|
- this.closeAllContextMenus();
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // 关闭所有右键菜单的方法
|
|
|
- this.closeAllContextMenus = () => {
|
|
|
- const contextMenus = document.querySelectorAll('.ce-contextmenu, [class*="contextmenu"], [class*="context-menu"]');
|
|
|
- contextMenus.forEach(menu => {
|
|
|
- if (menu.style.display !== 'none') {
|
|
|
- menu.style.display = 'none';
|
|
|
- menu.style.visibility = 'hidden';
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- // 也尝试通过移除菜单元素来关闭
|
|
|
- const menuElements = document.querySelectorAll('.ce-contextmenu');
|
|
|
- menuElements.forEach(element => {
|
|
|
- if (element.parentNode) {
|
|
|
- element.parentNode.removeChild(element);
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- // 监听全局点击事件
|
|
|
- document.addEventListener('click', this.globalClickHandler, true);
|
|
|
|
|
|
// 回显编辑器数据
|
|
|
if (this.docJson !== null) {
|