提交 6712281f authored 作者: 王鹏飞's avatar 王鹏飞

refactor(admin): scope editor toolbar presentation

上级 0a74a978
...@@ -42,6 +42,7 @@ import HistoryModal from "../features/history/HistoryDialog"; ...@@ -42,6 +42,7 @@ import HistoryModal from "../features/history/HistoryDialog";
import { EditorHeader } from './EditorHeader' import { EditorHeader } from './EditorHeader'
import { EditorSidebar } from './EditorSidebar' import { EditorSidebar } from './EditorSidebar'
import { useEditorLifecycle } from './useEditorLifecycle' import { useEditorLifecycle } from './useEditorLifecycle'
import { useToolbarPresentation } from './useToolbarPresentation'
import "../index.less"; import "../index.less";
...@@ -327,40 +328,6 @@ const WangEditorCustomer = (props, ref) => { ...@@ -327,40 +328,6 @@ const WangEditorCustomer = (props, ref) => {
}, },
}; };
// 编辑器按钮重排
const toolSettingReplace = () => {
setTimeout(() => {
const editorToolbar = document.querySelector(".editor-toolbar-container");
if (!editorToolbar) return;
// 设置菜单模块标题
const dividerElements = editorToolbar.querySelectorAll(".w-e-bar-divider");
const dividerTitles = [
"常用格式",
"媒体资源",
"高级模块",
"AI文本辅助",
"AI试题辅助",
"更多AI功能",
];
dividerElements.forEach((element, index) => {
element.innerHTML = dividerTitles[index];
});
// 设置菜单标题
const menuButtonElements = editorToolbar.querySelectorAll(".w-e-bar-item button");
menuButtonElements.forEach((element, index) => {
if (index > 1 && index < 22) return;
const width = index === 0 || index === 1 ? "50%" : "25%";
element.parentElement.style.width = width;
element.classList.add("has-title");
const title = element.getAttribute("data-tooltip");
const span = document.createElement("span");
span.innerHTML = title;
span.className = "title";
element.appendChild(span);
});
}, 50);
};
editorConfig.onFocus = () => { editorConfig.onFocus = () => {
clearTimeout(saveRef.current); clearTimeout(saveRef.current);
}; };
...@@ -377,7 +344,6 @@ const WangEditorCustomer = (props, ref) => { ...@@ -377,7 +344,6 @@ const WangEditorCustomer = (props, ref) => {
// 及时销毁 editor ,重要! // 及时销毁 editor ,重要!
useEffect(() => { useEffect(() => {
if (editor) { if (editor) {
toolSettingReplace();
// 图片上传 // 图片上传
editor.on("ImageMenuClick", () => { editor.on("ImageMenuClick", () => {
console.log("ImageMenuClick", "----"); console.log("ImageMenuClick", "----");
...@@ -514,13 +480,11 @@ const WangEditorCustomer = (props, ref) => { ...@@ -514,13 +480,11 @@ const WangEditorCustomer = (props, ref) => {
}, [editor]); }, [editor]);
useEditorLifecycle({ editor, gData, disabled }); useEditorLifecycle({ editor, gData, disabled });
useToolbarPresentation({ toolbarRef, active: !isView && tabKey === "text" });
const tabKeyChange = (key) => { const tabKeyChange = (key) => {
if (key === "text") {
toolSettingReplace();
}
setTabKey(key); setTabKey(key);
editor.focus(); editor?.focus();
}; };
// 预览 // 预览
...@@ -543,8 +507,10 @@ const WangEditorCustomer = (props, ref) => { ...@@ -543,8 +507,10 @@ const WangEditorCustomer = (props, ref) => {
{ color: "#eb3351", name: "红色" }, { color: "#eb3351", name: "红色" },
]; ];
const setColor = (color) => { const setColor = (color) => {
const headers = document.querySelectorAll(`.w-e-scroll .chapter-item-header`); if (!editor) return;
const sections = document.querySelectorAll(`.w-e-scroll .chapter-item-section`); const editableContainer = editor.getEditableContainer();
const headers = editableContainer.querySelectorAll(`.chapter-item-header`);
const sections = editableContainer.querySelectorAll(`.chapter-item-section`);
headers.forEach((item) => { headers.forEach((item) => {
const node = DomEditor.toSlateNode(editor, item); const node = DomEditor.toSlateNode(editor, item);
const path = DomEditor.findPath(editor, node); const path = DomEditor.findPath(editor, node);
......
import { useEffect } from 'react'
const dividerTitles = [
'常用格式',
'媒体资源',
'高级模块',
'AI文本辅助',
'AI试题辅助',
'更多AI功能',
]
export const applyToolbarPresentation = toolbar => {
if (!toolbar) return
toolbar.querySelectorAll('.w-e-bar-divider').forEach((divider, index) => {
divider.textContent = dividerTitles[index] || ''
})
toolbar.querySelectorAll('.w-e-bar-item button').forEach((button, index) => {
if (index > 1 && index < 22) return
const item = button.parentElement
if (item) item.style.width = index === 0 || index === 1 ? '50%' : '25%'
button.classList.add('has-title')
const title = button.getAttribute('data-tooltip')
if (!title || button.querySelector('.title')) return
const titleElement = document.createElement('span')
titleElement.className = 'title'
titleElement.textContent = title
button.appendChild(titleElement)
})
}
export const useToolbarPresentation = ({ toolbarRef, active }) => {
useEffect(() => {
if (!active) return
const frame = requestAnimationFrame(() => applyToolbarPresentation(toolbarRef.current))
return () => cancelAnimationFrame(frame)
}, [active, toolbarRef])
}
import { describe, expect, it } from 'vitest'
import { applyToolbarPresentation } from '@/common/wangeditor-customer/shell/useToolbarPresentation'
describe('applyToolbarPresentation', () => {
it('only decorates the provided toolbar and does not duplicate menu titles', () => {
const toolbar = document.createElement('div')
toolbar.innerHTML = `
<i class="w-e-bar-divider"></i>
<div class="w-e-bar-item"><button data-tooltip="撤销"></button></div>
<div class="w-e-bar-item"><button data-tooltip="重做"></button></div>
<div class="w-e-bar-item"><button data-tooltip="字体"></button></div>
`
applyToolbarPresentation(toolbar)
applyToolbarPresentation(toolbar)
expect(toolbar.querySelector('.w-e-bar-divider')?.textContent).toBe('常用格式')
expect(toolbar.querySelectorAll('button .title')).toHaveLength(2)
expect(toolbar.querySelector('.w-e-bar-item')?.getAttribute('style')).toContain('width: 50%')
})
})
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论