diff --git a/src/assets/images/word-tool.svg b/src/assets/images/word-tool.svg new file mode 100644 index 0000000..21fbd33 --- /dev/null +++ b/src/assets/images/word-tool.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index a0a5328..adc1dd7 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -89,6 +89,7 @@ export class Command { private static setLocale: CommandAdapt['setLocale'] private static getCatalog: CommandAdapt['getCatalog'] private static locationCatalog: CommandAdapt['locationCatalog'] + private static wordTool: CommandAdapt['wordTool'] constructor(adapt: CommandAdapt) { Command.mode = adapt.mode.bind(adapt) @@ -170,6 +171,7 @@ export class Command { Command.setLocale = adapt.setLocale.bind(adapt) Command.getCatalog = adapt.getCatalog.bind(adapt) Command.locationCatalog = adapt.locationCatalog.bind(adapt) + Command.wordTool = adapt.wordTool.bind(adapt) } // 全局命令 @@ -495,4 +497,8 @@ export class Command { return Command.locationCatalog(titleId) } + public executeWordTool() { + return Command.wordTool() + } + } \ No newline at end of file diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index 36da2ae..ebfc4f2 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -1,4 +1,4 @@ -import { WRAP, ZERO } from '../../dataset/constant/Common' +import { NBSP, WRAP, ZERO } from '../../dataset/constant/Common' import { EDITOR_ELEMENT_STYLE_ATTR } from '../../dataset/constant/Element' import { titleSizeMapping } from '../../dataset/constant/Title' import { defaultWatermarkOption } from '../../dataset/constant/Watermark' @@ -1698,4 +1698,32 @@ export class CommandAdapt { }) } + public wordTool() { + const elementList = this.draw.getMainElementList() + let isApply = false + for (let i = 0; i < elementList.length; i++) { + const element = elementList[i] + // 删除空行、行首空格 + if (element.value === ZERO) { + while (i + 1 < elementList.length) { + const nextElement = elementList[i + 1] + if (nextElement.value !== ZERO && nextElement.value !== NBSP) break + elementList.splice(i + 1, 1) + isApply = true + } + } + } + if (!isApply) { + // 避免输入框光标丢失 + const isCollapsed = this.range.getIsCollapsed() + this.draw.getCursor().drawCursor({ + isShow: isCollapsed + }) + } else { + this.draw.render({ + isSetCursor: false + }) + } + } + } \ No newline at end of file diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index 489f080..7fec5ba 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -40,6 +40,11 @@ export class RangeManager { this.setRange(-1, -1) } + public getIsCollapsed(): boolean { + const { startIndex, endIndex } = this.range + return startIndex === endIndex + } + public getSelection(): IElement[] | null { const { startIndex, endIndex } = this.range if (startIndex === endIndex) return null diff --git a/src/main.ts b/src/main.ts index 0982b92..02f34a4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1243,6 +1243,16 @@ window.onload = function () { } }) } + }, + { + name: '格式整理', + icon: 'word-tool', + when: (payload) => { + return !payload.isReadonly + }, + callback: (command: Command) => { + command.executeWordTool() + } } ]) diff --git a/src/style.css b/src/style.css index 6755cbe..917f559 100644 --- a/src/style.css +++ b/src/style.css @@ -905,4 +905,8 @@ ul { .ce-contextmenu-signature { background-image: url('./assets/images/signature.svg'); +} + +.ce-contextmenu-word-tool { + background-image: url('./assets/images/word-tool.svg'); } \ No newline at end of file