feat: copy style information when wrapping #384

pr675
Hufe921 2 years ago
parent f9edf731a2
commit 981e4582f9

@ -29,6 +29,7 @@ import {
import { import {
IAppendElementListOption, IAppendElementListOption,
IDrawImagePayload, IDrawImagePayload,
IDrawOption,
IForceUpdateOption, IForceUpdateOption,
IGetImageOption, IGetImageOption,
IGetValueOption, IGetValueOption,
@ -271,16 +272,32 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return // 选区设置或设置换行处样式
selection.forEach(el => { let renderOption: IDrawOption = {}
el.font = '' let changeElementList: IElement[] = []
el.color = '' if (selection?.length) {
el.bold = false changeElementList = selection
el.italic = false renderOption = { isSetCursor: false }
el.underline = false } else {
el.strikeout = false 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) { public font(payload: string) {
@ -288,11 +305,20 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
selection.forEach(el => { selection.forEach(el => {
el.font = payload el.font = payload
}) })
this.draw.render({ isSetCursor: false }) 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) { public size(payload: number) {
@ -301,10 +327,25 @@ export class CommandAdapt {
const isDisabled = const isDisabled =
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
// 选区设置或设置换行处样式
let renderOption: IDrawOption = {}
let changeElementList: IElement[] = []
const selection = this.range.getTextLikeSelectionElementList() 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 let isExistUpdate = false
selection.forEach(el => { changeElementList.forEach(el => {
if ( if (
(!el.size && payload === defaultSize) || (!el.size && payload === defaultSize) ||
(el.size && el.size === payload) (el.size && el.size === payload)
@ -315,7 +356,7 @@ export class CommandAdapt {
isExistUpdate = true isExistUpdate = true
}) })
if (isExistUpdate) { if (isExistUpdate) {
this.draw.render({ isSetCursor: false }) this.draw.render(renderOption)
} }
} }
@ -324,10 +365,25 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getTextLikeSelectionElementList() 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 const { defaultSize, maxSize } = this.options
let isExistUpdate = false let isExistUpdate = false
selection.forEach(el => { changeElementList.forEach(el => {
if (!el.size) { if (!el.size) {
el.size = defaultSize el.size = defaultSize
} }
@ -340,7 +396,7 @@ export class CommandAdapt {
isExistUpdate = true isExistUpdate = true
}) })
if (isExistUpdate) { if (isExistUpdate) {
this.draw.render({ isSetCursor: false }) this.draw.render(renderOption)
} }
} }
@ -349,10 +405,25 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getTextLikeSelectionElementList() 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 const { defaultSize, minSize } = this.options
let isExistUpdate = false let isExistUpdate = false
selection.forEach(el => { changeElementList.forEach(el => {
if (!el.size) { if (!el.size) {
el.size = defaultSize el.size = defaultSize
} }
@ -365,7 +436,7 @@ export class CommandAdapt {
isExistUpdate = true isExistUpdate = true
}) })
if (isExistUpdate) { if (isExistUpdate) {
this.draw.render({ isSetCursor: false }) this.draw.render(renderOption)
} }
} }
@ -374,12 +445,21 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
const noBoldIndex = selection.findIndex(s => !s.bold) const noBoldIndex = selection.findIndex(s => !s.bold)
selection.forEach(el => { selection.forEach(el => {
el.bold = !!~noBoldIndex el.bold = !!~noBoldIndex
}) })
this.draw.render({ isSetCursor: false }) 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() { public italic() {
@ -387,12 +467,21 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
const noItalicIndex = selection.findIndex(s => !s.italic) const noItalicIndex = selection.findIndex(s => !s.italic)
selection.forEach(el => { selection.forEach(el => {
el.italic = !!~noItalicIndex el.italic = !!~noItalicIndex
}) })
this.draw.render({ isSetCursor: false }) 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() { public underline() {
@ -400,15 +489,24 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
const noUnderlineIndex = selection.findIndex(s => !s.underline) const noUnderlineIndex = selection.findIndex(s => !s.underline)
selection.forEach(el => { selection.forEach(el => {
el.underline = !!~noUnderlineIndex el.underline = !!~noUnderlineIndex
}) })
this.draw.render({ this.draw.render({
isSetCursor: false, isSetCursor: false,
isCompute: 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() { public strikeout() {
@ -416,15 +514,24 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
const noStrikeoutIndex = selection.findIndex(s => !s.strikeout) const noStrikeoutIndex = selection.findIndex(s => !s.strikeout)
selection.forEach(el => { selection.forEach(el => {
el.strikeout = !!~noStrikeoutIndex el.strikeout = !!~noStrikeoutIndex
}) })
this.draw.render({ this.draw.render({
isSetCursor: false, isSetCursor: false,
isCompute: 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() { public superscript() {
@ -492,14 +599,23 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
selection.forEach(el => { selection.forEach(el => {
el.color = payload el.color = payload
}) })
this.draw.render({ this.draw.render({
isSetCursor: false, isSetCursor: false,
isCompute: 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) { public highlight(payload: string) {
@ -507,14 +623,23 @@ export class CommandAdapt {
this.draw.isReadonly() || this.control.isDisabledControl() this.draw.isReadonly() || this.control.isDisabledControl()
if (isDisabled) return if (isDisabled) return
const selection = this.range.getSelectionElementList() const selection = this.range.getSelectionElementList()
if (!selection) return if (selection?.length) {
selection.forEach(el => { selection.forEach(el => {
el.highlight = payload el.highlight = payload
}) })
this.draw.render({ this.draw.render({
isSetCursor: false, isSetCursor: false,
isCompute: 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) { public title(payload: TitleLevel | null) {

@ -1327,7 +1327,7 @@ export class Draw {
} }
metrics.boundingBoxAscent = metrics.boundingBoxAscent =
(element.value === ZERO (element.value === ZERO
? defaultSize ? element.size || defaultSize
: fontMetrics.actualBoundingBoxAscent) * scale : fontMetrics.actualBoundingBoxAscent) * scale
metrics.boundingBoxDescent = metrics.boundingBoxDescent =
fontMetrics.actualBoundingBoxDescent * scale fontMetrics.actualBoundingBoxDescent * scale

@ -41,8 +41,8 @@ export function input(data: string, host: CanvasEvent) {
} }
const nextElement = elementList[endIndex + 1] const nextElement = elementList[endIndex + 1]
if ( if (
!copyElement.type ||
copyElement.type === TEXT || copyElement.type === TEXT ||
(!copyElement.type && copyElement.value !== ZERO) ||
(copyElement.type === HYPERLINK && nextElement?.type === HYPERLINK) || (copyElement.type === HYPERLINK && nextElement?.type === HYPERLINK) ||
(copyElement.type === DATE && nextElement?.type === DATE) || (copyElement.type === DATE && nextElement?.type === DATE) ||
(copyElement.type === SUBSCRIPT && nextElement?.type === SUBSCRIPT) || (copyElement.type === SUBSCRIPT && nextElement?.type === SUBSCRIPT) ||

@ -1,6 +1,10 @@
import { ZERO } from '../../../../dataset/constant/Common' import { ZERO } from '../../../../dataset/constant/Common'
import { EDITOR_ELEMENT_STYLE_ATTR } from '../../../../dataset/constant/Element'
import { IElement } from '../../../../interface/Element' import { IElement } from '../../../../interface/Element'
import { formatElementContext } from '../../../../utils/element' import {
formatElementContext,
getAnchorElement
} from '../../../../utils/element'
import { CanvasEvent } from '../../CanvasEvent' import { CanvasEvent } from '../../CanvasEvent'
export function enter(evt: KeyboardEvent, host: CanvasEvent) { export function enter(evt: KeyboardEvent, host: CanvasEvent) {
@ -40,6 +44,16 @@ export function enter(evt: KeyboardEvent, host: CanvasEvent) {
) { ) {
formatElementContext(elementList, [enterText], startIndex) formatElementContext(elementList, [enterText], startIndex)
} }
// 复制样式属性
const copyElement = getAnchorElement(elementList, endIndex)
if (copyElement) {
EDITOR_ELEMENT_STYLE_ATTR.forEach(attr => {
const value = copyElement[attr] as never
if (value !== undefined) {
enterText[attr] = value
}
})
}
// 控件或文档插入换行元素 // 控件或文档插入换行元素
const activeControl = control.getActiveControl() const activeControl = control.getActiveControl()
let curIndex: number let curIndex: number

Loading…
Cancel
Save