Skip to content

Commit

Permalink
feat: copy style information when wrapping #384
Browse files Browse the repository at this point in the history
  • Loading branch information
Hufe921 committed Jan 8, 2024
1 parent f9edf73 commit 981e458
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 72 deletions.
263 changes: 194 additions & 69 deletions src/editor/core/command/CommandAdapt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
import {
IAppendElementListOption,
IDrawImagePayload,
IDrawOption,
IForceUpdateOption,
IGetImageOption,
IGetValueOption,
Expand Down Expand Up @@ -271,28 +272,53 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
selection.forEach(el => {
el.font = ''
el.color = ''
el.bold = false
el.italic = false
el.underline = false
el.strikeout = false
// 选区设置或设置换行处样式
let renderOption: IDrawOption = {}
let changeElementList: IElement[] = []
if (selection?.length) {
changeElementList = selection
renderOption = { isSetCursor: false }
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
changeElementList.push(enterElement)
renderOption = { curIndex: endIndex }
}
}
if (!changeElementList.length) return
changeElementList.forEach(el => {
delete el.size
delete el.font
delete el.color
delete el.bold
delete el.italic
delete el.underline
delete el.strikeout
})
this.draw.render({ isSetCursor: false })
this.draw.render(renderOption)
}

public font(payload: string) {
const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
selection.forEach(el => {
el.font = payload
})
this.draw.render({ isSetCursor: false })
if (selection?.length) {
selection.forEach(el => {
el.font = payload
})
this.draw.render({ isSetCursor: false })
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.font = payload
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public size(payload: number) {
Expand All @@ -301,10 +327,25 @@ export class CommandAdapt {
const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
// 选区设置或设置换行处样式
let renderOption: IDrawOption = {}
let changeElementList: IElement[] = []
const selection = this.range.getTextLikeSelectionElementList()
if (!selection || !selection.length) return
if (selection?.length) {
changeElementList = selection
renderOption = { isSetCursor: false }
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
changeElementList.push(enterElement)
renderOption = { curIndex: endIndex }
}
}
if (!changeElementList.length) return
let isExistUpdate = false
selection.forEach(el => {
changeElementList.forEach(el => {
if (
(!el.size && payload === defaultSize) ||
(el.size && el.size === payload)
Expand All @@ -315,7 +356,7 @@ export class CommandAdapt {
isExistUpdate = true
})
if (isExistUpdate) {
this.draw.render({ isSetCursor: false })
this.draw.render(renderOption)
}
}

Expand All @@ -324,10 +365,25 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getTextLikeSelectionElementList()
if (!selection || !selection.length) return
// 选区设置或设置换行处样式
let renderOption: IDrawOption = {}
let changeElementList: IElement[] = []
if (selection?.length) {
changeElementList = selection
renderOption = { isSetCursor: false }
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
changeElementList.push(enterElement)
renderOption = { curIndex: endIndex }
}
}
if (!changeElementList.length) return
const { defaultSize, maxSize } = this.options
let isExistUpdate = false
selection.forEach(el => {
changeElementList.forEach(el => {
if (!el.size) {
el.size = defaultSize
}
Expand All @@ -340,7 +396,7 @@ export class CommandAdapt {
isExistUpdate = true
})
if (isExistUpdate) {
this.draw.render({ isSetCursor: false })
this.draw.render(renderOption)
}
}

Expand All @@ -349,10 +405,25 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getTextLikeSelectionElementList()
if (!selection || !selection.length) return
// 选区设置或设置换行处样式
let renderOption: IDrawOption = {}
let changeElementList: IElement[] = []
if (selection?.length) {
changeElementList = selection
renderOption = { isSetCursor: false }
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
changeElementList.push(enterElement)
renderOption = { curIndex: endIndex }
}
}
if (!changeElementList.length) return
const { defaultSize, minSize } = this.options
let isExistUpdate = false
selection.forEach(el => {
changeElementList.forEach(el => {
if (!el.size) {
el.size = defaultSize
}
Expand All @@ -365,7 +436,7 @@ export class CommandAdapt {
isExistUpdate = true
})
if (isExistUpdate) {
this.draw.render({ isSetCursor: false })
this.draw.render(renderOption)
}
}

Expand All @@ -374,57 +445,93 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
const noBoldIndex = selection.findIndex(s => !s.bold)
selection.forEach(el => {
el.bold = !!~noBoldIndex
})
this.draw.render({ isSetCursor: false })
if (selection?.length) {
const noBoldIndex = selection.findIndex(s => !s.bold)
selection.forEach(el => {
el.bold = !!~noBoldIndex
})
this.draw.render({ isSetCursor: false })
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.bold = !enterElement.bold
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public italic() {
const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
const noItalicIndex = selection.findIndex(s => !s.italic)
selection.forEach(el => {
el.italic = !!~noItalicIndex
})
this.draw.render({ isSetCursor: false })
if (selection?.length) {
const noItalicIndex = selection.findIndex(s => !s.italic)
selection.forEach(el => {
el.italic = !!~noItalicIndex
})
this.draw.render({ isSetCursor: false })
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.italic = !enterElement.italic
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public underline() {
const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
const noUnderlineIndex = selection.findIndex(s => !s.underline)
selection.forEach(el => {
el.underline = !!~noUnderlineIndex
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
if (selection?.length) {
const noUnderlineIndex = selection.findIndex(s => !s.underline)
selection.forEach(el => {
el.underline = !!~noUnderlineIndex
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.underline = !enterElement.underline
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public strikeout() {
const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
selection.forEach(el => {
el.strikeout = !!~noStrikeoutIndex
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
if (selection?.length) {
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
selection.forEach(el => {
el.strikeout = !!~noStrikeoutIndex
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.strikeout = !enterElement.strikeout
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public superscript() {
Expand Down Expand Up @@ -492,29 +599,47 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
selection.forEach(el => {
el.color = payload
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
if (selection?.length) {
selection.forEach(el => {
el.color = payload
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.color = payload
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public highlight(payload: string) {
const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return
const selection = this.range.getSelectionElementList()
if (!selection) return
selection.forEach(el => {
el.highlight = payload
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
if (selection?.length) {
selection.forEach(el => {
el.highlight = payload
})
this.draw.render({
isSetCursor: false,
isCompute: false
})
} else {
const { endIndex } = this.range.getRange()
const elementList = this.draw.getElementList()
const enterElement = elementList[endIndex]
if (enterElement?.value === ZERO) {
enterElement.highlight = payload
this.draw.render({ curIndex: endIndex, isCompute: false })
}
}
}

public title(payload: TitleLevel | null) {
Expand Down
2 changes: 1 addition & 1 deletion src/editor/core/draw/Draw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1327,7 +1327,7 @@ export class Draw {
}
metrics.boundingBoxAscent =
(element.value === ZERO
? defaultSize
? element.size || defaultSize
: fontMetrics.actualBoundingBoxAscent) * scale
metrics.boundingBoxDescent =
fontMetrics.actualBoundingBoxDescent * scale
Expand Down
2 changes: 1 addition & 1 deletion src/editor/core/event/handlers/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ export function input(data: string, host: CanvasEvent) {
}
const nextElement = elementList[endIndex + 1]
if (
!copyElement.type ||
copyElement.type === TEXT ||
(!copyElement.type && copyElement.value !== ZERO) ||
(copyElement.type === HYPERLINK && nextElement?.type === HYPERLINK) ||
(copyElement.type === DATE && nextElement?.type === DATE) ||
(copyElement.type === SUBSCRIPT && nextElement?.type === SUBSCRIPT) ||
Expand Down
Loading

0 comments on commit 981e458

Please sign in to comment.