feat:add editor mode
This commit is contained in:
@@ -6,6 +6,7 @@ import { CommandAdapt } from "./CommandAdapt"
|
|||||||
|
|
||||||
export class Command {
|
export class Command {
|
||||||
|
|
||||||
|
private static mode: Function
|
||||||
private static cut: Function
|
private static cut: Function
|
||||||
private static copy: Function
|
private static copy: Function
|
||||||
private static paste: Function
|
private static paste: Function
|
||||||
@@ -53,6 +54,7 @@ export class Command {
|
|||||||
private static insertElementList: Function
|
private static insertElementList: Function
|
||||||
|
|
||||||
constructor(adapt: CommandAdapt) {
|
constructor(adapt: CommandAdapt) {
|
||||||
|
Command.mode = adapt.mode.bind(adapt)
|
||||||
Command.cut = adapt.cut.bind(adapt)
|
Command.cut = adapt.cut.bind(adapt)
|
||||||
Command.copy = adapt.copy.bind(adapt)
|
Command.copy = adapt.copy.bind(adapt)
|
||||||
Command.paste = adapt.paste.bind(adapt)
|
Command.paste = adapt.paste.bind(adapt)
|
||||||
@@ -101,6 +103,10 @@ export class Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 全局命令
|
// 全局命令
|
||||||
|
public executeMode() {
|
||||||
|
return Command.mode()
|
||||||
|
}
|
||||||
|
|
||||||
public executeCut() {
|
public executeCut() {
|
||||||
return Command.cut()
|
return Command.cut()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { WRAP, ZERO } from "../../dataset/constant/Common"
|
import { WRAP, ZERO } from "../../dataset/constant/Common"
|
||||||
import { EDITOR_ELEMENT_STYLE_ATTR, TEXTLIKE_ELEMENT_TYPE } from "../../dataset/constant/Element"
|
import { EDITOR_ELEMENT_STYLE_ATTR, TEXTLIKE_ELEMENT_TYPE } from "../../dataset/constant/Element"
|
||||||
import { defaultWatermarkOption } from "../../dataset/constant/Watermark"
|
import { defaultWatermarkOption } from "../../dataset/constant/Watermark"
|
||||||
import { EditorContext } from "../../dataset/enum/Editor"
|
import { EditorContext, EditorMode } from "../../dataset/enum/Editor"
|
||||||
import { ElementType } from "../../dataset/enum/Element"
|
import { ElementType } from "../../dataset/enum/Element"
|
||||||
import { ElementStyleKey } from "../../dataset/enum/ElementStyle"
|
import { ElementStyleKey } from "../../dataset/enum/ElementStyle"
|
||||||
import { RowFlex } from "../../dataset/enum/Row"
|
import { RowFlex } from "../../dataset/enum/Row"
|
||||||
@@ -45,7 +45,19 @@ export class CommandAdapt {
|
|||||||
this.options = draw.getOptions()
|
this.options = draw.getOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public mode(payload: EditorMode) {
|
||||||
|
const mode = this.draw.getMode()
|
||||||
|
if (mode === payload) return
|
||||||
|
this.draw.setMode(payload)
|
||||||
|
this.draw.render({
|
||||||
|
isSetCursor: false,
|
||||||
|
isSubmitHistory: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public cut() {
|
public cut() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
this.canvasEvent.cut()
|
this.canvasEvent.cut()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,6 +66,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async paste() {
|
public async paste() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const text = await navigator.clipboard.readText()
|
const text = await navigator.clipboard.readText()
|
||||||
if (text) {
|
if (text) {
|
||||||
this.canvasEvent.input(text)
|
this.canvasEvent.input(text)
|
||||||
@@ -65,14 +79,20 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public undo() {
|
public undo() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
this.historyManager.undo()
|
this.historyManager.undo()
|
||||||
}
|
}
|
||||||
|
|
||||||
public redo() {
|
public redo() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
this.historyManager.redo()
|
this.historyManager.redo()
|
||||||
}
|
}
|
||||||
|
|
||||||
public painter() {
|
public painter() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const painterStyle: IElementStyle = {}
|
const painterStyle: IElementStyle = {}
|
||||||
@@ -89,6 +109,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public format() {
|
public format() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
selection.forEach(el => {
|
selection.forEach(el => {
|
||||||
@@ -103,6 +125,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public font(payload: string) {
|
public font(payload: string) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
selection.forEach(el => {
|
selection.forEach(el => {
|
||||||
@@ -112,6 +136,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public sizeAdd() {
|
public sizeAdd() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const lessThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size + 2 <= 72)
|
const lessThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size + 2 <= 72)
|
||||||
@@ -128,6 +154,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public sizeMinus() {
|
public sizeMinus() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const greaterThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size - 2 >= 8)
|
const greaterThanMaxSizeIndex = selection.findIndex(s => !s.size || s.size - 2 >= 8)
|
||||||
@@ -144,6 +172,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bold() {
|
public bold() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const noBoldIndex = selection.findIndex(s => !s.bold)
|
const noBoldIndex = selection.findIndex(s => !s.bold)
|
||||||
@@ -154,6 +184,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public italic() {
|
public italic() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const noItalicIndex = selection.findIndex(s => !s.italic)
|
const noItalicIndex = selection.findIndex(s => !s.italic)
|
||||||
@@ -164,6 +196,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public underline() {
|
public underline() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const noUnderlineIndex = selection.findIndex(s => !s.underline)
|
const noUnderlineIndex = selection.findIndex(s => !s.underline)
|
||||||
@@ -174,6 +208,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public strikeout() {
|
public strikeout() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
|
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
|
||||||
@@ -184,6 +220,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public superscript() {
|
public superscript() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const superscriptIndex = selection.findIndex(s => s.type === ElementType.SUPERSCRIPT)
|
const superscriptIndex = selection.findIndex(s => s.type === ElementType.SUPERSCRIPT)
|
||||||
@@ -205,6 +243,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public subscript() {
|
public subscript() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
const subscriptIndex = selection.findIndex(s => s.type === ElementType.SUBSCRIPT)
|
const subscriptIndex = selection.findIndex(s => s.type === ElementType.SUBSCRIPT)
|
||||||
@@ -226,6 +266,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public color(payload: string) {
|
public color(payload: string) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
selection.forEach(el => {
|
selection.forEach(el => {
|
||||||
@@ -235,6 +277,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public highlight(payload: string) {
|
public highlight(payload: string) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const selection = this.range.getSelection()
|
const selection = this.range.getSelection()
|
||||||
if (!selection) return
|
if (!selection) return
|
||||||
selection.forEach(el => {
|
selection.forEach(el => {
|
||||||
@@ -244,6 +288,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public rowFlex(payload: RowFlex) {
|
public rowFlex(payload: RowFlex) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const pageNo = this.draw.getPageNo()
|
const pageNo = this.draw.getPageNo()
|
||||||
@@ -268,6 +314,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public rowMargin(payload: number) {
|
public rowMargin(payload: number) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const pageNo = this.draw.getPageNo()
|
const pageNo = this.draw.getPageNo()
|
||||||
@@ -292,6 +340,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public insertTable(row: number, col: number) {
|
public insertTable(row: number, col: number) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
@@ -341,6 +391,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public insertTableTopRow() {
|
public insertTableTopRow() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, trIndex, tableId } = positionContext
|
const { index, trIndex, tableId } = positionContext
|
||||||
@@ -403,6 +455,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public insertTableBottomRow() {
|
public insertTableBottomRow() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, trIndex, tableId } = positionContext
|
const { index, trIndex, tableId } = positionContext
|
||||||
@@ -468,6 +522,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public insertTableLeftCol() {
|
public insertTableLeftCol() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, tdIndex, tableId } = positionContext
|
const { index, tdIndex, tableId } = positionContext
|
||||||
@@ -524,6 +580,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public insertTableRightCol() {
|
public insertTableRightCol() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, tdIndex, tableId } = positionContext
|
const { index, tdIndex, tableId } = positionContext
|
||||||
@@ -580,6 +638,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public deleteTableRow() {
|
public deleteTableRow() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, trIndex } = positionContext
|
const { index, trIndex } = positionContext
|
||||||
@@ -631,6 +691,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public deleteTableCol() {
|
public deleteTableCol() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, tdIndex, trIndex } = positionContext
|
const { index, tdIndex, trIndex } = positionContext
|
||||||
@@ -687,6 +749,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public deleteTable() {
|
public deleteTable() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const originalElementList = this.draw.getOriginalElementList()
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
@@ -702,6 +766,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public mergeTableCell() {
|
public mergeTableCell() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { isCrossRowCol, startTdIndex, endTdIndex, startTrIndex, endTrIndex } = this.range.getRange()
|
const { isCrossRowCol, startTdIndex, endTdIndex, startTrIndex, endTrIndex } = this.range.getRange()
|
||||||
@@ -809,6 +875,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public cancelMergeTableCell() {
|
public cancelMergeTableCell() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
if (!positionContext.isTable) return
|
if (!positionContext.isTable) return
|
||||||
const { index, tdIndex, trIndex } = positionContext
|
const { index, tdIndex, trIndex } = positionContext
|
||||||
@@ -869,6 +937,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public hyperlink(payload: IElement) {
|
public hyperlink(payload: IElement) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
@@ -893,6 +963,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public separator(payload: number[]) {
|
public separator(payload: number[]) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
@@ -930,6 +1002,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addWatermark(payload: IWatermark) {
|
public addWatermark(payload: IWatermark) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const options = this.draw.getOptions()
|
const options = this.draw.getOptions()
|
||||||
const { color, size, opacity, font } = defaultWatermarkOption
|
const { color, size, opacity, font } = defaultWatermarkOption
|
||||||
options.watermark.data = payload.data
|
options.watermark.data = payload.data
|
||||||
@@ -944,6 +1018,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public deleteWatermark() {
|
public deleteWatermark() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const options = this.draw.getOptions()
|
const options = this.draw.getOptions()
|
||||||
if (options.watermark && options.watermark.data) {
|
if (options.watermark && options.watermark.data) {
|
||||||
options.watermark = { ...defaultWatermarkOption }
|
options.watermark = { ...defaultWatermarkOption }
|
||||||
@@ -955,6 +1031,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public image(payload: IDrawImagePayload) {
|
public image(payload: IDrawImagePayload) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
@@ -1102,6 +1180,8 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public insertElementList(payload: IElement[]) {
|
public insertElementList(payload: IElement[]) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
if (!payload.length) return
|
if (!payload.length) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (!~startIndex && !~endIndex) return
|
if (!~startIndex && !~endIndex) return
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ interface IRenderPayload {
|
|||||||
|
|
||||||
export class ContextMenu {
|
export class ContextMenu {
|
||||||
|
|
||||||
|
private draw: Draw
|
||||||
private command: Command
|
private command: Command
|
||||||
private range: RangeManager
|
private range: RangeManager
|
||||||
private position: Position
|
private position: Position
|
||||||
@@ -25,6 +26,7 @@ export class ContextMenu {
|
|||||||
private contextMenuRelationShip: Map<HTMLDivElement, HTMLDivElement>
|
private contextMenuRelationShip: Map<HTMLDivElement, HTMLDivElement>
|
||||||
|
|
||||||
constructor(draw: Draw, command: Command) {
|
constructor(draw: Draw, command: Command) {
|
||||||
|
this.draw = draw
|
||||||
this.command = command
|
this.command = command
|
||||||
this.range = draw.getRange()
|
this.range = draw.getRange()
|
||||||
this.position = draw.getPosition()
|
this.position = draw.getPosition()
|
||||||
@@ -81,6 +83,8 @@ export class ContextMenu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _getContext(): IContextMenuContext {
|
private _getContext(): IContextMenuContext {
|
||||||
|
// 是否是只读模式
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
const { isCrossRowCol: crossRowCol, startIndex, endIndex } = this.range.getRange()
|
const { isCrossRowCol: crossRowCol, startIndex, endIndex } = this.range.getRange()
|
||||||
// 是否存在焦点
|
// 是否存在焦点
|
||||||
const editorTextFocus = !!(~startIndex || ~endIndex)
|
const editorTextFocus = !!(~startIndex || ~endIndex)
|
||||||
@@ -92,6 +96,7 @@ export class ContextMenu {
|
|||||||
// 是否存在跨行/列
|
// 是否存在跨行/列
|
||||||
const isCrossRowCol = isInTable && !!crossRowCol
|
const isCrossRowCol = isInTable && !!crossRowCol
|
||||||
return {
|
return {
|
||||||
|
isReadonly,
|
||||||
editorHasSelection,
|
editorHasSelection,
|
||||||
editorTextFocus,
|
editorTextFocus,
|
||||||
isInTable,
|
isInTable,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export const globalMenus: IRegisterContextMenu[] = [
|
|||||||
name: '剪切',
|
name: '剪切',
|
||||||
shortCut: 'Ctrl + X',
|
shortCut: 'Ctrl + X',
|
||||||
when: (payload) => {
|
when: (payload) => {
|
||||||
return payload.editorHasSelection
|
return !payload.isReadonly && payload.editorHasSelection
|
||||||
},
|
},
|
||||||
callback: (command: Command) => {
|
callback: (command: Command) => {
|
||||||
command.executeCut()
|
command.executeCut()
|
||||||
@@ -26,7 +26,7 @@ export const globalMenus: IRegisterContextMenu[] = [
|
|||||||
name: '粘贴',
|
name: '粘贴',
|
||||||
shortCut: 'Ctrl + V',
|
shortCut: 'Ctrl + V',
|
||||||
when: (payload) => {
|
when: (payload) => {
|
||||||
return payload.editorTextFocus
|
return !payload.isReadonly && payload.editorTextFocus
|
||||||
},
|
},
|
||||||
callback: (command: Command) => {
|
callback: (command: Command) => {
|
||||||
command.executePaste()
|
command.executePaste()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
name: '插入行列',
|
name: '插入行列',
|
||||||
icon: 'insert-row-col',
|
icon: 'insert-row-col',
|
||||||
when: (payload) => {
|
when: (payload) => {
|
||||||
return payload.isInTable
|
return !payload.isReadonly && payload.isInTable
|
||||||
},
|
},
|
||||||
childMenus: [
|
childMenus: [
|
||||||
{
|
{
|
||||||
@@ -50,7 +50,7 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
name: '删除行列',
|
name: '删除行列',
|
||||||
icon: 'delete-row-col',
|
icon: 'delete-row-col',
|
||||||
when: (payload) => {
|
when: (payload) => {
|
||||||
return payload.isInTable
|
return !payload.isReadonly && payload.isInTable
|
||||||
},
|
},
|
||||||
childMenus: [
|
childMenus: [
|
||||||
{
|
{
|
||||||
@@ -83,7 +83,7 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
name: '合并单元格',
|
name: '合并单元格',
|
||||||
icon: 'merge-cell',
|
icon: 'merge-cell',
|
||||||
when: (payload) => {
|
when: (payload) => {
|
||||||
return payload.isCrossRowCol
|
return !payload.isReadonly && payload.isCrossRowCol
|
||||||
},
|
},
|
||||||
callback: (command: Command) => {
|
callback: (command: Command) => {
|
||||||
command.executeMergeTableCell()
|
command.executeMergeTableCell()
|
||||||
@@ -93,7 +93,7 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
name: '取消合并',
|
name: '取消合并',
|
||||||
icon: 'merge-cancel-cell',
|
icon: 'merge-cancel-cell',
|
||||||
when: (payload) => {
|
when: (payload) => {
|
||||||
return payload.isInTable
|
return !payload.isReadonly && payload.isInTable
|
||||||
},
|
},
|
||||||
callback: (command: Command) => {
|
callback: (command: Command) => {
|
||||||
command.executeCancelMergeTableCell()
|
command.executeCancelMergeTableCell()
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ export class Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public drawCursor() {
|
public drawCursor() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
const cursorPosition = this.position.getCursorPosition()
|
const cursorPosition = this.position.getCursorPosition()
|
||||||
if (!cursorPosition) return
|
if (!cursorPosition) return
|
||||||
// 设置光标代理
|
// 设置光标代理
|
||||||
@@ -60,7 +61,7 @@ export class Cursor {
|
|||||||
// 模拟光标显示
|
// 模拟光标显示
|
||||||
this.cursorDom.style.left = `${cursorLeft}px`
|
this.cursorDom.style.left = `${cursorLeft}px`
|
||||||
this.cursorDom.style.top = `${cursorTop}px`
|
this.cursorDom.style.top = `${cursorTop}px`
|
||||||
this.cursorDom.style.display = 'block'
|
this.cursorDom.style.display = isReadonly ? 'none' : 'block'
|
||||||
this.cursorDom.style.height = `${cursorHeight}px`
|
this.cursorDom.style.height = `${cursorHeight}px`
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.cursorDom.classList.add('cursor--animation')
|
this.cursorDom.classList.add('cursor--animation')
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { SubscriptParticle } from "./particle/Subscript"
|
|||||||
import { SeparatorParticle } from "./particle/Separator"
|
import { SeparatorParticle } from "./particle/Separator"
|
||||||
import { PageBreakParticle } from "./particle/PageBreak"
|
import { PageBreakParticle } from "./particle/PageBreak"
|
||||||
import { Watermark } from "./frame/Watermark"
|
import { Watermark } from "./frame/Watermark"
|
||||||
|
import { EditorMode } from "../../dataset/enum/Editor"
|
||||||
|
|
||||||
export class Draw {
|
export class Draw {
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ export class Draw {
|
|||||||
private pageList: HTMLCanvasElement[]
|
private pageList: HTMLCanvasElement[]
|
||||||
private ctxList: CanvasRenderingContext2D[]
|
private ctxList: CanvasRenderingContext2D[]
|
||||||
private pageNo: number
|
private pageNo: number
|
||||||
|
private mode: EditorMode
|
||||||
private options: Required<IEditorOption>
|
private options: Required<IEditorOption>
|
||||||
private position: Position
|
private position: Position
|
||||||
private elementList: IElement[]
|
private elementList: IElement[]
|
||||||
@@ -85,6 +87,7 @@ export class Draw {
|
|||||||
this.pageList = []
|
this.pageList = []
|
||||||
this.ctxList = []
|
this.ctxList = []
|
||||||
this.pageNo = 0
|
this.pageNo = 0
|
||||||
|
this.mode = options.defaultMode
|
||||||
this.options = options
|
this.options = options
|
||||||
this.elementList = elementList
|
this.elementList = elementList
|
||||||
this.listener = listener
|
this.listener = listener
|
||||||
@@ -131,6 +134,18 @@ export class Draw {
|
|||||||
this.render({ isSetCursor: false })
|
this.render({ isSetCursor: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMode(): EditorMode {
|
||||||
|
return this.mode
|
||||||
|
}
|
||||||
|
|
||||||
|
public setMode(payload: EditorMode) {
|
||||||
|
this.mode = payload
|
||||||
|
}
|
||||||
|
|
||||||
|
public isReadonly() {
|
||||||
|
return this.mode === EditorMode.READONLY
|
||||||
|
}
|
||||||
|
|
||||||
public getWidth(): number {
|
public getWidth(): number {
|
||||||
return Math.floor(this.options.width * this.options.scale)
|
return Math.floor(this.options.width * this.options.scale)
|
||||||
}
|
}
|
||||||
@@ -650,7 +665,9 @@ export class Draw {
|
|||||||
} else if (element.type === ElementType.SEPARATOR) {
|
} else if (element.type === ElementType.SEPARATOR) {
|
||||||
this.separatorParticle.render(ctx, element, x, y)
|
this.separatorParticle.render(ctx, element, x, y)
|
||||||
} else if (element.type === ElementType.PAGE_BREAK) {
|
} else if (element.type === ElementType.PAGE_BREAK) {
|
||||||
this.pageBreakParticle.render(ctx, element, x, y)
|
if (this.mode !== EditorMode.CLEAN) {
|
||||||
|
this.pageBreakParticle.render(ctx, element, x, y)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this.textParticle.record(ctx, element, x, y + offsetY)
|
this.textParticle.record(ctx, element, x, y + offsetY)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ export class CanvasEvent {
|
|||||||
|
|
||||||
public mousedown(evt: MouseEvent) {
|
public mousedown(evt: MouseEvent) {
|
||||||
if (evt.button === MouseEventButton.RIGHT) return
|
if (evt.button === MouseEventButton.RIGHT) return
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
const target = evt.target as HTMLDivElement
|
const target = evt.target as HTMLDivElement
|
||||||
const pageIndex = target.dataset.index
|
const pageIndex = target.dataset.index
|
||||||
// 设置pageNo
|
// 设置pageNo
|
||||||
@@ -207,12 +208,12 @@ export class CanvasEvent {
|
|||||||
const curElement = elementList[curIndex]
|
const curElement = elementList[curIndex]
|
||||||
// 图片尺寸拖拽组件
|
// 图片尺寸拖拽组件
|
||||||
this.imageParticle.clearResizer()
|
this.imageParticle.clearResizer()
|
||||||
if (isDirectHitImage) {
|
if (isDirectHitImage && !isReadonly) {
|
||||||
this.imageParticle.drawResizer(curElement, positionList[curIndex])
|
this.imageParticle.drawResizer(curElement, positionList[curIndex])
|
||||||
}
|
}
|
||||||
// 表格工具组件
|
// 表格工具组件
|
||||||
this.tableTool.dispose()
|
this.tableTool.dispose()
|
||||||
if (isTable) {
|
if (isTable && !isReadonly) {
|
||||||
const originalElementList = this.draw.getOriginalElementList()
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
const originalPositionList = this.position.getOriginalPositionList()
|
const originalPositionList = this.position.getOriginalPositionList()
|
||||||
this.tableTool.render(originalElementList[index], originalPositionList[index])
|
this.tableTool.render(originalElementList[index], originalPositionList[index])
|
||||||
@@ -232,6 +233,7 @@ export class CanvasEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public keydown(evt: KeyboardEvent) {
|
public keydown(evt: KeyboardEvent) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
const cursorPosition = this.position.getCursorPosition()
|
const cursorPosition = this.position.getCursorPosition()
|
||||||
if (!cursorPosition) return
|
if (!cursorPosition) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
@@ -240,6 +242,7 @@ export class CanvasEvent {
|
|||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
const isCollapsed = startIndex === endIndex
|
const isCollapsed = startIndex === endIndex
|
||||||
if (evt.key === KeyMap.Backspace) {
|
if (evt.key === KeyMap.Backspace) {
|
||||||
|
if (isReadonly) return
|
||||||
// 判断是否允许删除
|
// 判断是否允许删除
|
||||||
if (elementList[index].value === ZERO && index === 0) {
|
if (elementList[index].value === ZERO && index === 0) {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
@@ -254,6 +257,7 @@ export class CanvasEvent {
|
|||||||
this.range.setRange(curIndex, curIndex)
|
this.range.setRange(curIndex, curIndex)
|
||||||
this.draw.render({ curIndex })
|
this.draw.render({ curIndex })
|
||||||
} else if (evt.key === KeyMap.Delete) {
|
} else if (evt.key === KeyMap.Delete) {
|
||||||
|
if (isReadonly) return
|
||||||
if (!isCollapsed) {
|
if (!isCollapsed) {
|
||||||
elementList.splice(startIndex + 1, endIndex - startIndex)
|
elementList.splice(startIndex + 1, endIndex - startIndex)
|
||||||
} else {
|
} else {
|
||||||
@@ -263,6 +267,7 @@ export class CanvasEvent {
|
|||||||
this.range.setRange(curIndex, curIndex)
|
this.range.setRange(curIndex, curIndex)
|
||||||
this.draw.render({ curIndex })
|
this.draw.render({ curIndex })
|
||||||
} else if (evt.key === KeyMap.Enter) {
|
} else if (evt.key === KeyMap.Enter) {
|
||||||
|
if (isReadonly) return
|
||||||
// 表格需要上下文信息
|
// 表格需要上下文信息
|
||||||
const positionContext = this.position.getPositionContext()
|
const positionContext = this.position.getPositionContext()
|
||||||
let restArg = {}
|
let restArg = {}
|
||||||
@@ -283,6 +288,7 @@ export class CanvasEvent {
|
|||||||
this.range.setRange(curIndex, curIndex)
|
this.range.setRange(curIndex, curIndex)
|
||||||
this.draw.render({ curIndex })
|
this.draw.render({ curIndex })
|
||||||
} else if (evt.key === KeyMap.Left) {
|
} else if (evt.key === KeyMap.Left) {
|
||||||
|
if (isReadonly) return
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
const curIndex = index - 1
|
const curIndex = index - 1
|
||||||
this.range.setRange(curIndex, curIndex)
|
this.range.setRange(curIndex, curIndex)
|
||||||
@@ -293,6 +299,7 @@ export class CanvasEvent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (evt.key === KeyMap.Right) {
|
} else if (evt.key === KeyMap.Right) {
|
||||||
|
if (isReadonly) return
|
||||||
if (index < position.length - 1) {
|
if (index < position.length - 1) {
|
||||||
const curIndex = index + 1
|
const curIndex = index + 1
|
||||||
this.range.setRange(curIndex, curIndex)
|
this.range.setRange(curIndex, curIndex)
|
||||||
@@ -303,6 +310,7 @@ export class CanvasEvent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (evt.key === KeyMap.Up || evt.key === KeyMap.Down) {
|
} else if (evt.key === KeyMap.Up || evt.key === KeyMap.Down) {
|
||||||
|
if (isReadonly) return
|
||||||
const { rowNo, index, coordinate: { leftTop, rightTop } } = cursorPosition
|
const { rowNo, index, coordinate: { leftTop, rightTop } } = cursorPosition
|
||||||
if ((evt.key === KeyMap.Up && rowNo !== 0) || (evt.key === KeyMap.Down && rowNo !== this.draw.getRowCount())) {
|
if ((evt.key === KeyMap.Up && rowNo !== 0) || (evt.key === KeyMap.Down && rowNo !== this.draw.getRowCount())) {
|
||||||
// 下一个光标点所在行位置集合
|
// 下一个光标点所在行位置集合
|
||||||
@@ -344,18 +352,22 @@ export class CanvasEvent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (evt.ctrlKey && evt.key === KeyMap.Z) {
|
} else if (evt.ctrlKey && evt.key === KeyMap.Z) {
|
||||||
|
if (isReadonly) return
|
||||||
this.historyManager.undo()
|
this.historyManager.undo()
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
} else if (evt.ctrlKey && evt.key === KeyMap.Y) {
|
} else if (evt.ctrlKey && evt.key === KeyMap.Y) {
|
||||||
|
if (isReadonly) return
|
||||||
this.historyManager.redo()
|
this.historyManager.redo()
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
} else if (evt.ctrlKey && evt.key === KeyMap.C) {
|
} else if (evt.ctrlKey && evt.key === KeyMap.C) {
|
||||||
this.copy()
|
this.copy()
|
||||||
} else if (evt.ctrlKey && evt.key === KeyMap.X) {
|
} else if (evt.ctrlKey && evt.key === KeyMap.X) {
|
||||||
|
if (isReadonly) return
|
||||||
this.cut()
|
this.cut()
|
||||||
} else if (evt.ctrlKey && evt.key === KeyMap.A) {
|
} else if (evt.ctrlKey && evt.key === KeyMap.A) {
|
||||||
this.selectAll()
|
this.selectAll()
|
||||||
} else if (evt.ctrlKey && evt.key === KeyMap.S) {
|
} else if (evt.ctrlKey && evt.key === KeyMap.S) {
|
||||||
|
if (isReadonly) return
|
||||||
const saved = this.listener.saved
|
const saved = this.listener.saved
|
||||||
if (saved) {
|
if (saved) {
|
||||||
saved(this.save())
|
saved(this.save())
|
||||||
@@ -365,6 +377,8 @@ export class CanvasEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public input(data: string) {
|
public input(data: string) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
if (!this.cursor) return
|
if (!this.cursor) return
|
||||||
const cursorPosition = this.position.getCursorPosition()
|
const cursorPosition = this.position.getCursorPosition()
|
||||||
if (!data || !cursorPosition || this.isCompositing) return
|
if (!data || !cursorPosition || this.isCompositing) return
|
||||||
@@ -423,6 +437,8 @@ export class CanvasEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public cut() {
|
public cut() {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
if (startIndex !== endIndex) {
|
if (startIndex !== endIndex) {
|
||||||
|
|||||||
@@ -10,3 +10,9 @@ export enum EditorContext {
|
|||||||
PAGE = 'page',
|
PAGE = 'page',
|
||||||
TABLE = 'table'
|
TABLE = 'table'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum EditorMode {
|
||||||
|
EDIT = 'edit',
|
||||||
|
CLEAN = 'clean',
|
||||||
|
READONLY = 'readonly'
|
||||||
|
}
|
||||||
+3
-1
@@ -13,7 +13,7 @@ import { globalMenus } from './core/contextmenu/menus/GlobalMenus'
|
|||||||
import { ContextMenu } from './core/contextmenu/ContextMenu'
|
import { ContextMenu } from './core/contextmenu/ContextMenu'
|
||||||
import { tableMenus } from './core/contextmenu/menus/tableMenus'
|
import { tableMenus } from './core/contextmenu/menus/tableMenus'
|
||||||
import { IContextMenuContext, IRegisterContextMenu } from './interface/contextmenu/ContextMenu'
|
import { IContextMenuContext, IRegisterContextMenu } from './interface/contextmenu/ContextMenu'
|
||||||
import { EditorComponent } from './dataset/enum/Editor'
|
import { EditorComponent, EditorMode } from './dataset/enum/Editor'
|
||||||
import { EDITOR_COMPONENT } from './dataset/constant/Editor'
|
import { EDITOR_COMPONENT } from './dataset/constant/Editor'
|
||||||
import { IHeader } from './interface/Header'
|
import { IHeader } from './interface/Header'
|
||||||
import { IWatermark } from './interface/Watermark'
|
import { IWatermark } from './interface/Watermark'
|
||||||
@@ -36,6 +36,7 @@ export default class Editor {
|
|||||||
...options.watermark
|
...options.watermark
|
||||||
}
|
}
|
||||||
const editorOptions: Required<IEditorOption> = {
|
const editorOptions: Required<IEditorOption> = {
|
||||||
|
defaultMode: EditorMode.EDIT,
|
||||||
defaultType: 'TEXT',
|
defaultType: 'TEXT',
|
||||||
defaultFont: 'Yahei',
|
defaultFont: 'Yahei',
|
||||||
defaultSize: 16,
|
defaultSize: 16,
|
||||||
@@ -92,6 +93,7 @@ export default class Editor {
|
|||||||
export {
|
export {
|
||||||
Editor,
|
Editor,
|
||||||
RowFlex,
|
RowFlex,
|
||||||
|
EditorMode,
|
||||||
ElementType,
|
ElementType,
|
||||||
EditorComponent,
|
EditorComponent,
|
||||||
EDITOR_COMPONENT
|
EDITOR_COMPONENT
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { IElement } from ".."
|
import { IElement } from ".."
|
||||||
|
import { EditorMode } from "../dataset/enum/Editor"
|
||||||
import { IHeader } from "./Header"
|
import { IHeader } from "./Header"
|
||||||
import { IWatermark } from "./Watermark"
|
import { IWatermark } from "./Watermark"
|
||||||
|
|
||||||
export interface IEditorOption {
|
export interface IEditorOption {
|
||||||
|
defaultMode?: EditorMode;
|
||||||
defaultType?: string;
|
defaultType?: string;
|
||||||
defaultFont?: string;
|
defaultFont?: string;
|
||||||
defaultSize?: number;
|
defaultSize?: number;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export interface IContextMenuContext {
|
export interface IContextMenuContext {
|
||||||
|
isReadonly: boolean;
|
||||||
editorHasSelection: boolean;
|
editorHasSelection: boolean;
|
||||||
editorTextFocus: boolean;
|
editorTextFocus: boolean;
|
||||||
isInTable: boolean;
|
isInTable: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user