y-mxgraph 0.1.6 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -13
- package/binding/index.d.ts +25 -0
- package/binding/index.d.ts.map +1 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/types/drawio.d.ts +4 -0
- package/types/drawio.d.ts.map +1 -1
- package/y-mxgraph.cjs.js +163 -20
- package/y-mxgraph.cjs.js.map +1 -1
- package/y-mxgraph.es.js +163 -20
- package/y-mxgraph.es.js.map +1 -1
- package/y-mxgraph.iife.js +163 -20
- package/y-mxgraph.iife.js.map +1 -1
- package/y-mxgraph.umd.js +163 -20
- package/y-mxgraph.umd.js.map +1 -1
package/README.md
CHANGED
|
@@ -24,25 +24,24 @@ pnpm add y-mxgraph yjs y-protocols
|
|
|
24
24
|
|
|
25
25
|
```ts
|
|
26
26
|
import * as Y from 'yjs';
|
|
27
|
-
import { Binding
|
|
27
|
+
import { Binding } from 'y-mxgraph';
|
|
28
28
|
|
|
29
29
|
const doc = new Y.Doc();
|
|
30
30
|
|
|
31
31
|
App.main((app) => {
|
|
32
32
|
const file = app.currentFile;
|
|
33
33
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const binding = new Binding(file, { doc });
|
|
34
|
+
// Binding automatically reconciles file and Y.Doc based on
|
|
35
|
+
// `initialContent` strategy (default: 'replace').
|
|
36
|
+
// - 'replace' : Y.Doc wins; file UI is replaced with doc XML
|
|
37
|
+
// - 'merge-remote' : union by diagram id; doc wins on conflicts
|
|
38
|
+
// - 'merge-client' : union by diagram id; file wins on conflicts
|
|
39
|
+
//
|
|
40
|
+
// By default only `file.ui.setFileData(xml)` is called (rebuilds UI).
|
|
41
|
+
// `file.setData(xml)` is intentionally NOT called so draw.io does not
|
|
42
|
+
// mark the file as modified and pop up the "Save diagrams to:" dialog.
|
|
43
|
+
// Override via `applyFileData` if you need to sync `file.data` too.
|
|
44
|
+
const binding = new Binding(file, { doc /*, initialContent: 'merge-remote' */ });
|
|
46
45
|
|
|
47
46
|
window.addEventListener('beforeunload', () => binding.destroy());
|
|
48
47
|
});
|
package/binding/index.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import * as Y from "yjs";
|
|
2
2
|
import { type Awareness } from "y-protocols/awareness";
|
|
3
3
|
import type { DrawioFile } from "../types/drawio";
|
|
4
|
+
/**
|
|
5
|
+
* 控制 Binding 构造时 file 与 Y.Doc 的初始内容对齐策略。
|
|
6
|
+
* - `replace` : doc 非空则用 doc 覆盖 file;doc 为空则保留 file 现有数据(默认)。
|
|
7
|
+
* - `merge-remote` : 按 diagram id 取并集,同 id 冲突时以 doc 为准(远端权威)。
|
|
8
|
+
* - `merge-client` : 按 diagram id 取并集,同 id 冲突时以 file 为准(本地权威,覆盖到 doc)。
|
|
9
|
+
*/
|
|
10
|
+
export type InitialContentStrategy = "replace" | "merge-remote" | "merge-client";
|
|
4
11
|
export interface BindDrawioFileOptions {
|
|
5
12
|
doc: Y.Doc;
|
|
6
13
|
awareness?: Awareness;
|
|
@@ -10,6 +17,20 @@ export interface BindDrawioFileOptions {
|
|
|
10
17
|
userNameKey?: string;
|
|
11
18
|
userColorKey?: string;
|
|
12
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* 初始内容对齐策略,默认 `replace`。详见 {@link InitialContentStrategy}。
|
|
22
|
+
*/
|
|
23
|
+
initialContent?: InitialContentStrategy;
|
|
24
|
+
/**
|
|
25
|
+
* 自定义把 XML 应用到 file 的方式。默认实现只调用
|
|
26
|
+
* `file.ui.setFileData(xml)`(刷新 UI / 重建 pages),
|
|
27
|
+
* **不会**调用 `file.setData(xml)`,以避免把 file 标记为「已修改」
|
|
28
|
+
* 触发 draw.io 的 "Save diagrams to:" 存储选择对话框。
|
|
29
|
+
*
|
|
30
|
+
* 若业务方确实需要同步 `file.data`(如自定义 CollabFile 或依赖
|
|
31
|
+
* `file.save()`),可提供自定义实现。
|
|
32
|
+
*/
|
|
33
|
+
applyFileData?: (file: DrawioFile, xml: string) => void;
|
|
13
34
|
}
|
|
14
35
|
/**
|
|
15
36
|
* Y-MXGraph 绑定类,管理 draw.io 文件与 Y.Doc 的双向同步
|
|
@@ -36,6 +57,10 @@ export declare class Binding {
|
|
|
36
57
|
private cleanupCollaborator?;
|
|
37
58
|
/** UndoManager 绑定清理函数 */
|
|
38
59
|
private cleanupUndoManager?;
|
|
60
|
+
/** 初始内容策略 */
|
|
61
|
+
private initialContentStrategy;
|
|
62
|
+
/** replace 策略下,构造时 doc 为空,现在 doc 有数据时需要强制替换 */
|
|
63
|
+
private get shouldReplaceWhenDocHasData();
|
|
39
64
|
constructor(file: DrawioFile, options: BindDrawioFileOptions);
|
|
40
65
|
/**
|
|
41
66
|
* 销毁绑定,解除所有监听器
|
package/binding/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/binding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/binding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAiBvD,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,cAAc,GACd,cAAc,CAAC;AAEnB,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EACH,OAAO,GACP;QACE,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACN;;OAEG;IACH,cAAc,CAAC,EAAE,sBAAsB,CAAC;IACxC;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACzD;AA0KD;;;;;;;GAOG;AACH,qBAAa,OAAO;IAClB,wBAAwB;IACxB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACpB,6BAA6B;IAC7B,OAAO,CAAC,YAAY,CAAe;IACnC,sBAAsB;IACtB,OAAO,CAAC,kBAAkB,CAAS;IACnC,4BAA4B;IAC5B,OAAO,CAAC,cAAc,CAAS;IAC/B,2BAA2B;IAC3B,OAAO,CAAC,UAAU,CAAa;IAC/B,oBAAoB;IACpB,OAAO,CAAC,WAAW,CAKT;IACV,gCAAgC;IAChC,OAAO,CAAC,mBAAmB,CAAC,CAAa;IACzC,yBAAyB;IACzB,OAAO,CAAC,kBAAkB,CAAC,CAAa;IACxC,aAAa;IACb,OAAO,CAAC,sBAAsB,CAAyB;IAEvD,+CAA+C;IAC/C,OAAO,KAAK,2BAA2B,GAEtC;gBAEW,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB;IA4I5D;;;OAGG;IACH,OAAO,CAAC,IAAI,UAAQ,GAAG,IAAI;IAS3B;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,oBAAoB,CAAC,SAAS,SAAc,GAAG,MAAM;IAa5D;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO;CAGzE"}
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Binding } from "./binding";
|
|
2
|
-
export type { BindDrawioFileOptions } from "./binding";
|
|
2
|
+
export type { BindDrawioFileOptions, InitialContentStrategy } from "./binding";
|
|
3
3
|
export { xml2doc, doc2xml } from "./transformer";
|
|
4
4
|
export { LOCAL_ORIGIN } from "./helper/origin";
|
|
5
5
|
export { DEFAULT_USER_NAME_KEY, DEFAULT_USER_COLOR_KEY, } from "./binding/collaborator";
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC"}
|
package/package.json
CHANGED
package/types/drawio.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export interface DrawioUi {
|
|
|
56
56
|
pages: unknown[];
|
|
57
57
|
diffPages(oldPages: unknown[], newPages: unknown[]): unknown;
|
|
58
58
|
clonePages(pages: unknown[]): unknown[];
|
|
59
|
+
/** 解析 XML 并重建 pages / mxGraphModel,触发 UI 重绘 */
|
|
60
|
+
setFileData(data: string): void;
|
|
59
61
|
}
|
|
60
62
|
/** mxGraph 事件对象 */
|
|
61
63
|
export interface MxEventObject {
|
|
@@ -71,6 +73,8 @@ export interface DrawioFile {
|
|
|
71
73
|
getUi(): DrawioUi;
|
|
72
74
|
setShadowPages(pages: unknown[]): void;
|
|
73
75
|
patch(patches: unknown[]): void;
|
|
76
|
+
/** 仅赋值 this.data = xml,不触发 UI 重绘 */
|
|
77
|
+
setData(data: string): void;
|
|
74
78
|
}
|
|
75
79
|
/** draw.io App(demo 中通过 iframe 访问) */
|
|
76
80
|
export interface DrawioApp {
|
package/types/drawio.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawio.d.ts","sourceRoot":"","sources":["../../src/types/drawio.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,iBAAiB;AACjB,MAAM,WAAW,UAAU;IACzB,KAAK,IAAI,MAAM,CAAC;CACjB;AAED,iBAAiB;AACjB,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iBAAiB;AACjB,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACnE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACtE,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;CACrC;AAED,mBAAmB;AACnB,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACnE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CACvE;AAED,iBAAiB;AACjB,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,WAAW,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,iBAAiB,IAAI,cAAc,CAAC;IACpC,aAAa,CACX,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ;QAAE,OAAO,IAAI,IAAI,CAAA;KAAE,CAAC;CACxB;AAED,kBAAkB;AAClB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE;QACZ,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;QAC3B,YAAY,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;QAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,YAAY,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CAC7C;AAED,iBAAiB;AACjB,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,WAAW,CAAC;IAC9B,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC7D,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"drawio.d.ts","sourceRoot":"","sources":["../../src/types/drawio.ts"],"names":[],"mappings":"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"}
|
package/y-mxgraph.cjs.js
CHANGED
|
@@ -1455,32 +1455,148 @@ function bindCollaborator(file, options) {
|
|
|
1455
1455
|
cleanupAwareness == null ? void 0 : cleanupAwareness();
|
|
1456
1456
|
};
|
|
1457
1457
|
}
|
|
1458
|
+
const defaultApplyFileData = (file, xml) => {
|
|
1459
|
+
file.ui.setFileData(xml);
|
|
1460
|
+
};
|
|
1461
|
+
function mergeFileIntoDoc(doc, fileXml, strategy) {
|
|
1462
|
+
let parsed;
|
|
1463
|
+
try {
|
|
1464
|
+
parsed = parse$4(fileXml);
|
|
1465
|
+
} catch (err) {
|
|
1466
|
+
console.warn(
|
|
1467
|
+
"[y-mxgraph] 合并失败,file XML 解析异常,回退到 replace:",
|
|
1468
|
+
err
|
|
1469
|
+
);
|
|
1470
|
+
return false;
|
|
1471
|
+
}
|
|
1472
|
+
const mxfileObj = parsed == null ? void 0 : parsed.mxfile;
|
|
1473
|
+
if (!mxfileObj || !Array.isArray(mxfileObj.diagram)) {
|
|
1474
|
+
console.warn(
|
|
1475
|
+
"[y-mxgraph] 合并失败,file XML 不是合法 mxfile,回退到 replace"
|
|
1476
|
+
);
|
|
1477
|
+
return false;
|
|
1478
|
+
}
|
|
1479
|
+
const mxfileMap = doc.getMap(key);
|
|
1480
|
+
const diagramMap = mxfileMap.get(key$1);
|
|
1481
|
+
const diagramOrder = mxfileMap.get(diagramOrderKey);
|
|
1482
|
+
if (!diagramMap || !diagramOrder) {
|
|
1483
|
+
console.warn("[y-mxgraph] 合并失败,doc 结构不完整,回退到 replace");
|
|
1484
|
+
return false;
|
|
1485
|
+
}
|
|
1486
|
+
doc.transact(() => {
|
|
1487
|
+
var _a;
|
|
1488
|
+
for (const diagram of mxfileObj.diagram) {
|
|
1489
|
+
const id = ((_a = diagram._attributes) == null ? void 0 : _a.id) || "";
|
|
1490
|
+
if (!id)
|
|
1491
|
+
continue;
|
|
1492
|
+
const docHas = diagramMap.has(id);
|
|
1493
|
+
if (docHas && strategy === "merge-remote") {
|
|
1494
|
+
continue;
|
|
1495
|
+
}
|
|
1496
|
+
const yDiagram = parse$1(
|
|
1497
|
+
diagram
|
|
1498
|
+
);
|
|
1499
|
+
diagramMap.set(id, yDiagram);
|
|
1500
|
+
if (!docHas) {
|
|
1501
|
+
diagramOrder.push([id]);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
});
|
|
1505
|
+
return true;
|
|
1506
|
+
}
|
|
1507
|
+
function reconcileInitialContent(doc, file, strategy, applyFileData) {
|
|
1508
|
+
const mxfileMap = doc.getMap(key);
|
|
1509
|
+
const docHasData = mxfileMap.size > 0;
|
|
1510
|
+
const fileHasAnyData = !!file.data;
|
|
1511
|
+
const fileHasDiagrams = fileHasAnyData && file.data.includes("<diagram");
|
|
1512
|
+
if (strategy === "replace") {
|
|
1513
|
+
if (docHasData) {
|
|
1514
|
+
const xml2 = doc2xml(doc);
|
|
1515
|
+
if (xml2 && xml2.includes("<diagram")) {
|
|
1516
|
+
applyFileData(file, xml2);
|
|
1517
|
+
} else if (!fileHasAnyData) {
|
|
1518
|
+
applyFileData(file, Binding.generateFileTemplate("diagram-0"));
|
|
1519
|
+
}
|
|
1520
|
+
} else if (!fileHasAnyData) {
|
|
1521
|
+
applyFileData(file, Binding.generateFileTemplate("diagram-0"));
|
|
1522
|
+
}
|
|
1523
|
+
return mxfileMap.size > 0;
|
|
1524
|
+
}
|
|
1525
|
+
if (!docHasData && !fileHasDiagrams) {
|
|
1526
|
+
if (!fileHasAnyData) {
|
|
1527
|
+
applyFileData(file, Binding.generateFileTemplate("diagram-0"));
|
|
1528
|
+
}
|
|
1529
|
+
return false;
|
|
1530
|
+
}
|
|
1531
|
+
if (!docHasData && fileHasDiagrams) {
|
|
1532
|
+
try {
|
|
1533
|
+
doc.transact(() => {
|
|
1534
|
+
xml2doc(file.data, doc);
|
|
1535
|
+
});
|
|
1536
|
+
return true;
|
|
1537
|
+
} catch (err) {
|
|
1538
|
+
console.warn(
|
|
1539
|
+
"[y-mxgraph] merge 模式下 xml2doc 失败,回退 replace:",
|
|
1540
|
+
err
|
|
1541
|
+
);
|
|
1542
|
+
applyFileData(file, Binding.generateFileTemplate("diagram-0"));
|
|
1543
|
+
return false;
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
if (docHasData && !fileHasDiagrams) {
|
|
1547
|
+
const xml2 = doc2xml(doc);
|
|
1548
|
+
if (xml2 && xml2.includes("<diagram")) {
|
|
1549
|
+
applyFileData(file, xml2);
|
|
1550
|
+
} else if (!fileHasAnyData) {
|
|
1551
|
+
applyFileData(file, Binding.generateFileTemplate("diagram-0"));
|
|
1552
|
+
}
|
|
1553
|
+
return mxfileMap.size > 0;
|
|
1554
|
+
}
|
|
1555
|
+
const ok = mergeFileIntoDoc(doc, file.data, strategy);
|
|
1556
|
+
if (!ok) {
|
|
1557
|
+
const xml2 = doc2xml(doc);
|
|
1558
|
+
if (xml2 && xml2.includes("<diagram"))
|
|
1559
|
+
applyFileData(file, xml2);
|
|
1560
|
+
return mxfileMap.size > 0;
|
|
1561
|
+
}
|
|
1562
|
+
const xml = doc2xml(doc);
|
|
1563
|
+
if (xml && xml.includes("<diagram"))
|
|
1564
|
+
applyFileData(file, xml);
|
|
1565
|
+
return true;
|
|
1566
|
+
}
|
|
1458
1567
|
class Binding {
|
|
1459
1568
|
constructor(file, options) {
|
|
1460
1569
|
this.suppressLocalApply = false;
|
|
1461
1570
|
this.docInitialized = false;
|
|
1462
|
-
const {
|
|
1571
|
+
const {
|
|
1572
|
+
doc,
|
|
1573
|
+
awareness,
|
|
1574
|
+
undoManager,
|
|
1575
|
+
mouseMoveThrottle,
|
|
1576
|
+
cursor,
|
|
1577
|
+
initialContent = "replace",
|
|
1578
|
+
applyFileData = defaultApplyFileData
|
|
1579
|
+
} = options;
|
|
1463
1580
|
this.doc = doc;
|
|
1581
|
+
this.initialContentStrategy = initialContent;
|
|
1464
1582
|
const ui = file.getUi();
|
|
1465
1583
|
const graph = ui.editor.graph;
|
|
1466
1584
|
this.mxGraphModel = graph.model;
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
file.patch([fullPatch]);
|
|
1478
|
-
} finally {
|
|
1479
|
-
this.suppressLocalApply = false;
|
|
1480
|
-
}
|
|
1585
|
+
this.suppressLocalApply = true;
|
|
1586
|
+
try {
|
|
1587
|
+
this.docInitialized = reconcileInitialContent(
|
|
1588
|
+
doc,
|
|
1589
|
+
file,
|
|
1590
|
+
initialContent,
|
|
1591
|
+
applyFileData
|
|
1592
|
+
);
|
|
1593
|
+
if (this.docInitialized) {
|
|
1594
|
+
initDocSnapshot(doc, false);
|
|
1481
1595
|
}
|
|
1482
|
-
|
|
1596
|
+
} finally {
|
|
1597
|
+
this.suppressLocalApply = false;
|
|
1483
1598
|
}
|
|
1599
|
+
file.setShadowPages(file.ui.clonePages(file.ui.pages));
|
|
1484
1600
|
this.mxListener = () => {
|
|
1485
1601
|
if (this.suppressLocalApply)
|
|
1486
1602
|
return;
|
|
@@ -1503,13 +1619,36 @@ class Binding {
|
|
|
1503
1619
|
};
|
|
1504
1620
|
this.mxGraphModel.addListener("change", this.mxListener);
|
|
1505
1621
|
this.docObserver = (events, transaction) => {
|
|
1506
|
-
if (!this.docInitialized) {
|
|
1507
|
-
this.docInitialized = true;
|
|
1508
|
-
}
|
|
1509
1622
|
if (transaction.local && transaction.origin === LOCAL_ORIGIN) {
|
|
1510
1623
|
generatePatch(events);
|
|
1511
1624
|
return;
|
|
1512
1625
|
}
|
|
1626
|
+
if (this.shouldReplaceWhenDocHasData) {
|
|
1627
|
+
const mxfileMap = doc.getMap(key);
|
|
1628
|
+
const diagramMap = mxfileMap.get(key$1);
|
|
1629
|
+
if (diagramMap && diagramMap.size > 0) {
|
|
1630
|
+
const xml = doc2xml(doc);
|
|
1631
|
+
if (xml && xml.includes("<diagram")) {
|
|
1632
|
+
this.suppressLocalApply = true;
|
|
1633
|
+
try {
|
|
1634
|
+
applyFileData(file, xml);
|
|
1635
|
+
file.setShadowPages(file.ui.clonePages(file.ui.pages));
|
|
1636
|
+
initDocSnapshot(doc, false);
|
|
1637
|
+
const ui2 = file.getUi();
|
|
1638
|
+
const editor = ui2.editor;
|
|
1639
|
+
editor.setStatus("");
|
|
1640
|
+
editor.setModified(false);
|
|
1641
|
+
} finally {
|
|
1642
|
+
this.suppressLocalApply = false;
|
|
1643
|
+
}
|
|
1644
|
+
this.docInitialized = true;
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
if (!this.docInitialized) {
|
|
1650
|
+
this.docInitialized = true;
|
|
1651
|
+
}
|
|
1513
1652
|
const patch = generatePatch(events);
|
|
1514
1653
|
if (Object.keys(patch).length === 0)
|
|
1515
1654
|
return;
|
|
@@ -1521,7 +1660,7 @@ class Binding {
|
|
|
1521
1660
|
this.suppressLocalApply = false;
|
|
1522
1661
|
}
|
|
1523
1662
|
};
|
|
1524
|
-
|
|
1663
|
+
doc.getMap(key).observeDeep(this.docObserver);
|
|
1525
1664
|
if (awareness) {
|
|
1526
1665
|
this.cleanupCollaborator = bindCollaborator(file, {
|
|
1527
1666
|
awareness,
|
|
@@ -1534,6 +1673,10 @@ class Binding {
|
|
|
1534
1673
|
this.cleanupUndoManager = bindUndoManager(doc, file, undoManager);
|
|
1535
1674
|
}
|
|
1536
1675
|
}
|
|
1676
|
+
/** replace 策略下,构造时 doc 为空,现在 doc 有数据时需要强制替换 */
|
|
1677
|
+
get shouldReplaceWhenDocHasData() {
|
|
1678
|
+
return this.initialContentStrategy === "replace" && !this.docInitialized;
|
|
1679
|
+
}
|
|
1537
1680
|
/**
|
|
1538
1681
|
* 销毁绑定,解除所有监听器
|
|
1539
1682
|
* @param deep - 是否深度清理(包括 awareness/undoManager),默认 false
|