diff --git a/src/editor/core/command/CommandAdapt.ts b/src/editor/core/command/CommandAdapt.ts index e61de04..eeee2a1 100644 --- a/src/editor/core/command/CommandAdapt.ts +++ b/src/editor/core/command/CommandAdapt.ts @@ -1,11 +1,13 @@ import { ZERO } from "../../dataset/constant/Common" import { EDITOR_ELEMENT_STYLE } from "../../dataset/constant/Element" +import { EditorContext } from "../../dataset/enum/Editor" import { ElementType } from "../../dataset/enum/Element" import { ElementStyleKey } from "../../dataset/enum/ElementStyle" import { RowFlex } from "../../dataset/enum/Row" import { IDrawImagePayload } from "../../interface/Draw" import { IEditorOption } from "../../interface/Editor" import { IElement, IElementStyle } from "../../interface/Element" +import { ISearchResult, ISearchResultRestArgs } from "../../interface/Search" import { IColgroup } from "../../interface/table/Colgroup" import { ITd } from "../../interface/table/Td" import { ITr } from "../../interface/table/Tr" @@ -291,19 +293,76 @@ export class CommandAdapt { public search(payload: string | null) { if (payload) { - const elementList = this.draw.getElementList() - const text = elementList.map(e => !e.type || e.type === ElementType.TEXT ? e.value : ZERO) - .filter(Boolean) - .join('') - const matchStartIndexList = [] - let index = text.indexOf(payload) - while (index !== -1) { - matchStartIndexList.push(index) - index = text.indexOf(payload, index + 1) + let searchMatchList: ISearchResult[] = [] + // elementList按table分隔 + const elementListGroup: { type: EditorContext, elementList: IElement[], index: number }[] = [] + const originalElementList = this.draw.getOriginalElementList() + let lastTextElementList: IElement[] = [] + for (let e = 0; e < originalElementList.length; e++) { + const element = originalElementList[e] + if (element.type === ElementType.TABLE) { + if (lastTextElementList.length) { + elementListGroup.push({ + index: e, + type: EditorContext.PAGE, + elementList: lastTextElementList + }) + lastTextElementList = [] + } + elementListGroup.push({ + index: e, + type: EditorContext.TABLE, + elementList: [element] + }) + } else { + lastTextElementList.push(element) + } + } + // 搜索文本 + function searchClosure(payload: string | null, type: EditorContext, elementList: IElement[], restArgs?: ISearchResultRestArgs) { + if (!payload) return + const text = elementList.map(e => !e.type || e.type === ElementType.TEXT ? e.value : ZERO) + .filter(Boolean) + .join('') + const matchStartIndexList = [] + let index = text.indexOf(payload) + while (index !== -1) { + matchStartIndexList.push(index) + index = text.indexOf(payload, index + 1) + } + for (let m = 0; m < matchStartIndexList.length; m++) { + const startIndex = matchStartIndexList[m] + for (let i = 0; i < payload.length; i++) { + const index = startIndex + i + searchMatchList.push({ + type, + index, + ...restArgs + }) + } + } + } + for (let e = 0; e < elementListGroup.length; e++) { + const group = elementListGroup[e] + if (group.type === EditorContext.TABLE) { + const tableElement = group.elementList[0] + for (let t = 0; t < tableElement.trList!.length; t++) { + const tr = tableElement.trList![t] + for (let d = 0; d < tr.tdList.length; d++) { + const td = tr.tdList[d] + const restArgs: ISearchResultRestArgs = { + tableIndex: group.index, + trIndex: t, + tdIndex: d + } + searchClosure(payload, group.type, td.value, restArgs) + } + } + } else { + searchClosure(payload, group.type, group.elementList) + } } - const searchMatch: number[][] = matchStartIndexList - .map(i => Array(payload.length).fill(i).map((_, j) => i + j)) - this.draw.setSearchMatch(searchMatch.length ? searchMatch : null) + this.draw.setSearchMatch(searchMatchList) } else { this.draw.setSearchMatch(null) } diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index f668561..55266de 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -24,6 +24,7 @@ import { TextParticle } from "./particle/TextParticle" import { PageNumber } from "./frame/PageNumber" import { GlobalObserver } from "../observer/GlobalObserver" import { TableParticle } from "./particle/table/TableParticle" +import { ISearchResult } from "../../interface/Search" export class Draw { @@ -53,7 +54,7 @@ export class Draw { private rowList: IRow[] private painterStyle: IElementStyle | null - private searchMatchList: number[][] | null + private searchMatchList: ISearchResult[] | null private visiblePageNoList: number[] private intersectionPageNo: number @@ -252,11 +253,11 @@ export class Draw { } } - public getSearchMatch(): number[][] | null { + public getSearchMatch(): ISearchResult[] | null { return this.searchMatchList } - public setSearchMatch(payload: number[][] | null) { + public setSearchMatch(payload: ISearchResult[] | null) { this.searchMatchList = payload } diff --git a/src/editor/core/draw/interactive/Search.ts b/src/editor/core/draw/interactive/Search.ts index e348c86..6812932 100644 --- a/src/editor/core/draw/interactive/Search.ts +++ b/src/editor/core/draw/interactive/Search.ts @@ -1,4 +1,6 @@ +import { EditorContext } from "../../../dataset/enum/Editor" import { IEditorOption } from "../../../interface/Editor" +import { IElementPosition } from "../../../interface/Element" import { Position } from "../../position/Position" import { Draw } from "../Draw" @@ -15,24 +17,32 @@ export class Search { } public render(ctx: CanvasRenderingContext2D, pageIndex: number) { - const searchMatch = this.draw.getSearchMatch() - if (!searchMatch || !searchMatch.length) return - const searchMatchList = searchMatch.flat() + const searchMatchList = this.draw.getSearchMatch() + if (!searchMatchList || !searchMatchList.length) return + const { searchMatchAlpha, searchMatchColor } = this.options const positionList = this.position.getOriginalPositionList() + const elementList = this.draw.getOriginalElementList() ctx.save() - ctx.globalAlpha = this.options.searchMatchAlpha - ctx.fillStyle = this.options.searchMatchColor - searchMatchList.forEach(s => { - const position = positionList[s] - if (!position) return + ctx.globalAlpha = searchMatchAlpha + ctx.fillStyle = searchMatchColor + for (let s = 0; s < searchMatchList.length; s++) { + const searchMatch = searchMatchList[s] + let position: IElementPosition | null = null + if (searchMatch.type === EditorContext.TABLE) { + const { tableIndex, trIndex, tdIndex, index } = searchMatch + position = elementList[tableIndex!]?.trList![trIndex!].tdList[tdIndex!]!?.positionList![index] + } else { + position = positionList[searchMatch.index] + } + if (!position) continue const { coordinate: { leftTop, leftBottom, rightTop }, pageNo } = position - if (pageNo !== pageIndex) return + if (pageNo !== pageIndex) continue const x = leftTop[0] const y = leftTop[1] const width = rightTop[0] - leftTop[0] const height = leftBottom[1] - leftTop[1] ctx.fillRect(x, y, width, height) - }) + } ctx.restore() } diff --git a/src/editor/dataset/enum/Editor.ts b/src/editor/dataset/enum/Editor.ts index 8376db2..9ec6035 100644 --- a/src/editor/dataset/enum/Editor.ts +++ b/src/editor/dataset/enum/Editor.ts @@ -2,4 +2,9 @@ export enum EditorComponent { MENU = 'menu', MAIN = 'main', FOOTER = 'footer' +} + +export enum EditorContext { + PAGE = 'page', + TABLE = 'table' } \ No newline at end of file diff --git a/src/editor/interface/Search.ts b/src/editor/interface/Search.ts new file mode 100644 index 0000000..6f79eb6 --- /dev/null +++ b/src/editor/interface/Search.ts @@ -0,0 +1,14 @@ +import { EditorContext } from "../dataset/enum/Editor" + +export interface ISearchResultBasic { + type: EditorContext; + index: number; +} + +export interface ISearchResultRestArgs { + tableIndex?: number; + trIndex?: number; + tdIndex?: number; +} + +export type ISearchResult = ISearchResultBasic & ISearchResultRestArgs \ No newline at end of file