fix:range boundary
This commit is contained in:
@@ -201,7 +201,7 @@ export class CommandAdapt {
|
|||||||
|
|
||||||
public rowFlex(payload: RowFlex) {
|
public rowFlex(payload: RowFlex) {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (startIndex === 0 && endIndex === 0) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const pageNo = this.draw.getPageNo()
|
const pageNo = this.draw.getPageNo()
|
||||||
const positionList = this.position.getPositionList()
|
const positionList = this.position.getPositionList()
|
||||||
// 开始/结束行号
|
// 开始/结束行号
|
||||||
@@ -225,7 +225,7 @@ export class CommandAdapt {
|
|||||||
|
|
||||||
public rowMargin(payload: number) {
|
public rowMargin(payload: number) {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (startIndex === 0 && endIndex === 0) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const pageNo = this.draw.getPageNo()
|
const pageNo = this.draw.getPageNo()
|
||||||
const positionList = this.position.getPositionList()
|
const positionList = this.position.getPositionList()
|
||||||
// 开始/结束行号
|
// 开始/结束行号
|
||||||
@@ -249,7 +249,7 @@ export class CommandAdapt {
|
|||||||
|
|
||||||
public insertTable(row: number, col: number) {
|
public insertTable(row: number, col: number) {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (startIndex === 0 && endIndex === 0) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
const { width, margins } = this.options
|
const { width, margins } = this.options
|
||||||
const innerWidth = width - margins[1] - margins[3]
|
const innerWidth = width - margins[1] - margins[3]
|
||||||
@@ -580,7 +580,9 @@ export class CommandAdapt {
|
|||||||
})
|
})
|
||||||
this.range.setRange(0, 0)
|
this.range.setRange(0, 0)
|
||||||
// 重新渲染
|
// 重新渲染
|
||||||
this.draw.render({ isSetCursor: false })
|
this.draw.render({
|
||||||
|
curIndex: positionContext.index
|
||||||
|
})
|
||||||
this.tableTool.dispose()
|
this.tableTool.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -634,7 +636,9 @@ export class CommandAdapt {
|
|||||||
})
|
})
|
||||||
this.range.setRange(0, 0)
|
this.range.setRange(0, 0)
|
||||||
// 重新渲染
|
// 重新渲染
|
||||||
this.draw.render({ isSetCursor: false })
|
this.draw.render({
|
||||||
|
curIndex: positionContext.index
|
||||||
|
})
|
||||||
this.tableTool.dispose()
|
this.tableTool.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -656,7 +660,7 @@ export class CommandAdapt {
|
|||||||
|
|
||||||
public hyperlink(payload: IElement) {
|
public hyperlink(payload: IElement) {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (startIndex === 0 && endIndex === 0) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
const { valueList, url } = payload
|
const { valueList, url } = payload
|
||||||
const hyperlinkId = getUUID()
|
const hyperlinkId = getUUID()
|
||||||
@@ -680,7 +684,7 @@ export class CommandAdapt {
|
|||||||
|
|
||||||
public image(payload: IDrawImagePayload) {
|
public image(payload: IDrawImagePayload) {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (startIndex === 0 && endIndex === 0) return
|
if (!~startIndex && !~endIndex) return
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
const { value, width, height } = payload
|
const { value, width, height } = payload
|
||||||
const element: IElement = {
|
const element: IElement = {
|
||||||
@@ -703,30 +707,41 @@ export class CommandAdapt {
|
|||||||
public search(payload: string | null) {
|
public search(payload: string | null) {
|
||||||
if (payload) {
|
if (payload) {
|
||||||
let searchMatchList: ISearchResult[] = []
|
let searchMatchList: ISearchResult[] = []
|
||||||
// elementList按table分隔
|
// 分组
|
||||||
const elementListGroup: { type: EditorContext, elementList: IElement[], index: number }[] = []
|
const elementListGroup: { type: EditorContext, elementList: IElement[], index: number }[] = []
|
||||||
const originalElementList = this.draw.getOriginalElementList()
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
let lastTextElementList: IElement[] = []
|
const originalElementListLength = originalElementList.length
|
||||||
for (let e = 0; e < originalElementList.length; e++) {
|
// 查找表格所在位置
|
||||||
|
const tabeleIndexList = []
|
||||||
|
for (let e = 0; e < originalElementListLength; e++) {
|
||||||
const element = originalElementList[e]
|
const element = originalElementList[e]
|
||||||
if (element.type === ElementType.TABLE) {
|
if (element.type === ElementType.TABLE) {
|
||||||
if (lastTextElementList.length) {
|
tabeleIndexList.push(e)
|
||||||
elementListGroup.push({
|
|
||||||
index: e,
|
|
||||||
type: EditorContext.PAGE,
|
|
||||||
elementList: lastTextElementList
|
|
||||||
})
|
|
||||||
lastTextElementList = []
|
|
||||||
}
|
|
||||||
elementListGroup.push({
|
|
||||||
index: e,
|
|
||||||
type: EditorContext.TABLE,
|
|
||||||
elementList: [element]
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
lastTextElementList.push(element)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let i = 0
|
||||||
|
let elementIndex = 0
|
||||||
|
while (elementIndex < originalElementListLength - 1) {
|
||||||
|
const endIndex = tabeleIndexList.length ? tabeleIndexList[i] : originalElementListLength
|
||||||
|
const pageElement = originalElementList.slice(elementIndex, endIndex)
|
||||||
|
if (pageElement.length) {
|
||||||
|
elementListGroup.push({
|
||||||
|
index: elementIndex,
|
||||||
|
type: EditorContext.PAGE,
|
||||||
|
elementList: pageElement
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const tableElement = originalElementList[endIndex]
|
||||||
|
if (tableElement) {
|
||||||
|
elementListGroup.push({
|
||||||
|
index: endIndex,
|
||||||
|
type: EditorContext.TABLE,
|
||||||
|
elementList: [tableElement]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
elementIndex += endIndex + 1
|
||||||
|
i++
|
||||||
|
}
|
||||||
// 搜索文本
|
// 搜索文本
|
||||||
function searchClosure(payload: string | null, type: EditorContext, elementList: IElement[], restArgs?: ISearchResultRestArgs) {
|
function searchClosure(payload: string | null, type: EditorContext, elementList: IElement[], restArgs?: ISearchResultRestArgs) {
|
||||||
if (!payload) return
|
if (!payload) return
|
||||||
@@ -743,7 +758,7 @@ export class CommandAdapt {
|
|||||||
for (let m = 0; m < matchStartIndexList.length; m++) {
|
for (let m = 0; m < matchStartIndexList.length; m++) {
|
||||||
const startIndex = matchStartIndexList[m]
|
const startIndex = matchStartIndexList[m]
|
||||||
for (let i = 0; i < payload.length; i++) {
|
for (let i = 0; i < payload.length; i++) {
|
||||||
const index = startIndex + i
|
const index = startIndex + i + (restArgs?.startIndex || 0)
|
||||||
searchMatchList.push({
|
searchMatchList.push({
|
||||||
type,
|
type,
|
||||||
index,
|
index,
|
||||||
@@ -769,7 +784,9 @@ export class CommandAdapt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
searchClosure(payload, group.type, group.elementList)
|
searchClosure(payload, group.type, group.elementList, {
|
||||||
|
startIndex: group.index
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.draw.setSearchMatch(searchMatchList)
|
this.draw.setSearchMatch(searchMatchList)
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export class ContextMenu {
|
|||||||
private _getContext(): IContextMenuContext {
|
private _getContext(): IContextMenuContext {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
// 是否存在焦点
|
// 是否存在焦点
|
||||||
const editorTextFocus = startIndex !== 0 || endIndex !== 0
|
const editorTextFocus = !!(~startIndex || ~endIndex)
|
||||||
// 是否存在选区
|
// 是否存在选区
|
||||||
const editorHasSelection = editorTextFocus && startIndex !== endIndex
|
const editorHasSelection = editorTextFocus && startIndex !== endIndex
|
||||||
// 是否在表格内
|
// 是否在表格内
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { ElementType } from "../.."
|
import { ElementType } from "../.."
|
||||||
import { ZERO } from "../../dataset/constant/Common"
|
import { ZERO } from "../../dataset/constant/Common"
|
||||||
|
import { EDITOR_ELEMENT_COPY_ATTR } from "../../dataset/constant/Element"
|
||||||
import { ElementStyleKey } from "../../dataset/enum/ElementStyle"
|
import { ElementStyleKey } from "../../dataset/enum/ElementStyle"
|
||||||
import { MouseEventButton } from "../../dataset/enum/Event"
|
import { MouseEventButton } from "../../dataset/enum/Event"
|
||||||
import { KeyMap } from "../../dataset/enum/Keymap"
|
import { KeyMap } from "../../dataset/enum/Keymap"
|
||||||
@@ -100,8 +101,8 @@ export class CanvasEvent {
|
|||||||
if (start > end) {
|
if (start > end) {
|
||||||
[start, end] = [end, start]
|
[start, end] = [end, start]
|
||||||
}
|
}
|
||||||
this.range.setRange(start, end)
|
|
||||||
if (start === end) return
|
if (start === end) return
|
||||||
|
this.range.setRange(start, end)
|
||||||
// 绘制
|
// 绘制
|
||||||
this.draw.render({
|
this.draw.render({
|
||||||
isSubmitHistory: false,
|
isSubmitHistory: false,
|
||||||
@@ -347,23 +348,16 @@ export class CanvasEvent {
|
|||||||
...restArg
|
...restArg
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
!element.type
|
element.type === TEXT
|
||||||
|| element.type === TEXT
|
|| (!element.type && element.value !== ZERO)
|
||||||
|| (element.type === HYPERLINK && elementList[endIndex + 1]?.type === HYPERLINK)
|
|| (element.type === HYPERLINK && elementList[endIndex + 1]?.type === HYPERLINK)
|
||||||
) {
|
) {
|
||||||
if (element.type) {
|
EDITOR_ELEMENT_COPY_ATTR.forEach(attr => {
|
||||||
newElement.type = element.type
|
const value = element[attr] as never
|
||||||
}
|
if (value !== undefined) {
|
||||||
newElement.font = element.font
|
newElement[attr] = value
|
||||||
newElement.size = element.size
|
}
|
||||||
newElement.bold = element.bold
|
})
|
||||||
newElement.color = element.color
|
|
||||||
newElement.highlight = element.highlight
|
|
||||||
newElement.italic = element.italic
|
|
||||||
newElement.underline = element.underline
|
|
||||||
newElement.strikeout = element.strikeout
|
|
||||||
newElement.url = element.url
|
|
||||||
newElement.hyperlinkId = element.hyperlinkId
|
|
||||||
}
|
}
|
||||||
return newElement
|
return newElement
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export class GlobalEvent {
|
|||||||
}
|
}
|
||||||
this.cursor.recoveryCursor()
|
this.cursor.recoveryCursor()
|
||||||
this.range.recoveryRangeStyle()
|
this.range.recoveryRangeStyle()
|
||||||
this.range.setRange(0, 0)
|
this.range.setRange(-1, -1)
|
||||||
this.imageParticle.clearResizer()
|
this.imageParticle.clearResizer()
|
||||||
this.tableTool.dispose()
|
this.tableTool.dispose()
|
||||||
this.hyperlinkParticle.clearHyperlinkPopup()
|
this.hyperlinkParticle.clearHyperlinkPopup()
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ export class RangeManager {
|
|||||||
this.listener = draw.getListener()
|
this.listener = draw.getListener()
|
||||||
this.historyManager = draw.getHistoryManager()
|
this.historyManager = draw.getHistoryManager()
|
||||||
this.range = {
|
this.range = {
|
||||||
startIndex: 0,
|
startIndex: -1,
|
||||||
endIndex: 0
|
endIndex: -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,8 @@ export class RangeManager {
|
|||||||
if (!curElementList) {
|
if (!curElementList) {
|
||||||
const elementList = this.draw.getElementList()
|
const elementList = this.draw.getElementList()
|
||||||
const { endIndex } = this.range
|
const { endIndex } = this.range
|
||||||
curElementList = [elementList[endIndex]]
|
const index = ~endIndex ? endIndex : 0
|
||||||
|
curElementList = [elementList[index]]
|
||||||
}
|
}
|
||||||
const curElement = curElementList[curElementList.length - 1]
|
const curElement = curElementList[curElementList.length - 1]
|
||||||
// 富文本
|
// 富文本
|
||||||
|
|||||||
@@ -1 +1,26 @@
|
|||||||
export const EDITOR_ELEMENT_STYLE = ['bold', 'color', 'highlight', 'font', 'size', 'italic', 'underline', 'strikeout']
|
import { IElement } from "../../interface/Element"
|
||||||
|
|
||||||
|
export const EDITOR_ELEMENT_STYLE = [
|
||||||
|
'bold',
|
||||||
|
'color',
|
||||||
|
'highlight',
|
||||||
|
'font',
|
||||||
|
'size',
|
||||||
|
'italic',
|
||||||
|
'underline',
|
||||||
|
'strikeout'
|
||||||
|
]
|
||||||
|
|
||||||
|
export const EDITOR_ELEMENT_COPY_ATTR: Array<keyof IElement> = [
|
||||||
|
'type',
|
||||||
|
'font',
|
||||||
|
'size',
|
||||||
|
'bold',
|
||||||
|
'color',
|
||||||
|
'italic',
|
||||||
|
'highlight',
|
||||||
|
'underline',
|
||||||
|
'strikeout',
|
||||||
|
'url',
|
||||||
|
'hyperlinkId'
|
||||||
|
]
|
||||||
@@ -9,6 +9,7 @@ export interface ISearchResultRestArgs {
|
|||||||
tableIndex?: number;
|
tableIndex?: number;
|
||||||
trIndex?: number;
|
trIndex?: number;
|
||||||
tdIndex?: number;
|
tdIndex?: number;
|
||||||
|
startIndex?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ISearchResult = ISearchResultBasic & ISearchResultRestArgs
|
export type ISearchResult = ISearchResultBasic & ISearchResultRestArgs
|
||||||
+1
-1
@@ -48,7 +48,7 @@ window.onload = function () {
|
|||||||
if (colorIndex.includes(index)) {
|
if (colorIndex.includes(index)) {
|
||||||
return {
|
return {
|
||||||
value,
|
value,
|
||||||
color: 'red',
|
color: '#FF0000',
|
||||||
size: 16
|
size: 16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user