فهرست منبع

富文本加着重点,缩进,段落间距

zq 1 هفته پیش
والد
کامیت
fa7adb6bb1
1فایلهای تغییر یافته به همراه120 افزوده شده و 12 حذف شده
  1. 120 12
      src/components/RichText.vue

+ 120 - 12
src/components/RichText.vue

@@ -91,7 +91,7 @@ export default {
       type: [String, Boolean],
       /* eslint-disable max-len */
       default:
-        'fontselect fontsizeselect forecolor backcolor | lineheight underline | bold italic strikethrough alignleft aligncenter alignright | bullist numlist | image media | link blockquote hr mathjax',
+        'fontselect fontsizeselect forecolor backcolor lineheight paragraphSpacing  indent outdent underline bold italic strikethrough alignleft aligncenter alignright bullist numlist dotEmphasis image media link blockquote hr mathjax',
     },
     wordlimitNum: {
       type: [Number, Boolean],
@@ -146,7 +146,26 @@ export default {
           mjx-container, mjx-container * {
             font-size: 16px !important; /* 强制固定字体 */
             line-height: 1.2 !important; /* 避免行高影响 */
-          }`, // 解决公式每点击一次字体就变大
+          }
+          .emphasis-dot {
+            border-bottom: none;
+            background-image: radial-gradient(
+              circle at center,
+              currentColor 0.15em,  /* 圆点大小相对于字体 */
+              transparent 0.16em
+            );
+            background-size: 1em 0.3em; /* 间距相对于字体大小,高度相对字体 */
+            background-repeat: repeat-x;
+            background-position: 0 100%;
+            padding-bottom: 0.3em; /* 间距也相对于字体 */
+            display: inline;
+          }
+           p { margin: 0 0 1em 0; }
+          .paragraph-spacing-small { margin-bottom: 0.5em; }
+          .paragraph-spacing-medium { margin-bottom: 1em; }
+          .paragraph-spacing-large { margin-bottom: 2em; }
+          .paragraph-spacing-custom { margin-bottom: var(--custom-spacing); }
+          `, // 解决公式每点击一次字体就变大
         valid_elements: '*[*]', // 允许所有标签和属性
         valid_children: '+body[style]', // 允许 MathJax 的样式
         extended_valid_elements: 'span[*],mjx-container[*],svg[*],path[*]', // 明确允许 MathJax 标签
@@ -164,6 +183,7 @@ export default {
         plugins: 'link lists image hr media autoresize ax_wordlimit paste', // 移除 lineheight
         toolbar: this.toolbar, // 工具栏
         lineheight_formats: '0.5 1.0 1.2 1.5 2.0 2.5 3.0', // 行高选项(倍数)
+        paragraphheight_formats: [0.5, 1.0, 1.2, 1.5, 2.0, 2.5, 3.0], // 段落间距
         contextmenu: false, // 右键菜单
         menubar: false, // 菜单栏
         branding: false, // 品牌
@@ -180,6 +200,33 @@ export default {
           editor.on('init', () => {
             editor.getBody().style.fontSize = this.init.font_size; // 设置默认字体大小
             editor.getBody().style.fontFamily = this.init.font_family; // 设置默认字体
+
+            this.init.paragraphheight_formats.forEach((config) => {
+              const formatName = `paragraphSpacing${config}_em`;
+              editor.formatter.register(formatName, {
+                selector: 'p',
+                styles: { 'margin-bottom': config + 'em' },
+              });
+            });
+
+            if (!editor.formatter.has('emphasisDot')) {
+              editor.formatter.register('emphasisDot', {
+                inline: 'span',
+                // classes: 'emphasis-dot',
+                styles: {
+                  'border-bottom': 'none',
+                  'background-image':
+                    'radial-gradient(circle at center, currentColor 0.15em, transparent 0.16em)' /* 圆点大小相对于字体 */,
+                  'background-size': '1em 0.3em' /* 间距相对于字体大小,高度相对字体 */,
+                  'background-repeat': 'repeat-x',
+                  'background-position': '0 100%',
+                  'padding-bottom': '0.3em' /* 间距也相对于字体 */,
+                  display: 'inline',
+                },
+                wrapper: true,
+                remove_similar: true,
+              });
+            }
           });
 
           // 自定义行高下拉(因为没有内置 lineheight 插件)
@@ -211,14 +258,65 @@ export default {
             },
           });
 
-          editor.on('click', () => {
-            if (editor?.queryCommandState('ToggleToolbarDrawer')) {
-              editor.execCommand('ToggleToolbarDrawer');
-            }
-            if (!isRendered && window.MathJax) {
-              isRendered = true;
-              window.MathJax.typesetPromise([editor.getBody()]);
-            }
+          // 添加段落间距下拉菜单
+          editor.ui.registry.addMenuButton('paragraphSpacing', {
+            icon: 'paragraph',
+            //text: '段落间距',
+            tooltip: '段落间距',
+            fetch: (callback) => {
+              const items = [];
+
+              // 动态生成菜单项
+              this.init.paragraphheight_formats.forEach((config) => {
+                const formatName = `paragraphSpacing${config}_em`;
+                items.push({
+                  type: 'menuitem',
+                  text: `${config}`,
+                  onAction: () => {
+                    // 先清除其他间距格式
+                    this.init.paragraphheight_formats.forEach((cfg) => {
+                      const fmtName = `paragraphSpacing${cfg}_em`;
+                      editor.formatter.remove(fmtName);
+                    });
+                    // 应用当前选择的间距
+                    editor.formatter.apply(formatName);
+                  },
+                });
+              });
+
+              // 添加清除间距选项
+              items.push({
+                type: 'separator', // 分隔线
+              });
+              items.push({
+                type: 'menuitem',
+                text: '清除间距',
+                onAction: () => {
+                  // 清除所有间距格式
+                  this.init.paragraphheight_formats.forEach((config) => {
+                    const formatName = `paragraphSpacing${config}_em`;
+                    editor.formatter.remove(formatName);
+                  });
+                },
+              });
+
+              callback(items);
+            },
+          });
+
+          // 添加 添加着重点 按钮
+          editor.ui.registry.addButton('dotEmphasis', {
+            text: '●',
+            tooltip: '着重点',
+            onAction: () => {
+              const editor = tinymce.activeEditor;
+
+              if (editor.formatter.match('emphasisDot')) {
+                editor.formatter.remove('emphasisDot');
+              } else {
+                editor.formatter.apply('emphasisDot');
+              }
+            },
           });
 
           // 添加 MathJax 按钮
@@ -230,6 +328,16 @@ export default {
             },
           });
 
+          editor.on('click', () => {
+            if (editor?.queryCommandState('ToggleToolbarDrawer')) {
+              editor.execCommand('ToggleToolbarDrawer');
+            }
+            if (!isRendered && window.MathJax) {
+              isRendered = true;
+              window.MathJax.typesetPromise([editor.getBody()]);
+            }
+          });
+
           // 内容变化时重新渲染公式
           editor.on('change', () => this.renderMath());
 
@@ -817,7 +925,7 @@ export default {
         if (eleMathArs.length === 0) return;
         await this.$nextTick();
         window.MathJax.typesetPromise(eleMathArs).catch((err) =>
-          /* eslint-disable */ console.error(...oo_tx(`483836707_818_65_818_101_11`, 'MathJax error:', err)),
+          /* eslint-disable */ console.error(...oo_tx(`483836707_818_65_818_101_11`, 'MathJax error:', err))
         );
         this.mathEleIsInit = true;
       }
@@ -968,7 +1076,7 @@ export default {
         {
           acceptNode: (node) => (node.textContent.trim() ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT),
         },
-        false,
+        false
       );
       return walker.nextNode();
     },