fix: paste and format element boundary error
This commit is contained in:
@@ -76,8 +76,9 @@ export class CursorAgent {
|
|||||||
const pasteElementList = getElementListByHTML(htmlText, {
|
const pasteElementList = getElementListByHTML(htmlText, {
|
||||||
innerWidth: this.draw.getOriginalInnerWidth()
|
innerWidth: this.draw.getOriginalInnerWidth()
|
||||||
})
|
})
|
||||||
if (~startIndex) {
|
// 全选粘贴无需格式化上下文
|
||||||
// 如果是复制到虚拟元素里,则粘贴列表的虚拟元素需扁平化处理
|
if (~startIndex && !rangeManager.getIsSelectAll()) {
|
||||||
|
// 如果是复制到虚拟元素里,则粘贴列表的虚拟元素需扁平化处理,避免产生新的虚拟元素
|
||||||
const anchorElement = elementList[startIndex]
|
const anchorElement = elementList[startIndex]
|
||||||
if (anchorElement?.titleId || anchorElement?.listId) {
|
if (anchorElement?.titleId || anchorElement?.listId) {
|
||||||
let start = 0
|
let start = 0
|
||||||
|
|||||||
@@ -154,6 +154,12 @@ export class RangeManager {
|
|||||||
return rangeElementList
|
return rangeElementList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getIsSelectAll() {
|
||||||
|
const elementList = this.draw.getElementList()
|
||||||
|
const { startIndex, endIndex } = this.range
|
||||||
|
return startIndex === 0 && elementList.length - 1 === endIndex
|
||||||
|
}
|
||||||
|
|
||||||
public getIsPointInRange(x: number, y: number): boolean {
|
public getIsPointInRange(x: number, y: number): boolean {
|
||||||
const { startIndex, endIndex } = this.range
|
const { startIndex, endIndex } = this.range
|
||||||
const positionList = this.position.getPositionList()
|
const positionList = this.position.getPositionList()
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ export function getElementListByHTML(htmlText: string, options: IGetElementListB
|
|||||||
document.body.appendChild(clipboardDom)
|
document.body.appendChild(clipboardDom)
|
||||||
const deleteNodes: ChildNode[] = []
|
const deleteNodes: ChildNode[] = []
|
||||||
clipboardDom.childNodes.forEach(child => {
|
clipboardDom.childNodes.forEach(child => {
|
||||||
if (child.nodeType !== 1) {
|
if (child.nodeType !== 1 && !child.textContent?.trim()) {
|
||||||
deleteNodes.push(child)
|
deleteNodes.push(child)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+104
-103
@@ -40,7 +40,60 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
let i = 0
|
let i = 0
|
||||||
while (i < elementList.length) {
|
while (i < elementList.length) {
|
||||||
let el = elementList[i]
|
let el = elementList[i]
|
||||||
if (el.type === ElementType.TABLE) {
|
// 优先处理虚拟元素
|
||||||
|
if (el.type === ElementType.TITLE) {
|
||||||
|
// 移除父节点
|
||||||
|
elementList.splice(i, 1)
|
||||||
|
// 格式化元素
|
||||||
|
const valueList = el.valueList || []
|
||||||
|
formatElementList(valueList, {
|
||||||
|
...options,
|
||||||
|
isHandleFirstElement: false
|
||||||
|
})
|
||||||
|
// 追加节点
|
||||||
|
if (valueList.length) {
|
||||||
|
const titleId = getUUID()
|
||||||
|
const titleOptions = editorOptions.title
|
||||||
|
for (let v = 0; v < valueList.length; v++) {
|
||||||
|
const value = valueList[v]
|
||||||
|
value.titleId = titleId
|
||||||
|
value.level = el.level
|
||||||
|
// 文本型元素设置字体及加粗
|
||||||
|
if (isTextLikeElement(value)) {
|
||||||
|
if (!value.size) {
|
||||||
|
value.size = titleOptions[titleSizeMapping[value.level!]]
|
||||||
|
}
|
||||||
|
if (value.bold === undefined) {
|
||||||
|
value.bold = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elementList.splice(i, 0, value)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
} else if (el.type === ElementType.LIST) {
|
||||||
|
// 移除父节点
|
||||||
|
elementList.splice(i, 1)
|
||||||
|
// 格式化元素
|
||||||
|
const valueList = el.valueList || []
|
||||||
|
formatElementList(valueList, {
|
||||||
|
...options
|
||||||
|
})
|
||||||
|
// 追加节点
|
||||||
|
if (valueList.length) {
|
||||||
|
const listId = getUUID()
|
||||||
|
for (let v = 0; v < valueList.length; v++) {
|
||||||
|
const value = valueList[v]
|
||||||
|
value.listId = listId
|
||||||
|
value.listType = el.listType
|
||||||
|
value.listStyle = el.listStyle
|
||||||
|
elementList.splice(i, 0, value)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
} else if (el.type === ElementType.TABLE) {
|
||||||
const tableId = getUUID()
|
const tableId = getUUID()
|
||||||
el.id = tableId
|
el.id = tableId
|
||||||
if (el.trList) {
|
if (el.trList) {
|
||||||
@@ -107,58 +160,6 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
i--
|
i--
|
||||||
} else if (el.type === ElementType.TITLE) {
|
|
||||||
// 移除父节点
|
|
||||||
elementList.splice(i, 1)
|
|
||||||
// 格式化元素
|
|
||||||
const valueList = el.valueList || []
|
|
||||||
formatElementList(valueList, {
|
|
||||||
...options,
|
|
||||||
isHandleFirstElement: false
|
|
||||||
})
|
|
||||||
// 追加节点
|
|
||||||
if (valueList.length) {
|
|
||||||
const titleId = getUUID()
|
|
||||||
const titleOptions = editorOptions.title
|
|
||||||
for (let v = 0; v < valueList.length; v++) {
|
|
||||||
const value = valueList[v]
|
|
||||||
value.titleId = titleId
|
|
||||||
value.level = el.level
|
|
||||||
// 文本型元素设置字体及加粗
|
|
||||||
if (isTextLikeElement(value)) {
|
|
||||||
if (!value.size) {
|
|
||||||
value.size = titleOptions[titleSizeMapping[value.level!]]
|
|
||||||
}
|
|
||||||
if (value.bold === undefined) {
|
|
||||||
value.bold = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elementList.splice(i, 0, value)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i--
|
|
||||||
} else if (el.type === ElementType.LIST) {
|
|
||||||
// 移除父节点
|
|
||||||
elementList.splice(i, 1)
|
|
||||||
// 格式化元素
|
|
||||||
const valueList = el.valueList || []
|
|
||||||
formatElementList(valueList, {
|
|
||||||
...options
|
|
||||||
})
|
|
||||||
// 追加节点
|
|
||||||
if (valueList.length) {
|
|
||||||
const listId = getUUID()
|
|
||||||
for (let v = 0; v < valueList.length; v++) {
|
|
||||||
const value = valueList[v]
|
|
||||||
value.listId = listId
|
|
||||||
value.listType = el.listType
|
|
||||||
value.listStyle = el.listStyle
|
|
||||||
elementList.splice(i, 0, value)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i--
|
|
||||||
} else if (el.type === ElementType.CONTROL) {
|
} else if (el.type === ElementType.CONTROL) {
|
||||||
const { prefix, postfix, value, placeholder, code, type, valueSets } = el.control!
|
const { prefix, postfix, value, placeholder, code, type, valueSets } = el.control!
|
||||||
const controlId = getUUID()
|
const controlId = getUUID()
|
||||||
@@ -359,8 +360,56 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
|||||||
e++
|
e++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// 表格、超链接、日期、控件特殊处理
|
// 优先处理虚拟元素,后表格、超链接、日期、控件特殊处理
|
||||||
if (element.type === ElementType.TABLE) {
|
if (element.titleId && element.level) {
|
||||||
|
// 标题处理
|
||||||
|
const titleId = element.titleId
|
||||||
|
const level = element.level
|
||||||
|
const titleElement: IElement = {
|
||||||
|
type: ElementType.TITLE,
|
||||||
|
value: '',
|
||||||
|
level
|
||||||
|
}
|
||||||
|
const valueList: IElement[] = []
|
||||||
|
while (e < elementList.length) {
|
||||||
|
const titleE = elementList[e]
|
||||||
|
if (titleId !== titleE.titleId) {
|
||||||
|
e--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
delete titleE.level
|
||||||
|
valueList.push(titleE)
|
||||||
|
e++
|
||||||
|
}
|
||||||
|
titleElement.valueList = zipElementList(valueList)
|
||||||
|
element = titleElement
|
||||||
|
} else if (element.listId && element.listType) {
|
||||||
|
// 列表处理
|
||||||
|
const listId = element.listId
|
||||||
|
const listType = element.listType
|
||||||
|
const listStyle = element.listStyle
|
||||||
|
const listElement: IElement = {
|
||||||
|
type: ElementType.LIST,
|
||||||
|
value: '',
|
||||||
|
listId,
|
||||||
|
listType,
|
||||||
|
listStyle
|
||||||
|
}
|
||||||
|
const valueList: IElement[] = []
|
||||||
|
while (e < elementList.length) {
|
||||||
|
const listE = elementList[e]
|
||||||
|
if (listId !== listE.listId) {
|
||||||
|
e--
|
||||||
|
break
|
||||||
|
}
|
||||||
|
delete listE.listType
|
||||||
|
delete listE.listStyle
|
||||||
|
valueList.push(listE)
|
||||||
|
e++
|
||||||
|
}
|
||||||
|
listElement.valueList = zipElementList(valueList)
|
||||||
|
element = listElement
|
||||||
|
} else if (element.type === ElementType.TABLE) {
|
||||||
if (element.trList) {
|
if (element.trList) {
|
||||||
for (let t = 0; t < element.trList.length; t++) {
|
for (let t = 0; t < element.trList.length; t++) {
|
||||||
const tr = element.trList[t]
|
const tr = element.trList[t]
|
||||||
@@ -422,54 +471,6 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
|||||||
}
|
}
|
||||||
dateElement.valueList = zipElementList(valueList)
|
dateElement.valueList = zipElementList(valueList)
|
||||||
element = dateElement
|
element = dateElement
|
||||||
} else if (element.titleId && element.level) {
|
|
||||||
// 标题处理
|
|
||||||
const titleId = element.titleId
|
|
||||||
const level = element.level
|
|
||||||
const titleElement: IElement = {
|
|
||||||
type: ElementType.TITLE,
|
|
||||||
value: '',
|
|
||||||
level
|
|
||||||
}
|
|
||||||
const valueList: IElement[] = []
|
|
||||||
while (e < elementList.length) {
|
|
||||||
const titleE = elementList[e]
|
|
||||||
if (titleId !== titleE.titleId) {
|
|
||||||
e--
|
|
||||||
break
|
|
||||||
}
|
|
||||||
delete titleE.level
|
|
||||||
valueList.push(titleE)
|
|
||||||
e++
|
|
||||||
}
|
|
||||||
titleElement.valueList = zipElementList(valueList)
|
|
||||||
element = titleElement
|
|
||||||
} else if (element.listId && element.listType) {
|
|
||||||
// 列表处理
|
|
||||||
const listId = element.listId
|
|
||||||
const listType = element.listType
|
|
||||||
const listStyle = element.listStyle
|
|
||||||
const listElement: IElement = {
|
|
||||||
type: ElementType.LIST,
|
|
||||||
value: '',
|
|
||||||
listId,
|
|
||||||
listType,
|
|
||||||
listStyle
|
|
||||||
}
|
|
||||||
const valueList: IElement[] = []
|
|
||||||
while (e < elementList.length) {
|
|
||||||
const listE = elementList[e]
|
|
||||||
if (listId !== listE.listId) {
|
|
||||||
e--
|
|
||||||
break
|
|
||||||
}
|
|
||||||
delete listE.listType
|
|
||||||
delete listE.listStyle
|
|
||||||
valueList.push(listE)
|
|
||||||
e++
|
|
||||||
}
|
|
||||||
listElement.valueList = zipElementList(valueList)
|
|
||||||
element = listElement
|
|
||||||
} else if (element.type === ElementType.CONTROL) {
|
} else if (element.type === ElementType.CONTROL) {
|
||||||
// 控件处理
|
// 控件处理
|
||||||
const controlId = element.controlId
|
const controlId = element.controlId
|
||||||
|
|||||||
Reference in New Issue
Block a user