From d95153299880ef7139d3a2d64d7d3dc16fbef615 Mon Sep 17 00:00:00 2001 From: zhoujingfu <1751218699@qq.com> Date: Tue, 21 Mar 2023 10:00:01 +0800 Subject: [PATCH 1/5] feat: add fontSize settings API --- src/editor/core/command/Command.ts | 8 +++++++- src/editor/core/command/CommandAdapt.ts | 14 ++++++++++++++ src/editor/core/range/RangeManager.ts | 4 ++++ src/editor/interface/Listener.ts | 1 + 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index 062afb8..10b5b41 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -22,6 +22,7 @@ export class Command { private static applyPainterStyle: CommandAdapt['applyPainterStyle'] private static format: CommandAdapt['format'] private static font: CommandAdapt['font'] + private static sizeSet: CommandAdapt['sizeSet'] private static sizeAdd: CommandAdapt['sizeAdd'] private static sizeMinus: CommandAdapt['sizeMinus'] private static bold: CommandAdapt['bold'] @@ -95,6 +96,7 @@ export class Command { Command.applyPainterStyle = adapt.applyPainterStyle.bind(adapt) Command.format = adapt.format.bind(adapt) Command.font = adapt.font.bind(adapt) + Command.sizeSet = adapt.sizeSet.bind(adapt) Command.sizeAdd = adapt.sizeAdd.bind(adapt) Command.sizeMinus = adapt.sizeMinus.bind(adapt) Command.bold = adapt.bold.bind(adapt) @@ -205,11 +207,15 @@ export class Command { return Command.format() } - // 字体、字体变大、字体变小、加粗、斜体、下划线、删除线、字体颜色、背景色 + // 字体、字体大小、字体变大、字体变小、加粗、斜体、下划线、删除线、字体颜色、背景色 public executeFont(payload: string) { return Command.font(payload) } + public executeSize(size: number) { + return Command.sizeSet(size) + } + public executeSizeAdd() { return Command.sizeAdd() } diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index 2b32b27..ef5a3c9 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -185,6 +185,20 @@ export class CommandAdapt { this.draw.render({ isSetCursor: false }) } + public sizeSet(size: number) { + const isReadonly = this.draw.isReadonly() + if (isReadonly) return + const selection = this.range.getSelection() + if (!selection) return + const lessThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size + 2 <= 72) + if (!~lessThanMaxSizeIndex) return + selection.forEach(el => { + if (size > 72) return + el.size = size + }) + this.draw.render({ isSetCursor: false }) + } + public sizeAdd() { const isReadonly = this.draw.isReadonly() if (isReadonly) return diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index 15da647..04d6f09 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -135,6 +135,7 @@ export class RangeManager { const type = curElement.type || ElementType.TEXT // 富文本 const font = curElement.font || this.options.defaultFont + const size = curElement.size || this.options.defaultSize const bold = !~curElementList.findIndex(el => !el.bold) const italic = !~curElementList.findIndex(el => !el.italic) const underline = !~curElementList.findIndex(el => !el.underline) @@ -154,6 +155,7 @@ export class RangeManager { redo, painter, font, + size, bold, italic, underline, @@ -169,6 +171,7 @@ export class RangeManager { public recoveryRangeStyle() { if (!this.listener.rangeStyleChange) return const font = this.options.defaultFont + const size = this.options.defaultSize const rowMargin = this.options.defaultRowMargin const painter = !!this.draw.getPainterStyle() const undo = this.historyManager.isCanUndo() @@ -179,6 +182,7 @@ export class RangeManager { redo, painter, font, + size, bold: false, italic: false, underline: false, diff --git a/src/editor/interface/Listener.ts b/src/editor/interface/Listener.ts index f822a85..f8f1af2 100644 --- a/src/editor/interface/Listener.ts +++ b/src/editor/interface/Listener.ts @@ -9,6 +9,7 @@ export interface IRangeStyle { redo: boolean; painter: boolean; font: string; + size: number; bold: boolean; italic: boolean; underline: boolean; From 3f218f698bd361ae73eac9043f31585c97058963 Mon Sep 17 00:00:00 2001 From: zhoujingfu <1751218699@qq.com> Date: Tue, 21 Mar 2023 10:00:46 +0800 Subject: [PATCH 2/5] feat: fontSize setting Example --- index.html | 23 +++++++++++++++++++++++ src/main.ts | 20 ++++++++++++++++++++ src/style.css | 8 ++++++-- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/index.html b/index.html index 16f2573..088f783 100644 --- a/index.html +++ b/index.html @@ -51,6 +51,29 @@ + diff --git a/src/main.ts b/src/main.ts index 5f9e2fb..526357c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -81,6 +81,20 @@ window.onload = function () { instance.command.executeFont(li.dataset.family!) } + const sizeSetDom = document.querySelector('.menu-item__size')! + const sizeSelectDom = sizeSetDom.querySelector('.select')! + const sizeOptionDom = sizeSetDom.querySelector('.options')! + sizeSetDom.title = `设置字号` + sizeSetDom.onclick = function () { + console.log('size') + sizeOptionDom.classList.toggle('visible') + } + sizeOptionDom.onclick = function (evt) { + const li = evt.target as HTMLLIElement + const size = Number(li.dataset.size!) as number + instance.command.executeSize(size) + } + const sizeAddDom = document.querySelector('.menu-item__size-add')! sizeAddDom.title = `增大字号(${isApple ? '⌘' : 'Ctrl'}+[)` sizeAddDom.onclick = function () { @@ -984,6 +998,12 @@ window.onload = function () { fontSelectDom.style.fontFamily = payload.font curFontDom.classList.add('active') } + sizeOptionDom.querySelectorAll('li').forEach(li => li.classList.remove('active')) + const curSizeDom = sizeOptionDom.querySelector(`[data-size='${payload.size}']`) + if (curSizeDom) { + sizeSelectDom.innerText = curSizeDom.innerText + curSizeDom.classList.add('active') + } payload.bold ? boldDom.classList.add('active') : boldDom.classList.remove('active') payload.italic ? italicDom.classList.add('active') : italicDom.classList.remove('active') payload.underline ? underlineDom.classList.add('active') : underlineDom.classList.remove('active') diff --git a/src/style.css b/src/style.css index 0843b68..5420779 100644 --- a/src/style.css +++ b/src/style.css @@ -156,12 +156,16 @@ ul { background-color: #e2e6ed; } -.menu-item .menu-item__font { +.menu-item .menu-item__font,.menu-item .menu-item__size { width: 65px; position: relative; } -.menu-item__font .select { +.menu-item .menu-item__size{ + text-align: center; +} + +.menu-item__font .select,.menu-item__size .select { width: 100%; height: 100%; } From 84e2fc95699adf81fd361ff7a76b900abfd2b164 Mon Sep 17 00:00:00 2001 From: Hufe921 Date: Wed, 22 Mar 2023 13:44:54 +0800 Subject: [PATCH 3/5] improve: font size setting api --- src/editor/core/command/Command.ts | 8 ++-- src/editor/core/command/CommandAdapt.ts | 64 +++++++++++++++---------- src/editor/core/range/RangeManager.ts | 7 +++ src/editor/index.ts | 2 + src/editor/interface/Editor.ts | 2 + src/main.ts | 5 +- src/style.css | 9 ++-- 7 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/editor/core/command/Command.ts b/src/editor/core/command/Command.ts index 10b5b41..f89301a 100644 --- a/src/editor/core/command/Command.ts +++ b/src/editor/core/command/Command.ts @@ -22,7 +22,7 @@ export class Command { private static applyPainterStyle: CommandAdapt['applyPainterStyle'] private static format: CommandAdapt['format'] private static font: CommandAdapt['font'] - private static sizeSet: CommandAdapt['sizeSet'] + private static size: CommandAdapt['size'] private static sizeAdd: CommandAdapt['sizeAdd'] private static sizeMinus: CommandAdapt['sizeMinus'] private static bold: CommandAdapt['bold'] @@ -96,7 +96,7 @@ export class Command { Command.applyPainterStyle = adapt.applyPainterStyle.bind(adapt) Command.format = adapt.format.bind(adapt) Command.font = adapt.font.bind(adapt) - Command.sizeSet = adapt.sizeSet.bind(adapt) + Command.size = adapt.size.bind(adapt) Command.sizeAdd = adapt.sizeAdd.bind(adapt) Command.sizeMinus = adapt.sizeMinus.bind(adapt) Command.bold = adapt.bold.bind(adapt) @@ -212,8 +212,8 @@ export class Command { return Command.font(payload) } - public executeSize(size: number) { - return Command.sizeSet(size) + public executeSize(payload: number) { + return Command.size(payload) } public executeSizeAdd() { diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index ef5a3c9..82e3ec7 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -185,54 +185,70 @@ export class CommandAdapt { this.draw.render({ isSetCursor: false }) } - public sizeSet(size: number) { + public size(payload: number) { + const { minSize, maxSize, defaultSize } = this.options + if (payload < minSize || payload > maxSize) return const isReadonly = this.draw.isReadonly() if (isReadonly) return - const selection = this.range.getSelection() - if (!selection) return - const lessThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size + 2 <= 72) - if (!~lessThanMaxSizeIndex) return + const selection = this.range.getTextLikeSelection() + if (!selection || !selection.length) return + let isExistUpdate = false selection.forEach(el => { - if (size > 72) return - el.size = size + if ((!el.size && payload === defaultSize) || (el.size && el.size === payload)) return + el.size = payload + isExistUpdate = true }) - this.draw.render({ isSetCursor: false }) + if (isExistUpdate) { + this.draw.render({ isSetCursor: false }) + } } public sizeAdd() { const isReadonly = this.draw.isReadonly() if (isReadonly) return - const selection = this.range.getSelection() - if (!selection) return - const lessThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size + 2 <= 72) - const { defaultSize } = this.options - if (!~lessThanMaxSizeIndex) return + const selection = this.range.getTextLikeSelection() + if (!selection || !selection.length) return + const { defaultSize, maxSize } = this.options + let isExistUpdate = false selection.forEach(el => { if (!el.size) { el.size = defaultSize } - if (el.size + 2 > 72) return - el.size += 2 + if (el.size >= maxSize) return + if (el.size + 2 > maxSize) { + el.size = maxSize + } else { + el.size += 2 + } + isExistUpdate = true }) - this.draw.render({ isSetCursor: false }) + if (isExistUpdate) { + this.draw.render({ isSetCursor: false }) + } } public sizeMinus() { const isReadonly = this.draw.isReadonly() if (isReadonly) return - const selection = this.range.getSelection() - if (!selection) return - const greaterThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size - 2 >= 8) - if (!~greaterThanMaxSizeIndex) return - const { defaultSize } = this.options + const selection = this.range.getTextLikeSelection() + if (!selection || !selection.length) return + const { defaultSize, minSize } = this.options + let isExistUpdate = false selection.forEach(el => { if (!el.size) { el.size = defaultSize } - if (el.size - 2 < 8) return - el.size -= 2 + if (el.size <= minSize) return + if (el.size - 2 < minSize) { + el.size = minSize + } else { + el.size -= 2 + } + isExistUpdate = true }) - this.draw.render({ isSetCursor: false }) + if (isExistUpdate) { + this.draw.render({ isSetCursor: false }) + } } public bold() { diff --git a/src/editor/core/range/RangeManager.ts b/src/editor/core/range/RangeManager.ts index 04d6f09..2dd7d71 100644 --- a/src/editor/core/range/RangeManager.ts +++ b/src/editor/core/range/RangeManager.ts @@ -1,5 +1,6 @@ import { ElementType } from '../..' import { ZERO } from '../../dataset/constant/Common' +import { TEXTLIKE_ELEMENT_TYPE } from '../../dataset/constant/Element' import { ControlComponent } from '../../dataset/enum/Control' import { IEditorOption } from '../../interface/Editor' import { IElement } from '../../interface/Element' @@ -45,6 +46,12 @@ export class RangeManager { return elementList.slice(startIndex + 1, endIndex + 1) } + public getTextLikeSelection(): IElement[] | null { + const selection = this.getSelection() + if (!selection) return null + return selection.filter(s => !s.type || TEXTLIKE_ELEMENT_TYPE.includes(s.type)) + } + // 获取光标所选位置行信息 public getRangeRow(): RangeRowMap | null { const { startIndex, endIndex } = this.range diff --git a/src/editor/index.ts b/src/editor/index.ts index 8b901f5..63f2312 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -66,6 +66,8 @@ export default class Editor { defaultType: 'TEXT', defaultFont: 'Yahei', defaultSize: 16, + minSize: 5, + maxSize: 72, defaultRowMargin: 1, defaultBasicRowMarginHeight: 8, defaultTabWidth: 32, diff --git a/src/editor/interface/Editor.ts b/src/editor/interface/Editor.ts index d5c1bb6..21d0cb5 100644 --- a/src/editor/interface/Editor.ts +++ b/src/editor/interface/Editor.ts @@ -18,6 +18,8 @@ export interface IEditorOption { defaultType?: string; defaultFont?: string; defaultSize?: number; + minSize?: number; + maxSize?: number; defaultBasicRowMarginHeight?: number; defaultRowMargin?: number; defaultTabWidth?: number; diff --git a/src/main.ts b/src/main.ts index 526357c..6eed966 100644 --- a/src/main.ts +++ b/src/main.ts @@ -91,8 +91,7 @@ window.onload = function () { } sizeOptionDom.onclick = function (evt) { const li = evt.target as HTMLLIElement - const size = Number(li.dataset.size!) as number - instance.command.executeSize(size) + instance.command.executeSize(Number(li.dataset.size!)) } const sizeAddDom = document.querySelector('.menu-item__size-add')! @@ -1003,6 +1002,8 @@ window.onload = function () { if (curSizeDom) { sizeSelectDom.innerText = curSizeDom.innerText curSizeDom.classList.add('active') + } else { + sizeSelectDom.innerText = `${payload.size}` } payload.bold ? boldDom.classList.add('active') : boldDom.classList.remove('active') payload.italic ? italicDom.classList.add('active') : italicDom.classList.remove('active') diff --git a/src/style.css b/src/style.css index 5420779..ac6d4f6 100644 --- a/src/style.css +++ b/src/style.css @@ -156,16 +156,19 @@ ul { background-color: #e2e6ed; } -.menu-item .menu-item__font,.menu-item .menu-item__size { +.menu-item .menu-item__font { width: 65px; position: relative; } -.menu-item .menu-item__size{ +.menu-item .menu-item__size { + width: 50px; text-align: center; + position: relative; } -.menu-item__font .select,.menu-item__size .select { +.menu-item__font .select, +.menu-item__size .select { width: 100%; height: 100%; } From 690aa1b96d185ca7d80b9af884d23a39dac9a2bf Mon Sep 17 00:00:00 2001 From: Hufe921 Date: Wed, 22 Mar 2023 13:50:37 +0800 Subject: [PATCH 4/5] docs: font size setting api --- docs/guide/command-execute.md | 8 ++++++++ docs/guide/option.md | 2 ++ 2 files changed, 10 insertions(+) diff --git a/docs/guide/command-execute.md b/docs/guide/command-execute.md index dd04d1b..5d5d8e9 100644 --- a/docs/guide/command-execute.md +++ b/docs/guide/command-execute.md @@ -113,6 +113,14 @@ instance.command.executeFormat() instance.command.executeFont(font: string) ``` +## executeSize +功能:设置字号 + +用法: +```javascript +instance.command.executeSize(size: number) +``` + ## executeSizeAdd 功能:增大字号 diff --git a/docs/guide/option.md b/docs/guide/option.md index da9ed7b..7f7c151 100644 --- a/docs/guide/option.md +++ b/docs/guide/option.md @@ -18,6 +18,8 @@ interface IEditorOption { defaultType?: string; // 默认元素类型。默认:TEXT defaultFont?: string; // 默认字体。默认:Yahei defaultSize?: number; // 默认字号。默认:16 + minSize?: number; // 最小字号。默认:5 + maxSize?: number; // 最大字号。默认:72 defaultBasicRowMarginHeight?: number; // 默认行高。默认:8 defaultRowMargin?: number; // 默认行间距。默认:1 defaultTabWidth?: number; // 默认tab宽度。默认:32 From 89012b7183327f3a5e6497ad96741e6f5badc699 Mon Sep 17 00:00:00 2001 From: Hufe921 Date: Wed, 22 Mar 2023 14:01:11 +0800 Subject: [PATCH 5/5] test: font size setting --- cypress/integration/menus/text.spec.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cypress/integration/menus/text.spec.ts b/cypress/integration/menus/text.spec.ts index 12aa394..bc49eed 100644 --- a/cypress/integration/menus/text.spec.ts +++ b/cypress/integration/menus/text.spec.ts @@ -37,6 +37,32 @@ describe('菜单-文本处理', () => { }) }) + it('字号设置', () => { + cy.getEditor().then((editor: Editor) => { + editor.command.executeSelectAll() + + editor.command.executeBackspace() + + editor.command.executeInsertElementList([{ + value: text + }]) + + editor.command.executeSetRange(0, textLength) + + cy.get('.menu-item__size').as('size').click() + + cy.get('@size') + .find('li') + .eq(0) + .click() + .then(() => { + const data = editor.command.getValue().data.main + + expect(data[0].size).to.eq(56) + }) + }) + }) + it('字体增大', () => { cy.getEditor().then((editor: Editor) => { editor.command.executeSelectAll()