feat: enter to delete list #376

pr675
Hufe921 2 years ago
parent 56ea7d8bb1
commit f542739d3e

@ -559,34 +559,7 @@ export class CommandAdapt {
public list(listType: ListType | null, listStyle?: ListStyle) {
const isReadonly = this.draw.isReadonly()
if (isReadonly) return
const { startIndex, endIndex } = this.range.getRange()
if (!~startIndex && !~endIndex) return
// 需要改变的元素列表
const changeElementList = this.range.getRangeParagraphElementList()
if (!changeElementList || !changeElementList.length) return
// 如果包含列表则设置为取消列表
const isUnsetList = changeElementList.find(
el => el.listType === listType && el.listStyle === listStyle
)
// 设置值
const listId = getUUID()
changeElementList.forEach(el => {
if (!isUnsetList && listType) {
el.listId = listId
el.listType = listType
el.listStyle = listStyle
} else {
if (el.listId) {
delete el.listId
delete el.listType
delete el.listStyle
}
}
})
// 光标定位
const isSetCursor = startIndex === endIndex
const curIndex = isSetCursor ? endIndex : startIndex
this.draw.render({ curIndex, isSetCursor })
this.draw.getListParticle().setList(listType, listStyle)
}
public rowFlex(payload: RowFlex) {

@ -7,9 +7,13 @@ import { DeepRequired } from '../../../interface/Common'
import { IEditorOption } from '../../../interface/Editor'
import { IElement, IElementPosition } from '../../../interface/Element'
import { IRow } from '../../../interface/Row'
import { getUUID } from '../../../utils'
import { RangeManager } from '../../range/RangeManager'
import { Draw } from '../Draw'
export class ListParticle {
private draw: Draw
private range: RangeManager
private options: DeepRequired<IEditorOption>
// 非递增样式直接返回默认值
@ -18,9 +22,80 @@ export class ListParticle {
private readonly LIST_GAP = 10
constructor(draw: Draw) {
this.draw = draw
this.range = draw.getRange()
this.options = draw.getOptions()
}
public setList(listType: ListType | null, listStyle?: ListStyle) {
const isReadonly = this.draw.isReadonly()
if (isReadonly) return
const { startIndex, endIndex } = this.range.getRange()
if (!~startIndex && !~endIndex) return
// 需要改变的元素列表
const changeElementList = this.range.getRangeParagraphElementList()
if (!changeElementList || !changeElementList.length) return
// 如果包含列表则设置为取消列表
const isUnsetList = changeElementList.find(
el => el.listType === listType && el.listStyle === listStyle
)
if (isUnsetList || !listType) {
this.unsetList()
return
}
// 设置值
const listId = getUUID()
changeElementList.forEach(el => {
el.listId = listId
el.listType = listType
el.listStyle = listStyle
})
// 光标定位
const isSetCursor = startIndex === endIndex
const curIndex = isSetCursor ? endIndex : startIndex
this.draw.render({ curIndex, isSetCursor })
}
public unsetList() {
const isReadonly = this.draw.isReadonly()
if (isReadonly) return
const { startIndex, endIndex } = this.range.getRange()
if (!~startIndex && !~endIndex) return
// 需要改变的元素列表
const changeElementList = this.range
.getRangeParagraphElementList()
?.filter(el => el.listId)
if (!changeElementList || !changeElementList.length) return
// 如果列表最后字符不是换行符则需插入换行符
const elementList = this.draw.getElementList()
const endElement = elementList[endIndex]
if (endElement.listId) {
let start = endIndex + 1
while (start < elementList.length) {
const element = elementList[start]
if (element.value === ZERO && !element.listWrap) break
if (element.listId !== endElement.listId) {
this.draw.spliceElementList(elementList, start, 0, {
value: ZERO
})
break
}
start++
}
}
// 取消设置
changeElementList.forEach(el => {
delete el.listId
delete el.listType
delete el.listStyle
delete el.listWrap
})
// 光标定位
const isSetCursor = startIndex === endIndex
const curIndex = isSetCursor ? endIndex : startIndex
this.draw.render({ curIndex, isSetCursor })
}
public computeListStyle(
ctx: CanvasRenderingContext2D,
elementList: IElement[]

@ -0,0 +1,70 @@
import { ZERO } from '../../../../dataset/constant/Common'
import { IElement } from '../../../../interface/Element'
import { formatElementContext } from '../../../../utils/element'
import { CanvasEvent } from '../../CanvasEvent'
export function enter(evt: KeyboardEvent, host: CanvasEvent) {
const draw = host.getDraw()
const isReadonly = draw.isReadonly()
const control = draw.getControl()
if (isReadonly || control.isPartRangeInControlOutside()) return
const rangeManager = draw.getRange()
const { startIndex, endIndex } = rangeManager.getRange()
const isCollapsed = rangeManager.getIsCollapsed()
const elementList = draw.getElementList()
const startElement = elementList[startIndex]
const endElement = elementList[endIndex]
// 最后一个列表项行首回车取消列表设置
if (
isCollapsed &&
endElement.listId &&
endElement.value === ZERO &&
elementList[endIndex + 1]?.listId !== endElement.listId
) {
draw.getListParticle().unsetList()
return
}
// 列表块内换行
const enterText: IElement = {
value: ZERO
}
if (evt.shiftKey && startElement.listId) {
enterText.listWrap = true
}
// 标题结尾处回车无需格式化
if (
!(
endElement.titleId &&
endElement.titleId !== elementList[endIndex + 1]?.titleId
)
) {
formatElementContext(elementList, [enterText], startIndex)
}
// 控件或文档插入换行元素
const activeControl = control.getActiveControl()
let curIndex: number
if (activeControl && !control.isRangInPostfix()) {
curIndex = control.setValue([enterText])
} else {
const position = draw.getPosition()
const cursorPosition = position.getCursorPosition()
if (!cursorPosition) return
const { index } = cursorPosition
if (isCollapsed) {
draw.spliceElementList(elementList, index + 1, 0, enterText)
} else {
draw.spliceElementList(
elementList,
startIndex + 1,
endIndex - startIndex,
enterText
)
}
curIndex = index + 1
}
if (~curIndex) {
rangeManager.setRange(curIndex, curIndex)
draw.render({ curIndex })
}
evt.preventDefault()
}

@ -1,12 +1,13 @@
import { EditorMode, EditorZone } from '../../..'
import { ZERO } from '../../../dataset/constant/Common'
import { ElementType } from '../../../dataset/enum/Element'
import { KeyMap } from '../../../dataset/enum/KeyMap'
import { MoveDirection } from '../../../dataset/enum/Observer'
import { IElement, IElementPosition } from '../../../interface/Element'
import { formatElementContext } from '../../../utils/element'
import { isMod } from '../../../utils/hotkey'
import { CanvasEvent } from '../CanvasEvent'
import { ZERO } from '../../../../dataset/constant/Common'
import { EditorMode, EditorZone } from '../../../../dataset/enum/Editor'
import { ElementType } from '../../../../dataset/enum/Element'
import { KeyMap } from '../../../../dataset/enum/KeyMap'
import { MoveDirection } from '../../../../dataset/enum/Observer'
import { IElement, IElementPosition } from '../../../../interface/Element'
import { formatElementContext } from '../../../../utils/element'
import { isMod } from '../../../../utils/hotkey'
import { CanvasEvent } from '../../CanvasEvent'
import { enter } from './enter'
export function keydown(evt: KeyboardEvent, host: CanvasEvent) {
if (host.isComposing) return
@ -85,46 +86,7 @@ export function keydown(evt: KeyboardEvent, host: CanvasEvent) {
rangeManager.setRange(curIndex, curIndex)
draw.render({ curIndex })
} else if (evt.key === KeyMap.Enter) {
if (isReadonly || control.isPartRangeInControlOutside()) return
const enterText: IElement = {
value: ZERO
}
const startElement = elementList[startIndex]
const endElement = elementList[endIndex]
// 列表块内换行
if (evt.shiftKey && startElement.listId) {
enterText.listWrap = true
}
// 标题结尾处回车无需格式化
if (
!(
endElement.titleId &&
endElement.titleId !== elementList[endIndex + 1]?.titleId
)
) {
formatElementContext(elementList, [enterText], startIndex)
}
let curIndex: number
if (activeControl && !control.isRangInPostfix()) {
curIndex = control.setValue([enterText])
} else {
if (isCollapsed) {
draw.spliceElementList(elementList, index + 1, 0, enterText)
} else {
draw.spliceElementList(
elementList,
startIndex + 1,
endIndex - startIndex,
enterText
)
}
curIndex = index + 1
}
if (~curIndex) {
rangeManager.setRange(curIndex, curIndex)
draw.render({ curIndex })
}
evt.preventDefault()
enter(evt, host)
} else if (evt.key === KeyMap.Left) {
if (isReadonly) return
if (index > 0) {

@ -154,9 +154,12 @@ export class RangeManager {
if (!rowArray.includes(rowNo)) {
rowArray.unshift(rowNo)
}
const element = elementList[start]
const preElement = elementList[start - 1]
if (
positionList[start]?.value === ZERO ||
elementList[start].titleId !== elementList[start - 1]?.titleId
(element.value === ZERO && !element.listWrap) ||
element.listId !== preElement?.listId ||
element.titleId !== preElement?.titleId
) {
break
}
@ -181,9 +184,12 @@ export class RangeManager {
// 向下查找
let end = endIndex
while (end < positionList.length) {
const element = elementList[end]
const nextElement = elementList[end + 1]
if (
positionList[end].value === ZERO ||
elementList[end].titleId !== elementList[end + 1]?.titleId
(element.value === ZERO && !element.listWrap) ||
element.listId !== nextElement?.listId ||
element.titleId !== nextElement?.titleId
) {
break
}

Loading…
Cancel
Save