From 46fd1eefc116be18c3a657cc9a203672cdd78a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A7=8B=E4=BA=8E=E5=88=9D=E8=A7=81?= <752204717@qq.com> Date: Thu, 2 Jan 2025 13:40:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/css/main.css | 8 ++ src/common/js/commonJS.js | 4 +- src/components/page/GenerateCharts.vue | 27 ++++- .../page/components/Tinymce/index.vue | 94 +++++++++++---- src/components/page/components/table/word.vue | 109 ++++++++++-------- 5 files changed, 173 insertions(+), 69 deletions(-) diff --git a/src/assets/css/main.css b/src/assets/css/main.css index 093a2f7..f0f56e2 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -1165,6 +1165,14 @@ a { mso-font-kerning: 1pt !important; line-height: 10pt !important; mos-line-height: 10pt !important; +} +.wordTableHtml table blue { + color: rgb(0, 130, 170) !important; + font-family: 'Charis SIL' !important; + font-size: 7.5pt !important; + mso-font-kerning: 1pt !important; + line-height: 10pt !important; + mos-line-height: 10pt !important; } .wordTableHtml table tr:first-child td { border-top: 1px solid #000 !important; diff --git a/src/common/js/commonJS.js b/src/common/js/commonJS.js index e0120d8..627cd09 100644 --- a/src/common/js/commonJS.js +++ b/src/common/js/commonJS.js @@ -1153,4 +1153,6 @@ convertParagraphsToHtml(paragraphs) { // 通用递归方法 }; -export { mediaUrl }; \ No newline at end of file +export { mediaUrl }; + + diff --git a/src/components/page/GenerateCharts.vue b/src/components/page/GenerateCharts.vue index 447ed53..a443995 100644 --- a/src/components/page/GenerateCharts.vue +++ b/src/components/page/GenerateCharts.vue @@ -461,8 +461,31 @@ export default { content = content.replace(/\s*style="[^"]*"/g, ''); // 3. 将 转换为 转换为 -content = content.replace(//g, '').replace(/<\/strong>/g, ''); -content = content.replace(//g, '').replace(/<\/em>/g, ''); + + + var div = document.createElement('div'); +div.innerHTML = content; // 将 HTML 字符串加载到 div 中 + +// 替换所有 +var strongTags = div.getElementsByTagName('strong'); +for (var i = 0; i < strongTags.length; i++) { + var bTag = document.createElement('b'); + bTag.innerHTML = strongTags[i].innerHTML; // 保留内容 + strongTags[i].parentNode.replaceChild(bTag, strongTags[i]); +} + +// 替换所有 +var emTags = div.getElementsByTagName('em'); +for (var i = 0; i < emTags.length; i++) { + var iTag = document.createElement('i'); + iTag.innerHTML = emTags[i].innerHTML; // 保留内容 + emTags[i].parentNode.replaceChild(iTag, emTags[i]); +} + +// 获取最终修改后的 HTML +content = div.innerHTML; + + // 4. 去除多余的空格:替换连续的空格、换行符、制表符等 content = content.replace(/\s+/g, ' ').trim(); // 将多个空白字符替换为一个空格,并去除前后空白 diff --git a/src/components/page/components/Tinymce/index.vue b/src/components/page/components/Tinymce/index.vue index 293b5b1..94383ce 100644 --- a/src/components/page/components/Tinymce/index.vue +++ b/src/components/page/components/Tinymce/index.vue @@ -339,7 +339,7 @@ export default { bold: { inline: 'b' }, italic: { inline: 'i' } }, - + body_class: 'panel-body ', object_resizing: false, toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, @@ -382,24 +382,75 @@ export default { ed.ui.registry.addButton('removeBlue', { text: 'Remove Blue', // 按钮文本 onAction: function () { - var selectedContent = ed.selection.getContent(); // 获取选中的文本内容 + const range = ed.selection.getRng(); // 获取选区范围 + let startNode = range.startContainer; // 获取选区起始节点 + let closestBlue = null; - // 如果选中内容中有 标签,去除它们 - var cleanedContent = selectedContent.replace(/<\/?blue>/g, ''); // 删除所有 标签 - ed.selection.setContent(cleanedContent); // 更新内容 - }, - onPostRender: function (buttonApi) { - // 监听编辑器中内容的变化 - ed.on('NodeChange', function () { - var selectedContent = ed.selection.getContent(); // 获取选中的内容 - - // 检查选中的内容是否包含 标签 - if (selectedContent.includes('')) { - buttonApi.setActive(true); // 激活按钮 - } else { - buttonApi.setActive(false); // 禁用按钮 + // 向上查找最近的 标签 + while (startNode) { + if (startNode.nodeName && startNode.nodeName.toLowerCase() === 'blue') { + closestBlue = startNode; + break; } - }); + startNode = startNode.parentNode; + } + + if (closestBlue) { + // 如果找到最近的 标签,移除它的外层标签,但保留内容 + const parent = closestBlue.parentNode; + while (closestBlue.firstChild) { + parent.insertBefore(closestBlue.firstChild, closestBlue); + } + parent.removeChild(closestBlue); + } else { + // 未找到 标签,仅移除选中的 标签内容 + const selectedContent = ed.selection.getContent({ format: 'html' }); + + // 使用正则表达式移除选区中的 标签 + const cleanedContent = selectedContent + .replace(/]*>/g, '') // 删除起始标签 + .replace(/<\/blue>/g, ''); // 删除结束标签 + + // 更新选中的内容 + ed.selection.setContent(cleanedContent); + } + } + }); + ed.ui.registry.addToggleButton('toggleBlue', { + text: 'Toggle Blue', // 按钮文本 + onAction: function () { + var selectedContent = ed.selection.getContent({ format: 'html' }); // 获取选中内容(HTML 格式) + + // 创建临时 DOM 容器 + var tempDiv = document.createElement('div'); + tempDiv.innerHTML = selectedContent; + + // 检查是否完全被 包裹 + if (tempDiv.childNodes.length === 1 && tempDiv.firstChild.nodeName.toLowerCase() === 'blue') { + // 移除 标签 + var unwrappedContent = tempDiv.firstChild.innerHTML; + ed.selection.setContent(unwrappedContent); // 更新内容 + } else { + // 添加 标签 + var wrappedContent = `${selectedContent}`; + ed.selection.setContent(wrappedContent); // 更新内容 + } + }, + onSetup: function (buttonApi) { + // 更新按钮状态(激活或非激活) + function updateButtonState() { + var selectedContent = ed.selection.getContent({ format: 'html' }); + var tempDiv = document.createElement('div'); + tempDiv.innerHTML = selectedContent; + + buttonApi.setActive( + tempDiv.childNodes.length === 1 && tempDiv.firstChild.nodeName.toLowerCase() === 'blue' + ); + } + + // 监听编辑器中的选区变化 + ed.on('NodeChange', updateButtonState); + ed.on('KeyUp', updateButtonState); // 处理键盘操作导致的内容变化 } }); ed.ui.registry.addButton('uploadWord', { @@ -476,7 +527,7 @@ export default { // 插入自定义表格到编辑器中 let content = ed.getContent(); // 获取内容 content = content.replace(//g, '').replace(/<\/strong>/g, ''); - content = content.replace(//g, '').replace(/<\/strong>/g, ''); + content = content.replace(//g, '').replace(/<\/em>/g, ''); const container = document.createElement('div'); container.innerHTML = content; @@ -540,8 +591,11 @@ export default { }, //获取内容 getContent(type) { - this.$emit('getContent', type, window.tinymce.get(this.tinymceId).getContent()); - console.log('window.tinymce.get(this.tinymceId).getContent() at line 431:', window.tinymce.get(this.tinymceId).getContent()); + var content = window.tinymce.get(this.tinymceId).getContent(); + content = content.replace(//g, '').replace(/<\/strong>/g, ''); + content = content.replace(//g, '').replace(/<\/em>/g, ''); + this.$emit('getContent', type, content); + console.log('window.tinymce.get(this.tinymceId).getContent() at line 431:', content); }, async export(type, data) { diff --git a/src/components/page/components/table/word.vue b/src/components/page/components/table/word.vue index 57b3949..447ee98 100644 --- a/src/components/page/components/table/word.vue +++ b/src/components/page/components/table/word.vue @@ -388,54 +388,71 @@ export default { content_css: 'default ', setup(ed) { - ed.ui.registry.addButton('customBlue', { - text: 'Blue', // 按钮文本 - onAction: function() { - // 在选中的文本周围包裹 标签 - var selectedText = ed.selection.getContent(); - var wrappedText = `${selectedText}`; - ed.selection.setContent(wrappedText); + ed.ui.registry.addButton('customBlue', { + text: 'Blue', // 按钮文本 + onAction: function () { + // 在选中的文本周围包裹 标签 + var selectedText = ed.selection.getContent(); + var wrappedText = `${selectedText}`; + ed.selection.setContent(wrappedText); + } + }); + ed.ui.registry.addButton('removeBlue', { + text: 'Remove Blue', // 按钮文本 + onAction: function () { + var content = ed.selection.getContent(); // 获取选中的文本内容 + + // 如果选中内容中有 标签,去掉它们 + var cleanedContent = content.replace(/<\/?blue>/g, ''); // 删除所有 标签 + + // 更新编辑器中的内容 + ed.selection.setContent(cleanedContent); } }); - if(!_this.readonly){ -ed.on('click', function (e) { - // 判断点击的是否是目标元素 - const target = e.target; - console.log('target at line 351:', target); - - if (target.classList.contains('isRemarkIcon')) { - _this.$emit('onComment', target.getAttribute('main-id')); - } - }); - // // 添加批注按钮 - ed.ui.registry.addButton('addImageButton', { - text: 'Add Figure', - icon: 'comment', - onAction: function () { - _this.$emit('add', img); - // const selection = ed.selection; - // const selectedNode = selection.getNode(); // 获取选中的节点 - // console.log('selectedNode at line 333:', selectedNode); - // if (selectedNode) { - // const comment = prompt('Enter your comment:'); - // if (comment) { - // const dataId = selectedNode.getAttribute('main-id'); - // _this.comments.push({ text: comment, time: new Date().getTime(), mId: dataId }); - // } - // } else { - // alert('Please select some text to comment on.'); - // } - } - }); - ed.on('dragstart', (e) => { - // 阻止拖动事件 - e.preventDefault(); - }); - // 监听焦点变化并高亮当前选中的元素 - ed.on('focus', function () { - if (!isDeleting) { - // 处理正常的焦点逻辑 - ed.getBody().style.outline = 'none'; // 当编辑器获取焦点时,移除焦点框 + if (!_this.readonly) { + ed.on('click', function (e) { + // 判断点击的是否是目标元素 + const target = e.target; + console.log('target at line 351:', target); + + if (target.classList.contains('isRemarkIcon')) { + _this.$emit('onComment', target.getAttribute('main-id')); + } + }); + // // 添加批注按钮 + ed.ui.registry.addButton('addImageButton', { + text: 'Add Figure', + icon: 'comment', + onAction: function () { + _this.$emit('add', img); + // const selection = ed.selection; + // const selectedNode = selection.getNode(); // 获取选中的节点 + // console.log('selectedNode at line 333:', selectedNode); + // if (selectedNode) { + // const comment = prompt('Enter your comment:'); + // if (comment) { + // const dataId = selectedNode.getAttribute('main-id'); + // _this.comments.push({ text: comment, time: new Date().getTime(), mId: dataId }); + // } + // } else { + // alert('Please select some text to comment on.'); + // } + } + }); + ed.on('dragstart', (e) => { + // 阻止拖动事件 + e.preventDefault(); + }); + // 监听焦点变化并高亮当前选中的元素 + ed.on('focus', function () { + if (!isDeleting) { + // 处理正常的焦点逻辑 + ed.getBody().style.outline = 'none'; // 当编辑器获取焦点时,移除焦点框 + _this.updateCurrentTag(ed); + } + }); + // 监听焦点变化并高亮当前选中的元素 + ed.on('selectionChange', function () { _this.updateCurrentTag(ed); });