feat:data persistence

pr675
黄云飞 4 years ago
parent e4002c3415
commit 8a4688cfd1

@ -7,12 +7,14 @@ import { KeyMap } from "../../dataset/enum/Keymap"
import { IElement } from "../../interface/Element"
import { ICurrentPosition } from "../../interface/Position"
import { writeTextByElementList } from "../../utils/clipboard"
import { zipElementList } from "../../utils/element"
import { Cursor } from "../cursor/Cursor"
import { Draw } from "../draw/Draw"
import { HyperlinkParticle } from "../draw/particle/HyperlinkParticle"
import { ImageParticle } from "../draw/particle/ImageParticle"
import { TableTool } from "../draw/particle/table/TableTool"
import { HistoryManager } from "../history/HistoryManager"
import { Listener } from "../listener/Listener"
import { Position } from "../position/Position"
import { RangeManager } from "../range/RangeManager"
@ -32,6 +34,7 @@ export class CanvasEvent {
private imageParticle: ImageParticle
private tableTool: TableTool
private hyperlinkParticle: HyperlinkParticle
private listener: Listener
constructor(draw: Draw) {
this.isAllowDrag = false
@ -48,6 +51,7 @@ export class CanvasEvent {
this.imageParticle = this.draw.getImageParticle()
this.tableTool = this.draw.getTableTool()
this.hyperlinkParticle = this.draw.getHyperlinkParticle()
this.listener = this.draw.getListener()
}
public register() {
@ -349,6 +353,12 @@ export class CanvasEvent {
this.cut()
} else if (evt.ctrlKey && evt.key === KeyMap.A) {
this.selectAll()
} else if (evt.ctrlKey && evt.key === KeyMap.S) {
const saved = this.listener.saved
if (saved) {
saved(this.save())
}
evt.preventDefault()
}
}
@ -445,4 +455,10 @@ export class CanvasEvent {
this.isCompositing = false
}
public save(): IElement[] {
const elementList = this.draw.getOriginalElementList()
const data = zipElementList(elementList)
return data
}
}

@ -3,6 +3,7 @@ import {
IPageScaleChange,
IPageSizeChange,
IRangeStyleChange,
ISaved,
IVisiblePageNoListChange
} from "../../interface/Listener"
@ -13,6 +14,7 @@ export class Listener {
public intersectionPageNoChange: IIntersectionPageNoChange | null
public pageSizeChange: IPageSizeChange | null
public pageScaleChange: IPageScaleChange | null
public saved: ISaved | null
constructor() {
this.rangeStyleChange = null
@ -20,6 +22,7 @@ export class Listener {
this.intersectionPageNoChange = null
this.pageSizeChange = null
this.pageScaleChange = null
this.saved = null
}
}

@ -1,6 +1,6 @@
import { IElement } from "../../interface/Element"
export const EDITOR_ELEMENT_STYLE = [
export const EDITOR_ELEMENT_STYLE_ATTR = [
'bold',
'color',
'highlight',
@ -24,4 +24,23 @@ export const EDITOR_ELEMENT_COPY_ATTR: Array<keyof IElement> = [
'rowFlex',
'url',
'hyperlinkId'
]
export const EDITOR_ELEMENT_ZIP_ATTR: Array<keyof IElement> = [
'type',
'font',
'size',
'bold',
'color',
'italic',
'highlight',
'underline',
'strikeout',
'rowFlex',
'trList',
'width',
'height',
'url',
'colgroup',
'valueList'
]

@ -8,6 +8,7 @@ export enum KeyMap {
Down = "ArrowDown",
A = "a",
C = "c",
S = "s",
X = "x",
Y = "y",
Z = "z"

@ -1,3 +1,4 @@
import { IElement } from ".."
import { RowFlex } from "../dataset/enum/Row"
export interface IRangeStype {
@ -24,3 +25,5 @@ export type IIntersectionPageNoChange = (payload: number) => void
export type IPageSizeChange = (payload: number) => void
export type IPageScaleChange = (payload: number) => void
export type ISaved = (payload: IElement[]) => void

@ -1,6 +1,7 @@
import { getUUID } from "."
import { deepClone, getUUID } from "."
import { ElementType, IElement } from ".."
import { ZERO } from "../dataset/constant/Common"
import { EDITOR_ELEMENT_ZIP_ATTR } from "../dataset/constant/Element"
export function formatElementList(elementList: IElement[]) {
if (elementList[0]?.value !== ZERO) {
@ -59,4 +60,70 @@ export function formatElementList(elementList: IElement[]) {
}
i++
}
}
}
export function zipElementList(payload: IElement[]): IElement[] {
const elementList = deepClone(payload)
const zipElementListData: IElement[] = []
let e = 0
while (e < elementList.length) {
let element = elementList[e]
// 筛选所需项
if (e === 0 && element.value === ZERO) {
e++
continue
}
// 表格处理
if (element.type === ElementType.TABLE) {
if (element.trList) {
for (let t = 0; t < element.trList.length; t++) {
const tr = element.trList[t]
delete tr.id
for (let d = 0; d < tr.tdList.length; d++) {
const td = tr.tdList[d]
tr.tdList[d] = {
colspan: td.colspan,
rowspan: td.rowspan,
value: zipElementList(td.value)
}
}
}
}
} else if (element.type === ElementType.HYPERLINK) {
// 超链接处理
const hyperlinkId = element.hyperlinkId
const hyperlinkElement: IElement = {
type: ElementType.HYPERLINK,
value: '',
url: element.url
}
const valueList: IElement[] = []
while (e < elementList.length) {
const hyperlinkE = elementList[e]
if (hyperlinkId !== hyperlinkE.hyperlinkId) {
e--
break
}
delete hyperlinkE.type
delete hyperlinkE.url
valueList.push(hyperlinkE)
e++
}
hyperlinkElement.valueList = zipElementList(valueList)
element = hyperlinkElement
}
// 压缩保留字段
const newElement: IElement = {
value: element.value === ZERO ? `\n` : element.value,
}
EDITOR_ELEMENT_ZIP_ATTR.forEach(attr => {
const value = element[attr] as never
if (value !== undefined) {
newElement[attr] = value
}
})
zipElementListData.push(newElement)
e++
}
return zipElementListData
}

@ -11,7 +11,7 @@ export function debounce(func: Function, delay: number) {
}
}
export function deepClone(obj: any) {
export function deepClone<T>(obj: T): T {
if (!obj || typeof obj !== 'object') {
return obj
}
@ -20,6 +20,7 @@ export function deepClone(obj: any) {
newObj = obj.map(item => deepClone(item))
} else {
Object.keys(obj).forEach((key) => {
// @ts-ignore
return newObj[key] = deepClone(obj[key])
})
}

@ -194,7 +194,7 @@ window.onload = function () {
}])
// 初始化编辑器
const container = document.querySelector<HTMLDivElement>('.editor')!
const instance = new Editor(container, data, {
const instance = new Editor(container, <IElement[]>data, {
margins: [100, 120, 100, 120]
})
console.log('实例: ', instance)
@ -541,4 +541,8 @@ window.onload = function () {
document.querySelector<HTMLSpanElement>('.page-scale-percentage')!.innerText = `${Math.floor(payload * 10 * 10)}%`
}
instance.listener.saved = function (payload) {
console.log('elementList: ', payload)
}
}
Loading…
Cancel
Save