Skip to content

Commit da5a1f5

Browse files
committed
feat: serialize & deserialize
1 parent 641d9cd commit da5a1f5

6 files changed

Lines changed: 49 additions & 14 deletions

File tree

packages/core/src/clipboard/modules/copy.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ export class Copy extends EditorModule {
9393
return root as T;
9494
}
9595
if (this.reflex.isBlock(current)) {
96-
const lineFragment = document.createDocumentFragment();
97-
current.children.forEach(child => this.serialize(child, lineFragment));
98-
const context: CopyContext = { node: current, html: lineFragment };
96+
const blockFragment = document.createDocumentFragment();
97+
current.children.forEach(child => this.serialize(child, blockFragment));
98+
const context: CopyContext = { node: current, html: blockFragment };
9999
this.plugin.call(CALLER_TYPE.SERIALIZE, context, PLUGIN_TYPE.BLOCK);
100100
root.appendChild(context.html);
101101
return root as T;

packages/core/src/clipboard/modules/paste.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export class Paste extends EditorModule {
6767
} else {
6868
const context: PasteContext = { nodes: root, html: current };
6969
this.plugin.call(CALLER_TYPE.DESERIALIZE, context);
70+
return context.nodes;
7071
}
7172
return root;
7273
}

packages/core/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export type { Clipboard } from "./clipboard";
22
export { isDOMElement, isDOMNode, isDOMText, isHTMLElement } from "./clipboard/utils/deserialize";
33
export { getFragmentText, getTextContent, serializeHTML } from "./clipboard/utils/serialize";
4-
export type { CopyContext, PasteContext } from "./clipboard/utils/types";
4+
export type { CopyContext, PasteContext, PasteNodesContext } from "./clipboard/utils/types";
55
export type { Command } from "./command";
66
export type { CommandFn, EditorCommands } from "./command/types";
77
export type { Do } from "./do";

packages/core/src/plugin/modules/declare.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ abstract class BasePlugin {
1313
public abstract readonly type: PluginType;
1414
/**
1515
* 插件调度优先级
16-
* 渲染层面 优先级越高`DOM`结构在越外层
16+
* 渲染层面 优先级越高 DOM 结构在越外层
1717
* */
1818
public readonly priority?: number;
1919
/** 插件销毁时调度 */
2020
public abstract destroy(): void;
2121
/** 插件命令注册 */
2222
public onCommand?: CommandFn;
23-
/** 对`Range[]`进行装饰 */
23+
/** 对 Range[] 进行装饰 */
2424
public onDecorate?(entry: NodeEntry): Range[];
25-
/** 将`Fragment`序列化为`HTML` */
25+
/** 将 Fragment 序列化为 HTML */
2626
public serialize?(context: CopyContext): void;
27-
/** 将`HTML`反序列化为`Fragment` */
27+
/** 将 HTML 反序列化为 Fragment */
2828
public deserialize?(context: PasteContext): void;
29-
/** 对节点进行`Normalize` */
29+
/** 对节点进行 Normalize */
3030
public normalize?(entry: NodeEntry): void;
3131
/** 内容即将写入剪贴板 */
3232
public willSetToClipboard?(context: CopyContext): void;

packages/plugin/src/clipboard/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { PasteContext } from "doc-editor-core";
22
import type { EditorKit } from "doc-editor-core";
3+
import type { PasteNodesContext } from "doc-editor-core";
34
import { BlockPlugin } from "doc-editor-core";
4-
import type { PasteNodesContext } from "doc-editor-core/dist/clipboard/utils/types";
55
import type { BaseNode } from "doc-editor-delta";
66
import { getUniqueId, isText } from "doc-editor-utils";
77

packages/plugin/src/image/index.tsx

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import "./styles/index.scss";
22

3-
import type { BlockContext, EditorKit } from "doc-editor-core";
3+
import type { BlockContext, CopyContext, EditorKit, PasteContext } from "doc-editor-core";
44
import type { CommandFn } from "doc-editor-core";
5-
import { BlockPlugin } from "doc-editor-core";
6-
import type { RenderElementProps } from "doc-editor-delta";
5+
import { BlockPlugin, isHTMLElement } from "doc-editor-core";
6+
import type { BlockElement, RenderElementProps } from "doc-editor-delta";
77
import { Editor, HistoryEditor, Range, Transforms } from "doc-editor-delta";
8-
import { existKey, getClosestBlockPath, getUniqueId } from "doc-editor-utils";
8+
import { existKey, getClosestBlockPath, getId, getUniqueId } from "doc-editor-utils";
99

10+
import { isMatchTag } from "../clipboard/utils/is";
1011
import { focusSelection } from "../shared/modules/selection";
1112
import { DocImage } from "./components/doc-image";
1213
import { IMAGE_KEY, IMAGE_STATUS } from "./types";
@@ -105,6 +106,39 @@ export class ImagePlugin extends BlockPlugin {
105106
imageInput.click();
106107
};
107108

109+
public serialize(context: CopyContext): void {
110+
const element = context.node as BlockElement;
111+
const img = element[IMAGE_KEY];
112+
if (!img) return void 0;
113+
const node = document.createElement("img");
114+
node.src = img.src;
115+
node.setAttribute("data-type", IMAGE_KEY);
116+
node.appendChild(context.html);
117+
context.html = node;
118+
}
119+
120+
public deserialize(context: PasteContext): void {
121+
const { html } = context;
122+
if (!isHTMLElement(html)) return void 0;
123+
if (isMatchTag(html, "img")) {
124+
const src = html.getAttribute("src") || "";
125+
const width = html.getAttribute("data-width") || 100;
126+
const height = html.getAttribute("data-height") || 100;
127+
context.nodes = [
128+
{
129+
[IMAGE_KEY]: {
130+
src: src,
131+
status: IMAGE_STATUS.SUCCESS,
132+
width: Number(width),
133+
height: Number(height),
134+
},
135+
uuid: getId(),
136+
children: [{ text: "" }],
137+
},
138+
];
139+
}
140+
}
141+
108142
public render(context: BlockContext): JSX.Element {
109143
return (
110144
<DocImage editor={this.editor} element={context.element} readonly={this.readonly}></DocImage>

0 commit comments

Comments
 (0)